11import { SourceMapGenerator } from 'source-map'
2- import esprima from 'esprima'
2+ import { parse as parseTemplate } from './parsers/template'
3+ import { parse as parseJs } from './parsers/js'
4+ import { parse as parseCss } from './parsers/css'
5+ import { offset } from './util'
36
4- // Riot tags fragments
7+ // Riot tags fragments regex
58const SCRIPT = / < s c r i p t ( \s + [ ^ > ] * ) ? > \n ? ( [ \S \s ] * ?) < \/ s c r i p t \s * > / gi
69const TEMPLATE = / < t e m p l a t e ( \s + [ ^ > ] * ) ? > \n ? ( [ \S \s ] * ?) < \/ t e m p l a t e \s * > / gi
710const STYLE = / < s t y l e ( \s + [ ^ > ] * ) ? > \n ? ( [ \S \s ] * ?) < \/ s t y l e \s * > / gi
@@ -21,8 +24,8 @@ function sourcemap(source, code, generated) {
2124 * @returns { String } output.type - the "type" attribute used on the current fragment
2225 * @returns { String } output.code - the code contained in this fragment
2326 */
24- function getFragment ( source , regExp ) {
25- const match = regExp . exec ( source )
27+ function fragment ( source , regExp ) {
28+ const match = source ? regExp . exec ( source ) : null
2629 return match ? {
2730 // get the type="whathever" attribute
2831 type : match [ 1 ] ? TYPE_ATTR . exec ( match [ 1 ] ) [ 2 ] : null ,
@@ -31,30 +34,38 @@ function getFragment(source, regExp) {
3134}
3235
3336/**
34- * Generate the output code together with the sourcemap
35- * @param { String } source - source code of the tag we will need to compile
36- * @param { Object } options - user options
37- * @returns { Promise } output
38- * @returns { String } output.code
39- * @returns { String } output.map
40- * @returns { String } output.fragments
37+ * Generate the js output from the parsing result
38+ * @param { String } name - the component name
39+ * @param { String } head - additional javascript that could be added to the component
40+ * @param { String } template - the result of the template parsing
41+ * @param { String } exports - all the methods exported by the component
42+ * @param { String } css - component specific syles
43+ * @returns { String } object that must be provided to the riot.define method
4144 */
42- function generate ( source , options ) {
43- new Promise ( ( resolve , reject ) => {
44- const fragments = {
45- css : getFragment ( STYLE ) ,
46- js : getFragment ( SCRIPT ) ,
47- template : getFragment ( TEMPLATE )
48- }
49-
50- const map = sourcemap ( options . src , source , options . dist )
51-
52- resolve ( {
53- fragments,
54- code : '' , // TODO: generate the output code
55- map
45+ export function generate ( name , head , exports , template , css ) {
46+ return `
47+ ${ head }
48+ riot.define(${ name } , {
49+ ${ exports ? `
50+ ${ exports }
51+ ` : ''
52+ }
53+ ${
54+ css ? `
55+ get css() {
56+ return \`${ css } \`
57+ }
58+ ` : ''
59+ }
60+ ${
61+ template ? `
62+ render(h) {
63+ return\`${ template } \`
64+ }
65+ ` : ''
66+ }
5667 })
57- } )
68+ `
5869}
5970
6071/**
@@ -66,12 +77,22 @@ function generate(source, options) {
6677 * @returns { String } output.fragments
6778 */
6879export function parse ( name , source , options ) {
69- return generate ( source , options )
70- . then ( ( { code, map, fragments} ) => {
71- return {
72- code : `riot.define(${ name } , ${ code } )` ,
73- fragments,
74- map
75- }
80+ return new Promise ( ( resolve , reject ) => {
81+ const fragments = {
82+ css : fragment ( source , STYLE ) ,
83+ js : fragment ( source , SCRIPT ) ,
84+ template : fragment ( source , TEMPLATE )
85+ }
86+
87+ const map = options . src && options . dist ? sourcemap ( options . src , source , options . dist ) : ''
88+ const js = parseJs ( fragments . js , offset ( source , '<script' ) )
89+ const template = parseTemplate ( fragments . template , offset ( source , '<template' ) )
90+ const css = parseCss ( fragments . css , offset ( source , '<style' ) )
91+
92+ resolve ( {
93+ fragments,
94+ code : generate ( name , js . head , js . exports , template . code , css . code ) ,
95+ map
7696 } )
97+ } )
7798}
0 commit comments