]> git.gir.st - VimFx.git/blob - extension/lib/main.coffee
Port settings page to a modern format
[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 {AddonManager} = Cu.import('resource://gre/modules/AddonManager.jsm', {})
24
25 module.exports = (data, reason) ->
26 # Set default prefs and apply migrations as early as possible.
27 prefs.default.init()
28 applyMigrations(migrations)
29
30 parsedOptions = {}
31 for pref of defaults.all_options
32 parsedOptions[pref] = parsePref(pref)
33 vimfx = new VimFx(modes, parsedOptions)
34 vimfx.id = data.id
35 vimfx.version = data.version
36 AddonManager.getAddonByID(vimfx.id).then( (info) -> vimfx.info = info )
37
38 utils.loadCss("#{ADDON_PATH}/skin/style.css")
39
40 options.observe(vimfx)
41
42 prefs.observe('', (pref) ->
43 if pref.startsWith('mode.') or pref.startsWith('custom.')
44 vimfx.createKeyTrees()
45 else if pref of defaults.all_options
46 value = parsePref(pref)
47 vimfx.options[pref] = value
48 )
49
50 button.injectButton(vimfx)
51
52 setWindowAttribute = (window, name, value) ->
53 window.document.documentElement.setAttribute("vimfx-#{name}", value)
54
55 onModeDisplayChange = (data) ->
56 window = data.vim?.window ? data.event.originalTarget.ownerGlobal
57
58 # The 'modeChange' event provides the `vim` object that changed mode, but
59 # it might not be the current `vim` anymore so always get the current one.
60 return unless vim = vimfx.getCurrentVim(window)
61
62 setWindowAttribute(window, 'mode', vim.mode)
63 vimfx.emit('modeDisplayChange', {vim})
64
65 vimfx.on('modeChange', onModeDisplayChange)
66 vimfx.on('TabSelect', onModeDisplayChange)
67
68 vimfx.on('focusTypeChange', ({vim}) ->
69 setWindowAttribute(vim.window, 'focus-type', vim.focusType)
70 )
71
72 # `config.load` sends a 'loadConfig' message to all frame scripts, but it is
73 # intenionally run _before_ the frame scripts are loaded. Even if it is run
74 # after the frame scripts have been `messageManager.load`ed, we cannot know
75 # when it is ready to receive messages. Instead, the frame scripts trigger
76 # their 'loadConfig' code manually.
77 config.load(vimfx)
78 vimfx.on('shutdown', -> messageManager.send('unloadConfig'))
79
80 # Since VimFx has its own Caret mode, it doesn’t make much sense having
81 # Firefox’s Caret mode always own, so make sure that it is disabled (or
82 # enabled if the user has chosen to explicitly have it always on.)
83 vimfx.resetCaretBrowsing()
84
85 module.onShutdown(->
86 # Make sure that users are not left with Firefox’s own Caret mode
87 # accidentally enabled.
88 vimfx.resetCaretBrowsing()
89
90 # Make sure to run the below lines in this order. The second line results in
91 # removing all message listeners in frame scripts, including the one for
92 # 'unloadConfig' (see above).
93 vimfx.emit('shutdown')
94 messageManager.send('shutdown')
95 )
96
97 windows = new WeakSet()
98 messageManager.listen('tabCreated', (data, callback, browser) ->
99 # Frame scripts are run in more places than we need. Tell those not to do
100 # anything.
101 unless browser.getAttribute('messagemanagergroup') == 'browsers'
102 callback(false)
103 return
104
105 window = browser.ownerGlobal
106 vimfx.addVim(browser)
107
108 unless windows.has(window)
109 windows.add(window)
110 eventManager = new UIEventManager(vimfx, window)
111 eventManager.addListeners(vimfx, window)
112 setWindowAttribute(window, 'mode', 'normal')
113 setWindowAttribute(window, 'focus-type', 'none')
114 module.onShutdown(->
115 MarkerContainer.remove(window)
116 help.removeHelp(window)
117 )
118
119 callback(true)
120 )
121
122 # For tabs not visited yet since a session restore (“pending” tabs), Firefox
123 # seems to not load the frame script immediately, but instead remember the URI
124 # and load it when the user eventually visits that tab. If VimFx is updated
125 # during that time this means that the below URI is saved several times, and
126 # will be loaded that many times. Therefore the URI is changed with each
127 # build, causing remembered URIs to point to non-existent files.
128 messageManager.load("#{ADDON_PATH}/content/bootstrap-frame-#{BUILD_TIME}.js")
129
130 # @if TESTS
131 runTests = true
132 messageManager.listen('runTests', (data, callback) ->
133 # Running the regular tests inside this callback means that there will be a
134 # `window` available for tests, if they need one.
135 test(vimfx) if runTests
136 callback(runTests)
137 runTests = false
138 )
139 # @endif
Imprint / Impressum