Extension List Generator

For Scriptish only. Generate list of enabled extensions from Add-ons Manager to HTML, Markdown, BBCode or plain text output.

当前为 2014-02-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @id extension-list-generator@loucypher
  3. // @name Extension List Generator
  4. // @description For Scriptish only. Generate list of enabled extensions from Add-ons Manager to HTML, Markdown, BBCode or plain text output.
  5. // @namespace https://greasyfork.org/scripts/13
  6. // @version 1.20140221232908
  7. // @author LouCypher
  8. // @license MPL 2.0
  9. // @screenshot https://lh3.googleusercontent.com/-T1PPKIZoT1M/UW7tiMF0rWI/AAAAAAAADfY/XWzdfEDgtD4/s0/extension-list-generator.png
  10. // @icon https://addons.cdn.mozilla.net/media/img/addon-icons/default-32.png
  11. // @icon64URL https://addons.cdn.mozilla.net/media/img/addon-icons/default-64.png
  12. // @contributionURL http://loucypher.github.io/userscripts/donate.html?Extensions+List+Generator
  13. // @homepageURL https://greasyfork.org/scripts/13
  14. // @supportURL https://greasyfork.org/scripts/13
  15. // @updateURL https://greasyfork.org/scripts/13/code.meta.js
  16. // @downloadURL https://greasyfork.org/scripts/13/code.user.js
  17. // @resource options https://raw.github.com/LouCypher/userscripts/master/scriptish/extension-list-generator/options.xul
  18. // @resource CHANGELOG https://raw.github.com/LouCypher/userscripts/master/scriptish/extension-list-generator/changelog.txt
  19. // @resource LICENSE https://raw.github.com/LouCypher/userscripts/master/licenses/MPL/LICENSE.txt
  20. // @include about:addons
  21. // @include chrome://mozapps/content/extensions/extensions.xul
  22. // ==/UserScript==
  23. /*
  24. * This Source Code Form is subject to the terms of the Mozilla Public
  25. * License, v. 2.0. If a copy of the MPL was not distributed with this
  26. * file, you can obtain one at http://mozilla.org/MPL/2.0/.
  27. *
  28. */
  29.  
  30.  
  31.  
  32. var utilsMenu = document.getElementById("utils-menu");
  33. utilsMenu.appendChild(document.createElement("menuseparator"));
  34.  
  35. var menu = utilsMenu.appendChild(document.createElement("menu"));
  36. menu.setAttribute("label", "Generate extension list");
  37.  
  38. var menupopup = menu.appendChild(document.createElement("menupopup"));
  39.  
  40. ["HTML", "Markdown", "BBCode", "Plain text"].forEach(function(format) {
  41. var menuitem = menupopup.appendChild(document.createElement("menuitem"));
  42. menuitem.setAttribute("label", format);
  43. })
  44.  
  45. menupopup.appendChild(document.createElement("menuseparator"));
  46.  
  47. var optionsMenu = menupopup.appendChild(document.createElement("menuitem"));
  48. optionsMenu.setAttribute("label", "Options");
  49. optionsMenu.addEventListener("command", openOptions, false);
  50.  
  51. menupopup.addEventListener("command", generate, false);
  52.  
  53. var rptCurrentDate, rptAddonsURLs, rptAddonsDescs, rptThemeScreenshot,
  54. rptInsideSpoiler;
  55.  
  56. initPrefs();
  57.  
  58. function generate(aEvent) {
  59. if (aEvent.target.getAttribute("label") == "Options") return;
  60. initPrefs();
  61. AddonManager.getAddonsByTypes(["theme", "extension"], function(addons) {
  62. var theme;
  63. var extArray = [];
  64. addons.forEach(function(addon) {
  65. if (addon.isActive) {
  66. if (addon.type == "theme") theme = addon;
  67. else extArray.push(addon);
  68. }
  69. })
  70. extArray.sort(function(a, b) {
  71. a = a.name.toLowerCase();
  72. b = b.name.toLowerCase();
  73. if (a < b) return -1;
  74. if (a > b) return 1;
  75. return 0;
  76. })
  77. var title = "My " + Application.name + " information";
  78. switch (aEvent.target.getAttribute("label")) {
  79. case "HTML": generateHTML(title, theme, extArray); break;
  80. case "Markdown": generateMarkdown(title, theme, extArray); break;
  81. case "BBCode": generateBBCode(title, theme, extArray); break;
  82. case "Plain text": generateText(title, theme, extArray);
  83. }
  84. })
  85. }
  86.  
  87. function generateHTML(aTitle, aTheme, aArray) {
  88. var extensions = '<!doctype html><html itemscope="itemscope"'
  89. + ' itemtype="http://schema.org/WebPage"><head>'
  90. + '<meta charset="utf-8"><meta itemprop="description"'
  91. + ' content="' + aTitle + '"><meta name="description"'
  92. + ' content="' + aTitle + '"><title>' + aTitle + '</title>'
  93. + '</head><body><h1>' + aTitle + '</h1>'
  94. + (rptCurrentDate ? "<p>Last updated: " + (new Date()) + "</p>" : "")
  95. + "<h2>User agent</h2><p>" + navigator.userAgent
  96. + "</p><h2>Theme</h2><p>"
  97. + (rptAddonsURLs && !isDefaultTheme(aTheme)
  98. ? '<a href="' + getThemeURL(aTheme) + '">' + aTheme.name + '</a>'
  99. : aTheme.name)
  100. + "</p>"
  101. + (rptThemeScreenshot && !isDefaultTheme(aTheme) &&
  102. aTheme.screenshots && !/getpersonas/.test(aTheme.screenshots)
  103. ? '<p><img src="' + aTheme.screenshots[0].url +
  104. '" alt="' + aTheme.name + '"/></p>'
  105. : "")
  106. + "<h2>Extensions</h2>"
  107. + '<ol style="width:900px">';
  108. aArray.forEach(function(addon) {
  109. extensions += '<li style="margin-bottom:1em">'
  110. + (rptAddonsURLs
  111. ? ((addon.reviewURL
  112. ? '<a href="' + getAMOPage(addon.reviewURL) + '">'
  113. : addon.homepageURL
  114. ? '<a href="' + addon.homepageURL + '">'
  115. : '<a href="http://www.google.com/search?q="' +
  116. encodeURIComponent(addon.name + " extension") +
  117. '">')
  118. + addon.name + '</a>')
  119. : addon.name)
  120. + (addon.version ? " " + addon.version : "")
  121. + (rptAddonsDescs ? "<br/>" + addon.description : "")
  122. + "</li>";
  123. })
  124. extensions += "</ol></body></html>";
  125. doSomething(extensions, "text/html");
  126. }
  127.  
  128. function generateMarkdown(aTitle, aTheme, aArray) {
  129. var idx = 0;
  130. var extensions = "# " + aTitle
  131. + (rptCurrentDate ? "\n\nLast updated: " + (new Date()) : "")
  132. + "\n\n## User agent\n\n" + navigator.userAgent
  133. + "\n\n## Theme\n\n"
  134. + (rptAddonsURLs && !isDefaultTheme(aTheme)
  135. ? "[" + aTheme.name + "](" + getThemeURL(aTheme) + ")"
  136. : aTheme.name)
  137. + (rptThemeScreenshot && !isDefaultTheme(aTheme) &&
  138. aTheme.screenshots && !/getpersonas/.test(aTheme.screenshots)
  139. ? "\n\n![" + aTheme.name + "](" + aTheme.screenshots[0].url + ")"
  140. : "")
  141. + "\n\n## Extensions";
  142. aArray.forEach(function(addon) {
  143. idx++;
  144. extensions += "\n\n" + idx + ". "
  145. + (rptAddonsURLs
  146. ? ((addon.reviewURL
  147. ? "[" + addon.name + "](" + getAMOPage(addon.reviewURL)
  148. : addon.homepageURL
  149. ? "[" + addon.name + "](" + addon.homepageURL
  150. : "[" + addon.name + "](" +
  151. "http://www.google.com/search?q=" +
  152. encodeURIComponent(addon.name + " extension"))
  153. + ")")
  154. : addon.name)
  155. + (addon.version ? " " + addon.version : "")
  156. + (rptAddonsDescs ? " \n" + addon.description : "")
  157. })
  158. doSomething(extensions, "text/plain", "%0A%0A.md");
  159. }
  160.  
  161. function generateBBCode(aTitle, aTheme, aArray) {
  162. var extensions = (rptInsideSpoiler ? "[spoiler=" + aTitle + "]" : "")
  163. + (rptCurrentDate ? "[b]Last updated: [/b]" + (new Date()) : "")
  164. + "\n\n[b]User agent:[/b] " + navigator.userAgent
  165. + "\n\n[b]Theme:[/b] "
  166. + (rptAddonsURLs && !isDefaultTheme(aTheme)
  167. ? "[url=" + getThemeURL(aTheme) + "]" + aTheme.name + "[/url]"
  168. : aTheme.name)
  169. + (rptThemeScreenshot && !isDefaultTheme(aTheme) &&
  170. aTheme.screenshots && !/getpersonas/.test(aTheme.screenshots)
  171. ? "\n[img]" + aTheme.screenshots[0].url + "[/img]"
  172. : "")
  173. + "\n\n[b]Extensions:[/b]\n[list=1]"
  174. aArray.forEach(function(addon) {
  175. extensions += "[*]"
  176. + (rptAddonsURLs
  177. ? ((addon.reviewURL
  178. ? "[url=" + getAMOPage(addon.reviewURL)
  179. : addon.homepageURL
  180. ? "[url=" + addon.homepageURL
  181. : "[url=http://www.google.com/search?q=" +
  182. encodeURIComponent(addon.name + " extension"))
  183. + "]" + addon.name + "[/url]")
  184. : addon.name)
  185. + (addon.version ? " " + addon.version : "")
  186. + (rptAddonsDescs ? "\n" + addon.description : "");
  187. })
  188. extensions += rptInsideSpoiler ? "[/list][/spoiler]" : "[/list]";
  189. doSomething(extensions, "text/plain");
  190. }
  191.  
  192. function generateText(aTitle, aTheme, aArray) {
  193. var idx = 0;
  194. var extensions = aTitle + "\n"
  195. for (var i = 0; i < aTitle.length; i++) {
  196. extensions += "=";
  197. }
  198. extensions += (rptCurrentDate ? "\n\nLast updated: " + (new Date()) : "")
  199. + "\n\nUser agent: " + navigator.userAgent
  200. + "\n\nTheme: " + aTheme.name + "\n\nExtensions\n----------";
  201. aArray.forEach(function(addon) {
  202. idx++;
  203. extensions += "\n" + idx + ". " + addon.name
  204. + (addon.version ? " " + addon.version : "")
  205. + (rptAddonsDescs ? "\n" + addon.description : "")
  206. + (rptAddonsURLs
  207. ? "\n" + (addon.reviewURL ? getAMOPage(addon.reviewURL)
  208. : addon.homepageURL
  209. ? addon.homepageURL
  210. : "")
  211. : "")
  212. + (rptAddonsDescs || rptAddonsURLs ? "\n" : "");
  213. })
  214. doSomething(extensions, "text/plain");
  215. }
  216.  
  217. function isDefaultTheme(aTheme) {
  218. return aTheme.id == "{972ce4c6-7e08-4474-a285-3208198ce6fd}" ||
  219. aTheme.id == "modern@themes.mozilla.org";
  220. }
  221.  
  222. function getAMOPage(aReviewURL) {
  223. var url = aReviewURL.replace(/\/reviews\/.*$/, "/")
  224. .replace(/mozilla.org\/.*\/addon\//, "mozilla.org/addon/");
  225. url += "?src=external-extension-list-generator";
  226. return url;
  227. }
  228.  
  229. function getThemeURL(aAddon) {
  230. var url;
  231. if (aAddon.reviewURL) {
  232. return getAMOPage(aAddon.reviewURL);
  233. } else {
  234. var id = aAddon.id.match(/\d+/).toString();
  235. if (/getpersonas/.test(aAddon.screenshots[0].url)) {
  236. url = "http://getpersonas.com/persona/" + id;
  237. } else {
  238. url = "http://addons.mozilla.org/addon/" + id;
  239. }
  240. }
  241. url += "/?src=external-extension-list-generator";
  242. return url;
  243. }
  244.  
  245. function doSomething(aString, aContentType, aExt) {
  246. var prompts = Services.prompt;
  247. var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_IS_STRING +
  248. prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_CANCEL +
  249. prompts.BUTTON_POS_2 * prompts.BUTTON_TITLE_IS_STRING;
  250. var doWhat = prompts.confirmEx(null, "Extension List Generator",
  251. "Extension list has been generated.", flags,
  252. "Copy", "", "View", null, {value:false});
  253. switch (doWhat) {
  254. case 0: // Copy
  255. Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
  256. .copyString(aString);
  257. Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).
  258. showAlertNotification("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png",
  259. "Extension List Generator", "Copied to clipboard!",
  260. false, "", null);
  261. break;
  262. case 2: // View
  263. openOptionsInTab("data:" + aContentType + ";charset=utf-8," +
  264. encodeURIComponent(aString) + (aExt ? aExt : ""));
  265. default: // Cancel
  266. }
  267. }
  268.  
  269. function getBoolPref(aPrefName, aDefVal) {
  270. var prefRoot = "extensions.scriptish.scriptvals.extension-list-generator@loucypher.report.";
  271. var prefBranch = Services.prefs.getBranch(prefRoot);
  272. try {
  273. return prefBranch.getBoolPref(aPrefName);
  274. } catch(ex) {
  275. prefBranch.setBoolPref(aPrefName, aDefVal);
  276. return aDefVal;
  277. }
  278. }
  279.  
  280. function initPrefs() {
  281. rptCurrentDate = getBoolPref("currentDate", true);
  282. rptAddonsURLs = getBoolPref("addonsURLs", true);
  283. rptAddonsDescs = getBoolPref("addonsDescriptions", false);
  284. rptThemeScreenshot = getBoolPref("themeScreenshot", true);
  285. rptInsideSpoiler = getBoolPref("insideSpoiler", false);
  286. }
  287.  
  288. function openOptions() {
  289. var em = Services.ww.getWindowEnumerator();
  290. var winName = "extension-list-generator-options";
  291. var index = 1;
  292. while (em.hasMoreElements()) {
  293. let win = em.getNext();
  294. if(win.name == winName) {
  295. win.focus();
  296. return;
  297. }
  298. index++
  299. }
  300. openDialog(GM_getResourceURL("options"), winName,
  301. "chrome, dialog, centerscreen, close");
  302. }