diff --git a/src/html/util/unicode.ts b/src/html/util/unicode.ts
index 3087de54..c69142b9 100644
--- a/src/html/util/unicode.ts
+++ b/src/html/util/unicode.ts
@@ -45,6 +45,7 @@ export const LATIN_SMALL_Z = 0x7A
export const LEFT_CURLY_BRACKET = 0x7B // {
export const RIGHT_CURLY_BRACKET = 0x7D // }
export const NULL_REPLACEMENT = 0xFFFD
+export const COMMA = 0x2C
/**
* Check whether the code point is a whitespace.
diff --git a/src/style/index.ts b/src/style/index.ts
index da81c040..140bc998 100644
--- a/src/style/index.ts
+++ b/src/style/index.ts
@@ -121,6 +121,7 @@ function parseStyle(
quote,
openingParenOffset,
comments,
+ defaultValue,
} of iterateVBind(code, cssOptions)) {
insertComments(
document,
@@ -201,6 +202,32 @@ function parseStyle(
),
)
}
+ if (defaultValue.length) {
+ afterTokens.unshift(
+ createSimpleToken(
+ "Punctuator",
+ locationCalculator.getOffsetWithGap(
+ defaultValue[0].range[0],
+ ),
+ locationCalculator.getOffsetWithGap(
+ defaultValue[0].range[1],
+ ),
+ ",",
+ locationCalculator,
+ ),
+ createSimpleToken(
+ "HTMLRawText",
+ locationCalculator.getOffsetWithGap(
+ defaultValue[1].range[0],
+ ),
+ locationCalculator.getOffsetWithGap(
+ defaultValue[1].range[1],
+ ),
+ defaultValue[1].value,
+ locationCalculator,
+ ),
+ )
+ }
const beforeLast = beforeTokens[beforeTokens.length - 1]
replaceAndSplitTokens(
document,
@@ -287,6 +314,7 @@ type VBindLocations = {
quote: '"' | "'" | null
openingParenOffset: number
comments: CSSCommentToken[]
+ defaultValue: CSSToken[]
}
/**
@@ -317,6 +345,7 @@ function* iterateVBind(
quote: arg.quote,
openingParenOffset: openingParen.openingParen.range[0],
comments: [...openingParen.comments, ...arg.comments],
+ defaultValue: arg.defaultValue,
}
}
}
@@ -350,6 +379,7 @@ function parseVBindArg(tokenizer: CSSTokenScanner): {
quote: '"' | "'" | null
closingParen: CSSPunctuatorToken
comments: CSSCommentToken[]
+ defaultValue: CSSToken[]
} | null {
const tokensBuffer: CSSToken[] = []
const comments: CSSCommentToken[] = []
@@ -370,14 +400,25 @@ function parseVBindArg(tokenizer: CSSTokenScanner): {
quote: quotedToken.quote,
closingParen: token,
comments,
+ defaultValue: [],
}
}
const startToken = tokensBuffer[0] || token
+ const commaToken = tokens.find(
+ (tk) =>
+ tk.type === CSSTokenType.Punctuator && tk.value === ",",
+ )
return {
- exprRange: [startToken.range[0], token.range[0]],
+ exprRange: [
+ startToken.range[0],
+ (commaToken || token).range[0],
+ ],
quote: null,
closingParen: token,
comments: [],
+ defaultValue: commaToken
+ ? tokens.slice(tokens.indexOf(commaToken))
+ : [],
}
}
diff --git a/src/style/tokenizer.ts b/src/style/tokenizer.ts
index b01e9a38..dfe455c5 100644
--- a/src/style/tokenizer.ts
+++ b/src/style/tokenizer.ts
@@ -19,6 +19,7 @@ import {
SEMICOLON,
LEFT_SQUARE_BRACKET,
RIGHT_SQUARE_BRACKET,
+ COMMA,
} from "../html/util/unicode"
export const enum CSSTokenType {
@@ -315,6 +316,7 @@ export class CSSTokenizer {
function isPunctuator(cp: number): boolean {
return (
+ cp === COMMA ||
cp === COLON ||
cp === SEMICOLON ||
// Brackets
diff --git a/test/fixtures/document-fragment/style-variables-with-default-value/document-fragment.json b/test/fixtures/document-fragment/style-variables-with-default-value/document-fragment.json
new file mode 100644
index 00000000..6adfa645
--- /dev/null
+++ b/test/fixtures/document-fragment/style-variables-with-default-value/document-fragment.json
@@ -0,0 +1,561 @@
+{
+ "type": "VDocumentFragment",
+ "range": [
+ 0,
+ 62
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 6,
+ "column": 0
+ }
+ },
+ "children": [
+ {
+ "type": "VElement",
+ "range": [
+ 0,
+ 61
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 5,
+ "column": 8
+ }
+ },
+ "name": "style",
+ "rawName": "style",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 0,
+ 7
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 1,
+ "column": 7
+ }
+ },
+ "selfClosing": false,
+ "attributes": []
+ },
+ "children": [
+ {
+ "type": "VText",
+ "range": [
+ 7,
+ 28
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 7
+ },
+ "end": {
+ "line": 3,
+ "column": 11
+ }
+ },
+ "value": "\n .text{\n color: "
+ },
+ {
+ "type": "VExpressionContainer",
+ "range": [
+ 28,
+ 47
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 11
+ },
+ "end": {
+ "line": 3,
+ "column": 30
+ }
+ },
+ "expression": {
+ "type": "Identifier",
+ "start": 35,
+ "end": 40,
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 18
+ },
+ "end": {
+ "line": 3,
+ "column": 23
+ }
+ },
+ "range": [
+ 35,
+ 40
+ ],
+ "name": "color"
+ },
+ "references": [
+ {
+ "id": {
+ "type": "Identifier",
+ "start": 35,
+ "end": 40,
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 18
+ },
+ "end": {
+ "line": 3,
+ "column": 23
+ }
+ },
+ "range": [
+ 35,
+ 40
+ ],
+ "name": "color"
+ },
+ "mode": "r"
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "range": [
+ 47,
+ 53
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 30
+ },
+ "end": {
+ "line": 5,
+ "column": 0
+ }
+ },
+ "value": ";\n }\n"
+ }
+ ],
+ "endTag": {
+ "type": "VEndTag",
+ "range": [
+ 53,
+ 61
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 0
+ },
+ "end": {
+ "line": 5,
+ "column": 8
+ }
+ }
+ },
+ "variables": [],
+ "style": true
+ },
+ {
+ "type": "VText",
+ "range": [
+ 61,
+ 62
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 8
+ },
+ "end": {
+ "line": 6,
+ "column": 0
+ }
+ },
+ "value": "\n"
+ }
+ ],
+ "tokens": [
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 0,
+ 6
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 1,
+ "column": 6
+ }
+ },
+ "value": "style"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 6,
+ 7
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 6
+ },
+ "end": {
+ "line": 1,
+ "column": 7
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 7,
+ 10
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 7
+ },
+ "end": {
+ "line": 2,
+ "column": 2
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 10,
+ 16
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 2
+ },
+ "end": {
+ "line": 2,
+ "column": 8
+ }
+ },
+ "value": ".text{"
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 16,
+ 21
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 8
+ },
+ "end": {
+ "line": 3,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 21,
+ 27
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 4
+ },
+ "end": {
+ "line": 3,
+ "column": 10
+ }
+ },
+ "value": "color:"
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 27,
+ 28
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 10
+ },
+ "end": {
+ "line": 3,
+ "column": 11
+ }
+ },
+ "value": " "
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 28,
+ 34
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 11
+ },
+ "end": {
+ "line": 3,
+ "column": 17
+ }
+ },
+ "value": "v-bind"
+ },
+ {
+ "type": "Punctuator",
+ "range": [
+ 34,
+ 35
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 17
+ },
+ "end": {
+ "line": 3,
+ "column": 18
+ }
+ },
+ "value": "("
+ },
+ {
+ "type": "Identifier",
+ "value": "color",
+ "start": 35,
+ "end": 40,
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 18
+ },
+ "end": {
+ "line": 3,
+ "column": 23
+ }
+ },
+ "range": [
+ 35,
+ 40
+ ]
+ },
+ {
+ "type": "Punctuator",
+ "range": [
+ 40,
+ 41
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 23
+ },
+ "end": {
+ "line": 3,
+ "column": 24
+ }
+ },
+ "value": ","
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 42,
+ 46
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 25
+ },
+ "end": {
+ "line": 3,
+ "column": 29
+ }
+ },
+ "value": "blue"
+ },
+ {
+ "type": "Punctuator",
+ "range": [
+ 46,
+ 47
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 29
+ },
+ "end": {
+ "line": 3,
+ "column": 30
+ }
+ },
+ "value": ")"
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 47,
+ 48
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 30
+ },
+ "end": {
+ "line": 3,
+ "column": 31
+ }
+ },
+ "value": ";"
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 48,
+ 51
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 31
+ },
+ "end": {
+ "line": 4,
+ "column": 2
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLRawText",
+ "range": [
+ 51,
+ 52
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 2
+ },
+ "end": {
+ "line": 4,
+ "column": 3
+ }
+ },
+ "value": "}"
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 52,
+ 53
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 3
+ },
+ "end": {
+ "line": 5,
+ "column": 0
+ }
+ },
+ "value": "\n"
+ },
+ {
+ "type": "HTMLEndTagOpen",
+ "range": [
+ 53,
+ 60
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 0
+ },
+ "end": {
+ "line": 5,
+ "column": 7
+ }
+ },
+ "value": "style"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 60,
+ 61
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 7
+ },
+ "end": {
+ "line": 5,
+ "column": 8
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 61,
+ 62
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 8
+ },
+ "end": {
+ "line": 6,
+ "column": 0
+ }
+ },
+ "value": "\n"
+ }
+ ],
+ "comments": [],
+ "errors": []
+}
\ No newline at end of file
diff --git a/test/fixtures/document-fragment/style-variables-with-default-value/source.vue b/test/fixtures/document-fragment/style-variables-with-default-value/source.vue
new file mode 100644
index 00000000..8daa0a3e
--- /dev/null
+++ b/test/fixtures/document-fragment/style-variables-with-default-value/source.vue
@@ -0,0 +1,5 @@
+
diff --git a/test/fixtures/document-fragment/style-variables-with-default-value/token-ranges.json b/test/fixtures/document-fragment/style-variables-with-default-value/token-ranges.json
new file mode 100644
index 00000000..4efd3679
--- /dev/null
+++ b/test/fixtures/document-fragment/style-variables-with-default-value/token-ranges.json
@@ -0,0 +1,22 @@
+[
+ "",
+ "\n"
+]
\ No newline at end of file
diff --git a/test/fixtures/document-fragment/style-variables-with-default-value/tree.json b/test/fixtures/document-fragment/style-variables-with-default-value/tree.json
new file mode 100644
index 00000000..3cce7e83
--- /dev/null
+++ b/test/fixtures/document-fragment/style-variables-with-default-value/tree.json
@@ -0,0 +1,50 @@
+[
+ {
+ "type": "VDocumentFragment",
+ "text": "\n",
+ "children": [
+ {
+ "type": "VElement",
+ "text": "",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": []
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n",
+ "children": []
+ }
+ ]
+ }
+]
\ No newline at end of file