Revert "Updated application sources" 03/22403/1 master
authorPiotr Wronski <p.wronski@samsung.com>
Tue, 3 Jun 2014 05:54:24 +0000 (22:54 -0700)
committerPiotr Wronski <p.wronski@samsung.com>
Tue, 3 Jun 2014 05:54:24 +0000 (22:54 -0700)
This reverts commit 335f789d65024a4f29b1fc71773bac03430de476.

Change-Id: Iabb29838bd0089cd3e9497f8618a02c7c8a623c4

20 files changed:
project/.project
project/NOTICE
project/config.xml
project/css/style.css
project/index.html
project/js/app.config.js
project/js/app.helpers.js
project/js/app.js
project/js/app.model.js
project/js/app.ui.js
project/js/app.ui.templateManager.js
project/js/app.ui.templateManager.modifiers.js
project/js/main.js
project/templates/callItemRow.tpl
project/templates/callView.tpl
project/templates/callerCallItemRow.tpl
project/templates/callerHistory.tpl
project/templates/dateRow.tpl
project/templates/errorWindow.tpl
project/templates/messageWindow.tpl

index b4cdad6..0b84754 100644 (file)
@@ -1,59 +1,59 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-    <name>CallLog</name>
-    <comment></comment>
-    <projects>
-    </projects>
-    <buildSpec>
-        <buildCommand>
-            <name>org.eclipse.wst.common.project.facet.core.builder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>json.validation.builder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.tizen.web.jslint.nature.JSLintBuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.tizen.web.css.nature.CSSBuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.eclipse.wst.validation.validationbuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.tizen.web.project.builder.WebBuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.tizen.web.privilege.nature.PrivilegeBuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-        <buildCommand>
-            <name>org.tizen.web.editor.css.nature.CSSBuilder</name>
-            <arguments>
-            </arguments>
-        </buildCommand>
-    </buildSpec>
-    <natures>
-        <nature>json.validation.nature</nature>
-        <nature>org.tizen.web.jslint.nature.JSLintNature</nature>
-        <nature>org.tizen.web.css.nature.CSSNature</nature>
-        <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
-        <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
-        <nature>org.tizen.web.project.builder.WebNature</nature>
-        <nature>org.tizen.web.privilege.nature.PrivilegeNature</nature>
-        <nature>org.tizen.web.editor.css.nature.CSSNature</nature>
-    </natures>
+       <name>CallLog</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.wst.common.project.facet.core.builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>json.validation.builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.web.jslint.nature.JSLintBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.web.css.nature.CSSBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.wst.validation.validationbuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.web.project.builder.WebBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.web.privilege.nature.PrivilegeBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.tizen.web.editor.css.nature.CSSBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>json.validation.nature</nature>
+               <nature>org.tizen.web.jslint.nature.JSLintNature</nature>
+               <nature>org.tizen.web.css.nature.CSSNature</nature>
+               <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+               <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+               <nature>org.tizen.web.project.builder.WebNature</nature>
+               <nature>org.tizen.web.privilege.nature.PrivilegeNature</nature>
+               <nature>org.tizen.web.editor.css.nature.CSSNature</nature>
+       </natures>
 </projectDescription>
index e5d95db..092bc04 100644 (file)
@@ -1,3 +1,4 @@
 Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
 Except as noted, this software is licensed under Flora License, Version 1.1
 Please, see the LICENSE.Flora file for Flora License, Version 1.1 terms and conditions.
+
index a69111a..6442a3b 100644 (file)
@@ -1,34 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<widget
-    xmlns="http://www.w3.org/ns/widgets"
-    xmlns:tizen="http://tizen.org/ns/widgets"
-    id="http://sample-web-application.tizen.org/CallLog"
-    version="2.2.0"
-    viewmodes="maximized">
-
-    <tizen:application
-        id="1I49ZSFY56.CallLog"
-        package="1I49ZSFY56"
-        required_version="2.2" />
-
-    <content src="index.html" />
-
-    <icon src="icon.png" />
-
-    <name>Call Log</name>
-
-    <feature name="http://tizen.org/feature/screen.size.normal.720.1280" />
-
-    <tizen:privilege name="http://tizen.org/privilege/application.launch" />
-    <tizen:privilege name="http://tizen.org/privilege/callhistory.read" />
-    <tizen:privilege name="http://tizen.org/privilege/callhistory.write" />
-    <tizen:privilege name="http://tizen.org/privilege/contact.read" />
-
-    <tizen:setting
-        screen-orientation="portrait"
-        context-menu="disable"
-        background-support="disable"
-        encryption="disable"
-        install-location="auto" />
-
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://sample-web-application.tizen.org/CallLog" version="2.2.0" viewmodes="maximized">
+       <tizen:application id="1I49ZSFY56.CallLog" package="1I49ZSFY56" required_version="2.2"/>
+       <content src="index.html"/>
+       <icon src="icon.png"/>
+       <name>Call Log</name>
+       <feature name="http://tizen.org/feature/screen.size.normal.720.1280"/>
+       <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
+       <tizen:privilege name="http://tizen.org/privilege/callhistory.read"/>
+       <tizen:privilege name="http://tizen.org/privilege/callhistory.write"/>
+       <tizen:privilege name="http://tizen.org/privilege/contact.read"/>
+       <tizen:setting screen-orientation="portrait" context-menu="disable" background-support="disable" encryption="disable" install-location="auto"/>
 </widget>
