]> git.gir.st - VimFx.git/blob - extension/lib/main.coffee
remove workarounds for legacy browsers
[VimFx.git] / extension / lib / main.coffee
1 # This file pulls in all the different parts of VimFx, initializes them, and
2 # stiches them together.
3
4 button = require('./button')
5 config = require('./config')
6 defaults = require('./defaults')
7 help = require('./help')
8 {applyMigrations} = require('./legacy')
9 MarkerContainer = require('./marker-container')
10 messageManager = require('./message-manager')
11 migrations = require('./migrations')
12 modes = require('./modes')
13 options = require('./options')
14 {parsePref} = require('./parse-prefs')
15 prefs = require('./prefs')
16 UIEventManager = require('./events')
17 utils = require('./utils')
18 VimFx = require('./vimfx')
19 # @if TESTS
20 test = require('../test/index')
21 # @endif
22
23 module.exports = (data, reason) ->
24 # Set default prefs and apply migrations as early as possible.
25 prefs.default.init()
26 applyMigrations(migrations)
27
28 parsedOptions = {}
29 for pref of defaults.all_options
30 parsedOptions[pref] = parsePref(pref)
31 vimfx = new VimFx(modes, parsedOptions)
32 vimfx.id = data.id
33 vimfx.version = data.version
34
35 utils.loadCss("#{ADDON_PATH}/skin/style.css")
36
37 options.observe(vimfx)
38
39 prefs.observe('', (pref) ->
40 if pref.startsWith('mode.') or pref.startsWith('custom.')
41 vimfx.createKeyTrees()
42 else if pref of defaults.all_options
43 value = parsePref(pref)
44 vimfx.options[pref] = value
45 )
46
47 button.injectButton(vimfx)
48
49 setWindowAttribute = (window, name, value) ->
50 window.document.documentElement.setAttribute("vimfx-#{name}", value)
51
52 onModeDisplayChange = (data) ->
53 window = data.vim?.window ? data.event.originalTarget.ownerGlobal
54
55 # The 'modeChange' event provides the `vim` object that changed mode, but
56 # it might not be the current `vim` anymore so always get the current one.
57 return unless vim = vimfx.getCurrentVim(window)
58
59 setWindowAttribute(window, 'mode', vim.mode)
60 vimfx.emit('modeDisplayChange', {vim})
61
62 vimfx.on('modeChange', onModeDisplayChange)
63 vimfx.on('TabSelect', onModeDisplayChange)
64
65 vimfx.on('focusTypeChange', ({vim}) ->
66 setWindowAttribute(vim.window, 'focus-type', vim.focusType)
67 )
68
69 # `config.load` sends a 'loadConfig' message to all frame scripts, but it is
70 # intenionally run _before_ the frame scripts are loaded. Even if it is run
71 # after the frame scripts have been `messageManager.load`ed, we cannot know
72 # when it is ready to receive messages. Instead, the frame scripts trigger
73 # their 'loadConfig' code manually.
74 config.load(vimfx)
75 vimfx.on('shutdown', -> messageManager.send('unloadConfig'))
76
77 # Since VimFx has its own Caret mode, it doesn’t make much sense having
78 # Firefox’s Caret mode always own, so make sure that it is disabled (or
79 # enabled if the user has chosen to explicitly have it always on.)
80 vimfx.resetCaretBrowsing()
81
82 module.onShutdown(->
83 # Make sure that users are not left with Firefox’s own Caret mode
84 # accidentally enabled.
85 vimfx.resetCaretBrowsing()
86
87 # Make sure to run the below lines in this order. The second line results in
88 # removing all message listeners in frame scripts, including the one for
89 # 'unloadConfig' (see above).
90 vimfx.emit('shutdown')
91 messageManager.send('shutdown')
92 )
93
94 windows = new WeakSet()
95 messageManager.listen('tabCreated', (data, callback, browser) ->
96 # Frame scripts are run in more places than we need. Tell those not to do
97 # anything.
98 unless browser.getAttribute('messagemanagergroup') == 'browsers'
99 callback(false)
100 return
101
102 window = browser.ownerGlobal
103 vimfx.addVim(browser)
104
105 unless windows.has(window)
106 windows.add(window)
107 eventManager = new UIEventManager(vimfx, window)
108 eventManager.addListeners(vimfx, window)
109 setWindowAttribute(window, 'mode', 'normal')
110 setWindowAttribute(window, 'focus-type', 'none')
111 module.onShutdown(->
112 MarkerContainer.remove(window)
113 help.removeHelp(window)
114 )
115
116 # check whether Fission is enabled, and warn the user if so.
117 FISSION_ENABLED_PREF = 'fission.autostart'
118 FISSION_ISOLATION_PREF = 'fission.webContentIsolationStrategy'
119 IGNORE_FISSION_PREF = 'ignore_fission'
120 isFissionWindow = window.docShell.nsILoadContext.useRemoteSubframes
121 isFissionEnabled = prefs.root.get(FISSION_ENABLED_PREF)
122 isIsolateNothing = (try prefs.root.get(FISSION_ISOLATION_PREF)) == 0
123 isFissionIgnored = (try prefs.get(IGNORE_FISSION_PREF)) == true
124 if isFissionWindow and isFissionEnabled and not isIsolateNothing and
125 not isFissionIgnored
126 console.error('VimFx: Fission is enabled in your browser.'
127 'VimFx will not be able to interact with third party iframes.')
128 docs = "#{HOMEPAGE}/blob/master/documentation/known-bugs.md#fission"
129 console.info("Please consult VimFx' documentation: #{docs}")
130
131 callback(true)
132 )
133
134 # For tabs not visited yet since a session restore (“pending” tabs), Firefox
135 # seems to not load the frame script immediately, but instead remember the URI
136 # and load it when the user eventually visits that tab. If VimFx is updated
137 # during that time this means that the below URI is saved several times, and
138 # will be loaded that many times. Therefore the URI is changed with each
139 # build, causing remembered URIs to point to non-existent files.
140 messageManager.load("#{ADDON_PATH}/content/bootstrap-frame-#{BUILD_TIME}.js")
141
142 # @if TESTS
143 runTests = true
144 messageManager.listen('runTests', (data, callback) ->
145 # Running the regular tests inside this callback means that there will be a
146 # `window` available for tests, if they need one.
147 test(vimfx) if runTests
148 callback(runTests)
149 runTests = false
150 )
151 # @endif
Imprint / Impressum