Index: ui/file_manager/file_manager/common/js/util.js |
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js |
deleted file mode 100644 |
index 02620223076f1a782f543a55f66ffab5ef3e889d..0000000000000000000000000000000000000000 |
--- a/ui/file_manager/file_manager/common/js/util.js |
+++ /dev/null |
@@ -1,1013 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-'use strict'; |
- |
-/** |
- * Namespace for utility functions. |
- */ |
-var util = {}; |
- |
-/** |
- * @param {string} name File error name. |
- * @return {string} Translated file error string. |
- */ |
-util.getFileErrorString = function(name) { |
- var candidateMessageFragment; |
- switch (name) { |
- case 'NotFoundError': |
- candidateMessageFragment = 'NOT_FOUND'; |
- break; |
- case 'SecurityError': |
- candidateMessageFragment = 'SECURITY'; |
- break; |
- case 'NotReadableError': |
- candidateMessageFragment = 'NOT_READABLE'; |
- break; |
- case 'NoModificationAllowedError': |
- candidateMessageFragment = 'NO_MODIFICATION_ALLOWED'; |
- break; |
- case 'InvalidStateError': |
- candidateMessageFragment = 'INVALID_STATE'; |
- break; |
- case 'InvalidModificationError': |
- candidateMessageFragment = 'INVALID_MODIFICATION'; |
- break; |
- case 'PathExistsError': |
- candidateMessageFragment = 'PATH_EXISTS'; |
- break; |
- case 'QuotaExceededError': |
- candidateMessageFragment = 'QUOTA_EXCEEDED'; |
- break; |
- } |
- |
- return loadTimeData.getString('FILE_ERROR_' + candidateMessageFragment) || |
- loadTimeData.getString('FILE_ERROR_GENERIC'); |
-}; |
- |
-/** |
- * Mapping table for FileError.code style enum to DOMError.name string. |
- * |
- * @enum {string} |
- * @const |
- */ |
-util.FileError = { |
- ABORT_ERR: 'AbortError', |
- INVALID_MODIFICATION_ERR: 'InvalidModificationError', |
- INVALID_STATE_ERR: 'InvalidStateError', |
- NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError', |
- NOT_FOUND_ERR: 'NotFoundError', |
- NOT_READABLE_ERR: 'NotReadable', |
- PATH_EXISTS_ERR: 'PathExistsError', |
- QUOTA_EXCEEDED_ERR: 'QuotaExceededError', |
- TYPE_MISMATCH_ERR: 'TypeMismatchError', |
- ENCODING_ERR: 'EncodingError', |
-}; |
-Object.freeze(util.FileError); |
- |
-/** |
- * @param {string} str String to escape. |
- * @return {string} Escaped string. |
- */ |
-util.htmlEscape = function(str) { |
- return str.replace(/[<>&]/g, function(entity) { |
- switch (entity) { |
- case '<': return '<'; |
- case '>': return '>'; |
- case '&': return '&'; |
- } |
- }); |
-}; |
- |
-/** |
- * @param {string} str String to unescape. |
- * @return {string} Unescaped string. |
- */ |
-util.htmlUnescape = function(str) { |
- return str.replace(/&(lt|gt|amp);/g, function(entity) { |
- switch (entity) { |
- case '<': return '<'; |
- case '>': return '>'; |
- case '&': return '&'; |
- } |
- }); |
-}; |
- |
-/** |
- * Renames the entry to newName. |
- * @param {Entry} entry The entry to be renamed. |
- * @param {string} newName The new name. |
- * @param {function(Entry)} successCallback Callback invoked when the rename |
- * is successfully done. |
- * @param {function(DOMError)} errorCallback Callback invoked when an error |
- * is found. |
- */ |
-util.rename = function(entry, newName, successCallback, errorCallback) { |
- entry.getParent(function(parentEntry) { |
- var parent = /** @type {!DirectoryEntry} */ (parentEntry); |
- |
- // Before moving, we need to check if there is an existing entry at |
- // parent/newName, since moveTo will overwrite it. |
- // Note that this way has some timing issue. After existing check, |
- // a new entry may be create on background. However, there is no way not to |
- // overwrite the existing file, unfortunately. The risk should be low, |
- // assuming the unsafe period is very short. |
- (entry.isFile ? parent.getFile : parent.getDirectory).call( |
- parent, newName, {create: false}, |
- function(entry) { |
- // The entry with the name already exists. |
- errorCallback(util.createDOMError(util.FileError.PATH_EXISTS_ERR)); |
- }, |
- function(error) { |
- if (error.name != util.FileError.NOT_FOUND_ERR) { |
- // Unexpected error is found. |
- errorCallback(error); |
- return; |
- } |
- |
- // No existing entry is found. |
- entry.moveTo(parent, newName, successCallback, errorCallback); |
- }); |
- }, errorCallback); |
-}; |
- |
-/** |
- * Remove a file or a directory. |
- * @param {Entry} entry The entry to remove. |
- * @param {function()} onSuccess The success callback. |
- * @param {function(DOMError)} onError The error callback. |
- */ |
-util.removeFileOrDirectory = function(entry, onSuccess, onError) { |
- if (entry.isDirectory) |
- entry.removeRecursively(onSuccess, onError); |
- else |
- entry.remove(onSuccess, onError); |
-}; |
- |
-/** |
- * Convert a number of bytes into a human friendly format, using the correct |
- * number separators. |
- * |
- * @param {number} bytes The number of bytes. |
- * @return {string} Localized string. |
- */ |
-util.bytesToString = function(bytes) { |
- // Translation identifiers for size units. |
- var UNITS = ['SIZE_BYTES', |
- 'SIZE_KB', |
- 'SIZE_MB', |
- 'SIZE_GB', |
- 'SIZE_TB', |
- 'SIZE_PB']; |
- |
- // Minimum values for the units above. |
- var STEPS = [0, |
- Math.pow(2, 10), |
- Math.pow(2, 20), |
- Math.pow(2, 30), |
- Math.pow(2, 40), |
- Math.pow(2, 50)]; |
- |
- var str = function(n, u) { |
- return strf(u, n.toLocaleString()); |
- }; |
- |
- var fmt = function(s, u) { |
- var rounded = Math.round(bytes / s * 10) / 10; |
- return str(rounded, u); |
- }; |
- |
- // Less than 1KB is displayed like '80 bytes'. |
- if (bytes < STEPS[1]) { |
- return str(bytes, UNITS[0]); |
- } |
- |
- // Up to 1MB is displayed as rounded up number of KBs. |
- if (bytes < STEPS[2]) { |
- var rounded = Math.ceil(bytes / STEPS[1]); |
- return str(rounded, UNITS[1]); |
- } |
- |
- // This loop index is used outside the loop if it turns out |bytes| |
- // requires the largest unit. |
- var i; |
- |
- for (i = 2 /* MB */; i < UNITS.length - 1; i++) { |
- if (bytes < STEPS[i + 1]) |
- return fmt(STEPS[i], UNITS[i]); |
- } |
- |
- return fmt(STEPS[i], UNITS[i]); |
-}; |
- |
-/** |
- * Utility function to read specified range of bytes from file |
- * @param {File} file The file to read. |
- * @param {number} begin Starting byte(included). |
- * @param {number} end Last byte(excluded). |
- * @param {function(File, ByteReader)} callback Callback to invoke. |
- * @param {function(string)} onError Error handler. |
- */ |
-util.readFileBytes = function(file, begin, end, callback, onError) { |
- var fileReader = new FileReader(); |
- fileReader.onerror = function(event) { |
- onError(event.type); |
- }; |
- fileReader.onloadend = function() { |
- callback(file, new ByteReader( |
- /** @type {ArrayBuffer} */ (fileReader.result))); |
- }; |
- fileReader.readAsArrayBuffer(file.slice(begin, end)); |
-}; |
- |
-/** |
- * Returns a string '[Ctrl-][Alt-][Shift-][Meta-]' depending on the event |
- * modifiers. Convenient for writing out conditions in keyboard handlers. |
- * |
- * @param {Event} event The keyboard event. |
- * @return {string} Modifiers. |
- */ |
-util.getKeyModifiers = function(event) { |
- return (event.ctrlKey ? 'Ctrl-' : '') + |
- (event.altKey ? 'Alt-' : '') + |
- (event.shiftKey ? 'Shift-' : '') + |
- (event.metaKey ? 'Meta-' : ''); |
-}; |
- |
-/** |
- * @param {Element} element Element to transform. |
- * @param {Object} transform Transform object, |
- * contains scaleX, scaleY and rotate90 properties. |
- */ |
-util.applyTransform = function(element, transform) { |
- element.style.webkitTransform = |
- transform ? 'scaleX(' + transform.scaleX + ') ' + |
- 'scaleY(' + transform.scaleY + ') ' + |
- 'rotate(' + transform.rotate90 * 90 + 'deg)' : |
- ''; |
-}; |
- |
-/** |
- * Extracts path from filesystem: URL. |
- * @param {string} url Filesystem URL. |
- * @return {?string} The path. |
- */ |
-util.extractFilePath = function(url) { |
- var match = |
- /^filesystem:[\w-]*:\/\/[\w]*\/(external|persistent|temporary)(\/.*)$/. |
- exec(url); |
- var path = match && match[2]; |
- if (!path) return null; |
- return decodeURIComponent(path); |
-}; |
- |
-/** |
- * A shortcut function to create a child element with given tag and class. |
- * |
- * @param {Element} parent Parent element. |
- * @param {string=} opt_className Class name. |
- * @param {string=} opt_tag Element tag, DIV is omitted. |
- * @return {Element} Newly created element. |
- */ |
-util.createChild = function(parent, opt_className, opt_tag) { |
- var child = parent.ownerDocument.createElement(opt_tag || 'div'); |
- if (opt_className) |
- child.className = opt_className; |
- parent.appendChild(child); |
- return child; |
-}; |
- |
-/** |
- * Updates the app state. |
- * |
- * @param {string} currentDirectoryURL Currently opened directory as an URL. |
- * If null the value is left unchanged. |
- * @param {string} selectionURL Currently selected entry as an URL. If null the |
- * value is left unchanged. |
- * @param {string|Object=} opt_param Additional parameters, to be stored. If |
- * null, then left unchanged. |
- */ |
-util.updateAppState = function(currentDirectoryURL, selectionURL, opt_param) { |
- window.appState = window.appState || {}; |
- if (opt_param !== undefined && opt_param !== null) |
- window.appState.params = opt_param; |
- if (currentDirectoryURL !== null) |
- window.appState.currentDirectoryURL = currentDirectoryURL; |
- if (selectionURL !== null) |
- window.appState.selectionURL = selectionURL; |
- util.saveAppState(); |
-}; |
- |
-/** |
- * Returns a translated string. |
- * |
- * Wrapper function to make dealing with translated strings more concise. |
- * Equivalent to loadTimeData.getString(id). |
- * |
- * @param {string} id The id of the string to return. |
- * @return {string} The translated string. |
- */ |
-function str(id) { |
- return loadTimeData.getString(id); |
-} |
- |
-/** |
- * Returns a translated string with arguments replaced. |
- * |
- * Wrapper function to make dealing with translated strings more concise. |
- * Equivalent to loadTimeData.getStringF(id, ...). |
- * |
- * @param {string} id The id of the string to return. |
- * @param {...*} var_args The values to replace into the string. |
- * @return {string} The translated string with replaced values. |
- */ |
-function strf(id, var_args) { |
- return loadTimeData.getStringF.apply(loadTimeData, arguments); |
-} |
- |
-/** |
- * @return {boolean} True if Files.app is running as an open files or a select |
- * folder dialog. False otherwise. |
- */ |
-util.runningInBrowser = function() { |
- return !window.appID; |
-}; |
- |
-/** |
- * Attach page load handler. |
- * @param {function()} handler Application-specific load handler. |
- */ |
-util.addPageLoadHandler = function(handler) { |
- document.addEventListener('DOMContentLoaded', function() { |
- handler(); |
- }); |
-}; |
- |
-/** |
- * Save app launch data to the local storage. |
- */ |
-util.saveAppState = function() { |
- if (!window.appState) |
- return; |
- var items = {}; |
- |
- items[window.appID] = JSON.stringify(window.appState); |
- chrome.storage.local.set(items); |
-}; |
- |
-/** |
- * AppCache is a persistent timestamped key-value storage backed by |
- * HTML5 local storage. |
- * |
- * It is not designed for frequent access. In order to avoid costly |
- * localStorage iteration all data is kept in a single localStorage item. |
- * There is no in-memory caching, so concurrent access is _almost_ safe. |
- * |
- * TODO(kaznacheev) Reimplement this based on Indexed DB. |
- */ |
-util.AppCache = function() {}; |
- |
-/** |
- * Local storage key. |
- */ |
-util.AppCache.KEY = 'AppCache'; |
- |
-/** |
- * Max number of items. |
- */ |
-util.AppCache.CAPACITY = 100; |
- |
-/** |
- * Default lifetime. |
- */ |
-util.AppCache.LIFETIME = 30 * 24 * 60 * 60 * 1000; // 30 days. |
- |
-/** |
- * @param {string} key Key. |
- * @param {function(number)} callback Callback accepting a value. |
- */ |
-util.AppCache.getValue = function(key, callback) { |
- util.AppCache.read_(function(map) { |
- var entry = map[key]; |
- callback(entry && entry.value); |
- }); |
-}; |
- |
-/** |
- * Update the cache. |
- * |
- * @param {string} key Key. |
- * @param {string} value Value. Remove the key if value is null. |
- * @param {number=} opt_lifetime Maximum time to keep an item (in milliseconds). |
- */ |
-util.AppCache.update = function(key, value, opt_lifetime) { |
- util.AppCache.read_(function(map) { |
- if (value != null) { |
- map[key] = { |
- value: value, |
- expire: Date.now() + (opt_lifetime || util.AppCache.LIFETIME) |
- }; |
- } else if (key in map) { |
- delete map[key]; |
- } else { |
- return; // Nothing to do. |
- } |
- util.AppCache.cleanup_(map); |
- util.AppCache.write_(map); |
- }); |
-}; |
- |
-/** |
- * @param {function(Object)} callback Callback accepting a map of timestamped |
- * key-value pairs. |
- * @private |
- */ |
-util.AppCache.read_ = function(callback) { |
- chrome.storage.local.get(util.AppCache.KEY, function(values) { |
- var json = values[util.AppCache.KEY]; |
- if (json) { |
- try { |
- callback(/** @type {Object} */ (JSON.parse(json))); |
- } catch (e) { |
- // The local storage item somehow got messed up, start fresh. |
- } |
- } |
- callback({}); |
- }); |
-}; |
- |
-/** |
- * @param {Object} map A map of timestamped key-value pairs. |
- * @private |
- */ |
-util.AppCache.write_ = function(map) { |
- var items = {}; |
- items[util.AppCache.KEY] = JSON.stringify(map); |
- chrome.storage.local.set(items); |
-}; |
- |
-/** |
- * Remove over-capacity and obsolete items. |
- * |
- * @param {Object} map A map of timestamped key-value pairs. |
- * @private |
- */ |
-util.AppCache.cleanup_ = function(map) { |
- // Sort keys by ascending timestamps. |
- var keys = []; |
- for (var key in map) { |
- if (map.hasOwnProperty(key)) |
- keys.push(key); |
- } |
- keys.sort(function(a, b) { return map[a].expire - map[b].expire; }); |
- |
- var cutoff = Date.now(); |
- |
- var obsolete = 0; |
- while (obsolete < keys.length && |
- map[keys[obsolete]].expire < cutoff) { |
- obsolete++; |
- } |
- |
- var overCapacity = Math.max(0, keys.length - util.AppCache.CAPACITY); |
- |
- var itemsToDelete = Math.max(obsolete, overCapacity); |
- for (var i = 0; i != itemsToDelete; i++) { |
- delete map[keys[i]]; |
- } |
-}; |
- |
-/** |
- * Load an image. |
- * |
- * @param {HTMLImageElement} image Image element. |
- * @param {string} url Source url. |
- * @param {Object=} opt_options Hash array of options, eg. width, height, |
- * maxWidth, maxHeight, scale, cache. |
- * @param {function()=} opt_isValid Function returning false iff the task |
- * is not valid and should be aborted. |
- * @return {?number} Task identifier or null if fetched immediately from |
- * cache. |
- */ |
-util.loadImage = function(image, url, opt_options, opt_isValid) { |
- return ImageLoaderClient.loadToImage(url, |
- image, |
- opt_options || {}, |
- function() {}, |
- function() { |
- image.onerror(new Event('load-error')); |
- }, |
- opt_isValid); |
-}; |
- |
-/** |
- * Cancels loading an image. |
- * @param {number} taskId Task identifier returned by util.loadImage(). |
- */ |
-util.cancelLoadImage = function(taskId) { |
- ImageLoaderClient.getInstance().cancel(taskId); |
-}; |
- |
-/** |
- * Returns true if the board of the device matches the given prefix. |
- * @param {string} boardPrefix The board prefix to match against. |
- * (ex. "x86-mario". Prefix is used as the actual board name comes with |
- * suffix like "x86-mario-something". |
- * @return {boolean} True if the board of the device matches the given prefix. |
- */ |
-util.boardIs = function(boardPrefix) { |
- // The board name should be lower-cased, but making it case-insensitive for |
- // backward compatibility just in case. |
- var board = str('CHROMEOS_RELEASE_BOARD'); |
- var pattern = new RegExp('^' + boardPrefix, 'i'); |
- return board.match(pattern) != null; |
-}; |
- |
-/** |
- * Adds an isFocused method to the current window object. |
- */ |
-util.addIsFocusedMethod = function() { |
- var focused = true; |
- |
- window.addEventListener('focus', function() { |
- focused = true; |
- }); |
- |
- window.addEventListener('blur', function() { |
- focused = false; |
- }); |
- |
- /** |
- * @return {boolean} True if focused. |
- */ |
- window.isFocused = function() { |
- return focused; |
- }; |
-}; |
- |
-/** |
- * Checks, if the Files.app's window is in a full screen mode. |
- * |
- * @param {chrome.app.window.AppWindow} appWindow App window to be maximized. |
- * @return {boolean} True if the full screen mode is enabled. |
- */ |
-util.isFullScreen = function(appWindow) { |
- if (appWindow) { |
- return appWindow.isFullscreen(); |
- } else { |
- console.error('App window not passed. Unable to check status of ' + |
- 'the full screen mode.'); |
- return false; |
- } |
-}; |
- |
-/** |
- * Toggles the full screen mode. |
- * |
- * @param {chrome.app.window.AppWindow} appWindow App window to be maximized. |
- * @param {boolean} enabled True for enabling, false for disabling. |
- */ |
-util.toggleFullScreen = function(appWindow, enabled) { |
- if (appWindow) { |
- if (enabled) |
- appWindow.fullscreen(); |
- else |
- appWindow.restore(); |
- return; |
- } |
- |
- console.error( |
- 'App window not passed. Unable to toggle the full screen mode.'); |
-}; |
- |
-/** |
- * The type of a file operation. |
- * @enum {string} |
- * @const |
- */ |
-util.FileOperationType = { |
- COPY: 'COPY', |
- MOVE: 'MOVE', |
- ZIP: 'ZIP', |
-}; |
-Object.freeze(util.FileOperationType); |
- |
-/** |
- * The type of a file operation error. |
- * @enum {number} |
- * @const |
- */ |
-util.FileOperationErrorType = { |
- UNEXPECTED_SOURCE_FILE: 0, |
- TARGET_EXISTS: 1, |
- FILESYSTEM_ERROR: 2, |
-}; |
-Object.freeze(util.FileOperationErrorType); |
- |
-/** |
- * The kind of an entry changed event. |
- * @enum {number} |
- * @const |
- */ |
-util.EntryChangedKind = { |
- CREATED: 0, |
- DELETED: 1, |
-}; |
-Object.freeze(util.EntryChangedKind); |
- |
-/** |
- * Obtains whether an entry is fake or not. |
- * @param {(Entry|Object)} entry Entry or a fake entry. |
- * @return {boolean} True if the given entry is fake. |
- */ |
-util.isFakeEntry = function(entry) { |
- return !('getParent' in entry); |
-}; |
- |
-/** |
- * Creates an instance of UserDOMError with given error name that looks like a |
- * FileError except that it does not have the deprecated FileError.code member. |
- * |
- * @param {string} name Error name for the file error. |
- * @return {DOMError} DOMError instance |
- */ |
-util.createDOMError = function(name) { |
- return new util.UserDOMError(name); |
-}; |
- |
-/** |
- * Creates a DOMError-like object to be used in place of returning file errors. |
- * |
- * @param {string} name Error name for the file error. |
- * @extends {DOMError} |
- * @constructor |
- */ |
-util.UserDOMError = function(name) { |
- /** |
- * @type {string} |
- * @private |
- */ |
- this.name_ = name; |
- Object.freeze(this); |
-}; |
- |
-util.UserDOMError.prototype = { |
- /** |
- * @return {string} File error name. |
- */ |
- get name() { return this.name_; |
- } |
-}; |
- |
-/** |
- * Compares two entries. |
- * @param {Entry|Object} entry1 The entry to be compared. Can be a fake. |
- * @param {Entry|Object} entry2 The entry to be compared. Can be a fake. |
- * @return {boolean} True if the both entry represents a same file or |
- * directory. Returns true if both entries are null. |
- */ |
-util.isSameEntry = function(entry1, entry2) { |
- if (!entry1 && !entry2) |
- return true; |
- if (!entry1 || !entry2) |
- return false; |
- return entry1.toURL() === entry2.toURL(); |
-}; |
- |
-/** |
- * Compares two file systems. |
- * @param {FileSystem} fileSystem1 The file system to be compared. |
- * @param {FileSystem} fileSystem2 The file system to be compared. |
- * @return {boolean} True if the both file systems are equal. Also, returns true |
- * if both file systems are null. |
- */ |
-util.isSameFileSystem = function(fileSystem1, fileSystem2) { |
- if (!fileSystem1 && !fileSystem2) |
- return true; |
- if (!fileSystem1 || !fileSystem2) |
- return false; |
- return util.isSameEntry(fileSystem1.root, fileSystem2.root); |
-}; |
- |
-/** |
- * Collator for sorting. |
- * @type {Intl.Collator} |
- */ |
-util.collator = new Intl.Collator( |
- [], {usage: 'sort', numeric: true, sensitivity: 'base'}); |
- |
-/** |
- * Compare by name. The 2 entries must be in same directory. |
- * @param {Entry} entry1 First entry. |
- * @param {Entry} entry2 Second entry. |
- * @return {number} Compare result. |
- */ |
-util.compareName = function(entry1, entry2) { |
- return util.collator.compare(entry1.name, entry2.name); |
-}; |
- |
-/** |
- * Compare by path. |
- * @param {Entry} entry1 First entry. |
- * @param {Entry} entry2 Second entry. |
- * @return {number} Compare result. |
- */ |
-util.comparePath = function(entry1, entry2) { |
- return util.collator.compare(entry1.fullPath, entry2.fullPath); |
-}; |
- |
-/** |
- * Checks if the child entry is a descendant of another entry. If the entries |
- * point to the same file or directory, then returns false. |
- * |
- * @param {DirectoryEntry|Object} ancestorEntry The ancestor directory entry. |
- * Can be a fake. |
- * @param {Entry|Object} childEntry The child entry. Can be a fake. |
- * @return {boolean} True if the child entry is contained in the ancestor path. |
- */ |
-util.isDescendantEntry = function(ancestorEntry, childEntry) { |
- if (!ancestorEntry.isDirectory) |
- return false; |
- if (!util.isSameFileSystem(ancestorEntry.filesystem, childEntry.filesystem)) |
- return false; |
- if (util.isSameEntry(ancestorEntry, childEntry)) |
- return false; |
- if (util.isFakeEntry(ancestorEntry) || util.isFakeEntry(childEntry)) |
- return false; |
- |
- // Check if the ancestor's path with trailing slash is a prefix of child's |
- // path. |
- var ancestorPath = ancestorEntry.fullPath; |
- if (ancestorPath.slice(-1) !== '/') |
- ancestorPath += '/'; |
- return childEntry.fullPath.indexOf(ancestorPath) === 0; |
-}; |
- |
-/** |
- * Visit the URL. |
- * |
- * If the browser is opening, the url is opened in a new tag, otherwise the url |
- * is opened in a new window. |
- * |
- * @param {string} url URL to visit. |
- */ |
-util.visitURL = function(url) { |
- window.open(url); |
-}; |
- |
-/** |
- * Returns normalized current locale, or default locale - 'en'. |
- * @return {string} Current locale |
- */ |
-util.getCurrentLocaleOrDefault = function() { |
- // chrome.i18n.getMessage('@@ui_locale') can't be used in packed app. |
- // Instead, we pass it from C++-side with strings. |
- return str('UI_LOCALE') || 'en'; |
-}; |
- |
-/** |
- * Converts array of entries to an array of corresponding URLs. |
- * @param {Array.<Entry>} entries Input array of entries. |
- * @return {Array.<string>} Output array of URLs. |
- */ |
-util.entriesToURLs = function(entries) { |
- return entries.map(function(entry) { |
- return entry.toURL(); |
- }); |
-}; |
- |
-/** |
- * Converts array of URLs to an array of corresponding Entries. |
- * |
- * @param {Array.<string>} urls Input array of URLs. |
- * @param {function(Array.<Entry>, Array.<URL>)=} opt_callback Completion |
- * callback with array of success Entries and failure URLs. |
- * @return {Promise} Promise fulfilled with the object that has entries property |
- * and failureUrls property. The promise is never rejected. |
- */ |
-util.URLsToEntries = function(urls, opt_callback) { |
- var promises = urls.map(function(url) { |
- return new Promise(window.webkitResolveLocalFileSystemURL.bind(null, url)). |
- then(function(entry) { |
- return {entry: entry}; |
- }, function(failureUrl) { |
- // Not an error. Possibly, the file is not accessible anymore. |
- console.warn('Failed to resolve the file with url: ' + url + '.'); |
- return {failureUrl: url}; |
- }); |
- }); |
- var resultPromise = Promise.all(promises).then(function(results) { |
- var entries = []; |
- var failureUrls = []; |
- for (var i = 0; i < results.length; i++) { |
- if ('entry' in results[i]) |
- entries.push(results[i].entry); |
- if ('failureUrl' in results[i]) { |
- failureUrls.push(results[i].failureUrl); |
- } |
- } |
- return { |
- entries: entries, |
- failureUrls: failureUrls |
- }; |
- }); |
- |
- // Invoke the callback. If opt_callback is specified, resultPromise is still |
- // returned and fulfilled with a result. |
- if (opt_callback) { |
- resultPromise.then(function(result) { |
- opt_callback(result.entries, result.failureUrls); |
- }).catch(function(error) { |
- console.error( |
- 'util.URLsToEntries is failed.', |
- error.stack ? error.stack : error); |
- }); |
- } |
- |
- return resultPromise; |
-}; |
- |
-/** |
- * Returns whether the window is teleported or not. |
- * @param {Window} window Window. |
- * @return {Promise.<boolean>} Whether the window is teleported or not. |
- */ |
-util.isTeleported = function(window) { |
- return new Promise(function(onFulfilled) { |
- window.chrome.fileManagerPrivate.getProfiles( |
- function(profiles, currentId, displayedId) { |
- onFulfilled(currentId !== displayedId); |
- }); |
- }); |
-}; |
- |
-/** |
- * Sets up and shows the alert to inform a user the task is opened in the |
- * desktop of the running profile. |
- * |
- * TODO(hirono): Move the function from the util namespace. |
- * @param {cr.ui.dialogs.AlertDialog} alertDialog Alert dialog to be shown. |
- * @param {Array.<Entry>} entries List of opened entries. |
- */ |
-util.showOpenInOtherDesktopAlert = function(alertDialog, entries) { |
- if (!entries.length) |
- return; |
- chrome.fileManagerPrivate.getProfiles( |
- function(profiles, currentId, displayedId) { |
- // Find strings. |
- var displayName; |
- for (var i = 0; i < profiles.length; i++) { |
- if (profiles[i].profileId === currentId) { |
- displayName = profiles[i].displayName; |
- break; |
- } |
- } |
- if (!displayName) { |
- console.warn('Display name is not found.'); |
- return; |
- } |
- |
- var title = entries.length > 1 ? |
- entries[0].name + '\u2026' /* ellipsis */ : entries[0].name; |
- var message = strf(entries.length > 1 ? |
- 'OPEN_IN_OTHER_DESKTOP_MESSAGE_PLURAL' : |
- 'OPEN_IN_OTHER_DESKTOP_MESSAGE', |
- displayName, |
- currentId); |
- |
- // Show the dialog. |
- alertDialog.showWithTitle(title, message, null, null, null); |
- }.bind(this)); |
-}; |
- |
-/** |
- * Runs chrome.test.sendMessage in test environment. Does nothing if running |
- * in production environment. |
- * |
- * @param {string} message Test message to send. |
- */ |
-util.testSendMessage = function(message) { |
- var test = chrome.test || window.top.chrome.test; |
- if (test) |
- test.sendMessage(message); |
-}; |
- |
-/** |
- * Extracts the extension of the path. |
- * |
- * Examples: |
- * util.splitExtension('abc.ext') -> ['abc', '.ext'] |
- * util.splitExtension('a/b/abc.ext') -> ['a/b/abc', '.ext'] |
- * util.splitExtension('a/b') -> ['a/b', ''] |
- * util.splitExtension('.cshrc') -> ['', '.cshrc'] |
- * util.splitExtension('a/b.backup/hoge') -> ['a/b.backup/hoge', ''] |
- * |
- * @param {string} path Path to be extracted. |
- * @return {Array.<string>} Filename and extension of the given path. |
- */ |
-util.splitExtension = function(path) { |
- var dotPosition = path.lastIndexOf('.'); |
- if (dotPosition <= path.lastIndexOf('/')) |
- dotPosition = -1; |
- |
- var filename = dotPosition != -1 ? path.substr(0, dotPosition) : path; |
- var extension = dotPosition != -1 ? path.substr(dotPosition) : ''; |
- return [filename, extension]; |
-}; |
- |
-/** |
- * Returns the localized name of the entry. |
- * |
- * @param {(VolumeManager|VolumeManagerWrapper)} volumeManager The volume |
- * manager. |
- * @param {!Entry} entry The entry to be retrieve the name of. |
- * @return {?string} The localized name. |
- */ |
-util.getEntryLabel = function(volumeManager, entry) { |
- var locationInfo = volumeManager.getLocationInfo(entry); |
- |
- if (locationInfo && locationInfo.isRootEntry) { |
- switch (locationInfo.rootType) { |
- case VolumeManagerCommon.RootType.DOWNLOADS: |
- return str('DOWNLOADS_DIRECTORY_LABEL'); |
- case VolumeManagerCommon.RootType.DRIVE: |
- return str('DRIVE_MY_DRIVE_LABEL'); |
- case VolumeManagerCommon.RootType.DRIVE_OFFLINE: |
- return str('DRIVE_OFFLINE_COLLECTION_LABEL'); |
- case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME: |
- return str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL'); |
- case VolumeManagerCommon.RootType.DRIVE_RECENT: |
- return str('DRIVE_RECENT_COLLECTION_LABEL'); |
- case VolumeManagerCommon.RootType.DRIVE_OTHER: |
- case VolumeManagerCommon.RootType.DOWNLOADS: |
- case VolumeManagerCommon.RootType.ARCHIVE: |
- case VolumeManagerCommon.RootType.REMOVABLE: |
- case VolumeManagerCommon.RootType.MTP: |
- case VolumeManagerCommon.RootType.PROVIDED: |
- return locationInfo.volumeInfo.label; |
- default: |
- console.error('Unsupported root type: ' + locationInfo.rootType); |
- return locationInfo.volumeInfo.label; |
- } |
- } |
- |
- return entry.name; |
-}; |
- |
-/** |
- * Checks if the specified set of allowed effects contains the given effect. |
- * See: http://www.w3.org/TR/html5/editing.html#the-datatransfer-interface |
- * |
- * @param {string} effectAllowed The string denoting the set of allowed effects. |
- * @param {string} dropEffect The effect to be checked. |
- * @return {boolean} True if |dropEffect| is included in |effectAllowed|. |
- */ |
-util.isDropEffectAllowed = function(effectAllowed, dropEffect) { |
- return effectAllowed === 'all' || |
- effectAllowed.toLowerCase().indexOf(dropEffect) !== -1; |
-}; |
- |
-/** |
- * Verifies the user entered name for file or folder to be created or |
- * renamed to. Name restrictions must correspond to File API restrictions |
- * (see DOMFilePath::isValidPath). Curernt WebKit implementation is |
- * out of date (spec is |
- * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going to |
- * be fixed. Shows message box if the name is invalid. |
- * |
- * It also verifies if the name length is in the limit of the filesystem. |
- * |
- * @param {DirectoryEntry} parentEntry The URL of the parent directory entry. |
- * @param {string} name New file or folder name. |
- * @param {boolean} filterHiddenOn Whether to report the hidden file name error |
- * or not. |
- * @return {Promise} Promise fulfilled on success, or rejected with the error |
- * message. |
- */ |
-util.validateFileName = function(parentEntry, name, filterHiddenOn) { |
- var testResult = /[\/\\\<\>\:\?\*\"\|]/.exec(name); |
- var msg; |
- if (testResult) |
- return Promise.reject(strf('ERROR_INVALID_CHARACTER', testResult[0])); |
- else if (/^\s*$/i.test(name)) |
- return Promise.reject(str('ERROR_WHITESPACE_NAME')); |
- else if (/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name)) |
- return Promise.reject(str('ERROR_RESERVED_NAME')); |
- else if (filterHiddenOn && /\.crdownload$/i.test(name)) |
- return Promise.reject(str('ERROR_RESERVED_NAME')); |
- else if (filterHiddenOn && name[0] == '.') |
- return Promise.reject(str('ERROR_HIDDEN_NAME')); |
- |
- return new Promise(function(fulfill, reject) { |
- chrome.fileManagerPrivate.validatePathNameLength( |
- parentEntry.toURL(), |
- name, |
- function(valid) { |
- if (valid) |
- fulfill(null); |
- else |
- reject(str('ERROR_LONG_NAME')); |
- }); |
- }); |
-}; |