menu.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * FeHelper 右键菜单管理
  3. * @type {{manage}}
  4. * @author zhaoxianlie
  5. */
  6. import CrxDownloader from './crx-download.js';
  7. import Awesome from './awesome.js';
  8. import toolMap from './tools.js';
  9. export default (function () {
  10. let FeJson = {
  11. contextMenuId:"fhm_main"
  12. };
  13. // 邮件菜单配置项
  14. let defaultMenuOptions = {
  15. 'download-crx': {
  16. icon: '♥',
  17. text: '插件下载分享',
  18. onClick: function (info, tab) {
  19. CrxDownloader.downloadCrx(tab);
  20. }
  21. },
  22. 'fehelper-setting': {
  23. icon: '❂',
  24. text: 'FeHelper设置',
  25. onClick: function (info, tab) {
  26. chrome.runtime.openOptionsPage();
  27. }
  28. }
  29. };
  30. // 初始化菜单配置
  31. let _initMenuOptions = (() => {
  32. Object.keys(toolMap).forEach(tool => {
  33. // context-menu
  34. switch (tool) {
  35. case 'json-format':
  36. toolMap[tool].menuConfig[0].onClick = function (info, tab) {
  37. chrome.scripting.executeScript({
  38. target: {tabId:tab.id,allFrames:false},
  39. args: [info.selectionText],
  40. func: (text) => text
  41. }, resp => chrome.DynamicToolRunner({
  42. tool, withContent: resp[0].result
  43. }));
  44. };
  45. break;
  46. case 'code-beautify':
  47. case 'en-decode':
  48. toolMap[tool].menuConfig[0].onClick = function (info, tab) {
  49. chrome.scripting.executeScript({
  50. target: {tabId:tab.id,allFrames:false},
  51. args: [info.linkUrl || info.srcUrl || info.selectionText || info.pageUrl],
  52. func: (text) => text
  53. }, resp => chrome.DynamicToolRunner({
  54. tool, withContent: resp[0].result
  55. }));
  56. };
  57. break;
  58. case 'qr-code':
  59. toolMap[tool].menuConfig[0].onClick = function (info, tab) {
  60. chrome.scripting.executeScript({
  61. target: {tabId:tab.id,allFrames:false},
  62. args: [info.linkUrl || info.srcUrl || info.selectionText || info.pageUrl || tab.url],
  63. func: (text) => text
  64. }, resp => chrome.DynamicToolRunner({
  65. tool, withContent: resp[0].result
  66. }));
  67. };
  68. toolMap[tool].menuConfig[1].onClick = function (info, tab) {
  69. chrome.scripting.executeScript({
  70. target: {tabId:tab.id,allFrames:false},
  71. args: [info.srcUrl],
  72. func: (text) => {
  73. try {
  74. if (typeof window.qrcodeContentScript === 'function') {
  75. let qrcode = window.qrcodeContentScript();
  76. if (typeof qrcode.decode === 'function') {
  77. qrcode.decode(pInfo.srcUrl);
  78. return 1;
  79. }
  80. }
  81. } catch (e) {
  82. return 0;
  83. }
  84. }
  85. });
  86. };
  87. break;
  88. default:
  89. toolMap[tool].menuConfig[0].onClick = function (info, tab) {
  90. chrome.DynamicToolRunner({
  91. tool, withContent: tool === 'image-base64' ? info.srcUrl : ''
  92. })
  93. };
  94. break;
  95. }
  96. });
  97. })();
  98. /**
  99. * 创建一个menu 菜单
  100. * @param toolName
  101. * @param menuList
  102. * @returns {boolean}
  103. * @private
  104. */
  105. let _createItem = (toolName, menuList) => {
  106. menuList && menuList.forEach && menuList.forEach(menu => {
  107. let _menu_id = 'fhm_c' + escape(menu.text).replace(/\W/g,'');
  108. chrome.contextMenus.create({
  109. id: _menu_id,
  110. title: menu.icon + ' ' + menu.text,
  111. contexts: menu.contexts || ['all'],
  112. parentId: FeJson.contextMenuId
  113. });
  114. chrome.contextMenus.onClicked.addListener(((tool,mId,mFunc) => (info, tab) => {
  115. if(info.menuItemId === mId) {
  116. if(mFunc) {
  117. mFunc(info,tab);
  118. }else{
  119. chrome.DynamicToolRunner({ tool });
  120. }
  121. }
  122. })(toolName,_menu_id,menu.onClick));
  123. });
  124. };
  125. /**
  126. * 绘制一条分割线
  127. * @private
  128. */
  129. let _createSeparator = function () {
  130. chrome.contextMenus.create({
  131. id: 'fhm_s' + Math.ceil(Math.random()*10e9),
  132. type: 'separator',
  133. parentId: FeJson.contextMenuId
  134. });
  135. };
  136. /**
  137. * 创建扩展专属的右键菜单
  138. */
  139. let _createContextMenu = function () {
  140. _removeContextMenu();
  141. chrome.contextMenus.create({
  142. id: FeJson.contextMenuId,
  143. title: "FeHelper",
  144. contexts: ['page', 'selection', 'editable', 'link', 'image'],
  145. documentUrlPatterns: ['http://*/*', 'https://*/*', 'file://*/*']
  146. });
  147. // 绘制用户安装的菜单,放在前面
  148. Awesome.getInstalledTools().then(tools => {
  149. let allMenus = Object.keys(tools).filter(tool => tools[tool].installed && tools[tool].menu);
  150. let onlineTools = allMenus.filter(tool => tool !== 'devtools' && !tools[tool].hasOwnProperty('_devTool'));
  151. let devTools = allMenus.filter(tool => tool === 'devtools' || tools[tool].hasOwnProperty('_devTool'));
  152. // 绘制FH提供的工具菜单
  153. onlineTools.forEach(tool => _createItem(tool, tools[tool].menuConfig));
  154. // 如果有本地工具的菜单需要绘制,则需要加一条分割线
  155. devTools.length && _createSeparator();
  156. // 绘制本地工具的菜单
  157. devTools.forEach(tool => _createItem(tool, tools[tool].menuConfig));
  158. });
  159. // 绘制两个系统提供的菜单,放到最后
  160. let sysMenu = ['download-crx', 'fehelper-setting'];
  161. let arrPromises = sysMenu.map(menu => Awesome.menuMgr(menu, 'get'));
  162. Promise.all(arrPromises).then(values => {
  163. let needDraw = String(values[0]) === '1' || String(values[1]) !== '0';
  164. // 绘制一条分割线
  165. _createSeparator();
  166. // 绘制菜单
  167. String(values[0]) === '1' && _createItem(sysMenu[0], [defaultMenuOptions[sysMenu[0]]]);
  168. String(values[1]) !== '0' && _createItem(sysMenu[1], [defaultMenuOptions[sysMenu[1]]]);
  169. });
  170. };
  171. /**
  172. * 移除扩展专属的右键菜单
  173. */
  174. let _removeContextMenu = function () {
  175. chrome.contextMenus.removeAll();
  176. };
  177. /**
  178. * 创建或移除扩展专属的右键菜单
  179. */
  180. let _createOrRemoveContextMenu = function (_settings) {
  181. _settings.getOptions((opts) => {
  182. if (String(opts['OPT_ITEM_CONTEXTMENUS']) !== 'false') {
  183. _createContextMenu();
  184. } else {
  185. _removeContextMenu();
  186. }
  187. });
  188. };
  189. return {
  190. manage: _createOrRemoveContextMenu
  191. };
  192. })();