OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 'use strict'; | |
6 | |
7 /** | |
8 * Type of a root directory. | |
9 * @enum | |
10 */ | |
11 var RootType = { | |
12 DOWNLOADS: 'downloads', | |
13 ARCHIVE: 'archive', | |
14 REMOVABLE: 'removable', | |
15 DRIVE: 'drive', | |
16 DRIVE_OFFLINE: 'drive_offline', // A fake root. Not the actual filesystem. | |
17 DRIVE_SHARED_WITH_ME: 'drive_shared_with_me', // A fake root. | |
18 DRIVE_RECENT: 'drive_recent' // A fake root. | |
19 }; | |
20 | |
21 /** | |
22 * Top directory for each root type. | |
23 * @type {Object.<RootType,string>} | |
24 */ | |
25 var RootDirectory = { | |
26 DOWNLOADS: '/Downloads', | |
27 ARCHIVE: '/archive', | |
28 REMOVABLE: '/removable', | |
29 DRIVE: '/drive', | |
30 DRIVE_OFFLINE: '/drive_offline', // A fake root. Not the actual filesystem. | |
31 DRIVE_SHARED_WITH_ME: '/drive_shared_with_me', // A fake root. | |
32 DRIVE_RECENT: '/drive_recent' // A fake root. | |
33 }; | |
34 | |
35 /** | |
36 * Sub root directory for Drive. "root" and "other". This is not used now. | |
37 * TODO(haruki): Add namespaces support. http://crbug.com/174233. | |
38 * @enum | |
39 */ | |
40 var DriveSubRootDirectory = { | |
41 ROOT: 'root', | |
42 OTHER: 'other', | |
43 }; | |
44 | |
45 var PathUtil = {}; | |
46 | |
47 /** | |
48 * The path to the default directory. | |
49 * @type {string} | |
50 * @const | |
51 */ | |
52 PathUtil.DEFAULT_DIRECTORY = RootDirectory.DOWNLOADS; | |
53 | |
54 /** | |
55 * Checks if the given path represents a special search. Fake entries in | |
56 * RootDirectory correspond to special searches. | |
57 * @param {string} path Path to check. | |
58 * @return {boolean} True if the given path represents a special search. | |
59 */ | |
60 PathUtil.isSpecialSearchRoot = function(path) { | |
61 var type = PathUtil.getRootType(path); | |
62 return type == RootType.DRIVE_OFFLINE || | |
63 type == RootType.DRIVE_SHARED_WITH_ME || | |
64 type == RootType.DRIVE_RECENT; | |
65 }; | |
66 | |
67 /** | |
68 * Checks |path| and return true if it is under Google Drive or a special | |
69 * search root which represents a special search from Google Drive. | |
70 * @param {string} path Path to check. | |
71 * @return {boolean} True if the given path represents a Drive based path. | |
72 */ | |
73 PathUtil.isDriveBasedPath = function(path) { | |
74 var rootType = PathUtil.getRootType(path); | |
75 return rootType === RootType.DRIVE || | |
76 rootType === RootType.DRIVE_SHARED_WITH_ME || | |
77 rootType === RootType.DRIVE_RECENT || | |
78 rootType === RootType.DRIVE_OFFLINE; | |
79 }; | |
80 | |
81 /** | |
82 * @param {string} path Path starting with '/'. | |
83 * @return {string} Top directory (starting with '/'). | |
84 */ | |
85 PathUtil.getTopDirectory = function(path) { | |
86 var i = path.indexOf('/', 1); | |
87 return i === -1 ? path : path.substring(0, i); | |
88 }; | |
89 | |
90 /** | |
91 * Obtains the parent path of the specified path. | |
92 * @param {string} path Path string. | |
93 * @return {string} Parent path. | |
94 */ | |
95 PathUtil.getParentDirectory = function(path) { | |
96 if (path[path.length - 1] == '/') | |
97 return PathUtil.getParentDirectory(path.substring(0, path.length - 1)); | |
98 var index = path.lastIndexOf('/'); | |
99 if (index == 0) | |
100 return '/'; | |
101 else if (index == -1) | |
102 return '.'; | |
103 return path.substring(0, index); | |
104 }; | |
105 | |
106 /** | |
107 * @param {string} path Any unix-style path (may start or not start from root). | |
108 * @return {Array.<string>} Path components. | |
109 */ | |
110 PathUtil.split = function(path) { | |
111 var fromRoot = false; | |
112 if (path[0] === '/') { | |
113 fromRoot = true; | |
114 path = path.substring(1); | |
115 } | |
116 | |
117 var components = path.split('/'); | |
118 if (fromRoot) | |
119 components[0] = '/' + components[0]; | |
120 return components; | |
121 }; | |
122 | |
123 /** | |
124 * Returns a directory part of the given |path|. In other words, the path | |
125 * without its base name. | |
126 * | |
127 * Examples: | |
128 * PathUtil.dirname('abc') -> '' | |
129 * PathUtil.dirname('a/b') -> 'a' | |
130 * PathUtil.dirname('a/b/') -> 'a/b' | |
131 * PathUtil.dirname('a/b/c') -> 'a/b' | |
132 * PathUtil.dirname('/') -> '/' | |
133 * PathUtil.dirname('/abc') -> '/' | |
134 * PathUtil.dirname('/abc/def') -> '/abc' | |
135 * PathUtil.dirname('') -> '' | |
136 * | |
137 * @param {string} path The path to be parsed. | |
138 * @return {string} The directory path. | |
139 */ | |
140 PathUtil.dirname = function(path) { | |
141 var index = path.lastIndexOf('/'); | |
142 if (index < 0) | |
143 return ''; | |
144 if (index == 0) | |
145 return '/'; | |
146 return path.substring(0, index); | |
147 }; | |
148 | |
149 /** | |
150 * Returns the base name (the last component) of the given |path|. If the | |
151 * |path| ends with '/', returns an empty component. | |
152 * | |
153 * Examples: | |
154 * PathUtil.basename('abc') -> 'abc' | |
155 * PathUtil.basename('a/b') -> 'b' | |
156 * PathUtil.basename('a/b/') -> '' | |
157 * PathUtil.basename('a/b/c') -> 'c' | |
158 * PathUtil.basename('/') -> '' | |
159 * PathUtil.basename('/abc') -> 'abc' | |
160 * PathUtil.basename('/abc/def') -> 'def' | |
161 * PathUtil.basename('') -> '' | |
162 * | |
163 * @param {string} path The path to be parsed. | |
164 * @return {string} The base name. | |
165 */ | |
166 PathUtil.basename = function(path) { | |
167 var index = path.lastIndexOf('/'); | |
168 return index >= 0 ? path.substring(index + 1) : path; | |
169 }; | |
170 | |
171 /** | |
172 * Join path components into a single path. Can be called either with a list of | |
173 * components as arguments, or with an array of components as the only argument. | |
174 * | |
175 * Examples: | |
176 * Path.join('abc', 'def') -> 'abc/def' | |
177 * Path.join('/', 'abc', 'def/ghi') -> '/abc/def/ghi' | |
178 * Path.join(['/abc/def', 'ghi']) -> '/abc/def/ghi' | |
179 * | |
180 * @return {string} Resulting path. | |
181 */ | |
182 PathUtil.join = function() { | |
183 var components; | |
184 | |
185 if (arguments.length === 1 && typeof(arguments[0]) === 'object') { | |
186 components = arguments[0]; | |
187 } else { | |
188 components = arguments; | |
189 } | |
190 | |
191 var path = ''; | |
192 for (var i = 0; i < components.length; i++) { | |
193 if (components[i][0] === '/') { | |
194 path = components[i]; | |
195 continue; | |
196 } | |
197 if (path.length === 0 || path[path.length - 1] !== '/') | |
198 path += '/'; | |
199 path += components[i]; | |
200 } | |
201 return path; | |
202 }; | |
203 | |
204 /** | |
205 * @param {string} path Path starting with '/'. | |
206 * @return {RootType} RootType.DOWNLOADS, RootType.DRIVE etc. | |
207 */ | |
208 PathUtil.getRootType = function(path) { | |
209 var rootDir = PathUtil.getTopDirectory(path); | |
210 for (var type in RootDirectory) { | |
211 if (rootDir === RootDirectory[type]) | |
212 return RootType[type]; | |
213 } | |
214 }; | |
215 | |
216 /** | |
217 * @param {string} path Any path. | |
218 * @return {string} The root path. | |
219 */ | |
220 PathUtil.getRootPath = function(path) { | |
221 var type = PathUtil.getRootType(path); | |
222 | |
223 if (type == RootType.DOWNLOADS || type == RootType.DRIVE_OFFLINE || | |
224 type == RootType.DRIVE_SHARED_WITH_ME || type == RootType.DRIVE_RECENT) | |
225 return PathUtil.getTopDirectory(path); | |
226 | |
227 if (type == RootType.DRIVE || type == RootType.ARCHIVE || | |
228 type == RootType.REMOVABLE) { | |
229 var components = PathUtil.split(path); | |
230 if (components.length > 1) { | |
231 return PathUtil.join(components[0], components[1]); | |
232 } else { | |
233 return components[0]; | |
234 } | |
235 } | |
236 | |
237 return '/'; | |
238 }; | |
239 | |
240 /** | |
241 * @param {string} path A path. | |
242 * @return {boolean} True if it is a path to the root. | |
243 */ | |
244 PathUtil.isRootPath = function(path) { | |
245 return PathUtil.getRootPath(path) === path; | |
246 }; | |
247 | |
248 /** | |
249 * @param {string} path A root path. | |
250 * @return {boolean} True if the given path is root and user can unmount it. | |
251 */ | |
252 PathUtil.isUnmountableByUser = function(path) { | |
253 if (!PathUtil.isRootPath(path)) | |
254 return false; | |
255 | |
256 var type = PathUtil.getRootType(path); | |
257 return (type == RootType.ARCHIVE || type == RootType.REMOVABLE); | |
258 }; | |
259 | |
260 /** | |
261 * @param {string} parent_path The parent path. | |
262 * @param {string} child_path The child path. | |
263 * @return {boolean} True if |parent_path| is parent file path of |child_path|. | |
264 */ | |
265 PathUtil.isParentPath = function(parent_path, child_path) { | |
266 if (!parent_path || parent_path.length == 0 || | |
267 !child_path || child_path.length == 0) | |
268 return false; | |
269 | |
270 if (parent_path[parent_path.length - 1] != '/') | |
271 parent_path += '/'; | |
272 | |
273 if (child_path[child_path.length - 1] != '/') | |
274 child_path += '/'; | |
275 | |
276 return child_path.indexOf(parent_path) == 0; | |
277 }; | |
278 | |
279 /** | |
280 * Return the localized name for the root. | |
281 * @param {string} path The full path of the root (starting with slash). | |
282 * @return {string} The localized name. | |
283 */ | |
284 PathUtil.getRootLabel = function(path) { | |
285 var str = function(id) { | |
286 return loadTimeData.getString(id); | |
287 }; | |
288 | |
289 if (path === RootDirectory.DOWNLOADS) | |
290 return str('DOWNLOADS_DIRECTORY_LABEL'); | |
291 | |
292 if (path === RootDirectory.ARCHIVE) | |
293 return str('ARCHIVE_DIRECTORY_LABEL'); | |
294 if (PathUtil.isParentPath(RootDirectory.ARCHIVE, path)) | |
295 return path.substring(RootDirectory.ARCHIVE.length + 1); | |
296 | |
297 if (path === RootDirectory.REMOVABLE) | |
298 return str('REMOVABLE_DIRECTORY_LABEL'); | |
299 if (PathUtil.isParentPath(RootDirectory.REMOVABLE, path)) | |
300 return path.substring(RootDirectory.REMOVABLE.length + 1); | |
301 | |
302 // TODO(haruki): Add support for "drive/root" and "drive/other". | |
303 if (path === RootDirectory.DRIVE + '/' + DriveSubRootDirectory.ROOT) | |
304 return str('DRIVE_DIRECTORY_LABEL'); | |
305 | |
306 if (path === RootDirectory.DRIVE_OFFLINE) | |
307 return str('DRIVE_OFFLINE_COLLECTION_LABEL'); | |
308 | |
309 if (path === RootDirectory.DRIVE_SHARED_WITH_ME) | |
310 return str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL'); | |
311 | |
312 if (path === RootDirectory.DRIVE_RECENT) | |
313 return str('DRIVE_RECENT_COLLECTION_LABEL'); | |
314 | |
315 return path; | |
316 }; | |
317 | |
318 /** | |
319 * Return the label of the folder to be shown. Eg. | |
320 * - '/foo/bar/baz' -> 'baz' | |
321 * - '/hoge/fuga/ -> 'fuga' | |
322 * If the directory is root, returns the root label, which is same as | |
323 * PathUtil.getRootLabel(). | |
324 * | |
325 * @param {string} directoryPath The full path of the folder. | |
326 * @return {string} The label to be shown. | |
327 */ | |
328 PathUtil.getFolderLabel = function(directoryPath) { | |
329 var label = ''; | |
330 if (PathUtil.isRootPath(directoryPath)) | |
331 label = PathUtil.getRootLabel(directoryPath); | |
332 | |
333 if (label && label != directoryPath) | |
334 return label; | |
335 | |
336 var matches = directoryPath.match(/([^\/]*)[\/]?$/); | |
337 if (matches[1]) | |
338 return matches[1]; | |
339 | |
340 return directoryPath; | |
341 }; | |
342 | |
343 /** | |
344 * Returns if the given path can be a target path of folder shortcut. | |
345 * | |
346 * @param {string} directoryPath Directory path to be checked. | |
347 * @return {boolean} True if the path can be a target path of the shortcut. | |
348 */ | |
349 PathUtil.isEligibleForFolderShortcut = function(directoryPath) { | |
350 return !PathUtil.isSpecialSearchRoot(directoryPath) && | |
351 !PathUtil.isRootPath(directoryPath) && | |
352 PathUtil.isDriveBasedPath(directoryPath); | |
353 }; | |
354 | |
355 /** | |
356 * Returns the extension of the filename | |
357 * | |
358 * @param {string} filename Filename to be extracted. | |
359 * @return {string} Extension of the given filename. | |
360 */ | |
361 PathUtil.extractExtension = function(filename) { | |
362 if (filename.indexOf('/') != -1) | |
363 filename = filename.substr(filename.lastIndexOf('/') + 1); | |
364 var extension = filename.lastIndexOf('.') != -1 ? | |
365 filename.substr(filename.lastIndexOf('.') + 1) : ''; | |
366 return extension; | |
367 }; | |
OLD | NEW |