CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
input.js277 linesDownload Raw Back to lib
1'use strict'2 3let { nanoid } = require('nanoid/non-secure')4let { isAbsolute, resolve } = require('path')5let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')6let { fileURLToPath, pathToFileURL } = require('url')7 8let CssSyntaxError = require('./css-syntax-error')9let PreviousMap = require('./previous-map')10let terminalHighlight = require('./terminal-highlight')11 12let lineToIndexCache = Symbol('lineToIndexCache')13 14let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)15let pathAvailable = Boolean(resolve && isAbsolute)16 17function getLineToIndex(input) {18  if (input[lineToIndexCache]) return input[lineToIndexCache]19  let lines = input.css.split('\n')20  let lineToIndex = new Array(lines.length)21  let prevIndex = 022 23  for (let i = 0, l = lines.length; i < l; i++) {24    lineToIndex[i] = prevIndex25    prevIndex += lines[i].length + 126  }27 28  input[lineToIndexCache] = lineToIndex29  return lineToIndex30}31 32class Input {33  get from() {34    return this.file || this.id35  }36 37  constructor(css, opts = {}) {38    if (39      css === null ||40      typeof css === 'undefined' ||41      (typeof css === 'object' && !css.toString)42    ) {43      throw new Error(`PostCSS received ${css} instead of CSS string`)44    }45 46    this.css = css.toString()47 48    if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') {49      this.hasBOM = true50      this.css = this.css.slice(1)51    } else {52      this.hasBOM = false53    }54 55    this.document = this.css56    if (opts.document) this.document = opts.document.toString()57 58    if (opts.from) {59      if (60        !pathAvailable ||61        /^\w+:\/\//.test(opts.from) ||62        isAbsolute(opts.from)63      ) {64        this.file = opts.from65      } else {66        this.file = resolve(opts.from)67      }68    }69 70    if (pathAvailable && sourceMapAvailable) {71      let map = new PreviousMap(this.css, opts)72      if (map.text) {73        this.map = map74        let file = map.consumer().file75        if (!this.file && file) this.file = this.mapResolve(file)76      }77    }78 79    if (!this.file) {80      this.id = '<input css ' + nanoid(6) + '>'81    }82    if (this.map) this.map.file = this.from83  }84 85  error(message, line, column, opts = {}) {86    let endColumn, endLine, endOffset, offset, result87 88    if (line && typeof line === 'object') {89      let start = line90      let end = column91      if (typeof start.offset === 'number') {92        offset = start.offset93        let pos = this.fromOffset(offset)94        line = pos.line95        column = pos.col96      } else {97        line = start.line98        column = start.column99        offset = this.fromLineAndColumn(line, column)100      }101      if (typeof end.offset === 'number') {102        endOffset = end.offset103        let pos = this.fromOffset(endOffset)104        endLine = pos.line105        endColumn = pos.col106      } else {107        endLine = end.line108        endColumn = end.column109        endOffset = this.fromLineAndColumn(end.line, end.column)110      }111    } else if (!column) {112      offset = line113      let pos = this.fromOffset(offset)114      line = pos.line115      column = pos.col116    } else {117      offset = this.fromLineAndColumn(line, column)118    }119 120    let origin = this.origin(line, column, endLine, endColumn)121    if (origin) {122      result = new CssSyntaxError(123        message,124        origin.endLine === undefined125          ? origin.line126          : { column: origin.column, line: origin.line },127        origin.endLine === undefined128          ? origin.column129          : { column: origin.endColumn, line: origin.endLine },130        origin.source,131        origin.file,132        opts.plugin133      )134    } else {135      result = new CssSyntaxError(136        message,137        endLine === undefined ? line : { column, line },138        endLine === undefined ? column : { column: endColumn, line: endLine },139        this.css,140        this.file,141        opts.plugin142      )143    }144 145    result.input = {146      column,147      endColumn,148      endLine,149      endOffset,150      line,151      offset,152      source: this.css153    }154    if (this.file) {155      if (pathToFileURL) {156        result.input.url = pathToFileURL(this.file).toString()157      }158      result.input.file = this.file159    }160 161    return result162  }163 164  fromLineAndColumn(line, column) {165    let lineToIndex = getLineToIndex(this)166    let index = lineToIndex[line - 1]167    return index + column - 1168  }169 170  fromOffset(offset) {171    let lineToIndex = getLineToIndex(this)172    let lastLine = lineToIndex[lineToIndex.length - 1]173 174    let min = 0175    if (offset >= lastLine) {176      min = lineToIndex.length - 1177    } else {178      let max = lineToIndex.length - 2179      let mid180      while (min < max) {181        mid = min + ((max - min) >> 1)182        if (offset < lineToIndex[mid]) {183          max = mid - 1184        } else if (offset >= lineToIndex[mid + 1]) {185          min = mid + 1186        } else {187          min = mid188          break189        }190      }191    }192    return {193      col: offset - lineToIndex[min] + 1,194      line: min + 1195    }196  }197 198  mapResolve(file) {199    if (/^\w+:\/\//.test(file)) {200      return file201    }202    return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file)203  }204 205  origin(line, column, endLine, endColumn) {206    if (!this.map) return false207    let consumer = this.map.consumer()208 209    let from = consumer.originalPositionFor({ column: column - 1, line })210    if (!from.source) return false211 212    let to213    if (typeof endLine === 'number') {214      to = consumer.originalPositionFor({215        column: endColumn - 1,216        line: endLine217      })218    }219 220    let fromUrl221 222    if (isAbsolute(from.source)) {223      fromUrl = pathToFileURL(from.source)224    } else {225      fromUrl = new URL(226        from.source,227        this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile)228      )229    }230 231    let result = {232      column: from.column + 1,233      endColumn: to && to.column + 1,234      endLine: to && to.line,235      line: from.line,236      url: fromUrl.toString()237    }238 239    if (fromUrl.protocol === 'file:') {240      if (fileURLToPath) {241        result.file = fileURLToPath(fromUrl)242      } else {243        /* c8 ignore next 2 */244        throw new Error(`file: protocol is not available in this PostCSS build`)245      }246    }247 248    let source = consumer.sourceContentFor(from.source)249    if (source) result.source = source250 251    return result252  }253 254  toJSON() {255    let json = {}256    for (let name of ['hasBOM', 'css', 'file', 'id']) {257      if (this[name] != null) {258        json[name] = this[name]259      }260    }261    if (this.map) {262      json.map = { ...this.map }263      if (json.map.consumerCache) {264        json.map.consumerCache = undefined265      }266    }267    return json268  }269}270 271module.exports = Input272Input.default = Input273 274if (terminalHighlight && terminalHighlight.registerInput) {275  terminalHighlight.registerInput(Input)276}277