1// Miscellaneous core Javascript functions for Moodle 2 3function popupchecker(msg) { 4 var testwindow = window.open('itestwin.html', '', 'width=1,height=1,left=0,top=0,scrollbars=no'); 5 if (testwindow == null) 6 {alert(msg);} 7 else { 8 testwindow.close(); 9 } 10} 11 12/* 13function popUpProperties(inobj) { 14/// Legacy function 15 var op = window.open(); 16 op.document.open('text/plain'); 17 for (objprop in inobj) { 18 op.document.write(objprop + ' => ' + inobj[objprop] + '\n'); 19 } 20 op.document.close(); 21} 22 23function fillmessagebox(text) { 24/// Legacy function 25 document.form.message.value = text; 26} 27 28function copyrichtext(textname) { 29/// Legacy stub for old editor - to be removed soon 30 return true; 31} 32*/ 33 34function checkall() { 35 var el = document.getElementsByTagName('input'); 36 for(var i=0; i<el.length; i++) { 37 if(el[i].type == 'checkbox') { 38 el[i].checked = true; 39 } 40 } 41} 42 43function checknone() { 44 var el = document.getElementsByTagName('input'); 45 for(var i=0; i<el.length; i++) { 46 if(el[i].type == 'checkbox') { 47 el[i].checked = false; 48 } 49 } 50} 51 52function lockoptions(formid, master, subitems) { 53 // Subitems is an array of names of sub items. 54 // Optionally, each item in subitems may have a 55 // companion hidden item in the form with the 56 // same name but prefixed by "h". 57 var form = document.forms[formid]; 58 59 if (eval("form."+master+".checked")) { 60 for (i=0; i<subitems.length; i++) { 61 unlockoption(form, subitems[i]); 62 } 63 } else { 64 for (i=0; i<subitems.length; i++) { 65 lockoption(form, subitems[i]); 66 } 67 } 68 return(true); 69} 70 71function lockoption(form,item) { 72 eval("form."+item+".disabled=true");/* IE thing */ 73 if(form.elements['h'+item]) { 74 eval("form.h"+item+".value=1"); 75 } 76} 77 78function unlockoption(form,item) { 79 eval("form."+item+".disabled=false");/* IE thing */ 80 if(form.elements['h'+item]) { 81 eval("form.h"+item+".value=0"); 82 } 83} 84 85/** 86 * Get the value of the 'virtual form element' with a particular name. That is, 87 * abstracts away the difference between a normal form element, like a select 88 * which is a single HTML element with a .value property, and a set of radio 89 * buttons, which is several HTML elements. 90 * 91 * @param form a HTML form. 92 * @param master the name of an element in that form. 93 * @return the value of that element. 94 */ 95function get_form_element_value(form, name) { 96 var element = form[name]; 97 if (!element) { 98 return null; 99 } 100 if (element.tagName) { 101 // Ordinarly thing like a select box. 102 return element.value; 103 } 104 // Array of things, like radio buttons. 105 for (var j = 0; j < element.length; j++) { 106 var el = element[j]; 107 if (el.checked) { 108 return el.value; 109 } 110 } 111 return null; 112} 113 114 115/** 116 * Set the disabled state of the 'virtual form element' with a particular name. 117 * This abstracts away the difference between a normal form element, like a select 118 * which is a single HTML element with a .value property, and a set of radio 119 * buttons, which is several HTML elements. 120 * 121 * @param form a HTML form. 122 * @param master the name of an element in that form. 123 * @param disabled the disabled state to set. 124 */ 125function set_form_element_disabled(form, name, disabled) { 126 var element = form[name]; 127 if (!element) { 128 return; 129 } 130 if (element.tagName) { 131 // Ordinarly thing like a select box. 132 element.disabled = disabled; 133 } 134 // Array of things, like radio buttons. 135 for (var j = 0; j < element.length; j++) { 136 var el = element[j]; 137 el.disabled = disabled; 138 } 139} 140 141/** 142 * Set the hidden state of the 'virtual form element' with a particular name. 143 * This abstracts away the difference between a normal form element, like a select 144 * which is a single HTML element with a .value property, and a set of radio 145 * buttons, which is several HTML elements. 146 * 147 * @param form a HTML form. 148 * @param master the name of an element in that form. 149 * @param hidden the hidden state to set. 150 */ 151function set_form_element_hidden(form, name, hidden) { 152 var element = form[name]; 153 if (!element) { 154 return; 155 } 156 if (element.tagName) { 157 var el = findParentNode(element, 'DIV', 'fitem', false); 158 if (el!=null) { 159 el.style.display = hidden ? 'none' : ''; 160 el.style.visibility = hidden ? 'hidden' : ''; 161 } 162 } 163 // Array of things, like radio buttons. 164 for (var j = 0; j < element.length; j++) { 165 var el = findParentNode(element[j], 'DIV', 'fitem', false); 166 if (el!=null) { 167 el.style.display = hidden ? 'none' : ''; 168 el.style.visibility = hidden ? 'hidden' : ''; 169 } 170 } 171} 172 173function lockoptionsall(formid) { 174 var form = document.forms[formid]; 175 var dependons = eval(formid + 'items'); 176 var tolock = []; 177 var tohide = []; 178 for (var dependon in dependons) { 179 // change for MooTools compatibility 180 if (!dependons.propertyIsEnumerable(dependon)) { 181 continue; 182 }
183 if (!form[dependon]) { 184 continue; 185 } 186 for (var condition in dependons[dependon]) { 187 for (var value in dependons[dependon][condition]) { 188 var lock; 189 var hide = false; 190 switch (condition) { 191 case 'notchecked': 192 lock = !form[dependon].checked; break; 193 case 'checked': 194 lock = form[dependon].checked; break; 195 case 'noitemselected': 196 lock = form[dependon].selectedIndex == -1; break; 197 case 'eq': 198 lock = get_form_element_value(form, dependon) == value; break; 199 case 'hide': 200 // hide as well as disable 201 hide = true; break; 202 default: 203 lock = get_form_element_value(form, dependon) != value; break; 204 } 205 for (var ei in dependons[dependon][condition][value]) { 206 var eltolock = dependons[dependon][condition][value][ei]; 207 if (hide) { 208 tohide[eltolock] = true; 209 } 210 if (tolock[eltolock] != null) { 211 tolock[eltolock] = lock || tolock[eltolock]; 212 } else { 213 tolock[eltolock] = lock; 214 } 215 } 216 } 217 } 218 } 219 for (var el in tolock) { 220 // change for MooTools compatibility 221 if (!tolock.propertyIsEnumerable(el)) { 222 continue; 223 } 224 set_form_element_disabled(form, el, tolock[el]); 225 if (tohide.propertyIsEnumerable(el)) { 226 set_form_element_hidden(form, el, tolock[el]); 227 } 228 } 229 return true; 230} 231 232function lockoptionsallsetup(formid) { 233 var form = document.forms[formid]; 234 var dependons = eval(formid+'items'); 235 for (var dependon in dependons) { 236 // change for MooTools compatibility 237 if (!dependons.propertyIsEnumerable(dependon)) { 238 continue; 239 } 240 var masters = form[dependon]; 241 if (!masters) { 242 continue; 243 } 244 if (masters.tagName) { 245 // If master is radio buttons, we get an array, otherwise we don't. 246 // Convert both cases to an array for convinience. 247 masters = [masters]; 248 } 249 for (var j = 0; j < masters.length; j++) { 250 master = masters[j]; 251 master.formid = formid; 252 master.onclick = function() {return lockoptionsall(this.formid);}; 253 master.onblur = function() {return lockoptionsall(this.formid);}; 254 master.onchange = function() {return lockoptionsall(this.formid);}; 255 } 256 } 257 for (var i = 0; i < form.elements.length; i++) { 258 var formelement = form.elements[i]; 259 if (formelement.type=='reset') { 260 formelement.formid = formid; 261 formelement.onclick = function() {this.form.reset();return lockoptionsall(this.formid);}; 262 formelement.onblur = function() {this.form.reset();return lockoptionsall(this.formid);}; 263 formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);}; 264 } 265 } 266 return lockoptionsall(formid); 267} 268 269 270function submitFormById(id) { 271 var theform = document.getElementById(id); 272 if(!theform) { 273 return false; 274 } 275 if(theform.tagName.toLowerCase() != 'form') { 276 return false; 277 } 278 if(!theform.onsubmit || theform.onsubmit()) { 279 return theform.submit(); 280 } 281} 282 283function select_all_in(elTagName, elClass, elId) { 284 var inputs = document.getElementsByTagName('input'); 285 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);}); 286 for(var i = 0; i < inputs.length; ++i) { 287 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') { 288 inputs[i].checked = 'checked'; 289 } 290 } 291} 292 293function deselect_all_in(elTagName, elClass, elId) { 294 var inputs = document.getElementsByTagName('INPUT'); 295 inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);}); 296 for(var i = 0; i < inputs.length; ++i) { 297 if(inputs[i].type == 'checkbox' || inputs[i].type == 'radio') { 298 inputs[i].checked = ''; 299 } 300 } 301} 302 303function confirm_if(expr, message) { 304 if(!expr) { 305 return true; 306 } 307 return confirm(message); 308} 309 310 311/* 312 findParentNode (start, elementName, elementClass, elementID) 313 314 Travels up the DOM hierarchy to find a parent element with the 315 specified tag name, class, and id. All conditions must be met, 316 but any can be ommitted. Returns the BODY element if no match 317 found. 318*/ 319function findParentNode(el, elName, elClass, elId) { 320 while(el.nodeName.toUpperCase() != 'BODY') { 321 if( 322 (!elName || el.nodeName.toUpperCase() == elName) && 323 (!elClass || el.className.indexOf(elClass) != -1) && 324 (!elId || el.id == elId)) 325 { 326 break; 327 } 328 el = el.parentNode; 329 } 330 return el; 331} 332/* 333 findChildNode (start, elementName, elementClass, elementID) 334 335 Travels down the DOM hierarchy to find all child elements with the 336 specified tag name, class, and id. All conditions must be met, 337 but any can be ommitted. 338 Doesn't examine children of matches. 339*/ 340function findChildNodes(start, tagName, elementClass, elementID, elementName) { 341 var children = new Array(); 342 for (var i = 0; i < start.childNodes.length; i++) { 343 var classfound = false;
344 var child = start.childNodes[i]; 345 if((child.nodeType == 1) &&//element node type 346 (elementClass && (typeof(child.className)=='string'))) { 347 var childClasses = child.className.split(/\s+/); 348 for (var childClassIndex in childClasses) { 349 if (childClasses[childClassIndex]==elementClass) { 350 classfound = true; 351 break; 352 } 353 } 354 } 355 if(child.nodeType == 1) { //element node type 356 if ( (!tagName || child.nodeName == tagName) && 357 (!elementClass || classfound)&& 358 (!elementID || child.id == elementID) && 359 (!elementName || child.name == elementName)) 360 { 361 children = children.concat(child); 362 } else { 363 children = children.concat(findChildNodes(child, tagName, elementClass, elementID, elementName)); 364 } 365 } 366 } 367 return children; 368} 369/* 370 elementSetHide (elements, hide) 371 372 Adds or removes the "hide" class for the specified elements depending on boolean hide. 373*/ 374function elementShowAdvanced(elements, show) { 375 for (var elementIndex in elements) { 376 element = elements[elementIndex]; 377 element.className = element.className.replace(new RegExp(' ?hide'), '') 378 if(!show) { 379 element.className += ' hide'; 380 } 381 } 382} 383 384function showAdvancedInit(addBefore, nameAttr, buttonLabel, hideText, showText) { 385 var showHideButton = document.createElement("input"); 386 showHideButton.type = 'button'; 387 showHideButton.value = buttonLabel; 388 showHideButton.name = nameAttr; 389 showHideButton.moodle = { 390 hideLabel: hideText, 391 showLabel: showText 392 }; 393 YAHOO.util.Event.addListener(showHideButton, 'click', showAdvancedOnClick); 394 el = document.getElementById(addBefore); 395 el.parentNode.insertBefore(showHideButton, el); 396} 397 398function showAdvancedOnClick(e) { 399 var button = e.target ? e.target : e.srcElement; 400 401 var toSet=findChildNodes(button.form, null, 'advanced'); 402 var buttontext = ''; 403 if (button.form.elements['mform_showadvanced_last'].value == '0' || button.form.elements['mform_showadvanced_last'].value == '' ) { 404 elementShowAdvanced(toSet, true); 405 buttontext = button.moodle.hideLabel; 406 button.form.elements['mform_showadvanced_last'].value = '1'; 407 } else { 408 elementShowAdvanced(toSet, false); 409 buttontext = button.moodle.showLabel; 410 button.form.elements['mform_showadvanced_last'].value = '0'; 411 } 412 var formelements = button.form.elements; 413 // Fixed MDL-10506 414 for (var i = 0; i < formelements.length; i++) { 415 if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')) { 416 formelements[i].value = buttontext; 417 } 418 } 419 //never submit the form if js is enabled. 420 return false; 421} 422 423function unmaskPassword(id) { 424 var pw = document.getElementById(id); 425 var chb = document.getElementById(id+'unmask'); 426 427 try { 428 // first try IE way - it can not set name attribute later 429 if (chb.checked) { 430 var newpw = document.createElement('<input type="text" autocomplete="off" name="'+pw.name+'">'); 431 } else { 432 var newpw = document.createElement('<input type="password" autocomplete="off" name="'+pw.name+'">'); 433 } 434 newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue; 435 } catch (e) { 436 var newpw = document.createElement('input'); 437 newpw.setAttribute('autocomplete', 'off'); 438 newpw.setAttribute('name', pw.name); 439 if (chb.checked) { 440 newpw.setAttribute('type', 'text'); 441 } else { 442 newpw.setAttribute('type', 'password'); 443 } 444 newpw.setAttribute('class', pw.getAttribute('class')); 445 } 446 newpw.id = pw.id; 447 newpw.size = pw.size; 448 newpw.onblur = pw.onblur; 449 newpw.onchange = pw.onchange; 450 newpw.value = pw.value; 451 pw.parentNode.replaceChild(newpw, pw); 452} 453 454/* 455 elementToggleHide (element, elementFinder) 456 457 If elementFinder is not provided, toggles the "hidden" class for the specified element. 458 If elementFinder is provided, then the "hidden" class will be toggled for the object 459 returned by the function call elementFinder(element). 460 461 If persistent == true, also sets a cookie for this. 462*/ 463function elementToggleHide(el, persistent, elementFinder, strShow, strHide) { 464 if(!elementFinder) { 465 var obj = el; //el:container 466 el = document.getElementById('togglehide_'+obj.id); 467 } 468 else { 469 var obj = elementFinder(el); //el:button. 470 } 471 if(obj.className.indexOf('hidden') == -1) { 472 obj.className += ' hidden'; 473 if (el.src) { 474 el.src = el.src.replace('switch_minus', 'switch_plus'); 475 el.alt = strShow;
476 el.title = strShow; 477 } 478 var shown = 0; 479 } 480 else { 481 obj.className = obj.className.replace(new RegExp(' ?hidden'), ''); 482 if (el.src) { 483 el.src = el.src.replace('switch_plus', 'switch_minus'); 484 el.alt = strHide; 485 el.title = strHide; 486 } 487 var shown = 1; 488 } 489 490 if(persistent == true) { 491 new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set(); 492 } 493} 494 495function elementCookieHide(id, strShow, strHide) { 496 var obj = document.getElementById(id); 497 var cook = new cookie('hide:' + id).read(); 498 if(cook != null) { 499 elementToggleHide(obj, false, null, strShow, strHide); 500 } 501} 502 503function filterByParent(elCollection, parentFinder) { 504 var filteredCollection = []; 505 for(var i = 0; i < elCollection.length; ++i) { 506 var findParent = parentFinder(elCollection[i]); 507 if(findParent.nodeName != 'BODY') { 508 filteredCollection.push(elCollection[i]); 509 } 510 } 511 return filteredCollection; 512} 513 514/* 515 All this is here just so that IE gets to handle oversized blocks 516 in a visually pleasing manner. It does a browser detect. So sue me. 517*/ 518 519function fix_column_widths() { 520 var agt = navigator.userAgent.toLowerCase(); 521 if ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) { 522 fix_column_width('left-column'); 523 fix_column_width('right-column'); 524 } 525} 526 527function fix_column_width(colName) { 528 if(column = document.getElementById(colName)) { 529 if(!column.offsetWidth) { 530 setTimeout("fix_column_width('" + colName + "')", 20); 531 return; 532 } 533 534 var width = 0; 535 var nodes = column.childNodes; 536 537 for(i = 0; i < nodes.length; ++i) { 538 if(nodes[i].className.indexOf("sideblock") != -1 ) { 539 if(width < nodes[i].offsetWidth) { 540 width = nodes[i].offsetWidth; 541 } 542 } 543 } 544 545 for(i = 0; i < nodes.length; ++i) { 546 if(nodes[i].className.indexOf("sideblock") != -1 ) { 547 nodes[i].style.width = width + 'px'; 548 } 549 } 550 } 551} 552 553 554/* 555 Insert myValue at current cursor position 556 */ 557function insertAtCursor(myField, myValue) { 558 // IE support 559 if (document.selection) { 560 myField.focus(); 561 sel = document.selection.createRange(); 562 sel.text = myValue; 563 } 564 // Mozilla/Netscape support 565 else if (myField.selectionStart || myField.selectionStart == '0') { 566 var startPos = myField.selectionStart; 567 var endPos = myField.selectionEnd; 568 myField.value = myField.value.substring(0, startPos) 569 + myValue + myField.value.substring(endPos, myField.value.length); 570 } else { 571 myField.value += myValue; 572 } 573} 574 575 576/* 577 Call instead of setting window.onload directly or setting body onload=. 578 Adds your function to a chain of functions rather than overwriting anything 579 that exists. 580*/ 581function addonload(fn) { 582 var oldhandler=window.onload; 583 window.onload=function() { 584 if(oldhandler) oldhandler(); 585 fn(); 586 } 587}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.