You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							151 lines
						
					
					
						
							3.7 KiB
						
					
					
				
			
		
		
	
	
							151 lines
						
					
					
						
							3.7 KiB
						
					
					
				'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;
 | 
						|
 |