1 /* 2 * SIMPLICITE - runtime & framework 3 * http://www.simplicite.fr 4 * Copyright (c)2006-2013 Simplicite Software. All rights reserved. 5 */ 6 7 // Simplicite is defined when using generic web UI but must be defined for standalone usage 8 if (window["Simplicite"] === undefined) var Simplicite = {}; 9 10 /** 11 * Simplicité® application. 12 * <br/>Sample usage: 13 * <pre> 14 * // Using authenticated user thru UI gateway 15 * var app = new Simplicite.Ajax("myapp"); 16 * // Using public user thru public UI gateway 17 * var app = new Simplicite.Ajax("myapp", "uipublic"); 18 * // Using website user thru WS gateway 19 * var app = new Simplicite.Ajax("myapp", "ws", "myuser", "mypassword"); 20 * // Using website user thru API gateway 21 * var app = new Simplicite.Ajax("myapp", "api", "myuser", "mypassword"); 22 * </pre> 23 * @param approot Application root (either application name or /<context root> or absolute base URL) 24 * @param gateway Gateway type to use : 25 * <ul> 26 * <li>1 or "ui": Authenticated UI gateway (default)</li> 27 * <li>2 or "uipublic" : Public UI gateway</li> 28 * <li>3 or "ws" : Webservices gateway</li> 29 * </ul> 30 * @param login User's login (not required for UI gateways) 31 * @param password User's password (not required for UI gateways) 32 * @param async Asynchronous calls by default (true if absent) ? 33 * @class 34 */ 35 Simplicite.Ajax = function(approot, gateway, login, password, async) { 36 37 /** @ignore */ 38 this._errorActive = true; 39 this.error = function(err) { 40 if (this._errorActive == true) { 41 var m = "ERROR" + (err.level !== undefined ? " (" + err.level + ")" : "") + ": " + this.getErrorMessage(err); 42 try { console.error(m); } catch(e) { alert(m); } 43 try { if (err.message.stack) console.error(err.message.stack); } catch(e) {} 44 } 45 }; 46 47 /** @ignore */ 48 this._warningActive = true; 49 this.warning = function(msg) { 50 if (this._warningActive == true) { 51 var m = "WARNING: " + msg; 52 try { console.warn(m); } catch (e) { console.log(m); } 53 } 54 }; 55 56 /** @ignore */ 57 this._infoActive = true; 58 this.info = function(msg) { 59 if (this._infoActive == true) { 60 try { console.log("INFO: " + msg); } catch(e) {} 61 } 62 }; 63 64 /** @ignore */ 65 this._debugActive = false; 66 this.debug = function(msg) { 67 if (this._debugActive == true) { 68 var m = "DEBUG: " + msg; 69 try { console.debug(m); } catch (e) { console.log(m); } 70 } 71 }; 72 73 /** @ignore */ 74 this._approot = ""; 75 /** @ignore */ 76 this._baseURL = ""; 77 78 if (approot !== undefined && (approot.substring(0, 4) === "http" || approot.substring(0, 2) === "//")) { 79 this._baseURL = approot; 80 } else { 81 this._approot = approot === undefined ? (Simplicite.ROOT === undefined ? (Simplicite.APPLICATION === undefined ? "__unknown__" : "/" + Simplicite.APPLICATION) : Simplicite.ROOT) : approot; 82 if (this._approot != "" && this._approot.charAt(0) != "/") this._approot = "/" + this._approot; 83 84 this._baseURL = window.location.protocol + "//" + window.location.hostname + (window.location.port != "" ? ":" + window.location.port : ""); 85 this.debug("Base URL: " + this._baseURL + ", application root: " + this._approot + ", login: " + this._login + ", asynchronous: " + this._async); 86 } 87 88 /** @ignore */ 89 this._gateway = undefined; 90 /** @ignore */ 91 this._appURL = undefined; 92 /** @ignore */ 93 this._objURL = undefined; 94 /** @ignore */ 95 this._pcsURL = undefined; 96 /** @ignore */ 97 this._documentURL = undefined; 98 /** @ignore */ 99 this._contentURL = undefined; 100 /** @ignore */ 101 this._resourceURL = undefined; 102 /** @ignore */ 103 this._login = undefined; 104 /** @ignore */ 105 this._password = undefined; 106 107 this.GATEWAY_UI = "ui"; 108 this.GATEWAY_UI_PUBLIC = "uipublic"; 109 this.GATEWAY_API = "api"; 110 this.GATEWAY_WS = "ws"; 111 112 /** @ignore */ 113 this._version = 3; 114 115 this.setGateway = function(gateway, login, password) { 116 if (!gateway || gateway == 1 || gateway == this.GATEWAY_UI) { 117 this._gateway = this.GATEWAY_UI; 118 if (this._version < 3) { 119 this._appURL = "/jsp/SYS_json.jsp"; 120 this._objURL = "/jsp/ALL_json.jsp"; 121 this._pcsURL = "/jsp/PCS_json.jsp"; 122 this._contentURL = "/PUB_content.jsp"; 123 this._resourceURL = "/PUB_resource.jsp"; 124 } else { 125 var r = "/" + (this._version < 4 ? "jsp" : "ui") 126 this._appURL = r + "/json/app"; 127 this._objURL = r + "/json/obj"; 128 this._pcsURL = r + "/json/pcs"; 129 this._contentURL = "/content"; 130 this._resourceURL = "/resource"; 131 } 132 this._documentURL = "/jsp/ALL_docblob.jsp"; 133 this._login = undefined; 134 this._password = undefined; 135 this.debug("Using UI gateway"); 136 } else if (gateway == 2 || gateway == this.GATEWAY_UI_PUBLIC) { 137 this._gateway = this.GATEWAY_UI_PUBLIC; 138 if (this._version < 3) { 139 this._appURL = "/PUB_json_app.jsp"; 140 this._objURL = "/PUB_json_obj.jsp"; 141 this._pcsURL = "/PUB_json_pcs.jsp"; 142 this._contentURL = "/PUB_content.jsp"; 143 this._resourceURL = "/PUB_resource.jsp"; 144 } else { 145 this._appURL = "/json/app"; 146 this._objURL = "/json/obj"; 147 this._pcsURL = "/json/pcs"; 148 this._contentURL = "/content"; 149 this._resourceURL = "/resource"; 150 } 151 this._documentURL = "/PUB_document.jsp"; 152 this._login = undefined; 153 this._password = undefined; 154 this.debug("Using public UI gateway"); 155 } else if (gateway == 3 || gateway == this.GATEWAY_WS) { 156 this._gateway = this.GATEWAY_WS; 157 if (this._version < 3) { 158 this._appURL = "/jsonappservice.jsp"; 159 this._objURL = "/jsonservice.jsp"; 160 this._pcsURL = "/jsonpcsservice.jsp"; 161 this._contentURL = "/rawcontentservice.jsp"; 162 this._resourceURL = "/rawresourceservice.jsp"; 163 this._documentURL = "/rawdbdocservice.jsp"; 164 } else { 165 this._appURL = "/json/app"; 166 this._objURL = "/json/obj"; 167 this._pcsURL = "/json/pcs"; 168 this._contentURL = "/raw/content"; 169 this._resourceURL = "/raw/resource"; 170 this._documentURL = "/raw/dbdoc"; 171 } 172 this._login = login; 173 this._password = password; 174 this.debug("Using WS gateway with login " + login); 175 } else if (this._version >= 3 && gateway == this.GATEWAY_API) { 176 this._gateway = this.GATEWAY_API; 177 this._appURL = "/api/json/app"; 178 this._objURL = "/api/json/obj"; 179 this._pcsURL = "/api/json/pcs"; 180 this._contentURL = "/api/raw/content"; 181 this._resourceURL = "/api/raw/resource"; 182 this._documentURL = "/api/raw/dbdoc"; 183 this._login = login; 184 this._password = password; 185 this.debug("Using API gateway with login " + login); 186 } else 187 this.error("Unknown gateway: " + gateway); 188 }; 189 this.setGateway(gateway, login, password); 190 this.getGateway = function() { return this._gateway; }; 191 192 /** @ignore */ 193 this._async = true; 194 this.setAsync = function(async) { 195 if (async !== undefined) { 196 this._async = async; 197 this.debug("Async mode set to " + async); 198 } 199 }; 200 this.setAsync(async); 201 this.getAsync = function() { return this._async; }; 202 203 /** @ignore */ 204 this._timeout = 0; 205 this.setTimeout = function(timeout) { 206 if (timeout !== undefined) { 207 this._timeout = timeout; 208 this.debug("Timeout set to " + timeout); 209 } 210 }; 211 this.getTimeout = function() { return this._timeout; }; 212 213 this.isWinIE = function() { return navigator.userAgent.indexOf("MSIE")!=-1 && navigator.userAgent.indexOf("Win") != -1; }; 214 this.winIEVersion = function() { return parseInt(navigator.appVersion.split("MSIE")[1]); }; 215 this.isFirefox = function() { return navigator.userAgent.toLowerCase().indexOf("firefox") != -1; }; 216 this.isWebkit = function() { return navigator.userAgent.toLowerCase().indexOf("webkit") != -1; }; 217 218 /** 219 * Default row ID value (for creation). 220 * @constant 221 */ 222 this.DEFAULT_ROW_ID = "0"; 223 224 /** 225 * No context. 226 * @constant 227 */ 228 this.CONTEXT_NONE = 0; 229 /** 230 * Search context. 231 * @constant 232 */ 233 this.CONTEXT_SEARCH = 1; 234 /** 235 * List context. 236 * @constant 237 */ 238 this.CONTEXT_LIST = 2; 239 /** 240 * Creation context. 241 * @constant 242 */ 243 this.CONTEXT_CREATE = 3; 244 /** 245 * Copy context. 246 * @constant 247 */ 248 this.CONTEXT_COPY = 4; 249 /** 250 * Update context. 251 * @constant 252 */ 253 this.CONTEXT_UPDATE = 5; 254 /** 255 * Delete context. 256 * @constant 257 */ 258 this.CONTEXT_DELETE = 6; 259 /** 260 * Chart context. 261 * @constant 262 */ 263 this.CONTEXT_GRAPH = 7; 264 /** 265 * Cross table context. 266 * @constant 267 */ 268 this.CONTEXT_CROSSTAB = 8; 269 /** 270 * Publication template context. 271 * @constant 272 */ 273 this.CONTEXT_PRINTTMPL = 9; 274 /** 275 * Bulk update context. 276 * @constant 277 */ 278 this.CONTEXT_UPDATEALL = 10; 279 /** 280 * Reference selection context. 281 * @constant 282 */ 283 this.CONTEXT_REFSELECT = 11; 284 /** 285 * Data mapping selection context. 286 * @constant 287 */ 288 this.CONTEXT_DATAMAPSELECT = 12; 289 /** 290 * Pre-validate context. 291 * @constant 292 */ 293 this.CONTEXT_PREVALIDATE = 13; 294 /** 295 * Post validate context. 296 * @constant 297 */ 298 this.CONTEXT_POSTVALIDATE = 14; 299 /** 300 * State transition context. 301 * @constant 302 */ 303 this.CONTEXT_STATETRANSITION = 15; 304 /** 305 * Export context. 306 * @constant 307 */ 308 this.CONTEXT_EXPORT = 16; 309 /** 310 * Import context. 311 * @constant 312 */ 313 this.CONTEXT_IMPORT = 17; 314 /** 315 * Association context. 316 * @constant 317 */ 318 this.CONTEXT_ASSOCIATE = 18; 319 /** 320 * Panel list context. 321 * @constant 322 */ 323 this.CONTEXT_PANELLIST = 19; 324 /** 325 * Action context. 326 * @constant 327 */ 328 this.CONTEXT_ACTION = 20; 329 /** 330 * Agenda context. 331 * @constant 332 */ 333 this.CONTEXT_AGENDA = 21; 334 /** 335 * Place map context. 336 * @constant 337 */ 338 this.CONTEXT_PLACEMAP = 22; 339 340 /** 341 * Internal ID (foreign key) type. 342 * @constant 343 */ 344 this.TYPE_ID = 0; 345 /** 346 * Integer type. 347 * @constant 348 */ 349 this.TYPE_INT = 1; 350 /** 351 * Float type. 352 * @constant 353 */ 354 this.TYPE_FLOAT = 2; 355 /** 356 * String type. 357 * @constant 358 */ 359 this.TYPE_STRING = 3; 360 /** 361 * Date type. 362 * @constant 363 */ 364 this.TYPE_DATE = 4; 365 /** 366 * Date and time type. 367 * @constant 368 */ 369 this.TYPE_DATETIME = 5; 370 /** 371 * Time type. 372 * @constant 373 */ 374 this.TYPE_TIME = 6; 375 /** 376 * Single enumerated (list of values) type. 377 * @constant 378 */ 379 this.TYPE_ENUM = 7; 380 /** 381 * Boolean type. 382 * @constant 383 */ 384 this.TYPE_BOOLEAN = 8; 385 /** 386 * Password type. 387 * @constant 388 */ 389 this.TYPE_PASSWORD = 9; 390 /** 391 * URL type. 392 * @constant 393 */ 394 this.TYPE_URL = 10; 395 /** 396 * HTML content type. 397 * @constant 398 */ 399 this.TYPE_HTML = 11; 400 /** 401 * Email type. 402 * @constant 403 */ 404 this.TYPE_EMAIL = 12; 405 /** 406 * Long string (unlimited) type. 407 * @constant 408 */ 409 this.TYPE_LONG_STRING = 13; 410 /** 411 * Multiple enumerated (list of values) type. 412 * @constant 413 */ 414 this.TYPE_ENUM_MULTI = 14; 415 /** 416 * Regular expression type. 417 * @constant 418 */ 419 this.TYPE_REGEXP = 15; 420 /** 421 * Document type 422 * @constant 423 */ 424 this.TYPE_DOC = 17; 425 /** 426 * Float type (same as TYPE_FLOAT). 427 * @constant 428 */ 429 this.TYPE_FLOAT_EMPTY = 18; 430 /** 431 * External file reference type. 432 * @constant 433 */ 434 this.TYPE_EXTFILE = 19; 435 /** 436 * Image type. 437 * @constant 438 */ 439 this.TYPE_IMAGE = 20; 440 /** 441 * Notepad (incremental long text) type. 442 * @constant 443 */ 444 this.TYPE_NOTEPAD = 21; 445 /** 446 * Phone number type. 447 * @constant 448 */ 449 this.TYPE_PHONENUM = 22; 450 /** 451 * Color type. 452 * @constant 453 */ 454 this.TYPE_COLOR = 23; 455 /** 456 * Object type. 457 * @constant 458 */ 459 this.TYPE_OBJECT = 24; 460 /** 461 * Geo coordinates type. 462 * @constant 463 */ 464 this.TYPE_GEOCOORDS = 25; 465 466 /** 467 * Not visible. 468 * @constant 469 */ 470 this.VIS_NOT = 0; 471 /** 472 * Visible in lists. 473 * @constant 474 */ 475 this.VIS_LIST = 1; 476 /** 477 * Visible in forms. 478 * @constant 479 */ 480 this.VIS_FORM = 2; 481 /** 482 * Visible in lists and forms. 483 * @constant 484 */ 485 this.VIS_BOTH = 3; 486 487 /** 488 * Not searchable. 489 * @constant 490 */ 491 this.SEARCH_NONE = 0; 492 /** 493 * Searchable. 494 * @constant 495 */ 496 this.SEARCH_MONO = 1; 497 /** 498 * Searchable using check boxes. 499 * @constant 500 */ 501 this.SEARCH_MULTI_CHECK = 2; 502 /** 503 * Searchable using list box. 504 * @constant 505 */ 506 this.SEARCH_MULTI_LIST = 3; 507 /** 508 * Searchable using period. 509 * @constant 510 */ 511 this.SEARCH_PERIOD = 4; 512 513 /** 514 * Default rendering. 515 * @constant 516 */ 517 this.RENDERING_DEFAULT = ""; 518 /** 519 * Select box rendering (single or multiple select). 520 * @constant 521 */ 522 this.RENDERING_SELECTBOX = "SB"; 523 /** 524 * Rendering horizontal checkbox(es). 525 * @constant 526 */ 527 this.RENDERING_HORIZCHECKBOX = "HCB"; 528 /** 529 * Rendering vertical checkbox(es). 530 * @constant 531 */ 532 this.RENDERING_VERTCHECKBOX = "VCB"; 533 /** 534 * Rendering horizontal radio button(s). 535 * @constant 536 */ 537 this.RENDERING_HORIZRADIOBUTTON = "HRB"; 538 /** 539 * Rendering vertical radio button(s). 540 * @constant 541 */ 542 this.RENDERING_VERTRADIOBUTTON = "VRB"; 543 544 /** 545 * True value 546 * @constant 547 */ 548 this.TRUE = "1"; 549 /** 550 * False value 551 * @constant 552 */ 553 this.FALSE = "0"; 554 555 /** 556 * Fatal error value 557 * @constant 558 */ 559 this.ERRLEVEL_FATAL = 1; 560 /** 561 * Error error value 562 * @constant 563 */ 564 this.ERRLEVEL_ERROR = 2; 565 /** 566 * Minor error value 567 * @constant 568 */ 569 this.ERRLEVEL_WARNING = 3; 570 571 /** 572 * Application info data. 573 * <ul> 574 * <li>name: Application name</li> 575 * <li>version: Application version</li> 576 * <li>platformversion: Platform version</li> 577 * <li>encoding: Encoding</li> 578 * <li>server: Server vendor</li> 579 * <li>TO BE COMPLETED...</li> 580 * </ul> 581 * @field 582 */ 583 this.appinfo = new Object(); 584 585 /** 586 * Grant data. 587 * <ul> 588 * <li>login: User login</li> 589 * <li>firstname: User first name</li> 590 * <li>lastname: User last name</li> 591 * <li>responsibilities: User active responsibilites array</li> 592 * <li>TO BE COMPLETED...</li> 593 * </ul> 594 * @field 595 */ 596 this.grant = new Object(); 597 598 /** 599 * System parameters array. Use sysparams["<name>"] to get a system parameter value. 600 * @field 601 */ 602 this.sysparams = new Array(); 603 604 /** 605 * Texts array. Use texts["<code>"] to get a text value. 606 * @field 607 */ 608 this.texts = new Array(); 609 610 /** 611 * Menu data. 612 * <ul> 613 * <li>TO BE COMPLETED...</li> 614 * </ul> 615 * @field 616 */ 617 this.menu = new Array(); 618 619 /** 620 * News array. Use news["<code>"] to get a news object), each news object is: 621 * <ul> 622 * <li>TO BE COMPLETED...</li> 623 * </ul> 624 * @field 625 */ 626 this.news = new Array(); 627 }; 628 629 /** 630 * Set default JSON services version compatibility 631 * @param version Simplicite(R) JSON services version to be compatible with (e.g. 2.7) 632 * @function 633 */ 634 Simplicite.Ajax.prototype.setVersionCompatibility = function(version) { 635 this._version = version; 636 }; 637 638 /** @ignore */ 639 Simplicite.Ajax.prototype.getStandardError = function(level, message, details) { 640 return { 641 level: level, 642 message: message, 643 details: details 644 }; 645 }; 646 647 /** @ignore */ 648 Simplicite.Ajax.prototype.getErrorMessage = function(err) { 649 var msg = ""; 650 if (err.messages !== undefined) { 651 for (var i = 0; i < err.messages.length; i++) 652 msg += (msg == "" ? "" : "\n") + err.messages[i]; 653 } else if (err.message !== undefined) 654 msg = err.message; 655 else if (err.description !== undefined) 656 msg = err.description; 657 else 658 msg = err; 659 return msg; 660 }; 661 662 /** 663 * Set default global error handler active or inactive. 664 * @param active Active status 665 * @function 666 */ 667 Simplicite.Ajax.prototype.setErrorHandlerActive = function(active) { 668 this._errorActive = active; 669 };/** 670 * Change default global error handler. 671 * @param errorHandler Error handler function 672 * @function 673 */ 674 Simplicite.Ajax.prototype.setErrorHandler = function(errorHandler) { 675 var self = this; 676 self.error = function(err) { 677 if (self._errorActive == true) 678 errorHandler.call(this, err); 679 }; 680 }; 681 682 /** 683 * Set default global warning handler active or inactive. 684 * @param active Active status 685 * @function 686 */ 687 Simplicite.Ajax.prototype.setWarningHandlerActive = function(active) { 688 this._warningActive = active; 689 }; 690 /** 691 * Change default global warning handler. 692 * @param warningHandler Warning handler function 693 * @function 694 */ 695 Simplicite.Ajax.prototype.setWarningHandler = function(warningHandler) { 696 var self = this; 697 self.warning = function(msg) { 698 if (self._warningActive == true) 699 warningHandler.call(this, msg); 700 }; 701 }; 702 703 /** 704 * Set default global information handler active or inactive. 705 * @param active Active status 706 * @function 707 */ 708 Simplicite.Ajax.prototype.setInfoHandlerActive = function(active) { 709 this._infoActive = active; 710 }; 711 /** 712 * Change default global information handler. 713 * @param infoHandler Information handler function 714 * @function 715 */ 716 Simplicite.Ajax.prototype.setInfoHandler = function(infoHandler) { 717 var self = this; 718 self.info = function(msg) { 719 if (self._infoActive == true) 720 infoHandler.call(this, msg); 721 }; 722 }; 723 724 /** 725 * Set default global debug handler active or inactive. 726 * @param active Active status 727 * @function 728 */ 729 Simplicite.Ajax.prototype.setDebugHandlerActive = function(active) { 730 this._debugActive = active; 731 }; 732 /** 733 * Change default global debug handler. 734 * @param debugHandler Debug handler function 735 * @function 736 */ 737 Simplicite.Ajax.prototype.setDebugHandler = function(debugHandler) { 738 var self = this; 739 self.debug = function(msg) { 740 if (self._debugActive == true) 741 debugHandler.call(this, msg); 742 }; 743 }; 744 745 /** @ignore */ 746 Simplicite.Ajax.prototype._url = function(url) { 747 return this._baseURL + this._approot + (this._gateway == this.GATEWAY_WS ? "ws" : "") + url; 748 }; 749 750 /** 751 * Returns local data URL (e.g. suitable for src of img tags). 752 * @param doc Document 753 * @function 754 */ 755 Simplicite.Ajax.prototype.dataURL = function(doc) { 756 if (doc !== undefined && doc.mime !== undefined && doc.content !== undefined) 757 return "data:" + doc.mime + ";base64," + doc.content; 758 }; 759 760 /** 761 * Returns document URL. 762 * @param object Object name 763 * @param field Field name 764 * @param rowId Object record row ID 765 * @param docId Document ID (can be omitted then a lookup is done on record matching rowId) 766 * @function 767 */ 768 Simplicite.Ajax.prototype.documentURL = function(object, field, rowId, docId) { 769 return this._url(this._documentURL + "?object=" + object + "&field=" + field + "&row_id=" + rowId + (docId !== undefined ? "&doc_id=" + docId : "")); 770 }; 771 772 /** 773 * Returns content URL. 774 * @param file Content file name 775 * @function 776 */ 777 Simplicite.Ajax.prototype.contentURL = function(file) { 778 return this._url(this._contentURL + "?file=" + file); 779 }; 780 781 /** 782 * Returns disposition resource URL. 783 * @param code Resource code 784 * @param type Resource type (IMG=image (default), ICO=Icon, CSS=stylesheet, JS=Javascript, HTML=HTML) 785 * @function 786 */ 787 Simplicite.Ajax.prototype.dispositionResourceURL = function(code, type) { 788 return this._url(this._resourceURL + "?code=" + code + "&type=" + type); 789 }; 790 791 /** 792 * Returns resource URL. 793 * @param id Resource ID (e.g. taken from business object or external object resources list in metadata) 794 * @function 795 */ 796 Simplicite.Ajax.prototype.resourceURL = function(id) { 797 return this._url(this._resourceURL + "?row_id=" + id); 798 }; 799 800 /** @ignore */ 801 Simplicite.Ajax.prototype._callParams = function(data) { 802 var p = ""; 803 if (data === undefined) 804 return p; 805 var n = 0; 806 for (var i in data) { 807 var d = data[i]; 808 if (d === undefined) 809 d = ""; 810 if (d.id !== undefined && d.content !== undefined) // Document ? 811 p += (n++ != 0 ? "&" : "") + i + "=" + encodeURIComponent("id|" + d.id + "|name|" + d.name + "|content|" + d.content); 812 else if (d.object !== undefined && d.row_id !== undefined) // Object ? 813 p += (n++ != 0 ? "&" : "") + i + "=" + encodeURIComponent("object|" + d.object + "|row_id|" + d.row_id); 814 else if (d.sort) { // Array ? 815 if (!d.length) 816 p += (n++ != 0 ? "&" : "") + i + "="; // empty enum multi 817 else 818 for (var j = 0; j < d.length; j++) 819 p += (n++ != 0 ? "&" : "") + i + "=" + encodeURIComponent(d[j]); 820 } else 821 p += (n++ != 0 ? "&" : "") + i + "=" + encodeURIComponent(d); 822 } 823 return p; 824 }; 825 826 /** @ignore */ 827 Simplicite.Ajax.prototype._callAuth = function(login, password) { 828 return "Basic " + this.base64Encode(login + ":" + password); 829 }; 830 831 /** @ignore */ 832 Simplicite.Ajax.prototype._call = function(async, url, params, callback, scope) { 833 try { 834 var self; 835 var xhr = undefined; 836 if (window.XMLHttpRequest) { 837 xhr = new XMLHttpRequest(); 838 } else if (window.ActiveXObject) { 839 try { 840 xhr = new ActiveXObject("Msxml2.XMLHTTP"); 841 } catch (e) { 842 xhr = new ActiveXObject("Microsoft.XMLHTTP"); 843 } 844 } 845 if (xhr === undefined) 846 throw new Exception("Ajax not available"); 847 848 var a = (async === undefined) ? this._async : async; 849 var u = this._url(url); 850 xhr.open("POST", u, a); 851 try { if (a) xhr.withCredentials = true; } catch(ex) {} 852 853 if (this._gateway === this.GATEWAY_API) { 854 if (this.authToken !== undefined) 855 xhr.setRequestHeader("X-Simplicite-Authorization", "Bearer " + this.authToken); 856 else if (this._login !== undefined && this._password !== undefined) 857 xhr.setRequestHeader("X-Simplicite-Authorization", this._callAuth(this._login, this._password)); 858 } else if (this._gateway === this.GATEWAY_WS) { 859 xhr.setRequestHeader("Authorization", this._callAuth(this._login, this._password)); 860 } 861 862 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 863 864 // Encoding must be explicitly set to UTF-8 with XMLHttpRequest posts 865 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); 866 867 if (this._timeout > 0) { 868 self = this; 869 xhr.timeout = this._timeout; 870 xhr.ontimeout = function() { 871 self.error(self.getStandardError(this.LEVEL_ERROR, "The call is in timeout", "Timeout")); 872 } 873 } 874 875 var p = this._callParams(params); 876 this.debug("POST call to URL: " + u + " with params: " + p); 877 xhr.send(p); 878 879 if (a) { 880 self = this; 881 /** @ignore */ 882 xhr.onreadystatechange = function() { 883 self._callResponse(xhr, callback, scope); 884 }; 885 } else { 886 return this._callResponse(xhr, callback, scope); 887 } 888 } catch (e) { 889 this.error(this.getStandardError(this.LEVEL_ERROR, e.message, e.name)); 890 } 891 }; 892 893 /** @ignore */ 894 Simplicite.Ajax.prototype._callError = function(level, message, details) { 895 return { 896 type: "error", 897 response: this.getStandardError(level, message, details) 898 }; 899 }; 900 901 /** @ignore */ 902 Simplicite.Ajax.prototype._callResponse = function(xhr, callback, scope) { 903 if (xhr.readyState == 4) { 904 this.debug("Response: status=" + xhr.status + ", length=" + xhr.responseText.length + " bytes"); 905 var r, res = xhr.responseText; 906 try { 907 if (xhr.status == 200) { 908 if (res.indexOf("j_security_check") > 0) // In case of form based login (TODO : to be improved) 909 throw "HTTP 401"; 910 try { 911 r = JSON.parse(res); 912 } catch(err) { 913 console.log("JSON parsing error for " + res); 914 throw err; 915 } 916 if (callback !== undefined) 917 callback.call(scope !== undefined ? scope : this, r); 918 return r !== undefined && r.type != "error" ? r.response : undefined; 919 } else 920 throw "HTTP " + xhr.status; 921 } catch (e) { 922 if (callback !== undefined) 923 callback.call(scope !== undefined ? scope : this, this._callError(this.LEVEL_ERROR, e, res)); 924 else 925 throw e; 926 } 927 } 928 }; 929 930 /** 931 * Loads application info data. 932 * @param callback Callback function called when loading is completed (loaded application info data is passed to this function) 933 * @param params Optional parameters: 934 * <ul> 935 * <li>async Asynchronous call (use default if absent) ?</li> 936 * <li>error Custom error handler (use default error handler if absent) ?</li> 937 * </ul> 938 * @function 939 */ 940 Simplicite.Ajax.prototype.getAppInfo = function(callback, params) { 941 var self = this; 942 var url = self._appURL + "?action=getinfo"; 943 if (params === undefined) 944 params = new Object(); 945 return self._call(params.async, url, undefined, function(r) { 946 if (r.type == "error") { 947 self.appinfo = new Object(); 948 if (params.error !== undefined) 949 params.error.call(self, r.response); 950 else 951 self.error(r.response); 952 } else { 953 self.appinfo = r.response; 954 if (callback !== undefined) 955 callback.call(this, self.appinfo); 956 } 957 }); 958 }; 959 960 /** 961 * Loads system info data. 962 * @param callback Callback function called when loading is completed (loaded system info data is passed to this function) 963 * @param params Optional parameters: 964 * <ul> 965 * <li>async Asynchronous call (use default if absent) ?</li> 966 * <li>error Custom error handler (use default error handler if absent) ?</li> 967 * </ul> 968 * @function 969 */ 970 Simplicite.Ajax.prototype.getSysInfo = function(callback, params) { 971 var self = this; 972 var url = self._appURL + "?action=getsysinfo"; 973 if (params === undefined) 974 params = new Object(); 975 return self._call(params.async, url, undefined, function(r) { 976 if (r.type == "error") { 977 if (params.error !== undefined) 978 params.error.call(self, r.response); 979 else 980 self.error(r.response); 981 } else { 982 if (callback !== undefined) 983 callback.call(this, r.response); 984 } 985 }); 986 }; 987 988 /** 989 * Loads grant data. 990 * @param callback Callback function called when loading is completed (loaded grant data is passed to this function) 991 * @param params Optional parameters: 992 * <ul> 993 * <li>inlinePicture Inline picture (false if absent or undefined)</li> 994 * <li>async Asynchronous call (use default if absent) ?</li> 995 * <li>error Custom error handler (use default error handler if absent) ?</li> 996 * </ul> 997 * @function 998 */ 999 Simplicite.Ajax.prototype.getGrant = function(callback, params) { 1000 var self = this; 1001 var url = self._appURL + "?action=getgrant"; 1002 if (params === undefined) 1003 params = new Object(); 1004 if (params.inlinePicture !== undefined) 1005 url += "&inline_picture=" + params.inlinePicture; 1006 return self._call(params.async, url, undefined, function(r) { 1007 if (r.type == "error") { 1008 self.grant = new Object(); 1009 if (params.error !== undefined) 1010 params.error.call(self, r.response); 1011 else 1012 self.error(r.response); 1013 } else { 1014 self.grant = r.response; 1015 if (self.grant.picture !== undefined) { 1016 var p = self.grant.picture; 1017 p.getURL = function() { return self.documentURL("User", "usr_image_id", self.grant.userid); }; 1018 p.getThumbnailURL = function() { return self.grant.picture.getURL() + "&thumbnail=true"; }; 1019 p.getDataURL = function() { return self.dataURL(p); }; 1020 } 1021 /** 1022 * Get user ID 1023 * @function 1024 */ 1025 self.grant.getUserID = function() { return this.userid; }; 1026 /** 1027 * Get user login 1028 * @function 1029 */ 1030 self.grant.getLogin = function() { return this.login; }; 1031 /** 1032 * Get user language 1033 * @function 1034 */ 1035 self.grant.getLang = function() { return this.lang; }; 1036 /** 1037 * Get user email 1038 * @function 1039 */ 1040 self.grant.getEmail = function() { return this.email; }; 1041 /** 1042 * Get user first name 1043 * @function 1044 */ 1045 self.grant.getFirstName = function() { return this.firstname; }; 1046 /** 1047 * Get user last name 1048 * @function 1049 */ 1050 self.grant.getLastName = function() { return this.lastname; }; 1051 /** 1052 * Check if user has responsibility on specified group 1053 * @param group Group name 1054 * @function 1055 */ 1056 self.grant.hasResponsibility = function(group) { return this.responsibilities !== undefined && this.responsibilities.indexOf(group) != -1; }; 1057 if (callback !== undefined) 1058 callback.call(this, self.grant); 1059 } 1060 }); 1061 }; 1062 1063 /** 1064 * Loads menu data. 1065 * @param callback Callback function called when loading is completed (loaded menu data is passed to this function) 1066 * @param params Optional parameters: 1067 * <ul> 1068 * <li>async Asynchronous call (use default if absent) ?</li> 1069 * <li>error Custom error handler (use default error handler if absent) ?</li> 1070 * </ul> 1071 * @function 1072 */ 1073 Simplicite.Ajax.prototype.getMenu = function(callback, params) { 1074 var self = this; 1075 var url = self._appURL + "?action=getmenu"; 1076 if (params === undefined) 1077 params = new Object(); 1078 return self._call(params.async, url, undefined, function(r) { 1079 if (r.type == "error") { 1080 self.menu = new Array(); 1081 if (params.error !== undefined) 1082 params.error.call(self, r.response); 1083 else 1084 self.error(r.response); 1085 } else { 1086 self.menu = r.response; 1087 if (callback !== undefined) 1088 callback.call(this, self.menu); 1089 } 1090 }); 1091 }; 1092 1093 /** 1094 * Loads system parameters. 1095 * @param callback Callback function called when loading is completed (loaded system parameters array is passed to this function) 1096 * @param params Optional parameters: 1097 * <ul> 1098 * <li>async Asynchronous call (use default if absent) ?</li> 1099 * <li>error Custom error handler (use default error handler if absent) ?</li> 1100 * </ul> 1101 * @function 1102 */ 1103 Simplicite.Ajax.prototype.getSysParams = function(callback, params) { 1104 var self = this; 1105 var url = self._appURL + "?action=getsysparams"; 1106 if (params === undefined) 1107 params = new Object(); 1108 return self._call(params.async, url, undefined, function(r) { 1109 if (r.type == "error") { 1110 self.sysparams = new Object(); 1111 if (params.error !== undefined) 1112 params.error.call(self, r.response); 1113 else 1114 self.error(r.response); 1115 } else { 1116 self.sysparams = new Object(); 1117 for (var i = 0; i < r.response.length; i++) 1118 self.sysparams[r.response[i].name] = r.response[i].value; 1119 if (callback !== undefined) 1120 callback.call(this, self.sysparams); 1121 } 1122 }); 1123 }; 1124 1125 /** 1126 * Get system parameter value. 1127 * @param name System parameter name 1128 * @param params Optional parameters: 1129 * <ul> 1130 * <li>async Asynchronous call (use default if absent) ?</li> 1131 * <li>error Custom error handler (use default error handler if absent) ?</li> 1132 * </ul> 1133 * @function 1134 */ 1135 Simplicite.Ajax.prototype.getSysParam = function(callback, name, params) { 1136 var self = this; 1137 var url = self._appURL + "?action=getsysparam"; 1138 if (params === undefined) 1139 params = new Object(); 1140 var res = self._call(params.async, url, { name: name }, function(r) { 1141 if (r.type == "error") { 1142 if (params.error !== undefined) 1143 params.error.call(self, r.response); 1144 else 1145 self.error(r.response); 1146 } else { 1147 self.sysparams[name] = r.response.value; 1148 if (callback !== undefined) 1149 callback.call(this, r.response.value); 1150 } 1151 }); 1152 if (res !== undefined && res.value != undefined) return res.value; 1153 }, 1154 1155 /** 1156 * Set a user system parameter. 1157 * @param callback Callback function called when loading is completed (parameter is passed to this function) 1158 * @param name Parameter name 1159 * @param value Parameter value (if undefined parameter is unset) 1160 * @param save Save parameter in user parameters (if undefined parameter is not saved) 1161 * @param params Optional parameters : 1162 * <ul> 1163 * <li>async Asynchronous call (use default if absent) ?</li> 1164 * <li>error Custom error handler (use default error handler if absent) ?</li> 1165 * </ul> 1166 * @function 1167 */ 1168 Simplicite.Ajax.prototype.setSysParam = function(callback, name, value, save, params) { 1169 var self = this; 1170 var url = self._appURL + "?action=setsysparam"; 1171 if (params === undefined) 1172 params = new Object(); 1173 var p = { name: name, save: save !== undefined ? save : false }; 1174 if (value !== undefined) 1175 p.value = value; 1176 var res = self._call(params.async, url, p, function(r) { 1177 if (r.type == "error") { 1178 if (params.error !== undefined) 1179 params.error.call(this, r.response); 1180 else 1181 self.error(r.response); 1182 } else { 1183 self.sysparams[name] = r.response.value; 1184 if (callback !== undefined) 1185 callback.call(this, r.response.value); 1186 } 1187 }, this); 1188 if (res !== undefined && res.value != undefined) return res.value; 1189 }; 1190 1191 /** 1192 * Loads texts. 1193 * @param callback Callback function called when loading is completed (loaded texts array is passed to this function) 1194 * @param params Optional parameters: 1195 * <ul> 1196 * <li>async Asynchronous call (use default if absent) ?</li> 1197 * <li>error Custom error handler (use default error handler if absent) ?</li> 1198 * </ul> 1199 * @function 1200 */ 1201 Simplicite.Ajax.prototype.getTexts = function(callback, params) { 1202 var self = this; 1203 var url = self._appURL + "?data=texts"; 1204 if (params === undefined) 1205 params = new Object(); 1206 return self._call(params.async, url, undefined, function(r) { 1207 if (r.type == "error") { 1208 self.texts = new Object(); 1209 if (params.error !== undefined) 1210 params.error.call(self, r.response); 1211 else 1212 self.error(r.response); 1213 } else { 1214 self.texts = new Object(); 1215 for (var i = 0; i < r.response.length; i++) 1216 self.texts[r.response[i].code] = r.response[i].value; 1217 if (callback !== undefined) 1218 callback.call(this, self.texts); 1219 } 1220 }); 1221 }; 1222 1223 /** 1224 * Get text value. 1225 * @param code Text code 1226 * @function 1227 */ 1228 Simplicite.Ajax.prototype.getText = function(code) { 1229 if (this.texts === undefined) 1230 this.getTexts(undefined, { async: false }); 1231 return this.texts[code]; 1232 }, 1233 1234 /** 1235 * Alias for getText 1236 * @function 1237 */ 1238 Simplicite.Ajax.prototype.T = Simplicite.Ajax.prototype.getText; 1239 1240 /** 1241 * Loads news. 1242 * @param callback Callback function called when loading is completed (loaded news array is passed to this function) 1243 * @param params Optional parameters: 1244 * <ul> 1245 * <li>inlineImages Inline news images (false if absent or undefined)</li> 1246 * <li>async Asynchronous call (use default if absent) ?</li> 1247 * <li>error Custom error handler (use default error handler if absent) ?</li> 1248 * </ul> 1249 * @function 1250 */ 1251 Simplicite.Ajax.prototype.getNews = function(callback, params) { 1252 var self = this; 1253 var url = self._appURL + "?data=news"; 1254 if (params === undefined) 1255 params = new Object(); 1256 if (params.inlineImages !== undefined) 1257 url += "&inline_images=" + params.inlineImages; 1258 return self._call(params.async, url, undefined, function(r) { 1259 if (r.type == "error") { 1260 self.news = new Array(); 1261 if (params.error !== undefined) 1262 params.error.call(self, r.response); 1263 else 1264 self.error(r.response); 1265 } else { 1266 self.news = r.response; 1267 var n = self.news; 1268 n.getTitle = function(i) { return self.news[i].title; }; 1269 n.getDate = function(i) { return self.parseDateTimeValue(self.news[i].date); }; 1270 n.getContent = function(i) { return self.news[i].content; }; 1271 n.getImageURL = function(i) { return self.documentURL("WebNews", "nws_image", self.news[i].id); }; 1272 n.getImageThumbnailURL = function(i) { return self.news.getImageURL(i) + "&thumbnail=true"; }; 1273 n.getImageDataURL = function(i) { return self.dataURL(self.news[i].image); }; 1274 if (callback !== undefined) 1275 callback.call(this, self.news); 1276 } 1277 }); 1278 }; 1279 1280 /** 1281 * Loads external object. 1282 * @param callback Callback function called when loading is completed (loaded external object is passed to this function) 1283 * @param name External object name 1284 * @param params Optional parameters: 1285 * <ul> 1286 * <li>async Asynchronous call (use default if absent) ?</li> 1287 * <li>error Custom error handler (use default error handler if absent) ?</li> 1288 * </ul> 1289 * @function 1290 */ 1291 Simplicite.Ajax.prototype.getExternalObject = function(callback, name, params) { 1292 var self = this; 1293 var url = self._appURL + "?data=extobject&name=" + name; 1294 if (params === undefined) 1295 params = new Object(); 1296 return self._call(params.async, url, undefined, function(r) { 1297 if (r.type == "error") { 1298 if (params.error !== undefined) 1299 params.error.call(self, r.response); 1300 else 1301 self.error(r.response); 1302 } else { 1303 var extobj = r.response; 1304 ; 1305 if (callback !== undefined) 1306 callback.call(self, extobj); 1307 } 1308 }); 1309 }; 1310 1311 /** 1312 * Server side session identifier. 1313 * @field 1314 */ 1315 Simplicite.Ajax.prototype.sessionId = undefined; 1316 1317 /** 1318 * Server side session authentication token. 1319 * @field 1320 */ 1321 Simplicite.Ajax.prototype.authToken = undefined; 1322 1323 /** 1324 * Session init (retrieves server side session identifier). Note that this call is forced to be a synchronous call. 1325 * @param successCallback Callback function called when session init is sucessful 1326 * @param failureCallback Callback function called when session init fails 1327 * @function 1328 */ 1329 Simplicite.Ajax.prototype.session = function(successCallback, failureCallback) { 1330 var self = this; 1331 var url = self._appURL + "?data=session"; 1332 return self._call(true, url, undefined, function(r) { 1333 if (r.type == "error") { 1334 self.sessionId = undefined; 1335 if (failureCallback !== undefined) 1336 failureCallback.call(this, r.response); 1337 else 1338 self.error(r.response); 1339 } else { 1340 self.sessionId = r.response.id; 1341 self.authToken = r.response.authtoken; 1342 if (successCallback !== undefined) 1343 successCallback.call(this, self.sessionId); 1344 } 1345 }); 1346 }; 1347 1348 /** 1349 * Server side login (same as session()). Note that this call is forced to be a synchronous call. 1350 * @param successCallback Callback function called when login is sucessful 1351 * @param failureCallback Callback function called when login fails 1352 * @function 1353 */ 1354 Simplicite.Ajax.prototype.login = function(successCallback, failureCallback) { 1355 this.session(successCallback, failureCallback); 1356 }, 1357 1358 /** 1359 * Server side logout (does not work on some web browsers). Note that this call is forced to be a synchronous call. 1360 * @param successCallback Callback function called when login is sucessful 1361 * @param failureCallback Callback function called when login fails 1362 * @param params Optional parameters: 1363 * <ul> 1364 * <li>async Asynchronous call (use default if absent) ?</li> 1365 * <li>error Custom error handler (use default error handler if absent) ?</li> 1366 * </ul> 1367 * @function 1368 */ 1369 Simplicite.Ajax.prototype.logout = function(successCallback, failureCallback, params) { 1370 var self = this; 1371 var url = self._appURL + "?data=logout"; 1372 return self._call(true, url, undefined, function(r) { 1373 self._approot = "__none__"; 1374 self._gateway = undefined; 1375 self._baseURL = undefined; 1376 self._appURL = undefined; 1377 self._objURL = undefined; 1378 self._pcsURL = undefined; 1379 self._documentURL = undefined; 1380 self._contentURL = undefined; 1381 self._resourceURL = undefined; 1382 self._login = undefined; 1383 self._password = undefined; 1384 self.sessionId = undefined; 1385 self.grant = new Object(); 1386 self.menu = new Array(); 1387 self.sysparams = new Array(); 1388 self.texts = new Array(); 1389 self.news = new Array(); 1390 self._businessObjectsCache = undefined; 1391 if (r.type == "error") { 1392 if (failureCallback !== undefined) 1393 failureCallback.call(this, r.response); 1394 else 1395 self.error(r.response); 1396 } else { 1397 if (successCallback !== undefined) 1398 successCallback.call(this); 1399 } 1400 }); 1401 }; 1402 1403 /** 1404 * Parse a date value into a Javascript Date 1405 * @param v Date value (YYYY-MM-DD) 1406 * @function 1407 */ 1408 Simplicite.Ajax.prototype.parseDateValue = function(v) { 1409 return this.parseDateTimeValue(v + " 00:00:00"); 1410 }; 1411 1412 /** 1413 * Parse a date time value into a Javascript Date 1414 * @param v Date time value (YYYY-MM-DD hh:mm:ss) 1415 * @function 1416 */ 1417 Simplicite.Ajax.prototype.parseDateTimeValue = function(v) { 1418 var yy = parseInt(v.substring(0, 4)), 1419 mm = parseInt(v.substring(5, 7)) - 1, 1420 dd = parseInt(v.substring(8, 10)), 1421 h = parseInt(v.substring(11, 13)), 1422 m = parseInt(v.substring(14, 16)), 1423 s = parseInt(v.substring(17, 19)); 1424 return new Date(yy, mm, dd, h, m, s, 0); 1425 }; 1426 1427 /** 1428 * Parse a Javascript Date into a date value 1429 * @param d Javascript date 1430 * @function 1431 */ 1432 Simplicite.Ajax.prototype.toDateValue = function(d) { 1433 var yy = d.getFullYear(); 1434 var mm = d.getMonth() + 1; 1435 var dd = d.getDate(); 1436 return yy + "-" + (mm < 10 ? "0" : "") + mm + "-" + (dd < 10 ? "0" : "") + dd; 1437 }; 1438 1439 /** 1440 * Parse a Javascript Date into a time value 1441 * @param d Javascript date 1442 * @function 1443 */ 1444 Simplicite.Ajax.prototype.toTimeValue = function(d) { 1445 var h = d.getHours(); 1446 var m = d.getMinutes(); 1447 var s = d.getSeconds(); 1448 return (h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s; 1449 }; 1450 1451 /** 1452 * Parse a Javascript Date into a date time value 1453 * @param d Javascript date 1454 * @function 1455 */ 1456 Simplicite.Ajax.prototype.toDateTimeValue = function(d) { 1457 return this.toDateValue(d) + " " + this.toTimeValue(d); 1458 }; 1459 1460 /** 1461 * Encode a string to base64 1462 * @param s Input string 1463 * @return Base64-encoded string 1464 * @function 1465 */ 1466 Simplicite.Ajax.prototype.base64Encode = function(s) { 1467 if (s === undefined || typeof s != "string" || s.length == 0) return ""; 1468 //if (typeof btoa !== "undefined") return btoa(s); 1469 1470 var o = s.replace(/\r\n/g, "\n"); 1471 var u = ""; 1472 for ( var n = 0; n < o.length; n++) { 1473 var c = o.charCodeAt(n); 1474 if (c < 128) { 1475 u += String.fromCharCode(c); 1476 } else if ((c > 127) && (c < 2048)) { 1477 u += String.fromCharCode((c >> 6) | 192); 1478 u += String.fromCharCode((c & 63) | 128); 1479 } else { 1480 u += String.fromCharCode((c >> 12) | 224); 1481 u += String.fromCharCode(((c >> 6) & 63) | 128); 1482 u += String.fromCharCode((c & 63) | 128); 1483 } 1484 } 1485 1486 o = ""; 1487 var c1, c2, c3 = ""; 1488 var e1, e2, e3, e4 = ""; 1489 var i = 0; 1490 var k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 1491 do { 1492 c1 = u.charCodeAt(i++); 1493 c2 = u.charCodeAt(i++); 1494 c3 = u.charCodeAt(i++); 1495 1496 e1 = c1 >> 2; 1497 e2 = ((c1 & 3) << 4) | (c2 >> 4); 1498 e3 = ((c2 & 15) << 2) | (c3 >> 6); 1499 e4 = c3 & 63; 1500 1501 if (isNaN(c2)) { 1502 e3 = e4 = 64; 1503 } else if (isNaN(c3)) { 1504 e4 = 64; 1505 } 1506 1507 o = o + 1508 k.charAt(e1) + 1509 k.charAt(e2) + 1510 k.charAt(e3) + 1511 k.charAt(e4); 1512 c1 = c2 = c3 = ""; 1513 e1 = e2 = e3 = e4 = ""; 1514 } while (i < u.length); 1515 1516 return o; 1517 }; 1518 1519 1520 /** 1521 * Encode an array buffer (such as got from a local file read) to to base64 1522 * @param b Array buffer 1523 * @return Base64-encoded string 1524 * @function 1525 */ 1526 Simplicite.Ajax.prototype.base64EncodeArrayBuffer = function(b) { 1527 var s = ""; 1528 var bs = new Uint8Array(b); 1529 for (var i = 0; i < bs.byteLength; i++) 1530 s += String.fromCharCode(bs[i]); 1531 return this.base64Encode(s); 1532 }; 1533 1534 /** 1535 * Decode a base64 string to string 1536 * @param s Base64-encoded string 1537 * @return Decoded string 1538 * @function 1539 */ 1540 Simplicite.Ajax.prototype.base64Decode = function(s) { 1541 if (s === undefined || typeof s != "string" || s.length == 0) return ""; 1542 //if (typeof atob !== "undefined") return atob(s); 1543 1544 var o = ""; 1545 var c1, c2, c3 = ""; 1546 var e1, e2, e3, e4 = ""; 1547 var i = 0; 1548 var k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 1549 do { 1550 e1 = k.indexOf(s.charAt(i++)); 1551 e2 = k.indexOf(s.charAt(i++)); 1552 e3 = k.indexOf(s.charAt(i++)); 1553 e4 = k.indexOf(s.charAt(i++)); 1554 1555 c1 = (e1 << 2) | (e2 >> 4); 1556 c2 = ((e2 & 15) << 4) | (e3 >> 2); 1557 c3 = ((e3 & 3) << 6) | e4; 1558 1559 o = o + String.fromCharCode(c1); 1560 1561 if (e3 != 64) { 1562 o = o + String.fromCharCode(c2); 1563 } 1564 if (e4 != 64) { 1565 o = o + String.fromCharCode(c3); 1566 } 1567 1568 c1 = c2 = c3 = ""; 1569 e1 = e2 = e3 = e4 = ""; 1570 1571 } while (i < s.length); 1572 1573 var u = ""; 1574 var i = 0; 1575 var c = c1 = c2 = 0; 1576 while (i < o.length) { 1577 c = o.charCodeAt(i); 1578 if (c < 128) { 1579 u += String.fromCharCode(c); 1580 i++; 1581 } else if ((c > 191) && (c < 224)) { 1582 c2 = o.charCodeAt(i + 1); 1583 u += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 1584 i += 2; 1585 } else { 1586 c2 = o.charCodeAt(i + 1); 1587 c3 = o.charCodeAt(i + 2); 1588 u += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 1589 i += 3; 1590 } 1591 } 1592 return u; 1593 }; 1594 1595 // Backward compatibility... 1596 //SimpliciteAjax = Simplicite.Ajax;