diff options
author | Pushkar Joshi | 2012-02-24 12:08:49 -0800 |
---|---|---|
committer | Pushkar Joshi | 2012-02-24 12:08:49 -0800 |
commit | 03ca7a5ed13c25faaa9100bb666e062fd15335e6 (patch) | |
tree | c51112223ceb9121cd595a60335eb2795215590f /js/components/hintable.reel/hintable.js | |
parent | fcb12cc09eb3cd3b42bd215877ba18f449275b75 (diff) | |
parent | 053fc63a2950c7a5ee4ebf98033b64d474a3c46e (diff) | |
download | ninja-03ca7a5ed13c25faaa9100bb666e062fd15335e6.tar.gz |
Merge branch 'pentool' into brushtool
Conflicts:
imports/codemirror/mode/scheme/scheme.js
js/tools/BrushTool.js
Diffstat (limited to 'js/components/hintable.reel/hintable.js')
-rw-r--r-- | js/components/hintable.reel/hintable.js | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/js/components/hintable.reel/hintable.js b/js/components/hintable.reel/hintable.js new file mode 100644 index 00000000..5ed46b3c --- /dev/null +++ b/js/components/hintable.reel/hintable.js | |||
@@ -0,0 +1,366 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | |||
7 | /* ComputedStyleSubPanel.js */ | ||
8 | var Montage = require("montage").Montage, | ||
9 | Component = require("montage/ui/component").Component, | ||
10 | Editable = require("js/components/editable.reel").Editable; | ||
11 | |||
12 | |||
13 | /* | ||
14 | |||
15 | EDITABLE - Methods | ||
16 | - startEdit | ||
17 | - stopEdit | ||
18 | - value | ||
19 | - | ||
20 | - _suggest | ||
21 | - _suggestNext | ||
22 | - _suggestPrev | ||
23 | - _clearSuggest | ||
24 | - _accept | ||
25 | - _revert | ||
26 | - _setCaret | ||
27 | |||
28 | */ | ||
29 | |||
30 | |||
31 | exports.Hintable = Montage.create(Editable, { | ||
32 | inheritsFrom : { value : Editable }, | ||
33 | _matchIndex : { value : 0 }, | ||
34 | matches : { value : [] }, | ||
35 | |||
36 | _hint : { value : null }, | ||
37 | hint : { | ||
38 | get : function() { | ||
39 | return this._hint; | ||
40 | }, | ||
41 | set : function(hint) { | ||
42 | hint = hint || ''; | ||
43 | |||
44 | ///// Set the hint element's text | ||
45 | this._getFirstTextNode(this.hintElement).textContent = hint; | ||
46 | ///// if hintElement was removed from the DOM, the object still | ||
47 | ///// exists, so it needs to be re-appended | ||
48 | if(this.hintElement.parentNode === null) { | ||
49 | this._element.appendChild(this.hintElement); | ||
50 | } | ||
51 | |||
52 | this._hint = hint; | ||
53 | } | ||
54 | }, | ||
55 | |||
56 | _hintElement : { value : null }, | ||
57 | hintElement : { | ||
58 | get : function() { | ||
59 | if(!this._hintElement) { | ||
60 | /// Remove the phantom "<BR>" element that is generated when | ||
61 | /// content editable element is empty | ||
62 | this._children(this._element, function(item) { | ||
63 | return item.nodeName === 'BR'; | ||
64 | }).forEach(function(item) { | ||
65 | this._element.removeChild(item); | ||
66 | }, this); | ||
67 | |||
68 | this._hintElement = document.createElement('span'); | ||
69 | this._hintElement.classList.add(this.hintClass); | ||
70 | |||
71 | this._element.appendChild(this._hintElement); | ||
72 | } | ||
73 | |||
74 | return this._hintElement; | ||
75 | }, | ||
76 | set : function(el) { | ||
77 | this._hintElement = el; | ||
78 | } | ||
79 | }, | ||
80 | |||
81 | _getHintDifference : { | ||
82 | value : function() { | ||
83 | if(!this.matches[this._matchIndex]) { | ||
84 | debugger; | ||
85 | } | ||
86 | return this.matches[this._matchIndex].substr(this.value.length); | ||
87 | } | ||
88 | }, | ||
89 | |||
90 | hintNext : { | ||
91 | value : function(e) { | ||
92 | if(e) { e.preventDefault(); } | ||
93 | console.log('next1'); | ||
94 | |||
95 | if(this._matchIndex < this.matches.length - 1) { | ||
96 | console.log('next'); | ||
97 | ++this._matchIndex; | ||
98 | this.hint = this._getHintDifference(); | ||
99 | } | ||
100 | } | ||
101 | }, | ||
102 | hintPrev : { | ||
103 | value : function(e) { | ||
104 | if(e) { e.preventDefault(); } | ||
105 | console.log('prev1'); | ||
106 | if(this._matchIndex !== 0) { | ||
107 | console.log('prev'); | ||
108 | --this._matchIndex; | ||
109 | this.hint = this._getHintDifference(); | ||
110 | } | ||
111 | } | ||
112 | }, | ||
113 | |||
114 | accept : { | ||
115 | value: function(e, preserveCaretPosition) { | ||
116 | if(e) { | ||
117 | e.preventDefault(); | ||
118 | } | ||
119 | var fullText = this._hint; | ||
120 | this.hint = null; | ||
121 | this.value += fullText; | ||
122 | |||
123 | if(!preserveCaretPosition) { | ||
124 | this.setCursor('end'); | ||
125 | } | ||
126 | |||
127 | this._sendEvent('accept'); | ||
128 | } | ||
129 | }, | ||
130 | revert : { | ||
131 | value : function(e, forceRevert) { | ||
132 | this.hint = null; | ||
133 | |||
134 | if(this.isEditable || forceRevert) { | ||
135 | /// revert to old value | ||
136 | this.value = (this._preEditValue); | ||
137 | this._sendEvent('revert'); | ||
138 | console.log('reverting'); | ||
139 | |||
140 | } | ||
141 | } | ||
142 | }, | ||
143 | value : { | ||
144 | get: function() { | ||
145 | return this._getFirstTextNode().textContent; | ||
146 | }, | ||
147 | set: function(str) { | ||
148 | var node = this._getFirstTextNode(); | ||
149 | node.textContent = str; | ||
150 | } | ||
151 | }, | ||
152 | |||
153 | handleKeydown : { | ||
154 | value : function handleKeydown(e) { | ||
155 | var k = e.keyCode, | ||
156 | isCaretAtEnd, selection, text; | ||
157 | |||
158 | this._super(arguments); | ||
159 | |||
160 | if(k === 39) { | ||
161 | selection = window.getSelection(); | ||
162 | text = selection.baseNode.textContent; | ||
163 | isCaretAtEnd = (selection.anchorOffset === text.length); | ||
164 | } | ||
165 | |||
166 | if(this.hint && isCaretAtEnd) { | ||
167 | ///// Advance the cursor | ||
168 | this.hint = this.hint.substr(0, 1); | ||
169 | this.accept(e); | ||
170 | this.handleInput(); | ||
171 | } | ||
172 | |||
173 | this._execKeyAction(e); | ||
174 | } | ||
175 | }, | ||
176 | ///// Text input has changed values | ||
177 | handleInput : { | ||
178 | value : function handleInput(e) { | ||
179 | this._super(arguments); | ||
180 | |||
181 | var val = this.value, | ||
182 | matches, hint; | ||
183 | console.log('val = "' + val + '"'); | ||
184 | //// Handle auto-suggest if configured | ||
185 | if(this.hints instanceof Array) { | ||
186 | |||
187 | if(val.length > 0) { // content is not empty | ||
188 | |||
189 | this._matchIndex = 0; | ||
190 | this.matches = this.hints.filter(function(h) { | ||
191 | return h.indexOf(val) === 0; | ||
192 | }).sort(); | ||
193 | |||
194 | ///// If there are no matches, or the new value doesn't match all the | ||
195 | ///// previous matches, then get new list of matches | ||
196 | if(!this.matches.length || !this._matchesAll(val)) { | ||
197 | } | ||
198 | |||
199 | if(this.matches.length) { // match(es) found | ||
200 | if(this.matches[this._matchIndex] !== val) { | ||
201 | // Suggest the matched hint, subtracting the typed-in string | ||
202 | // Only if the hint is not was the user has typed already | ||
203 | this.hint = this._getHintDifference(); | ||
204 | } else { | ||
205 | this.hint = null; | ||
206 | } | ||
207 | } else { // no matches found | ||
208 | this.hint = null; | ||
209 | } | ||
210 | } else { // no suggestion for empty string | ||
211 | this.hint = null; | ||
212 | } | ||
213 | |||
214 | } | ||
215 | } | ||
216 | }, | ||
217 | handleBackspace : { | ||
218 | value : function(e) { | ||
219 | this.matches.length = 0; | ||
220 | } | ||
221 | }, | ||
222 | _matchesAll : { | ||
223 | value : function(value) { | ||
224 | return this.matches.every(function(match) { | ||
225 | return match.indexOf(value) === 0; | ||
226 | }, this); | ||
227 | } | ||
228 | }, | ||