index.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. 'use strict'
  2. var fs = require('fs')
  3. var path = require('path')
  4. var PREFS = [
  5. 'user_pref("browser.shell.checkDefaultBrowser", false);',
  6. 'user_pref("browser.bookmarks.restore_default_bookmarks", false);',
  7. 'user_pref("dom.disable_open_during_load", false);',
  8. 'user_pref("dom.max_script_run_time", 0);',
  9. 'user_pref("dom.min_background_timeout_value", 10);',
  10. 'user_pref("extensions.autoDisableScopes", 0);',
  11. 'user_pref("browser.tabs.remote.autostart", false);',
  12. 'user_pref("browser.tabs.remote.autostart.2", false);',
  13. 'user_pref("extensions.enabledScopes", 15);'
  14. ].join('\n')
  15. // Get all possible Program Files folders even on other drives
  16. // inspect the user's path to find other drives that may contain Program Files folders
  17. var getAllPrefixes = function () {
  18. var drives = []
  19. var paden = process.env.Path.split(';')
  20. var re = /^[A-Z]:\\/i
  21. var pad
  22. for (var p = 0; p < paden.length; p++) {
  23. pad = paden[p]
  24. if (re.test(pad) && drives.indexOf(pad[0]) === -1) {
  25. drives.push(pad[0])
  26. }
  27. }
  28. var result = []
  29. var prefixes = [process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']]
  30. var prefix
  31. for (var i = 0; i < prefixes.length; i++) {
  32. if (typeof prefixes[i] !== 'undefined') {
  33. for (var d = 0; d < drives.length; d += 1) {
  34. prefix = drives[d] + prefixes[i].substr(1)
  35. if (result.indexOf(prefix) === -1) {
  36. result.push(prefix)
  37. }
  38. }
  39. }
  40. }
  41. return result
  42. }
  43. // Return location of firefox.exe file for a given Firefox directory
  44. // (available: "Mozilla Firefox", "Aurora", "Nightly").
  45. var getFirefoxExe = function (firefoxDirName) {
  46. if (process.platform !== 'win32' && process.platform !== 'win64') {
  47. return null
  48. }
  49. var prefix
  50. var prefixes = getAllPrefixes()
  51. var suffix = '\\' + firefoxDirName + '\\firefox.exe'
  52. for (var i = 0; i < prefixes.length; i++) {
  53. prefix = prefixes[i]
  54. if (fs.existsSync(prefix + suffix)) {
  55. return prefix + suffix
  56. }
  57. }
  58. return 'C:\\Program Files' + suffix
  59. }
  60. var getFirefoxWithFallbackOnOSX = function () {
  61. if (process.platform !== 'darwin') {
  62. return null
  63. }
  64. var firefoxDirNames = Array.prototype.slice.call(arguments)
  65. var prefix = '/Applications/'
  66. var suffix = '.app/Contents/MacOS/firefox-bin'
  67. var bin
  68. var homeBin
  69. for (var i = 0; i < firefoxDirNames.length; i++) {
  70. bin = prefix + firefoxDirNames[i] + suffix
  71. if ('HOME' in process.env) {
  72. homeBin = path.join(process.env.HOME, bin)
  73. if (fs.existsSync(homeBin)) {
  74. return homeBin
  75. }
  76. }
  77. if (fs.existsSync(bin)) {
  78. return bin
  79. }
  80. }
  81. }
  82. var makeHeadlessVersion = function (Browser) {
  83. var HeadlessBrowser = function () {
  84. Browser.apply(this, arguments)
  85. var execCommand = this._execCommand
  86. this._execCommand = function (command, args) {
  87. // --start-debugger-server ws:6000 can also be used, since remote debugging protocol also speaks WebSockets
  88. // https://hacks.mozilla.org/2017/12/using-headless-mode-in-firefox/
  89. execCommand.call(this, command, args.concat(['-headless', '--start-debugger-server 6000']))
  90. }
  91. }
  92. HeadlessBrowser.prototype = Object.create(Browser.prototype, {
  93. name: { value: Browser.prototype.name + 'Headless' }
  94. })
  95. HeadlessBrowser.$inject = Browser.$inject
  96. return HeadlessBrowser
  97. }
  98. // https://developer.mozilla.org/en-US/docs/Command_Line_Options
  99. var FirefoxBrowser = function (id, baseBrowserDecorator, args) {
  100. baseBrowserDecorator(this)
  101. this._getPrefs = function (prefs) {
  102. if (typeof prefs !== 'object') {
  103. return PREFS
  104. }
  105. var result = PREFS
  106. for (var key in prefs) {
  107. result += 'user_pref("' + key + '", ' + JSON.stringify(prefs[key]) + ');\n'
  108. }
  109. return result
  110. }
  111. this._start = function (url) {
  112. var self = this
  113. var command = this._getCommand()
  114. var profilePath = args.profile || self._tempDir
  115. var flags = args.flags || []
  116. var extensionsDir
  117. if (Array.isArray(args.extensions)) {
  118. extensionsDir = path.resolve(profilePath, 'extensions')
  119. fs.mkdirSync(extensionsDir)
  120. args.extensions.forEach(function (ext) {
  121. var extBuffer = fs.readFileSync(ext)
  122. var copyDestination = path.resolve(extensionsDir, path.basename(ext))
  123. fs.writeFileSync(copyDestination, extBuffer)
  124. })
  125. }
  126. fs.writeFileSync(profilePath + '/prefs.js', this._getPrefs(args.prefs))
  127. self._execCommand(
  128. command,
  129. [url, '-profile', profilePath, '-no-remote'].concat(flags)
  130. )
  131. }
  132. }
  133. FirefoxBrowser.prototype = {
  134. name: 'Firefox',
  135. DEFAULT_CMD: {
  136. linux: 'firefox',
  137. freebsd: 'firefox',
  138. darwin: getFirefoxWithFallbackOnOSX('Firefox'),
  139. win32: getFirefoxExe('Mozilla Firefox')
  140. },
  141. ENV_CMD: 'FIREFOX_BIN'
  142. }
  143. FirefoxBrowser.$inject = ['id', 'baseBrowserDecorator', 'args']
  144. var FirefoxHeadlessBrowser = makeHeadlessVersion(FirefoxBrowser)
  145. var FirefoxDeveloperBrowser = function () {
  146. FirefoxBrowser.apply(this, arguments)
  147. }
  148. FirefoxDeveloperBrowser.prototype = {
  149. name: 'FirefoxDeveloper',
  150. DEFAULT_CMD: {
  151. linux: 'firefox',
  152. darwin: getFirefoxWithFallbackOnOSX('FirefoxDeveloperEdition', 'FirefoxAurora'),
  153. win32: getFirefoxExe('Firefox Developer Edition')
  154. },
  155. ENV_CMD: 'FIREFOX_DEVELOPER_BIN'
  156. }
  157. FirefoxDeveloperBrowser.$inject = ['id', 'baseBrowserDecorator', 'args']
  158. var FirefoxDeveloperHeadlessBrowser = makeHeadlessVersion(FirefoxDeveloperBrowser)
  159. var FirefoxAuroraBrowser = function () {
  160. FirefoxBrowser.apply(this, arguments)
  161. }
  162. FirefoxAuroraBrowser.prototype = {
  163. name: 'FirefoxAurora',
  164. DEFAULT_CMD: {
  165. linux: 'firefox',
  166. darwin: getFirefoxWithFallbackOnOSX('FirefoxAurora'),
  167. win32: getFirefoxExe('Aurora')
  168. },
  169. ENV_CMD: 'FIREFOX_AURORA_BIN'
  170. }
  171. FirefoxAuroraBrowser.$inject = ['id', 'baseBrowserDecorator', 'args']
  172. var FirefoxAuroraHeadlessBrowser = makeHeadlessVersion(FirefoxAuroraBrowser)
  173. var FirefoxNightlyBrowser = function () {
  174. FirefoxBrowser.apply(this, arguments)
  175. }
  176. FirefoxNightlyBrowser.prototype = {
  177. name: 'FirefoxNightly',
  178. DEFAULT_CMD: {
  179. linux: 'firefox',
  180. darwin: getFirefoxWithFallbackOnOSX('FirefoxNightly'),
  181. win32: getFirefoxExe('Nightly')
  182. },
  183. ENV_CMD: 'FIREFOX_NIGHTLY_BIN'
  184. }
  185. FirefoxNightlyBrowser.$inject = ['id', 'baseBrowserDecorator', 'args']
  186. var FirefoxNightlyHeadlessBrowser = makeHeadlessVersion(FirefoxNightlyBrowser)
  187. // PUBLISH DI MODULE
  188. module.exports = {
  189. 'launcher:Firefox': ['type', FirefoxBrowser],
  190. 'launcher:FirefoxHeadless': ['type', FirefoxHeadlessBrowser],
  191. 'launcher:FirefoxDeveloper': ['type', FirefoxDeveloperBrowser],
  192. 'launcher:FirefoxDeveloperHeadless': ['type', FirefoxDeveloperHeadlessBrowser],
  193. 'launcher:FirefoxAurora': ['type', FirefoxAuroraBrowser],
  194. 'launcher:FirefoxAuroraHeadless': ['type', FirefoxAuroraHeadlessBrowser],
  195. 'launcher:FirefoxNightly': ['type', FirefoxNightlyBrowser],
  196. 'launcher:FirefoxNightlyHeadless': ['type', FirefoxNightlyHeadlessBrowser]
  197. }