var Path = require('path'); var crypto = require('crypto'); module.exports = (function() { 'use strict'; var path_without_ext = function(path) { var ext = Path.extname(path); return path.substr(0, path.length - ext.length); }; var dirname_with_sep = function(path) { return Path.dirname(path).replace(/\\/g, '/') + '/'; } var join_path_url = function (prefix, path) { prefix = prefix.replace(/\/$/, ''); path = path.replace(/^\//, ''); return [ prefix, path ].join('/'); }; /** * Joins a directory and a filename, replaces Windows forward-slash with a backslash. */ var join_path = function (directory, filename) { return Path.join(directory, filename).replace(/^[a-z]:\\/i, '/').replace(/\\/g, '/'); }; /** * Given a base path and resource path, will return resource path relative to the base. * Also replaces Windows forward-slash with a backslash. */ var get_relative_path = function (base, path, noStartingSlash) { if (base === path) { return ''; } // Sanitize inputs, convert windows to posix style slashes, ensure trailing slash for base base = base.replace(/^[a-z]:/i, '').replace(/\\/g, '/').replace(/\/$/g, '') + '/'; path = path.replace(/^[a-z]:/i, '').replace(/\\/g, '/'); // Only truncate paths that overap with the base if (base === path.substr(0, base.length)) { path = '/' + path.substr(base.length); } var modifyStartingSlash = noStartingSlash !== undefined; if (modifyStartingSlash) { if (path[0] === '/' && noStartingSlash) { path = path.substr(1); } else if (path[0] !== '/' && !noStartingSlash){ path = '/' + path; } } return path; }; var md5 = function (str) { return crypto.createHash('md5').update(str, 'utf8').digest('hex'); }; var is_binary_file = function (file) { var length = (file.contents.length > 50) ? 50 : file.contents.length; for (var i = 0; i < length; i++) { if (file.contents[i] === 0) { return true; } } return false; }; /** * Given a file (context) and a file reference, return all the possible representations of paths to get from * the context to the reference file. * */ var get_reference_representations_relative = function (fileCurrentReference, file) { var representations = []; // Scenario 2: Current file is the same directory or lower than the reference // (ie. file.path and the reference file.path are the same) // // file.base = /user/project // file.path = /user/project/second/current_file.html // fileCurrentReference.path = /user/project/second/index.html if (dirname_with_sep(fileCurrentReference.path).indexOf(dirname_with_sep(file.path)) === 0) { // index.html representations.push(get_relative_path(Path.dirname(file.path), fileCurrentReference.revPathOriginal, true)); // ./index.html (reference: relative) representations.push('.' + get_relative_path(Path.dirname(file.path), fileCurrentReference.revPathOriginal, false)); } // Scenario 3: Current file is in a different child directory than the reference // (ie. file.path and the reference file.path are different, not in root directory) // // file.base = /user/project // file.path = /user/project/first/index.html // fileCurrentReference.path = /user/project/second/index.html if (dirname_with_sep(file.path) !== dirname_with_sep(fileCurrentReference.path) && dirname_with_sep(fileCurrentReference.path).indexOf(dirname_with_sep(file.path)) === -1) { var pathCurrentReference = dirname_with_sep(get_relative_path(fileCurrentReference.base, fileCurrentReference.revPathOriginal)); var pathFile = dirname_with_sep(get_relative_path(file.base, file.revPathOriginal)); // ../second/index.html var relPath = Path.relative(pathFile, pathCurrentReference); relPath = relPath.replace(/\\/g, '/'); representations.push(relPath + '/' + Path.basename(fileCurrentReference.revPathOriginal)); } return representations; }; /** * Given a file (context) and a file reference, return all the possible representations of paths to get from * the context to the reference file. * */ var get_reference_representations_absolute = function (fileCurrentReference, file) { var representations = []; var representation; // Scenario 1: Current file is anywhere // /view/index.html (reference: absolute) representations.push(get_relative_path(fileCurrentReference.base, fileCurrentReference.revPathOriginal, false)); // Without starting slash, only if it contains a directory // view/index.html (reference: absolute, without slash prefix) representation = get_relative_path(fileCurrentReference.base, fileCurrentReference.revPathOriginal, true); if (representation.indexOf('/')) { representations.push(representation); } return representations; }; return { get_relative_path: get_relative_path, md5: md5, is_binary_file: is_binary_file, path_without_ext: path_without_ext, join_path: join_path, join_path_url: join_path_url, get_reference_representations_relative: get_reference_representations_relative, get_reference_representations_absolute: get_reference_representations_absolute }; })();