Skip to content

Commit 1a26c9f

Browse files
committed
Add support for passing data through
1 parent 7178e86 commit 1a26c9f

File tree

2 files changed

+167
-94
lines changed

2 files changed

+167
-94
lines changed

index.js

Lines changed: 134 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var style = require('style-to-object')
1414
var position = require('unist-util-position')
1515
var zwitch = require('zwitch')
1616

17+
var own = {}.hasOwnProperty
1718
var push = [].push
1819

1920
var handlers = {
@@ -45,7 +46,16 @@ function toEstree(tree, options) {
4546

4647
if (result) {
4748
if (result.type !== 'JSXFragment' && result.type !== 'JSXElement') {
48-
result = createJsxFragment(tree, [result])
49+
result = create(tree, {
50+
type: 'JSXFragment',
51+
openingFragment: {
52+
type: 'JSXOpeningFragment',
53+
attributes: [],
54+
selfClosing: false
55+
},
56+
closingFragment: {type: 'JSXClosingFragment'},
57+
children: [result]
58+
})
4959
}
5060

5161
body.push(create(tree, {type: 'ExpressionStatement', expression: result}))
@@ -70,7 +80,7 @@ function unknown(node) {
7080
function ignore() {}
7181

7282
function comment(node, context) {
73-
var esnode = create(node, {type: 'Block', value: node.value})
83+
var esnode = inherit(node, {type: 'Block', value: node.value})
7484

7585
context.comments.push(esnode)
7686

@@ -138,51 +148,56 @@ function element(node, context) {
138148
cssProperties = []
139149

140150
for (cssProp in value) {
141-
cssProperties.push(
142-
create(null, {
143-
type: 'Property',
144-
method: false,
145-
shorthand: false,
146-
computed: false,
147-
key: create(null, {type: 'Identifier', name: cssProp}),
148-
value: create(null, {
149-
type: 'Literal',
150-
value: String(value[cssProp]),
151-
raw: JSON.stringify(String(value[cssProp]))
152-
}),
153-
kind: 'init'
154-
})
155-
)
151+
cssProperties.push({
152+
type: 'Property',
153+
method: false,
154+
shorthand: false,
155+
computed: false,
156+
key: {type: 'Identifier', name: cssProp},
157+
value: {
158+
type: 'Literal',
159+
value: String(value[cssProp]),
160+
raw: JSON.stringify(String(value[cssProp]))
161+
},
162+
kind: 'init'
163+
})
156164
}
157165

158-
value = create(null, {
166+
value = {
159167
type: 'JSXExpressionContainer',
160-
expression: create(null, {
161-
type: 'ObjectExpression',
162-
properties: cssProperties
163-
})
164-
})
168+
expression: {type: 'ObjectExpression', properties: cssProperties}
169+
}
165170
} else {
166-
value = create(null, {
171+
value = {
167172
type: 'Literal',
168173
value: String(value),
169174
raw: JSON.stringify(String(value))
170-
})
175+
}
171176
}
172177

173-
attributes.push(
174-
create(null, {
175-
type: 'JSXAttribute',
176-
name: create(null, {type: 'JSXIdentifier', name: prop}),
177-
value: value
178-
})
179-
)
178+
attributes.push({
179+
type: 'JSXAttribute',
180+
name: {type: 'JSXIdentifier', name: prop},
181+
value: value
182+
})
180183
}
181184

182185
// Restore parent schema.
183186
context.schema = parentSchema
184187

185-
return createJsxElement(node, node.tagName, attributes, children)
188+
return inherit(node, {
189+
type: 'JSXElement',
190+
openingElement: {
191+
type: 'JSXOpeningElement',
192+
attributes: attributes,
193+
name: createJsxName(node.tagName),
194+
selfClosing: !children.length
195+
},
196+
closingElement: children.length
197+
? {type: 'JSXClosingElement', name: createJsxName(node.tagName)}
198+
: null,
199+
children: children
200+
})
186201
}
187202

188203
function mdxjsEsm(node, context) {
@@ -205,7 +220,7 @@ function mdxExpression(node, context) {
205220
expression = estree.body[0] && estree.body[0].expression
206221
}
207222

208-
return create(node, {
223+
return inherit(node, {
209224
type: 'JSXExpressionContainer',
210225
expression: expression || create(node, {type: 'JSXEmptyExpression'})
211226
})
@@ -221,6 +236,7 @@ function mdxJsxElement(node, context) {
221236
var children
222237
var attr
223238
var value
239+
var expression
224240
var estree
225241

226242
if (
@@ -242,35 +258,33 @@ function mdxJsxElement(node, context) {
242258
if (value == null) {
243259
// Empty.
244260
}
245-
// MDXJsxAttributeValueExpression.
261+
// `MDXJsxAttributeValueExpression`.
246262
else if (typeof value === 'object') {
247263
estree = value.data && value.data.estree
248-
value = null
264+
expression = null
249265

250266
if (estree) {
251267
push.apply(context.comments, estree.comments)
252268
attachComments(estree, estree.comments)
253-
value = estree.body[0] && estree.body[0].expression
269+
expression = estree.body[0] && estree.body[0].expression
254270
}
255271

256-
// To do: `node` is wrong.
257-
value = create(node, {
272+
value = inherit(value, {
258273
type: 'JSXExpressionContainer',
259-
expression: value || create(null, {type: 'JSXEmptyExpression'})
274+
expression: expression || {type: 'JSXEmptyExpression'}
260275
})
261276
}
262277
// Anything else.
263278
else {
264-
// To do: use `value`?
265-
value = create(null, {
279+
value = {
266280
type: 'Literal',
267281
value: String(value),
268282
raw: JSON.stringify(String(value))
269-
})
283+
}
270284
}
271285

272286
attributes.push(
273-
create(null, {
287+
inherit(attr, {
274288
type: 'JSXAttribute',
275289
name: createJsxName(attr.name),
276290
value: value
@@ -294,10 +308,9 @@ function mdxJsxElement(node, context) {
294308
}
295309

296310
attributes.push(
297-
create(null, {
311+
inherit(attr, {
298312
type: 'JSXSpreadAttribute',
299-
argument:
300-
value || create(null, {type: 'ObjectExpression', properties: {}})
313+
argument: value || {type: 'ObjectExpression', properties: {}}
301314
})
302315
)
303316
}
@@ -306,9 +319,33 @@ function mdxJsxElement(node, context) {
306319
// Restore parent schema.
307320
context.schema = parentSchema
308321

309-
return node.name
310-
? createJsxElement(node, node.name, attributes, children)
311-
: createJsxFragment(node, children)
322+
return inherit(
323+
node,
324+
node.name
325+
? {
326+
type: 'JSXElement',
327+
openingElement: {
328+
type: 'JSXOpeningElement',
329+
attributes: attributes,
330+
name: createJsxName(node.name),
331+
selfClosing: !children.length
332+
},
333+
closingElement: children.length
334+
? {type: 'JSXClosingElement', name: createJsxName(node.name)}
335+
: null,
336+
children: children
337+
}
338+
: {
339+
type: 'JSXFragment',
340+
openingFragment: {
341+
type: 'JSXOpeningFragment',
342+
attributes: [],
343+
selfClosing: false
344+
},
345+
closingFragment: {type: 'JSXClosingFragment'},
346+
children: children
347+
}
348+
)
312349
}
313350

314351
function root(node, context) {
@@ -334,7 +371,16 @@ function root(node, context) {
334371
}
335372
}
336373

337-
return createJsxFragment(node, cleanChildren)
374+
return inherit(node, {
375+
type: 'JSXFragment',
376+
openingFragment: {
377+
type: 'JSXOpeningFragment',
378+
attributes: [],
379+
selfClosing: false
380+
},
381+
closingFragment: {type: 'JSXClosingFragment'},
382+
children: cleanChildren
383+
})
338384
}
339385

340386
function text(node) {
@@ -344,71 +390,42 @@ function text(node) {
344390

345391
return create(node, {
346392
type: 'JSXExpressionContainer',
347-
expression: create(node, {
393+
expression: inherit(node, {
348394
type: 'Literal',
349395
value: value,
350396
raw: JSON.stringify(value)
351397
})
352398
})
353399
}
354400

355-
function createJsxElement(node, name, attributes, children) {
356-
return create(node, {
357-
type: 'JSXElement',
358-
openingElement: create(null, {
359-
type: 'JSXOpeningElement',
360-
attributes: attributes,
361-
name: createJsxName(name),
362-
selfClosing: !children.length
363-
}),
364-
closingElement: children.length
365-
? create(null, {type: 'JSXClosingElement', name: createJsxName(name)})
366-
: null,
367-
children: children
368-
})
369-
}
370-
371401
function createJsxName(name) {
372402
var parts
373403
var node
374404

375405
if (name.indexOf('.') > -1) {
376406
parts = name.split('.')
377-
node = create(null, {type: 'JSXIdentifier', name: parts.shift()})
407+
node = {type: 'JSXIdentifier', name: parts.shift()}
378408
while (parts.length) {
379409
node = {
380410
type: 'JSXMemberExpression',
381411
object: node,
382-
property: create(null, {type: 'JSXIdentifier', name: parts.shift()})
412+
property: {type: 'JSXIdentifier', name: parts.shift()}
383413
}
384414
}
385415
} else if (name.indexOf(':') > -1) {
386416
parts = name.split(':')
387417
node = {
388418
type: 'JSXNamespacedName',
389-
namespace: create(null, {type: 'JSXIdentifier', name: parts[0]}),
390-
name: create(null, {type: 'JSXIdentifier', name: parts[1]})
419+
namespace: {type: 'JSXIdentifier', name: parts[0]},
420+
name: {type: 'JSXIdentifier', name: parts[1]}
391421
}
392422
} else {
393-
node = create(null, {type: 'JSXIdentifier', name: name})
423+
node = {type: 'JSXIdentifier', name: name}
394424
}
395425

396426
return node
397427
}
398428

399-
function createJsxFragment(node, children) {
400-
return create(node, {
401-
type: 'JSXFragment',
402-
openingFragment: create(null, {
403-
type: 'JSXOpeningFragment',
404-
attributes: [],
405-
selfClosing: false
406-
}),
407-
closingFragment: create(null, {type: 'JSXClosingFragment'}),
408-
children: children
409-
})
410-
}
411-
412429
function all(parent, context) {
413430
var children = parent.children || []
414431
var results = []
@@ -425,19 +442,42 @@ function all(parent, context) {
425442
return results
426443
}
427444

428-
function create(hast, esnode, fromStart, fromEnd) {
445+
// Take positional info and data from `hast`.
446+
function inherit(hast, esnode) {
447+
var left = hast.data
448+
var right
449+
var key
450+
451+
create(hast, esnode)
452+
453+
if (left) {
454+
for (key in left) {
455+
if (own.call(left, key) && key !== 'estree') {
456+
if (!right) right = {}
457+
right[key] = left[key]
458+
}
459+
}
460+
461+
if (right) {
462+
esnode.data = right
463+
}
464+
}
465+
466+
return esnode
467+
}
468+
469+
// Take just positional info.
470+
function create(hast, esnode) {
429471
var p = position(hast)
430-
var left = fromStart || 0
431-
var right = fromEnd || 0
432472

433473
if (p.start.line) {
434-
esnode.start = p.start.offset + left
435-
esnode.end = p.end.offset - right
474+
esnode.start = p.start.offset
475+
esnode.end = p.end.offset
436476
esnode.loc = {
437-
start: {line: p.start.line, column: p.start.column - 1 + left},
438-
end: {line: p.end.line, column: p.end.column - 1 - right}
477+
start: {line: p.start.line, column: p.start.column - 1},
478+
end: {line: p.end.line, column: p.end.column - 1}
439479
}
440-
esnode.range = [p.start.offset + left, p.end.offset - right]
480+
esnode.range = [p.start.offset, p.end.offset]
441481
}
442482

443483
return esnode

0 commit comments

Comments
 (0)