代码拉取完成,页面将自动刷新
const wu=require("./wuLib.js");
const {getZ}=require("./wuRestoreZ.js");
const {wxsBeautify}=require("./wuJs.js");
const fs=require('fs');
const path=require("path");
const esprima=require('esprima');
const {VM}=require('vm2');
const escodegen=require('escodegen');
function analyze(core,z,namePool,xPool,fakePool={},zMulName="0"){
function anaRecursion(core,fakePool={}){
return analyze(core,z,namePool,xPool,fakePool,zMulName);
}
function push(name,elem){
namePool[name]=elem;
}
function pushSon(pname,son){
if(fakePool[pname])fakePool[pname].son.push(son);
else namePool[pname].son.push(son);
}
for(let ei=0;ei<core.length;ei++){let e=core[ei];
switch(e.type){
case "ExpressionStatement":
{
let f=e.expression;
if(f.callee){
if(f.callee.type=="Identifier"){
switch(f.callee.name){
case "_r":
namePool[f.arguments[0].name].v[f.arguments[1].value]=z[f.arguments[2].value];
break;
case "_rz":
namePool[f.arguments[1].name].v[f.arguments[2].value]=z.mul[zMulName][f.arguments[3].value];
break;
case "_":
pushSon(f.arguments[0].name,namePool[f.arguments[1].name]);
break;
case "_2":
{
let item=f.arguments[6].value;//def:item
let index=f.arguments[7].value;//def:index
let data=z[f.arguments[0].value];
let key=escodegen.generate(f.arguments[8]).slice(1,-1);//f.arguments[8].value;//def:""
let obj=namePool[f.arguments[5].name];
let gen=namePool[f.arguments[1].name];
if(gen.tag=="gen"){
let ret=gen.func.body.body.pop().argument.name;
anaRecursion(gen.func.body.body,{[ret]:obj});
}
obj.v["wx:for"]=data;
if(index!="index")obj.v["wx:for-index"]=index;
if(item!="item")obj.v["wx:for-item"]=item;
if(key!="")obj.v["wx:key"]=key;
}
break;
case "_2z":
{
let item=f.arguments[7].value;//def:item
let index=f.arguments[8].value;//def:index
let data=z.mul[zMulName][f.arguments[1].value];
let key=escodegen.generate(f.arguments[9]).slice(1,-1);//f.arguments[9].value;//def:""
let obj=namePool[f.arguments[6].name];
let gen=namePool[f.arguments[2].name];
if(gen.tag=="gen"){
let ret=gen.func.body.body.pop().argument.name;
anaRecursion(gen.func.body.body,{[ret]:obj});
}
obj.v["wx:for"]=data;
if(index!="index")obj.v["wx:for-index"]=index;
if(item!="item")obj.v["wx:for-item"]=item;
if(key!="")obj.v["wx:key"]=key;
}
break;
case "_ic":
pushSon(f.arguments[5].name,{tag:"include",son:[],v:{src:xPool[f.arguments[0].property.value]}});
break;
case "_ai":
{//template import
let to=Object.keys(fakePool)[0];
if(to)pushSon(to,{tag:"import",son:[],v:{src:xPool[f.arguments[1].property.value]}});
else throw Error("Unexpected fake pool");
}
break;
case "_af":
//ignore _af
break;
default:throw Error("Unknown expression callee name "+f.callee.name);
}
}else if(f.callee.type=="MemberExpression"){
if(f.callee.object.name=="cs"||f.callee.property.name=="pop")break;
throw Error("Unknown member expression");
}else throw Error("Unknown callee type "+f.callee.type);
}else if(f.type=="AssignmentExpression"&&f.operator=="="){
//no special use
}else throw Error("Unknown expression statement.");
break;
}
case "VariableDeclaration":
for(let dec of e.declarations){
if(dec.init.type=="CallExpression"){
switch(dec.init.callee.name){
case "_n":
push(dec.id.name,{tag:dec.init.arguments[0].value,son:[],v:{}});
break;
case "_v":
push(dec.id.name,{tag:"block",son:[],v:{}});
break;
case "_o":
push(dec.id.name,{tag:"__textNode__",textNode:true,content:z[dec.init.arguments[0].value]});
break;
case "_oz":
push(dec.id.name,{tag:"__textNode__",textNode:true,content:z.mul[zMulName][dec.init.arguments[1].value]});
break;
case "_m":
{
if(dec.init.arguments[2].elements.length>0)
throw Error("Noticable generics content: "+dec.init.arguments[2].toString());
let mv={};
let name=null,base=0;
for(let x of dec.init.arguments[1].elements){
let v=x.value;
if(!v&&typeof v!="number"){
if(x.type=="UnaryExpression"&&x.operator=="-")v=-x.argument.value;
else throw Error("Unknown type of object in _m attrs array: "+x.type);
}
if(name===null){
name=v;
}else{
if(base+v<0)mv[name]=null;else{
mv[name]=z[base+v];
if(base==0)base=v;
}
name=null;
}
}
push(dec.id.name,{tag:dec.init.arguments[0].value,son:[],v:mv});
}
break;
case "_mz":
{
if(dec.init.arguments[3].elements.length>0)
throw Error("Noticable generics content: "+dec.init.arguments[3].toString());
let mv={};
let name=null,base=0;
for(let x of dec.init.arguments[2].elements){
let v=x.value;
if(!v&&typeof v!="number"){
if(x.type=="UnaryExpression"&&x.operator=="-")v=-x.argument.value;
else throw Error("Unknown type of object in _mz attrs array: "+x.type);
}
if(name===null){
name=v;
}else{
if(base+v<0)mv[name]=null;else{
mv[name]=z.mul[zMulName][base+v];
if(base==0)base=v;
}
name=null;
}
}
push(dec.id.name,{tag:dec.init.arguments[1].value,son:[],v:mv});
}
break;
case "_gd"://template use/is
{
let is=namePool[dec.init.arguments[1].name].content;
let data=null,obj=null;
ei++;
for(let e of core[ei].consequent.body){
if(e.type=="VariableDeclaration"){
for(let f of e.declarations){
if(f.init.type=="LogicalExpression"&&f.init.left.type=="CallExpression"){
if(f.init.left.callee.name=="_1")data=z[f.init.left.arguments[0].value];
else if(f.init.left.callee.name=="_1z")data=z.mul[zMulName][f.init.left.arguments[1].value];
}
}
}else if(e.type=="ExpressionStatement"){
let f=e.expression;
if(f.type=="AssignmentExpression"&&f.operator=="="&&f.left.property&&f.left.property.name=="wxXCkey"){
obj=f.left.object.name;
}
}
}
namePool[obj].tag="template";
Object.assign(namePool[obj].v,{is:is,data:data});
}
break;
default:
{
let funName=dec.init.callee.name;
if(funName.startsWith("gz$gwx")){
zMulName=funName.slice(6);
}else throw Error("Unknown init callee "+funName);
}
}
}else if(dec.init.type=="FunctionExpression"){
push(dec.id.name,{tag:"gen",func:dec.init});
}else if(dec.init.type=="MemberExpression"){
if(dec.init.object.type=="MemberExpression"&&dec.init.object.object.name=="e_"&&dec.init.object.property.type=="MemberExpression"&&dec.init.object.property.object.name=="x"){
if(dec.init.property.name=="j"){//include
//do nothing
}else if(dec.init.property.name=="i"){//import
//do nothing
}else throw Error("Unknown member expression declaration.");
}else throw Error("Unknown member expression declaration.");
}else throw Error("Unknown declaration init type " + dec.init.type);
}
break;
case "IfStatement":
if(e.test.callee.name.startsWith("_o")){
function parse_OFun(e){
if(e.test.callee.name=="_o")return z[e.test.arguments[0].value];
else if(e.test.callee.name=="_oz")return z.mul[zMulName][e.test.arguments[1].value];
else throw Error("Unknown if statement test callee name:"+e.test.callee.name);
}
let vname=e.consequent.body[0].expression.left.object.name;
let nif={tag:"block",v:{"wx:if":parse_OFun(e)},son:[]};
anaRecursion(e.consequent.body,{[vname]:nif});
pushSon(vname,nif);
if(e.alternate){
while(e.alternate&&e.alternate.type=="IfStatement"){
e=e.alternate;
nif={tag:"block",v:{"wx:elif":parse_OFun(e)},son:[]};
anaRecursion(e.consequent.body,{[vname]:nif});
pushSon(vname,nif);
}
if(e.alternate&&e.alternate.type=="BlockStatement"){
e=e.alternate;
nif={tag:"block",v:{"wx:else":null},son:[]};
anaRecursion(e.body,{[vname]:nif});
pushSon(vname,nif);
}
}
}else throw Error("Unknown if statement.");
break;
default:
throw Error("Unknown type "+e.type);
}
}
}
function wxmlify(str,isText){
if(typeof str=="undefined"||str===null)return "Empty";//throw Error("Empty str in "+(isText?"text":"prop"));
if(isText)return str;//may have some bugs in some specific case(undocumented by tx)
else return str.replace(/"/g, '\\"');
}
function elemToString(elem,dep,moreInfo=false){
const longerList=[];//put tag name which can't be <x /> style.
const indent=' '.repeat(4);
function isTextTag(elem){
return elem.tag=="__textNode__"&&elem.textNode;
}
function elemRecursion(elem,dep){
return elemToString(elem,dep,moreInfo);
}
function trimMerge(rets){
let needTrimLeft=false,ans="";
for(let ret of rets){
if(ret.textNode==1){
if(!needTrimLeft){
needTrimLeft=true;
ans=ans.trimRight();
}
}else if(needTrimLeft){
needTrimLeft=false;
ret=ret.trimLeft();
}
ans+=ret;
}
return ans;
}
if(isTextTag(elem)){
//In comment, you can use typify text node, which beautify its code, but may destroy ui.
//So, we use a "hack" way to solve this problem by letting typify program stop when face textNode
let str=new String(wxmlify(elem.content,true));
str.textNode=1;
return wxmlify(str,true);//indent.repeat(dep)+wxmlify(elem.content.trim(),true)+"\n";
}
if(elem.tag=="block"&&!moreInfo){
if(elem.son.length==1&&!isTextTag(elem.son[0])){
let ok=true,s=elem.son[0];
for(let x in elem.v)if(x in s.v){
ok=false;
break;
}
if(ok&&!(("wx:for" in s.v||"wx:if" in s.v)&&("wx:if" in elem.v||"wx:else" in elem.v||"wx:elif" in elem.v))){//if for and if in one tag, the default result is an if in for. And we should block if nested in elif/else been combined.
Object.assign(s.v,elem.v);
return elemRecursion(s,dep);
}
}else if(Object.keys(elem.v).length==0){
let ret=[];
for(let s of elem.son)ret.push(elemRecursion(s,dep));
return trimMerge(ret);
}
}
let ret=indent.repeat(dep)+"<"+elem.tag;
for(let v in elem.v)ret+=" "+v+(elem.v[v]!==null?"=\""+wxmlify(elem.v[v])+"\"":"");
if(elem.son.length==0){
if(longerList.includes(elem.tag))return ret+" />\n";
else return ret+"></"+elem.tag+">\n";
}
ret+=">\n";
let rets=[ret];
for(let s of elem.son)rets.push(elemRecursion(s,dep+1));
rets.push(indent.repeat(dep)+"</"+elem.tag+">\n");
return trimMerge(rets);
}
function doWxml(state,dir,name,code,z,xPool,rDs,wxsList,moreInfo){
let rname=code.slice(code.lastIndexOf("return")+6).replace(/[\;\}]/g,"").trim();
code=code.slice(code.indexOf("\n"),code.lastIndexOf("return")).trim();
let r={son:[]};
analyze(esprima.parseScript(code).body,z,{[rname]:r},xPool,{[rname]:r});
let ans=[];
for(let elem of r.son)ans.push(elemToString(elem,0,moreInfo));
let result=[ans.join("")];
for(let v in rDs){
state[0]=v;
let oriCode=rDs[v].toString();
let rname=oriCode.slice(oriCode.lastIndexOf("return")+6).replace(/[\;\}]/g,"").trim();
let tryPtr=oriCode.indexOf("\ntry{");
let zPtr=oriCode.indexOf("var z=gz$gwx");
let code=oriCode.slice(tryPtr+5,oriCode.lastIndexOf("\n}catch(")).trim();
if(zPtr!=-1&&tryPtr>zPtr){
let attach=oriCode.slice(zPtr);
attach=attach.slice(0,attach.indexOf("()"))+"()\n";
code=attach+code;
}
let r={tag:"template",v:{name:v},son:[]};
analyze(esprima.parseScript(code).body,z,{[rname]:r},xPool,{[rname]:r});
result.unshift(elemToString(r,0,moreInfo));
}
name=path.resolve(dir,name);
if(wxsList[name])result.push(wxsList[name]);
wu.save(name,result.join(""));
}
function tryWxml(dir,name,code,z,xPool,rDs,...args){
console.log("Decompile "+name+"...");
let state=[null];
try{
doWxml(state,dir,name,code,z,xPool,rDs,...args);
console.log("Decompile success!");
}catch(e){
console.log("error on "+name+"("+(state[0]===null?"Main":"Template-"+state[0])+")\nerr: ",e);
if(state[0]===null)wu.save(path.resolve(dir,name+".ori.js"),code);
else wu.save(path.resolve(dir,name+".tem-"+state[0]+".ori.js"),rDs[state[0]].toString());
}
}
function doWxs(code){
const before='nv_module={nv_exports:{}};';
return wxsBeautify(code.slice(code.indexOf(before)+before.length,code.lastIndexOf('return nv_module.nv_exports;}')).replace(/nv\_/g,''));
}
function doFrame(name,cb,order){
let moreInfo=order.includes("m");
wxsList={};
wu.get(name,code=>{
getZ(code,z=>{
const before="\nvar nv_require=function(){var nnm=";
code=code.slice(code.indexOf(before)+before.length,code.lastIndexOf("if(path&&e_[path]){"));
json=code.slice(0,code.indexOf("};")+1);
let endOfRequire=code.indexOf("()\r\n")+4;
if(endOfRequire==4-1)endOfRequire=code.indexOf("()\n")+3;
code=code.slice(endOfRequire);
let rD={},rE={},rF={},requireInfo,x,vm=new VM({sandbox:{d_:rD,e_:rE,f_:rF,_vmRev_(data){
[x,requireInfo]=data;
},nv_require(path){
return ()=>path;
}}});
vm.run(code+"\n_vmRev_([x,"+json+"])");
let dir=path.dirname(name),pF=[];
for(let info in rF)if(typeof rF[info]=="function"){
let name=path.resolve(dir,(info[0]=='/'?'.':'')+info),ref=rF[info]();
pF[ref]=info;
wu.save(name,doWxs(requireInfo[ref].toString()));
}
for(let info in rF)if(typeof rF[info]=="object"){
let name=path.resolve(dir,(info[0]=='/'?'.':'')+info);
let res=[],now=rF[info];
for(let deps in now){
let ref=now[deps]();
if(ref.includes(":"))res.push("<wxs module=\""+deps+"\">\n"+doWxs(requireInfo[ref].toString())+"\n</wxs>");
else if(pF[ref])res.push("<wxs module=\""+deps+"\" src=\""+wu.toDir(pF[ref],info)+"\" />");
else res.push("<wxs module=\""+deps+"\" src=\""+wu.toDir(ref.slice(2),info)+"\" />");
wxsList[name]=res.join("\n");
}
}
for(let name in rE)tryWxml(dir,name,rE[name].f.toString(),z,x,rD[name],wxsList,moreInfo);
cb({[name]:4});
});
});
}
module.exports={doFrame:doFrame};
if(require.main===module){
wu.commandExecute(doFrame,"Restore wxml files.\n\n<files...>\n\n<files...> restore wxml file from page-frame.html or app-wxss.js.");
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。