From 1b58fc3d4fa33938e15e90b8c3d57096c7e0be7e Mon Sep 17 00:00:00 2001 From: avl Date: Thu, 2 Oct 2008 23:51:13 +0300 Subject: [PATCH] Tiny MCE images plugin --- ipf.php | 4 + .../tiny_mce/plugins/images/css/default.css | 216 + .../media/tiny_mce/plugins/images/desktop.ini | 4 + .../tiny_mce/plugins/images/editor_plugin.js | 1 + .../plugins/images/editor_plugin_src.js | 38 + .../media/tiny_mce/plugins/images/fancy.htm | 110 + .../media/tiny_mce/plugins/images/images.htm | 239 + .../tiny_mce/plugins/images/images/arrow.gif | Bin 0 -> 101 bytes .../plugins/images/images/back/back.gif | Bin 0 -> 157 bytes .../plugins/images/images/back/browse.gif | Bin 0 -> 1136 bytes .../plugins/images/images/back/clean.gif | Bin 0 -> 713 bytes .../plugins/images/images/back/del_file.gif | Bin 0 -> 1175 bytes .../plugins/images/images/back/files.gif | Bin 0 -> 784 bytes .../plugins/images/images/back/larr.gif | Bin 0 -> 1132 bytes .../plugins/images/images/back/left.gif | Bin 0 -> 316 bytes .../plugins/images/images/back/new_folder.gif | Bin 0 -> 766 bytes .../plugins/images/images/back/ok.gif | Bin 0 -> 1192 bytes .../plugins/images/images/back/right.gif | Bin 0 -> 317 bytes .../tiny_mce/plugins/images/images/bar.gif | Bin 0 -> 163 bytes .../tiny_mce/plugins/images/images/failed.png | Bin 0 -> 1391 bytes .../tiny_mce/plugins/images/images/file.png | Bin 0 -> 1008 bytes .../tiny_mce/plugins/images/images/folder.gif | Bin 0 -> 632 bytes .../tiny_mce/plugins/images/images/icon.gif | Bin 0 -> 631 bytes .../plugins/images/images/progress.gif | Bin 0 -> 796 bytes .../plugins/images/images/success.png | Bin 0 -> 844 bytes .../plugins/images/images/upload_back.gif | Bin 0 -> 609 bytes .../plugins/images/images/uploading.png | Bin 0 -> 1211 bytes .../plugins/images/js/FancyUpload2.js | 449 ++ .../plugins/images/js/Fx.ProgressBar.js | 40 + .../plugins/images/js/JsHttpRequest.js | 576 ++ .../plugins/images/js/Swiff.Uploader.js | 110 + .../plugins/images/js/Swiff.Uploader.swf | Bin 0 -> 3687 bytes .../tiny_mce/plugins/images/js/images.js | 24 + .../tiny_mce/plugins/images/js/mootools.js | 5209 +++++++++++++++++ .../media/tiny_mce/plugins/images/langs/en.js | 3 + .../tiny_mce/plugins/images/langs/en_dlg.js | 22 + .../media/tiny_mce/plugins/images/langs/ru.js | 3 + .../tiny_mce/plugins/images/langs/ru_dlg.js | 22 + .../media/tiny_mce/plugins/images/read_ru.txt | 3 + .../images/server_connector/JsHttpRequest.php | 521 ++ .../plugins/images/server_connector/ajax.php | 20 + .../images/server_connector/files_conn.php | 8 + .../images/server_connector/tinyimages.php | 490 ++ ipf/form/widget/htmlinput.php | 32 +- 44 files changed, 8124 insertions(+), 20 deletions(-) create mode 100755 ipf/admin/media/tiny_mce/plugins/images/css/default.css create mode 100755 ipf/admin/media/tiny_mce/plugins/images/desktop.ini create mode 100755 ipf/admin/media/tiny_mce/plugins/images/editor_plugin.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/editor_plugin_src.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/fancy.htm create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images.htm create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/arrow.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/back.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/browse.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/clean.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/del_file.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/files.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/larr.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/left.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/new_folder.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/ok.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/back/right.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/bar.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/failed.png create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/file.png create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/folder.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/icon.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/progress.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/success.png create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/upload_back.gif create mode 100755 ipf/admin/media/tiny_mce/plugins/images/images/uploading.png create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/FancyUpload2.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/Fx.ProgressBar.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/JsHttpRequest.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/Swiff.Uploader.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/Swiff.Uploader.swf create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/images.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/js/mootools.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/langs/en.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/langs/en_dlg.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/langs/ru.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/langs/ru_dlg.js create mode 100755 ipf/admin/media/tiny_mce/plugins/images/read_ru.txt create mode 100755 ipf/admin/media/tiny_mce/plugins/images/server_connector/JsHttpRequest.php create mode 100755 ipf/admin/media/tiny_mce/plugins/images/server_connector/ajax.php create mode 100755 ipf/admin/media/tiny_mce/plugins/images/server_connector/files_conn.php create mode 100755 ipf/admin/media/tiny_mce/plugins/images/server_connector/tinyimages.php diff --git a/ipf.php b/ipf.php index 491a505..15a1692 100644 --- a/ipf.php +++ b/ipf.php @@ -75,6 +75,10 @@ final class IPF{ IPF::$settings['media_url'] = '/media/'; } + if (!isset(IPF::$settings['tiny_mce_url'])){ + IPF::$settings['tiny_mce_url'] = '/media/tiny_mce/'; + } + if (!isset(IPF::$settings['admin_media_url'])){ IPF::$settings['admin_media_url'] = '/ipf/ipf/admin/media/'; } diff --git a/ipf/admin/media/tiny_mce/plugins/images/css/default.css b/ipf/admin/media/tiny_mce/plugins/images/css/default.css new file mode 100755 index 0000000..acac999 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/css/default.css @@ -0,0 +1,216 @@ +.all { + width:100%; + height:100%; +} +html, body { height:99%; } +html, body, td, th { + padding:0px; + margin:0px; + vertical-align:top; + font-family:Verdana,Arial,Helvetica,sans-serif; + font-size:10px; +} +img { border:none; } + +.header { + height:50px; +} + +.header .path { + margin-bottom:3px; + padding:2px; + font-size:14px; + border-left: #888 solid 1px; + border-top: #888 solid 1px; + border-right: #ccc solid 1px; + border-bottom: #ccc solid 1px; +} +.header .path a { + background: transparent url(../images/arrow.gif) left center no-repeat; + padding: 2px 10px 3px 15px; + text-decoration:none; +} +.header .path a:hover { background-color:#cfe1fc; } + +.header img { vertical-align:middle; } +.header .path .first { background:none; padding:0px 10px 0px 0px; } + +.panel { background:#468da0 url(../images/back/back.gif) top repeat-x; height:32px; } +.p1 { background:transparent url(../images/back/left.gif) left no-repeat; height:32px; } +.p2 { background:transparent url(../images/back/right.gif) right no-repeat; height:32px; } +.panel .btns a { + color: white; + height:32px; + text-decoration:none; + margin:0 5px 0 10px; +} +.panel .btns img { vertical-align:middle; } + +.left { + border-right:1px solid #ddd; + width:150px; +} + +.content { + +} + +h1.blue_header { + font-size:16px; + font-weight:normal; + color:#6FA8DC; + margin-bottom:10px; +} + +.folder { + background: transparent url(../images/folder.gif) left center no-repeat; + margin: 1px 10px 1px 5px; + padding:1px; + height:16px; + font-size:12px; +} + +.folder a { + padding:0 0 0 20px; + text-decoration:none; + outline: none; +} + + +.item { + width:120px; + height:150px; + margin:5px 0 0 5px; + float:left; + overflow:hidden; +} +.item:hover { background-color:#deecff; } +.item img { width:100px; height:100px; margin:10px; } +.item .labels { color:#0a4d76; text-align:center; } +.item_ { + background-color:#cfe1fc; +} +.item_:hover { + background-color:#bfd9ff; +} + +.upload { + background:transparent url(../images/upload_back.gif) top repeat-x; + text-align: center; +} +.upload input { + font-size: 20px; + font-family: serif; + margin: 10px 0 10px 0; + width: 150px; +} + +#mainfield { + width:530px; + height:475px; + overflow:scroll; +} + + + +/* Fancy */ +#demo-status +{ + /*background-color: #F9F7ED;*/ + padding: 10px 15px; + width: 420px; +} + +#demo-status fieldset +{ + padding: 0.5em 1em; + border: none; +} + +#demo-status legend +{ + display: block; + font: 1.2em bold Verdana, Geneva, Arial, Helvetica, sans-serif; +} + +#demo-status .progress +{ + background: white url(../images/progress.gif) no-repeat; + background-position: +50% 0; + margin-right: 0.5em; +} + +#demo-status .progress-text +{ + font-size: 0.9em; + font-weight: bold; +} + +#demo-list +{ + list-style: none; + width: 450px; + /*overflow: auto;*/ + margin: 0; +} + +#demo-list li.file +{ + border-bottom: 1px solid #eee; + /*overflow: auto;*/ + background: url(../images/file.png) no-repeat 4px 4px; +} +#demo-list li.file.file-uploading +{ + background-image: url(../images/uploading.png); + background-color: #D9DDE9; +} +#demo-list li.file.file-success +{ + background-image: url(../images/success.png); +} +#demo-list li.file.file-failed +{ + background-image: url(../images/failed.png); +} + +#demo-list li.file .file-name +{ + font-size: 1.2em; + margin-left: 44px; + display: block; + line-height: 40px; + height: 40px; + font-weight: bold; +} +#demo-list li.file .file-size +{ + line-height: 20px; + float: right; +} +#demo-list li.file .file-info +{ + display: block; + margin-left: 44px; +} +#demo-list li.file .file-remove +{ + clear: right; + float: right; + line-height: 20px; +} +.overall-title { + font-size: 16px; + margin: 0 0 3px 5px; +} +.current-title { + font-size: 16px; + margin: 8px 0 3px 5px; +} +.current-text { + position: absolute; + right:10px; + top: 65px; + width:320px; + font-size: 15px; +} \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/desktop.ini b/ipf/admin/media/tiny_mce/plugins/images/desktop.ini new file mode 100755 index 0000000..8a96fbb --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/desktop.ini @@ -0,0 +1,4 @@ +[ViewState] +Mode= +Vid= +FolderType=NotSpecified diff --git a/ipf/admin/media/tiny_mce/plugins/images/editor_plugin.js b/ipf/admin/media/tiny_mce/plugins/images/editor_plugin.js new file mode 100755 index 0000000..dd30479 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/editor_plugin.js @@ -0,0 +1 @@ +(function(){tinymce.create('tinymce.plugins.Images',{init:function(ed,url){ed.addCommand('mceImages',function(){ed.windowManager.open({file:url+'/images.htm',width:700,height:550,inline:1},{plugin_url:url})});ed.addButton('images',{title:'images.desc',cmd:'mceImages',image:url+'/images/icon.gif'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('images',n.nodeName=='IMG')})},getInfo:function(){return{longname:'Images',author:'Antonov Andrey',authorurl:'http://dustweb.ru/',infourl:'http://dustweb.ru/log/projects/tinymce_images/',version:"1.0"}}});tinymce.PluginManager.add('images',tinymce.plugins.Images)})(); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/editor_plugin_src.js b/ipf/admin/media/tiny_mce/plugins/images/editor_plugin_src.js new file mode 100755 index 0000000..16cb6f3 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/editor_plugin_src.js @@ -0,0 +1,38 @@ +(function() { + tinymce.create('tinymce.plugins.Images', { + init : function(ed, url) { + ed.addCommand('mceImages', function() { + ed.windowManager.open({ + file : url + '/images.htm', + width : 700, + height : 550, + inline : 1 + }, { + plugin_url : url + }); + }); + + ed.addButton('images', { + title : 'images.desc', + cmd : 'mceImages', + image : url + '/images/icon.gif' + }); + + ed.onNodeChange.add(function(ed, cm, n) { + cm.setActive('images', n.nodeName == 'IMG'); + }); + }, + + getInfo : function() { + return { + longname : 'Images', + author : 'Antonov Andrey', + authorurl : 'http://dustweb.ru/', + infourl : 'http://dustweb.ru/log/projects/tinymce_images/', + version : "1.0" + }; + } + }); + + tinymce.PluginManager.add('images', tinymce.plugins.Images); +})(); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/fancy.htm b/ipf/admin/media/tiny_mce/plugins/images/fancy.htm new file mode 100755 index 0000000..779f2af --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/fancy.htm @@ -0,0 +1,110 @@ + + + + {#images_dlg.fancy_title} + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+ + + diff --git a/ipf/admin/media/tiny_mce/plugins/images/images.htm b/ipf/admin/media/tiny_mce/plugins/images/images.htm new file mode 100755 index 0000000..0a98b80 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/images.htm @@ -0,0 +1,239 @@ + + + + {#images_dlg.title} + + + + + + + + + + + +
+
{#images_dlg.del_sel_folder}
+
{#images_dlg.sel_files_for_del}
+
{#images_dlg.files_to_del}
+
{#images_dlg.delete_str}
+
+ + + + + + + + + +
+
+ +
+ +
+ + + + + +
+ + +
+ +
+
+
+ + + + + + diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/arrow.gif b/ipf/admin/media/tiny_mce/plugins/images/images/arrow.gif new file mode 100755 index 0000000000000000000000000000000000000000..5549ad4ede3b61c7ec574b6099482a418f5deb1c GIT binary patch literal 101 zcmZ?wbhEHbWMyDy*v!Fj=kZHEK7Lj+s014?|_ zmgLXf>eM!0HKo<5ex68pm0isou7Hxj&Sioj<&{f!OGej5Bvx|+YJ1av?I$W8`UsRvhC=<>60gC&Yr8AJonbkn=hU}FPgf%a_W+{ReP4K-@1O=E|IW`S1(^ZxPM{6fIjp2bBot`)3-^@blV{H6_Rh_pwK1{0 z@ynMll}mR=BvxBgPW7F-N-wvERmXAD=^J$`_LeT(A)nBgHEZ+K!{<~}TJz^_b!wa6 zv}!-YD4;TrBUb;M^sXnKAL?WQ|}wrz4w|o}S*pC30i26JLi`P|B+-l?`2zI&zQh?6~~w zNaJFU!Xq!7Rh(F)JdgQ!I&9UNz?P8mL%=zyuiZpmrb9Gag{PfcOef}nK+AD%j)I3) zf|nG!SU9z%Qf3@@)EK|t>{`x=3kw)0^NJMhNIWpZaHfugTE+#3M0a5mZli3s0Cg4- z)tIUSD-W_YzP!vOqO&oH$$6e&$%GY^ldZNk-i~&eaHMBE literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/clean.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/clean.gif new file mode 100755 index 0000000000000000000000000000000000000000..6abb6f280cadbce546cb0c93994dd28ecf35468f GIT binary patch literal 713 zcmb7>=}(ez0LOnIBIrC?Hc`_&%6U*}r>!@l&7;g_m#)%ecFfkbRc@}W;g#mp7R@8m zQWJERO$`K1MM=^{8c0;Wa2^P9JP$lP+#s6vAM|c6NCT-049^k zVzC&F2DMscwOU~qG8j;WLT)e^OeW*%s={Wo>2z8I(TOBdtyXI`n^9CRmi|(yl;WS# z{Q6$KUT-uS?RLAv;Xn|?Znr6wt4`}yaL4s}#9}cIe4Wv1VaC8{F1<&iQFjdR zY&NUIVK`~6-kIs>)cJ|1ETsbYBLs8`68+JispXB#kRuw}9L8IR#Fa)6}IxL*k zz*@0Hs)k{uMw4CJ?Q}ZV*Vl)?iB%9RlPz~}#x_qVR4SHWn#LSz{J<$^7+N~zQ zZG)CqQd(Aey`u72<=yI<+L{|L=r8G4>l+#yZoY1AX};as*4|dYV0JQN4_rQbGAr{; zQqB(6DFQYIgNwp>q$Wp1TqF>EaHQx4-75Q&_AG%Zdn@xKrhjq?GN z1T1kOI5=R5~ji%?@2xs zM+21Sgn$4Rpe$2dJVVLZ1ThWc;uD$S8<{2>cfs$^^_`;U^J(5>cfwv|X#)5rdPOcS zKA=g6JH6H-iv#>P;U>=g2pK;piSu!Oh>EJ` g-*ajfc(jcw|8#CF^>F3(n2dC0pKP+$1p|)%1zgK_^8f$< literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/del_file.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/del_file.gif new file mode 100755 index 0000000000000000000000000000000000000000..f094e1420ed1da6817c80554fe0bb7cb4efcc002 GIT binary patch literal 1175 zcmZ?wbhEHb6kt$b_|Cx4v}(U(bZzpq4RMp!iiB4QhLlJ2ty*MjJ~1V2vABR=n_TuOz)tN&4&7O>5QUUu{^sTvqHwXX`vUv0bWi+a0ZT*ja2>m5VCr z+HGlcy|nOQYr}!akoii|eFi$}o+;1!x?c8mEw{J4)L6T{sd2q1-&#?=gOMS#rA6k- ziSPAwUty&4a>LqkW0NvtlWujD9(9%btqnUZjb_M+PnQ!v6yUW~N%~<$$+@`53k|hr zGE-K_irp$Jde+%`I4*LXp86_zi7T1Ox28^NZu6{cDx{GTT|nK0Ixm1?)TCX)|%)Y_Hy0nXmva{^JQ1-8YSsNejaN~^j64A zL>G4+jf-4iZ+Rj&bC$Ho>A1*OU9FW%cSj^vTU1W=WcasoB#j+e}+*24gtlVEMQs(M1t}J1IK>`V@?^54GC)g9Ku>L zFE|?xw+kpU{czd1=xFzRgUmZ8HY%$HC^&b?aITtia^S1#Gts=j&*ZECC#Qg2$&D2O z2cLRNXvbBh1T0wAKhtr!##PHLFG6NH*uT*bP+WO>a&W^;7RH)W6P6k(nPe1hapzAw z)FgCQb4g;yA`81Bg{nUt$EV6#Jqb~CR&JYQ-@i~N)8sg-sAfY#!^|%d9|WbN<9rMQ z-Q0u^af=D8Q(>9ZDJbyCBD3I?LlXHR8yIj@u+jwj75*Sbhc%jQZqQF@wjJpPtxOFi)R*I Q>NekAJno;%!opw;0L!^|bN~PV literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/files.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/files.gif new file mode 100755 index 0000000000000000000000000000000000000000..9ef118527ed743a081c1d9576b8b9ef60f112df9 GIT binary patch literal 784 zcmV+r1MmDtNk%w1VG{r#0OkMyHFcHd=jU6Ftr;>wTVZTsUTGFrePmo`Wm{)eimC=n zbWVn*NrI#aI8+2cWCk`<9yLN`TxbnYcM(&11|cyCB{T|7b_h*%GG~PbMRF5LYXl!J z{r&wrc$)=Fbp=awFHmFzJzoVbM)LCV`1tty`};q8o2q{7jq=GIpEL{{O$U z;rjpobDp@6zM5T=aebw|2Rc}geE=auSP)NiUS4V)T!E0jF~@r{R)?fQImvUx|2}Y! z2|{F$&;N&N{|rcLtklZ2;IRNT0Hm#)J&q62+EficU5384ez*D}XO(Bh9WPXB))@d{ zovuuhs{a4~rQQFa>;EA`S3-lIFHBzG;o;%o;>qEXfvCSQUU^G*lDy!`99)5Np12}l zg?FO6fT+JqlB#^Ay(?*qXqU5XnzcZKpRviuLvMgSNC+R#YBkwyoI9XenzGN5EhGZ;duRO!J(1_vQx#&nROrOlQKK72rSjHb?? zIu+#nvE)h_GF(dd$(PN6f(sW&fGJW%N)r+r9y}1imFt5G7A&Ax<7J1BD=0SPQ$YlZ z1ql*uMkw)uCCic#6dE*8!MDK_xDzJSs1YNL3>X0@XnC=s@rxsY4H(d1qk?72HZ(}y zycv$?&!9tpP9mqY>C>o9=eWbVwd>ce0mzs3`)3$^su#_vH zWWv74hV5n(4@9~*E!=RvZ_DYvrNu4p1I~N`=$ylr$KdpPgu@e7=s@g5)TP{sl zduE1xO=01Bh1RuMi;lLGZdNQ?XR!8kzo36!>U_1btqLV;OiDJ%w`~cXbD*qYysT36obeZMUyp=TN^Ue*VF#s*PrqThtntHz}vacCYJh+a6J{Mx|k&O8>5yt{w3< z6(xPUBjgg|(-tVlPVT()bmz`1(_*LD+1FG$)m2%R7Rkg`E;v?PwpD)J+5XwPdKVrm z*?4Yp)dmO7fRfs+rdzK~%3iMM*<9PU-@>7`vSpW@Vp4X&f`pC(w)2k`mu^-L>TaHU zxOmBl%BacCa}Sl)Z#U0ctl7OQK{q>7CN9CJL;vutO}5qLfgMZNpY2_DuCHLFu0d)> z+?1~NeRh3&BC9qT&pT2Q)H1j4nDg|b>D@acr|c{2-VqVj(_gp6zHp6d?FOHX7y6{* z~ z!IX4j7H`lWhlT@bCppyH7?vLVeDw4*6;Umdg9hq7T#}JiA8r(?^D(mvDp@2vQ1h$GEsTa*%?CV3;w)3tnR)*z{_XBhYLwvtP0IyItIIqC23AD^R>j_lw6|9_8$(t`#Tu@xs&IMh}=Xqv3^=s~l9 a+YS#^k+6)1ty4`FJ#3RHyW!!$U=0Ac$84Pd literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/left.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/left.gif new file mode 100755 index 0000000000000000000000000000000000000000..6d6d7400ce57575b82eb2f888243847a4d7a76e4 GIT binary patch literal 316 zcmV-C0mJ@BNk%w1VFLgl0M!5h1xR!cPkIDMbatS-TZErYgQi-9pRC2!2T66X$k?L3 z(XPkWNPnbQgP)VY&SHt9puEq)+Tu!(s$h_?SAw3Y!_+x-oIin|ah$k9d!d7?zm&Af zDQ1jjm9y00>88QcY?7-BOm_%Nc4m#Ig{s19n6-bVzaU+OUWTEHw#Rv(x0tugREVmd zrK?(utprGQjIYLtt;AS^o`b2uo4L(2a+Mlbfmni`d!xONvBz?luoP2$J$Rl1C_!6h zaR2}SA^8LV00000EC2ui00RIZ000JAz?N_5N%$5f-vQ^V416DqPf_wgIzHOOw{rP5 zEMKnRgE4%ujE}_g%`863%hwS2WB}g{;WLPQ1R*{s0X`2qJ|i|hASXUL96l;FJ{lK3 ODH1*r4n93SK>$0FJdADt literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/new_folder.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/new_folder.gif new file mode 100755 index 0000000000000000000000000000000000000000..79392dee5471ac7df50cfd6bf134f553a4a8c8f3 GIT binary patch literal 766 zcmVW%m5iuL7!{rIZ-@Rk!-c_n3qqot7a<9$|PboAwh^5A^);Cb=faq!!9 z{Pv~%^`ZOnnps_Ib)mR#owfY-s8e8hSzvDa@|^ndo$}sz@Z5Ou+;lE&j8R^D_UDGg zpJu9)Xw{D>{<9)#o3tNbf_|vJf~&y)&01oWuk7sX)2~v|tWDXsUh>{_`0S6?vsm4` zX3VBT&Z$WD=!ZUio&5BlSdOau^PckGd;9Xd|H)BRUvlQfdiLm$_UVxM@0j!9f8)J$ z^x}bGc5nUor}gEC1uQ}G;CGOhdiCUfzR9@s;(P!6xcl;;?AfR2)r9!#lgOrIT)Evy zrPFGfv+&w-`}M#5yE*aQc=Y49_wBa$?YNtuj7*26<;GWns=w>cTk+j}Z=SV6ho6G0 zzb9YrPv z3@|m-L`u!vMII4kFEB`D2a_oksyNj!CPfZ6V2lC)vgCr36Dhck*#N{% zm=-u&f0T7%#LR}ZD1NwM<3fT2I)DQUrqjYj6u*2DD_+c)51z-6BR`fwS;mCRm@{jh wpkj{a&!9u+8BMyh={y1As9w#wb)VO;W6SRIr?&0exc^Ym!@IZd-+=%CJCC!PVgLXD literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/ok.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/ok.gif new file mode 100755 index 0000000000000000000000000000000000000000..a02750411ff866a9fff5b9f8f0b65316e416e947 GIT binary patch literal 1192 zcmZ?wbhEHb6kt$b_|Cx4v}%9yv<;HcwQ-ZyiiB51^sN#MDG!~kGxKCpU~f&tT%Bug zHpEO?5I9{=D=*2l)5U+9&bgfFMl z6$+7aOq4PsYu8nKw9HV+NLq0@-?_Pb-PKCh){@wz3h|4ygL`Y@7i)L!3+vt=vi#_r zpqVew-uj)+ ziOW=~ws=%;bFE#U;xS1hbhc*i!LY2=rn~NRw{B0JbTBh=fy(J;3t|^5@4ed_GE2v% z*(rUs`ks5;p|iF3U)zYH!Y1@+YgPBr(Mq;vG@;fl5CJMXkb&e!mmpfl%0;pu1dryNPH-W-s$RNH@sYRT%L z;8~iB&gIwb@YsE~t9GaT#_QD?%N&Ad>fCy_t!0mA`YQGP*LLo`*R$?Q&E#YL-hCl+ z&m{Qtg#=AEo_R8H$E~*VH5rKu>=&F*a_=))d~kNyeA$wX)}9k}mR%@Vajwm0qD|m* zop_+DZq((hF>~!PNnNfRFiR$FrB3sXs5z(OXY6YWpQ~-#>=ZUfbN}W2o37Wbx{?z$ zU%mUFZ{^b65sB3nl~aAEuF}ixVbyWmboxf!ioK-^cgQC+X3g3>_3$~>l-B&YTbwrj5o?zhk&ydb3NeM8y8t~|hirYG;y$c;raLlus>y^Ra*v_KhXX(;W z(W*LQk)(=7qr^gXMy8PdTM=4HY7rZPC-wC-xGeRVWZNOd`7rT^*BVhRnM$rJF2So+ z?OY`NOcMpBsC(#zN(P@W5EeW5%wlFi^ORYEtE&#&5IVXc(cZ}CspIMBir@ZbP5ugQl7W|07m19}Q= z8jm`5|44e&sj=)ux312%7mvEPT~K=5V{*-d+rZ-4ipPBit~`3&@4y!6t?we1`DEhW QJByx7@-eIQc3`ju046`h761SM literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/back/right.gif b/ipf/admin/media/tiny_mce/plugins/images/images/back/right.gif new file mode 100755 index 0000000000000000000000000000000000000000..354e2dc083ab7a3a78a6cb5339268a928f2abcf0 GIT binary patch literal 317 zcmV-D0mA-ANk%w1VFLgl0M!5h8f$lDn4p@>&lziXXPKaBrmr1sd8y3NtIg7+$<8Ek ze4nMORGFhpm7g4Jc!aXJwA0rpbbp$|$c($dgSEViy1`_ltWcMsm%+z>v$}PywQ{1U zkG#WcoT6x%pk|q&WtpHEYN9g~kJVIM$ zaR2}SA^8LV00000EC2ui00RIZ000JBK%Z~nGWjYs-wooU?0gxUkB0DR4nAJOSAh8} zD4$H?BVl}um+unuH8{Qy$T#@-041Lz;4=_>Djq%x9X=5{J~$gbCpkVNB0ek+J}nbI PGbug-D?U9vK0yFGC0LW( literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/bar.gif b/ipf/admin/media/tiny_mce/plugins/images/images/bar.gif new file mode 100755 index 0000000000000000000000000000000000000000..abc513f888238bdd1b794e4ae36a95c5384d7596 GIT binary patch literal 163 zcmZ?wbhEHb{Kde-u!sQ!l2Vh3E32DZoB#j+4;BCsia%KxL9`Bt0I6kQ&hQYr^UvUv z=jy!{ug~uOe{%tgL*~4URqJwI?<>$bUy^%&hYU~3yZ;9k6nN+yk~p@c=wyyn^oivq zUTdTLFRm^-{r23ZdmAcpSSO!|$T{#O;x8{MXRf)ZEhACaT2A GU=09q07TjV literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/failed.png b/ipf/admin/media/tiny_mce/plugins/images/images/failed.png new file mode 100755 index 0000000000000000000000000000000000000000..7233d45d8e6e41ef8fcb318c76303a9b6f23997e GIT binary patch literal 1391 zcmV-#1(5oQP)}piCG~<@Tj_&{ee%V|SZW{gB8?y>5~HGEkRU`Q5xgR16NK8$#%7av&gnyv zB_>9ji%*39&LbK3qFu zI7(%ZZ%;}2Gqh=wf?-g1;X+qD8r}8{{PEcV%0X!tqH%6yq(DC>&`hf#DjvXW3(1702fiEY= zF5vsm0&oGwD!P6+uzb1JdigTStXXLJ`Pjl?)VXtsUA;>7;>9+ps^67D`lthR!lCrM zJiGbuAzhIO`u_b0*{$vea+<+#n+u)TG0)=^W&Y8i0fonJZU{&O3K7Vlni6`w*i02KV;P{rfRu zG0etBGUm-QC7c=+fU_{mF@F3e|CA|e+x6?%3JOrCPscC}T3cI*Mx&UfiIS0lW6Kua z*4E+=1XR`QT~P`vMhu|BsqFlGD_&EBWm!0O?*~ty__PKSBsxE>~io%jH4{flNukRa8X# z{rjXQCrg{pH?0i59u|NFLJ0B8)HQ2(TUCW{yU};B)sYgKfwF=i#fQ*|T%prYYO&>#^_Jg-l9HIC3}~D2jrjDCoMLxDnFn#I<)X9Z#O% zl~TASP4c~kT|)vm3aV6;lT*TB*>>d$((gwvEKE2_WWLjh)9HL~UI>A6!v?geQ)#cO zBP%CIQ>6UickujYfDG8-Td-iF{q<|n@$@N&XN+4a)1MXii!#xt%)zy89UYGz zG12e0NnI~2gPDT@C~$aEUY=^+y^GP-hO?w((CCB^XqtxXDMlUN#ETcC z1p+4hp6CQXDP-AvzM{13Y_09qE$nO8qUGca8odyL^73*nUc5M{b0Gw_%uGDnx6}FT z856u-Rdc(;WsuwJSM3x1@yun*tghR)G2?Oc_3NRv6|2V>LcBLlv~F)$efs`;+#5F% zJ#z;0`E&f~>DJ4JhLgbjz5vpKd|!698oPE4fasPj{qtqSV!U}nQhK`b970DyKML_) z0Ovbsj@-OC=8MgnrPMUAEG)wS)5J22?y+HDnPzw2Z#-bF|D0)J#^W@9&7>1-t%; zZoBM??ke>U^dD4er7kL=hDJeZLn7jm5(v08gqI)OnbXC!k+JW?xKusTXl69mbH4MM z@xcEq@?UJK$`~hw1@dkN7mNd7!v<|zXR5g`LOT&)eSQ72TrT&mh?I;m7-R6>>yxk%nY!jFra=|`UYN$jJFw$o6!Q~hf9-+XQxm0cZ zJOI$ON<^+(?>q^>$`OG*B(MkM>^|0nAkF)!0Ktc~6Mw%ewATx-0 z2=>Fy#)6oaAmto-RYqh2Z%eTNabbvae=k5%Xre;9nY`Cxo3Q|K&2t~+0bbw5`9+*Bg4+i7q|>%JJZgfrw$XMK(PuKxMWP1) zmY0{W>pwdb1w8NJv=RMSizu_;qj``kQ{8>c()+Ea(0)p>xdkyNp>qyZjjXz5Nh%eb zJ_06CKaG(SAOf&5#fzQa`ScU_6UFA1NR%C^9_W{0asp;?Orsp*IYRUtB#$=>{POGf z$mGS7-aUt|f-L1XOD{mFpjwHh3d#hRje(RK4xrbrCP4qK*Ol9z4QaP$ zB0w01u}ZUm;sE+(Xb;3G&N>H11xP%I05&!@FlI1uh6OanWah@e?qL{S$7*F|CG}!T zQk>+WI7tmb|J9u4iTE=iTT(+XjMA*NEST6TNGiioz`DnJl8oemyOdkq1z9qR=SBkP zt&A)XRZRu!2Phk3PF1yBE|(FB-UUGr{Oh~`$mjECz&vmawE6)`KxJ=l@5|NI)h|Rk zFN(X9=I-w9SHJ>bfdjzz`fv=G1MUG+ow>a$ literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/folder.gif b/ipf/admin/media/tiny_mce/plugins/images/images/folder.gif new file mode 100755 index 0000000000000000000000000000000000000000..9cf8707448feffcbc6947fa9ad64ee4a653b7b15 GIT binary patch literal 632 zcmV-;0*C!aNk%w1VGsZi0Oo%H*S}oa!eQ~=iPpee;>>T`$8zM0`{~%aQN*uf%(G1O?4`=EMDE^+|NsBp$YbNmU(vvK&ADgi z)O6&{ap1*O#HmQ(%5KTBTH(%X)VNjm?5^6#ed^)3<eqSu_q+M@ zw(i-3^W}>9^08dG-SzS1_x0-b@y7oB^hl-C7^5vJ%w@v2Ojl-rw+Qeqw#%SEdWb4?9+QeS;>Y4Q9jrHe_(z;R9 zy;bbjfa=_&_U^9S&3M+nTinB9-^ps}*m&yTv+&@A4IyDHF&HNn1Y?kE&=Eyo zP+1l{9UNMaNevMW2vss?-y_uc=^*Zw;dtL?t~f7#jpo3BiDT<+MjJEeN%{}~7Whwctd zoB2QUd}im?|9K1khxBUo@5x|DV-T(so`3$o_C)R44Ue@N9KQVg|K{6&g*JtNnJbNF z8c#m!Q>yXD>cK31&0cjnpurmZj9cO@Kq z^ncNjXM6Ac-+c4G=koaPzyJUJ_dmJEr+wGkS^FMk%s%(%!~e|3{CL^B11&ny~#|~X9O3S*NCChKkOk+4R)A&CaFboBt_>+Z^fx&}8 z2jo~#oG`FoY4B)jZfR|6@96C66jssG)z;9^*40xHZdY=jJ!kH0r8XHuZf+@kRaJed zC5AF>vWk3sB0O7pL^dhPwy7C#a7c0;;*#8Npw?zA&dV#rcAib>jJR=|raUL7g0i%< zvcgSy%{Ea9mgi!Ef@05EBt+ZPr6vY0I53e}fJI;xz+;8%36xsY(MsjY!ot8WFz Y&WsDq%&dF?Z!A3;0vB~LF)~;K0F_SEH~;_u literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/progress.gif b/ipf/admin/media/tiny_mce/plugins/images/images/progress.gif new file mode 100755 index 0000000000000000000000000000000000000000..2988647327b9806a9e36d8decbf51779fca5b513 GIT binary patch literal 796 zcmV+%1LOQhNk%w1Ve|nE0K@?R_4V~)WMZ4UXQ;$_c%(9luua<9+Vb-9-QC^h=H{is zcbvRvhptGX!E%48Jb9%wsm6Vsy=sE1L42n-pTBMZ0000000000000000000000000 z000000000000000A^8LW00031EC2ui0Q3P2000I5U?7fUX`X1Ru59bRa4gSsZQppV z?|kq7q{u=*ED{xiq;deE2#rPLGTD4W1=4ACc+D=IT&P#s3>(K(t9Y6OU$JbayBpuW z(Q@^41ejE#gp!cSLL&_Y z{==s);zNiOC-$qD(OyS{^g@apNwVZ3gaMQPTr5%$f=Z5LUTUNw(__p5EBB?uIg?3E zls9wg3<{Gb&z>%i65N@ye_ z9a@#S){--l#H!u9c&!rHD?vhmzkmxcc(AvyVZVX@4mQjfapJ{{3p)-BIr3z{l^Z8k zOgJ)u%bY!b-YmGYXV9fZkKUYFGi%e9Nw=0P8@B5MxO3~?&AYen-@t`qr3l`puYY4 z`19-E&%eL_{{RLk;D7`cXyAbe9#|fkbh8x}UxVGHH{W^_Zl|7w6^?hIh8v!jp@)$@ zNZx`H!uOtufFYpbiY&J1;)^iGDC3MY)@b96IOeG1jy(3rV|;>5z#eNtb{OQ4j};lB zY)VGPq>&6Xncb66N;xHwNK$5{gH$ew<%R}?Ddw1DmTBghXr`&=nryb|=9_TFDd(JY a&I!bwc;>0+o_zM{=bwNEDyRt|0027xppljU literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/images/success.png b/ipf/admin/media/tiny_mce/plugins/images/images/success.png new file mode 100755 index 0000000000000000000000000000000000000000..5b7e64910e6b549d37a0f0c0063f8b73aa15fe5a GIT binary patch literal 844 zcmV-S1GD^zP)iTsi)!sWzk*lz?LPeE-Uo}T%@-s zQdt!whEz-vJ1kmTj`L?S6+1r3isN|f_r3T0B?JF^h;-oU>gq$5Wj8>jltN00a}H~5 zXkFKZYusNN19n~4eZ0B3`5Nz+jSvZOeQ|M7J@>AkgHN z>rh<$^T)@><@90FtOq5CT`#4isw%Q9LkPji$w}y!WjUBX#lnjvh)t-q##$RHVb^tG z-qLYg&4AZ3&E97aOX8dh40u33%PA&~k|5Q-?|ZDZ;YH+WkHOY;jdN~RhNA$)3kxC0 zvW%*#26OAW4sv);D5XZ59L+#VwFe-j9QeZ+L!RdWtWs)qS)K)up6ApDaVVt*40x&1 zs<;%Zj-f9$vHt$-d(GoIvD@ud1DN_E8c-#KV6)j!mgUG`o6QET^IgQ>!(=g`yQ?JBsgD3{P*Qjq^F>gQvT}u{?*yp zSs0wtxhRUo#nbYe=lKqJ2mA!~DS!%ibANyT`TYF+6HqR$zB2MWr)e655P$CO?!Ex; z0R?;qT%1}CyaiqZTfjU|{1@?ur(|p32k;H}4HJJ(pEoX^0j(=%hrW}939;aF`8h6EU6~h6pRw<#fUA5(HIkZLB$eFlxXaVEr(SEBiJrN@Q+Zz zgEt{~k*VLboo{+?I|V!n9^4gthsO^dyuxpEY|p@!3yYASh=(9y7$!*)1OZ8sj^m&x zS}K*IC}J2!(=^jG4Z~nrmLP~YjyaAKC9$k~p6B~MMNtBTX`0HiOw+)!ESjcuT~E^_ zj$%oYB}pO)!nSQiQ3OHYixs3vS}KL2DB?JglueUFkrh=@XoevO+_oK6Q%REY+)7Bf zis!jFj;X2|grV!Xz8|Qn#G(-rCMM2j! z%eMF;Pm+XX*&NHUEaN&ZieajvVi@jM)_74Vq8U1g6Hp#TQcw^?D54meq$z|@({(7o zFbG`N#WB3xTTxYpW+;+0bluPm(=uJhQDm6{K$ayM0MGYWh7J6{aclr+%d|*>#L9U% zj{HadclO`eU*XD6km~P+s^?XcgU6oE&0U>6v3d60>i6sG>N-Che3JQ?xxVRa!$J@fosjPzx{>mbmRkb5?lbz#lGS#o!0}0VZmD2ElG`kf$#uCeP~RRYTM9I z0gVQ{q$FazRUZ~hQ>{Va$wo-DY1K$-n)qa2j35tEDO8{(Ty_^)v|5l|wp}>q_yBWy z&R$?4ee;)0&dltb`F-a5`_0T*_`jPawxhGN^MKWA?FQ_!EF(!0s;Z(Wie6S%SM{f{ zzEK~rw7R-_th>AWd!s*V9FfIxwz09%zFyb+HBB>(GqzK#+nbu2&H@_)D2n0$n3|fx zVzKBD#-|a?SWnazAi24@M59qh>~C=Znx^SaW@l&hNsEh%^?EQE)E$ZbWX?CUH~>{u z^~n;gTGV5eNd+J_j7b563dtNMbNWCOP!z>9p(sY#jn0gH!C+9Y8$%;3Wd&lLi?*g| z3=NO)+m%74ru~GMm)T{v<0;!i<&zZ@y9zf9O-cYlfmr8v78dy8%N|@sF6xgRB|k3@ zt1P3aD!1n6Isa`hfk1#)UToxHha>53NEyILzp%K-na?|U^Z09c%RD+1eg2?4~)0j`aXvU_(admecdNs>$j(47kq?_(ZHN=xV;7%-^__wy?y z0AYQ<4)E;$XX2d8vaACbRgh(wg9r9=WoU?^q9RI4O17?mF$5EnljP;(#R2$yZ2rQOCua! z-X4H42i$HqcDo%_Rdwg$+0f8HT3Q;iEYsiLZwif~sHCUwWM*cDKp>!>A=}D`ucUiKX1=dSWuuVCoE+EV-7rBQ_T;Tel$5Z)+;M3 zxp3h;&CSg^z&GFZ@_2bU>FMcP--gB<2m}HY7UVNLJi_GkRNTwLDk>@%9=-~|*!Vbu zgG1C*SK;+~O}ikGZ5jfAmm2DM?*kv#CvNDg&@@diilU&ZDkFbfqows7>S~XWlaqtZ zW{bN$V=duPY?R7kv5@U_;`{IfzLTfeTkfIu(DM`)>p= zV?ADvhuqxUl&Z7 zB}w{M)3jX<$Nf+E?R;z|de>&NEdlw!9pGLpfE~!0o16QnuCDHVAbs0j6NB9K`~7Et z0zd|C0;+LoHXsjh0uEru`oITacUfC(82ASW03k^5=XBli&UK*eYi~9cSYb`}dw`xO Z{{b8o9CwgR7rX!f002ovPDHLkV1gZnKuQ1r literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/FancyUpload2.js b/ipf/admin/media/tiny_mce/plugins/images/js/FancyUpload2.js new file mode 100755 index 0000000..6d3656d --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/js/FancyUpload2.js @@ -0,0 +1,449 @@ +/** + * FancyUpload - Flash meets Ajax for simply working uploads + * + * @version 2.0 beta 2 + * + * @license MIT License + * + * @author Harald Kirschner + * @copyright Authors + */ + +if(tinyMCEPopup.editor.settings.language != 'ru'){ +var FancyUpload2 = new Class({ + + Extends: Swiff.Uploader, + + options: { + createElement: null, + updateElement: null, + removeElement: null + }, + + initialize: function(status, list, options) { + this.status = $(status); + this.list = $(list); + + this.files = []; + + this.overallTitle = this.status.getElement('.overall-title'); + this.currentTitle = this.status.getElement('.current-title'); + this.currentText = this.status.getElement('.current-text'); + + var progress = this.status.getElement('.overall-progress'); + this.overallProgress = new Fx.ProgressBar(progress, { + text: new Element('span', {'class': 'progress-text'}).inject(progress, 'after') + }); + progress = this.status.getElement('.current-progress') + this.currentProgress = new Fx.ProgressBar(progress, { + text: new Element('span', {'class': 'progress-text'}).inject(progress, 'after') + }); + + this.parent(options); + }, + + onLoad: function() { + this.log('Uploader ready!'); + }, + + onBeforeOpen: function(file) { + this.log('Initialize upload for "{name}".', file); + }, + + onOpen: function(file, overall) { + this.log('Starting upload "{name}".', file); + file = this.getFile(file); + file.element.addClass('file-uploading'); + this.currentProgress.cancel().set(0); + this.currentTitle.set('html', 'File Progress "{name}"'.substitute(file) ); + }, + + onProgress: function(file, current, overall) { + this.overallProgress.start(overall.bytesLoaded, overall.bytesTotal); + var units = Date.parseIntervals(current.timeLeft || 0), timeLeft = []; + for (var unit in units) timeLeft.push(units[unit] + ' ' + unit); + this.currentText.set('html', 'Upload with {rate}/s. Est. time left: {timeLeft}'.substitute({ + rate: (current.rate) ? this.sizeToKB(current.rate) : '- B', + timeLeft: timeLeft.join(', ') + })); + this.currentProgress.start(current.bytesLoaded, current.bytesTotal); + }, + + onSelect: function(file, index, length) { + this.log('Checked in file ' + index + '/' + length + ' "' + file.name + '" with ' + file.size + ' bytes.'); + }, + + onAllSelect: function(files, current, overall) { + $('demo-status').style.display = 'block'; + $('demo-browse').style.display = 'none'; + this.log('Added ' + files.length + ' files, now we have (' + current.bytesTotal + ' bytes).', arguments); + this.overallTitle.set('html', 'Overall Progress ({size})'.substitute({size: this.sizeToKB(current.bytesTotal)})); + files.each(function(file) { + this.createFileElement(file); + this.files.push(file); + }, this); + this.status.removeClass('status-browsing'); + }, + + onComplete: function(file, response) { + this.log('Completed upload "' + file.name + '".', arguments); + this.currentText.set('html', 'Upload complete!'); + this.currentProgress.start(100); + file = this.getFile(file); + file.element.removeClass('file-uploading'); + var json = $H(JSON.decode(response, true)); + if (json.get('result') == 'success') { + file.element.addClass('file-success'); + file.info.set('html', json.get('size')); + } else { + file.element.addClass('file-failed'); + file.info.set('html', json.get('error') || response); + } + }, + + onError: function(file, error, info) { + this.log('Upload "' + file.name + '" failed. "{1}": "{2}".', arguments); + file = this.finishFile(file); + file.element.addClass('file-failed'); + file.info.set('html', '' + error + '
' + info); + }, + + onCancel: function() { + this.log('Filebrowser cancelled.', arguments); + this.status.removeClass('file-browsing'); + }, + + onAllComplete: function(current) { + this.log('Completed all files, ' + current.bytesTotal + ' bytes.', arguments); + this.overallTitle.set('html', 'Overall Progress (' + this.sizeToKB(current.bytesTotal) + ')'); + this.overallProgress.start(100); + this.status.removeClass('file-uploading'); + }, + + browse: function(fileList) { + var ret = this.parent(fileList); + if (ret !== true){ + this.log('Browse in progress.'); + if (ret) alert(ret); + } else { + this.log('Browse started.'); + this.status.addClass('file-browsing'); + } + }, + + upload: function(options) { + var ret = this.parent(options); + if (ret !== true) { + this.log('Upload in progress or nothing to upload.'); + if (ret) alert(ret); + } else { + this.log('Upload started.'); + this.status.addClass('file-uploading'); + this.overallProgress.set(0); + } + }, + + removeFile: function(file) { + if (!file) { + this.files.each(this.removeFileElement, this); + this.files.empty(); + } else { + if (!file.element) file = this.getFile(file); + this.files.erase(file); + this.removeFileElement(file); + } + this.parent(file); + }, + + getFile: function(file) { + var ret = null; + this.files.some(function(value) { + if ((value.name != file.name) || (value.size != file.size)) return false; + ret = value; + return true; + }); + return ret; + }, + + removeFileElement: function(file) { + file.element.fade('out').retrieve('tween').chain(Element.destroy.bind(Element, file.element)); + }, + + finishFile: function(file) { + file = this.getFile(file); + file.element.removeClass('file-uploading'); + file.finished = true; + return file; + }, + + createFileElement: function(file) { + file.info = new Element('span', {'class': 'file-info'}); + file.element = new Element('li', {'class': 'file'}).adopt( + new Element('span', {'class': 'file-size', 'html': this.sizeToKB(file.size)}), + new Element('a', { + 'class': 'file-remove', + 'href': '#', + 'html': 'Remove', + 'events': { + 'click': function() { + this.removeFile(file); + return false; + }.bind(this) + } + }), + new Element('span', {'class': 'file-name', 'html': file.name}), + file.info + ).inject(this.list); + }, + + sizeToKB: function(size) { + var unit = 'B'; + if ((size / 1048576) > 1) { + unit = 'MB'; + size /= 1048576; + } else if ((size / 1024) > 1) { + unit = 'kB'; + size /= 1024; + } + return size.round(1) + ' ' + unit; + }, + + log: function(text, args) { + if (window.console) console.log(text.substitute(args || {})); + } + +}); + +Date.parseIntervals = function(sec, max) { + var units = {}, conv = Date.durations, count = 0; + for (var unit in conv) { + var value = Math.floor(sec / conv[unit]); + if (value) { + units[unit] = value; + if ((max && max <= ++count) || !(sec -= value * conv[unit])) break; + } + } + return units; +}; + +Date.intervals = {y: 31556926, mo: 2629743.83, d: 86400, h: 3600, mi: 60, s: 1, ms: 0.001}; +} +else { +var FancyUpload2 = new Class({ + + Extends: Swiff.Uploader, + + options: { + createElement: null, + updateElement: null, + removeElement: null + }, + + initialize: function(status, list, options) { + this.status = $(status); + this.list = $(list); + + this.files = []; + + this.overallTitle = this.status.getElement('.overall-title'); + this.currentTitle = this.status.getElement('.current-title'); + this.currentText = this.status.getElement('.current-text'); + + var progress = this.status.getElement('.overall-progress'); + this.overallProgress = new Fx.ProgressBar(progress, { + text: new Element('span', {'class': 'progress-text'}).inject(progress, 'after') + }); + progress = this.status.getElement('.current-progress') + this.currentProgress = new Fx.ProgressBar(progress, { + text: new Element('span', {'class': 'progress-text'}).inject(progress, 'after') + }); + + this.parent(options); + }, + + onLoad: function() { + this.log('Uploader ready!'); + }, + + onBeforeOpen: function(file) { + this.log('Initialize upload for "{name}".', file); + }, + + onOpen: function(file, overall) { + this.log('Starting upload "{name}".', file); + file = this.getFile(file); + file.element.addClass('file-uploading'); + this.currentProgress.cancel().set(0); + this.currentTitle.set('html', 'Ñòàòóñ ôàéëà "{name}"'.substitute(file) ); + }, + + onProgress: function(file, current, overall) { + this.overallProgress.start(overall.bytesLoaded, overall.bytesTotal); + var units = Date.parseIntervals(current.timeLeft || 0), timeLeft = []; + for (var unit in units) timeLeft.push(units[unit] + ' ' + unit); + this.currentText.set('html', 'Ñêîðîñòü çàãðóçêè {rate}/ñ. '.substitute({ + rate: (current.rate) ? this.sizeToKB(current.rate) : '- B', + timeLeft: timeLeft.join(', ') + })); + this.currentProgress.start(current.bytesLoaded, current.bytesTotal); + }, + + onSelect: function(file, index, length) { + this.log('Checked in file ' + index + '/' + length + ' "' + file.name + '" with ' + file.size + ' bytes.'); + }, + + onAllSelect: function(files, current, overall) { + $('demo-status').style.display = 'block'; + $('demo-browse').style.display = 'none'; + this.log('Added ' + files.length + ' files, now we have (' + current.bytesTotal + ' bytes).', arguments); + this.overallTitle.set('html', 'Îáùèé ñòàòóñ ({size})'.substitute({size: this.sizeToKB(current.bytesTotal)})); + files.each(function(file) { + this.createFileElement(file); + this.files.push(file); + }, this); + this.status.removeClass('status-browsing'); + }, + + onComplete: function(file, response) { + this.log('Completed upload "' + file.name + '".', arguments); + this.currentText.set('html', 'Çàãðóçêà çàâåðøåíà!'); + this.currentProgress.start(100); + file = this.getFile(file); + file.element.removeClass('file-uploading'); + var json = $H(JSON.decode(response, true)); + if (json.get('result') == 'success') { + file.element.addClass('file-success'); + file.info.set('html', json.get('size')); + } else { + file.element.addClass('file-failed'); + file.info.set('html', json.get('error') || response); + } + }, + + onError: function(file, error, info) { + this.log('Çàãðóçêà "' + file.name + '" íå óäàëàñü. "{1}": "{2}".', arguments); + file = this.finishFile(file); + file.element.addClass('file-failed'); + file.info.set('html', '' + error + '
' + info); + }, + + onCancel: function() { + this.log('Filebrowser cancelled.', arguments); + this.status.removeClass('file-browsing'); + }, + + onAllComplete: function(current) { + this.log('Completed all files, ' + current.bytesTotal + ' bytes.', arguments); + this.overallTitle.set('html', 'Îáùèé ñòàòóñ (' + this.sizeToKB(current.bytesTotal) + ')'); + this.overallProgress.start(100); + this.status.removeClass('file-uploading'); + }, + + browse: function(fileList) { + var ret = this.parent(fileList); + if (ret !== true){ + this.log('Browse in progress.'); + if (ret) alert(ret); + } else { + this.log('Browse started.'); + this.status.addClass('file-browsing'); + } + }, + + upload: function(options) { + var ret = this.parent(options); + if (ret !== true) { + this.log('Upload in progress or nothing to upload.'); + if (ret) alert(ret); + } else { + this.log('Upload started.'); + this.status.addClass('file-uploading'); + this.overallProgress.set(0); + } + }, + + removeFile: function(file) { + if (!file) { + this.files.each(this.removeFileElement, this); + this.files.empty(); + } else { + if (!file.element) file = this.getFile(file); + this.files.erase(file); + this.removeFileElement(file); + } + this.parent(file); + }, + + getFile: function(file) { + var ret = null; + this.files.some(function(value) { + if ((value.name != file.name) || (value.size != file.size)) return false; + ret = value; + return true; + }); + return ret; + }, + + removeFileElement: function(file) { + file.element.fade('out').retrieve('tween').chain(Element.destroy.bind(Element, file.element)); + }, + + finishFile: function(file) { + file = this.getFile(file); + file.element.removeClass('file-uploading'); + file.finished = true; + return file; + }, + + createFileElement: function(file) { + file.info = new Element('span', {'class': 'file-info'}); + file.element = new Element('li', {'class': 'file'}).adopt( + new Element('span', {'class': 'file-size', 'html': this.sizeToKB(file.size)}), + new Element('a', { + 'class': 'file-remove', + 'href': '#', + 'html': 'Óáðàòü', + 'events': { + 'click': function() { + this.removeFile(file); + return false; + }.bind(this) + } + }), + new Element('span', {'class': 'file-name', 'html': file.name}), + file.info + ).inject(this.list); + }, + + sizeToKB: function(size) { + var unit = 'B'; + if ((size / 1048576) > 1) { + unit = 'MB'; + size /= 1048576; + } else if ((size / 1024) > 1) { + unit = 'kB'; + size /= 1024; + } + return size.round(1) + ' ' + unit; + }, + + log: function(text, args) { + if (window.console) console.log(text.substitute(args || {})); + } + +}); + +Date.parseIntervals = function(sec, max) { + var units = {}, conv = Date.durations, count = 0; + for (var unit in conv) { + var value = Math.floor(sec / conv[unit]); + if (value) { + units[unit] = value; + if ((max && max <= ++count) || !(sec -= value * conv[unit])) break; + } + } + return units; +}; + +Date.intervals = {y: 31556926, mo: 2629743.83, d: 86400, h: 3600, mi: 60, s: 1, ms: 0.001}; +} \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/Fx.ProgressBar.js b/ipf/admin/media/tiny_mce/plugins/images/js/Fx.ProgressBar.js new file mode 100755 index 0000000..1b55469 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/js/Fx.ProgressBar.js @@ -0,0 +1,40 @@ +/** + * FancyUpload - Flash meets Ajax for simply working uploads + * + * @version 1.0 + * + * @license MIT License + * + * @author Harald Kirschner + * @copyright Authors + */ + +Fx.ProgressBar = new Class({ + + Extends: Fx, + + options: { + text: null, + transition: Fx.Transitions.Circ.easeOut, + link: 'cancel' + }, + + initialize: function(element, options) { + this.element = $(element); + this.parent(options); + this.text = $(this.options.text); + this.set(0); + }, + + start: function(to, total) { + return this.parent(this.now, (arguments.length == 1) ? to.limit(0, 100) : to / total * 100); + }, + + set: function(to) { + this.now = to; + this.element.setStyle('backgroundPosition', (100 - to) + '% 0px'); + if (this.text) this.text.set('text', Math.round(to) + '%'); + return this; + } + +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/JsHttpRequest.js b/ipf/admin/media/tiny_mce/plugins/images/js/JsHttpRequest.js new file mode 100755 index 0000000..e0d9323 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/js/JsHttpRequest.js @@ -0,0 +1,576 @@ +/** + * JsHttpRequest: JavaScript "AJAX" data loader + * Minimized version: see debug directory for the complete one. + * + * @license LGPL + * @author Dmitry Koterov, http://en.dklab.ru/lib/JsHttpRequest/ + * @version 5.x $Id$ + */ +function JsHttpRequest(){ +var t=this; +t.onreadystatechange=null; +t.readyState=0; +t.responseText=null; +t.responseXML=null; +t.status=200; +t.statusText="OK"; +t.responseJS=null; +t.caching=false; +t.loader=null; +t.session_name="PHPSESSID"; +t._ldObj=null; +t._reqHeaders=[]; +t._openArgs=null; +t._errors={inv_form_el:"Invalid FORM element detected: name=%, tag=%",must_be_single_el:"If used,
must be a single HTML element in the list.",js_invalid:"JavaScript code generated by backend is invalid!\n%",url_too_long:"Cannot use so long query with GET request (URL is larger than % bytes)",unk_loader:"Unknown loader: %",no_loaders:"No loaders registered at all, please check JsHttpRequest.LOADERS array",no_loader_matched:"Cannot find a loader which may process the request. Notices are:\n%"}; +t.abort=function(){ +with(this){ +if(_ldObj&&_ldObj.abort){ +_ldObj.abort(); +} +_cleanup(); +if(readyState==0){ +return; +} +if(readyState==1&&!_ldObj){ +readyState=0; +return; +} +_changeReadyState(4,true); +} +}; +t.open=function(_2,_3,_4,_5,_6){ +with(this){ +if(_3.match(/^((\w+)\.)?(GET|POST)\s+(.*)/i)){ +this.loader=RegExp.$2?RegExp.$2:null; +_2=RegExp.$3; +_3=RegExp.$4; +} +try{ +if(document.location.search.match(new RegExp("[&?]"+session_name+"=([^&?]*)"))||document.cookie.match(new RegExp("(?:;|^)\\s*"+session_name+"=([^;]*)"))){ +_3+=(_3.indexOf("?")>=0?"&":"?")+session_name+"="+this.escape(RegExp.$1); +} +} +catch(e){ +} +_openArgs={method:(_2||"").toUpperCase(),url:_3,asyncFlag:_4,username:_5!=null?_5:"",password:_6!=null?_6:""}; +_ldObj=null; +_changeReadyState(1,true); +return true; +} +}; +t.send=function(_7){ +if(!this.readyState){ +return; +} +this._changeReadyState(1,true); +this._ldObj=null; +var _8=[]; +var _9=[]; +if(!this._hash2query(_7,null,_8,_9)){ +return; +} +var _a=null; +if(this.caching&&!_9.length){ +_a=this._openArgs.username+":"+this._openArgs.password+"@"+this._openArgs.url+"|"+_8+"#"+this._openArgs.method; +var _b=JsHttpRequest.CACHE[_a]; +if(_b){ +this._dataReady(_b[0],_b[1]); +return false; +} +} +var _c=(this.loader||"").toLowerCase(); +if(_c&&!JsHttpRequest.LOADERS[_c]){ +return this._error("unk_loader",_c); +} +var _d=[]; +var _e=JsHttpRequest.LOADERS; +for(var _f in _e){ +var ldr=_e[_f].loader; +if(!ldr){ +continue; +} +if(_c&&_f!=_c){ +continue; +} +var _11=new ldr(this); +JsHttpRequest.extend(_11,this._openArgs); +JsHttpRequest.extend(_11,{queryText:_8.join("&"),queryElem:_9,id:(new Date().getTime())+""+JsHttpRequest.COUNT++,hash:_a,span:null}); +var _12=_11.load(); +if(!_12){ +this._ldObj=_11; +JsHttpRequest.PENDING[_11.id]=this; +return true; +} +if(!_c){ +_d[_d.length]="- "+_f.toUpperCase()+": "+this._l(_12); +}else{ +return this._error(_12); +} +} +return _f?this._error("no_loader_matched",_d.join("\n")):this._error("no_loaders"); +}; +t.getAllResponseHeaders=function(){ +with(this){ +return _ldObj&&_ldObj.getAllResponseHeaders?_ldObj.getAllResponseHeaders():[]; +} +}; +t.getResponseHeader=function(_13){ +with(this){ +return _ldObj&&_ldObj.getResponseHeader?_ldObj.getResponseHeader(_13):null; +} +}; +t.setRequestHeader=function(_14,_15){ +with(this){ +_reqHeaders[_reqHeaders.length]=[_14,_15]; +} +}; +t._dataReady=function(_16,js){ +with(this){ +if(caching&&_ldObj){ +JsHttpRequest.CACHE[_ldObj.hash]=[_16,js]; +} +responseText=responseXML=_16; +responseJS=js; +if(js!==null){ +status=200; +statusText="OK"; +}else{ +status=500; +statusText="Internal Server Error"; +} +_changeReadyState(2); +_changeReadyState(3); +_changeReadyState(4); +_cleanup(); +} +}; +t._l=function(_18){ +var i=0,p=0,msg=this._errors[_18[0]]; +while((p=msg.indexOf("%",p))>=0){ +var a=_18[++i]+""; +msg=msg.substring(0,p)+a+msg.substring(p+1,msg.length); +p+=1+a.length; +} +return msg; +}; +t._error=function(msg){ +msg=this._l(typeof (msg)=="string"?arguments:msg); +msg="JsHttpRequest: "+msg; +if(!window.Error){ +throw msg; +}else{ +if((new Error(1,"test")).description=="test"){ +throw new Error(1,msg); +}else{ +throw new Error(msg); +} +} +}; +t._hash2query=function(_1e,_1f,_20,_21){ +if(_1f==null){ +_1f=""; +} +if((""+typeof (_1e)).toLowerCase()=="object"){ +var _22=false; +if(_1e&&_1e.parentNode&&_1e.parentNode.appendChild&&_1e.tagName&&_1e.tagName.toUpperCase()=="FORM"){ +_1e={form:_1e}; +} +for(var k in _1e){ +var v=_1e[k]; +if(v instanceof Function){ +continue; +} +var _25=_1f?_1f+"["+this.escape(k)+"]":this.escape(k); +var _26=v&&v.parentNode&&v.parentNode.appendChild&&v.tagName; +if(_26){ +var tn=v.tagName.toUpperCase(); +if(tn=="FORM"){ +_22=true; +}else{ +if(tn=="INPUT"||tn=="TEXTAREA"||tn=="SELECT"){ +}else{ +return this._error("inv_form_el",(v.name||""),v.tagName); +} +} +_21[_21.length]={name:_25,e:v}; +}else{ +if(v instanceof Object){ +this._hash2query(v,_25,_20,_21); +}else{ +if(v===null){ +continue; +} +if(v===true){ +v=1; +} +if(v===false){ +v=""; +} +_20[_20.length]=_25+"="+this.escape(""+v); +} +} +if(_22&&_21.length>1){ +return this._error("must_be_single_el"); +} +} +}else{ +_20[_20.length]=_1e; +} +return true; +}; +t._cleanup=function(){ +var _28=this._ldObj; +if(!_28){ +return; +} +JsHttpRequest.PENDING[_28.id]=false; +var _29=_28.span; +if(!_29){ +return; +} +_28.span=null; +var _2a=function(){ +_29.parentNode.removeChild(_29); +}; +JsHttpRequest.setTimeout(_2a,50); +}; +t._changeReadyState=function(s,_2c){ +with(this){ +if(_2c){ +status=statusText=responseJS=null; +responseText=""; +} +readyState=s; +if(onreadystatechange){ +onreadystatechange(); +} +} +}; +t.escape=function(s){ +return escape(s).replace(new RegExp("\\+","g"),"%2B"); +}; +} +JsHttpRequest.COUNT=0; +JsHttpRequest.MAX_URL_LEN=2000; +JsHttpRequest.CACHE={}; +JsHttpRequest.PENDING={}; +JsHttpRequest.LOADERS={}; +JsHttpRequest._dummy=function(){ +}; +JsHttpRequest.TIMEOUTS={s:window.setTimeout,c:window.clearTimeout}; +JsHttpRequest.setTimeout=function(_2e,dt){ +window.JsHttpRequest_tmp=JsHttpRequest.TIMEOUTS.s; +if(typeof (_2e)=="string"){ +id=window.JsHttpRequest_tmp(_2e,dt); +}else{ +var id=null; +var _31=function(){ +_2e(); +delete JsHttpRequest.TIMEOUTS[id]; +}; +id=window.JsHttpRequest_tmp(_31,dt); +JsHttpRequest.TIMEOUTS[id]=_31; +} +window.JsHttpRequest_tmp=null; +return id; +}; +JsHttpRequest.clearTimeout=function(id){ +window.JsHttpRequest_tmp=JsHttpRequest.TIMEOUTS.c; +delete JsHttpRequest.TIMEOUTS[id]; +var r=window.JsHttpRequest_tmp(id); +window.JsHttpRequest_tmp=null; +return r; +}; +JsHttpRequest.query=function(url,_35,_36,_37){ +var req=new this(); +req.caching=!_37; +req.onreadystatechange=function(){ +if(req.readyState==4){ +_36(req.responseJS,req.responseText); +} +}; +req.open(null,url,true); +req.send(_35); +}; +JsHttpRequest.dataReady=function(d){ +var th=this.PENDING[d.id]; +delete this.PENDING[d.id]; +if(th){ +th._dataReady(d.text,d.js); +}else{ +if(th!==false){ +throw "dataReady(): unknown pending id: "+d.id; +} +} +}; +JsHttpRequest.extend=function(_3b,src){ +for(var k in src){ +_3b[k]=src[k]; +} +}; +JsHttpRequest.LOADERS.xml={loader:function(req){ +JsHttpRequest.extend(req._errors,{xml_no:"Cannot use XMLHttpRequest or ActiveX loader: not supported",xml_no_diffdom:"Cannot use XMLHttpRequest to load data from different domain %",xml_no_headers:"Cannot use XMLHttpRequest loader or ActiveX loader, POST method: headers setting is not supported, needed to work with encodings correctly",xml_no_form_upl:"Cannot use XMLHttpRequest loader: direct form elements using and uploading are not implemented"}); +this.load=function(){ +if(this.queryElem.length){ +return ["xml_no_form_upl"]; +} +if(this.url.match(new RegExp("^([a-z]+://[^\\/]+)(.*)","i"))){ +if(RegExp.$1.toLowerCase()!=document.location.protocol+"//"+document.location.hostname.toLowerCase()){ +return ["xml_no_diffdom",RegExp.$1]; +} +} +var xr=null; +if(window.XMLHttpRequest){ +try{ +xr=new XMLHttpRequest(); +} +catch(e){ +} +}else{ +if(window.ActiveXObject){ +try{ +xr=new ActiveXObject("Microsoft.XMLHTTP"); +} +catch(e){ +} +if(!xr){ +try{ +xr=new ActiveXObject("Msxml2.XMLHTTP"); +} +catch(e){ +} +} +} +} +if(!xr){ +return ["xml_no"]; +} +var _40=window.ActiveXObject||xr.setRequestHeader; +if(!this.method){ +this.method=_40&&this.queryText.length?"POST":"GET"; +} +if(this.method=="GET"){ +if(this.queryText){ +this.url+=(this.url.indexOf("?")>=0?"&":"?")+this.queryText; +} +this.queryText=""; +if(this.url.length>JsHttpRequest.MAX_URL_LEN){ +return ["url_too_long",JsHttpRequest.MAX_URL_LEN]; +} +}else{ +if(this.method=="POST"&&!_40){ +return ["xml_no_headers"]; +} +} +this.url+=(this.url.indexOf("?")>=0?"&":"?")+"JsHttpRequest="+(req.caching?"0":this.id)+"-xml"; +var id=this.id; +xr.onreadystatechange=function(){ +if(xr.readyState!=4){ +return; +} +xr.onreadystatechange=JsHttpRequest._dummy; +req.status=null; +try{ +req.status=xr.status; +req.responseText=xr.responseText; +} +catch(e){ +} +if(!req.status){ +return; +} +try{ +eval("JsHttpRequest._tmp = function(id) { var d = "+req.responseText+"; d.id = id; JsHttpRequest.dataReady(d); }"); +} +catch(e){ +return req._error("js_invalid",req.responseText); +} +JsHttpRequest._tmp(id); +JsHttpRequest._tmp=null; +}; +xr.open(this.method,this.url,true,this.username,this.password); +if(_40){ +for(var i=0;i=0?"&":"?")+this.queryText; +} +this.url+=(this.url.indexOf("?")>=0?"&":"?")+"JsHttpRequest="+this.id+"-"+"script"; +this.queryText=""; +if(!this.method){ +this.method="GET"; +} +if(this.method!=="GET"){ +return ["script_only_get"]; +} +if(this.queryElem.length){ +return ["script_no_form"]; +} +if(this.url.length>JsHttpRequest.MAX_URL_LEN){ +return ["url_too_long",JsHttpRequest.MAX_URL_LEN]; +} +var th=this,d=document,s=null,b=d.body; +if(!window.opera){ +this.span=s=d.createElement("SCRIPT"); +var _49=function(){ +s.language="JavaScript"; +if(s.setAttribute){ +s.setAttribute("src",th.url); +}else{ +s.src=th.url; +} +b.insertBefore(s,b.lastChild); +}; +}else{ +this.span=s=d.createElement("SPAN"); +s.style.display="none"; +b.insertBefore(s,b.lastChild); +s.innerHTML="Workaround for IE."; +var _49=function(){ +s=s.getElementsByTagName("SCRIPT")[0]; +s.language="JavaScript"; +if(s.setAttribute){ +s.setAttribute("src",th.url); +}else{ +s.src=th.url; +} +}; +} +JsHttpRequest.setTimeout(_49,10); +return null; +}; +}}; +JsHttpRequest.LOADERS.form={loader:function(req){ +JsHttpRequest.extend(req._errors,{form_el_not_belong:"Element \"%\" does not belong to any form!",form_el_belong_diff:"Element \"%\" belongs to a different form. All elements must belong to the same form!",form_el_inv_enctype:"Attribute \"enctype\" of the form must be \"%\" (for IE), \"%\" given."}); +this.load=function(){ +var th=this; +if(!th.method){ +th.method="POST"; +} +th.url+=(th.url.indexOf("?")>=0?"&":"?")+"JsHttpRequest="+th.id+"-"+"form"; +if(th.method=="GET"){ +if(th.queryText){ +th.url+=(th.url.indexOf("?")>=0?"&":"?")+th.queryText; +} +if(th.url.length>JsHttpRequest.MAX_URL_LEN){ +return ["url_too_long",JsHttpRequest.MAX_URL_LEN]; +} +var p=th.url.split("?",2); +th.url=p[0]; +th.queryText=p[1]||""; +} +var _4d=null; +var _4e=false; +if(th.queryElem.length){ +if(th.queryElem[0].e.tagName.toUpperCase()=="FORM"){ +_4d=th.queryElem[0].e; +_4e=true; +th.queryElem=[]; +}else{ +_4d=th.queryElem[0].e.form; +for(var i=0;i")+""; +if(!_4d){ +_4d=th.span.firstChild; +} +d.body.insertBefore(s,d.body.lastChild); +var _56=function(e,_58){ +var sv=[]; +var _5a=e; +if(e.mergeAttributes){ +var _5a=d.createElement("form"); +_5a.mergeAttributes(e,false); +} +for(var i=0;i<_58.length;i++){ +var k=_58[i][0],v=_58[i][1]; +sv[sv.length]=[k,_5a.getAttribute(k)]; +_5a.setAttribute(k,v); +} +if(e.mergeAttributes){ +e.mergeAttributes(_5a,false); +} +return sv; +}; +var _5e=function(){ +top.JsHttpRequestGlobal=JsHttpRequest; +var _5f=[]; +if(!_4e){ +for(var i=0,n=_4d.elements.length;i=0;i--){ +var _63=qt[i].split("=",2); +var e=d.createElement("INPUT"); +e.type="hidden"; +e.name=unescape(_63[0]); +e.value=_63[1]!=null?unescape(_63[1]):""; +_4d.appendChild(e); +} +for(var i=0;i + * @copyright Authors + */ + +Swiff.Uploader = new Class({ + + Extends: Swiff, + + Implements: Events, + + options: { + path: 'Swiff.Uploader.swf', + multiple: true, + queued: true, + typeFilter: null, + url: null, + method: 'post', + data: null, + fieldName: 'Filedata', + callBacks: null + }, + + initialize: function(options){ + if (Browser.Plugins.Flash.version < 9) return false; + this.setOptions(options); + + var callBacks = this.options.callBacks || this; + if (callBacks.onLoad) this.addEvent('onLoad', callBacks.onLoad); + + var prepare = {}, self = this; + ['onSelect', 'onAllSelect', 'onCancel', 'onBeforeOpen', 'onOpen', 'onProgress', 'onComplete', 'onError', 'onAllComplete'].each(function(index) { + var fn = (callBacks[index]) ? callBacks[index] : $empty; + prepare[index] = function() { + return fn.apply(self, arguments); + }; + }, this); + + prepare.onLoad = this.load.create({delay: 10, bind: this}); + this.options.callBacks = prepare; + + var path = this.options.path; + if (!path.contains('?')) path += '?noCache=' + $time(); // quick fix + + delete this.options.params.wMode; + this.parent(path); + + if (!this.options.container) document.body.appendChild(this.object); + return this; + }, + + load: function(){ + this.remote('register', this.instance, this.options.multiple, this.options.queued); + this.fireEvent('onLoad'); + }, + + /* + Method: browse + Open the file browser. + */ + + browse: function(typeFilter){ + return this.remote('browse', $pick(typeFilter, this.options.typeFilter)); + }, + + /* + Method: upload + Starts the upload of all selected files. + */ + + upload: function(options){ + var current = this.options; + options = $extend({data: current.data, url: current.url, method: current.method, fieldName: current.fieldName}, options); + if ($type(options.data) == 'element') options.data = $(options.data).toQueryString(); + return this.remote('upload', options); + }, + + /* + Method: removeFile + For multiple uploads cancels and removes the given file from queue. + + Arguments: + name - (string) Filename + name - (string) Filesize in byte + */ + + removeFile: function(file){ + if (file) file = {name: file.name, size: file.size}; + return this.remote('removeFile', file); + }, + + /* + Method: getFileList + Returns one Array with with arrays containing name and size of the file. + + Returns: + (array) An array with files + */ + + getFileList: function(){ + return this.remote('getFileList'); + } + +}); diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/Swiff.Uploader.swf b/ipf/admin/media/tiny_mce/plugins/images/js/Swiff.Uploader.swf new file mode 100755 index 0000000000000000000000000000000000000000..a816031968b0c1a4011986969ae0f4498e4a63de GIT binary patch literal 3687 zcmV-t4w&&nS5pa67XScwoRv6RdmG1fa~8XpUEByjBqULyNJpZnjeQ5LArY{8XnS5_w z`XBnho|#>cqU+}Sf={z^X6BqT=YB>^c*qv<0htZSgpe6we}DfseO?5CWC~hU8@fWs zZ+ibH!Zz?1B;#!Q2O#c@Wg69Wdb3t5Yid>8s2N3{URE2Wacx7ZS`8`5CU-jjmR7L* z%Vure)EW)Gsm!XD%AuaQ)z#&UrCLq<#5bQ#nr6-9i*QCOG)=?WJlv9|O;g=;-)>g& znyJ{=RW-|>GRoSDrfa5FEoe&Sp`q*d@zl4Z8r4;!qLq!R=C{#{Mx$O91ce7rusYOLC7WvhUK(k&{Ev>7G$3AB_drYlT+t3&&Sx9cmb=6cWsCuYm zS#?{#Ikj3WYi3W~p?B7jS}xZf`U@%wUUv2ZMvbfNEZsUX)2?`pYEgTX*4Z_^jpt3{ z;K@d{VKF}LyjgqL(7d&}R&~xOzeX#1bfaoCN{okhU9;G{Xf!N;Lo1`3x{OS19XCb1f0bq6s4+`9S7>jNHZHAd$q3B zDqb6`XhlPHXzCc8c-^|gud#{hR2&iu8Ok=;G#pwkkP}dkD&^xxVrA+eR(g-_XYd+J ziyqyawP!o3JgG4K_|ZyHubt`i}9Sn(IB{F2u#B>&y zRI4PJwPv;GuWKgOJj>Q!W|_RG=@z?khNmZWGEl_&rBT$I)e35tg(Ah=Gue#jX-qt6 z-Bjx(+N?H8hHiOr_n>k#Y|2`bZ_hY6CL$YE#toj+p2N!FZt%%}BF`BCRnKz4c#al9C+4N7FRS3cdS>a z@J&sxnHn>-q8nPdcpGJqnM}-%uBKTIl+;H0Au~HV7E23~-%(A2g;Q>m9igu-zOCn%hx&`;qMh0_!UD4d}%NMVS=Fr{ZHoTCt>aGt^lg;5G) z6fRJRQMgDUPT>-TaSE4}1Sm;RQlQ)dWe$|vpe%#(8YoMktbnor)Rm#Id`h5!JIWg< z>6_H^8ui>&zKwEbDZNMOeM)nbs!AS|S3y}soC1ZSqJg4=Qo^M{J#Q%wKq(` z27vUQ0pc5ENJBt+hJnzt1a&zFU9pcL4~KqaOkykW&P0=y7c) zZZXlo;|**l?wuVeoxRr=C8a*x6}+Oydv`mL8{8TBLXG7HbAx)U6$_(Q7dj(fwA72a z!K}0(5jBp0cfm{4OI=_*HyEFflK29SS8*)jSc;N0Nxh6G>Gqb&?sd6DulE|Vz0^)$ z0i4H2?fEhr`b1lQVN0E0aBNq<`gCunqh6I=vXC8Xr^aB85K(e@{r@g(Cti>3CNvms zRRj%&9(yY;4aO=WgZ&jrgLVZp#y1uY5|VvUgEHtZrCx+q(1&Zkv-U%aGvF#PCY<79 zLNthyW_xIbm6e6|tiO-|O&r-KQo#Q(g2FYhg z^Eum^Z=>7YF2UpNWs!NP$@*4$3NWUqD0#dqOiceSin^Eex4CO^$!=m++DR<{x=z~b zbh585yh>7wBvugBrMxJM>TQQ#1ueXT=4DE9(-2uwJl=m44q1;C#Ib@j+$y+pXEA@t zt$SxjOJ{%Ah286#1+l}erl-T76VlO_nWAa5&$GPP(U+bvT~n_?GggqIp1?_t5-U*s z+9$DsoTqtNy(Y^tZQ?P(`-506lun1)bvf_WC(*Wf_ftH`yYo`tf9>ygaw$B`ON{UN z|E8a*Gkga{FK)!bGOHLoc{jq? zXtKd{kOXh?gpP$n2Q1&&a`*_{0@)o=68loU)0P3JS$n#QlRANS1z4(NwiE4~sK1`; zPro5B=*`@D2fCXZ=8#+ecJ2g+sQ#VYD2HS{n>)@SkA5$AhC_;eKX(ctWZff4-rz2D zi!Up?tolA-#dqj&j@2)$yC~rGFqV_ixx>OLu!0*#7E!Xtz*a#Fj`P}z(SL?B$mW~^ z#%q^8xsVfVmSsjPVpW?EU7`Qj-9l7fCDVW>tN`Pg?5rY=}vKHI_}h zWU9dA8JP>8beU%@}azd)fVYS_blJ{{X3StnwS zl!y!aHFmDxFAsDdV=CFo8XK|Dp+`UMs*d`~%%u!s{c=P#nERQ3v&R^2l<1S`W58;> z-EM>+K35d`kaq!g%mBMPFf$1DC4GC?8~%S~M&{u9NAOeBMYur(A9;%_6cPllmmYM| zFfRQ;rq7owE-&2(r5>>TV{UvV|0@=~u{|twVmtgH3OvxpZr9xFME85SdW@ih@|AfL z>O>)3VWN%O&`vnUgV}ECv%IO#@}^#p^gBTp7lD;QF&MU6&!xP`rOAs}1I4`PnCUb1Ni<98=~`uS^Z z;W&I%y%W5Ac=lYvA@vR4jNCdw)N^4v9K3ohp%5i^}k@@)0yi$MPu*iwZ6{&esmw%^?5L>$F>vkCs;1? z@s+k-kAH;V+wq^_*Gx4?{3!w!0&5cDM*<#?_qV)tNxXG2Uk*KP+T9BWMUmnxf!O?5 z3gXk3KkXh%NZ=HpPhiUqmz~s75+>Qy5>XdA>-07lKzwW_ffE3>OU6i?;FHMct1Ms}!MI>@TuaTj)iliP{W-E41rB-JZy z?CylSF5f|$pK#%$`Yn7^+mGbZ;B&9*+{^KJZY2E}1cXL%Lk<+l1s$kA*XuyBT$Dlg zBH8y~TW^8>KBV3Q&_94u1RWEJe~wQJ`{{F%-5AM FGO{>n9KHYm literal 0 HcmV?d00001 diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/images.js b/ipf/admin/media/tiny_mce/plugins/images/js/images.js new file mode 100755 index 0000000..5a4f195 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/js/images.js @@ -0,0 +1,24 @@ +tinyMCEPopup.requireLangPack(); + +var ImagesDialog = { + init : function(ed) { + tinyMCEPopup.resizeToInnerSize(); + }, + + insert : function(file, title, width) { + var ed = tinyMCEPopup.editor, dom = ed.dom; + + tinyMCEPopup.execCommand('mceInsertContent', false, dom.createHTML('img', { + src : file, + alt : title, + title : title, + width : width, + /*height : 0,*/ + border : 0 + })); + + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(ImagesDialog.init, ImagesDialog); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/js/mootools.js b/ipf/admin/media/tiny_mce/plugins/images/js/mootools.js new file mode 100755 index 0000000..1247f1c --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/js/mootools.js @@ -0,0 +1,5209 @@ +/* +Script: Core.js + MooTools - My Object Oriented JavaScript Tools. + +License: + MIT-style license. + +Copyright: + Copyright (c) 2006-2007 [Valerio Proietti](http://mad4milk.net/). + +Code & Documentation: + [The MooTools production team](http://mootools.net/developers/). + +Inspiration: + - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) + - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) +*/ + +var MooTools = { + 'version': '1.2dev', + 'build': '%build%' +}; + +var Native = function(options){ + options = options || {}; + + var afterImplement = options.afterImplement || function(){}; + var generics = options.generics; + generics = (generics !== false); + var legacy = options.legacy; + var initialize = options.initialize; + var protect = options.protect; + var name = options.name; + + var object = initialize || legacy; + + object.constructor = Native; + object.$family = {name: 'native'}; + if (legacy && initialize) object.prototype = legacy.prototype; + object.prototype.constructor = object; + + if (name){ + var family = name.toLowerCase(); + object.prototype.$family = {name: family}; + Native.typize(object, family); + } + + var add = function(obj, name, method, force){ + if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method; + if (generics) Native.genericize(obj, name, protect); + afterImplement.call(obj, name, method); + return obj; + }; + + object.implement = function(a1, a2, a3){ + if (typeof a1 == 'string') return add(this, a1, a2, a3); + for (var p in a1) add(this, p, a1[p], a2); + return this; + }; + + object.alias = function(a1, a2, a3){ + if (typeof a1 == 'string'){ + a1 = this.prototype[a1]; + if (a1) add(this, a2, a1, a3); + } else { + for (var a in a1) this.alias(a, a1[a], a2); + } + return this; + }; + + return object; +}; + +Native.implement = function(objects, properties){ + for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties); +}; + +Native.genericize = function(object, property, check){ + if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){ + var args = Array.prototype.slice.call(arguments); + return object.prototype[property].apply(args.shift(), args); + }; +}; + +Native.typize = function(object, family){ + if (!object.type) object.type = function(item){ + return ($type(item) === family); + }; +}; + +Native.alias = function(objects, a1, a2, a3){ + for (var i = 0, j = objects.length; i < j; i++) objects[i].alias(a1, a2, a3); +}; + +(function(objects){ + for (var name in objects) Native.typize(objects[name], name.toLowerCase()); +})({'Boolean': Boolean, 'Native': Native, 'Object': Object}); + +(function(objects){ + for (var name in objects) new Native({name: name, initialize: objects[name], protect: true}); +})({'String': String, 'Function': Function, 'Number': Number, 'Array': Array, 'RegExp': RegExp, 'Date': Date}); + +(function(object, methods){ + for (var i = 0, l = methods.length; i < l; i++) Native.genericize(object, methods[i], true); + return arguments.callee; +}) +(Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 'toString', 'valueOf', 'indexOf', 'lastIndexOf']) +(String, ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'replace', 'search', 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase', 'valueOf']); + +function $chk(obj){ + return !!(obj || obj === 0); +}; + +function $clear(timer){ + clearTimeout(timer); + clearInterval(timer); + return null; +}; + +function $defined(obj){ + return (obj != undefined); +}; + +function $empty(){}; + +function $arguments(i){ + return function(){ + return arguments[i]; + }; +}; + +function $lambda(value){ + return (typeof value == 'function') ? value : function(){ + return value; + }; +}; + +function $extend(original, extended){ + for (var key in (extended || {})) original[key] = extended[key]; + return original; +}; + +function $unlink(object){ + var unlinked = null; + + switch ($type(object)){ + case 'object': + unlinked = {}; + for (var p in object) unlinked[p] = $unlink(object[p]); + break; + case 'hash': + unlinked = $unlink(object.getClean()); + break; + case 'array': + unlinked = []; + for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]); + break; + default: return object; + } + + return unlinked; +}; + +function $merge(){ + var mix = {}; + for (var i = 0, l = arguments.length; i < l; i++){ + var object = arguments[i]; + if ($type(object) != 'object') continue; + for (var key in object){ + var op = object[key], mp = mix[key]; + mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op); + } + } + return mix; +}; + +function $pick(){ + for (var i = 0, l = arguments.length; i < l; i++){ + if (arguments[i] != undefined) return arguments[i]; + } + return null; +}; + +function $random(min, max){ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +function $splat(obj){ + var type = $type(obj); + return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : []; +}; + +var $time = Date.now || function(){ + return new Date().getTime(); +}; + +function $try(){ + for (var i = 0, l = arguments.length; i < l; i++){ + try { + return arguments[i](); + } catch(e){} + } + return null; +}; + +function $type(obj){ + if (obj == undefined) return false; + if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name; + if (obj.nodeName){ + switch (obj.nodeType){ + case 1: return 'element'; + case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; + } + } else if (typeof obj.length == 'number'){ + if (obj.callee) return 'arguments'; + else if (obj.item) return 'collection'; + } + return typeof obj; +}; + +var Hash = new Native({ + + name: 'Hash', + + initialize: function(object){ + if ($type(object) == 'hash') object = $unlink(object.getClean()); + for (var key in object) this[key] = object[key]; + return this; + } + +}); + +Hash.implement({ + + getLength: function(){ + var length = 0; + for (var key in this){ + if (this.hasOwnProperty(key)) length++; + } + return length; + }, + + forEach: function(fn, bind){ + for (var key in this){ + if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this); + } + }, + + getClean: function(){ + var clean = {}; + for (var key in this){ + if (this.hasOwnProperty(key)) clean[key] = this[key]; + } + return clean; + } + +}); + +Hash.alias('forEach', 'each'); + +function $H(object){ + return new Hash(object); +}; + +Array.implement({ + + forEach: function(fn, bind){ + for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this); + } + +}); + +Array.alias('forEach', 'each'); + +function $A(iterable){ + if (iterable.item){ + var array = []; + for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i]; + return array; + } + return Array.prototype.slice.call(iterable); +}; + +function $each(iterable, fn, bind){ + var type = $type(iterable); + ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind); +}; +/* +Script: Browser.js + The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash. + +License: + MIT-style license. +*/ + +var Browser = new Hash({ + Engine: {name: 'unknown', version: ''}, + Platform: {name: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()}, + Features: {xpath: !!(document.evaluate), air: !!(window.runtime)}, + Plugins: {} +}); + +if (window.opera) Browser.Engine = {name: 'presto', version: (document.getElementsByClassName) ? 950 : 925}; +else if (window.ActiveXObject) Browser.Engine = {name: 'trident', version: (window.XMLHttpRequest) ? 5 : 4}; +else if (!navigator.taintEnabled) Browser.Engine = {name: 'webkit', version: (Browser.Features.xpath) ? 420 : 419}; +else if (document.getBoxObjectFor != null) Browser.Engine = {name: 'gecko', version: (document.getElementsByClassName) ? 19 : 18}; +Browser.Engine[Browser.Engine.name] = Browser.Engine[Browser.Engine.name + Browser.Engine.version] = true; + +if (window.orientation != undefined) Browser.Platform.name = 'ipod'; + +Browser.Platform[Browser.Platform.name] = true; + +Browser.Request = function(){ + return $try(function(){ + return new XMLHttpRequest(); + }, function(){ + return new ActiveXObject('MSXML2.XMLHTTP'); + }); +}; + +Browser.Features.xhr = !!(Browser.Request()); + +Browser.Plugins.Flash = (function(){ + var version = ($try(function(){ + return navigator.plugins['Shockwave Flash'].description; + }, function(){ + return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + }) || '0 r0').match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), build: parseInt(version[2] || 0)}; +})(); + +function $exec(text){ + if (!text) return text; + if (window.execScript){ + window.execScript(text); + } else { + var script = document.createElement('script'); + script.setAttribute('type', 'text/javascript'); + script.text = text; + document.head.appendChild(script); + document.head.removeChild(script); + } + return text; +}; + +Native.UID = 1; + +var $uid = (Browser.Engine.trident) ? function(item){ + return (item.uid || (item.uid = [Native.UID++]))[0]; +} : function(item){ + return item.uid || (item.uid = Native.UID++); +}; + +var Window = new Native({ + + name: 'Window', + + legacy: (Browser.Engine.trident) ? null: window.Window, + + initialize: function(win){ + $uid(win); + if (!win.Element){ + win.Element = $empty; + if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2 + win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {}; + } + return $extend(win, Window.Prototype); + }, + + afterImplement: function(property, value){ + window[property] = Window.Prototype[property] = value; + } + +}); + +Window.Prototype = {$family: {name: 'window'}}; + +new Window(window); + +var Document = new Native({ + + name: 'Document', + + legacy: (Browser.Engine.trident) ? null: window.Document, + + initialize: function(doc){ + $uid(doc); + doc.head = doc.getElementsByTagName('head')[0]; + doc.html = doc.getElementsByTagName('html')[0]; + doc.window = doc.defaultView || doc.parentWindow; + if (Browser.Engine.trident4) $try(function(){ + doc.execCommand("BackgroundImageCache", false, true); + }); + return $extend(doc, Document.Prototype); + }, + + afterImplement: function(property, value){ + document[property] = Document.Prototype[property] = value; + } + +}); + +Document.Prototype = {$family: {name: 'document'}}; + +new Document(document);/* +Script: Array.js + Contains Array Prototypes like copy, each, contains, and remove. + +License: + MIT-style license. +*/ + +Array.implement({ + + every: function(fn, bind){ + for (var i = 0, l = this.length; i < l; i++){ + if (!fn.call(bind, this[i], i, this)) return false; + } + return true; + }, + + filter: function(fn, bind){ + var results = []; + for (var i = 0, l = this.length; i < l; i++){ + if (fn.call(bind, this[i], i, this)) results.push(this[i]); + } + return results; + }, + + clean: function() { + return this.filter($defined); + }, + + indexOf: function(item, from){ + var len = this.length; + for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ + if (this[i] === item) return i; + } + return -1; + }, + + map: function(fn, bind){ + var results = []; + for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this); + return results; + }, + + some: function(fn, bind){ + for (var i = 0, l = this.length; i < l; i++){ + if (fn.call(bind, this[i], i, this)) return true; + } + return false; + }, + + associate: function(keys){ + var obj = {}, length = Math.min(this.length, keys.length); + for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; + return obj; + }, + + link: function(object){ + var result = {}; + for (var i = 0, l = this.length; i < l; i++){ + for (var key in object){ + if (object[key](this[i])){ + result[key] = this[i]; + delete object[key]; + break; + } + } + } + return result; + }, + + contains: function(item, from){ + return this.indexOf(item, from) != -1; + }, + + extend: function(array){ + for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); + return this; + }, + + getLast: function(){ + return (this.length) ? this[this.length - 1] : null; + }, + + getRandom: function(){ + return (this.length) ? this[$random(0, this.length - 1)] : null; + }, + + include: function(item){ + if (!this.contains(item)) this.push(item); + return this; + }, + + combine: function(array){ + for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); + return this; + }, + + erase: function(item){ + for (var i = this.length; i--; i){ + if (this[i] === item) this.splice(i, 1); + } + return this; + }, + + empty: function(){ + this.length = 0; + return this; + }, + + flatten: function(){ + var array = []; + for (var i = 0, l = this.length; i < l; i++){ + var type = $type(this[i]); + if (!type) continue; + array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]); + } + return array; + }, + + hexToRgb: function(array){ + if (this.length != 3) return null; + var rgb = this.map(function(value){ + if (value.length == 1) value += value; + return value.toInt(16); + }); + return (array) ? rgb : 'rgb(' + rgb + ')'; + }, + + rgbToHex: function(array){ + if (this.length < 3) return null; + if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (this[i] - 0).toString(16); + hex.push((bit.length == 1) ? '0' + bit : bit); + } + return (array) ? hex : '#' + hex.join(''); + } + +});/* +Script: Function.js + Contains Function Prototypes like create, bind, pass, and delay. + +License: + MIT-style license. +*/ + +Function.implement({ + + extend: function(properties){ + for (var property in properties) this[property] = properties[property]; + return this; + }, + + create: function(options){ + var self = this; + options = options || {}; + return function(event){ + var args = options.arguments; + args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0); + if (options.event) args = [event || window.event].extend(args); + var returns = function(){ + return self.apply(options.bind || null, args); + }; + if (options.delay) return setTimeout(returns, options.delay); + if (options.periodical) return setInterval(returns, options.periodical); + if (options.attempt) return $try(returns); + return returns(); + }; + }, + + pass: function(args, bind){ + return this.create({arguments: args, bind: bind}); + }, + + attempt: function(args, bind){ + return this.create({arguments: args, bind: bind, attempt: true})(); + }, + + bind: function(bind, args){ + return this.create({bind: bind, arguments: args}); + }, + + bindWithEvent: function(bind, args){ + return this.create({bind: bind, event: true, arguments: args}); + }, + + delay: function(delay, bind, args){ + return this.create({delay: delay, bind: bind, arguments: args})(); + }, + + periodical: function(interval, bind, args){ + return this.create({periodical: interval, bind: bind, arguments: args})(); + }, + + run: function(args, bind){ + return this.apply(bind, $splat(args)); + } + +});/* +Script: Number.js + Contains Number Prototypes like limit, round, times, and ceil. + +License: + MIT-style license. +*/ + +Number.implement({ + + limit: function(min, max){ + return Math.min(max, Math.max(min, this)); + }, + + round: function(precision){ + precision = Math.pow(10, precision || 0); + return Math.round(this * precision) / precision; + }, + + times: function(fn, bind){ + for (var i = 0; i < this; i++) fn.call(bind, i, this); + }, + + toFloat: function(){ + return parseFloat(this); + }, + + toInt: function(base){ + return parseInt(this, base || 10); + } + +}); + +Number.alias('times', 'each'); + +(function(math){ + var methods = {}; + math.each(function(name){ + if (!Number[name]) methods[name] = function(){ + return Math[name].apply(null, [this].concat($A(arguments))); + }; + }); + Number.implement(methods); +})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);/* +Script: String.js + Contains String Prototypes like camelCase, capitalize, test, and toInt. + +License: + MIT-style license. +*/ + +String.implement({ + + test: function(regex, params){ + return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); + }, + + contains: function(string, separator){ + return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1; + }, + + trim: function(){ + return this.replace(/^\s+|\s+$/g, ''); + }, + + clean: function(){ + return this.replace(/\s+/g, ' ').trim(); + }, + + camelCase: function(){ + return this.replace(/-\D/g, function(match){ + return match.charAt(1).toUpperCase(); + }); + }, + + hyphenate: function(){ + return this.replace(/[A-Z]/g, function(match){ + return ('-' + match.charAt(0).toLowerCase()); + }); + }, + + capitalize: function(){ + return this.replace(/\b[a-z]/g, function(match){ + return match.toUpperCase(); + }); + }, + + escapeRegExp: function(){ + return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); + }, + + toInt: function(base){ + return parseInt(this, base || 10); + }, + + toFloat: function(){ + return parseFloat(this); + }, + + hexToRgb: function(array){ + var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); + return (hex) ? hex.slice(1).hexToRgb(array) : null; + }, + + rgbToHex: function(array){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? rgb.rgbToHex(array) : null; + }, + + stripScripts: function(option){ + var scripts = ''; + var text = this.replace(/]*>([\s\S]*?)<\/script>/gi, function(){ + scripts += arguments[1] + '\n'; + return ''; + }); + if (option === true) $exec(scripts); + else if ($type(option) == 'function') option(scripts, text); + return text; + }, + + substitute: function(object, regexp){ + return this.replace(regexp || (/\\?\{([^}]+)\}/g), function(match, name){ + if (match.charAt(0) == '\\') return match.slice(1); + return (object[name] != undefined) ? object[name] : ''; + }); + } + +});/* +Script: Hash.js + Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects. + +License: + MIT-style license. +*/ + +Hash.implement({ + + has: Object.prototype.hasOwnProperty, + + keyOf: function(value){ + for (var key in this){ + if (this.hasOwnProperty(key) && this[key] === value) return key; + } + return null; + }, + + hasValue: function(value){ + return (Hash.keyOf(this, value) !== null); + }, + + extend: function(properties){ + Hash.each(properties, function(value, key){ + Hash.set(this, key, value); + }, this); + return this; + }, + + combine: function(properties){ + Hash.each(properties, function(value, key){ + Hash.include(this, key, value); + }, this); + return this; + }, + + erase: function(key){ + if (this.hasOwnProperty(key)) delete this[key]; + return this; + }, + + get: function(key){ + return (this.hasOwnProperty(key)) ? this[key] : null; + }, + + set: function(key, value){ + if (!this[key] || this.hasOwnProperty(key)) this[key] = value; + return this; + }, + + empty: function(){ + Hash.each(this, function(value, key){ + delete this[key]; + }, this); + return this; + }, + + include: function(key, value){ + var k = this[key]; + if (k == undefined) this[key] = value; + return this; + }, + + map: function(fn, bind){ + var results = new Hash; + Hash.each(this, function(value, key){ + results.set(key, fn.call(bind, value, key, this)); + }, this); + return results; + }, + + filter: function(fn, bind){ + var results = new Hash; + Hash.each(this, function(value, key){ + if (fn.call(bind, value, key, this)) results.set(key, value); + }, this); + return results; + }, + + every: function(fn, bind){ + for (var key in this){ + if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key)) return false; + } + return true; + }, + + some: function(fn, bind){ + for (var key in this){ + if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true; + } + return false; + }, + + getKeys: function(){ + var keys = []; + Hash.each(this, function(value, key){ + keys.push(key); + }); + return keys; + }, + + getValues: function(){ + var values = []; + Hash.each(this, function(value){ + values.push(value); + }); + return values; + }, + + toQueryString: function(base){ + var queryString = []; + Hash.each(this, function(value, key){ + if (base) key = base + '[' + key + ']'; + var result; + switch ($type(value)){ + case 'object': result = Hash.toQueryString(value, key); break; + case 'array': + var qs = {}; + value.each(function(val, i){ + qs[i] = val; + }); + result = Hash.toQueryString(qs, key); + break; + default: result = key + '=' + encodeURIComponent(value); + } + if (value != undefined) queryString.push(result); + }); + + return queryString.join('&'); + } + +}); + +Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});/* +Script: Event.js + Contains the Event Native, to make the event object completely crossbrowser. + +License: + MIT-style license. +*/ + +var Event = new Native({ + + name: 'Event', + + initialize: function(event, win){ + win = win || window; + var doc = win.document; + event = event || win.event; + if (event.$extended) return event; + this.$extended = true; + var type = event.type; + var target = event.target || event.srcElement; + while (target && target.nodeType == 3) target = target.parentNode; + + if (type.test(/key/)){ + var code = event.which || event.keyCode; + var key = Event.Keys.keyOf(code); + if (type == 'keydown'){ + var fKey = code - 111; + if (fKey > 0 && fKey < 13) key = 'f' + fKey; + } + key = key || String.fromCharCode(code).toLowerCase(); + } else if (type.match(/(click|mouse|menu)/i)){ + doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; + var page = { + x: event.pageX || event.clientX + doc.scrollLeft, + y: event.pageY || event.clientY + doc.scrollTop + }; + var client = { + x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX, + y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY + }; + if (type.match(/DOMMouseScroll|mousewheel/)){ + var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; + } + var rightClick = (event.which == 3) || (event.button == 2); + var related = null; + if (type.match(/over|out/)){ + switch (type){ + case 'mouseover': related = event.relatedTarget || event.fromElement; break; + case 'mouseout': related = event.relatedTarget || event.toElement; + } + if (!(function(){ + while (related && related.nodeType == 3) related = related.parentNode; + return true; + }).create({attempt: Browser.Engine.gecko})()) related = false; + } + } + + return $extend(this, { + event: event, + type: type, + + page: page, + client: client, + rightClick: rightClick, + + wheel: wheel, + + relatedTarget: related, + target: target, + + code: code, + key: key, + + shift: event.shiftKey, + control: event.ctrlKey, + alt: event.altKey, + meta: event.metaKey + }); + } + +}); + +Event.Keys = new Hash({ + 'enter': 13, + 'up': 38, + 'down': 40, + 'left': 37, + 'right': 39, + 'esc': 27, + 'space': 32, + 'backspace': 8, + 'tab': 9, + 'delete': 46 +}); + +Event.implement({ + + stop: function(){ + return this.stopPropagation().preventDefault(); + }, + + stopPropagation: function(){ + if (this.event.stopPropagation) this.event.stopPropagation(); + else this.event.cancelBubble = true; + return this; + }, + + preventDefault: function(){ + if (this.event.preventDefault) this.event.preventDefault(); + else this.event.returnValue = false; + return this; + } + +});/* +Script: Class.js + Contains the Class Function for easily creating, extending, and implementing reusable Classes. + +License: + MIT-style license. +*/ + +var Class = new Native({ + + name: 'Class', + + initialize: function(properties){ + + properties = properties || {}; + + var klass = function(empty){ + + for (var key in this) this[key] = $unlink(this[key]); + + for (var mutator in Class.Mutators){ + if (!this[mutator]) continue; + Class.Mutators[mutator](this, this[mutator]); + delete this[mutator]; + } + + this.constructor = klass; + + if (empty === $empty) return this; + + var self = (this.initialize) ? this.initialize.apply(this, arguments) : this; + if (this.options && this.options.initialize) this.options.initialize.call(this); + + return self; + }; + + $extend(klass, this); + klass.constructor = Class; + klass.prototype = properties; + return klass; + } + +}); + +Class.implement({ + + implement: function(){ + Class.Mutators.Implements(this.prototype, Array.slice(arguments)); + return this; + } + +}); + +Class.Mutators = {}; + +Class.Mutators.Implements = function(self, klasses){ + $splat(klasses).each(function(klass){ + $extend(self, ($type(klass) == 'class') ? new klass($empty) : klass); + }); +}; + +Class.Mutators.Extends = function(self, klass){ + + var instance = new klass($empty); + + delete instance.parent; + delete instance.parentOf; + + for (var key in instance){ + + var current = self[key], previous = instance[key]; + + if (current == undefined){ + self[key] = previous; + continue; + } + + var ctype = $type(current), ptype = $type(previous); + + if (ctype != ptype) continue; + + switch (ctype){ + case 'function': + + // opera does not support function.caller, so we replace the function code with brute force. Not pretty, but its just for opera. + // if future opera versions will support function.caller, this code wont be executed anymore. + // this code will be only executed if the current browser does not support function.caller (only opera). + // there is also a fix for an opera bug where in the function string, parentheses around numbers are ignored, and an error is thrown. + + if (!arguments.callee.caller) self[key] = eval('(' + String(current).replace(/\bthis\.parent\(\s*(\))?/g, function(full, close){ + return 'arguments.callee._parent_.call(this' + (close || ', '); + }).replace(/(\d+)\.([A-Za-z_])/g, '($1).$2') + ')'); + + // end "opera" code + + self[key]._parent_ = previous; + break; + case 'object': self[key] = $merge(previous, current); + } + + } + + self.parent = function(){ + return arguments.callee.caller._parent_.apply(this, arguments); + }; + + self.parentOf = function(descendant){ + return descendant._parent_.apply(this, Array.slice(arguments, 1)); + }; + +};/* +Script: Class.Extras.js + Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks. + +License: + MIT-style license. +*/ + +var Chain = new Class({ + + chain: function(){ + this.$chain = (this.$chain || []).extend(arguments); + return this; + }, + + callChain: function(){ + return (this.$chain && this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false; + }, + + clearChain: function(){ + if (this.$chain) this.$chain.empty(); + return this; + } + +}); + +var Events = new Class({ + + addEvent: function(type, fn, internal){ + if (fn != $empty){ + this.$events = this.$events || {}; + this.$events[type] = this.$events[type] || []; + this.$events[type].include(fn); + if (internal) fn.internal = true; + } + return this; + }, + + addEvents: function(events){ + for (var type in events) this.addEvent(type, events[type]); + return this; + }, + + fireEvent: function(type, args, delay){ + if (!this.$events || !this.$events[type]) return this; + this.$events[type].each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + return this; + }, + + removeEvent: function(type, fn){ + if (!this.$events || !this.$events[type]) return this; + if (!fn.internal) this.$events[type].erase(fn); + return this; + }, + + removeEvents: function(type){ + for (var e in this.$events){ + if (type && type != e) continue; + var fns = this.$events[e]; + for (var i = fns.length; i--; i) this.removeEvent(e, fns[i]); + } + return this; + } + +}); + +var Options = new Class({ + + setOptions: function(){ + this.options = $merge.run([this.options].extend(arguments)); + if (!this.addEvent) return this; + for (var option in this.options){ + if ($type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; + this.addEvent(option, this.options[option]); + delete this.options[option]; + } + return this; + } + +});/* +Script: Element.js + One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, + time-saver methods to let you easily work with HTML Elements. + +License: + MIT-style license. +*/ + +Document.implement({ + + newElement: function(tag, props){ + if (Browser.Engine.trident && props){ + ['name', 'type', 'checked'].each(function(attribute){ + if (!props[attribute]) return; + tag += ' ' + attribute + '="' + props[attribute] + '"'; + if (attribute != 'checked') delete props[attribute]; + }); + tag = '<' + tag + '>'; + } + return $.element(this.createElement(tag)).set(props); + }, + + newTextNode: function(text){ + return this.createTextNode(text); + }, + + getDocument: function(){ + return this; + }, + + getWindow: function(){ + return this.defaultView || this.parentWindow; + }, + + purge: function(){ + var elements = this.getElementsByTagName('*'); + for (var i = 0, l = elements.length; i < l; i++) Browser.freeMem(elements[i]); + } + +}); + +var Element = new Native({ + + name: 'Element', + + legacy: window.Element, + + initialize: function(tag, props){ + var konstructor = Element.Constructors.get(tag); + if (konstructor) return konstructor(props); + if (typeof tag == 'string') return document.newElement(tag, props); + return $(tag).set(props); + }, + + afterImplement: function(key, value){ + if (!Array[key]) Elements.implement(key, Elements.multi(key)); + Element.Prototype[key] = value; + } + +}); + +Element.Prototype = {$family: {name: 'element'}}; + +Element.Constructors = new Hash; + +var IFrame = new Native({ + + name: 'IFrame', + + generics: false, + + initialize: function(){ + var params = Array.link(arguments, {properties: Object.type, iframe: $defined}); + var props = params.properties || {}; + var iframe = $(params.iframe) || false; + var onload = props.onload || $empty; + delete props.onload; + props.id = props.name = $pick(props.id, props.name, iframe.id, iframe.name, 'IFrame_' + $time()); + iframe = new Element(iframe || 'iframe', props); + var onFrameLoad = function(){ + var host = $try(function(){ + return iframe.contentWindow.location.host; + }); + if (host && host == window.location.host){ + var win = new Window(iframe.contentWindow); + var doc = new Document(iframe.contentWindow.document); + $extend(win.Element.prototype, Element.Prototype); + } + onload.call(iframe.contentWindow, iframe.contentWindow.document); + }; + (!window.frames[props.id]) ? iframe.addListener('load', onFrameLoad) : onFrameLoad(); + return iframe; + } + +}); + +var Elements = new Native({ + + initialize: function(elements, options){ + options = $extend({ddup: true, cash: true}, options); + elements = elements || []; + if (options.ddup || options.cash){ + var uniques = {}, returned = []; + for (var i = 0, l = elements.length; i < l; i++){ + var el = $.element(elements[i], !options.cash); + if (options.ddup){ + if (uniques[el.uid]) continue; + uniques[el.uid] = true; + } + returned.push(el); + } + elements = returned; + } + return (options.cash) ? $extend(elements, this) : elements; + } + +}); + +Elements.implement({ + + filter: function(filter, bind){ + if (!filter) return this; + return new Elements(Array.filter(this, (typeof filter == 'string') ? function(item){ + return item.match(filter); + } : filter, bind)); + } + +}); + +Elements.multi = function(property){ + return function(){ + var items = []; + var elements = true; + for (var i = 0, j = this.length; i < j; i++){ + var returns = this[i][property].apply(this[i], arguments); + items.push(returns); + if (elements) elements = ($type(returns) == 'element'); + } + return (elements) ? new Elements(items) : items; + }; +}; + +Window.implement({ + + $: function(el, nocash){ + if (el && el.$family && el.uid) return el; + var type = $type(el); + return ($[type]) ? $[type](el, nocash, this.document) : null; + }, + + $$: function(selector){ + if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector); + var elements = []; + var args = Array.flatten(arguments); + for (var i = 0, l = args.length; i < l; i++){ + var item = args[i]; + switch ($type(item)){ + case 'element': item = [item]; break; + case 'string': item = this.document.getElements(item, true); break; + default: item = false; + } + if (item) elements.extend(item); + } + return new Elements(elements); + }, + + getDocument: function(){ + return this.document; + }, + + getWindow: function(){ + return this; + } + +}); + +$.string = function(id, nocash, doc){ + id = doc.getElementById(id); + return (id) ? $.element(id, nocash) : null; +}; + +$.element = function(el, nocash){ + $uid(el); + if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){ + var proto = Element.Prototype; + for (var p in proto) el[p] = proto[p]; + }; + return el; +}; + +$.object = function(obj, nocash, doc){ + if (obj.toElement) return $.element(obj.toElement(doc), nocash); + return null; +}; + +$.textnode = $.whitespace = $.window = $.document = $arguments(0); + +Native.implement([Element, Document], { + + getElement: function(selector, nocash){ + return $(this.getElements(selector, true)[0] || null, nocash); + }, + + getElements: function(tags, nocash){ + tags = tags.split(','); + var elements = []; + var ddup = (tags.length > 1); + tags.each(function(tag){ + var partial = this.getElementsByTagName(tag.trim()); + (ddup) ? elements.extend(partial) : elements = partial; + }, this); + return new Elements(elements, {ddup: ddup, cash: !nocash}); + } + +}); + +Element.Storage = { + + get: function(uid){ + return (this[uid] || (this[uid] = {})); + } + +}; + +Element.Inserters = new Hash({ + + before: function(context, element){ + if (element.parentNode) element.parentNode.insertBefore(context, element); + }, + + after: function(context, element){ + if (!element.parentNode) return; + var next = element.nextSibling; + (next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context); + }, + + bottom: function(context, element){ + element.appendChild(context); + }, + + top: function(context, element){ + var first = element.firstChild; + (first) ? element.insertBefore(context, first) : element.appendChild(context); + } + +}); + +Element.Inserters.inside = Element.Inserters.bottom; + +Element.Inserters.each(function(value, key){ + + var Key = key.capitalize(); + + Element.implement('inject' + Key, function(el){ + value(this, $(el, true)); + return this; + }); + + Element.implement('grab' + Key, function(el){ + value($(el, true), this); + return this; + }); + +}); + +Element.implement({ + + getDocument: function(){ + return this.ownerDocument; + }, + + getWindow: function(){ + return this.ownerDocument.getWindow(); + }, + + getElementById: function(id, nocash){ + var el = this.ownerDocument.getElementById(id); + if (!el) return null; + for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ + if (!parent) return null; + } + return $.element(el, nocash); + }, + + set: function(prop, value){ + switch ($type(prop)){ + case 'object': + for (var p in prop) this.set(p, prop[p]); + break; + case 'string': + var property = Element.Properties.get(prop); + (property && property.set) ? property.set.apply(this, Array.slice(arguments, 1)) : this.setProperty(prop, value); + } + return this; + }, + + get: function(prop){ + var property = Element.Properties.get(prop); + return (property && property.get) ? property.get.apply(this, Array.slice(arguments, 1)) : this.getProperty(prop); + }, + + erase: function(prop){ + var property = Element.Properties.get(prop); + (property && property.erase) ? property.erase.apply(this, Array.slice(arguments, 1)) : this.removeProperty(prop); + return this; + }, + + match: function(tag){ + return (!tag || Element.get(this, 'tag') == tag); + }, + + inject: function(el, where){ + Element.Inserters.get(where || 'bottom')(this, $(el, true)); + return this; + }, + + wraps: function(el, where){ + el = $(el, true); + return this.replaces(el).grab(el, where); + }, + + grab: function(el, where){ + Element.Inserters.get(where || 'bottom')($(el, true), this); + return this; + }, + + appendText: function(text, where){ + return this.grab(this.getDocument().newTextNode(text), where); + }, + + adopt: function(){ + Array.flatten(arguments).each(function(element){ + element = $(element, true); + if (element) this.appendChild(element); + }, this); + return this; + }, + + dispose: function(){ + return (this.parentNode) ? this.parentNode.removeChild(this) : this; + }, + + clone: function(contents, keepid){ + switch ($type(this)){ + case 'element': + var attributes = {}; + for (var j = 0, l = this.attributes.length; j < l; j++){ + var attribute = this.attributes[j], key = attribute.nodeName.toLowerCase(); + var value = (key == 'style' && this.style) ? this.style.cssText : attribute.nodeValue; + if (!$chk(value) || key == 'uid' || (key == 'id' && !keepid)) continue; + if (value != 'inherit' && ['string', 'number'].contains($type(value))) attributes[key] = value; + } + var element = new Element(this.nodeName.toLowerCase(), attributes); + if (contents !== false){ + for (var i = 0, k = this.childNodes.length; i < k; i++){ + var child = Element.clone(this.childNodes[i], true, keepid); + if (child) element.grab(child); + } + } + return element; + case 'textnode': return document.newTextNode(this.nodeValue); + } + return null; + }, + + replaces: function(el){ + el = $(el, true); + el.parentNode.replaceChild(this, el); + return this; + }, + + hasClass: function(className){ + return this.className.contains(className, ' '); + }, + + addClass: function(className){ + if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); + return this; + }, + + removeClass: function(className){ + this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean(); + return this; + }, + + toggleClass: function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + getComputedStyle: function(property){ + if (this.currentStyle) return this.currentStyle[property.camelCase()]; + var computed = this.getWindow().getComputedStyle(this, null); + return (computed) ? computed.getPropertyValue([property.hyphenate()]) : null; + }, + + empty: function(){ + $A(this.childNodes).each(function(node){ + Browser.freeMem(node); + Element.empty(node); + Element.dispose(node); + }, this); + return this; + }, + + destroy: function(){ + Browser.freeMem(this.empty().dispose()); + return null; + }, + + getSelected: function(){ + return new Elements($A(this.options).filter(function(option){ + return option.selected; + })); + }, + + toQueryString: function(){ + var queryString = []; + this.getElements('input, select, textarea').each(function(el){ + if (!el.name || el.disabled) return; + var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){ + return opt.value; + }) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value; + $splat(value).each(function(val){ + if (val) queryString.push(el.name + '=' + encodeURIComponent(val)); + }); + }); + return queryString.join('&'); + }, + + getProperty: function(attribute){ + var EA = Element.Attributes, key = EA.Props[attribute]; + var value = (key) ? this[key] : this.getAttribute(attribute, 2); + return (EA.Bools[attribute]) ? !!value : (key) ? value : value || null; + }, + + getProperties: function(){ + var args = $A(arguments); + return args.map(function(attr){ + return this.getProperty(attr); + }, this).associate(args); + }, + + setProperty: function(attribute, value){ + var EA = Element.Attributes, key = EA.Props[attribute], hasValue = $defined(value); + if (key && EA.Bools[attribute]) value = (value || !hasValue) ? true : false; + else if (!hasValue) return this.removeProperty(attribute); + (key) ? this[key] = value : this.setAttribute(attribute, value); + return this; + }, + + setProperties: function(attributes){ + for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]); + return this; + }, + + removeProperty: function(attribute){ + var EA = Element.Attributes, key = EA.Props[attribute], isBool = (key && EA.Bools[attribute]); + (key) ? this[key] = (isBool) ? false : '' : this.removeAttribute(attribute); + return this; + }, + + removeProperties: function(){ + Array.each(arguments, this.removeProperty, this); + return this; + } + +}); + +(function(){ + +var walk = function(element, walk, start, match, all, nocash){ + var el = element[start || walk]; + var elements = []; + while (el){ + if (el.nodeType == 1 && (!match || Element.match(el, match))){ + elements.push(el); + if (!all) break; + } + el = el[walk]; + } + return (all) ? new Elements(elements, {ddup: false, cash: !nocash}) : $(elements[0], nocash); +}; + +Element.implement({ + + getPrevious: function(match, nocash){ + return walk(this, 'previousSibling', null, match, false, nocash); + }, + + getAllPrevious: function(match, nocash){ + return walk(this, 'previousSibling', null, match, true, nocash); + }, + + getNext: function(match, nocash){ + return walk(this, 'nextSibling', null, match, false, nocash); + }, + + getAllNext: function(match, nocash){ + return walk(this, 'nextSibling', null, match, true, nocash); + }, + + getFirst: function(match, nocash){ + return walk(this, 'nextSibling', 'firstChild', match, false, nocash); + }, + + getLast: function(match, nocash){ + return walk(this, 'previousSibling', 'lastChild', match, false, nocash); + }, + + getParent: function(match, nocash){ + return walk(this, 'parentNode', null, match, false, nocash); + }, + + getParents: function(match, nocash){ + return walk(this, 'parentNode', null, match, true, nocash); + }, + + getChildren: function(match, nocash){ + return walk(this, 'nextSibling', 'firstChild', match, true, nocash); + }, + + hasChild: function(el){ + el = $(el, true); + return (!!el && $A(this.getElementsByTagName(el.tagName)).contains(el)); + } + +}); + +})(); + +Element.Properties = new Hash; + +Element.Properties.style = { + + set: function(style){ + this.style.cssText = style; + }, + + get: function(){ + return this.style.cssText; + }, + + erase: function(){ + this.style.cssText = ''; + } + +}; + +Element.Properties.tag = {get: function(){ + return this.tagName.toLowerCase(); +}}; + +Element.Properties.href = {get: function(){ + return (!this.href) ? null : this.href.replace(new RegExp('^' + document.location.protocol + '\/\/' + document.location.host), ''); +}}; + +Element.Properties.html = {set: function(){ + return this.innerHTML = Array.flatten(arguments).join(''); +}}; + +Native.implement([Element, Window, Document], { + + addListener: function(type, fn){ + if (this.addEventListener) this.addEventListener(type, fn, false); + else this.attachEvent('on' + type, fn); + return this; + }, + + removeListener: function(type, fn){ + if (this.removeEventListener) this.removeEventListener(type, fn, false); + else this.detachEvent('on' + type, fn); + return this; + }, + + retrieve: function(property, dflt){ + var storage = Element.Storage.get(this.uid); + var prop = storage[property]; + if ($defined(dflt) && !$defined(prop)) prop = storage[property] = dflt; + return $pick(prop); + }, + + store: function(property, value){ + var storage = Element.Storage.get(this.uid); + storage[property] = value; + return this; + }, + + eliminate: function(property){ + var storage = Element.Storage.get(this.uid); + delete storage[property]; + return this; + } + +}); + +Element.Attributes = new Hash({ + Props: {'html': 'innerHTML', 'class': 'className', 'for': 'htmlFor', 'text': (Browser.Engine.trident) ? 'innerText' : 'textContent'}, + Bools: ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'], + Camels: ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap'] +}); + +Browser.freeMem = function(item){ + if (!item) return; + if (Browser.Engine.trident && (/object/i).test(item.tagName)){ + for (var p in item){ + if (typeof item[p] == 'function') item[p] = $empty; + } + Element.dispose(item); + } + if (item.uid && item.removeEvents) item.removeEvents(); +}; + +(function(EA){ + + var EAB = EA.Bools, EAC = EA.Camels; + EA.Bools = EAB = EAB.associate(EAB); + Hash.extend(Hash.combine(EA.Props, EAB), EAC.associate(EAC.map(function(v){ + return v.toLowerCase(); + }))); + EA.erase('Camels'); + +})(Element.Attributes); + +window.addListener('unload', function(){ + window.removeListener('unload', arguments.callee); + document.purge(); + if (Browser.Engine.trident) CollectGarbage(); +});/* +Script: Element.Event.js + Contains Element methods for dealing with events, and custom Events. + +License: + MIT-style license. +*/ + +Element.Properties.events = {set: function(events){ + this.addEvents(events); +}}; + +Native.implement([Element, Window, Document], { + + addEvent: function(type, fn){ + var events = this.retrieve('events', {}); + events[type] = events[type] || {'keys': [], 'values': []}; + if (events[type].keys.contains(fn)) return this; + events[type].keys.push(fn); + var realType = type, custom = Element.Events.get(type), condition = fn, self = this; + if (custom){ + if (custom.onAdd) custom.onAdd.call(this, fn); + if (custom.condition){ + condition = function(event){ + if (custom.condition.call(this, event)) return fn.call(this, event); + return false; + }; + } + realType = custom.base || realType; + } + var defn = function(){ + return fn.call(self); + }; + var nativeEvent = Element.NativeEvents[realType] || 0; + if (nativeEvent){ + if (nativeEvent == 2){ + defn = function(event){ + event = new Event(event, self.getWindow()); + if (condition.call(self, event) === false) event.stop(); + }; + } + this.addListener(realType, defn); + } + events[type].values.push(defn); + return this; + }, + + removeEvent: function(type, fn){ + var events = this.retrieve('events'); + if (!events || !events[type]) return this; + var pos = events[type].keys.indexOf(fn); + if (pos == -1) return this; + var key = events[type].keys.splice(pos, 1)[0]; + var value = events[type].values.splice(pos, 1)[0]; + var custom = Element.Events.get(type); + if (custom){ + if (custom.onRemove) custom.onRemove.call(this, fn); + type = custom.base || type; + } + return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this; + }, + + addEvents: function(events){ + for (var event in events) this.addEvent(event, events[event]); + return this; + }, + + removeEvents: function(type){ + var events = this.retrieve('events'); + if (!events) return this; + if (!type){ + for (var evType in events) this.removeEvents(evType); + events = null; + } else if (events[type]){ + while (events[type].keys[0]) this.removeEvent(type, events[type].keys[0]); + events[type] = null; + } + return this; + }, + + fireEvent: function(type, args, delay){ + var events = this.retrieve('events'); + if (!events || !events[type]) return this; + events[type].keys.each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + return this; + }, + + cloneEvents: function(from, type){ + from = $(from); + var fevents = from.retrieve('events'); + if (!fevents) return this; + if (!type){ + for (var evType in fevents) this.cloneEvents(from, evType); + } else if (fevents[type]){ + fevents[type].keys.each(function(fn){ + this.addEvent(type, fn); + }, this); + } + return this; + } + +}); + +Element.NativeEvents = { + click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons + mousewheel: 2, DOMMouseScroll: 2, //mouse wheel + mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement + keydown: 2, keypress: 2, keyup: 2, //keyboard + focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements + load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window + error: 1, abort: 1, scroll: 1 //misc +}; + +(function(){ + +var $check = function(event){ + var related = event.relatedTarget; + if (related == undefined) return true; + if (related === false) return false; + return ($type(this) != 'document' && related != this && related.prefix != 'xul' && !this.hasChild(related)); +}; + +Element.Events = new Hash({ + + mouseenter: { + base: 'mouseover', + condition: $check + }, + + mouseleave: { + base: 'mouseout', + condition: $check + }, + + mousewheel: { + base: (Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel' + } + +}); + +})();/* +Script: Element.Style.js + Contains methods for interacting with the styles of Elements in a fashionable way. + +License: + MIT-style license. +*/ + +Element.Properties.styles = {set: function(styles){ + this.setStyles(styles); +}}; + +Element.Properties.opacity = { + + set: function(opacity, novisibility){ + if (!novisibility){ + if (opacity == 0){ + if (this.style.visibility != 'hidden') this.style.visibility = 'hidden'; + } else { + if (this.style.visibility != 'visible') this.style.visibility = 'visible'; + } + } + if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; + if (Browser.Engine.trident) this.style.filter = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')'; + this.style.opacity = opacity; + this.store('opacity', opacity); + }, + + get: function(){ + return this.retrieve('opacity', 1); + } + +}; + +Element.implement({ + + setOpacity: function(value){ + return this.set('opacity', value, true); + }, + + getOpacity: function(){ + return this.get('opacity'); + }, + + setStyle: function(property, value){ + switch (property){ + case 'opacity': return this.set('opacity', parseFloat(value)); + case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat'; + } + property = property.camelCase(); + if ($type(value) != 'string'){ + var map = (Element.Styles.get(property) || '@').split(' '); + value = $splat(value).map(function(val, i){ + if (!map[i]) return ''; + return ($type(val) == 'number') ? map[i].replace('@', Math.round(val)) : val; + }).join(' '); + } else if (value == String(Number(value))){ + value = Math.round(value); + } + this.style[property] = value; + return this; + }, + + getStyle: function(property){ + switch (property){ + case 'opacity': return this.get('opacity'); + case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat'; + } + property = property.camelCase(); + var result = this.style[property]; + if (!$chk(result)){ + result = []; + for (var style in Element.ShortStyles){ + if (property != style) continue; + for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s)); + return result.join(' '); + } + result = this.getComputedStyle(property); + } + if (result){ + result = String(result); + var color = result.match(/rgba?\([\d\s,]+\)/); + if (color) result = result.replace(color[0], color[0].rgbToHex()); + } + if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result)))){ + if (property.test(/^(height|width)$/)){ + var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0; + values.each(function(value){ + size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt(); + }, this); + return this['offset' + property.capitalize()] - size + 'px'; + } + if (Browser.Engine.presto && String(result).test('px')) return result; + if (property.test(/(border(.+)Width|margin|padding)/)) return '0px'; + } + return result; + }, + + setStyles: function(styles){ + for (var style in styles) this.setStyle(style, styles[style]); + return this; + }, + + getStyles: function(){ + var result = {}; + Array.each(arguments, function(key){ + result[key] = this.getStyle(key); + }, this); + return result; + } + +}); + +Element.Styles = new Hash({ + left: '@px', top: '@px', bottom: '@px', right: '@px', + width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px', + backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)', + fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)', + margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)', + borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)', + zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@' +}); + +Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}}; + +['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ + var Short = Element.ShortStyles; + var All = Element.Styles; + ['margin', 'padding'].each(function(style){ + var sd = style + direction; + Short[style][sd] = All[sd] = '@px'; + }); + var bd = 'border' + direction; + Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)'; + var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color'; + Short[bd] = {}; + Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px'; + Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@'; + Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)'; +}); +/* +Script: Element.Dimensions.js + Contains methods to work with size, scroll, or positioning of Elements and the window object. + +License: + MIT-style license. + +Credits: + - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html). + - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html). +*/ + +(function(){ + +Element.implement({ + + scrollTo: function(x, y){ + if (isBody(this)){ + this.getWindow().scrollTo(x, y); + } else { + this.scrollLeft = x; + this.scrollTop = y; + } + return this; + }, + + getSize: function(){ + if (isBody(this)) return this.getWindow().getSize(); + return {x: this.offsetWidth, y: this.offsetHeight}; + }, + + getScrollSize: function(){ + if (isBody(this)) return this.getWindow().getScrollSize(); + return {x: this.scrollWidth, y: this.scrollHeight}; + }, + + getScroll: function(){ + if (isBody(this)) return this.getWindow().getScroll(); + return {x: this.scrollLeft, y: this.scrollTop}; + }, + + getScrolls: function(){ + var element = this, position = {x: 0, y: 0}; + while (element && !isBody(element)){ + position.x += element.scrollLeft; + position.y += element.scrollTop; + element = element.parentNode; + } + return position; + }, + + getOffsets: function(){ + var element = this, position = {x: 0, y: 0}; + if (isBody(this)) return position; + + while (element && !isBody(element)){ + position.x += element.offsetLeft; + position.y += element.offsetTop; + + if (Browser.Engine.gecko){ + if (!borderBox(element)){ + position.x += leftBorder(element); + position.y += topBorder(element); + } + var parent = element.parentNode; + if (parent && styleString(parent, 'overflow') != 'visible'){ + position.x += leftBorder(parent); + position.y += topBorder(parent); + } + } else if (element != this && (Browser.Engine.trident || Browser.Engine.webkit)){ + position.x += leftBorder(element); + position.y += topBorder(element); + } + + element = element.offsetParent; + if (Browser.Engine.trident){ + while (element && !element.currentStyle.hasLayout) element = element.offsetParent; + } + } + if (Browser.Engine.gecko && !borderBox(this)){ + position.x -= leftBorder(this); + position.y -= topBorder(this); + } + return position; + }, + + getPosition: function(relative){ + if (isBody(this)) return {x: 0, y: 0}; + var offset = this.getOffsets(), scroll = this.getScrolls(); + var position = {x: offset.x - scroll.x, y: offset.y - scroll.y}; + var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0}; + return {x: position.x - relativePosition.x, y: position.y - relativePosition.y}; + }, + + getCoordinates: function(element){ + if (isBody(this)) return this.getWindow().getCoordinates(); + var position = this.getPosition(element), size = this.getSize(); + var obj = {left: position.x, top: position.y, width: size.x, height: size.y}; + obj.right = obj.left + obj.width; + obj.bottom = obj.top + obj.height; + return obj; + }, + + computePosition: function(obj){ + return {left: obj.x - styleNumber(this, 'margin-left'), top: obj.y - styleNumber(this, 'margin-top')}; + }, + + position: function(obj){ + return this.setStyles(this.computePosition(obj)); + } + +}); + +Native.implement([Document, Window], { + + getSize: function(){ + var win = this.getWindow(); + if (Browser.Engine.presto || Browser.Engine.webkit) return {x: win.innerWidth, y: win.innerHeight}; + var doc = getCompatElement(this); + return {x: doc.clientWidth, y: doc.clientHeight}; + }, + + getScroll: function(){ + var win = this.getWindow(); + var doc = getCompatElement(this); + return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop}; + }, + + getScrollSize: function(){ + var doc = getCompatElement(this); + var min = this.getSize(); + return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)}; + }, + + getPosition: function(){ + return {x: 0, y: 0}; + }, + + getCoordinates: function(){ + var size = this.getSize(); + return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x}; + } + +}); + +// private methods + +var styleString = Element.getComputedStyle; + +function styleNumber(element, style){ + return styleString(element, style).toInt() || 0; +}; + +function borderBox(element){ + return styleString(element, '-moz-box-sizing') == 'border-box'; +}; + +function topBorder(element){ + return styleNumber(element, 'border-top-width'); +}; + +function leftBorder(element){ + return styleNumber(element, 'border-left-width'); +}; + +function isBody(element){ + return (/^(?:body|html)$/i).test(element.tagName); +}; + +function getCompatElement(element){ + var doc = element.getDocument(); + return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; +}; + +})(); + +//aliases + +Native.implement([Window, Document, Element], { + + getHeight: function(){ + return this.getSize().y; + }, + + getWidth: function(){ + return this.getSize().x; + }, + + getScrollTop: function(){ + return this.getScroll().y; + }, + + getScrollLeft: function(){ + return this.getScroll().x; + }, + + getScrollHeight: function(){ + return this.getScrollSize().y; + }, + + getScrollWidth: function(){ + return this.getScrollSize().x; + }, + + getTop: function(){ + return this.getPosition().y; + }, + + getLeft: function(){ + return this.getPosition().x; + } + +});/* +Script: Selectors.js + Adds advanced CSS Querying capabilities for targeting elements. Also includes pseudoselectors support. + +License: + MIT-style license. +*/ + +Native.implement([Document, Element], { + + getElements: function(expression, nocash){ + expression = expression.split(','); + var items, local = {}; + for (var i = 0, l = expression.length; i < l; i++){ + var selector = expression[i], elements = Selectors.Utils.search(this, selector, local); + if (i != 0 && elements.item) elements = $A(elements); + items = (i == 0) ? elements : (items.item) ? $A(items).concat(elements) : items.concat(elements); + } + return new Elements(items, {ddup: (expression.length > 1), cash: !nocash}); + } + +}); + +Element.implement({ + + match: function(selector){ + if (!selector) return true; + var tagid = Selectors.Utils.parseTagAndID(selector); + var tag = tagid[0], id = tagid[1]; + if (!Selectors.Filters.byID(this, id) || !Selectors.Filters.byTag(this, tag)) return false; + var parsed = Selectors.Utils.parseSelector(selector); + return (parsed) ? Selectors.Utils.filter(this, parsed, {}) : true; + } + +}); + +var Selectors = {Cache: {nth: {}, parsed: {}}}; + +Selectors.RegExps = { + id: (/#([\w-]+)/), + tag: (/^(\w+|\*)/), + quick: (/^(\w+|\*)$/), + splitter: (/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g), + combined: (/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)["']?(.*?)["']?)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g) +}; + +Selectors.Utils = { + + chk: function(item, uniques){ + if (!uniques) return true; + var uid = $uid(item); + if (!uniques[uid]) return uniques[uid] = true; + return false; + }, + + parseNthArgument: function(argument){ + if (Selectors.Cache.nth[argument]) return Selectors.Cache.nth[argument]; + var parsed = argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/); + if (!parsed) return false; + var inta = parseInt(parsed[1]); + var a = (inta || inta === 0) ? inta : 1; + var special = parsed[2] || false; + var b = parseInt(parsed[3]) || 0; + if (a != 0){ + b--; + while (b < 1) b += a; + while (b >= a) b -= a; + } else { + a = b; + special = 'index'; + } + switch (special){ + case 'n': parsed = {a: a, b: b, special: 'n'}; break; + case 'odd': parsed = {a: 2, b: 0, special: 'n'}; break; + case 'even': parsed = {a: 2, b: 1, special: 'n'}; break; + case 'first': parsed = {a: 0, special: 'index'}; break; + case 'last': parsed = {special: 'last-child'}; break; + case 'only': parsed = {special: 'only-child'}; break; + default: parsed = {a: (a - 1), special: 'index'}; + } + + return Selectors.Cache.nth[argument] = parsed; + }, + + parseSelector: function(selector){ + if (Selectors.Cache.parsed[selector]) return Selectors.Cache.parsed[selector]; + var m, parsed = {classes: [], pseudos: [], attributes: []}; + while ((m = Selectors.RegExps.combined.exec(selector))){ + var cn = m[1], an = m[2], ao = m[3], av = m[4], pn = m[5], pa = m[6]; + if (cn){ + parsed.classes.push(cn); + } else if (pn){ + var parser = Selectors.Pseudo.get(pn); + if (parser) parsed.pseudos.push({parser: parser, argument: pa}); + else parsed.attributes.push({name: pn, operator: '=', value: pa}); + } else if (an){ + parsed.attributes.push({name: an, operator: ao, value: av}); + } + } + if (!parsed.classes.length) delete parsed.classes; + if (!parsed.attributes.length) delete parsed.attributes; + if (!parsed.pseudos.length) delete parsed.pseudos; + if (!parsed.classes && !parsed.attributes && !parsed.pseudos) parsed = null; + return Selectors.Cache.parsed[selector] = parsed; + }, + + parseTagAndID: function(selector){ + var tag = selector.match(Selectors.RegExps.tag); + var id = selector.match(Selectors.RegExps.id); + return [(tag) ? tag[1] : '*', (id) ? id[1] : false]; + }, + + filter: function(item, parsed, local){ + var i; + if (parsed.classes){ + for (i = parsed.classes.length; i--; i){ + var cn = parsed.classes[i]; + if (!Selectors.Filters.byClass(item, cn)) return false; + } + } + if (parsed.attributes){ + for (i = parsed.attributes.length; i--; i){ + var att = parsed.attributes[i]; + if (!Selectors.Filters.byAttribute(item, att.name, att.operator, att.value)) return false; + } + } + if (parsed.pseudos){ + for (i = parsed.pseudos.length; i--; i){ + var psd = parsed.pseudos[i]; + if (!Selectors.Filters.byPseudo(item, psd.parser, psd.argument, local)) return false; + } + } + return true; + }, + + getByTagAndID: function(ctx, tag, id){ + if (id){ + var item = ctx.getElementById(id, true); + return (item && Selectors.Filters.byTag(item, tag)) ? [item] : []; + } else { + return ctx.getElementsByTagName(tag); + } + }, + + search: function(self, expression, local){ + var splitters = []; + + var selectors = expression.trim().replace(Selectors.RegExps.splitter, function(m0, m1, m2){ + splitters.push(m1); + return ':)' + m2; + }).split(':)'); + + var items, match, filtered, item; + + for (var i = 0, l = selectors.length; i < l; i++){ + + var selector = selectors[i]; + + if (i == 0 && Selectors.RegExps.quick.test(selector)){ + items = self.getElementsByTagName(selector); + continue; + } + + var splitter = splitters[i - 1]; + + var tagid = Selectors.Utils.parseTagAndID(selector); + var tag = tagid[0], id = tagid[1]; + + if (i == 0){ + items = Selectors.Utils.getByTagAndID(self, tag, id); + } else { + var uniques = {}, found = []; + for (var j = 0, k = items.length; j < k; j++) found = Selectors.Getters[splitter](found, items[j], tag, id, uniques); + items = found; + } + + var parsed = Selectors.Utils.parseSelector(selector); + + if (parsed){ + filtered = []; + for (var m = 0, n = items.length; m < n; m++){ + item = items[m]; + if (Selectors.Utils.filter(item, parsed, local)) filtered.push(item); + } + items = filtered; + } + + } + + return items; + + } + +}; + +Selectors.Getters = { + + ' ': function(found, self, tag, id, uniques){ + var items = Selectors.Utils.getByTagAndID(self, tag, id); + for (var i = 0, l = items.length; i < l; i++){ + var item = items[i]; + if (Selectors.Utils.chk(item, uniques)) found.push(item); + } + return found; + }, + + '>': function(found, self, tag, id, uniques){ + var children = Selectors.Utils.getByTagAndID(self, tag, id); + for (var i = 0, l = children.length; i < l; i++){ + var child = children[i]; + if (child.parentNode == self && Selectors.Utils.chk(child, uniques)) found.push(child); + } + return found; + }, + + '+': function(found, self, tag, id, uniques){ + while ((self = self.nextSibling)){ + if (self.nodeType == 1){ + if (Selectors.Utils.chk(self, uniques) && Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self); + break; + } + } + return found; + }, + + '~': function(found, self, tag, id, uniques){ + + while ((self = self.nextSibling)){ + if (self.nodeType == 1){ + if (!Selectors.Utils.chk(self, uniques)) break; + if (Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self); + } + } + return found; + } + +}; + +Selectors.Filters = { + + byTag: function(self, tag){ + return (tag == '*' || (self.tagName && self.tagName.toLowerCase() == tag)); + }, + + byID: function(self, id){ + return (!id || (self.id && self.id == id)); + }, + + byClass: function(self, klass){ + return (self.className && self.className.contains(klass, ' ')); + }, + + byPseudo: function(self, parser, argument, local){ + return parser.call(self, argument, local); + }, + + byAttribute: function(self, name, operator, value){ + var result = Element.prototype.getProperty.call(self, name); + if (!result) return false; + if (!operator || value == undefined) return true; + switch (operator){ + case '=': return (result == value); + case '*=': return (result.contains(value)); + case '^=': return (result.substr(0, value.length) == value); + case '$=': return (result.substr(result.length - value.length) == value); + case '!=': return (result != value); + case '~=': return result.contains(value, ' '); + case '|=': return result.contains(value, '-'); + } + return false; + } + +}; + +Selectors.Pseudo = new Hash({ + + // w3c pseudo selectors + + empty: function(){ + return !(this.innerText || this.textContent || '').length; + }, + + not: function(selector){ + return !Element.match(this, selector); + }, + + contains: function(text){ + return (this.innerText || this.textContent || '').contains(text); + }, + + 'first-child': function(){ + return Selectors.Pseudo.index.call(this, 0); + }, + + 'last-child': function(){ + var element = this; + while ((element = element.nextSibling)){ + if (element.nodeType == 1) return false; + } + return true; + }, + + 'only-child': function(){ + var prev = this; + while ((prev = prev.previousSibling)){ + if (prev.nodeType == 1) return false; + } + var next = this; + while ((next = next.nextSibling)){ + if (next.nodeType == 1) return false; + } + return true; + }, + + 'nth-child': function(argument, local){ + argument = (argument == undefined) ? 'n' : argument; + var parsed = Selectors.Utils.parseNthArgument(argument); + if (parsed.special != 'n') return Selectors.Pseudo[parsed.special].call(this, parsed.a, local); + var count = 0; + local.positions = local.positions || {}; + var uid = $uid(this); + if (!local.positions[uid]){ + var self = this; + while ((self = self.previousSibling)){ + if (self.nodeType != 1) continue; + count ++; + var position = local.positions[$uid(self)]; + if (position != undefined){ + count = position + count; + break; + } + } + local.positions[uid] = count; + } + return (local.positions[uid] % parsed.a == parsed.b); + }, + + // custom pseudo selectors + + index: function(index){ + var element = this, count = 0; + while ((element = element.previousSibling)){ + if (element.nodeType == 1 && ++count > index) return false; + } + return (count == index); + }, + + even: function(argument, local){ + return Selectors.Pseudo['nth-child'].call(this, '2n+1', local); + }, + + odd: function(argument, local){ + return Selectors.Pseudo['nth-child'].call(this, '2n', local); + } + +});/* +Script: Domready.js + Contains the domready custom event. + +License: + MIT-style license. +*/ + +Element.Events.domready = { + + onAdd: function(fn){ + if (Browser.loaded) fn.call(this); + } + +}; + +(function(){ + + var domready = function(){ + if (Browser.loaded) return; + Browser.loaded = true; + window.fireEvent('domready'); + document.fireEvent('domready'); + }; + + switch (Browser.Engine.name){ + + case 'webkit': (function(){ + (['loaded', 'complete'].contains(document.readyState)) ? domready() : arguments.callee.delay(50); + })(); break; + + case 'trident': + var temp = document.createElement('div'); + (function(){ + ($try(function(){ + temp.doScroll('left'); + return $(temp).inject(document.body).set('html', 'temp').dispose(); + })) ? domready() : arguments.callee.delay(50); + })(); + break; + + default: + window.addEvent('load', domready); + document.addEvent('DOMContentLoaded', domready); + + } + +})();/* +Script: JSON.js + JSON encoder and decoder. + +License: + MIT-style license. + +See Also: + +*/ + +var JSON = new Hash({ + + encode: function(obj){ + switch ($type(obj)){ + case 'string': + return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"'; + case 'array': + return '[' + String(obj.map(JSON.encode).filter($defined)) + ']'; + case 'object': case 'hash': + var string = []; + Hash.each(obj, function(value, key){ + var json = JSON.encode(value); + if (json) string.push(JSON.encode(key) + ':' + json); + }); + return '{' + string + '}'; + case 'number': case 'boolean': return String(obj); + case false: return 'null'; + } + return null; + }, + + $specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'}, + + $replaceChars: function(chr){ + return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16); + }, + + decode: function(string, secure){ + if ($type(string) != 'string' || !string.length) return null; + if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null; + return eval('(' + string + ')'); + } + +}); + +Native.implement([Hash, Array, String, Number], { + + toJSON: function(){ + return JSON.encode(this); + } + +}); +/* +Script: Cookie.js + Class for creating, loading, and saving browser Cookies. + +License: + MIT-style license. + +Credits: + Based on the functions by Peter-Paul Koch (http://quirksmode.org). +*/ + +var Cookie = new Class({ + + Implements: Options, + + options: { + path: false, + domain: false, + duration: false, + secure: false, + document: document + }, + + initialize: function(key, options){ + this.key = key; + this.setOptions(options); + }, + + write: function(value){ + value = encodeURIComponent(value); + if (this.options.domain) value += '; domain=' + this.options.domain; + if (this.options.path) value += '; path=' + this.options.path; + if (this.options.duration){ + var date = new Date(); + date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000); + value += '; expires=' + date.toGMTString(); + } + if (this.options.secure) value += '; secure'; + this.options.document.cookie = this.key + '=' + value; + return this; + }, + + read: function(){ + var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)'); + return (value) ? decodeURIComponent(value[1]) : null; + }, + + dispose: function(){ + new Cookie(this.key, $merge(this.options, {duration: -1})).write(''); + return this; + } + +}); + +Cookie.write = function(key, value, options){ + return new Cookie(key, options).write(value); +}; + +Cookie.read = function(key){ + return new Cookie(key).read(); +}; + +Cookie.dispose = function(key, options){ + return new Cookie(key, options).dispose(); +};/* +Script: Swiff.js + Wrapper for embedding SWF movies. Supports (and fixes) External Interface Communication. + +License: + MIT-style license. + +Credits: + Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject. +*/ + +var Swiff = new Class({ + + Implements: [Options], + + options: { + id: null, + height: 1, + width: 1, + container: null, + properties: {}, + params: { + quality: 'high', + allowScriptAccess: 'always', + wMode: 'transparent', + swLiveConnect: true + }, + callBacks: {}, + vars: {} + }, + + toElement: function(){ + return this.object; + }, + + initialize: function(path, options){ + this.instance = 'Swiff_' + $time(); + + this.setOptions(options); + options = this.options; + var id = this.id = options.id || this.instance; + var container = $(options.container); + + Swiff.CallBacks[this.instance] = {}; + + var params = options.params, vars = options.vars, callBacks = options.callBacks; + var properties = $extend({height: options.height, width: options.width}, options.properties); + + var self = this; + + for (var callBack in callBacks){ + Swiff.CallBacks[this.instance][callBack] = (function(option){ + return function(){ + return option.apply(self.object, arguments); + }; + })(callBacks[callBack]); + vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack; + } + + params.flashVars = Hash.toQueryString(vars); + if (Browser.Engine.trident){ + properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; + params.movie = path; + } else { + properties.type = 'application/x-shockwave-flash'; + properties.data = path; + } + var build = ''; + } + build += ''; + this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild; + }, + + replaces: function(element){ + element = $(element, true); + element.parentNode.replaceChild(this.toElement(), element); + return this; + }, + + inject: function(element){ + $(element, true).appendChild(this.toElement()); + return this; + }, + + remote: function(){ + return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments)); + } + +}); + +Swiff.CallBacks = {}; + +Swiff.remote = function(obj, fn){ + var rs = obj.CallFunction('' + __flash__argumentsToXML(arguments, 2) + ''); + return eval(rs); +};/* +Script: Fx.js + Contains the basic animation logic to be extended by all other Fx Classes. + +License: + MIT-style license. +*/ + +var Fx = new Class({ + + Implements: [Chain, Events, Options], + + options: { + /* + onStart: $empty, + onCancel: $empty, + onComplete: $empty, + */ + fps: 50, + unit: false, + duration: 500, + link: 'ignore', + transition: function(p){ + return -(Math.cos(Math.PI * p) - 1) / 2; + } + }, + + initialize: function(options){ + this.subject = this.subject || this; + this.setOptions(options); + this.options.duration = Fx.Durations[this.options.duration] || this.options.duration.toInt(); + var wait = this.options.wait; + if (wait === false) this.options.link = 'cancel'; + }, + + step: function(){ + var time = $time(); + if (time < this.time + this.options.duration){ + var delta = this.options.transition((time - this.time) / this.options.duration); + this.set(this.compute(this.from, this.to, delta)); + } else { + this.set(this.compute(this.from, this.to, 1)); + this.complete(); + } + }, + + set: function(now){ + return now; + }, + + compute: function(from, to, delta){ + return Fx.compute(from, to, delta); + }, + + check: function(caller){ + if (!this.timer) return true; + switch (this.options.link){ + case 'cancel': this.cancel(); return true; + case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false; + } + return false; + }, + + start: function(from, to){ + if (!this.check(arguments.callee, from, to)) return this; + this.from = from; + this.to = to; + this.time = 0; + this.startTimer(); + this.onStart(); + return this; + }, + + complete: function(){ + if (this.stopTimer()) this.onComplete(); + return this; + }, + + cancel: function(){ + if (this.stopTimer()) this.onCancel(); + return this; + }, + + onStart: function(){ + this.fireEvent('onStart', this.subject); + }, + + onComplete: function(){ + this.fireEvent('onComplete', this.subject); + if (!this.callChain()) this.fireEvent('onChainComplete', this.subject); + }, + + onCancel: function(){ + this.fireEvent('onCancel', this.subject).clearChain(); + }, + + pause: function(){ + this.stopTimer(); + return this; + }, + + resume: function(){ + this.startTimer(); + return this; + }, + + stopTimer: function(){ + if (!this.timer) return false; + this.time = $time() - this.time; + this.timer = $clear(this.timer); + return true; + }, + + startTimer: function(){ + if (this.timer) return false; + this.time = $time() - this.time; + this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this); + return true; + } + +}); + +Fx.compute = function(from, to, delta){ + return (to - from) * delta + from; +}; + +Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000}; +/* +Script: Fx.CSS.js + Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements. + +License: + MIT-style license. +*/ + +Fx.CSS = new Class({ + + Extends: Fx, + + //prepares the base from/to object + + prepare: function(element, property, values){ + values = $splat(values); + var values1 = values[1]; + if (!$chk(values1)){ + values[1] = values[0]; + values[0] = element.getStyle(property); + } + var parsed = values.map(this.parse); + return {from: parsed[0], to: parsed[1]}; + }, + + //parses a value into an array + + parse: function(value){ + value = $lambda(value)(); + value = (typeof value == 'string') ? value.split(' ') : $splat(value); + return value.map(function(val){ + val = String(val); + var found = false; + Fx.CSS.Parsers.each(function(parser, key){ + if (found) return; + var parsed = parser.parse(val); + if ($chk(parsed)) found = {value: parsed, parser: parser}; + }); + found = found || {value: val, parser: Fx.CSS.Parsers.String}; + return found; + }); + }, + + //computes by a from and to prepared objects, using their parsers. + + compute: function(from, to, delta){ + var computed = []; + (Math.min(from.length, to.length)).times(function(i){ + computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser}); + }); + computed.$family = {name: 'fx:css:value'}; + return computed; + }, + + //serves the value as settable + + serve: function(value, unit){ + if ($type(value) != 'fx:css:value') value = this.parse(value); + var returned = []; + value.each(function(bit){ + returned = returned.concat(bit.parser.serve(bit.value, unit)); + }); + return returned; + }, + + //renders the change to an element + + render: function(element, property, value, unit){ + element.setStyle(property, this.serve(value, unit)); + }, + + //searches inside the page css to find the values for a selector + + search: function(selector){ + if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector]; + var to = {}; + Array.each(document.styleSheets, function(sheet, j){ + var href = sheet.href; + if (href && href.contains('://') && !href.contains(document.domain)) return; + var rules = sheet.rules || sheet.cssRules; + Array.each(rules, function(rule, i){ + if (!rule.style) return; + var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){ + return m.toLowerCase(); + }) : null; + if (!selectorText || !selectorText.test('^' + selector + '$')) return; + Element.Styles.each(function(value, style){ + if (!rule.style[style] || Element.ShortStyles[style]) return; + value = String(rule.style[style]); + to[style] = (value.test(/^rgb/)) ? value.rgbToHex() : value; + }); + }); + }); + return Fx.CSS.Cache[selector] = to; + } + +}); + +Fx.CSS.Cache = {}; + +Fx.CSS.Parsers = new Hash({ + + Color: { + parse: function(value){ + if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true); + return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false; + }, + compute: function(from, to, delta){ + return from.map(function(value, i){ + return Math.round(Fx.compute(from[i], to[i], delta)); + }); + }, + serve: function(value){ + return value.map(Number); + } + }, + + Number: { + parse: parseFloat, + compute: Fx.compute, + serve: function(value, unit){ + return (unit) ? value + unit : value; + } + }, + + String: { + parse: $lambda(false), + compute: $arguments(1), + serve: $arguments(0) + } + +}); +/* +Script: Fx.Tween.js + Formerly Fx.Style, effect to transition any CSS property for an element. + +License: + MIT-style license. +*/ + +Fx.Tween = new Class({ + + Extends: Fx.CSS, + + initialize: function(element, options){ + this.element = this.subject = $(element); + this.parent(options); + }, + + set: function(property, now){ + if (arguments.length == 1){ + now = property; + property = this.property || this.options.property; + } + this.render(this.element, property, now, this.options.unit); + return this; + }, + + start: function(property, from, to){ + if (!this.check(arguments.callee, property, from, to)) return this; + var args = Array.flatten(arguments); + this.property = this.options.property || args.shift(); + var parsed = this.prepare(this.element, this.property, args); + return this.parent(parsed.from, parsed.to); + } + +}); + +Element.Properties.tween = { + + set: function(options){ + var tween = this.retrieve('tween'); + if (tween) tween.cancel(); + return this.eliminate('tween').store('tween:options', $extend({link: 'cancel'}, options)); + }, + + get: function(options){ + if (options || !this.retrieve('tween')){ + if (options || !this.retrieve('tween:options')) this.set('tween', options); + this.store('tween', new Fx.Tween(this, this.retrieve('tween:options'))); + } + return this.retrieve('tween'); + } + +}; + +Element.implement({ + + tween: function(property, from, to){ + this.get('tween').start(arguments); + return this; + }, + + fade: function(how){ + var fade = this.get('tween'), o = 'opacity', toggle; + how = $pick(how, 'toggle'); + switch (how){ + case 'in': fade.start(o, 1); break; + case 'out': fade.start(o, 0); break; + case 'show': fade.set(o, 1); break; + case 'hide': fade.set(o, 0); break; + case 'toggle': + var flag = this.retrieve('fade:flag', this.get('opacity') == 1); + fade.start(o, (flag) ? 0 : 1); + this.store('fade:flag', !flag); + toggle = true; + break; + default: fade.start(o, arguments); + } + if (!toggle) this.eliminate('fade:flag'); + return this; + }, + + highlight: function(start, end){ + if (!end){ + end = this.retrieve('highlight:original', this.getStyle('background-color')); + end = (end == 'transparent') ? '#fff' : end; + } + var tween = this.get('tween'); + tween.start('background-color', start || '#ffff88', end).chain(function(){ + this.setStyle('background-color', this.retrieve('highlight:original')); + tween.callChain(); + }.bind(this)); + return this; + } + +}); +/* +Script: Fx.Morph.js + Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules. + +License: + MIT-style license. +*/ + +Fx.Morph = new Class({ + + Extends: Fx.CSS, + + initialize: function(element, options){ + this.element = this.subject = $(element); + this.parent(options); + }, + + set: function(now){ + if (typeof now == 'string') now = this.search(now); + for (var p in now) this.render(this.element, p, now[p], this.options.unit); + return this; + }, + + compute: function(from, to, delta){ + var now = {}; + for (var p in from) now[p] = this.parent(from[p], to[p], delta); + return now; + }, + + start: function(properties){ + if (!this.check(arguments.callee, properties)) return this; + if (typeof properties == 'string') properties = this.search(properties); + var from = {}, to = {}; + for (var p in properties){ + var parsed = this.prepare(this.element, p, properties[p]); + from[p] = parsed.from; + to[p] = parsed.to; + } + return this.parent(from, to); + } + +}); + +Element.Properties.morph = { + + set: function(options){ + var morph = this.retrieve('morph'); + if (morph) morph.cancel(); + return this.eliminate('morph').store('morph:options', $extend({link: 'cancel'}, options)); + }, + + get: function(options){ + if (options || !this.retrieve('morph')){ + if (options || !this.retrieve('morph:options')) this.set('morph', options); + this.store('morph', new Fx.Morph(this, this.retrieve('morph:options'))); + } + return this.retrieve('morph'); + } + +}; + +Element.implement({ + + morph: function(props){ + this.get('morph').start(props); + return this; + } + +});/* +Script: Fx.Transitions.js + Contains a set of advanced transitions to be used with any of the Fx Classes. + +License: + MIT-style license. + +Credits: + Easing Equations by Robert Penner, , modified and optimized to be used with MooTools. +*/ + +(function(){ + + var old = Fx.prototype.initialize; + + Fx.prototype.initialize = function(options){ + old.call(this, options); + var trans = this.options.transition; + if (typeof trans == 'string' && (trans = trans.split(':'))){ + var base = Fx.Transitions; + base = base[trans[0]] || base[trans[0].capitalize()]; + if (trans[1]) base = base['ease' + trans[1].capitalize() + (trans[2] ? trans[2].capitalize() : '')]; + this.options.transition = base; + } + }; + +})(); + +Fx.Transition = function(transition, params){ + params = $splat(params); + return $extend(transition, { + easeIn: function(pos){ + return transition(pos, params); + }, + easeOut: function(pos){ + return 1 - transition(1 - pos, params); + }, + easeInOut: function(pos){ + return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2; + } + }); +}; + +Fx.Transitions = new Hash({ + + linear: $arguments(0) + +}); + +Fx.Transitions.extend = function(transitions){ + for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]); +}; + +Fx.Transitions.extend({ + + Pow: function(p, x){ + return Math.pow(p, x[0] || 6); + }, + + Expo: function(p){ + return Math.pow(2, 8 * (p - 1)); + }, + + Circ: function(p){ + return 1 - Math.sin(Math.acos(p)); + }, + + Sine: function(p){ + return 1 - Math.sin((1 - p) * Math.PI / 2); + }, + + Back: function(p, x){ + x = x[0] || 1.618; + return Math.pow(p, 2) * ((x + 1) * p - x); + }, + + Bounce: function(p){ + var value; + for (var a = 0, b = 1; 1; a += b, b /= 2){ + if (p >= (7 - 4 * a) / 11){ + value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b; + break; + } + } + return value; + }, + + Elastic: function(p, x){ + return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3); + } + +}); + +['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){ + Fx.Transitions[transition] = new Fx.Transition(function(p){ + return Math.pow(p, [i + 2]); + }); +}); +/* +Script: Request.js + Powerful all purpose Request Class. Uses XMLHTTPRequest. + +License: + MIT-style license. +*/ + +var Request = new Class({ + + Implements: [Chain, Events, Options], + + options: { + /*onRequest: $empty, + onSuccess: $empty, + onFailure: $empty, + onException: $empty,*/ + url: '', + data: '', + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }, + async: true, + method: 'post', + link: 'ignore', + isSuccess: null, + emulation: true, + urlEncoded: true, + encoding: 'utf-8', + evalScripts: false, + evalResponse: false + }, + + initialize: function(options){ + this.xhr = new Browser.Request(); + this.setOptions(options); + this.options.isSuccess = this.options.isSuccess || this.isSuccess; + this.headers = new Hash(this.options.headers); + }, + + onStateChange: function(){ + if (this.xhr.readyState != 4 || !this.running) return; + this.running = false; + this.status = 0; + $try(function(){ + this.status = this.xhr.status; + }.bind(this)); + if (this.options.isSuccess.call(this, this.status)){ + this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML}; + this.success(this.response.text, this.response.xml); + } else { + this.response = {text: null, xml: null}; + this.failure(); + } + this.xhr.onreadystatechange = $empty; + }, + + isSuccess: function(){ + return ((this.status >= 200) && (this.status < 300)); + }, + + processScripts: function(text){ + if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return $exec(text); + return text.stripScripts(this.options.evalScripts); + }, + + success: function(text, xml){ + this.onSuccess(this.processScripts(text), xml); + }, + + onSuccess: function(){ + this.fireEvent('onComplete', arguments).fireEvent('onSuccess', arguments).callChain(); + }, + + failure: function(){ + this.onFailure(); + }, + + onFailure: function(){ + this.fireEvent('onComplete').fireEvent('onFailure', this.xhr); + }, + + setHeader: function(name, value){ + this.headers.set(name, value); + return this; + }, + + getHeader: function(name){ + return $try(function(){ + return this.xhr.getResponseHeader(name); + }.bind(this)); + }, + + check: function(caller){ + if (!this.running) return true; + switch (this.options.link){ + case 'cancel': this.cancel(); return true; + case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false; + } + return false; + }, + + send: function(options){ + if (!this.check(arguments.callee, options)) return this; + this.running = true; + + var type = $type(options); + if (type == 'string' || type == 'element') options = {data: options}; + + var old = this.options; + options = $extend({data: old.data, url: old.url, method: old.method}, options); + var data = options.data, url = options.url, method = options.method; + + switch ($type(data)){ + case 'element': data = $(data).toQueryString(); break; + case 'object': case 'hash': data = Hash.toQueryString(data); + } + + if (this.options.emulation && ['put', 'delete'].contains(method)){ + var _method = '_method=' + method; + data = (data) ? _method + '&' + data : _method; + method = 'post'; + } + + if (this.options.urlEncoded && method == 'post'){ + var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; + this.headers.set('Content-type', 'application/x-www-form-urlencoded' + encoding); + } + + if (data && method == 'get'){ + url = url + (url.contains('?') ? '&' : '?') + data; + data = null; + } + + this.xhr.open(method.toUpperCase(), url, this.options.async); + + this.xhr.onreadystatechange = this.onStateChange.bind(this); + + this.headers.each(function(value, key){ + if (!$try(function(){ + this.xhr.setRequestHeader(key, value); + return true; + }.bind(this))) this.fireEvent('onException', [key, value]); + }, this); + + this.fireEvent('onRequest'); + this.xhr.send(data); + if (!this.options.async) this.onStateChange(); + return this; + }, + + cancel: function(){ + if (!this.running) return this; + this.running = false; + this.xhr.abort(); + this.xhr.onreadystatechange = $empty; + this.xhr = new Browser.Request(); + this.fireEvent('onCancel'); + return this; + } + +}); + +(function(){ + +var methods = {}; +['get', 'post', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){ + methods[method] = function(){ + var params = Array.link(arguments, {url: String.type, data: $defined}); + return this.send($extend(params, {method: method.toLowerCase()})); + }; +}); + +Request.implement(methods); + +})(); + +Element.Properties.send = { + + set: function(options){ + var send = this.retrieve('send'); + if (send) send.cancel(); + return this.eliminate('send').store('send:options', $extend({ + data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action') + }, options)); + }, + + get: function(options){ + if (options || !this.retrieve('send')){ + if (options || !this.retrieve('send:options')) this.set('send', options); + this.store('send', new Request(this.retrieve('send:options'))); + } + return this.retrieve('send'); + } + +}; + +Element.implement({ + + send: function(url){ + var sender = this.get('send'); + sender.send({data: this, url: url || sender.options.url}); + return this; + } + +}); +/* +Script: Request.HTML.js + Extends the basic Request Class with additional methods for interacting with HTML responses. + +License: + MIT-style license. +*/ + +Request.HTML = new Class({ + + Extends: Request, + + options: { + update: false, + evalScripts: true, + filter: false + }, + + processHTML: function(text){ + var match = text.match(/]*>([\s\S]*?)<\/body>/i); + text = (match) ? match[1] : text; + + var container = new Element('div'); + + return $try(function(){ + var root = '' + text + '', doc; + if (Browser.Engine.trident){ + doc = new ActiveXObject('Microsoft.XMLDOM'); + doc.async = false; + doc.loadXML(root); + } else { + doc = new DOMParser().parseFromString(root, 'text/xml'); + } + root = doc.getElementsByTagName('root')[0]; + for (var i = 0, k = root.childNodes.length; i < k; i++){ + var child = Element.clone(root.childNodes[i], true, true); + if (child) container.grab(child); + } + return container; + }) || container.set('html', text); + }, + + success: function(text){ + var options = this.options, response = this.response; + + response.html = text.stripScripts(function(script){ + response.javascript = script; + }); + + var temp = this.processHTML(response.html); + + response.tree = temp.childNodes; + response.elements = temp.getElements('*'); + + if (options.filter) response.tree = response.elements.filter(options.filter); + if (options.update) $(options.update).empty().adopt(response.tree); + if (options.evalScripts) $exec(response.javascript); + + this.onSuccess(response.tree, response.elements, response.html, response.javascript); + } + +}); + +Element.Properties.load = { + + set: function(options){ + var load = this.retrieve('load'); + if (load) send.cancel(); + return this.eliminate('load').store('load:options', $extend({data: this, link: 'cancel', update: this, method: 'get'}, options)); + }, + + get: function(options){ + if (options || ! this.retrieve('load')){ + if (options || !this.retrieve('load:options')) this.set('load', options); + this.store('load', new Request.HTML(this.retrieve('load:options'))); + } + return this.retrieve('load'); + } + +}; + +Element.implement({ + + load: function(){ + this.get('load').send(Array.link(arguments, {data: Object.type, url: String.type})); + return this; + } + +}); +/* +Script: Request.JSON.js + Extends the basic Request Class with additional methods for sending and receiving JSON data. + +License: + MIT-style license. +*/ + +Request.JSON = new Class({ + + Extends: Request, + + options: { + secure: true + }, + + initialize: function(options){ + this.parent(options); + this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'}); + }, + + success: function(text){ + this.response.json = JSON.decode(text, this.options.secure); + this.onSuccess(this.response.json, text); + } + +});/* +Script: Fx.Slide.js + Effect to slide an element in and out of view. + +License: + MIT-style license. +*/ + +Fx.Slide = new Class({ + + Extends: Fx, + + options: { + mode: 'vertical' + }, + + initialize: function(element, options){ + this.addEvent('onComplete', function(){ + this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0); + if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper); + }, true); + this.element = this.subject = $(element); + this.parent(options); + var wrapper = this.element.retrieve('wrapper'); + this.wrapper = wrapper || new Element('div', { + styles: $extend(this.element.getStyles('margin', 'position'), {'overflow': 'hidden'}) + }).wraps(this.element); + this.element.store('wrapper', this.wrapper).setStyle('margin', 0); + this.now = []; + this.open = true; + }, + + vertical: function(){ + this.margin = 'margin-top'; + this.layout = 'height'; + this.offset = this.element.offsetHeight; + }, + + horizontal: function(){ + this.margin = 'margin-left'; + this.layout = 'width'; + this.offset = this.element.offsetWidth; + }, + + set: function(now){ + this.element.setStyle(this.margin, now[0]); + this.wrapper.setStyle(this.layout, now[1]); + return this; + }, + + compute: function(from, to, delta){ + var now = []; + (2).times(function(i){ + now[i] = Fx.compute(from[i], to[i], delta); + }); + return now; + }, + + start: function(how, mode){ + if (!this.check(arguments.callee, how, mode)) return this; + this[mode || this.options.mode](); + var margin = this.element.getStyle(this.margin).toInt(); + var layout = this.wrapper.getStyle(this.layout).toInt(); + var caseIn = [[margin, layout], [0, this.offset]]; + var caseOut = [[margin, layout], [-this.offset, 0]]; + var start; + switch (how){ + case 'in': start = caseIn; break; + case 'out': start = caseOut; break; + case 'toggle': start = (this.wrapper['offset' + this.layout.capitalize()] == 0) ? caseIn : caseOut; + } + return this.parent(start[0], start[1]); + }, + + slideIn: function(mode){ + return this.start('in', mode); + }, + + slideOut: function(mode){ + return this.start('out', mode); + }, + + hide: function(mode){ + this[mode || this.options.mode](); + this.open = false; + return this.set([-this.offset, 0]); + }, + + show: function(mode){ + this[mode || this.options.mode](); + this.open = true; + return this.set([0, this.offset]); + }, + + toggle: function(mode){ + return this.start('toggle', mode); + } + +}); + +Element.Properties.slide = { + + set: function(options){ + var slide = this.retrieve('slide'); + if (slide) slide.cancel(); + return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options)); + }, + + get: function(options){ + if (options || !this.retrieve('slide')){ + if (options || !this.retrieve('slide:options')) this.set('slide', options); + this.store('slide', new Fx.Slide(this, this.retrieve('slide:options'))); + } + return this.retrieve('slide'); + } + +}; + +Element.implement({ + + slide: function(how, mode){ + how = how || 'toggle'; + var slide = this.get('slide'), toggle; + switch (how){ + case 'hide': slide.hide(mode); break; + case 'show': slide.show(mode); break; + case 'toggle': + var flag = this.retrieve('slide:flag', slide.open); + slide[(flag) ? 'slideOut' : 'slideIn'](mode); + this.store('slide:flag', !flag); + toggle = true; + break; + default: slide.start(how, mode); + } + if (!toggle) this.eliminate('slide:flag'); + return this; + } + +}); +/* +Script: Fx.Scroll.js + Effect to smoothly scroll any element, including the window. + +License: + MIT-style license. +*/ + +Fx.Scroll = new Class({ + + Extends: Fx, + + options: { + offset: {'x': 0, 'y': 0}, + wheelStops: true + }, + + initialize: function(element, options){ + this.element = this.subject = $(element); + this.parent(options); + var cancel = this.cancel.bind(this, false); + + if ($type(this.element) != 'element') this.element = $(this.element.getDocument().body); + + var stopper = this.element; + + if (this.options.wheelStops){ + this.addEvent('onStart', function(){ + stopper.addEvent('mousewheel', cancel); + }, true); + this.addEvent('onComplete', function(){ + stopper.removeEvent('mousewheel', cancel); + }, true); + } + }, + + set: function(){ + var now = Array.flatten(arguments); + this.element.scrollTo(now[0], now[1]); + }, + + compute: function(from, to, delta){ + var now = []; + (2).times(function(i){ + now.push(Fx.compute(from[i], to[i], delta)); + }); + return now; + }, + + start: function(x, y){ + if (!this.check(arguments.callee, x, y)) return this; + var offsetSize = this.element.getSize(), scrollSize = this.element.getScrollSize(); + var scroll = this.element.getScroll(), values = {x: x, y: y}; + for (var z in values){ + var max = scrollSize[z] - offsetSize[z]; + if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max; + else values[z] = scroll[z]; + values[z] += this.options.offset[z]; + } + return this.parent([scroll.x, scroll.y], [values.x, values.y]); + }, + + toTop: function(){ + return this.start(false, 0); + }, + + toLeft: function(){ + return this.start(0, false); + }, + + toRight: function(){ + return this.start('right', false); + }, + + toBottom: function(){ + return this.start(false, 'bottom'); + }, + + toElement: function(el){ + var position = $(el).getPosition(this.element); + return this.start(position.x, position.y); + } + +}); +/* +Script: Fx.Elements.js + Effect to change any number of CSS properties of any number of Elements. + +License: + MIT-style license. +*/ + +Fx.Elements = new Class({ + + Extends: Fx.CSS, + + initialize: function(elements, options){ + this.elements = this.subject = $$(elements); + this.parent(options); + }, + + compute: function(from, to, delta){ + var now = {}; + for (var i in from){ + var iFrom = from[i], iTo = to[i], iNow = now[i] = {}; + for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta); + } + return now; + }, + + set: function(now){ + for (var i in now){ + var iNow = now[i]; + for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit); + } + return this; + }, + + start: function(obj){ + if (!this.check(arguments.callee, obj)) return this; + var from = {}, to = {}; + for (var i in obj){ + var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {}; + for (var p in iProps){ + var parsed = this.prepare(this.elements[i], p, iProps[p]); + iFrom[p] = parsed.from; + iTo[p] = parsed.to; + } + } + return this.parent(from, to); + } + +});/* +Script: Drag.js + The base Drag Class. Can be used to drag and resize Elements using mouse events. + +License: + MIT-style license. +*/ + +var Drag = new Class({ + + Implements: [Events, Options], + + options: {/* + onBeforeStart: $empty, + onStart: $empty, + onDrag: $empty, + onCancel: $empty, + onComplete: $empty,*/ + snap: 6, + unit: 'px', + grid: false, + style: true, + limit: false, + handle: false, + invert: false, + preventDefault: false, + modifiers: {x: 'left', y: 'top'} + }, + + initialize: function(){ + var params = Array.link(arguments, {'options': Object.type, 'element': $defined}); + this.element = $(params.element); + this.document = this.element.getDocument(); + this.setOptions(params.options || {}); + var htype = $type(this.options.handle); + this.handles = (htype == 'array' || htype == 'collection') ? $$(this.options.handle) : $(this.options.handle) || this.element; + this.mouse = {'now': {}, 'pos': {}}; + this.value = {'start': {}, 'now': {}}; + + this.selection = (Browser.Engine.trident) ? 'selectstart' : 'mousedown'; + + this.bound = { + start: this.start.bind(this), + check: this.check.bind(this), + drag: this.drag.bind(this), + stop: this.stop.bind(this), + cancel: this.cancel.bind(this), + eventStop: $lambda(false) + }; + this.attach(); + }, + + attach: function(){ + this.handles.addEvent('mousedown', this.bound.start); + return this; + }, + + detach: function(){ + this.handles.removeEvent('mousedown', this.bound.start); + return this; + }, + + start: function(event){ + if (this.options.preventDefault) event.preventDefault(); + this.fireEvent('onBeforeStart', this.element); + this.mouse.start = event.page; + var limit = this.options.limit; + this.limit = {'x': [], 'y': []}; + for (var z in this.options.modifiers){ + if (!this.options.modifiers[z]) continue; + if (this.options.style) this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt(); + else this.value.now[z] = this.element[this.options.modifiers[z]]; + if (this.options.invert) this.value.now[z] *= -1; + this.mouse.pos[z] = event.page[z] - this.value.now[z]; + if (limit && limit[z]){ + for (var i = 2; i--; i){ + if ($chk(limit[z][i])) this.limit[z][i] = $lambda(limit[z][i])(); + } + } + } + if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid}; + this.document.addEvents({mousemove: this.bound.check, mouseup: this.bound.cancel}); + this.document.addEvent(this.selection, this.bound.eventStop); + }, + + check: function(event){ + if (this.options.preventDefault) event.preventDefault(); + var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2))); + if (distance > this.options.snap){ + this.cancel(); + this.document.addEvents({ + mousemove: this.bound.drag, + mouseup: this.bound.stop + }); + this.fireEvent('onStart', this.element).fireEvent('onSnap', this.element); + } + }, + + drag: function(event){ + if (this.options.preventDefault) event.preventDefault(); + this.mouse.now = event.page; + for (var z in this.options.modifiers){ + if (!this.options.modifiers[z]) continue; + this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z]; + if (this.options.invert) this.value.now[z] *= -1; + if (this.options.limit && this.limit[z]){ + if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){ + this.value.now[z] = this.limit[z][1]; + } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){ + this.value.now[z] = this.limit[z][0]; + } + } + if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]); + if (this.options.style) this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit); + else this.element[this.options.modifiers[z]] = this.value.now[z]; + } + this.fireEvent('onDrag', this.element); + }, + + cancel: function(event){ + this.document.removeEvent('mousemove', this.bound.check); + this.document.removeEvent('mouseup', this.bound.cancel); + if (event){ + this.document.removeEvent(this.selection, this.bound.eventStop); + this.fireEvent('onCancel', this.element); + } + }, + + stop: function(event){ + this.document.removeEvent(this.selection, this.bound.eventStop); + this.document.removeEvent('mousemove', this.bound.drag); + this.document.removeEvent('mouseup', this.bound.stop); + if (event) this.fireEvent('onComplete', this.element); + } + +}); + +Element.implement({ + + makeResizable: function(options){ + return new Drag(this, $merge({modifiers: {'x': 'width', 'y': 'height'}}, options)); + } + +});/* +Script: Drag.Move.js + A Drag extension that provides support for the constraining of draggables to containers and droppables. + +License: + MIT-style license. +*/ + +Drag.Move = new Class({ + + Extends: Drag, + + options: { + droppables: [], + container: false + }, + + initialize: function(element, options){ + this.parent(element, options); + this.droppables = $$(this.options.droppables); + this.container = $(this.options.container); + if (this.container && $type(this.container) != 'element') this.container = $(this.container.getDocument().body); + element = this.element; + + var current = element.getStyle('position'); + var position = (current != 'static') ? current : 'absolute'; + if (element.getStyle('left') == 'auto' || element.getStyle('top') == 'auto') element.position(element.getPosition(element.offsetParent)); + + element.setStyle('position', position); + + this.addEvent('onStart', function(){ + this.checkDroppables(); + }, true); + }, + + start: function(event){ + if (this.container){ + var el = this.element, cont = this.container, ccoo = cont.getCoordinates(el.offsetParent), cps = {}, ems = {}; + + ['top', 'right', 'bottom', 'left'].each(function(pad){ + cps[pad] = cont.getStyle('padding-' + pad).toInt(); + ems[pad] = el.getStyle('margin-' + pad).toInt(); + }, this); + + var width = el.offsetWidth + ems.left + ems.right, height = el.offsetHeight + ems.top + ems.bottom; + var x = [ccoo.left + cps.left, ccoo.right - cps.right - width]; + var y = [ccoo.top + cps.top, ccoo.bottom - cps.bottom - height]; + + this.options.limit = {x: x, y: y}; + } + this.parent(event); + }, + + checkAgainst: function(el){ + el = el.getCoordinates(); + var now = this.mouse.now; + return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top); + }, + + checkDroppables: function(){ + var overed = this.droppables.filter(this.checkAgainst, this).getLast(); + if (this.overed != overed){ + if (this.overed) this.fireEvent('onLeave', [this.element, this.overed]); + if (overed){ + this.overed = overed; + this.fireEvent('onEnter', [this.element, overed]); + } else { + this.overed = null; + } + } + }, + + drag: function(event){ + this.parent(event); + if (this.droppables.length) this.checkDroppables(); + }, + + stop: function(event){ + this.checkDroppables(); + this.fireEvent('onDrop', [this.element, this.overed]); + this.overed = null; + return this.parent(event); + } + +}); + +Element.implement({ + + makeDraggable: function(options){ + return new Drag.Move(this, options); + } + +}); +/* +Script: Color.js + Class for creating and manipulating colors in JavaScript. Supports HSB -> RGB Conversions and vice versa. + +License: + MIT-style license. +*/ + +var Color = new Native({ + + initialize: function(color, type){ + if (arguments.length >= 3){ + type = "rgb"; color = Array.slice(arguments, 0, 3); + } else if (typeof color == 'string'){ + if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true); + else if (color.match(/hsb/)) color = color.hsbToRgb(); + else color = color.hexToRgb(true); + } + type = type || 'rgb'; + switch (type){ + case 'hsb': + var old = color; + color = color.hsbToRgb(); + color.hsb = old; + break; + case 'hex': color = color.hexToRgb(true); break; + } + color.rgb = color.slice(0, 3); + color.hsb = color.hsb || color.rgbToHsb(); + color.hex = color.rgbToHex(); + return $extend(color, this); + } + +}); + +Color.implement({ + + mix: function(){ + var colors = Array.slice(arguments); + var alpha = ($type(colors.getLast()) == 'number') ? colors.pop() : 50; + var rgb = this.slice(); + colors.each(function(color){ + color = new Color(color); + for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); + }); + return new Color(rgb, 'rgb'); + }, + + invert: function(){ + return new Color(this.map(function(value){ + return 255 - value; + })); + }, + + setHue: function(value){ + return new Color([value, this.hsb[1], this.hsb[2]], 'hsb'); + }, + + setSaturation: function(percent){ + return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb'); + }, + + setBrightness: function(percent){ + return new Color([this.hsb[0], this.hsb[1], percent], 'hsb'); + } + +}); + +function $RGB(r, g, b){ + return new Color([r, g, b], 'rgb'); +}; + +function $HSB(h, s, b){ + return new Color([h, s, b], 'hsb'); +}; + +function $HEX(hex){ + return new Color(hex, 'hex'); +}; + +Array.implement({ + + rgbToHsb: function(){ + var red = this[0], green = this[1], blue = this[2]; + var hue, saturation, brightness; + var max = Math.max(red, green, blue), min = Math.min(red, green, blue); + var delta = max - min; + brightness = max / 255; + saturation = (max != 0) ? delta / max : 0; + if (saturation == 0){ + hue = 0; + } else { + var rr = (max - red) / delta; + var gr = (max - green) / delta; + var br = (max - blue) / delta; + if (red == max) hue = br - gr; + else if (green == max) hue = 2 + rr - br; + else hue = 4 + gr - rr; + hue /= 6; + if (hue < 0) hue++; + } + return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)]; + }, + + hsbToRgb: function(){ + var br = Math.round(this[2] / 100 * 255); + if (this[1] == 0){ + return [br, br, br]; + } else { + var hue = this[0] % 360; + var f = hue % 60; + var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255); + var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255); + var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255); + switch (Math.floor(hue / 60)){ + case 0: return [br, t, p]; + case 1: return [q, br, p]; + case 2: return [p, br, t]; + case 3: return [p, q, br]; + case 4: return [t, p, br]; + case 5: return [br, p, q]; + } + } + return false; + } + +}); + +String.implement({ + + rgbToHsb: function(){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? hsb.rgbToHsb() : null; + }, + + hsbToRgb: function(){ + var hsb = this.match(/\d{1,3}/g); + return (hsb) ? hsb.hsbToRgb() : null; + } + +}); +/* +Script: Group.js + Class for monitoring collections of events + +License: + MIT-style license. +*/ + +var Group = new Class({ + + initialize: function(){ + this.instances = Array.flatten(arguments); + this.events = {}; + this.checker = {}; + }, + + addEvent: function(type, fn){ + this.checker[type] = this.checker[type] || {}; + this.events[type] = this.events[type] || []; + if (this.events[type].contains(fn)) return false; + else this.events[type].push(fn); + this.instances.each(function(instance, i){ + instance.addEvent(type, this.check.bind(this, [type, instance, i])); + }, this); + return this; + }, + + check: function(type, instance, i){ + this.checker[type][i] = true; + var every = this.instances.every(function(current, j){ + return this.checker[type][j] || false; + }, this); + if (!every) return; + this.checker[type] = {}; + this.events[type].each(function(event){ + event.call(this, this.instances, instance); + }, this); + } + +}); +/* +Script: Hash.Cookie.js + Class for creating, reading, and deleting Cookies in JSON format. + +License: + MIT-style license. +*/ + +Hash.Cookie = new Class({ + + Extends: Cookie, + + options: { + autoSave: true + }, + + initialize: function(name, options){ + this.parent(name, options); + this.load(); + }, + + save: function(){ + var value = JSON.encode(this.hash); + if (!value || value.length > 4096) return false; //cookie would be truncated! + if (value == '{}') this.dispose(); + else this.write(value); + return true; + }, + + load: function(){ + this.hash = new Hash(JSON.decode(this.read(), true)); + return this; + } + +}); + +Hash.Cookie.implement((function(){ + + var methods = {}; + + Hash.each(Hash.prototype, function(method, name){ + methods[name] = function(){ + var value = method.apply(this.hash, arguments); + if (this.options.autoSave) this.save(); + return value; + }; + }); + + return methods; + +})());/* +Script: Sortables.js + Class for creating a drag and drop sorting interface for lists of items. + +License: + MIT-style license. +*/ + +var Sortables = new Class({ + + Implements: [Events, Options], + + options: {/* + onSort: $empty, + onStart: $empty, + onComplete: $empty,*/ + snap: 4, + opacity: 1, + clone: false, + revert: false, + handle: false, + constrain: false + }, + + initialize: function(lists, options){ + this.setOptions(options); + this.elements = []; + this.lists = []; + this.idle = true; + + this.addLists($$($(lists) || lists)); + if (!this.options.clone) this.options.revert = false; + if (this.options.revert) this.effect = new Fx.Morph(null, $merge({duration: 250, link: 'cancel'}, this.options.revert)); + }, + + attach: function(){ + this.addLists(this.lists); + return this; + }, + + detach: function(){ + this.lists = this.removeLists(this.lists); + return this; + }, + + addItems: function(){ + Array.flatten(arguments).each(function(element){ + this.elements.push(element); + var start = element.retrieve('sortables:start', this.start.bindWithEvent(this, element)); + (this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start); + }, this); + return this; + }, + + addLists: function(){ + Array.flatten(arguments).each(function(list){ + this.lists.push(list); + this.addItems(list.getChildren()); + }, this); + return this; + }, + + removeItems: function(){ + var elements = []; + Array.flatten(arguments).each(function(element){ + elements.push(element); + this.elements.erase(element); + var start = element.retrieve('sortables:start'); + (this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start); + }, this); + return $$(elements); + }, + + removeLists: function(){ + var lists = []; + Array.flatten(arguments).each(function(list){ + lists.push(list); + this.lists.erase(list); + this.removeItems(list.getChildren()); + }, this); + return $$(lists); + }, + + getClone: function(event, element){ + if (!this.options.clone) return new Element('div').inject(document.body); + if ($type(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list); + return element.clone(true).setStyles({ + 'margin': '0px', + 'position': 'absolute', + 'visibility': 'hidden', + 'width': element.getStyle('width') + }).inject(this.list).position(element.getPosition(element.offsetParent)); + }, + + getDroppables: function(){ + var droppables = this.list.getChildren(); + if (!this.options.constrain) droppables = this.lists.concat(droppables).erase(this.list); + return droppables.erase(this.clone).erase(this.element); + }, + + insert: function(dragging, element){ + var where = 'inside'; + if (this.lists.contains(element)){ + this.list = element; + this.drag.droppables = this.getDroppables(); + } else { + where = this.element.getAllPrevious().contains(element) ? 'before' : 'after'; + } + this.element.inject(element, where); + this.fireEvent('onSort', [this.element, this.clone]); + }, + + start: function(event, element){ + if (!this.idle) return; + this.idle = false; + this.element = element; + this.opacity = element.get('opacity'); + this.list = element.getParent(); + this.clone = this.getClone(event, element); + + this.drag = new Drag.Move(this.clone, { + snap: this.options.snap, + container: this.options.constrain && this.element.getParent(), + droppables: this.getDroppables(), + onSnap: function(){ + event.stop(); + this.clone.setStyle('visibility', 'visible'); + this.element.set('opacity', this.options.opacity || 0); + this.fireEvent('onStart', [this.element, this.clone]); + }.bind(this), + onEnter: this.insert.bind(this), + onCancel: this.reset.bind(this), + onComplete: this.end.bind(this) + }); + + this.clone.inject(this.element, 'before'); + this.drag.start(event); + }, + + end: function(){ + this.drag.detach(); + this.element.set('opacity', this.opacity); + if (this.effect){ + var dim = this.element.getStyles('width', 'height'); + var pos = this.clone.computePosition(this.element.getPosition(this.clone.offsetParent)); + this.effect.element = this.clone; + this.effect.start({ + top: pos.top, + left: pos.left, + width: dim.width, + height: dim.height, + opacity: 0.25 + }).chain(this.reset.bind(this)); + } else { + this.reset(); + } + }, + + reset: function(){ + this.idle = true; + this.clone.destroy(); + this.fireEvent('onComplete', this.element); + }, + + serialize: function(){ + var params = Array.link(arguments, {modifier: Function.type, index: $defined}); + var serial = this.lists.map(function(list){ + return list.getChildren().map(params.modifier || function(element){ + return element.get('id'); + }, this); + }, this); + + var index = params.index; + if (this.lists.length == 1) index = 0; + return $chk(index) && index >= 0 && index < this.lists.length ? serial[index] : serial; + } + +});/* +Script: Tips.js + Class for creating nice tips that follow the mouse cursor when hovering an element. + +License: + MIT-style license. +*/ + +var Tips = new Class({ + + Implements: [Events, Options], + + options: { + onShow: function(tip){ + tip.setStyle('visibility', 'visible'); + }, + onHide: function(tip){ + tip.setStyle('visibility', 'hidden'); + }, + showDelay: 100, + hideDelay: 100, + className: null, + offsets: {x: 16, y: 16}, + fixed: false + }, + + initialize: function(){ + var params = Array.link(arguments, {options: Object.type, elements: $defined}); + this.setOptions(params.options || null); + + this.tip = new Element('div').inject(document.body); + + if (this.options.className) this.tip.addClass(this.options.className); + + var top = new Element('div', {'class': 'tip-top'}).inject(this.tip); + this.container = new Element('div', {'class': 'tip'}).inject(this.tip); + var bottom = new Element('div', {'class': 'tip-bottom'}).inject(this.tip); + + this.tip.setStyles({position: 'absolute', top: 0, left: 0, visibility: 'hidden'}); + + if (params.elements) this.attach(params.elements); + }, + + attach: function(elements){ + $$(elements).each(function(element){ + var title = element.retrieve('tip:title', element.get('title')); + var text = element.retrieve('tip:text', element.get('rel') || element.get('href')); + var enter = element.retrieve('tip:enter', this.elementEnter.bindWithEvent(this, element)); + var leave = element.retrieve('tip:leave', this.elementLeave.bindWithEvent(this, element)); + element.addEvents({mouseenter: enter, mouseleave: leave}); + if (!this.options.fixed){ + var move = element.retrieve('tip:move', this.elementMove.bindWithEvent(this, element)); + element.addEvent('mousemove', move); + } + element.store('tip:native', element.get('title')); + element.erase('title'); + }, this); + return this; + }, + + detach: function(elements){ + $$(elements).each(function(element){ + element.removeEvent('mouseenter', element.retrieve('tip:enter') || $empty); + element.removeEvent('mouseleave', element.retrieve('tip:leave') || $empty); + element.removeEvent('mousemove', element.retrieve('tip:move') || $empty); + element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move'); + var original = element.retrieve('tip:native'); + if (original) element.set('title', original); + }); + return this; + }, + + elementEnter: function(event, element){ + + $A(this.container.childNodes).each(Element.dispose); + + var title = element.retrieve('tip:title'); + + if (title){ + this.titleElement = new Element('div', {'class': 'tip-title'}).inject(this.container); + this.fill(this.titleElement, title); + } + + var text = element.retrieve('tip:text'); + if (text){ + this.textElement = new Element('div', {'class': 'tip-text'}).inject(this.container); + this.fill(this.textElement, text); + } + + this.timer = $clear(this.timer); + this.timer = this.show.delay(this.options.showDelay, this); + + this.position((!this.options.fixed) ? event : {page: element.getPosition()}); + }, + + elementLeave: function(event){ + $clear(this.timer); + this.timer = this.hide.delay(this.options.hideDelay, this); + }, + + elementMove: function(event){ + this.position(event); + }, + + position: function(event){ + var size = window.getSize(), scroll = window.getScroll(); + var tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight}; + var props = {x: 'left', y: 'top'}; + for (var z in props){ + var pos = event.page[z] + this.options.offsets[z]; + if ((pos + tip[z] - scroll[z]) > size[z]) pos = event.page[z] - this.options.offsets[z] - tip[z]; + this.tip.setStyle(props[z], pos); + } + }, + + fill: function(element, contents){ + (typeof contents == 'string') ? element.set('html', contents) : element.adopt(contents); + }, + + show: function(){ + this.fireEvent('onShow', this.tip); + }, + + hide: function(){ + this.fireEvent('onHide', this.tip); + } + +});/* +Script: SmoothScroll.js + Class for creating a smooth scrolling effect to all internal links on the page. + +License: + MIT-style license. +*/ + +var SmoothScroll = new Class({ + + Extends: Fx.Scroll, + + initialize: function(options, context){ + context = context || document; + var doc = context.getDocument(), win = context.getWindow(); + this.parent(doc, options); + this.links = (this.options.links) ? $$(this.options.links) : $$(doc.links); + var location = win.location.href.match(/^[^#]*/)[0] + '#'; + this.links.each(function(link){ + if (link.href.indexOf(location) != 0) return; + var anchor = link.href.substr(location.length); + if (anchor && $(anchor)) this.useLink(link, anchor); + }, this); + if (!Browser.Engine.webkit419) this.addEvent('onComplete', function(){ + win.location.hash = this.anchor; + }, true); + }, + + useLink: function(link, anchor){ + link.addEvent('click', function(event){ + this.anchor = anchor; + this.toElement(anchor); + event.stop(); + }.bind(this)); + } + +});/* +Script: Slider.js + Class for creating horizontal and vertical slider controls. + +License: + MIT-style license. +*/ + +var Slider = new Class({ + + Implements: [Events, Options], + + options: {/* + onChange: $empty, + onComplete: $empty,*/ + onTick: function(position){ + if(this.options.snap) position = this.toPosition(this.step); + this.knob.setStyle(this.property, position); + }, + snap: false, + offset: 0, + range: false, + wheel: false, + steps: 100, + mode: 'horizontal' + }, + + initialize: function(element, knob, options){ + this.setOptions(options); + this.element = $(element); + this.knob = $(knob); + this.previousChange = this.previousEnd = this.step = -1; + this.element.addEvent('mousedown', this.clickedElement.bind(this)); + if (this.options.wheel) this.element.addEvent('mousewheel', this.scrolledElement.bindWithEvent(this)); + var offset, limit = {}, modifiers = {'x': false, 'y': false}; + switch (this.options.mode){ + case 'vertical': + this.axis = 'y'; + this.property = 'top'; + offset = 'offsetHeight'; + break; + case 'horizontal': + this.axis = 'x'; + this.property = 'left'; + offset = 'offsetWidth'; + } + this.half = this.knob[offset] / 2; + this.full = this.element[offset] - this.knob[offset] + (this.options.offset * 2); + this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0; + this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps; + this.range = this.max - this.min; + this.steps = this.options.steps || this.full; + this.stepSize = Math.abs(this.range) / this.steps; + this.stepWidth = this.stepSize * this.full / Math.abs(this.range) ; + + this.knob.setStyle('position', 'relative').setStyle(this.property, - this.options.offset); + modifiers[this.axis] = this.property; + limit[this.axis] = [- this.options.offset, this.full - this.options.offset]; + this.drag = new Drag(this.knob, { + snap: 0, + limit: limit, + modifiers: modifiers, + onDrag: this.draggedKnob.bind(this), + onStart: this.draggedKnob.bind(this), + onComplete: function(){ + this.draggedKnob(); + this.end(); + }.bind(this) + }); + if (this.options.snap) { + this.drag.options.grid = Math.ceil(this.stepWidth); + this.drag.options.limit[this.axis][1] = this.full; + } + }, + + set: function(step){ + if (!((this.range > 0) ^ (step < this.min))) step = this.min; + if (!((this.range > 0) ^ (step > this.max))) step = this.max; + + this.step = Math.round(step); + this.checkStep(); + this.end(); + this.fireEvent('onTick', this.toPosition(this.step)); + return this; + }, + + clickedElement: function(event){ + var dir = this.range < 0 ? -1 : 1; + var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half; + position = position.limit(-this.options.offset, this.full -this.options.offset); + + this.step = Math.round(this.min + dir * this.toStep(position)); + this.checkStep(); + this.end(); + this.fireEvent('onTick', position); + }, + + scrolledElement: function(event){ + var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0); + this.set(mode ? this.step - this.stepSize : this.step + this.stepSize); + event.stop(); + }, + + draggedKnob: function(){ + var dir = this.range < 0 ? -1 : 1; + var position = this.drag.value.now[this.axis]; + position = position.limit(-this.options.offset, this.full -this.options.offset); + this.step = Math.round(this.min + dir * this.toStep(position)); + this.checkStep(); + }, + + checkStep: function(){ + if (this.previousChange != this.step){ + this.previousChange = this.step; + this.fireEvent('onChange', this.step); + } + }, + + end: function(){ + if (this.previousEnd !== this.step){ + this.previousEnd = this.step; + this.fireEvent('onComplete', this.step + ''); + } + }, + + toStep: function(position){ + var step = (position + this.options.offset) * this.stepSize / this.full * this.steps; + return this.options.steps ? Math.round(step -= step % this.stepSize) : step; + }, + + toPosition: function(step){ + return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset; + } + +});/* +Script: Scroller.js + Class which scrolls the contents of any Element (including the window) when the mouse reaches the Element's boundaries. + +License: + MIT-style license. +*/ + +var Scroller = new Class({ + + Implements: [Events, Options], + + options: { + area: 20, + velocity: 1, + onChange: function(x, y){ + this.element.scrollTo(x, y); + } + }, + + initialize: function(element, options){ + this.setOptions(options); + this.element = $(element); + this.listener = ($type(this.element) != 'element') ? $(this.element.getDocument().body) : this.element; + this.timer = null; + }, + + start: function(){ + this.coord = this.getCoords.bind(this); + this.listener.addEvent('mousemove', this.coord); + }, + + stop: function(){ + this.listener.removeEvent('mousemove', this.coord); + this.timer = $clear(this.timer); + }, + + getCoords: function(event){ + this.page = (this.listener.get('tag') == 'body') ? event.client : event.page; + if (!this.timer) this.timer = this.scroll.periodical(50, this); + }, + + scroll: function(){ + var size = this.element.getSize(), scroll = this.element.getScroll(), pos = this.element.getPosition(), change = {'x': 0, 'y': 0}; + for (var z in this.page){ + if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0) + change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity; + else if (this.page[z] + this.options.area > (size[z] + pos[z]) && size[z] + size[z] != scroll[z]) + change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity; + } + if (change.y || change.x) this.fireEvent('onChange', [scroll.x + change.x, scroll.y + change.y]); + } + +});/* +Script: Assets.js + Provides methods to dynamically load JavaScript, CSS, and Image files into the document. + +License: + MIT-style license. +*/ + +var Asset = new Hash({ + + javascript: function(source, properties){ + properties = $extend({ + onload: $empty, + document: document, + check: $lambda(true) + }, properties); + + var script = new Element('script', {'src': source, 'type': 'text/javascript'}); + + var load = properties.onload.bind(script), check = properties.check, doc = properties.document; + delete properties.onload; delete properties.check; delete properties.document; + + script.addEvents({ + load: load, + readystatechange: function(){ + if (['loaded', 'complete'].contains(this.readyState)) load(); + } + }).setProperties(properties); + + + if (Browser.Engine.webkit419) var checker = (function(){ + if (!$try(check)) return; + $clear(checker); + load(); + }).periodical(50); + + return script.inject(doc.head); + }, + + css: function(source, properties){ + return new Element('link', $merge({ + 'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source + }, properties)).inject(document.head); + }, + + image: function(source, properties){ + properties = $merge({ + 'onload': $empty, + 'onabort': $empty, + 'onerror': $empty + }, properties); + var image = new Image(); + var element = $(image) || new Element('img'); + ['load', 'abort', 'error'].each(function(name){ + var type = 'on' + name; + var event = properties[type]; + delete properties[type]; + image[type] = function(){ + if (!image) return; + if (!element.parentNode){ + element.width = image.width; + element.height = image.height; + } + image = image.onload = image.onabort = image.onerror = null; + event.delay(1, element, element); + element.fireEvent(name, element, 1); + }; + }); + image.src = element.src = source; + if (image && image.complete) image.onload.delay(1); + return element.setProperties(properties); + }, + + images: function(sources, options){ + options = $merge({ + onComplete: $empty, + onProgress: $empty + }, options); + if (!sources.push) sources = [sources]; + var images = []; + var counter = 0; + sources.each(function(source){ + var img = new Asset.image(source, { + 'onload': function(){ + options.onProgress.call(this, counter, sources.indexOf(source)); + counter++; + if (counter == sources.length) options.onComplete(); + } + }); + images.push(img); + }); + return new Elements(images); + } + +});/* +Script: Accordion.js + An Fx.Elements extension which allows you to easily create accordion type controls. + +License: + MIT-style license. +*/ + +var Accordion = new Class({ + + Extends: Fx.Elements, + + options: {/* + onActive: $empty, + onBackground: $empty,*/ + display: 0, + show: false, + height: true, + width: false, + opacity: true, + fixedHeight: false, + fixedWidth: false, + wait: false, + alwaysHide: false + }, + + initialize: function(){ + var params = Array.link(arguments, {'container': Element.type, 'options': Object.type, 'togglers': $defined, 'elements': $defined}); + this.parent(params.elements, params.options); + this.togglers = $$(params.togglers); + this.container = $(params.container); + this.previous = -1; + if (this.options.alwaysHide) this.options.wait = true; + if ($chk(this.options.show)){ + this.options.display = false; + this.previous = this.options.show; + } + if (this.options.start){ + this.options.display = false; + this.options.show = false; + } + this.effects = {}; + if (this.options.opacity) this.effects.opacity = 'fullOpacity'; + if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth'; + if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight'; + for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]); + this.elements.each(function(el, i){ + if (this.options.show === i){ + this.fireEvent('onActive', [this.togglers[i], el]); + } else { + for (var fx in this.effects) el.setStyle(fx, 0); + } + }, this); + if ($chk(this.options.display)) this.display(this.options.display); + }, + + addSection: function(toggler, element, pos){ + toggler = $(toggler); + element = $(element); + var test = this.togglers.contains(toggler); + var len = this.togglers.length; + this.togglers.include(toggler); + this.elements.include(element); + if (len && (!test || pos)){ + pos = $pick(pos, len - 1); + toggler.inject(this.togglers[pos], 'before'); + element.inject(toggler, 'after'); + } else if (this.container && !test){ + toggler.inject(this.container); + element.inject(this.container); + } + var idx = this.togglers.indexOf(toggler); + toggler.addEvent('click', this.display.bind(this, idx)); + if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'}); + if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'}); + element.fullOpacity = 1; + if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth; + if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight; + element.setStyle('overflow', 'hidden'); + if (!test){ + for (var fx in this.effects) element.setStyle(fx, 0); + } + return this; + }, + + display: function(index){ + index = ($type(index) == 'element') ? this.elements.indexOf(index) : index; + if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this; + this.previous = index; + var obj = {}; + this.elements.each(function(el, i){ + obj[i] = {}; + var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0)); + this.fireEvent(hide ? 'onBackground' : 'onActive', [this.togglers[i], el]); + for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]]; + }, this); + return this.start(obj); + } + +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/langs/en.js b/ipf/admin/media/tiny_mce/plugins/images/langs/en.js new file mode 100755 index 0000000..573158a --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/langs/en.js @@ -0,0 +1,3 @@ +tinyMCE.addI18n('en.images',{ + desc : 'Upload and insert picture' +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/langs/en_dlg.js b/ipf/admin/media/tiny_mce/plugins/images/langs/en_dlg.js new file mode 100755 index 0000000..e4ea417 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/langs/en_dlg.js @@ -0,0 +1,22 @@ +tinyMCE.addI18n('en.images_dlg',{ +title:"Pictures", +del_sel_folder:"Remove selected folder?", +sel_files_for_del:"Select files for removal.\n\nYou can remove several files simultaneously by selecting it with Ctrl.", +files_to_del:"Files for removal", +delete_str:"Remove", +create_new_fld:"Create new folder", +create_fld:"Create folder", +upload_files:"Upload files", +delete_file:"Delete file", + +fancy_title:"Image uploading", +fancy_back_alt:"Back to files list", +fancy_back:"Back to files", +fancy_browse:"Browse", +fancy_begin_upload:"Start upload", +fancy_upload_files:"Upload files", +fancy_clear:"Clear list", +fancy_begin_upload_files:"Start files upload", +fancy_general_status:"General status", +fancy_file_status:"File status" +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/langs/ru.js b/ipf/admin/media/tiny_mce/plugins/images/langs/ru.js new file mode 100755 index 0000000..2ed3767 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/langs/ru.js @@ -0,0 +1,3 @@ +tinyMCE.addI18n('ru.images',{ + desc : '\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u0020\u0438\u0020\u0432\u0441\u0442\u0430\u0432\u043A\u0430\u0020\u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439' +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/langs/ru_dlg.js b/ipf/admin/media/tiny_mce/plugins/images/langs/ru_dlg.js new file mode 100755 index 0000000..f964e1e --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/langs/ru_dlg.js @@ -0,0 +1,22 @@ +tinyMCE.addI18n('ru.images_dlg',{ +title:"\u041A\u0430\u0440\u0442\u0438\u043D\u043A\u0438", +del_sel_folder:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C\u0020\u0432\u044B\u0431\u0440\u0430\u043D\u043D\u0443\u044E\u0020\u043F\u0430\u043F\u043A\u0443?", +sel_files_for_del:"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435\u0020\u0444\u0430\u0439\u043B\u044B\u0020\u0434\u043B\u044F\u0020\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F\u002E\u005C\u006E\u005C\u006E\u0414\u043B\u044F\u0020\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F\u0020\u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u0438\u0445\u0020\u0444\u0430\u0439\u043B\u043E\u0432\u0020\u0432\u044B\u0434\u0435\u043B\u0438\u0442\u0435\u0020\u0438\u0445\u0020\u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044F\u0020\u0043\u0074\u0072\u006C\u002E", +files_to_del:"\u0424\u0430\u0439\u043B\u043E\u0432\u0020\u043A\u0020\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044E", +delete_str:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C", +create_new_fld:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C\u0020\u043D\u043E\u0432\u0443\u044E\u0020\u043F\u0430\u043F\u043A\u0443", +create_fld:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C\u0020\u043F\u0430\u043F\u043A\u0443", +upload_files:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\u0020\u0444\u0430\u0439\u043B\u044B", +delete_file:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C\u0020\u0444\u0430\u0439\u043B", + +fancy_title:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u0020\u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439", +fancy_back_alt:"\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F\u0020\u043A\u0020\u0441\u043F\u0438\u0441\u043A\u0443\u0020\u0444\u0430\u0439\u043B\u043E\u0432", +fancy_back:"\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F\u0020\u043A\u0020\u0444\u0430\u0439\u043B\u0430\u043C", +fancy_browse:"\u041E\u0431\u0437\u043E\u0440", +fancy_begin_upload:"\u041D\u0430\u0447\u0430\u0442\u044C\u0020\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", +fancy_upload_files:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\u0020\u0444\u0430\u0439\u043B\u044B", +fancy_clear:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u0020\u0441\u043F\u0438\u0441\u043E\u043A", +fancy_begin_upload_files:"\u041D\u0430\u0447\u0430\u0442\u044C\u0020\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443\u0020\u0444\u0430\u0439\u043B\u043E\u0432", +fancy_general_status:"\u041E\u0431\u0449\u0438\u0439\u0020\u0441\u0442\u0430\u0442\u0443\u0441", +fancy_file_status:"\u0421\u0442\u0430\u0442\u0443\u0441\u0020\u0444\u0430\u0439\u043B\u0430" +}); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/read_ru.txt b/ipf/admin/media/tiny_mce/plugins/images/read_ru.txt new file mode 100755 index 0000000..a62fc1b --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/read_ru.txt @@ -0,0 +1,3 @@ +TinyMCE Images Plugin + +Ñàéò àâòîðà: http://dustweb.ru/log/projects/tinymce_images/ \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/server_connector/JsHttpRequest.php b/ipf/admin/media/tiny_mce/plugins/images/server_connector/JsHttpRequest.php new file mode 100755 index 0000000..9348199 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/server_connector/JsHttpRequest.php @@ -0,0 +1,521 @@ + "text/javascript", + "xml" => "text/plain", // In XMLHttpRequest mode we must return text/plain - stupid Opera 8.0. :( + "form" => "text/html", + "" => "text/plain", // for unknown loader + ); + // Internal: conversion to UTF-8 JSON cancelled because of non-ascii key. + var $_toUtfFailed = false; + // Internal: list of characters 128...255 (for strpbrk() ASCII check). + var $_nonAsciiChars = ''; + // Which Unicode conversion function is available? + var $_unicodeConvMethod = null; + // Emergency memory buffer to be freed on memory_limit error. + var $_emergBuffer = null; + + + /** + * Constructor. + * + * Create new JsHttpRequest backend object and attach it + * to script output buffer. As a result - script will always return + * correct JavaScript code, even in case of fatal errors. + * + * QUERY_STRING is in form of: PHPSESSID=&a=aaa&b=bbb&JsHttpRequest=- + * where is a request ID, is a loader name, - a session ID (if present), + * PHPSESSID - session parameter name (by default = "PHPSESSID"). + * + * If an object is created WITHOUT an active AJAX query, it is simply marked as + * non-active. Use statuc method isActive() to check. + */ + function JsHttpRequest($enc) + { + global $JsHttpRequest_Active; + + // To be on a safe side - do not allow to drop reference counter on ob processing. + $GLOBALS['_RESULT'] =& $this->RESULT; + + // Parse QUERY_STRING. + if (preg_match('/^(.*)(?:&|^)JsHttpRequest=(?:(\d+)-)?([^&]+)((?:&|$).*)$/s', @$_SERVER['QUERY_STRING'], $m)) { + $this->ID = $m[2]; + $this->LOADER = strtolower($m[3]); + $_SERVER['QUERY_STRING'] = preg_replace('/^&+|&+$/s', '', preg_replace('/(^|&)'.session_name().'=[^&]*&?/s', '&', $m[1] . $m[4])); + unset( + $_GET['JsHttpRequest'], + $_REQUEST['JsHttpRequest'], + $_GET[session_name()], + $_POST[session_name()], + $_REQUEST[session_name()] + ); + // Detect Unicode conversion method. + $this->_unicodeConvMethod = function_exists('mb_convert_encoding')? 'mb' : (function_exists('iconv')? 'iconv' : null); + + // Fill an emergency buffer. We erase it at the first line of OB processor + // to free some memory. This memory may be used on memory_limit error. + $this->_emergBuffer = str_repeat('a', 1024 * 200); + + // Intercept fatal errors via display_errors (seems it is the only way). + $this->_uniqHash = md5('JsHttpRequest' . microtime() . getmypid()); + $this->_prevDisplayErrors = ini_get('display_errors'); + ini_set('display_errors', $this->_magic); // + ini_set('error_prepend_string', $this->_uniqHash . ini_get('error_prepend_string')); + ini_set('error_append_string', ini_get('error_append_string') . $this->_uniqHash); + + // Start OB handling early. + ob_start(array(&$this, "_obHandler")); + $JsHttpRequest_Active = true; + + // Set up the encoding. + $this->setEncoding($enc); + + // Check if headers are already sent (see Content-Type library usage). + // If true - generate a debug message and exit. + $file = $line = null; + $headersSent = version_compare(PHP_VERSION, "4.3.0") < 0? headers_sent() : headers_sent($file, $line); + if ($headersSent) { + trigger_error( + "HTTP headers are already sent" . ($line !== null? " in $file on line $line" : " somewhere in the script") . ". " + . "Possibly you have an extra space (or a newline) before the first line of the script or any library. " + . "Please note that JsHttpRequest uses its own Content-Type header and fails if " + . "this header cannot be set. See header() function documentation for more details", + E_USER_ERROR + ); + exit(); + } + } else { + $this->ID = 0; + $this->LOADER = 'unknown'; + $JsHttpRequest_Active = false; + } + } + + + /** + * Static function. + * Returns true if JsHttpRequest output processor is currently active. + * + * @return boolean True if the library is active, false otherwise. + */ + function isActive() + { + return !empty($GLOBALS['JsHttpRequest_Active']); + } + + + /** + * string getJsCode() + * + * Return JavaScript part of the library. + */ + function getJsCode() + { + return file_get_contents(dirname(__FILE__) . '/JsHttpRequest.js'); + } + + + /** + * void setEncoding(string $encoding) + * + * Set an active script encoding & correct QUERY_STRING according to it. + * Examples: + * "windows-1251" - set plain encoding (non-windows characters, + * e.g. hieroglyphs, are totally ignored) + * "windows-1251 entities" - set windows encoding, BUT additionally replace: + * "&" -> "&" + * hieroglyph -> &#XXXX; entity + */ + function setEncoding($enc) + { + // Parse an encoding. + preg_match('/^(\S*)(?:\s+(\S*))$/', $enc, $p); + $this->SCRIPT_ENCODING = strtolower(!empty($p[1])? $p[1] : $enc); + $this->SCRIPT_DECODE_MODE = !empty($p[2])? $p[2] : ''; + // Manually parse QUERY_STRING because of damned Unicode's %uXXXX. + $this->_correctSuperglobals(); + } + + + /** + * string quoteInput(string $input) + * + * Quote a string according to the input decoding mode. + * If entities are used (see setEncoding()), no '&' character is quoted, + * only '"', '>' and '<' (we presume that '&' is already quoted by + * an input reader function). + * + * Use this function INSTEAD of htmlspecialchars() for $_GET data + * in your scripts. + */ + function quoteInput($s) + { + if ($this->SCRIPT_DECODE_MODE == 'entities') + return str_replace(array('"', '<', '>'), array('"', '<', '>'), $s); + else + return htmlspecialchars($s); + } + + + /** + * Convert a PHP scalar, array or hash to JS scalar/array/hash. This function is + * an analog of json_encode(), but it can work with a non-UTF8 input and does not + * analyze the passed data. Output format must be fully JSON compatible. + * + * @param mixed $a Any structure to convert to JS. + * @return string JavaScript equivalent structure. + */ + function php2js($a=false) + { + if (is_null($a)) return 'null'; + if ($a === false) return 'false'; + if ($a === true) return 'true'; + if (is_scalar($a)) { + if (is_float($a)) { + // Always use "." for floats. + $a = str_replace(",", ".", strval($a)); + } + // All scalars are converted to strings to avoid indeterminism. + // PHP's "1" and 1 are equal for all PHP operators, but + // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend, + // we should get the same result in the JS frontend (string). + // Character replacements for JSON. + static $jsonReplaces = array( + array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), + array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"') + ); + return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; + } + $isList = true; + for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { + if (key($a) !== $i) { + $isList = false; + break; + } + } + $result = array(); + if ($isList) { + foreach ($a as $v) { + $result[] = JsHttpRequest::php2js($v); + } + return '[ ' . join(', ', $result) . ' ]'; + } else { + foreach ($a as $k => $v) { + $result[] = JsHttpRequest::php2js($k) . ': ' . JsHttpRequest::php2js($v); + } + return '{ ' . join(', ', $result) . ' }'; + } + } + + + /** + * Internal methods. + */ + + /** + * Parse & decode QUERY_STRING. + */ + function _correctSuperglobals() + { + // In case of FORM loader we may go to nirvana, everything is already parsed by PHP. + if ($this->LOADER == 'form') return; + + // ATTENTION!!! + // HTTP_RAW_POST_DATA is only accessible when Content-Type of POST request + // is NOT default "application/x-www-form-urlencoded"!!! + // Library frontend sets "application/octet-stream" for that purpose, + // see JavaScript code. In PHP 5.2.2.HTTP_RAW_POST_DATA is not set sometimes; + // in such cases - read the POST data manually from the STDIN stream. + $rawPost = strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') == 0? (isset($GLOBALS['HTTP_RAW_POST_DATA'])? $GLOBALS['HTTP_RAW_POST_DATA'] : @file_get_contents("php://input")) : null; + $source = array( + '_GET' => !empty($_SERVER['QUERY_STRING'])? $_SERVER['QUERY_STRING'] : null, + '_POST'=> $rawPost, + ); + foreach ($source as $dst=>$src) { + // First correct all 2-byte entities. + $s = preg_replace('/%(?!5B)(?!5D)([0-9a-f]{2})/si', '%u00\\1', $src); + // Now we can use standard parse_str() with no worry! + $data = null; + parse_str($s, $data); + $GLOBALS[$dst] = $this->_ucs2EntitiesDecode($data); + } + $GLOBALS['HTTP_GET_VARS'] = $_GET; // deprecated vars + $GLOBALS['HTTP_POST_VARS'] = $_POST; + $_REQUEST = + (isset($_COOKIE)? $_COOKIE : array()) + + (isset($_POST)? $_POST : array()) + + (isset($_GET)? $_GET : array()); + if (ini_get('register_globals')) { + // TODO? + } + } + + + /** + * Called in case of error too! + */ + function _obHandler($text) + { + unset($this->_emergBuffer); // free a piece of memory for memory_limit error + unset($GLOBALS['JsHttpRequest_Active']); + + // Check for error & fetch a resulting data. + if (preg_match("/{$this->_uniqHash}(.*?){$this->_uniqHash}/sx", $text, $m)) { + if (!ini_get('display_errors') || (!$this->_prevDisplayErrors && ini_get('display_errors') == $this->_magic)) { + // Display_errors: + // 1. disabled manually after the library initialization, or + // 2. was initially disabled and is not changed + $text = str_replace($m[0], '', $text); // strip whole error message + } else { + $text = str_replace($this->_uniqHash, '', $text); + } + } + if ($m && preg_match('/\bFatal error(<.*?>)?:/i', $m[1])) { + // On fatal errors - force null result (generate 500 error). + $this->RESULT = null; + } else { + // Make a resulting hash. + if (!isset($this->RESULT)) { + global $_RESULT; + $this->RESULT = $_RESULT; + } + } + + $result = array( + 'id' => $this->ID, + 'js' => $this->RESULT, + 'text' => $text, + ); + $text = null; + $encoding = $this->SCRIPT_ENCODING; + $status = $this->RESULT !== null? 200 : 500; + + // Try to use very fast json_encode: 3-4 times faster than a manual encoding. + if (function_exists('array_walk_recursive') && function_exists('json_encode') && $this->_unicodeConvMethod) { + $this->_nonAsciiChars = join("", array_map('chr', range(128, 255))); + $this->_toUtfFailed = false; + $resultUtf8 = $result; + array_walk_recursive($resultUtf8, array(&$this, '_toUtf8_callback'), $this->SCRIPT_ENCODING); + if (!$this->_toUtfFailed) { + // If some key contains non-ASCII character, convert everything manually. + $text = json_encode($resultUtf8); + $encoding = "UTF-8"; + } + } + + // On failure, use manual encoding. + if ($text === null) { + $text = $this->php2js($result); + } + + if ($this->LOADER != "xml") { + // In non-XML mode we cannot use plain JSON. So - wrap with JS function call. + // If top.JsHttpRequestGlobal is not defined, loading is aborted and + // iframe is removed, so - do not call dataReady(). + $text = "" + . ($this->LOADER == "form"? 'top && top.JsHttpRequestGlobal && top.JsHttpRequestGlobal' : 'JsHttpRequest') + . ".dataReady(" . $text . ")\n" + . ""; + if ($this->LOADER == "form") { + $text = ''; + } + + // Always return 200 code in non-XML mode (else SCRIPT does not work in FF). + // For XML mode, 500 code is okay. + $status = 200; + } + + // Status header. To be safe, display it only in error mode. In case of success + // termination, do not modify the status (""HTTP/1.1 ..." header seems to be not + // too cross-platform). + if ($this->RESULT === null) { + if (php_sapi_name() == "cgi") { + header("Status: $status"); + } else { + header("HTTP/1.1 $status"); + } + } + + // In XMLHttpRequest mode we must return text/plain - damned stupid Opera 8.0. :( + $ctype = !empty($this->_contentTypes[$this->LOADER])? $this->_contentTypes[$this->LOADER] : $this->_contentTypes['']; + header("Content-type: $ctype; charset=$encoding"); + + return $text; + } + + + /** + * Internal function, used in array_walk_recursive() before json_encode() call. + * If a key contains non-ASCII characters, this function sets $this->_toUtfFailed = true, + * becaues array_walk_recursive() cannot modify array keys. + */ + function _toUtf8_callback(&$v, $k, $fromEnc) + { + if ($v === null || is_bool($v)) return; + if ($this->_toUtfFailed || !is_scalar($v) || strpbrk($k, $this->_nonAsciiChars) !== false) { + $this->_toUtfFailed = true; + } else { + $v = $this->_unicodeConv($fromEnc, 'UTF-8', $v); + } + } + + + /** + * Decode all %uXXXX entities in string or array (recurrent). + * String must not contain %XX entities - they are ignored! + */ + function _ucs2EntitiesDecode($data) + { + if (is_array($data)) { + $d = array(); + foreach ($data as $k=>$v) { + $d[$this->_ucs2EntitiesDecode($k)] = $this->_ucs2EntitiesDecode($v); + } + return $d; + } else { + if (strpos($data, '%u') !== false) { // improve speed + $data = preg_replace_callback('/%u([0-9A-F]{1,4})/si', array(&$this, '_ucs2EntitiesDecodeCallback'), $data); + } + return $data; + } + } + + + /** + * Decode one %uXXXX entity (RE callback). + */ + function _ucs2EntitiesDecodeCallback($p) + { + $hex = $p[1]; + $dec = hexdec($hex); + if ($dec === "38" && $this->SCRIPT_DECODE_MODE == 'entities') { + // Process "&" separately in "entities" decode mode. + $c = "&"; + } else { + if ($this->_unicodeConvMethod) { + $c = @$this->_unicodeConv('UCS-2BE', $this->SCRIPT_ENCODING, pack('n', $dec)); + } else { + $c = $this->_decUcs2Decode($dec, $this->SCRIPT_ENCODING); + } + if (!strlen($c)) { + if ($this->SCRIPT_DECODE_MODE == 'entities') { + $c = '&#' . $dec . ';'; + } else { + $c = '?'; + } + } + } + return $c; + } + + + /** + * Wrapper for iconv() or mb_convert_encoding() functions. + * This function will generate fatal error if none of these functons available! + * + * @see iconv() + */ + function _unicodeConv($fromEnc, $toEnc, $v) + { + if ($this->_unicodeConvMethod == 'iconv') { + return iconv($fromEnc, $toEnc, $v); + } + return mb_convert_encoding($v, $toEnc, $fromEnc); + } + + + /** + * If there is no ICONV, try to decode 1-byte characters manually + * (for most popular charsets only). + */ + + /** + * Convert from UCS-2BE decimal to $toEnc. + */ + function _decUcs2Decode($code, $toEnc) + { + if ($code < 128) return chr($code); + if (isset($this->_encTables[$toEnc])) { + // TODO: possible speedup by using array_flip($this->_encTables) and later hash access in the constructor. + $p = array_search($code, $this->_encTables[$toEnc]); + if ($p !== false) return chr(128 + $p); + } + return ""; + } + + + /** + * UCS-2BE -> 1-byte encodings (from #128). + */ + var $_encTables = array( + 'windows-1251' => array( + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0098, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + ), + 'koi8-r' => array( + 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, + 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, + 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255d, 0x255E, + 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, + 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043d, 0x043E, + 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044C, 0x044B, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044A, + 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041d, 0x041E, + 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042C, 0x042B, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042A + ), + ); +} diff --git a/ipf/admin/media/tiny_mce/plugins/images/server_connector/ajax.php b/ipf/admin/media/tiny_mce/plugins/images/server_connector/ajax.php new file mode 100755 index 0000000..f022184 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/server_connector/ajax.php @@ -0,0 +1,20 @@ + 'Íå çàäàí ìåòîä'); + exit(); +} +list($module, $method) = explode('->',$_REQUEST['m']); +if(empty($method)) { + list($module, $method) = explode('-%3E',$_REQUEST['m']); +} +$method = 'ajax'.$method; + +$timgs = new tinyimages(); + +$GLOBALS['_RESULT'] = $timgs->$method($_REQUEST); +exit(); \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/server_connector/files_conn.php b/ipf/admin/media/tiny_mce/plugins/images/server_connector/files_conn.php new file mode 100755 index 0000000..189681d --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/server_connector/files_conn.php @@ -0,0 +1,8 @@ +UploadFiles(); +?> \ No newline at end of file diff --git a/ipf/admin/media/tiny_mce/plugins/images/server_connector/tinyimages.php b/ipf/admin/media/tiny_mce/plugins/images/server_connector/tinyimages.php new file mode 100755 index 0000000..040c885 --- /dev/null +++ b/ipf/admin/media/tiny_mce/plugins/images/server_connector/tinyimages.php @@ -0,0 +1,490 @@ +folder = $this->folder; + $this->restrict = $this->folder; + } + + private function leftPanel() { + $ret = array(); + if ($handle = opendir ( DIR.$this->folder )) { + while (false !== ($file = readdir ( $handle ))) { + if (is_dir(DIR.$this->folder.'/'.$file) && $file != '.') { + $ret[] = array( + 'path' => $file, + 'name' => $file + ); + } + } + closedir ($handle); + } + + if(count($ret) > 0) { + $return = ''; + foreach ($ret as $val) { + if($val['path'] == '.thumbs') continue; + if($val['path'] == '..') { + $act = ''; + if($this->folder == $this->restrict) continue; + $path = substr($this->folder,0,strrpos($this->folder,'/')); + if($path == '') continue; + } + else { $path = $this->folder.'/'.$val['path']; $act = 'onclick="activateDir(this, \''.$path.'\'); return false;"'; } + $return .= ''; + } + + $name = ''; + + return $return; + } + } + + private function addressBar() { + $way = explode('/',str_replace($this->restrict, '', $this->folder)); + $way = array_filter($way); + $ret = $link = ''; + foreach ($way as $val) { + $link = $link.'/'.$val; + $ret .= ''.$val.''; + } + return ''.$ret; + } + + private function mainField() { + $ret = array(); + if ($handle = opendir ( DIR.$this->folder )) { + while (false !== ($file = readdir ( $handle ))) { + if (is_file(DIR.$this->folder.'/'.$file)) { + + list($width, $height, $type, $attr) = getimagesize(DIR.$this->folder.'/'.$file); + + $size = number_format((filesize(DIR.$this->folder.'/'.$file)/1024),2,',',' ').' KB'; + + $ret[] = array( + 'src' => $this->folder.'/.thumbs/100x100_'.$file, + 'attr' => $attr, + 'path' => $this->folder.'/'.$file, + 'name' => $file, + 'width' => $width, + 'height'=> $height, + 'size' => $size + ); + } + } + closedir ($handle); + } + + + if(count($ret) > 0) { + $return = ''; + foreach ($ret as $val) { + $width_for_insert = $val['width']>500?500:$val['width']; + $return .= '
'.$val['width'].'x'.$val['height'].'
'.$val['size'].'
'; + } + + $name = ''; + + return $return.'
'; + } + } + + function ajaxChangeDir($input) { + + $our_folder = $this->folder; + + if($input['uri'] != '') { + $this->folder = $input['uri']; + + $realpath1 = realpath(DIR.$our_folder); + $realpath2 = realpath(DIR.$input['uri']); + + $strlen1 = strlen($realpath1); + $strlen2 = strlen($realpath2); + if($strlen1 > $strlen2) { page404(); exit(); } + for($i=0;$i<$strlen1;$i++) { + if($realpath1[$i] != $realpath2[$i]) { page404(); exit(); } + } + }elseif(isset($_SESSION['tiny_folder'])) { + if($_SESSION['tiny_folder'] != '') { + $this->folder = $_SESSION['tiny_folder']; + } + } + + + $_SESSION['tiny_folder'] = $this->folder; + return array( + 'leftpanel' => $this->leftPanel(), + 'addressbar' => $this->addressBar(), + 'mainfield' => $this->mainField(), + 'uri' => $this->folder + ); + } + + + + function ajaxDelDir($input) { + $our_folder = $this->folder; + + if($input['dir'] != '') { + $this->folder = $input['dir']; + + $realpath1 = realpath(DIR.$our_folder); + $realpath2 = realpath(DIR.$input['dir']); + + $strlen1 = strlen($realpath1); + $strlen2 = strlen($realpath2); + if($strlen1 > $strlen2) { page404(); exit(); } + for($i=0;$i<$strlen1;$i++) { + if($realpath1[$i] != $realpath2[$i]) { page404(); exit(); } + } + } else { page404(); exit(); } + + if ($handle = opendir ( DIR.$input['dir'] )) { + while (false !== ($file = readdir ( $handle ))) { + if (is_file(DIR.$input['dir'].'/'.$file)) { + + $thumb_info = pathinfo(DIR.$input['dir'].'/'.$file); + $thumb = $thumb_info['dirname'].'/.thumbs/100x100_'.$thumb_info['basename']; + unlink($thumb); + unlink(DIR.$input['dir'].'/'.$file); + } + } + closedir ($handle); + } + + if ($handle = opendir ( DIR.$input['dir'].'/.thumbs' )) { + while (false !== ($file = readdir ( $handle ))) { + if (is_file(DIR.$input['dir'].'/.thumbs'.'/'.$file)) { + + $thumb_info = pathinfo(DIR.$input['dir'].'/.thumbs'.'/'.$file); + $thumb = $thumb_info['dirname'].'/.thumbs/100x100_'.$thumb_info['basename']; + unlink($thumb); + unlink(DIR.$input['dir'].'/.thumbs'.'/'.$file); + } + } + closedir ($handle); + } + rmdir(DIR.$input['dir'].'/.thumbs'); + + if(!rmdir(DIR.$input['dir'])) { + if($input['lng']=='ru') { + return array('error'=>'Îøèáêà óäàëåíèÿ ïàïêè, âîçìîæíî îíà ñîäåðæèò íå óäàëåííûå êàòàëîãè!'); + } else { + return array('error'=>'Error delete a folder, perhaps it has not deleted directories!'); + } + } else return array(); + + } + + + function ajaxDelFile($input) { + + $error = array(); + + $input['src'] = array_filter($input['src']); + + $input['src'] = array_unique($input['src']); + + foreach ($input['src'] as $key=>$val) { + if(!is_numeric($key)) continue; + $our_folder = $this->folder; + $pi = pathinfo($val); + $input['uri'] = $pi['dirname']; + + if($input['uri'] != '') { + $this->folder = $input['uri']; + + $realpath1 = realpath(DIR.$our_folder); + $realpath2 = realpath(DIR.$input['uri']); + + $strlen1 = strlen($realpath1); + $strlen2 = strlen($realpath2); + if($strlen1 > $strlen2) { page404(); exit(); } + for($i=0;$i<$strlen1;$i++) { + if($realpath1[$i] != $realpath2[$i]) { page404(); exit(); } + } + } else { page404(); exit(); } + + if(is_file(DIR.$input['src'][$key])) { + $thumb_info = pathinfo(DIR.$input['src'][$key]); + $thumb = $thumb_info['dirname'].'/.thumbs/100x100_'.$thumb_info['basename']; + unlink($thumb); + unlink(DIR.$input['src'][$key]); + } else { + if($input['lng']=='ru') { + $error[] = 'Ôàéë '.$val.' íå íàéäåí!'; + } else { + $error[] = 'File '.$val.' not found!'; + } + } + + } + + if(count($error) > 0) return array('error'=>implode(', ',$error)); + else return array(); + } + + + function UploadFiles() { + $our_folder = $this->folder; + + if($_GET['uri'] != '') { + $this->folder = $_GET['uri']; + + $realpath1 = realpath(DIR.$our_folder); + $realpath2 = realpath(DIR.$_GET['uri']); + + $strlen1 = strlen($realpath1); + $strlen2 = strlen($realpath2); + + if($strlen1 > $strlen2) { page404(); exit(); } + for($i=0;$i<$strlen1;$i++) { + if($realpath1[$i] != $realpath2[$i]) { page404(); exit(); } + } + } + + $result = array(); + + if (isset($_FILES['photoupload'])) { + $file = $_FILES['photoupload']['tmp_name']; + $error = false; + $size = false; + + if (!is_uploaded_file($file) || ($_FILES['photoupload']['size'] > 2 * 1024 * 1024) ) { + if($_GET['lng']=='ru') { + $error = 'Ïîæàëóéñòà, çàãðóæàéòå ôàéëû íå áîëåå 2Ìá!'; + } else { + $error = 'Please do not upload files over 2Mb!'; + } + } else + if (!$error && !($size = @getimagesize($file) ) ) { + if($_GET['lng']=='ru') { + $error = 'Îøèáêà, íå âåðíûé òèï ôàéëà'; + } else { + $error = 'Error, unsupported type of file'; + } + } else + if (!$error && !in_array($size[2], array(1, 2, 3, 7, 8) ) ) { + if($_GET['lng']=='ru') { + $error = 'Îøèáêà òèïà ôàéëà, ðåêîìåíäóåòñÿ çàãðóæàòü ôàéëû JPEG'; + } else { + $error = 'Error type of file, recommend upload JPEG files'; + } + } else + if (!$error && ($size[0] < 5) || ($size[1] < 5)) { + if($_GET['lng']=='ru') { + $error = 'Ïîæàëóéñòà, çàãðóæàéòå êàðòèíêè ðàçìåðîì áîëåå 5px.'; + } else { + $error = 'Please upload pictures larger than 5px.'; + } + } + if ($error) { + $result['result'] = 'failed'; + $result['error'] = $error; + } + else { + $ext = substr($_FILES['photoupload']['name'],strrpos($_FILES['photoupload']['name'],'.')+1); + $name = md5_file($_FILES['photoupload']['tmp_name']); + $source = DIR.$this->folder.'/'.$name.'.'.$ext; + + if(!copy($_FILES['photoupload']['tmp_name'], $source)) { + $result['result'] = 'error'; + if($_GET['lng']=='ru') { + $result['error'] = 'Îøèáêà ïðè êîïèðîâàíèè ôàéëà!'; + } else { + $result['error'] = 'Failed to copy a file!'; + } + } else { + + if(!file_exists(DIR.$this->folder.'/.thumbs')) mkdir(DIR.$this->folder.'/.thumbs'); + $thumb = DIR.$this->folder.'/.thumbs/100x100_'.$name.'.'.$ext; + + //$image = new files('tinyimages'); + $this->Resize($source,$thumb,100,100,'back-ffffff'); + + $result['result'] = 'success'; + if($_GET['lng']=='ru') { + $result['size'] = "Çàãðóæåíî èçîáðàæåíèå ({$size['mime']}) ðàçìåðîì {$size[0]}px/{$size[1]}px."; + } else { + $result['size'] = "Uploaded image ({$size['mime']}) size {$size[0]}px/{$size[1]}px."; + } + } + } + } + else { + $result['result'] = 'error'; + if($_GET['lng']=='ru') { + $result['error'] = 'Íåò ôàéëà èëè âíóòðåííÿÿ îøèáêà!'; + } else { + $result['error'] = 'No file or an internal error!'; + } + } + if (!headers_sent() ) { + header('Content-type: application/json'); + } + + foreach ($result as $key=>$val) { + $return[$key] = iconv("windows-1251", "utf-8", $val); + } + + + header("Content-Type: text/plain; charset=UTF-8"); + echo json_encode($return); + exit(); + } + + function ajaxMakeFolder($input) { + + if($input['lng']=='ru') { + if(trim($input['name']) == '') return array('error' => 'Íå çàäàíî èìÿ'); + } else { + if(trim($input['name']) == '') return array('error' => 'Not a name'); + } + + if($input['uri'] != '') { + $this->folder = $input['uri']; + + $realpath1 = realpath(DIR.$our_folder); + $realpath2 = realpath(DIR.$input['uri']); + + $strlen1 = strlen($realpath1); + $strlen2 = strlen($realpath2); + + if($strlen1 > $strlen2) { page404(); exit(); } + for($i=0;$i<$strlen1;$i++) { + if($realpath1[$i] != $realpath2[$i]) { page404(); exit(); } + } + } + + if(mkdir(DIR.$this->folder.'/'.$input['name'])) { return array(); } + else { + if($input['lng']=='ru') { + array('error' => 'Íå óäàëîñü ñîçäàòü ïàïêó'); + } else { + array('error' => 'Unable to create a folder'); + } + } + } + + + function Resize($filename, $dest, $width, $height, $pictype = "") { + $format = strtolower(substr(strrchr($filename,"."),1)); + switch($format) + { + case 'gif' : + $type ="gif"; + $img = ImageCreateFromGif($filename); + break; + case 'png' : + $type ="png"; + $img = ImageCreateFromPng($filename); + break; + case 'jpg' : + $type ="jpg"; + $img = ImageCreateFromJpeg($filename); + break; + case 'jpeg' : + $type ="jpg"; + $img = ImageCreateFromJpeg($filename); + break; + default : + return false; + break; + } + + list($org_width, $org_height) = getimagesize($filename); + $xoffset = 0; + $yoffset = 0; + if ($pictype == "thumb") // To minimize destortion + { + if ($org_width / $width > $org_height/ $height) + { + $xtmp = $org_width; + $xratio = 1-((($org_width/$org_height)-($width/$height))/2); + $org_width = $org_width * $xratio; + $xoffset = ($xtmp - $org_width)/2; + } + elseif ($org_height/ $height > $org_width / $width) + { + $ytmp = $org_height; + $yratio = 1-((($width/$height)-($org_width/$org_height))/2); + $org_height = $org_height * $yratio; + $yoffset = ($ytmp - $org_height)/2; + } + //Added this else part ------------- + } elseif(substr($pictype,0,4) == "back") { + $xtmp = $org_width/$width; + $new_width = $width; + $new_height = $org_height/$xtmp; + if ($new_height > $org_height && $new_width > $org_width) { + $new_height = $org_height; + $new_width = $org_width; + } elseif ($new_height > $height){ + $ytmp = $org_height/$height; + $new_height = $height; + $new_width = $org_width/$ytmp; + } + $width_d = round($new_width)<$width?$width:round($new_width); + $height_d = round($new_height)<$height?$height:round($new_height); + + $width = round($new_width); + $height = round($new_height); + + $width_diff = $width_d - $width; + $height_diff = $height_d - $height; + } else { + $xtmp = $org_width/$width; + $new_width = $width; + $new_height = $org_height/$xtmp; + if ($new_height > $height){ + $ytmp = $org_height/$height; + $new_height = $height; + $new_width = $org_width/$ytmp; + } + $width = round($new_width); + $height = round($new_height); + } + + if(substr($pictype,0,4) == "back") { + $img_n=imagecreatetruecolor ($width+$width_diff, $height+$height_diff); + $r = hexdec(substr($pictype,5,2)); + $g = hexdec(substr($pictype,7,2)); + $b = hexdec(substr($pictype,9,2)); + $back = imagecolorallocate($img_n, $r, $g, $b); + imagefill($img_n, 0, 0, $back); + imagecopyresampled($img_n, $img, round($width_diff/2), round($height_diff/2), $xoffset, $yoffset, $width, $height, $org_width, $org_height); + } else { + $img_n=imagecreatetruecolor ($width, $height); + imagecopyresampled($img_n, $img, 0, 0, $xoffset, $yoffset, $width, $height, $org_width, $org_height); + } + + if($type=="gif") + { + imagegif($img_n, $dest); + } + elseif($type=="jpg") + { + imagejpeg($img_n, $dest, 100); + } + elseif($type=="png") + { + imagepng($img_n, $dest); + } + elseif($type=="bmp") + { + imagewbmp($img_n, $dest); + } + return true; + } +} + +?> \ No newline at end of file diff --git a/ipf/form/widget/htmlinput.php b/ipf/form/widget/htmlinput.php index 10958c1..99d7f2b 100644 --- a/ipf/form/widget/htmlinput.php +++ b/ipf/form/widget/htmlinput.php @@ -45,44 +45,36 @@ class IPF_Form_Widget_HTMLInput extends IPF_Form_Widget $extra_config = ",\n".implode(",\n", $_st); } } - $final_attrs = $this->buildAttrs(array('name' => $name), - $extra_attrs); - // The special include for tinyMCE - + $final_attrs = $this->buildAttrs(array('name' => $name), $extra_attrs); $out = ''; - if (!IPF_Form_Widget_HTMLInput::$js_include){ IPF_Form_Widget_HTMLInput::$js_include = true; - $out .= ''."\n"; + $out .= ''."\n"; $out .=''; - - } - - -// buttons: code, separator pastetext, pasteword, -//plugins : "inlinepopups, paste, table, fullscreen, preview, print, charmap, separator, ", - return new IPF_Template_SafeString( $out.sprintf('%s', IPF_Form_Widget_Attrs($final_attrs), -- 2.49.0