aeq = ( function ( aeq ) {
/**
* [file description]
* @namespace aeq.file
* @memberof aeq
* @type {Object}
*/
aeq.file = aeq.extend({}, {
toString: function () {
return '[object aeq.file]';
},
// Function for extending the prototype using objects
extend: aeq.extend,
/**
* The value of the OS's file system path separator symbol; \ or /
* @memberof aeq.file
* @type {string}
*/
pathSeparatorSymbol: $.os.indexOf( 'Windows' ) > -1 ? '\\' : '/',
// NormalizePathArray, pathIsAbsolute, normalizePath, joinPath adapted from path-browserify
// (https://github.com/substack/path-browserify/)
//
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
/**
* [description]
* @method
* @memberof aeq.file
* @param {string[]} parts Array of path components
* @param {boolean} allowAboveRoot [description]
* @return {string[]} [description]
*/
normalizePathArray: function ( parts, allowAboveRoot ) {
// If the path tries to go above the root, `up` ends up > 0
var up = 0;
for ( var i = parts.length - 1; i >= 0; i-- ) {
var last = parts[i];
if ( last === '.' ) {
parts.splice( i, 1 );
} else if ( last === '..' ) {
parts.splice( i, 1 );
up++;
} else if ( up ) {
parts.splice( i, 1 );
up--;
}
}
// If the path is allowed to go above the root, restore leading ..s
if ( allowAboveRoot ) {
for ( ; up--; up ) {
parts.unshift( '..' );
}
}
return parts;
},
/**
* Checks whether the path starts with the OS separator symbol
* @method
* @memberof aeq.file
* @param {string} path File path
* @return {boolean} True if first character equals path separator symbol
*/
pathIsAbsolute: function ( path ) {
return path.charAt( 0 ) === aeq.file.pathSeparatorSymbol;
},
/**
* [description]
* @method
* @memberof aeq.file
* @param {string} path Raw joined file path
* @return {string} Normalized path
*/
normalizePath: function ( path ) {
var pathIsAbsolute = aeq.file.pathIsAbsolute( path ),
trailingSlash = path.substr( -1 ) === aeq.file.pathSeparatorSymbol;
// Normalize the path
var splitPath = path.split( aeq.file.pathSeparatorSymbol );
var filteredPath = aeq.filter( splitPath, function ( p ) {
return !!p;
});
path = aeq.file.normalizePathArray( filteredPath, !pathIsAbsolute );
path = path.join( aeq.file.pathSeparatorSymbol );
if ( !path && !pathIsAbsolute ) {
path = '.';
}
if ( path && trailingSlash ) {
path += aeq.file.pathSeparatorSymbol;
}
return ( pathIsAbsolute ? aeq.file.pathSeparatorSymbol : '' ) + path;
},
/**
* Joins path components into an OS-formatted file path string
* @method
* @memberof aeq.file
* @param {...(String|File|Folder)} paths The path elements to join.
* @return {string} File path string joined with OS's path separator
*/
joinPath: function () {
var paths = Array.prototype.slice.call( arguments, 0 );
return aeq.file.normalizePath( aeq.filter( paths, function ( p, index ) {
// Path is a File or Folder object.
if ( p && typeof p.fsName === 'string' ) {
p = p.fsName;
paths[index] = p;
}
if ( typeof p !== 'string' ) {
throw new TypeError( 'Arguments to path.join must be strings, Files or Folders' );
}
return p;
}).join( aeq.file.pathSeparatorSymbol ) );
},
/**
* Returns the extension of target file
* @method
* @memberof aeq.file
* @param {File|string} filePath String path to a file, or file object
* @return {string} Extension of target file
*/
getExtension: function ( filePath ) {
var filePathStr = aeq.isFile( filePath ) ? filePath.name : filePath;
return filePathStr.substr( filePathStr.lastIndexOf( '.' ) + 1, filePathStr.length );
},
/**
* Returns the filename of target file without extension
* @method
* @memberof aeq.file
* @param {File|string} filePath String path to a file, or file object
* @return {string} Filename without extension
*/
stripExtension: function ( filePath ) {
var filePathStr = aeq.isFile( filePath ) ? filePath.name : filePath;
return filePathStr.substr( 0, filePathStr.lastIndexOf( '.' ) );
},
/**
* Takes a file path or a file object, and returns a file object
* allows functions to be flexible in whether they take a path vs file
* @method
* @memberof aeq
* @param {File|string} filePath String path to a file, or file object
* @return {File} Resolved file object
*/
getFileObject: function ( filePath ) {
return aeq.isFile( filePath ) ? filePath : new File( filePath );
},
/**
* Gets target file by path or file object, or null if doesn't exist
* @method
* @memberof aeq.file
* @param {File|string} filePath String path to a file, or file object
* @return {File|null} Target file, or null if doesn't exist
*/
getFile: function ( filePath ) {
var file = aeq.getFileObject( filePath );
if ( !file.exists ) return null;
return file;
},
/**
* Gets all files in target path that matches filter (or, all files if no filter)
* @method
* @memberof aeq.file
* @param {File|string} folderPath Folder or path to get
* @param {string|function} [filter=""] Filter string or function
* @return {aeq.arrayEx|null} Array of filtered files, or null if none
*/
getFiles: function ( folderPath, filter ) {
filter = setDefault( filter, '' );
var folder = aeq.getFolder( folderPath ),
files;
files = folder.getFiles( filter );
if ( files === null || files.length === 0 ) return null;
return aeq.arrayEx( files );
},
/**
* Recursively scan folder for all files matching filter
* @method
* @memberof aeq.file
* @param {Folder|String} folder Folder or path to get files from
* @param {string|function} [filter=""] Filter string or function
* @returns {File[]} Array of found files
*/
getFilesRecursive: function ( folder, filter ) {
var foundItems = aeq.arrayEx();
var folderObject = aeq.file.getFolder( folder );
if ( aeq.isNullOrUndefined( folderObject ) ) {
return foundItems;
}
// Find all folders within folderObject and
// recursively append anything it finds to foundItems
var folderFiles = aeq.file.getFiles( folderObject );
if ( aeq.isNullOrUndefined( folderFiles ) ) {
return foundItems;
}
folderFiles.filter( function ( item ) {
return aeq.isFolder( item );
}).forEach( function ( folderItem ) {
foundItems = foundItems.concat( aeq.file.getFilesRecursive( folderItem, filter ) );
});
var filesInFolder = aeq.file.getFiles( folderObject, filter );
if ( !aeq.isNullOrUndefined( filesInFolder ) ) {
foundItems = foundItems.concat( filesInFolder );
}
return aeq.arrayEx( foundItems );
},
/**
* Takes a folder path or a folder object, and returns a folder object
* allows functions to be flexible in whether they take a path vs folder
* @method
* @memberof aeq
* @param {Folder|string} folderPath String path to a folder, or folder object
* @return {Folder} Resolved folder object
*/
getFolderObject: function ( folderPath ) {
return aeq.isFolder( folderPath ) ? folderPath : new Folder( folderPath );
},
/**
* Returns a folder, or null if it doesn't exist
* @method
* @memberof aeq.file
* @param {File|string} folderPath Folder path to get
* @return {Folder|null} Target folder, or null if it doesn't exist
*/
getFolder: function ( folderPath ) {
var folder = aeq.getFolderObject( folderPath );
if ( !folder.exists ) return null;
return folder;
},
/**
* Returns a folder, creating if it doesn't exist
* @method
* @memberof aeq.file
* @param {File|string} folderPath Folder path to get or create
* @return {Folder} Target folder
*/
ensureFolderExists: function ( folderPath ) {
var folder = aeq.getFolderObject( folderPath );
if ( !folder.exists ) folder.create();
return folder;
},
/**
* Returns the contents of a specified file
* @method
* @memberof aeq
* @param {File|string} filePath Path or file to read
* @param {string} [encoding=UTF-8] Encoding method
* @return {string|null} Contents of the file, or null if file doesn't exist
*/
readFile: function ( filePath, encoding ) {
var file = aeq.getFileObject( filePath ),
contents;
encoding = setDefault( encoding, 'UTF-8' );
if ( file.exists ) {
if ( File.isEncodingAvailable( encoding ) ) {
file.encoding = encoding;
}
file.open();
contents = file.read();
file.close();
return contents;
}
return null;
},
/**
* Writes data to a file, returns file
* @method
* @memberof aeq
* @param {File|string} filePath Path or file to write to
* @param {string} contents Data to write to the file
* @param {object} [options] Options for writing file.
* @param {boolean} [options.overwrite=false] `true` if file should be overwritten if exists.
* @param {string} [options.encoding="UTF-8"] Encoding method.
* @return {File|null} New file, or null if file was not written
* correctly or file exits and overwrite = false
*/
writeFile: function ( filePath, contents, options ) {
var file = aeq.getFileObject( filePath );
options = aeq.setDefault( options, {});
if ( file.exists && options.overwrite === false ) {
return null;
}
if ( !file.exists ) {
aeq.file.ensureFolderExists( file.path );
}
if ( !aeq.isNullOrUndefined( options.encoding ) &&
File.isEncodingAvailable( options.encoding ) ) {
file.encoding = options.encoding;
}
file.open( 'w' );
var success = file.write( contents );
file.close();
if ( success ) return file;
return null;
},
/**
* Prompts user to select files
* @method
* @memberof aeq.file
* @param {string[]} extensionList Array of file extensions to accept
* @param {boolean} [multiSelect=false] `true` to allow multiple files
* @return {file[]|null} ArrayEx of selected file(s), or null if canceled
*
* @example
* var myFiles = selectFiles(["jsx", "theme", "someOtherExtension"], true);
*/
selectFiles: function ( extensionList, multiSelect ) {
multiSelect = aeq.setDefault( multiSelect, false );
var message = multiSelect ? 'Please select multiple files' : 'Please select file';
if ( !aeq.isArray( extensionList ) ) {
extensionList = [ extensionList ];
}
var getFilterForFiles = function () {
if ( aeq.isWin ) {
return '*.' + extensionList.join( ';*.' );
}
var extensionListRe = '.(' + extensionList.join( '|' ) + ')$';
var re = new RegExp( extensionListRe, 'i' );
return function ( file ) {
return file.name.match( re ) || file.constructor.name === 'Folder';
};
};
var files = File.openDialog( message, getFilterForFiles(), multiSelect );
if ( aeq.isNullOrUndefined( files ) ) {
return null;
}
if ( !aeq.isArray( files ) ) {
files = [ files ];
}
return aeq.arrayEx( files );
}
});
// Function aliases
aeq.pathSeparatorSymbol = aeq.file.pathSeparatorSymbol;
aeq.getFileObject = aeq.file.getFileObject;
aeq.getFolderObject = aeq.file.getFolderObject;
aeq.getFile = aeq.file.get = aeq.file.getFile;
aeq.getFiles = aeq.file.getFiles;
aeq.getFilesRecursive = aeq.file.getFilesRecursive;
aeq.getFolder = aeq.file.getFolder;
aeq.readFile = aeq.file.readFile;
aeq.writeFile = aeq.file.writeFile;
aeq.selectFiles = aeq.file.selectFiles;
return aeq;
}( aeq || {}) );