Extension List Generator

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

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