1/* 2 * Copyright 2005 Joe Walker 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** 18 * Declare an object to which we can add real functions. 19 */ 20if (dwr == null) var dwr = {}; 21if (dwr.util == null) dwr.util = {}; 22if (DWRUtil == null) var DWRUtil = dwr.util; 23 24/** @private The flag we use to decide if we should escape html */ 25dwr.util._escapeHtml = true; 26 27/** 28 * Set the global escapeHtml flag 29 */ 30dwr.util.setEscapeHtml = function(escapeHtml) { 31 dwr.util._escapeHtml = escapeHtml; 32}; 33 34/** @private Work out from an options list and global settings if we should be esccaping */ 35dwr.util._shouldEscapeHtml = function(options) { 36 if (options && options.escapeHtml != null) { 37 return options.escapeHtml; 38 } 39 return dwr.util._escapeHtml; 40}; 41 42/** 43 * Return a string with &, < and > replaced with their entities 44 * @see TODO 45 */ 46dwr.util.escapeHtml = function(original) { 47 return original.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); 48}; 49 50/** 51 * Replace common XML entities with characters (see dwr.util.escapeHtml()) 52 * @see TODO 53 */ 54dwr.util.unescapeHtml = function(original) { 55 return original.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); 56}; 57 58/** 59 * Replace characters dangerous for XSS reasons with visually similar characters 60 * @see TODO 61 */ 62dwr.util.replaceXmlCharacters = function(original) { 63 original = original.replace("&", "+"); 64 original = original.replace("<", "\u2039"); 65 original = original.replace(">", "\u203A"); 66 original = original.replace("\'", "\u2018"); 67 original = original.replace("\"", "\u201C"); 68 return original; 69}; 70 71/** 72 * Return true iff the input string contains any XSS dangerous characters 73 * @see TODO 74 */ 75dwr.util.containsXssRiskyCharacters = function(original) { 76 return (original.indexOf('&') != -1 77 || original.indexOf('<') != -1 78 || original.indexOf('>') != -1 79 || original.indexOf('\'') != -1 80 || original.indexOf('\"') != -1); 81}; 82 83/** 84 * Enables you to react to return being pressed in an input 85 * @see http://getahead.org/dwr/browser/util/selectrange 86 */ 87dwr.util.onReturn = function(event, action) { 88 if (!event) event = window.event; 89 if (event && event.keyCode && event.keyCode == 13) action(); 90}; 91 92/** 93 * Select a specific range in a text box. Useful for 'google suggest' type functions. 94 * @see http://getahead.org/dwr/browser/util/selectrange 95 */ 96dwr.util.selectRange = function(ele, start, end) { 97 ele = dwr.util._getElementById(ele, "selectRange()"); 98 if (ele == null) return; 99 if (ele.setSelectionRange) { 100 ele.setSelectionRange(start, end); 101 } 102 else if (ele.createTextRange) { 103 var range = ele.createTextRange(); 104 range.moveStart("character", start); 105 range.moveEnd("character", end - ele.value.length); 106 range.select(); 107 } 108 ele.focus(); 109}; 110 111/** 112 * Find the element in the current HTML document with the given id or ids 113 * @see http://getahead.org/dwr/browser/util/$ 114 */ 115if (document.getElementById) { 116 dwr.util.byId = function() { 117 var elements = new Array(); 118 for (var i = 0; i < arguments.length; i++) { 119 var element = arguments[i]; 120 if (typeof element == 'string') { 121 element = document.getElementById(element); 122 } 123 if (arguments.length == 1) { 124 return element; 125 } 126 elements.push(element); 127 } 128 return elements; 129 }; 130} 131else if (document.all) { 132 dwr.util.byId = function() { 133 var elements = new Array(); 134 for (var i = 0; i < arguments.length; i++) { 135 var element = arguments[i]; 136 if (typeof element == 'string') { 137 element = document.all[element]; 138 } 139 if (arguments.length == 1) { 140 return element; 141 } 142 elements.push(element); 143 } 144 return elements; 145 }; 146} 147 148/** 149 * Alias $ to dwr.util.byId 150 * @see http://getahead.org/dwr/browser/util/$ 151 */ 152if (window['$'] == null) { 153 window['$'] = dwr.util.byId; 154} 155 156/** 157 * This function pretty-prints simple data or whole object graphs, f ex as an aid in debugging. 158 * @see http://getahead.org/dwr/browser/util/todescriptivestring 159 */ 160dwr.util.toDescriptiveString = function(data, showLevels, options) { 161 if (showLevels === undefined) showLevels = 1; 162 var opt = {}; 163 if (dwr.util._isObject(options)) opt = options; 164 var defaultoptions = { 165 escapeHtml:false, 166 baseIndent: "", 167 childIndent: "\u00A0\u00A0", 168 lineTerminator: "\n", 169 oneLineMaxItems: 5, 170 shortStringMaxLength: 13, 171 propertyNameMaxLength: 30 172 }; 173 for (var p in defaultoptions) { 174 if (!(p in opt)) { 175 opt[p] = defaultoptions[p]; 176 } 177 } 178 179 var skipDomProperties = { 180 document:true, ownerDocument:true, 181 all:true, 182 parentElement:true, parentNode:true, offsetParent:true, 183 children:true, firstChild:true, lastChild:true, 184 previousSibling:true, nextSibling:true, 185 innerHTML:true, outerHTML:true, 186 innerText:true, outerText:true, textContent:true, 187 attributes:true, 188 style:true, currentStyle:true, runtimeStyle:true, 189 parentTextEdit:true 190 }; 191 192 function recursive(data, showLevels, indentDepth, options) { 193 var reply = ""; 194 try { 195 // string 196 if (typeof data == "string") { 197 var str = data; 198 if (showLevels == 0 && str.length > options.shortStringMaxLength) 199 str = str.substring(0, options.shortStringMaxLength-3) + "..."; 200 if (options.escapeHtml) { 201 // Do the escape separately for every line as escapeHtml() on some 202 // browsers (IE) will strip line breaks and we want to preserve them 203 var lines = str.split("\n"); 204 for (var i = 0; i < lines.length; i++) lines[i] = dwr.util.escapeHtml(lines[i]); 205 str = lines.join("\n"); 206 } 207 if (showLevels == 0) { // Short format 208 str = str.replace(/\n|\r|\t/g, function(ch) { 209 switch (ch) { 210 case "\n": return "\\n"; 211 case "\r": return ""; 212 case "\t": return "\\t"; 213 } 214 }); 215 } 216 else { // Long format 217 str = str.replace(/\n|\r|\t/g, function(ch) { 218 switch (ch) { 219 case "\n": return options.lineTerminator + indent(indentDepth+1, options); 220 case "\r": return ""; 221 case "\t": return "\\t"; 222 } 223 }); 224 } 225 reply = '"' + str + '"'; 226 } 227 228 // function 229 else if (typeof data == "function") { 230 reply = "function"; 231 } 232 233 // Array 234 else if (dwr.util._isArray(data)) { 235 if (showLevels == 0) { // Short format (don't show items) 236 if (data.length > 0) 237 reply = "[...]"; 238 else 239 reply = "[]"; 240 } 241 else { // Long format (show items) 242 var strarr = []; 243 strarr.push("["); 244 var count = 0; 245 for (var i = 0; i < data.length; i++) {
246 if (! (i in data)) continue; 247 var itemvalue = data[i]; 248 if (count > 0) strarr.push(", "); 249 if (showLevels == 1) { // One-line format 250 if (count == options.oneLineMaxItems) { 251 strarr.push("..."); 252 break; 253 } 254 } 255 else { // Multi-line format 256 strarr.push(options.lineTerminator + indent(indentDepth+1, options)); 257 } 258 if (i != count) { 259 strarr.push(i); 260 strarr.push(":"); 261 } 262 strarr.push(recursive(itemvalue, showLevels-1, indentDepth+1, options)); 263 count++; 264 } 265 if (showLevels > 1) strarr.push(options.lineTerminator + indent(indentDepth, options)); 266 strarr.push("]"); 267 reply = strarr.join(""); 268 } 269 } 270 271 // Objects except Date 272 else if (dwr.util._isObject(data) && !dwr.util._isDate(data)) { 273 if (showLevels == 0) { // Short format (don't show properties) 274 reply = dwr.util._detailedTypeOf(data); 275 } 276 else { // Long format (show properties) 277 var strarr = []; 278 if (dwr.util._detailedTypeOf(data) != "Object") { 279 strarr.push(dwr.util._detailedTypeOf(data)); 280 if (typeof data.valueOf() != "object") { 281 strarr.push(":"); 282 strarr.push(recursive(data.valueOf(), 1, indentDepth, options)); 283 } 284 strarr.push(" "); 285 } 286 strarr.push("{"); 287 var isDomObject = dwr.util._isHTMLElement(data); 288 var count = 0; 289 for (var prop in data) { 290 var propvalue = data[prop]; 291 if (isDomObject) { 292 if (!propvalue) continue; 293 if (typeof propvalue == "function") continue; 294 if (skipDomProperties[prop]) continue; 295 if (prop.toUpperCase() == prop) continue; 296 } 297 if (count > 0) strarr.push(", "); 298 if (showLevels == 1) { // One-line format 299 if (count == options.oneLineMaxItems) { 300 strarr.push("..."); 301 break; 302 } 303 } 304 else { // Multi-line format 305 strarr.push(options.lineTerminator + indent(indentDepth+1, options)); 306 } 307 strarr.push(prop.length > options.propertyNameMaxLength ? prop.substring(0, options.propertyNameMaxLength-3) + "..." : prop); 308 strarr.push(":"); 309 strarr.push(recursive(propvalue, showLevels-1, indentDepth+1, options)); 310 count++; 311 } 312 if (showLevels > 1 && count > 0) strarr.push(options.lineTerminator + indent(indentDepth, options)); 313 strarr.push("}"); 314 reply = strarr.join(""); 315 } 316 } 317 318 // undefined, null, number, boolean, Date 319 else { 320 reply = "" + data; 321 } 322 323 return reply; 324 } 325 catch(err) { 326 return (err.message ? err.message : ""+err); 327 } 328 } 329 330 function indent(count, options) { 331 var strarr = []; 332 strarr.push(options.baseIndent); 333 for (var i=0; i<count; i++) { 334 strarr.push(options.childIndent); 335 } 336 return strarr.join(""); 337 }; 338 339 return recursive(data, showLevels, 0, opt); 340}; 341 342/** 343 * Setup a GMail style loading message. 344 * @see http://getahead.org/dwr/browser/util/useloadingmessage 345 */ 346dwr.util.useLoadingMessage = function(message) { 347 var loadingMessage; 348 if (message) loadingMessage = message; 349 else loadingMessage = "Loading"; 350 dwr.engine.setPreHook(function() { 351 var disabledZone = dwr.util.byId('disabledZone'); 352 if (!disabledZone) { 353 disabledZone = document.createElement('div'); 354 disabledZone.setAttribute('id', 'disabledZone'); 355 disabledZone.style.position = "absolute"; 356 disabledZone.style.zIndex = "1000"; 357 disabledZone.style.left = "0px"; 358 disabledZone.style.top = "0px"; 359 disabledZone.style.width = "100%"; 360 disabledZone.style.height = "100%"; 361 document.body.appendChild(disabledZone); 362 var messageZone = document.createElement('div'); 363 messageZone.setAttribute('id', 'messageZone'); 364 messageZone.style.position = "absolute"; 365 messageZone.style.top = "0px"; 366 messageZone.style.right = "0px"; 367 messageZone.style.background = "red"; 368 messageZone.style.color = "white"; 369 messageZone.style.fontFamily = "Arial,Helvetica,sans-serif"; 370 messageZone.style.padding = "4px"; 371 disabledZone.appendChild(messageZone); 372 var text = document.createTextNode(loadingMessage); 373 messageZone.appendChild(text); 374 dwr.util._disabledZoneUseCount = 1; 375 } 376 else { 377 dwr.util.byId('messageZone').innerHTML = loadingMessage; 378 disabledZone.style.visibility = 'visible'; 379 dwr.util._disabledZoneUseCount++; 380 } 381 }); 382 dwr.engine.setPostHook(function() { 383 dwr.util._disabledZoneUseCount--; 384 if (dwr.util._disabledZoneUseCount == 0) { 385 dwr.util.byId('disabledZone').style.visibility = 'hidden'; 386 } 387 }); 388}; 389 390/** 391 * Set a global highlight handler 392 */ 393dwr.util.setHighlightHandler = function(handler) { 394 dwr.util._highlightHandler = handler; 395}; 396 397/** 398 * An example highlight handler 399 */ 400dwr.util.yellowFadeHighlightHandler = function(ele) { 401 dwr.util._yellowFadeProcess(ele, 0); 402}; 403dwr.util._yellowFadeSteps = [ "d0", "b0", "a0", "90", "98", "a0", "a8", "b0", "b8", "c0", "c8", "d0", "d8", "e0", "e8", "f0", "f8" ]; 404dwr.util._yellowFadeProcess = function(ele, colorIndex) { 405 ele = dwr.util.byId(ele); 406 if (colorIndex < dwr.util._yellowFadeSteps.length) { 407 ele.style.backgroundColor = "#ffff" + dwr.util._yellowFadeSteps[colorIndex]; 408 setTimeout("dwr.util._yellowFadeProcess('" + ele.id + "'," + (colorIndex + 1) + ")", 200); 409 } 410 else { 411 ele.style.backgroundColor = "transparent";
412 } 413}; 414 415/** 416 * An example highlight handler 417 */ 418dwr.util.borderFadeHighlightHandler = function(ele) { 419 ele.style.borderWidth = "2px"; 420 ele.style.borderStyle = "solid"; 421 dwr.util._borderFadeProcess(ele, 0); 422}; 423dwr.util._borderFadeSteps = [ "d0", "b0", "a0", "90", "98", "a0", "a8", "b0", "b8", "c0", "c8", "d0", "d8", "e0", "e8", "f0", "f8" ]; 424dwr.util._borderFadeProcess = function(ele, colorIndex) { 425 ele = dwr.util.byId(ele); 426 if (colorIndex < dwr.util._borderFadeSteps.length) { 427 ele.style.borderColor = "#ff" + dwr.util._borderFadeSteps[colorIndex] + dwr.util._borderFadeSteps[colorIndex]; 428 setTimeout("dwr.util._borderFadeProcess('" + ele.id + "'," + (colorIndex + 1) + ")", 200); 429 } 430 else { 431 ele.style.backgroundColor = "transparent"; 432 } 433}; 434 435/** 436 * A focus highlight handler 437 */ 438dwr.util.focusHighlightHandler = function(ele) { 439 try { 440 ele.focus(); 441 } 442 catch (ex) { /* ignore */ } 443}; 444 445/** @private the current global highlight style */ 446dwr.util._highlightHandler = null; 447 448/** 449 * Highlight that an element has changed 450 */ 451dwr.util.highlight = function(ele, options) { 452 if (options && options.highlightHandler) { 453 options.highlightHandler(dwr.util.byId(ele)); 454 } 455 else if (dwr.util._highlightHandler != null) { 456 dwr.util._highlightHandler(dwr.util.byId(ele)); 457 } 458}; 459 460/** 461 * Set the value an HTML element to the specified value. 462 * @see http://getahead.org/dwr/browser/util/setvalue 463 */ 464dwr.util.setValue = function(ele, val, options) { 465 if (val == null) val = ""; 466 if (options == null) options = {}; 467 468 var orig = ele; 469 if (typeof ele == "string") { 470 ele = dwr.util.byId(ele); 471 // We can work with names and need to sometimes for radio buttons, and IE has 472 // an annoying bug where getElementById() returns an element based on name if 473 // it doesn't find it by id. Here we don't want to do that, so: 474 if (ele && ele.id != orig) ele = null; 475 } 476 var nodes = null; 477 if (ele == null) { 478 // Now it is time to look by name 479 nodes = document.getElementsByName(orig); 480 if (nodes.length >= 1) ele = nodes.item(0); 481 } 482 483 if (ele == null) { 484 dwr.util._debug("setValue() can't find an element with id/name: " + orig + "."); 485 return; 486 } 487 488 // All paths now lead to some update so we highlight a change 489 dwr.util.highlight(ele, options); 490 491 if (dwr.util._isHTMLElement(ele, "select")) { 492 if (ele.type == "select-multiple" && dwr.util._isArray(val)) dwr.util._selectListItems(ele, val); 493 else dwr.util._selectListItem(ele, val); 494 return; 495 } 496 497 if (dwr.util._isHTMLElement(ele, "input")) { 498 if (ele.type == "radio" || ele.type == "checkbox") { 499 if (nodes && nodes.length >= 1) { 500 for (var i = 0; i < nodes.length; i++) { 501 var node = nodes.item(i); 502 if (node.type != ele.type) continue; 503 if (dwr.util._isArray(val)) { 504 node.checked = false; 505 for (var j = 0; j < val.length; j++) 506 if (val[j] == node.value) node.checked = true; 507 } 508 else { 509 node.checked = (node.value == val); 510 } 511 } 512 } 513 else { 514 ele.checked = (val == true); 515 } 516 } 517 else ele.value = val; 518 519 return; 520 } 521 522 if (dwr.util._isHTMLElement(ele, "textarea")) { 523 ele.value = val; 524 return; 525 } 526 527 // If the value to be set is a DOM object then we try importing the node 528 // rather than serializing it out 529 if (val.nodeType) { 530 if (val.nodeType == 9 /*Node.DOCUMENT_NODE*/) val = val.documentElement; 531 val = dwr.util._importNode(ele.ownerDocument, val, true); 532 ele.appendChild(val); 533 return; 534 } 535 536 // Fall back to innerHTML and friends 537 if (dwr.util._shouldEscapeHtml(options)) { 538 if ("textContent" in ele) ele.textContent = val.toString(); 539 else if ("innerText" in ele) ele.innerText = val.toString(); 540 else ele.innerHTML = dwr.util.escapeHtml(val.toString()); 541 } 542 else { 543 ele.innerHTML = val; 544 } 545}; 546 547/** 548 * @private Find multiple items in a select list and select them. Used by setValue() 549 * @param ele The select list item 550 * @param val The array of values to select 551 */ 552dwr.util._selectListItems = function(ele, val) { 553 // We deal with select list elements by selecting the matching option 554 // Begin by searching through the values 555 var found = false;
556 var i; 557 var j; 558 for (i = 0; i < ele.options.length; i++) { 559 ele.options[i].selected = false; 560 for (j = 0; j < val.length; j++) { 561 if (ele.options[i].value == val[j]) { 562 ele.options[i].selected = true; 563 } 564 } 565 } 566 // If that fails then try searching through the visible text 567 if (found) return; 568 569 for (i = 0; i < ele.options.length; i++) { 570 for (j = 0; j < val.length; j++) { 571 if (ele.options[i].text == val[j]) { 572 ele.options[i].selected = true; 573 } 574 } 575 } 576}; 577 578/** 579 * @private Find an item in a select list and select it. Used by setValue() 580 * @param ele The select list item 581 * @param val The value to select 582 */ 583dwr.util._selectListItem = function(ele, val) { 584 // We deal with select list elements by selecting the matching option 585 // Begin by searching through the values 586 var found = false; 587 var i; 588 for (i = 0; i < ele.options.length; i++) { 589 if (ele.options[i].value == val) { 590 ele.options[i].selected = true; 591 found = true; 592 } 593 else { 594 ele.options[i].selected = false; 595 } 596 } 597 598 // If that fails then try searching through the visible text 599 if (found) return; 600 601 for (i = 0; i < ele.options.length; i++) { 602 ele.options[i].selected = (ele.options[i].text == val); 603 } 604}; 605 606/** 607 * Read the current value for a given HTML element. 608 * @see http://getahead.org/dwr/browser/util/getvalue 609 */ 610dwr.util.getValue = function(ele, options) { 611 if (options == null) options = {}; 612 var orig = ele; 613 if (typeof ele == "string") { 614 ele = dwr.util.byId(ele); 615 // We can work with names and need to sometimes for radio buttons, and IE has 616 // an annoying bug where getElementById() returns an element based on name if 617 // it doesn't find it by id. Here we don't want to do that, so: 618 if (ele && ele.id != orig) ele = null; 619 } 620 var nodes = null; 621 if (ele == null) { 622 // Now it is time to look by name 623 nodes = document.getElementsByName(orig); 624 if (nodes.length >= 1) ele = nodes.item(0); 625 } 626 if (ele == null) { 627 dwr.util._debug("getValue() can't find an element with id/name: " + orig + "."); 628 return ""; 629 } 630 631 if (dwr.util._isHTMLElement(ele, "select")) { 632 // Using "type" property instead of "multiple" as "type" is an official 633 // client-side property since JS 1.1 634 if (ele.type == "select-multiple") { 635 var reply = new Array(); 636 for (var i = 0; i < ele.options.length; i++) { 637 var item = ele.options[i]; 638 if (item.selected) { 639 var valueAttr = item.getAttributeNode("value"); 640 if (valueAttr && valueAttr.specified) { 641 reply.push(item.value); 642 } 643 else { 644 reply.push(item.text); 645 } 646 } 647 } 648 return reply; 649 } 650 else { 651 var sel = ele.selectedIndex; 652 if (sel != -1) { 653 var item = ele.options[sel]; 654 var valueAttr = item.getAttributeNode("value"); 655 if (valueAttr && valueAttr.specified) { 656 return item.value; 657 } 658 return item.text; 659 } 660 else { 661 return ""; 662 } 663 } 664 } 665 666 if (dwr.util._isHTMLElement(ele, "input")) { 667 if (ele.type == "radio") { 668 if (nodes && nodes.length >= 1) { 669 for (var i = 0; i < nodes.length; i++) { 670 var node = nodes.item(i); 671 if (node.type == ele.type) { 672 if (node.checked) return node.value; 673 } 674 } 675 } 676 return ele.checked; 677 } 678 if (ele.type == "checkbox") { 679 if (nodes && nodes.length >= 1) { 680 var reply = []; 681 for (var i = 0; i < nodes.length; i++) { 682 var node = nodes.item(i); 683 if (node.type == ele.type) { 684 if (node.checked) reply.push(node.value); 685 } 686 } 687 return reply; 688 } 689 return ele.checked; 690 } 691 return ele.value; 692 } 693 694 if (dwr.util._isHTMLElement(ele, "textarea")) { 695 return ele.value; 696 } 697 698 if (dwr.util._shouldEscapeHtml(options)) { 699 if (ele.textContent) return ele.textContent; 700 else if (ele.innerText) return ele.innerText; 701 } 702 return ele.innerHTML; 703}; 704 705/** 706 * getText() is like getValue() except that it reads the text (and not the value) from select elements 707 * @see http://getahead.org/dwr/browser/util/gettext 708 */ 709dwr.util.getText = function(ele) { 710 ele = dwr.util._getElementById(ele, "getText()"); 711 if (ele == null) return null; 712 if (!dwr.util._isHTMLElement(ele, "select")) { 713 dwr.util._debug("getText() can only be used with select elements. Attempt to use: " + dwr.util._detailedTypeOf(ele) + " from id: " + orig + "."); 714 return ""; 715 } 716 717 // This is a bit of a scam because it assumes single select 718 // but I'm not sure how we should treat multi-select. 719 var sel = ele.selectedIndex; 720 if (sel != -1) { 721 return ele.options[sel].text; 722 } 723 else { 724 return ""; 725 } 726}; 727 728/** 729 * Given a map, or a recursive structure consisting of arrays and maps, call 730 * setValue() for all leaf entries and use intermediate levels to form nested 731 * element ids. 732 * @see http://getahead.org/dwr/browser/util/setvalues 733 */ 734dwr.util.setValues = function(data, options) { 735 var prefix = ""; 736 var depth = 100; 737 if (options && options.prefix) prefix = options.prefix; 738 if (options && options.idPrefix) prefix = options.idPrefix; 739 if (options && "depth" in options) depth = options.depth; 740 dwr.util._setValuesRecursive(data, prefix, depth, options); 741}; 742 743/** 744 * @private Recursive helper for setValues() 745 */ 746dwr.util._setValuesRecursive = function(data, idpath, depth, options) { 747 if (depth == 0) return; 748 // Array containing objects -> add "[n]" to prefix and make recursive call 749 // for each item object 750 if (dwr.util._isArray(data) && data.length > 0 && dwr.util._isObject(data[0])) { 751 for (var i = 0; i < data.length; i++) { 752 dwr.util._setValuesRecursive(data[i], idpath+"["+i+"]", depth-1, options); 753 } 754 } 755 // Object (not array) -> handle nested object properties 756 else if (dwr.util._isObject(data) && !dwr.util._isArray(data)) { 757 for (var prop in data) { 758 var subidpath = idpath ? idpath+"."+prop : prop; 759 // Object (not array), or array containing objects -> call ourselves recursively 760 if (dwr.util._isObject(data[prop]) && !dwr.util._isArray(data[prop]) && !dwr.util._isDate(data[prop]) 761 || dwr.util._isArray(data[prop]) && data[prop].length > 0 && dwr.util._isObject(data[prop][0])) { 762 dwr.util._setValuesRecursive(data[prop], subidpath, depth-1, options); 763 } 764 // Functions -> skip 765 else if (typeof data[prop] == "function") { 766 // NOP 767 } 768 // Only simple values left (or array of simple values, or empty array) 769 // -> call setValue() 770 else { 771 // Are there any elements with that id or name 772 if (dwr.util.byId(subidpath) != null || document.getElementsByName(subidpath).length >= 1) { 773 dwr.util.setValue(subidpath, data[prop], options); 774 } 775 } 776 } 777 } 778}; 779 780/** 781 * Given a map, or a recursive structure consisting of arrays and maps, call 782 * getValue() for all leaf entries and use intermediate levels to form nested 783 * element ids. 784 * Given a string or element that refers to a form, create an object from the 785 * elements of the form. 786 * @see http://getahead.org/dwr/browser/util/getvalues 787 */ 788dwr.util.getValues = function(data, options) { 789 if (typeof data == "string" || dwr.util._isHTMLElement(data)) { 790 return dwr.util.getFormValues(data); 791 } 792 else { 793 var prefix = ""; 794 var depth = 100; 795 if (options != null && options.prefix) prefix = options.prefix; 796 if (options != null && options.idPrefix) prefix = options.idPrefix; 797 if (options != null && "depth" in options) depth = options.depth; 798 dwr.util._getValuesRecursive(data, prefix, depth, options); 799 return data; 800 } 801}; 802 803/** 804 * Given a string or element that refers to a form, create an object from the 805 * elements of the form. 806 * @see http://getahead.org/dwr/browser/util/getvalues 807 */ 808dwr.util.getFormValues = function(eleOrNameOrId) { 809 var ele = null; 810 if (typeof eleOrNameOrId == "string") { 811 ele = document.forms[eleOrNameOrId]; 812 if (ele == null) ele = dwr.util.byId(eleOrNameOrId); 813 } 814 else if (dwr.util._isHTMLElement(eleOrNameOrId)) { 815 ele = eleOrNameOrId; 816 } 817 if (ele != null) { 818 if (ele.elements == null) { 819 alert("getFormValues() requires an object or reference to a form element."); 820 return null; 821 } 822 var reply = {}; 823 var name; 824 var value; 825 for (var i = 0; i < ele.elements.length; i++) { 826 if (ele[i].type in {button:0,submit:0,reset:0,image:0,file:0}) continue; 827 if (ele[i].name) { 828 name = ele[i].name; 829 value = dwr.util.getValue(name); 830 } 831 else { 832 if (ele[i].id) name = ele[i].id; 833 else name = "element" + i; 834 value = dwr.util.getValue(ele[i]); 835 } 836 reply[name] = value; 837 } 838 return reply; 839 } 840}; 841 842/** 843 * @private Recursive helper for getValues(). 844 */ 845dwr.util._getValuesRecursive = function(data, idpath, depth, options) { 846 if (depth == 0) return; 847 // Array containing objects -> add "[n]" to idpath and make recursive call 848 // for each item object 849 if (dwr.util._isArray(data) && data.length > 0 && dwr.util._isObject(data[0])) { 850 for (var i = 0; i < data.length; i++) { 851 dwr.util._getValuesRecursive(data[i], idpath+"["+i+"]", depth-1, options); 852 } 853 } 854 // Object (not array) -> handle nested object properties 855 else if (dwr.util._isObject(data) && !dwr.util._isArray(data)) { 856 for (var prop in data) { 857 var subidpath = idpath ? idpath+"."+prop : prop; 858 // Object, or array containing objects -> call ourselves recursively 859 if (dwr.util._isObject(data[prop]) && !dwr.util._isArray(data[prop]) 860 || dwr.util._isArray(data[prop]) && data[prop].length > 0 && dwr.util._isObject(data[prop][0])) { 861 dwr.util._getValuesRecursive(data[prop], subidpath, depth-1, options); 862 } 863 // Functions -> skip 864 else if (typeof data[prop] == "function") { 865 // NOP 866 } 867 // Only simple values left (or array of simple values, or empty array) 868 // -> call getValue() 869 else { 870 // Are there any elements with that id or name 871 if (dwr.util.byId(subidpath) != null || document.getElementsByName(subidpath).length >= 1) { 872 data[prop] = dwr.util.getValue(subidpath); 873 } 874 } 875 } 876 } 877}; 878 879/** 880 * Add options to a list from an array or map.
881 * @see http://getahead.org/dwr/browser/lists 882 */ 883dwr.util.addOptions = function(ele, data/*, options*/) { 884 ele = dwr.util._getElementById(ele, "addOptions()"); 885 if (ele == null) return; 886 var useOptions = dwr.util._isHTMLElement(ele, "select"); 887 var useLi = dwr.util._isHTMLElement(ele, ["ul", "ol"]); 888 if (!useOptions && !useLi) { 889 dwr.util._debug("addOptions() can only be used with select/ul/ol elements. Attempt to use: " + dwr.util._detailedTypeOf(ele)); 890 return; 891 } 892 if (data == null) return; 893 894 var argcount = arguments.length; 895 var options = {}; 896 var lastarg = arguments[argcount - 1]; 897 if (argcount > 2 && dwr.util._isObject(lastarg)) { 898 options = lastarg; 899 argcount--; 900 } 901 var arg3 = null; if (argcount >= 3) arg3 = arguments[2]; 902 var arg4 = null; if (argcount >= 4) arg4 = arguments[3]; 903 if (!options.optionCreator && useOptions) options.optionCreator = dwr.util._defaultOptionCreator; 904 if (!options.optionCreator && useLi) options.optionCreator = dwr.util._defaultListItemCreator; 905 options.document = ele.ownerDocument; 906 907 var text, value, li; 908 if (dwr.util._isArray(data)) { 909 // Loop through the data that we do have 910 for (var i = 0; i < data.length; i++) { 911 options.data = data[i]; 912 options.text = null; 913 options.value = null; 914 if (useOptions) { 915 if (arg3 != null) { 916 if (arg4 != null) { 917 options.text = dwr.util._getValueFrom(data[i], arg4); 918 options.value = dwr.util._getValueFrom(data[i], arg3); 919 } 920 else options.text = options.value = dwr.util._getValueFrom(data[i], arg3); 921 } 922 else options.text = options.value = dwr.util._getValueFrom(data[i]); 923 924 if (options.text != null || options.value) { 925 var opt = options.optionCreator(options); 926 opt.text = options.text; 927 opt.value = options.value; 928 ele.options[ele.options.length] = opt; 929 } 930 } 931 else { 932 options.value = dwr.util._getValueFrom(data[i], arg3); 933 if (options.value != null) { 934 li = options.optionCreator(options); 935 if (dwr.util._shouldEscapeHtml(options)) { 936 options.value = dwr.util.escapeHtml(options.value); 937 } 938 li.innerHTML = options.value; 939 ele.appendChild(li); 940 } 941 } 942 } 943 } 944 else if (arg4 != null) { 945 if (!useOptions) { 946 alert("dwr.util.addOptions can only create select lists from objects."); 947 return; 948 } 949 for (var prop in data) { 950 options.data = data[prop]; 951 options.value = dwr.util._getValueFrom(data[prop], arg3); 952 options.text = dwr.util._getValueFrom(data[prop], arg4); 953 954 if (options.text != null || options.value) { 955 var opt = options.optionCreator(options); 956 opt.text = options.text; 957 opt.value = options.value; 958 ele.options[ele.options.length] = opt; 959 } 960 } 961 } 962 else { 963 if (!useOptions) { 964 dwr.util._debug("dwr.util.addOptions can only create select lists from objects."); 965 return; 966 } 967 for (var prop in data) { 968 if (typeof data[prop] == "function") continue; 969 options.data = data[prop]; 970 if (!arg3) { 971 options.value = prop; 972 options.text = data[prop]; 973 } 974 else { 975 options.value = data[prop]; 976 options.text = prop; 977 } 978 if (options.text != null || options.value) { 979 var opt = options.optionCreator(options); 980 opt.text = options.text; 981 opt.value = options.value; 982 ele.options[ele.options.length] = opt; 983 } 984 } 985 } 986 987 // All error routes through this function result in a return, so highlight now 988 dwr.util.highlight(ele, options); 989}; 990 991/** 992 * @private Get the data from an array function for dwr.util.addOptions 993 */ 994dwr.util._getValueFrom = function(data, method) { 995 if (method == null) return data; 996 else if (typeof method == 'function') return method(data); 997 else return data[method]; 998}; 999 1000/** 1001 * @private Default option creation function 1002 */ 1003dwr.util._defaultOptionCreator = function(options) { 1004 return options.document.createElement("option"); 1005}; 1006 1007/** 1008 * @private Default list item creation function 1009 */ 1010dwr.util._defaultListItemCreator = function(options) { 1011 return options.document.createElement("li"); 1012}; 1013 1014/** 1015 * Remove all the options from a select list (specified by id) 1016 * @see http://getahead.org/dwr/browser/lists 1017 */ 1018dwr.util.removeAllOptions = function(ele) { 1019 ele = dwr.util._getElementById(ele, "removeAllOptions()"); 1020 if (ele == null) return; 1021 var useOptions = dwr.util._isHTMLElement(ele, "select"); 1022 var useLi = dwr.util._isHTMLElement(ele, ["ul", "ol"]); 1023 if (!useOptions && !useLi) { 1024 dwr.util._debug("removeAllOptions() can only be used with select, ol and ul elements. Attempt to use: " + dwr.util._detailedTypeOf(ele)); 1025 return; 1026 } 1027 if (useOptions) { 1028 ele.options.length = 0; 1029 } 1030 else { 1031 while (ele.childNodes.length > 0) { 1032 ele.removeChild(ele.firstChild); 1033 } 1034 } 1035}; 1036 1037/** 1038 * Create rows inside a the table, tbody, thead or tfoot element (given by id).
1039 * @see http://getahead.org/dwr/browser/tables 1040 */ 1041dwr.util.addRows = function(ele, data, cellFuncs, options) { 1042 ele = dwr.util._getElementById(ele, "addRows()"); 1043 if (ele == null) return; 1044 if (!dwr.util._isHTMLElement(ele, ["table", "tbody", "thead", "tfoot"])) { 1045 dwr.util._debug("addRows() can only be used with table, tbody, thead and tfoot elements. Attempt to use: " + dwr.util._detailedTypeOf(ele)); 1046 return; 1047 } 1048 if (!options) options = {}; 1049 if (!options.rowCreator) options.rowCreator = dwr.util._defaultRowCreator; 1050 if (!options.cellCreator) options.cellCreator = dwr.util._defaultCellCreator; 1051 options.document = ele.ownerDocument; 1052 var tr, rowNum; 1053 if (dwr.util._isArray(data)) { 1054 for (rowNum = 0; rowNum < data.length; rowNum++) { 1055 options.rowData = data[rowNum]; 1056 options.rowIndex = rowNum; 1057 options.rowNum = rowNum; 1058 options.data = null; 1059 options.cellNum = -1; 1060 tr = dwr.util._addRowInner(cellFuncs, options); 1061 if (tr != null) ele.appendChild(tr); 1062 } 1063 } 1064 else if (typeof data == "object") { 1065 rowNum = 0; 1066 for (var rowIndex in data) { 1067 options.rowData = data[rowIndex]; 1068 options.rowIndex = rowIndex; 1069 options.rowNum = rowNum; 1070 options.data = null; 1071 options.cellNum = -1; 1072 tr = dwr.util._addRowInner(cellFuncs, options); 1073 if (tr != null) ele.appendChild(tr); 1074 rowNum++; 1075 } 1076 } 1077 1078 dwr.util.highlight(ele, options); 1079}; 1080 1081/** 1082 * @private Internal function to draw a single row of a table. 1083 */ 1084dwr.util._addRowInner = function(cellFuncs, options) { 1085 var tr = options.rowCreator(options); 1086 if (tr == null) return null; 1087 for (var cellNum = 0; cellNum < cellFuncs.length; cellNum++) { 1088 var func = cellFuncs[cellNum]; 1089 if (typeof func == 'function') options.data = func(options.rowData, options); 1090 else options.data = func || ""; 1091 options.cellNum = cellNum; 1092 var td = options.cellCreator(options); 1093 if (td != null) { 1094 if (options.data != null) { 1095 if (dwr.util._isHTMLElement(options.data)) td.appendChild(options.data); 1096 else { 1097 if (dwr.util._shouldEscapeHtml(options) && typeof(options.data) == "string") { 1098 td.innerHTML = dwr.util.escapeHtml(options.data); 1099 } 1100 else { 1101 td.innerHTML = options.data; 1102 } 1103 } 1104 } 1105 tr.appendChild(td); 1106 } 1107 } 1108 return tr; 1109}; 1110 1111/** 1112 * @private Default row creation function 1113 */ 1114dwr.util._defaultRowCreator = function(options) { 1115 return options.document.createElement("tr"); 1116}; 1117 1118/** 1119 * @private Default cell creation function 1120 */ 1121dwr.util._defaultCellCreator = function(options) { 1122 return options.document.createElement("td"); 1123}; 1124 1125/** 1126 * Remove all the children of a given node. 1127 * @see http://getahead.org/dwr/browser/tables 1128 */ 1129dwr.util.removeAllRows = function(ele, options) { 1130 ele = dwr.util._getElementById(ele, "removeAllRows()"); 1131 if (ele == null) return; 1132 if (!options) options = {}; 1133 if (!options.filter) options.filter = function() { return true; }; 1134 if (!dwr.util._isHTMLElement(ele, ["table", "tbody", "thead", "tfoot"])) { 1135 dwr.util._debug("removeAllRows() can only be used with table, tbody, thead and tfoot elements. Attempt to use: " + dwr.util._detailedTypeOf(ele)); 1136 return; 1137 } 1138 var child = ele.firstChild; 1139 var next; 1140 while (child != null) { 1141 next = child.nextSibling; 1142 if (options.filter(child)) { 1143 ele.removeChild(child); 1144 } 1145 child = next; 1146 } 1147}; 1148 1149/** 1150 * dwr.util.byId(ele).className = "X", that we can call from Java easily. 1151 */ 1152dwr.util.setClassName = function(ele, className) { 1153 ele = dwr.util._getElementById(ele, "setClassName()"); 1154 if (ele == null) return; 1155 ele.className = className; 1156}; 1157 1158/** 1159 * dwr.util.byId(ele).className += "X", that we can call from Java easily. 1160 */ 1161dwr.util.addClassName = function(ele, className) { 1162 ele = dwr.util._getElementById(ele, "addClassName()"); 1163 if (ele == null) return; 1164 ele.className += " " + className; 1165}; 1166 1167/** 1168 * dwr.util.byId(ele).className -= "X", that we can call from Java easily 1169 * From code originally by Gavin Kistner 1170 */ 1171dwr.util.removeClassName = function(ele, className) { 1172 ele = dwr.util._getElementById(ele, "removeClassName()"); 1173 if (ele == null) return; 1174 var regex = new RegExp("(^|\\s)" + className + "(\\s|$)", 'g'); 1175 ele.className = ele.className.replace(regex, ''); 1176}; 1177 1178/** 1179 * dwr.util.byId(ele).className |= "X", that we can call from Java easily. 1180 */ 1181dwr.util.toggleClassName = function(ele, className) { 1182 ele = dwr.util._getElementById(ele, "toggleClassName()"); 1183 if (ele == null) return; 1184 var regex = new RegExp("(^|\\s)" + className + "(\\s|$)"); 1185 if (regex.test(ele.className)) { 1186 ele.className = ele.className.replace(regex, ''); 1187 } 1188 else { 1189 ele.className += " " + className; 1190 } 1191}; 1192 1193/** 1194 * Clone a node and insert it into the document just above the 'template' node 1195 * @see http://getahead.org/dwr/??? 1196 */ 1197dwr.util.cloneNode = function(ele, options) { 1198 ele = dwr.util._getElementById(ele, "cloneNode()"); 1199 if (ele == null) return null; 1200 if (options == null) options = {}; 1201 var clone = ele.cloneNode(true); 1202 if (options.idPrefix || options.idSuffix) { 1203 dwr.util._updateIds(clone, options); 1204 } 1205 else { 1206 dwr.util._removeIds(clone); 1207 } 1208 ele.parentNode.insertBefore(clone, ele); 1209 return clone; 1210}; 1211 1212/** 1213 * @private Update all of the ids in an element tree 1214 */ 1215dwr.util._updateIds = function(ele, options) { 1216 if (options == null) options = {}; 1217 if (ele.id) { 1218 ele.setAttribute("id", (options.idPrefix || "") + ele.id + (options.idSuffix || "")); 1219 } 1220 var children = ele.childNodes; 1221 for (var i = 0; i < children.length; i++) { 1222 var child = children.item(i); 1223 if (child.nodeType == 1 /*Node.ELEMENT_NODE*/) { 1224 dwr.util._updateIds(child, options); 1225 } 1226 } 1227}; 1228 1229/** 1230 * @private Remove all the Ids from an element 1231 */ 1232dwr.util._removeIds = function(ele) { 1233 if (ele.id) ele.removeAttribute("id"); 1234 var children = ele.childNodes; 1235 for (var i = 0; i < children.length; i++) { 1236 var child = children.item(i); 1237 if (child.nodeType == 1 /*Node.ELEMENT_NODE*/) { 1238 dwr.util._removeIds(child); 1239 } 1240 } 1241}; 1242 1243/** 1244 * Clone a template node and its embedded template child nodes according to 1245 * cardinalities (of arrays) in supplied data. 1246 */ 1247dwr.util.cloneNodeForValues = function(templateEle, data, options) { 1248 templateEle = dwr.util._getElementById(templateEle, "cloneNodeForValues()"); 1249 if (templateEle == null) return null; 1250 if (options == null) options = {}; 1251 var idpath; 1252 if (options.idPrefix != null) 1253 idpath = options.idPrefix; 1254 else 1255 idpath = templateEle.id || ""; 1256 return dwr.util._cloneNodeForValuesRecursive(templateEle, data, idpath, options); 1257}; 1258 1259/** 1260 * @private Recursive helper for cloneNodeForValues(). 1261 */ 1262dwr.util._cloneNodeForValuesRecursive = function(templateEle, data, idpath, options) { 1263 // Incoming array -> make an id for each item and call clone of the template 1264 // for each of them 1265 if (dwr.util._isArray(data)) { 1266 var clones = []; 1267 for (var i = 0; i < data.length; i++) { 1268 var item = data[i]; 1269 var clone = dwr.util._cloneNodeForValuesRecursive(templateEle, item, idpath + "[" + i + "]", options); 1270 clones.push(clone); 1271 } 1272 return clones; 1273 } 1274 else 1275 // Incoming object (not array) -> clone the template, add id prefixes, add 1276 // clone to DOM, and then recurse into any array properties if they contain 1277 // objects and there is a suitable template 1278 if (dwr.util._isObject(data) && !dwr.util._isArray(data)) { 1279 var clone = templateEle.cloneNode(true); 1280 if (options.updateCloneStyle && clone.style) { 1281 for (var propname in options.updateCloneStyle) { 1282 clone.style[propname] = options.updateCloneStyle[propname]; 1283 } 1284 } 1285 dwr.util._replaceIds(clone, templateEle.id, idpath); 1286 templateEle.parentNode.insertBefore(clone, templateEle); 1287 dwr.util._cloneSubArrays(data, idpath, options); 1288 return clone; 1289 } 1290 1291 // It is an error to end up here so we return nothing 1292 return null; 1293}; 1294 1295/** 1296 * @private Substitute a leading idpath fragment with another idpath for all 1297 * element ids tree, and remove ids that don't match the idpath. 1298 */ 1299dwr.util._replaceIds = function(ele, oldidpath, newidpath) { 1300 if (ele.id) { 1301 var newId = null; 1302 if (ele.id == oldidpath) { 1303 newId = newidpath; 1304 } 1305 else if (ele.id.length > oldidpath.length) { 1306 if (ele.id.substr(0, oldidpath.length) == oldidpath) { 1307 var trailingChar = ele.id.charAt(oldidpath.length); 1308 if (trailingChar == "." || trailingChar == "[") { 1309 newId = newidpath + ele.id.substr(oldidpath.length); 1310 } 1311 } 1312 } 1313 if (newId) { 1314 ele.setAttribute("id", newId); 1315 } 1316 else { 1317 ele.removeAttribute("id"); 1318 } 1319 } 1320 var children = ele.childNodes; 1321 for (var i = 0; i < children.length; i++) { 1322 var child = children.item(i); 1323 if (child.nodeType == 1 /*Node.ELEMENT_NODE*/) { 1324 dwr.util._replaceIds(child, oldidpath, newidpath); 1325 } 1326 } 1327}; 1328 1329/** 1330 * @private Finds arrays in supplied data and uses any corresponding template 1331 * node to make a clone for each item in the array. 1332 */ 1333dwr.util._cloneSubArrays = function(data, idpath, options) { 1334 for (prop in data) { 1335 var value = data[prop]; 1336 // Look for potential recursive cloning in all array properties 1337 if (dwr.util._isArray(value)) { 1338 // Only arrays with objects are interesting for cloning 1339 if (value.length > 0 && dwr.util._isObject(value[0])) { 1340 var subTemplateId = idpath + "." + prop; 1341 var subTemplateEle = dwr.util.byId(subTemplateId); 1342 if (subTemplateEle != null) { 1343 dwr.util._cloneNodeForValuesRecursive(subTemplateEle, value, subTemplateId, options); 1344 } 1345 } 1346 } 1347 // Continue looking for arrays in object properties 1348 else if (dwr.util._isObject(value)) { 1349 dwr.util._cloneSubArrays(value, idpath + "." + prop, options); 1350 } 1351 } 1352}; 1353 1354/** 1355 * @private Helper to turn a string into an element with an error message 1356 */ 1357dwr.util._getElementById = function(ele, source) { 1358 var orig = ele; 1359 ele = dwr.util.byId(ele); 1360 if (ele == null) { 1361 dwr.util._debug(source + " can't find an element with id: " + orig + "."); 1362 } 1363 return ele; 1364}; 1365 1366/** 1367 * @private Is the given node an HTML element (optionally of a given type)? 1368 * @param ele The element to test 1369 * @param nodeName eg "input", "textarea" - check for node name (optional) 1370 * if nodeName is an array then check all for a match. 1371 */ 1372dwr.util._isHTMLElement = function(ele, nodeName) { 1373 if (ele == null || typeof ele != "object" || ele.nodeName == null) { 1374 return false;
1375 } 1376 if (nodeName != null) { 1377 var test = ele.nodeName.toLowerCase(); 1378 if (typeof nodeName == "string") { 1379 return test == nodeName.toLowerCase(); 1380 } 1381 if (dwr.util._isArray(nodeName)) { 1382 var match = false; 1383 for (var i = 0; i < nodeName.length && !match; i++) { 1384 if (test == nodeName[i].toLowerCase()) { 1385 match = true; 1386 } 1387 } 1388 return match; 1389 } 1390 dwr.util._debug("dwr.util._isHTMLElement was passed test node name that is neither a string or array of strings"); 1391 return false; 1392 } 1393 return true; 1394}; 1395 1396/** 1397 * @private Like typeOf except that more information for an object is returned other than "object" 1398 */ 1399dwr.util._detailedTypeOf = function(x) { 1400 var reply = typeof x; 1401 if (reply == "object") { 1402 reply = Object.prototype.toString.apply(x); // Returns "[object class]" 1403 reply = reply.substring(8, reply.length-1); // Just get the class bit 1404 } 1405 return reply; 1406}; 1407 1408/** 1409 * @private Object detector. Excluding null from objects. 1410 */ 1411dwr.util._isObject = function(data) { 1412 return (data && typeof data == "object"); 1413}; 1414 1415/** 1416 * @private Array detector. Note: instanceof doesn't work with multiple frames. 1417 */ 1418dwr.util._isArray = function(data) { 1419 return (data && data.join); 1420}; 1421 1422/** 1423 * @private Date detector. Note: instanceof doesn't work with multiple frames. 1424 */ 1425dwr.util._isDate = function(data) { 1426 return (data && data.toUTCString) ? true : false; 1427}; 1428 1429/** 1430 * @private Used by setValue. Gets around the missing functionallity in IE. 1431 */ 1432dwr.util._importNode = function(doc, importedNode, deep) { 1433 var newNode; 1434 1435 if (importedNode.nodeType == 1 /*Node.ELEMENT_NODE*/) { 1436 newNode = doc.createElement(importedNode.nodeName); 1437 1438 for (var i = 0; i < importedNode.attributes.length; i++) { 1439 var attr = importedNode.attributes[i]; 1440 if (attr.nodeValue != null && attr.nodeValue != '') { 1441 newNode.setAttribute(attr.name, attr.nodeValue); 1442 } 1443 } 1444 1445 if (importedNode.style != null) { 1446 newNode.style.cssText = importedNode.style.cssText; 1447 } 1448 } 1449 else if (importedNode.nodeType == 3 /*Node.TEXT_NODE*/) { 1450 newNode = doc.createTextNode(importedNode.nodeValue); 1451 } 1452 1453 if (deep && importedNode.hasChildNodes()) { 1454 for (i = 0; i < importedNode.childNodes.length; i++) { 1455 newNode.appendChild(dwr.util._importNode(doc, importedNode.childNodes[i], true)); 1456 } 1457 } 1458 1459 return newNode; 1460}; 1461 1462/** @private Used internally when some message needs to get to the programmer */ 1463dwr.util._debug = function(message, stacktrace) { 1464 var written = false; 1465 try { 1466 if (window.console) { 1467 if (stacktrace && window.console.trace) window.console.trace(); 1468 window.console.log(message); 1469 written = true; 1470 } 1471 else if (window.opera && window.opera.postError) { 1472 window.opera.postError(message); 1473 written = true; 1474 } 1475 } 1476 catch (ex) { /* ignore */ } 1477 1478 if (!written) { 1479 var debug = document.getElementById("dwr-debug"); 1480 if (debug) { 1481 var contents = message + "<br/>" + debug.innerHTML; 1482 if (contents.length > 2048) contents = contents.substring(0, 2048); 1483 debug.innerHTML = contents; 1484 } 1485 } 1486}; 1487
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.