From: Piotr Wronski Date: Tue, 3 Jun 2014 06:17:45 +0000 (-0700) Subject: Revert "Updated application sources" X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=HEAD;p=apps%2Fweb%2Fsample%2FFileManager.git Revert "Updated application sources" This reverts commit 3610a7e902a7d3a18d5762295f8899dcd9e4f5c3. Change-Id: I0d94179178225eeb08080cf7d753d350ac2f7ec7 --- diff --git a/project/config.xml b/project/config.xml index 8f6f03c..45f5279 100644 --- a/project/config.xml +++ b/project/config.xml @@ -1,29 +1,13 @@ - - - - - - File Manager - - - - - - - - + + + + File Manager + + + + + + + diff --git a/project/css/style.css b/project/css/style.css index 4cec128..94917c0 100644 --- a/project/css/style.css +++ b/project/css/style.css @@ -1,257 +1,245 @@ * { - margin: 0px; - padding: 0px; + margin: 0px; + padding: 0px; } body { - overflow: hidden; - -webkit-user-select: none; + overflow: hidden; } #fileList { - margin: 0; + margin: 0; } #mainTitle { - width: 210px; + width: 210px; } #fileList > li { - padding-top: 0.3rem; - padding-bottom: 0.3rem; - border-top: solid 1px #ddd; + padding-top: 0.3rem; + padding-bottom: 0.3rem; + border-top: solid 1px #ddd; } #fileList > li > span.nodename { - display: inline-block; - position: absolute; - line-height: 32px; - white-space: pre; - text-overflow: ellipsis; - width: 75%; - overflow: hidden; - margin-top: 5px; - height: 32px; + display: inline-block; + position: absolute; + line-height: 32px; + white-space: nowrap; + text-overflow: ellipsis; + width: 75%; + overflow: hidden; + margin-top: 5px; } #fileList > li.gradientBackground > span.nodename { - color: #fff !important; + color: #fff !important; } #fileList > li.file img { - width: 32px; - height: 32px; - padding-top: 5px; + width: 32px; + height: 32px; } #fileList > li.folder img { - margin-top: 0.1rem; + margin-top: 0.1rem; } #fileList > li.levelUp { - padding-left: 47px !important; - height: 32px; + padding-left: 47px !important; + height: 32px; } .selectAll { - padding-left: 6px; - display: inline-block; + padding-left: 6px; + display: inline-block; } .selectAll span.ui-btn-text { - line-height: 40px; + padding-left: 2rem !important; + line-height: 40px; } #navbar { - height: 16px; - padding: 2px 10px; - font-size: 14px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background-color: rgba(255, 255, 255, 0.5); - border-top: solid 1px #DDD; - text-align: left; + height: 16px; + padding: 2px 10px; + font-size: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + background-color: rgba(255, 255, 255, 0.5); + border-top: solid 1px #DDD; + text-align: left; } .ui-pathDiv { - position: absolute; - top: 49px; - left: 0px; - right: 0px; - bottom: 0px; + position: absolute; + top: 49px; + left: 0px; + right: 0px; + bottom: 0px; } #pathDiv { - padding: 2px 0px 0px 5px; - border: 0px; + padding: 2px 0px 0px 5px; + border: 0px; } #pathDiv .ui-li-text-main { - font-size: 18px; + font-size: 18px; } #morePopup td.text a { - color:#FFF; - text-decoration:none; + color:#FFF; + text-decoration:none; } #morePopup td.text { - padding: 5px; + padding: 5px; } #morePopup { - margin: 2px; + margin: 2px; } #alertPopup .text { - text-align:left; - padding:20px; - min-height: 100px !important; + text-align:left; + padding:20px; + min-height: 100px !important; } #alertPopup .alertPopup-button { - padding-bottom: 10px; + padding-bottom: 10px; } #confirmPopup .text { - text-align:left; - padding:20px; - font-size: 18px; + text-align:left; + padding:20px; + font-size: 18px; } .ui-header.ui-bar-s .ui-btn.standard { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } #homeBtn, #levelUpBtn { - top:0px; + top:0px; } .ui-li-1line-bigicon1.ui-li.ui-li-static.ui-body-s.ui-li-has-thumb { - padding-left: 0.7rem; - padding-right: 0rem; + padding-left: 0.7rem; + padding-right: 0rem; } .my-ui-checkbox { - display: inline-block; - margin-top: 0rem; - margin-right: 0rem; - position: relative !important; - top: -0.7rem; - left: -1.5rem; + display: inline-block; + margin-top: 0rem; + margin-right: 0rem; + position: relative !important; + top: -0.7rem; + left: -1.5rem; } ul.ui-listview > li.ui-li-1line-bigicon1 img.ui-li-bigicon { - display: inline-block; - margin-top: 0rem; - margin-right: 0.7rem; - position: relative; - left: 5px; + display: inline-block; + margin-top: 0rem; + margin-right: 0.7rem; + position: relative; + left: 5px; } .ui-checkbox .ui-btn.ui-btn-icon-left .ui-btn-inner { - line-height: 1.1rem; - padding: 0 5 0 0rem; - width: 30px; + line-height: 1.1rem; + padding: 0 0 0 0rem; + width: 30px; } .ui-checkbox .ui-btn.ui-btn-icon-left .ui-btn-inner.ui-btn-hastxt { - width: 100%; + width: 100%; } .ui-btn-corner-all { - -webkit-border-radius: 0px; - bordert-radius: 0px; + -webkit-border-radius: 0px; + bordert-radius: 0px; } .ui-content.ui-scrollview-clip > div.ui-scrollview-view { - padding: 0px; + padding: 0px; } input.ui-input-text.new_folder { - width: 100%; - height: 50px; - padding: 0 0 0 .4em; + width: 100%; + height: 50px; + padding: 0 0 0 .4em; } .gradientBackground { - background: -webkit-linear-gradient(top, #5A99BA 0%, #205473 100%) !important; /* from tizen-white */ + background: -webkit-linear-gradient(top, #5A99BA 0%, #205473 100%) !important; /* from tizen-white */ } .hidden { - display: none !important; + display: none !important; } .vhidden { - visibility: hidden !important; + visibility: hidden !important; } .ui-tabbar a { - color: #999 !important; + color: #999 !important; } #newFolderName { - box-sizing: border-box; - width: 100%; + box-sizing: border-box; + width: 100%; } .ui-header.ui-bar-s > .ui-btn { - width: 2rem; + width: 2rem; } -/** workaround to prevent hiding footer -caused by broken softkeyboardupdate event**/ -[data-role='footer'] { - display: block !important; +/** workaround to prevent hiding footer caused by broken softkeyboardupdate event**/ +[data-role="footer"] { + display: block !important; } .ui-ctxpopup .horizontal a.ui-link { - display: block; + display: block; } .ui-footer .ui-btn-text { - text-transform: uppercase; + text-transform: uppercase; } -.ui-tabbar:not(.ui-tabbar-persist) a.ui-btn-active .ui-btn-text, -.ui-tabbar:not(.ui-tabbar-persist) .ui-btn-show-style .ui-btn-text { - border:none; +.ui-tabbar:not(.ui-tabbar-persist) a.ui-btn-active .ui-btn-text, .ui-tabbar:not(.ui-tabbar-persist) .ui-btn-show-style .ui-btn-text { + border:none; } #overlay { - background-color: rgba(0, 0, 0, 0.5); - width: 100%; - height: 100%; - position: absolute; - left: 0px; - top: 0px; - z-index: 9000; - display: none; + background-color: rgba(0, 0, 0, 0.5); + width: 100%; + height: 100%; + position: absolute; + left: 0px; + top: 0px; + z-index: 9000; + display: none; } #infoPopup { - background-color: #fff; - height: 130px; - padding: 15px 0px; - position: absolute; - text-align: center; - box-shadow: 0px 0px 20px #444; - border-radius: 5px; + background-color: #fff; + height: 130px; + padding: 15px 0px; + position: absolute; + text-align: center; + box-shadow: 0px 0px 20px #444; + border-radius: 5px; } #infoPopup img { - -webkit-animation: rotation 2s infinite linear; + -webkit-animation: rotation 2s infinite linear; } @-webkit-keyframes rotation { - from {-webkit-transform: rotate(0deg);} - to {-webkit-transform: rotate(359deg);} -} - -.white-space-pre { - white-space: pre !important; -} - -#alertPopup p:first-letter { - text-transform: uppercase; -} + from {-webkit-transform: rotate(0deg);} + to {-webkit-transform: rotate(359deg);} +} \ No newline at end of file diff --git a/project/images/etc.png b/project/images/etc.png old mode 100644 new mode 100755 index 4b757e2..26748d8 Binary files a/project/images/etc.png and b/project/images/etc.png differ diff --git a/project/images/img.png b/project/images/img.png old mode 100644 new mode 100755 index f8b7a34..4dd3be3 Binary files a/project/images/img.png and b/project/images/img.png differ diff --git a/project/images/music.png b/project/images/music.png old mode 100644 new mode 100755 index dc4891f..449d29d Binary files a/project/images/music.png and b/project/images/music.png differ diff --git a/project/images/video.png b/project/images/video.png old mode 100644 new mode 100755 index ca96031..9786439 Binary files a/project/images/video.png and b/project/images/video.png differ diff --git a/project/index.html b/project/index.html index e50998a..9366eb2 100644 --- a/project/index.html +++ b/project/index.html @@ -5,9 +5,9 @@ File Manager - - - + + + diff --git a/project/js/app.clipboard.js b/project/js/app.clipboard.js index aa5d175..cee9925 100644 --- a/project/js/app.clipboard.js +++ b/project/js/app.clipboard.js @@ -1,19 +1,3 @@ -/* - * 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 $*/ @@ -21,153 +5,143 @@ * @class Config */ function Clipboard() { - 'use strict'; - this.mode = this.INACTIVE_MODE; + 'use strict'; + this.mode = this.INACTIVE_MODE; } (function () { // strict mode wrapper - 'use strict'; - Clipboard.prototype = { - /** - * Clipboard mode for copying - */ - COPY_MODE_ID: 0, - - /** - * Clipboard mode for moving - */ - MOVE_MODE_ID: 1, - - /** - * Clipbboard inactive mode - */ - INACTIVE_MODE: -1, - - /** - * Clipboard data - */ - data: [], - - /** - * Clipboard mode: [copy | move | inactive] - */ - mode: undefined, - - /** - * Returns all paths in clipboard - * @returns {array} - */ - get: function Clipboard_get() { - return this.data; - }, - - /** - * Add new path to clipboard - * @param {array} paths array of full paths - * @returns {number} current length of clipboard objects - */ - add: function Clipboard_add(paths) { - var len = paths.length, - i; - - // clear clipboard - this.clear(); - for (i = 0; i < len; i += 1) { - if (this.has(paths[i]) === false) { - this.data.push(paths[i]); - } - } - - return this.data.length; - }, - - /** - * Remove specified path is already in clipboard - * @param {string} path full path - * @returns {number} current length of clipboard objects - */ - remove: function Clipboard_remove(path) { - var index = $.inArray(path, this.data), - length; - if (index >= 0) { - this.data.splice(index, 1); - length = this.data.length; - if (length === 0) { - this.mode = this.INACTIVE_MODE; - } - } - return length; - }, - - /** - * Remove specified path and all children paths if already in clipboard - * @param {string} path full path - * @returns {number} current length of clipboard objects - */ - removeRecursively: function Clipboard_removeRecursively(path) { - var escapeRegExp = function (str) { - return str - .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - childPattern = new RegExp(escapeRegExp(path)), - index = this.data.length - 1; - while (index >= 0) { - if (childPattern.test(this.data[index])) { - this.data.splice(index, 1); - } - index -= 1; - } - return this.data.length; - }, - - /** - * Checks if specified path is already in clipboard - * @param {string} path full path - * @returns {boolean} - */ - has: function Clipboard_has(path) { - return $.inArray(path, this.data) === -1 ? false : true; - }, - - /** - * Clears all clipboard data and resets clipboard mode - */ - clear: function Clipboard_clear() { - this.data = []; - this.mode = this.INACTIVE_MODE; - }, - - /** - * Sets clipboard mode - * @param {number} mode - * @returns {boolean} - */ - setMode: function Clipboard_setMode(mode) { - if ( - $.inArray( - mode, - [this.MOVE_MODE_ID, this.COPY_MODE_ID] - ) === false - ) { - console.error('Incorrect clipboard mode'); - return false; - } - this.mode = mode; - return true; - }, - - /** - * @returns {number} mode Clipboard mode - */ - getMode: function Clipboard_getMode() { - return this.mode; - }, - - /** - * @returns {boolean} - */ - isEmpty: function Clipboard_isEmpty() { - return this.data.length === 0; - } - }; + 'use strict'; + Clipboard.prototype = { + /** + * Clipboard mode for copying + */ + COPY_MODE_ID: 0, + + /** + * Clipboard mode for moving + */ + MOVE_MODE_ID: 1, + + /** + * Clipbboard inactive mode + */ + INACTIVE_MODE: -1, + + /** + * Clipboard data + */ + data: [], + + /** + * Clipboard mode: [copy | move | inactive] + */ + mode: undefined, + + /** + * Returns all paths in clipboard + * @returns {array} + */ + get: function Clipboard_get() { + return this.data; + }, + + /** + * Add new path to clipboard + * @param {array} paths array of full paths + * @returns {number} current length of clipboard objects + */ + add: function Clipboard_add(paths) { + var len = paths.length, + i; + + // clear clipboard + this.clear(); + for (i = 0; i < len; i += 1) { + if (this.has(paths[i]) === false) { + this.data.push(paths[i]); + } + } + + return this.data.length; + }, + + /** + * Remove specified path is already in clipboard + * @param {string} path full path + * @returns {number} current length of clipboard objects + */ + remove: function Clipboard_remove(path) { + var index = $.inArray(path, this.data); + var length; + if (index >= 0) { + this.data.splice(index, 1); + length = this.data.length; + if (length === 0) { + this.mode = this.INACTIVE_MODE; + } + } + return length; + }, + + /** + * Remove specified path and all children paths if already in clipboard + * @param {string} path full path + * @returns {number} current length of clipboard objects + */ + removeRecursively: function Clipboard_removeRecursively(path) { + var childPattern = new RegExp(path), + index = this.data.length; + while (index--) { + if(childPattern.test(this.data[index])) { + this.data.splice(index, 1); + } + } + return this.data.length; + }, + + /** + * Checks if specified path is already in clipboard + * @param {string} path full path + * @returns {boolean} + */ + has: function Clipboard_has(path) { + return $.inArray(path, this.data) === -1 ? false : true; + }, + + /** + * Clears all clipboard data and resets clipboard mode + */ + clear: function Clipboard_clear() { + this.data = []; + this.mode = this.INACTIVE_MODE; + }, + + /** + * Sets clipboard mode + * @param {number} mode + * @returns {boolean} + */ + setMode: function Clipboard_setMode(mode) { + if ($.inArray(mode, [this.MOVE_MODE_ID, this.COPY_MODE_ID]) === false) { + console.error('Incorrect clipboard mode'); + return false; + } + this.mode = mode; + return true; + }, + + /** + * @returns {number} mode Clipboard mode + */ + getMode: function Clipboard_getMode() { + return this.mode; + }, + + /** + * @returns {boolean} + */ + isEmpty: function Clipboard_isEmpty() { + return this.data.length === 0; + } + }; }()); diff --git a/project/js/app.config.js b/project/js/app.config.js index a7681e0..e0332c3 100644 --- a/project/js/app.config.js +++ b/project/js/app.config.js @@ -1,44 +1,28 @@ -/* - * 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. - */ - /** * @class Config */ function Config() { - 'use strict'; + 'use strict'; } (function () { // strict mode wrapper - 'use strict'; - Config.prototype = { + 'use strict'; + Config.prototype = { - properties: { - 'templateDir': 'templates', - 'templateExtension': '.tpl' - }, + properties: { + 'templateDir': 'templates', + 'templateExtension': '.tpl' + }, - /** - * Returns config value - */ - get: function (value, defaultValue) { + /** + * Returns config value + */ + get: function (value, defaultValue) { - if (this.properties.hasOwnProperty(value)) { - return this.properties[value]; - } - return defaultValue; - } - }; + if (this.properties.hasOwnProperty(value)) { + return this.properties[value]; + } + return defaultValue; + } + }; }()); diff --git a/project/js/app.helpers.js b/project/js/app.helpers.js index 86c8f5e..12cd314 100644 --- a/project/js/app.helpers.js +++ b/project/js/app.helpers.js @@ -1,19 +1,3 @@ -/* - * 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 $, jQuery */ @@ -21,178 +5,158 @@ * @class Helpers */ function Helpers() { - 'use strict'; + 'use strict'; } (function () { // strict mode wrapper - 'use strict'; - Helpers.prototype = { - - extensions: { - '.bmp': 'img.png', - '.gif': 'img.png', - '.jpeg': 'img.png', - '.jpg': 'img.png', - '.png': 'img.png', - '.tiff': 'img.png', - '.3ga': 'music.png', - '.aac': 'music.png', - '.ac3': 'music.png', - '.amr': 'music.png', - '.awb': 'music.png', - '.m4a': 'music.png', - '.m4p': 'music.png', - '.m4r': 'music.png', - '.mp3': 'music.png', - '.ogg': 'music.png', - '.wav': 'music.png', - '.wma': 'music.png', - '.3gp': 'video.png', - '.avc': 'video.png', - '.avi': 'video.png', - '.m4v': 'video.png', - '.mkv': 'video.png', - '.mov': 'video.png', - '.mp4': 'video.png', - '.mpeg': 'video.png', - '.mpg': 'video.png', - '.ogv': 'video.png', - '.vc1': 'video.png', - '.wmv': 'video.png', - '.doc': 'text.png', - '.docx': 'text.png', - '.odt': 'text.png', - '.ods': 'text.png', - '.txt': 'text.png', - '.xls': 'text.png', - '.xlsx': 'text.png', - '.vcard': 'text.png', - '.vcf': 'text.png', - '.icalendar': 'text.png', - '.ical': 'text.png', - '.ics': 'text.png', - '.ifb': 'text.png', - '.pdf': 'pdf.png', - '.odp': 'ppt.png', - '.ppt': 'ppt.png', - '.wgt': 'etc.png' - }, - - /** - * Capitalise the first letter - * - * @param {string} text - * @returns {string} - */ - UCFirst: function Helpers_UCFirst(text) { - return text.charAt(0).toUpperCase() + text.slice(1); - }, - - /** - * @param {string} fileName - * @returns {string} file name without extension - */ - getFileName: function Helpers_getFileName(fileName) { - var fileNameLen = fileName.lastIndexOf('.'); - if (fileNameLen !== -1) { - fileName = fileName.slice(0, fileNameLen); - } - return fileName; - }, - - /** - * @param {string} fileName - * @returns {string} extension for specified file name - */ - getFileExtension: function Helpers_getFileExtension(fileName) { - var splittedFileName = fileName.split('.'), - ext = ''; - - if (splittedFileName.length > 1) { - ext = '.' + splittedFileName.pop(); - } - return ext; - }, - - /** - * Return icon filename for the given extension. - * For example, for '.mp3' returns 'music.png' - * - * @param {string} ext - * @return {string} - */ - resolveFileIcon: function Helpers_resolveFileIcon(ext) { - ext = ext.toLowerCase(); - return this.extensions[ext] || 'etc.png'; - }, - - /** - * Returns thumbnail URI for specified file - * @param {string} fileName - * @param {File} node - * @returns {string} - */ - getThumbnailURI: function Helpers_getThumbnailURI(fileName, node) { - var ext = this.getFileExtension(fileName); - - if (!node.thumbnailURIs) { - return 'images/' + this.resolveFileIcon(ext); - } - - if ( - node.thumbnailURIs[0] && - $.inArray(ext, ['.mp4', '.jpg', '.png', '.gif']) - ) { - return node.thumbnailURIs[0]; - } - - return 'images/etc.png'; - }, - - /** - * File name automatic number increase for copy files - */ - getCopyFileName: function Helpers_getCopyFileName( - sourceName, - filesList - ) { - var i = 1, copyFileName = sourceName, - filesNames = filesList.map(function (element) { - return element.name; - }), - index = filesNames.indexOf(copyFileName), - ext = this.getFileExtension(sourceName); - - while (index !== -1) { - if (filesList[index].isDirectory) { - copyFileName = sourceName + '(' + i + ')'; - } else { - copyFileName = this.getFileName( - sourceName - ) + '(' + i + ')' + ext; - } - i += 1; - index = filesNames.indexOf(copyFileName); - } - - return copyFileName; - }, - - /** - * Fixes invalid URI returned by API's File::toURI() method. - * See issue https://bugs.tizendev.org/jira/browse/N_SE-54639 - */ - fixURI: function Helpers_fixURI(invaliduri) { - var scheme, address, k; - invaliduri = invaliduri.split('://'); - scheme = invaliduri[0]; - invaliduri.shift(); - address = invaliduri.join('://').split('/'); - for (k = address.length - 1; k >= 0; k -= 1) { - address[k] = encodeURIComponent(address[k]); - } - return scheme + '://' + address.join('/'); - } - - }; + 'use strict'; + Helpers.prototype = { + + extensions: { + '.bmp': {mime:'image/*', icon:'img.png'}, + '.gif': {mime:'image/*', icon:'img.png'}, + '.jpeg': {mime:'image/*', icon:'img.png'}, + '.jpg': {mime:'image/*', icon:'img.png'}, + '.png': {mime:'image/*', icon:'img.png'}, + '.tiff': {mime:'image/*', icon:'img.png'}, + '.3ga': {mime:'audio/*', icon:'music.png'}, + '.aac': {mime:'audio/*', icon:'music.png'}, + '.ac3': {mime:'audio/*', icon:'music.png'}, + '.amr': {mime:'audio/*', icon:'music.png'}, + '.awb': {mime:'audio/*', icon:'music.png'}, + '.m4a': {mime:'audio/*', icon:'music.png'}, + '.m4p': {mime:'audio/*', icon:'music.png'}, + '.m4r': {mime:'audio/*', icon:'music.png'}, + '.mp3': {mime:'audio/*', icon:'music.png'}, + '.ogg': {mime:'audio/*', icon:'music.png'}, + '.wav': {mime:'audio/*', icon:'music.png'}, + '.wma': {mime:'audio/*', icon:'music.png'}, + '.3gp': {mime:'video/*', icon:'video.png'}, + '.avc': {mime:'video/*', icon:'video.png'}, + '.avi': {mime:'video/*', icon:'video.png'}, + '.m4v': {mime:'video/*', icon:'video.png'}, + '.mkv': {mime:'video/*', icon:'video.png'}, + '.mov': {mime:'video/*', icon:'video.png'}, + '.mp4': {mime:'video/*', icon:'video.png'}, + '.mpeg': {mime:'video/*', icon:'video.png'}, + '.mpg': {mime:'video/*', icon:'video.png'}, + '.ogv': {mime:'video/*', icon:'video.png'}, + '.vc1': {mime:'video/*', icon:'video.png'}, + '.wmv': {mime:'video/*', icon:'video.png'}, + '.doc': {mime:'', icon:'text.png'}, + '.docx': {mime:'', icon:'text.png'}, + '.odt': {mime:'', icon:'text.png'}, + '.ods': {mime:'', icon:'text.png'}, + '.txt': {mime:'', icon:'text.png'}, + '.xls': {mime:'', icon:'text.png'}, + '.xlsx': {mime:'', icon:'text.png'}, + '.vcard': {mime:'text/vcard', icon:'text.png'}, + '.vcf': {mime:'text/vcard', icon:'text.png'}, + '.icalendar': {mime:'text/calendar', icon:'text.png'}, + '.ical': {mime:'text/calendar', icon:'text.png'}, + '.ics': {mime:'text/calendar', icon:'text.png'}, + '.ifb': {mime:'text/calendar', icon:'text.png'}, + '.pdf': {mime:'', icon:'pdf.png'}, + '.odp': {mime:'', icon:'ppt.png'}, + '.ppt': {mime:'', icon:'ppt.png'}, + '.wgt': {mime:'application/widget', icon:'etc.png'} + }, + + /** + * Capitalise the first letter + * + * @param {string} text + * @returns {string} + */ + UCFirst: function Helpers_UCFirst(text) { + return text.charAt(0).toUpperCase() + text.slice(1); + }, + + /** + * @param {string} fileName + * @returns {string} file name without extension + */ + getFileName: function Helpers_getFileName(fileName) { + var fileNameLen = fileName.indexOf('.'); + if (fileNameLen !== -1) { + fileName = fileName.slice(0, fileNameLen); + } + return fileName; + }, + + /** + * @param {string} fileName + * @returns {string} extension for specified file name + */ + getFileExtension: function Helpers_getFileExtension(fileName) { + var splittedFileName = fileName.split('.'), + ext = ''; + + if (splittedFileName.length > 1) { + ext = '.' + splittedFileName.pop(); + } + return ext; + }, + + /** + * Return icon filename for the given extension. + * For example, for '.mp3' returns 'music.png' + * + * @param {string} ext + * @return {string} + */ + resolveFileIcon: function Helpers_resolveFileIcon(ext) { + ext = ext.toLowerCase(); + var info = this.extensions[ext]; + return info ? info.icon : 'etc.png'; + }, + + /** + * Resolve file extension to MIME type + * + * @param {string} ext File extension + * @returns {string} + */ + resolveMimeType: function Helpers_resolveMimeType(ext) { + ext = ext.toLowerCase(); + var info = this.extensions[ext]; + return info ? info.mime : ''; + }, + + /** + * Returns thumbnail URI for specified file + * @param {string} fileName + * @param {File} node + * @returns {string} + */ + getThumbnailURI: function Helpers_getThumbnailURI(fileName, node) { + var ext = this.getFileExtension(fileName); + + if (!node.thumbnailURIs) { + return 'images/' + this.resolveFileIcon(ext); + } + + if (node.thumbnailURIs[0] && $.inArray(ext, ['.mp4', '.jpg', '.png', '.gif'])) { + return node.thumbnailURIs[0]; + } + + return 'images/etc.png'; + }, + + /** + * File name automatic number increase for copy files + */ + getCopyFileName: function (sourceName, filesList) { + var ext = this.getFileExtension(sourceName), + fileName = this.getFileName(sourceName), + copyFileName = sourceName, + i = 1; + + while ($.inArray(copyFileName, filesList) !== -1) { + i += 1; + copyFileName = fileName + '(' + i + ')' + ext; + } + return copyFileName; + } + }; }()); diff --git a/project/js/app.js b/project/js/app.js index 296356f..297023b 100644 --- a/project/js/app.js +++ b/project/js/app.js @@ -1,318 +1,278 @@ -/* - * 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, Ui, Model, Helpers, Config, Clipboard*/ var App = null; (function () { // strict mode wrapper - 'use strict'; - - /** - * Creates a new application object - * - * @class Application - * @constructor - */ - App = function App() { - }; - - 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.systemIO.js', - 'js/app.helpers.js', - 'js/app.clipboard.js' - ], - - /** - * @type Model - */ - model: null, - - /** - * @type Ui - */ - ui: null, - - /** - * @type Config - */ - config: null, - - /** - * @type SystemIO - */ - systemIO: null, - - /** - * @type Helpers - */ - helpers: null, - - /** - * @type {string} - */ - currentPath: 'root', - - /** - * - */ - currentDirHandle: null, - - /** - * @type {Clipboard} - */ - clipboard: null, - - /** - * Initialization - */ - init: function App_init() { - this.config = new Config(); - this.model = new Model(); - this.ui = new Ui(); - this.helpers = new Helpers(); - this.clipboard = new Clipboard(); - - this.initUi(); - }, - - /** - * UI initialization - */ - initUi: function App_initUi() { - this.ui.init(this.model.getInternalStorages()); - }, - - /** - * Displays media storages - */ - displayStorages: function App_displayStorages() { - this.currentPath = ''; - if (!this.ui.editMode) { - this.ui.scrollContentTo(0); - } - this.ui.displayStorages(this.model.getInternalStorages()); - }, - - /** - * Displays specified folder - * @param {string} path - * @param {bool} [refresh=false] - */ - displayFolder: function App_displayFolder(path, refresh) { - var self = this; - - refresh = refresh || false; - - // get folder data and push into rendering method - this.model.getFolderData(path, function (dir, nodes) { - // on success - - // update current path - self.currentPath = path; - - // update current dir handle - self.currentDirHandle = dir; - - // display folder UI - if (refresh === undefined) { - self.ui.scrollContentTo(0); - } - self.ui.displayFolder(path, nodes, refresh); - }); - }, - - /** - * Opens specified file - * @params {string} uri File URI - */ - openFile: function App_openFile(uri, fullUri) { - tizen.filesystem.resolve( - fullUri, - function (file) { - this.model.openFile(fullUri); - }.bind(this), - function () { - // file doesn't exists - this.ui.alertPopup('File does no longer exist', - this.refreshCurrentPage.bind(this, true)); - }.bind(this) - ); - }, - - /** - * Displays parent location - */ - goLevelUp: function App_goLevelUp() { - // split current path and get proper path for parent location - var newPath = this.currentPath.split('/').slice(0, -1).join('/'); - - if (newPath !== '') { - this.displayFolder(newPath); - } else { - this.displayStorages(); - } - }, - - /** - * creates new dir in currently viewed dir - * @param {string} dirName - * @return {boolean} return status - */ - createDir: function App_createDir(dirName, callback) { - var status = true; - if (this.currentDirPath !== '') { - try { - this.currentDirHandle.createDirectory(dirName); - } catch (e) { - status = false; - app.ui.alertPopup(e.message, callback); - } - this.refreshCurrentPage(); - } else { - status = false; - app.ui.alertPopup( - 'You can\'t create new nodes in the main view' - ); - } - return status; - }, - - /** - * Triggers refresh current page - */ - refreshCurrentPage: function App_refreshCurrentPage(refresh) { - refresh = refresh || false; - if (this.currentPath === 'root') { - this.ui.toggleInfoPopup(); - return; - } - if (this.currentPath !== '') { - app.model.isStorageExists(this.currentPath, - app.displayFolder.bind(app, app.model.currentPath, refresh), - function () { - app.ui.popupHardClose(); - app.displayStorages(); - setTimeout( - function () { - app.ui.alertPopup( - 'Path "' + - app.model.currentPath + - '" does no longer exist' - ); - }, - 200 - ); - }); - } else { - this.displayStorages(); - } - }, - - /** - * Deletes nodes with specified paths - * @param {string[]} nodes nodePaths - */ - deleteNodes: function App_deleteNodes(nodes) { - this.model.deleteNodes( - nodes, - this.currentDirHandle, - this.ui.removeNodeFromList.bind(this.ui) - ); - }, - - /** - * @param {string[]} paths filepaths - * @param {number} mode clipboard mode - */ - saveToClipboard: function App_saveToClipboard(paths, mode) { - var clipboardLength = this.clipboard.add(paths); - - if (clipboardLength > 0) { - this.clipboard.setMode(mode); - app.ui.alertPopup('Data saved in clipboard'); - this.ui.clearTabbars(); - } else { - app.ui.alertPopup( - 'Error occured. Data has not been saved in clipboard' - ); - } - - this.ui.refreshPasteActionBtn(this.clipboard.isEmpty()); - }, - - /** - * Paste nodes from clipboard to current dir - */ - pasteClipboard: function App_pasteClipboard() { - var clipboardData = this.clipboard.get(); - - if (clipboardData.length === 0) { - app.ui.alertPopup('Clipboard is empty'); - return false; - } - - if (this.clipboard.getMode() === this.clipboard.COPY_MODE_ID) { - this.model.copyNodes( - this.currentDirHandle, - clipboardData, - this.currentPath, - this.onPasteClipboardSuccess.bind(this) - ); - } else { - this.model.moveNodes( - this.currentDirHandle, - clipboardData, - this.currentPath, - this.onPasteClipboardSuccess.bind(this) - ); - } - - this.ui.refreshPasteActionBtn(this.clipboard.isEmpty()); - - return true; - }, - - emptyClipboard: function App_emptyClipboard() { - return this.clipboard.get().length === 0; - }, - - /** - * Handler for paste clipboard success - */ - onPasteClipboardSuccess: function App_onPasteClipboardSuccess() { - this.clipboard.clear(); - this.refreshCurrentPage(); - }, - - /** - * App exit - */ - exit: function App_exit() { - tizen.application.getCurrentApplication().exit(); - } - }; + 'use strict'; + + /** + * Creates a new application object + * + * @class Application + * @constructor + */ + App = function App() { + }; + + 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.systemIO.js', + 'js/app.helpers.js', + 'js/app.clipboard.js' + ], + + /** + * @type Model + */ + model: null, + + /** + * @type Ui + */ + ui: null, + + /** + * @type Config + */ + config: null, + + /** + * @type SystemIO + */ + systemIO: null, + + /** + * @type Helpers + */ + helpers: null, + + /** + * @type {string} + */ + currentPath: 'root', + + /** + * + */ + currentDirHandle: null, + + /** + * @type {Clipboard} + */ + clipboard: null, + + /** + * Initialization + */ + init: function App_init() { + this.config = new Config(); + this.model = new Model(); + this.ui = new Ui(); + this.helpers = new Helpers(); + this.clipboard = new Clipboard(); + + this.initUi(); + }, + + /** + * UI initialization + */ + initUi: function App_initUi() { + this.ui.init(this.model.getInternalStorages()); + }, + + /** + * Displays media storages + */ + displayStorages: function App_displayStorages() { + this.currentPath = ''; + if (!this.ui.editMode) { + this.ui.scrollContentTo(0); + } + this.ui.displayStorages(this.model.getInternalStorages()); + }, + + /** + * Displays specified folder + * @param {string} path + * @param {bool} [refresh=false] + */ + displayFolder: function App_displayFolder(path, refresh) { + var self = this; + + refresh = refresh || false; + + // get folder data and push into rendering method + this.model.getFolderData(path, function (dir, nodes) { + // on success + + // update current path + self.currentPath = path; + + // update current dir handle + self.currentDirHandle = dir; + + // display folder UI + if (refresh === undefined) { + self.ui.scrollContentTo(0); + } + self.ui.displayFolder(path, nodes, refresh); + }); + }, + + /** + * Opens specified file + * @params {string} uri File URI + */ + openFile: function App_openFile(uri, fullUri) { + var ext = this.helpers.getFileExtension(uri), + mime = this.helpers.resolveMimeType(ext); + + if (mime !== '') { + this.model.openFile(fullUri, mime); + } else { + console.error('Unsupported mime type for extension ' + ext); + } + }, + + /** + * Displays parent location + */ + goLevelUp: function App_goLevelUp() { + // split current path and get proper path for parent location + var newPath = this.currentPath.split('/').slice(0, -1).join('/'); + + if (newPath !== '') { + this.displayFolder(newPath); + } else { + this.displayStorages(); + } + }, + + /** + * creates new dir in currently viewed dir + * @param {string} dirName + * @return {boolean} return status + */ + createDir: function App_createDir(dirName, callback) { + var status = true; + if (this.currentDirPath !== '') { + try { + this.currentDirHandle.createDirectory(dirName); + } catch (e) { + status = false; + app.ui.alertPopup(e.message, callback); + } + this.refreshCurrentPage(); + } else { + status = false; + app.ui.alertPopup("You can't create new nodes in the main view"); + } + return status; + }, + + /** + * Triggers refresh current page + */ + refreshCurrentPage: function App_refreshCurrentPage(refresh) { + refresh = refresh || false; + if (this.currentPath === 'root') { + return; + } + if (this.currentPath !== '') { + app.model.isStorageExists(this.currentPath, + app.displayFolder.bind(app, app.model.currentPath, refresh), + function () { + $.mobile.popup.active && $.mobile.popup.active.close(); + app.displayStorages(); + setTimeout( + function(){ + app.ui.alertPopup( + 'Path "' + app.model.currentPath + '" does no longer exist' + ); + }, + 200 + ); + }); + } else { + this.displayStorages(); + } + }, + + /** + * Deletes nodes with specified paths + * @param {string[]} nodes nodePaths + */ + deleteNodes: function App_deleteNodes(nodes) { + this.model.deleteNodes(nodes, this.currentDirHandle, this.ui.removeNodeFromList.bind(this.ui)); + }, + + /** + * @param {string[]} paths filepaths + * @param {number} mode clipboard mode + */ + saveToClipboard: function App_saveToClipboard(paths, mode) { + var clipboardLength = this.clipboard.add(paths); + + if (clipboardLength > 0) { + this.clipboard.setMode(mode); + app.ui.alertPopup('Data saved in clipboard'); + this.ui.clearTabbars(); + } else { + app.ui.alertPopup('Error occured. Data has not been saved in clipboard'); + } + + this.ui.refreshPasteActionBtn(this.clipboard.isEmpty()); + }, + + /** + * Paste nodes from clipboard to current dir + */ + pasteClipboard: function App_pasteClipboard() { + var clipboardData = this.clipboard.get(); + + if (clipboardData.length === 0) { + app.ui.alertPopup('Clipboard is empty'); + return false; + } + + if (this.clipboard.getMode() === this.clipboard.COPY_MODE_ID) { + this.model.copyNodes(this.currentDirHandle, clipboardData, this.currentPath, this.onPasteClipboardSuccess.bind(this)); + } else { + this.model.moveNodes(this.currentDirHandle, clipboardData, this.currentPath, this.onPasteClipboardSuccess.bind(this)); + } + + this.ui.refreshPasteActionBtn(this.clipboard.isEmpty()); + + return true; + }, + + emptyClipboard: function App_emptyClipboard() { + return this.clipboard.get().length === 0; + }, + + /** + * Handler for paste clipboard success + */ + onPasteClipboardSuccess: function App_onPasteClipboardSuccess() { + this.clipboard.clear(); + this.refreshCurrentPage(); + }, + + /** + * App exit + */ + exit: function App_exit() { + tizen.application.getCurrentApplication().exit(); + } + }; }()); diff --git a/project/js/app.model.js b/project/js/app.model.js index 6d179fe..7b2b4a1 100644 --- a/project/js/app.model.js +++ b/project/js/app.model.js @@ -1,19 +1,3 @@ -/* - * 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, SystemIO, $, app */ @@ -21,436 +5,348 @@ * @class Model */ function Model() { - 'use strict'; - this.init(); + 'use strict'; + this.init(); } (function () { // strict mode wrapper - 'use strict'; - Model.prototype = { - - /** - * file open unlock flag - * @type {boolean} - */ - openFileUnLocked: true, - - /** - * @type SystemIO - */ - systemIO: null, - - /** - * @type Array - */ - storages: [{label: 'root', type: 'INTERNAL'}], - - /** - * @type String - */ - currentPath: '', - - /** - * API module initialisation - */ - init: function Model_init() { - this.systemIO = new SystemIO(); - }, - - /** - * @returns {FileSystemStorage[]} storages - */ - getInternalStorages: function Model_getInternalStorages() { - return this.storages; - }, - - /** - * Saves storages - * @param {function} onSuccess callback - */ - loadInternalStorages: function Model_loadInternalStorages(onSuccess) { - var self = this; - - this.systemIO.getStorages('INTERNAL', function (storages) { - self.storages = storages; - if (typeof onSuccess === 'function') { - onSuccess(); - } - }, 'internal0'); - }, - - /** - * Returns folder data - * @param {string} path Node path - * @param {function} onSuccess Success callback - * @param {function} onError Error callback - */ - getFolderData: function Model_getFolderData(path, onSuccess, onError) { - var self = this, - onOpenSuccess = function (dir) { - dir.listFiles( - function (files) { - self.currentPath = dir.fullPath; - onSuccess(dir, files); - }, - function (e) { - console.error( - 'Model_getFolderData listFiles error', - e - ); - } - ); - }, - onOpenError = function (e) { - console.error('Model_getFolderData openDir error', e); - }; - - this.systemIO.openDir(path, onOpenSuccess, onOpenError); - }, - - isStorageExists: function (nodeName, success, error) { - tizen.filesystem.resolve(nodeName, success, error); - }, - - /** - * Launch a service to open the file - * @param {string} fullUri ext - * @param {string} mime uri - */ - openFile: function Model_openFile(fullUri) { - if (this.openFileUnLocked) { - var self = this, serviceReplyCB = { - onsuccess: function (reply) { - self.openFileUnLocked = true; - }, - onfailure: function () { - self.openFileUnLocked = true; - console.error('Launch service failed'); - } - }; - this.openFileUnLocked = false; - try { - console.log('Launching view for file "' + fullUri + '"'); - tizen.application.launchAppControl( - new tizen.ApplicationControl( - 'http://tizen.org/appcontrol/operation/view', - fullUri - ), - null, - function () { - setTimeout(function () { - self.openFileUnLocked = true; - }, 500); - }, - function (e) { - self.openFileUnLocked = true; - console.error( - 'Service launch failed. Exception message:' + - e.message - ); - }, - serviceReplyCB - ); - } catch (e) { - self.openFileUnLocked = true; - console.error('openFile failed', e); - } - } - }, - - refreshContent: function (path, successCallback, mode) { - successCallback = successCallback || null; - mode = mode || 'copy'; - var isDir = true, - onResolveSuccess; - onResolveSuccess = function () {}; - - tizen.filesystem.resolve(path, function (file) { - if (file.isFile) { - tizen.content.scanFile(path, successCallback); - } else { - successCallback(); - } - }, null); - }, - - resolveAndRefresh: function (path, successCallback, mode) { - var self = this; - tizen.filesystem.resolve(path, function (file) { - self.refreshContent(file.toURI(), successCallback); - }, null); - }, - - /** - * @param {File[]} nodes Collection of node objects - * @param {File} dir Directory handle - * @param {function} onSuccess - * @param {function} onError - */ - deleteNodes: function Model_deleteNodes( - nodes, - dir, - onSuccess, - onError - ) { - var len = nodes.length, - self = this, - onDeleteNodeSuccess = function (file) { - try { - app.clipboard.removeRecursively(file.fullPath); - app.ui.refreshPasteActionBtn(); - if (onSuccess instanceof Function) { - onSuccess(file.fullPath); - } - } catch (e) { - console.error(e); - } - }, - onDeleteNodeError = function (e) { - if (typeof onError === 'function') { - onError(); - } - }, - i, - remove = function (file, success, failure) { - var parent = file.parent, fullPath = file.fullPath, - removeSuccess = function () { - if (success instanceof Function) { - success(file); - } - }, - removeFailure = function (error) { - if (failure instanceof Function) { - failure(error, file); - } - }; - - if (file.isFile) { - parent.deleteFile( - fullPath, - function () { - tizen.content.scanFile( - file.toURI(), - removeSuccess, - removeFailure - ); - }, - removeFailure - ); - } else { - file.listFiles( - function (files) { - var len = files.length, - index = len - 1, - counter = 0, - removeEmptyDir = function () { - parent.deleteDirectory( - fullPath, - false, - removeSuccess, - removeFailure - ); - }; - - if (len > 0) { - while (index >= 0) { - remove( - files[index], - function () { - counter += 1; - if (counter === len) { - removeEmptyDir(); - } - }, - removeFailure - ); - index -= 1; - } - } else { - removeEmptyDir(); - } - }, - removeFailure - ); - } - }; - - for (i = 0; i < len; i = i + 1) { - tizen.filesystem.resolve( - nodes[i].uri, - function (file) { - remove(file, onDeleteNodeSuccess, onDeleteNodeError); - }.bind(this), - null - ); - } - }, - - /** - * Copy specified files to destination path - * Overwrites existing files - * - * @param {File} dir Directory handle - * @param {string[]} paths Array with absolute virtual file paths - * @param {string} destinationPath - * @param {function} onSuccess callback - */ - copyNodes: function Model_copyNodes( - dir, - paths, - destinationPath, - onSuccess - ) { - var len = paths.length, self = this, - scaned = 0, - scanSuccess = function () { - scaned += 1; - if (scaned === len) { - onSuccess(); - } - }, - onCopyNodeSuccess = function (file) { - self.refreshContent(file.toURI(), scanSuccess, 'copy'); - }, - onCopyNodeFailure = function (e) { - console.error(e); - setTimeout(function () { - app.refreshCurrentPage(); - app.ui.alertPopup('Copying error'); - }, 200); - }, - i, - sourceName, - decision; - - this.systemIO.getFilesList(dir, function (filesList) { - for (i = 0; i < len; i = i + 1) { - if (destinationPath.indexOf(paths[i]) !== -1) { - setTimeout(function () { - app.ui.alertPopup('Copying error'); - }, 200); - return; - } - } - - for (i = 0; i < len; i = i + 1) { - decision = true; - sourceName = paths[i].split('/').pop(); - sourceName = app.helpers.getCopyFileName( - sourceName, - filesList - ); - - try { - dir.copyTo( - paths[i], - destinationPath + '/' + sourceName, - true, - onCopyNodeSuccess, - onCopyNodeFailure - ); - } catch (e) { - console.error(e); - } - } - }); - }, - - /** - * Move specified files to destination path - * Overwrites existing files - * - * @param {File} dir Directory handle - * @param {string[]} paths Array with absolute virtual file paths - * @param {string} destinationPath - * @param {function} onSuccess callback - */ - moveNodes: function Model_moveNodes( - dir, - paths, - destinationPath, - onSuccess - ) { - var len = paths.length, self = this, - scaned = 0, - toScan = len * 2, - illegalMove = false, - scanSuccess = function () { - scaned += 1; - if (scaned === toScan) { - onSuccess(); - } - }, - onMoveNodeSuccess = function (oldfile, file) { - self.refreshContent(oldfile.toURI(), scanSuccess, 'delete'); - self.refreshContent(file.toURI(), scanSuccess, 'copy'); - }, - onMoveNodeFailure = function () { - app.ui.alertPopup('Moving error'); - }, - i, - sourceName, - decision; - - len -= 1; - while (len >= 0) { - if (destinationPath.match(paths[len])) { - illegalMove = true; - break; - } - len -= 1; - } - - len = paths.length; - - if (illegalMove) { - setTimeout(function () { - app.ui.alertPopup('Can not move catalog into itself.'); - }, 200); - return; - } - - this.systemIO.getFilesList(dir, function (filesList) { - var resolveSuccess = function ( - path, - destinationPath, - sourceName, - oldfile - ) { - dir.moveTo( - path, - destinationPath + '/' + sourceName, - false, - onMoveNodeSuccess.bind(self, oldfile), - onMoveNodeFailure - ); - }; - for (i = 0; i < len; i = i + 1) { - if (destinationPath.indexOf(paths[i]) !== -1) { - app.ui.alertPopup('Moving error'); - return; - } - } - - for (i = 0; i < len; i = i + 1) { - decision = true; - sourceName = paths[i].split('/').pop(); - try { - tizen.filesystem.resolve( - paths[i], - resolveSuccess.bind( - self, - paths[i], - destinationPath, - sourceName - ), - onMoveNodeFailure - ); - } catch (e) { - console.error(e); - } - } - }); - } - }; + 'use strict'; + Model.prototype = { + + /** + * file open unlock flag + * @type {boolean} + */ + openFileUnLocked: true, + + /** + * @type SystemIO + */ + systemIO: null, + + /** + * @type Array + */ + storages: [{label: 'root', type: 'INTERNAL'}], + + /** + * @type String + */ + currentPath: '', + + /** + * API module initialisation + */ + init: function Model_init() { + this.systemIO = new SystemIO(); + }, + + /** + * @returns {FileSystemStorage[]} storages + */ + getInternalStorages: function Model_getInternalStorages() { + return this.storages; + }, + + /** + * Saves storages + * @param {function} onSuccess callback + */ + loadInternalStorages: function Model_loadInternalStorages(onSuccess) { + var self = this; + + this.systemIO.getStorages('INTERNAL', function (storages) { + self.storages = storages; + if (typeof onSuccess === 'function') { + onSuccess(); + } + }, 'internal0'); + }, + + /** + * Returns folder data + * @param {string} path Node path + * @param {function} onSuccess Success callback + * @param {function} onError Error callback + */ + getFolderData: function Model_getFolderData(path, onSuccess, onError) { + var self = this, + onOpenSuccess = function (dir) { + dir.listFiles( + function (files) { + self.currentPath = dir.fullPath; + onSuccess(dir, files); + }, + function (e) { + console.error('Model_getFolderData listFiles error', e); + } + ); + }, + onOpenError = function (e) { + console.error('Model_getFolderData openDir error', e); + }; + + this.systemIO.openDir(path, onOpenSuccess, onOpenError); + }, + + isStorageExists: function (nodeName, success, error) { + tizen.filesystem.resolve(nodeName, success, error); + }, + + /** + * Launch a service to open the file + * @param {string} fullUri ext + * @param {string} mime uri + */ + openFile: function Model_openFile(fullUri, mime) { + if (this.openFileUnLocked) { + var self = this, serviceReplyCB = { + onsuccess: function (reply) { + self.openFileUnLocked = true; + }, + onfailure: function () { + self.openFileUnLocked = true; + console.error('Launch service failed'); + } + }; + this.openFileUnLocked = false; + try { + console.log('Launching view for file "' + fullUri + '" (mime="' + mime + '")...'); + tizen.application.launchAppControl(new tizen.ApplicationControl( + 'http://tizen.org/appcontrol/operation/view', + fullUri, + mime + ), + null, + function () { + setTimeout(function () { + self.openFileUnLocked = true; + }, 500); + }, + function (e) { + self.openFileUnLocked = true; + console.error('Service launch failed. Exception message:' + e.message); + }, + serviceReplyCB + ); + } catch (e) { + self.openFileUnLocked = true; + console.error('openFile failed', e); + } + } + }, + + refreshContent: function (path, successCallback, mode) { + successCallback = successCallback || null; + mode = mode || 'copy'; + var isDir = true, + onResolveSuccess; + if(app.helpers.getFileExtension(path) !== '') { + isDir = false; + } + onResolveSuccess = function () {}; + + if(isDir) { + switch (mode) { + case 'delete': + tizen.filesystem.resolve(path, onResolveSuccess, successCallback); + break; + default: + tizen.filesystem.resolve(path, successCallback); + } + } else { + tizen.content.scanFile(path, successCallback); + } + }, + + resolveAndRefresh: function (path, successCallback, mode) { + var self = this; + tizen.filesystem.resolve(path, function (file) { + self.refreshContent(file.toURI(), successCallback); + }, null); + }, + + /** + * @param {File[]} nodes Collection of node objects + * @param {File} dir Directory handle + * @param {function} onSuccess + * @param {function} onError + */ + deleteNodes: function Model_deleteNodes(nodes, dir, onSuccess, onError) { + var len = nodes.length, + self = this, + onDeleteNodeSuccess = function (node, isDir, fileobject) { + try { + this.refreshContent(fileobject.toURI(), function () { + app.clipboard.removeRecursively(node.uri); + app.ui.refreshPasteActionBtn(); + if (typeof onSuccess === 'function') { + onSuccess(node.id); + } + }, 'delete'); + } catch (e) { + console.error(e); + } + }, + onDeleteNodeError = function (e) { + console.error('Folder delete error', e); + if (typeof onError === 'function') { + onError(); + } + }, + i; + + for (i = 0; i < len; i = i + 1) { + tizen.filesystem.resolve( + nodes[i].uri, + function (node, fileobject) { + if (node.folder) { + dir.deleteDirectory( + node.uri, + true, + onDeleteNodeSuccess.bind(this, node, true, fileobject), + onDeleteNodeError + ); + } else { + dir.deleteFile( + node.uri, + onDeleteNodeSuccess.bind(this, node, false, fileobject), + onDeleteNodeError + ); + } + }.bind(this, nodes[i]), + null + ); + } + }, + + /** + * Copy specified files to destination path + * Overwrites existing files + * + * @param {File} dir Directory handle + * @param {string[]} paths Array with absolute virtual file paths + * @param {string} destinationPath + * @param {function} onSuccess callback + */ + copyNodes: function Model_copyNodes(dir, paths, destinationPath, onSuccess) { + var len = paths.length, self = this, + scaned = 0, + scanSuccess = function () { + scaned += 1; + if (scaned === len) { + onSuccess(); + } + }, + onCopyNodeSuccess = function (file) { + self.refreshContent(file.toURI(), scanSuccess, 'copy'); + }, + onCopyNodeFailure = function (e) { + console.error(e); + setTimeout(function () { + app.ui.alertPopup('Copying error'); + }, 200); + }, + i, + sourceName, + decision; + + this.systemIO.getFilesList(dir, function (filesList) { + for (i = 0; i < len; i = i + 1) { + if (destinationPath.indexOf(paths[i]) !== -1) { + setTimeout(function () { + app.ui.alertPopup('Copying error'); + }, 200); + return; + } + } + + for (i = 0; i < len; i = i + 1) { + decision = true; + sourceName = paths[i].split('/').pop(); + sourceName = app.helpers.getCopyFileName(sourceName, filesList); + + try { + dir.copyTo(paths[i], destinationPath + '/' + sourceName, true, onCopyNodeSuccess, onCopyNodeFailure); + self.resolveAndRefresh(paths[i]); + } catch (e) { + console.error(e); + } + } + }); + }, + + /** + * Move specified files to destination path + * Overwrites existing files + * + * @param {File} dir Directory handle + * @param {string[]} paths Array with absolute virtual file paths + * @param {string} destinationPath + * @param {function} onSuccess callback + */ + moveNodes: function Model_moveNodes(dir, paths, destinationPath, onSuccess) { + var len = paths.length, self = this, + scaned = 0, + toScan = len * 2, + illegalMove = false, + scanSuccess = function () { + scaned += 1; + if (scaned === toScan) { + onSuccess(); + } + }, + onMoveNodeSuccess = function (oldfile, file) { + self.refreshContent(oldfile.toURI(), scanSuccess, 'delete'); + self.refreshContent(file.toURI(), scanSuccess, 'copy'); + }, + onMoveNodeFailure = function () { + app.ui.alertPopup('Moving error'); + }, + i, + sourceName, + decision; + + while (len--) { + if (destinationPath.match(paths[len])) { + illegalMove = true; + break; + } + } + + len = paths.length; + + if (illegalMove) { + setTimeout(function () { + app.ui.alertPopup('Can not move catalog into itself.'); + }, 200); + return; + } + + this.systemIO.getFilesList(dir, function (filesList) { + for (i = 0; i < len; i = i + 1) { + if (destinationPath.indexOf(paths[i]) !== -1) { + app.ui.alertPopup('Moving error'); + return; + } + } + + for (i = 0; i < len; i = i + 1) { + decision = true; + sourceName = paths[i].split('/').pop(); + try { + tizen.filesystem.resolve( + paths[i], + function (path, destinationPath, sourceName, oldfile) { + dir.moveTo(path, destinationPath + '/' + sourceName, false, onMoveNodeSuccess.bind(self, oldfile), onMoveNodeFailure); + }.bind(self, paths[i], destinationPath, sourceName), + null + ); + } catch (e) { + console.error(e); + } + } + }); + } + }; }()); diff --git a/project/js/app.systemIO.js b/project/js/app.systemIO.js index 4aef763..4c70377 100644 --- a/project/js/app.systemIO.js +++ b/project/js/app.systemIO.js @@ -1,19 +1,3 @@ -/* - * 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, localStorage */ @@ -21,318 +5,257 @@ * @class SystemIO */ function SystemIO() { - 'use strict'; + 'use strict'; } (function () { // strict mode wrapper - 'use strict'; - SystemIO.prototype = { - /** - * Creates new empty file in specified location - * - * @param {File} directoryHandle - * @param {string} fileName - */ - createFile: function SystemIO_createFile(directoryHandle, fileName) { + 'use strict'; + SystemIO.prototype = { + /** + * Creates new empty file in specified location + * + * @param {File} directoryHandle + * @param {string} fileName + */ + createFile: function SystemIO_createFile(directoryHandle, fileName) { - try { - return directoryHandle.createFile(fileName); - } catch (e) { - console.error('SystemIO_createFile error:' + e.message); - return false; - } - }, + try { + return directoryHandle.createFile(fileName); + } catch (e) { + console.error('SystemIO_createFile error:' + e.message); + return false; + } + }, - /** - * Writes content to file stream - * - * @param {File} fileHandle file handler - * @param {string} fileContent file content - * @param {function} onSuccess on success callback - * @param {function} onError on error callback - * @param {string} content encoding - */ - writeFile: function SystemIO_writeFile( - fileHandle, - fileContent, - onSuccess, - onError, - contentEncoding - ) { - onError = onError || function () {}; + /** + * Writes content to file stream + * + * @param {File} fileHandle file handler + * @param {string} fileContent file content + * @param {function} onSuccess on success callback + * @param {function} onError on error callback + * @param {string} content encoding + */ + writeFile: function SystemIO_writeFile(fileHandle, fileContent, onSuccess, onError, contentEncoding) { + onError = onError || function () {}; - fileHandle.openStream('w', function (fileStream) { - if (contentEncoding === 'base64') { - fileStream.writeBase64(fileContent); - } else { - fileStream.write(fileContent); - } + fileHandle.openStream('w', function (fileStream) { + if (contentEncoding === 'base64') { + fileStream.writeBase64(fileContent); + } else { + fileStream.write(fileContent); + } - fileStream.close(); + fileStream.close(); - // launch onSuccess callback - if (typeof onSuccess === 'function') { - onSuccess(); - } - }, onError, 'UTF-8'); - }, + // launch onSuccess callback + if (typeof onSuccess === 'function') { + onSuccess(); + } + }, onError, 'UTF-8'); + }, - /** - * Opens specified location - * - * @param {string} directory path - * @param {function} on success callback - * @param {function} on error callback - * @param {string} mode - */ - openDir: function SystemIO_openDir( - directoryPath, - onSuccess, - onError, - openMode - ) { - openMode = openMode || 'rw'; - onSuccess = onSuccess || function () {}; + /** + * Opens specified location + * + * @param {string} directory path + * @param {function} on success callback + * @param {function} on error callback + * @param {string} mode + */ + openDir: function SystemIO_openDir(directoryPath, onSuccess, onError, openMode) { + openMode = openMode || 'rw'; + onSuccess = onSuccess || function () {}; - try { - tizen.filesystem.resolve( - directoryPath, - onSuccess, - onError, - openMode - ); - } catch (e) { - } - }, + try { + tizen.filesystem.resolve(directoryPath, onSuccess, onError, openMode); + } catch (e) { + } + }, - /** - * Parse specified filepath and returns data parts - * - * @param {string} filePath - * @returns {array} - */ - getPathData: function SystemIO_getPathData(filePath) { - var path = { - originalPath: filePath, - fileName: '', - dirName: '' - }, - splittedPath = filePath.split('/'); + /** + * Parse specified filepath and returns data parts + * + * @param {string} filePath + * @returns {array} + */ + getPathData: function SystemIO_getPathData(filePath) { + var path = { + originalPath: filePath, + fileName: '', + dirName: '' + }, + splittedPath = filePath.split('/'); - path.fileName = splittedPath.pop(); - path.dirName = splittedPath.join('/') || '/'; + path.fileName = splittedPath.pop(); + path.dirName = splittedPath.join('/') || '/'; - return path; - }, + return path; + }, - /** - * Save specified content to file - * - * @param {string} file path - * @param {string} file content - * @param {string} file encoding - */ - saveFileContent: function SystemIO_saveFileContent( - filePath, - fileContent, - onSaveSuccess, - fileEncoding - ) { - var pathData = this.getPathData(filePath), - self = this, - fileHandle; + /** + * Save specified content to file + * + * @param {string} file path + * @param {string} file content + * @param {string} file encoding + */ + saveFileContent: function SystemIO_saveFileContent(filePath, fileContent, onSaveSuccess, fileEncoding) { + var pathData = this.getPathData(filePath), + self = this, + fileHandle; - function onOpenDirSuccess(dir) { - // create new file - fileHandle = self.createFile(dir, pathData.fileName); - if (fileHandle !== false) { - // save data into this file - self.writeFile( - fileHandle, - fileContent, - onSaveSuccess, - false, - fileEncoding - ); - } - } + function onOpenDirSuccess(dir) { + // create new file + fileHandle = self.createFile(dir, pathData.fileName); + if (fileHandle !== false) { + // save data into this file + self.writeFile(fileHandle, fileContent, onSaveSuccess, false, fileEncoding); + } + } - // open directory - this.openDir(pathData.dirName, onOpenDirSuccess); - }, + // open directory + this.openDir(pathData.dirName, onOpenDirSuccess); + }, - /** - * Deletes node with specified path - * - * @param {string} node path - * @param {function} success callback - */ - deleteNode: function SystemIO_deleteNode(nodePath, onSuccess) { - var pathData = this.getPathData(nodePath), - self = this; + /** + * Deletes node with specified path + * + * @param {string} node path + * @param {function} success callback + */ + deleteNode: function SystemIO_deleteNode(nodePath, onSuccess) { + var pathData = this.getPathData(nodePath), + self = this; - function onDeleteSuccess() { - onSuccess(); - } + function onDeleteSuccess() { + onSuccess(); + } - function onDeleteError(e) { - console.error('SystemIO_deleteNode:_onDeleteError', e); - } + function onDeleteError(e) { + console.error('SystemIO_deleteNode:_onDeleteError', e); + } - function onOpenDirSuccess(dir) { - var onListFiles = function (files) { - if (files.length > 0) { - // file exists; - if (files[0].isDirectory) { - self.deleteDir( - dir, - files[0].fullPath, - onDeleteSuccess, - onDeleteError - ); - } else { - self.deleteFile( - dir, - files[0].fullPath, - onDeleteSuccess, - onDeleteError - ); - } - } else { - onDeleteSuccess(); - } - }; + function onOpenDirSuccess(dir) { + var onListFiles = function (files) { + if (files.length > 0) { + // file exists; + if (files[0].isDirectory) { + self.deleteDir(dir, files[0].fullPath, onDeleteSuccess, onDeleteError); + } else { + self.deleteFile(dir, files[0].fullPath, onDeleteSuccess, onDeleteError); + } + } else { + onDeleteSuccess(); + } + }; - // check file exists; - dir.listFiles(onListFiles, function (e) { - console.error(e); - }, { - name: pathData.fileName - }); - } + // check file exists; + dir.listFiles(onListFiles, function (e) { + console.error(e); + }, { + name: pathData.fileName + }); + } - this.openDir(pathData.dirName, onOpenDirSuccess, function (e) { - console.error('openDir error:' + e.message); - }); - }, + this.openDir(pathData.dirName, onOpenDirSuccess, function (e) { + console.error('openDir error:' + e.message); + }); + }, - /** - * Deletes specified file - * - * @param {File} dir - * @param {string} file path - * @param {function} delete success callback - * @param {function} delete error callback - */ - deleteFile: function SystemIO_deleteFile( - dir, - filePath, - onDeleteSuccess, - onDeleteError - ) { - try { - dir.deleteFile(filePath, onDeleteSuccess, onDeleteError); - } catch (e) { - console.error('SystemIO_deleteFile error: ' + e.message); - return false; - } - }, + /** + * Deletes specified file + * + * @param {File} dir + * @param {string} file path + * @param {function} delete success callback + * @param {function} delete error callback + */ + deleteFile: function SystemIO_deleteFile(dir, filePath, onDeleteSuccess, onDeleteError) { + try { + dir.deleteFile(filePath, onDeleteSuccess, onDeleteError); + } catch (e) { + console.error('SystemIO_deleteFile error: ' + e.message); + return false; + } + }, - /** - * Deletes specified directory - * - * @param {File} dir - * @param {string} dirPath dir path - * @param {function} onDeleteSuccess delete success callback - * @param {function} onDeleteError delete error callback - * @returns {boolean} - */ - deleteDir: function SystemIO_deleteDir( - dir, - dirPath, - onDeleteSuccess, - onDeleteError - ) { - try { - dir.deleteDirectory( - dirPath, - false, - onDeleteSuccess, - onDeleteError - ); - } catch (e) { - console.error('SystemIO_deleteDir error:' + e.message); - return false; - } + /** + * Deletes specified directory + * + * @param {File} dir + * @param {string} dirPath dir path + * @param {function} onDeleteSuccess delete success callback + * @param {function} onDeleteError delete error callback + * @returns {boolean} + */ + deleteDir: function SystemIO_deleteDir(dir, dirPath, onDeleteSuccess, onDeleteError) { + try { + dir.deleteDirectory(dirPath, false, onDeleteSuccess, onDeleteError); + } catch (e) { + console.error('SystemIO_deleteDir error:' + e.message); + return false; + } - return true; - }, + return true; + }, - /** - * @param {string} type storage type - * @param {function} onSuccess on success callback - * @param {string} excluded Excluded storage - */ - getStorages: function SystemIO_getStorages(type, onSuccess, excluded) { - try { - tizen.filesystem.listStorages(function (storages) { - var tmp = [], - len = storages.length, - i; + /** + * @param {string} type storage type + * @param {function} onSuccess on success callback + * @param {string} excluded Excluded storage + */ + getStorages: function SystemIO_getStorages(type, onSuccess, excluded) { + try { + tizen.filesystem.listStorages(function (storages) { + var tmp = [], + len = storages.length, + i; - if (type !== undefined) { - for (i = 0; i < len; i += 1) { - if (storages[i].label !== excluded) { - if ( - storages[i].type === 0 || - storages[i].type === type - ) { - tmp.push(storages[i]); - } - } - } - } else { - tmp = storages; - } + if (type !== undefined) { + for (i = 0; i < len; i += 1) { + if (storages[i].label !== excluded) { + if (storages[i].type === 0 || storages[i].type === type) { + tmp.push(storages[i]); + } + } + } + } else { + tmp = storages; + } - if (typeof onSuccess === 'function') { - onSuccess(tmp); - } - }); - } catch (e) { - console.error('SystemIO_getStorages error:' + e.message); - } - }, + if (typeof onSuccess === 'function') { + onSuccess(tmp); + } + }); + } catch (e) { + console.error('SystemIO_getStorages error:' + e.message); + } + }, - getFilesList: function SystemIO_getFilesList(dir, onSuccess) { - try { - dir.listFiles( - function (files) { - var tmp = [], - len = files.length, - i; + getFilesList: function SystemIO_getFilesList(dir, onSuccess) { + try { + dir.listFiles( + function (files) { + var tmp = [], + len = files.length, + i; - for (i = 0; i < len; i += 1) { - tmp.push({ - name: files[i].name, - isDirectory: files[i].isDirectory - }); - } + for (i = 0; i < len; i += 1) { + tmp.push(files[i].name); + } - if (typeof onSuccess === 'function') { - onSuccess(tmp); - } - }, - function (e) { - console.error( - 'SystemIO_getFilesList dir.listFiles() error:', - e - ); - } - ); - } catch (e) { - console.error('SystemIO_getFilesList error:', e.message); - } - } - }; -}()); + if (typeof onSuccess === 'function') { + onSuccess(tmp); + } + }, + function (e) { + console.error('SystemIO_getFilesList dir.listFiles() error:', e); + } + ); + } catch (e) { + console.error('SystemIO_getFilesList error:', e.message); + } + } + }; +}()); \ No newline at end of file diff --git a/project/js/app.ui.js b/project/js/app.ui.js index 9d94607..b6b30e1 100644 --- a/project/js/app.ui.js +++ b/project/js/app.ui.js @@ -1,1109 +1,961 @@ -/* - * 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 window, tizen, $, app, TemplateManager, Helpers */ +/*global $, app, TemplateManager, Helpers */ /** * @class Ui */ function Ui() { - 'use strict'; + 'use strict'; } (function () { // strict mode wrapper - 'use strict'; - Ui.prototype = { - /** - * root mode - * @type {boolean} - */ - root: true, - - /** - * locked folders - * @type {array} - */ - lockedFolders: ['ringtones'], - - /** - * UI edit mode - * @type {boolean} - */ - editMode: false, - - /** - * @type {bool} block clicks until the page change is completed - */ - nodeTapBlock: false, - - /** - * @type {TemplateManager} - */ - templateManager: null, - - /** - * @type Helpers - */ - helpers: null, - - /** - * @type Info popup lock - */ - infoPopupVisibility: false, - - /** - * @const {number} - */ - PATH_DIV_HEIGHT: 20, - - /** - * @const {number} - */ - SELECT_ALL_HEIGHT: 32, - - /** - * @const {number} header height, set on domReady - */ - HEADER_HEIGHT: 53, - - /** - * name of row gradient class - */ - CSS_GRADIENT_CLASS: 'gradientBackground', - - /** - * Standard tabbar actions - * @type {number} - */ - STD_TABBAR_EDIT_ACTION: 0, - STD_TABBAR_MORE_ACTION: 1, - STD_TABBAR_EXIT_ACTION: 2, - - /** - * Edit tabbar actions - * @type {number} - */ - EDIT_TABBAR_DELETE_ACTION: 0, - EDIT_TABBAR_MOVE_ACTION: 1, - EDIT_TABBAR_COPY_ACTION: 2, - EDIT_TABBAR_CANCEL_ACTION: 3, - - currentHeaderHeight: null, - currentScrollPosition: null, - - /** - * UI Initialization - */ - init: function Ui_init(storages) { - this.templateManager = new TemplateManager(); - this.helpers = new Helpers(); - // Disable text selection - $.mobile.tizen.disableSelection(document); - $(document).ready(this.initDom.bind(this, storages)); - }, - - initDom: function Ui_initDom(storages) { - var self = this, - overlay = $('#overlay'), - popup = $('#infoPopup'), - windowWidth, - windowHeight, - popWidth; - - this.templateManager.loadToCache( - [ - 'main', - 'fileRow', - 'folderRow', - 'levelUpRow', - 'emptyFolder' - ], - function () { - $('#main') - .append($(self.templateManager.get('main')).children()) - .trigger('pagecreate'); - self.addEvents(); - self.displayStorages(storages); - } - ); - - windowWidth = $(window).width(); - windowHeight = $(window).height(); - - overlay.css({ - 'width': windowWidth + 'px', - 'height': windowHeight + 'px' - }); - - popWidth = windowWidth / 2 + 30; - popup.css({ - 'width': popWidth + 'px', - 'left': (windowWidth / 2 - popWidth / 2) + 'px', - 'top': (windowHeight / 2 - popup.height() / 2) + 'px' - }); - }, - - /** - * Add UI events - */ - addEvents: function Ui_addEvents() { - var self = this; - - document.addEventListener('webkitvisibilitychange', function () { - if (document.webkitVisibilityState === 'visible') { - if (self.infoPopupVisibility) { - return; - } - self.toggleInfoPopup(); - self.refreshSelectAllStatus(); - app.refreshCurrentPage(true); - } - }); - - window.addEventListener('tizenhwkey', function (e) { - var uri = $('#navbar span+span').attr('uri'); - if (e.keyName === 'back') { - if (self.infoPopupVisibility) { - return; - } else if ($.mobile.popup.active) { - $.mobile.popup.active.close(); - } else if (self.editMode === true) { - self.handleCancelEditAction(); - } else if (!uri) { - if (app.ui.root === false) { - app.ui.root = true; - $('#fileList').empty(); - app.ui.prepareFolderRow(0, 'root'); - app.currentPath = 'root'; - } else { - tizen.application.getCurrentApplication().exit(); - } - } else { - if (!app.ui.root) { - app.goLevelUp(); - } - } - } - }); - - $(window).resize(function () { - $.mobile.activePage.page('refresh'); - }); - - // touch events for all nodes - $('ul#fileList') - .on('click', 'li.levelUp', function () { - if (self.editMode === true) { - self.handleCancelEditAction(); - } - app.goLevelUp(); - }) - .on('click', 'li.node', function (e) { - e.preventDefault(); - e.stopPropagation(); - self.handleNodeClick($(this), true); - }) - .on('change', 'input[type=checkbox]', function (e) { - self.handleNodeClick($(this).closest('li.node'), false); - }) - .on('touchstart', 'li', function (event) { - $(this).addClass(self.CSS_GRADIENT_CLASS); - }) - .on('touchend touchmove', 'li', function (event) { - $(this).removeClass(self.CSS_GRADIENT_CLASS); - }); - - $('.selectAll input').on( - 'change', - this.handleSelectAllChange.bind(this) - ); - - // navbar - $('#navbar').on('click', 'span', function () { - var uri = $(this).attr('uri'); - if (uri === 'home') { - if (app.currentPath !== '') { - app.displayStorages(); - } - } else if (uri === app.model.currentPath) { - app.displayFolder(uri, true); - } else { - if (self.editMode === true) { - self.handleCancelEditAction(); - } - app.displayFolder(uri); - } - }); - - // level up - $('#levelUpBtn').on('click', function () { - if (self.editMode === true) { - self.handleCancelEditAction(); - } - app.goLevelUp(); - }); - - $('#homeBtn').on('click', app.displayStorages.bind(app)); - - // edit action - $('#editActionBtn').on('click', this.handleEditAction.bind(this)); - - // delete action - $('#deleteActionBtn').on( - 'click', - this.handleDeleteAction.bind(this) - ); - - // cancel edit - $('#cancelActionBtn').on('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - self.handleCancelEditAction(); - }); - - // copy action - $('#copyActionBtn').on('click', this.handleCopyAction.bind(this)); - - // move action - $('#moveActionBtn').on('click', this.handleMoveAction.bind(this)); - - // paste action - $('a#pasteActionBtn').on('click', function () { - if (!self.infoPopupVisibility) { - self.toggleInfoPopup(app.pasteClipboard.bind(app)); - } - $('#morePopup').popup('close'); - }); - - // remove active class - $('[data-role = "tabbar"] li > a').on('click', function () { - $(this).removeClass('ui-focus, ui-btn-active'); - }); - // exit - $('.ui-myExit').on('click', app.exit); - - // add folder popup actions - $('#addFolderPopup').on('popupafterclose', function () { - // clear input value - $('#newFolderName').val('New folder'); - }); - - $('#newFolderName').on('focus', function () { - if ($(this).attr('value') === 'New folder') { - $(this).attr('value', ''); - } - }); - - $('#saveNewFolder').on('click', this.saveNewFolder.bind(this)); - $('#newFolderForm').on('submit', this.saveNewFolder.bind(this)); - }, - - saveNewFolder: function Ui_saveNewFolder(e) { - var folderName = $('#newFolderName').val(), status = true, - open = function () { - $('#addFolderPopup').popup('open', { - positionTo: 'window' - }); - }, - self = this, - buttons = $('#addFolderPopup .ui-popup-button-bg a'), - aPopup; - e.preventDefault(); - e.stopPropagation(); - buttons.addClass('ui-disabled'); - $('#addFolderPopup').one('popupafterclose', function () { - if (folderName === '') { - self.alertPopup('Empty folder name', open); - status = false; - } else if (folderName.match(/[\*\.\/\\\?\"\'\:<>|]/)) { - self.alertPopup('The following special characters ' - + 'are not allowed: *./\\?:<>|\'"', open); - status = false; - } else { - status = app.createDir(folderName, open); - } - buttons.removeClass('ui-disabled'); - }); - aPopup = $.mobile.popup.active; - if ( - aPopup && aPopup.element.attr('id') === 'addFolderPopup' - ) { - aPopup.close(); - } - return status; - }, - - toggleInfoPopup: function (callback) { - var overlay = $('#overlay'); - if (this.infoPopupVisibility) { - overlay.hide(); - document.onkeydown = null; - } else { - document.onkeydown = function () { return false; }; - overlay.show(); - } - this.infoPopupVisibility = !this.infoPopupVisibility; - if (callback instanceof Function) { - setTimeout(callback, 200); - } - }, - - popupHardClose: function () { - var popup = $.mobile.popup.active; - - if (popup) { - popup.element.off(); - popup.close(); - } - }, - - alertPopup: function (text, callback) { - $('#alertPopup .text').text(text); - $('#alertPopup').popup('open', {'positionTo': 'window'}); - if (callback instanceof Function) { - $('#alertPopup').one('popupafteropen', function () { - callback(); - }); - } - if (this.infoPopupVisibility) { - this.toggleInfoPopup(); - } - }, - - confirmPopup: function (text, confirmCallback, completeCallback) { - var popup = $('#confirmPopup'); - popup.find('.text').text(text); - popup.popup('open', {positionTo: 'window'}); - popup.find('.confirm').one('click', function () { - if (confirmCallback instanceof Function) { - confirmCallback(); - } - }); - if (completeCallback instanceof Function) { - popup.one('popupafterclose', function () { - completeCallback(); - }); - } - }, - - clearTabbars: function Ui_clearTabbars() { - $('[data-role = "tabbar"] li > a') - .removeClass('ui-focus, ui-btn-active'); - }, - - /** - * Handler for node click - * @param {File} node - * @param {boolean} toggleCheckbox - */ - handleNodeClick: function Ui_handleNodeClick(node, toggleCheckbox) { - if (this.root) { - app.model.loadInternalStorages(function () { - app.displayStorages(); - }); - this.root = false; - } else if (this.editMode === true) { - //if edit mode is on toggle checkbox state - if (toggleCheckbox === true) { - this.toggleCheckBoxState(node); // select the checkbox - } - - this.refreshSelectAllStatus(); - this.refreshEditMenu(); - } else if (node.hasClass('folder')) { - // otherwise display folder - app.displayFolder(node.attr('uri')); - } else { - // file - app.openFile(node.attr('uri'), node.attr('fullUri')); - } - }, - - /** - * Handler for edit action - */ - handleEditAction: function Ui_handleEditAction() { - this.editMode = true; - this.clearTabbars(); - $('.standardTabbar').hide(); - $('div.editTabbar').show(); - this.disableControlBarButtons( - $('div.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - $('#fileList .folder .nodename, #fileList > li > span.nodename') - .animate({'width': '70%'}); - this.showEditCheckBoxes(); - }, - - /** - * Handler for cancel edit action - */ - handleCancelEditAction: function Ui_handleCancelEditAction(emptyList) { - this.editMode = false; - this.clearTabbars(); - $('div.editTabbar').hide(); - $('.standardTabbar').show(); - $('#fileList .folder .nodename, #fileList > li > span.nodename') - .animate({'width': '75%'}); - this.hideEditCheckBoxes(); - if (this.isFileListEmpty() || emptyList) { - $('#editActionBtn').addClass('vhidden').blur(); - } - }, - - /** - * Handler for delete action - */ - handleDeleteAction: function Ui_handleDeleteAction(e) { - var nodesToDelete = [], - $rowElement, - self = this, - conf, - listLength = $('ul#fileList li.node').length; - - e.stopPropagation(); - e.preventDefault(); - - this.confirmPopup('Selected nodes will be deleted. Are you sure?', - function () { - $('ul#fileList input:checkbox:checked') - .each(function (index) { - $rowElement = $(this).closest('li'); - nodesToDelete.push({ - id: $rowElement.attr('id'), - uri: $rowElement.attr('uri'), - name: $rowElement.attr('label'), - folder: $rowElement.hasClass('folder') - }); - } - ); - if (nodesToDelete.length > 0) { - app.deleteNodes(nodesToDelete); - self.scrollContentTo(0); - $('ul#fileList input:checkbox:checked').remove(); - if (nodesToDelete.length === listLength) { - self.handleCancelEditAction(true); - } else { - self.refreshEditMenu(); - } - } - }, - function () { - self.clearTabbars(); - }); - }, - - /** - * Handler for copy action - */ - handleCopyAction: function Ui_handleCopyAction(e) { - var paths = []; - - e.stopPropagation(); - e.preventDefault(); - - if (this.editMode === true) { - $('ul#fileList input:checkbox:checked').each(function (index) { - paths.push($(this).closest('li').attr('uri')); - }); - app.saveToClipboard(paths, app.clipboard.COPY_MODE_ID); - } - }, - - /** - * Handler for move action - */ - handleMoveAction: function Ui_handleMoveAction(e) { - var paths = []; - - e.stopPropagation(); - e.preventDefault(); - - if (this.editMode === true) { - $('ul#fileList input:checkbox:checked').each(function (index) { - paths.push($(this).closest('li').attr('uri')); - }); - app.saveToClipboard(paths, app.clipboard.MOVE_MODE_ID); - } - }, - - /** - * Handler for paste action - */ - handlePasteAction: function Ui_handlePasteAction() { - }, - - /** - * Scrolls content to the specified position - */ - scrollContentTo: function scrollContentTo(value) { - $('#main [data-role="content"]').scrollview('scrollTo', 0, value); - }, - - /** - * @param {FileSystemStorage[]} nodes Storage elements - */ - displayStorages: function Ui_displayStorages(nodes) { - var len = nodes.length, nodeName, i; - - this.updateNavbar(''); - $('#fileList').empty(); - - for (i = 0; i < len; i = i + 1) { - nodeName = nodes[i].label; - if (nodeName !== '' - && (nodes[i].type === 0 || nodes[i].type === 'INTERNAL') - && nodeName.indexOf('wgt-') === -1 - && $.inArray(nodeName, this.lockedFolders) === -1) { - if (!this.root) { - app.model.isStorageExists( - nodeName, - app.ui.prepareFolderRow.bind(app.ui, i, nodeName), - null - ); - } else { - this.prepareFolderRow(i, nodeName); - } - } - } - - $('#levelUpBtn').addClass('vhidden'); - $('#homeBtn').addClass('vhidden'); - - $('#editActionBtn').addClass('vhidden').blur(); - $('#moreActionBtn').addClass('vhidden').blur(); - $('h1#mainTitle').html('Media'); - - if (this.editMode) { - this.scrollContentTo(0); - } - - this.resetDefaultCheckBoxLabelEvents(); - this.hideSelectAllArea(); - this.handleCancelEditAction(); - - if (this.infoPopupVisibility) { - this.toggleInfoPopup(); - } - }, - - prepareFolderRow: function (id, name) { - if (!this.root || name === 'root') { - $(this.templateManager.get('folderRow', { - id: id, - name: name, - uri: name, - fullUri: name, - })).appendTo('#fileList'); - } - }, - - /** - * File comparison function using their names (case insensitive) - * - * @param {File} x - * @param {File} y - * @returns {Number} - */ - fileComparison: function fileComparison(x, y) { - if (x.isDirectory !== y.isDirectory) { - return x.isDirectory ? -1 : 1; - } - var a = x.name.toLowerCase(), - b = y.name.toLowerCase(); - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; - }, - - /** - * renders node list for folder - * @param {string} folderName - * @param {File[]} nodes - * @param {bool} [refresh=false] - */ - displayFolder: function Ui_displayFolder(folderName, nodes, refresh) { - var len = nodes.length, - listElements = [this.templateManager.get('levelUpRow')], - nodeName, - checkedRows = [], - checkedRowsLen, - i; - refresh = refresh || false; - - // update title - this.updateTitle( - this.templateManager.modifiers.escape(folderName) - ); - // update navbar - this.updateNavbar( - this.templateManager.modifiers.escape(folderName) - ); - this.refreshPasteActionBtn(); - - nodes.sort(this.fileComparison); - - // render nodes - for (i = 0; i < len; i = i + 1) { - nodeName = nodes[i].name; - if (nodeName !== '') { - if (nodes[i].isDirectory) { - // folder - listElements.push(this.templateManager.get( - 'folderRow', - { - id: i, - name: nodeName, - uri: nodes[i].fullPath, - fullUri: nodes[i].toURI() - } - )); - } else { - // file - listElements.push(this.templateManager.get( - 'fileRow', - { - id: i, - name: nodeName, - uri: nodes[i].fullPath, - fullUri: nodes[i].toURI(), - thumbnailURI: this.helpers.getThumbnailURI( - nodeName, - nodes[i] - ) - } - )); - } - } - } - - if (listElements.length === 1) { - // set content for empty folder - listElements.push(this.templateManager.get('emptyFolder')); - // hide edit button for empty content - $('#editActionBtn').addClass('vhidden').blur(); - this.handleCancelEditAction(); - } else { - $('#editActionBtn').removeClass('vhidden'); - } - - // scroll to top of list - this.scrollContentTo(0); - - $('#levelUpBtn').removeClass('vhidden'); - $('#homeBtn').removeClass('vhidden'); - $('#moreActionBtn').removeClass('vhidden'); - - if (refresh === true && this.editMode === true) { - $.each($('#fileList .ui-checkbox input:checked'), function () { - checkedRows.push($(this).closest('li').attr('uri')); - }); - } - - // update file list - $('#fileList').html(listElements.join('')) - .trigger('refresh') - .trigger('create'); - - if (this.editMode === true) { - $('.selectAll').show(); - $('#fileList .folder .nodename, #fileList > li > span.nodename') - .css('width', '70%'); - $('ul#fileList > li').css('paddingLeft', '2rem'); - $('.my-ui-checkbox').removeClass('hidden'); - - if (refresh === true) { - checkedRowsLen = checkedRows.length; - if (checkedRowsLen) { - if ( - checkedRowsLen !== - $('#fileList .ui-checkbox input').length - ) { - this.setCheckboxValue('.selectAll input', false); - } - // restore checked checkboxes - for (i = 0; i < checkedRowsLen; i += 1) { - this.setCheckboxValue( - '#' + - $('#fileList [uri="' + - checkedRows[i] + - '"]').attr('id') + - ' input:checkbox', - 'checked' - ); - } - - // if there are no checked checkboxes - if (!$('#fileList .ui-checkbox input:checked').length) { - this.clearDeleteMode(); - } - } else { - this.clearDeleteMode(); - } - } - } else { - $('.selectAll').hide(); - $('#fileList .folder .nodename, #fileList > li > span.nodename') - .css('width', '75%'); - $('ul#fileList > li').css('paddingLeft', '0'); - $('.my-ui-checkbox').addClass('hidden'); - this.clearDeleteMode(); - } - if (!refresh) { - this.hideSelectAllArea(); - } - - if (this.infoPopupVisibility) { - this.toggleInfoPopup(); - } - - this.refreshSelectAllStatus(); - }, - - /** - * Clear confirm popup and disable action buttons - */ - clearDeleteMode: function Ui_clearDeleteMode() { - var aPopup = $.mobile.popup.active; - if (aPopup && aPopup.element.attr('id') === 'confirmPopup') { - $.mobile.popup.active.close(); - } - this.disableControlBarButtons( - $('div.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - }, - - /** - * Toggle a checkbox associated with a given list element - * @param {jQuery} listElement - */ - toggleCheckBoxState: function Ui_toggleCheckBoxState(listElement) { - var checkboxInput = null; - - checkboxInput = listElement.find('form > div.ui-checkbox input'); - this.setCheckboxValue( - checkboxInput, - !checkboxInput.attr('checked') - ); - }, - - /** - * Shows item checkboxes and topbar with select all option - */ - showEditCheckBoxes: function Ui_showEditCheckBoxes() { - var self = this; - - this.showSelectAllArea(); - - $('ul#fileList > li').animate( - {paddingLeft: '2rem'}, - 500, - 'swing', - function () { - self.editMode = true; - $('.my-ui-checkbox').removeClass('hidden'); - } - ); - }, - - /** - * Hides item checkboxes and topbar with select all option - * All checkboxes are auto uncheked - */ - hideEditCheckBoxes: function Ui_hideEditCheckBoxes() { - var self = this; - - this.hideSelectAllArea(); // hide select all option topbar - - $('ul#fileList > li').animate( - {paddingLeft: '0'}, - 200, - 'swing', - function () { - $('.my-ui-checkbox').addClass('hidden'); - $.mobile.activePage.page('refresh'); - } - ); - - // uncheck all checkboxes - $('ul#fileList input[type=checkbox]').each(function (index) { - self.setCheckboxValue(this, false); - }); - - //uncheck select all input - this.setCheckboxValue('.ui-header .selectAll input', false); - }, - - /** - * Save current header and content height - */ - saveHeights: function Ui_saveHeights() { - this.currentHeaderHeight = $('#main div[data-role="header"]') - .height(); - this.currentScrollPosition = $('#main div[data-role="content"]') - .scrollview('getScrollPosition').y; - }, - - /** - * Changes content scroll position after showing/hiding selectAllArea - */ - changeContentScrollPosition: function Ui_changeContentScrollPosition() { - var diff, - contentHeight; - if (this.currentScrollPosition !== 0) { - contentHeight = $('#main div[data-role="header"]').height(); - diff = contentHeight - this.currentHeaderHeight; - $('#main div[data-role="content"]') - .scrollview( - 'scrollTo', - 0, - -(this.currentScrollPosition + diff) - ); - } - }, - - /** - * Shows topbar with select all option - */ - showSelectAllArea: function Ui_showSelectAllArea() { - this.saveHeights(); - $('.selectAll').show(); - $.mobile.activePage.page('refresh'); - this.changeContentScrollPosition(); - }, - - /** - * Hides topbar with select all option - */ - hideSelectAllArea: function Ui_hideSelectAllArea() { - this.saveHeights(); - $('.selectAll').hide(); - $.mobile.activePage.page('refresh'); - this.changeContentScrollPosition(); - }, - - /** - * Enable specified options for tabbar - * @param {object} tabbar - * @param {array} enableOptions options to enable - */ - enableControlBarButtons: function Ui_enableControlBarButtons( - tabbar, - enableOptions - ) { - var i = 0, - len = enableOptions.length; - - for (i = 0; i < len; i += 1) { - tabbar.tabbar('enable', enableOptions[i]); - } - }, - - /** - * Disable specified options for tabbar - * @param {object} tabbar controlbar - * @param {array} disableOptions options to enable - */ - disableControlBarButtons: function Ui_disableControlBarButtons( - tabbar, - disableOptions - ) { - var i = 0, - len = disableOptions.length; - - for (i = 0; i < len; i += 1) { - tabbar.tabbar('disable', disableOptions[i]); - } - }, - - /** - * @param {string} path - */ - updateTitle: function Ui_updateTitle(path) { - var regexp = new RegExp('([^\/])+$', 'g'), - match = path.match(regexp), - lastDir = match[0] || '(dir)'; - $('h1#mainTitle').html(lastDir); - }, - - /** - * @param {string} path - */ - updateNavbar: function Ui_updateNavbar(path) { - var html = ['Media'], - splitted, - len, - i; - - if (typeof path === 'string' && path !== '') { - splitted = path.split('/'); - len = splitted.length; - - for (i = 0; i < len; i = i + 1) { - html.push( - '' + - splitted[i] + - '' - ); - } - } - $('#navbar').html(html.join(' > ')); - }, - - handleSelectAllChange: function Ui_handleSelectAllChange() { - var $selectAllInput = $('.ui-header .selectAll .ui-checkbox input'), - self = this; - $selectAllInput.data('checkboxradio').refresh(); - - if ($selectAllInput.is(':checked')) { - // check all checkboxes - $('ul#fileList input[type=checkbox]').each(function (index) { - self.setCheckboxValue(this, true); - }); - - this.enableControlBarButtons( - $('.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - } else { - $('ul#fileList input[type=checkbox]').each(function (index) { - self.setCheckboxValue(this, false); - }); - - this.disableControlBarButtons( - $('.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - } - }, - - /** - * - */ - refreshSelectAllStatus: function Ui_refreshSelectAllStatus() { - var $selectAllInput = $('.ui-header .selectAll .ui-checkbox input'); - // update status of select all checkbox - if ($('ul#fileList input:checkbox:not(:checked)').length === 0) { - // all nodes checked - this.setCheckboxValue($selectAllInput, true); - } else { - // some node is not checked - this.setCheckboxValue($selectAllInput, false); - } - }, - - /** - * Refresh activity of edit menu - */ - refreshEditMenu: function () { - if ($('ul#fileList input:checkbox:checked').length > 0) { - this.enableControlBarButtons( - $('.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - } else { - this.disableControlBarButtons( - $('.editTabbar'), - [ - this.EDIT_TABBAR_DELETE_ACTION, - this.EDIT_TABBAR_COPY_ACTION, - this.EDIT_TABBAR_MOVE_ACTION - ] - ); - } - }, - - /** - * Unbinds default events for checkbox labels - */ - resetDefaultCheckBoxLabelEvents: function Ui_resetLabelEvents() { - $('div.ui-checkbox > label') - .unbind('vmousedown') - .unbind('vmouseup') - .unbind('vmouseover') - .unbind('vclick'); - }, - - /** - * Remove html node element from list - * @param {string} nodeUri node uri - */ - removeNodeFromList: function Ui_removeNodeFromList(nodeUri) { - $('ul#fileList > li[uri="' + nodeUri.replace(/"/g, '\"') + '"]') - .remove(); - - // hide select All checkbox if removed all elements; - if ($('ul#fileList > li.node').length === 0) { - this.hideSelectAllArea(); - } - }, - - /** - * Enable/Disable - */ - refreshPasteActionBtn: function Ui_refreshPasteActionBtn() { - if (app.emptyClipboard()) { - $('#pasteActionBtnRow').addClass('hidden'); - } else { - $('#pasteActionBtnRow').removeClass('hidden'); - } - }, - - isFileListEmpty: function Ui_isFileListEmpty() { - return ($('ul#fileList').children('.node').length < 1); - }, - - setCheckboxValue: function Ui_setCheckboxValue(element, value) { - var $element = $(element), - checkboxradio = $element.data('checkboxradio'); - - $(element).attr('checked', value); - if (checkboxradio) { - checkboxradio.refresh(); - } - - } - }; + 'use strict'; + Ui.prototype = { + /** + * root mode + * @type {boolean} + */ + root: true, + + /** + * locked folders + * @type {array} + */ + lockedFolders: ['ringtones'], + + /** + * UI edit mode + * @type {boolean} + */ + editMode: false, + + /** + * @type {bool} block clicks until the page change is completed + */ + nodeTapBlock: false, + + /** + * @type {TemplateManager} + */ + templateManager: null, + + /** + * @type Helpers + */ + helpers: null, + + /** + * @type Info popup lock + */ + infoPopupVisibility: false, + + /** + * @const {number} + */ + PATH_DIV_HEIGHT: 20, + + /** + * @const {number} + */ + SELECT_ALL_HEIGHT: 32, + + /** + * @const {number} header height, set on domReady + */ + HEADER_HEIGHT: 53, + + /** + * name of row gradient class + */ + CSS_GRADIENT_CLASS: 'gradientBackground', + + /** + * Standard tabbar actions + * @type {number} + */ + STD_TABBAR_EDIT_ACTION: 0, + STD_TABBAR_MORE_ACTION: 1, + STD_TABBAR_EXIT_ACTION: 2, + + /** + * Edit tabbar actions + * @type {number} + */ + EDIT_TABBAR_DELETE_ACTION: 0, + EDIT_TABBAR_MOVE_ACTION: 1, + EDIT_TABBAR_COPY_ACTION: 2, + EDIT_TABBAR_CANCEL_ACTION: 3, + + currentHeaderHeight: null, + currentScrollPosition: null, + + /** + * UI Initialization + */ + init: function Ui_init(storages) { + this.templateManager = new TemplateManager(); + this.helpers = new Helpers(); + // Disable text selection + $.mobile.tizen.disableSelection(document); + $(document).ready(this.initDom.bind(this, storages)); + }, + + initDom: function Ui_initDom(storages) { + var self = this, + overlay = $('#overlay'), + popup = $('#infoPopup'), + windowWidth, + windowHeight, + popWidth; + + this.templateManager.loadToCache(['main', 'fileRow', 'folderRow', 'levelUpRow', 'emptyFolder'], function () { + $('#main').append($(self.templateManager.get('main')).children()).trigger('pagecreate'); + self.addEvents(); + self.displayStorages(storages); + }); + + windowWidth = $(window).width(); + windowHeight = $(window).height(); + + overlay.css({ + 'width': windowWidth + 'px', + 'height': windowHeight + 'px' + }); + + popWidth = windowWidth / 2 + 30; + popup.css({ + 'width': popWidth + 'px', + 'left': (windowWidth / 2 - popWidth / 2) + 'px', + 'top': (windowHeight / 2 - popup.height() / 2) + 'px' + }); + }, + + /** + * Add UI events + */ + addEvents: function Ui_addEvents() { + var self = this; + + document.addEventListener('webkitvisibilitychange', function () { + if (document.webkitVisibilityState === 'visible') { + self.refreshSelectAllStatus(); + app.refreshCurrentPage(true); + } + }); + + window.addEventListener('tizenhwkey', function(e) { + var uri = $('#navbar span+span').attr('uri'); + if (e.keyName == "back") { + if (self.infoPopupVisibility) { + return; + } else if ($.mobile.popup.active) { + $.mobile.popup.active.close(); + } else if (self.editMode === true) { + self.handleCancelEditAction(); + } else if (!uri) { + if ( app.ui.root === false ) { + $('#fileList').empty(); + app.ui.prepareFolderRow(0, "root"); + app.ui.root = true; + } else { + tizen.application.getCurrentApplication().exit(); + } + } else { + app.goLevelUp(); + } + } + }); + + $(window).resize( function () { + $.mobile.activePage.page('refresh') + }); + + // touch events for all nodes + $('ul#fileList') + .on('click', 'li.levelUp', function () { + if (self.editMode === true) { + self.handleCancelEditAction(); + } + app.goLevelUp(); + }) + .on('click', 'li.node', function (e) { + e.preventDefault(); + e.stopPropagation(); + self.handleNodeClick($(this), true); + }) + .on('change', 'input[type=checkbox]', function (e) { + self.handleNodeClick($(this).closest('li.node'), false); + }) + .on('touchstart', 'li', function (event) { + $(this).addClass(self.CSS_GRADIENT_CLASS); + }) + .on('touchend touchmove', 'li', function (event) { + $(this).removeClass(self.CSS_GRADIENT_CLASS); + }); + + $('.selectAll input').on('change', this.handleSelectAllChange.bind(this)); + + // navbar + $('#navbar').on('click', 'span', function () { + var uri = $(this).attr('uri'); + if (uri === 'home') { + if (app.currentPath !== '') { + app.displayStorages(); + } + } else if (uri === app.model.currentPath) { + app.displayFolder(uri,true); + } else { + if (self.editMode === true) { + self.handleCancelEditAction(); + } + app.displayFolder(uri); + } + }); + + // level up + $('#levelUpBtn').on('click', function () { + if (self.editMode === true) { + self.handleCancelEditAction(); + } + app.goLevelUp(); + }); + + $('#homeBtn').on('click', app.displayStorages.bind(app)); + + // edit action + $('#editActionBtn').on('click', this.handleEditAction.bind(this)); + + // delete action + $('#deleteActionBtn').on('click', this.handleDeleteAction.bind(this)); + + // cancel edit + $('#cancelActionBtn').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + self.handleCancelEditAction(); + }); + + // copy action + $('#copyActionBtn').on('click', this.handleCopyAction.bind(this)); + + // move action + $('#moveActionBtn').on('click', this.handleMoveAction.bind(this)); + + // paste action + $('a#pasteActionBtn').on('click', function () { + if (!self.infoPopupVisibility) { + self.toggleInfoPopup(); + setTimeout(app.pasteClipboard.bind(app), 100); + } + $("#morePopup").popup('close'); + }); + + // remove active class + $('[data-role = "tabbar"] li > a').on('click', function () { + $(this).removeClass('ui-focus, ui-btn-active'); + }); + // exit + $('.ui-myExit').on('click', app.exit); + + // add folder popup actions + $('#addFolderPopup').on("popupafterclose", function () { + // clear input value + $('#newFolderName').val('New folder'); + }); + + $('#newFolderName').on('click', function () { + if ($(this).attr('value') === 'New folder') { + $(this).attr('value', ''); + } + }); + + $('#saveNewFolder').on('click', this.saveNewFolder.bind(this)); + $('#newFolderForm').on('submit', this.saveNewFolder.bind(this)); + }, + + saveNewFolder: function Ui_saveNewFolder(e) { + var folderName = $('#newFolderName').val().trim(), status = true, + open = function () { + $("#addFolderPopup").popup('open', { + positionTo: "window" + }); + }, + self = this, + buttons = $("#addFolderPopup .ui-popup-button-bg a"), + activePopup; + e.preventDefault(); + e.stopPropagation(); + buttons.addClass('ui-disabled'); + $("#addFolderPopup").one("popupafterclose", function () { + if (folderName === '') { + self.alertPopup("Empty folder name", open); + status = false; + } else if (folderName.match(/[\*\.\/\\\?\"\'\:<>|]/)) { + self.alertPopup("The following special characters " + +"are not allowed: *./\\?:<>|'\"", open); + status = false; + } else { + status = app.createDir(folderName, open); + } + buttons.removeClass('ui-disabled'); + }); + activePopup = $.mobile.popup.active; + if ( + activePopup && + activePopup.element.attr('id') === 'addFolderPopup' + ) { + activePopup.close(); + } + return status; + }, + + toggleInfoPopup: function () { + var overlay = $('#overlay'); + + if (this.infoPopupVisibility) { + overlay.hide(); + document.onkeydown = null; + } else { + document.onkeydown = function(){return false;} + overlay.show(); + } + + this.infoPopupVisibility = !this.infoPopupVisibility; + }, + + alertPopup: function (text, callback) { + $("#alertPopup .text").text(text); + $("#alertPopup").popup('open', {'positionTo': 'window'}); + if (callback instanceof Function) { + $("#alertPopup").one("popupafterclose", function () { + callback(); + }); + } + if (this.infoPopupVisibility) { + this.toggleInfoPopup(); + } + }, + + confirmPopup: function (text, confirmCallback, completeCallback) { + var popup = $("#confirmPopup"); + popup.find(".text").text(text); + popup.popup('open', {positionTo: 'window'}); + popup.find(".confirm").one("click", function () { + if (confirmCallback instanceof Function) { + confirmCallback(); + } + }); + if (completeCallback instanceof Function) { + popup.one('popupafterclose', function () { + completeCallback(); + }); + } + }, + + clearTabbars: function Ui_clearTabbars() { + $('[data-role = "tabbar"] li > a').removeClass('ui-focus, ui-btn-active'); + }, + + /** + * Handler for node click + * @param {File} node + * @param {boolean} toggleCheckbox + */ + handleNodeClick: function Ui_handleNodeClick(node, toggleCheckbox) { + if (this.root) { + app.model.loadInternalStorages(function () { app.displayStorages(); }); + this.root = false; + } else if (this.editMode === true) { + //if edit mode is on toggle checkbox state + if (toggleCheckbox === true) { + this.toggleCheckBoxState(node); // select the checkbox + } + + this.refreshSelectAllStatus(); + this.refreshEditMenu(); + } else if (node.hasClass('folder')) { + // otherwise display folder + app.displayFolder(node.attr('uri')); + } else { + // file + app.openFile(node.attr('uri'), node.attr('fullUri')); + } + }, + + /** + * Handler for edit action + */ + handleEditAction: function Ui_handleEditAction() { + this.editMode = true; + this.clearTabbars(); + $('.standardTabbar').hide(); + $('div.editTabbar').show(); + this.disableControlBarButtons($('div.editTabbar'), [this.EDIT_TABBAR_DELETE_ACTION, this.EDIT_TABBAR_COPY_ACTION, this.EDIT_TABBAR_MOVE_ACTION]); + $('#fileList .folder .nodename, #fileList > li > span.nodename') + .animate({'width': '70%'}); + this.showEditCheckBoxes(); + }, + + /** + * Handler for cancel edit action + */ + handleCancelEditAction: function Ui_handleCancelEditAction() { + this.editMode = false; + this.clearTabbars(); + $('div.editTabbar').hide(); + $('.standardTabbar').show(); + $('#fileList .folder .nodename, #fileList > li > span.nodename') + .animate({'width': '75%'}); + this.hideEditCheckBoxes(); + if (this.isFileListEmpty()) { + $('#editActionBtn').addClass('vhidden').blur(); + } + }, + + /** + * Handler for delete action + */ + handleDeleteAction: function Ui_handleDeleteAction(e) { + var nodesToDelete = [], + $rowElement, + self = this, + conf; + + e.stopPropagation(); + e.preventDefault(); + + this.confirmPopup('Selected nodes will be deleted. Are you sure?', + function () { + $('ul#fileList input:checkbox:checked').each(function (index) { + $rowElement = $(this).closest('li'); + nodesToDelete.push({ + id: $rowElement.attr('id'), + uri: $rowElement.attr('uri'), + name: $rowElement.attr('label'), + folder: $rowElement.hasClass('folder') + }); + }); + if (nodesToDelete.length > 0) { + app.deleteNodes(nodesToDelete); + self.scrollContentTo(0); + $('ul#fileList input:checkbox:checked').remove(); + self.refreshEditMenu(); + } + }, + function () { + self.clearTabbars(); + } + ); + }, + + /** + * Handler for copy action + */ + handleCopyAction: function Ui_handleCopyAction(e) { + var paths = []; + + e.stopPropagation(); + e.preventDefault(); + + if (this.editMode === true) { + $('ul#fileList input:checkbox:checked').each(function (index) { + paths.push($(this).closest('li').attr('uri')); + }); + app.saveToClipboard(paths, app.clipboard.COPY_MODE_ID); + } + }, + + /** + * Handler for move action + */ + handleMoveAction: function Ui_handleMoveAction(e) { + var paths = []; + + e.stopPropagation(); + e.preventDefault(); + + if (this.editMode === true) { + $('ul#fileList input:checkbox:checked').each(function (index) { + paths.push($(this).closest('li').attr('uri')); + }); + app.saveToClipboard(paths, app.clipboard.MOVE_MODE_ID); + } + }, + + /** + * Handler for paste action + */ + handlePasteAction: function Ui_handlePasteAction() { + }, + + /** + * Scrolls content to the specified position + */ + scrollContentTo: function scrollContentTo(value) { + $('#main [data-role="content"]').scrollview('scrollTo', 0, value); + }, + + /** + * @param {FileSystemStorage[]} nodes Storage elements + */ + displayStorages: function Ui_displayStorages(nodes) { + var len = nodes.length, nodeName, i; + + this.updateNavbar(''); + $('#fileList').empty(); + + for (i = 0; i < len; i = i + 1) { + nodeName = nodes[i].label.trim(); + if (nodeName !== '' + && (nodes[i].type === 0 || nodes[i].type === 'INTERNAL') + && nodeName.indexOf('wgt-') === -1 + && $.inArray(nodeName, this.lockedFolders) === -1 + ) { + if (!this.root) { + app.model.isStorageExists(nodeName, + app.ui.prepareFolderRow.bind(app.ui, i, nodeName), null); + } else { + this.prepareFolderRow(i, nodeName); + } + } + } + + $('#levelUpBtn').addClass('vhidden'); + $('#homeBtn').addClass('vhidden'); + + $('#editActionBtn').addClass('vhidden').blur(); + $('#moreActionBtn').addClass('vhidden').blur(); + $('h1#mainTitle').html('Media'); + + if (this.editMode) { + this.scrollContentTo(0); + } + + this.resetDefaultCheckBoxLabelEvents(); + this.hideSelectAllArea(); + this.handleCancelEditAction(); + + if (this.infoPopupVisibility) { + this.toggleInfoPopup(); + } + }, + + prepareFolderRow: function (id, name) { + $(this.templateManager.get('folderRow', { + id: id, + name: name, + uri: name, + fullUri: name, + })).appendTo('#fileList'); + }, + + /** + * File comparison function using their names (case insensitive) + * + * @param {File} x + * @param {File} y + * @returns {Number} + */ + fileComparison: function fileComparison(x, y) { + if(x.isDirectory !== y.isDirectory) { + return x.isDirectory ? -1 : 1; + } + var a = x.name.toLowerCase(), + b = y.name.toLowerCase(); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + }, + + /** + * renders node list for folder + * @param {string} folderName + * @param {File[]} nodes + * @param {bool} [refresh=false] + */ + displayFolder: function Ui_displayFolder(folderName, nodes, refresh) { + var len = nodes.length, + listElements = [this.templateManager.get('levelUpRow')], + nodeName, + checkedRows = [], + checkedRowsLen, + i; + refresh = refresh || false; + + // update title + this.updateTitle(this.templateManager.modifiers.escape(folderName)); + // update navbar + this.updateNavbar(this.templateManager.modifiers.escape(folderName)); + this.refreshPasteActionBtn(); + + nodes.sort(this.fileComparison); + + // render nodes + for (i = 0; i < len; i = i + 1) { + nodeName = nodes[i].name; + if (nodeName !== '') { + if (nodes[i].isDirectory) { + // folder + listElements.push(this.templateManager.get('folderRow', { + id: i, + name: nodeName, + uri: nodes[i].fullPath, + fullUri: nodes[i].toURI() + })); + } else { + // file + listElements.push(this.templateManager.get('fileRow', { + id: i, + name: nodeName, + uri: nodes[i].fullPath, + fullUri: nodes[i].toURI(), + thumbnailURI: this.helpers.getThumbnailURI(nodeName, nodes[i]) + })); + } + } + } + + if (listElements.length === 1) { + // set content for empty folder + listElements.push(this.templateManager.get('emptyFolder')); + // hide edit button for empty content + $('#editActionBtn').addClass('vhidden').blur(); + this.handleCancelEditAction(); + } else { + $('#editActionBtn').removeClass('vhidden'); + } + + // scroll to top of list + this.scrollContentTo(0); + + $('#levelUpBtn').removeClass('vhidden'); + $('#homeBtn').removeClass('vhidden'); + $('#moreActionBtn').removeClass('vhidden'); + + if (refresh === true && this.editMode === true) { + $.each($('#fileList .ui-checkbox input:checked'), function () { + checkedRows.push($(this).closest('li').attr('uri')); + }); + } + + // update file list + $('#fileList').html(listElements.join('')) + .trigger('refresh') + .trigger('create'); + + if (this.editMode === true) { + $('.selectAll').show(); + $('#fileList .folder .nodename, #fileList > li > span.nodename') + .css('width', '70%'); + $('ul#fileList > li').css('paddingLeft', '2rem'); + $('.my-ui-checkbox').removeClass('hidden'); + + if (refresh === true) { + checkedRowsLen = checkedRows.length; + if (checkedRowsLen) { + if (checkedRowsLen !== $('#fileList .ui-checkbox input').length) { + this.setCheckboxValue('.selectAll input', false); + } + // restore checked checkboxes + for (i = 0; i < checkedRowsLen; i += 1) { + this.setCheckboxValue( + '#' + + $('#fileList [uri="' + + checkedRows[i] + + '"]').attr('id') + + ' input:checkbox', + 'checked' + ); + } + + // if there are no checked checkboxes + if (!$('#fileList .ui-checkbox input:checked').length) { + this.clearDeleteMode(); + } + } else { + this.clearDeleteMode(); + } + } + } else { + $('.selectAll').hide(); + $('#fileList .folder .nodename, #fileList > li > span.nodename') + .css('width', '75%'); + $('ul#fileList > li').css('paddingLeft', '0'); + $('.my-ui-checkbox').addClass('hidden'); + this.clearDeleteMode(); + } + if (!refresh) this.hideSelectAllArea(); + + if (this.infoPopupVisibility) { + this.toggleInfoPopup(); + } + + this.refreshSelectAllStatus(); + }, + + /** + * Clear confirm popup and disable action buttons + */ + clearDeleteMode: function Ui_clearDeleteMode () { + if ( + $.mobile.popup.active && + $.mobile.popup.active.element.attr('id') === 'confirmPopup' + ) { + $.mobile.popup.active.close(); + } + this.disableControlBarButtons($('div.editTabbar'), + [this.EDIT_TABBAR_DELETE_ACTION, + this.EDIT_TABBAR_COPY_ACTION, + this.EDIT_TABBAR_MOVE_ACTION] + ); + }, + + /** + * Toggle a checkbox associated with a given list element + * @param {jQuery} listElement + */ + toggleCheckBoxState: function Ui_toggleCheckBoxState(listElement) { + var checkboxInput = null; + + checkboxInput = listElement.find('form > div.ui-checkbox input'); + this.setCheckboxValue(checkboxInput, !checkboxInput.attr('checked')); + }, + + /** + * Shows item checkboxes and topbar with select all option + */ + showEditCheckBoxes: function Ui_showEditCheckBoxes() { + var self = this; + + this.showSelectAllArea(); + + $('ul#fileList > li').animate({paddingLeft: '2rem'}, 500, 'swing', function () { + self.editMode = true; + $('.my-ui-checkbox').removeClass('hidden'); + }); + }, + + /** + * Hides item checkboxes and topbar with select all option + * All checkboxes are auto uncheked + */ + hideEditCheckBoxes: function Ui_hideEditCheckBoxes() { + var self = this; + + this.hideSelectAllArea(); // hide select all option topbar + + $('ul#fileList > li').animate({paddingLeft: '0'}, 200, 'swing', function () { + $('.my-ui-checkbox').addClass('hidden'); + $.mobile.activePage.page('refresh'); + }); + + // uncheck all checkboxes + $('ul#fileList input[type=checkbox]').each(function (index) { + self.setCheckboxValue(this, false); + }); + + //uncheck select all input + this.setCheckboxValue('.ui-header .selectAll input', false); + }, + + /** + * Save current header and content height + */ + saveHeights: function Ui_saveHeights() { + this.currentHeaderHeight = $('#main div[data-role="header"]').height(); + this.currentScrollPosition = $('#main div[data-role="content"]').scrollview('getScrollPosition').y; + }, + + /** + * Changes content scroll position after showing/hiding selectAllArea + */ + changeContentScrollPosition: function Ui_changeContentScrollPosition() { + var diff; + if (this.currentScrollPosition !== 0) { + diff = $('#main div[data-role="header"]').height() - this.currentHeaderHeight; + $('#main div[data-role="content"]').scrollview('scrollTo', 0, -(this.currentScrollPosition + diff)); + } + }, + + /** + * Shows topbar with select all option + */ + showSelectAllArea: function Ui_showSelectAllArea() { + this.saveHeights(); + $('.selectAll').show(); + $.mobile.activePage.page('refresh'); + this.changeContentScrollPosition(); + }, + + /** + * Hides topbar with select all option + */ + hideSelectAllArea: function Ui_hideSelectAllArea() { + this.saveHeights(); + $('.selectAll').hide(); + $.mobile.activePage.page('refresh'); + this.changeContentScrollPosition(); + }, + + /** + * Enable specified options for tabbar + * @param {object} tabbar + * @param {array} enableOptions options to enable + */ + enableControlBarButtons: function Ui_enableControlBarButtons(tabbar, enableOptions) { + var i = 0, + len = enableOptions.length; + + for (i = 0; i < len; i += 1) { + tabbar.tabbar('enable', enableOptions[i]); + } + }, + + /** + * Disable specified options for tabbar + * @param {object} tabbar controlbar + * @param {array} disableOptions options to enable + */ + disableControlBarButtons: function Ui_disableControlBarButtons(tabbar, disableOptions) { + var i = 0, + len = disableOptions.length; + + for (i = 0; i < len; i += 1) { + tabbar.tabbar('disable', disableOptions[i]); + } + }, + + /** + * @param {string} path + */ + updateTitle: function Ui_updateTitle(path) { + var regexp = new RegExp('([^\/])+$', 'g'), + match = path.match(regexp), + lastDir = match[0] || '(dir)'; + $('h1#mainTitle').html(lastDir); + }, + + /** + * @param {string} path + */ + updateNavbar: function Ui_updateNavbar(path) { + var html = ['Media'], + splitted, + len, + i; + + if (typeof path === 'string' && path !== '') { + splitted = path.split('/'); + len = splitted.length; + + for (i = 0; i < len; i = i + 1) { + html.push('' + splitted[i] + ''); + } + } + $('#navbar').html(html.join(' > ')); + }, + + handleSelectAllChange: function Ui_handleSelectAllChange() { + var $selectAllInput = $('.ui-header .selectAll .ui-checkbox input'), + self = this; + $selectAllInput.data('checkboxradio').refresh(); + + if ($selectAllInput.is(':checked')) { + // check all checkboxes + $('ul#fileList input[type=checkbox]').each(function (index) { + self.setCheckboxValue(this, true); + }); + + this.enableControlBarButtons($('.editTabbar'), [this.EDIT_TABBAR_DELETE_ACTION, this.EDIT_TABBAR_COPY_ACTION, this.EDIT_TABBAR_MOVE_ACTION]); + } else { + $('ul#fileList input[type=checkbox]').each(function (index) { + self.setCheckboxValue(this, false); + }); + + this.disableControlBarButtons($('.editTabbar'), [this.EDIT_TABBAR_DELETE_ACTION, this.EDIT_TABBAR_COPY_ACTION, this.EDIT_TABBAR_MOVE_ACTION]); + } + }, + + /** + * + */ + refreshSelectAllStatus: function Ui_refreshSelectAllStatus() { + var $selectAllInput = $('.ui-header .selectAll .ui-checkbox input'); + // update status of select all checkbox + if ($('ul#fileList input:checkbox:not(:checked)').length === 0) { + // all nodes checked + this.setCheckboxValue($selectAllInput, true); + } else { + // some node is not checked + this.setCheckboxValue($selectAllInput, false); + } + }, + + /** + * Refresh activity of edit menu + */ + refreshEditMenu: function () { + if ($('ul#fileList input:checkbox:checked').length > 0) { + this.enableControlBarButtons($('.editTabbar'), + [this.EDIT_TABBAR_DELETE_ACTION, this.EDIT_TABBAR_COPY_ACTION, this.EDIT_TABBAR_MOVE_ACTION]); + } else { + this.disableControlBarButtons($('.editTabbar'), + [this.EDIT_TABBAR_DELETE_ACTION, this.EDIT_TABBAR_COPY_ACTION, this.EDIT_TABBAR_MOVE_ACTION]); + } + }, + + /** + * Unbinds default events for checkbox labels + */ + resetDefaultCheckBoxLabelEvents: function Ui_resetDefaultCheckBoxLabelEvents() { + $('div.ui-checkbox > label') + .unbind('vmousedown') + .unbind('vmouseup') + .unbind('vmouseover') + .unbind('vclick'); + }, + + /** + * Remove html node element from list + * @param {string} nodeId node id + */ + removeNodeFromList: function Ui_removeNodeFromList(nodeId) { + $('ul#fileList > li#' + nodeId).remove(); + + // hide select All checkbox if removed all elements; + if ($('ul#fileList > li.node').length === 0) { + this.hideSelectAllArea(); + } + }, + + /** + * Enable/Disable + */ + refreshPasteActionBtn: function Ui_refreshPasteActionBtn() { + if (app.emptyClipboard()) { + $('#pasteActionBtnRow').addClass('hidden'); + } else { + $('#pasteActionBtnRow').removeClass('hidden'); + } + }, + + isFileListEmpty: function Ui_isFileListEmpty() { + return ($('ul#fileList').children('.node').length < 1); + }, + + setCheckboxValue: function Ui_setCheckboxValue (element, value) { + var $element = $(element), + checkboxradio = $element.data('checkboxradio'); + + $(element).attr('checked', value); + if (checkboxradio) { + checkboxradio.refresh(); + } + + } + }; }()); diff --git a/project/js/app.ui.templateManager.js b/project/js/app.ui.templateManager.js index c880c5e..e2a440a 100644 --- a/project/js/app.ui.templateManager.js +++ b/project/js/app.ui.templateManager.js @@ -1,187 +1,136 @@ -/* -* 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 + '\\|([a-zA-Z]){1,}%', 'g'), + regModOff = new RegExp(['%', tplParam, '%'].join(''), 'g'), + regModGet = new RegExp('%' + tplParam + '\\|(.+?)%'), + specRegExp = new RegExp('\\$','g'), + modifier; + + if (content && (typeof content === 'string')) { + content = content.replace(specRegExp, '$$$$'); + } + + if (regModOn.test(tplHtml)) { + modifier = tplHtml.match(regModGet)[1]; + try { + content = this.modifiers[modifier](content); + } catch (error) { + console.error('unknown modifier: ' + modifier); + } + tplHtml = tplHtml.replace(regModOn, content); + } else { + tplHtml = tplHtml.replace(regModOff, content); + } + return tplHtml; + } + }; + +}()); \ No newline at end of file diff --git a/project/js/app.ui.templateManager.modifiers.js b/project/js/app.ui.templateManager.modifiers.js index 16264a9..95e9d0a 100644 --- a/project/js/app.ui.templateManager.modifiers.js +++ b/project/js/app.ui.templateManager.modifiers.js @@ -1,63 +1,47 @@ -/* - * 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 */ function ModifierManager() { - 'use strict'; - this.init(); + 'use strict'; + this.init(); } (function () { - 'use strict'; - ModifierManager.prototype = { + 'use strict'; + ModifierManager.prototype = { - /** - * UI module initialisation - */ - init: function () { - }, + /** + * UI module initialisation + */ + init: function () { + }, - /** - * @return modifiers object - */ - getAll: function () { - return this.modifiers; - }, + /** + * @return modifiers object + */ + getAll: function () { + return this.modifiers; + }, - /** - * modifiers definitions - */ - modifiers: { - escape: function escape(str) { - return $('').text(str).html(); - }, - escapeEncies: function escapeEncies(str) { - var tagsToReplace = { - '&': '&', - '<': '<', - '>': '>', - '"': '"' - }; - return str.replace(/[&<>\"]/g, function (tag) { - return tagsToReplace[tag] || tag; - }); - } - } - }; + /** + * modifiers definitions + */ + modifiers: { + escape: function escape(str) { + return $('').text(str).html(); + }, + escapeEncies: function escapeEncies(str) { + var tagsToReplace = { + '&': '&', + '<': '<', + '>': '>', + '"': '"' + }; + return str.replace(/[&<>\"]/g, function(tag) { + return tagsToReplace[tag] || tag; + }); + } + } + }; }()); \ No newline at end of file diff --git a/project/js/main.js b/project/js/main.js index 2f53df2..360b951 100644 --- a/project/js/main.js +++ b/project/js/main.js @@ -30,55 +30,49 @@ var app = null; (function () { // strict mode wrapper - 'use strict'; + '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); - }, + ({ + /** + * 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); - }); - } - }, + /** + * 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 - ) { - app.ui.alertPopup('An error occurred: ' + e.message); - } - }).init(); // run the loader + /** + * Handle ajax errors + */ + onGetScriptError: function onGetScriptError(e, jqxhr, setting, exception) { + app.ui.alertPopup('An error occurred: ' + e.message); + } + }).init(); // run the loader }()); diff --git a/project/templates/fileRow.tpl b/project/templates/fileRow.tpl index 4374b04..38f6b03 100644 --- a/project/templates/fileRow.tpl +++ b/project/templates/fileRow.tpl @@ -1,5 +1,5 @@
  • - - - %name|escape% + + + %name|escape%
  • \ No newline at end of file diff --git a/project/templates/folderRow.tpl b/project/templates/folderRow.tpl index b77ca46..ba82018 100644 --- a/project/templates/folderRow.tpl +++ b/project/templates/folderRow.tpl @@ -1,6 +1,6 @@
  • - - - %name|escape% - + + + %name|escape% +
  • \ No newline at end of file diff --git a/project/templates/levelUpRow.tpl b/project/templates/levelUpRow.tpl index 9a71e88..ddbc7cf 100644 --- a/project/templates/levelUpRow.tpl +++ b/project/templates/levelUpRow.tpl @@ -1,3 +1,3 @@
  • - .. + ..
  • \ No newline at end of file diff --git a/project/templates/main.tpl b/project/templates/main.tpl index ed01f54..d5d17e7 100644 --- a/project/templates/main.tpl +++ b/project/templates/main.tpl @@ -1,84 +1,83 @@ -
    -
    -

    - Home - Up - - -
    +
    +
    +

    + Home + Up + + +
    -
    -
      -
      -
      -

      Add new folder

      -

      -
      -
      - -
      -
      -
      - Cancel - Save -
      -
      -
      -

      -
      - OK -
      -
      -
      -
      -

      -
      -
      - CANCEL - OK -
      -
      -
      +
      +
        +
        +
        +

        Add new folder

        +

        +
        +
        + +
        +
        +
        + Cancel + Save +
        +
        +
        +

        +
        + OK +
        +
        +
        +
        +

        +
        +
        + CANCEL + OK +
        +
        +
        -
        -
        -
        - -
        - -
        -
        - - - - - - - -
        - New folder -
        - Paste to folder -
        -
        -
        -
        \ No newline at end of file +
        +
        +
        + +
        + +
        +
        + + + + + + + +
        + New folder +
        + Paste to folder +
        +
        +
        +
        \ No newline at end of file