fe-background.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /**
  2. * FE-Helper后台运行程序
  3. * @author [email protected]
  4. */
  5. var BgPageInstance = (function () {
  6. //各种元素的就绪情况
  7. var _readyState = {
  8. css: false,
  9. js: false,
  10. html: true,
  11. allDone: false
  12. };
  13. /**
  14. * 文本格式,可以设置一个图标和标题
  15. * @param {Object} options
  16. * @config {string} type notification的类型,可选值:html、text
  17. * @config {string} icon 图标
  18. * @config {string} title 标题
  19. * @config {string} message 内容
  20. */
  21. var notifyText = function (options) {
  22. if (!window.Notification) {
  23. return;
  24. }
  25. if (!options.icon) {
  26. options.icon = "static/img/fe-48.png";
  27. }
  28. if (!options.title) {
  29. options.title = "温馨提示";
  30. }
  31. chrome.notifications.create('', {
  32. type: 'basic',
  33. title: options.title,
  34. iconUrl: chrome.runtime.getURL(options.icon),
  35. message: options.message
  36. });
  37. };
  38. //侦测的interval
  39. var _detectInterval = null;
  40. //侦测就绪情况
  41. var _detectReadyState = function () {
  42. _detectInterval = window.setInterval(function () {
  43. if (_readyState.css && _readyState.js && _readyState.html) {
  44. _readyState.allDone = true;
  45. window.clearInterval(_detectInterval);
  46. }
  47. }, 100);
  48. };
  49. /**
  50. * 执行前端FCPHelper检测
  51. */
  52. var _doFcpDetect = function (tab) {
  53. //所有元素都准备就绪
  54. if (_readyState.allDone) {
  55. chrome.tabs.sendMessage(tab.id, {
  56. type: MSG_TYPE.BROWSER_CLICKED,
  57. event: MSG_TYPE.FCP_HELPER_DETECT
  58. });
  59. } else {
  60. //显示桌面提醒
  61. notifyText({
  62. message: "正在准备数据,请稍等..."
  63. });
  64. }
  65. };
  66. /**
  67. * 查看页面wpo信息
  68. */
  69. var _showPageWpoInfo = function (wpoInfo) {
  70. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  71. if (!wpoInfo) {
  72. notifyText({
  73. message: "对不起,检测失败"
  74. });
  75. } else {
  76. chrome.tabs.create({
  77. url: "template/fehelper_wpo.html?" + btoa(encodeURIComponent(JSON.stringify(wpoInfo))),
  78. active: true
  79. });
  80. }
  81. });
  82. };
  83. /**
  84. * 获取页面wpo信息
  85. * @return {[type]}
  86. */
  87. var _getPageWpoInfo = function () {
  88. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  89. var tab = tabs[0];
  90. //显示桌面提醒
  91. chrome.tabs.sendMessage(tab.id, {
  92. type: MSG_TYPE.GET_PAGE_WPO_INFO
  93. });
  94. });
  95. };
  96. /**
  97. * 代码压缩工具
  98. * @private
  99. */
  100. var _goCompressTool = function () {
  101. var url = "http://www.baidufe.com/fehelper/codecompress.html";
  102. chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, function (tabs) {
  103. var isOpened = false;
  104. var tabId;
  105. var reg = new RegExp("fehelper.*codecompress.html$", "i");
  106. for (var i = 0, len = tabs.length; i < len; i++) {
  107. if (reg.test(tabs[i].url)) {
  108. isOpened = true;
  109. tabId = tabs[i].id;
  110. break;
  111. }
  112. }
  113. if (!isOpened) {
  114. chrome.tabs.create({
  115. url: url,
  116. active: true
  117. });
  118. } else {
  119. chrome.tabs.update(tabId, {highlighted: true});
  120. }
  121. });
  122. };
  123. /**
  124. * 创建或更新成功执行的动作
  125. * @param evt
  126. * @param content
  127. * @private
  128. */
  129. var _tabUpdatedCallback = function (evt, content) {
  130. return function (newTab) {
  131. if (content) {
  132. setTimeout(function () {
  133. chrome.tabs.sendMessage(newTab.id, {
  134. type: MSG_TYPE.TAB_CREATED_OR_UPDATED,
  135. content: content,
  136. event: evt
  137. });
  138. }, 300)
  139. }
  140. };
  141. };
  142. /**
  143. * 打开对应文件,运行该Helper
  144. * @param tab
  145. * @param file
  146. * @param txt
  147. * @private
  148. */
  149. var _openFileAndRun = function (tab, file, txt) {
  150. chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, function (tabs) {
  151. var isOpened = false;
  152. var tabId;
  153. var reg = new RegExp("^chrome.*" + file + ".html$", "i");
  154. for (var i = 0, len = tabs.length; i < len; i++) {
  155. if (reg.test(tabs[i].url)) {
  156. isOpened = true;
  157. tabId = tabs[i].id;
  158. break;
  159. }
  160. }
  161. if (!isOpened) {
  162. chrome.tabs.create({
  163. url: 'template/fehelper_' + file + '.html',
  164. active: true
  165. }, _tabUpdatedCallback(file, txt));
  166. } else {
  167. chrome.tabs.update(tabId, {highlighted: true}, _tabUpdatedCallback(file, txt));
  168. }
  169. });
  170. };
  171. /**
  172. * 根据给定参数,运行对应的Helper
  173. */
  174. var _runHelper = function (config) {
  175. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  176. var tab = tabs[0];
  177. // 如果是采用独立文件方式访问,直接打开该页面即可
  178. if (config.useFile == '1') {
  179. var content = config.msgType == MSG_TYPE.QR_CODE ? tab.url : '';
  180. _openFileAndRun(tab, config.msgType, content);
  181. } else {
  182. switch (config.msgType) {
  183. //fcphelper检测
  184. case MSG_TYPE.FCP_HELPER_DETECT:
  185. _doFcpDetect(tab);
  186. break;
  187. //查看网页加载时间
  188. case MSG_TYPE.SHOW_PAGE_LOAD_TIME:
  189. _getPageWpoInfo();
  190. break;
  191. //代码压缩
  192. case MSG_TYPE.CODE_COMPRESS:
  193. _goCompressTool();
  194. break;
  195. }
  196. }
  197. });
  198. };
  199. /**
  200. * 创建扩展专属的右键菜单
  201. */
  202. var _createContextMenu = function () {
  203. _removeContextMenu();
  204. baidu.contextMenuId = chrome.contextMenus.create({
  205. title: "FeHelper",
  206. contexts: ['page', 'selection', 'editable', 'link'],
  207. documentUrlPatterns: ['http://*/*', 'https://*/*']
  208. });
  209. chrome.contextMenus.create({
  210. title: "生成二维码",
  211. contexts: ['page', 'selection', 'editable', 'link'],
  212. parentId: baidu.contextMenuId,
  213. onclick: function (info, tab) {
  214. chrome.tabs.executeScript(tab.id, {
  215. code: '(' + (function () {
  216. return window.getSelection().toString() || location.href;
  217. }).toString() + ')()',
  218. allFrames: false
  219. }, function (txt) {
  220. _openFileAndRun(tab, 'qrcode', txt);
  221. });
  222. }
  223. });
  224. chrome.contextMenus.create({
  225. type: 'separator',
  226. contexts: ['all'],
  227. parentId: baidu.contextMenuId
  228. });
  229. chrome.contextMenus.create({
  230. title: "页面取色器",
  231. contexts: ['page', 'selection', 'editable'],
  232. parentId: baidu.contextMenuId,
  233. onclick: function (info, tab) {
  234. _showColorPicker();
  235. }
  236. });
  237. chrome.contextMenus.create({
  238. type: 'separator',
  239. contexts: ['all'],
  240. parentId: baidu.contextMenuId
  241. });
  242. chrome.contextMenus.create({
  243. title: "字符串编解码",
  244. contexts: ['page', 'selection', 'editable'],
  245. parentId: baidu.contextMenuId,
  246. onclick: function (info, tab) {
  247. chrome.tabs.executeScript(tab.id, {
  248. code: '(' + (function () {
  249. return window.getSelection().toString();
  250. }).toString() + ')()',
  251. allFrames: false
  252. }, function (txt) {
  253. _openFileAndRun(tab, 'endecode', txt);
  254. });
  255. }
  256. });
  257. chrome.contextMenus.create({
  258. type: 'separator',
  259. contexts: ['all'],
  260. parentId: baidu.contextMenuId
  261. });
  262. chrome.contextMenus.create({
  263. title: "JSON格式化",
  264. contexts: ['page', 'selection', 'editable'],
  265. parentId: baidu.contextMenuId,
  266. onclick: function (info, tab) {
  267. chrome.tabs.executeScript(tab.id, {
  268. code: '(' + (function () {
  269. return window.getSelection().toString();
  270. }).toString() + ')()',
  271. allFrames: false
  272. }, function (txt) {
  273. _openFileAndRun(tab, 'jsonformat', txt);
  274. });
  275. }
  276. });
  277. chrome.contextMenus.create({
  278. type: 'separator',
  279. contexts: ['all'],
  280. parentId: baidu.contextMenuId
  281. });
  282. chrome.contextMenus.create({
  283. title: "代码格式化",
  284. contexts: ['page', 'selection', 'editable'],
  285. parentId: baidu.contextMenuId,
  286. onclick: function (info, tab) {
  287. chrome.tabs.executeScript(tab.id, {
  288. code: '(' + (function () {
  289. return window.getSelection().toString();
  290. }).toString() + ')()',
  291. allFrames: false
  292. }, function (txt) {
  293. _openFileAndRun(tab, 'codebeautify', txt);
  294. });
  295. }
  296. });
  297. };
  298. /**
  299. * 移除扩展专属的右键菜单
  300. */
  301. var _removeContextMenu = function () {
  302. if (!baidu.contextMenuId) return;
  303. chrome.contextMenus.remove(baidu.contextMenuId);
  304. baidu.contextMenuId = null;
  305. };
  306. /**
  307. * 创建或移除扩展专属的右键菜单
  308. */
  309. var _createOrRemoveContextMenu = function () {
  310. //管理右键菜单
  311. if (baidu.feOption.getOptionItem('opt_item_contextMenus') !== 'false') {
  312. _createContextMenu();
  313. } else {
  314. _removeContextMenu();
  315. }
  316. };
  317. /**
  318. * 显示color picker
  319. * @private
  320. */
  321. var _showColorPicker = function () {
  322. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  323. var tab = tabs[0];
  324. var tabid = tab.id;
  325. var port = chrome.tabs.connect(tabid, {name: "popupshown"});
  326. chrome.tabs.sendMessage(tabid, {enableColorPicker: true}, function (response) {
  327. chrome.tabs.sendMessage(tabid, {doPick: true}, function (r) {
  328. });
  329. });
  330. });
  331. };
  332. /**
  333. * 将网页截成一张图,实现取色
  334. * @param callback
  335. * @private
  336. */
  337. var _drawColorPicker = function (callback) {
  338. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  339. var tab = tabs[0];
  340. var tabid = tab.id;
  341. chrome.tabs.captureVisibleTab(null, {format: 'png'}, function (dataUrl) {
  342. chrome.tabs.sendMessage(tabid, {
  343. setPickerImage: true,
  344. pickerImage: dataUrl
  345. }, function (response) {
  346. callback && callback();
  347. });
  348. });
  349. });
  350. };
  351. /**
  352. * 接收来自content_scripts发来的消息
  353. */
  354. var _addExtensionListener = function () {
  355. chrome.runtime.onMessage.addListener(function (request, sender, callback) {
  356. //处理CSS的请求
  357. if (request.type == MSG_TYPE.GET_CSS) {
  358. //直接AJAX获取CSS文件内容
  359. baidu.network.readFileContent(request.link, callback);
  360. }
  361. //处理JS的请求
  362. else if (request.type == MSG_TYPE.GET_JS) {
  363. //直接AJAX获取JS文件内容
  364. baidu.network.readFileContent(request.link, callback);
  365. }
  366. //处理HTML的请求
  367. else if (request.type == MSG_TYPE.GET_HTML) {
  368. //直接AJAX获取JS文件内容
  369. baidu.network.readFileContent(request.link, callback);
  370. }
  371. //处理cookie
  372. else if (request.type == MSG_TYPE.GET_COOKIE) {
  373. baidu.network.getCookies(request, callback);
  374. }
  375. //移除cookie
  376. else if (request.type == MSG_TYPE.REMOVE_COOKIE) {
  377. baidu.network.removeCookie(request, callback);
  378. }
  379. //设置cookie
  380. else if (request.type == MSG_TYPE.SET_COOKIE) {
  381. baidu.network.setCookie(request, callback);
  382. }
  383. //CSS准备就绪
  384. else if (request.type == MSG_TYPE.CSS_READY) {
  385. _readyState.css = true;
  386. }
  387. //JS准备就绪
  388. else if (request.type == MSG_TYPE.JS_READY) {
  389. _readyState.js = true;
  390. }
  391. //HTML准备就绪
  392. else if (request.type == MSG_TYPE.HTML_READY) {
  393. _readyState.html = true;
  394. }
  395. //提取配置项
  396. else if (request.type == MSG_TYPE.GET_OPTIONS) {
  397. baidu.feOption.doGetOptions(request.items, callback);
  398. }
  399. //保存配置项
  400. else if (request.type == MSG_TYPE.SET_OPTIONS) {
  401. baidu.feOption.doSetOptions(request.items, callback);
  402. //管理右键菜单
  403. _createOrRemoveContextMenu();
  404. }
  405. //保存当前网页加载时间
  406. else if (request.type == MSG_TYPE.CALC_PAGE_LOAD_TIME) {
  407. _showPageWpoInfo(request.wpo);
  408. }
  409. // 从popup中点过来的
  410. else if (request.type == MSG_TYPE.FROM_POPUP) {
  411. _runHelper(request.config);
  412. }
  413. // color picker
  414. else if (request.type == MSG_TYPE.COLOR_PICKER) {
  415. _drawColorPicker(callback);
  416. }
  417. return true;
  418. });
  419. };
  420. /**
  421. * 初始化
  422. */
  423. var _init = function () {
  424. _addExtensionListener();
  425. _detectReadyState();
  426. _createOrRemoveContextMenu();
  427. };
  428. return {
  429. init: _init,
  430. runHelper: _runHelper,
  431. showColorPicker: _showColorPicker
  432. };
  433. })();
  434. //初始化
  435. BgPageInstance.init();