crx-download.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /**
  2. * FeHelper:从chrome webstore下载extension文件的工具
  3. * @author zhaoxianlie
  4. */
  5. import MSG_TYPE from '../static/js/common.js';
  6. export default (function () {
  7. let FeJson = {notifyTimeoutId:-1};
  8. /**
  9. * 文本格式,可以设置一个图标和标题
  10. * @param {Object} options
  11. * @config {string} type notification的类型,可选值:html、text
  12. * @config {string} icon 图标
  13. * @config {string} title 标题
  14. * @config {string} message 内容
  15. */
  16. let notifyText = function (options) {
  17. let notifyId = 'FeJson-notify-id';
  18. if(typeof options === 'string') {
  19. options = {message: options};
  20. }
  21. clearTimeout(FeJson.notifyTimeoutId);
  22. if (options.closeImmediately) {
  23. return chrome.notifications.clear(notifyId);
  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(notifyId, {
  32. type: 'basic',
  33. title: options.title,
  34. iconUrl: chrome.runtime.getURL(options.icon),
  35. message: options.message
  36. });
  37. FeJson.notifyTimeoutId = setTimeout(() => {
  38. chrome.notifications.clear(notifyId);
  39. }, parseInt(options.autoClose || 3000, 10));
  40. };
  41. /**
  42. * 检测Google chrome服务能不能访问,在2s内检测心跳
  43. * @param success
  44. * @param failure
  45. */
  46. let detectGoogleDotCom = function (success, failure) {
  47. Promise.race([
  48. fetch('https://clients2.google.com/service/update2/crx'),
  49. new Promise(function (resolve, reject) {
  50. setTimeout(() => reject(new Error('request timeout')), 2000)
  51. })])
  52. .then((data) => {
  53. success && success();
  54. }).catch(() => {
  55. failure && failure();
  56. });
  57. };
  58. /**
  59. * 从google官方渠道下载chrome扩展
  60. * @param crxId 需要下载的extension id
  61. * @param crxName 扩展名称
  62. * @param callback 下载动作结束后的回调
  63. */
  64. let downloadCrxFileByCrxId = function (crxId, crxName, callback) {
  65. detectGoogleDotCom(() => {
  66. // google可以正常访问,则正常下载
  67. let url = "https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D"
  68. + crxId + "%26uc&prodversion=" + navigator.userAgent.split("Chrome/")[1].split(" ")[0];
  69. if (!chrome.downloads) {
  70. let a = document.createElement('a');
  71. a.href = url;
  72. a.download = crxName || (crxId + '.crx');
  73. (document.body || document.documentElement).appendChild(a);
  74. a.click();
  75. a.remove();
  76. } else {
  77. chrome.downloads.download({
  78. url: url,
  79. filename: crxName || crxId,
  80. conflictAction: 'overwrite',
  81. saveAs: true
  82. }, function (downloadId) {
  83. if (chrome.runtime.lastError) {
  84. notifyText('抱歉,下载失败!错误信息:' + chrome.runtime.lastError.message);
  85. }
  86. });
  87. }
  88. }, () => {
  89. // google不能正常访问
  90. callback ? callback() : notifyText('抱歉,下载失败!');
  91. });
  92. };
  93. /**
  94. * 从chrome webstore下载crx文件
  95. * 在chrome extension详情页使用
  96. */
  97. let downloadCrxFileFromWebStoreDetailPage = function (callback) {
  98. chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
  99. let tab = tabs[0];
  100. let crxId = tab.url.split("/")[6].split('?')[0];
  101. let crxName = tab.title.split(" - Chrome")[0] + ".crx";
  102. crxName = crxName.replace(/[&\/\\:"*<>|?]/g, '');
  103. downloadCrxFileByCrxId(crxId, crxName, callback);
  104. });
  105. };
  106. /**
  107. * 通过右键菜单下载或者分享crx
  108. * @param tab
  109. * @private
  110. */
  111. let _downloadCrx = function (tab) {
  112. let isWebStoreDetailPage = tab.url.indexOf('https://chrome.google.com/webstore/detail/') === 0;
  113. if (isWebStoreDetailPage) {
  114. // 如果是某个chrome extension的详情页面了,直接下载当前crx文件
  115. downloadCrxFileFromWebStoreDetailPage(() => {
  116. notifyText('下载失败,可能是当前网络无法访问Google站点!');
  117. });
  118. } else {
  119. // 否则,下载FeHelper并分享出去
  120. let crxId = MSG_TYPE.STABLE_EXTENSION_ID;
  121. let crxName = chrome.runtime.getManifest().name + '-latestVersion.crx';
  122. downloadCrxFileByCrxId(crxId, crxName, () => {
  123. chrome.tabs.create({
  124. url: MSG_TYPE.DOWNLOAD_FROM_GITHUB
  125. });
  126. });
  127. }
  128. };
  129. return {
  130. downloadCrx: _downloadCrx
  131. };
  132. })();