summaryrefslogtreecommitdiff
path: root/node_modules/tailwindcss/src/value-parser/parse.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/tailwindcss/src/value-parser/parse.js
Docs
Diffstat (limited to 'node_modules/tailwindcss/src/value-parser/parse.js')
-rw-r--r--node_modules/tailwindcss/src/value-parser/parse.js303
1 files changed, 303 insertions, 0 deletions
diff --git a/node_modules/tailwindcss/src/value-parser/parse.js b/node_modules/tailwindcss/src/value-parser/parse.js
new file mode 100644
index 0000000..4455996
--- /dev/null
+++ b/node_modules/tailwindcss/src/value-parser/parse.js
@@ -0,0 +1,303 @@
+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)
+var uLower = 'u'.charCodeAt(0)
+var uUpper = 'U'.charCodeAt(0)
+var plus = '+'.charCodeAt(0)
+var isUnicodeRange = /^[a-f0-9?-]+$/i
+
+module.exports = function (input) {
+ var tokens = []
+ var value = input
+
+ var next, quote, prev, token, escape, escapePos, whitespacePos, parenthesesOpenPos
+ 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
+ prev.sourceEndIndex += token.length
+ } else if (
+ code === comma ||
+ code === colon ||
+ (code === slash &&
+ value.charCodeAt(next + 1) !== star &&
+ (!parent || (parent && parent.type === 'function' && false)))
+ ) {
+ before = token
+ } else {
+ tokens.push({
+ type: 'space',
+ sourceIndex: pos,
+ sourceEndIndex: next,
+ 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)
+ token.sourceEndIndex = token.unclosed ? next : next + 1
+ tokens.push(token)
+ pos = next + 1
+ code = value.charCodeAt(pos)
+
+ // Comments
+ } else if (code === slash && value.charCodeAt(pos + 1) === star) {
+ next = value.indexOf('*/', pos)
+
+ token = {
+ type: 'comment',
+ sourceIndex: pos,
+ sourceEndIndex: next + 2,
+ }
+
+ if (next === -1) {
+ token.unclosed = true
+ next = value.length
+ token.sourceEndIndex = next
+ }
+
+ token.value = value.slice(pos + 2, next)
+ tokens.push(token)
+
+ pos = next + 2
+ code = value.charCodeAt(pos)
+
+ // Operation within calc
+ } else if ((code === slash || code === star) && parent && parent.type === 'function' && true) {
+ token = value[pos]
+ tokens.push({
+ type: 'word',
+ sourceIndex: pos - before.length,
+ sourceEndIndex: pos + token.length,
+ value: token,
+ })
+ pos += 1
+ code = value.charCodeAt(pos)
+
+ // Dividers
+ } else if (code === slash || code === comma || code === colon) {
+ token = value[pos]
+
+ tokens.push({
+ type: 'div',
+ sourceIndex: pos - before.length,
+ sourceEndIndex: pos + token.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)
+ parenthesesOpenPos = pos
+ token = {
+ type: 'function',
+ sourceIndex: pos - name.length,
+ value: name,
+ before: value.slice(parenthesesOpenPos + 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 (parenthesesOpenPos < whitespacePos) {
+ if (pos !== whitespacePos + 1) {
+ token.nodes = [
+ {
+ type: 'word',
+ sourceIndex: pos,
+ sourceEndIndex: whitespacePos + 1,
+ 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,
+ sourceEndIndex: next,
+ value: value.slice(whitespacePos + 1, next),
+ })
+ } else {
+ token.after = value.slice(whitespacePos + 1, next)
+ token.sourceEndIndex = next
+ }
+ } else {
+ token.after = ''
+ token.nodes = []
+ }
+ pos = next + 1
+ token.sourceEndIndex = token.unclosed ? next : pos
+ code = value.charCodeAt(pos)
+ tokens.push(token)
+ } else {
+ balanced += 1
+ token.after = ''
+ token.sourceEndIndex = pos + 1
+ 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
+ parent.sourceEndIndex += after.length
+ after = ''
+ balanced -= 1
+ stack[stack.length - 1].sourceEndIndex = pos
+ 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 === star && parent && parent.type === 'function' && true) ||
+ (code === slash && parent.type === 'function' && true) ||
+ (code === closeParentheses && balanced)
+ )
+ )
+ token = value.slice(pos, next)
+
+ if (openParentheses === code) {
+ name = token
+ } else if (
+ (uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) &&
+ plus === token.charCodeAt(1) &&
+ isUnicodeRange.test(token.slice(2))
+ ) {
+ tokens.push({
+ type: 'unicode-range',
+ sourceIndex: pos,
+ sourceEndIndex: next,
+ value: token,
+ })
+ } else {
+ tokens.push({
+ type: 'word',
+ sourceIndex: pos,
+ sourceEndIndex: next,
+ value: token,
+ })
+ }
+
+ pos = next
+ }
+ }
+
+ for (pos = stack.length - 1; pos; pos -= 1) {
+ stack[pos].unclosed = true
+ stack[pos].sourceEndIndex = value.length
+ }
+
+ return stack[0].nodes
+}