]> git.gir.st - VimFx.git/blob - extension/lib/mode-hints/marker.coffee
Remove bloomfilter
[VimFx.git] / extension / lib / mode-hints / marker.coffee
1 ###
2 # Copyright Anton Khodakivskiy 2012, 2013.
3 # Copyright Simon Lydell 2013, 2014.
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 { createElement } = require('../utils')
22
23 # Wraps the markable element and provides methods to manipulate the markers.
24 class Marker
25 # Creates the marker DOM node.
26 constructor: (@element, @elementShape) ->
27 document = @element.ownerDocument
28 @markerElement = createElement(document, 'div', {class: 'VimFxHintMarker'})
29
30 show: -> @setVisibility(true)
31 hide: -> @setVisibility(false)
32 setVisibility: (visible) ->
33 @markerElement.classList.toggle('VimFxHiddenHintMarker', not visible)
34 updateVisibility: ->
35 if @hintChars.startsWith(@enteredHintChars) then @show() else @hide()
36
37 # To be called when the marker has been both assigned a hint and inserted
38 # into the DOM, and thus gotten a height and width.
39 setPosition: (viewport) ->
40 {
41 markerElement: { offsetHeight: height, offsetWidth: width }
42 elementShape: { nonCoveredPoint: { x: left, y: top, offset, rect } }
43 } = this
44
45 # Center the marker vertically on the non-covered point.
46 top -= height / 2
47
48 # Make sure that the marker stays within its element (vertically).
49 top = Math.min(top, rect.bottom - height)
50 top = Math.max(top, rect.top)
51
52 # Make the position relative to the top frame.
53 left += offset.left
54 top += offset.top
55
56 # Make sure that the marker stays within the viewport.
57 left = Math.min(left, viewport.right - width)
58 top = Math.min(top, viewport.bottom - height)
59 left = Math.max(left, viewport.left)
60 top = Math.max(top, viewport.top)
61
62 # Make the position relative to the document, rather than to the viewport.
63 left += viewport.scrollX
64 top += viewport.scrollY
65
66 # The positioning is absolute.
67 @markerElement.style.left = "#{ left }px"
68 @markerElement.style.top = "#{ top }px"
69
70 # For quick access.
71 @position = {
72 left, right: left + width,
73 top, bottom: top + height,
74 height, width
75 }
76
77 setHint: (@hintChars) ->
78 # Hint chars that have been matched so far.
79 @enteredHintChars = ''
80
81 document = @element.ownerDocument
82
83 while @markerElement.hasChildNodes()
84 @markerElement.firstChild.remove()
85
86 fragment = document.createDocumentFragment()
87 for char in @hintChars
88 charContainer = createElement(document, 'span')
89 charContainer.textContent = char.toUpperCase()
90 fragment.appendChild(charContainer)
91
92 @markerElement.appendChild(fragment)
93
94 matchHintChar: (char) ->
95 @toggleLastHintChar(true)
96 @enteredHintChars += char.toLowerCase()
97 @updateVisibility()
98
99 deleteHintChar: ->
100 @enteredHintChars = @enteredHintChars[...-1]
101 @toggleLastHintChar(false)
102 @updateVisibility()
103
104 toggleLastHintChar: (visible) ->
105 @markerElement.children[@enteredHintChars.length]
106 ?.classList.toggle('VimFxCharMatch', visible)
107
108 isMatched: ->
109 return @hintChars == @enteredHintChars
110
111 reset: ->
112 @setHint(@hintChars)
113 @show()
114
115 exports.Marker = Marker
Imprint / Impressum