Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81159 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*/
9
/*global exports:true*/
10
"use strict";
11
var Syntax = require('jstransform').Syntax;
12
var utils = require('jstransform/src/utils');
13
14
var knownTags = {
15
a: true,
16
abbr: true,
17
address: true,
18
applet: true,
19
area: true,
20
article: true,
21
aside: true,
22
audio: true,
23
b: true,
24
base: true,
25
bdi: true,
26
bdo: true,
27
big: true,
28
blockquote: true,
29
body: true,
30
br: true,
31
button: true,
32
canvas: true,
33
caption: true,
34
circle: true,
35
cite: true,
36
code: true,
37
col: true,
38
colgroup: true,
39
command: true,
40
data: true,
41
datalist: true,
42
dd: true,
43
defs: true,
44
del: true,
45
details: true,
46
dfn: true,
47
dialog: true,
48
div: true,
49
dl: true,
50
dt: true,
51
ellipse: true,
52
em: true,
53
embed: true,
54
fieldset: true,
55
figcaption: true,
56
figure: true,
57
footer: true,
58
form: true,
59
g: true,
60
h1: true,
61
h2: true,
62
h3: true,
63
h4: true,
64
h5: true,
65
h6: true,
66
head: true,
67
header: true,
68
hgroup: true,
69
hr: true,
70
html: true,
71
i: true,
72
iframe: true,
73
img: true,
74
input: true,
75
ins: true,
76
kbd: true,
77
keygen: true,
78
label: true,
79
legend: true,
80
li: true,
81
line: true,
82
linearGradient: true,
83
link: true,
84
main: true,
85
map: true,
86
mark: true,
87
marquee: true,
88
mask: false,
89
menu: true,
90
menuitem: true,
91
meta: true,
92
meter: true,
93
nav: true,
94
noscript: true,
95
object: true,
96
ol: true,
97
optgroup: true,
98
option: true,
99
output: true,
100
p: true,
101
param: true,
102
path: true,
103
pattern: false,
104
picture: true,
105
polygon: true,
106
polyline: true,
107
pre: true,
108
progress: true,
109
q: true,
110
radialGradient: true,
111
rect: true,
112
rp: true,
113
rt: true,
114
ruby: true,
115
s: true,
116
samp: true,
117
script: true,
118
section: true,
119
select: true,
120
small: true,
121
source: true,
122
span: true,
123
stop: true,
124
strong: true,
125
style: true,
126
sub: true,
127
summary: true,
128
sup: true,
129
svg: true,
130
table: true,
131
tbody: true,
132
td: true,
133
text: true,
134
textarea: true,
135
tfoot: true,
136
th: true,
137
thead: true,
138
time: true,
139
title: true,
140
tr: true,
141
track: true,
142
tspan: true,
143
u: true,
144
ul: true,
145
'var': true,
146
video: true,
147
wbr: true
148
};
149
150
function renderXJSLiteral(object, isLast, state, start, end) {
151
var lines = object.value.split(/\r\n|\n|\r/);
152
153
if (start) {
154
utils.append(start, state);
155
}
156
157
var lastNonEmptyLine = 0;
158
159
lines.forEach(function (line, index) {
160
if (line.match(/[^ \t]/)) {
161
lastNonEmptyLine = index;
162
}
163
});
164
165
lines.forEach(function (line, index) {
166
var isFirstLine = index === 0;
167
var isLastLine = index === lines.length - 1;
168
var isLastNonEmptyLine = index === lastNonEmptyLine;
169
170
// replace rendered whitespace tabs with spaces
171
var trimmedLine = line.replace(/\t/g, ' ');
172
173
// trim whitespace touching a newline
174
if (!isFirstLine) {
175
trimmedLine = trimmedLine.replace(/^[ ]+/, '');
176
}
177
if (!isLastLine) {
178
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
179
}
180
181
if (!isFirstLine) {
182
utils.append(line.match(/^[ \t]*/)[0], state);
183
}
184
185
if (trimmedLine || isLastNonEmptyLine) {
186
utils.append(
187
JSON.stringify(trimmedLine) +
188
(!isLastNonEmptyLine ? " + ' ' +" : ''),
189
state);
190
191
if (isLastNonEmptyLine) {
192
if (end) {
193
utils.append(end, state);
194
}
195
if (!isLast) {
196
utils.append(', ', state);
197
}
198
}
199
200
// only restore tail whitespace if line had literals
201
if (trimmedLine && !isLastLine) {
202
utils.append(line.match(/[ \t]*$/)[0], state);
203
}
204
}
205
206
if (!isLastLine) {
207
utils.append('\n', state);
208
}
209
});
210
211
utils.move(object.range[1], state);
212
}
213
214
function renderXJSExpressionContainer(traverse, object, isLast, path, state) {
215
// Plus 1 to skip `{`.
216
utils.move(object.range[0] + 1, state);
217
traverse(object.expression, path, state);
218
219
if (!isLast && object.expression.type !== Syntax.XJSEmptyExpression) {
220
// If we need to append a comma, make sure to do so after the expression.
221
utils.catchup(object.expression.range[1], state, trimLeft);
222
utils.append(', ', state);
223
}
224
225
// Minus 1 to skip `}`.
226
utils.catchup(object.range[1] - 1, state, trimLeft);
227
utils.move(object.range[1], state);
228
return false;
229
}
230
231
function quoteAttrName(attr) {
232
// Quote invalid JS identifiers.
233
if (!/^[a-z_$][a-z\d_$]*$/i.test(attr)) {
234
return '"' + attr + '"';
235
}
236
return attr;
237
}
238
239
function trimLeft(value) {
240
return value.replace(/^[ ]+/, '');
241
}
242
243
exports.knownTags = knownTags;
244
exports.renderXJSExpressionContainer = renderXJSExpressionContainer;
245
exports.renderXJSLiteral = renderXJSLiteral;
246
exports.quoteAttrName = quoteAttrName;
247
exports.trimLeft = trimLeft;
248
249