chore:更换到主分支

This commit is contained in:
张益铭
2021-03-01 15:26:05 +08:00
parent 9064b372e8
commit 6a5f1810f9
3530 changed files with 59613 additions and 479452 deletions

View File

@@ -1,3 +1,17 @@
# 14.0.0 / 2020-12-14
This release should not have breaking changes for the vast majority of users; only those with `@charset` statements in their CSS _may_ be affected.
- **BREAKING:** Error if multiple incompatible `@charset` statements ([#447](https://github.com/postcss/postcss-import/pull/447))
- **BREAKING:** Warn if `@charset` statements are not at the top of files ([#447](https://github.com/postcss/postcss-import/pull/447))
- Fix handing of `@charset` ([#436](https://github.com/postcss/postcss-import/issues/436), [#447](https://github.com/postcss/postcss-import/pull/447))
# 13.0.0 / 2020-10-20
- **BREAKING:** Require Node 10+ ([#429](https://github.com/postcss/postcss-import/pull/429))
- **BREAKING:** Upgrade to postcss v8 and require it as a `peerDependency` ([#427](https://github.com/postcss/postcss-import/issues/427), [#432](https://github.com/postcss/postcss-import/pull/432))
- Update dependencies
# 12.0.1 / 2018-10-22
- Add `plugin` property to dependency messages ([#379](https://github.com/postcss/postcss-import/issues/379), [#380](https://github.com/postcss/postcss-import/pull/380))

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) Maxime Thirouin, Jason Campbell & Kevin Mårtensson
Copyright (c) 2014 Maxime Thirouin, Jason Campbell & Kevin Mårtensson
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

517
node_modules/postcss-import/index.js generated vendored
View File

@@ -2,9 +2,6 @@
// builtin tooling
const path = require("path")
// external tooling
const postcss = require("postcss")
// internal tooling
const joinMedia = require("./lib/join-media")
const resolveId = require("./lib/resolve-id")
@@ -13,18 +10,16 @@ const processContent = require("./lib/process-content")
const parseStatements = require("./lib/parse-statements")
function AtImport(options) {
options = Object.assign(
{
root: process.cwd(),
path: [],
skipDuplicates: true,
resolve: resolveId,
load: loadContent,
plugins: [],
addModulesDirectories: [],
},
options
)
options = {
root: process.cwd(),
path: [],
skipDuplicates: true,
resolve: resolveId,
load: loadContent,
plugins: [],
addModulesDirectories: [],
...options,
}
options.root = path.resolve(options.root)
@@ -35,234 +30,270 @@ function AtImport(options) {
options.path = options.path.map(p => path.resolve(options.root, p))
return function(styles, result) {
const state = {
importedFiles: {},
hashFiles: {},
}
if (styles.source && styles.source.input && styles.source.input.file) {
state.importedFiles[styles.source.input.file] = {}
}
if (options.plugins && !Array.isArray(options.plugins)) {
throw new Error("plugins option must be an array")
}
return parseStyles(result, styles, options, state, []).then(bundle => {
applyRaws(bundle)
applyMedia(bundle)
applyStyles(bundle, styles)
})
}
}
function applyRaws(bundle) {
bundle.forEach((stmt, index) => {
if (index === 0) return
if (stmt.parent) {
const before = stmt.parent.node.raws.before
if (stmt.type === "nodes") stmt.nodes[0].raws.before = before
else stmt.node.raws.before = before
} else if (stmt.type === "nodes") {
stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n"
}
})
}
function applyMedia(bundle) {
bundle.forEach(stmt => {
if (!stmt.media.length) return
if (stmt.type === "import") {
stmt.node.params = `${stmt.fullUri} ${stmt.media.join(", ")}`
} else if (stmt.type === "media") stmt.node.params = stmt.media.join(", ")
else {
const nodes = stmt.nodes
const parent = nodes[0].parent
const mediaNode = postcss.atRule({
name: "media",
params: stmt.media.join(", "),
source: parent.source,
})
parent.insertBefore(nodes[0], mediaNode)
// remove nodes
nodes.forEach(node => {
node.parent = undefined
})
// better output
nodes[0].raws.before = nodes[0].raws.before || "\n"
// wrap new rules with media query
mediaNode.append(nodes)
stmt.type = "media"
stmt.node = mediaNode
delete stmt.nodes
}
})
}
function applyStyles(bundle, styles) {
styles.nodes = []
// Strip additional statements.
bundle.forEach(stmt => {
if (stmt.type === "import") {
stmt.node.parent = undefined
styles.append(stmt.node)
} else if (stmt.type === "media") {
stmt.node.parent = undefined
styles.append(stmt.node)
} else if (stmt.type === "nodes") {
stmt.nodes.forEach(node => {
node.parent = undefined
styles.append(node)
})
}
})
}
function parseStyles(result, styles, options, state, media) {
const statements = parseStatements(result, styles)
return Promise.resolve(statements)
.then(stmts => {
// process each statement in series
return stmts.reduce((promise, stmt) => {
return promise.then(() => {
stmt.media = joinMedia(media, stmt.media || [])
// skip protocol base uri (protocol://url) or protocol-relative
if (stmt.type !== "import" || /^(?:[a-z]+:)?\/\//i.test(stmt.uri)) {
return
}
if (options.filter && !options.filter(stmt.uri)) {
// rejected by filter
return
}
return resolveImportId(result, stmt, options, state)
})
}, Promise.resolve())
})
.then(() => {
const imports = []
const bundle = []
// squash statements and their children
statements.forEach(stmt => {
if (stmt.type === "import") {
if (stmt.children) {
stmt.children.forEach((child, index) => {
if (child.type === "import") imports.push(child)
else bundle.push(child)
// For better output
if (index === 0) child.parent = stmt
})
} else imports.push(stmt)
} else if (stmt.type === "media" || stmt.type === "nodes") {
bundle.push(stmt)
}
})
return imports.concat(bundle)
})
}
function resolveImportId(result, stmt, options, state) {
const atRule = stmt.node
let sourceFile
if (atRule.source && atRule.source.input && atRule.source.input.file) {
sourceFile = atRule.source.input.file
}
const base = sourceFile
? path.dirname(atRule.source.input.file)
: options.root
return Promise.resolve(options.resolve(stmt.uri, base, options))
.then(paths => {
if (!Array.isArray(paths)) paths = [paths]
// Ensure that each path is absolute:
return Promise.all(
paths.map(file => {
return !path.isAbsolute(file) ? resolveId(file, base, options) : file
})
)
})
.then(resolved => {
// Add dependency messages:
resolved.forEach(file => {
result.messages.push({
type: "dependency",
plugin: "postcss-import",
file: file,
parent: sourceFile,
})
})
return Promise.all(
resolved.map(file => {
return loadImportContent(result, stmt, file, options, state)
})
)
})
.then(result => {
// Merge loaded statements
stmt.children = result.reduce((result, statements) => {
return statements ? result.concat(statements) : result
}, [])
})
}
function loadImportContent(result, stmt, filename, options, state) {
const atRule = stmt.node
const media = stmt.media
if (options.skipDuplicates) {
// skip files already imported at the same scope
if (state.importedFiles[filename] && state.importedFiles[filename][media]) {
return
}
// save imported files to skip them next time
if (!state.importedFiles[filename]) state.importedFiles[filename] = {}
state.importedFiles[filename][media] = true
}
return Promise.resolve(options.load(filename, options)).then(content => {
if (content.trim() === "") {
result.warn(`${filename} is empty`, { node: atRule })
return
}
// skip previous imported files not containing @import rules
if (state.hashFiles[content] && state.hashFiles[content][media]) return
return processContent(result, content, filename, options).then(
importedResult => {
const styles = importedResult.root
result.messages = result.messages.concat(importedResult.messages)
if (options.skipDuplicates) {
const hasImport = styles.some(child => {
return child.type === "atrule" && child.name === "import"
})
if (!hasImport) {
// save hash files to skip them next time
if (!state.hashFiles[content]) state.hashFiles[content] = {}
state.hashFiles[content][media] = true
}
}
// recursion: import @import from imported file
return parseStyles(result, styles, options, state, media)
return {
postcssPlugin: "postcss-import",
Once(styles, { result, atRule }) {
const state = {
importedFiles: {},
hashFiles: {},
}
)
})
if (styles.source && styles.source.input && styles.source.input.file) {
state.importedFiles[styles.source.input.file] = {}
}
if (options.plugins && !Array.isArray(options.plugins)) {
throw new Error("plugins option must be an array")
}
return parseStyles(result, styles, options, state, []).then(bundle => {
applyRaws(bundle)
applyMedia(bundle)
applyStyles(bundle, styles)
})
function applyRaws(bundle) {
bundle.forEach((stmt, index) => {
if (index === 0) return
if (stmt.parent) {
const { before } = stmt.parent.node.raws
if (stmt.type === "nodes") stmt.nodes[0].raws.before = before
else stmt.node.raws.before = before
} else if (stmt.type === "nodes") {
stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n"
}
})
}
function applyMedia(bundle) {
bundle.forEach(stmt => {
if (!stmt.media.length) return
if (stmt.type === "import") {
stmt.node.params = `${stmt.fullUri} ${stmt.media.join(", ")}`
} else if (stmt.type === "media")
stmt.node.params = stmt.media.join(", ")
else {
const { nodes } = stmt
const { parent } = nodes[0]
const mediaNode = atRule({
name: "media",
params: stmt.media.join(", "),
source: parent.source,
})
parent.insertBefore(nodes[0], mediaNode)
// remove nodes
nodes.forEach(node => {
node.parent = undefined
})
// better output
nodes[0].raws.before = nodes[0].raws.before || "\n"
// wrap new rules with media query
mediaNode.append(nodes)
stmt.type = "media"
stmt.node = mediaNode
delete stmt.nodes
}
})
}
function applyStyles(bundle, styles) {
styles.nodes = []
// Strip additional statements.
bundle.forEach(stmt => {
if (["charset", "import", "media"].includes(stmt.type)) {
stmt.node.parent = undefined
styles.append(stmt.node)
} else if (stmt.type === "nodes") {
stmt.nodes.forEach(node => {
node.parent = undefined
styles.append(node)
})
}
})
}
function parseStyles(result, styles, options, state, media) {
const statements = parseStatements(result, styles)
return Promise.resolve(statements)
.then(stmts => {
// process each statement in series
return stmts.reduce((promise, stmt) => {
return promise.then(() => {
stmt.media = joinMedia(media, stmt.media || [])
// skip protocol base uri (protocol://url) or protocol-relative
if (
stmt.type !== "import" ||
/^(?:[a-z]+:)?\/\//i.test(stmt.uri)
) {
return
}
if (options.filter && !options.filter(stmt.uri)) {
// rejected by filter
return
}
return resolveImportId(result, stmt, options, state)
})
}, Promise.resolve())
})
.then(() => {
let charset
const imports = []
const bundle = []
function handleCharset(stmt) {
if (!charset) charset = stmt
// charsets aren't case-sensitive, so convert to lower case to compare
else if (
stmt.node.params.toLowerCase() !==
charset.node.params.toLowerCase()
) {
throw new Error(
`Incompatable @charset statements:
${stmt.node.params} specified in ${stmt.node.source.input.file}
${charset.node.params} specified in ${charset.node.source.input.file}`
)
}
}
// squash statements and their children
statements.forEach(stmt => {
if (stmt.type === "charset") handleCharset(stmt)
else if (stmt.type === "import") {
if (stmt.children) {
stmt.children.forEach((child, index) => {
if (child.type === "import") imports.push(child)
else if (child.type === "charset") handleCharset(child)
else bundle.push(child)
// For better output
if (index === 0) child.parent = stmt
})
} else imports.push(stmt)
} else if (stmt.type === "media" || stmt.type === "nodes") {
bundle.push(stmt)
}
})
return charset
? [charset, ...imports.concat(bundle)]
: imports.concat(bundle)
})
}
function resolveImportId(result, stmt, options, state) {
const atRule = stmt.node
let sourceFile
if (atRule.source && atRule.source.input && atRule.source.input.file) {
sourceFile = atRule.source.input.file
}
const base = sourceFile
? path.dirname(atRule.source.input.file)
: options.root
return Promise.resolve(options.resolve(stmt.uri, base, options))
.then(paths => {
if (!Array.isArray(paths)) paths = [paths]
// Ensure that each path is absolute:
return Promise.all(
paths.map(file => {
return !path.isAbsolute(file)
? resolveId(file, base, options)
: file
})
)
})
.then(resolved => {
// Add dependency messages:
resolved.forEach(file => {
result.messages.push({
type: "dependency",
plugin: "postcss-import",
file,
parent: sourceFile,
})
})
return Promise.all(
resolved.map(file => {
return loadImportContent(result, stmt, file, options, state)
})
)
})
.then(result => {
// Merge loaded statements
stmt.children = result.reduce((result, statements) => {
return statements ? result.concat(statements) : result
}, [])
})
}
function loadImportContent(result, stmt, filename, options, state) {
const atRule = stmt.node
const { media } = stmt
if (options.skipDuplicates) {
// skip files already imported at the same scope
if (
state.importedFiles[filename] &&
state.importedFiles[filename][media]
) {
return
}
// save imported files to skip them next time
if (!state.importedFiles[filename]) state.importedFiles[filename] = {}
state.importedFiles[filename][media] = true
}
return Promise.resolve(options.load(filename, options)).then(
content => {
if (content.trim() === "") {
result.warn(`${filename} is empty`, { node: atRule })
return
}
// skip previous imported files not containing @import rules
if (state.hashFiles[content] && state.hashFiles[content][media])
return
return processContent(result, content, filename, options).then(
importedResult => {
const styles = importedResult.root
result.messages = result.messages.concat(
importedResult.messages
)
if (options.skipDuplicates) {
const hasImport = styles.some(child => {
return child.type === "atrule" && child.name === "import"
})
if (!hasImport) {
// save hash files to skip them next time
if (!state.hashFiles[content]) state.hashFiles[content] = {}
state.hashFiles[content][media] = true
}
}
// recursion: import @import from imported file
return parseStyles(result, styles, options, state, media)
}
)
}
)
}
},
}
}
module.exports = postcss.plugin("postcss-import", AtImport)
AtImport.postcss = true
module.exports = AtImport

View File

@@ -1,6 +1,6 @@
"use strict"
module.exports = function(parentMedia, childMedia) {
module.exports = function (parentMedia, childMedia) {
if (!parentMedia.length && childMedia.length) return childMedia
if (parentMedia.length && !childMedia.length) return parentMedia
if (!parentMedia.length && !childMedia.length) return []

View File

@@ -4,7 +4,7 @@
const valueParser = require("postcss-value-parser")
// extended tooling
const stringify = valueParser.stringify
const { stringify } = valueParser
function split(params, start) {
const list = []
@@ -20,7 +20,7 @@ function split(params, start) {
return list
}
module.exports = function(result, styles) {
module.exports = function (result, styles) {
const statements = []
let nodes = []
@@ -29,13 +29,14 @@ module.exports = function(result, styles) {
if (node.type === "atrule") {
if (node.name === "import") stmt = parseImport(result, node)
else if (node.name === "media") stmt = parseMedia(result, node)
else if (node.name === "charset") stmt = parseCharset(result, node)
}
if (stmt) {
if (nodes.length) {
statements.push({
type: "nodes",
nodes: nodes,
nodes,
media: [],
})
nodes = []
@@ -47,7 +48,7 @@ module.exports = function(result, styles) {
if (nodes.length) {
statements.push({
type: "nodes",
nodes: nodes,
nodes,
media: [],
})
}
@@ -64,19 +65,34 @@ function parseMedia(result, atRule) {
}
}
function parseCharset(result, atRule) {
if (atRule.prev()) {
return result.warn("@charset must precede all other statements", {
node: atRule,
})
}
return {
type: "charset",
node: atRule,
media: [],
}
}
function parseImport(result, atRule) {
let prev = getPrev(atRule)
let prev = atRule.prev()
if (prev) {
do {
if (
prev.type !== "atrule" ||
(prev.name !== "import" && prev.name !== "charset")
prev.type !== "comment" &&
(prev.type !== "atrule" ||
(prev.name !== "import" && prev.name !== "charset"))
) {
return result.warn(
"@import must precede all other statements (besides @charset)",
{ node: atRule }
)
} else prev = getPrev(prev)
}
prev = prev.prev()
} while (prev)
}
@@ -127,11 +143,3 @@ function parseImport(result, atRule) {
return stmt
}
function getPrev(item) {
let prev = item.prev()
while (prev && prev.type === "comment") {
prev = prev.prev()
}
return prev
}

View File

@@ -10,7 +10,7 @@ const postcss = require("postcss")
let sugarss
module.exports = function processContent(result, content, filename, options) {
const plugins = options.plugins
const { plugins } = options
const ext = path.extname(filename)
const parserList = []
@@ -20,9 +20,7 @@ module.exports = function processContent(result, content, filename, options) {
if (!sugarss) {
try {
sugarss = require("sugarss")
} catch (e) {
// Ignore
}
} catch {} // Ignore
}
if (sugarss) return runPostcss(content, filename, plugins, [sugarss])
}

View File

@@ -11,13 +11,13 @@ function resolveModule(id, opts) {
})
}
module.exports = function(id, base, options) {
module.exports = function (id, base, options) {
const paths = options.path
const resolveOpts = {
basedir: base,
moduleDirectory: moduleDirectories.concat(options.addModulesDirectories),
paths: paths,
paths,
extensions: [".css"],
packageFilter: function processPackage(pkg) {
if (pkg.style) pkg.main = pkg.style

View File

@@ -1,22 +0,0 @@
Copyright (c) Bogdan Chadkin <trysound@yandex.ru>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,253 +0,0 @@
# postcss-value-parser
[![Travis CI](https://travis-ci.org/TrySound/postcss-value-parser.svg)](https://travis-ci.org/TrySound/postcss-value-parser)
Transforms CSS declaration values and at-rule parameters into a tree of nodes, and provides a simple traversal API.
## Usage
```js
var valueParser = require('postcss-value-parser');
var cssBackgroundValue = 'url(foo.png) no-repeat 40px 73%';
var parsedValue = valueParser(cssBackgroundValue);
// parsedValue exposes an API described below,
// e.g. parsedValue.walk(..), parsedValue.toString(), etc.
```
For example, parsing the value `rgba(233, 45, 66, .5)` will return the following:
```js
{
nodes: [
{
type: 'function',
value: 'rgba',
before: '',
after: '',
nodes: [
{ type: 'word', value: '233' },
{ type: 'div', value: ',', before: '', after: ' ' },
{ type: 'word', value: '45' },
{ type: 'div', value: ',', before: '', after: ' ' },
{ type: 'word', value: '66' },
{ type: 'div', value: ',', before: ' ', after: '' },
{ type: 'word', value: '.5' }
]
}
]
}
```
If you wanted to convert each `rgba()` value in `sourceCSS` to a hex value, you could do so like this:
```js
var valueParser = require('postcss-value-parser');
var parsed = valueParser(sourceCSS);
// walk() will visit all the of the nodes in the tree,
// invoking the callback for each.
parsed.walk(function (node) {
// Since we only want to transform rgba() values,
// we can ignore anything else.
if (node.type !== 'function' && node.value !== 'rgba') return;
// We can make an array of the rgba() arguments to feed to a
// convertToHex() function
var color = node.nodes.filter(function (node) {
return node.type === 'word';
}).map(function (node) {
return Number(node.value);
}); // [233, 45, 66, .5]
// Now we will transform the existing rgba() function node
// into a word node with the hex value
node.type = 'word';
node.value = convertToHex(color);
})
parsed.toString(); // #E92D42
```
## Nodes
Each node is an object with these common properties:
- **type**: The type of node (`word`, `string`, `div`, `space`, `comment`, or `function`).
Each type is documented below.
- **value**: Each node has a `value` property; but what exactly `value` means
is specific to the node type. Details are documented for each type below.
- **sourceIndex**: The starting index of the node within the original source
string. For example, given the source string `10px 20px`, the `word` node
whose value is `20px` will have a `sourceIndex` of `5`.
### word
The catch-all node type that includes keywords (e.g. `no-repeat`),
quantities (e.g. `20px`, `75%`, `1.5`), and hex colors (e.g. `#e6e6e6`).
Node-specific properties:
- **value**: The "word" itself.
### string
A quoted string value, e.g. `"something"` in `content: "something";`.
Node-specific properties:
- **value**: The text content of the string.
- **quote**: The quotation mark surrounding the string, either `"` or `'`.
- **unclosed**: `true` if the string was not closed properly. e.g. `"unclosed string `.
### div
A divider, for example
- `,` in `animation-duration: 1s, 2s, 3s`
- `/` in `border-radius: 10px / 23px`
- `:` in `(min-width: 700px)`
Node-specific properties:
- **value**: The divider character. Either `,`, `/`, or `:` (see examples above).
- **before**: Whitespace before the divider.
- **after**: Whitespace after the divider.
### space
Whitespace used as a separator, e.g. ` ` occurring twice in `border: 1px solid black;`.
Node-specific properties:
- **value**: The whitespace itself.
### comment
A CSS comment starts with `/*` and ends with `*/`
Node-specific properties:
- **value**: The comment value without `/*` and `*/`
- **unclosed**: `true` if the comment was not closed properly. e.g. `/* comment without an end `.
### function
A CSS function, e.g. `rgb(0,0,0)` or `url(foo.bar)`.
Function nodes have nodes nested within them: the function arguments.
Additional properties:
- **value**: The name of the function, e.g. `rgb` in `rgb(0,0,0)`.
- **before**: Whitespace after the opening parenthesis and before the first argument,
e.g. ` ` in `rgb( 0,0,0)`.
- **after**: Whitespace before the closing parenthesis and after the last argument,
e.g. ` ` in `rgb(0,0,0 )`.
- **nodes**: More nodes representing the arguments to the function.
- **unclosed**: `true` if the parentheses was not closed properly. e.g. `( unclosed-function `.
Media features surrounded by parentheses are considered functions with an
empty value. For example, `(min-width: 700px)` parses to these nodes:
```js
[
{
type: 'function', value: '', before: '', after: '',
nodes: [
{ type: 'word', value: 'min-width' },
{ type: 'div', value: ':', before: '', after: ' ' },
{ type: 'word', value: '700px' }
]
}
]
```
`url()` functions can be parsed a little bit differently depending on
whether the first character in the argument is a quotation mark.
`url( /gfx/img/bg.jpg )` parses to:
```js
{ type: 'function', sourceIndex: 0, value: 'url', before: ' ', after: ' ', nodes: [
{ type: 'word', sourceIndex: 5, value: '/gfx/img/bg.jpg' }
] }
```
`url( "/gfx/img/bg.jpg" )`, on the other hand, parses to:
```js
{ type: 'function', sourceIndex: 0, value: 'url', before: ' ', after: ' ', nodes: [
type: 'string', sourceIndex: 5, quote: '"', value: '/gfx/img/bg.jpg' },
] }
```
## API
```
var valueParser = require('postcss-value-parser');
```
### valueParser.unit(quantity)
Parses `quantity`, distinguishing the number from the unit. Returns an object like the following:
```js
// Given 2rem
{
number: '2',
unit: 'rem'
}
```
If the `quantity` argument cannot be parsed as a number, returns `false`.
*This function does not parse complete values*: you cannot pass it `1px solid black` and expect `px` as
the unit. Instead, you should pass it single quantities only. Parse `1px solid black`, then pass it
the stringified `1px` node (a `word` node) to parse the number and unit.
### valueParser.stringify(nodes[, custom])
Stringifies a node or array of nodes.
The `custom` function is called for each `node`; return a string to override the default behaviour.
### valueParser.walk(nodes, callback[, bubble])
Walks each provided node, recursively walking all descendent nodes within functions.
Returning `false` in the `callback` will prevent traversal of descendent nodes (within functions).
You can use this feature to for shallow iteration, walking over only the *immediate* children.
*Note: This only applies if `bubble` is `false` (which is the default).*
By default, the tree is walked from the outermost node inwards.
To reverse the direction, pass `true` for the `bubble` argument.
The `callback` is invoked with three arguments: `callback(node, index, nodes)`.
- `node`: The current node.
- `index`: The index of the current node.
- `nodes`: The complete nodes array passed to `walk()`.
Returns the `valueParser` instance.
### var parsed = valueParser(value)
Returns the parsed node tree.
### parsed.nodes
The array of nodes.
### parsed.toString()
Stringifies the node tree.
### parsed.walk(callback[, bubble])
Walks each node inside `parsed.nodes`. See the documentation for `valueParser.walk()` above.
# License
MIT © [Bogdan Chadkin](mailto:trysound@yandex.ru)

View File

@@ -1,28 +0,0 @@
var parse = require("./parse");
var walk = require("./walk");
var stringify = require("./stringify");
function ValueParser(value) {
if (this instanceof ValueParser) {
this.nodes = parse(value);
return this;
}
return new ValueParser(value);
}
ValueParser.prototype.toString = function() {
return Array.isArray(this.nodes) ? stringify(this.nodes) : "";
};
ValueParser.prototype.walk = function(cb, bubble) {
walk(this.nodes, cb, bubble);
return this;
};
ValueParser.unit = require("./unit");
ValueParser.walk = walk;
ValueParser.stringify = stringify;
module.exports = ValueParser;

View File

@@ -1,251 +0,0 @@
var openParentheses = "(".charCodeAt(0);
var closeParentheses = ")".charCodeAt(0);
var singleQuote = "'".charCodeAt(0);
var doubleQuote = '"'.charCodeAt(0);
var backslash = "\\".charCodeAt(0);
var slash = "/".charCodeAt(0);
var comma = ",".charCodeAt(0);
var colon = ":".charCodeAt(0);
var star = "*".charCodeAt(0);
module.exports = function(input) {
var tokens = [];
var value = input;
var next, quote, prev, token, escape, escapePos, whitespacePos;
var pos = 0;
var code = value.charCodeAt(pos);
var max = value.length;
var stack = [{ nodes: tokens }];
var balanced = 0;
var parent;
var name = "";
var before = "";
var after = "";
while (pos < max) {
// Whitespaces
if (code <= 32) {
next = pos;
do {
next += 1;
code = value.charCodeAt(next);
} while (code <= 32);
token = value.slice(pos, next);
prev = tokens[tokens.length - 1];
if (code === closeParentheses && balanced) {
after = token;
} else if (prev && prev.type === "div") {
prev.after = token;
} else if (
code === comma ||
code === colon ||
(code === slash && value.charCodeAt(next + 1) !== star)
) {
before = token;
} else {
tokens.push({
type: "space",
sourceIndex: pos,
value: token
});
}
pos = next;
// Quotes
} else if (code === singleQuote || code === doubleQuote) {
next = pos;
quote = code === singleQuote ? "'" : '"';
token = {
type: "string",
sourceIndex: pos,
quote: quote
};
do {
escape = false;
next = value.indexOf(quote, next + 1);
if (~next) {
escapePos = next;
while (value.charCodeAt(escapePos - 1) === backslash) {
escapePos -= 1;
escape = !escape;
}
} else {
value += quote;
next = value.length - 1;
token.unclosed = true;
}
} while (escape);
token.value = value.slice(pos + 1, next);
tokens.push(token);
pos = next + 1;
code = value.charCodeAt(pos);
// Comments
} else if (code === slash && value.charCodeAt(pos + 1) === star) {
token = {
type: "comment",
sourceIndex: pos
};
next = value.indexOf("*/", pos);
if (next === -1) {
token.unclosed = true;
next = value.length;
}
token.value = value.slice(pos + 2, next);
tokens.push(token);
pos = next + 2;
code = value.charCodeAt(pos);
// Dividers
} else if (code === slash || code === comma || code === colon) {
token = value[pos];
tokens.push({
type: "div",
sourceIndex: pos - before.length,
value: token,
before: before,
after: ""
});
before = "";
pos += 1;
code = value.charCodeAt(pos);
// Open parentheses
} else if (openParentheses === code) {
// Whitespaces after open parentheses
next = pos;
do {
next += 1;
code = value.charCodeAt(next);
} while (code <= 32);
token = {
type: "function",
sourceIndex: pos - name.length,
value: name,
before: value.slice(pos + 1, next)
};
pos = next;
if (name === "url" && code !== singleQuote && code !== doubleQuote) {
next -= 1;
do {
escape = false;
next = value.indexOf(")", next + 1);
if (~next) {
escapePos = next;
while (value.charCodeAt(escapePos - 1) === backslash) {
escapePos -= 1;
escape = !escape;
}
} else {
value += ")";
next = value.length - 1;
token.unclosed = true;
}
} while (escape);
// Whitespaces before closed
whitespacePos = next;
do {
whitespacePos -= 1;
code = value.charCodeAt(whitespacePos);
} while (code <= 32);
if (pos !== whitespacePos + 1) {
token.nodes = [
{
type: "word",
sourceIndex: pos,
value: value.slice(pos, whitespacePos + 1)
}
];
} else {
token.nodes = [];
}
if (token.unclosed && whitespacePos + 1 !== next) {
token.after = "";
token.nodes.push({
type: "space",
sourceIndex: whitespacePos + 1,
value: value.slice(whitespacePos + 1, next)
});
} else {
token.after = value.slice(whitespacePos + 1, next);
}
pos = next + 1;
code = value.charCodeAt(pos);
tokens.push(token);
} else {
balanced += 1;
token.after = "";
tokens.push(token);
stack.push(token);
tokens = token.nodes = [];
parent = token;
}
name = "";
// Close parentheses
} else if (closeParentheses === code && balanced) {
pos += 1;
code = value.charCodeAt(pos);
parent.after = after;
after = "";
balanced -= 1;
stack.pop();
parent = stack[balanced];
tokens = parent.nodes;
// Words
} else {
next = pos;
do {
if (code === backslash) {
next += 1;
}
next += 1;
code = value.charCodeAt(next);
} while (
next < max &&
!(
code <= 32 ||
code === singleQuote ||
code === doubleQuote ||
code === comma ||
code === colon ||
code === slash ||
code === openParentheses ||
(code === closeParentheses && balanced)
)
);
token = value.slice(pos, next);
if (openParentheses === code) {
name = token;
} else {
tokens.push({
type: "word",
sourceIndex: pos,
value: token
});
}
pos = next;
}
}
for (pos = stack.length - 1; pos; pos -= 1) {
stack[pos].unclosed = true;
}
return stack[0].nodes;
};

View File

@@ -1,48 +0,0 @@
function stringifyNode(node, custom) {
var type = node.type;
var value = node.value;
var buf;
var customResult;
if (custom && (customResult = custom(node)) !== undefined) {
return customResult;
} else if (type === "word" || type === "space") {
return value;
} else if (type === "string") {
buf = node.quote || "";
return buf + value + (node.unclosed ? "" : buf);
} else if (type === "comment") {
return "/*" + value + (node.unclosed ? "" : "*/");
} else if (type === "div") {
return (node.before || "") + value + (node.after || "");
} else if (Array.isArray(node.nodes)) {
buf = stringify(node.nodes);
if (type !== "function") {
return buf;
}
return (
value +
"(" +
(node.before || "") +
buf +
(node.after || "") +
(node.unclosed ? "" : ")")
);
}
return value;
}
function stringify(nodes, custom) {
var result, i;
if (Array.isArray(nodes)) {
result = "";
for (i = nodes.length - 1; ~i; i -= 1) {
result = stringifyNode(nodes[i], custom) + result;
}
return result;
}
return stringifyNode(nodes, custom);
}
module.exports = stringify;

View File

@@ -1,49 +0,0 @@
var minus = "-".charCodeAt(0);
var plus = "+".charCodeAt(0);
var dot = ".".charCodeAt(0);
var exp = "e".charCodeAt(0);
var EXP = "E".charCodeAt(0);
module.exports = function(value) {
var pos = 0;
var length = value.length;
var dotted = false;
var sciPos = -1;
var containsNumber = false;
var code;
while (pos < length) {
code = value.charCodeAt(pos);
if (code >= 48 && code <= 57) {
containsNumber = true;
} else if (code === exp || code === EXP) {
if (sciPos > -1) {
break;
}
sciPos = pos;
} else if (code === dot) {
if (dotted) {
break;
}
dotted = true;
} else if (code === plus || code === minus) {
if (pos !== 0) {
break;
}
} else {
break;
}
pos += 1;
}
if (sciPos + 1 === pos) pos--;
return containsNumber
? {
number: value.slice(0, pos),
unit: value.slice(pos)
}
: false;
};

View File

@@ -1,22 +0,0 @@
module.exports = function walk(nodes, cb, bubble) {
var i, max, node, result;
for (i = 0, max = nodes.length; i < max; i += 1) {
node = nodes[i];
if (!bubble) {
result = cb(node, i, nodes);
}
if (
result !== false &&
node.type === "function" &&
Array.isArray(node.nodes)
) {
walk(node.nodes, cb, bubble);
}
if (bubble) {
cb(node, i, nodes);
}
}
};

View File

@@ -1,90 +0,0 @@
{
"_args": [
[
"postcss-value-parser@3.3.1",
"J:\\Github\\CURD-TS"
]
],
"_development": true,
"_from": "postcss-value-parser@3.3.1",
"_id": "postcss-value-parser@3.3.1",
"_inBundle": false,
"_integrity": "sha1-n/giVH4okyE88cMO+lGsX9G6goE=",
"_location": "/postcss-import/postcss-value-parser",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "postcss-value-parser@3.3.1",
"name": "postcss-value-parser",
"escapedName": "postcss-value-parser",
"rawSpec": "3.3.1",
"saveSpec": null,
"fetchSpec": "3.3.1"
},
"_requiredBy": [
"/postcss-import"
],
"_resolved": "http://192.168.250.101:4873/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
"_spec": "3.3.1",
"_where": "J:\\Github\\CURD-TS",
"author": {
"name": "Bogdan Chadkin",
"email": "trysound@yandex.ru"
},
"bugs": {
"url": "https://github.com/TrySound/postcss-value-parser/issues"
},
"description": "Transforms css values and at-rule params into the tree",
"devDependencies": {
"eslint": "^5.6.1",
"husky": "^1.0.0",
"lint-staged": "^7.3.0",
"prettier": "^1.4.4",
"tap-spec": "^5.0.0",
"tape": "^4.2.0"
},
"eslintConfig": {
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended"
},
"files": [
"lib"
],
"homepage": "https://github.com/TrySound/postcss-value-parser",
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"keywords": [
"postcss",
"value",
"parser"
],
"license": "MIT",
"lint-staged": {
"*.js": [
"eslint",
"prettier --write",
"git add"
]
},
"main": "lib/index.js",
"name": "postcss-value-parser",
"repository": {
"type": "git",
"url": "git+https://github.com/TrySound/postcss-value-parser.git"
},
"scripts": {
"lint": "yarn lint:js && yarn lint:prettier",
"lint:js": "eslint . --cache",
"lint:prettier": "prettier '**/*.js' --list-different",
"pretest": "yarn lint",
"test": "tape test/*.js | tap-spec"
},
"version": "3.3.1"
}

View File

@@ -1,32 +1,32 @@
{
"_args": [
[
"postcss-import@12.0.1",
"postcss-import@14.0.0",
"J:\\Github\\CURD-TS"
]
],
"_development": true,
"_from": "postcss-import@12.0.1",
"_id": "postcss-import@12.0.1",
"_from": "postcss-import@14.0.0",
"_id": "postcss-import@14.0.0",
"_inBundle": false,
"_integrity": "sha1-z4x6sLXMq1ZJAkU25WX4QZKLcVM=",
"_integrity": "sha1-PtHa2sWhZlC94/TN6mYzucPHgpY=",
"_location": "/postcss-import",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "postcss-import@12.0.1",
"raw": "postcss-import@14.0.0",
"name": "postcss-import",
"escapedName": "postcss-import",
"rawSpec": "12.0.1",
"rawSpec": "14.0.0",
"saveSpec": null,
"fetchSpec": "12.0.1"
"fetchSpec": "14.0.0"
},
"_requiredBy": [
"/vite"
"#DEV:/"
],
"_resolved": "http://192.168.250.101:4873/postcss-import/-/postcss-import-12.0.1.tgz",
"_spec": "12.0.1",
"_resolved": "http://192.168.250.101:4873/postcss-import/-/postcss-import-14.0.0.tgz",
"_spec": "14.0.0",
"_where": "J:\\Github\\CURD-TS",
"author": {
"name": "Maxime Thirouin"
@@ -35,27 +35,29 @@
"url": "https://github.com/postcss/postcss-import/issues"
},
"dependencies": {
"postcss": "^7.0.1",
"postcss-value-parser": "^3.2.3",
"postcss-value-parser": "^4.0.0",
"read-cache": "^1.0.0",
"resolve": "^1.1.7"
},
"description": "PostCSS plugin to import CSS files",
"devDependencies": {
"ava": "^0.25.0",
"eslint": "^5.0.0",
"eslint-config-i-am-meticulous": "^11.0.0",
"eslint-plugin-import": "^2.2.0",
"ava": "^3.0.0",
"eslint": "^7.0.0",
"eslint-config-problems": "^5.0.0",
"eslint-plugin-prettier": "^3.0.0",
"postcss-scss": "^2.0.0",
"prettier": "~1.14.0",
"sugarss": "^2.0.0"
"postcss": "^8.0.0",
"postcss-scss": "^3.0.0",
"prettier": "~2.2.0",
"sugarss": "^3.0.0"
},
"engines": {
"node": ">=6.0.0"
"node": ">=10.0.0"
},
"eslintConfig": {
"extends": "eslint-config-i-am-meticulous",
"extends": "eslint-config-problems",
"env": {
"node": true
},
"plugins": [
"prettier"
],
@@ -64,7 +66,7 @@
"error",
{
"semi": false,
"trailingComma": "es5"
"arrowParens": "avoid"
}
]
}
@@ -84,6 +86,9 @@
],
"license": "MIT",
"name": "postcss-import",
"peerDependencies": {
"postcss": "^8.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/postcss/postcss-import.git"
@@ -94,5 +99,5 @@
"pretest": "npm run lint",
"test": "ava"
},
"version": "12.0.1"
"version": "14.0.0"
}