[ Index ] |
PHP Cross Reference of BardCMS V2 |
[Summary view] [Print] [Text view]
1 /* 2 * Copyright (c) 1995-2005 Macromedia, Inc. All rights reserved. 3 */ 4 5 /////////////////////////////////////////////////////////////////////////// 6 // 7 // Filename: wddx.js 8 // 9 // Authors: Simeon Simeonov (simeons@allaire.com) 10 // Nate Weiss (nweiss@icesinc.com) 11 // 12 // Last Modified: February 2, 2001 13 // 14 /////////////////////////////////////////////////////////////////////////// 15 16 17 /////////////////////////////////////////////////////////////////////////// 18 // 19 // WddxSerializer 20 // 21 /////////////////////////////////////////////////////////////////////////// 22 23 24 /////////////////////////////////////////////////////////////////////////// 25 // serializeValue() serializes any value that can be serialized 26 // returns true/false 27 function wddxSerializer_serializeValue(obj) 28 { 29 var bSuccess = true; 30 var val; 31 32 //alert(this.extractPacket()); 33 //alert(typeof(obj.valueOf())); 34 //alert(obj.valueOf()); 35 36 if (obj == null) 37 { 38 // Null value 39 this.write("<null/>"); 40 } 41 else if (typeof(val = obj.valueOf()) == "string") 42 { 43 // String value 44 this.serializeString(val); 45 } 46 else if (typeof(val = obj.valueOf()) == "number") 47 { 48 // Distinguish between numbers and date-time values 49 50 if ( 51 typeof(obj.getTimezoneOffset) == "function" && 52 typeof(obj.toGMTString) == "function") 53 { 54 // Possible Date 55 // Note: getYear() fix is from David Flanagan's 56 // "JS: The Definitive Guide". This code is Y2K safe. 57 this.write("<dateTime>" + 58 (obj.getYear() < 1000 ? 1900+obj.getYear() : obj.getYear()) + "-" + (obj.getMonth() + 1) + "-" + obj.getDate() + 59 "T" + obj.getHours() + ":" + obj.getMinutes() + ":" + obj.getSeconds()); 60 if (this.useTimezoneInfo) 61 { 62 this.write(this.timezoneString); 63 } 64 this.write("</dateTime>"); 65 } 66 else 67 { 68 // Number value 69 this.write("<number>" + val + "</number>"); 70 } 71 } 72 else if (typeof(val = obj.valueOf()) == "boolean") 73 { 74 // Boolean value 75 this.write("<boolean value='" + val + "'/>"); 76 } 77 else if (typeof(obj) == "object") 78 { 79 if (typeof(obj.wddxSerialize) == "function") 80 { 81 // Object knows how to serialize itself 82 bSuccess = obj.wddxSerialize(this); 83 } 84 else if ( 85 typeof(obj.join) == "function" && 86 typeof(obj.reverse) == "function" && 87 typeof(obj.sort) == "function" && 88 typeof(obj.length) == "number") 89 { 90 // Possible Array 91 this.write("<array length='" + obj.length + "'>"); 92 for (var i = 0; bSuccess && i < obj.length; ++i) 93 { 94 bSuccess = this.serializeValue(obj[i]); 95 } 96 this.write("</array>"); 97 } 98 else 99 { 100 // Some generic object; treat it as a structure 101 102 // Use the wddxSerializationType property as a guide as to its type 103 if (typeof(obj.wddxSerializationType) == 'string') 104 { 105 this.write('<struct type="'+ obj.wddxSerializationType +'">') 106 } 107 else 108 { 109 this.write("<struct>"); 110 } 111 112 for (var prop in obj) 113 { 114 if (prop != 'wddxSerializationType') 115 { 116 bSuccess = this.serializeVariable(prop, obj[prop]); 117 if (! bSuccess) 118 { 119 break; 120 } 121 } 122 } 123 124 this.write("</struct>"); 125 } 126 } 127 else 128 { 129 // Error: undefined values or functions 130 bSuccess = false; 131 } 132 133 // Successful serialization 134 return bSuccess; 135 } 136 137 138 139 /////////////////////////////////////////////////////////////////////////// 140 // serializeAttr() serializes an attribute (such as a var tag) using JavaScript 141 // functionality available in NS 3.0 and above 142 function wddxSerializer_serializeAttr(s) 143 { 144 for (var i = 0; i < s.length; ++i) 145 { 146 this.write(this.at[s.charAt(i)]); 147 } 148 } 149 150 151 /////////////////////////////////////////////////////////////////////////// 152 // serializeAttrOld() serializes a string using JavaScript functionality 153 // available in IE 3.0. We don't support special characters for IE3, so 154 // just throw the unencoded text and hope for the best 155 function wddxSerializer_serializeAttrOld(s) 156 { 157 this.write(s); 158 } 159 160 161 /////////////////////////////////////////////////////////////////////////// 162 // serializeString() serializes a string using JavaScript functionality 163 // available in NS 3.0 and above 164 function wddxSerializer_serializeString(s) 165 { 166 this.write("<string>"); 167 for (var i = 0; i < s.length; ++i) 168 { 169 if (s.charCodeAt(i) > 255) 170 this.write(s.charAt(i)); 171 else 172 this.write(this.et[s.charAt(i)]); 173 } 174 this.write("</string>"); 175 } 176 177 178 /////////////////////////////////////////////////////////////////////////// 179 // serializeStringOld() serializes a string using JavaScript functionality 180 // available in IE 3.0 181 function wddxSerializer_serializeStringOld(s) 182 { 183 this.write("<string><![CDATA["); 184 185 pos = s.indexOf("]]>"); 186 if (pos != -1) 187 { 188 startPos = 0; 189 while (pos != -1) 190 { 191 this.write(s.substring(startPos, pos) + "]]>]]><![CDATA["); 192 193 startPos = pos + 3; 194 if (startPos < s.length) 195 { 196 pos = s.indexOf("]]>", startPos); 197 } 198 else 199 { 200 // Work around bug in indexOf() 201 // "" will be returned instead of -1 if startPos > length 202 pos = -1; 203 } 204 } 205 this.write(s.substring(startPos, s.length)); 206 } 207 else 208 { 209 this.write(s); 210 } 211 212 this.write("]]></string>"); 213 } 214 215 216 /////////////////////////////////////////////////////////////////////////// 217 // serializeVariable() serializes a property of a structure 218 // returns true/false 219 function wddxSerializer_serializeVariable(name, obj) 220 { 221 var bSuccess = true; 222 223 if (typeof(obj) != "function") 224 { 225 this.write("<var name='"); 226 this.preserveVarCase ? this.serializeAttr(name) : this.serializeAttr(name.toLowerCase()); 227 this.write("'>"); 228 229 bSuccess = this.serializeValue(obj); 230 this.write("</var>"); 231 } 232 233 return bSuccess; 234 } 235 236 237 /////////////////////////////////////////////////////////////////////////// 238 // write() appends text to the wddxPacket buffer 239 function wddxSerializer_write(str) 240 { 241 this.wddxPacket[this.wddxPacket.length] = str; 242 } 243 244 245 /////////////////////////////////////////////////////////////////////////// 246 // writeOld() appends text to the wddxPacket buffer using IE 3.0 (JS 1.0) 247 // functionality. Unfortunately, the += operator has quadratic complexity 248 // which will cause slowdowns for large packets. 249 function wddxSerializer_writeOld(str) 250 { 251 this.wddxPacket += str; 252 } 253 254 255 /////////////////////////////////////////////////////////////////////////// 256 // initPacket() initializes the WDDX packet 257 function wddxSerializer_initPacket() 258 { 259 this.wddxPacket = new Array(); 260 } 261 262 263 /////////////////////////////////////////////////////////////////////////// 264 // initPacketOld() initializes the WDDX packet for use with IE 3.0 (JS 1.0) 265 function wddxSerializer_initPacketOld() 266 { 267 this.wddxPacket = ""; 268 } 269 270 271 /////////////////////////////////////////////////////////////////////////// 272 // extractPacket() extracts the WDDX packet as a string 273 function wddxSerializer_extractPacket() 274 { 275 return this.wddxPacket.join(""); 276 } 277 278 279 /////////////////////////////////////////////////////////////////////////// 280 // extractPacketOld() extracts the WDDX packet as a string (IE 3.0/JS 1.0) 281 function wddxSerializer_extractPacketOld() 282 { 283 return this.wddxPacket; 284 } 285 286 287 /////////////////////////////////////////////////////////////////////////// 288 // serialize() creates a WDDX packet for a given object 289 // returns the packet on success or null on failure 290 function wddxSerializer_serialize(rootObj) 291 { 292 this.initPacket(); 293 294 this.write("<wddxPacket version='1.0'><header/><data>"); 295 var bSuccess = this.serializeValue(rootObj); 296 this.write("</data></wddxPacket>"); 297 298 299 if (bSuccess) 300 { 301 return this.extractPacket(); 302 } 303 else 304 { 305 return null; 306 } 307 } 308 309 310 /////////////////////////////////////////////////////////////////////////// 311 // WddxSerializer() binds the function properties of the object 312 function WddxSerializer() 313 { 314 // Compatibility section 315 if (navigator.appVersion != "" && navigator.appVersion.indexOf("MSIE 3.") == -1) 316 { 317 // Character encoding table 318 319 // Encoding table for strings (CDATA) 320 var et = new Array(); 321 322 // Numbers to characters table and 323 // characters to numbers table 324 var n2c = new Array(); 325 var c2n = new Array(); 326 327 // Encoding table for attributes (i.e. var=str) 328 var at = new Array(); 329 330 for (var i = 0; i < 256; ++i) 331 { 332 // Build a character from octal code 333 var d1 = Math.floor(i/64); 334 var d2 = Math.floor((i%64)/8); 335 var d3 = i%8; 336 var c = eval("\"\\" + d1.toString(10) + d2.toString(10) + d3.toString(10) + "\""); 337 338 // Modify character-code conversion tables 339 n2c[i] = c; 340 c2n[c] = i; 341 342 // Modify encoding table 343 if (i < 32 && i != 9 && i != 10 && i != 13) 344 { 345 // Control characters that are not tabs, newlines, and carriage returns 346 347 // Create a two-character hex code representation 348 var hex = i.toString(16); 349 if (hex.length == 1) 350 { 351 hex = "0" + hex; 352 } 353 354 et[n2c[i]] = "<char code='" + hex + "'/>"; 355 356 // strip control chars from inside attrs 357 at[n2c[i]] = ""; 358 359 } 360 else if (i < 128) 361 { 362 // Low characters that are not special control characters 363 et[n2c[i]] = n2c[i]; 364 365 // attr table 366 at[n2c[i]] = n2c[i]; 367 } 368 else 369 { 370 // High characters 371 et[n2c[i]] = "&#x" + i.toString(16) + ";"; 372 at[n2c[i]] = "&#x" + i.toString(16) + ";"; 373 } 374 } 375 376 // Special escapes for CDATA encoding 377 et["<"] = "<"; 378 et[">"] = ">"; 379 et["&"] = "&"; 380 381 // Special escapes for attr encoding 382 at["<"] = "<"; 383 at[">"] = ">"; 384 at["&"] = "&"; 385 at["'"] = "'"; 386 at["\""] = """; 387 388 // Store tables 389 this.n2c = n2c; 390 this.c2n = c2n; 391 this.et = et; 392 this.at = at; 393 394 // The browser is not MSIE 3.x 395 this.serializeString = wddxSerializer_serializeString; 396 this.serializeAttr = wddxSerializer_serializeAttr; 397 this.write = wddxSerializer_write; 398 this.initPacket = wddxSerializer_initPacket; 399 this.extractPacket = wddxSerializer_extractPacket; 400 } 401 else 402 { 403 // The browser is most likely MSIE 3.x, it is NS 2.0 compatible 404 this.serializeString = wddxSerializer_serializeStringOld; 405 this.serializeAttr = wddxSerializer_serializeAttrOld; 406 this.write = wddxSerializer_writeOld; 407 this.initPacket = wddxSerializer_initPacketOld; 408 this.extractPacket = wddxSerializer_extractPacketOld; 409 } 410 411 // Setup timezone information 412 413 var tzOffset = (new Date()).getTimezoneOffset(); 414 415 // Invert timezone offset to convert local time to UTC time 416 if (tzOffset >= 0) 417 { 418 this.timezoneString = '-'; 419 } 420 else 421 { 422 this.timezoneString = '+'; 423 } 424 this.timezoneString += Math.floor(Math.abs(tzOffset) / 60) + ":" + (Math.abs(tzOffset) % 60); 425 426 // Common properties 427 this.preserveVarCase = false; 428 this.useTimezoneInfo = true; 429 430 // Common functions 431 this.serialize = wddxSerializer_serialize; 432 this.serializeValue = wddxSerializer_serializeValue; 433 this.serializeVariable = wddxSerializer_serializeVariable; 434 } 435 436 437 /////////////////////////////////////////////////////////////////////////// 438 // 439 // WddxRecordset 440 // 441 /////////////////////////////////////////////////////////////////////////// 442 443 444 /////////////////////////////////////////////////////////////////////////// 445 // isColumn(name) returns true/false based on whether this is a column name 446 function wddxRecordset_isColumn(name) 447 { 448 // Columns must be objects 449 // WddxRecordset extensions might use properties prefixed with 450 // _private_ and these will not be treated as columns 451 return (typeof(this[name]) == "object" && 452 name.indexOf("_private_") == -1); 453 } 454 455 456 /////////////////////////////////////////////////////////////////////////// 457 // getRowCount() returns the number of rows in the recordset 458 function wddxRecordset_getRowCount() 459 { 460 var nRowCount = 0; 461 for (var col in this) 462 { 463 if (this.isColumn(col)) 464 { 465 nRowCount = this[col].length; 466 break; 467 } 468 } 469 return nRowCount; 470 } 471 472 473 /////////////////////////////////////////////////////////////////////////// 474 // addColumn(name) adds a column with that name and length == getRowCount() 475 function wddxRecordset_addColumn(name) 476 { 477 var nLen = this.getRowCount(); 478 var colValue = new Array(nLen); 479 for (var i = 0; i < nLen; ++i) 480 { 481 colValue[i] = null; 482 } 483 this[this.preserveFieldCase ? name : name.toLowerCase()] = colValue; 484 } 485 486 487 /////////////////////////////////////////////////////////////////////////// 488 // addRows() adds n rows to all columns of the recordset 489 function wddxRecordset_addRows(n) 490 { 491 for (var col in this) 492 { 493 if (this.isColumn(col)) 494 { 495 var nLen = this[col].length; 496 for (var i = nLen; i < nLen + n; ++i) 497 { 498 this[col][i] = null; 499 } 500 } 501 } 502 } 503 504 505 /////////////////////////////////////////////////////////////////////////// 506 // getField() returns the element in a given (row, col) position 507 function wddxRecordset_getField(row, col) 508 { 509 return this[this.preserveFieldCase ? col : col.toLowerCase()][row]; 510 } 511 512 513 /////////////////////////////////////////////////////////////////////////// 514 // setField() sets the element in a given (row, col) position to value 515 function wddxRecordset_setField(row, col, value) 516 { 517 this[this.preserveFieldCase ? col : col.toLowerCase()][row] = value; 518 } 519 520 521 /////////////////////////////////////////////////////////////////////////// 522 // wddxSerialize() serializes a recordset 523 // returns true/false 524 function wddxRecordset_wddxSerialize(serializer) 525 { 526 // Create an array and a list of column names 527 var colNamesList = ""; 528 var colNames = new Array(); 529 var i = 0; 530 for (var col in this) 531 { 532 if (this.isColumn(col)) 533 { 534 colNames[i++] = col; 535 536 if (colNamesList.length > 0) 537 { 538 colNamesList += ","; 539 } 540 colNamesList += col; 541 } 542 } 543 544 var nRows = this.getRowCount(); 545 546 serializer.write("<recordset rowCount='" + nRows + "' fieldNames='" + colNamesList + "'>"); 547 548 var bSuccess = true; 549 for (i = 0; bSuccess && i < colNames.length; i++) 550 { 551 var name = colNames[i]; 552 serializer.write("<field name='" + name + "'>"); 553 554 for (var row = 0; bSuccess && row < nRows; row++) 555 { 556 bSuccess = serializer.serializeValue(this[name][row]); 557 } 558 559 serializer.write("</field>"); 560 } 561 562 serializer.write("</recordset>"); 563 564 return bSuccess; 565 } 566 567 568 /////////////////////////////////////////////////////////////////////////// 569 // dump(escapeStrings) returns an HTML table with the recordset data 570 // It is a convenient routine for debugging and testing recordsets 571 // The boolean parameter escapeStrings determines whether the <>& 572 // characters in string values are escaped as <>& 573 function wddxRecordset_dump(escapeStrings) 574 { 575 // Get row count 576 var nRows = this.getRowCount(); 577 578 // Determine column names 579 var colNames = new Array(); 580 var i = 0; 581 for (var col in this) 582 { 583 if (typeof(this[col]) == "object") 584 { 585 colNames[i++] = col; 586 } 587 } 588 589 // Build table headers 590 var o = "<table border=1><tr><td><b>RowNumber</b></td>"; 591 for (i = 0; i < colNames.length; ++i) 592 { 593 o += "<td><b>" + colNames[i] + "</b></td>"; 594 } 595 o += "</tr>"; 596 597 // Build data cells 598 for (var row = 0; row < nRows; ++row) 599 { 600 o += "<tr><td>" + row + "</td>"; 601 for (i = 0; i < colNames.length; ++i) 602 { 603 var elem = this.getField(row, colNames[i]); 604 if (escapeStrings && typeof(elem) == "string") 605 { 606 var str = ""; 607 for (var j = 0; j < elem.length; ++j) 608 { 609 var ch = elem.charAt(j); 610 if (ch == '<') 611 { 612 str += "<"; 613 } 614 else if (ch == '>') 615 { 616 str += ">"; 617 } 618 else if (ch == '&') 619 { 620 str += "&"; 621 } 622 else 623 { 624 str += ch; 625 } 626 } 627 o += ("<td>" + str + "</td>"); 628 } 629 else 630 { 631 o += ("<td>" + elem + "</td>"); 632 } 633 } 634 o += "</tr>"; 635 } 636 637 // Close table 638 o += "</table>"; 639 640 // Return HTML recordset dump 641 return o; 642 } 643 644 645 /////////////////////////////////////////////////////////////////////////// 646 // WddxRecordset([flagPreserveFieldCase]) creates an empty recordset. 647 // WddxRecordset(columns [, flagPreserveFieldCase]) creates a recordset 648 // with a given set of columns provided as an array of strings. 649 // WddxRecordset(columns, rows [, flagPreserveFieldCase]) creates a 650 // recordset with these columns and some number of rows. 651 // In all cases, flagPreserveFieldCase determines whether the exact case 652 // of field names is preserved. If omitted, the default value is false 653 // which means that all field names will be lowercased. 654 function WddxRecordset() 655 { 656 // Add default properties 657 this.preserveFieldCase = false; 658 659 // Add extensions 660 if (typeof(wddxRecordsetExtensions) == "object") 661 { 662 for (var prop in wddxRecordsetExtensions) 663 { 664 // Hook-up method to WddxRecordset object 665 this[prop] = wddxRecordsetExtensions[prop] 666 } 667 } 668 669 // Add built-in methods 670 this.getRowCount = wddxRecordset_getRowCount; 671 this.addColumn = wddxRecordset_addColumn; 672 this.addRows = wddxRecordset_addRows; 673 this.isColumn = wddxRecordset_isColumn; 674 this.getField = wddxRecordset_getField; 675 this.setField = wddxRecordset_setField; 676 this.wddxSerialize = wddxRecordset_wddxSerialize; 677 this.dump = wddxRecordset_dump; 678 679 // Perfom any needed initialization 680 if (WddxRecordset.arguments.length > 0) 681 { 682 if (typeof(val = WddxRecordset.arguments[0].valueOf()) == "boolean") 683 { 684 // Case preservation flag is provided as 1st argument 685 this.preserveFieldCase = WddxRecordset.arguments[0]; 686 } 687 else 688 { 689 // First argument is the array of column names 690 var cols = WddxRecordset.arguments[0]; 691 692 // Second argument could be the length or the preserve case flag 693 var nLen = 0; 694 if (WddxRecordset.arguments.length > 1) 695 { 696 if (typeof(val = WddxRecordset.arguments[1].valueOf()) == "boolean") 697 { 698 // Case preservation flag is provided as 2nd argument 699 this.preserveFieldCase = WddxRecordset.arguments[1]; 700 } 701 else 702 { 703 // Explicitly specified recordset length 704 nLen = WddxRecordset.arguments[1]; 705 706 if (WddxRecordset.arguments.length > 2) 707 { 708 // Case preservation flag is provided as 3rd argument 709 this.preserveFieldCase = WddxRecordset.arguments[2]; 710 } 711 } 712 } 713 714 for (var i = 0; i < cols.length; ++i) 715 { 716 var colValue = new Array(nLen); 717 for (var j = 0; j < nLen; ++j) 718 { 719 colValue[j] = null; 720 } 721 722 this[this.preserveFieldCase ? cols[i] : cols[i].toLowerCase()] = colValue; 723 } 724 } 725 } 726 } 727 728 729 /////////////////////////////////////////////////////////////////////////// 730 // 731 // WddxRecordset extensions 732 // 733 // The WddxRecordset class has been designed with extensibility in mind. 734 // 735 // Developers can add new properties to the object and as long as their 736 // names are prefixed with _private_ the WDDX serialization function of 737 // WddxRecordset will not treat them as recordset columns. 738 // 739 // Developers can create new methods for the class outside this file as 740 // long as they make a call to registerWddxRecordsetExtension() with the 741 // name of the method and the function object that implements the method. 742 // The WddxRecordset constructor will automatically register all these 743 // methods with instances of the class. 744 // 745 // Example: 746 // 747 // If I want to add a new WddxRecordset method called addOneRow() I can 748 // do the following: 749 // 750 // - create the method implementation 751 // 752 // function wddxRecordset_addOneRow() 753 // { 754 // this.addRows(1); 755 // } 756 // 757 // - call registerWddxRecordsetExtension() 758 // 759 // registerWddxRecordsetExtension("addOneRow", wddxRecordset_addOneRow); 760 // 761 // - use the new function 762 // 763 // rs = new WddxRecordset(); 764 // rs.addOneRow(); 765 // 766 /////////////////////////////////////////////////////////////////////////// 767 768 769 /////////////////////////////////////////////////////////////////////////// 770 // registerWddxRecordsetExtension(name, func) can be used to extend 771 // functionality by registering functions that should be added as methods 772 // to WddxRecordset instances. 773 function registerWddxRecordsetExtension(name, func) 774 { 775 // Perform simple validation of arguments 776 if (typeof(name) == "string" && typeof(func) == "function") 777 { 778 // Guarantee existence of wddxRecordsetExtensions object 779 if (typeof(wddxRecordsetExtensions) != "object") 780 { 781 // Create wddxRecordsetExtensions instance 782 wddxRecordsetExtensions = new Object(); 783 } 784 785 // Register extension; override an existing one 786 wddxRecordsetExtensions[name] = func; 787 } 788 } 789 790 791 792 /////////////////////////////////////////////////////////////////////////// 793 // 794 // WddxBinary 795 // 796 /////////////////////////////////////////////////////////////////////////// 797 798 799 /////////////////////////////////////////////////////////////////////////// 800 // wddxSerialize() serializes a binary value 801 // returns true/false 802 function wddxBinary_wddxSerialize(serializer) 803 { 804 serializer.write( 805 "<binary encoding='" + this.encoding + "'>" + this.data + "</binary>"); 806 return true; 807 } 808 809 810 /////////////////////////////////////////////////////////////////////////// 811 // WddxBinary() constructs an empty binary value 812 // WddxBinary(base64Data) constructs a binary value from base64 encoded data 813 // WddxBinary(data, encoding) constructs a binary value from encoded data 814 function WddxBinary(data, encoding) 815 { 816 this.data = data != null ? data : ""; 817 this.encoding = encoding != null ? encoding : "base64"; 818 819 // Custom serialization mechanism 820 this.wddxSerialize = wddxBinary_wddxSerialize; 821 } 822 823
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Sep 19 20:28:49 2006 | Cross-referenced by PHPXref 0.6 |