index 38d63a6..e613077 100644 (file)
@@ -5,7 +5,6 @@ html,body {
        color: #fff;
        font-family: Lucida Sans, Arial, Helvetica, sans-serif;
        overflow: hidden;
-       -webkit-user-select: none;
 }
 
 ul.calllogList li.date {
@@ -266,8 +265,7 @@ li.ui-screen-hidden{
        float: left;
        background-size: 100%;
        border-radius: 4px;
-       margin-right: 6px;
-       margin-top: 14px;
+       margin-right: 5px;
 }
 
 .toRemove input {
@@ -372,6 +370,10 @@ li.ui-screen-hidden{
        border: 0px;
 }
 
+#header.ui-bar-s .ui-btn {
+       /*width: 100px; // this property changed back button width*/
+}
+
 .ui-popupwindow {
        color: black;
        padding:0.4em;
index 2622b33..c3c0778 100644 (file)
@@ -1,24 +1,20 @@
 <!DOCTYPE html>
 <html>
 <head>
+       <meta charset="utf-8"/>
+       <meta name="description" content="Call log Web Sample App"/>
+       <meta name="viewport" content="width=360, user-scalable=no"/>
 
-    <meta charset="utf-8" />
-    <meta name="viewport" content="width=360, user-scalable=no" />
+       <title>Call log</title>
 
-    <title>Call log</title>
-    <meta name="description" content="Call log" />
-
-    <script src="/usr/share/tizen-web-ui-fw/latest/js/jquery.min.js"></script>
-    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js"></script>
-    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.min.js" data-framework-theme="tizen-white" data-framework-viewport-scale="false"></script>
-
-    <link rel="stylesheet" type="text/css" href="./css/style.css" />
-    <script type="text/javascript" src="./js/main.js"></script>
+       <script src="tizen-web-ui-fw/latest/js/jquery.min.js"></script>
+       <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js"></script>
+       <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw.min.js" data-framework-theme="tizen-white" data-framework-viewport-scale="false"></script>
 
+       <script type="text/javascript" src="./js/main.js"></script>
+       <link rel="stylesheet" type="text/css" href="./css/style.css"/>
 </head>
 <body>
-
-    <div data-role="page" data-footer-Exist="false" id="callView"></div>
-
+       <div data-role="page" data-footer-Exist="false" id="callView"></div>
 </body>
-</html>
+</html>
\ No newline at end of file
index 4a9ccb4..03eb992 100644 (file)
@@ -1,49 +1,30 @@
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 tizen*/
 
 /**
-* @class Config
-*/
+ * @class Config
+ */
 function Config() {
-    'use strict';
+       'use strict';
 }
 
 (function () { // strict mode wrapper
-    'use strict';
-
-    Config.prototype = {
-
-        properties: {
-            'templateDir': 'templates',
-            'templateExtension': '.tpl'
-        },
-
-        /**
-        * Returns config value
-        */
-        get: function (value, defaultValue) {
-
-            if (this.properties.hasOwnProperty(value)) {
-                return this.properties[value];
-            }
-            return defaultValue;
-        }
-
-    };
-
+       'use strict';
+       Config.prototype = {
+
+               properties: {
+                       'templateDir': 'templates',
+                       'templateExtension': '.tpl'
+               },
+
+               /**
+                * Returns config value
+                */
+               get: function (value, defaultValue) {
+
+                       if (this.properties.hasOwnProperty(value)) {
+                               return this.properties[value];
+                       }
+                       return defaultValue;
+               }
+       };
 }());
index 6b8ee7d..868f551 100644 (file)
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 devel: true*/
-/*global tizen, $*/
+/*global */
 
 /**
-* @class Helpers
-*/
+ * @class Helpers
+ */
 function Helpers() {
-    'use strict';
+       'use strict';
 }
 
 (function () { // strict mode wrapper
-    'use strict';
+       'use strict';
+       Helpers.prototype = {
+
+               /**
+                * Returns date in format YYYY/MM/DD
+                * @param dateObj
+                * @returns {String} formatted
+                */
+               getShortDate: function Helpers_getShortDate(dateObj) {
+                       var dd, mm, yyyy;
 
-    Helpers.prototype = {
+                       try {
+                               yyyy = dateObj.getFullYear().toString();
+                               mm = (dateObj.getMonth() + 1).toString(); // getMonth() is zero-based
+                               dd  = dateObj.getDate().toString();
+                       } catch (e) {
+                               console.error('error', e);
+                       }
 
-        /**
-        * Returns date in format YYYY/MM/DD
-        * @param dateObj
-        * @returns {String} formatted
-        */
-        getShortDate: function Helpers_getShortDate(dateObj) {
-            var dd, mm, yyyy;
+                       return yyyy + '/' + (mm[1] ? mm : '0' + mm[0]) + '/' + (dd[1] ? dd : '0' + dd[0]);
+               },
+               /**
+                * Returns date in format DD short_month YYYY
+                * @param dateObj
+                * @returns {String} formatted
+                */
+               toNativeDate: function Helpers_toNativeDate(dateObj) {
+                       var date = dateObj.toDateString().split(" ");
 
-            try {
-                yyyy = dateObj.getFullYear().toString();
-                mm = (dateObj.getMonth() + 1).toString(); // January === 0
-                dd  = dateObj.getDate().toString();
-            } catch (e) {
-                console.error('error', e);
-            }
+                       return  date[2] + ' ' + date[1] + ' ' + date[3];
+               },
+               /**
+                * Returns time in format HH:mm or hh:mm ap
+                * @param dateObj
+                * @returns {String} formatted
+                */
+               toNativeTime: function Helpers_toNativeDate(dateObj) {
+                       var hours, apHours;
 
-            // return in format yyyy/mm/dd
-            return yyyy + '/' + (mm[1] ?
-                mm :
-                '0' + mm[0]) + '/' + (dd[1] ? dd : '0' + dd[0]);
-        },
-        /**
-        * Returns date in format DD short_month YYYY
-        * @param dateObj
-        * @returns {String} formatted
-        */
-        toNativeDate: function Helpers_toNativeDate(dateObj) {
-            var date = dateObj.toDateString().split(" ");
-            return date[2] + ' ' + date[1] + ' ' + date[3];
-        },
-        /**
-        * Returns time in format HH:mm or hh:mm ap
-        * @param dateObj
-        * @returns {String} formatted
-        */
-        toNativeTime: function Helpers_toNativeDate(dateObj) {
-            var hours, apHours;
-            if (tizen.time.getTimeFormat().indexOf('ap') !== -1) {
-                hours = dateObj.getHours();
-                apHours = hours % 12 < 10 ? '0' + hours % 12 : hours % 12;
+                       if (tizen.time.getTimeFormat().indexOf('ap') != -1) {
+                               hours = dateObj.getHours();
+                               apHours = hours % 12 < 10 ? '0' + hours % 12 : hours % 12;
 
-                return apHours.toString().replace("00", "12") + ':' +
-                    (dateObj.getMinutes() < 10 ? "0" + dateObj.getMinutes() :
-                    dateObj.getMinutes()) + (hours > 11 ? ' PM' : ' AM');
-            }
-            return dateObj.toTimeString().substring(0, 5);
-        },
-        /**
-        * Seconds to hours converter
-        *
-        * @param seconds
-        * @returns {string}
-        */
-        secondsToHours: function Helpers_secondsToHours(seconds) {
-            var str = '';
-            str = ((seconds % 60 < 10) ? '0' : '') + (seconds % 60);
-            seconds = parseInt(seconds / 60, 10);
-            str = ':' + str;
-            str = ((seconds % 60 < 10) ? '0' : '') + (seconds % 60) + str;
-            seconds = parseInt(seconds / 60, 10);
-            str = ':' + str;
-            str = ((seconds % 24 < 10) ? '0' : '') + (seconds % 24) + str;
-            seconds = parseInt(seconds / 24, 10);
-            return str;
-        },
+                               return apHours.toString().replace("00", "12") + ':' +
+                                       (dateObj.getMinutes() < 10 ? "0" + dateObj.getMinutes() :
+                                       dateObj.getMinutes()) + (hours > 11 ? ' PM' : ' AM');
+                       }
 
-        /**
-        * Returns scroll position of the given scroll view.
-        * @param {object} element ScrollView element
-        * @returns {number} scroll position
-        */
-        getScrollPosition: function Helpers_getScrollPosition(element) {
-            return element.scrollview('getScrollPosition').y;
-        },
+                       return dateObj.toTimeString().substring(0, 5);
+               },
+               /**
+                * Seconds to hours converter
+                *
+                * @param seconds
+                * @returns {string}
+                */
+               secondsToHours: function Helpers_secondsToHours(seconds) {
+                       var str = '';
+                       str = ((seconds % 60 < 10) ? '0' : '') + (seconds % 60);
+                       seconds = parseInt(seconds / 60, 10);
+                       str = ':' + str;
+                       str = ((seconds % 60 < 10) ? '0' : '') + (seconds % 60) + str;
+                       seconds = parseInt(seconds / 60, 10);
+                       str = ':' + str;
+                       str = ((seconds % 24 < 10) ? '0' : '') + (seconds % 24) + str;
+                       seconds = parseInt(seconds / 24, 10);
+                       return str;
+               },
 
-        /**
-        * Scrolls given jQuery ScrollView to given Y position.
-        * @param {object} element ScrollView element to be scrolled.
-        * @param {number} position Y position to scroll to
-        */
-        scrollTo: function Helpers_scrollTo(element, position) {
-            // don't allow scrolling too much
-            var maxPosition =
-                element.children().first().outerHeight(true) -
-                element.height();
-            if (maxPosition < 0) {
-                maxPosition = 0;
-            }
-            if (position > maxPosition) {
-                position = maxPosition;
-            }
-            if (position < 0) {
-                position = 0;
-            }
-            // scroll
-            element.scrollview('scrollTo', 0, -position);
-        }
+               /**
+                * Returns scroll position of the given scroll view.
+                * @param {object} element ScrollView element
+                * @returns {number} scroll position
+                */
+               getScrollPosition: function Helpers_getScrollPosition(element) {
+                       return element.scrollview('getScrollPosition').y;
+               },
 
-    };
+               /**
+                * Scrolls given jQuery ScrollView to given Y position.
+                * @param {object} element ScrollView element to be scrolled.
+                * @param {number} position Y position to scroll to
+                */
+               scrollTo: function Helpers_scrollTo(element, position) {
+                       // don't allow scrolling too much
+                       var maxPosition = element.children().first().outerHeight(true) - element.height();
+                       if (maxPosition < 0) {
+                               maxPosition = 0;
+                       }
+                       if (position > maxPosition) {
+                               position = maxPosition;
+                       }
+                       if (position < 0) {
+                               position = 0;
+                       }
+                       // scroll
+                       element.scrollview('scrollTo', 0, -position);
+               }
 
+       };
 }());
index 77acebe..e58ca9d 100644 (file)
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 devel: true*/
-/*global Config, Model, Ui, tizen, setTimeout, navigator, app */
+/*global Config, Model, Ui, tizen, setTimeout, navigator */
 
 var App = null;
 
 (function () { // strict mode wrapper
-    'use strict';
-
-    /**
-    * Creates a new application object
-    *
-    * @class Application
-    */
-    App = function App() {
-        this.configData = {};
-    };
-
-    App.prototype = {
-        /**
-        * @type Array
-        */
-        requires: [
-            'js/app.config.js',
-            'js/app.model.js',
-            'js/app.ui.js',
-            'js/app.ui.templateManager.js',
-            'js/app.ui.templateManager.modifiers.js',
-            'js/app.helpers.js'
-        ],
-
-        /**
-        * @type Model
-        */
-        model: null,
-
-        /**
-        * @type Ui
-        */
-        ui: null,
-
-        /**
-        * @type Config
-        */
-        config: null,
-
-        /**
-        * @type {number}
-        */
-        lastViewedCaller: 0,
-
-        /**
-        * Initialisation function
-        */
-        init: function App_init() {
-            // instantiate the libs
-            this.config = new Config();
-            this.model = new Model();
-            this.model.registerChangeListener(this.updateCallLists.bind(this));
-            this.ui = new Ui();
-            this.updateCallLists();
-
-            return this;
-        },
-
-        /**
-        * Updates call history and caller detailed history lists
-        */
-        updateCallLists: function App_updateCallLists() {
-            this.ui.updateCheckboxes();
-            // workaround - time zone update
-            tizen.time.getCurrentDateTime().toLocalTimezone();
-            // workaround;
-            setTimeout(this.showHistoryForCaller(this.lastViewedCaller), 500);
-            this.showCallHistory();
-        },
-
-        /**
-        * Renders call history view
-        */
-        showCallHistory: function App_showCallHistory() {
-            this.model.getCallHistory(this.ui.showCallHistory.bind(this.ui));
-        },
-
-        /**
-        * Renders history for caller view
-        * @param {string} phoneNumber
-        */
-        showHistoryForCaller: function App_showHistoryForCaller(phoneNumber) {
-            this.lastViewedCaller = phoneNumber;
-            this.model.getCallHistoryForCaller(
-                phoneNumber,
-                this.ui.showHistoryForCaller.bind(this.ui, phoneNumber)
-            );
-        },
-
-        /**
-        * @param {number} addressBookId
-        * @param {number} contactId
-        * @returns {string} photoURI Photo URI for specified contact
-        */
-        getPhotoURIForContact: function App_getPhotoURIForContact(personId) {
-            return this.model.getPhotoURIForContact(personId);
-        },
-
-        /**
-        * Launch extension call service
-        * @param {string} phoneNumber
-        */
-        makeCall: function App_makeCall(phoneNumber) {
-            var self = this,
-                appControl = new tizen.ApplicationControl(
-                    'http://tizen.org/appcontrol/operation/call',
-                    'tel:' + phoneNumber
-                );
-            tizen.application.launchAppControl(
-                appControl,
-                null,
-                function () {
-                    setTimeout(
-                        function () {
-                            self.ui.unlockButtons();
-                        },
-                        1500
-                    );
-                },
-                function (e) {
-                    console.error('Call to ' + phoneNumber
-                        + ' failed. Call service is unavailable.', e);
-                    self.ui.showErrorPopup('Call failed. '
-                        + 'Call service is unavailable.');
-                    self.ui.unlockButtons();
-                },
-                {
-                    onsuccess: function () {
-                        self.ui.unlockButtons();
-                    },
-                    onfailure: function (e) {
-                        console.log('App_makeCall: Call to ' + phoneNumber
-                            + ' failed. Call service was busy.', e);
-                        self.ui.unlockButtons();
-                        //self.ui.showErrorPopup('Call failed.'
-                        //     + 'Call service was busy.');
-                    }
-                }
-            );
-        },
-
-        /**
-        * Launch extension sms service
-        * @param {string} phoneNumber
-        */
-        sendSms: function App_sendSms(phoneNumber) {
-
-            var self = this,
-                appControl = new tizen.ApplicationControl(
-                    'http://tizen.org/appcontrol/operation/compose',
-                    'sms:' + phoneNumber
-                );
-
-            tizen.application.launchAppControl(
-                appControl,
-                null,
-                null,
-                function (e) {
-                    console.error('Message launch error: ', e);
-                    self.ui.showErrorPopup('Message service is unavailable');
-                    app.ui.unlockOptionButtons();
-                },
-                {
-                    onfailure: function (er) {
-                        console.error('Message service launch error: ', er);
-                        self.ui.showErrorPopup(
-                            'Message service is unavailable'
-                        );
-                        app.ui.unlockOptionButtons();
-                    }
-                }
-            );
-        },
-
-        /**
-        * Deletes specified log entry
-        * @param {CallHistoryEntry} entry
-        */
-        deleteLog: function App_deleteLogs(entry) {
-            this.model.deleteLog(entry);
-        },
-
-        /**
-        * App exit
-        */
-        exit: function App_exit(event) {
-            event.preventDefault();
-            event.stopPropagation();
-            tizen.application.getCurrentApplication().exit();
-        }
-
-    };
-
+       'use strict';
+
+       /**
+        * Creates a new application object
+        *
+        * @class Application
+        */
+       App = function App() {
+               this.configData = {};
+       };
+
+       App.prototype = {
+               /**
+                * @type Array
+                */
+               requires: ['js/app.config.js', 'js/app.model.js', 'js/app.ui.js', 'js/app.ui.templateManager.js', 'js/app.ui.templateManager.modifiers.js', 'js/app.helpers.js'],
+
+               /**
+                * @type Model
+                */
+               model: null,
+
+               /**
+                * @type Ui
+                */
+               ui: null,
+
+               /**
+                * @type Config
+                */
+               config: null,
+
+               /**
+                * @type {number}
+                */
+               lastViewedCaller: 0,
+
+               /**
+                * Initialisation function
+                */
+               init: function App_init() {
+                       // instantiate the libs
+                       this.config = new Config();
+                       this.model = new Model();
+                       this.model.registerChangeListener(this.updateCallLists.bind(this));
+                       this.ui = new Ui();
+                       this.updateCallLists();
+
+                       return this;
+               },
+
+               /**
+                * Updates call history and caller detailed history lists
+                */
+               updateCallLists: function App_updateCallLists() {
+                       // workaround - time zone update
+                       tizen.time.getCurrentDateTime().toLocalTimezone();
+                       // workaround;
+                       setTimeout(this.showHistoryForCaller(this.lastViewedCaller), 500);
+                       this.showCallHistory();
+               },
+
+               /**
+                * Renders call history view
+                */
+               showCallHistory: function App_showCallHistory() {
+                       this.model.getCallHistory(this.ui.showCallHistory.bind(this.ui));
+               },
+
+               /**
+                * Renders history for caller view
+                * @param {string} phoneNumber
+                */
+               showHistoryForCaller: function App_showHistoryForCaller(phoneNumber) {
+                       this.lastViewedCaller = phoneNumber;
+                       this.model.getCallHistoryForCaller(phoneNumber, this.ui.showHistoryForCaller.bind(this.ui, phoneNumber));
+               },
+
+               /**
+                * @param {number} addressBookId
+                * @param {number} contactId
+                * @returns {string} photoURI Photo URI for specified contact
+                */
+               getPhotoURIForContact: function App_getPhotoURIForContact(personId) {
+                       return this.model.getPhotoURIForContact(personId);
+               },
+
+               /**
+                * Launch extension call service
+                * @param {string} phoneNumber
+                */
+               makeCall: function App_makeCall(phoneNumber) {
+                       var self = this,
+                               appControl = new tizen.ApplicationControl(
+                                       'http://tizen.org/appcontrol/operation/call',
+                                       'tel:' + phoneNumber
+                               );
+                       tizen.application.launchAppControl(
+                               appControl,
+                               null,
+                               function () {
+                               },
+                               function (e) {
+                                       console.error('Call to ' + phoneNumber
+                                               + ' failed. Call service is unavailable.', e);
+                                       self.ui.showErrorPopup('Call failed. '
+                                               + 'Call service is unavailable.');
+                               },
+                               {
+                                       onsuccess: function () {
+                                       },
+                                       onfailure: function (e) {
+                                               console.log('App_makeCall: Call to ' + phoneNumber
+                                                       + ' failed. Call service was busy.', e);
+                                               //self.ui.showErrorPopup('Call failed.'
+                                               //      + 'Call service was busy.');
+                                       }
+                               }
+                       );
+               },
+
+               /**
+                * Launch extension sms service
+                * @param {string} phoneNumber
+                */
+               sendSms: function App_sendSms(phoneNumber) {
+
+                       var self = this,
+                               appControl = new tizen.ApplicationControl(
+                                       'http://tizen.org/appcontrol/operation/compose',
+                                       'sms:' + phoneNumber
+                               );
+
+                       tizen.application.launchAppControl(
+                               appControl,
+                               null,
+                               null,
+                               function (e) {
+                                       console.error('Message launch error: ', e);
+                                       self.ui.showErrorPopup('Message service is unavailable');
+                                       app.ui.unlockOptionButtons();
+                               },
+                               {
+                                       onfailure: function (er) {
+                                               console.error('Message service launch error: ', er);
+                                               self.ui.showErrorPopup('Message service is unavailable');
+                                               app.ui.unlockOptionButtons();
+                                       }
+                               }
+                       );
+               },
+
+               /**
+                * Deletes specified log entry
+                * @param {CallHistoryEntry} entry
+                */
+               deleteLog: function App_deleteLogs(entry) {
+                       this.model.deleteLog(entry);
+               },
+
+               /**
+                * App exit
+                */
+               exit: function App_exit(event) {
+                       event.preventDefault();
+                       event.stopPropagation();
+                       tizen.application.getCurrentApplication().exit();
+               }
+       };
 }());
index 0273e5c..42c3c64 100644 (file)
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 devel: true*/
 /*global tizen, $, app, localStorage */
 
 /**
-* @class Model
-*/
+ * @class Model
+ */
 function Model() {
-    'use strict';
+       'use strict';
 
-    this.init();
+       this.init();
 }
 
 (function () { // strict mode wrapper
-    'use strict';
+       'use strict';
+       Model.prototype = {
+
+               /**
+                * API module initialisation
+                */
+               init: function Model_init() {
+               },
 
-    Model.prototype = {
+               /**
+                * Registers listener for call history change
+                * @param {onSuccessCallback} function
+                */
+               registerChangeListener: function Model_registerChangeListener(onSuccessCallback) {
 
-        /**
-        * API module initialisation
-        */
-        init: function Model_init() {
-        },
+                       var callHistoryListener = {
+                               onadded: onSuccessCallback,
+                               onchanged: onSuccessCallback,
+                               onremoved: onSuccessCallback
+                       };
 
-        /**
-        * Registers listener for call history change
-        * @param {onSuccessCallback} function
-        */
-        registerChangeListener: function Model_registerChangeListener(
-            onSuccessCallback
-        ) {
-            var callHistoryListener = {
-                onadded: onSuccessCallback,
-                onchanged: onSuccessCallback,
-                onremoved: onSuccessCallback
-            };
-            tizen.callhistory.addChangeListener(callHistoryListener);
-        },
+                       tizen.callhistory.addChangeListener(callHistoryListener);
+               },
 
-        /**
-        * @param {function} onSuccess callback
-        * @param {function} onError callback
-        */
-        getCallHistory: function Model_getCallHistory(onSuccess, onError) {
-            if (typeof onError !== 'function') {
-                onError = function (e) {
-                    console.error('Model_getCallHistory error', e);
-                };
-            }
+               /**
+                * @param {function} onSuccess callback
+                * @param {function} onError callback
+                */
+               getCallHistory: function Model_getCallHistory(onSuccess, onError) {
+                       if (typeof onError !== 'function') {
+                               onError = function (e) {
+                                       console.error('Model_getCallHistory error', e);
+                               };
+                       }
 
-            tizen.callhistory.find(
-                onSuccess,
-                onError,
-                null,
-                new tizen.SortMode('startTime', 'DESC')
-            );
-        },
+                       tizen.callhistory.find(onSuccess, onError, null, new tizen.SortMode('startTime', 'DESC'));
+               },
 
-        /**
-        * @param {number} phoneNumber
-        * @param {function} onSuccess Callback
-        */
-        getCallHistoryForCaller: function Model_getCallHistoryForCaller(
-            phoneNumber,
-            onSuccess
-        ) {
-            var filter = null, success;
-            if (phoneNumber) {
-                filter = new tizen.AttributeFilter(
-                    'remoteParties.remoteParty',
-                    'EXACTLY',
-                    phoneNumber
-                );
-                success = onSuccess;
-            } else {
-                success = function (calls) {
-                    onSuccess(calls.filter(function (element) {
-                        if (!element.remoteParties[0].remoteParty) {
-                            return element;
-                        }
-                    }));
-                };
-            }
+               /**
+                * @param {number} phoneNumber
+                * @param {function} onSuccess Callback
+                */
+               getCallHistoryForCaller: function Model_getCallHistoryForCaller(phoneNumber, onSuccess) {
+                       var filter = null, success;
+                       if (phoneNumber) {
+                               filter = new tizen.AttributeFilter('remoteParties.remoteParty', 'EXACTLY', phoneNumber);
+                               success = onSuccess;
+                       } else {
+                               success = function (calls) {
+                                       onSuccess(calls.filter(function (element) {
+                                               if(!element.remoteParties[0].remoteParty) {
+                                                       return element;
+                                               }
+                                       }));
+                               };
+                       }
 
-            tizen.callhistory.find(success,
-                function (e) {
-                    console.error(e);
-                },
-                filter,
-                new tizen.SortMode('startTime', 'DESC')
-                );
-        },
+                       tizen.callhistory.find(success,
+                                       function (e) {
+                                               console.error(e);
+                                       },
+                                       filter,
+                                       new tizen.SortMode('startTime', 'DESC')
+                                       );
+               },
 
-        /**
-        * Deletes specified log entry
-        * @param {CallHistoryEntry} entry
-        */
-        deleteLog: function Model_deleteLog(entry) {
-            try {
-                tizen.callhistory.remove(entry);
-            } catch (e) {
-                console.error('Error on entry delete: ' + e.message);
-            }
-        },
+               /**
+                * Deletes specified log entry
+                * @param {CallHistoryEntry} entry
+                */
+               deleteLog: function Model_deleteLog(entry) {
+                       try {
+                               tizen.callhistory.remove(entry);
+                       } catch (e) {
+                               console.error('Error on entry delete: ' + e.message);
+                       }
+               },
 
-        /**
-        * @param {number} addressBookId
-        * @param {number} contactId
-        * @returns {string} photoURI
-        */
-        getPhotoURIForContact: function Model_getPhotoURIForContact(personId) {
-            try {
-                var addressBook = tizen.contact.getDefaultAddressBook(),
-                    contact;
-                if (addressBook) {
-                    contact = addressBook.get(personId);
-                    return contact.photoURI || false;
-                }
-            } catch (e) {
-                console.error('updatePhotoByContactId error:' + e.message);
-            }
-            return false;
-        }
+               /**
+                * @param {number} addressBookId
+                * @param {number} contactId
+                * @returns {string} photoURI
+                */
+               getPhotoURIForContact: function Model_getPhotoURIForContact(personId) {
+                       try {
+                               var addressBook = tizen.contact.getDefaultAddressBook(),
+                                       contact;
 
-    };
+                               if (addressBook) {
+                                       contact = addressBook.get(personId);
+                                       return contact.photoURI || false;
+                               }
+                       } catch (e) {
+                               console.error('updatePhotoByContactId error:' + e.message);
+                       }
+                       return false;
+               }
 
+       };
 }());
index 483675f..073572a 100644 (file)
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 devel: true*/
 /*global tizen, document, $, jQuery, app, UiPanel, UiContact, TemplateManager, window, Helpers */
 
 /**
-* @class Ui
-*/
+ * @class Ui
+ */
+
 function Ui(contacts) {
-    'use strict';
-    this.init();
+       'use strict';
+       this.init();
 }
 
 (function () { // strict mode wrapper
-    'use strict';
-
-    Ui.prototype = {
-
-        /**
-        * UI remove mode
-        * @type {boolean}
-        */
-        removeMode: false,
-
-        /**
-         * Default tizen address book
-         * @type {AddressBook}
-         */
-        addressBook: tizen.contact.getDefaultAddressBook(),
-
-        /**
-         * Default photo uri
-         * @type {String}
-         */
-        photoURIdefault: null,
-
-        /**
-         * Cached contacts from address book
-         * @type {Array}
-         */
-        contactsLoaded: null,
-
-        /**
-         * identifiers of currently checked checkboxes
-         * @type {Array}
-         */
-        checkedLogs: [],
-
-        /**
-        * @type {TemplateManager}
-        */
-        templateManager: null,
-
-        /**
-        * UI Initializer
-        */
-        init: function Ui_init() {
-            this.loadContacts();
-            this.templateManager = new TemplateManager();
-            this.helpers = new Helpers();
-            $(document).ready(this.domInit.bind(this));
-            $.mobile.tizen.disableSelection(document);
-        },
-
-        /**
-        * When DOM is ready, initialise it (bind events)
-        */
-        domInit: function Ui_domInit() {
-            this.templateManager.loadToCache(['callView',
-                'callerHistory',
-                'callItemRow',
-                'callerCallItemRow',
-                'messageWindow',
-                'errorWindow',
-                'dateRow'], this.initPages.bind(this));
-        },
-
-        /**
-        * UI pages initializer
-        */
-        initPages: function Ui_initPages() {
-            var pages = [], body = $('body');
-
-            body
-                .append(this.templateManager.get('messageWindow'))
-                .append(this.templateManager.get('errorWindow'))
-                .trigger('create');
-            $('#callView')
-                .append(
-                    $(this.templateManager.get('callView')).children()
-                )
-                .trigger('pagecreate')
-                .trigger('pageshow');
-            pages.push(this.templateManager.get('callerHistory'));
-            body.append(pages.join(''));
-            this.removeSearchBarToHeader();
-
-            this.addEvents();
-            app.showCallHistory();
-
-            this.photoURIdefault = $("#header .photo").css('background-image');
-        },
-
-        /**
-        * Add UI events
-        */
-        addEvents: function Ui_addEvents() {
-            var self = this;
-
-            // recalculating page size when window resize
-            // (eg. when soft keybord appear)
-            $(window).on('resize', function () {
-                $.mobile.activePage.page('refresh');
-            });
-
-            // creating call history view
-            $('#callView').on('pagebeforeshow', function () {
-                app.showCallHistory();
-            });
-
-            // creating single contact history view
-            $('#historyForCallerView').on('pagebeforeshow', function () {
-                self.hideCheckboxes();
-                // move scrollbar to top
-                $('#historyForCallerView')
-                    .find('.ui-content.ui-scrollview-clip')
-                    .find('.ui-scrollview-view')
-                    .css('-webkit-transform', 'translate3d(0px, 0px, 0px)');
-                $('#selectAllDetails').on('change', function () {
-                    self.selectAll();
-                });
-            });
-
-
-            // HACK not dissapearing scrollview indicator
-            $('#historyForCallerView').on('pageshow', function () {
-                $('#content').css('top', '160px');
-                $('#header').css('height', '160px');
-                $('#callerListContainer')
-                    .children(
-                        '.ui-overflow-indicator-top',
-                        '.ui-overflow-indicator-bottom'
-                    ).hide();
-            });
-
-            // HACK not dissapearing scrollview indicator
-            $('#callerListContainer').on('scrollstart', function () {
-                $(this)
-                    .children(
-                        '.ui-overflow-indicator-top',
-                        '.ui-overflow-indicator-bottom'
-                    ).fadeIn(200);
-            });
-
-            // HACK not dissapearing scrollview indicator
-            $('#callerListContainer').on('scrollstop', function () {
-                $(this)
-                    .children(
-                        '.ui-overflow-indicator-top',
-                        '.ui-overflow-indicator-bottom'
-                    ).fadeOut(200);
-            });
-
-            // selecting all checkboxes
-            $('.selectAllBox').children().on('click', function () {
-                $('.selectAllBox input[type=checkbox]').trigger('click');
-                self.selectAll();
-                self.selectAllDetailsEach();
-            });
-
-            $('#calllogList').on('click', '.date', function (event) {
-                event.stopPropagation();
-            });
-
-            // when clicked on a log display all history from that contact
-            $('#calllogList').on(
-                'click keypress',
-                '.call',
-                function onCalllogEntryClick(event) {
-                    if (event.type === 'keypress' && event.keyCode !== 13) {
-                        return;
-                    }
-                    var remoteParty = $(this)
-                        .data('entries')[0]
-                        .remoteParties[0]
-                        .remoteParty;
-                    app.showHistoryForCaller(remoteParty);
-                    $.mobile.changePage('#historyForCallerView');
-                }
-            );
-
-            // run sms service on click
-            $('#smsActionBtn').on('click', function (event) {
-                event.stopPropagation();
-                event.preventDefault();
-                self.lockButtons('#smsActionBtn, #callActionBtn');
-                self.hideCheckboxes();
-                self.lockButtons('#deleteActionBtn');
-                app.sendSms($('#forCallerList').data('remoteParty'));
-            });
-
-            // run call service on btn click
-            $('#callActionBtn').on("click", function (event) {
-                self.lockButtons('#callActionBtn, #smsActionBtn');
-                self.hideCheckboxes();
-                self.lockButtons('#deleteActionBtn');
-                app.makeCall($('#forCallerList').data('remoteParty'));
-            });
-
-            $('#deleteActionBtn').on('click', function () {
-                self.changeDetailsToRemoveState();
-            });
-
-            // selecting all checkboxes
-            $('.selectAllBox').on('click', 'li', function () {
-                var checkbox = $(this).find(':checkbox');
-                if (self.removeMode === true) {
-                    if (checkbox.attr('checked')) {
-                        checkbox.attr('checked', false)
-                            .data('checkboxradio')
-                            .refresh();
-                    } else {
-                        checkbox.attr('checked', true)
-                            .data('checkboxradio')
-                            .refresh();
-                    }
-                    self.setSelectAllDetails();
-                }
-            });
-
-            $('#popup')
-                .on(
-                    'click',
-                    '#popupCancelActionBtn',
-                    this.closePopup.bind(this)
-                ).on(
-                    'click',
-                    '#popupSubmitActionBtn',
-                    this.deleteCheckedLogs.bind(this)
-                );
-
-            $('#errorPopup').on(
-                'click',
-                '#errorPopupOkBtn',
-                this.closeErrorPopup
-            );
-
-            $('#errorPopup').bind(
-                {
-                    popupafterclose: function () {
-                        self.unlockButtons();
-                    }
-                }
-            );
-
-            $(window).keyup(function (e) {
-                if (e.which === 13) {
-                    $('input:focus').blur();
-                }
-            });
-
-            // bind hardware back button
-            window.addEventListener('tizenhwkey', function (e) {
-                if (e.keyName === "back") {
-                    // if there is any popup close it
-                    if ($.mobile.popup.active) {
-                        $.mobile.popup.active.close();
-                    // if app is in remove mode close it
-                    } else if (self.removeMode === true) {
-                        app.ui.changeDetailsToRemoveState(undefined, true);
-                    // if app is on calls page close app
-                    } else if ($.mobile.activePage.attr('id') === 'callView') {
-                        tizen.application.getCurrentApplication().exit();
-                    // else back to calls page
-                    } else {
-                        history.back();
-                    }
-                }
-            });
-            // bind callback to visbility change event
-            self.onVisibilityChange();
-        },
-
-        /**
-         * Bind change event
-         */
-        addEventsForCallerListCheckboxes:
-            function Ui_addEventsForCallerListCheckboxes() {
-            var self = this;
-            $('#forCallerList :checkbox').on('change', function (event) {
-                if ($(this).attr('checked')) {
-                    $(this).attr('checked', true);
-                } else {
-                    $(this).attr('checked', false);
-                }
-                self.setSelectAllDetails();
-            });
-        },
-
-        /**
-         * Callback function for click on select all element
-         */
-        selectAll: function () {
-            // if select all checkbox is checked
-            if ($('#selectAllDetails').attr('checked')) {
-                this.selectCheckbox($('#selectAllDetails'), true);
-            } else {
-                this.selectCheckbox($('#selectAllDetails'), false);
-            }
-            // select each checkbox separatly
-            this.selectAllDetailsEach();
-        },
-
-        /**
-         * Select single checkbox and enable delete button
-         */
-        selectCheckbox: function (obj, state) {
-            var deleteButton = $('#deleteActionBtn'), numChecked;
-            // check checkbox and refresh its view
-            obj.attr('checked', state)
-                .data('checkboxradio')
-                .refresh();
-
-            // check if there is any checked checkbox
-            // and toggle delete button availability
-            numChecked = $('#forCallerList input:checked').length;
-            if (this.removeMode && numChecked === 0) {
-                deleteButton
-                    .addClass('ui-disabled')
-                    .attr('tabIndex', '-1')
-                    .blur();
-            } else if (deleteButton.hasClass('ui-disabled')) {
-                deleteButton
-                    .removeClass('ui-disabled')
-                    .attr('tabIndex', '0');
-            }
-        },
-
-        /**
-        * Returns number of selected call logs
-        * @return {number} length
-        */
-        getCountSelectedLogEntries: function Ui_getCountSelectedLogEntries() {
-            return $('#forCallerList li .toRemove label.ui-checkbox-on').length;
-        },
-
-        /**
-         * Select each checkbox separatly
-         */
-        selectAllDetailsEach: function Ui_selectAllDetailsEach() {
-            var self = this;
-            $('#forCallerList').find('input').each(function () {
-                if ($('#selectAllDetails').attr('checked')) {
-                    self.selectCheckbox($(this), true);
-                } else {
-                    self.selectCheckbox($(this), false);
-                }
-            });
-        },
-
-        /**
-        * Hides checkboxes
-        */
-        hideCheckboxes: function Ui_hideCheckboxes() {
-            var self = this;
-            this.selectCheckbox($('#selectAllDetails'), false);
-
-            $('#forCallerList').find('input').each(function () {
-                self.selectCheckbox($(this), false);
-            });
-            this.changeDetailsToRemoveState('hide');
-        },
-
-        /**
-        * Returns css classes for specified entry
-        *
-        * @param {CallHistoryEntry} entry
-        * @returns {string}
-        */
-        cssClassesForEntry: function Ui_cssClassesForEntry(entry) {
-            return 'call dir_' +
-                entry.direction.toLowerCase() +
-                ' type_' +
-                entry.type.replace('.', '-').toLowerCase();
-        },
-
-        /**
-         * Check if all details checkboxes are selected
-         * and if so check selectAll element
-         */
-        setSelectAllDetails: function Ui_setSelectAllDetails() {
-            if (
-                $('#forCallerList input[type="checkbox"]').length ===
-                    $('#forCallerList input[checked="checked"]').length
-            ) {
-                this.selectCheckbox($('#selectAllDetails'), true);
-            } else {
-                this.selectCheckbox($('#selectAllDetails'), false);
-            }
-        },
-
-        /**
-        * Shows popup with specified message
-        * @param {string} message
-        */
-        showPopup: function Ui_showPopup(message) {
-            $('#popupMessage').html(message);
-            $('#popup').popup('open', {'positionTo': 'window'});
-        },
-
-        /**
-        * Hides popup
-        */
-        closePopup: function Ui_closePopup() {
-            $('#popup').popup('close');
-        },
-
-        /**
-         * Display error popup
-         */
-        showErrorPopup: function Ui_showErrorPopup(message) {
-            $('#errorPopupMessage').html(message);
-            $('#errorPopup').popup('open', {'positionTo': 'window'});
-        },
-
-        /**
-         * Hides error popup
-         */
-        closeErrorPopup: function Ui_closeErrorPopup() {
-            $('#errorPopup').popup('close');
-        },
-
-        /**
-        * Deletes checked log entries
-        */
-        deleteCheckedLogs: function Ui_deleteCheckedLogs(e) {
-            // if there is popup open close it
-            this.closePopup();
-
-            // uncheck SelectAll checkbox
-            this.selectCheckbox($('#selectAllDetails'), false);
-
-            // iterate through all entries
-            $('#forCallerList li.call').each(function () {
-                // if entry contains selected checkbox
-                if ($(this).find('form label').hasClass('ui-checkbox-on')) {
-                    // remove that entry
-                    app.deleteLog($(this).data('entries')[0]);
-                    // and remove connected html element
-                    $(this).remove();
-                }
-            });
-
-            // if there are still some entries
-            if ($('#forCallerList li.call').length > 0) {
-                // update header info
-                this.updateCallerHeaderNumberOfEntries(
-                    $('#forCallerList li.call').length
-                );
-            } else {
-                // if no entries change page
-                e.preventDefault();
-                $('.ui-listview-filter .ui-input-text').val('');
-                $('.ui-listview-filter .ui-input-text').trigger('change');
-                $.mobile.changePage('#callView');
-            }
-
-            this.changeDetailsToRemoveState(true);
-            this.scrollToBottom();
-        },
-
-        /**
-         * TODO Dont really know what that method exacly doing
-         * and what should do
-         * TODO need refactor
-         */
-        changeDetailsToRemoveState: function Ui_changeDetailsToRemoveState(
-            set,
-            clear
-        ) {
-            var counter = this.getCountSelectedLogEntries(),
-                numChecked = $('#forCallerList input:checked').length,
-                matrix,
-                pos;
-            if (clear === true) {
-                counter = 0;
-                // uncheck all checkboxes
-                $('#forCallerList').find(':checkbox').attr('checked', false)
-                    .data('checkboxradio').refresh();
-                $('.selectAllBox').find(':checkbox').attr('checked', false)
-                    .data('checkboxradio').refresh();
-            }
-            // TODO it is hard ot understand this
-            if (set !== undefined) {
-                this.removeMode = false;
-            } else if (counter === 0) {
-                this.removeMode = !this.removeMode;
-            }
-
-            // if app is in remove mode and there are no selected checkboxes
-            if (this.removeMode && numChecked === 0) {
-                // disable delete button
-                $('#deleteActionBtn')
-                    .addClass('ui-disabled')
-                    .attr('tabIndex', '-1')
-                    .blur();
-            // if app is not in removeMode
-            } else if (!this.removeMode) {
-                // set delete button to enabled
-                $('#deleteActionBtn')
-                    .removeClass('ui-disabled')
-                    .attr('tabIndex', '0');
-                this.selectAllDetailsEach();
-            }
-
-            // if there are no selected entries
-            if (counter === 0) {
-                // again checking removeMode
-                if (this.removeMode) {
-                    // show buttons from remove mode
-                    $('#historyForCallerView .toRemove').removeClass('hidden');
-                    $('#historyForCallerView .selectAllBox')
-                        .removeClass('hidden');
-                } else {
-                    $('#historyForCallerView .toRemove').addClass('hidden');
-                    $('#historyForCallerView .selectAllBox').addClass('hidden');
-                }
-            } else {
-                // TODO I dont understand
-                this.showPopup(
-                    counter > 1 ?
-                        'Are you sure you want to delete selected logs?' :
-                        'Are you sure you want to delete selected log?'
-                );
-            }
-
-            // TODO need refactorin
-            // HACK probably scrollview hack
-            matrix =
-                $('#historyForCallerView .ui-scrollview-view')
-                .css('transform');
-            pos = matrix.substr(7, matrix.length - 8).split(',')[5];
-            if (pos !== undefined) {
-                $('#callerListContainer')
-                    .scrollview('scrollTo', 100, parseInt(pos, 10), 10);
-            } else {
-                this.refreshScrollView();
-            }
-        },
-
-        /**
-        * Renders call history list
-        *
-        * @param {CallHistoryEntry[]} callEntries
-        */
-        showCallHistory: function Ui_showCallHistory(callEntries) {
-            var self = this,
-                pdate = null, // previous date
-                date = '',
-                elements = [], // list elements
-                len = callEntries.length, // entries length
-                tempLength = 0, // length of temporary table;
-                i, // loop counter
-                j, // loop counter
-                current, // current entry object
-                today = this.helpers.getShortDate(new Date()),
-                entryShortDate,
-                filterResult,
-                groupsOfDays = [],
-                dayLog,
-                index = 0,
-                calllogList = $('#calllogList'),
-                calllogListContent = $('#calllogListContent'),
-                calllogListContentPos;
-
-            // return duplicated entries
-            function filterForSameEntry(element) {
-                return self.getNumber(current) === self.getNumber(element)
-                    && current.direction === element.direction;
-            }
-
-            $('.selectedCount').hide();
-
-            for (i = 0; i < len; i = i + 1) {
-                current = callEntries[i];
-                date = this.helpers.toNativeDate(current.startTime);
-
-                // if date is changed create new deyLog;
-                if (date !== pdate) {
-                    dayLog = {};
-                    dayLog.date = date;
-                    dayLog.entries = [];
-                    dayLog.counters = [];
-                    groupsOfDays.push(dayLog);
-                    pdate = date;
-                }
-
-                // group entries by remote Party;
-                filterResult = dayLog.entries.filter(filterForSameEntry);
-                if (filterResult.length) {
-                    index = dayLog.entries.indexOf(filterResult[0]);
-                    dayLog.counters[index] += 1;
-                } else {
-                    dayLog.entries.push(current);
-                    dayLog.counters[dayLog.entries.length - 1] = 1;
-                }
-            }
-            // Create UL list with dividers;
-            len = groupsOfDays.length;
-            for (i = 0; i < len; i += 1) {
-                dayLog = groupsOfDays[i];
-                tempLength = dayLog.entries.length;
-                entryShortDate = this.helpers.getShortDate(
-                    dayLog.entries[0].startTime
-                );
-                for (j = 0; j < tempLength; j = j + 1) {
-                    elements.push(
-                        this.getCallItemRow(
-                            dayLog.entries[j],
-                            dayLog.counters[j]
-                        )
-                    );
-                }
-            }
-            calllogListContentPos = this.helpers.getScrollPosition(
-                calllogListContent
-            );
-            calllogList.empty().append(elements);
-
-            //workaround solution for searching phrase remain
-            // TODO FIXME
-            if ($("[data-type='search']").val().length !== "") {
-                calllogList.listview('refresh');
-                $("[data-type='search']").trigger("keyup");
-                $(".ui-li-divider")
-                    .removeClass("ui-li ui-li-divider ui-bar-s")
-                    .addClass("date");
-            } else {
-                calllogList.listview({
-                    autodividers: true,
-                    //filter: true,
-                    autodividersSelector: function (li) {
-                        return $(li).find('.callDate').text() ===
-                            app.ui.helpers.toNativeDate(new Date()) ?
-                            "Today" : $(li).find('.callDate').text();
-                    }
-                }).listview('refresh');
-                $(".ui-li-divider").removeClass().addClass("date");
-            }
-
-            setTimeout(
-                this.helpers.scrollTo.bind(
-                    this,
-                    calllogListContent,
-                    calllogListContentPos
-                ),
-                10
-            );
-        },
-
-        /**
-        * @param: {CallHistoryEntry} entry
-        */
-        getNumber: function (entry) {
-            return entry.remoteParties[0].remoteParty;
-        },
-
-        /**
-        * Returns HTML for single log entry
-        *
-        * @param {CallHistoryEntry} entry
-        * @param {number} counter
-        * @returns {HTMLPartial}
-        */
-        getCallItemRow: function Ui_getCallItemRow(entry, counter) {
-            var party = entry.remoteParties[0],
-                name = this.getNameByNumber(party.remoteParty),
-                tpl;
-
-            if (counter > 1) {
-                name += ' (' + counter + ')';
-            }
-
-            // prepare html string
-            tpl = this.templateManager.get('callItemRow', {
-                'name': name,
-                'callTime': this.helpers.toNativeTime(entry.startTime),
-                'callDate': this.helpers.toNativeDate(entry.startTime),
-                'cssClasses': this.cssClassesForEntry(entry),
-                'uid': entry.uid
-            });
-
-            // return clean DOM element so that array of those could be appended
-            // at once
-            return $(tpl)
-                .data('remoteParty', entry.remoteParties[0].remoteParty)
-                .data('entries', [entry])
-                .get(0); 
-        },
-
-        /**
-         * Return readable number identifier
-         *
-         * @param {string} number
-         * @returns {string}
-         */
-        getNameByNumber: function (number) {
-            var i, j, contact, name;
-            // iterate through loaded contacts
-            for (i in this.contactsLoaded) {
-                if (this.contactsLoaded.hasOwnProperty(i)) {
-                    contact = this.contactsLoaded[i];
-                    // iterate through numbers of contact
-                    for (j in contact.phoneNumbers) {
-                        if (contact.phoneNumbers.hasOwnProperty(j)) {
-                            // check if first 9 characters match number
-                            if (contact.phoneNumbers[j].number.substr(-9)
-                                    === number.substr(-9)) {
-                                // get display name
-                                name = contact.name.displayName;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-            return name || number || 'Unknown';
-        },
-
-        /**
-        * Returns HTML for single caller log entry
-        *
-        * @param {CallHistoryEntry} entry
-        * @returns {HTMLElement}
-        */
-        getCallerCallLogRow: function Ui_getCallerCallLogRow(entry) {
-            return $(this.templateManager.get('callerCallItemRow', {
-                'cssClass': this.cssClassesForEntry(entry),
-                'callTime': this.helpers.toNativeTime(entry.startTime),
-                'callDuration': this.helpers.secondsToHours(entry.duration),
-                'uid': entry.uid
-            })).data('entries', [entry]).get(0);
-        },
-
-        /**
-        * Renders call log list for specified caller
-        * TODO that methods is too long!
-        *
-        * @param {string} remoteParty
-        * @param {CallHistoryEntry[]} entries
-        */
-        showHistoryForCaller: function Ui_showHistoryForCaller(
-            remoteParty,
-            entries
-        ) {
-            var pdate = '', // previous data
-                date = '',
-                elements = [],
-                len = entries.length, // number of entries
-                i,
-                checkbox;
-
-            if (len) {
-                this.updateCallerHeader(entries[0], entries.length);
-            } else {
-                // if last call log has been removed
-                this.removedLastLog();
-                this.app.lastViewedCaller = 0;
-            }
-
-            // clean the list
-            $('#forCallerList')
-                .data('remoteParty', remoteParty)
-                .data('modified', false)
-                .empty();
-
-            // group caller log entries by date
-            for (i = 0; i < len; i = i + 1) {
-                date = this.helpers.toNativeDate(entries[i].startTime);
-
-                // if date is changed render new header
-                if (date !== pdate) {
-                    elements.push(
-                        $(this.templateManager.get(
-                            'dateRow',
-                            {'date': date}
-                        )).get(0)
-                    );
-                    pdate = date;
-                }
-                elements.push(this.getCallerCallLogRow(entries[i]));
-            }
-
-            $('#forCallerList')
-                .empty()
-                .append(elements);
-
-            // set state of delete button
-            if (elements.length > 0) {
-                $('li#delete > a').addClass('ui-btn-active');
-            } else {
-                $('li#delete > a').removeClass('ui-btn-active');
-            }
-
-            $('#forCallerList').trigger('create');
-
-            // change to remove mode if it was active before registering call
-            if (this.removeMode) {
-                this.removeMode = !this.removeMode;
-                this.changeDetailsToRemoveState();
-                // check previous checked entries
-                this.checkedLogs.forEach(function (logUid) {
-                    checkbox =
-                        $('#forCallerList li.call[data-uid="' + logUid + '"]')
-                        .find(':checkbox');
-                    if (checkbox.length > 0) {
-                        checkbox.attr('checked', true)
-                            .data('checkboxradio')
-                            .refresh();
-                        $('#deleteActionBtn')
-                            .removeClass('ui-disabled')
-                            .attr('tabIndex', '0');
-                    }
-                });
-
-                this.setSelectAllDetails();
-
-                // close popup if there are no checked checkboxes
-                if (!$("#forCallerList input:checked").length) {
-                    if ($.mobile.popup.active) {
-                        $.mobile.popup.active.close();
-                    }
-                }
-            }
-            this.addEventsForCallerListCheckboxes();
-            // lock buttons if unknown caller
-            if (remoteParty) {
-                this.unlockButtons();
-            } else {
-                this.lockButtons(
-                    '#callActionBtn, #smsActionBtn, #deleteActionBtn'
-                );
-            }
-        },
-
-        /**
-        * Update accoundId
-        * @param {string} accountId
-        */
-        updateCallerHeaderAccountId: function Ui_updateCallerHeaderAccountId(
-            accountId
-        ) {
-            $('.infoContainer .accountId').html(accountId);
-        },
-
-        /**
-        * Update number of entries
-        * @param numberOfEntries
-        */
-        updateCallerHeaderNumberOfEntries:
-            function Ui_updateCallerHeaderNumberOfEntries(numberOfEntries) {
-            $('.infoContainer .numberOfEntries').html(
-                numberOfEntries +
-                    ' ' +
-                    (numberOfEntries === 1 ? 'call' : 'calls')
-            );
-        },
-
-        /**
-        * Updates caller main info
-        * @param {CallHistoryEntry} entry
-        * @param {number} numberOfEntries
-        */
-        updateCallerHeader: function Ui_updateCallerHeader(
-            entry,
-            numberOfEntries
-        ) {
-            // TODO need to refactor
-            // looks complicated
-            var name = '', party, imgPath, personId;
-
-            $('#header .photo').css('background-image', this.photoURIdefault);
-
-            if (entry.remoteParties !== null) {
-                party = entry.remoteParties[0];
-                personId = parseInt(party.personId, 10);
-                name = this.getNameByNumber(party.remoteParty);
-                if (party.displayName) {
-                    this.updateCallerHeaderAccountId(party.remoteParty);
-                }
-                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
-                if (personId !== 0) {
-                    imgPath = app.getPhotoURIForContact(personId);
-                    if (imgPath !== false) {
-                        $('#header .photo')
-                            .css('background-image', 'url(' + imgPath + ')');
-                    }
-                }
-            } else if (entry.contactId !== null) {
-                name = entry.accountId;
-                this.updateCallerHeaderAccountId(entry.accountId);
-                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
-            } else {
-                name = entry.accountId;
-                this.updateCallerHeaderAccountId('');
-                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
-            }
-            $('.contact > .infoContainer > .name').html(
-                this.templateManager.modifiers.escape(name)
-            );
-        },
-
-        // TODO FIXME why that method is in the UI ?
-        loadContacts: function Model_loadContacts(callback) {
-            var contactsFoundCB, errorCB;
-
-            this.contactsLoaded = null;
-
-            contactsFoundCB = function (contacts) {
-                this.contactsLoaded = contacts;
-                if (callback instanceof Function) {
-                    callback();
-                }
-            };
-
-            errorCB = function (error) {
-                console.error(
-                    'Model_loadContacts, problem with find() method: ' +
-                        error.message
-                );
-            };
-
-            this.addressBook.find(contactsFoundCB.bind(this), errorCB);
-        },
-
-        /**
-        * Remove search filter from content and appends it to header
-        */
-        // TODO FIXME HACK it is one big hack for web-ui-fw
-        // title need to be changed
-        removeSearchBarToHeader: function () {
-            $('#page-header').append($('#callView .ui-listview-filter'));
-            $.mobile.activePage.page('refresh');
-            $('.ui-input-cancel').remove(); // patch for WebUI bug
-            $('#calllogListContent').trigger('resize'); // WebUi scrollview fix
-        },
-
-        /**
-         * Scroll to bottom
-         */
-        scrollToBottom: function () {
-            var scrollView = $(".ui-scrollview-view");
-            scrollView.css("-webkit-transform", "translate3d(0px, -" +
-                        scrollView.height() + "px, 0px)");
-        },
-
-        /**
-         * Binding visibility state change event
-         */
-        onVisibilityChange: function () {
-            var self = this;
-            document.addEventListener('webkitvisibilitychange', function () {
-                if (document.webkitVisibilityState === 'hidden') {
-                    self.updateCheckboxes();
-                } else {
-                    self.loadContacts(app.updateCallLists.bind(app));
-                    $('#callActionBtn, #smsActionBtn')
-                        .removeClass('ui-disabled');
-                }
-            });
-        },
-
-        /**
-         * Store uid of checked entries in checkedLogs Array
-         */
-        updateCheckboxes: function Ui_updateCheckboxes() {
-            // empty checkedLogs logs array
-            var checkedLogs = this.checkedLogs = [];
-            // iterate through the entries
-            $('#forCallerList li.call').each(function () {
-                // if entry cotains checked checkbox
-                if ($(this).find('form label').hasClass('ui-checkbox-on')) {
-                    var checkedEntry = $(this).data('entries')[0];
-                    // push the entry uid to checkedLogs array
-                    checkedLogs.push(checkedEntry.uid);
-                }
-            });
-        },
-
-        /**
-         * Disabling element
-         * @param {jQuery} element
-         */
-        lockButtons: function Ui_lockButtons(buttons) {
-            $(buttons).addClass('ui-disabled').attr('tabIndex', '-1').blur();
-        },
-
-        /**
-         * Enabling element
-         * @param {jQuery} element
-         */
-        unlockButtons: function Ui_unlockButtons() {
-            $('#callActionBtn, #smsActionBtn, #deleteActionBtn')
-                .removeClass('ui-disabled')
-                .attr('tabIndex', '0');
-        },
-
-        /**
-        * HACK TODO FIXME;
-        * Patch for UI, bad refresh scrollView
-        */
-        refreshScrollView: function () {
-            var scrollView = $('.ui-scrollview-view'),
-                show = function () {
-                    scrollView.show();
-                };
-            scrollView.hide();
-            setTimeout(show, 0);
-        },
-
-        /**
-         * Handle event when last log is removed
-         */
-        removedLastLog: function () {
-            this.hideCheckboxes();
-            $(".ui-popup").popup('close');
-            $.mobile.changePage('#callView');
-        }
-    };
+       'use strict';
+       Ui.prototype = {
+               /**
+                * UI remove mode
+                * @type {boolean}
+                */
+               removeMode: false,
+
+               addressBook: tizen.contact.getDefaultAddressBook(),
+
+               photoURIdefault: null,
+
+               contactsLoaded: null,
+
+               checkedLogs: [],
+
+               /**
+                * @type {TemplateManager}
+                */
+               templateManager: null,
+
+               /**
+                * UI Initializer
+                */
+               init: function Ui_init() {
+                       this.loadContacts();
+                       this.templateManager = new TemplateManager();
+                       this.helpers = new Helpers();
+                       $(document).ready(this.domInit.bind(this));
+                       $.mobile.tizen.disableSelection(document);
+               },
+
+               /**
+                * When DOM is ready, initialise it (bind events)
+                */
+               domInit: function Ui_domInit() {
+                       this.templateManager.loadToCache(['callView',
+                               'callerHistory',
+                               'callItemRow',
+                               'callerCallItemRow',
+                               'messageWindow',
+                               'errorWindow',
+                               'dateRow'], this.initPages.bind(this));
+               },
+
+               /**
+                * UI pages initializer
+                */
+               initPages: function Ui_initPages() {
+                       var pages = [], body = $('body');
+
+                       body
+                               .append(this.templateManager.get('messageWindow'))
+                               .append(this.templateManager.get('errorWindow'))
+                               .trigger('create');
+                       $('#callView')
+                               .append($(this.templateManager.get('callView'))
+                                       .children())
+                                       .trigger('pagecreate')
+                                       .trigger('pageshow');
+                       pages.push(this.templateManager.get('callerHistory'));
+                       body.append(pages.join(''));
+                       this.removeSearchBarToHeader();
+
+                       this.addEvents();
+                       app.showCallHistory();
+
+                       this.photoURIdefault = $("#header .photo").css('background-image');
+               },
+
+               /**
+                * Add UI events
+                */
+               addEvents: function Ui_addEvents() {
+                       var self = this;
+
+                       $(window).on('resize', function () {
+                               $.mobile.activePage.page('refresh');
+                       });
+
+                       $('#callView').on('pagebeforeshow', function () {
+                               app.showCallHistory();
+                       });
+
+                       //original code, do not remove until web-ui release; N_SE-48946
+                       //$(".ui-scrollview-view").listview();
+
+                       $('#historyForCallerView').on('pagebeforeshow', function () {
+                               self.hideCheckboxes();
+                               $('#historyForCallerView .ui-content.ui-scrollview-clip .ui-scrollview-view')
+                                       .css('-webkit-transform', 'translate3d(0px, 0px, 0px)');
+                               $('#selectAllDetails').on('change', function () {
+                                       self.selectAll();
+                               });
+                       });
+
+                       $('#historyForCallerView').on('pageshow', function () {
+                               $('#content').css('top', '160px');
+                               $('#header').css('height', '160px');
+                               $('#callerListContainer')
+                                       .children('.ui-overflow-indicator-top', '.ui-overflow-indicator-bottom')
+                                       .hide();
+                       });
+
+                       $('#callerListContainer').on('scrollstart', function () {
+                               $(this)
+                                       .children('.ui-overflow-indicator-top', '.ui-overflow-indicator-bottom')
+                                       .fadeIn(200);
+                       });
+
+                       $('#callerListContainer').on('scrollstop', function () {
+                               $(this)
+                                       .children('.ui-overflow-indicator-top', '.ui-overflow-indicator-bottom')
+                                       .fadeOut(200);
+                       });
+
+                       $('.selectAllBox').children().on('click', function () {
+                               $('.selectAllBox input[type=checkbox]').trigger('click');
+                               self.selectAll();
+                               self.selectAllDetailsEach();
+                       });
+
+                       $('#calllogList').on('click', '.date', function (event) {
+                               event.stopPropagation();
+                       });
+
+                       $('#calllogList').on('click', '.call', function onCalllogEntryClick(event) {
+                               var remoteParty = $(this)
+                                       .data('entries')[0]
+                                       .remoteParties[0]
+                                       .remoteParty;
+                               app.showHistoryForCaller(remoteParty);
+                               $.mobile.changePage('#historyForCallerView');
+                       });
+
+                       $('#smsActionBtn').on('click', function (event) {
+                               event.stopPropagation();
+                               event.preventDefault();
+                               self.lockButtons('#smsActionBtn');
+                               self.hideCheckboxes();
+                               app.sendSms($('#forCallerList').data('remoteParty'));
+                       });
+
+                       $('#callActionBtn').on("click", function (event) {
+                               self.lockButtons('#callActionBtn');
+                               self.hideCheckboxes();
+                               app.makeCall($('#forCallerList').data('remoteParty'));
+                       });
+
+                       $('#deleteActionBtn').on('click', function () {
+                               self.changeDetailsToRemoveState();
+                       });
+
+                       $('.selectAllBox').on('click', 'li', function () {
+                               var checkbox = $(this).find(':checkbox');
+                               if (self.removeMode === true) {
+                                       if (checkbox.attr('checked')) {
+                                               checkbox.attr('checked', false)
+                                                       .data('checkboxradio')
+                                                       .refresh();
+                                       } else {
+                                               checkbox.attr('checked', true)
+                                                       .data('checkboxradio')
+                                                       .refresh();
+                                       }
+                                       self.setSelectAllDetails();
+                               }
+                       });
+
+                       $('#popup')
+                               .on('click', '#popupCancelActionBtn', this.closePopup.bind(this))
+                               .on('click', '#popupSubmitActionBtn', this.deleteCheckedLogs.bind(this));
+
+                       $('#errorPopup').on('click', '#errorPopupOkBtn', this.closeErrorPopup);
+
+                       $( "#errorPopup" ).bind({
+                               popupafterclose: function(){
+                                       self.unlockButtons();
+                               }
+                       });
+
+                       $(window).keyup(function(e){
+                               if (e.which === 13) {
+                                       $('input:focus').blur();
+                               }
+                       });
+
+                       window.addEventListener('tizenhwkey', function(e) {
+                               if (e.keyName == "back") {
+                                       if ($.mobile.popup.active) {
+                                               $.mobile.popup.active.close();
+                                       } else if (self.removeMode === true) {
+                                               app.ui.changeDetailsToRemoveState(undefined, true);
+                                       } else if ($.mobile.activePage.attr('id') === 'callView') {
+                                               tizen.application.getCurrentApplication().exit();
+                                       } else {
+                                               history.back();
+                                       }
+                               }
+                       });
+                       self.onVisibilityChange();
+               },
+
+               addEventsForCallerListCheckboxes: function Ui_addEventsForCallerListCheckboxes() {
+                       var self = this;
+                       $('#forCallerList :checkbox').on('change', function (event) {
+                               if ($(this).attr('checked')) {
+                                       $(this).attr('checked', true);
+                               } else {
+                                       $(this).attr('checked', false);
+                               }
+                               self.setSelectAllDetails();
+                       });
+               },
+
+               selectAll: function () {
+                       if ($('#selectAllDetails').attr('checked')) {
+                               this.selectCheckbox($('#selectAllDetails'), true);
+                       } else {
+                               this.selectCheckbox($('#selectAllDetails'), false);
+                       }
+                       this.selectAllDetailsEach();
+               },
+
+               selectCheckbox: function (obj, state) {
+                       var deleteButton = $('#deleteActionBtn'), numChecked;
+                       obj.attr('checked', state)
+                               .data('checkboxradio')
+                               .refresh();
+
+                       numChecked = $('#forCallerList input:checked').length;
+                       if (this.removeMode && numChecked === 0 && !deleteButton.hasClass('ui-disabled')) {
+                               deleteButton.addClass('ui-disabled').attr('tabIndex', '-1').blur();
+                       } else if (deleteButton.hasClass('ui-disabled')) {
+                               deleteButton.removeClass('ui-disabled').attr('tabIndex', '0');
+                       }
+               },
+
+               /**
+                * Returns number of selected call logs
+                * @return {number} length
+                */
+               getCountSelectedLogEntries: function Ui_getCountSelectedLogEntries() {
+                       return $('#forCallerList li .toRemove label.ui-checkbox-on').length;
+               },
+
+               selectAllDetailsEach: function Ui_selectAllDetailsEach() {
+                       var self = this;
+                       $('#forCallerList').find('input').each(function () {
+                               if ($('#selectAllDetails').attr('checked')) {
+                                       self.selectCheckbox($(this), true);
+                               } else {
+                                       self.selectCheckbox($(this), false);
+                               }
+                       });
+               },
+
+               /**
+                * Hides checkboxes
+                */
+               hideCheckboxes: function Ui_hideCheckboxes() {
+                       var self = this;
+                       this.selectCheckbox($('#selectAllDetails'), false);
+
+                       $('#forCallerList').find('input').each(function () {
+                               self.selectCheckbox($(this), false);
+                       });
+                       this.changeDetailsToRemoveState('hide');
+               },
+
+               /**
+                * Returns css classes for specified entry
+                *
+                * @param {CallHistoryEntry} entry
+                * @returns {string}
+                */
+               cssClassesForEntry: function Ui_cssClassesForEntry(entry) {
+                       return 'call dir_' + entry.direction.toLowerCase() + ' type_' + entry.type.replace('.', '-').toLowerCase();
+               },
+
+               setSelectAllDetails: function Ui_setSelectAllDetails() {
+                       if ($('#forCallerList input[type="checkbox"]').length ===
+                               $('#forCallerList input[checked="checked"]').length) {
+                               this.selectCheckbox($('#selectAllDetails'), true);
+                       } else {
+                               this.selectCheckbox($('#selectAllDetails'), false);
+                       }
+               },
+
+               /**
+                * Shows popup with specified message
+                * @param {string} message
+                */
+               showPopup: function Ui_showPopup(message) {
+                       $('#popupMessage').html(message);
+                       $('#popup').popup('open', {'positionTo': 'window'});
+               },
+
+               /**
+                * Hides popup
+                */
+               closePopup: function Ui_closePopup() {
+                       $('#popup').popup('close');
+               },
+
+               showErrorPopup: function Ui_showErrorPopup(message) {
+                       $('#errorPopupMessage').html(message);
+                       $('#errorPopup').popup('open', {'positionTo': 'window'});
+               },
+
+               closeErrorPopup: function Ui_closeErrorPopup() {
+                       $('#errorPopup').popup('close');
+               },
+
+               /**
+                * Deletes checked log entries
+                */
+               deleteCheckedLogs: function Ui_deleteCheckedLogs(e) {
+                       this.closePopup();
+
+                       this.selectCheckbox($('#selectAllDetails'), false);
+
+                       $('#forCallerList li.call').each(function () {
+                               if ($(this).find('form label').hasClass('ui-checkbox-on')) {
+                                       app.deleteLog($(this).data('entries')[0]);
+                                       $(this).remove();
+                               }
+                       });
+
+                       if ($('#forCallerList li.call').length > 0) {
+                               this.updateCallerHeaderNumberOfEntries($('#forCallerList li.call').length);
+                       } else {
+                               e.preventDefault();
+                               $('.ui-listview-filter .ui-input-text').val('');
+                               $('.ui-listview-filter .ui-input-text').trigger('change');
+                               $.mobile.changePage('#callView');
+                       }
+
+                       this.changeDetailsToRemoveState(true);
+                       this.scrollToBottom();
+               },
+
+               changeDetailsToRemoveState: function Ui_changeDetailsToRemoveState(set, clear) {
+                       var counter = this.getCountSelectedLogEntries(),
+                               numChecked = $('#forCallerList input:checked').length,
+                               matrix, pos;
+                       if (clear === true) {
+                               counter = 0;
+                               $('#forCallerList').find(':checkbox').attr('checked', false)
+                                       .data('checkboxradio').refresh();
+                               $('.selectAllBox').find(':checkbox').attr('checked', false)
+                                       .data('checkboxradio').refresh();
+                       }
+                       if (set !== undefined) {
+                               this.removeMode = false;
+                       } else if (counter === 0) {
+                               this.removeMode = !this.removeMode;
+                       }
+
+                       if (this.removeMode && numChecked === 0) {
+                               $('#deleteActionBtn').addClass('ui-disabled').attr('tabIndex', '-1').blur();
+                       } else if (!this.removeMode) {
+                               $('#deleteActionBtn').removeClass('ui-disabled').attr('tabIndex', '0');
+                               this.selectAllDetailsEach();
+                       }
+
+                       if (counter === 0) {
+                               if (this.removeMode) {
+                                       $('#historyForCallerView .toRemove').removeClass('hidden');
+                                       $('#historyForCallerView .selectAllBox')
+                                               .removeClass('hidden');
+                               } else {
+                                       $('#historyForCallerView .toRemove').addClass('hidden');
+                                       $('#historyForCallerView .selectAllBox').addClass('hidden');
+                               }
+                       } else if (counter > 1) {
+                               this.showPopup('Are you sure you want to delete selected logs?');
+                       } else {
+                               this.showPopup('Are you sure you want to delete selected log?');
+                       }
+
+                       matrix = $('#historyForCallerView .ui-scrollview-view').css('transform');
+                       pos = matrix.substr(7, matrix.length -8).split(',')[5];
+                       if (pos !== undefined) {
+                               $('#callerListContainer').scrollview('scrollTo', 100, parseInt(pos), 10);
+                       } else {
+                               this.refreshScrollView();
+                       }
+               },
+
+               /**
+                * Renders call history list
+                *
+                * @param {CallHistoryEntry[]} callEntries
+                */
+               showCallHistory: function Ui_showCallHistory(callEntries) {
+                       var self = this,
+                               pdate = null, // previous date
+                               date = '',
+                               elements = [], // list elements
+                               len = callEntries.length, // entries length
+                               tempLength = 0, // length of temporary table;
+                               i, // loop counter
+                               j, // loop counter
+                               current, // current entry object
+                               today = this.helpers.getShortDate(new Date()), // today short date
+                               entryShortDate,
+                               filterResult,
+                               groupsOfDays = [],
+                               dayLog,
+                               index = 0,
+                               calllogList = $('#calllogList'),
+                               calllogListContent = $('#calllogListContent'),
+                               calllogListContentPos;
+
+                       function filterForSameEntry(element) {
+                               return self.getNumber(current) === self.getNumber(element)
+                                       && current.direction === element.direction;
+                       }
+
+                       $('.selectedCount').hide();
+
+                       for (i = 0; i < len; i = i + 1) {
+                               current = callEntries[i];
+                               date = this.helpers.toNativeDate(current.startTime);
+
+                               // if date is changed create new deyLog;
+                               if (date !== pdate) {
+                                       dayLog = {};
+                                       dayLog.date = date;
+                                       dayLog.entries = [];
+                                       dayLog.counters = [];
+                                       groupsOfDays.push(dayLog);
+                                       pdate = date;
+                               }
+
+                               // group entries by remote Party;
+                               filterResult = dayLog.entries.filter(filterForSameEntry);
+                               if (filterResult.length) {
+                                       index = dayLog.entries.indexOf(filterResult[0]);
+                                       dayLog.counters[index] += 1;
+                               } else {
+                                       dayLog.entries.push(current);
+                                       dayLog.counters[dayLog.entries.length - 1] = 1;
+                               }
+                       }
+                       // Create UL list with dividers;
+                       len = groupsOfDays.length;
+                       for (i = 0; i < len; i += 1) {
+                               dayLog = groupsOfDays[i];
+                               tempLength = dayLog.entries.length;
+                               entryShortDate = this.helpers.getShortDate(dayLog.entries[0].startTime);
+                               // add date header;
+                               //original code, do not remove until web-ui release; N_SE-48946
+//                             elements.push($(this.templateManager.get('dateRow', {
+//                                     'date': today === entryShortDate ? 'Today' : dayLog.date
+//                             })).get(0));
+
+                               for (j = 0; j < tempLength; j = j + 1) {
+                                       elements.push(this.getCallItemRow(dayLog.entries[j], dayLog.counters[j]));
+                               }
+                       }
+                       calllogListContentPos = this.helpers.getScrollPosition(calllogListContent);
+                       calllogList.empty().append(elements);
+
+                       /* workaround solution for searching phrase remain*/
+                       if ($("[data-type='search']").val().length != "") {
+                               calllogList.listview('refresh');
+                               $("[data-type='search']").trigger("keyup");
+                               $(".ui-li-divider").removeClass("ui-li ui-li-divider ui-bar-s").addClass("date");
+                       } else {
+                           calllogList.listview({
+                                       autodividers: true,
+                                       //filter: true,
+                                       autodividersSelector: function ( li ) {
+                                               return $(li).find('.callDate').text() === app.ui.helpers.toNativeDate(new Date())
+                                               ? "Today" : $(li).find('.callDate').text();
+                                       }
+                               }).listview('refresh');
+                               $(".ui-li-divider").removeClass().addClass("date");
+                       }
+
+                       setTimeout(this.helpers.scrollTo.bind(this, calllogListContent, calllogListContentPos), 10);
+               },
+
+               /**
+                * @param: {CallHistoryEntry} entry
+                */
+               getNumber: function (entry) {
+                       return entry.remoteParties[0].remoteParty;
+               },
+
+               /**
+                * Returns HTML for single log entry
+                *
+                * @param {CallHistoryEntry} entry
+                * @param {number} counter
+                * @returns {HTMLPartial}
+                */
+               getCallItemRow: function Ui_getCallItemRow(entry, counter) {
+                       var party = entry.remoteParties[0],
+                               name = this.getNameByNumber(party.remoteParty),
+                               tpl;
+
+                       if (counter > 1) {
+                               name += ' (' + counter + ')';
+                       }
+
+                       tpl = this.templateManager.get('callItemRow', {
+                               'name': name,
+                               'callTime': this.helpers.toNativeTime(entry.startTime),
+                               'callDate': this.helpers.toNativeDate(entry.startTime),
+                               'cssClasses': this.cssClassesForEntry(entry),
+                               'uid': entry.uid
+                       });
+
+                       return $(tpl)
+                               .data('remoteParty', entry.remoteParties[0].remoteParty)
+                               .data('entries', [entry])
+                               .get(0); // return clean DOM element so array of those could be appended at once*/
+               },
+
+               getNameByNumber: function (number) {
+                       var i, j, contact, name;
+                       for (i in this.contactsLoaded) {
+                               if (this.contactsLoaded.hasOwnProperty(i)) {
+                                       contact = this.contactsLoaded[i];
+                                       for (j in contact.phoneNumbers) {
+                                               if (contact.phoneNumbers.hasOwnProperty(j)) {
+                                                       if (contact.phoneNumbers[j].number.substr(-9)
+                                                                       === number.substr(-9)) {
+                                                               name = contact.name.displayName;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       return name || number || 'Unknown';
+               },
+
+               /**
+                * Returns HTML for single caller log entry
+                *
+                * @param {CallHistoryEntry} entry
+                * @returns {HTMLElement}
+                */
+               getCallerCallLogRow: function Ui_getCallerCallLogRow(entry) {
+                       return $(this.templateManager.get('callerCallItemRow', {
+                               'cssClass': this.cssClassesForEntry(entry),
+                               'callTime': this.helpers.toNativeTime(entry.startTime),
+                               'callDuration': this.helpers.secondsToHours(entry.duration),
+                               'uid': entry.uid
+                       })).data('entries', [entry]).get(0);
+               },
+
+               /**
+                * Renders call log list for specified caller
+                *
+                * @param {string} remoteParty
+                * @param {CallHistoryEntry[]} entries
+                */
+               showHistoryForCaller: function Ui_showHistoryForCaller(remoteParty, entries) {
+                       var pdate = '',
+                               date = '',
+                               elements = [],
+                               len = entries.length,
+                               i,
+                               checkbox;
+
+                       if (len) {
+                               this.updateCallerHeader(entries[0], entries.length);
+                       } else {
+                               // if last call log has been removed
+                               this.removedLastLog();
+                               this.app.lastViewedCaller = 0;
+                       }
+
+                       $('#forCallerList')
+                               .data('remoteParty', remoteParty)
+                               .data('modified', false)
+                               .empty();
+
+                       // group caller log entries by date
+                       for (i = 0; i < len; i = i + 1) {
+                               date = this.helpers.toNativeDate(entries[i].startTime);
+
+                               // if date is changed render new header
+                               if (date !== pdate) {
+                                       elements.push($(this.templateManager.get('dateRow', {'date': date})).get(0));
+                                       pdate = date;
+                               }
+                               elements.push(this.getCallerCallLogRow(entries[i]));
+                       }
+
+                       $('#forCallerList')
+                               .empty()
+                               .append(elements);
+
+                       if (elements.length > 0) {
+                               $('li#delete > a').addClass('ui-btn-active');
+                       } else {
+                               $('li#delete > a').removeClass('ui-btn-active');
+                       }
+
+                       $('#forCallerList').trigger('create');
+
+                       // change to remove mode if it was active before registering call
+                       if (this.removeMode) {
+                               this.removeMode = !this.removeMode;
+                               this.changeDetailsToRemoveState();
+                               // check previous checked entries
+                               this.checkedLogs.forEach(function(logUid){
+                                       checkbox = $('#forCallerList li.call[data-uid="' + logUid + '"]')
+                                               .find(':checkbox');
+
+                                       if (checkbox.length > 0) {
+                                               checkbox.attr('checked', true)
+                                                       .data('checkboxradio')
+                                                       .refresh();
+                                               $('#deleteActionBtn').removeClass('ui-disabled').attr('tabIndex', '0');
+                                       }
+                               });
+
+                               this.setSelectAllDetails();
+
+                               // close popup if there are no checked checkboxes
+                               if (!$("#forCallerList input:checked").length) {
+                                       if ($.mobile.popup.active) {
+                                               $.mobile.popup.active.close();
+                                       }
+                               }
+                       }
+                       this.addEventsForCallerListCheckboxes();
+                       // lock buttons if unknown caller
+                       if (remoteParty) {
+                               this.unlockButtons();
+                       } else {
+                               this.lockButtons('#callActionBtn, #smsActionBtn');
+                       }
+               },
+
+               /**
+                * Update accoundId
+                * @param {string} accountId
+                */
+               updateCallerHeaderAccountId: function Ui_updateCallerHeaderAccountId(accountId) {
+                       $('.infoContainer .accountId').html(accountId);
+               },
+
+               /**
+                * Update number of entries
+                * @param numberOfEntries
+                */
+               updateCallerHeaderNumberOfEntries: function Ui_updateCallerHeaderNumberOfEntries(numberOfEntries) {
+                       $('.infoContainer .numberOfEntries').html('' + numberOfEntries + ' ' + (numberOfEntries === 1 ? 'call' : 'calls'));
+               },
+
+               /**
+                * Updates caller main info
+                * @param {CallHistoryEntry} entry
+                * @param {number} numberOfEntries
+                */
+               updateCallerHeader: function Ui_updateCallerHeader(entry, numberOfEntries) {
+                       var name = '', party, imgPath, personId;
+
+                       $('#header .photo').css('background-image', this.photoURIdefault);
+
+                       if (entry.remoteParties !== null) {
+                               party = entry.remoteParties[0];
+                               personId = parseInt(party.personId, 10);
+                               name = this.getNameByNumber(party.remoteParty);
+                               if (party.displayName) {
+                                       this.updateCallerHeaderAccountId(party.remoteParty);
+                               }
+                               this.updateCallerHeaderNumberOfEntries(numberOfEntries);
+                               if (personId !== 0) {
+                                       imgPath = app.getPhotoURIForContact(personId);
+                                       if (imgPath !== false) {
+                                               $('#header .photo').css('background-image', 'url(' + imgPath + ')');
+                                       }
+                               }
+                       } else if (entry.contactId !== null) {
+                               name = entry.accountId;
+                               this.updateCallerHeaderAccountId(entry.accountId);
+                               this.updateCallerHeaderNumberOfEntries(numberOfEntries);
+                       } else {
+                               name = entry.accountId;
+                               this.updateCallerHeaderAccountId('');
+                               this.updateCallerHeaderNumberOfEntries(numberOfEntries);
+                       }
+                       $('.contact > .infoContainer > .name').html(this.templateManager.modifiers.escape(name));
+
+               },
+
+               loadContacts: function Model_loadContacts(callback) {
+                       var contactsFoundCB, errorCB;
+
+                       this.contactsLoaded = null;
+
+                       contactsFoundCB = function (contacts) {
+                               this.contactsLoaded = contacts;
+                               if (callback instanceof Function) {
+                                       callback();
+                               }
+                       };
+
+                       errorCB = function (error) {
+                               console.error('Model_loadContacts, problem with find() method: ' + error.message);
+                       };
+
+                       this.addressBook.find(contactsFoundCB.bind(this), errorCB);
+               },
+
+               /**
+                * Remove search filter from content and appends it to header
+                */
+               removeSearchBarToHeader: function () {
+                       $('#page-header').append($('#callView .ui-listview-filter'));
+                       $.mobile.activePage.page('refresh');
+                       $('.ui-input-cancel').remove(); // patch for WebUI bug
+                       $('#calllogListContent').trigger('resize'); // WebUi scrollview fix
+               },
+
+               scrollToBottom: function () {
+                       var scrollView = $(".ui-scrollview-view");
+                       scrollView.css("-webkit-transform", "translate3d(0px, -" +
+                                               scrollView.height() + "px, 0px)");
+               },
+
+               onVisibilityChange: function () {
+                       var self = this;
+                       document.addEventListener('webkitvisibilitychange', function () {
+                               if (document.webkitVisibilityState === 'hidden') {
+                                       self.checkedLogs = [];
+                                       $('#forCallerList li.call').each(function () {
+                                               if ($(this).find('form label')
+                                                       .hasClass('ui-checkbox-on')) {
+                                                       var checkedEntry = $(this).data('entries')[0];
+                                                       self.checkedLogs.push(checkedEntry.uid);
+                                               }
+                                       });
+                               } else {
+                                       self.loadContacts(app.updateCallLists.bind(app));
+                                       $('#callActionBtn, #smsActionBtn')
+                                               .removeClass('ui-disabled');
+                               }
+                       });
+               },
+
+               lockButtons: function Ui_lockButtons(buttons) {
+                       $(buttons).addClass('ui-disabled').attr('tabIndex', '-1').blur();
+               },
+
+               unlockButtons: function Ui_unlockButtons(){
+                       $('#callActionBtn, #smsActionBtn').removeClass('ui-disabled').attr('tabIndex', '0');
+               },
+
+               /**
+                * WORKAROUND;
+                * Patch for UI, bad refresh scrollView
+                */
+               refreshScrollView: function () {
+                       var scrollView = $('.ui-scrollview-view'),
+                               show = function () {
+                                       scrollView.show();
+                               };
+                       scrollView.hide();
+                       setTimeout(show, 0);
+               },
+
+               removedLastLog: function () {
+                       this.hideCheckboxes();
+                       $(".ui-popup").popup('close');
+                       $.mobile.changePage('#callView');
+               }
+       };
 
 }());
index c880c5e..463c032 100644 (file)
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 tizen, $, app, ModifierManager */
-
 /**
-* @class TemplateManager
-*/
+ * @class TemplateManager
+ */
 function TemplateManager() {
-    'use strict';
-    this.init();
+       'use strict';
+       this.init();
 }
 
 (function () { // strict mode wrapper
-    'use strict';
-
-    TemplateManager.prototype = {
-
-        /**
-        * Template cache
-        */
-        cache: {},
-
-        /**
-        * UI module initialisation
-        */
-        init: function init() {
-            this.modifiers = new ModifierManager().getAll();
-        },
-
-        /**
-        * Returns template html (from cache)
-        * @param {string} tplName
-        * @param {string} tplParams
-        */
-        get: function TemplateManager_get(tplName, tplParams) {
-            if (this.cache[tplName] !== undefined) {
-                return this.getCompleted(this.cache[tplName], tplParams);
-            }
-            return '';
-        },
-
-        /**
-        * Load templates to cache
-        * @param {string} tplNames
-        * @param {function} onSuccess
-        */
-        loadToCache: function TemplateManager_loadToCache(tplNames, onSuccess) {
-            var self = this,
-                cachedTemplates = 0,
-                tplName,
-                tplPath;
-
-            if ($.isArray(tplNames)) {
-
-                // for each template
-                $.each(tplNames, function (index, fileName) {
-
-                    // cache template html
-                    if (self.cache[fileName] === undefined) {
-                        tplName = [
-                            fileName,
-                            app.config.get('templateExtension')
-                        ].join('');
-                        tplPath = [
-                            app.config.get('templateDir'),
-                            tplName
-                        ].join('/');
-
-                        $.ajax({
-                            url: tplPath,
-                            cache: true,
-                            dataType: 'html',
-                            async: true,
-                            success: function (data) {
-                                // increase counter
-                                cachedTemplates += 1;
-
-                                // save to cache
-                                self.cache[fileName] = data;
-
-                                // if all templates are cached launch callback
-                                if (
-                                    cachedTemplates >= tplNames.length &&
-                                        typeof onSuccess === 'function'
-                                ) {
-                                    onSuccess();
-                                }
-                            },
-                            error: function (jqXHR, textStatus, errorThrown) {
-                                console.error(
-                                    'templateManagerError: ' +
-                                        errorThrown
-                                );
-                            }
-                        });
-                    } else {
-                        // template is already cached
-                        cachedTemplates += 1;
-                        // if all templates are cached launch callback
-                        if (
-                            cachedTemplates >= tplNames.length &&
-                                typeof onSuccess === 'function'
-                        ) {
-                            onSuccess();
-                        }
-                    }
-                });
-
-            }
-        },
-
-        /**
-        * Returns template completed by specified params
-        * @param {string} tplHtml
-        * @param {string} tplParams
-        */
-        getCompleted: function TemplateManager_getCompleted(
-            tplHtml,
-            tplParams
-        ) {
-            var tplParam;
-
-            for (tplParam in tplParams) {
-                if (tplParams.hasOwnProperty(tplParam)) {
-                    tplHtml = this.passThruModifiers(
-                        tplHtml,
-                        tplParam,
-                        tplParams[tplParam]
-                    );
-                }
-            }
-
-            return tplHtml;
-        },
-
-        /**
-         * Returns template completed by specified params
-         * including modifiers
-         * @param {string} tplHtml
-         * @param {string} tplParams
-         * @param {string} content
-         */
-        passThruModifiers: function (tplHtml, tplParam, content) {
-            var regModOn = new RegExp('%' + tplParam + '(\\|(.+?)){1,}%', 'g'),
-                regModOff = new RegExp(['%', tplParam, '%'].join(''), 'g'),
-                regModGet = new RegExp('%' + tplParam + '\\|(.+?)%'),
-                regModPut = new RegExp('%' + tplParam + '\\|(.+?)%', 'g'),
-                specRegExp = new RegExp('\\$', 'g'),
-                modifiers,
-                i;
-
-            if (content && (typeof content === 'string')) {
-                content = content.replace(specRegExp, '$$$$');
-            }
-
-            if (regModOn.test(tplHtml)) {
-                modifiers = tplHtml.match(regModGet)[1].split('|');
-                for (i in modifiers) {
-                    if (this.modifiers[modifiers[i]] instanceof Function) {
-                        content = this.modifiers[modifiers[i]](content);
-                    } else {
-                        console.error('unknown modifier: ' + modifiers[i]);
-                    }
-                }
-                tplHtml = tplHtml.replace(regModPut, content);
-            }
-            tplHtml = tplHtml.replace(regModOff, content);
-
-            return tplHtml;
-        }
-    };
-
-}());
+       'use strict';
+       TemplateManager.prototype = {
+
+               /**
+                * Template cache
+                */
+               cache: {},
+
+               /**
+                * UI module initialisation
+                */
+               init: function init() {
+                       this.modifiers = new ModifierManager().getAll();
+               },
+
+               /**
+                * Returns template html (from cache)
+                * @param {string} tplName
+                * @param {string} tplParams
+                */
+               get: function TemplateManager_get(tplName, tplParams) {
+                       if (this.cache[tplName] !== undefined) {
+                               return this.getCompleted(this.cache[tplName], tplParams);
+                       }
+                       return '';
+               },
+
+               /**
+                * Load templates to cache
+                * @param {string} tplNames
+                * @param {function} onSuccess
+                */
+               loadToCache: function TemplateManager_loadToCache(tplNames, onSuccess) {
+                       var self = this,
+                               cachedTemplates = 0,
+                               tplName,
+                               tplPath;
+
+                       if ($.isArray(tplNames)) {
+
+                               // for each template
+                               $.each(tplNames, function (index, fileName) {
+
+                                       // cache template html
+                                       if (self.cache[fileName] === undefined) {
+                                               tplName = [fileName, app.config.get('templateExtension')].join('');
+                                               tplPath = [app.config.get('templateDir'), tplName].join('/');
+
+                                               $.ajax({
+                                                       url: tplPath,
+                                                       cache: true,
+                                                       dataType: 'html',
+                                                       async: true,
+                                                       success: function (data) {
+                                                               // increase counter
+                                                               cachedTemplates += 1;
+
+                                                               // save to cache
+                                                               self.cache[fileName] = data;
+
+                                                               // if all templates are cached launch callback
+                                                               if (cachedTemplates >= tplNames.length && typeof onSuccess === 'function') {
+                                                                       onSuccess();
+                                                               }
+                                                       },
+                                                       error: function (jqXHR, textStatus, errorThrown) {
+                                                               console.error('templateManagerError: ' + errorThrown);
+                                                       }
+                                               });
+                                       } else {
+                                               // template is already cached
+                                               cachedTemplates += 1;
+                                               // if all templates are cached launch callback
+                                               if (cachedTemplates >= tplNames.length && typeof onSuccess === 'function') {
+                                                       onSuccess();
+                                               }
+                                       }
+                               });
+
+                       }
+               },
+
+               /**
+                * Returns template completed by specified params
+               * @param {string} tplHtml
+               * @param {string} tplParams
+                */
+               getCompleted: function TemplateManager_getCompleted(tplHtml, tplParams) {
+                       var tplParam;
+
+                       for (tplParam in tplParams) {
+                               if (tplParams.hasOwnProperty(tplParam)) {
+                                       tplHtml = this.passThruModifiers(tplHtml, tplParam, tplParams[tplParam]);
+                               }
+                       }
+
+                       return tplHtml;
+               },
+
+               passThruModifiers: function (tplHtml, tplParam, content) {
+                       var regModOn = new RegExp('%' + tplParam + '(\\|(.+?)){1,}%', 'g'),
+                               regModOff = new RegExp(['%', tplParam, '%'].join(''), 'g'),
+                               regModGet = new RegExp('%' + tplParam + '\\|(.+?)%'),
+                               regModPut = new RegExp('%' + tplParam + '\\|(.+?)%', 'g'),
+                               specRegExp = new RegExp('\\$','g'),
+                               modifiers, i;
+
+                       if (content && (typeof content === 'string')) {
+                               content = content.replace(specRegExp, '$$$$');
+                       }
+
+                       if (regModOn.test(tplHtml)) {
+                               modifiers = tplHtml.match(regModGet)[1].split('|');
+                               for (i in modifiers) {
+                                       if (this.modifiers[modifiers[i]] instanceof Function){
+                                               content = this.modifiers[modifiers[i]](content);
+                                       } else {
+                                               console.error('unknown modifier: ' + modifiers[i]);
+                                       }
+                               }
+                               tplHtml = tplHtml.replace(regModPut, content);
+                       }
+                       tplHtml = tplHtml.replace(regModOff, content);
+
+                       return tplHtml;
+               }
+       };
+
+}());
\ No newline at end of file
index a31ff56..1d57ce7 100644 (file)
@@ -1,56 +1,36 @@
-/*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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 $*/
-
 /**
-* @class ModifierManager
-*/
+ * @class ModifierManager
+ */
 function ModifierManager() {
-    'use strict';
-    this.init();
+       'use strict';
+       this.init();
 }
 
 (function () {
-    'use strict';
-
-    ModifierManager.prototype = {
-
-        /**
-        * UI module initialisation
-        */
-        init: function () {
-        },
-
-        /**
-        * @return modifiers object
-        */
-        getAll: function () {
-            return this.modifiers;
-        },
-
-        /**
-        * modifiers definitions
-        */
-        modifiers: {
-            escape: function escape(str) {
-                return $('<span>').text(str).html();
-            }
-        }
-
-    };
-
-}());
+       'use strict';
+       ModifierManager.prototype = {
+
+               /**
+                * UI module initialisation
+                */
+               init: function () {
+               },
+
+               /**
+                * @return modifiers object
+                */
+               getAll: function () {
+                       return this.modifiers;
+               },
+
+               /**
+                * modifiers definitions
+                */
+               modifiers: {
+                       escape: function escape(str) {
+                               return $('<span>').text(str).html();
+                       }
+               }
+       };
+}());
\ No newline at end of file
index 27ca1c4..8a205f5 100644 (file)
@@ -1,85 +1,78 @@
 /*
-*      Copyright 2013  Samsung Electronics Co., Ltd
-*
-*      Licensed under the Flora License, Version 1.1 (the "License");
-*      you may not use this file except in compliance with the License.
-*      You may obtain a copy of the License at
-*
-*              http://floralicense.org/license/
-*
-*      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.
-*/
+ *      Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ *      Licensed under the Flora License, Version 1.1 (the "License");
+ *      you may not use this file except in compliance with the License.
+ *      You may obtain a copy of the License at
+ *
+ *              http://floralicense.org/license/
+ *
+ *      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 devel: true*/
 /*global $, tizen, App  */
 
 /**
-* This file acts as a loader for the application and its dependencies
-*
-* First, the 'app.js' script is loaded .
-* Then, scripts defined in 'app.requires' are loaded.
-* Finally, the app is initialised - the app is instantiated ('app = new App()')
-* and 'app.init()' is called.
-*/
+ * This file acts as a loader for the application and its dependencies
+ *
+ * First, the 'app.js' script is loaded .
+ * Then, scripts defined in 'app.requires' are loaded.
+ * Finally, the app is initialised - the app is instantiated ('app = new App()')
+ * and 'app.init()' is called.
+ */
+
 
 var app = null;
 
 (function () { // strict mode wrapper
-    'use strict';
-
-    ({
-        /**
-        * Loader init - load the App constructor
-        */
-        init: function init() {
-            var self = this;
-            $.getScript('js/app.js')
-                .done(function () {
-                    // once the app is loaded, create the app object
-                    // and load the libraries
-                    app = new App();
-                    self.loadLibs();
-                })
-                .fail(this.onGetScriptError);
-        },
-
-        /**
-        * Load dependencies
-        */
-        loadLibs: function loadLibs() {
-            var loadedLibs = 0;
-            if ($.isArray(app.requires)) {
-                $.each(app.requires, function (index, filename) {
-                    $.getScript(filename)
-                        .done(function () {
-                            loadedLibs += 1;
-                            if (loadedLibs >= app.requires.length) {
-                                // all dependencies are loaded,
-                                // initialise the app
-                                app.init();
-                            }
-                        })
-                        .fail(this.onGetScriptError);
-                });
-            }
-        },
+       'use strict';
 
-        /**
-        * Handle ajax errors
-        */
-        onGetScriptError: function onGetScriptError(
-            e,
-            jqxhr,
-            setting,
-            exception
-        ) {
-            console.error('An error occurred: ' + e.message);
-        }
+       ({
+               /**
+                * Loader init - load the App constructor
+                */
+               init: function init() {
+                       var self = this;
+                       $.getScript('js/app.js')
+                               .done(function () {
+                                       // once the app is loaded, create the app object
+                                       // and load the libraries
+                                       app = new App();
+                                       self.loadLibs();
+                               })
+                               .fail(this.onGetScriptError);
+               },
 
-    }).init(); // run the loader
+               /**
+                * Load dependencies
+                */
+               loadLibs: function loadLibs() {
+                       var loadedLibs = 0;
+                       if ($.isArray(app.requires)) {
+                               $.each(app.requires, function (index, filename) {
+                                       $.getScript(filename)
+                                               .done(function () {
+                                                       loadedLibs += 1;
+                                                       if (loadedLibs >= app.requires.length) {
+                                                               // All dependencies are loaded - initialise the app
+                                                               app.init();
+                                                       }
+                                               })
+                                               .fail(this.onGetScriptError);
+                               });
+                       }
+               },
 
+               /**
+                * Handle ajax errors
+                */
+               onGetScriptError: function onGetScriptError(e, jqxhr, setting, exception) {
+                       console.error('An error occurred: ' + e.message);
+               }
+       }).init(); // run the loader
 }());
index 4eef397..7cdb23a 100644 (file)
@@ -1,6 +1,7 @@
 <li data-filtertext="%name|escape%" class="%cssClasses%">
-    <div class="numberOrName">%name|escape%</div>
-    <div class="iconStatus"></div>
-    <div class="callTime">%callTime%</div>
-    <div class="callDate hidden">%callDate%</div>
-</li>
+       <div class="toRemove hidden"><input type="checkbox" /></div>
+       <div class="numberOrName">%name|escape%</div>
+       <div class="iconStatus"></div>
+       <div class="callTime">%callTime%</div>
+       <div class="callDate hidden">%callDate%</div>
+</li>
\ No newline at end of file
index 6822cdd..15c7610 100644 (file)
@@ -1,14 +1,16 @@
-<div data-role="page" id="callView" data-add-back-btn="header">
-    <div data-role="header" id="page-header" data-position="fixed">
-        <h1>Call log</h1>
-    </div>
-    <div data-role="content" id="calllogListContent">
-        <ul data-role="listview"
-            id="calllogList"
-            data-filter="true"
-            data-autodividers="true"
-            data-position="fixed"
-            data-inset="true">
-        </ul>
-    </div>
-</div>
+       <div data-role="page" id="callView" data-add-back-btn="header">
+               <div data-role="header" id="page-header" data-position="fixed">
+                       <h1>Call log</h1>
+               </div>
+               <div data-role="content" id="calllogListContent">
+                       <ul data-role="listview"
+                               id="calllogList"
+                               data-filter="true"
+                               data-autodividers="true"
+                               data-position="fixed"
+                               data-inset="true">
+                       </ul>
+               </div>
+               </div>
+               <!-- <div data-role="footer" data-position="fixed"></div> -->
+       </div>
\ No newline at end of file
index 1ffd75f..08c6f67 100644 (file)
@@ -1,6 +1,6 @@
 <li class="ui-li-has-multiline call %cssClass%" data-uid="%uid%">
-    <div class="toRemove hidden"><form><input type="checkbox" /></form></div>
-    <div class="callAllTime">%callTime%</div>
-    <div class="iconStatus"></div>
-    <div class="callDuration">%callDuration%</div>
-</li>
+       <div class="toRemove hidden"><form><input type="checkbox" /></form></div>
+       <div class="callAllTime">%callTime%</div>
+       <div class="iconStatus"></div>
+       <div class="callDuration">%callDuration%</div>
+</li>
\ No newline at end of file
index 7ed8729..f936220 100644 (file)
@@ -1,36 +1,36 @@
-<div data-role="page" id="historyForCallerView">
-    <div data-role="header" data-position="fixed" id="header">
-        <h1>History for caller</h1>
-        <div class="contact">
-            <div class="infoContainer">
-                <div class="photo"></div>
-                <div class="name"></div>
-                <div class="number"><span class="accountId"></span><span class="numberOfEntries"></span></div>
-            </div>
-            <div class="options">
-                <a data-role="button" class="actionButton" id="callActionBtn" data-inline="true">Call</a>
-                <a data-role="button" class="actionButton" id="smsActionBtn" data-inline="true">Message</a>
-            </div>
-        </div>
-    </div>
-    <div data-role="content" id="callerListContainer">
-        <div class="selectAllBox">
-            <div class="toRemove">
-                <input type="checkbox" id="selectAllDetails"/>
-            </div>
-            <p id="selectAllText">Select all</p>
-        </div>
-        <div id="content">
-            <ul data-role="listview" id="forCallerList"></ul>
-        </div>
-    </div>
-    <div data-role="footer" data-position="fixed">
-        <div data-role="tabbar" data-style="toolbar" id="delete-toolbar">
-            <ul>
-                <li id="delete">
-                    <a id="deleteActionBtn">Delete</a>
-                </li>
-            </ul>
-        </div>
-    </div>
-</div>
+       <div data-role="page" id="historyForCallerView">
+               <div data-role="header" data-position="fixed" id="header">
+                       <h1>History for caller</h1>
+                       <div class="contact">
+                               <div class="infoContainer">
+                                       <div class="photo"></div>
+                                       <div class="name"></div>
+                                       <div class="number"><span class="accountId"></span><span class="numberOfEntries"></span></div>
+                               </div>
+                               <div class="options">
+                                       <a href="javascript:void(0)" data-role="button" class="actionButton" id="callActionBtn" data-inline="true">Call</a>
+                                       <a href="javascript:void(0)" data-role="button" class="actionButton" id="smsActionBtn" data-inline="true">Message</a>
+                               </div>
+                       </div>
+               </div>
+               <div data-role="content" id="callerListContainer">
+                       <div class="selectAllBox">
+                               <div class="toRemove">
+                                       <input type="checkbox" id="selectAllDetails"/>
+                               </div>
+                               <p id="selectAllText">Select all</p>
+                       </div>
+                       <div id="content">
+                               <ul data-role="listview" id="forCallerList"></ul>
+                       </div>
+               </div>
+               <div data-role="footer" data-position="fixed">
+                       <div data-role="tabbar" data-style="toolbar" id="delete-toolbar">
+                               <ul>
+                                       <li id="delete">
+                                               <a id="deleteActionBtn">Delete</a>
+                                       </li>
+                               </ul>
+                       </div>
+               </div>
+       </div>
\ No newline at end of file
index 6643907..9e6caa9 100644 (file)
@@ -1 +1 @@
-<li class="date">%date%</li>
+<li class="date">%date%</li>
\ No newline at end of file
index e4fd514..f0b0216 100644 (file)
@@ -1,6 +1,6 @@
-<div id="errorPopup" data-role="popup" class="center_basic_2btn">
-    <div class="ui-popup-text" id="errorPopupMessage"></div>
-    <div class="ui-popup-button-bg">
-        <a data-role="button" data-inline="true" id="errorPopupOkBtn">OK</a>
-    </div>
-</div>
+               <div id="errorPopup" data-role="popup" class="center_basic_2btn">
+                       <div class="ui-popup-text" id="errorPopupMessage"></div>
+                       <div class="ui-popup-button-bg">
+                               <a data-role="button" data-inline="true" id="errorPopupOkBtn">OK</a>
+                       </div>
+               </div>
index 3a79873..d916cae 100644 (file)
@@ -1,7 +1,7 @@
-<div id="popup" data-role="popup" class="center_basic_2btn">
-    <div class="ui-popup-text" id="popupMessage"></div>
-    <div class="ui-popup-button-bg">
-        <a data-role="button" data-inline="true" id="popupCancelActionBtn">No</a>
-        <a data-role="button" data-inline="true" id="popupSubmitActionBtn">Yes</a>
-    </div>
-</div>
+               <div id="popup" data-role="popup" class="center_basic_2btn">
+                       <div class="ui-popup-text" id="popupMessage"></div>
+                       <div class="ui-popup-button-bg">
+                               <a data-role="button" data-inline="true" id="popupCancelActionBtn">No</a>
+                               <a data-role="button" data-inline="true" id="popupSubmitActionBtn">Yes</a>
+                       </div>
+               </div>