| 'use strict'; |
| |
| const path = require('path'); |
| const emojisList = require('emojis-list'); |
| const getHashDigest = require('./getHashDigest'); |
| |
| const emojiRegex = /[\uD800-\uDFFF]./; |
| const emojiList = emojisList.filter((emoji) => emojiRegex.test(emoji)); |
| const emojiCache = {}; |
| |
| function encodeStringToEmoji(content, length) { |
| if (emojiCache[content]) { |
| return emojiCache[content]; |
| } |
| |
| length = length || 1; |
| |
| const emojis = []; |
| |
| do { |
| if (!emojiList.length) { |
| throw new Error('Ran out of emoji'); |
| } |
| |
| const index = Math.floor(Math.random() * emojiList.length); |
| |
| emojis.push(emojiList[index]); |
| emojiList.splice(index, 1); |
| } while (--length > 0); |
| |
| const emojiEncoding = emojis.join(''); |
| |
| emojiCache[content] = emojiEncoding; |
| |
| return emojiEncoding; |
| } |
| |
| function interpolateName(loaderContext, name, options) { |
| let filename; |
| |
| const hasQuery = |
| loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1; |
| |
| if (typeof name === 'function') { |
| filename = name( |
| loaderContext.resourcePath, |
| hasQuery ? loaderContext.resourceQuery : undefined |
| ); |
| } else { |
| filename = name || '[hash].[ext]'; |
| } |
| |
| const context = options.context; |
| const content = options.content; |
| const regExp = options.regExp; |
| |
| let ext = 'bin'; |
| let basename = 'file'; |
| let directory = ''; |
| let folder = ''; |
| let query = ''; |
| |
| if (loaderContext.resourcePath) { |
| const parsed = path.parse(loaderContext.resourcePath); |
| let resourcePath = loaderContext.resourcePath; |
| |
| if (parsed.ext) { |
| ext = parsed.ext.substr(1); |
| } |
| |
| if (parsed.dir) { |
| basename = parsed.name; |
| resourcePath = parsed.dir + path.sep; |
| } |
| |
| if (typeof context !== 'undefined') { |
| directory = path |
| .relative(context, resourcePath + '_') |
| .replace(/\\/g, '/') |
| .replace(/\.\.(\/)?/g, '_$1'); |
| directory = directory.substr(0, directory.length - 1); |
| } else { |
| directory = resourcePath.replace(/\\/g, '/').replace(/\.\.(\/)?/g, '_$1'); |
| } |
| |
| if (directory.length === 1) { |
| directory = ''; |
| } else if (directory.length > 1) { |
| folder = path.basename(directory); |
| } |
| } |
| |
| if (loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1) { |
| query = loaderContext.resourceQuery; |
| |
| const hashIdx = query.indexOf('#'); |
| |
| if (hashIdx >= 0) { |
| query = query.substr(0, hashIdx); |
| } |
| } |
| |
| let url = filename; |
| |
| if (content) { |
| // Match hash template |
| url = url |
| // `hash` and `contenthash` are same in `loader-utils` context |
| // let's keep `hash` for backward compatibility |
| .replace( |
| /\[(?:([^:\]]+):)?(?:hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi, |
| (all, hashType, digestType, maxLength) => |
| getHashDigest(content, hashType, digestType, parseInt(maxLength, 10)) |
| ) |
| .replace(/\[emoji(?::(\d+))?\]/gi, (all, length) => |
| encodeStringToEmoji(content, parseInt(length, 10)) |
| ); |
| } |
| |
| url = url |
| .replace(/\[ext\]/gi, () => ext) |
| .replace(/\[name\]/gi, () => basename) |
| .replace(/\[path\]/gi, () => directory) |
| .replace(/\[folder\]/gi, () => folder) |
| .replace(/\[query\]/gi, () => query); |
| |
| if (regExp && loaderContext.resourcePath) { |
| const match = loaderContext.resourcePath.match(new RegExp(regExp)); |
| |
| match && |
| match.forEach((matched, i) => { |
| url = url.replace(new RegExp('\\[' + i + '\\]', 'ig'), matched); |
| }); |
| } |
| |
| if ( |
| typeof loaderContext.options === 'object' && |
| typeof loaderContext.options.customInterpolateName === 'function' |
| ) { |
| url = loaderContext.options.customInterpolateName.call( |
| loaderContext, |
| url, |
| name, |
| options |
| ); |
| } |
| |
| return url; |
| } |
| |
| module.exports = interpolateName; |