(bug 2115) Support shift-selecting multiple checkboxes with javascript
[lhc/web/wiklou.git] / skins / common / wikibits.js
1 // Wikipedia JavaScript support functions
2
3 var clientPC = navigator.userAgent.toLowerCase(); // Get client info
4 var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
5 && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
6 var is_safari = ((clientPC.indexOf('AppleWebKit')!=-1) && (clientPC.indexOf('spoofer')==-1));
7 var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
8 if (clientPC.indexOf('opera') != -1) {
9 var is_opera = true;
10 var is_opera_preseven = (window.opera && !document.childNodes);
11 var is_opera_seven = (window.opera && document.childNodes);
12 }
13
14 // add any onload functions in this hook (please don't hard-code any events in the xhtml source)
15
16 var doneOnloadHook;
17
18 if (!window.onloadFuncts)
19 var onloadFuncts = [];
20
21 function addOnloadHook(hookFunct) {
22 // Allows add-on scripts to add onload functions
23 onloadFuncts[onloadFuncts.length] = hookFunct;
24 }
25
26 function runOnloadHook() {
27 // don't run anything below this for non-dom browsers
28 if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName))
29 return;
30
31 histrowinit();
32 unhidetzbutton();
33 tabbedprefs();
34 akeytt();
35 scrollEditBox();
36 setupCheckboxShiftClick();
37
38 // Run any added-on functions
39 for (var i = 0; i < onloadFuncts.length; i++)
40 onloadFuncts[i]();
41
42 doneOnloadHook = true;
43 }
44
45 function hookEvent(hookName, hookFunct) {
46 if (window.addEventListener)
47 addEventListener(hookName, hookFunct, false);
48 else if (window.attachEvent)
49 attachEvent("on" + hookName, hookFunct);
50 }
51
52 hookEvent("load", runOnloadHook);
53
54 // document.write special stylesheet links
55 if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
56 if (is_opera_preseven) {
57 document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
58 } else if (is_opera_seven) {
59 document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
60 } else if (is_khtml) {
61 document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
62 }
63 }
64 // Un-trap us from framesets
65 if (window.top != window)
66 window.top.location = window.location;
67
68 // for enhanced RecentChanges
69 function toggleVisibility(_levelId, _otherId, _linkId) {
70 var thisLevel = document.getElementById(_levelId);
71 var otherLevel = document.getElementById(_otherId);
72 var linkLevel = document.getElementById(_linkId);
73 if (thisLevel.style.display == 'none') {
74 thisLevel.style.display = 'block';
75 otherLevel.style.display = 'none';
76 linkLevel.style.display = 'inline';
77 } else {
78 thisLevel.style.display = 'none';
79 otherLevel.style.display = 'inline';
80 linkLevel.style.display = 'none';
81 }
82 }
83
84 // page history stuff
85 // attach event handlers to the input elements on history page
86 function histrowinit() {
87 hf = document.getElementById('pagehistory');
88 if (!hf)
89 return;
90 lis = hf.getElementsByTagName('li');
91 for (i = 0; i < lis.length; i++) {
92 inputs = lis[i].getElementsByTagName('input');
93 if (inputs[0] && inputs[1]) {
94 inputs[0].onclick = diffcheck;
95 inputs[1].onclick = diffcheck;
96 }
97 }
98 diffcheck();
99 }
100
101 // check selection and tweak visibility/class onclick
102 function diffcheck() {
103 var dli = false; // the li where the diff radio is checked
104 var oli = false; // the li where the oldid radio is checked
105 hf = document.getElementById('pagehistory');
106 if (!hf)
107 return;
108 lis = hf.getElementsByTagName('li');
109 for (i=0;i<lis.length;i++) {
110 inputs = lis[i].getElementsByTagName('input');
111 if (inputs[1] && inputs[0]) {
112 if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
113 if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value)
114 return false;
115 if (oli) { // it's the second checked radio
116 if (inputs[1].checked) {
117 oli.className = "selected";
118 return false
119 }
120 } else if (inputs[0].checked) {
121 return false;
122 }
123 if (inputs[0].checked)
124 dli = lis[i];
125 if (!oli)
126 inputs[0].style.visibility = 'hidden';
127 if (dli)
128 inputs[1].style.visibility = 'hidden';
129 lis[i].className = "selected";
130 oli = lis[i];
131 } else { // no radio is checked in this row
132 if (!oli)
133 inputs[0].style.visibility = 'hidden';
134 else
135 inputs[0].style.visibility = 'visible';
136 if (dli)
137 inputs[1].style.visibility = 'hidden';
138 else
139 inputs[1].style.visibility = 'visible';
140 lis[i].className = "";
141 }
142 }
143 }
144 }
145
146 // generate toc from prefs form, fold sections
147 // XXX: needs testing on IE/Mac and safari
148 // more comments to follow
149 function tabbedprefs() {
150 var prefform = document.getElementById('preferences');
151 if (!prefform || !document.createElement)
152 return;
153 if (prefform.nodeName.toLowerCase() == 'a')
154 return; // Occasional IE problem
155 prefform.className = prefform.className + 'jsprefs';
156 var sections = new Array();
157 children = prefform.childNodes;
158 var seci = 0;
159 for (i = 0; i < children.length; i++) {
160 if (children[i].nodeName.toLowerCase() == 'fieldset') {
161 children[i].id = 'prefsection-' + seci;
162 children[i].className = 'prefsection';
163 if (is_opera || is_khtml)
164 children[i].className = 'prefsection operaprefsection';
165 legends = children[i].getElementsByTagName('legend');
166 sections[seci] = new Object();
167 legends[0].className = 'mainLegend';
168 if (legends[0] && legends[0].firstChild.nodeValue)
169 sections[seci].text = legends[0].firstChild.nodeValue;
170 else
171 sections[seci].text = '# ' + seci;
172 sections[seci].secid = children[i].id;
173 seci++;
174 if (sections.length != 1)
175 children[i].style.display = 'none';
176 else
177 var selectedid = children[i].id;
178 }
179 }
180 var toc = document.createElement('ul');
181 toc.id = 'preftoc';
182 toc.selectedid = selectedid;
183 for (i = 0; i < sections.length; i++) {
184 var li = document.createElement('li');
185 if (i == 0)
186 li.className = 'selected';
187 var a = document.createElement('a');
188 a.href = '#' + sections[i].secid;
189 a.onmousedown = a.onclick = uncoversection;
190 a.appendChild(document.createTextNode(sections[i].text));
191 a.secid = sections[i].secid;
192 li.appendChild(a);
193 toc.appendChild(li);
194 }
195 prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
196 document.getElementById('prefsubmit').id = 'prefcontrol';
197 }
198
199 function uncoversection() {
200 oldsecid = this.parentNode.parentNode.selectedid;
201 newsec = document.getElementById(this.secid);
202 if (oldsecid != this.secid) {
203 ul = document.getElementById('preftoc');
204 document.getElementById(oldsecid).style.display = 'none';
205 newsec.style.display = 'block';
206 ul.selectedid = this.secid;
207 lis = ul.getElementsByTagName('li');
208 for (i = 0; i< lis.length; i++) {
209 lis[i].className = '';
210 }
211 this.parentNode.className = 'selected';
212 }
213 return false;
214 }
215
216 // Timezone stuff
217 // tz in format [+-]HHMM
218 function checkTimezone(tz, msg) {
219 var localclock = new Date();
220 // returns negative offset from GMT in minutes
221 var tzRaw = localclock.getTimezoneOffset();
222 var tzHour = Math.floor( Math.abs(tzRaw) / 60);
223 var tzMin = Math.abs(tzRaw) % 60;
224 var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
225 if (tz != tzString) {
226 var junk = msg.split('$1');
227 document.write(junk[0] + "UTC" + tzString + junk[1]);
228 }
229 }
230
231 function unhidetzbutton() {
232 tzb = document.getElementById('guesstimezonebutton')
233 if (tzb)
234 tzb.style.display = 'inline';
235 }
236
237 // in [-]HH:MM format...
238 // won't yet work with non-even tzs
239 function fetchTimezone() {
240 // FIXME: work around Safari bug
241 var localclock = new Date();
242 // returns negative offset from GMT in minutes
243 var tzRaw = localclock.getTimezoneOffset();
244 var tzHour = Math.floor( Math.abs(tzRaw) / 60);
245 var tzMin = Math.abs(tzRaw) % 60;
246 var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
247 ":" + ((tzMin < 10) ? "0" : "") + tzMin;
248 return tzString;
249 }
250
251 function guessTimezone(box) {
252 document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
253 }
254
255 function showTocToggle() {
256 if (document.createTextNode) {
257 // Uses DOM calls to avoid document.write + XHTML issues
258
259 var linkHolder = document.getElementById('toctitle')
260 if (!linkHolder)
261 return;
262
263 var outerSpan = document.createElement('span');
264 outerSpan.className = 'toctoggle';
265
266 var toggleLink = document.createElement('a');
267 toggleLink.id = 'togglelink';
268 toggleLink.className = 'internal';
269 toggleLink.href = 'javascript:toggleToc()';
270 toggleLink.appendChild(document.createTextNode(tocHideText));
271
272 outerSpan.appendChild(document.createTextNode('['));
273 outerSpan.appendChild(toggleLink);
274 outerSpan.appendChild(document.createTextNode(']'));
275
276 linkHolder.appendChild(document.createTextNode(' '));
277 linkHolder.appendChild(outerSpan);
278
279 var cookiePos = document.cookie.indexOf("hidetoc=");
280 if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1)
281 toggleToc();
282 }
283 }
284
285 function changeText(el, newText) {
286 // Safari work around
287 if (el.innerText)
288 el.innerText = newText;
289 else if (el.firstChild && el.firstChild.nodeValue)
290 el.firstChild.nodeValue = newText;
291 }
292
293 function toggleToc() {
294 var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
295 var toggleLink = document.getElementById('togglelink')
296
297 if (toc && toggleLink && toc.style.display == 'none') {
298 changeText(toggleLink, tocHideText);
299 toc.style.display = 'block';
300 document.cookie = "hidetoc=0";
301 } else {
302 changeText(toggleLink, tocShowText);
303 toc.style.display = 'none';
304 document.cookie = "hidetoc=1";
305 }
306 }
307
308 // this function generates the actual toolbar buttons with localized text
309 // we use it to avoid creating the toolbar where javascript is not enabled
310 function addButton(imageFile, speedTip, tagOpen, tagClose, sampleText) {
311 // Don't generate buttons for browsers which don't fully
312 // support it.
313 if (!document.selection && !is_gecko) {
314 return false;
315 }
316 imageFile = escapeQuotesHTML(imageFile);
317 speedTip = escapeQuotesHTML(speedTip);
318 tagOpen = escapeQuotes(tagOpen);
319 tagClose = escapeQuotes(tagClose);
320 sampleText = escapeQuotes(sampleText);
321 var mouseOver = "";
322
323 document.write("<a href=\"javascript:insertTags");
324 document.write("('"+tagOpen+"','"+tagClose+"','"+sampleText+"');\">");
325 document.write("<img width=\"23\" height=\"22\" src=\""+imageFile+"\" border=\"0\" alt=\""+speedTip+"\" title=\""+speedTip+"\""+mouseOver+">");
326 document.write("</a>");
327 return;
328 }
329
330 function escapeQuotes(text) {
331 var re = new RegExp("'","g");
332 text = text.replace(re,"\\'");
333 re = new RegExp("\\n","g");
334 text = text.replace(re,"\\n");
335 return escapeQuotesHTML(text);
336 }
337
338 function escapeQuotesHTML(text) {
339 var re = new RegExp('&',"g");
340 text = text.replace(re,"&amp;");
341 var re = new RegExp('"',"g");
342 text = text.replace(re,"&quot;");
343 var re = new RegExp('<',"g");
344 text = text.replace(re,"&lt;");
345 var re = new RegExp('>',"g");
346 text = text.replace(re,"&gt;");
347 return text;
348 }
349
350 // apply tagOpen/tagClose to selection in textarea,
351 // use sampleText instead of selection if there is none
352 // copied and adapted from phpBB
353 function insertTags(tagOpen, tagClose, sampleText) {
354 if (document.editform)
355 var txtarea = document.editform.wpTextbox1;
356 else {
357 // some alternate form? take the first one we can find
358 var areas = document.getElementsByTagName('textarea');
359 var txtarea = areas[0];
360 }
361
362 // IE
363 if (document.selection && !is_gecko) {
364 var theSelection = document.selection.createRange().text;
365 if (!theSelection)
366 theSelection=sampleText;
367 txtarea.focus();
368 if (theSelection.charAt(theSelection.length - 1) == " ") { // exclude ending space char, if any
369 theSelection = theSelection.substring(0, theSelection.length - 1);
370 document.selection.createRange().text = tagOpen + theSelection + tagClose + " ";
371 } else {
372 document.selection.createRange().text = tagOpen + theSelection + tagClose;
373 }
374
375 // Mozilla
376 } else if(txtarea.selectionStart || txtarea.selectionStart == '0') {
377 var replaced = false;
378 var startPos = txtarea.selectionStart;
379 var endPos = txtarea.selectionEnd;
380 if (endPos-startPos)
381 replaced = true;
382 var scrollTop = txtarea.scrollTop;
383 var myText = (txtarea.value).substring(startPos, endPos);
384 if (!myText)
385 myText=sampleText;
386 if (myText.charAt(myText.length - 1) == " ") { // exclude ending space char, if any
387 subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " ";
388 } else {
389 subst = tagOpen + myText + tagClose;
390 }
391 txtarea.value = txtarea.value.substring(0, startPos) + subst +
392 txtarea.value.substring(endPos, txtarea.value.length);
393 txtarea.focus();
394 //set new selection
395 if (replaced) {
396 var cPos = startPos+(tagOpen.length+myText.length+tagClose.length);
397 txtarea.selectionStart = cPos;
398 txtarea.selectionEnd = cPos;
399 } else {
400 txtarea.selectionStart = startPos+tagOpen.length;
401 txtarea.selectionEnd = startPos+tagOpen.length+myText.length;
402 }
403 txtarea.scrollTop = scrollTop;
404
405 // All other browsers get no toolbar.
406 // There was previously support for a crippled "help"
407 // bar, but that caused more problems than it solved.
408 }
409 // reposition cursor if possible
410 if (txtarea.createTextRange)
411 txtarea.caretPos = document.selection.createRange().duplicate();
412 }
413
414 function akeytt() {
415 if (typeof ta == "undefined" || !ta)
416 return;
417 var pref = 'alt-';
418 if (is_safari || navigator.userAgent.toLowerCase().indexOf('mac') + 1
419 || navigator.userAgent.toLowerCase().indexOf('konqueror') + 1 )
420 pref = 'control-';
421 if (is_opera)
422 pref = 'shift-esc-';
423
424 for (var id in ta) {
425 var n = document.getElementById(id);
426 if (n) {
427 var a = null;
428 var ak = '';
429 // Are we putting accesskey in it
430 if (ta[id][0].length > 0) {
431 // Is this object a object? If not assume it's the next child.
432
433 if (n.nodeName.toLowerCase() == "a") {
434 a = n;
435 } else {
436 a = n.childNodes[0];
437 }
438
439 if (a) {
440 a.accessKey = ta[id][0];
441 ak = ' ['+pref+ta[id][0]+']';
442 }
443 } else {
444 // We don't care what type the object is when assigning tooltip
445 a = n;
446 ak = '';
447 }
448
449 if (a) {
450 a.title = ta[id][1]+ak;
451 }
452 }
453 }
454 }
455
456 function setupRightClickEdit() {
457 if (document.getElementsByTagName) {
458 var divs = document.getElementsByTagName('div');
459 for (var i = 0; i < divs.length; i++) {
460 var el = divs[i];
461 if(el.className == 'editsection') {
462 addRightClickEditHandler(el);
463 }
464 }
465 }
466 }
467
468 function addRightClickEditHandler(el) {
469 for (var i = 0; i < el.childNodes.length; i++) {
470 var link = el.childNodes[i];
471 if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
472 var editHref = link.getAttribute('href');
473
474 // find the following a
475 var next = el.nextSibling;
476 while (next.nodeType != 1)
477 next = next.nextSibling;
478
479 // find the following header
480 next = next.nextSibling;
481 while (next.nodeType != 1)
482 next = next.nextSibling;
483
484 if (next && next.nodeType == 1 &&
485 next.nodeName.match(/^[Hh][1-6]$/)) {
486 next.oncontextmenu = function() {
487 document.location = editHref;
488 return false;
489 }
490 }
491 }
492 }
493 }
494
495 function setupCheckboxShiftClick() {
496 if (document.getElementsByTagName) {
497 var uls = document.getElementsByTagName('ul');
498 var len = uls.length;
499 for (var i = 0; i < len; ++i) {
500 addCheckboxClickHandlers(uls[i]);
501 }
502 }
503 }
504
505 function addCheckboxClickHandlers(ul) {
506 if ( !ul.childNodes ) {
507 return;
508 }
509 var len = ul.childNodes.length;
510 if (len < 2) {
511 return;
512 }
513 ul.checkboxes = [];
514 ul.lastCheckbox = null;
515 for (var i = 0; i<len; ++i) {
516 var child = ul.childNodes[i];
517 if ( child && child.childNodes && child.childNodes[0] ) {
518 var cb = child.childNodes[0];
519 if ( !cb.nodeName || cb.nodeName.toLowerCase() != 'input' ||
520 !cb.type || cb.type.toLowerCase() != 'checkbox' ) {
521 continue;
522 }
523 cb.index = ul.checkboxes.push(cb) - 1;
524 cb.container = ul;
525 cb.onmouseup = checkboxMouseupHandler;
526 }
527 }
528 }
529
530 function checkboxMouseupHandler(e) {
531 if (typeof e == 'undefined') {
532 e = window.event;
533 }
534 if ( !e.shiftKey || this.container.lastCheckbox === null ) {
535 this.container.lastCheckbox = this.index;
536 return true;
537 }
538 var endState = !this.checked;
539 if ( is_opera ) { // opera has already toggled the checkbox by this point
540 endState = !endState;
541 }
542 var start, finish;
543 if ( this.index < this.container.lastCheckbox ) {
544 start = this.index + 1;
545 finish = this.container.lastCheckbox;
546 } else {
547 start = this.container.lastCheckbox;
548 finish = this.index - 1;
549 }
550 for (var i = start; i <= finish; ++i ) {
551 this.container.checkboxes[i].checked = endState;
552 }
553 this.container.lastCheckbox = this.index;
554 return true;
555 }
556
557 function fillDestFilename() {
558 if (!document.getElementById)
559 return;
560 var path = document.getElementById('wpUploadFile').value;
561 // Find trailing part
562 var slash = path.lastIndexOf('/');
563 var backslash = path.lastIndexOf('\\');
564 var fname;
565 if (slash == -1 && backslash == -1) {
566 fname = path;
567 } else if (slash > backslash) {
568 fname = path.substring(slash+1, 10000);
569 } else {
570 fname = path.substring(backslash+1, 10000);
571 }
572
573 // Capitalise first letter and replace spaces by underscores
574 fname = fname.charAt(0).toUpperCase().concat(fname.substring(1,10000)).replace(/ /g, '_');
575
576 // Output result
577 var destFile = document.getElementById('wpDestFile');
578 if (destFile)
579 destFile.value = fname;
580 }
581
582
583 function considerChangingExpiryFocus() {
584 if (!document.getElementById)
585 return;
586 var drop = document.getElementById('wpBlockExpiry');
587 if (!drop)
588 return;
589 var field = document.getElementById('wpBlockOther');
590 if (!field)
591 return;
592 var opt = drop.value;
593 if (opt == 'other')
594 field.style.display = '';
595 else
596 field.style.display = 'none';
597 }
598
599 function scrollEditBox() {
600 var editBoxEl = document.getElementById("wpTextbox1");
601 var scrollTopEl = document.getElementById("wpScrolltop");
602 var editFormEl = document.getElementById("editform");
603
604 if (editBoxEl && scrollTopEl) {
605 if (scrollTopEl.value) editBoxEl.scrollTop = scrollTopEl.value;
606 editFormEl.onsubmit = function() {
607 document.getElementById("wpScrolltop").value = document.getElementById("wpTextbox1").scrollTop;
608 }
609 }
610 }
611
612 hookEvent("load", scrollEditBox);
613
614 function allmessagesfilter() {
615 text = document.getElementById('allmessagesinput').value;
616 k = document.getElementById('allmessagestable');
617 if (!k) { return;}
618
619 var items = k.getElementsByTagName('span');
620
621 if ( text.length > allmessages_prev.length ) {
622 for (var i = items.length-1, j = 0; i >= 0; i--) {
623 j = allmessagesforeach(items, i, j);
624 }
625 } else {
626 for (var i = 0, j = 0; i < items.length; i++) {
627 j = allmessagesforeach(items, i, j);
628 }
629 }
630 allmessages_prev = text;
631 }
632
633 function allmessagesforeach(items, i, j) {
634 var hItem = items[i].getAttribute('id');
635 if (hItem.substring(0,17) == 'sp-allmessages-i-') {
636 if (items[i].firstChild && items[i].firstChild.nodeName == '#text' && items[i].firstChild.nodeValue.indexOf(text) != -1) {
637 var itemA = document.getElementById( hItem.replace('i', 'r1') );
638 var itemB = document.getElementById( hItem.replace('i', 'r2') );
639 if ( itemA.style.display != '' ) {
640 var s = "allmessageshider(\"" + hItem.replace('i', 'r1') + "\", \"" + hItem.replace('i', 'r2') + "\", '')";
641 var k = window.setTimeout(s,j++*5);
642 }
643 } else {
644 var itemA = document.getElementById( hItem.replace('i', 'r1') );
645 var itemB = document.getElementById( hItem.replace('i', 'r2') );
646 if ( itemA.style.display != 'none' ) {
647 var s = "allmessageshider(\"" + hItem.replace('i', 'r1') + "\", \"" + hItem.replace('i', 'r2') + "\", 'none')";
648 var k = window.setTimeout(s,j++*5);
649 }
650 }
651 }
652 return j;
653 }
654
655
656 function allmessageshider(idA, idB, cstyle) {
657 var itemA = document.getElementById( idA );
658 var itemB = document.getElementById( idB );
659 if (itemA) { itemA.style.display = cstyle; }
660 if (itemB) { itemB.style.display = cstyle; }
661 }
662
663 function allmessagesmodified() {
664 allmessages_modified = !allmessages_modified;
665 k = document.getElementById('allmessagestable');
666 if (!k) { return;}
667 var items = k.getElementsByTagName('tr');
668 for (var i = 0, j = 0; i< items.length; i++) {
669 if (!allmessages_modified ) {
670 if ( items[i].style.display != '' ) {
671 var s = "allmessageshider(\"" + items[i].getAttribute('id') + "\", null, '')";
672 var k = window.setTimeout(s,j++*5);
673 }
674 } else if (items[i].getAttribute('class') == 'def' && allmessages_modified) {
675 if ( items[i].style.display != 'none' ) {
676 var s = "allmessageshider(\"" + items[i].getAttribute('id') + "\", null, 'none')";
677 var k = window.setTimeout(s,j++*5);
678 }
679 }
680 }
681 }
682
683 function allmessagesshow() {
684 k = document.getElementById('allmessagesfilter');
685 if (k) { k.style.display = ''; }
686
687 allmessages_prev = '';
688 allmessages_modified = false;
689 }
690
691 hookEvent("load", allmessagesshow);