aboutsummaryrefslogtreecommitdiff
path: root/js/components
diff options
context:
space:
mode:
Diffstat (limited to 'js/components')
-rw-r--r--js/components/editable.reel/editable.js250
-rw-r--r--js/components/hintable.reel/hintable.js360
2 files changed, 610 insertions, 0 deletions
diff --git a/js/components/editable.reel/editable.js b/js/components/editable.reel/editable.js
new file mode 100644
index 00000000..1d0ad776
--- /dev/null
+++ b/js/components/editable.reel/editable.js
@@ -0,0 +1,250 @@
1/* ComputedStyleSubPanel.js */
2var Montage = require("montage").Montage,
3 Component = require("montage/ui/component").Component;
4
5
6/*
7
8EDITABLE - Methods
9- startEdit
10- stopEdit
11- value
12-
13- _suggest
14- _suggestNext
15- _suggestPrev
16- _clearSuggest
17- _accept
18- _revert
19- _setCaret
20
21*/
22
23
24exports.Editable = Montage.create(Component, {
25 hasTemplate: { value: false },
26
27 _element : { value : null },
28 element : {
29 get : function() {
30 return this._element;
31 },
32 set : function(el) {
33 this._element = el;
34 this._element.addEventListener('keydown', this, false);
35 this._element.addEventListener('input', this, false);
36
37 if(this.startOnEvent) {
38 this._element.addEventListener(this.startOnEvent, this, false);
39 }
40
41 }
42 },
43 _readOnly : {
44 value: false
45 },
46 readOnly : {
47 get : function() { return this._readOnly; },
48 set : function(makeReadOnly) {
49 var action = makeReadOnly ? 'add' : 'remove';
50
51 this._element.classList[action](this.readOnlyClass);
52
53 if(this.isEditable) {
54 this.stop();
55 }
56 this._readOnly = makeReadOnly;
57 }
58 },
59 _isEditable : {
60 value : false
61 },
62 isEditable : {
63 get : function() {
64 return this._isEditable;
65 },
66 set: function(makeEditable) {
67 if(this._readOnly && makeEditable) { return false; }
68 this._isEditable = makeEditable;
69 }
70 },
71 _isDirty : {
72 value: false
73 },
74 isDirty : {
75 get : function() {
76 return this._isDirty;
77 },
78 set : function(setDirty) {
79 if(setDirty) {
80 this._isDirty = true;
81 this._sendEvent('dirty');
82 } else {
83 this._isDirty = false;
84 }
85 }
86 },
87 value : {
88 get: function() {
89 return this._element.textContent;
90 },
91 set: function(str) {
92 this._element.textContent = str;
93 }
94 },
95
96 ///// Pre Edit Value
97 ///// Value stored when editing starts
98 ///// Useful for reverting to previous value
99
100 _preEditValue : {
101 value : null
102 },
103 start : {
104 value: function() {
105 if(!this._readOnly) {
106 this._isEditable = this._element.contentEditable = true;
107 this._element.classList.add(this.editingClass);
108
109 ///// Save the preEditValue
110 this._preEditValue = this.value;
111
112 if(this.selectOnStart) {
113 this.selectAll();
114 }
115
116 if(this.stopOnBlur) {
117 console.log('adding mousedown event listener');
118 ///// Simulate blur on editable node by listening to the doc
119 document.addEventListener('mouseup', this, false);
120 }
121
122 this._sendEvent('start');
123 }
124
125 }
126 },
127 stop : {
128 value: function() {
129 this._isEditable = this._element.contentEditable = false;
130 this._element.classList.remove(this.editingClass);
131
132 this._sendEvent('stop');
133
134 ///// if value is different than pre-edit val, call onchange method
135 if(this._preEditValue !== this.value) {
136 this._sendEvent('change');
137 }
138 }
139 },
140 selectAll : {
141 value : function() {
142 var range = document.createRange(),
143 sel = window.getSelection();
144
145 sel.removeAllRanges();
146 range.selectNodeContents(this._element);
147 sel.addRange(range);
148 }
149 },
150 setCursor : {
151 value : function(position) {
152 var index = position,
153 range, node, sel;
154
155 ///// argument can be "end" or an index
156 if(typeof position === 'string' && position === 'end') {
157 index = this.value.length;
158 }
159
160 sel = window.getSelection();
161 sel.removeAllRanges();
162 //debugger;
163 node = this._getFirstTextNode();
164 range = document.createRange();
165 range.setStart(node, index);
166 range.setEnd(node, index);
167 sel.addRange(range);
168 }
169 },
170 blur : {
171 value : function() {
172 if(this._hint) {
173 this.accept();
174 }
175 this.stop();
176 document.removeEventListener('mouseup', this, false);
177 this._sendEvent('blur');
178 }
179 },
180
181 /* -------------------- User Event Handling -------------------- */
182
183 handleKeydown : {
184 value : function(e) {
185 var k = e.keyCode;
186 console.log('keyCode: ' + k);
187 }
188 },
189 ///// Text input has changed values
190 handleInput : {
191 value : function(e) {
192 if(!this.isDirty) {
193 this.isDirty = true;
194 }
195
196 this._sendEvent('input');
197 }
198 },
199 handleMouseup : {
200 value : function(e) {
201 console.log('handle mouse down');
202 ///// Listen for simulated blur event
203 if(this.stopOnBlur && e._event.target !== this._element) {
204 this.blur();
205 }
206 }
207 },
208 handleEvent : {
209 value : function(e) {
210 console.log("event type : " + e._event.type);
211 ///// If configured, start on specified event
212 if(e._event.type === this.startOnEvent) {
213 this.start();
214 }
215 }
216 },
217 _sendEvent : {
218 value : function(type) {
219 var evt = document.createEvent("CustomEvent");
220 evt.initCustomEvent(type, true, true);
221 this.dispatchEvent(evt);
222 }
223 },
224
225 /* -------------------- CONFIG -------------------- */
226
227 editingClass : {
228 value : 'editable'
229 },
230 readOnlyClass : {
231 value : 'readOnly'
232 },
233 selectOnStart : {
234 value : true
235 },
236 startOnEvent : {
237 value : 'dblclick'
238 },