|
| 1 | +'use strict' |
| 2 | + |
| 3 | +constpath=require('path') |
| 4 | + |
1 | 5 | constloaderUtils=require('loader-utils') |
| 6 | +constvalidateOptions=require('schema-utils') |
| 7 | + |
| 8 | +constschema=require('./options.json') |
| 9 | + |
2 | 10 | constposthtml=require('posthtml') |
| 11 | +constposthtmlrc=require('posthtml-load-config') |
3 | 12 |
|
4 | | -module.exports=function(source){ |
5 | | -if(this.cacheable)this.cacheable() |
| 13 | +constparseOptions=require('./options') |
6 | 14 |
|
7 | | -// configure options |
8 | | -constqs=loaderUtils.parseQuery(this.query) |
| 15 | +constLoaderError=require('./Error') |
| 16 | +/** |
| 17 | + * PostHTML Loader |
| 18 | + * |
| 19 | + *@author Michael Ciniawsky <michael.ciniawsky@gmail.com> (@michael-ciniawsky) |
| 20 | + *@license MIT |
| 21 | + * |
| 22 | + *@version 1.0.0 |
| 23 | + * |
| 24 | + *@requires loader-utils |
| 25 | + *@requires schema-utils |
| 26 | + * |
| 27 | + *@requires posthtml |
| 28 | + *@requires posthtml-load-config |
| 29 | + * |
| 30 | + *@method posthtml-loader |
| 31 | + * |
| 32 | + *@param {String} html HTML |
| 33 | + * |
| 34 | + *@return {String} html HTML |
| 35 | + */ |
| 36 | +module.exports=functionloader(html,map,meta){ |
| 37 | +// Loader Options |
| 38 | +constoptions=loaderUtils.getOptions(this)||{} |
| 39 | + |
| 40 | +validateOptions(schema,options,'PostHTML Loader') |
| 41 | + |
| 42 | +// Make the loader async |
9 | 43 | constcb=this.async() |
10 | | -letconfig |
11 | | -try{ |
12 | | -config=parseOptions.call(this,this.options.posthtml,qs) |
13 | | -}catch(err){ |
14 | | -returncb(err) |
15 | | -} |
16 | | - |
17 | | -// configure custom parser argument if necessary |
18 | | -constprocessArgs=[source.toString()] |
19 | | -if(config.parser){processArgs.push({parser:config.parser})} |
20 | | - |
21 | | -// run posthtml |
22 | | -constph=posthtml(config.plugins) |
23 | | -ph.process.apply(ph,processArgs) |
24 | | -.then((result)=>cb(null,result.html),cb) |
25 | | -} |
| 44 | +constfile=this.resourcePath |
26 | 45 |
|
27 | | -functionparseOptions(config=[],qs={}){ |
28 | | -constres={} |
| 46 | +Promise.resolve().then(()=>{ |
| 47 | +constlength=Object.keys(options) |
| 48 | +.filter((option)=>{ |
| 49 | +switch(option){ |
| 50 | +case'ident': |
| 51 | +case'config': |
| 52 | +return |
| 53 | +default: |
| 54 | +returnoption |
| 55 | +} |
| 56 | +}) |
| 57 | +.length |
29 | 58 |
|
30 | | -// if we have a function, run it |
31 | | -if(typeofconfig==='function'){config=config.call(this,this)} |
| 59 | +if(length){ |
| 60 | +returnparseOptions.call(this,options) |
| 61 | +} |
32 | 62 |
|
33 | | -// if it's not an object at this point, error |
34 | | -if(typeofconfig!=='object'){ |
35 | | -thrownewError('Configuration must return an array or object') |
36 | | -} |
| 63 | +constrc={ |
| 64 | +path:path.dirname(file), |
| 65 | +ctx:{ |
| 66 | +file:{ |
| 67 | +extname:path.extname(file), |
| 68 | +dirname:path.dirname(file), |
| 69 | +basename:path.basename(file) |
| 70 | +}, |
| 71 | +options:{} |
| 72 | +} |
| 73 | +} |
37 | 74 |
|
38 | | -// if we now have an array, that represents the plugins directly |
39 | | -if(Array.isArray(config)){ |
40 | | -res.plugins=config |
41 | | -// if not, it's an object. if a plugin pack is being used, use it. |
42 | | -// otherwise, use default plugins |
43 | | -}else{ |
44 | | -res.plugins=qs.pack ?config[qs.pack] :config.plugins |
45 | | -} |
| 75 | +if(options.config){ |
| 76 | +if(options.config.path){ |
| 77 | +rc.path=path.resolve(options.config.path) |
| 78 | +} |
46 | 79 |
|
47 | | -// load in the custom parser if there is one |
48 | | -if(config.parser){res.parser=config.parser} |
| 80 | +if(options.config.ctx){ |
| 81 | +rc.ctx.options=options.config.ctx |
| 82 | +} |
| 83 | +} |
49 | 84 |
|
50 | | -// try loading custom parser from query |
51 | | -if(qs.parser){ |
52 | | -res.parser=require(qs.parser) |
53 | | -} |
| 85 | +returnposthtmlrc(rc.ctx,rc.path,{argv:false}) |
| 86 | +}) |
| 87 | +.then((config)=>{ |
| 88 | +if(!config)config={} |
54 | 89 |
|
55 | | -returnres |
56 | | -} |
| 90 | +if(config.file)this.addDependency(config.file) |
| 91 | + |
| 92 | +if(config.options){ |
| 93 | +// Disable overriding `options.to` (`posthtml.config.js`) |
| 94 | +if(config.options.to)deleteconfig.options.to |
| 95 | +// Disable overriding `options.from` (`posthtml.config.js`) |
| 96 | +if(config.options.from)deleteconfig.options.from |
| 97 | +} |
| 98 | + |
| 99 | +letplugins=config.plugins||[] |
| 100 | +letoptions=Object.assign( |
| 101 | +{from:file,to:file}, |
| 102 | +config.options |
| 103 | +) |
| 104 | + |
| 105 | +if(typeofoptions.parser==='string'){ |
| 106 | +options.parser=require(options.parser)() |
| 107 | +} |
| 108 | + |
| 109 | +// TODO(michael-ciniawsky) enable if when custom renderer available |
| 110 | +// if (typeof options.render === 'string') { |
| 111 | +// options.render = require(options.render)() |
| 112 | +// } |
| 113 | + |
| 114 | +returnposthtml(plugins) |
| 115 | +.process(html,options) |
| 116 | +.then((result)=>{ |
| 117 | +if(result.messages){ |
| 118 | +result.messages.forEach((msg)=>{ |
| 119 | +switch(msg.type){ |
| 120 | +case'error': |
| 121 | +this.emitError(msg.message) |
57 | 122 |
|
58 | | -module.exports.parseOptions=parseOptions |
| 123 | +break |
| 124 | +case'warning': |
| 125 | +this.emitWarning(msg.message) |
| 126 | + |
| 127 | +break |
| 128 | +case'dependency': |
| 129 | +this.addDependency(msg.file) |
| 130 | + |
| 131 | +break |
| 132 | +default: |
| 133 | +break |
| 134 | +} |
| 135 | +}) |
| 136 | +} |
| 137 | + |
| 138 | +html=result.html |
| 139 | + |
| 140 | +if(this.loaderIndex===0){ |
| 141 | +html=`export default \`${html}\`` |
| 142 | + |
| 143 | +cb(null,html) |
| 144 | + |
| 145 | +returnnull |
| 146 | +} |
| 147 | + |
| 148 | +if(!meta)meta={} |
| 149 | + |
| 150 | +meta.ast={type:'posthtml',root:result.tree} |
| 151 | +meta.messages=result.messages |
| 152 | + |
| 153 | +cb(null,html,map,meta) |
| 154 | + |
| 155 | +returnnull |
| 156 | +}) |
| 157 | +}) |
| 158 | +.catch((err)=>{ |
| 159 | +cb(newLoaderError(err)) |
| 160 | + |
| 161 | +returnnull |
| 162 | +}) |
| 163 | +} |