index.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /**
  2. * FE-Helper后台运行程序
  3. * @author zhaoxianlie
  4. */
  5. var BgPageInstance = (function () {
  6. let MSG_TYPE = Tarp.require('../static/js/msg_type');
  7. let Settings = Tarp.require('../options/settings');
  8. let Network = Tarp.require('../background/network');
  9. let PageCapture = Tarp.require('../page-capture/capture-api')(MSG_TYPE);
  10. let feHelper = {
  11. codeStandardMgr: {},
  12. ajaxDebuggerMgr: {},
  13. csDetectIntervals: [],
  14. manifest: chrome.runtime.getManifest(),
  15. notifyTimeoutId: -1
  16. };
  17. let devToolsDetected = false;
  18. //侦测就绪情况
  19. let _detectReadyState = function (getType, callback) {
  20. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  21. let tabId = tabs[0].id;
  22. feHelper.codeStandardMgr[tabId][getType] = true;
  23. if (feHelper.codeStandardMgr[tabId].css && feHelper.codeStandardMgr[tabId].js) {
  24. feHelper.codeStandardMgr[tabId].allDone = true;
  25. }
  26. if (feHelper.codeStandardMgr[tabId].allDone && typeof callback === 'function') {
  27. callback();
  28. }
  29. });
  30. };
  31. /**
  32. * 执行前端FCPHelper检测
  33. */
  34. let _doFcpDetect = function (tab) {
  35. feHelper.codeStandardMgr[tab.id] = feHelper.codeStandardMgr[tab.id] || {};
  36. //所有元素都准备就绪
  37. if (feHelper.codeStandardMgr[tab.id].allDone) {
  38. clearInterval(feHelper.csDetectIntervals[tab.id]);
  39. chrome.tabs.sendMessage(tab.id, {
  40. type: MSG_TYPE.CODE_STANDARDS,
  41. event: MSG_TYPE.FCP_HELPER_DETECT
  42. });
  43. } else if (feHelper.csDetectIntervals[tab.id] === undefined) {
  44. chrome.tabs.sendMessage(tab.id, {
  45. type: MSG_TYPE.CODE_STANDARDS,
  46. event: MSG_TYPE.FCP_HELPER_INIT
  47. });
  48. //显示桌面提醒
  49. notifyText({
  50. message: "正在准备数据,请稍等..."
  51. });
  52. feHelper.csDetectIntervals[tab.id] = setInterval(function () {
  53. _doFcpDetect(tab);
  54. }, 200);
  55. }
  56. };
  57. /**
  58. * 文本格式,可以设置一个图标和标题
  59. * @param {Object} options
  60. * @config {string} type notification的类型,可选值:html、text
  61. * @config {string} icon 图标
  62. * @config {string} title 标题
  63. * @config {string} message 内容
  64. */
  65. let notifyText = function (options) {
  66. let notifyId = 'fehleper-notify-id';
  67. clearTimeout(feHelper.notifyTimeoutId);
  68. if (options.closeImmediately) {
  69. return chrome.notifications.clear(notifyId);
  70. }
  71. if (!options.icon) {
  72. options.icon = "static/img/fe-48.png";
  73. }
  74. if (!options.title) {
  75. options.title = "温馨提示";
  76. }
  77. chrome.notifications.create(notifyId, {
  78. type: 'basic',
  79. title: options.title,
  80. iconUrl: chrome.runtime.getURL(options.icon),
  81. message: options.message
  82. });
  83. feHelper.notifyTimeoutId = setTimeout(() => {
  84. chrome.notifications.clear(notifyId);
  85. }, parseInt(options.autoClose || 3000, 10));
  86. };
  87. /**
  88. * 查看页面wpo信息
  89. */
  90. let _showPageWpoInfo = function (wpoInfo) {
  91. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  92. if (!wpoInfo) {
  93. notifyText({
  94. message: "对不起,检测失败"
  95. });
  96. } else {
  97. chrome.tabs.create({
  98. url: "wpo/index.html?" + btoa(encodeURIComponent(JSON.stringify(wpoInfo))),
  99. active: true
  100. });
  101. }
  102. });
  103. };
  104. /**
  105. * 获取页面wpo信息
  106. * @return {[type]}
  107. */
  108. let _getPageWpoInfo = function () {
  109. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  110. let tab = tabs[0];
  111. //显示桌面提醒
  112. chrome.tabs.sendMessage(tab.id, {
  113. type: MSG_TYPE.GET_PAGE_WPO_INFO
  114. });
  115. });
  116. };
  117. /**
  118. * 创建或更新成功执行的动作
  119. * @param evt
  120. * @param content
  121. * @private
  122. */
  123. let _tabUpdatedCallback = function (evt, content) {
  124. return function (newTab) {
  125. if (content) {
  126. setTimeout(function () {
  127. chrome.tabs.sendMessage(newTab.id, {
  128. type: MSG_TYPE.TAB_CREATED_OR_UPDATED,
  129. content: content,
  130. event: evt
  131. });
  132. }, 300)
  133. }
  134. };
  135. };
  136. /**
  137. * 打开对应文件,运行该Helper
  138. * @param tab
  139. * @param file
  140. * @param txt
  141. * @private
  142. */
  143. let _openFileAndRun = function (tab, file, txt) {
  144. chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, function (tabs) {
  145. Settings.getOptsFromBgPage((opts) => {
  146. let isOpened = false;
  147. let tabId;
  148. // 允许在新窗口打开
  149. if (opts['FORBID_OPEN_IN_NEW_TAB']) {
  150. let reg = new RegExp("^chrome.*/" + file + "/index.html$", "i");
  151. for (let i = 0, len = tabs.length; i < len; i++) {
  152. if (reg.test(tabs[i].url)) {
  153. isOpened = true;
  154. tabId = tabs[i].id;
  155. break;
  156. }
  157. }
  158. }
  159. if (!isOpened) {
  160. chrome.tabs.create({
  161. url: '' + file + '/index.html',
  162. active: true
  163. }, _tabUpdatedCallback(file, txt));
  164. } else {
  165. chrome.tabs.update(tabId, {highlighted: true}, _tabUpdatedCallback(file, txt));
  166. }
  167. });
  168. });
  169. };
  170. /**
  171. * ajax debugger 开关切换
  172. * @private
  173. */
  174. let _debuggerSwitchOn = function (callback) {
  175. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  176. let tab = tabs[0];
  177. feHelper.ajaxDebuggerMgr[tab.id] = !feHelper.ajaxDebuggerMgr[tab.id];
  178. chrome.tabs.executeScript(tab.id, {
  179. code: 'console.info("FeHelper提醒:Ajax Debugger开关已' + (feHelper.ajaxDebuggerMgr[tab.id] ? '开启' : '关闭') + '!");',
  180. allFrames: false
  181. });
  182. callback && callback();
  183. });
  184. };
  185. /**
  186. * 告诉DevTools页面,当前的debug开关是否打开
  187. * @param callback
  188. * @param withAlert
  189. * @private
  190. */
  191. let _tellDevToolsDbgSwitchOn = function (callback, withAlert) {
  192. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  193. let tab = tabs[0];
  194. callback && callback(feHelper.ajaxDebuggerMgr[tab.id]);
  195. if (withAlert) {
  196. let msg = '';
  197. if (feHelper.ajaxDebuggerMgr[tab.id]) {
  198. if (devToolsDetected) {
  199. msg = 'DevTools已打开,确保已切换到【Console】界面,并关注信息输出,愉快的进行Ajax Debugger!'
  200. } else {
  201. msg = '请打开DevTools,并切换到【Console】界面,关注信息输出,愉快的进行Ajax Debugger!';
  202. }
  203. } else {
  204. msg = '已停止当前页面的Ajax Debugger功能!';
  205. }
  206. alert(msg);
  207. }
  208. });
  209. };
  210. /**
  211. * 根据给定参数,运行对应的Helper
  212. */
  213. let _runHelper = function (config, callback) {
  214. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  215. let tab = tabs[0];
  216. // 如果是采用独立文件方式访问,直接打开该页面即可
  217. if (config.useFile === 1) {
  218. let content = config.msgType === MSG_TYPE.QR_CODE ? tab.url : '';
  219. _openFileAndRun(tab, config.msgType, content);
  220. } else {
  221. switch (config.msgType) {
  222. //编码规范检测
  223. case MSG_TYPE.FCP_HELPER_DETECT:
  224. _doFcpDetect(tab);
  225. break;
  226. //将当前网页转为图片
  227. case MSG_TYPE.PAGE_CAPTURE:
  228. PageCapture.full(tab);
  229. break;
  230. //查看网页加载时间
  231. case MSG_TYPE.SHOW_PAGE_LOAD_TIME:
  232. _getPageWpoInfo();
  233. break;
  234. //Ajax调试
  235. case MSG_TYPE.AJAX_DEBUGGER:
  236. _debuggerSwitchOn(callback);
  237. break;
  238. default :
  239. break;
  240. }
  241. }
  242. });
  243. };
  244. /**
  245. * 右键菜单创建工具
  246. * @param menuList
  247. * @private
  248. */
  249. let _contextMenuCreator = function (menuList) {
  250. let menus = Settings.getMenuOpts();
  251. menuList.forEach(m => {
  252. if (m === 'MENU_PAGE_ENCODING') {
  253. // 网页编码设置的menu
  254. PageEncoding.createMenu(feHelper.contextMenuId, menus.MENU_PAGE_ENCODING);
  255. } else {
  256. let onClick = {
  257. MENU_QRCODE_CREATE: function (info, tab) {
  258. chrome.tabs.executeScript(tab.id, {
  259. code: '(' + (function (pInfo) {
  260. let linkUrl = pInfo.linkUrl;
  261. let pageUrl = pInfo.pageUrl;
  262. let imgUrl = pInfo.srcUrl;
  263. let selection = pInfo.selectionText;
  264. return linkUrl || imgUrl || selection || pageUrl;
  265. }).toString() + ')(' + JSON.stringify(info) + ')',
  266. allFrames: false
  267. }, function (txt) {
  268. _openFileAndRun(tab, MSG_TYPE.QR_CODE, (typeof txt === 'object') ? txt[0] : txt);
  269. });
  270. },
  271. MENU_QRCODE_DECODE: function (info, tab) {
  272. _qrDecode(info, tab);
  273. },
  274. MENU_PAGE_CAPTURE: function (info, tab) {
  275. PageCapture.full(tab);
  276. },
  277. MENU_COLOR_PICKER: function (info, tab) {
  278. _showColorPicker();
  279. },
  280. MENU_STR_ENDECODE: function (info, tab) {
  281. chrome.tabs.executeScript(tab.id, {
  282. code: '(' + (function (pInfo) {
  283. return pInfo.selectionText;
  284. }).toString() + ')(' + JSON.stringify(info) + ')',
  285. allFrames: false
  286. }, function (txt) {
  287. _openFileAndRun(tab, MSG_TYPE.EN_DECODE, (typeof txt === 'object') ? txt[0] : txt);
  288. });
  289. },
  290. MENU_JSON_FORMAT: function (info, tab) {
  291. chrome.tabs.executeScript(tab.id, {
  292. code: '(' + (function (pInfo) {
  293. return pInfo.selectionText;
  294. }).toString() + ')(' + JSON.stringify(info) + ')',
  295. allFrames: false
  296. }, function (txt) {
  297. _openFileAndRun(tab, MSG_TYPE.JSON_FORMAT, (typeof txt === 'object') ? txt[0] : txt);
  298. });
  299. },
  300. MENU_CODE_FORMAT: function (info, tab) {
  301. chrome.tabs.executeScript(tab.id, {
  302. code: '(' + (function (pInfo) {
  303. return pInfo.selectionText;
  304. }).toString() + ')(' + JSON.stringify(info) + ')',
  305. allFrames: false
  306. }, function (txt) {
  307. _openFileAndRun(tab, MSG_TYPE.CODE_BEAUTIFY, (typeof txt === 'object') ? txt[0] : txt);
  308. });
  309. },
  310. MENU_AJAX_DEBUGGER: function (info, tab) {
  311. _debuggerSwitchOn(() => {
  312. _tellDevToolsDbgSwitchOn(null, true);
  313. });
  314. },
  315. MENU_CODE_STANDARD: function (info, tab) {
  316. _doFcpDetect(tab);
  317. },
  318. MENU_IMAGE_BASE64: function (info, tab) {
  319. _openFileAndRun(tab, MSG_TYPE.IMAGE_BASE64, info.srcUrl);
  320. },
  321. MENU_JSON_COMPARE: function (info, tab) {
  322. _openFileAndRun(tab, MSG_TYPE.JSON_COMPARE);
  323. },
  324. MENU_CODE_COMPRESS: function (info, tab) {
  325. _openFileAndRun(tab, MSG_TYPE.CODE_COMPRESS);
  326. },
  327. MENU_PAGE_OPTIMI: function (info, tab) {
  328. _openFileAndRun(tab, MSG_TYPE.SHOW_PAGE_LOAD_TIME);
  329. },
  330. MENU_TIME_STAMP: function (info, tab) {
  331. _openFileAndRun(tab, MSG_TYPE.TIME_STAMP);
  332. },
  333. MENU_RANDOM_PASS: function (info, tab) {
  334. _openFileAndRun(tab, MSG_TYPE.RANDOM_PASSWORD);
  335. },
  336. MENU_JS_REGEXP: function (info, tab) {
  337. _openFileAndRun(tab, MSG_TYPE.REGEXP_TOOL);
  338. },
  339. MENU_MARKDOWN_TL: function (info, tab) {
  340. _openFileAndRun(tab, MSG_TYPE.HTML_TO_MARKDOWN);
  341. },
  342. MENU_STICKY_NOTE: function (info, tab) {
  343. _openFileAndRun(tab, MSG_TYPE.STICKY_NOTES);
  344. }
  345. };
  346. chrome.contextMenus.create({
  347. title: menus[m].icon + ' ' + menus[m].text,
  348. contexts: menus[m].contexts || ['all'],
  349. parentId: feHelper.contextMenuId,
  350. onclick: onClick[m]
  351. });
  352. }
  353. });
  354. };
  355. /**
  356. * 创建扩展专属的右键菜单
  357. */
  358. let _createContextMenu = function () {
  359. _removeContextMenu();
  360. feHelper.contextMenuId = chrome.contextMenus.create({
  361. title: "FeHelper工具",
  362. contexts: ['page', 'selection', 'editable', 'link', 'image'],
  363. documentUrlPatterns: ['http://*/*', 'https://*/*', 'file://*/*']
  364. });
  365. if (!Settings.didMenuSettingSaved()) {
  366. _contextMenuCreator(Settings.getDefaultContextMenus());
  367. } else {
  368. Settings.getOptsFromBgPage((opts) => {
  369. _contextMenuCreator(Object.keys(opts).filter(m => /^MENU_/.test(m)));
  370. });
  371. }
  372. };
  373. /**
  374. * 移除扩展专属的右键菜单
  375. */
  376. let _removeContextMenu = function () {
  377. if (!feHelper.contextMenuId) return;
  378. chrome.contextMenus.remove(feHelper.contextMenuId);
  379. feHelper.contextMenuId = null;
  380. };
  381. /**
  382. * 创建或移除扩展专属的右键菜单
  383. */
  384. let _createOrRemoveContextMenu = function () {
  385. Settings.getOptsFromBgPage((opts) => {
  386. if (opts['opt_item_contextMenus']) {
  387. _createContextMenu();
  388. } else {
  389. _removeContextMenu();
  390. }
  391. });
  392. };
  393. /**
  394. * 二维码转码
  395. * @param info
  396. * @param tab
  397. * @private
  398. */
  399. let _qrDecode = function (info, tab) {
  400. let qrcode = Tarp.require('../static/vendor/zxing/zxing.min.js');
  401. qrcode.callback = function (text) {
  402. if ((text || '').indexOf('error decoding QR Code') !== -1) {
  403. let image = new Image();
  404. image.src = info.srcUrl;
  405. image.onload = function () {
  406. let width = this.naturalWidth;
  407. let height = this.naturalHeight;
  408. // url方式解码失败,再转换成data uri后继续解码
  409. (function createCanvasContext(img, t, l, w, h) {
  410. let canvas = document.createElement('canvas');
  411. canvas.setAttribute('id', 'qr-canvas');
  412. canvas.height = h + 100;
  413. canvas.width = w + 100;
  414. let context = canvas.getContext('2d');
  415. context.fillStyle = 'rgb(255,255,255)';
  416. context.fillRect(0, 0, canvas.width, canvas.height);
  417. context.drawImage(img, l, t, w, h, 50, 50, w, h);
  418. qrcode.callback = function (txt) {
  419. chrome.tabs.sendMessage(tab.id, {
  420. type: MSG_TYPE.QR_DECODE,
  421. result: txt
  422. });
  423. };
  424. qrcode.decode(canvas.toDataURL());
  425. })(image, 0, 0, width, height);
  426. }
  427. } else {
  428. chrome.tabs.sendMessage(tab.id, {
  429. type: MSG_TYPE.QR_DECODE,
  430. result: text
  431. });
  432. }
  433. };
  434. qrcode.decode(info.srcUrl);
  435. };
  436. /**
  437. * 显示color picker
  438. * @private
  439. */
  440. let _showColorPicker = function () {
  441. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  442. let tab = tabs[0];
  443. let tabid = tab.id;
  444. chrome.tabs.sendMessage(tabid, {
  445. type: MSG_TYPE.SHOW_COLOR_PICKER,
  446. enableColorPicker: true
  447. }, function (response) {
  448. chrome.tabs.sendMessage(tabid, {
  449. type: MSG_TYPE.SHOW_COLOR_PICKER,
  450. doPick: true
  451. }, function (r) {
  452. });
  453. });
  454. });
  455. };
  456. /**
  457. * 将网页截成一张图,实现取色
  458. * @param callback
  459. * @private
  460. */
  461. let _drawColorPicker = function (callback) {
  462. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  463. let tab = tabs[0];
  464. let tabid = tab.id;
  465. chrome.tabs.captureVisibleTab(null, {format: 'png'}, function (dataUrl) {
  466. chrome.tabs.sendMessage(tabid, {
  467. type: MSG_TYPE.SHOW_COLOR_PICKER,
  468. setPickerImage: true,
  469. pickerImage: dataUrl
  470. }, function (response) {
  471. callback && callback();
  472. });
  473. });
  474. });
  475. };
  476. /**
  477. * 在当前页面的控制台输出console
  478. * @param request
  479. * @private
  480. */
  481. let _ajaxDebugger = function (request) {
  482. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  483. let tab = tabs[0];
  484. chrome.tabs.executeScript(tab.id, {
  485. code: "(" + (function (jsonStr) {
  486. let args = JSON.parse(unescape(jsonStr));
  487. console[args[0]].apply(console, Array.prototype.slice.call(args, 1));
  488. }).toString() + ")('" + request.content + "');"
  489. });
  490. });
  491. };
  492. //判断是否可以针对json页面进行自动格式化
  493. let _jsonAutoFormatRequest = function () {
  494. Settings.getOptsFromBgPage(opts => {
  495. opts.JSON_PAGE_FORMAT && chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  496. chrome.tabs.sendMessage(tabs[0].id, {
  497. type: MSG_TYPE.JSON_PAGE_FORMAT,
  498. options: {
  499. MAX_JSON_KEYS_NUMBER: opts.MAX_JSON_KEYS_NUMBER,
  500. AUTO_TEXT_DECODE: opts.AUTO_TEXT_DECODE === 'true'
  501. }
  502. });
  503. });
  504. });
  505. };
  506. //判断是否可以针对js、css自动检测格式化
  507. let _jsCssAutoDetectRequest = function () {
  508. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  509. let tab = tabs[0];
  510. chrome.tabs.executeScript(tab.id, {
  511. code: '(' + (() => {
  512. let ext = location.pathname.substring(location.pathname.lastIndexOf(".") + 1).toLowerCase();
  513. let fileType = ({'js': 'javascript', 'css': 'css'})[ext];
  514. let contentType = document.contentType.toLowerCase();
  515. if (!fileType) {
  516. if (/\/javascript$/.test(contentType)) {
  517. fileType = 'javascript';
  518. } else if (/\/css$/.test(contentType)) {
  519. fileType = 'css';
  520. }
  521. } else if (contentType === 'text/html') {
  522. fileType = undefined;
  523. }
  524. return fileType;
  525. }).toString() + ')()'
  526. }, function (fileType) {
  527. if (fileType[0] === 'javascript' || fileType[0] === 'css') {
  528. Settings.getOptsFromBgPage(opts => {
  529. opts.JS_CSS_PAGE_BEAUTIFY && chrome.tabs.sendMessage(tab.id, {
  530. type: MSG_TYPE.JS_CSS_PAGE_BEAUTIFY,
  531. content: fileType[0]
  532. });
  533. });
  534. }
  535. });
  536. });
  537. };
  538. /**
  539. * 接收来自content_scripts发来的消息
  540. */
  541. let _addExtensionListener = function () {
  542. chrome.runtime.onMessage.addListener(function (request, sender, callback) {
  543. //提取配置项
  544. if (request.type === MSG_TYPE.GET_OPTIONS) {
  545. Settings.getOptsFromBgPage(callback);
  546. }
  547. //保存配置项
  548. else if (request.type === MSG_TYPE.SET_OPTIONS) {
  549. Settings.setOptsFromBgPage(request.items);
  550. //管理右键菜单
  551. _createOrRemoveContextMenu();
  552. notifyText({
  553. message: '配置已生效,请继续使用!',
  554. autoClose: 2000
  555. });
  556. }
  557. // 判断菜单是否保存过
  558. else if(request.type === MSG_TYPE.MENU_SAVED){
  559. Settings.didMenuSettingSaved(callback);
  560. }
  561. //判断是否可以针对json页面进行自动格式化
  562. else if (request.type === MSG_TYPE.JSON_PAGE_FORMAT_REQUEST) {
  563. _jsonAutoFormatRequest();
  564. }
  565. //判断是否可以针对js、css自动检测格式化
  566. else if (request.type === MSG_TYPE.JS_CSS_PAGE_BEAUTIFY_REQUEST) {
  567. _jsCssAutoDetectRequest();
  568. }
  569. //保存当前网页加载时间
  570. else if (request.type === MSG_TYPE.CALC_PAGE_LOAD_TIME) {
  571. _showPageWpoInfo(request.wpo);
  572. }
  573. // color picker
  574. else if (request.type === MSG_TYPE.COLOR_PICKER) {
  575. _drawColorPicker(callback);
  576. }
  577. // console switch
  578. else if (request.type === MSG_TYPE.AJAX_DEBUGGER_SWITCH) {
  579. _tellDevToolsDbgSwitchOn(callback);
  580. }
  581. // console show
  582. else if (request.type === MSG_TYPE.AJAX_DEBUGGER_CONSOLE) {
  583. _ajaxDebugger(request);
  584. }
  585. // 打开设置页
  586. else if (request.type === MSG_TYPE.OPEN_OPTIONS_PAGE) {
  587. chrome.runtime.openOptionsPage();
  588. }
  589. // ===========================以下为编码规范检测====start==================================
  590. //处理CSS的请求
  591. else if (request.type === MSG_TYPE.GET_CSS) {
  592. //直接AJAX获取CSS文件内容
  593. Network.readFileContent(request.link, callback);
  594. }
  595. //处理JS的请求
  596. else if (request.type === MSG_TYPE.GET_JS) {
  597. //直接AJAX获取JS文件内容
  598. Network.readFileContent(request.link, callback);
  599. }
  600. //处理HTML的请求
  601. else if (request.type === MSG_TYPE.GET_HTML) {
  602. //直接AJAX获取JS文件内容
  603. Network.readFileContent(request.link, callback);
  604. }
  605. //处理cookie
  606. else if (request.type === MSG_TYPE.GET_COOKIE) {
  607. Network.getCookies(request, callback);
  608. }
  609. //移除cookie
  610. else if (request.type === MSG_TYPE.REMOVE_COOKIE) {
  611. Network.removeCookie(request, callback);
  612. }
  613. //设置cookie
  614. else if (request.type === MSG_TYPE.SET_COOKIE) {
  615. Network.setCookie(request, callback);
  616. }
  617. //CSS准备就绪
  618. else if (request.type === MSG_TYPE.CSS_READY) {
  619. _detectReadyState('css', callback);
  620. }
  621. //JS准备就绪
  622. else if (request.type === MSG_TYPE.JS_READY) {
  623. _detectReadyState('js', callback);
  624. }
  625. //HTML准备就绪
  626. else if (request.type === MSG_TYPE.HTML_READY) {
  627. _detectReadyState('html', callback);
  628. }
  629. // ===========================以上为编码规范检测====end==================================
  630. return true;
  631. });
  632. // 检测DevTools是否打开
  633. let openCount = 0;
  634. chrome.runtime.onConnect.addListener(function (port) {
  635. if (port.name === MSG_TYPE.DEV_TOOLS) {
  636. if (openCount === 0) {
  637. devToolsDetected = true;
  638. }
  639. openCount++;
  640. port.onDisconnect.addListener(function (port) {
  641. openCount--;
  642. if (openCount === 0) {
  643. devToolsDetected = false;
  644. }
  645. });
  646. }
  647. });
  648. // 安装与更新
  649. chrome.runtime.onInstalled.addListener(({reason, previousVersion}) => {
  650. switch (reason) {
  651. case 'install':
  652. chrome.runtime.openOptionsPage();
  653. break;
  654. case 'update':
  655. setTimeout(() => {
  656. chrome.browserAction.setBadgeText({text: '+++1'});
  657. setTimeout(() => {
  658. chrome.browserAction.setBadgeText({text: ''});
  659. }, 1500);
  660. }, 1500);
  661. break;
  662. }
  663. });
  664. // 卸载
  665. chrome.runtime.setUninstallURL(feHelper.manifest.homepage_url);
  666. };
  667. /**
  668. * 检查插件更新
  669. * @private
  670. */
  671. let _checkUpdate = function () {
  672. setTimeout(() => {
  673. chrome.runtime.requestUpdateCheck((status) => {
  674. if (status === "update_available") {
  675. chrome.runtime.reload();
  676. }
  677. });
  678. }, 1000 * 10);
  679. };
  680. /**
  681. * 初始化
  682. */
  683. let _init = function () {
  684. _checkUpdate();
  685. _addExtensionListener();
  686. _createOrRemoveContextMenu();
  687. };
  688. return {
  689. init: _init,
  690. runHelper: _runHelper,
  691. notify: notifyText,
  692. showColorPicker: _showColorPicker,
  693. tellMeAjaxDbgSwitch: _tellDevToolsDbgSwitchOn,
  694. getCapturedData: PageCapture.getCapturedData
  695. };
  696. })();
  697. //初始化
  698. BgPageInstance.init();