1 | /** |
---|
2 | * technikum29.de | Translation contribution system |
---|
3 | * |
---|
4 | * This is a one-of-a-kind "almost wiki" interactive feedback system for user driven |
---|
5 | * improvements directly on the page. There is almost no way to make it more easier |
---|
6 | * for users to improve the translation. |
---|
7 | * |
---|
8 | * $Id: editor.js 209 2010-10-24 20:10:33Z sven $ |
---|
9 | * (c) GPL, Sven Koeppel, 01.09.2010 |
---|
10 | **/ |
---|
11 | |
---|
12 | if(!t29) t29 = {}; // defined in tools.js |
---|
13 | if(!t29.tr) t29.tr = {}; // this namespace, also defined in tools.js |
---|
14 | |
---|
15 | // Basic Settings |
---|
16 | t29.tr.settings = { |
---|
17 | disable_img_license_system: true, // when tr system enabled, disable img licenses for more cleareness |
---|
18 | editable_elements: function(){ return $("#content").find("p, ul, ol, blockquote, dl, table, h2, h3"); }, |
---|
19 | messages_url: "/en/dev/translation/messages.xml" |
---|
20 | }; |
---|
21 | |
---|
22 | // Message system |
---|
23 | t29.tr.msg = {}; |
---|
24 | t29.tr.load_messages = function() { |
---|
25 | $.ajax({ |
---|
26 | dataType: "xml", |
---|
27 | url: t29.tr.settings.messages_url, |
---|
28 | async: false, timeout: 2000, // ms |
---|
29 | success: function(xml) { |
---|
30 | $("body > span, body > section", xml).each(function(){ |
---|
31 | t29.tr.msg[this.id] = (this.tagName == "span") ? $(this).text() : $(this).contents() |
---|
32 | }); |
---|
33 | }, |
---|
34 | error: function(xhr, status) { |
---|
35 | alert("Error while fetching translation messages: "+status); |
---|
36 | } |
---|
37 | }); |
---|
38 | } |
---|
39 | |
---|
40 | /* SYSTEM STATE: PAGE STATE: USER STATE: |
---|
41 | enabled = true inspecting already_edited = true => cookie |
---|
42 | disabled = false editing never_edited = false |
---|
43 | */ |
---|
44 | |
---|
45 | |
---|
46 | /** |
---|
47 | * Onload handler: Some basic preparations for translation system. |
---|
48 | * tasks: |
---|
49 | * - Prepare sidebar box link handlers |
---|
50 | **/ |
---|
51 | t29.tr.onload = function(){ |
---|
52 | if(!t29.tr.is_enabled()) $("body").addClass("tr-disabled"); // prepare |
---|
53 | t29.tr.sidebar = $("#sidebar-tr"); |
---|
54 | t29.tr.sidebar.find(".tr-enabled .button").attr("href","#back_to_normal_mode").click(t29.tr.call("set_enabled",false)); |
---|
55 | t29.tr.load_messages(); |
---|
56 | t29.tr.defaultvalue(); // as general system |
---|
57 | // initial value |
---|
58 | //t29.tr.set_enabled(true); // won't work any more (call t29.tr.preloader.start) |
---|
59 | }; |
---|
60 | |
---|
61 | // helper: foobar.click(t29.tr.call(anything, value)); is shorthand for |
---|
62 | // foobar.call(function(){ t29.tr.anything(value); }); |
---|
63 | t29.tr.call = function(f, v){ return function(){ t29.tr[f](v);} }; |
---|
64 | |
---|
65 | // helper: default value input elements. highly compressed selfwritten :) |
---|
66 | // usage: <input value="my default value bla" class="defaultvalue"/> |
---|
67 | t29.tr.defaultvalue = function(){ |
---|
68 | $("input.defaultvalue").live('focus.t29tr', function(){ |
---|
69 | if(!(dv=(t=$(this)).data('dv'))) t.data('dv', t.val()); |
---|
70 | if(t.val()==dv) t.val(''); |
---|
71 | }).live('blur.t29tr', function(){ |
---|
72 | if((dv=((t=$(this)).data('dv'))) && /^\s*$/.test(t.val())) t.val(dv); |
---|
73 | }); |
---|
74 | }; |
---|
75 | |
---|
76 | /** |
---|
77 | * Tells if the translation system is started up (e.g. the user started it) or not |
---|
78 | * (which means just an ordinary page) |
---|
79 | * @returns boolean |
---|
80 | **/ |
---|
81 | t29.tr.is_enabled = function() { |
---|
82 | return t29.tr.enabled ? true : false; |
---|
83 | }; |
---|
84 | |
---|
85 | /** |
---|
86 | * The main switch to turn the translation system on or off. Turning on will always |
---|
87 | * success (the system switches into inspection mode immediately), turning off will |
---|
88 | * check if the user just modified a text - if yes and if the user want to continue, |
---|
89 | * it will fail. In every case this is a clean operation. |
---|
90 | * @param value boolean true: Turn system on, false: Turn it off |
---|
91 | * @returns boolean if operation succeeded. |
---|
92 | **/ |
---|
93 | t29.tr.set_enabled = function(value) { |
---|
94 | if(!value && t29.tr.is_really_editing() && t29.tr.stop_editing()) { |
---|
95 | // currently enabled + user is editing |
---|
96 | // + user interrupted process => fail, still enabled |
---|
97 | return false; |
---|
98 | } |
---|
99 | |
---|
100 | t29.tr.enabled = value; |
---|
101 | // toggle image license system |
---|
102 | if(t29.tr.settings.disable_img_license_system) |
---|
103 | t29.img_license_settings.enabled = ! t29.tr.enabled; |
---|
104 | // set infos on body |
---|
105 | $("body").toggleClass("tr-enabled", t29.tr.enabled) |
---|
106 | .toggleClass("tr-inspecting", t29.tr.enabled && !t29.tr.is_editing()) |
---|
107 | .toggleClass("tr-disabled", !t29.tr.enabled); |
---|
108 | |
---|
109 | if(t29.tr.enabled) { |
---|
110 | // system powered on. |
---|
111 | t29.tr.create_ui(); |
---|
112 | t29.tr.editables |
---|
113 | .hover(t29.tr.mouseover_editables, t29.tr.mouseout_editables) |
---|
114 | .click(t29.tr.click_editables); |
---|
115 | |
---|
116 | // doesn't work yet (nachschauen) |
---|
117 | /*$(document).keyup(function(e) { |
---|
118 | var code = e.keyCode || e.which; |
---|
119 | if (code == 27) // escape key -> quit system |
---|
120 | t29.tr.set_enabled(false); |
---|
121 | }); */ |
---|
122 | } else { |
---|
123 | // system powered off |
---|
124 | t29.tr.set_editing(false); // for safety, just another time |
---|
125 | t29.tr.editables.unbind(); // safely remove *all* hovering handlers |
---|
126 | // remove any old trash: |
---|
127 | $(".tr-inspecting").removeClass("tr-inspecting"); |
---|
128 | t29.tr.mouseout_editables(); // falls noch was uebrig ist |
---|
129 | |
---|
130 | // remove *ALL* handlers anywhere (new namespace .t29tr) |
---|
131 | $("*").unbind(".t29tr"); |
---|
132 | } |
---|
133 | return true; // success |
---|
134 | } // set_enabled |
---|
135 | |
---|
136 | /** |
---|
137 | * Helper function for set_enabled(): Set up the general User Interface for |
---|
138 | * the translation system, that is the inspection widgets. The function |
---|
139 | * remembers if it has created them already, so it's safe to call this multiple |
---|
140 | * times on each set_enabeld(true) call. |
---|
141 | **/ |
---|
142 | t29.tr.create_ui = function() { |
---|
143 | // Create #tr-info, #tr-editor, all ".tr-editable"s, etc. |
---|
144 | if(!t29.tr.ui_created) { |
---|
145 | t29.tr.ui_created = true; // Now create all those nice elements |
---|
146 | |
---|
147 | // Sidebar arrow |
---|
148 | t29.tr.sidebar.append(t29.tr.msg.sidebar_arrow); |
---|
149 | |
---|
150 | // create Infobox, editorbox, topnoticebox, design elements |
---|
151 | $("body").append(t29.tr.msg.create_ui_body_append); |
---|
152 | $("#content").before(t29.tr.msg.create_ui_topbox); |
---|
153 | $.each(["infobox", "editorbox", "topbox"], function(){ t29.tr[this] = $("#tr-"+this); }); |
---|
154 | t29.tr.infobox.hide(); |
---|
155 | t29.tr.editorbox.hide(); // default state |
---|
156 | |
---|
157 | // make topbox being fixed at top scrolling |
---|
158 | var top = t29.tr.topbox.offset().top; // - parseFloat($('#comment').css('marginTop').replace(/auto/, 0)) |
---|
159 | $(window).bind("scroll.t29tr", function(e) { |
---|
160 | var now_fixed = $(this).scrollTop() >= top; |
---|
161 | // since topbox was embedded in content (not sidebar), place is |
---|
162 | // removed there when switching from static to fixed. Setting the |
---|
163 | // height is a workaround. |
---|
164 | (p=t29.tr.topbox.parent()).css('height', now_fixed ? p.height() : ''); |
---|
165 | t29.tr.topbox.toggleClass('fixed', now_fixed); |
---|
166 | }); |
---|
167 | |
---|
168 | // create all event handlers in the topbox |
---|
169 | |
---|
170 | // Fields where clicking yields extender bar (poor man tab bar) |
---|
171 | var hideall_tabs = function() { |
---|
172 | t29.tr.topbox.find(".field.extends").removeClass('active'); |
---|
173 | t29.tr.topbox.find(".extender > div").slideUp(); |
---|
174 | } |
---|
175 | t29.tr.topbox.find(".field.extends").toggle(function(){ |
---|
176 | hideall_tabs(); // make sure no other is shown |
---|
177 | var extender = $(this).hasClass('name') ? 'name' : 'feedback'; |
---|
178 | t29.tr.topbox.find('.extender .'+extender).slideDown() |
---|
179 | $(this).addClass('active'); |
---|
180 | }, hideall_tabs); |
---|
181 | |
---|
182 | // User name box form |
---|
183 | t29.tr.topbox.find(".name :text").keyup(function(){ |
---|
184 | t29.tr.settings[$(this).attr('name')] = $(this).val(); |
---|
185 | t29.tr.topbox.find('.name .feedback').html("<b>"+t29.tr.settings.name+"</b> from <b>"+t29.tr.settings.location+"</b>"); |
---|
186 | t29.tr.topbox.find('.name .stored').text(' - Thank you'); |
---|
187 | }); |
---|
188 | |
---|
189 | // Edit whole page button |
---|
190 | t29.tr.topbox.find('.field.editwhole').click(t29.tr.edit_whole_page); |
---|
191 | t29.tr.topbox.find('.field.help').click(t29.tr.help); |
---|
192 | t29.tr.topbox.find('.field.exit').click(t29.tr.call('set_enabled', false)); |
---|
193 | |
---|
194 | |
---|
195 | // Create Editor UI (only once) |
---|
196 | t29.tr.editorbox.html(t29.tr.msg.create_editorui_editorbox); // remove all possible old classes |
---|
197 | t29.tr.editorbox.find(".cancel").click(t29.tr.stop_editing); |
---|
198 | t29.tr.editorbox.find(".submit").click(t29.tr.submit_editing); |
---|
199 | t29.tr.editorbox.find(".help").click(t29.tr.help); |
---|
200 | |
---|
201 | |
---|
202 | // create all wrapper elements (most important step) |
---|
203 | t29.tr.settings.editable_elements().wrapInner("<span class='tr-editable'/>"); |
---|
204 | t29.tr.editables = $(".tr-editable"); |
---|
205 | } // INITIAL ui created |
---|
206 | |
---|
207 | // regular ui creations: |
---|
208 | // update the nice arrow in the sidebar =) (some timeout for slow startups) |
---|
209 | setTimeout(function(){ |
---|
210 | t29.tr.sidebar.find(".arrow").css({ "border-bottom-width": |
---|
211 | (a=Math.floor(t29.tr.sidebar.outerHeight()/2-1)),"border-top-width": a }); |
---|
212 | }, 1000); |
---|
213 | } |
---|
214 | |
---|
215 | /** |
---|
216 | * Mouseover (mouseenter) handler for all editables. This will handle infobox |
---|
217 | * styling and content and setup other handlers. |
---|
218 | **/ |
---|
219 | t29.tr.mouseover_editables = function() { |
---|
220 | if(!t29.tr.is_enabled() || t29.tr.is_editing()) return; // disable while editing |
---|
221 | if(t29.tr.current_editable) { |
---|
222 | // this is weird and should not be - cleanup missed! |
---|
223 | t29.tr.current_editable.removeClass("tr-inspecting"); |
---|
224 | } |
---|
225 | t29.tr.current_editable = $(this).addClass('tr-inspecting'); |
---|
226 | |
---|
227 | // show infobox for current editable |
---|
228 | t29.tr.infobox.empty().append( (h=t29.tr.current_editable.hasClass("tr-corrected")) |
---|
229 | ? t29.tr.msg.infobox_corrected : t29.tr.msg.infobox_default); |
---|
230 | if(h) t29.tr.infobox.addClass("tr-corrected"); // tell infobox that current editable is corrected (for css) |
---|
231 | |
---|
232 | // position infobox for current editable |
---|
233 | t29.tr.infobox.css({ |
---|
234 | top: t29.tr.current_editable.offset().top - t29.tr.infobox.outerHeight(), |
---|
235 | left: t29.tr.current_editable.offset().left |
---|
236 | }).show(); |
---|
237 | |
---|
238 | $(document).bind("mousemove.t29tr", t29.tr.mouseover_editables_positioner); |
---|
239 | }; |
---|
240 | |
---|
241 | /** |
---|
242 | * Mouseover helper: Another handler for mouse movements to nicely arrange the |
---|
243 | * infobox according to the mouse cursor x position. |
---|
244 | **/ |
---|
245 | t29.tr.mouseover_editables_positioner = function(e) { |
---|
246 | if(e.pageX) { // document.mousemove event |
---|
247 | var left = e.pageX - t29.tr.infobox.outerWidth()/2; |
---|
248 | // check boundaries |
---|
249 | left = Math.max(left, t29.tr.current_editable.offset().left); |
---|
250 | left = Math.min(left, t29.tr.current_editable.offset().left + t29.tr.current_editable.outerWidth() - t29.tr.infobox.outerWidth()); |
---|
251 | t29.tr.infobox.css("left", left); |
---|
252 | } |
---|
253 | } |
---|
254 | |
---|
255 | /** |
---|
256 | * Mouseout (mouseleave) handler: Makes a nice cleanup. Can be called multiple times, |
---|
257 | * will detect if already cleaned up. This should be done, since it unbinds a |
---|
258 | * nervous mousemove handler. |
---|
259 | **/ |
---|
260 | t29.tr.mouseout_editables = function() { |
---|
261 | if(t29.tr.current_editable) { |
---|
262 | t29.tr.current_editable.removeClass('tr-inspecting'); |
---|
263 | t29.tr.current_editable = null; |
---|
264 | t29.tr.infobox.hide().removeClass(); // remove all classes |
---|
265 | $(document).unbind("mousemove.t29tr", t29.tr.mouseover_editables_positioner); |
---|
266 | } |
---|
267 | }; |
---|
268 | |
---|
269 | /** |
---|
270 | * Click handler for clicking editables. This will immediately start the editing |
---|
271 | * engine if the user is not already editing another text. |
---|
272 | **/ |
---|
273 | t29.tr.click_editables = function() { |
---|
274 | if(t29.tr.is_editing()) return; |
---|
275 | t29.tr.set_editing($(this)); |
---|
276 | }; |
---|
277 | |
---|
278 | /** |
---|
279 | * Testing function to find out if user is currently editing, that is: There is an editor |
---|
280 | * window currently open. ("The editor engine is running"). |
---|
281 | * @returns boolean value if an editor window is open |
---|
282 | **/ |
---|
283 | t29.tr.is_editing = function() { |
---|
284 | // user is editing. |
---|
285 | return (t29.tr.editor && !jQuery.isEmptyObject(t29.tr.editor)); |
---|
286 | }; |
---|
287 | |
---|
288 | /** |
---|
289 | * Testing function to find out if user modified something in the currently opened editing, |
---|
290 | * if avaliable. If the user doesn't currently edit at all, this returns false. |
---|
291 | * @returns boolean User works with local modified text and will be angry if you delete it |
---|
292 | */ |
---|
293 | t29.tr.is_really_editing = function() { |
---|
294 | // user is editing and has made some changes |
---|
295 | return t29.tr.is_editing() && (t29.tr.editor.html() != t29.tr.initial_editor.html()) |
---|
296 | }; |
---|
297 | |
---|
298 | /** |
---|
299 | * This is the main switch for the editor engine. Calling this function you can safely |
---|
300 | * start or stop editing. Starting is simple: Just tell it what to edit: |
---|
301 | * t29.tr.set_editing($("your element")); |
---|
302 | * Stopping is a brutal action, since this low level function does NOT check if there |
---|
303 | * are modifications. Use stop_editing() for an interactive version. Especially, |
---|
304 | * set_editing(false) won't fail :-) |
---|
305 | * @param editing_target_or_false false for turning off, any jQuery object for turning on |
---|
306 | * @returns nothing |
---|
307 | */ |
---|
308 | t29.tr.set_editing = function(editing_target_or_false) { |
---|
309 | if(editing_target_or_false && t29.tr.is_editing()) { |
---|
310 | alert("Bad state: Starting editing while editing?"); |
---|
311 | return; // bad |
---|
312 | } else if(!editing_target_or_false && !t29.tr.is_editing()) { |
---|
313 | // hab gar nicht bearbeitet. |
---|
314 | return; |
---|
315 | } |
---|
316 | |
---|
317 | var old_editor = t29.tr.editor; // backup old editor for cleanup |
---|
318 | t29.tr.editor = editing_target_or_false; |
---|
319 | $("body").toggleClass("tr-editing", t29.tr.is_editing()); |
---|
320 | $("body").toggleClass("tr-inspecting", t29.tr.is_enabled() && !t29.tr.is_editing()); |
---|
321 | |
---|
322 | if(t29.tr.is_editing()) { |
---|
323 | // start up editing |
---|
324 | |
---|
325 | // setup editor |
---|
326 | t29.tr.initial_editor = t29.tr.editor.clone(); // make a backup of the original, for the form |
---|
327 | t29.tr.editor.attr("contenteditable", "true").addClass("tr-editing").focus(); |
---|
328 | |
---|
329 | // switch the boxes |
---|
330 | t29.tr.mouseout_editables(); // rauemt vom editing auf (infobox.hide(), etc.) |
---|
331 | t29.tr.create_editorui(); |
---|
332 | |
---|
333 | // ask at window unloading |
---|
334 | window.onbeforeunload = function() { |
---|
335 | if(t29.tr.is_really_editing()) { |
---|
336 | return ("You have made changes on this page that you have not yet submitted." |
---|
337 | +"If you navigate away from this page you will loose your work."); |
---|
338 | } |
---|
339 | }; |
---|
340 | } else { |
---|
341 | // stop editing |
---|
342 | t29.tr.initial_editor = null; |
---|
343 | if(old_editor) { // falls es noch irgendeinen anderen Muell geben sollte |
---|
344 | old_editor.add(".tr-editing").attr("contenteditable", "false").removeClass("tr-editing"); |
---|
345 | } |
---|
346 | t29.tr.editorbox.hide(); |
---|
347 | } |
---|
348 | }; // set_editing |
---|
349 | |
---|
350 | /** |
---|
351 | * This is the interactive version of set_editing(false). If the user modified the |
---|
352 | * document, it will ask him if he wants to quit. If no, it returns false. |
---|
353 | * @returns boolean true if editing was stopped, false if not. |
---|
354 | **/ |
---|
355 | t29.tr.stop_editing = function() { |
---|
356 | // Frontend Function to *ask* user if he wants to stop editing |
---|
357 | if(!t29.tr.is_really_editing(true) || |
---|
358 | confirm("Do you want to quit the currently edited paragraph and loose all changes?")) { |
---|
359 | t29.tr.set_editing(false); |
---|
360 | return true; |
---|
361 | } else { |
---|
362 | return false; |
---|
363 | } |
---|
364 | }; |
---|
365 | |
---|
366 | /** |
---|
367 | * Shorthand method to start editing the whole #content area. May be called with |
---|
368 | * callbacks, directly, etc. Will make sure that there is no other editor. |
---|
369 | **/ |
---|
370 | t29.tr.edit_whole_page = function() { |
---|
371 | t29.tr.set_editing(false); // make sure there is no other editor |
---|
372 | $("#content").wrapInner("<div class='tr-editable'/>"); |
---|
373 | t29.tr.set_editing( $("#content > .tr-editable") ); |
---|
374 | }; |
---|
375 | |
---|
376 | /** |
---|
377 | * Button callback for Submitting in the Editor engine. This will compose the |
---|
378 | * HTTP POST call and send it via AJAX. Especially it immediately returns. |
---|
379 | **/ |
---|
380 | t29.tr.submit_editing = function() { |
---|
381 | // button submitting |
---|
382 | if(!t29.tr.is_really_editing()) { |
---|
383 | // funktioniert nicht zuverlaessig. |
---|
384 | //alert("You didn't make any changes to the text. Where's the improvement? :-)"); |
---|
385 | //return false; |
---|
386 | } |
---|
387 | |
---|
388 | $.ajax({ |
---|
389 | type: 'POST', |
---|
390 | url: '/en/dev/translation/submit.php', |
---|
391 | success: t29.tr.submit_successful, |
---|
392 | error: function(req, textStatus) { |
---|
393 | t29.tr.editorbox.removeClass('loading').addClass('error'); |
---|
394 | t29.tr.editorbox.find('h3').html("Sending your improved text failed!"); |
---|
395 | t29.tr.editorbox.find('p').html("Please consult the <span class='button small red'>Help</span>") |
---|
396 | .find('.button').click(t29.tr.help); |
---|
397 | if(req.responseText) |
---|
398 | t29.tr.editorbox.find('p').prepend("<b>"+req.responseText+"</b> "); |
---|
399 | alert("Submitting your text failed!"); |
---|
400 | }, |
---|
401 | data: { |
---|
402 | source: 'ajax', |
---|
403 | page: location.href, |
---|
404 | node: "foobar", // t29.tr.editor XQUERY PATH |
---|
405 | initial_text: t29.tr.initial_editor.text().replace(/\s+/g,' '), |
---|
406 | initial_html: t29.tr.initial_editor.html(), |
---|
407 | new_text: t29.tr.editor.text().replace(/\s+/g,' '), |
---|
408 | new_html: t29.tr.editor.html() |
---|
409 | } |
---|
410 | }); |
---|
411 | |
---|
412 | // wg. langen Ladezeiten: Buttons ausblenden! |
---|
413 | t29.tr.editorbox.addClass('loading'); |
---|
414 | }; |
---|
415 | |
---|
416 | /** |
---|
417 | * Callback function for success AJAX submission call. This will display a short |
---|
418 | * nice message before shutting down nicely the editor engine, leaving the user back |
---|
419 | * to inspect just another element. |
---|
420 | **/ |
---|
421 | t29.tr.submit_successful = function(server_data) { |
---|
422 | // Editorbox |
---|
423 | t29.tr.editorbox.removeClass('loading').addClass('success').prepend("<div class='response'>Thank you! :-)</div>"); |
---|
424 | t29.tr.editorbox.delay(1100).fadeOut(1000, function(){ |
---|
425 | t29.tr.set_editing(false); // sic - hard finishing. |
---|
426 | // + TODO REMARK "USER already edited"! |
---|
427 | }); |
---|
428 | |
---|
429 | // Editor |
---|
430 | t29.tr.editor.addClass("tr-corrected"); |
---|
431 | |
---|
432 | // System, user credits |
---|
433 | $("body").addClass("tr-successful"); |
---|
434 | t29.tr.sidebar.find(".dynamic").text( |
---|
435 | "Thank you very much for your contribution! Blablabla" |
---|
436 | ); |
---|
437 | }; |
---|
438 | |
---|
439 | /** |
---|
440 | * Helper function for set_editing(): Set up the User Interface elements for |
---|
441 | * the editor engine. This function can and should be called on each |
---|
442 | * set_editing(true) call, since it also cleans up :) |
---|
443 | **/ |
---|
444 | t29.tr.create_editorui = function() { |
---|
445 | // Basic initial setup of the editorbox (HTML, callbacks) is already done in general UI) |
---|
446 | |
---|
447 | |
---|
448 | t29.tr.editorbox.removeClass() |
---|
449 | .css('width', t29.tr.editor.width()) // IMPORTANT - to be done before outerHeight() call |
---|
450 | .css({ |
---|
451 | top: t29.tr.editor.offset().top - t29.tr.editorbox.outerHeight(), |
---|
452 | left: t29.tr.editor.offset().left |
---|
453 | }).show(); |
---|
454 | }; |
---|
455 | |
---|
456 | /** |
---|
457 | * Open a nice help window |
---|
458 | **/ |
---|
459 | t29.tr.help = function() { |
---|
460 | window.open("http://dev.technikum29.de/wiki/%dcbersetzung/Help"); |
---|
461 | |
---|
462 | }; |
---|
463 | |
---|
464 | |
---|
465 | |
---|
466 | t29.tr.display_startup_notice = function(msg) { |
---|
467 | // display a short text in the startup-thingy |
---|
468 | t29.tr.topbox.find('.startup').html( t29.tr.msg["startup_topbox_"+msg] ).show(); |
---|
469 | }; |
---|
470 | |
---|
471 | |
---|
472 | // Master entry point: Load onload handler at startup. |
---|
473 | $(t29.tr.onload); |
---|