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 * Namespace object for file type utility functions.
9 */
10var FileType = {};
11
12/**
13 * Description of known file types.
14 * Pair type-subtype defines order when sorted by file type.
15 */
16FileType.types = [
17  // Images
18  {
19    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'JPEG',
20    pattern: /\.jpe?g$/i
21  },
22  {
23    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'BMP',
24    pattern: /\.bmp$/i
25  },
26  {
27    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'GIF',
28    pattern: /\.gif$/i
29  },
30  {
31    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'ICO',
32    pattern: /\.ico$/i
33  },
34  {
35    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'PNG',
36    pattern: /\.png$/i
37  },
38  {
39    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'WebP',
40    pattern: /\.webp$/i
41  },
42  {
43    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'TIFF',
44    pattern: /\.tiff?$/i
45  },
46
47  // Video
48  {
49    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: '3GP',
50    pattern: /\.3gp$/i
51  },
52  {
53    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'AVI',
54    pattern: /\.avi$/i
55  },
56  {
57    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'QuickTime',
58    pattern: /\.mov$/i
59  },
60  {
61    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'MKV',
62    pattern: /\.mkv$/i
63  },
64  {
65    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'MPEG',
66    pattern: /\.m(p4|4v|pg|peg|pg4|peg4)$/i
67  },
68  {
69    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'OGG',
70    pattern: /\.og(m|v|x)$/i
71  },
72  {
73    type: 'video', name: 'VIDEO_FILE_TYPE', subtype: 'WebM',
74    pattern: /\.webm$/i
75  },
76
77  // Audio
78  {
79    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'AMR',
80    pattern: /\.amr$/i
81  },
82  {
83    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'FLAC',
84    pattern: /\.flac$/i
85  },
86  {
87    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'MP3',
88    pattern: /\.mp3$/i
89  },
90  {
91    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'MPEG',
92    pattern: /\.m4a$/i
93  },
94  {
95    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'OGG',
96    pattern: /\.og(a|g)$/i
97  },
98  {
99    type: 'audio', name: 'AUDIO_FILE_TYPE', subtype: 'WAV',
100    pattern: /\.wav$/i
101  },
102
103  // Text
104  {
105    type: 'text', name: 'PLAIN_TEXT_FILE_TYPE', subtype: 'TXT',
106    pattern: /\.txt$/i
107  },
108
109  // Archive
110  {
111    type: 'archive', name: 'ZIP_ARCHIVE_FILE_TYPE', subtype: 'ZIP',
112    pattern: /\.zip$/i
113  },
114  {
115    type: 'archive', name: 'RAR_ARCHIVE_FILE_TYPE', subtype: 'RAR',
116    pattern: /\.rar$/i
117  },
118  {
119    type: 'archive', name: 'TAR_ARCHIVE_FILE_TYPE', subtype: 'TAR',
120    pattern: /\.tar$/i
121  },
122  {
123    type: 'archive', name: 'TAR_BZIP2_ARCHIVE_FILE_TYPE', subtype: 'TBZ2',
124    pattern: /\.(tar\.bz2|tbz|tbz2)$/i
125  },
126  {
127    type: 'archive', name: 'TAR_GZIP_ARCHIVE_FILE_TYPE', subtype: 'TGZ',
128    pattern: /\.(tar\.|t)gz$/i
129  },
130
131  // Hosted docs.
132  {
133    type: 'hosted', icon: 'gdoc', name: 'GDOC_DOCUMENT_FILE_TYPE',
134    subtype: 'doc', pattern: /\.gdoc$/i
135  },
136  {
137    type: 'hosted', icon: 'gsheet', name: 'GSHEET_DOCUMENT_FILE_TYPE',
138    subtype: 'sheet', pattern: /\.gsheet$/i
139  },
140  {
141    type: 'hosted', icon: 'gslides', name: 'GSLIDES_DOCUMENT_FILE_TYPE',
142    subtype: 'slides', pattern: /\.gslides$/i
143  },
144  {
145    type: 'hosted', icon: 'gdraw', name: 'GDRAW_DOCUMENT_FILE_TYPE',
146    subtype: 'draw', pattern: /\.gdraw$/i
147  },
148  {
149    type: 'hosted', icon: 'gtable', name: 'GTABLE_DOCUMENT_FILE_TYPE',
150    subtype: 'table', pattern: /\.gtable$/i
151  },
152  {
153    type: 'hosted', icon: 'glink', name: 'GLINK_DOCUMENT_FILE_TYPE',
154    subtype: 'glink', pattern: /\.glink$/i
155  },
156  {
157    type: 'hosted', icon: 'gform', name: 'GFORM_DOCUMENT_FILE_TYPE',
158    subtype: 'form', pattern: /\.gform$/i
159  },
160
161  // Others
162  {
163    type: 'document', icon: 'pdf', name: 'PDF_DOCUMENT_FILE_TYPE',
164    subtype: 'PDF', pattern: /\.pdf$/i
165  },
166  {
167    type: 'document', name: 'HTML_DOCUMENT_FILE_TYPE',
168    subtype: 'HTML', pattern: /\.(html?|mht|mhtml)$/i
169  },
170  {
171    type: 'document', icon: 'word', name: 'WORD_DOCUMENT_FILE_TYPE',
172    subtype: 'Word', pattern: /\.(doc|docx)$/i
173  },
174  {
175    type: 'document', icon: 'ppt', name: 'POWERPOINT_PRESENTATION_FILE_TYPE',
176    subtype: 'PPT', pattern: /\.(ppt|pptx)$/i
177  },
178  {
179    type: 'document', icon: 'excel', name: 'EXCEL_FILE_TYPE',
180    subtype: 'Excel', pattern: /\.(xls|xlsx)$/i
181  }
182];
183
184/**
185 * A special type for directory.
186 */
187FileType.DIRECTORY = {name: 'FOLDER', type: '.folder', icon: 'folder'};
188
189/**
190 * Returns the file path extension for a given file.
191 *
192 * @param {Entry} entry Reference to the file.
193 * @return {string} The extension including a leading '.', or empty string if
194 *     not found.
195 */
196FileType.getExtension = function(entry) {
197  // No extension for a directory.
198  if (entry.isDirectory)
199    return '';
200
201  var extensionStartIndex = entry.name.lastIndexOf('.');
202  if (extensionStartIndex === -1 ||
203      extensionStartIndex === entry.name.length - 1) {
204    return '';
205  }
206
207  return entry.name.substr(extensionStartIndex);
208};
209
210/**
211 * Gets the file type object for a given file name (base name). Use getType()
212 * if possible, since this method can't recognize directories.
213 *
214 * @param {string} name Name of the file.
215 * @return {Object} The matching file type object or an empty object.
216 */
217FileType.getTypeForName = function(name) {
218  var types = FileType.types;
219  for (var i = 0; i < types.length; i++) {
220    if (types[i].pattern.test(name))
221      return types[i];
222  }
223
224  // Unknown file type.
225  var extension = util.splitExtension(name)[1];
226  if (extension === '') {
227    return { name: 'NO_EXTENSION_FILE_TYPE', type: 'UNKNOWN', icon: '' };
228  }
229  // subtype is the extension excluding the first dot.
230  return {
231    name: 'GENERIC_FILE_TYPE', type: 'UNKNOWN',
232    subtype: extension.substr(1).toUpperCase(), icon: ''
233  };
234};
235
236/**
237 * Gets the file type object for a given file.
238 * @param {Entry} entry Reference to the file.
239 * @return {Object} The matching file type object or an empty object.
240 */
241FileType.getType = function(entry) {
242  if (entry.isDirectory)
243    return FileType.DIRECTORY;
244
245  var types = FileType.types;
246  for (var i = 0; i < types.length; i++) {
247    if (types[i].pattern.test(entry.name))
248      return types[i];
249  }
250
251  // Unknown file type.
252  var extension = FileType.getExtension(entry);
253  if (extension === '') {
254    return { name: 'NO_EXTENSION_FILE_TYPE', type: 'UNKNOWN', icon: '' };
255  }
256  // subtype is the extension excluding the first dot.
257  return {
258    name: 'GENERIC_FILE_TYPE', type: 'UNKNOWN',
259    subtype: extension.substr(1).toUpperCase(), icon: ''
260  };
261};
262
263/**
264 * @param {Object} fileType Type object returned by FileType.getType().
265 * @return {string} Localized string representation of file type.
266 */
267FileType.typeToString = function(fileType) {
268  if (fileType.subtype)
269    return strf(fileType.name, fileType.subtype);
270  else
271    return str(fileType.name);
272};
273
274/**
275 * Gets the media type for a given file.
276 *
277 * @param {Entry} entry Reference to the file.
278 * @return {string} The value of 'type' property from one of the elements in
279 *     FileType.types or undefined.
280 */
281FileType.getMediaType = function(entry) {
282  return FileType.getType(entry).type;
283};
284
285/**
286 * @param {Entry} entry Reference to the file.
287 * @return {boolean} True if audio file.
288 */
289FileType.isAudio = function(entry) {
290  return FileType.getMediaType(entry) === 'audio';
291};
292
293/**
294 * @param {Entry} entry Reference to the file.
295 * @return {boolean} True if image file.
296 */
297FileType.isImage = function(entry) {
298  return FileType.getMediaType(entry) === 'image';
299};
300
301/**
302 * @param {Entry} entry Reference to the file.
303 * @return {boolean} True if video file.
304 */
305FileType.isVideo = function(entry) {
306  return FileType.getMediaType(entry) === 'video';
307};
308
309
310/**
311 * Files with more pixels won't have preview.
312 * @param {Entry} entry Reference to the file.
313 * @return {boolean} True if image or video.
314 */
315FileType.isImageOrVideo = function(entry) {
316  var type = FileType.getMediaType(entry);
317  return type === 'image' || type === 'video';
318};
319
320/**
321 * @param {Entry} entry Reference to the file.
322 * @return {boolean} Returns true if the file is hosted.
323 */
324FileType.isHosted = function(entry) {
325  return FileType.getType(entry).type === 'hosted';
326};
327
328/**
329 * @param {Entry} entry Reference to the file.
330 * @return {string} Returns string that represents the file icon.
331 *     It refers to a file 'images/filetype_' + icon + '.png'.
332 */
333FileType.getIcon = function(entry) {
334  var fileType = FileType.getType(entry);
335  return fileType.icon || fileType.type || 'unknown';
336};
337
338