]> git.gir.st - VimFx.git/blob - extension/lib/options.coffee
Introduce a `VimFx` instance to hold global state
[VimFx.git] / extension / lib / options.coffee
1 ###
2 # Copyright Simon Lydell 2013, 2014.
3 # Copyright Wang Zhuochun 2013.
4 #
5 # This file is part of VimFx.
6 #
7 # VimFx is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # VimFx is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
19 ###
20
21 utils = require('./utils')
22 defaults = require('./defaults')
23 help = require('./help')
24 _ = require('./l10n')
25
26 observe = (options) ->
27 observer = new Observer(defaults, validators, options)
28 observer.hooks.injectSettings = setupCustomizeButton
29
30 Services.obs.addObserver(observer, 'addon-options-displayed', false)
31 Services.obs.addObserver(observer, 'addon-options-hidden', false)
32
33 module.onShutdown(->
34 Services.obs.removeObserver(observer, 'addon-options-displayed')
35 Services.obs.removeObserver(observer, 'addon-options-hidden')
36 )
37
38 class Observer
39 constructor: (@defaults, @validators, @options) ->
40 @document = null
41 @container = null
42 @listeners = []
43 @hooks = {}
44
45 useCapture: false
46
47 listen: (element, event, action) ->
48 element.addEventListener(event, action, @useCapture)
49 @listeners.push([element, event, action, @useCapture])
50
51 unlisten: ->
52 for [element, event, action, useCapture] in @listeners
53 element.removeEventListener(event, action, useCapture)
54 @listeners.length = 0
55
56 typeMap:
57 string: 'string'
58 number: 'integer'
59 boolean: 'bool'
60
61 injectSettings: ->
62 @container = @document.getElementById('detail-rows')
63
64 for key, value of @defaults.options
65 desc = _("pref_#{ key }_desc")
66 if typeof value == 'string' and value != ''
67 desc += "\n#{ _('prefs_default', value) }"
68 setting = utils.createElement(@document, 'setting', {
69 pref: "#{ @defaults.BRANCH }#{ key }"
70 type: @typeMap[typeof value]
71 title: _("pref_#{ key }_title")
72 desc: desc.trim()
73 })
74 @listen(setting, 'change', @validators[key]) if key of @validators
75 @container.appendChild(setting)
76
77 @hooks.injectSettings?.call(this)
78
79 @container.querySelector('setting').setAttribute('first-row', 'true')
80
81 observe: (@document, topic, addonId) ->
82 return unless addonId == @options.ID
83 switch topic
84 when 'addon-options-displayed'
85 @injectSettings()
86 when 'addon-options-hidden'
87 @unlisten()
88
89 setupCustomizeButton = ->
90 shortcuts = utils.createElement(@document, 'setting', {
91 type: 'control',
92 title: _('prefs_customize_shortcuts_title')
93 })
94 button = utils.createElement(@document, 'button', {
95 label: _('prefs_customize_shortcuts_label')
96 })
97 shortcuts.appendChild(button)
98 @listen(button, 'command',
99 help.injectHelp.bind(undefined, @document, @options))
100 @container.appendChild(shortcuts)
101
102 filterChars = (event) ->
103 input = event.target
104 input.value = utils.removeDuplicateCharacters(input.value).replace(/\s/g, '')
105 input.valueToPreference()
106
107 validatePatterns = (event) ->
108 input = event.target
109 input.value =
110 utils.removeDuplicates(utils.splitListString(input.value))
111 .filter((pattern) -> pattern != '')
112 .join(',')
113 input.valueToPreference()
114
115 validators =
116 'hint_chars': filterChars
117 'black_list': utils.updateBlacklist
118 'prev_patterns': validatePatterns
119 'next_patterns': validatePatterns
120
121 exports.observe = observe
Imprint / Impressum