summaryrefslogtreecommitdiff
path: root/node_modules/postcss/lib/container.js
diff options
context:
space:
mode:
authorPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:54:57 +0100
committerPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:57:48 +0100
commitb1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c (patch)
tree49d360fd6cbc6a2754efe93524ac47ff0fbe0f7d /node_modules/postcss/lib/container.js
Docs
Diffstat (limited to 'node_modules/postcss/lib/container.js')
-rw-r--r--node_modules/postcss/lib/container.js439
1 files changed, 439 insertions, 0 deletions
diff --git a/node_modules/postcss/lib/container.js b/node_modules/postcss/lib/container.js
new file mode 100644
index 0000000..914c053
--- /dev/null
+++ b/node_modules/postcss/lib/container.js
@@ -0,0 +1,439 @@
+'use strict'
+
+let { isClean, my } = require('./symbols')
+let Declaration = require('./declaration')
+let Comment = require('./comment')
+let Node = require('./node')
+
+let parse, Rule, AtRule, Root
+
+function cleanSource(nodes) {
+ return nodes.map(i => {
+ if (i.nodes) i.nodes = cleanSource(i.nodes)
+ delete i.source
+ return i
+ })
+}
+
+function markDirtyUp(node) {
+ node[isClean] = false
+ if (node.proxyOf.nodes) {
+ for (let i of node.proxyOf.nodes) {
+ markDirtyUp(i)
+ }
+ }
+}
+
+class Container extends Node {
+ append(...children) {
+ for (let child of children) {
+ let nodes = this.normalize(child, this.last)
+ for (let node of nodes) this.proxyOf.nodes.push(node)
+ }
+
+ this.markDirty()
+
+ return this
+ }
+
+ cleanRaws(keepBetween) {
+ super.cleanRaws(keepBetween)
+ if (this.nodes) {
+ for (let node of this.nodes) node.cleanRaws(keepBetween)
+ }
+ }
+
+ each(callback) {
+ if (!this.proxyOf.nodes) return undefined
+ let iterator = this.getIterator()
+
+ let index, result
+ while (this.indexes[iterator] < this.proxyOf.nodes.length) {
+ index = this.indexes[iterator]
+ result = callback(this.proxyOf.nodes[index], index)
+ if (result === false) break
+
+ this.indexes[iterator] += 1
+ }
+
+ delete this.indexes[iterator]
+ return result
+ }
+
+ every(condition) {
+ return this.nodes.every(condition)
+ }
+
+ getIterator() {
+ if (!this.lastEach) this.lastEach = 0
+ if (!this.indexes) this.indexes = {}
+
+ this.lastEach += 1
+ let iterator = this.lastEach
+ this.indexes[iterator] = 0
+
+ return iterator
+ }
+
+ getProxyProcessor() {
+ return {
+ get(node, prop) {
+ if (prop === 'proxyOf') {
+ return node
+ } else if (!node[prop]) {
+ return node[prop]
+ } else if (
+ prop === 'each' ||
+ (typeof prop === 'string' && prop.startsWith('walk'))
+ ) {
+ return (...args) => {
+ return node[prop](
+ ...args.map(i => {
+ if (typeof i === 'function') {
+ return (child, index) => i(child.toProxy(), index)
+ } else {
+ return i
+ }
+ })
+ )
+ }
+ } else if (prop === 'every' || prop === 'some') {
+ return cb => {
+ return node[prop]((child, ...other) =>
+ cb(child.toProxy(), ...other)
+ )
+ }
+ } else if (prop === 'root') {
+ return () => node.root().toProxy()
+ } else if (prop === 'nodes') {
+ return node.nodes.map(i => i.toProxy())
+ } else if (prop === 'first' || prop === 'last') {
+ return node[prop].toProxy()
+ } else {
+ return node[prop]
+ }
+ },
+
+ set(node, prop, value) {
+ if (node[prop] === value) return true
+ node[prop] = value
+ if (prop === 'name' || prop === 'params' || prop === 'selector') {
+ node.markDirty()
+ }
+ return true
+ }
+ }
+ }
+
+ index(child) {
+ if (typeof child === 'number') return child
+ if (child.proxyOf) child = child.proxyOf
+ return this.proxyOf.nodes.indexOf(child)
+ }
+
+ insertAfter(exist, add) {
+ let existIndex = this.index(exist)
+ let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()
+ existIndex = this.index(exist)
+ for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)
+
+ let index
+ for (let id in this.indexes) {
+ index = this.indexes[id]
+ if (existIndex < index) {
+ this.indexes[id] = index + nodes.length
+ }
+ }
+
+ this.markDirty()
+
+ return this
+ }
+
+ insertBefore(exist, add) {
+ let existIndex = this.index(exist)
+ let type = existIndex === 0 ? 'prepend' : false
+ let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse()
+ existIndex = this.index(exist)
+ for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)
+
+ let index
+ for (let id in this.indexes) {
+ index = this.indexes[id]
+ if (existIndex <= index) {
+ this.indexes[id] = index + nodes.length
+ }
+ }
+
+ this.markDirty()
+
+ return this
+ }
+
+ normalize(nodes, sample) {
+ if (typeof nodes === 'string') {
+ nodes = cleanSource(parse(nodes).nodes)
+ } else if (Array.isArray(nodes)) {
+ nodes = nodes.slice(0)
+ for (let i of nodes) {
+ if (i.parent) i.parent.removeChild(i, 'ignore')
+ }
+ } else if (nodes.type === 'root' && this.type !== 'document') {
+ nodes = nodes.nodes.slice(0)
+ for (let i of nodes) {
+ if (i.parent) i.parent.removeChild(i, 'ignore')
+ }
+ } else if (nodes.type) {
+ nodes = [nodes]
+ } else if (nodes.prop) {
+ if (typeof nodes.value === 'undefined') {
+ throw new Error('Value field is missed in node creation')
+ } else if (typeof nodes.value !== 'string') {
+ nodes.value = String(nodes.value)
+ }
+ nodes = [new Declaration(nodes)]
+ } else if (nodes.selector) {
+ nodes = [new Rule(nodes)]
+ } else if (nodes.name) {
+ nodes = [new AtRule(nodes)]
+ } else if (nodes.text) {
+ nodes = [new Comment(nodes)]
+ } else {
+ throw new Error('Unknown node type in node creation')
+ }
+
+ let processed = nodes.map(i => {
+ /* c8 ignore next */
+ if (!i[my]) Container.rebuild(i)
+ i = i.proxyOf
+ if (i.parent) i.parent.removeChild(i)
+ if (i[isClean]) markDirtyUp(i)
+ if (typeof i.raws.before === 'undefined') {
+ if (sample && typeof sample.raws.before !== 'undefined') {
+ i.raws.before = sample.raws.before.replace(/\S/g, '')
+ }
+ }
+ i.parent = this.proxyOf
+ return i
+ })
+
+ return processed
+ }
+
+ prepend(...children) {
+ children = children.reverse()
+ for (let child of children) {
+ let nodes = this.normalize(child, this.first, 'prepend').reverse()
+ for (let node of nodes) this.proxyOf.nodes.unshift(node)
+ for (let id in this.indexes) {
+ this.indexes[id] = this.indexes[id] + nodes.length
+ }
+ }
+
+ this.markDirty()
+
+ return this
+ }
+
+ push(child) {
+ child.parent = this
+ this.proxyOf.nodes.push(child)
+ return this
+ }
+
+ removeAll() {
+ for (let node of this.proxyOf.nodes) node.parent = undefined
+ this.proxyOf.nodes = []
+
+ this.markDirty()
+
+ return this
+ }
+
+ removeChild(child) {
+ child = this.index(child)
+ this.proxyOf.nodes[child].parent = undefined
+ this.proxyOf.nodes.splice(child, 1)
+
+ let index
+ for (let id in this.indexes) {
+ index = this.indexes[id]
+ if (index >= child) {
+ this.indexes[id] = index - 1
+ }
+ }
+
+ this.markDirty()
+
+ return this
+ }
+
+ replaceValues(pattern, opts, callback) {
+ if (!callback) {
+ callback = opts
+ opts = {}
+ }
+
+ this.walkDecls(decl => {
+ if (opts.props && !opts.props.includes(decl.prop)) return
+ if (opts.fast && !decl.value.includes(opts.fast)) return
+
+ decl.value = decl.value.replace(pattern, callback)
+ })
+
+ this.markDirty()
+
+ return this
+ }
+
+ some(condition) {
+ return this.nodes.some(condition)
+ }
+
+ walk(callback) {
+ return this.each((child, i) => {
+ let result
+ try {
+ result = callback(child, i)
+ } catch (e) {
+ throw child.addToError(e)
+ }
+ if (result !== false && child.walk) {
+ result = child.walk(callback)
+ }
+
+ return result
+ })
+ }
+
+ walkAtRules(name, callback) {
+ if (!callback) {
+ callback = name
+ return this.walk((child, i) => {
+ if (child.type === 'atrule') {
+ return callback(child, i)
+ }
+ })
+ }
+ if (name instanceof RegExp) {
+ return this.walk((child, i) => {
+ if (child.type === 'atrule' && name.test(child.name)) {
+ return callback(child, i)
+ }
+ })
+ }
+ return this.walk((child, i) => {
+ if (child.type === 'atrule' && child.name === name) {
+ return callback(child, i)
+ }
+ })
+ }
+
+ walkComments(callback) {
+ return this.walk((child, i) => {
+ if (child.type === 'comment') {
+ return callback(child, i)
+ }
+ })
+ }
+
+ walkDecls(prop, callback) {
+ if (!callback) {
+ callback = prop
+ return this.walk((child, i) => {
+ if (child.type === 'decl') {
+ return callback(child, i)
+ }
+ })
+ }
+ if (prop instanceof RegExp) {
+ return this.walk((child, i) => {
+ if (child.type === 'decl' && prop.test(child.prop)) {
+ return callback(child, i)
+ }
+ })
+ }
+ return this.walk((child, i) => {
+ if (child.type === 'decl' && child.prop === prop) {
+ return callback(child, i)
+ }
+ })
+ }
+
+ walkRules(selector, callback) {
+ if (!callback) {
+ callback = selector
+
+ return this.walk((child, i) => {
+ if (child.type === 'rule') {
+ return callback(child, i)
+ }
+ })
+ }
+ if (selector instanceof RegExp) {
+ return this.walk((child, i) => {
+ if (child.type === 'rule' && selector.test(child.selector)) {
+ return callback(child, i)
+ }
+ })
+ }
+ return this.walk((child, i) => {
+ if (child.type === 'rule' && child.selector === selector) {
+ return callback(child, i)
+ }
+ })
+ }
+
+ get first() {
+ if (!this.proxyOf.nodes) return undefined
+ return this.proxyOf.nodes[0]
+ }
+
+ get last() {
+ if (!this.proxyOf.nodes) return undefined
+ return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]
+ }
+}
+
+Container.registerParse = dependant => {
+ parse = dependant
+}
+
+Container.registerRule = dependant => {
+ Rule = dependant
+}
+
+Container.registerAtRule = dependant => {
+ AtRule = dependant
+}
+
+Container.registerRoot = dependant => {
+ Root = dependant
+}
+
+module.exports = Container
+Container.default = Container
+
+/* c8 ignore start */
+Container.rebuild = node => {
+ if (node.type === 'atrule') {
+ Object.setPrototypeOf(node, AtRule.prototype)
+ } else if (node.type === 'rule') {
+ Object.setPrototypeOf(node, Rule.prototype)
+ } else if (node.type === 'decl') {
+ Object.setPrototypeOf(node, Declaration.prototype)
+ } else if (node.type === 'comment') {
+ Object.setPrototypeOf(node, Comment.prototype)
+ } else if (node.type === 'root') {
+ Object.setPrototypeOf(node, Root.prototype)
+ }
+
+ node[my] = true
+
+ if (node.nodes) {
+ node.nodes.forEach(child => {
+ Container.rebuild(child)
+ })
+ }
+}
+/* c8 ignore stop */