1 // The "Dynano" Javascript framework. Similar in syntax to JQuery but highly Enano-specific (TinyMCE, etc). |
1 // The "Dynano" Javascript framework. Similar in syntax to JQuery but highly Enano-specific (TinyMCE, etc). |
2 |
2 |
3 var $dynano = function(id) |
3 var $dynano = function(id) |
4 { |
4 { |
5 return new DNobj(id); |
5 return new DNobj(id); |
6 } |
6 } |
7 function DNobj(id) |
7 function DNobj(id) |
8 { |
8 { |
9 if ( id == undefined ) |
9 if ( id == undefined ) |
10 { |
10 { |
11 return {}; |
11 return {}; |
12 } |
12 } |
13 this.object = ( typeof(id) == 'object' ) ? id : document.getElementById(id); |
13 this.object = ( typeof(id) == 'object' ) ? id : document.getElementById(id); |
14 if ( !this.object ) |
14 if ( !this.object ) |
15 { |
15 { |
16 console.warn('Dynano: requested object is bad. id parameter follows.'); |
16 console.warn('Dynano: requested object is bad. id parameter follows.'); |
17 console.debug(id); |
17 console.debug(id); |
18 this.object = false; |
18 this.object = false; |
19 return this; |
19 return this; |
20 } |
20 } |
21 if ( this.object.Dynano ) |
21 if ( this.object.Dynano ) |
22 { |
22 { |
23 return this.object.Dynano; |
23 return this.object.Dynano; |
24 } |
24 } |
25 this.object.Dynano = this; |
25 this.object.Dynano = this; |
26 |
26 |
27 this.height = __DNObjGetHeight(this.object); |
27 this.height = __DNObjGetHeight(this.object); |
28 this.width = __DNObjGetWidth(this.object); |
28 this.width = __DNObjGetWidth(this.object); |
29 |
29 |
30 if ( this.object.tagName == 'TEXTAREA' && ( typeof(tinyMCE) == 'object' || typeof(tinyMCE_GZ) == 'object' ) ) |
30 if ( this.object.tagName == 'TEXTAREA' && ( typeof(tinyMCE) == 'object' || typeof(tinyMCE_GZ) == 'object' ) ) |
31 { |
31 { |
32 this.object.dnIsMCE = 'no'; |
32 this.object.dnIsMCE = 'no'; |
33 this.switchToMCE = DN_switchToMCE; |
33 this.switchToMCE = DN_switchToMCE; |
34 this.destroyMCE = DN_destroyMCE; |
34 this.destroyMCE = DN_destroyMCE; |
35 this.getContent = DN_mceFetchContent; |
35 this.getContent = DN_mceFetchContent; |
36 this.setContent = DN_mceSetContent; |
36 this.setContent = DN_mceSetContent; |
37 this.makeSwitchable = DN_makeSwitchableTA; |
37 this.makeSwitchable = DN_makeSwitchableTA; |
38 this.isMCE = DN_isMCE; |
38 this.isMCE = DN_isMCE; |
39 } |
39 } |
40 } |
40 } |
41 function __DNObjGetHeight(o) { |
41 function __DNObjGetHeight(o) { |
42 return o.offsetHeight; |
42 return o.offsetHeight; |
43 } |
43 } |
44 |
44 |
45 function __DNObjGetWidth(o) { |
45 function __DNObjGetWidth(o) { |
46 return o.offsetWidth; |
46 return o.offsetWidth; |
47 } |
47 } |
48 |
48 |
49 function addClass(obj, clsname) |
49 function addClass(obj, clsname) |
50 { |
50 { |
51 var cnt = obj.className; |
51 var cnt = obj.className; |
52 var space = ( (cnt + '').length > 0 ) ? ' ' : ''; |
52 var space = ( (cnt + '').length > 0 ) ? ' ' : ''; |
53 var cls = cnt + space + clsname; |
53 var cls = cnt + space + clsname; |
54 obj.className = cls; |
54 obj.className = cls; |
55 } |
55 } |
56 |
56 |
57 function rmClass(obj, clsname) |
57 function rmClass(obj, clsname) |
58 { |
58 { |
59 var cnt = obj.className; |
59 var cnt = obj.className; |
60 if ( cnt == clsname ) |
60 if ( cnt == clsname ) |
61 { |
61 { |
62 obj.className = ''; |
62 obj.className = ''; |
63 } |
63 } |
64 else |
64 else |
65 { |
65 { |
66 cnt = cnt.replace(clsname, ''); |
66 cnt = cnt.replace(clsname, ''); |
67 cnt = trim(cnt); |
67 cnt = trim(cnt); |
68 obj.className = cnt; |
68 obj.className = cnt; |
69 } |
69 } |
70 } |
70 } |
71 |
71 |
72 function hasClass(obj, clsname) |
72 function hasClass(obj, clsname) |
73 { |
73 { |
74 var cnt = obj.className; |
74 var cnt = obj.className; |
75 if ( !cnt ) |
75 if ( !cnt ) |
76 return false; |
76 return false; |
77 if ( cnt == clsname ) |
77 if ( cnt == clsname ) |
78 return true; |
78 return true; |
79 cnt = cnt.split(' '); |
79 cnt = cnt.split(' '); |
80 |
80 |
81 for ( var i in cnt ) |
81 for ( var i in cnt ) |
82 if ( cnt[i] == clsname ) |
82 if ( cnt[i] == clsname ) |
83 return true; |
83 return true; |
84 |
84 |
85 return false; |
85 return false; |
86 } |
86 } |
87 function __DNObjGetLeft(obj) { |
87 function __DNObjGetLeft(obj) { |
88 var left_offset = obj.offsetLeft; |
88 var left_offset = obj.offsetLeft; |
89 while ((obj = obj.offsetParent) != null) { |
89 while ((obj = obj.offsetParent) != null) { |
90 left_offset += obj.offsetLeft; |
90 left_offset += obj.offsetLeft; |
91 } |
91 } |
92 return left_offset; |
92 return left_offset; |
93 } |
93 } |
94 |
94 |
95 function __DNObjGetTop(obj) { |
95 function __DNObjGetTop(obj) { |
96 var left_offset = obj.offsetTop; |
96 var left_offset = obj.offsetTop; |
97 while ((obj = obj.offsetParent) != null) { |
97 while ((obj = obj.offsetParent) != null) { |
98 left_offset += obj.offsetTop; |
98 left_offset += obj.offsetTop; |
99 } |
99 } |
100 return left_offset; |
100 return left_offset; |
101 } |
101 } |
102 |
102 |
103 function DN_switchToMCE(performWikiTransform) |
103 function DN_switchToMCE(performWikiTransform) |
104 { |
104 { |
105 if ( !this.object.id ) |
105 if ( !this.object.id ) |
106 this.object.id = 'textarea_' + Math.floor(Math.random() * 1000000); |
106 this.object.id = 'textarea_' + Math.floor(Math.random() * 1000000); |
107 if ( !this.object.name ) |
107 if ( !this.object.name ) |
108 this.object.name = 'textarea_' + Math.floor(Math.random() * 1000000); |
108 this.object.name = 'textarea_' + Math.floor(Math.random() * 1000000); |
109 // Updated for TinyMCE 3.x |
109 // Updated for TinyMCE 3.x |
110 if ( performWikiTransform ) |
110 if ( performWikiTransform ) |
111 { |
111 { |
112 this.object.value = DN_WikitextToXHTML(this.object.value); |
112 this.object.value = DN_WikitextToXHTML(this.object.value); |
113 } |
113 } |
114 // If tinyMCE init hasn't been called yet, do it now. |
114 // If tinyMCE init hasn't been called yet, do it now. |
115 if ( !tinymce_initted ) |
115 if ( !tinymce_initted ) |
116 { |
116 { |
117 console.info('$dynano().switchToMCE(): doing "exact"-type MCE init'); |
117 console.info('$dynano().switchToMCE(): doing "exact"-type MCE init'); |
118 enano_tinymce_options.mode = 'exact'; |
118 enano_tinymce_options.mode = 'exact'; |
119 enano_tinymce_options.elements = this.object.id; |
119 enano_tinymce_options.elements = this.object.id; |
120 initTinyMCE(); |
120 initTinyMCE(); |
121 this.object.dnIsMCE = 'yes'; |
121 this.object.dnIsMCE = 'yes'; |
122 return true; |
122 return true; |
123 } |
123 } |
124 else |
124 else |
125 { |
125 { |
126 console.info('$dynano().switchToMCE(): tinyMCE already loaded, calling mceAddControl'); |
126 console.info('$dynano().switchToMCE(): tinyMCE already loaded, calling mceAddControl'); |
127 tinymce.EditorManager.execCommand("mceAddControl", true, this.object.id); |
127 tinymce.EditorManager.execCommand("mceAddControl", true, this.object.id); |
128 this.object.dnIsMCE = 'yes'; |
128 this.object.dnIsMCE = 'yes'; |
129 } |
129 } |
130 return this; |
130 return this; |
131 } |
131 } |
132 |
132 |
133 function DN_destroyMCE(performWikiTransform) |
133 function DN_destroyMCE(performWikiTransform) |
134 { |
134 { |
135 //if ( !this.object.dn_is_mce ) |
135 //if ( !this.object.dn_is_mce ) |
136 // return this; |
136 // return this; |
137 if ( this.object.id && window.tinymce ) |
137 if ( this.object.id && window.tinymce ) |
138 { |
138 { |
139 // TinyMCE 2.x |
139 // TinyMCE 2.x |
140 // tinymce.EditorManager.removeMCEControl(this.object.name); |
140 // tinymce.EditorManager.removeMCEControl(this.object.name); |
141 // TinyMCE 3.x |
141 // TinyMCE 3.x |
142 var ed = tinymce.EditorManager.getInstanceById(this.object.id); |
142 var ed = tinymce.EditorManager.getInstanceById(this.object.id); |
143 if ( ed ) |
143 if ( ed ) |
144 { |
144 { |
145 if ( !tinymce.EditorManager.execCommand("mceRemoveEditor", false, this.object.id) ) |
145 if ( !tinymce.EditorManager.execCommand("mceRemoveEditor", false, this.object.id) ) |
146 alert('could not destroy editor'); |
146 alert('could not destroy editor'); |
147 if ( performWikiTransform ) |
147 if ( performWikiTransform ) |
148 { |
148 { |
149 this.object.value = DN_XHTMLToWikitext(this.object.value); |
149 this.object.value = DN_XHTMLToWikitext(this.object.value); |
150 } |
150 } |
151 } |
151 } |
152 } |
152 } |
153 this.object.dnIsMCE = 'no'; |
153 this.object.dnIsMCE = 'no'; |
154 return this; |
154 return this; |
155 } |
155 } |
156 |
156 |
157 function DN_isMCE() |
157 function DN_isMCE() |
158 { |
158 { |
159 return ( this.object.dnIsMCE == 'yes' ); |
159 return ( this.object.dnIsMCE == 'yes' ); |
160 } |
160 } |
161 |
161 |
162 function DN_mceFetchContent() |
162 function DN_mceFetchContent() |
163 { |
163 { |
164 if ( this.object.name ) |
164 if ( this.object.name ) |
165 { |
165 { |
166 var text = this.object.value; |
166 var text = this.object.value; |
167 if ( tinymce.EditorManager.get(this.object.id) ) |
167 if ( tinymce.EditorManager.get(this.object.id) ) |
168 { |
168 { |
169 var editor = tinymce.EditorManager.get(this.object.id); |
169 var editor = tinymce.EditorManager.get(this.object.id); |
170 text = editor.getContent(); |
170 text = editor.getContent(); |
171 } |
171 } |
172 return text; |
172 return text; |
173 } |
173 } |
174 else |
174 else |
175 { |
175 { |
176 return this.object.value; |
176 return this.object.value; |
177 } |
177 } |
178 } |
178 } |
179 |
179 |
180 function DN_mceSetContent(text) |
180 function DN_mceSetContent(text) |
181 { |
181 { |
182 if ( this.object.name ) |
182 if ( this.object.name ) |
183 { |
183 { |
184 this.object.value = text; |
184 this.object.value = text; |
185 if ( tinymce.EditorManager.get(this.object.id) ) |
185 if ( tinymce.EditorManager.get(this.object.id) ) |
186 { |
186 { |
187 var editor = tinymce.EditorManager.get(this.object.id); |
187 var editor = tinymce.EditorManager.get(this.object.id); |
188 editor.setContent(text); |
188 editor.setContent(text); |
189 } |
189 } |
190 } |
190 } |
191 else |
191 else |
192 { |
192 { |
193 this.object.value = text; |
193 this.object.value = text; |
194 } |
194 } |
195 } |
195 } |
196 |
196 |
197 var P_BOTTOM = 1; |
197 var P_BOTTOM = 1; |
198 var P_TOP = 2; |
198 var P_TOP = 2; |
199 |
199 |
200 function DN_makeSwitchableTA(pos) |
200 function DN_makeSwitchableTA(pos) |
201 { |
201 { |
202 if ( this.toggler ) |
202 if ( this.toggler ) |
203 return false; |
203 return false; |
204 |
204 |
205 if ( !pos ) |
205 if ( !pos ) |
206 pos = P_BOTTOM; |
206 pos = P_BOTTOM; |
207 |
207 |
208 load_component('l10n'); |
208 load_component('l10n'); |
209 var cookiename = 'enano_editor_mode'; |
209 var cookiename = 'enano_editor_mode'; |
210 |
210 |
211 var toggler = document.createElement('div'); |
211 var toggler = document.createElement('div'); |
212 toggler.dynano = this; |
212 toggler.dynano = this; |
213 this.toggler = toggler; |
213 this.toggler = toggler; |
214 |
214 |
215 if ( !this.object.id ) |
215 if ( !this.object.id ) |
216 this.object.id = 'dynano_auto_' + Math.floor(Math.random() * 1000000); |
216 this.object.id = 'dynano_auto_' + Math.floor(Math.random() * 1000000); |
217 |
217 |
218 toggler.s_mode_text = $lang.get('editor_btn_wikitext'); |
218 toggler.s_mode_text = $lang.get('editor_btn_wikitext'); |
219 toggler.s_mode_graphical = $lang.get('editor_btn_graphical'); |
219 toggler.s_mode_graphical = $lang.get('editor_btn_graphical'); |
220 |
220 |
221 toggler.set_text = function() |
221 toggler.set_text = function() |
222 { |
222 { |
223 if ( this.dynano.object.dnIsMCE == 'yes' ) |
223 if ( this.dynano.object.dnIsMCE == 'yes' ) |
224 this.dynano.destroyMCE(); |
224 this.dynano.destroyMCE(); |
225 |
225 |
226 this.innerHTML = ''; |
226 this.innerHTML = ''; |
227 this.appendChild(document.createTextNode(this.s_mode_text + ' | ')); |
227 this.appendChild(document.createTextNode(this.s_mode_text + ' | ')); |
228 |
228 |
229 var link = document.createElement('a'); |
229 var link = document.createElement('a'); |
230 link.href = '#'; |
230 link.href = '#'; |
231 link.onclick = function() |
231 link.onclick = function() |
232 { |
232 { |
233 this.parentNode.set_graphical(); |
233 this.parentNode.set_graphical(); |
234 return false; |
234 return false; |
235 } |
235 } |
236 link.appendChild(document.createTextNode(this.s_mode_graphical)); |
236 link.appendChild(document.createTextNode(this.s_mode_graphical)); |
237 this.appendChild(link); |
237 this.appendChild(link); |
238 |
238 |
239 createCookie('enano_editor_mode', 'text', 365); |
239 createCookie('enano_editor_mode', 'text', 365); |
240 } |
240 } |
241 |
241 |
242 toggler.set_graphical = function() |
242 toggler.set_graphical = function() |
243 { |
243 { |
244 this.dynano.switchToMCE(); |
244 this.dynano.switchToMCE(); |
245 this.innerHTML = ''; |
245 this.innerHTML = ''; |
246 |
246 |
247 var link = document.createElement('a'); |
247 var link = document.createElement('a'); |
248 link.href = '#'; |
248 link.href = '#'; |
249 link.onclick = function() |
249 link.onclick = function() |
250 { |
250 { |
251 this.parentNode.set_text(); |
251 this.parentNode.set_text(); |
252 return false; |
252 return false; |
253 } |
253 } |
254 link.appendChild(document.createTextNode(this.s_mode_text)); |
254 link.appendChild(document.createTextNode(this.s_mode_text)); |
255 this.appendChild(link); |
255 this.appendChild(link); |
256 |
256 |
257 this.appendChild(document.createTextNode(' | ' + this.s_mode_graphical)); |
257 this.appendChild(document.createTextNode(' | ' + this.s_mode_graphical)); |
258 createCookie('enano_editor_mode', 'tinymce', 365); |
258 createCookie('enano_editor_mode', 'tinymce', 365); |
259 } |
259 } |
260 |
260 |
261 toggler.style.styleFloat = 'right'; |
261 toggler.style.styleFloat = 'right'; |
262 toggler.style.cssFloat = 'right'; |
262 toggler.style.cssFloat = 'right'; |
263 if ( pos == P_BOTTOM ) |
263 if ( pos == P_BOTTOM ) |
264 { |
264 { |
265 insertAfter(this.object.parentNode, toggler, this.object); |
265 insertAfter(this.object.parentNode, toggler, this.object); |
266 } |
266 } |
267 else |
267 else |
268 { |
268 { |
269 this.object.parentNode.insertBefore(toggler, this.object); |
269 this.object.parentNode.insertBefore(toggler, this.object); |
270 } |
270 } |
271 |
271 |
272 if ( readCookie(cookiename) == 'tinymce' ) |
272 if ( readCookie(cookiename) == 'tinymce' ) |
273 { |
273 { |
274 toggler.set_graphical(); |
274 toggler.set_graphical(); |
275 } |
275 } |
276 else |
276 else |
277 { |
277 { |
278 toggler.set_text(); |
278 toggler.set_text(); |
279 } |
279 } |
280 } |
280 } |
281 |
281 |
282 function DN_WikitextToXHTML(text) |
282 function DN_WikitextToXHTML(text) |
283 { |
283 { |
284 return DN_AjaxGetTransformedText(text, 'xhtml'); |
284 return DN_AjaxGetTransformedText(text, 'xhtml'); |
285 } |
285 } |
286 |
286 |
287 function DN_XHTMLToWikitext(text) |
287 function DN_XHTMLToWikitext(text) |
288 { |
288 { |
289 return DN_AjaxGetTransformedText(text, 'wikitext'); |
289 return DN_AjaxGetTransformedText(text, 'wikitext'); |
290 } |
290 } |
291 |
291 |
292 // AJAX to the server to transform text |
292 // AJAX to the server to transform text |
293 function DN_AjaxGetTransformedText(text, to) |
293 function DN_AjaxGetTransformedText(text, to) |
294 { |
294 { |
295 // get an XHR instance |
295 // get an XHR instance |
296 var ajax = ajaxMakeXHR(); |
296 var ajax = ajaxMakeXHR(); |
297 |
297 |
298 var uri = stdAjaxPrefix + '&_mode=transform&to=' + to; |
298 var uri = stdAjaxPrefix + '&_mode=transform&to=' + to; |
299 var parms = 'text=' + ajaxEscape(text); |
299 var parms = 'text=' + ajaxEscape(text); |
300 try |
300 try |
301 { |
301 { |
302 ajax.open('POST', uri, false); |
302 ajax.open('POST', uri, false); |
303 ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
303 ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
304 // Setting Content-length in Safari triggers a warning |
304 // Setting Content-length in Safari triggers a warning |
305 if ( !is_Safari ) |
305 if ( !is_Safari ) |
306 { |
306 { |
307 ajax.setRequestHeader("Content-length", parms.length); |
307 ajax.setRequestHeader("Content-length", parms.length); |
308 } |
308 } |
309 ajax.send(parms); |
309 ajax.send(parms); |
310 // async request, so if status != 200 at this point then we're screwed |
310 // async request, so if status != 200 at this point then we're screwed |
311 if ( ajax.readyState == 4 && ajax.status == 200 ) |
311 if ( ajax.readyState == 4 && ajax.status == 200 ) |
312 { |
312 { |
313 var response = String(ajax.responseText + ''); |
313 var response = String(ajax.responseText + ''); |
314 if ( !check_json_response(response) ) |
314 if ( !check_json_response(response) ) |
315 { |
315 { |
316 handle_invalid_json(response); |
316 handle_invalid_json(response); |
317 return text; |
317 return text; |
318 } |
318 } |
319 response = parseJSON(response); |
319 response = parseJSON(response); |
320 if ( response.mode == 'error' ) |
320 if ( response.mode == 'error' ) |
321 { |
321 { |
322 alert(response.error); |
322 alert(response.error); |
323 return text; |
323 return text; |
324 } |
324 } |
325 return response.text; |
325 return response.text; |
326 } |
326 } |
327 } |
327 } |
328 catch(e) |
328 catch(e) |
329 { |
329 { |
330 console.warn('DN_AjaxGetTransformedText: XHR failed'); |
330 console.warn('DN_AjaxGetTransformedText: XHR failed'); |
331 } |
331 } |
332 return text; |
332 return text; |
333 } |
333 } |
334 |
334 |
335 DNobj.prototype.addClass = function(clsname) { addClass(this.object, clsname); return this; }; |
335 DNobj.prototype.addClass = function(clsname) { addClass(this.object, clsname); return this; }; |
336 DNobj.prototype.rmClass = function(clsname) { rmClass( this.object, clsname); return this; }; |
336 DNobj.prototype.rmClass = function(clsname) { rmClass( this.object, clsname); return this; }; |
337 DNobj.prototype.hasClass = function(clsname) { return hasClass(this.object, clsname); }; |
337 DNobj.prototype.hasClass = function(clsname) { return hasClass(this.object, clsname); }; |