| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795 | 
							- import Awesome from '../background/awesome.js';
 
- const DEV_TOOLS_MY_TOOLS = 'DEV-TOOLS:MY-TOOLS';
 
- const TOOL_NAME_TPL = 'DYNAMIC_TOOL:#TOOL-NAME#';
 
- const TOOL_CONTENT_SCRIPT_TPL = 'DYNAMIC_TOOL:CS:#TOOL-NAME#';
 
- const TOOL_CONTENT_SCRIPT_CSS_TPL = 'DYNAMIC_TOOL:CS:CSS:#TOOL-NAME#';
 
- let editor = null;
 
- new Vue({
 
-     el: '#pageContainer',
 
-     data: {
 
-         showGivenIcons: false,
 
-         myTools: {},
 
-         showEditorFlag: false,
 
-         showNewToolForm: false,
 
-         updateUrlMode: false,
 
-         givenIconList: [],
 
-         model: {},
 
-         demo: {
 
-             name: 'hello-world',
 
-             files: ['fh-config.js', 'index.html', 'index.js', 'index.css', 'content-script.js']
 
-         }
 
-     },
 
-     mounted: function () {
 
-         // 本地没安装过demo,就强制再更新一遍
 
-         this.getContentFromLocal(this.demo.name, 'index.html').then(content => {
 
-             if(content) {
 
-                 this.getToolConfigs();
 
-             }else{
 
-                 this.loadDemo().then(() => this.getToolConfigs());
 
-             }
 
-         });
 
-     },
 
-     methods: {
 
-         toggleEditor(show, toolName) {
 
-             this.showEditorFlag = show;
 
-             if (show && toolName) {
 
-                 let toolObj = this.myTools[toolName] || {};
 
-                 this.model = {
 
-                     tool: toolName,
 
-                     name: toolObj.name
 
-                 };
 
-                 this.getToolFilesFromLocal(toolName).then(files => {
 
-                     this.model.files = files;
 
-                     if (!editor) {
 
-                         editor = CodeMirror.fromTextArea(this.$refs.txtEditor, {
 
-                             mode: 'javascript',
 
-                             lineNumbers: true,
 
-                             matchBrackets: true,
 
-                             styleActiveLine: true,
 
-                             lineWrapping: true
 
-                         });
 
-                         editor.on('change', (editor, changes) => {
 
-                             let result = this.saveContentToLocal(this.model.tool, this.model.editingFile, editor.getValue());
 
-                             if (this.model.editingFile === 'fh-config.js' && result) {
 
-                                 result.contentScriptJs && !this.model.files.includes('content-script.js') && this.model.files.push('content-script.js');
 
-                                 result.contentScriptCss && !this.model.files.includes('content-script.css') && this.model.files.push('content-script.css');
 
-                                 this.$forceUpdate();
 
-                             }
 
-                         });
 
-                         editor.on('keydown', (editor, event) => {
 
-                             if (event.metaKey || event.ctrlKey) {
 
-                                 if (event.code === 'KeyS') {
 
-                                     this.toast('当前代码是自动保存的,无需Ctrl+S手动保存!');
 
-                                     event.preventDefault();
 
-                                     event.stopPropagation();
 
-                                     return false;
 
-                                 }
 
-                             }
 
-                         });
 
-                     }
 
-                     this.$nextTick(() => this.editFile(toolName, files[0]));
 
-                 });
 
-             }
 
-         },
 
-         editFile(toolName, fileName) {
 
-             let editorMode = {
 
-                 css: 'text/css',
 
-                 js: {name: 'javascript', json: true},
 
-                 html: 'htmlmixed'
 
-             };
 
-             let mode = editorMode[/\.(js|css|html)$/.exec(fileName)[1]];
 
-             editor.setOption('mode', mode);
 
-             this.model.editingFile = fileName;
 
-             this.getContentFromLocal(toolName, fileName).then(content => {
 
-                 editor.setValue(content);
 
-                 editor.focus();
 
-                 this.$forceUpdate();
 
-             });
 
-         },
 
-         importFile(toolName) {
 
-             let fileInput = document.createElement('input');
 
-             fileInput.type = 'file';
 
-             fileInput.multiple = 'multiple';
 
-             fileInput.accept = 'text/javascript,text/css,text/html';
 
-             fileInput.style.cssText = 'position:absolute;top:-100px;left:-100px';
 
-             fileInput.addEventListener('change', (evt) => {
 
-                 Array.prototype.slice.call(fileInput.files).forEach(file => {
 
-                     let reader = new FileReader();
 
-                     reader.onload = (evt) => {
 
-                         if (this.model.files.includes(file.name)) {
 
-                             if (!confirm(`文件 ${file.name} 已经存在,是否需要覆盖?`)) {
 
-                                 return false;
 
-                             }
 
-                         } else {
 
-                             this.model.files.push(file.name);
 
-                         }
 
-                         this.saveContentToLocal(toolName, file.name, evt.target.result);
 
-                         this.editFile(toolName, file.name);
 
-                     };
 
-                     reader.readAsText(file);
 
-                 })
 
-             }, false);
 
-             document.body.appendChild(fileInput);
 
-             fileInput.click();
 
-             window.setTimeout(() => fileInput.remove(), 3000);
 
-         },
 
-         createFile(toolName) {
 
-             let fileName = prompt('请输入你要创建的文件名!注意,只能是 *.html 、*.js 、*.css 类型的文件!').trim();
 
-             let result = /^[\w\-_\.]+\.(html|js|css)$/.exec(fileName);
 
-             if (!result) {
 
-                 return alert('文件格式不正确!创建文件失败!');
 
-             }
 
-             if (this.model.files.includes(fileName)) {
 
-                 return alert(`文件 ${fileName} 已经存在!`);
 
-             }
 
-             this.model.files.push(fileName);
 
-             this.saveContentToLocal(toolName, fileName, '');
 
-             this.editFile(toolName, fileName);
 
-         },
 
-         deleteFile(toolName, fileName, event) {
 
-             event.preventDefault();
 
-             event.stopPropagation();
 
-             if (['fh-config.js', 'index.html'].includes(fileName)) {
 
-                 return alert(`文件 ${fileName} 不允许被删除!`);
 
-             }
 
-             if (confirm(`确定要删除文件 ${fileName} 吗?此操作不可撤销,请三思!`)) {
 
-                 this.model.files.splice(this.model.files.indexOf(fileName), 1);
 
-                 this.$forceUpdate();
 
-                 let key = '';
 
-                 switch (fileName) {
 
-                     case 'index.html':
 
-                         key = TOOL_NAME_TPL.replace('#TOOL-NAME#', toolName);
 
-                         break;
 
-                     case 'content-script.js':
 
-                         key = TOOL_CONTENT_SCRIPT_TPL.replace('#TOOL-NAME#', toolName);
 
-                         break;
 
-                     case 'content-script.css':
 
-                         key = TOOL_CONTENT_SCRIPT_CSS_TPL.replace('#TOOL-NAME#', toolName);
 
-                         break;
 
-                     default:
 
-                         key = fileName.startsWith(`../${toolName}/`) ? fileName : `../${toolName}/${fileName}`;
 
-                 }
 
-                 Awesome.StorageMgr.remove(key);
 
-             }
 
-         },
 
-         addNewTool(localOrUrl) {
 
-             this.showNewToolForm = true;
 
-             this.updateUrlMode = localOrUrl === 'url';
 
-             if (this.updateUrlMode) {
 
-                 this.toast('请务必载入自己的Web工具服务!PS:请尽量别把它当成网站原内容的爬取工具,因为别人的网站你爬取过来也不一定完全能运行!');
 
-             }
 
-         },
 
-         newToolAction(event) {
 
-             let toolId = this.$refs.toolId.value;
 
-             let toolName = this.$refs.toolName.value;
 
-             let toolIcon = this.$refs.toolIcon.value;
 
-             let contentScript = this.$refs.hasContentScript.checked;
 
-             let noPage = this.$refs.noPage.checked;
 
-             let updateUrl = '';
 
-             if (this.updateUrlMode) {
 
-                 updateUrl = this.$refs.updateUrl.value;
 
-                 if (updateUrl.indexOf('baidufe.com') > -1 || updateUrl.indexOf('fehelper.com') > -1) {
 
-                     return this.toast('如果你是要安装FeHelper官网的工具,请到插件配置页直接安装!');
 
-                 }
 
-             }
 
-             if (this.myTools[toolId]) {
 
-                 this.toast(`ID为 ${toolId} 的工具在本地已存在,请重新命名!`);
 
-                 event.preventDefault();
 
-                 return false;
 
-             }
 
-             // 关闭Form表单
 
-             this.showNewToolForm = false;
 
-             // 创建文件列表
 
-             let files = ['fh-config.js'];
 
-             (contentScript || noPage) && files.push('content-script.js');
 
-             // 本地创建的模式,需要用模板来初始化
 
-             if (!this.updateUrlMode) {
 
-                 files.push('index.html');
 
-                 if (!noPage) {
 
-                     files.push('index.css');
 
-                     files.push('index.js');
 
-                 }
 
-             }
 
-             // 初始化的文件内容,需要进行存储
 
-             files.forEach(file => {
 
-                 let content = FileTpl[file].replace(/#toolName#/gm, toolId)
 
-                     .replace(/#toolFullName#/gm, toolName)
 
-                     .replace(/#toolIcon#/gm, toolIcon)
 
-                     .replace(/#updateUrl#/gm, updateUrl)
 
-                     .replace(/#contentScript#/gm, !!contentScript || !!noPage)
 
-                     .replace(/#noPage#/gm, !!noPage)
 
-                     .replace(/#toolNameLower#/gm, toolId.replace(/[\-_]/g, ''));
 
-                 if (noPage && file === 'content-script.js') {
 
-                     content += '\n\n' + FileTpl['noPage.js'].replace(/#toolName#/gm, toolId)
 
-                         .replace(/#toolNameLower#/gm, toolId.replace(/[\-_]/g, ''));
 
-                 }
 
-                 this.saveContentToLocal(toolId, file, content);
 
-             });
 
-             if (this.updateUrlMode) {
 
-                 // 远程下载并安装工具
 
-                 this.loadRemoteTool(toolId, updateUrl, this.toast).then(progress => {
 
-                     this.toast(progress);
 
-                     this.toggleEditor(true, toolId);
 
-                     this.toast('工具创建成功!现在可以进行实时编辑了!');
 
-                 });
 
-             } else {
 
-                 this.toggleEditor(true, toolId);
 
-                 this.toast('工具创建成功!现在可以进行实时编辑了!');
 
-             }
 
-             event.preventDefault();
 
-             return false;
 
-         },
 
-         loadRemoteTool(toolName, updateUrl, fnProgress) {
 
-             return new Promise((resolve, reject) => {
 
-                 fnProgress && fnProgress('开始下载...');
 
-                 fetch(updateUrl).then(resp => resp.text()).then(html => {
 
-                     let result = this.htmlTplEncode(toolName, html, updateUrl);
 
-                     html = result.html;
 
-                     let files = result.jsCss;
 
-                     // 获取所有网络文件的总个数,以便于计算进度
 
-                     let total = eval(Object.values(files).map(a => a.length).join('+')) + 1;
 
-                     let loaded = 1;
 
-                     fnProgress && fnProgress(Math.floor(100 * loaded / total) + '%');
 
-                     (async () => {
 
-                         let toolObj = this.myTools[toolName];
 
-                         for (let t in files) {
 
-                             for (let f = 0; f < files[t].length; f++) {
 
-                                 let fs = files[t][f];
 
-                                 // script-block内识别出来的代码,直接保存
 
-                                 if (t === 'js' && fs[0].indexOf('fh-script-block.js') > -1) {
 
-                                     this.saveContentToLocal(toolName, fs[0], fs[2]);
 
-                                     continue;
 
-                                 }
 
-                                 await fetch(fs[2]).then(resp => resp.text()).then(txt => {
 
-                                     this.saveContentToLocal(toolName, fs[0], txt);
 
-                                     // 保存content-script / background-script
 
-                                     if (toolObj.contentScriptJs && fs[0].indexOf(toolName + '/content-script.js') !== -1) {
 
-                                         this.saveContentToLocal(toolName, 'content-script.js', txt);
 
-                                         // 存储content-script.css文件内容
 
-                                         if (toolObj.contentScriptCss) {
 
-                                             fetch(fs[2].replace('content-script.js', 'content-script.css')).then(resp => resp.text()).then(css => {
 
-                                                 this.saveContentToLocal(toolName, 'content-script.css', css);
 
-                                             });
 
-                                         }
 
-                                     }
 
-                                     fnProgress && fnProgress(Math.floor(100 * ++loaded / total) + '%');
 
-                                 });
 
-                             }
 
-                         }
 
-                         // 全部下载完成!
 
-                         resolve && resolve('100%');
 
-                     })();
 
-                     this.saveContentToLocal(toolName, 'index.html', html);
 
-                 }).catch(e => {
 
-                     this.delToolConfigs(toolName);
 
-                     fnProgress && fnProgress(`糟糕,下载出错,工具远程安装失败!${e.toString()}`);
 
-                 });
 
-             });
 
-         },
 
-         loadDemo() {
 
-             let demoName = this.demo.name;
 
-             let files = this.demo.files;
 
-             let site = '.';
 
-             if (window.chrome && chrome.runtime && chrome.runtime.getURL) {
 
-                 site = chrome.runtime.getURL('devtools');
 
-             }
 
-             let arrPromise = files.map(file => fetch(`${site}/${demoName}/${file}`).then(resp => resp.text()));
 
-             return Promise.all(arrPromise).then(contents => {
 
-                 // fh-config.js
 
-                 let json = JSON.parse(contents[0]);
 
-                 this.addToolConfigs(json);
 
-                 // index.html
 
-                 let result = this.htmlTplEncode(demoName, contents[1]);
 
-                 this.saveContentToLocal(demoName, files[1], result.html, true);
 
-                 // 其他文件
 
-                 for (let i = 2; i < contents.length; i++) {
 
-                     this.saveContentToLocal(demoName, files[i], contents[i]);
 
-                 }
 
-                 this.toast('工具更新成功!');
 
-             });
 
-         },
 
-         downloadTool(tool) {
 
-             let toolName = tool || this.demo.name;
 
-             this.getToolFilesFromLocal(toolName).then(files => {
 
-                 let arrPromise = files.map(file => this.getContentFromLocal(toolName, file));
 
-                 Promise.all(arrPromise).then(contents => {
 
-                     let zipper = new JSZip();
 
-                     let zipPkg = zipper.folder(toolName);
 
-                     files.forEach((file, index) => zipPkg.file(file, contents[index]));
 
-                     zipper.generateAsync({type: "blob"})
 
-                         .then(function (content) {
 
-                             let elA = document.createElement('a');
 
-                             elA.style.cssText = 'position:absolute;top:-1000px;left:-10000px;';
 
-                             elA.setAttribute('download', `${toolName}.zip`);
 
-                             elA.href = URL.createObjectURL(new Blob([content], {type: 'application/octet-stream'}));
 
-                             document.body.appendChild(elA);
 
-                             elA.click();
 
-                         });
 
-                 });
 
-             });
 
-         },
 
-         downloadDemo() {
 
-             // 本地没安装过demo,就强制再更新一遍
 
-             this.getContentFromLocal(this.demo.name, 'index.html').then(content => {
 
-                 if(content) {
 
-                     this.downloadTool(this.demo.name);
 
-                 }else{
 
-                     this.loadDemo().then(() => this.downloadTool(this.demo.name));
 
-                 }
 
-             });
 
-         },
 
-         upgrade(tool, urlMode) {
 
-             if (tool === this.demo.name) {
 
-                 this.loadDemo();
 
-             } else if (urlMode) {
 
-                 // 远程下载并安装工具
 
-                 this.loadRemoteTool(tool, this.myTools[tool].updateUrl, this.toast).then(progress => {
 
-                     this.toast(progress);
 
-                     this.toast('工具更新完成!');
 
-                 });
 
-             } else {
 
-                 this.loadTool(true, tool);
 
-             }
 
-         },
 
-         loadTool(upgradeMode, upgradeToolName) {
 
-             let Model = (function () {
 
-                 zip.useWebWorkers = false;
 
-                 return {
 
-                     getEntries: function (file, onend) {
 
-                         zip.createReader(new zip.BlobReader(file), function (zipReader) {
 
-                             zipReader.getEntries(onend);
 
-                         }, function (e) {
 
-                             console.log(e);
 
-                         });
 
-                     },
 
-                     getEntryFile: function (entry, onend, onprogress) {
 
-                         entry.getData(new zip.TextWriter(), function (text) {
 
-                             onend(text);
 
-                         }, onprogress);
 
-                     }
 
-                 };
 
-             })();
 
-             let fileInput = document.createElement('input');
 
-             fileInput.type = 'file';
 
-             fileInput.accept = 'application/zip';
 
-             fileInput.style.cssText = 'position:absolute;top:-100px;left:-100px';
 
-             fileInput.addEventListener('change', (evt) => {
 
-                 let toolName = fileInput.files[0].name.replace('.zip', '');
 
-                 if (upgradeMode && upgradeToolName !== toolName) {
 
-                     return this.toast(`请确保上传${upgradeToolName}.zip进行更新!`);
 
-                 }
 
-                 Model.getEntries(fileInput.files[0], (entries) => {
 
-                     entries = entries.filter(entry => !entry.directory && /\.(html|js|css)$/.test(entry.filename));
 
-                     let reg = /(fh-config\.js|index\.html|content-script\.(js|css))$/;
 
-                     let entPart1 = entries.filter(en => reg.test(en.filename));
 
-                     let entPart2 = entries.filter(en => !reg.test(en.filename));
 
-                     entPart1.forEach((entry) => {
 
-                         Model.getEntryFile(entry, (fileContent) => {
 
-                             let fileName = entry.filename.split('/').pop();
 
-                             try {
 
-                                 if (fileName === `fh-config.js`) {
 
-                                     let json = JSON.parse(fileContent);
 
-                                     this.addToolConfigs(json);
 
-                                 } else if (fileName === 'index.html') {
 
-                                     let result = this.htmlTplEncode(toolName, fileContent);
 
-                                     this.saveContentToLocal(toolName, fileName, result.html, true);
 
-                                     // 所有被引用的静态文件都在这里进行遍历
 
-                                     entPart2.forEach(jcEntry => {
 
-                                         Model.getEntryFile(jcEntry, jcContent => {
 
-                                             Object.keys(result.jsCss).forEach(tp => {
 
-                                                 result.jsCss[tp].some(file => {
 
-                                                     if (file[0].indexOf(jcEntry.filename) > -1) {
 
-                                                         this.saveContentToLocal(toolName, file[0].replace(`../${toolName}/`, ''), jcContent);
 
-                                                         return true;
 
-                                                     }
 
-                                                 });
 
-                                             });
 
-                                         });
 
-                                     });
 
-                                 } else if (['content-script.js', 'content-script.css'].includes(fileName)) {
 
-                                     this.saveContentToLocal(toolName, fileName, fileContent);
 
-                                 }
 
-                             } catch (err) {
 
-                                 this.toast(`${fileName} 文件发生错误:${err.message}`);
 
-                             }
 
-                         });
 
-                     });
 
-                     this.toast('工具更新成功!');
 
-                 });
 
-             }, false);
 
-             document.body.appendChild(fileInput);
 
-             fileInput.click();
 
-             window.setTimeout(() => fileInput.remove(), 3000);
 
-         },
 
-         getToolConfigs() {
 
-             return Awesome.StorageMgr.get(DEV_TOOLS_MY_TOOLS).then(data => {
 
-                 this.myTools = JSON.parse(data || localStorage.getItem(DEV_TOOLS_MY_TOOLS) || '{}');
 
-                 Object.keys(this.myTools).forEach(t => {
 
-                     if(this.myTools[t].menuConfig) {
 
-                         this.myTools.icon = this.myTools[t].menuConfig[0].icon;
 
-                         delete this.myTools[t].menuConfig;
 
-                     }
 
-                     if(this.myTools[t].contentScript) {
 
-                         this.myTools[t].contentScriptJs = this.myTools[t].contentScript;
 
-                         delete this.myTools[t].contentScript;
 
-                     }
 
-                     if(!this.myTools[t].icon) {
 
-                         this.myTools[t].icon = '◆';
 
-                     }
 
-                 });
 
-                 this.setToolConfigs();
 
-             });
 
-         },
 
-         setToolConfigs() {
 
-             Awesome.StorageMgr.set(DEV_TOOLS_MY_TOOLS,JSON.stringify(this.myTools));
 
-         },
 
-         addToolConfigs(configs) {
 
-             this.getToolConfigs().then(() => {
 
-                 Object.keys(configs).forEach(key => {
 
-                     let config = configs[key];
 
-                     this.myTools[key] = {
 
-                         _devTool: true,
 
-                         _enable: this.myTools[key] && this.myTools[key]._enable,
 
-                         name: config.name,
 
-                         tips: config.tips,
 
-                         icon: config.icon,
 
-                         noPage: !!config.noPage,
 
-                         contentScriptJs: !!config.contentScriptJs || !!config.contentScript,
 
-                         contentScriptCss: !!config.contentScriptCss,
 
-                         updateUrl: config.updateUrl || null
 
-                     }
 
-                 });
 
-                 this.setToolConfigs();
 
-             });
 
-         },
 
-         delToolConfigs(tools) {
 
-             // 先删除文件
 
-             [].concat(tools).forEach(tool => {
 
-                 this.getToolFilesFromLocal(tool).then(files => {
 
-                     Awesome.StorageMgr.remove(files.map(file =>
 
-                         file.startsWith(`../${tool}`) ? file : `../${tool}/${file}` ));
 
-                 });
 
-                 // 删模板等
 
-                 let removeItems = [
 
-                     TOOL_NAME_TPL.replace('#TOOL-NAME#', tool),
 
-                     TOOL_CONTENT_SCRIPT_TPL.replace('#TOOL-NAME#', tool),
 
-                     TOOL_CONTENT_SCRIPT_CSS_TPL.replace('#TOOL-NAME#', tool)
 
-                 ];
 
-                 Awesome.StorageMgr.remove(removeItems);
 
-             });
 
-             // 再删配置
 
-             [].concat(tools).forEach(tool => {
 
-                 delete this.myTools[tool];
 
-             });
 
-             this.setToolConfigs();
 
-             this.$forceUpdate();
 
-             this.toast('工具删除成功!');
 
-         },
 
-         toggleToolEnableStatus(tool) {
 
-             this.myTools[tool]._enable = !this.myTools[tool]._enable;
 
-             this.setToolConfigs();
 
-             this.$forceUpdate();
 
-         },
 
-         getToolFilesFromLocal(toolName) {
 
-             return new Promise(resolve => {
 
-                 let files = ['fh-config.js', 'index.html'];
 
-                 let toolObj = this.myTools[toolName];
 
-                 toolObj.contentScriptJs && files.push('content-script.js');
 
-                 toolObj.contentScriptCss && files.push('content-script.css');
 
-                 chrome.storage.local.get(null, allDatas => {
 
-                     let fs = Object.keys(allDatas).filter(key => String(key).startsWith(`../${toolName}/`));
 
-                     files = files.concat(fs);
 
-                     resolve(files.map(f => f.replace(`../${toolName}/`, '')));
 
-                 });
 
-             });
 
-         },
 
-         saveContentToLocal(toolName, fileName, content, htmlDone) {
 
-             if (fileName === 'fh-config.js') {
 
-                 try {
 
-                     let json = JSON.parse(content);
 
-                     this.addToolConfigs(json);
 
-                     this.$forceUpdate();
 
-                     return json[toolName];
 
-                 } catch (e) {
 
-                     return null;
 
-                 }
 
-             }
 
-             let key = '';
 
-             switch (fileName) {
 
-                 case 'index.html':
 
-                     key = TOOL_NAME_TPL.replace('#TOOL-NAME#', toolName);
 
-                     if (!htmlDone) {
 
-                         let result = this.htmlTplEncode(toolName, content);
 
-                         content = result.html;
 
-                     }
 
-                     break;
 
-                 case 'content-script.js':
 
-                     key = TOOL_CONTENT_SCRIPT_TPL.replace('#TOOL-NAME#', toolName);
 
-                     break;
 
-                 case 'content-script.css':
 
-                     key = TOOL_CONTENT_SCRIPT_CSS_TPL.replace('#TOOL-NAME#', toolName);
 
-                     break;
 
-                 default:
 
-                     key = fileName.startsWith(`../${toolName}/`) ? fileName : `../${toolName}/${fileName}`;
 
-             }
 
-             Awesome.StorageMgr.set(key,content);
 
-         },
 
-         getContentFromLocal(toolName, fileName) {
 
-             return new Promise((resolve, reject) => {
 
-                 if (fileName === 'fh-config.js') {
 
-                     let counter = 0;
 
-                     let config = {};
 
-                     config[toolName] = this.myTools[toolName];
 
-                     ['_devTool', '_enable'].forEach(k => delete config[toolName][k]);
 
-                     delete config[toolName].menuConfig;
 
-                     let jsonText = JSON.stringify(config,null,4);
 
-                     resolve(jsonText);
 
-                 } else {
 
-                     let key = '';
 
-                     switch (fileName) {
 
-                         case 'index.html':
 
-                             key = TOOL_NAME_TPL.replace('#TOOL-NAME#', toolName);
 
-                             break;
 
-                         case 'content-script.js':
 
-                             key = TOOL_CONTENT_SCRIPT_TPL.replace('#TOOL-NAME#', toolName);
 
-                             break;
 
-                         case 'content-script.css':
 
-                             key = TOOL_CONTENT_SCRIPT_CSS_TPL.replace('#TOOL-NAME#', toolName);
 
-                             break;
 
-                         default:
 
-                             key = fileName.startsWith(`../${toolName}/`) ? fileName : `../${toolName}/${fileName}`;
 
-                     }
 
-                     // 获取到的数据需要做二次加工
 
-                     let _update = (content) => {
 
-                         content = content || '';
 
-                         if (fileName === 'index.html') {
 
-                             content = this.htmlTplDecode(toolName, content);
 
-                         }
 
-                         // 如果noPage为true,但content-script.js中还没有window.xxxNoPage定义的话,就自动加一个
 
-                         else if (fileName === 'content-script.js' && this.myTools[toolName].noPage) {
 
-                             if (content.indexOf(`window.${toolName.replace(/[\-_]/g, '')}NoPage`) === -1) {
 
-                                 content += '\n\n' + FileTpl['noPage.js'].replace(/#toolName#/gm, toolName)
 
-                                     .replace(/#toolNameLower#/gm, toolName.replace(/[\-_]/g, ''));
 
-                                 this.saveContentToLocal(toolName, fileName, content);
 
-                             }
 
-                         }
 
-                         return content
 
-                     };
 
-                     Awesome.StorageMgr.get(key).then(data => {
 
-                         resolve(_update(data));
 
-                     });
 
-                 }
 
-             });
 
-         },
 
-         htmlTplEncode(toolName, html, updateUrl) {
 
-             let jsReg = /<script[^>]*src=['"]([^'"]+)['"][^>]*>\s*?<\/[^>]*script>/igm;
 
-             let csReg = /<link\s+[^>]*[^>]*href=['"]([^'"]+)['"][^>]*[^>]*>/igm;
 
-             let scriptBlockReg = /<script(?:[^>]+|(?!src=))*>([^<]+|<(?!\/script>))+<\/script>/gim;
 
-             let files = {};
 
-             [csReg, jsReg].forEach(reg => {
 
-                 html = html.replace(reg, (tag, src) => {
 
-                     let tagName = /<script/.test(tag) ? 'js' : 'css';
 
-                     if (tagName === 'css' && !/stylesheet/i.test(tag)) {
 
-                         return tag;
 
-                     }
 
-                     // 这里必须保留带有md5戳的原地址,要不然会有cdn缓存,更新会失败
 
-                     let originSrc = src;
 
-                     // 这个src是携带了Query的,用于直接存储到html中
 
-                     let withQuerySrc = src;
 
-                     // src 去query处理,用于Storage存储,避免过多冗余key出现
 
-                     if (src.indexOf('?') !== -1) {
 
-                         let x = src.split('?');
 
-                         x.pop();
 
-                         src = x.join('');
 
-                     }
 
-                     if (!/^\./.test(src)) {
 
-                         src = `../${toolName}/${src}`;
 
-                         withQuerySrc = `../${toolName}/${withQuerySrc}`;
 
-                     }
 
-                     // 存储静态文件的内容
 
-                     let filePath = originSrc;
 
-                     if (!/^(http(s)?:)?\/\//.test(originSrc) && updateUrl) {
 
-                         filePath = new URL(originSrc, updateUrl).href;
 
-                     }
 
-                     files[tagName] = files[tagName] || [];
 
-                     files[tagName].push([src, withQuerySrc, filePath]);
 
-                     return '';
 
-                 });
 
-             });
 
-             // 识别所有无src属性的script标签
 
-             let blockCodes = [];
 
-             html = html.replace(scriptBlockReg, (tag, codes) => {
 
-                 codes = codes.trim();
 
-                 codes.length && blockCodes.push(codes);
 
-                 return '';
 
-             });
 
-             if (blockCodes.length) {
 
-                 let blockName = `../${toolName}/fh-script-block.js`;
 
-                 files.js = files.js || [];
 
-                 files.js.push([blockName, blockName, blockCodes.join(';\n\n')]);
 
-             }
 
-             // 如果是updateURL模式,需要替换所有相对链接为绝对链接,包括:img、a
 
-             if (updateUrl) {
 
-                 let relativePathRegexp = /^(http:\/\/|https:\/\/|\/\/)[^\s'"]+/igm;
 
-                 let imgReg = /<img[^>]*src=['"]([^'"]+)['"][^>]*>(\s*?<\/[^>]*img>)?/igm;
 
-                 let aReg = /<a[^>]*href=['"]([^'"]+)['"][^>]*>(\s*?<\/[^>]*a>)?/igm;
 
-                 html = html.replace(imgReg, (tag, link) => {
 
-                     if (!relativePathRegexp.test(link)) {
 
-                         tag = tag.replace(/src=['"]([^'"]+)['"]/igm, () => ` src="${new URL(link, updateUrl).href}"`);
 
-                     }
 
-                     return tag;
 
-                 }).replace(aReg, (tag, link) => {
 
-                     if (!relativePathRegexp.test(link)) {
 
-                         tag = tag.replace(/href=['"]([^'"]+)['"]/igm, () => ` href="${new URL(link, updateUrl).href}"`);
 
-                     }
 
-                     return tag;
 
-                 });
 
-             }
 
-             html = html.replace('static/img/favicon.ico', 'static/img/fe-16.png')  // 替换favicon
 
-                 .replace(/<\/body>/, () => { // 将静态文件添加到页面最底部
 
-                     return Object.keys(files).map(t => {
 
-                         return `<dynamic data-type="${t}" data-source="${files[t].map(f => f[1]).join(',')}"></dynamic>`;
 
-                     }).join('') + '</body>';
 
-                 });
 
-             return {
 
-                 html: html,
 
-                 jsCss: files
 
-             };
 
-         },
 
-         htmlTplDecode(toolName, html) {
 
-             let reg = /<dynamic\s+data\-type="(js|css)"\s+data\-source=['"]([^'"]+)['"][^>]*>\s*?<\/[^>]*dynamic>/igm;
 
-             return html.replace(reg, (frag, tag, list) => {
 
-                 list = list.split(',');
 
-                 if (tag === 'js') {
 
-                     return list.map(src => `<script src="${src.replace(`../${toolName}/`, '')}"></script>`).join('');
 
-                 } else {
 
-                     return list.map(href => `<link rel="stylesheet" type="text/css" href="${href.replace(`../${toolName}/`, '')}" />`).join('');
 
-                 }
 
-             });
 
-         },
 
-         givenIcons(forceClose) {
 
-             if (!this.givenIconList.length) {
 
-                 this.givenIconList = FileTpl['given-icons'].replace(/\s/gm, '').split('');
 
-             }
 
-             if (forceClose) {
 
-                 this.showGivenIcons = false;
 
-             } else {
 
-                 this.showGivenIcons = !this.showGivenIcons;
 
-             }
 
-             this.$forceUpdate();
 
-         },
 
-         selectIcon(icon) {
 
-             if (this.showNewToolForm) {
 
-                 this.$refs.toolIcon.value = icon;
 
-                 this.givenIcons(true);
 
-             } else {
 
-                 this.copyToClipboard(icon);
 
-                 this.toast(`图标 ${icon} 复制成功,随处粘贴可用!`);
 
-             }
 
-         },
 
-         toast(content) {
 
-             window.clearTimeout(window.feHelperAlertMsgTid);
 
-             let elAlertMsg = document.querySelector("#fehelper_alertmsg");
 
-             if (!elAlertMsg) {
 
-                 let elWrapper = document.createElement('div');
 
-                 elWrapper.innerHTML = '<div id="fehelper_alertmsg">' + content + '</div>';
 
-                 elAlertMsg = elWrapper.childNodes[0];
 
-                 document.body.appendChild(elAlertMsg);
 
-             } else {
 
-                 elAlertMsg.innerHTML = content;
 
-                 elAlertMsg.style.display = 'block';
 
-             }
 
-             window.feHelperAlertMsgTid = window.setTimeout(function () {
 
-                 elAlertMsg.style.display = 'none';
 
-             }, 3000);
 
-         },
 
-         copyToClipboard(text) {
 
-             let input = document.createElement('textarea');
 
-             input.style.position = 'fixed';
 
-             input.style.opacity = 0;
 
-             input.value = text;
 
-             document.body.appendChild(input);
 
-             input.select();
 
-             document.execCommand('Copy');
 
-             document.body.removeChild(input);
 
-         },
 
-         fhDeveloperDoc() {
 
-             window.open(`https://github.com/zxlie/FeHelper/blob/master/README_NEW.md#%E5%85%ADopen-api`);
 
-         }
 
-     }
 
- });
 
 
  |