2 # Copyright Simon Lydell 2015.
4 # This file is part of VimFx.
6 # VimFx is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # VimFx is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
20 defaults = require('./defaults')
21 translate = require('./l10n')
22 prefs = require('./prefs')
23 utils = require('./utils')
31 observe = (options) ->
32 observer = new Observer(options)
33 utils.observe('addon-options-displayed', observer)
34 utils.observe('addon-options-hidden', observer)
39 # Generalized observer.
41 constructor: (@options) ->
48 listen: (element, event, action) ->
49 element.addEventListener(event, action, @useCapture)
50 @listeners.push([element, event, action, @useCapture])
53 for [element, event, action, useCapture] in @listeners
54 element.removeEventListener(event, action, useCapture)
57 type: (value) -> TYPE_MAP[typeof value]
61 appendSetting: (attributes) ->
62 setting = @document.createElement('setting')
63 utils.setAttributes(setting, attributes)
64 @container.appendChild(setting)
67 observe: (@document, topic, addonId) ->
68 return unless addonId == @options.id
70 when 'addon-options-displayed'
72 when 'addon-options-hidden'
76 @container = @document.getElementById('detail-rows')
82 # VimFx specific observer.
83 class Observer extends BaseObserver
84 constructor: (@vimfx) ->
85 super({id: @vimfx.id})
94 injectInstructions: ->
97 title: translate('prefs_instructions_title')
98 desc: translate('prefs_instructions_desc',
99 @vimfx.options['options.key.quote'],
100 @vimfx.options['options.key.insert_default'],
101 @vimfx.options['options.key.reset_default'],
107 for key, value of defaults.options
108 setting = @appendSetting({
109 pref: "#{ defaults.BRANCH }#{ key }"
111 title: translate("pref_#{ key }_title")
112 desc: translate("pref_#{ key }_desc")
117 for mode in @vimfx.getGroupedCommands()
124 for category in mode.categories
132 for { command } in category.commands
136 title: command.description()
137 desc: @generateErrorMessage(command.pref)
143 generateErrorMessage: (pref) ->
144 commandErrors = @vimfx.errors[pref] ? []
145 return commandErrors.map(({ id, context, subject }) ->
146 return translate("error_#{ id }", context ? subject, subject)
151 @listen(@container, 'keydown', (event) =>
152 setting = event.target
153 isString = (setting.type == 'string')
155 { input, pref } = setting
156 keyString = @vimfx.stringifyKeyEvent(event)
158 # Some shortcuts only make sense for string settings. We still match
159 # those shortcuts and suppress the default behavior for _all_ types of
160 # settings for consistency. For example, pressing <c-d> in a number input
161 # (which looks like a text input) would otherwise bookmark the page, and
162 # <c-q> would close the window!
167 break unless isString
168 utils.insertText(input, keyString)
170 when keyString == @vimfx.options['options.key.quote']
171 break unless isString
173 when keyString == @vimfx.options['options.key.insert_default']
174 break unless isString
175 utils.insertText(input, prefs.root.default.get(pref))
176 when keyString == @vimfx.options['options.key.reset_default']
177 prefs.root.set(pref, null)
181 event.preventDefault()
182 setting.valueToPreference()
183 @refreshShortcutErrors()
185 @listen(@container, 'blur', -> quote = false)
188 @listen(@container, 'input', (event) =>
189 setting = event.target
190 # Disable default behavior of updating the pref of the setting on each
191 # input. Do it on the 'change' event instead (see below), because all
192 # settings are validated and auto-adjusted as soon as the pref changes.
193 event.stopPropagation()
194 if setting.classList.contains('is-shortcut')
195 # However, for the shortcuts we _do_ want live validation, because they
196 # cannot be auto-adjusted. Instead an error message is shown.
197 setting.valueToPreference()
198 @refreshShortcutErrors()
200 @listen(@container, 'change', (event) ->
201 setting = event.target
202 unless setting.classList.contains('is-shortcut')
203 setting.valueToPreference()
207 refreshShortcutErrors: ->
208 for setting in @container.getElementsByClassName('is-shortcut')
209 setting.setAttribute('desc', @generateErrorMessage(setting.pref))