fe-background.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  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. * 执行栅格检测
  68. */
  69. var _doGridDetect = function (tab) {
  70. chrome.tabs.sendMessage(tab.id, {
  71. type: MSG_TYPE.BROWSER_CLICKED,
  72. event: MSG_TYPE.GRID_DETECT
  73. });
  74. };
  75. /**
  76. * 查看页面wpo信息
  77. */
  78. var _showPageWpoInfo = function (wpoInfo) {
  79. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  80. if (!wpoInfo) {
  81. notifyText({
  82. message: "对不起,检测失败"
  83. });
  84. } else {
  85. chrome.tabs.create({
  86. url: "template/fehelper_wpo.html?" + btoa(encodeURIComponent(JSON.stringify(wpoInfo))),
  87. active: true
  88. });
  89. }
  90. });
  91. };
  92. /**
  93. * 获取页面wpo信息
  94. * @return {[type]}
  95. */
  96. var _getPageWpoInfo = function () {
  97. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  98. var tab = tabs[0];
  99. //显示桌面提醒
  100. chrome.tabs.sendMessage(tab.id, {
  101. type: MSG_TYPE.GET_PAGE_WPO_INFO
  102. });
  103. });
  104. };
  105. /**
  106. * 执行JS Tracker
  107. * @private
  108. */
  109. var _doJsTracker = function () {
  110. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  111. var tab = tabs[0];
  112. chrome.tabs.executeScript(tab.id, {
  113. code: "void function(t,r,a,c,k){t.tracker_type='bm';t.tracker_uid='fehelper';"
  114. + "(k=t.TrackerGlobalEvent)?k.f(r):[(k=t[a]('script')).charset='utf-8',"
  115. + "k.src='http://www.ucren.com/'+c+'/'+c+'.js?'+Math.random(),"
  116. + "t.documentElement.appendChild(k)]}(document,'TrackerJSLoad','createElement','tracker') ",
  117. allFrames: false,
  118. runAt: 'document_end'
  119. });
  120. });
  121. };
  122. /**
  123. * 代码压缩工具
  124. * @private
  125. */
  126. var _goCompressTool = function () {
  127. var url = "http://www.baidufe.com/fehelper/codecompress.html";
  128. chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, function (tabs) {
  129. var isOpened = false;
  130. var tabId;
  131. var reg = new RegExp("fehelper.*codecompress.html$", "i");
  132. for (var i = 0, len = tabs.length; i < len; i++) {
  133. if (reg.test(tabs[i].url)) {
  134. isOpened = true;
  135. tabId = tabs[i].id;
  136. break;
  137. }
  138. }
  139. if (!isOpened) {
  140. chrome.tabs.create({
  141. url: url,
  142. active: true
  143. });
  144. } else {
  145. chrome.tabs.update(tabId, {highlighted: true});
  146. }
  147. });
  148. };
  149. /**
  150. * 创建或更新成功执行的动作
  151. * @param evt
  152. * @param content
  153. * @private
  154. */
  155. var _tabUpdatedCallback = function (evt, content) {
  156. return function (newTab) {
  157. if (content) {
  158. chrome.tabs.sendMessage(newTab.id, {
  159. type: MSG_TYPE.TAB_CREATED_OR_UPDATED,
  160. content: content,
  161. event: evt
  162. });
  163. }
  164. };
  165. };
  166. /**
  167. * 打开对应文件,运行该Helper
  168. * @param tab
  169. * @param file
  170. * @param txt
  171. * @private
  172. */
  173. var _openFileAndRun = function (tab, file, txt) {
  174. chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, function (tabs) {
  175. var isOpened = false;
  176. var tabId;
  177. var reg = new RegExp("^chrome.*" + file + ".html$", "i");
  178. for (var i = 0, len = tabs.length; i < len; i++) {
  179. if (reg.test(tabs[i].url)) {
  180. isOpened = true;
  181. tabId = tabs[i].id;
  182. break;
  183. }
  184. }
  185. if (!isOpened) {
  186. chrome.tabs.create({
  187. url: 'template/fehelper_' + file + '.html',
  188. active: true
  189. }, _tabUpdatedCallback(file, txt));
  190. } else {
  191. chrome.tabs.update(tabId, {highlighted: true}, _tabUpdatedCallback(file, txt));
  192. }
  193. });
  194. };
  195. /**
  196. * 根据给定参数,运行对应的Helper
  197. */
  198. var _runHelper = function (config) {
  199. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  200. var tab = tabs[0];
  201. // 如果是采用独立文件方式访问,直接打开该页面即可
  202. if (config.useFile == '1') {
  203. _openFileAndRun(tab, config.msgType);
  204. } else {
  205. switch (config.msgType) {
  206. //fcphelper检测
  207. case MSG_TYPE.FCP_HELPER_DETECT:
  208. _doFcpDetect(tab);
  209. break;
  210. //栅格检测
  211. case MSG_TYPE.GRID_DETECT:
  212. _doGridDetect(tab);
  213. break;
  214. //查看网页加载时间
  215. case MSG_TYPE.SHOW_PAGE_LOAD_TIME:
  216. _getPageWpoInfo();
  217. break;
  218. //js tracker
  219. case MSG_TYPE.JS_TRACKER:
  220. _doJsTracker();
  221. break;
  222. //代码压缩
  223. case MSG_TYPE.CODE_COMPRESS:
  224. _goCompressTool();
  225. break;
  226. }
  227. }
  228. });
  229. };
  230. /**
  231. * 创建扩展专属的右键菜单
  232. */
  233. var _createContextMenu = function () {
  234. _removeContextMenu();
  235. baidu.contextMenuId = chrome.contextMenus.create({
  236. title: "FeHelper",
  237. contexts: ['page', 'selection', 'editable', 'link'],
  238. documentUrlPatterns: ['http://*/*', 'https://*/*']
  239. });
  240. chrome.contextMenus.create({
  241. title: "JSON格式化",
  242. contexts: ['page', 'selection', 'editable'],
  243. parentId: baidu.contextMenuId,
  244. onclick: function (info, tab) {
  245. chrome.tabs.executeScript(tab.id, {
  246. code: '(' + (function () {
  247. return window.getSelection().toString();
  248. }).toString() + ')()',
  249. allFrames: false
  250. }, function (txt) {
  251. _openFileAndRun(tab, 'jsonformat', txt);
  252. });
  253. }
  254. });
  255. chrome.contextMenus.create({
  256. type: 'separator',
  257. contexts: ['all'],
  258. parentId: baidu.contextMenuId
  259. });
  260. chrome.contextMenus.create({
  261. title: "字符串编解码",
  262. contexts: ['page', 'selection', 'editable'],
  263. parentId: baidu.contextMenuId,
  264. onclick: function (info, tab) {
  265. chrome.tabs.executeScript(tab.id, {
  266. code: '(' + (function () {
  267. return window.getSelection().toString();
  268. }).toString() + ')()',
  269. allFrames: false
  270. }, function (txt) {
  271. _openFileAndRun(tab, 'endecode', txt);
  272. });
  273. }
  274. });
  275. chrome.contextMenus.create({
  276. type: 'separator',
  277. contexts: ['all'],
  278. parentId: baidu.contextMenuId
  279. });
  280. chrome.contextMenus.create({
  281. title: "生成二维码",
  282. contexts: ['page', 'selection', 'editable', 'link'],
  283. parentId: baidu.contextMenuId,
  284. onclick: function (info, tab) {
  285. chrome.tabs.executeScript(tab.id, {
  286. code: '(' + (function () {
  287. return window.getSelection().toString() || location.href;
  288. }).toString() + ')()',
  289. allFrames: false
  290. }, function (txt) {
  291. _openFileAndRun(tab, 'qrcode', txt);
  292. });
  293. }
  294. });
  295. chrome.contextMenus.create({
  296. type: 'separator',
  297. contexts: ['all'],
  298. parentId: baidu.contextMenuId
  299. });
  300. chrome.contextMenus.create({
  301. title: "代码格式化",
  302. contexts: ['page', 'selection', 'editable'],
  303. parentId: baidu.contextMenuId,
  304. onclick: function (info, tab) {
  305. chrome.tabs.executeScript(tab.id, {
  306. code: '(' + (function () {
  307. return window.getSelection().toString();
  308. }).toString() + ')()',
  309. allFrames: false
  310. }, function (txt) {
  311. _openFileAndRun(tab, 'codebeautify', txt);
  312. });
  313. }
  314. });
  315. chrome.contextMenus.create({
  316. type: 'separator',
  317. contexts: ['all'],
  318. parentId: baidu.contextMenuId
  319. });
  320. chrome.contextMenus.create({
  321. title: "代码压缩",
  322. contexts: ['page', 'selection', 'editable'],
  323. parentId: baidu.contextMenuId,
  324. onclick: function (info, tab) {
  325. _goCompressTool();
  326. }
  327. });
  328. chrome.contextMenus.create({
  329. type: 'separator',
  330. contexts: ['all'],
  331. parentId: baidu.contextMenuId
  332. });
  333. chrome.contextMenus.create({
  334. title: "页面取色器",
  335. contexts: ['page', 'selection', 'editable'],
  336. parentId: baidu.contextMenuId,
  337. onclick: function (info, tab) {
  338. _showColorPicker();
  339. }
  340. });
  341. };
  342. /**
  343. * 移除扩展专属的右键菜单
  344. */
  345. var _removeContextMenu = function () {
  346. if (!baidu.contextMenuId) return;
  347. chrome.contextMenus.remove(baidu.contextMenuId);
  348. baidu.contextMenuId = null;
  349. };
  350. /**
  351. * 创建或移除扩展专属的右键菜单
  352. */
  353. var _createOrRemoveContextMenu = function () {
  354. //管理右键菜单
  355. if (baidu.feOption.getOptionItem('opt_item_contextMenus') !== 'false') {
  356. _createContextMenu();
  357. } else {
  358. _removeContextMenu();
  359. }
  360. };
  361. /**
  362. * 显示color picker
  363. * @private
  364. */
  365. var _showColorPicker = function () {
  366. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  367. var tab = tabs[0];
  368. var tabid = tab.id;
  369. var port = chrome.tabs.connect(tabid, {name: "popupshown"});
  370. chrome.tabs.sendMessage(tabid, {enableColorPicker: true}, function (response) {
  371. chrome.tabs.sendMessage(tabid, {doPick: true}, function (r) {
  372. });
  373. });
  374. });
  375. };
  376. /**
  377. * 将网页截成一张图,实现取色
  378. * @param callback
  379. * @private
  380. */
  381. var _drawColorPicker = function (callback) {
  382. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  383. var tab = tabs[0];
  384. var tabid = tab.id;
  385. chrome.tabs.captureVisibleTab(null, {format: 'png'}, function (dataUrl) {
  386. chrome.tabs.sendMessage(tabid, {
  387. setPickerImage: true,
  388. pickerImage: dataUrl
  389. }, function (response) {
  390. callback && callback();
  391. });
  392. });
  393. });
  394. };
  395. /**
  396. * 接收来自content_scripts发来的消息
  397. */
  398. var _addExtensionListener = function () {
  399. chrome.runtime.onMessage.addListener(function (request, sender, callback) {
  400. //处理CSS的请求
  401. if (request.type == MSG_TYPE.GET_CSS) {
  402. //直接AJAX获取CSS文件内容
  403. baidu.network.readFileContent(request.link, callback);
  404. }
  405. //处理JS的请求
  406. else if (request.type == MSG_TYPE.GET_JS) {
  407. //直接AJAX获取JS文件内容
  408. baidu.network.readFileContent(request.link, callback);
  409. }
  410. //处理HTML的请求
  411. else if (request.type == MSG_TYPE.GET_HTML) {
  412. //直接AJAX获取JS文件内容
  413. baidu.network.readFileContent(request.link, callback);
  414. }
  415. //处理cookie
  416. else if (request.type == MSG_TYPE.GET_COOKIE) {
  417. baidu.network.getCookies(request, callback);
  418. }
  419. //移除cookie
  420. else if (request.type == MSG_TYPE.REMOVE_COOKIE) {
  421. baidu.network.removeCookie(request, callback);
  422. }
  423. //设置cookie
  424. else if (request.type == MSG_TYPE.SET_COOKIE) {
  425. baidu.network.setCookie(request, callback);
  426. }
  427. //CSS准备就绪
  428. else if (request.type == MSG_TYPE.CSS_READY) {
  429. _readyState.css = true;
  430. }
  431. //JS准备就绪
  432. else if (request.type == MSG_TYPE.JS_READY) {
  433. _readyState.js = true;
  434. }
  435. //HTML准备就绪
  436. else if (request.type == MSG_TYPE.HTML_READY) {
  437. _readyState.html = true;
  438. }
  439. //提取配置项
  440. else if (request.type == MSG_TYPE.GET_OPTIONS) {
  441. baidu.feOption.doGetOptions(request.items, callback);
  442. }
  443. //保存配置项
  444. else if (request.type == MSG_TYPE.SET_OPTIONS) {
  445. baidu.feOption.doSetOptions(request.items, callback);
  446. //管理右键菜单
  447. _createOrRemoveContextMenu();
  448. }
  449. //保存当前网页加载时间
  450. else if (request.type == MSG_TYPE.CALC_PAGE_LOAD_TIME) {
  451. _showPageWpoInfo(request.wpo);
  452. }
  453. // 从popup中点过来的
  454. else if (request.type == MSG_TYPE.FROM_POPUP) {
  455. _runHelper(request.config);
  456. }
  457. // color picker
  458. else if (request.type == "color-picker:newImage") {
  459. _drawColorPicker(callback);
  460. }
  461. return true;
  462. });
  463. };
  464. /**
  465. * 初始化
  466. */
  467. var _init = function () {
  468. _addExtensionListener();
  469. _detectReadyState();
  470. _createOrRemoveContextMenu();
  471. };
  472. return {
  473. init: _init,
  474. runHelper: _runHelper,
  475. showColorPicker: _showColorPicker
  476. };
  477. })();
  478. //初始化
  479. BgPageInstance.init();