| [ Index ] | PHP Cross Reference of Mambo 4.6.5 |
|
| [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 2 /* file:jscripts/tiny_mce/classes/tinymce.js */ 3 4 var tinymce = { 5 majorVersion : '3', 6 minorVersion : '0', 7 releaseDate : '2008-01-30', 8 9 _init : function() { 10 var t = this, ua = navigator.userAgent, i, nl, n, base; 11 12 // Browser checks 13 t.isOpera = window.opera && opera.buildNumber; 14 t.isWebKit = /WebKit/.test(ua); 15 t.isOldWebKit = t.isWebKit && !window.getSelection().getRangeAt; 16 t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName); 17 t.isIE6 = t.isIE && /MSIE [56]/.test(ua); 18 t.isGecko = !t.isWebKit && /Gecko/.test(ua); 19 // t.isGecko3 = t.isGecko && /(Firefox|Minefield)\/[3-9]/.test(ua); 20 t.isMac = ua.indexOf('Mac') != -1; 21 22 // TinyMCE .NET webcontrol might be setting the values for TinyMCE 23 if (window.tinyMCEPreInit) { 24 t.suffix = tinyMCEPreInit.suffix; 25 t.baseURL = tinyMCEPreInit.base; 26 return; 27 } 28 29 // Get suffix and base 30 t.suffix = ''; 31 32 // If base element found, add that infront of baseURL 33 nl = document.getElementsByTagName('base'); 34 for (i=0; i<nl.length; i++) { 35 if (nl[i].href) 36 base = nl[i].href; 37 } 38 39 function getBase(n) { 40 if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) { 41 if (/_(src|dev)\.js/g.test(n.src)) 42 t.suffix = '_src'; 43 44 t.baseURL = n.src.substring(0, n.src.lastIndexOf('/')); 45 46 // If path to script is relative and a base href was found add that one infront 47 if (base && t.baseURL.indexOf('://') == -1) 48 t.baseURL = base + t.baseURL; 49 50 return t.baseURL; 51 } 52 53 return null; 54 }; 55 56 // Check document 57 nl = document.getElementsByTagName('script'); 58 for (i=0; i<nl.length; i++) { 59 if (getBase(nl[i])) 60 return; 61 } 62 63 // Check head 64 n = document.getElementsByTagName('head')[0]; 65 if (n) { 66 nl = n.getElementsByTagName('script'); 67 for (i=0; i<nl.length; i++) { 68 if (getBase(nl[i])) 69 return; 70 } 71 } 72 73 return; 74 }, 75 76 is : function(o, t) { 77 var n = typeof(o); 78 79 if (!t) 80 return n != 'undefined'; 81 82 if (t == 'array' && (o instanceof Array)) 83 return true; 84 85 return n == t; 86 }, 87 88 // #if !jquery 89 90 each : function(o, cb, s) { 91 var n, l; 92 93 if (!o) 94 return 0; 95 96 s = s || o; 97 98 if (typeof(o.length) != 'undefined') { 99 // Indexed arrays, needed for Safari 100 for (n=0, l = o.length; n<l; n++) { 101 if (cb.call(s, o[n], n, o) === false) 102 return 0; 103 } 104 } else { 105 // Hashtables 106 for (n in o) { 107 if (o.hasOwnProperty(n)) { 108 if (cb.call(s, o[n], n, o) === false) 109 return 0; 110 } 111 } 112 } 113 114 return 1; 115 }, 116 117 map : function(a, f) { 118 var o = []; 119 120 tinymce.each(a, function(v) { 121 o.push(f(v)); 122 }); 123 124 return o; 125 }, 126 127 grep : function(a, f) { 128 var o = []; 129 130 tinymce.each(a, function(v) { 131 if (!f || f(v)) 132 o.push(v); 133 }); 134 135 return o; 136 }, 137 138 inArray : function(a, v) { 139 var i, l; 140 141 if (a) { 142 for (i = 0, l = a.length; i < l; i++) { 143 if (a[i] === v) 144 return i; 145 } 146 } 147 148 return -1; 149 }, 150 151 extend : function(o, e) { 152 var i, a = arguments; 153 154 for (i=1; i<a.length; i++) { 155 e = a[i]; 156 157 tinymce.each(e, function(v, n) { 158 if (typeof(v) !== 'undefined') 159 o[n] = v; 160 }); 161 } 162 163 return o; 164 }, 165 166 trim : function(s) { 167 return (s ? '' + s : '').replace(/^\s*|\s*$/g, ''); 168 }, 169 170 // #endif 171 172 create : function(s, p) { 173 var t = this, sp, ns, cn, scn, c, de = 0; 174 175 // Parse : <prefix> <class>:<super class> 176 s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s); 177 cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name 178 179 // Create namespace for new class 180 ns = t.createNS(s[3].replace(/\.\w+$/, '')); 181 182 // Class already exists 183 if (ns[cn]) 184 return; 185 186 // Make pure static class 187 if (s[2] == 'static') { 188 ns[cn] = p; 189 190 if (this.onCreate) 191 this.onCreate(s[2], s[3], ns[cn]); 192 193 return; 194 } 195 196 // Create default constructor 197 if (!p[cn]) { 198 p[cn] = function() {}; 199 de = 1; 200 } 201 202 // Add constructor and methods 203 ns[cn] = p[cn]; 204 t.extend(ns[cn].prototype, p); 205 206 // Extend 207 if (s[5]) { 208 sp = t.resolve(s[5]).prototype; 209 scn = s[5].match(/\.(\w+)$/i)[1]; // Class name 210 211 // Extend constructor 212 c = ns[cn]; 213 if (de) { 214 // Add passthrough constructor 215 ns[cn] = function() { 216 return sp[scn].apply(this, arguments); 217 }; 218 } else { 219 // Add inherit constructor 220 ns[cn] = function() { 221 this.parent = sp[scn]; 222 return c.apply(this, arguments); 223 }; 224 } 225 ns[cn].prototype[cn] = ns[cn]; 226 227 // Add super methods 228 t.each(sp, function(f, n) { 229 if (n != scn) 230 ns[cn].prototype[n] = sp[n]; 231 }); 232 233 // Add overridden methods 234 t.each(p, function(f, n) { 235 // Extend methods if needed 236 if (sp[n]) { 237 ns[cn].prototype[n] = function() { 238 this.parent = sp[n]; 239 return f.apply(this, arguments); 240 }; 241 } else { 242 if (n != cn) 243 ns[cn].prototype[n] = f; 244 } 245 }); 246 } 247 248 // Add static methods 249 t.each(p['static'], function(f, n) { 250 ns[cn][n] = f; 251 }); 252 253 if (this.onCreate) 254 this.onCreate(s[2], s[3], ns[cn].prototype); 255 }, 256 257 walk : function(o, f, n, s) { 258 s = s || this; 259 260 if (o) { 261 if (n) 262 o = o[n]; 263 264 tinymce.each(o, function(o, i) { 265 if (f.call(s, o, i, n) === false) 266 return false; 267 268 tinymce.walk(o, f, n, s); 269 }); 270 } 271 }, 272 273 createNS : function(n, o) { 274 var i, v; 275 276 o = o || window; 277 278 n = n.split('.'); 279 for (i=0; i<n.length; i++) { 280 v = n[i]; 281 282 if (!o[v]) 283 o[v] = {}; 284 285 o = o[v]; 286 } 287 288 return o; 289 }, 290 291 resolve : function(n, o) { 292 var i, l; 293 294 o = o || window; 295 296 n = n.split('.'); 297 for (i=0, l = n.length; i<l; i++) { 298 o = o[n[i]]; 299 300 if (!o) 301 break; 302 } 303 304 return o; 305 }, 306 307 addUnload : function(f, s) { 308 var t = this, w = window, unload; 309 310 f = {func : f, scope : s || this}; 311 312 if (!t.unloads) { 313 unload = function() { 314 var li = t.unloads, o, n; 315 316 // Call unload handlers 317 for (n in li) { 318 o = li[n]; 319 320 if (o && o.func) 321 o.func.call(o.scope); 322 } 323 324 // Detach unload function 325 if (w.detachEvent) 326 w.detachEvent('onunload', unload); 327 else if (w.removeEventListener) 328 w.removeEventListener('unload', unload, false); 329 330 // Destroy references 331 o = li = w = unload = null; 332 333 // Run garbarge collector on IE 334 if (window.CollectGarbage) 335 window.CollectGarbage(); 336 }; 337 338 // Attach unload handler 339 if (w.attachEvent) 340 w.attachEvent('onunload', unload); 341 else if (w.addEventListener) 342 w.addEventListener('unload', unload, false); 343 344 // Setup initial unload handler array 345 t.unloads = [f]; 346 } else 347 t.unloads.push(f); 348 349 return f; 350 }, 351 352 removeUnload : function(f) { 353 var u = this.unloads, r = null; 354 355 tinymce.each(u, function(o, i) { 356 if (o && o.func == f) { 357 u.splice(i, 1); 358 r = f; 359 return false; 360 } 361 }); 362 363 return r; 364 } 365 366 }; 367 368 // Required for GZip AJAX loading 369 window.tinymce = tinymce; 370 371 // Initialize the API 372 tinymce._init(); 373 374 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */ 375 376 377 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */ 378 379 380 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */ 381 382 tinymce.create('tinymce.util.Dispatcher', { 383 scope : null, 384 listeners : null, 385 386 Dispatcher : function(s) { 387 this.scope = s || this; 388 this.listeners = []; 389 }, 390 391 add : function(cb, s) { 392 this.listeners.push({cb : cb, scope : s || this.scope}); 393 394 return cb; 395 }, 396 397 addToTop : function(cb, s) { 398 this.listeners.unshift({cb : cb, scope : s || this.scope}); 399 400 return cb; 401 }, 402 403 remove : function(cb) { 404 var l = this.listeners, o = null; 405 406 tinymce.each(l, function(c, i) { 407 if (cb == c.cb) { 408 o = cb; 409 l.splice(i, 1); 410 return false; 411 } 412 }); 413 414 return o; 415 }, 416 417 dispatch : function() { 418 var s, a = arguments; 419 420 tinymce.each(this.listeners, function(c) { 421 return s = c.cb.apply(c.scope, a); 422 }); 423 424 return s; 425 } 426 427 }); 428 429 /* file:jscripts/tiny_mce/classes/util/URI.js */ 430 431 (function() { 432 var each = tinymce.each; 433 434 tinymce.create('tinymce.util.URI', { 435 URI : function(u, s) { 436 var t = this, o, a, b; 437 438 // Default settings 439 s = t.settings = s || {}; 440 441 // Strange app protocol or local anchor 442 if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) { 443 t.source = u; 444 return; 445 } 446 447 // Absolute path with no host, fake host and protocol 448 if (u.indexOf('/') === 0 && u.indexOf('//') !== 0) 449 u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u; 450 451 // Relative path 452 if (u.indexOf('://') === -1 && u.indexOf('//') !== 0) 453 u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u); 454 455 // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri) 456 u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something 457 u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u); 458 each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) { 459 var s = u[i]; 460 461 // Zope 3 workaround, they use @@something 462 if (s) 463 s = s.replace(/\(mce_at\)/g, '@@'); 464 465 t[v] = s; 466 }); 467 468 if (b = s.base_uri) { 469 if (!t.protocol) 470 t.protocol = b.protocol; 471 472 if (!t.userInfo) 473 t.userInfo = b.userInfo; 474 475 if (!t.port && t.host == 'mce_host') 476 t.port = b.port; 477 478 if (!t.host || t.host == 'mce_host') 479 t.host = b.host; 480 481 t.source = ''; 482 } 483 484 //t.path = t.path || '/'; 485 }, 486 487 setPath : function(p) { 488 var t = this; 489 490 p = /^(.*?)\/?(\w+)?$/.exec(p); 491 492 // Update path parts 493 t.path = p[0]; 494 t.directory = p[1]; 495 t.file = p[2]; 496 497 // Rebuild source 498 t.source = ''; 499 t.getURI(); 500 }, 501 502 toRelative : function(u) { 503 var t = this, o; 504 505 u = new tinymce.util.URI(u, {base_uri : t}); 506 507 // Not on same domain/port or protocol 508 if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol) 509 return u.getURI(); 510 511 o = t.toRelPath(t.path, u.path); 512 513 // Add query 514 if (u.query) 515 o += '?' + u.query; 516 517 // Add anchor 518 if (u.anchor) 519 o += '#' + u.anchor; 520 521 return o; 522 }, 523 524 toAbsolute : function(u, nh) { 525 var u = new tinymce.util.URI(u, {base_uri : this}); 526 527 return u.getURI(this.host == u.host ? nh : 0); 528 }, 529 530 toRelPath : function(base, path) { 531 var items, bp = 0, out = '', i; 532 533 // Split the paths 534 base = base.substring(0, base.lastIndexOf('/')); 535 base = base.split('/'); 536 items = path.split('/'); 537 538 if (base.length >= items.length) { 539 for (i = 0; i < base.length; i++) { 540 if (i >= items.length || base[i] != items[i]) { 541 bp = i + 1; 542 break; 543 } 544 } 545 } 546 547 if (base.length < items.length) { 548 for (i = 0; i < items.length; i++) { 549 if (i >= base.length || base[i] != items[i]) { 550 bp = i + 1; 551 break; 552 } 553 } 554 } 555 556 if (bp == 1) 557 return path; 558 559 for (i = 0; i < base.length - (bp - 1); i++) 560 out += "../"; 561 562 for (i = bp - 1; i < items.length; i++) { 563 if (i != bp - 1) 564 out += "/" + items[i]; 565 else 566 out += items[i]; 567 } 568 569 return out; 570 }, 571 572 toAbsPath : function(base, path) { 573 var i, nb = 0, o = []; 574 575 // Split paths 576 base = base.split('/'); 577 path = path.split('/'); 578 579 // Remove empty chunks 580 each(base, function(k) { 581 if (k) 582 o.push(k); 583 }); 584 585 base = o; 586 587 // Merge relURLParts chunks 588 for (i = path.length - 1, o = []; i >= 0; i--) { 589 // Ignore empty or . 590 if (path[i].length == 0 || path[i] == ".") 591 continue; 592 593 // Is parent 594 if (path[i] == '..') { 595 nb++; 596 continue; 597 } 598 599 // Move up 600 if (nb > 0) { 601 nb--; 602 continue; 603 } 604 605 o.push(path[i]); 606 } 607 608 i = base.length - nb; 609 610 // If /a/b/c or / 611 if (i <= 0) 612 return '/' + o.reverse().join('/'); 613 614 return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/'); 615 }, 616 617 getURI : function(nh) { 618 var s, t = this; 619 620 // Rebuild source 621 if (!t.source || nh) { 622 s = ''; 623 624 if (!nh) { 625 if (t.protocol) 626 s += t.protocol + '://'; 627 628 if (t.userInfo) 629 s += t.userInfo + '@'; 630 631 if (t.host) 632 s += t.host; 633 634 if (t.port) 635 s += ':' + t.port; 636 } 637 638 if (t.path) 639 s += t.path; 640 641 if (t.query) 642 s += '?' + t.query; 643 644 if (t.anchor) 645 s += '#' + t.anchor; 646 647 t.source = s; 648 } 649 650 return t.source; 651 } 652 653 }); 654 })(); 655 656 /* file:jscripts/tiny_mce/classes/util/Cookie.js */ 657 658 (function() { 659 var each = tinymce.each; 660 661 tinymce.create('static tinymce.util.Cookie', { 662 getHash : function(n) { 663 var v = this.get(n), h; 664 665 if (v) { 666 each(v.split('&'), function(v) { 667 v = v.split('='); 668 h = h || {}; 669 h[unescape(v[0])] = unescape(v[1]); 670 }); 671 } 672 673 return h; 674 }, 675 676 setHash : function(n, v, e, p, d, s) { 677 var o = ''; 678 679 each(v, function(v, k) { 680 o += (!o ? '' : '&') + escape(k) + '=' + escape(v); 681 }); 682 683 this.set(n, o, e, p, d, s); 684 }, 685 686 get : function(n) { 687 var c = document.cookie, e, p = n + "=", b; 688 689 // Strict mode 690 if (!c) 691 return; 692 693 b = c.indexOf("; " + p); 694 695 if (b == -1) { 696 b = c.indexOf(p); 697 698 if (b != 0) 699 return null; 700 } else 701 b += 2; 702 703 e = c.indexOf(";", b); 704 705 if (e == -1) 706 e = c.length; 707 708 return unescape(c.substring(b + p.length, e)); 709 }, 710 711 set : function(n, v, e, p, d, s) { 712 document.cookie = n + "=" + escape(v) + 713 ((e) ? "; expires=" + e.toGMTString() : "") + 714 ((p) ? "; path=" + escape(p) : "") + 715 ((d) ? "; domain=" + d : "") + 716 ((s) ? "; secure" : ""); 717 }, 718 719 remove : function(n, p) { 720 var d = new Date(); 721 722 d.setTime(d.getTime() - 1000); 723 724 this.set(n, '', d, p, d); 725 } 726 727 }); 728 })(); 729 730 /* file:jscripts/tiny_mce/classes/util/JSON.js */ 731 732 tinymce.create('static tinymce.util.JSON', { 733 serialize : function(o) { 734 var i, v, s = tinymce.util.JSON.serialize, t; 735 736 if (o == null) 737 return 'null'; 738 739 t = typeof o; 740 741 if (t == 'string') { 742 v = '\bb\tt\nn\ff\rr\""\'\'\\\\'; 743 744 return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) { 745 i = v.indexOf(b); 746 747 if (i + 1) 748 return '\\' + v.charAt(i + 1); 749 750 a = b.charCodeAt().toString(16); 751 752 return '\\u' + '0000'.substring(a.length) + a; 753 }) + '"'; 754 } 755 756 if (t == 'object') { 757 if (o instanceof Array) { 758 for (i=0, v = '['; i<o.length; i++) 759 v += (i > 0 ? ',' : '') + s(o[i]); 760 761 return v + ']'; 762 } 763 764 v = '{'; 765 766 for (i in o) 767 v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : ''; 768 769 return v + '}'; 770 } 771 772 return '' + o; 773 }, 774 775 parse : function(s) { 776 try { 777 return eval('(' + s + ')'); 778 } catch (ex) { 779 // Ignore 780 } 781 } 782 783 }); 784 785 /* file:jscripts/tiny_mce/classes/util/XHR.js */ 786 787 tinymce.create('static tinymce.util.XHR', { 788 send : function(o) { 789 var x, t, w = window, c = 0; 790 791 // Default settings 792 o.scope = o.scope || this; 793 o.success_scope = o.success_scope || o.scope; 794 o.error_scope = o.error_scope || o.scope; 795 o.async = o.async === false ? false : true; 796 o.data = o.data || ''; 797 798 function get(s) { 799 x = 0; 800 801 try { 802 x = new ActiveXObject(s); 803 } catch (ex) { 804 } 805 806 return x; 807 }; 808 809 x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP'); 810 811 if (x) { 812 if (x.overrideMimeType) 813 x.overrideMimeType(o.content_type); 814 815 x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async); 816 817 if (o.content_type) 818 x.setRequestHeader('Content-Type', o.content_type); 819 820 x.send(o.data); 821 822 // Wait for response, onReadyStateChange can not be used since it leaks memory in IE 823 t = w.setInterval(function() { 824 if (x.readyState == 4 || c++ > 10000) { 825 w.clearInterval(t); 826 827 if (o.success && c < 10000 && x.status == 200) 828 o.success.call(o.success_scope, '' + x.responseText, x, o); 829 else if (o.error) 830 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o); 831 832 x = null; 833 } 834 }, 10); 835 } 836 837 } 838 }); 839 840 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */ 841 842 (function() { 843 var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR; 844 845 tinymce.create('tinymce.util.JSONRequest', { 846 JSONRequest : function(s) { 847 this.settings = extend({ 848 }, s); 849 this.count = 0; 850 }, 851 852 send : function(o) { 853 var ecb = o.error, scb = o.success; 854 855 o = extend(this.settings, o); 856 857 o.success = function(c, x) { 858 c = JSON.parse(c); 859 860 if (typeof(c) == 'undefined') { 861 c = { 862 error : 'JSON Parse error.' 863 }; 864 } 865 866 if (c.error) 867 ecb.call(o.error_scope || o.scope, c.error, x); 868 else 869 scb.call(o.success_scope || o.scope, c.result); 870 }; 871 872 o.error = function(ty, x) { 873 ecb.call(o.error_scope || o.scope, ty, x); 874 }; 875 876 o.data = JSON.serialize({ 877 id : o.id || 'c' + (this.count++), 878 method : o.method, 879 params : o.params 880 }); 881 882 XHR.send(o); 883 }, 884 885 'static' : { 886 sendRPC : function(o) { 887 return new tinymce.util.JSONRequest().send(o); 888 } 889 } 890 891 }); 892 }()); 893 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */ 894 895 (function() { 896 // Shorten names 897 var each = tinymce.each, is = tinymce.is; 898 var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE; 899 900 tinymce.create('tinymce.dom.DOMUtils', { 901 doc : null, 902 root : null, 903 files : null, 904 listeners : {}, 905 pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/, 906 cache : {}, 907 idPattern : /^#[\w]+$/, 908 elmPattern : /^[\w_*]+$/, 909 elmClassPattern : /^([\w_]*)\.([\w_]+)$/, 910 911 DOMUtils : function(d, s) { 912 var t = this; 913 914 t.doc = d; 915 t.files = {}; 916 t.cssFlicker = false; 917 t.counter = 0; 918 t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 919 920 this.settings = s = tinymce.extend({ 921 keep_values : false, 922 hex_colors : 1, 923 process_html : 1 924 }, s); 925 926 // Fix IE6SP2 flicker and check it failed for pre SP2 927 if (tinymce.isIE6) { 928 try { 929 d.execCommand('BackgroundImageCache', false, true); 930 } catch (e) { 931 t.cssFlicker = true; 932 } 933 } 934 935 tinymce.addUnload(function() { 936 t.doc = t.root = null; 937 }); 938 }, 939 940 getRoot : function() { 941 var t = this, s = t.settings; 942 943 return (s && t.get(s.root_element)) || t.doc.body; 944 }, 945 946 getViewPort : function(w) { 947 var d, b; 948 949 w = !w ? window : w; 950 d = w.document; 951 b = this.boxModel ? d.documentElement : d.body; 952 953 // Returns viewport size excluding scrollbars 954 return { 955 x : w.pageXOffset || b.scrollLeft, 956 y : w.pageYOffset || b.scrollTop, 957 w : w.innerWidth || b.clientWidth, 958 h : w.innerHeight || b.clientHeight 959 }; 960 }, 961 962 getRect : function(e) { 963 var p, t = this, w, h; 964 965 e = t.get(e); 966 p = t.getPos(e); 967 w = t.getStyle(e, 'width'); 968 h = t.getStyle(e, 'height'); 969 970 // Non pixel value, then force offset/clientWidth 971 if (w.indexOf('px') === -1) 972 w = 0; 973 974 // Non pixel value, then force offset/clientWidth 975 if (h.indexOf('px') === -1) 976 h = 0; 977 978 return { 979 x : p.x, 980 y : p.y, 981 w : parseInt(w) || e.offsetWidth || e.clientWidth, 982 h : parseInt(h) || e.offsetHeight || e.clientHeight 983 }; 984 }, 985 986 getParent : function(n, f, r) { 987 var na, se = this.settings; 988 989 n = this.get(n); 990 991 if (se.strict_root) 992 r = r || this.getRoot(); 993 994 // Wrap node name as func 995 if (is(f, 'string')) { 996 na = f.toUpperCase(); 997 998 f = function(n) { 999 var s = false; 1000 1001 // Any element 1002 if (n.nodeType == 1 && na === '*') { 1003 s = true; 1004 return false; 1005 } 1006 1007 each(na.split(','), function(v) { 1008 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName == v)) { 1009 s = true; 1010 return false; // Break loop 1011 } 1012 }); 1013 1014 return s; 1015 }; 1016 } 1017 1018 while (n) { 1019 if (n == r) 1020 return null; 1021 1022 if (f(n)) 1023 return n; 1024 1025 n = n.parentNode; 1026 } 1027 1028 return null; 1029 }, 1030 1031 get : function(e) { 1032 if (typeof(e) == 'string') 1033 return this.doc.getElementById(e); 1034 1035 return e; 1036 }, 1037 1038 // #if !jquery 1039 1040 select : function(pa, s) { 1041 var t = this, cs, c, pl, o = [], x, i, l, n; 1042 1043 s = t.get(s) || t.doc; 1044 1045 if (t.settings.strict) { 1046 function get(s, n) { 1047 return s.getElementsByTagName(n.toLowerCase()); 1048 }; 1049 } else { 1050 function get(s, n) { 1051 return s.getElementsByTagName(n); 1052 }; 1053 } 1054 1055 // Simple element pattern. For example: "p" or "*" 1056 if (t.elmPattern.test(pa)) { 1057 x = get(s, pa); 1058 1059 for (i = 0, l = x.length; i<l; i++) 1060 o.push(x[i]); 1061 1062 return o; 1063 } 1064 1065 // Simple class pattern. For example: "p.class" or ".class" 1066 if (t.elmClassPattern.test(pa)) { 1067 pl = t.elmClassPattern.exec(pa); 1068 x = get(s, pl[1] || '*'); 1069 c = ' ' + pl[2] + ' '; 1070 1071 for (i = 0, l = x.length; i<l; i++) { 1072 n = x[i]; 1073 1074 if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1) 1075 o.push(n); 1076 } 1077 1078 return o; 1079 } 1080 1081 function collect(n) { 1082 if (!n.mce_save) { 1083 n.mce_save = 1; 1084 o.push(n); 1085 } 1086 }; 1087 1088 function collectIE(n) { 1089 if (!n.getAttribute('mce_save')) { 1090 n.setAttribute('mce_save', '1'); 1091 o.push(n); 1092 } 1093 }; 1094 1095 function find(n, f, r) { 1096 var i, l, nl = get(r, n); 1097 1098 for (i = 0, l = nl.length; i < l; i++) 1099 f(nl[i]); 1100 }; 1101 1102 each(pa.split(','), function(v, i) { 1103 v = tinymce.trim(v); 1104 1105 // Simple element pattern, most common in TinyMCE 1106 if (t.elmPattern.test(v)) { 1107 each(get(s, v), function(n) { 1108 collect(n); 1109 }); 1110 1111 return; 1112 } 1113 1114 // Simple element pattern with class, fairly common in TinyMCE 1115 if (t.elmClassPattern.test(v)) { 1116 x = t.elmClassPattern.exec(v); 1117 1118 each(get(s, x[1]), function(n) { 1119 if (t.hasClass(n, x[2])) 1120 collect(n); 1121 }); 1122 1123 return; 1124 } 1125 1126 if (!(cs = t.cache[pa])) { 1127 cs = 'x=(function(cf, s) {'; 1128 pl = v.split(' '); 1129 1130 each(pl, function(v) { 1131 var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v); 1132 1133 // Find elements 1134 p[1] = p[1] || '*'; 1135 cs += 'find("' + p[1] + '", function(n) {'; 1136 1137 // Check id 1138 if (p[2]) 1139 cs += 'if (n.id !== "' + p[2] + '") return;'; 1140 1141 // Check classes 1142 if (p[3]) { 1143 cs += 'var c = " " + n.className + " ";'; 1144 cs += 'if ('; 1145 c = ''; 1146 each(p[3].split('.'), function(v) { 1147 if (v) 1148 c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1'; 1149 }); 1150 cs += c + ') return;'; 1151 } 1152 }); 1153 1154 cs += 'cf(n);'; 1155 1156 for (i = pl.length - 1; i >= 0; i--) 1157 cs += '}, ' + (i ? 'n' : 's') + ');'; 1158 1159 cs += '})'; 1160 1161 // Compile CSS pattern function 1162 t.cache[pa] = cs = eval(cs); 1163 } 1164 1165 // Run selector function 1166 cs(isIE ? collectIE : collect, s); 1167 }); 1168 1169 // Cleanup 1170 each(o, function(n) { 1171 if (isIE) 1172 n.removeAttribute('mce_save'); 1173 else 1174 delete n.mce_save; 1175 }); 1176 1177 return o; 1178 }, 1179 1180 // #endif 1181 1182 add : function(p, n, a, h, c) { 1183 var t = this; 1184 1185 return this.run(p, function(p) { 1186 var e, k; 1187 1188 e = is(n, 'string') ? t.doc.createElement(n) : n; 1189 1190 if (a) { 1191 for (k in a) { 1192 if (a.hasOwnProperty(k) && !is(a[k], 'object')) 1193 t.setAttrib(e, k, '' + a[k]); 1194 } 1195 1196 if (a.style && !is(a.style, 'string')) { 1197 each(a.style, function(v, n) { 1198 t.setStyle(e, n, v); 1199 }); 1200 } 1201 } 1202 1203 if (h) { 1204 if (h.nodeType) 1205 e.appendChild(h); 1206 else 1207 t.setHTML(e, h); 1208 } 1209 1210 return !c ? p.appendChild(e) : e; 1211 }); 1212 }, 1213 1214 create : function(n, a, h) { 1215 return this.add(this.doc.createElement(n), n, a, h, 1); 1216 }, 1217 1218 createHTML : function(n, a, h) { 1219 var o = '', t = this, k; 1220 1221 o += '<' + n; 1222 1223 for (k in a) { 1224 if (a.hasOwnProperty(k)) 1225 o += ' ' + k + '="' + t.encode(a[k]) + '"'; 1226 } 1227 1228 if (tinymce.is(h)) 1229 return o + '>' + h + '</' + n + '>'; 1230 1231 return o + ' />'; 1232 }, 1233 1234 remove : function(n, k) { 1235 return this.run(n, function(n) { 1236 var p; 1237 1238 p = n.parentNode; 1239 1240 if (!p) 1241 return null; 1242 1243 if (k) { 1244 each (n.childNodes, function(c) { 1245 p.insertBefore(c.cloneNode(true), n); 1246 }); 1247 } 1248 1249 return p.removeChild(n); 1250 }); 1251 }, 1252 1253 // #if !jquery 1254 1255 setStyle : function(n, na, v) { 1256 var t = this; 1257 1258 return t.run(n, function(e) { 1259 var s, i; 1260 1261 s = e.style; 1262 1263 // Camelcase it, if needed 1264 na = na.replace(/-(\D)/g, function(a, b){ 1265 return b.toUpperCase(); 1266 }); 1267 1268 // Default px suffix on these 1269 if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v))) 1270 v += 'px'; 1271 1272 switch (na) { 1273 case 'opacity': 1274 // IE specific opacity 1275 if (isIE) { 1276 s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")"; 1277 1278 if (!n.currentStyle || !n.currentStyle.hasLayout) 1279 s.display = 'inline-block'; 1280 } 1281 1282 // Fix for older browsers 1283 s['-moz-opacity'] = s['-khtml-opacity'] = v; 1284 break; 1285 1286 case 'float': 1287 isIE ? s.styleFloat = v : s.cssFloat = v; 1288 break; 1289 } 1290 1291 s[na] = v || ''; 1292 1293 // Force update of the style data 1294 if (t.settings.update_styles) 1295 t.setAttrib(e, 'mce_style'); 1296 }); 1297 }, 1298 1299 getStyle : function(n, na, c) { 1300 n = this.get(n); 1301 1302 if (!n) 1303 return false; 1304 1305 // Gecko 1306 if (this.doc.defaultView && c) { 1307 // Remove camelcase 1308 na = na.replace(/[A-Z]/g, function(a){ 1309 return '-' + a; 1310 }); 1311 1312 try { 1313 return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na); 1314 } catch (ex) { 1315 // Old safari might fail 1316 return null; 1317 } 1318 } 1319 1320 // Camelcase it, if needed 1321 na = na.replace(/-(\D)/g, function(a, b){ 1322 return b.toUpperCase(); 1323 }); 1324 1325 if (na == 'float') 1326 na = isIE ? 'styleFloat' : 'cssFloat'; 1327 1328 // IE & Opera 1329 if (n.currentStyle && c) 1330 return n.currentStyle[na]; 1331 1332 return n.style[na]; 1333 }, 1334 1335 setStyles : function(e, o) { 1336 var t = this, s = t.settings, ol; 1337 1338 ol = s.update_styles; 1339 s.update_styles = 0; 1340 1341 each(o, function(v, n) { 1342 t.setStyle(e, n, v); 1343 }); 1344 1345 // Update style info 1346 s.update_styles = ol; 1347 if (s.update_styles) 1348 t.setAttrib(e, s.cssText); 1349 }, 1350 1351 setAttrib : function(e, n, v) { 1352 var t = this; 1353 1354 // Strict XML mode 1355 if (t.settings.strict) 1356 n = n.toLowerCase(); 1357 1358 return this.run(e, function(e) { 1359 var s = t.settings; 1360 1361 switch (n) { 1362 case "style": 1363 if (s.keep_values) { 1364 if (v) 1365 e.setAttribute('mce_style', v, 2); 1366 else 1367 e.removeAttribute('mce_style', 2); 1368 } 1369 1370 e.style.cssText = v; 1371 break; 1372 1373 case "class": 1374 e.className = v; 1375 break; 1376 1377 case "src": 1378 case "href": 1379 if (s.keep_values) { 1380 if (s.url_converter) 1381 v = s.url_converter.call(s.url_converter_scope || t, v, n, e); 1382 1383 t.setAttrib(e, 'mce_' + n, v, 2); 1384 } 1385 1386 break; 1387 } 1388 1389 if (is(v) && v !== null && v.length !== 0) 1390 e.setAttribute(n, '' + v, 2); 1391 else 1392 e.removeAttribute(n, 2); 1393 }); 1394 }, 1395 1396 setAttribs : function(e, o) { 1397 var t = this; 1398 1399 return this.run(e, function(e) { 1400 each(o, function(v, n) { 1401 t.setAttrib(e, n, v); 1402 }); 1403 }); 1404 }, 1405 1406 // #endif 1407 1408 getAttrib : function(e, n, dv) { 1409 var v, t = this; 1410 1411 e = t.get(e); 1412 1413 if (!e) 1414 return false; 1415 1416 if (!is(dv)) 1417 dv = ""; 1418 1419 // Try the mce variant for these 1420 if (/^(src|href|style|coords)$/.test(n)) { 1421 v = e.getAttribute("mce_" + n); 1422 1423 if (v) 1424 return v; 1425 } 1426 1427 v = e.getAttribute(n, 2); 1428 1429 if (!v) { 1430 switch (n) { 1431 case 'class': 1432 v = e.className; 1433 break; 1434 1435 default: 1436 v = e.attributes[n]; 1437 v = v && is(v.nodeValue) ? v.nodeValue : v; 1438 } 1439 } 1440 1441 switch (n) { 1442 case 'style': 1443 v = v || e.style.cssText; 1444 1445 if (v) { 1446 v = t.serializeStyle(t.parseStyle(v)); 1447 1448 if (t.settings.keep_values) 1449 e.setAttribute('mce_style', v); 1450 } 1451 1452 break; 1453 } 1454 1455 // Remove Apple and WebKit stuff 1456 if (isWebKit && n === "class" && v) 1457 v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, ''); 1458 1459 // Handle IE issues 1460 if (isIE) { 1461 switch (n) { 1462 case 'rowspan': 1463 case 'colspan': 1464 // IE returns 1 as default value 1465 if (v === 1) 1466 v = ''; 1467 1468 break; 1469 1470 case 'size': 1471 // IE returns +0 as default value for size 1472 if (v === '+0') 1473 v = ''; 1474 1475 break; 1476 1477 case 'hspace': 1478 // IE returns -1 as default value 1479 if (v === -1) 1480 v = ''; 1481 1482 break; 1483 1484 case 'tabindex': 1485 // IE returns 32768 as default value 1486 if (v === 32768) 1487 v = ''; 1488 1489 break; 1490 1491 case 'shape': 1492 v = v.toLowerCase(); 1493 break; 1494 1495 default: 1496 // IE has odd anonymous function for event attributes 1497 if (n.indexOf('on') === 0 && v) 1498 v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1'); 1499 } 1500 } 1501 1502 return (v && v != '') ? '' + v : dv; 1503 }, 1504 1505 getPos : function(n) { 1506 var t = this, x = 0, y = 0, e, d = t.doc, r; 1507 1508 n = t.get(n); 1509 1510 // Use getBoundingClientRect on IE, Opera has it but it's not perfect 1511 if (n && isIE) { 1512 n = n.getBoundingClientRect(); 1513 e = t.boxModel ? d.documentElement : d.body; 1514 x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border 1515 x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x; 1516 n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset 1517 1518 return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x}; 1519 } 1520 1521 r = n; 1522 while (r) { 1523 x += r.offsetLeft || 0; 1524 y += r.offsetTop || 0; 1525 1526 r = r.offsetParent; 1527 } 1528 1529 r = n; 1530 while (r) { 1531 x -= r.scrollLeft || 0; 1532 y -= r.scrollTop || 0; 1533 1534 r = r.parentNode; 1535 1536 if (r == d.body) 1537 break; 1538 } 1539 1540 return {x : x, y : y}; 1541 }, 1542 1543 parseStyle : function(st) { 1544 var t = this, s = t.settings, o = {}; 1545 1546 if (!st) 1547 return o; 1548 1549 function compress(p, s, ot) { 1550 var t, r, b, l; 1551 1552 // Get values and check it it needs compressing 1553 t = o[p + '-top' + s]; 1554 if (!t) 1555 return; 1556 1557 r = o[p + '-right' + s]; 1558 if (t != r) 1559 return; 1560 1561 b = o[p + '-bottom' + s]; 1562 if (r != b) 1563 return; 1564 1565 l = o[p + '-left' + s]; 1566 if (b != l) 1567 return; 1568 1569 // Compress 1570 o[ot] = l; 1571 delete o[p + '-top' + s]; 1572 delete o[p + '-right' + s]; 1573 delete o[p + '-bottom' + s]; 1574 delete o[p + '-left' + s]; 1575 }; 1576 1577 function compress2(ta, a, b, c) { 1578 var t; 1579 1580 t = o[a]; 1581 if (!t) 1582 return; 1583 1584 t = o[b]; 1585 if (!t) 1586 return; 1587 1588 t = o[c]; 1589 if (!t) 1590 return; 1591 1592 // Compress 1593 o[ta] = o[a] + ' ' + o[b] + ' ' + o[c]; 1594 delete o[a]; 1595 delete o[b]; 1596 delete o[c]; 1597 }; 1598 1599 each(st.split(';'), function(v) { 1600 var sv, ur = []; 1601 1602 if (v) { 1603 v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';}); 1604 v = v.split(':'); 1605 sv = tinymce.trim(v[1]); 1606 sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];}); 1607 1608 sv = sv.replace(/rgb\([^\)]+\)/g, function(v) { 1609 return t.toHex(v); 1610 }); 1611 1612 if (s.url_converter) { 1613 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) { 1614 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null)) + ')'; 1615 }); 1616 } 1617 1618 o[tinymce.trim(v[0]).toLowerCase()] = sv; 1619 } 1620 }); 1621 1622 compress("border", "", "border"); 1623 compress("border", "-width", "border-width"); 1624 compress("border", "-color", "border-color"); 1625 compress("border", "-style", "border-style"); 1626 compress("padding", "", "padding"); 1627 compress("margin", "", "margin"); 1628 compress2('border', 'border-width', 'border-style', 'border-color'); 1629 1630 if (isIE) { 1631 // Remove pointless border 1632 if (o.border == 'medium none') 1633 o.border = ''; 1634 } 1635 1636 return o; 1637 }, 1638 1639 serializeStyle : function(o) { 1640 var s = ''; 1641 1642 each(o, function(v, k) { 1643 if (k && v) { 1644 switch (k) { 1645 case 'color': 1646 case 'background-color': 1647 v = v.toLowerCase(); 1648 break; 1649 } 1650 1651 s += (s ? ' ' : '') + k + ': ' + v + ';'; 1652 } 1653 }); 1654 1655 return s; 1656 }, 1657 1658 loadCSS : function(u) { 1659 var t = this, d = this.doc; 1660 1661 if (!u) 1662 u = ''; 1663 1664 each(u.split(','), function(u) { 1665 if (t.files[u]) 1666 return; 1667 1668 t.files[u] = true; 1669 1670 if (!d.createStyleSheet) 1671 t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : u}); 1672 else 1673 d.createStyleSheet(u); 1674 }); 1675 }, 1676 1677 // #if !jquery 1678 1679 addClass : function(e, c) { 1680 return this.run(e, function(e) { 1681 var o; 1682 1683 if (!c) 1684 return 0; 1685 1686 if (this.hasClass(e, c)) 1687 return e.className; 1688 1689 o = this.removeClass(e, c); 1690 1691 return e.className = (o != '' ? (o + ' ') : '') + c; 1692 }); 1693 }, 1694 1695 removeClass : function(e, c) { 1696 var t = this, re; 1697 1698 return t.run(e, function(e) { 1699 var v; 1700 1701 if (t.hasClass(e, c)) { 1702 if (!re) 1703 re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g"); 1704 1705 v = e.className.replace(re, ' '); 1706 1707 return e.className = tinymce.trim(v != ' ' ? v : ''); 1708 } 1709 1710 return e.className; 1711 }); 1712 }, 1713 1714 hasClass : function(n, c) { 1715 n = this.get(n); 1716 1717 if (!n || !c) 1718 return false; 1719 1720 return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1; 1721 }, 1722 1723 show : function(e) { 1724 return this.setStyle(e, 'display', 'block'); 1725 }, 1726 1727 hide : function(e) { 1728 return this.setStyle(e, 'display', 'none'); 1729 }, 1730 1731 isHidden : function(e) { 1732 e = this.get(e); 1733 1734 return e.style.display == 'none' || this.getStyle(e, 'display') == 'none'; 1735 }, 1736 1737 // #endif 1738 1739 uniqueId : function(p) { 1740 return (!p ? 'mce_' : p) + (this.counter++); 1741 }, 1742 1743 setHTML : function(e, h) { 1744 var t = this; 1745 1746 return this.run(e, function(e) { 1747 var x; 1748 1749 h = t.processHTML(h); 1750 1751 if (isIE) { 1752 try { 1753 // IE will remove comments from the beginning 1754 // unless you padd the contents with something 1755 e.innerHTML = '<br />' + h; 1756 e.removeChild(e.firstChild); 1757 } catch (ex) { 1758 // IE sometimes produces an unknown runtime error on innerHTML 1759 // This seems to fix this issue, don't know why. 1760 x = t.create('div'); 1761 x.innerHTML = '<br />' + h; 1762 1763 each (x.childNodes, function(n, i) { 1764 // Skip the BR 1765 if (i > 1) 1766 e.appendChild(n); 1767 }); 1768 } 1769 } else 1770 e.innerHTML = h; 1771 1772 return h; 1773 }); 1774 }, 1775 1776 processHTML : function(h) { 1777 var t = this, s = t.settings; 1778 1779 if (!s.process_html) 1780 return h; 1781 1782 // Convert strong and em to b and i in FF since it can't handle them 1783 if (tinymce.isGecko) { 1784 h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>'); 1785 h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>'); 1786 } 1787 1788 // Fix some issues 1789 h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open 1790 1791 // Store away src and href in mce_src and mce_href since browsers mess them up 1792 if (s.keep_values) { 1793 // Wrap scripts in comments for serialization purposes 1794 if (h.indexOf('<script') !== -1) { 1795 h = h.replace(/<script>/g, '<script type="text/javascript">'); 1796 h = h.replace(/<script(|[^>]+)>(\s*<!--|\/\/\s*<\[CDATA\[)?[\r\n]*/g, '<mce:script$1><!--\n'); 1797 h = h.replace(/\s*(\/\/\s*-->|\/\/\s*]]>)?<\/script>/g, '\n// --></mce:script>'); 1798 h = h.replace(/<mce:script(|[^>]+)><!--\n\/\/ --><\/mce:script>/g, '<mce:script$1></mce:script>'); 1799 } 1800 1801 // Process all tags with src, href or style 1802 h = h.replace(/<([\w:]+) [^>]*(src|href|style|coords)[^>]*>/gi, function(a, n) { 1803 function handle(m, b, c) { 1804 var u = c; 1805 1806 // Tag already got a mce_ version 1807 if (a.indexOf('mce_' + b) != -1) 1808 return m; 1809 1810 if (b == 'style') { 1811 // Why did I need this one? 1812 //if (isIE) 1813 // u = t.serializeStyle(t.parseStyle(u)); 1814 1815 if (s.hex_colors) { 1816 u = u.replace(/rgb\([^\)]+\)/g, function(v) { 1817 return t.toHex(v); 1818 }); 1819 } 1820 1821 if (s.url_converter) { 1822 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) { 1823 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')'; 1824 }); 1825 } 1826 } else if (b != 'coords') { 1827 if (s.url_converter) 1828 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)); 1829 } 1830 1831 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"'; 1832 }; 1833 1834 a = a.replace(/ (src|href|style|coords)=[\"]([^\"]+)[\"]/gi, handle); // W3C 1835 a = a.replace(/ (src|href|style|coords)=[\']([^\']+)[\']/gi, handle); // W3C 1836 1837 return a.replace(/ (src|href|style|coords)=([^\s\"\'>]+)/gi, handle); // IE 1838 }); 1839 } 1840 1841 return h; 1842 }, 1843 1844 getOuterHTML : function(e) { 1845 var d; 1846 1847 e = this.get(e); 1848 1849 if (!e) 1850 return null; 1851 1852 if (isIE) 1853 return e.outerHTML; 1854 1855 d = (e.ownerDocument || this.doc).createElement("body"); 1856 d.appendChild(e.cloneNode(true)); 1857 1858 return d.innerHTML; 1859 }, 1860 1861 setOuterHTML : function(e, h, d) { 1862 var t = this; 1863 1864 return this.run(e, function(e) { 1865 var n, tp; 1866 1867 e = t.get(e); 1868 d = d || e.ownerDocument || t.doc; 1869 1870 if (isIE && e.nodeType == 1) 1871 e.outerHTML = h; 1872 else { 1873 tp = d.createElement("body"); 1874 tp.innerHTML = h; 1875 1876 n = tp.lastChild; 1877 while (n) { 1878 t.insertAfter(n.cloneNode(true), e); 1879 n = n.previousSibling; 1880 } 1881 1882 t.remove(e); 1883 } 1884 }); 1885 }, 1886 1887 decode : function(s) { 1888 var e = document.createElement("div"); 1889 1890 e.innerHTML = s; 1891 1892 return !e.firstChild ? s : e.firstChild.nodeValue; 1893 }, 1894 1895 encode : function(s) { 1896 return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) { 1897 switch (c) { 1898 case '&': 1899 return '&'; 1900 1901 case '"': 1902 return '"'; 1903 1904 case '<': 1905 return '<'; 1906 1907 case '>': 1908 return '>'; 1909 } 1910 1911 return c; 1912 }) : s; 1913 }, 1914 1915 // #if !jquery 1916 1917 insertAfter : function(n, r) { 1918 var t = this; 1919 1920 r = t.get(r); 1921 1922 return this.run(n, function(n) { 1923 var p, ns; 1924 1925 p = r.parentNode; 1926 ns = r.nextSibling; 1927 1928 if (ns) 1929 p.insertBefore(n, ns); 1930 else 1931 p.appendChild(n); 1932 1933 return n; 1934 }); 1935 }, 1936 1937 // #endif 1938 1939 isBlock : function(n) { 1940 if (n.nodeType && n.nodeType !== 1) 1941 return false; 1942 1943 n = n.nodeName || n; 1944 1945 return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n); 1946 }, 1947 1948 // #if !jquery 1949 1950 replace : function(n, o, k) { 1951 if (is(o, 'array')) 1952 n = n.cloneNode(true); 1953 1954 return this.run(o, function(o) { 1955 if (k) { 1956 each(o.childNodes, function(c) { 1957 n.appendChild(c.cloneNode(true)); 1958 }); 1959 } 1960 1961 return o.parentNode.replaceChild(n, o); 1962 }); 1963 }, 1964 1965 // #endif 1966 1967 toHex : function(s) { 1968 var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s); 1969 1970 function hex(s) { 1971 s = parseInt(s).toString(16); 1972 1973 return s.length > 1 ? s : '0' + s; // 0 -> 00 1974 }; 1975 1976 if (c) { 1977 s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]); 1978 1979 return s; 1980 } 1981 1982 return s; 1983 }, 1984 1985 getClasses : function() { 1986 var t = this, cl = [], i, lo = {}, f = t.settings.class_filter; 1987 1988 if (t.classes) 1989 return t.classes; 1990 1991 function addClasses(s) { 1992 // IE style imports 1993 each(s.imports, function(r) { 1994 addClasses(r); 1995 }); 1996 1997 each(s.cssRules || s.rules, function(r) { 1998 // Real type or fake it on IE 1999 switch (r.type || 1) { 2000 // Rule 2001 case 1: 2002 if (r.selectorText) { 2003 each(r.selectorText.split(','), function(v) { 2004 v = v.replace(/^\s*|\s*$|^\s\./g, ""); 2005 2006 if (f && !(v = f(v))) 2007 return; 2008 2009 if (/^\.mce/.test(v) || !/^\.[\w\-]+$/.test(v)) 2010 return; 2011 2012 v = v.substring(1); 2013 if (!lo[v]) { 2014 cl.push({'class' : v}); 2015 lo[v] = 1; 2016 } 2017 }); 2018 } 2019 break; 2020 2021 // Import 2022 case 3: 2023 addClasses(r.styleSheet); 2024 break; 2025 } 2026 }); 2027 }; 2028 2029 try { 2030 each(t.doc.styleSheets, addClasses); 2031 } catch (ex) { 2032 // Ignore 2033 } 2034 2035 if (cl.length > 0) 2036 t.classes = cl; 2037 2038 return cl; 2039 }, 2040 2041 run : function(e, f, s) { 2042 var t = this, o; 2043 2044 if (typeof(e) === 'string') 2045 e = t.doc.getElementById(e); 2046 2047 if (!e) 2048 return false; 2049 2050 s = s || this; 2051 if (!e.nodeType && (e.length || e.length === 0)) { 2052 o = []; 2053 2054 each(e, function(e, i) { 2055 if (e) { 2056 if (typeof(e) == 'string') 2057 e = t.doc.getElementById(e); 2058 2059 o.push(f.call(s, e, i)); 2060 } 2061 }); 2062 2063 return o; 2064 } 2065 2066 return f.call(s, e); 2067 } 2068 2069 /* 2070 walk : function(n, f, s) { 2071 var d = this.doc, w; 2072 2073 if (d.createTreeWalker) { 2074 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 2075 2076 while ((n = w.nextNode()) != null) 2077 f.call(s || this, n); 2078 } else 2079 tinymce.walk(n, f, 'childNodes', s); 2080 } 2081 */ 2082 2083 /* 2084 toRGB : function(s) { 2085 var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s); 2086 2087 if (c) { 2088 // #FFF -> #FFFFFF 2089 if (!is(c[3])) 2090 c[3] = c[2] = c[1]; 2091 2092 return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")"; 2093 } 2094 2095 return s; 2096 } 2097 */ 2098 2099 }); 2100 2101 // Setup page DOM 2102 tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0}); 2103 })(); 2104 2105 /* file:jscripts/tiny_mce/classes/dom/Event.js */ 2106 2107 (function() { 2108 // Shorten names 2109 var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event; 2110 2111 tinymce.create('static tinymce.dom.Event', { 2112 inits : [], 2113 events : [], 2114 2115 // #if !jquery 2116 2117 add : function(o, n, f, s) { 2118 var cb, t = this, el = t.events, r; 2119 2120 // Handle array 2121 if (o && o instanceof Array) { 2122 r = []; 2123 2124 each(o, function(o) { 2125 o = DOM.get(o); 2126 r.push(t.add(o, n, f, s)); 2127 }); 2128 2129 return r; 2130 } 2131 2132 o = DOM.get(o); 2133 2134 if (!o) 2135 return; 2136 2137 // Setup event callback 2138 cb = function(e) { 2139 e = e || window.event; 2140 2141 // Patch in target in IE it's W3C valid 2142 if (e && !e.target && isIE) 2143 e.target = e.srcElement; 2144 2145 if (!s) 2146 return f(e); 2147 2148 return f.call(s, e); 2149 }; 2150 2151 if (n == 'unload') { 2152 tinymce.unloads.unshift({func : cb}); 2153 return cb; 2154 } 2155 2156 if (n == 'init') { 2157 if (t.domLoaded) 2158 cb(); 2159 else 2160 t.inits.push(cb); 2161 2162 return cb; 2163 } 2164 2165 // Store away listener reference 2166 el.push({ 2167 obj : o, 2168 name : n, 2169 func : f, 2170 cfunc : cb, 2171 scope : s 2172 }); 2173 2174 t._add(o, n, cb); 2175 2176 return f; 2177 }, 2178 2179 remove : function(o, n, f) { 2180 var t = this, a = t.events, s = false, r; 2181 2182 // Handle array 2183 if (o && o instanceof Array) { 2184 r = []; 2185 2186 each(o, function(o) { 2187 o = DOM.get(o); 2188 r.push(t.remove(o, n, f)); 2189 }); 2190 2191 return r; 2192 } 2193 2194 o = DOM.get(o); 2195 2196 each(a, function(e, i) { 2197 if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) { 2198 a.splice(i, 1); 2199 t._remove(o, n, e.cfunc); 2200 s = true; 2201 return false; 2202 } 2203 }); 2204 2205 return s; 2206 }, 2207 2208 // #endif 2209 2210 cancel : function(e) { 2211 if (!e) 2212 return false; 2213 2214 this.stop(e); 2215 return this.prevent(e); 2216 }, 2217 2218 stop : function(e) { 2219 if (e.stopPropagation) 2220 e.stopPropagation(); 2221 else 2222 e.cancelBubble = true; 2223 2224 return false; 2225 }, 2226 2227 prevent : function(e) { 2228 if (e.preventDefault) 2229 e.preventDefault(); 2230 else 2231 e.returnValue = false; 2232 2233 return false; 2234 }, 2235 2236 _unload : function() { 2237 var t = Event; 2238 2239 each(t.events, function(e, i) { 2240 t._remove(e.obj, e.name, e.cfunc); 2241 e.obj = e.cfunc = null; 2242 }); 2243 2244 t.events = []; 2245 t = null; 2246 }, 2247 2248 _add : function(o, n, f) { 2249 if (o.attachEvent) 2250 o.attachEvent('on' + n, f); 2251 else if (o.addEventListener) 2252 o.addEventListener(n, f, false); 2253 else 2254 o['on' + n] = f; 2255 }, 2256 2257 _remove : function(o, n, f) { 2258 if (o.detachEvent) 2259 o.detachEvent('on' + n, f); 2260 else if (o.removeEventListener) 2261 o.removeEventListener(n, f, false); 2262 else 2263 o['on' + n] = null; 2264 }, 2265 2266 _pageInit : function() { 2267 var e = Event; 2268 2269 e._remove(window, 'DOMContentLoaded', e._pageInit); 2270 e.domLoaded = true; 2271 2272 each(e.inits, function(c) { 2273 c(); 2274 }); 2275 2276 e.inits = []; 2277 }, 2278 2279 _wait : function() { 2280 var t; 2281 2282 // No need since the document is already loaded 2283 if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) 2284 return; 2285 2286 if (isIE && document.location.protocol != 'https:') { 2287 // Fake DOMContentLoaded on IE 2288 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>'); 2289 DOM.get("__ie_onload").onreadystatechange = function() { 2290 if (this.readyState == "complete") { 2291 Event._pageInit(); 2292 DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak 2293 } 2294 }; 2295 } else { 2296 Event._add(window, 'DOMContentLoaded', Event._pageInit, Event); 2297 2298 if (isIE || isWebKit) { 2299 t = setInterval(function() { 2300 if (/loaded|complete/.test(document.readyState)) { 2301 clearInterval(t); 2302 Event._pageInit(); 2303 } 2304 }, 10); 2305 } 2306 } 2307 } 2308 2309 }); 2310 2311 // Shorten name 2312 Event = tinymce.dom.Event; 2313 2314 // Dispatch DOM content loaded event for IE and Safari 2315 Event._wait(); 2316 tinymce.addUnload(Event._unload); 2317 })(); 2318 2319 /* file:jscripts/tiny_mce/classes/dom/Element.js */ 2320 2321 (function() { 2322 var each = tinymce.each; 2323 2324 tinymce.create('tinymce.dom.Element', { 2325 Element : function(id, s) { 2326 var t = this, dom, el; 2327 2328 s = s || {}; 2329 t.id = id; 2330 t.dom = dom = s.dom || tinymce.DOM; 2331 t.settings = s; 2332 2333 // Only IE leaks DOM references, this is a lot faster 2334 if (!tinymce.isIE) 2335 el = t.dom.get(t.id); 2336 2337 each([ 2338 'getPos', 2339 'getRect', 2340 'getParent', 2341 'add', 2342 'setStyle', 2343 'getStyle', 2344 'setStyles', 2345 'setAttrib', 2346 'setAttribs', 2347 'getAttrib', 2348 'addClass', 2349 'removeClass', 2350 'hasClass', 2351 'getOuterHTML', 2352 'setOuterHTML', 2353 'remove', 2354 'show', 2355 'hide', 2356 'isHidden', 2357 'setHTML', 2358 'get' 2359 ], function(k) { 2360 t[k] = function() { 2361 var a = arguments, o; 2362 2363 // Opera fails 2364 if (tinymce.isOpera) { 2365 a = [id]; 2366 2367 each(arguments, function(v) { 2368 a.push(v); 2369 }); 2370 } else 2371 Array.prototype.unshift.call(a, el || id); 2372 2373 o = dom[k].apply(dom, a); 2374 t.update(k); 2375 2376 return o; 2377 }; 2378 }); 2379 }, 2380 2381 on : function(n, f, s) { 2382 return tinymce.dom.Event.add(this.id, n, f, s); 2383 }, 2384 2385 getXY : function() { 2386 return { 2387 x : parseInt(this.getStyle('left')), 2388 y : parseInt(this.getStyle('top')) 2389 }; 2390 }, 2391 2392 getSize : function() { 2393 var n = this.dom.get(this.id); 2394 2395 return { 2396 w : parseInt(this.getStyle('width') || n.clientWidth), 2397 h : parseInt(this.getStyle('height') || n.clientHeight) 2398 }; 2399 }, 2400 2401 moveTo : function(x, y) { 2402 this.setStyles({left : x, top : y}); 2403 }, 2404 2405 moveBy : function(x, y) { 2406 var p = this.getXY(); 2407 2408 this.moveTo(p.x + x, p.y + y); 2409 }, 2410 2411 resizeTo : function(w, h) { 2412 this.setStyles({width : w, height : h}); 2413 }, 2414 2415 resizeBy : function(w, h) { 2416 var s = this.getSize(); 2417 2418 this.resizeTo(s.w + w, s.h + h); 2419 }, 2420 2421 update : function(k) { 2422 var t = this, b, dom = t.dom; 2423 2424 if (tinymce.isIE6 && t.settings.blocker) { 2425 k = k || ''; 2426 2427 // Ignore getters 2428 if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0) 2429 return; 2430 2431 // Remove blocker on remove 2432 if (k == 'remove') { 2433 dom.remove(t.blocker); 2434 return; 2435 } 2436 2437 if (!t.blocker) { 2438 t.blocker = dom.uniqueId(); 2439 b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'}); 2440 dom.setStyle(b, 'opacity', 0); 2441 } else 2442 b = dom.get(t.blocker); 2443 2444 dom.setStyle(b, 'left', t.getStyle('left', 1)); 2445 dom.setStyle(b, 'top', t.getStyle('top', 1)); 2446 dom.setStyle(b, 'width', t.getStyle('width', 1)); 2447 dom.setStyle(b, 'height', t.getStyle('height', 1)); 2448 dom.setStyle(b, 'display', t.getStyle('display', 1)); 2449 dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1); 2450 } 2451 } 2452 2453 }); 2454 })(); 2455 2456 /* file:jscripts/tiny_mce/classes/dom/Selection.js */ 2457 2458 (function() { 2459 // Shorten names 2460 var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each; 2461 2462 tinymce.create('tinymce.dom.Selection', { 2463 Selection : function(dom, win, serializer) { 2464 var t = this; 2465 2466 t.dom = dom; 2467 t.win = win; 2468 t.serializer = serializer; 2469 2470 // Prevent leaks 2471 tinymce.addUnload(function() { 2472 t.win = null; 2473 }); 2474 }, 2475 2476 getContent : function(s) { 2477 var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n; 2478 2479 s = s || {}; 2480 wb = wa = ''; 2481 s.get = true; 2482 s.format = s.format || 'html'; 2483 2484 if (s.format == 'text') 2485 return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : '')); 2486 2487 if (r.cloneContents) { 2488 n = r.cloneContents(); 2489 2490 if (n) 2491 e.appendChild(n); 2492 } else if (is(r.item) || is(r.htmlText)) 2493 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText; 2494 else 2495 e.innerHTML = r.toString(); 2496 2497 // Keep whitespace before and after 2498 if (/^\s/.test(e.innerHTML)) 2499 wb = ' '; 2500 2501 if (/\s+$/.test(e.innerHTML)) 2502 wa = ' '; 2503 2504 s.getInner = true; 2505 2506 return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa; 2507 }, 2508 2509 setContent : function(h, s) { 2510 var t = this, r = t.getRng(), d; 2511 2512 s = s || {format : 'html'}; 2513 s.set = true; 2514 h = t.dom.processHTML(h); 2515 2516 if (r.insertNode) { 2517 d = t.win.document; 2518 2519 // Gecko has a bug where if you insert using InsertHTML it will insert a space instead 2520 // So we simply check if the input is HTML or text and then insert text using the insertNode method 2521 if (tinymce.isGecko && h.indexOf('<') == -1) { 2522 r.deleteContents(); 2523 r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>')); 2524 t.select(t.dom.get('__caret')); 2525 t.getRng().deleteContents(); 2526 return; 2527 } 2528 2529 // Use insert HTML if it exists (places cursor after content) 2530 if (d.queryCommandEnabled('InsertHTML')) 2531 return d.execCommand('InsertHTML', false, h); 2532 2533 r.deleteContents(); 2534 r.insertNode(t.getRng().createContextualFragment(h)); 2535 } else { 2536 if (r.item) 2537 r.item(0).outerHTML = h; 2538 else 2539 r.pasteHTML(h); 2540 } 2541 }, 2542 2543 getStart : function() { 2544 var t = this, r = t.getRng(), e; 2545 2546 if (isIE) { 2547 if (r.item) 2548 return r.item(0); 2549 2550 r = r.duplicate(); 2551 r.collapse(1); 2552 e = r.parentElement(); 2553 2554 if (e.nodeName == 'BODY') 2555 return e.firstChild; 2556 2557 return e; 2558 } else { 2559 e = r.startContainer; 2560 2561 if (e.nodeName == 'BODY') 2562 return e.firstChild; 2563 2564 return t.dom.getParent(e, function(n) {return n.nodeType == 1;}); 2565 } 2566 }, 2567 2568 getEnd : function() { 2569 var t = this, r = t.getRng(), e; 2570 2571 if (isIE) { 2572 if (r.item) 2573 return r.item(0); 2574 2575 r = r.duplicate(); 2576 r.collapse(0); 2577 e = r.parentElement(); 2578 2579 if (e.nodeName == 'BODY') 2580 return e.lastChild; 2581 2582 return e; 2583 } else { 2584 e = r.endContainer; 2585 2586 if (e.nodeName == 'BODY') 2587 return e.lastChild; 2588 2589 return t.dom.getParent(e, function(n) {return n.nodeType == 1;}); 2590 } 2591 }, 2592 2593 getBookmark : function(si) { 2594 var t = this, r = t.getRng(), tr, sx, sy, vp = t.dom.getViewPort(t.win), e, sp, bp, le, c = -0xFFFFFF, s, ro = t.dom.getRoot(); 2595 2596 sx = vp.x; 2597 sy = vp.y; 2598 2599 // Simple bookmark fast but not as persistent 2600 if (si == 'simple') 2601 return {rng : r, scrollX : sx, scrollY : sy}; 2602 2603 // Handle IE 2604 if (isIE) { 2605 // Control selection 2606 if (r.item) { 2607 e = r.item(0); 2608 2609 each(t.dom.select(e.nodeName), function(n, i) { 2610 if (e == n) { 2611 sp = i; 2612 return false; 2613 } 2614 }); 2615 2616 return { 2617 tag : e.nodeName, 2618 index : sp, 2619 scrollX : sx, 2620 scrollY : sy 2621 }; 2622 } 2623 2624 // Text selection 2625 tr = t.dom.doc.body.createTextRange(); 2626 tr.moveToElementText(ro); 2627 tr.collapse(true); 2628 bp = Math.abs(tr.move('character', c)); 2629 2630 tr = r.duplicate(); 2631 tr.collapse(true); 2632 sp = Math.abs(tr.move('character', c)); 2633 2634 tr = r.duplicate(); 2635 tr.collapse(false); 2636 le = Math.abs(tr.move('character', c)) - sp; 2637 2638 return { 2639 start : sp - bp, 2640 length : le, 2641 scrollX : sx, 2642 scrollY : sy 2643 }; 2644 } 2645 2646 // Handle W3C 2647 e = t.getNode(); 2648 s = t.getSel(); 2649 2650 if (!s) 2651 return null; 2652 2653 // Image selection 2654 if (e && e.nodeName == 'IMG') { 2655 return { 2656 scrollX : sx, 2657 scrollY : sy 2658 }; 2659 } 2660 2661 // Text selection 2662 2663 function getPos(r, sn, en) { 2664 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 2665 2666 while ((n = w.nextNode()) != null) { 2667 if (n == sn) 2668 d.start = p; 2669 2670 if (n == en) { 2671 d.end = p; 2672 return d; 2673 } 2674 2675 p += n.nodeValue ? n.nodeValue.length : 0; 2676 } 2677 2678 return null; 2679 }; 2680 2681 // Caret or selection 2682 if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) { 2683 e = getPos(ro, s.anchorNode, s.focusNode); 2684 2685 if (!e) 2686 return {scrollX : sx, scrollY : sy}; 2687 2688 return { 2689 start : e.start + s.anchorOffset, 2690 end : e.end + s.focusOffset, 2691 scrollX : sx, 2692 scrollY : sy 2693 }; 2694 } else { 2695 e = getPos(ro, r.startContainer, r.endContainer); 2696 2697 if (!e) 2698 return {scrollX : sx, scrollY : sy}; 2699 2700 return { 2701 start : e.start + r.startOffset, 2702 end : e.end + r.endOffset, 2703 scrollX : sx, 2704 scrollY : sy 2705 }; 2706 } 2707 }, 2708 2709 moveToBookmark : function(b) { 2710 var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd; 2711 2712 function getPos(r, sp, ep) { 2713 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 2714 2715 while ((n = w.nextNode()) != null) { 2716 p += n.nodeValue ? n.nodeValue.length : 0; 2717 2718 if (p >= sp && !d.startNode) { 2719 d.startNode = n; 2720 d.startOffset = sp - (p - n.nodeValue.length); 2721 } 2722 2723 if (p >= ep) { 2724 d.endNode = n; 2725 d.endOffset = ep - (p - n.nodeValue.length); 2726 2727 return d; 2728 } 2729 } 2730 2731 return null; 2732 }; 2733 2734 if (!b) 2735 return false; 2736 2737 t.win.scrollTo(b.scrollX, b.scrollY); 2738 2739 // Handle explorer 2740 if (isIE) { 2741 // Handle simple 2742 if (r = b.rng) { 2743 try { 2744 r.select(); 2745 } catch (ex) { 2746 // Ignore 2747 } 2748 2749 return true; 2750 } 2751 2752 t.win.focus(); 2753 2754 // Handle control bookmark 2755 if (b.tag) { 2756 r = ro.createControlRange(); 2757 2758 each(t.dom.select(b.tag), function(n, i) { 2759 if (i == b.index) 2760 r.addElement(n); 2761 }); 2762 } else { 2763 // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs 2764 try { 2765 // Incorrect bookmark 2766 if (b.start < 0) 2767 return true; 2768 2769 r = s.createRange(); 2770 r.moveToElementText(ro); 2771 r.collapse(true); 2772 r.moveStart('character', b.start); 2773 r.moveEnd('character', b.length); 2774 } catch (ex2) { 2775 return true; 2776 } 2777 } 2778 2779 try { 2780 r.select(); 2781 } catch (ex) { 2782 // Needed for some odd IE bug #1843306 2783 } 2784 2785 return true; 2786 } 2787 2788 // Handle W3C 2789 if (!s) 2790 return false; 2791 2792 // Handle simple 2793 if (b.rng) { 2794 s.removeAllRanges(); 2795 s.addRange(b.rng); 2796 } else { 2797 if (is(b.start) && is(b.end)) { 2798 try { 2799 sd = getPos(ro, b.start, b.end); 2800 if (sd) { 2801 r = t.dom.doc.createRange(); 2802 r.setStart(sd.startNode, sd.startOffset); 2803 r.setEnd(sd.endNode, sd.endOffset); 2804 s.removeAllRanges(); 2805 s.addRange(r); 2806 } 2807 2808 if (!tinymce.isOpera) 2809 t.win.focus(); 2810 } catch (ex) { 2811 // Ignore 2812 } 2813 } 2814 } 2815 }, 2816 2817 select : function(n, c) { 2818 var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document; 2819 2820 function first(n) { 2821 return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null; 2822 }; 2823 2824 function last(n) { 2825 var c, o, w; 2826 2827 if (!n) 2828 return null; 2829 2830 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 2831 while (c = w.nextNode()) 2832 o = c; 2833 2834 return o; 2835 }; 2836 2837 if (isIE) { 2838 try { 2839 b = d.body; 2840 2841 if (/^(IMG|TABLE)$/.test(n.nodeName)) { 2842 r = b.createControlRange(); 2843 r.addElement(n); 2844 } else { 2845 r = b.createTextRange(); 2846 r.moveToElementText(n); 2847 } 2848 2849 r.select(); 2850 } catch (ex) { 2851 // Throws illigal agrument in IE some times 2852 } 2853 } else { 2854 if (c) { 2855 fn = first(n); 2856 ln = last(n); 2857 2858 if (fn && ln) { 2859 //console.debug(fn, ln); 2860 r = d.createRange(); 2861 r.setStart(fn, 0); 2862 r.setEnd(ln, ln.nodeValue.length); 2863 } else 2864 r.selectNode(n); 2865 } else 2866 r.selectNode(n); 2867 2868 t.setRng(r); 2869 } 2870 2871 return n; 2872 }, 2873 2874 isCollapsed : function() { 2875 var t = this, r = t.getRng(), s = t.getSel(); 2876 2877 if (!r || r.item) 2878 return false; 2879 2880 return !s || r.boundingWidth == 0 || s.isCollapsed; 2881 }, 2882 2883 collapse : function(b) { 2884 var t = this, r = t.getRng(), n; 2885 2886 // Control range on IE 2887 if (r.item) { 2888 n = r.item(0); 2889 r = this.win.document.body.createTextRange(); 2890 r.moveToElementText(n); 2891 } 2892 2893 r.collapse(!!b); 2894 t.setRng(r); 2895 }, 2896 2897 getSel : function() { 2898 var t = this, w = this.win; 2899 2900 return w.getSelection ? w.getSelection() : w.document.selection; 2901 }, 2902 2903 getRng : function() { 2904 var t = this, s = t.getSel(), r; 2905 2906 try { 2907 if (s) 2908 r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange()); 2909 } catch (ex) { 2910 // IE throws unspecified error here if TinyMCE is placed in a frame/iframe 2911 } 2912 2913 // No range found then create an empty one 2914 // This can occur when the editor is placed in a hidden container element on Gecko 2915 // Or on IE when there was an exception 2916 if (!r) 2917 r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange(); 2918 2919 return r; 2920 }, 2921 2922 setRng : function(r) { 2923 var s; 2924 2925 if (!isIE) { 2926 s = this.getSel(); 2927 2928 if (s) { 2929 s.removeAllRanges(); 2930 s.addRange(r); 2931 } 2932 } else { 2933 try { 2934 r.select(); 2935 } catch (ex) { 2936 // Needed for some odd IE bug #1843306 2937 } 2938 } 2939 }, 2940 2941 setNode : function(n) { 2942 var t = this; 2943 2944 t.setContent(t.dom.getOuterHTML(n)); 2945 2946 return n; 2947 }, 2948 2949 getNode : function() { 2950 var t = this, r = t.getRng(), s = t.getSel(), e; 2951 2952 if (!isIE) { 2953 // Range maybe lost after the editor is made visible again 2954 if (!r) 2955 return t.dom.getRoot(); 2956 2957 e = r.commonAncestorContainer; 2958 2959 // Handle selection a image or other control like element such as anchors 2960 if (!r.collapsed) { 2961 if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) { 2962 if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) { 2963 if (r.startContainer.hasChildNodes()) 2964 e = r.startContainer.childNodes[r.startOffset]; 2965 } 2966 } 2967 } 2968 2969 return t.dom.getParent(e, function(n) { 2970 return n.nodeType == 1; 2971 }); 2972 } 2973 2974 return r.item ? r.item(0) : r.parentElement(); 2975 } 2976 2977 }); 2978 })(); 2979 2980 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */ 2981 2982 (function() { 2983 tinymce.create('tinymce.dom.XMLWriter', { 2984 node : null, 2985 2986 XMLWriter : function(s) { 2987 // Get XML document 2988 function getXML() { 2989 var i = document.implementation; 2990 2991 if (!i || !i.createDocument) { 2992 // Try IE objects 2993 try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {} 2994 try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {} 2995 } else 2996 return i.createDocument('', '', null); 2997 }; 2998 2999 this.doc = getXML(); 3000 this.reset(); 3001 }, 3002 3003 reset : function() { 3004 var t = this, d = t.doc; 3005 3006 if (d.firstChild) 3007 d.removeChild(d.firstChild); 3008 3009 t.node = d.appendChild(d.createElement("html")); 3010 }, 3011 3012 writeStartElement : function(n) { 3013 var t = this; 3014 3015 t.node = t.node.appendChild(t.doc.createElement(n)); 3016 }, 3017 3018 writeAttribute : function(n, v) { 3019 // Since Opera doesn't escape > into > we need to do it our self 3020 if (tinymce.isOpera) 3021 v = v.replace(/>/g, '|>'); 3022 3023 this.node.setAttribute(n, v); 3024 }, 3025 3026 writeEndElement : function() { 3027 this.node = this.node.parentNode; 3028 }, 3029 3030 writeFullEndElement : function() { 3031 var t = this, n = t.node; 3032 3033 n.appendChild(t.doc.createTextNode("")); 3034 t.node = n.parentNode; 3035 }, 3036 3037 writeText : function(v) { 3038 // Since Opera doesn't escape > into > we need to do it our self 3039 if (tinymce.isOpera) 3040 v = v.replace(/>/g, '|>'); 3041 3042 this.node.appendChild(this.doc.createTextNode(v)); 3043 }, 3044 3045 writeCDATA : function(v) { 3046 this.node.appendChild(this.doc.createCDATA(v)); 3047 }, 3048 3049 writeComment : function(v) { 3050 this.node.appendChild(this.doc.createComment(v)); 3051 }, 3052 3053 getContent : function() { 3054 var h; 3055 3056 h = this.doc.xml || new XMLSerializer().serializeToString(this.doc); 3057 h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, ''); 3058 h = h.replace(/ ?\/>/g, ' />'); 3059 3060 // Since Opera doesn't escape > into > we need to do it our self to normalize the output for all browsers 3061 if (tinymce.isOpera) 3062 h = h.replace(/\|>/g, '>'); 3063 3064 return h; 3065 } 3066 3067 }); 3068 })(); 3069 3070 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */ 3071 3072 (function() { 3073 // Shorten names 3074 var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE; 3075 3076 // Returns only attribites that have values not all attributes in IE 3077 function getIEAtts(n) { 3078 var o = []; 3079 3080 // Object will throw exception in IE 3081 if (n.nodeName == 'OBJECT') 3082 return n.attributes; 3083 3084 n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) { 3085 o.push({specified : 1, nodeName : b}); 3086 }); 3087 3088 return o; 3089 }; 3090 3091 function wildcardToRE(s) { 3092 return s.replace(/([?+*])/g, '.$1'); 3093 }; 3094 3095 tinymce.create('tinymce.dom.Serializer', { 3096 Serializer : function(s) { 3097 var t = this; 3098 3099 t.key = 0; 3100 t.onPreProcess = new Dispatcher(t); 3101 t.onPostProcess = new Dispatcher(t); 3102 t.writer = new tinymce.dom.XMLWriter(); 3103 3104 // Default settings 3105 t.settings = s = extend({ 3106 dom : tinymce.DOM, 3107 valid_nodes : 0, 3108 node_filter : 0, 3109 attr_filter : 0, 3110 invalid_attrs : /^(mce_|_moz_$)/, 3111 closed : /(br|hr|input|meta|img|link|param)/, 3112 entity_encoding : 'named', 3113 entities : '160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro', 3114 valid_elements : '*[*]', 3115 extended_valid_elements : 0, 3116 valid_child_elements : 0, 3117 invalid_elements : 0, 3118 fix_table_elements : 0, 3119 fix_list_elements : true, 3120 fix_content_duplication : true, 3121 convert_fonts_to_spans : false, 3122 font_size_classes : 0, 3123 font_size_style_values : 0, 3124 apply_source_formatting : 0, 3125 indent_mode : 'simple', 3126 indent_char : '\t', 3127 indent_levels : 1, 3128 remove_linebreaks : 1 3129 }, s); 3130 3131 t.dom = s.dom; 3132 3133 if (s.fix_list_elements) { 3134 t.onPreProcess.add(function(se, o) { 3135 var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np; 3136 3137 function prevNode(e, n) { 3138 var a = n.split(','), i; 3139 3140 while ((e = e.previousSibling) != null) { 3141 for (i=0; i<a.length; i++) { 3142 if (e.nodeName == a[i]) 3143 return e; 3144 } 3145 } 3146 3147 return null; 3148 }; 3149 3150 for (x=0; x<a.length; x++) { 3151 nl = t.dom.select(a[x], o.node); 3152 3153 for (i=0; i<nl.length; i++) { 3154 n = nl[i]; 3155 p = n.parentNode; 3156 3157 if (r.test(p.nodeName)) { 3158 np = prevNode(n, 'LI'); 3159 3160 if (!np) { 3161 np = t.dom.create('li'); 3162 np.innerHTML = ' '; 3163 np.appendChild(n); 3164 p.insertBefore(np, p.firstChild); 3165 } else 3166 np.appendChild(n); 3167 } 3168 } 3169 } 3170 }); 3171 } 3172 3173 if (s.fix_table_elements) { 3174 t.onPreProcess.add(function(se, o) { 3175 var ta = [], d = t.dom.doc; 3176 3177 // Build list of HTML chunks and replace tables with comment placeholders 3178 each(t.dom.select('table', o.node), function(e) { 3179 var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), p = [], i, h; 3180 3181 if (pa) { 3182 t.dom.getParent(e, function(n) { 3183 if (n != e) 3184 p.push(n.nodeName); 3185 }); 3186 3187 h = ''; 3188 3189 for (i = 0; i < p.length; i++) 3190 h += '</' + p[i]+ '>'; 3191 3192 h += t.dom.getOuterHTML(e); 3193 3194 for (i = p.length - 1; i >= 0; i--) 3195 h += '<' + p[i]+ '>'; 3196 3197 ta.push(h); 3198 e.parentNode.replaceChild(d.createComment('mcetable:' + (ta.length - 1)), e); 3199 } 3200 }); 3201 3202 // Replace table placeholders with end parents + table + start parents HTML code 3203 t.dom.setHTML(o.node, o.node.innerHTML.replace(/<!--mcetable:([0-9]+)-->/g, function(a, b) { 3204 return ta[parseInt(b)]; 3205 })); 3206 }); 3207 } 3208 }, 3209 3210 setEntities : function(s) { 3211 var t = this, a, i, l = {}, re = '', v; 3212 3213 // No need to setup more than once 3214 if (t.entityLookup) 3215 return; 3216 3217 // Build regex and lookup array 3218 a = s.split(','); 3219 for (i = 0; i < a.length; i += 2) { 3220 v = a[i]; 3221 3222 // Don't add default & " etc. 3223 if (v == 34 || v == 38 || v == 60 || v == 62) 3224 continue; 3225 3226 l[String.fromCharCode(a[i])] = a[i + 1]; 3227 3228 v = parseInt(a[i]).toString(16); 3229 re += '\\u' + '0000'.substring(v.length) + v; 3230 } 3231 3232 if (!re) { 3233 t.settings.entity_encoding = 'raw'; 3234 return; 3235 } 3236 3237 t.entitiesRE = new RegExp('[' + re + ']', 'g'); 3238 t.entityLookup = l; 3239 }, 3240 3241 setValidChildRules : function(s) { 3242 this.childRules = null; 3243 this.addValidChildRules(s); 3244 }, 3245 3246 addValidChildRules : function(s) { 3247 var t = this, inst, intr, bloc; 3248 3249 if (!s) 3250 return; 3251 3252 inst = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment'; 3253 intr = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment'; 3254 bloc = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; 3255 3256 each(s.split(','), function(s) { 3257 var p = s.split(/\[|\]/), re; 3258 3259 s = ''; 3260 each(p[1].split('|'), function(v) { 3261 if (s) 3262 s += '|'; 3263 3264 switch (v) { 3265 case '%itrans': 3266 v = intr; 3267 break; 3268 3269 case '%itrans_na': 3270 v = intr.substring(2); 3271 break; 3272 3273 case '%istrict': 3274 v = inst; 3275 break; 3276 3277 case '%istrict_na': 3278 v = inst.substring(2); 3279 break; 3280 3281 case '%btrans': 3282 v = bloc; 3283 break; 3284 3285 case '%bstrict': 3286 v = bloc; 3287 break; 3288 } 3289 3290 s += v; 3291 }); 3292 re = new RegExp('^(' + s.toLowerCase() + ')$', 'i'); 3293 3294 each(p[0].split('/'), function(s) { 3295 t.childRules = t.childRules || {}; 3296 t.childRules[s] = re; 3297 }); 3298 }); 3299 3300 // Build regex 3301 s = ''; 3302 each(t.childRules, function(v, k) { 3303 if (s) 3304 s += '|'; 3305 3306 s += k; 3307 }); 3308 3309 t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i'); 3310 3311 /*console.debug(t.parentElementsRE.toString()); 3312 each(t.childRules, function(v) { 3313 console.debug(v.toString()); 3314 });*/ 3315 }, 3316 3317 setRules : function(s) { 3318 var t = this; 3319 3320 t._setup(); 3321 t.rules = {}; 3322 t.wildRules = []; 3323 t.validElements = {}; 3324 3325 return t.addRules(s); 3326 }, 3327 3328 addRules : function(s) { 3329 var t = this, dr; 3330 3331 if (!s) 3332 return; 3333 3334 t._setup(); 3335 3336 each(s.split(','), function(s) { 3337 var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = []; 3338 3339 // Extend with default rules 3340 if (dr) 3341 at = tinymce.extend([], dr.attribs); 3342 3343 // Parse attributes 3344 if (p.length > 1) { 3345 each(p[1].split('|'), function(s) { 3346 var ar = {}, i; 3347 3348 at = at || []; 3349 3350 // Parse attribute rule 3351 s = s.replace(/::/g, '~'); 3352 s = /^([!\-])?([\w*.?~]+|)([=:<])?(.+)?$/.exec(s); 3353 s[2] = s[2].replace(/~/g, ':'); 3354 3355 // Add required attributes 3356 if (s[1] == '!') { 3357 ra = ra || []; 3358 ra.push(s[2]); 3359 } 3360 3361 // Remove inherited attributes 3362 if (s[1] == '-') { 3363 for (i = 0; i <at.length; i++) { 3364 if (at[i].name == s[2]) { 3365 at.splice(i, 1); 3366 return; 3367 } 3368 } 3369 } 3370 3371 switch (s[3]) { 3372 // Add default attrib values 3373 case '=': 3374 ar.defaultVal = s[4] || ''; 3375 break; 3376 3377 // Add forced attrib values 3378 case ':': 3379 ar.forcedVal = s[4]; 3380 break; 3381 3382 // Add validation values 3383 case '<': 3384 ar.validVals = s[4].split('?'); 3385 break; 3386 } 3387 3388 if (/[*.?]/.test(s[2])) { 3389 wat = wat || []; 3390 ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$'); 3391 wat.push(ar); 3392 } else { 3393 ar.name = s[2]; 3394 at.push(ar); 3395 } 3396 3397 va.push(s[2]); 3398 }); 3399 } 3400 3401 // Handle element names 3402 each(tn, function(s, i) { 3403 var pr = s.charAt(0), x = 1, ru = {}; 3404 3405 // Extend with default rule data 3406 if (dr) { 3407 if (dr.noEmpty) 3408 ru.noEmpty = dr.noEmpty; 3409 3410 if (dr.fullEnd) 3411 ru.fullEnd = dr.fullEnd; 3412 3413 if (dr.padd) 3414 ru.padd = dr.padd; 3415 } 3416 3417 // Handle prefixes 3418 switch (pr) { 3419 case '-': 3420 ru.noEmpty = true; 3421 break; 3422 3423 case '+': 3424 ru.fullEnd = true; 3425 break; 3426 3427 case '#': 3428 ru.padd = true; 3429 break; 3430 3431 default: 3432 x = 0; 3433 } 3434 3435 tn[i] = s = s.substring(x); 3436 t.validElements[s] = 1; 3437 3438 // Add element name or element regex 3439 if (/[*.?]/.test(tn[0])) { 3440 ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$'); 3441 t.wildRules = t.wildRules || {}; 3442 t.wildRules.push(ru); 3443 } else { 3444 ru.name = tn[0]; 3445 3446 // Store away default rule 3447 if (tn[0] == '@') 3448 dr = ru; 3449 3450 t.rules[s] = ru; 3451 } 3452 3453 ru.attribs = at; 3454 3455 if (ra) 3456 ru.requiredAttribs = ra; 3457 3458 if (wat) { 3459 // Build valid attributes regexp 3460 s = ''; 3461 each(va, function(v) { 3462 if (s) 3463 s += '|'; 3464 3465 s += '(' + wildcardToRE(v) + ')'; 3466 }); 3467 ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$'); 3468 ru.wildAttribs = wat; 3469 } 3470 }); 3471 }); 3472 3473 // Build valid elements regexp 3474 s = ''; 3475 each(t.validElements, function(v, k) { 3476 if (s) 3477 s += '|'; 3478 3479 if (k != '@') 3480 s += k; 3481 }); 3482 t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$'); 3483 3484 //console.debug(t.validElementsRE.toString()); 3485 //console.dir(t.rules); 3486 //console.dir(t.wildRules); 3487 }, 3488 3489 findRule : function(n) { 3490 var t = this, rl = t.rules, i, r; 3491 3492 t._setup(); 3493 3494 // Exact match 3495 r = rl[n]; 3496 if (r) 3497 return r; 3498 3499 // Try wildcards 3500 rl = t.wildRules; 3501 for (i = 0; i < rl.length; i++) { 3502 if (rl[i].nameRE.test(n)) 3503 return rl[i]; 3504 } 3505 3506 return null; 3507 }, 3508 3509 findAttribRule : function(ru, n) { 3510 var i, wa = ru.wildAttribs; 3511 3512 for (i = 0; i < wa.length; i++) { 3513 if (wa[i].nameRE.test(n)) 3514 return wa[i]; 3515 } 3516 3517 return null; 3518 }, 3519 3520 serialize : function(n, o) { 3521 var h, t = this; 3522 3523 t._setup(); 3524 o = o || {}; 3525 o.format = o.format || 'html'; 3526 t.processObj = o; 3527 n = n.cloneNode(true); 3528 t.key = '' + (parseInt(t.key) + 1); 3529 3530 // Pre process 3531 if (!o.no_events) { 3532 o.node = n; 3533 t.onPreProcess.dispatch(t, o); 3534 } 3535 3536 // Serialize HTML DOM into a string 3537 t.writer.reset(); 3538 t._serializeNode(n, o.getInner); 3539 3540 // Post process 3541 o.content = t.writer.getContent(); 3542 3543 if (!o.no_events) 3544 t.onPostProcess.dispatch(t, o); 3545 3546 t._postProcess(o); 3547 o.node = null; 3548 3549 return tinymce.trim(o.content); 3550 }, 3551 3552 // Internal functions 3553 3554 _postProcess : function(o) { 3555 var t = this, s = t.settings, h = o.content, sc = [], p, l; 3556 3557 if (o.format == 'html') { 3558 // Protect some elements 3559 p = t._protect({ 3560 content : h, 3561 patterns : [ 3562 /(<script[^>]*>)(.*?)(<\/script>)/g, 3563 /(<style[^>]*>)(.*?)(<\/style>)/g, 3564 /(<pre[^>]*>)(.*?)(<\/pre>)/g 3565 ] 3566 }); 3567 3568 h = p.content; 3569 3570 // Entity encode 3571 if (s.entity_encoding !== 'raw') { 3572 if (s.entity_encoding.indexOf('named') != -1) { 3573 t.setEntities(s.entities); 3574 l = t.entityLookup; 3575 3576 h = h.replace(t.entitiesRE, function(a) { 3577 var v; 3578 3579 if (v = l[a]) 3580 a = '&' + v + ';'; 3581 3582 return a; 3583 }); 3584 } 3585 3586 if (s.entity_encoding.indexOf('numeric') != -1) { 3587 h = h.replace(/[\u007E-\uFFFF]/g, function(a) { 3588 return '&#' + a.charCodeAt(0) + ';'; 3589 }); 3590 } 3591 } 3592 3593 // Use BR instead of padded P elements inside editor and use <p> </p> outside editor 3594 if (o.set) 3595 h = h.replace(/<p>\s+( | |\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>'); 3596 else 3597 h = h.replace(/<p>\s+( | |\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>'); 3598 3599 // Since Gecko and Safari keeps whitespace in the DOM we need to 3600 // remove it inorder to match other browsers. But I think Gecko and Safari is right. 3601 // This process is only done when getting contents out from the editor. 3602 if (!o.set) { 3603 if (s.remove_linebreaks) { 3604 h = h.replace(/(<[^>]+>)\s+/g, '$1 '); 3605 h = h.replace(/\s+(<\/[^>]+>)/g, ' $1'); 3606 h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start 3607 h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start 3608 h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end 3609 } 3610 3611 // Simple indentation 3612 if (s.apply_source_formatting && s.indent_mode == 'simple') { 3613 // Add line breaks before and after block elements 3614 h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n'); 3615 h = h.replace(/\s*<(p|h[1-6]|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>'); 3616 h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n'); 3617 h = h.replace(/\n\n/g, '\n'); 3618 } 3619 } 3620 3621 h = t._unprotect(h, p); 3622 } 3623 3624 o.content = h; 3625 }, 3626 3627 _serializeNode : function(n, inn) { 3628 var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv; 3629 3630 if (!s.node_filter || s.node_filter(n)) { 3631 switch (n.nodeType) { 3632 case 1: // Element 3633 if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus')) 3634 return; 3635 3636 iv = false; 3637 hc = n.hasChildNodes(); 3638 nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase(); 3639 3640 // Add correct prefix on IE 3641 if (isIE) { 3642 if (n.scopeName !== 'HTML' && n.scopeName !== 'html') 3643 nn = n.scopeName + ':' + nn; 3644 } 3645 3646 // Remove mce prefix on IE needed for the abbr element 3647 if (nn.indexOf('mce:') === 0) 3648 nn = nn.substring(4); 3649 3650 // Check if valid 3651 if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) { 3652 iv = true; 3653 break; 3654 } 3655 3656 if (isIE) { 3657 // Fix IE content duplication (DOM can have multiple copies of the same node) 3658 if (s.fix_content_duplication) { 3659 if (n.mce_serialized == t.key) 3660 return; 3661 3662 n.mce_serialized = t.key; 3663 } 3664 3665 // IE sometimes adds a / infront of the node name 3666 if (nn.charAt(0) == '/') 3667 nn = nn.substring(1); 3668 } 3669 3670 // Check if valid child 3671 if (t.childRules) { 3672 if (t.parentElementsRE.test(t.elementName)) { 3673 if (!t.childRules[t.elementName].test(nn)) { 3674 iv = true; 3675 break; 3676 } 3677 } 3678 3679 t.elementName = nn; 3680 } 3681 3682 ru = t.findRule(nn); 3683 nn = ru.name || nn; 3684 3685 // Skip empty nodes or empty node name in IE 3686 if ((!hc && ru.noEmpty) || (isIE && !nn)) { 3687 iv = true; 3688 break; 3689 } 3690 3691 // Check required 3692 if (ru.requiredAttribs) { 3693 a = ru.requiredAttribs; 3694 3695 for (i = a.length - 1; i >= 0; i--) { 3696 if (this.dom.getAttrib(n, a[i]) !== '') 3697 break; 3698 } 3699 3700 // None of the required was there 3701 if (i == -1) { 3702 iv = true; 3703 break; 3704 } 3705 } 3706 3707 w.writeStartElement(nn); 3708 3709 // Add ordered attributes 3710 if (ru.attribs) { 3711 for (i=0, at = ru.attribs, l = at.length; i<l; i++) { 3712 a = at[i]; 3713 v = t._getAttrib(n, a); 3714 3715 if (v !== null) 3716 w.writeAttribute(a.name, v); 3717 } 3718 } 3719 3720 // Add wild attributes 3721 if (ru.validAttribsRE) { 3722 at = isIE ? getIEAtts(n) : n.attributes; 3723 for (i=at.length-1; i>-1; i--) { 3724 no = at[i]; 3725 3726 if (no.specified) { 3727 a = no.nodeName.toLowerCase(); 3728 3729 if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a)) 3730 continue; 3731 3732 ar = t.findAttribRule(ru, a); 3733 v = t._getAttrib(n, ar, a); 3734 3735 if (v !== null) 3736 w.writeAttribute(a, v); 3737 } 3738 } 3739 } 3740 3741 // Padd empty nodes with a 3742 if (!hc && ru.padd) 3743 w.writeText('\u00a0'); 3744 3745 break; 3746 3747 case 3: // Text 3748 // Check if valid child 3749 if (t.childRules && t.parentElementsRE.test(t.elementName)) { 3750 if (!t.childRules[t.elementName].test(n.nodeName)) 3751 return; 3752 } 3753 3754 return w.writeText(n.nodeValue); 3755 3756 case 4: // CDATA 3757 return w.writeCDATA(n.nodeValue); 3758 3759 case 8: // Comment 3760 return w.writeComment(n.nodeValue); 3761 } 3762 } else if (n.nodeType == 1) 3763 hc = n.hasChildNodes(); 3764 3765 if (hc) { 3766 cn = n.firstChild; 3767 3768 while (cn) { 3769 t._serializeNode(cn); 3770 t.elementName = nn; 3771 cn = cn.nextSibling; 3772 } 3773 } 3774 3775 // Write element end 3776 if (!iv) { 3777 if (hc || !s.closed.test(nn)) 3778 w.writeFullEndElement(); 3779 else 3780 w.writeEndElement(); 3781 } 3782 }, 3783 3784 _protect : function(o) { 3785 o.items = o.items || []; 3786 3787 function enc(s) { 3788 return s.replace(/[\r\n]/g, function(c) { 3789 if (c === '\n') 3790 return '\\n'; 3791 3792 return '\\r'; 3793 }); 3794 }; 3795 3796 function dec(s) { 3797 return s.replace(/\\[rn]/g, function(c) { 3798 if (c === '\\n') 3799 return '\n'; 3800 3801 return '\r'; 3802 }); 3803 }; 3804 3805 each(o.patterns, function(p) { 3806 o.content = dec(enc(o.content).replace(p, function(x, a, b, c) { 3807 o.items.push(dec(b)); 3808 return a + '<!--mce:' + (o.items.length - 1) + '-->' + c; 3809 })); 3810 }); 3811 3812 return o; 3813 }, 3814 3815 _unprotect : function(h, o) { 3816 h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) { 3817 return o.items[parseInt(b)]; 3818 }); 3819 3820 o.items = []; 3821 3822 return h; 3823 }, 3824 3825 _setup : function() { 3826 var t = this, s = this.settings; 3827 3828 if (t.done) 3829 return; 3830 3831 t.done = 1; 3832 3833 t.setRules(s.valid_elements); 3834 t.addRules(s.extended_valid_elements); 3835 t.addValidChildRules(s.valid_child_elements); 3836 3837 if (s.invalid_elements) 3838 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(',', '|').toLowerCase()) + ')$'); 3839 3840 if (s.attrib_value_filter) 3841 t.attribValueFilter = s.attribValueFilter; 3842 }, 3843 3844 _getAttrib : function(n, a, na) { 3845 var i, v; 3846 3847 na = na || a.name; 3848 3849 if (a.forcedVal && (v = a.forcedVal)) { 3850 if (v === '{$uid}') 3851 return this.dom.uniqueId(); 3852 3853 return v; 3854 } 3855 3856 v = this.dom.getAttrib(n, na); 3857 3858 switch (na) { 3859 case 'rowspan': 3860 case 'colspan': 3861 // Whats the point? Remove usless attribute value 3862 if (v == '1') 3863 v = ''; 3864 3865 break; 3866 } 3867 3868 if (this.attribValueFilter) 3869 v = this.attribValueFilter(na, v, n); 3870 3871 if (a.validVals) { 3872 for (i = a.validVals.length - 1; i >= 0; i--) { 3873 if (v == a.validVals[i]) 3874 break; 3875 } 3876 3877 if (i == -1) 3878 return null; 3879 } 3880 3881 if (v === '' && typeof(a.defaultVal) != 'undefined') { 3882 v = a.defaultVal; 3883 3884 if (v === '{$uid}') 3885 return this.dom.uniqueId(); 3886 3887 return v; 3888 } else { 3889 // Remove internal mceItemXX classes when content is extracted from editor 3890 if (na == 'class' && this.processObj.get) 3891 v = v.replace(/\bmceItem\w+\b/g, ''); 3892 } 3893 3894 if (v === '') 3895 return null; 3896 3897 3898 return v; 3899 } 3900 3901 }); 3902 })(); 3903 3904 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */ 3905 3906 (function() { 3907 var each = tinymce.each; 3908 3909 tinymce.create('tinymce.dom.ScriptLoader', { 3910 ScriptLoader : function(s) { 3911 this.settings = s || {}; 3912 this.queue = []; 3913 this.lookup = {}; 3914 }, 3915 3916 markDone : function(u) { 3917 this.lookup[u] = {state : 2, url : u}; 3918 }, 3919 3920 add : function(u, cb, s, pr) { 3921 var t = this, lo = t.lookup, o; 3922 3923 if (o = lo[u]) { 3924 // Is loaded fire callback 3925 if (cb && o.state == 2) 3926 cb.call(s || this); 3927 3928 return o; 3929 } 3930 3931 o = {state : 0, url : u, func : cb, scope : s || this}; 3932 3933 if (pr) 3934 t.queue.unshift(o); 3935 else 3936 t.queue.push(o); 3937 3938 lo[u] = o; 3939 3940 return o; 3941 }, 3942 3943 load : function(u, cb, s) { 3944 var t = this, o; 3945 3946 function loadScript(u) { 3947 if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) { 3948 tinymce.util.XHR.send({ 3949 url : u, 3950 error : t.settings.error, 3951 async : false, 3952 success : function(co) { 3953 t.eval(co); 3954 } 3955 }); 3956 } else 3957 document.write('<script type="text/javascript" src="' + u + '"></script>'); 3958 }; 3959 3960 if (!tinymce.is(u, 'string')) { 3961 each(u, function(u) { 3962 loadScript(u); 3963 }); 3964 3965 if (cb) 3966 cb.call(s || t); 3967 } else { 3968 loadScript(u); 3969 3970 if (cb) 3971 cb.call(s || t); 3972 } 3973 }, 3974 3975 loadQueue : function(cb, s) { 3976 var t = this; 3977 3978 if (!t.queueLoading) { 3979 t.queueLoading = 1; 3980 t.queueCallbacks = []; 3981 3982 t.loadScripts(t.queue, function() { 3983 t.queueLoading = 0; 3984 3985 if (cb) 3986 cb.call(s || t); 3987 3988 each(t.queueCallbacks, function(o) { 3989 o.func.call(o.scope); 3990 }); 3991 }); 3992 } else if (cb) 3993 t.queueCallbacks.push({func : cb, scope : s || t}); 3994 }, 3995 3996 eval : function(co) { 3997 var w = window; 3998 3999 // Evaluate script 4000 if (!w.execScript) { 4001 try { 4002 eval.call(w, co); 4003 } catch (ex) { 4004 eval(co, w); // Firefox 3.0a8 4005 } 4006 } else 4007 w.execScript(co); // IE 4008 }, 4009 4010 loadScripts : function(sc, cb, s) { 4011 var t = this, lo = t.lookup; 4012 4013 function done(o) { 4014 o.state = 2; // Has been loaded 4015 4016 // Run callback 4017 if (o.func) 4018 o.func.call(o.scope || t); 4019 }; 4020 4021 function allDone() { 4022 var l; 4023 4024 // Check if all files are loaded 4025 l = sc.length; 4026 each(sc, function(o) { 4027 o = lo[o.url]; 4028 4029 if (o.state === 2) {// It has finished loading 4030 done(o); 4031 l--; 4032 } else 4033 load(o); 4034 }); 4035 4036 // They are all loaded 4037 if (l === 0 && cb) { 4038 cb.call(s || t); 4039 cb = 0; 4040 } 4041 }; 4042 4043 function load(o) { 4044 if (o.state > 0) 4045 return; 4046 4047 o.state = 1; // Is loading 4048 4049 tinymce.util.XHR.send({ 4050 url : o.url, 4051 error : t.settings.error, 4052 success : function(co) { 4053 t.eval(co); 4054 done(o); 4055 allDone(); 4056 } 4057 }); 4058 }; 4059 4060 each(sc, function(o) { 4061 var u = o.url; 4062 4063 // Add to queue if needed 4064 if (!lo[u]) { 4065 lo[u] = o; 4066 t.queue.push(o); 4067 } else 4068 o = lo[u]; 4069 4070 // Is already loading or has been loaded 4071 if (o.state > 0) 4072 return; 4073 4074 if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) { 4075 var ix, ol = ''; 4076 4077 // Add onload events 4078 if (cb || o.func) { 4079 o.state = 1; // Is loading 4080 4081 ix = tinymce.dom.ScriptLoader._addOnLoad(function() { 4082 done(o); 4083 allDone(); 4084 }); 4085 4086 if (tinymce.isIE) 4087 ol = ' onreadystatechange="'; 4088 else 4089 ol = ' onload="'; 4090 4091 ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"'; 4092 } 4093 4094 document.write('<script type="text/javascript" src="' + u + '"' + ol + '></script>'); 4095 4096 if (!o.func) 4097 done(o); 4098 } else 4099 load(o); 4100 }); 4101 4102 allDone(); 4103 }, 4104 4105 // Static methods 4106 'static' : { 4107 _addOnLoad : function(f) { 4108 var t = this; 4109 4110 t._funcs = t._funcs || []; 4111 t._funcs.push(f); 4112 4113 return t._funcs.length - 1; 4114 }, 4115 4116 _onLoad : function(e, u, ix) { 4117 if (!tinymce.isIE || e.readyState == 'complete') 4118 this._funcs[ix].call(this); 4119 } 4120 } 4121 4122 }); 4123 4124 // Global script loader 4125 tinymce.ScriptLoader = new tinymce.dom.ScriptLoader(); 4126 })(); 4127 4128 /* file:jscripts/tiny_mce/classes/ui/Control.js */ 4129 4130 (function() { 4131 // Shorten class names 4132 var DOM = tinymce.DOM, is = tinymce.is; 4133 4134 tinymce.create('tinymce.ui.Control', { 4135 Control : function(id, s) { 4136 this.id = id; 4137 this.settings = s = s || {}; 4138 this.rendered = false; 4139 this.onRender = new tinymce.util.Dispatcher(this); 4140 this.classPrefix = ''; 4141 this.scope = s.scope || this; 4142 this.disabled = 0; 4143 this.active = 0; 4144 }, 4145 4146 setDisabled : function(s) { 4147 var e; 4148 4149 if (s != this.disabled) { 4150 e = DOM.get(this.id); 4151 4152 // Add accessibility title for unavailable actions 4153 if (e && this.settings.unavailable_prefix) { 4154 if (s) { 4155 this.prevTitle = e.title; 4156 e.title = this.settings.unavailable_prefix + ": " + e.title; 4157 } else 4158 e.title = this.prevTitle; 4159 } 4160 4161 this.setState('Disabled', s); 4162 this.setState('Enabled', !s); 4163 this.disabled = s; 4164 } 4165 }, 4166 4167 isDisabled : function() { 4168 return this.disabled; 4169 }, 4170 4171 setActive : function(s) { 4172 if (s != this.active) { 4173 this.setState('Active', s); 4174 this.active = s; 4175 } 4176 }, 4177 4178 isActive : function() { 4179 return this.active; 4180 }, 4181 4182 setState : function(c, s) { 4183 var n = DOM.get(this.id); 4184 4185 c = this.classPrefix + c; 4186 4187 if (s) 4188 DOM.addClass(n, c); 4189 else 4190 DOM.removeClass(n, c); 4191 }, 4192 4193 isRendered : function() { 4194 return this.rendered; 4195 }, 4196 4197 renderHTML : function() { 4198 }, 4199 4200 renderTo : function(n) { 4201 DOM.setHTML(n, this.renderHTML()); 4202 }, 4203 4204 postRender : function() { 4205 var t = this, b; 4206 4207 // Set pending states 4208 if (is(t.disabled)) { 4209 b = t.disabled; 4210 t.disabled = -1; 4211 t.setDisabled(b); 4212 } 4213 4214 if (is(t.active)) { 4215 b = t.active; 4216 t.active = -1; 4217 t.setActive(b); 4218 } 4219 }, 4220 4221 destroy : function() { 4222 DOM.remove(this.id); 4223 } 4224 4225 }); 4226 })(); 4227 /* file:jscripts/tiny_mce/classes/ui/Container.js */ 4228 4229 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', { 4230 Container : function(id, s) { 4231 this.parent(id, s); 4232 this.controls = []; 4233 this.lookup = {}; 4234 }, 4235 4236 add : function(c) { 4237 this.lookup[c.id] = c; 4238 this.controls.push(c); 4239 4240 return c; 4241 }, 4242 4243 get : function(n) { 4244 return this.lookup[n]; 4245 } 4246 4247 }); 4248 4249 4250 /* file:jscripts/tiny_mce/classes/ui/Separator.js */ 4251 4252 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { 4253 renderHTML : function() { 4254 return tinymce.DOM.createHTML('span', {'class' : 'mceSeparator'}); 4255 } 4256 4257 }); 4258 4259 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */ 4260 4261 (function() { 4262 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; 4263 4264 tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', { 4265 MenuItem : function(id, s) { 4266 this.parent(id, s); 4267 this.classPrefix = 'mceMenuItem'; 4268 }, 4269 4270 setSelected : function(s) { 4271 this.setState('Selected', s); 4272 this.selected = s; 4273 }, 4274 4275 isSelected : function() { 4276 return this.selected; 4277 }, 4278 4279 postRender : function() { 4280 var t = this; 4281 4282 t.parent(); 4283 4284 // Set pending state 4285 if (is(t.selected)) 4286 t.setSelected(t.selected); 4287 } 4288 4289 }); 4290 })(); 4291 4292 /* file:jscripts/tiny_mce/classes/ui/Menu.js */ 4293 4294 (function() { 4295 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; 4296 4297 tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', { 4298 Menu : function(id, s) { 4299 var t = this; 4300 4301 t.parent(id, s); 4302 t.items = {}; 4303 t.collapsed = false; 4304 t.menuCount = 0; 4305 t.onAddItem = new tinymce.util.Dispatcher(this); 4306 }, 4307 4308 expand : function(d) { 4309 var t = this; 4310 4311 if (d) { 4312 walk(t, function(o) { 4313 if (o.expand) 4314 o.expand(); 4315 }, 'items', t); 4316 } 4317 4318 t.collapsed = false; 4319 }, 4320 4321 collapse : function(d) { 4322 var t = this; 4323 4324 if (d) { 4325 walk(t, function(o) { 4326 if (o.collapse) 4327 o.collapse(); 4328 }, 'items', t); 4329 } 4330 4331 t.collapsed = true; 4332 }, 4333 4334 isCollapsed : function() { 4335 return this.collapsed; 4336 }, 4337 4338 add : function(o) { 4339 if (!o.settings) 4340 o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o); 4341 4342 this.onAddItem.dispatch(this, o); 4343 4344 return this.items[o.id] = o; 4345 }, 4346 4347 addSeparator : function() { 4348 return this.add({separator : true}); 4349 }, 4350 4351 addMenu : function(o) { 4352 if (!o.collapse) 4353 o = this.createMenu(o); 4354 4355 this.menuCount++; 4356 4357 return this.add(o); 4358 }, 4359 4360 hasMenus : function() { 4361 return this.menuCount !== 0; 4362 }, 4363 4364 remove : function(o) { 4365 delete this.items[o.id]; 4366 }, 4367 4368 removeAll : function() { 4369 var t = this; 4370 4371 walk(t, function(o) { 4372 if (o.removeAll) 4373 o.removeAll(); 4374 4375 o.destroy(); 4376 }, 'items', t); 4377 4378 t.items = {}; 4379 }, 4380 4381 createMenu : function(o) { 4382 var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o); 4383 4384 m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem); 4385 4386 return m; 4387 } 4388 4389 }); 4390 })(); 4391 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */ 4392 4393 (function() { 4394 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element; 4395 4396 tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', { 4397 DropMenu : function(id, s) { 4398 s = s || {}; 4399 s.container = s.container || document.body; 4400 s.offset_x = s.offset_x || 0; 4401 s.offset_y = s.offset_y || 0; 4402 s.vp_offset_x = s.vp_offset_x || 0; 4403 s.vp_offset_y = s.vp_offset_y || 0; 4404 4405 if (is(s.icons) && !s.icons) 4406 s['class'] += ' noIcons'; 4407 4408 this.parent(id, s); 4409 this.onHideMenu = new tinymce.util.Dispatcher(this); 4410 this.classPrefix = 'mceMenu'; 4411 }, 4412 4413 createMenu : function(s) { 4414 var t = this, cs = t.settings, m; 4415 4416 s.container = s.container || cs.container; 4417 s.parent = t; 4418 s.constrain = s.constrain || cs.constrain; 4419 s['class'] = s['class'] || cs['class']; 4420 s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x; 4421 s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y; 4422 m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s); 4423 4424 m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem); 4425 4426 return m; 4427 }, 4428 4429 update : function() { 4430 var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th; 4431 4432 tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth; 4433 th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight; 4434 4435 if (!DOM.boxModel) 4436 t.element.setStyles({width : tw + 2, height : th + 2}); 4437 else 4438 t.element.setStyles({width : tw, height : th}); 4439 4440 if (s.max_width) 4441 DOM.setStyle(co, 'width', tw); 4442 4443 if (s.max_height) { 4444 DOM.setStyle(co, 'height', th); 4445 4446 if (tb.clientHeight < s.max_height) 4447 DOM.setStyle(co, 'overflow', 'hidden'); 4448 } 4449 }, 4450 4451 showMenu : function(x, y, px) { 4452 var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb; 4453 4454 t.collapse(1); 4455 4456 if (t.isMenuVisible) 4457 return; 4458 4459 if (!t.rendered) { 4460 co = DOM.add(t.settings.container, t.renderNode()); 4461 4462 each(t.items, function(o) { 4463 o.postRender(); 4464 }); 4465 4466 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container}); 4467 } else 4468 co = DOM.get('menu_' + t.id); 4469 4470 DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF}); 4471 DOM.show(co); 4472 t.update(); 4473 4474 x += s.offset_x || 0; 4475 y += s.offset_y || 0; 4476 vp.w -= 4; 4477 vp.h -= 4; 4478 4479 // Move inside viewport if not submenu 4480 if (s.constrain) { 4481 w = co.clientWidth - ot; 4482 h = co.clientHeight - ot; 4483 mx = vp.x + vp.w; 4484 my = vp.y + vp.h; 4485 4486 if ((x + s.vp_offset_x + w) > mx) 4487 x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w); 4488 4489 if ((y + s.vp_offset_y + h) > my) 4490 y = Math.max(0, (my - s.vp_offset_y) - h); 4491 } 4492 4493 DOM.setStyles(co, {left : x , top : y}); 4494 t.element.update(); 4495 4496 t.isMenuVisible = 1; 4497 t.mouseClickFunc = Event.add(co, 'click', function(e) { 4498 var m; 4499 4500 e = e.target; 4501 4502 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, 'mceMenuItemSub')) { 4503 m = t.items[e.id]; 4504 4505 if (m.isDisabled()) 4506 return; 4507 4508 if (m.settings.onclick) 4509 m.settings.onclick(e); 4510 4511 dm = t; 4512 4513 while (dm) { 4514 if (dm.hideMenu) 4515 dm.hideMenu(); 4516 4517 dm = dm.settings.parent; 4518 } 4519 4520 return Event.cancel(e); // Cancel to fix onbeforeunload problem 4521 } 4522 }); 4523 4524 if (t.hasMenus()) { 4525 t.mouseOverFunc = Event.add(co, 'mouseover', function(e) { 4526 var m, r, mi; 4527 4528 e = e.target; 4529 if (e && (e = DOM.getParent(e, 'TR'))) { 4530 m = t.items[e.id]; 4531 4532 if (t.lastMenu) 4533 t.lastMenu.collapse(1); 4534 4535 if (m.isDisabled()) 4536 return; 4537 4538 if (e && DOM.hasClass(e, 'mceMenuItemSub')) { 4539 //p = DOM.getPos(s.container); 4540 r = DOM.getRect(e); 4541 m.showMenu((r.x + r.w - ot), r.y - ot, r.x); 4542 t.lastMenu = m; 4543 DOM.addClass(DOM.get(m.id).firstChild, 'mceMenuItemActive'); 4544 } 4545 } 4546 }); 4547 } 4548 }, 4549 4550 hideMenu : function(c) { 4551 var t = this, co = DOM.get('menu_' + t.id), e; 4552 4553 if (!t.isMenuVisible) 4554 return; 4555 4556 Event.remove(co, 'mouseover', t.mouseOverFunc); 4557 Event.remove(co, 'click', t.mouseClickFunc); 4558 DOM.hide(co); 4559 t.isMenuVisible = 0; 4560 4561 if (!c) 4562 t.collapse(1); 4563 4564 if (t.element) 4565 t.element.hide(); 4566 4567 if (e = DOM.get(t.id)) 4568 DOM.removeClass(e.firstChild, 'mceMenuItemActive'); 4569 4570 t.onHideMenu.dispatch(t); 4571 }, 4572 4573 add : function(o) { 4574 var t = this, co; 4575 4576 o = t.parent(o); 4577 4578 if (t.isRendered && (co = DOM.get('menu_' + t.id))) 4579 t._add(DOM.select('tbody', co)[0], o); 4580 4581 return o; 4582 }, 4583 4584 collapse : function(d) { 4585 this.parent(d); 4586 this.hideMenu(1); 4587 }, 4588 4589 remove : function(o) { 4590 DOM.remove(o.id); 4591 4592 return this.parent(o); 4593 }, 4594 4595 destroy : function() { 4596 var t = this, co = DOM.get('menu_' + t.id); 4597 4598 Event.remove(co, 'mouseover', t.mouseOverFunc); 4599 Event.remove(co, 'click', t.mouseClickFunc); 4600 4601 if (t.element) 4602 t.element.remove(); 4603 4604 DOM.remove(co); 4605 }, 4606 4607 renderNode : function() { 4608 var t = this, s = t.settings, n, tb, co, w; 4609 4610 w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:150'}); 4611 co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenu' + (s['class'] ? ' ' + s['class'] : '')}); 4612 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container}); 4613 4614 if (s.menu_line) 4615 DOM.add(co, 'span', {'class' : 'mceMenuLine'}); 4616 4617 // n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'}); 4618 n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0}); 4619 tb = DOM.add(n, 'tbody'); 4620 4621 each(t.items, function(o) { 4622 t._add(tb, o); 4623 }); 4624 4625 t.rendered = true; 4626 4627 return w; 4628 }, 4629 4630 // Internal functions 4631 4632 _add : function(tb, o) { 4633 var n, s = o.settings, a, ro, it; 4634 4635 if (s.separator) { 4636 ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItemSeparator'}); 4637 DOM.add(ro, 'td', {'class' : 'mceMenuItemSeparator'}); 4638 4639 if (n = ro.previousSibling) 4640 DOM.addClass(n, 'last'); 4641 4642 return; 4643 } 4644 4645 n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItem mceMenuItemEnabled'}); 4646 n = it = DOM.add(n, 'td'); 4647 n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'}); 4648 4649 DOM.addClass(it, s['class']); 4650 // n = DOM.add(n, 'span', {'class' : 'item'}); 4651 DOM.add(n, 'span', {'class' : 'icon' + (s.icon ? ' ' + s.icon : '')}); 4652 n = DOM.add(n, s.element || 'span', {'class' : 'text', title : o.settings.title}, o.settings.title); 4653 4654 if (o.settings.style) 4655 DOM.setAttrib(n, 'style', o.settings.style); 4656 4657 if (tb.childNodes.length == 1) 4658 DOM.addClass(ro, 'first'); 4659 4660 if ((n = ro.previousSibling) && DOM.hasClass(n, 'mceMenuItemSeparator')) 4661 DOM.addClass(ro, 'first'); 4662 4663 if (o.collapse) 4664 DOM.addClass(ro, 'mceMenuItemSub'); 4665 4666 if (n = ro.previousSibling) 4667 DOM.removeClass(n, 'last'); 4668 4669 DOM.addClass(ro, 'last'); 4670 } 4671 4672 }); 4673 })(); 4674 /* file:jscripts/tiny_mce/classes/ui/Button.js */ 4675 4676 (function() { 4677 var DOM = tinymce.DOM; 4678 4679 tinymce.create('tinymce.ui.Button:tinymce.ui.Control', { 4680 Button : function(id, s) { 4681 this.parent(id, s); 4682 this.classPrefix = 'mceButton'; 4683 }, 4684 4685 renderHTML : function() { 4686 var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">'; 4687 4688 if (s.image) 4689 h += '<img class="icon" src="' + s.image + '" /></a>'; 4690 else 4691 h += '<span class="icon ' + s['class'] + '"></span></a>'; 4692 4693 return h; 4694 }, 4695 4696 postRender : function() { 4697 var t = this, s = t.settings; 4698 4699 tinymce.dom.Event.add(t.id, 'click', function(e) { 4700 if (!t.isDisabled()) 4701 return s.onclick.call(s.scope, e); 4702 }); 4703 } 4704 4705 }); 4706 })(); 4707 4708 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */ 4709 4710 (function() { 4711 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; 4712 4713 tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', { 4714 ListBox : function(id, s) { 4715 var t = this; 4716 4717 t.parent(id, s); 4718 t.items = []; 4719 t.onChange = new Dispatcher(t); 4720 t.onPostRender = new Dispatcher(t); 4721 t.onAdd = new Dispatcher(t); 4722 t.onRenderMenu = new tinymce.util.Dispatcher(this); 4723 t.classPrefix = 'mceListBox'; 4724 }, 4725 4726 select : function(v) { 4727 var t = this, e, fv; 4728 4729 // Do we need to do something? 4730 if (v != t.selectedValue) { 4731 e = DOM.get(t.id + '_text'); 4732 t.selectedValue = v; 4733 4734 // Find item 4735 each(t.items, function(o) { 4736 if (o.value == v) { 4737 DOM.setHTML(e, DOM.encode(o.title)); 4738 fv = 1; 4739 return false; 4740 } 4741 }); 4742 4743 // If no item was found then present title 4744 if (!fv) { 4745 DOM.setHTML(e, DOM.encode(t.settings.title)); 4746 DOM.addClass(e, 'title'); 4747 e = 0; 4748 return; 4749 } else 4750 DOM.removeClass(e, 'title'); 4751 } 4752 4753 e = 0; 4754 }, 4755 4756 add : function(n, v, o) { 4757 var t = this; 4758 4759 o = o || {}; 4760 o = tinymce.extend(o, { 4761 title : n, 4762 value : v 4763 }); 4764 4765 t.items.push(o); 4766 t.onAdd.dispatch(t, o); 4767 }, 4768 4769 getLength : function() { 4770 return this.items.length; 4771 }, 4772 4773 renderHTML : function() { 4774 var h = '', t = this, s = t.settings; 4775 4776 h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>'; 4777 h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'text', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>'; 4778 h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>'; 4779 h += '</tr></tbody></table>'; 4780 4781 return h; 4782 }, 4783 4784 showMenu : function() { 4785 var t = this, p1, p2, e = DOM.get(this.id), m; 4786 4787 if (t.isDisabled() || t.items.length == 0) 4788 return; 4789 4790 if (!t.isMenuRendered) { 4791 t.renderMenu(); 4792 t.isMenuRendered = true; 4793 } 4794 4795 p1 = DOM.getPos(this.settings.menu_container); 4796 p2 = DOM.getPos(e); 4797 4798 m = t.menu; 4799 m.settings.offset_x = p2.x; 4800 m.settings.offset_y = p2.y; 4801 4802 // Select in menu 4803 if (t.oldID) 4804 m.items[t.oldID].setSelected(0); 4805 4806 each(t.items, function(o) { 4807 if (o.value === t.selectedValue) { 4808 m.items[o.id].setSelected(1); 4809 t.oldID = o.id; 4810 } 4811 }); 4812 4813 m.showMenu(0, e.clientHeight); 4814 4815 Event.add(document, 'mousedown', t.hideMenu, t); 4816 DOM.addClass(t.id, 'mceListBoxSelected'); 4817 }, 4818 4819 hideMenu : function(e) { 4820 var t = this; 4821 4822 if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) { 4823 DOM.removeClass(t.id, 'mceListBoxSelected'); 4824 Event.remove(document, 'mousedown', t.hideMenu, t); 4825 4826 if (t.menu) 4827 t.menu.hideMenu(); 4828 } 4829 }, 4830 4831 renderMenu : function() { 4832 var t = this, m; 4833 4834 m = t.settings.control_manager.createDropMenu(t.id + '_menu', { 4835 menu_line : 1, 4836 'class' : 'mceListBoxMenu noIcons', 4837 max_width : 150, 4838 max_height : 150 4839 }); 4840 4841 m.onHideMenu.add(t.hideMenu, t); 4842 4843 m.add({ 4844 title : t.settings.title, 4845 'class' : 'mceMenuItemTitle' 4846 }).setDisabled(1); 4847 4848 each(t.items, function(o) { 4849 o.id = DOM.uniqueId(); 4850 o.onclick = function() { 4851 if (t.settings.onselect(o.value) !== false) 4852 t.select(o.value); // Must be runned after 4853 }; 4854 4855 m.add(o); 4856 }); 4857 4858 t.onRenderMenu.dispatch(t, m); 4859 t.menu = m; 4860 }, 4861 4862 postRender : function() { 4863 var t = this; 4864 4865 Event.add(t.id, 'click', t.showMenu, t); 4866 4867 // Old IE doesn't have hover on all elements 4868 if (tinymce.isIE6 || !DOM.boxModel) { 4869 Event.add(t.id, 'mouseover', function() { 4870 if (!DOM.hasClass(t.id, 'mceListBoxDisabled')) 4871 DOM.addClass(t.id, 'mceListBoxHover'); 4872 }); 4873 4874 Event.add(t.id, 'mouseout', function() { 4875 if (!DOM.hasClass(t.id, 'mceListBoxDisabled')) 4876 DOM.removeClass(t.id, 'mceListBoxHover'); 4877 }); 4878 } 4879 4880 t.onPostRender.dispatch(t, DOM.get(t.id)); 4881 } 4882 4883 }); 4884 })(); 4885 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */ 4886 4887 (function() { 4888 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; 4889 4890 tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', { 4891 NativeListBox : function(id, s) { 4892 this.parent(id, s); 4893 this.classPrefix = 'mceNativeListBox'; 4894 }, 4895 4896 setDisabled : function(s) { 4897 DOM.get(this.id).disabled = s; 4898 }, 4899 4900 isDisabled : function() { 4901 return DOM.get(this.id).disabled; 4902 }, 4903 4904 select : function(v) { 4905 var e = DOM.get(this.id), ol = e.options; 4906 4907 v = '' + (v || ''); 4908 4909 e.selectedIndex = 0; 4910 each(ol, function(o, i) { 4911 if (o.value == v) { 4912 e.selectedIndex = i; 4913 return false; 4914 } 4915 }); 4916 }, 4917 4918 add : function(n, v, a) { 4919 var o, t = this; 4920 4921 a = a || {}; 4922 a.value = v; 4923 4924 if (t.isRendered()) 4925 DOM.add(DOM.get(this.id), 'option', a, n); 4926 4927 o = { 4928 title : n, 4929 value : v, 4930 attribs : a 4931 }; 4932 4933 t.items.push(o); 4934 t.onAdd.dispatch(t, o); 4935 }, 4936 4937 getLength : function() { 4938 return DOM.get(this.id).options.length - 1; 4939 }, 4940 4941 renderHTML : function() { 4942 var h, t = this; 4943 4944 h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --'); 4945 4946 each(t.items, function(it) { 4947 h += DOM.createHTML('option', {value : it.value}, it.title); 4948 }); 4949 4950 h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h); 4951 4952 return h; 4953 }, 4954 4955 postRender : function() { 4956 var t = this, ch; 4957 4958 t.rendered = true; 4959 4960 function onChange(e) { 4961 var v = e.target.options[e.target.selectedIndex].value; 4962 4963 t.onChange.dispatch(t, v); 4964 4965 if (t.settings.onselect) 4966 t.settings.onselect(v); 4967 }; 4968 4969 Event.add(t.id, 'change', onChange); 4970 4971 // Accessibility keyhandler 4972 Event.add(t.id, 'keydown', function(e) { 4973 var bf; 4974 4975 Event.remove(t.id, 'change', ch); 4976 4977 bf = Event.add(t.id, 'blur', function() { 4978 Event.add(t.id, 'change', onChange); 4979 Event.remove(t.id, 'blur', bf); 4980 }); 4981 4982 if (e.keyCode == 13 || e.keyCode == 32) { 4983 onChange(e); 4984 return Event.cancel(e); 4985 } 4986 }); 4987