<commit_before>/*
 * MIT License http://opensource.org/licenses/MIT
 * Author: <NAME> @bholloway
 */
'use strict';

var path              = require('path'),
    fs                = require('fs'),
    loaderUtils       = require('loader-utils'),
    rework            = require('rework'),
    visit             = require('rework-visit'),
    convert           = require('convert-source-map'),
    camelcase         = require('camelcase'),
    defaults          = require('lodash.defaults'),
    SourceMapConsumer = require('source-map').SourceMapConsumer;

var findFile           = require('./lib/find-file'),
    absoluteToRelative = require('./lib/sources-absolute-to-relative'),
    relativeToAbsolute = require('./lib/sources-relative-to-absolute');

var PACKAGE_NAME = require('./package.json').name;

/**
 * A webpack loader that resolves absolute url() paths relative to their original source file.
 * Requires source-maps to do any meaningful work.
 * @param {string} content Css content
 * @param {object} sourceMap The source-map
 * @returns {string|String}
 */
function resolveUrlLoader(content, sourceMap) {
  /* jshint validthis:true */

  // details of the file being processed
  //  we would normally use compilation.getPath(options.output.path) to get the most correct outputPath,
  //  however we need to match to the sass-loader and it does not do so
  var loader     = this,
      filePath   = loader.context,
      outputPath = path.resolve(loader.options.context);

  // prefer loader query, else options object, else default values
  var options = defaults(loaderUtils.parseQuery(loader.query), loader.options[camelcase(PACKAGE_NAME)], {
    absolute  : false,
    sourceMap : false,
    fail      : false,
    silent    : false,
    keepQuery : false,
    root      : null
  });

  // validate root directory
  var resolvedRoot = (typeof options.root === 'string') && path.resolve(options.root),
      isValidRoot  = resolvedRoot && fs.existsSync(resolvedRoot);
  if (options.root && !isValidRoot) {
    return handleException('"root" option does not resolve to a valid path');
  }

  // loader result is cacheable
  loader.cacheable();

  // incoming source-map
  var sourceMapConsumer, contentWithMap, sourceRoot;
  if (sourceMap) {

    // sass-loader outputs source-map sources relative to output directory so start our search there
    try {
      relativeToAbsolute(sourceMap.sources, outputPath, resolvedRoot);
      // There are now absolute paths in the source map so we don't need it anymore
      // However, later when we go back to relative paths, we need to add it again
      sourceRoot = sourceMap.sourceRoot;
      sourceMap.sourceRoot = null;
    } catch (exception) {
      return handleException('source-map error', exception.message);
    }

    // prepare the adjusted sass source-map for later look-ups
    sourceMapConsumer = new SourceMapConsumer(sourceMap);

    // embed source-map in css for rework-css to use
    contentWithMap = content + convert.fromObject(sourceMap).toComment({multiline: true});
  }
  // absent source map
  else {
    contentWithMap = content;
  }

  // process
  //  rework-css will throw on css syntax errors
  var useMap = loader.sourceMap || options.sourceMap,
      reworked;
  try {
    reworked = rework(contentWithMap, {source: loader.resourcePath})
      .use(reworkPlugin)
      .toString({
        sourcemap        : useMap,
        sourcemapAsObject: useMap
      });
  }
    //  fail gracefully
  catch (exception) {
    return handleException('CSS error', exception);
  }

  // complete with source-map
  if (useMap) {

    // source-map sources seem to be relative to the file being processed
    absoluteToRelative(reworked.map.sources, filePath);
    
    // Set source root again
    reworked.map.sourceRoot = sourceRoot;
    // need to use callback when there are multiple arguments
    loader.callback(null, reworked.code, reworked.map);
  }
  // complete without source-map
  else {
    return reworked;
  }

  /**
   * Push an error for the given exception and return the original content.
   * @param {string} label
   * @param {string|Error} exception
   * @returns {string} The original CSS content
   */
  function handleException(label, exception) {
    var rest = (typeof exception === 'string') ? [exception] : (exception instanceof Error) ? [exception.message,
      exception.stack.split('\n')[1].trim()] : [];
    var message = '  resolve-url-loader cannot operate: ' + [label].concat(rest).filter(Boolean).join('\n  ');
    if (options.fail) {
      loader.emitError(message);
    }<commit_msg>Get relative path relative to sourceRoot<commit_after>/*
 * MIT License http://opensource.org/licenses/MIT
 * Author: <NAME> @bholloway
 */
'use strict';

var path              = require('path'),
    fs                = require('fs'),
    loaderUtils       = require('loader-utils'),
    rework            = require('rework'),
    visit             = require('rework-visit'),
    convert           = require('convert-source-map'),
    camelcase         = require('camelcase'),
    defaults          = require('lodash.defaults'),
    SourceMapConsumer = require('source-map').SourceMapConsumer;

var findFile           = require('./lib/find-file'),
    absoluteToRelative = require('./lib/sources-absolute-to-relative'),
    relativeToAbsolute = require('./lib/sources-relative-to-absolute');

var PACKAGE_NAME = require('./package.json').name;

/**
 * A webpack loader that resolves absolute url() paths relative to their original source file.
 * Requires source-maps to do any meaningful work.
 * @param {string} content Css content
 * @param {object} sourceMap The source-map
 * @returns {string|String}
 */
function resolveUrlLoader(content, sourceMap) {
  /* jshint validthis:true */

  // details of the file being processed
  //  we would normally use compilation.getPath(options.output.path) to get the most correct outputPath,
  //  however we need to match to the sass-loader and it does not do so
  var loader     = this,
      filePath   = loader.context,
      outputPath = path.resolve(loader.options.context);

  // prefer loader query, else options object, else default values
  var options = defaults(loaderUtils.parseQuery(loader.query), loader.options[camelcase(PACKAGE_NAME)], {
    absolute  : false,
    sourceMap : false,
    fail      : false,
    silent    : false,
    keepQuery : false,
    root      : null
  });

  // validate root directory
  var resolvedRoot = (typeof options.root === 'string') && path.resolve(options.root),
      isValidRoot  = resolvedRoot && fs.existsSync(resolvedRoot);
  if (options.root && !isValidRoot) {
    return handleException('"root" option does not resolve to a valid path');
  }

  // loader result is cacheable
  loader.cacheable();

  // incoming source-map
  var sourceMapConsumer, contentWithMap, sourceRoot;
  if (sourceMap) {

    // sass-loader outputs source-map sources relative to output directory so start our search there
    try {
      relativeToAbsolute(sourceMap.sources, outputPath, resolvedRoot);
      // There are now absolute paths in the source map so we don't need it anymore
      // However, later when we go back to relative paths, we need to add it again
      sourceRoot = sourceMap.sourceRoot;
      sourceMap.sourceRoot = null;
    } catch (exception) {
      return handleException('source-map error', exception.message);
    }

    // prepare the adjusted sass source-map for later look-ups
    sourceMapConsumer = new SourceMapConsumer(sourceMap);

    // embed source-map in css for rework-css to use
    contentWithMap = content + convert.fromObject(sourceMap).toComment({multiline: true});
  }
  // absent source map
  else {
    contentWithMap = content;
  }

  // process
  //  rework-css will throw on css syntax errors
  var useMap = loader.sourceMap || options.sourceMap,
      reworked;
  try {
    reworked = rework(contentWithMap, {source: loader.resourcePath})
      .use(reworkPlugin)
      .toString({
        sourcemap        : useMap,
        sourcemapAsObject: useMap
      });
  }
    //  fail gracefully
  catch (exception) {
    return handleException('CSS error', exception);
  }

  // complete with source-map
  if (useMap) {

    // source-map sources seem to be relative to the file being processed
    absoluteToRelative(reworked.map.sources, path.resolve(filePath, sourceRoot));
    
    // Set source root again
    reworked.map.sourceRoot = sourceRoot;

    // need to use callback when there are multiple arguments
    loader.callback(null, reworked.code, reworked.map);
  }
  // complete without source-map
  else {
    return reworked;
  }

  /**
   * Push an error for the given exception and return the original content.
   * @param {string} label
   * @param {string|Error} exception
   * @returns {string} The original CSS content
   */
  function handleException(label, exception) {
    var rest = (typeof exception === 'string') ? [exception] : (exception instanceof Error) ? [exception.message,
      exception.stack.split('\n')[1].trim()] : [];
    var message = '  resolve-url-loader cannot operate: ' + [label].concat(rest).filter(Boolean).join('\n  ');
    if (options.fail) {
      loader.emitError(message);
    }
{'fraction_non_alphanumeric': 0.11195158850226929, 'fraction_numerical': 0.0002161227577263886, 'mean_word_length': 2.984072320275506, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '992418', 'n_tokens_mistral': 2577, 'n_tokens_neox': 2534, 'n_words': 776}