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 # This file parses string prefs into more easily used data structures.
22 defaults = require('./defaults')
23 prefs = require('./prefs')
24 utils = require('./utils')
26 MIN_NUM_HINT_CHARS = 2
29 # Parsed options are not stored in Firefox’s prefs system, and are therefore
30 # always read from the defaults. The only way to override them is via the
32 if pref of defaults.parsed_options
33 return defaults.parsed_options[pref]
35 value = prefs.get(pref)
38 {parsed, normalized} = parsers[pref](value, defaults.all_options[pref])
39 if normalized? and normalized != value and prefs.has(pref)
40 prefs.set(pref, normalized)
45 # Splits a whitespace delimited string into an array, with empty elements and
46 # duplicates filtered.
47 parseSpaceDelimitedString = (value) ->
48 parsed = utils.removeDuplicates(value.split(/\s+/)).filter(Boolean)
49 return {parsed, normalized: parsed.join(' ')}
51 parsePatterns = (value) ->
52 result = parseSpaceDelimitedString(value)
53 # The patterns are case insensitive regexes and must match either in the
54 # beginning or at the end of a string. They do not match in the middle of
55 # words, so "previous" does not match "previously" (`previous\S*` can be used
56 # for that case). Note: `\s` is used instead of `\b` since it works better
57 # with non-English characters.
58 result.parsed = result.parsed.map((pattern) ->
61 RegExp(pattern).source
63 utils.regexEscape(pattern)
65 ^\s* (?:#{patternRegex}) (?:\s|$)
67 (?:\s|^) (?:#{patternRegex}) \s*$
73 hint_chars: (value, defaultValue) ->
74 parsed = utils.removeDuplicateCharacters(value).replace(/\s/g, '')
75 # Make sure that hint chars contain at least the required amount of chars.
76 if parsed.length < MIN_NUM_HINT_CHARS
77 parsed = defaultValue[...MIN_NUM_HINT_CHARS]
78 return {parsed, normalized: parsed}
80 prev_patterns: parsePatterns
81 next_patterns: parsePatterns
83 black_list: (value) ->
84 result = parseSpaceDelimitedString(value)
85 result.parsed = result.parsed.map((pattern) ->
86 return ///^#{utils.regexEscape(pattern).replace(/\\\*/g, '.*')}$///i
90 prevent_autofocus_modes: parseSpaceDelimitedString
92 adjustable_element_keys: parseSpaceDelimitedString
93 activatable_element_keys: parseSpaceDelimitedString
95 pattern_attrs: parseSpaceDelimitedString
97 module.exports = parsePref