+117
-13
lines changedFilter options
+117
-13
lines changed Original file line number Diff line number Diff line change
@@ -6,7 +6,8 @@ declare type CompilerOptions = {
6
6
isUnaryTag?: (tag: string) => ?boolean; // check if a tag is unary for the platform
7
7
canBeLeftOpenTag?: (tag: string) => ?boolean; // check if a tag can be left opened
8
8
isReservedTag?: (tag: string) => ?boolean; // check if a tag is a native for the platform
9
-
preserveWhitespace?: boolean; // preserve whitespace between elements?
9
+
preserveWhitespace?: boolean; // preserve whitespace between elements? (Deprecated)
10
+
whitespace?: 'preserve' | 'condense'; // whitespace handling strategy
10
11
optimize?: boolean; // optimize static content?
11
12
12
13
// web specific
Original file line number Diff line number Diff line change
@@ -33,12 +33,48 @@ Note the returned function code uses `with` and thus cannot be used in strict mo
33
33
34
34
#### Options
35
35
36
-
It's possible to hook into the compilation process to support custom template features. **However, beware that by injecting custom compile-time modules, your templates will not work with other build tools built on standard built-in modules, e.g `vue-loader` and `vueify`.**
36
+
- `whitespace`
37
+
- Type: `string`
38
+
- Valid values: `'preserve' | 'condense'`
39
+
- Default: `'preserve'`
37
40
38
-
The optional `options` object can contain the following:
41
+
The default value `'preserve'` handles whitespaces as follows:
42
+
43
+
- A whitespace-only text node between element tags is condensed into a single space.
44
+
- All other whitespaces are preserved as-is.
45
+
46
+
If set to `'condense'`:
47
+
48
+
- A whitespace-only text node between element tags is removed if it contains new lines. Otherwise, it is condensed into a single space.
49
+
- Consecutive whitespaces inside a non-whitespace-only text node is condensed into a single space.
50
+
51
+
Using condense mode will result in smaller compiled code size and slightly improved performance. However, it will produce minor visual layout differences compared to plain HTML in certain cases.
52
+
53
+
**This option does not affect the `<pre>` tag.**
54
+
55
+
Example:
56
+
57
+
``` html
58
+
<!-- source -->
59
+
<div>
60
+
<span>
61
+
foo
62
+
</span> <span>bar</span>
63
+
</div>
64
+
65
+
<!-- whitespace: 'preserve' -->
66
+
<div> <span>
67
+
foo
68
+
</span> <span>bar</span> </div>
69
+
70
+
<!-- whitespace: 'condense' -->
71
+
<div><span> foo </span> <span>bar</span></div>
72
+
```
39
73
40
74
- `modules`
41
75
76
+
It's possible to hook into the compilation process to support custom template features. **However, beware that by injecting custom compile-time modules, your templates will not work with other build tools built on standard built-in modules, e.g `vue-loader` and `vueify`.**
77
+
42
78
An array of compiler modules. For details on compiler modules, refer to the `ModuleOptions` type in [flow declarations](https://github.com/vuejs/vue/blob/dev/flow/compiler.js#L38-L45) and the [built-in modules](https://github.com/vuejs/vue/tree/dev/src/platforms/web/compiler/modules).
43
79
44
80
- `directives`
@@ -59,9 +95,11 @@ The optional `options` object can contain the following:
59
95
60
96
Refer to the implementation of some [built-in compile-time directives](https://github.com/vuejs/vue/tree/dev/src/platforms/web/compiler/directives).
61
97
62
-
- `preserveWhitespace`
98
+
- `preserveWhitespace` **Deprecated since 2.6**
99
+
- Type: `boolean`
100
+
- Default: `true`
63
101
64
-
Defaults to `true`. This means the compiled render function preserves all whitespace characters between HTML tags. If set to `false`, whitespace between tags will be ignored. This can result in slightly better performance but may affect layout for inline elements.
102
+
By default, the compiled render function preserves all whitespace characters between HTML tags. If set to `false`, whitespace between tags will be ignored. This can result in slightly better performance but may affect layout for inline elements.
65
103
66
104
---
67
105
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ interface CompilerOptions {
7
7
modules?: ModuleOptions[];
8
8
directives?: Record<string, DirectiveFunction>;
9
9
preserveWhitespace?: boolean;
10
+
whitespace?: 'preserve' | 'condense';
10
11
}
11
12
12
13
interface CompiledResult {
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import {
10
10
// check compile options
11
11
const compiled = compile("<div>hi</div>", {
12
12
preserveWhitespace: false,
13
+
whitespace: 'condense',
13
14
modules: [
14
15
{
15
16
preTransformNode: el => el,
Original file line number Diff line number Diff line change
@@ -30,6 +30,9 @@ const argRE = /:(.*)$/
30
30
export const bindRE = /^:|^v-bind:/
31
31
const modifierRE = /\.[^.]+/g
32
32
33
+
const lineBreakRE = /[\r\n]/
34
+
const whitespaceRE = /\s+/g
35
+
33
36
const decodeHTMLCached = cached(he.decode)
34
37
35
38
// configurable state
@@ -79,6 +82,7 @@ export function parse (
79
82
80
83
const stack = []
81
84
const preserveWhitespace = options.preserveWhitespace !== false
85
+
const whitespaceOption = options.whitespace
82
86
let root
83
87
let currentParent
84
88
let inVPre = false
@@ -235,11 +239,13 @@ export function parse (
235
239
},
236
240
237
241
end (tag, start, end) {
238
-
// remove trailing whitespace
239
242
const element = stack[stack.length - 1]
240
-
const lastNode = element.children[element.children.length - 1]
241
-
if (lastNode && lastNode.type === 3 && lastNode.text === ' ' && !inPre) {
242
-
element.children.pop()
243
+
if (!inPre) {
244
+
// remove trailing whitespace node
245
+
const lastNode = element.children[element.children.length - 1]
246
+
if (lastNode && lastNode.type === 3 && lastNode.text === ' ') {
247
+
element.children.pop()
248
+
}
243
249
}
244
250
// pop stack
245
251
stack.length -= 1
@@ -276,11 +282,27 @@ export function parse (
276
282
return
277
283
}
278
284
const children = currentParent.children
279
-
text = inPre || text.trim()
280
-
? isTextTag(currentParent) ? text : decodeHTMLCached(text)
281
-
// only preserve whitespace if its not right after a starting tag
282
-
: preserveWhitespace && children.length ? ' ' : ''
285
+
if (inPre || text.trim()) {
286
+
text = isTextTag(currentParent) ? text : decodeHTMLCached(text)
287
+
} else if (!children.length) {
288
+
// remove the whitespace-only node right after an opening tag
289
+
text = ''
290
+
} else if (whitespaceOption) {
291
+
if (whitespaceOption === 'condense') {
292
+
// in condense mode, remove the whitespace node if it contains
293
+
// line break, otherwise condense to a single space
294
+
text = lineBreakRE.test(text) ? '' : ' '
295
+
} else {
296
+
text = ' '
297
+
}
298
+
} else {
299
+
text = preserveWhitespace ? ' ' : ''
300
+
}
283
301
if (text) {
302
+
if (whitespaceOption === 'condense') {
303
+
// condense consecutive whitespaces into single space
304
+
text = text.replace(whitespaceRE, ' ')
305
+
}
284
306
let res
285
307
let child: ?ASTNode
286
308
if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
Original file line number Diff line number Diff line change
@@ -757,4 +757,45 @@ describe('parser', () => {
757
757
const ast = parse(`<p>{{\r\nmsg\r\n}}</p>`, baseOptions)
758
758
expect(ast.children[0].expression).toBe('_s(msg)')
759
759
})
760
+
761
+
it('preserveWhitespace: false', () => {
762
+
const options = extend({
763
+
preserveWhitespace: false
764
+
}, baseOptions)
765
+
766
+
const ast = parse('<p>\n Welcome to <b>Vue.js</b> <i>world</i> \n <span>.\n Have fun!\n</span></p>', options)
767
+
expect(ast.tag).toBe('p')
768
+
expect(ast.children.length).toBe(4)
769
+
expect(ast.children[0].type).toBe(3)
770
+
expect(ast.children[0].text).toBe('\n Welcome to ')
771
+
expect(ast.children[1].tag).toBe('b')
772
+
expect(ast.children[1].children[0].text).toBe('Vue.js')
773
+
expect(ast.children[2].tag).toBe('i')
774
+
expect(ast.children[2].children[0].text).toBe('world')
775
+
expect(ast.children[3].tag).toBe('span')
776
+
expect(ast.children[3].children[0].text).toBe('.\n Have fun!\n')
777
+
})
778
+
779
+
it(`whitespace: 'condense'`, () => {
780
+
const options = extend({
781
+
whitespace: 'condense',
782
+
// should be ignored when whitespace is specified
783
+
preserveWhitespace: false
784
+
}, baseOptions)
785
+
const ast = parse('<p>\n Welcome to <b>Vue.js</b> <i>world</i> \n <span>.\n Have fun!\n</span></p>', options)
786
+
expect(ast.tag).toBe('p')
787
+
expect(ast.children.length).toBe(5)
788
+
expect(ast.children[0].type).toBe(3)
789
+
expect(ast.children[0].text).toBe(' Welcome to ')
790
+
expect(ast.children[1].tag).toBe('b')
791
+
expect(ast.children[1].children[0].text).toBe('Vue.js')
792
+
expect(ast.children[2].type).toBe(3)
793
+
// should condense inline whitespace into single space
794
+
expect(ast.children[2].text).toBe(' ')
795
+
expect(ast.children[3].tag).toBe('i')
796
+
expect(ast.children[3].children[0].text).toBe('world')
797
+
// should have removed the whitespace node between tags that contains newlines
798
+
expect(ast.children[4].tag).toBe('span')
799
+
expect(ast.children[4].children[0].text).toBe('. Have fun! ')
800
+
})
760
801
})
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4