1 /** 2 * Top-level namespace of these objects. 3 * @namespace 4 */ 5 var ort; 6 (function(ort) { 7 'use strict'; 8 9 /** 10 * Convenience function to resolve a set of translated strings into a 11 * single one depending upon the current language. 12 * @param {langmap} vals - All translations of a given word. 13 * @private 14 * @function _strlang 15 * @memberof ort 16 */ 17 function _strlang(vals) 18 { 19 var lang; 20 lang = document.documentElement.lang; 21 if (null !== lang && lang in vals) 22 return vals[lang]; 23 else if ('_default' in vals) 24 return vals['_default']; 25 else 26 return ''; 27 } 28 29 /** 30 * Used exclusively by enumerations and bitfields to do language 31 * replacement conditional upon the label (<i>jslabel</i> in the 32 * configuration). 33 * Like {@link ort._replcl} with inclusion set to false. 34 * @param {HTMLElement} e - The root of the DOM tree in which we 35 * query for elements to fill into. 36 * @param {String} name - The class name we search for within the 37 * root (not inclusive). 38 * @param {langmap} vals - All possible translations. 39 * @private 40 * @function _replcllang 41 * @memberof ort 42 */ 43 function _replcllang(e, name, vals) 44 { 45 _replcl(e, name, _strlang(vals), false); 46 } 47 48 /** 49 * Used exclusively by enumerations and bitfields to do language 50 * replacement conditional upon the label (<i>jslabel</i> in the 51 * configuration). 52 * Like {@link ort._repl}. 53 * @param {HTMLElement} e - The root of the DOM tree in which we 54 * query for elements to fill into. 55 * @param {langmap} vals - All possible translations. 56 * @private 57 * @function _repllang 58 * @memberof ort 59 */ 60 function _repllang(e, vals) 61 { 62 _repl(e, _strlang(vals)); 63 } 64 65 function _attr(e, attr, text) 66 { 67 if (null !== e) 68 e.setAttribute(attr, text); 69 } 70 71 function _rattr(e, attr) 72 { 73 if (null !== e) 74 e.removeAttribute(attr); 75 } 76 77 /** 78 * Internal function for checking inputs for all elements of class 79 * strct-name-value-checked whose value matches the object's value. 80 * If the object is null, all elements are unchecked. 81 * @param {HTMLElement} e - The root of the DOM tree in which we 82 * query for elements to fill into. 83 * @param {String} strct - The name of the structure that we're 84 * filling in. 85 * @param {String} name - The name of the field. 86 * @param {Number|String|null} obj - The data itself. 87 * @param {Boolean} inc - Whether to include the root element in 88 * looking for elements to fill. 89 * @private 90 * @function _fillValueChecked 91 * @memberof ort 92 */ 93 function _fillValueChecked(e, fname, val, inc) 94 { 95 var list; 96 var i; 97 var valstr; 98 fname += '-value-checked'; 99 valstr = null === val ? null : 100 ("number" === typeof val ? val.toString() : val); 101 list = _elemList(e, fname, inc); 102 for (i = 0; i < list.length; i++) 103 if (valstr === null) 104 _rattr(list[i], 'checked'); 105 else if (valstr === (list[i]).value) 106 _attr(list[i], 'checked', 'true'); 107 else 108 _rattr(list[i], 'checked'); 109 } 110 111 /** 112 * Internal function that takes all <code><option></code> 113 * elements in the root and sets or unsets their 114 * <code>selected</code> status depending upon whether it matches the 115 * object's value. 116 * @param {HTMLElement} e - The root of the DOM tree in which we 117 * query for elements to fill into. 118 * @param {Number|String} val - The object's value. 119 * @private 120 * @function _fillValueSelect 121 * @memberof ort 122 */ 123 function _fillValueSelect(e, val) 124 { 125 var list; 126 var i; 127 var v; 128 if (null === e) 129 return; 130 list = e.getElementsByTagName('option'); 131 for (i = 0; i < list.length; i++) { 132 v = 'number' === typeof val ? 133 parseInt((list[i]).value) : 134 (list[i]).value; 135 if (val === v) 136 _attr(list[i], 'selected', 'true'); 137 else 138 _rattr(list[i], 'selected'); 139 } 140 } 141 142 function _attrcl(e, attr, name, text, inc) 143 { 144 var list; 145 var i; 146 if (null === e) 147 return; 148 list = _elemList(e, name, inc); 149 for (i = 0; i < list.length; i++) 150 _attr(list[i], attr, text); 151 } 152 153 function _elemList(e, cls, inc) 154 { 155 var a; 156 var list; 157 var i; 158 a = []; 159 if (null === e) 160 return a; 161 list = e.getElementsByClassName(cls); 162 for (i = 0; i < list.length; i++) 163 a.push(list[i]); 164 if (inc && e.classList.contains(cls)) 165 a.push(e); 166 return a; 167 } 168 169 function _repl(e, text) 170 { 171 if (null === e) 172 return; 173 while (e.firstChild) 174 e.removeChild(e.firstChild); 175 e.appendChild(document.createTextNode(text)); 176 } 177 178 /** 179 * Internal function for filling in ISO-8601 dates. 180 * @param {HTMLElement} e - The root of the DOM tree in which we 181 * query for elements to fill into. 182 * @param {String} strct - The name of the structure that we're 183 * filling in. 184 * @param {String} name - The name of the field. 185 * @param {Number|null} obj - The data itself. 186 * @param {Boolean} inc - Whether to include the root element in 187 * looking for elements to fill. 188 * @private 189 * @function _fillDateValue 190 * @memberof ort 191 */ 192 function _fillDateValue(e, strct, name, val, inc) 193 { 194 var fname; 195 var year; 196 var mo; 197 var day; 198 var full; 199 var d; 200 if (null === val) 201 return; 202 d = new Date(); 203 d.setTime(val * 1000); 204 year = d.getFullYear(); 205 mo = d.getMonth() + 1; 206 day = d.getDate(); 207 full = year + '-' + 208 (mo < 10 ? '0' : '') + mo + '-' + 209 (day < 10 ? '0' : '') + day; 210 fname = strct + '-' + name + '-date-value'; 211 _attrcl(e, 'value', fname, full, inc); 212 fname = strct + '-' + name + '-date-text'; 213 _replcl(e, fname, full, inc); 214 } 215 216 /** 217 * Internal function for checking inputs for all elements of class 218 * strct-name-bits-checked whose value is the bit-wise AND of the 219 * object's value. If the object is null, all elements are unchecked. 220 * @param {HTMLElement} e - The root of the DOM tree in which we 221 * query for elements to fill into. 222 * @param {String} strct - The name of the structure that we're 223 * filling in. 224 * @param {String} name - The name of the field. 225 * @param {Number|null} obj - The data itself. 226 * @param {Boolean} inc - Whether to include the root element in 227 * looking for elements to fill. 228 * @private 229 * @function _fillBitsChecked 230 * @memberof ort 231 */ 232 function _fillBitsChecked(e, strct, name, val, inc) 233 { 234 var list; 235 var fname; 236 var i; 237 var v; 238 fname = strct + '-' + name + '-bits-checked'; 239 list = _elemList(e, fname, inc); 240 for (i = 0; i < list.length; i++) { 241 if (val === null) { 242 _rattr(list[i], 'checked'); 243 continue; 244 } 245 v = parseInt((list[i]).value); 246 if (isNaN(v)) 247 _rattr(list[i], 'checked'); 248 else if (0 === v && 0 === val) 249 _attr(list[i], 'checked', 'true'); 250 else if ((1 << (v - 1)) & val) 251 _attr(list[i], 'checked', 'true'); 252 else 253 _rattr(list[i], 'checked'); 254 } 255 } 256 257 /** 258 * Internal function for filling a structure field. 259 * This first does the has/no class setting for null values, then 260 * optionally returns if null (running the custom fields first), 261 * otherwise the generic text/value/etc fields, then finally the 262 * custom fields. 263 * @param {HTMLElement} e - The root of the DOM tree in which we 264 * query for elements to fill into. 265 * @param {String} strct - The name of the structure that we're 266 * filling in. 267 * @param {String} name - The name of the field. 268 * @param {ort.DataCallbacks|null} custom - Custom callback functions 269 * to invoke on the field. 270 * @param obj - The data itself, which is either a native type or one 271 * of the data interfaces for an application-specific type. 272 * @param {Boolean} inc - Whether to include the root element in 273 * looking for elements to fill. Note that nested structures are 274 * alwyas filled non-inclusively. 275 * @param {Boolean} cannull - Whether the data object might be null. 276 * @param {Boolean} isblob - Whether the data object is a blob. 277 * @param sub - If the data object is a nested structure interface, 278 * this is the allocated class of that interface. 279 * @private 280 * @function _fillField 281 * @memberof ort 282 */ 283 function _fillField(e, strct, name, custom, obj, inc, cannull, isblob, sub) 284 { 285 var i; 286 var fname; 287 var list; 288 fname = strct + '-' + name; 289 /* First handle our has/no null situation. */ 290 if (cannull) { 291 if (null === obj) { 292 _hidecl(e, strct + '-has-' + name, inc); 293 _showcl(e, strct + '-no-' + name, inc); 294 } else { 295 _showcl(e, strct + '-has-' + name, inc); 296 _hidecl(e, strct + '-no-' + name, inc); 297 } 298 } 299 /* Don't process null values that can be null. */ 300 if (cannull && null === obj) { 301 if (null !== custom && fname in custom) { 302 if (custom[fname] instanceof Array) { 303 for (i = 0; i < custom[fname].length; i++) 304 custom[fname][i](e, fname, null); 305 } else { 306 custom[fname](e, fname, null); 307 } 308 } 309 return; 310 } 311 /* Non-null non-structs. */ 312 /* Don't account for blobs. */ 313 if (null !== sub) { 314 list = _elemList(e, fname + '-obj', inc); 315 for (i = 0; i < list.length; i++) { 316 sub.fillInner(list[i], custom); 317 } 318 } else if ( ! isblob) { 319 list = _elemList(e, fname + '-enum-select', inc); 320 for (i = 0; i < list.length; i++) { 321 _fillValueSelect(list[i], obj); 322 } 323 _replcl(e, fname + '-text', obj, inc); 324 _attrcl(e, 'value', fname + '-value', obj, inc); 325 _fillValueChecked(e, fname, obj, inc); 326 } 327 /* Lastly, handle the custom callback. */ 328 if (null !== custom && fname in custom) { 329 if (custom[fname] instanceof Array) { 330 for (i = 0; i < custom[fname].length; i++) 331 custom[fname][i](e, fname, obj); 332 } else { 333 custom[fname](e, fname, obj); 334 } 335 } 336 } 337 338 function _replcl(e, name, text, inc) 339 { 340 var list; 341 var i; 342 if (null === e) 343 return; 344 list = _elemList(e, name, inc); 345 for (i = 0; i < list.length; i++) 346 _repl(list[i], text); 347 } 348 349 function _classadd(e, name) 350 { 351 if (null === e) 352 return(null); 353 if ( ! e.classList.contains(name)) 354 e.classList.add(name); 355 return(e); 356 } 357 358 function _classaddcl(e, name, cls, inc) 359 { 360 var list; 361 var i; 362 if (null === e) 363 return; 364 list = _elemList(e, name, inc); 365 for (i = 0; i < list.length; i++) 366 _classadd(list[i], cls); 367 } 368 369 function _hide(e) 370 { 371 if (null === e) 372 return null; 373 if ( ! e.classList.contains('hide')) 374 e.classList.add('hide'); 375 return e; 376 } 377 378 function _hidecl(e, name, inc) 379 { 380 var list; 381 var i; 382 if (null === e) 383 return; 384 list = _elemList(e, name, inc); 385 for (i = 0; i < list.length; i++) 386 _hide(list[i]); 387 } 388 389 function _show(e) 390 { 391 if (null === e) 392 return null; 393 if (e.classList.contains('hide')) 394 e.classList.remove('hide'); 395 return e; 396 } 397 398 function _showcl(e, name, inc) 399 { 400 var list; 401 var i; 402 if (null === e) 403 return; 404 list = _elemList(e, name, inc); 405 for (i = 0; i < list.length; i++) 406 _show(list[i]); 407 } 408 409 /** 410 * All possible callback functions for passing to the "custom" 411 * associative array when filling in DOM trees. 412 * @interface ort.DataCallbacks 413 */ 414 /** 415 * 416 * A user within our system.<br/> 417 * 418 * @interface ort.userData 419 */ 420 /** 421 * 422 * A logged-in user.<br/> 423 * 424 * @interface ort.sessData 425 */ 426 /** 427 * Accepts {@link ort.userData} for writing into a DOM tree. 428 * @param {(ort.userData|ort.userData[])} obj - The object(s) to 429 * write. 430 * @memberof ort 431 * @constructor 432 * @class 433 */ 434 var user = (function() 435 { 436 function user(o) 437 { 438 this.obj = o; 439 } 440 /** 441 * Write the {@link ort.userData} into the given HTMLElement in 442 * the DOM tree. 443 * If constructed with an array, the first element is used. 444 * Elements within (and including) "e" having the following 445 * classes are manipulated as follows: 446 * <ul> 447 * <li>user-email-enum-select: sets the <code>select</code> 448 * attribute for <code><option></code> values matching 449 * <i>email</i> under the element</li> 450 * <li>user-email-value-checked: sets the <code>checked</code> 451 * attribute under the element matching the input</li> 452 * <li>user-email-text: replace contents with <i>email</i> 453 * data</li> 454 * <li>user-email-value: replace <code>value</code> attribute 455 * with <i>email</i> data</li> 456 * <li>user-hash-enum-select: sets the <code>select</code> 457 * attribute for <code><option></code> values matching 458 * <i>hash</i> under the element</li> 459 * <li>user-hash-value-checked: sets the <code>checked</code> 460 * attribute under the element matching the input</li> 461 * <li>user-hash-text: replace contents with <i>hash</i> 462 * data</li> 463 * <li>user-hash-value: replace <code>value</code> attribute with 464 * <i>hash</i> data</li> 465 * <li>user-id-enum-select: sets the <code>select</code> 466 * attribute for <code><option></code> values matching 467 * <i>id</i> under the element</li> 468 * <li>user-id-value-checked: sets the <code>checked</code> 469 * attribute under the element matching the input</li> 470 * <li>user-id-text: replace contents with <i>id</i> data</li> 471 * <li>user-id-value: replace <code>value</code> attribute with 472 * <i>id</i> data</li> 473 * </ul> 474 * @param {HTMLElement} e - The DOM element. 475 * @param {ort.DataCallbacks} custom - The optional dictionary of 476 * functions keyed by structure and field name (e.g., <i>foo</i> 477 * structure, <i>bar</i> field would be <code>foo-bar</code>). 478 * The value is a function for custom handling that accepts the 479 * "e" value, the name of the structure-field, and the value of 480 * the structure and field. 481 * You may also specify an array of functions instead of a 482 * singleton. 483 * These callbacks are invoked <b>after</b> the generic classes 484 * are filled. 485 * @function fill 486 * @memberof ort.user# 487 */ 488 user.prototype.fill = function(e, custom) 489 { 490 this._fill(e, this.obj, true, custom); 491 }; 492 493 /** 494 * Like {@link ort.user#fill} but instead of accepting a single 495 * element to fill, filling into all elements (non-inclusive) 496 * matching the given class name beneath (non-inclusive) the 497 * given root. 498 * @param {HTMLElement} e - The DOM element. 499 * @param {String} name - The name of the class into which to 500 * fill. 501 * @param {ort.DataCallbacks} custom - The optional custom 502 * handler dictionary (see {@link ort.user#fill} for details). 503 * @function fillByClass 504 * @memberof ort.user# 505 */ 506 user.prototype.fillByClass = function(e, name, custom) 507 { 508 this._fillByClass(e, name, true, custom); 509 }; 510 511 /** 512 * Like {@link ort.user#fillByClass} but inclusive the root and 513 * targets by class. 514 * @param {HTMLElement} e - The DOM element. 515 * @param {String} name - The name of the class into which to 516 * fill. 517 * @param {ort.DataCallbacks} custom - The optional custom 518 * handler dictionary (see {@link ort.user#fill} for details). 519 * @function fillInnerByClass 520 * @memberof ort.user# 521 */ 522 user.prototype.fillInnerByClass = function(e, name, custom) 523 { 524 this._fillByClass(e, name, false, custom); 525 }; 526 527 /** 528 * Like {@link ort.user#fill} but not including the root element 529 * "e". 530 * @param {HTMLElement} e - The DOM element. 531 * @param {ort.DataCallbacks} custom - The optional custom 532 * handler dictionary (see {@link ort.user#fill} for details). 533 * @function fillInner 534 * @memberof ort.user# 535 */ 536 user.prototype.fillInner = function(e, custom) 537 { 538 this._fill(e, this.obj, false, custom); 539 }; 540 541 /** 542 * Implements all {@link ort.user#fill} functions. 543 * @param {HTMLElement} e - The DOM element. 544 * @param {ort.userData|ort.userData[]|null} o - The object (or 545 * array) to fill. 546 * @param {Boolean} inc - Whether to include the root or not when 547 * processing. 548 * @param {ort.DataCallbacks} custom - The optional custom 549 * handler dictionary (see {@link ort.user#fill}). 550 * @private 551 * @function _fill 552 * @memberof ort.user# 553 */ 554 user.prototype._fill = function(e, o, inc, custom) 555 { 556 var i; 557 if (null === o || null === e) 558 return; 559 if (o instanceof Array) { 560 if (0 === o.length) 561 return; 562 o = o[0]; 563 } 564 if (typeof custom === 'undefined') 565 custom = null; 566 _fillField(e, 'user', 'email', custom, o.email, inc, false, false, null); 567 _fillField(e, 'user', 'hash', custom, o.hash, inc, false, false, null); 568 _fillField(e, 'user', 'id', custom, o.id, inc, false, false, null); 569 if (null !== custom && 'user' in custom) { 570 if (custom['user'] instanceof Array) { 571 for (i = 0; i < custom['user'].length; i++) 572 (custom['user'])[i](e, 'user', o); 573 } else { 574 (custom['user'])(e, 'user', o); 575 } 576 } 577 }; 578 579 /** 580 * Like {@link ort.user#_fill} but instead of accepting a single 581 * element to fill, filling into all elements matching the given 582 * class name beneath the given root. 583 * @param {HTMLElement} e - The DOM element. 584 * @param {String} name - The name of the class into which to 585 * fill. 586 * @param {Boolean} inc - Whether to include the roots or not 587 * when processing. 588 * @param {ort.DataCallbacks} custom - The optional custom 589 * handler dictionary (see {@link ort.user#fill} for details). 590 * @private 591 * @function _fillByClass 592 * @memberof ort.user# 593 */ 594 user.prototype._fillByClass = function(e, name, inc, custom) 595 { 596 var i; 597 var list; 598 list = _elemList(e, name, inc); 599 for (i = 0; i < list.length; i++) 600 this._fill(list[i], this.obj, inc, custom); 601 }; 602 603 /** 604 * Like {@link ort.user#fillArray}, but hiding an element if the 605 * array is empty or null. 606 * @param {HTMLElement|null} e - The DOM element. 607 * @param {HTMLElement|null} tohide - The DOM element to hide. 608 * @param {ort.userData|ort.userData[]|null} o - The array (or 609 * object) to fill. 610 * @param {ort.DataCallbacks} custom - The optional custom 611 * handler dictionary (see {@link ort.user#fill}). 612 * @function fillArrayOrHide 613 * @memberof ort.user# 614 */ 615 user.prototype.fillArrayOrHide = function(e, tohide, custom) 616 { 617 var len; 618 if (null === this.obj) 619 len = 0; 620 else if (this.obj instanceof Array) 621 len = this.obj.length; 622 else 623 len = 1; 624 if (null !== e) 625 _hide(e); 626 if (null !== tohide) 627 _show(tohide); 628 this.fillArray(e, custom); 629 if (null !== tohide && 0 === len) 630 _hide(tohide); 631 }; 632 /** 633 * Like {@link ort.user#fillArray}, but showing an element if the 634 * array is empty or null. 635 * @param {HTMLElement|null} e - The DOM element. 636 * @param {HTMLElement|null} toshow - The DOM element to show. 637 * @param {ort.userData|ort.userData[]|null} o - The array (or 638 * object) to fill. 639 * @param {ort.DataCallbacks} custom - The optional custom 640 * handler dictionary (see {@link ort.user#fill}). 641 * @function fillArrayOrShow 642 * @memberof ort.user# 643 */ 644 user.prototype.fillArrayOrShow = function(e, toshow, custom) 645 { 646 var len; 647 if (null === this.obj) 648 len = 0; 649 else if (this.obj instanceof Array) 650 len = this.obj.length; 651 else 652 len = 1; 653 if (null !== e) 654 _hide(e); 655 if (null !== toshow) 656 _hide(toshow); 657 this.fillArray(e, custom); 658 if (null !== toshow && 0 === len) 659 _show(toshow); 660 }; 661 /** 662 * Like {@link ort.user#fill} but for an array of {@link 663 * ort.userData}. 664 * If the data is not an array, it is remapped as an array of 665 * one. 666 * This will save the first element within "e", remove all 667 * children of "e", then repeatedly clone the saved element and 668 * re-append it, filling in the cloned subtree with the array 669 * (inclusive of the subtree root). 670 * If the input array is empty or null, "e" is hidden by using 671 * the <code>hide</code> class. 672 * Otherwise, the <code>hide</code> class is removed. 673 * @param {HTMLElement} e - The DOM element. 674 * @param {ort.DataCallbacks} custom - The optional custom 675 * handler dictionary (see {@link ort.user#fill}). 676 * @memberof ort.user# 677 * @function fillArray 678 */ 679 user.prototype.fillArray = function(e, custom) 680 { 681 var j; 682 var o; 683 var cln; 684 var ar; 685 var row; 686 o = this.obj; 687 if (null !== e) 688 _hide(e); 689 if (null === o || null === e) 690 return; 691 if ( ! (o instanceof Array)) { 692 ar = []; 693 ar.push(o); 694 o = ar; 695 } 696 if (0 === o.length) 697 return; 698 _show(e); 699 row = e.children[0]; 700 if (null === row) 701 return; 702 e.removeChild(row); 703 while (null !== e.firstChild) 704 e.removeChild(e.firstChild) 705 for (j = 0; j < o.length; j++) { 706 cln = row.cloneNode(true); 707 e.appendChild(cln); 708 this._fill(cln, o[j], true, custom); 709 } 710 }; 711 /** 712 * Like {@link ort.user#fillArray} but instead of accepting a 713 * single element to fill, filling all elements by class name 714 * beneath the given root (non-inclusive). 715 * @param {HTMLElement} e - The DOM element. 716 * @param {String} name - The name of the class into which to 717 * fill. 718 * @param {ort.DataCallbacks} custom - The optional custom 719 * handler dictionary (see {@link ort.user#fill} for details). 720 * @function fillArrayByClass 721 * @memberof ort.user# 722 */ 723 user.prototype.fillArrayByClass = function(e, name, custom) 724 { 725 var i; 726 var list; 727 list = _elemList(e, name, false); 728 for (i = 0; i < list.length; i++) 729 this.fillArray(list[i], custom); 730 }; 731 732 return user; 733 }()); 734 ort.user = user; 735 736 /** 737 * Accepts {@link ort.sessData} for writing into a DOM tree. 738 * @param {(ort.sessData|ort.sessData[])} obj - The object(s) to 739 * write. 740 * @memberof ort 741 * @constructor 742 * @class 743 */ 744 var sess = (function() 745 { 746 function sess(o) 747 { 748 this.obj = o; 749 } 750 /** 751 * Write the {@link ort.sessData} into the given HTMLElement in 752 * the DOM tree. 753 * If constructed with an array, the first element is used. 754 * Elements within (and including) "e" having the following 755 * classes are manipulated as follows: 756 * <ul> 757 * <li>sess-user-obj: invoke {@link ort.user#fillInner} with user 758 * data</li> 759 * <li>sess-userid-enum-select: sets the <code>select</code> 760 * attribute for <code><option></code> values matching 761 * <i>userid</i> under the element</li> 762 * <li>sess-userid-value-checked: sets the <code>checked</code> 763 * attribute under the element matching the input</li> 764 * <li>sess-userid-text: replace contents with <i>userid</i> 765 * data</li> 766 * <li>sess-userid-value: replace <code>value</code> attribute 767 * with <i>userid</i> data</li> 768 * <li>sess-token-enum-select: sets the <code>select</code> 769 * attribute for <code><option></code> values matching 770 * <i>token</i> under the element</li> 771 * <li>sess-token-value-checked: sets the <code>checked</code> 772 * attribute under the element matching the input</li> 773 * <li>sess-token-text: replace contents with <i>token</i> 774 * data</li> 775 * <li>sess-token-value: replace <code>value</code> attribute 776 * with <i>token</i> data</li> 777 * <li>sess-id-enum-select: sets the <code>select</code> 778 * attribute for <code><option></code> values matching 779 * <i>id</i> under the element</li> 780 * <li>sess-id-value-checked: sets the <code>checked</code> 781 * attribute under the element matching the input</li> 782 * <li>sess-id-text: replace contents with <i>id</i> data</li> 783 * <li>sess-id-value: replace <code>value</code> attribute with 784 * <i>id</i> data</li> 785 * </ul> 786 * @param {HTMLElement} e - The DOM element. 787 * @param {ort.DataCallbacks} custom - The optional dictionary of 788 * functions keyed by structure and field name (e.g., <i>foo</i> 789 * structure, <i>bar</i> field would be <code>foo-bar</code>). 790 * The value is a function for custom handling that accepts the 791 * "e" value, the name of the structure-field, and the value of 792 * the structure and field. 793 * You may also specify an array of functions instead of a 794 * singleton. 795 * These callbacks are invoked <b>after</b> the generic classes 796 * are filled. 797 * @function fill 798 * @memberof ort.sess# 799 */ 800 sess.prototype.fill = function(e, custom) 801 { 802 this._fill(e, this.obj, true, custom); 803 }; 804 805 /** 806 * Like {@link ort.sess#fill} but instead of accepting a single 807 * element to fill, filling into all elements (non-inclusive) 808 * matching the given class name beneath (non-inclusive) the 809 * given root. 810 * @param {HTMLElement} e - The DOM element. 811 * @param {String} name - The name of the class into which to 812 * fill. 813 * @param {ort.DataCallbacks} custom - The optional custom 814 * handler dictionary (see {@link ort.sess#fill} for details). 815 * @function fillByClass 816 * @memberof ort.sess# 817 */ 818 sess.prototype.fillByClass = function(e, name, custom) 819 { 820 this._fillByClass(e, name, true, custom); 821 }; 822 823 /** 824 * Like {@link ort.sess#fillByClass} but inclusive the root and 825 * targets by class. 826 * @param {HTMLElement} e - The DOM element. 827 * @param {String} name - The name of the class into which to 828 * fill. 829 * @param {ort.DataCallbacks} custom - The optional custom 830 * handler dictionary (see {@link ort.sess#fill} for details). 831 * @function fillInnerByClass 832 * @memberof ort.sess# 833 */ 834 sess.prototype.fillInnerByClass = function(e, name, custom) 835 { 836 this._fillByClass(e, name, false, custom); 837 }; 838 839 /** 840 * Like {@link ort.sess#fill} but not including the root element 841 * "e". 842 * @param {HTMLElement} e - The DOM element. 843 * @param {ort.DataCallbacks} custom - The optional custom 844 * handler dictionary (see {@link ort.sess#fill} for details). 845 * @function fillInner 846 * @memberof ort.sess# 847 */ 848 sess.prototype.fillInner = function(e, custom) 849 { 850 this._fill(e, this.obj, false, custom); 851 }; 852 853 /** 854 * Implements all {@link ort.sess#fill} functions. 855 * @param {HTMLElement} e - The DOM element. 856 * @param {ort.sessData|ort.sessData[]|null} o - The object (or 857 * array) to fill. 858 * @param {Boolean} inc - Whether to include the root or not when 859 * processing. 860 * @param {ort.DataCallbacks} custom - The optional custom 861 * handler dictionary (see {@link ort.sess#fill}). 862 * @private 863 * @function _fill 864 * @memberof ort.sess# 865 */ 866 sess.prototype._fill = function(e, o, inc, custom) 867 { 868 var i; 869 if (null === o || null === e) 870 return; 871 if (o instanceof Array) { 872 if (0 === o.length) 873 return; 874 o = o[0]; 875 } 876 if (typeof custom === 'undefined') 877 custom = null; 878 _fillField(e, 'sess', 'user', custom, o.user, inc, false, false, new user(o.user)); 879 _fillField(e, 'sess', 'userid', custom, o.userid, inc, false, false, null); 880 _fillField(e, 'sess', 'token', custom, o.token, inc, false, false, null); 881 _fillField(e, 'sess', 'id', custom, o.id, inc, false, false, null); 882 if (null !== custom && 'sess' in custom) { 883 if (custom['sess'] instanceof Array) { 884 for (i = 0; i < custom['sess'].length; i++) 885 (custom['sess'])[i](e, 'sess', o); 886 } else { 887 (custom['sess'])(e, 'sess', o); 888 } 889 } 890 }; 891 892 /** 893 * Like {@link ort.sess#_fill} but instead of accepting a single 894 * element to fill, filling into all elements matching the given 895 * class name beneath the given root. 896 * @param {HTMLElement} e - The DOM element. 897 * @param {String} name - The name of the class into which to 898 * fill. 899 * @param {Boolean} inc - Whether to include the roots or not 900 * when processing. 901 * @param {ort.DataCallbacks} custom - The optional custom 902 * handler dictionary (see {@link ort.sess#fill} for details). 903 * @private 904 * @function _fillByClass 905 * @memberof ort.sess# 906 */ 907 sess.prototype._fillByClass = function(e, name, inc, custom) 908 { 909 var i; 910 var list; 911 list = _elemList(e, name, inc); 912 for (i = 0; i < list.length; i++) 913 this._fill(list[i], this.obj, inc, custom); 914 }; 915 916 /** 917 * Like {@link ort.sess#fillArray}, but hiding an element if the 918 * array is empty or null. 919 * @param {HTMLElement|null} e - The DOM element. 920 * @param {HTMLElement|null} tohide - The DOM element to hide. 921 * @param {ort.sessData|ort.sessData[]|null} o - The array (or 922 * object) to fill. 923 * @param {ort.DataCallbacks} custom - The optional custom 924 * handler dictionary (see {@link ort.sess#fill}). 925 * @function fillArrayOrHide 926 * @memberof ort.sess# 927 */ 928 sess.prototype.fillArrayOrHide = function(e, tohide, custom) 929 { 930 var len; 931 if (null === this.obj) 932 len = 0; 933 else if (this.obj instanceof Array) 934 len = this.obj.length; 935 else 936 len = 1; 937 if (null !== e) 938 _hide(e); 939 if (null !== tohide) 940 _show(tohide); 941 this.fillArray(e, custom); 942 if (null !== tohide && 0 === len) 943 _hide(tohide); 944 }; 945 /** 946 * Like {@link ort.sess#fillArray}, but showing an element if the 947 * array is empty or null. 948 * @param {HTMLElement|null} e - The DOM element. 949 * @param {HTMLElement|null} toshow - The DOM element to show. 950 * @param {ort.sessData|ort.sessData[]|null} o - The array (or 951 * object) to fill. 952 * @param {ort.DataCallbacks} custom - The optional custom 953 * handler dictionary (see {@link ort.sess#fill}). 954 * @function fillArrayOrShow 955 * @memberof ort.sess# 956 */ 957 sess.prototype.fillArrayOrShow = function(e, toshow, custom) 958 { 959 var len; 960 if (null === this.obj) 961 len = 0; 962 else if (this.obj instanceof Array) 963 len = this.obj.length; 964 else 965 len = 1; 966 if (null !== e) 967 _hide(e); 968 if (null !== toshow) 969 _hide(toshow); 970 this.fillArray(e, custom); 971 if (null !== toshow && 0 === len) 972 _show(toshow); 973 }; 974 /** 975 * Like {@link ort.sess#fill} but for an array of {@link 976 * ort.sessData}. 977 * If the data is not an array, it is remapped as an array of 978 * one. 979 * This will save the first element within "e", remove all 980 * children of "e", then repeatedly clone the saved element and 981 * re-append it, filling in the cloned subtree with the array 982 * (inclusive of the subtree root). 983 * If the input array is empty or null, "e" is hidden by using 984 * the <code>hide</code> class. 985 * Otherwise, the <code>hide</code> class is removed. 986 * @param {HTMLElement} e - The DOM element. 987 * @param {ort.DataCallbacks} custom - The optional custom 988 * handler dictionary (see {@link ort.sess#fill}). 989 * @memberof ort.sess# 990 * @function fillArray 991 */ 992 sess.prototype.fillArray = function(e, custom) 993 { 994 var j; 995 var o; 996 var cln; 997 var ar; 998 var row; 999 o = this.obj; 1000 if (null !== e) 1001 _hide(e); 1002 if (null === o || null === e) 1003 return; 1004 if ( ! (o instanceof Array)) { 1005 ar = []; 1006 ar.push(o); 1007 o = ar; 1008 } 1009 if (0 === o.length) 1010 return; 1011 _show(e); 1012 row = e.children[0]; 1013 if (null === row) 1014 return; 1015 e.removeChild(row); 1016 while (null !== e.firstChild) 1017 e.removeChild(e.firstChild) 1018 for (j = 0; j < o.length; j++) { 1019 cln = row.cloneNode(true); 1020 e.appendChild(cln); 1021 this._fill(cln, o[j], true, custom); 1022 } 1023 }; 1024 /** 1025 * Like {@link ort.sess#fillArray} but instead of accepting a 1026 * single element to fill, filling all elements by class name 1027 * beneath the given root (non-inclusive). 1028 * @param {HTMLElement} e - The DOM element. 1029 * @param {String} name - The name of the class into which to 1030 * fill. 1031 * @param {ort.DataCallbacks} custom - The optional custom 1032 * handler dictionary (see {@link ort.sess#fill} for details). 1033 * @function fillArrayByClass 1034 * @memberof ort.sess# 1035 */ 1036 sess.prototype.fillArrayByClass = function(e, name, custom) 1037 { 1038 var i; 1039 var list; 1040 list = _elemList(e, name, false); 1041 for (i = 0; i < list.length; i++) 1042 this.fillArray(list[i], custom); 1043 }; 1044 1045 return sess; 1046 }()); 1047 ort.sess = sess; 1048 1049 ort.user = user; 1050 ort.sess = sess; 1051 })(ort || (ort = {}));