UNPKG

totorojs

Version:
812 lines (679 loc) 22.7 kB
var CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ .source.replace('@', S_STRINGS), 'gim'); var SCRIPTS = /<script(\s+[^>]*)?>\n?([\S\s]*?)<\/script\s*>/gi; var STYLES = /<style(\s+[^>]*)?>\n?([\S\s]*?)<\/style\s*>/gi; var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/; function getType (attribs) { if (attribs) { var match = attribs.match(TYPE_ATTR); match = match && (match[2] || match[3]); if (match) { return match.replace('text/', ''); } } return ''; } function riotjs (js) { var parts = [], match, toes5, pos, method, prefix, name, RE = RegExp; if (~js.indexOf('/')) { js = rmComms(js, JS_COMMS); } while ((match = js.match(JS_ES6SIGN))) { parts.push(RE.leftContext); js = RE.rightContext; pos = skipBody(js, JS_ES6END); method = match[1]; prefix = match[2] || ''; name = match[3]; toes5 = !/^(?:if|while|for|switch|catch|function)$/.test(name); if (toes5) { name = match[0].replace(method, 'this.' + name + ' =' + prefix + ' function'); } else { name = match[0]; } parts.push(name, js.slice(0, pos)); js = js.slice(pos); if (toes5 && !/^\s*.\s*bind\b/.test(js)) { parts.push('.bind(this)'); } } return parts.length ? parts.join('') + js : js; function rmComms (s, r, m) { r.lastIndex = 0; while ((m = r.exec(s))) { if (m[0][0] === '/' && !m[1] && !m[2]) { s = RE.leftContext + ' ' + RE.rightContext; r.lastIndex = m[3] + 1; } } return s; } function skipBody (s, r) { var m, i = 1; r.lastIndex = 0; while (i && (m = r.exec(s))) { if (m[0] === '{') { ++i; }else if (m[0] === '}') { --i; } } return i ? s.length : r.lastIndex; } } function getAttrib (attribs, name) { if (attribs) { var match = attribs.match(RegExp('\\s' + name + MISC_ATTR, 'i')); match = match && match[1]; if (match) { return (/^['"]/).test(match) ? match.slice(1, -1) : match; } } return ''; } function extend (obj, props) { if (props) { for (var prop in props) { /* istanbul ignore next */ if (props.hasOwnProperty(prop)) { obj[prop] = props[prop]; } } } return obj; } function cleanSource (src) { var mm,re = HTML_COMMS; if (~src.indexOf('\r')) { src = src.replace(/\r\n?/g, '\n'); } re.lastIndex = 0; while ((mm = re.exec(src))) { if (mm[0][0] === '<') { src = RegExp.leftContext + RegExp.rightContext; re.lastIndex = mm[3] + 1; } } return src; } var brackets = (function (UNDEF) { var REGLOB = 'g', R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g, R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g, S_QBLOCKS = R_STRINGS.source + '|' + /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' + /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?(\/)[gim]*/.source, UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'), NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g, FINDBRACES = { '(': RegExp('([()])|' + S_QBLOCKS, REGLOB), '[': RegExp('([[\\]])|' + S_QBLOCKS, REGLOB), '{': RegExp('([{}])|' + S_QBLOCKS, REGLOB) }, DEFAULT = '{ }'; var _pairs = [ '{', '}', '{', '}', /{[^}]*}/, /\\([{}])/g, /\\({)|{/g, RegExp('\\\\(})|([[({])|(})|' + S_QBLOCKS, REGLOB), DEFAULT, /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, /(^|[^\\]){=[\S\s]*?}/ ]; var cachedBrackets = UNDEF, _regex, _cache = [], _settings; function _loopback (re) { return re; } function _rewrite (re, bp) { if (!bp) { bp = _cache; } return new RegExp( re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : '' ); } function _create (pair) { if (pair === DEFAULT) { return _pairs; } var arr = pair.split(' '); if (arr.length !== 2 || UNSUPPORTED.test(pair)) { throw new Error('Unsupported brackets "' + pair + '"'); } arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' ')); arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr); arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr); arr[6] = _rewrite(_pairs[6], arr); arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB); arr[8] = pair; return arr; } function _brackets (reOrIdx) { return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx]; } _brackets.split = function split (str, tmpl, _bp) { // istanbul ignore next: _bp is for the compiler if (!_bp) { _bp = _cache; } var parts = [], match, isexpr, start, pos, re = _bp[6]; isexpr = start = re.lastIndex = 0; while ((match = re.exec(str))) { pos = match.index; if (isexpr) { if (match[2]) { re.lastIndex = skipBraces(str, match[2], re.lastIndex); continue; } if (!match[3]) { continue; } } if (!match[1]) { unescapeStr(str.slice(start, pos)); start = re.lastIndex; re = _bp[6 + (isexpr ^= 1)]; re.lastIndex = start; } } if (str && start < str.length) { unescapeStr(str.slice(start)); } return parts; function unescapeStr (s) { if (tmpl || isexpr) { parts.push(s && s.replace(_bp[5], '$1')); } else { parts.push(s); } } function skipBraces (s, ch, ix) { var match, recch = FINDBRACES[ch]; recch.lastIndex = ix; ix = 1; while ((match = recch.exec(s))) { if (match[1] && !(match[1] === ch ? ++ix : --ix)) { break; } } return ix ? s.length : recch.lastIndex; } }; _brackets.hasExpr = function hasExpr (str) { return _cache[4].test(str); }; _brackets.loopKeys = function loopKeys (expr) { var m = expr.match(_cache[9]); return m?{ key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }:{ val: expr.trim() } }; _brackets.array = function array (pair) { return pair ? _create(pair) : _cache; }; function _reset (pair) { if ((pair || (pair = DEFAULT)) !== _cache[8]) { _cache = _create(pair); _regex = pair === DEFAULT ? _loopback : _rewrite; _cache[9] = _regex(_pairs[9]); } cachedBrackets = pair; } function _setSettings (o) { var b; o = o || {}; b = o.brackets; Object.defineProperty(o, 'brackets', { set: _reset, get: function () { return cachedBrackets }, enumerable: true }); _settings = o; _reset(b); } Object.defineProperty(_brackets, 'settings', { set: _setSettings, get: function () { return _settings } }); /* istanbul ignore next: in the browser riot is always in the scope */ _brackets.settings = typeof tiny !== 'undefined' && tiny.settings || {}; _brackets.set = _reset; _brackets.R_STRINGS = R_STRINGS; _brackets.R_MLCOMMS = R_MLCOMMS; _brackets.S_QBLOCKS = S_QBLOCKS; return _brackets; })(); var JS_ES6SIGN = /^[ \t]*(((?:async|\*)\s*)?([$_A-Za-z][$\w]*))\s*\([^()]*\)\s*{/m; var JS_ES6END = RegExp('[{}]|' + brackets.S_QBLOCKS, 'g'); var JS_COMMS = RegExp(brackets.R_MLCOMMS.source + '|//[^\r\n]*|' + brackets.S_QBLOCKS, 'g'); /* eslint-enable */ var S_LINESTR = /"[^"\n\\]*(?:\\[\S\s][^"\n\\]*)*"|'[^'\n\\]*(?:\\[\S\s][^'\n\\]*)*'/.source; var S_STRINGS = brackets.R_STRINGS.source; var HTML_ATTRS = / *([-\w:\xA0-\xFF]+) ?(?:= ?('[^']*'|"[^"]*"|\S+))?/g; var HTML_COMMS = RegExp(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_LINESTR, 'g'); var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g; var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g; var RIOT_ATTRS = ['style', 'src', 'd', 'value']; var VOID_TAGS = /^(?:input|img|br|wbr|hr|area|base|col|embed|keygen|link|meta|param|source|track)$/; var PRE_TAGS = /<pre(?:\s+(?:[^">]*|"[^"]*")*)?>([\S\s]+?)<\/pre\s*>/gi; var SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i; var IMPORT_STATEMENT = /^\s*import(?!\w)(?:(?:\s|[^\s'"])*)['|"].*\n?/gm; var TRIM_TRAIL = /[ \t]+$/gm; var RE_HASEXPR = safeRegex(/@#\d/, 'x01'); var RE_REPEXPR = safeRegex(/@#(\d+)/g, 'x01'); var CH_IDEXPR = '\x01#'; var CH_DQCODE = '\u2057'; var DQ = '"'; var SQ = "'"; function safeRegex (re) { var arguments$1 = arguments; var src = re.source; var opt = re.global ? 'g' : ''; if (re.ignoreCase) { opt += 'i'; } if (re.multiline) { opt += 'm'; } for (var i = 1; i < arguments.length; i++) { src = src.replace('@', '\\' + arguments$1[i]); } return new RegExp(src, opt); } extend$1=extend; function _brackets (reOrIdx) { return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx] } function parseAttribs (str, pcex) { var list = [], match, type, vexp; HTML_ATTRS.lastIndex = 0; str = str.replace(/\s+/g, ' '); while ((match = HTML_ATTRS.exec(str))) { var k = match[1].toLowerCase(), v = match[2]; if (!v) { list.push(k); } else { if (v[0] !== DQ) { v = DQ + (v[0] === SQ ? v.slice(1, -1) : v) + DQ; } if (k === 'type' && SPEC_TYPES.test(v)) { type = v; } else { if (RE_HASEXPR.test(v)) { if (k === 'value') { vexp = 1; } if (~RIOT_ATTRS.indexOf(k)) { //k = 'riot-' + k; k=k; } } list.push(k + '=' + v); } } } if (type) { if (vexp) { type = DQ + pcex._bp[0] + SQ + type.slice(1, -1) + SQ + pcex._bp[1] + DQ; } list.push('type=' + type); } return list.join(' '); } function restoreExpr (html, pcex) { if (pcex.length) { html = html.replace(RE_REPEXPR, function (_, d) { return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) }); } return html; } function splitHtml (html, opts, pcex) { var _bp = pcex._bp; if (html && _bp[4].test(html)) { var jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, list = brackets.split(html, 0, _bp), expr; for (var i = 1; i < list.length; i += 2) { expr = list[i]; if (expr[0] === '^') { expr = expr.slice(1); } else if (jsfn) { expr = jsfn(expr, opts).trim(); if (expr.slice(-1) === ';') { expr = expr.slice(0, -1); } } list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1]; } html = list.join(''); } return html } function _compileHTML (html, opts, pcex) { if (!/\S/.test(html)) { return '' } html = splitHtml(html, opts, pcex) .replace(HTML_TAGS, function (_, name, attr, ends) { name = name.toLowerCase(); ends = ends && !VOID_TAGS.test(name) ? '></' + name : ''; if (attr) { name += ' ' + parseAttribs(attr, pcex); } return '<' + name + ends + '>' }); if (!opts.whitespace) { var p = []; if (/<pre[\s>]/.test(html)) { html = html.replace(PRE_TAGS, function (q) { p.push(q); return '\u0002' }); } html = html.trim().replace(/\s+/g, ' '); if (p.length) { html = html.replace(/\u0002/g, function () { return p.shift() }); } } if (opts.compact) { html = html.replace(HTML_PACK, '><$1'); } return restoreExpr(html, pcex).replace(TRIM_TRAIL, '') } function getCode (code, opts, attribs, base) { var type = getType(attribs), src = getAttrib(attribs, 'src'), jsParserOptions = extend$1({}, opts.parserOptions.js); if (src) { return false } return _compileJS( code, opts, type, extend$1(jsParserOptions, getParserOptions(attribs)), base ) } function unescapeHTML (str) { return str .replace(/&amp;/g, '&') .replace(/&lt;/g, '<') .replace(/&gt;/g, '>') .replace(/&quot;/g, '"') .replace(/&#039;/g, '\'') } function getParserOptions (attribs) { var opts = unescapeHTML(getAttrib(attribs, 'options')); return opts ? JSON.parse(opts) : null } function compile$1 (src, opts, url) { var parts = [], included, defaultParserptions = { template: {}, js: {}, style: {} }; if (!opts) { opts = {}; } opts.parserOptions = extend$1(defaultParserptions, opts.parserOptions || {}); included = opts.exclude ? function (s) { return opts.exclude.indexOf(s) < 0 } : function () { return 1 }; if (!url) { url = ''; } var _bp = brackets.array(opts.brackets); if (opts.template) { src = compileTemplate(src, url, opts.template, opts.parserOptions.template); } src = cleanSource(src) .replace(CUST_TAG, function (_, indent, tagName, attribs, body, body2) { var jscode = '', styles = '', html = '', imports = '', pcex = []; pcex._bp = _bp; tagName = tagName.toLowerCase(); attribs = attribs && included('attribs') ? restoreExpr( parseAttribs( splitHtml(attribs, opts, pcex), pcex), pcex) : ''; if ((body || (body = body2)) && /\S/.test(body)) { if (body2) { if (included('html')) { html = _compileHTML(body2, opts, pcex); } } else { body = body.replace(RegExp('^' + indent, 'gm'), ''); body = body.replace(SCRIPTS, function (_m, _attrs, _script) { if (included('js')) { var code = getCode(_script, opts, _attrs, url); if (code) { jscode += (jscode ? '\n' : '') + code; } } return '' }); body = body.replace(STYLES, function (_m, _attrs, _style) { if (included('css')) { styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName); } return '' }); var blocks = splitBlocks(body.replace(TRIM_TRAIL, '')); if (included('html')) { html = _compileHTML(blocks[0], opts, pcex); } if (included('js')) { body = _compileJS(blocks[1], opts, null, null, url); if (body) { jscode += (jscode ? '\n' : '') + body; } jscode = jscode.replace(IMPORT_STATEMENT, function (s) { imports += s.trim() + '\n'; return '' }); } } } jscode = /\S/.test(jscode) ? jscode.replace(/\n{3,}/g, '\n\n') : ''; if (opts.entities) { parts.push({ tagName: tagName, html: html, css: styles, attribs: attribs, js: jscode, imports: imports }); return '' } return mktag(tagName, html, styles, attribs, jscode, imports, opts) }); if (opts.entities) { return parts } return src } function cssCode (code, opts, attribs, url, tag) { var parserStyleOptions = extend$1({}, opts.parserOptions.style), extraOpts = { parserOpts: extend$1(parserStyleOptions, getParserOptions(attribs)), url: url }; return _compileCSS(code, tag, getType(attribs) || opts.style, extraOpts) } var CSS_SELECTOR = RegExp('([{}]|^)[; ]*((?:[^@ ;{}][^{}]*)?[^@ ;{}:] ?)(?={)|' + S_LINESTR, 'g'); function scopedCSS (tag, css) { var scope = ':scope'; return css.replace(CSS_SELECTOR, function (m, p1, p2) { if (!p2) { return m } p2 = p2.replace(/[^,]+/g, function (sel) { var s = sel.trim(); if (s.indexOf(tag) === 0) { return sel } if (!s || s === 'from' || s === 'to' || s.slice(-1) === '%') { return sel } if (s.indexOf(scope) < 0) { s = tag + ' ' + s + ',[data-is="' + tag + '"] ' + s; } else { s = s.replace(scope, tag) + ',' + s.replace(scope, '[data-is="' + tag + '"]'); } return s }); return p1 ? p1 + ' ' + p2 : p2 }) } function _compileCSS (css, tag, type, opts) { opts = opts || {}; if (type) { if (type !== 'css') { var parser = parsers$1._req('css.' + type, true); css = parser(tag, css, opts.parserOpts || {}, opts.url); } } css = css.replace(brackets.R_MLCOMMS, '').replace(/\s+/g, ' ').trim(); if (tag) { css = scopedCSS(tag, css); } return css } function splitBlocks (str) { if (/<[-\w]/.test(str)) { var m, k = str.lastIndexOf('<'), n = str.length; while (~k) { m = str.slice(k, n).match(END_TAGS); if (m) { k += m.index + m[0].length; m = str.slice(0, k); if (m.slice(-5) === '<-/>\n') { m = m.slice(0, -5); } return [m, str.slice(k)] } n = k; k = str.lastIndexOf('<', k - 1); } } return ['', str] } function _compileJS (js, opts, type, parserOpts, url) { if (!/\S/.test(js)) { return '' } if (!type) { type = opts.type; } var parser = opts.parser || type && parsers$1._req('js.' + type, true) || riotjs; return parser(js, parserOpts, url).replace(/\r\n?/g, '\n').replace(TRIM_TRAIL, '') } function _q (s, r) { if (!s) { return "''" } s = SQ + s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + SQ; return r && ~s.indexOf('\n') ? s.replace(/\n/g, '\\n') : s } function mktag (name, html, css, attr, js, imports, opts) { var c = opts.debug ? ',\n ' : ', ', s = '});'; if (js && js.slice(-1) !== '\n') { s = '\n' + s; } return imports + 'tiny.create$(\'' + name + SQ + c + _q(html, 1) + c + _q(css) + c + _q(attr) + ', function(opts) {\n' + js + s } var rf=require("fs"); var sys=require("sys"); var pro = require("./process"); var jsp = require("./parse-js"); // var ast = jsp.parse("riot.tag2('app-main', '<article></article>', '.w{}', '', function(opts) {var s=require('./a.js','./b.js').then(function(){});})"); // var ast3 = pro.ast_mangle(ast); // var ast4 = pro.ast_squeeze(ast3); // console.log(JSON.stringify(ast)) var fileNames=''; var getJsFile=function(err,data){ if(err){ console.log("error:"+err); }else{ var p=global.FILEDIR+'/output/'+this.name; var b2 = new Buffer(data,'utf-8'); var newBuff=new Buffer(3); newBuff[0]=239; newBuff[1]=187; newBuff[2]=191; var c=Buffer.concat([newBuff,b2],b2.length+3); //console.log(p) rf.writeFileSync(p,c.toString(),"utf-8"); } }; var parseAst=function(arr){ for(var i=0,l=arr.length;i<l;i++){ if({}.toString.call(arr[i])=='[object Array]'){ parseAst(arr[i]); }else if({}.toString.call(arr[i])=='[object String]'&&{}.toString.call(arr[i+1])=='[object Array]'){ if(arr[i]=='call'){ if(arr[i+1][1]=='require'){ // arr[i+2][0][1]='./ss.js'; if({}.toString.call(arr[i+2])=='[object Array]'){ for(var n=0,len=arr[i+2].length;n<len;n++){ (arr[i+2][n][1]).replace(/(\w+)\.\w+$/,function(e){ fileNames=e; //console.log(fileNames) rf.readFile(global.FILEDIR+'/'+(arr[i+2][n][1]),"utf-8",getJsFile.bind({name:fileNames})); arr[i+2][n][1]='./'+fileNames; }); } } arr[i+1][1]='tiny.require'; } }else{ //parseAst(arr[i+1]); } }else{ } } }; //sys.puts(pro.gen_code(ast, true)); var compilerTag=function(fileName,inputPath,outPath,fn){ //console.log(fileName,inputPath,outPath) var that=this; function callBack(err,data){ if(err){ console.log("error:"+err); }else{ var p=outPath+(fileName.replace('.xhtml','.js')); console.log(p) var cstr=compile$1(data); //console.log(cstr); var ast=jsp.parse(cstr.toString()); parseAst(ast); var string=pro.gen_code(ast,true); var b2 = new Buffer(compile$1(string),'utf-8'); var newBuff=new Buffer(3); newBuff[0]=239; newBuff[1]=187; newBuff[2]=191; var c=Buffer.concat([newBuff,b2],b2.length+3); var res=rf.writeFileSync(p,c.toString(),"utf-8"); //var buff = rf.readFileSync(p); // console.log(c); // if (buff[0].toString(16).toLowerCase() == "ef" && buff[1].toString(16).toLowerCase() == "bb" && buff[2].toString(16).toLowerCase() == "bf") { // //EF BB BF 239 187 191 // console.log('\发现BOM文件:', p, "\n"); // buff = buff.slice(3); // fs.writeFile(p, buff.toString(), "utf8"); // } fn(that); } } rf.readFile(inputPath,"utf-8",callBack); return true; }; module['exports'] = compilerTag;