From aad4a54b8b1bd2d5c475e8c7236389b4eff78cbb Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 28 Jul 2009 23:00:03 +0200 Subject: [PATCH] Almost there... --- bin/start-akka-server.sh | 1 + config/log4j.properties | 1 + deploy/akka-samples-java-0.5.jar | Bin 4254 -> 4256 bytes deploy/akka-samples-scala-0.5.jar | Bin 24479 -> 24639 bytes deploy/root/images/body-background.png | Bin 0 -> 2381 bytes deploy/root/images/header-background.png | Bin 0 -> 20847 bytes deploy/root/images/main-background.png | Bin 0 -> 8026 bytes deploy/root/index.html | 45 + deploy/root/javascripts/application.js | 93 + deploy/root/javascripts/behaviour.js | 254 +++ deploy/root/javascripts/moo.fx.js | 136 ++ deploy/root/javascripts/moo.fx.pack.js | 83 + deploy/root/javascripts/prototype.js | 1781 +++++++++++++++++ deploy/root/stylesheets/default.css | 54 + kernel/src/main/scala/Kernel.scala | 9 +- .../ActorComponentProviderFactory.scala | 17 +- .../src/main/scala/jersey/AkkaServlet.scala | 78 +- lib/akka-kernel-0.5.jar | Bin 552533 -> 554042 bytes lib/akka-util-java-0.5.jar | Bin 7246 -> 7246 bytes .../src/main/scala/SimpleService.scala | 11 +- 20 files changed, 2505 insertions(+), 58 deletions(-) create mode 100644 deploy/root/images/body-background.png create mode 100644 deploy/root/images/header-background.png create mode 100644 deploy/root/images/main-background.png create mode 100644 deploy/root/index.html create mode 100644 deploy/root/javascripts/application.js create mode 100644 deploy/root/javascripts/behaviour.js create mode 100644 deploy/root/javascripts/moo.fx.js create mode 100644 deploy/root/javascripts/moo.fx.pack.js create mode 100644 deploy/root/javascripts/prototype.js create mode 100644 deploy/root/stylesheets/default.css diff --git a/bin/start-akka-server.sh b/bin/start-akka-server.sh index 16c1109c0e..eb7e1f7de4 100755 --- a/bin/start-akka-server.sh +++ b/bin/start-akka-server.sh @@ -102,6 +102,7 @@ JVM_OPTS=" \ -Dcom.sun.management.jmxremote.port=8080 \ -Dcom.sun.management.jmxremote.ssl=false \ -Djava.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory \ + -Dcom.sun.grizzly.cometSupport=true \ -Dcom.sun.management.jmxremote.authenticate=false" diff --git a/config/log4j.properties b/config/log4j.properties index 0e58e64e80..7e38b9c134 100755 --- a/config/log4j.properties +++ b/config/log4j.properties @@ -17,3 +17,4 @@ log4j.appender.R.layout.ConversionPattern=%5p [%t] %d{ISO8601} %F (line %L) %m%n # Edit the next line to point to your logs directory log4j.appender.R.File=./logs/cassandra.log +log4j.logger.org.atmosphere=DEBUG diff --git a/deploy/akka-samples-java-0.5.jar b/deploy/akka-samples-java-0.5.jar index 839c7dd26fd49eb4ebfe8073ba0dfd2adb72cab2..93ef575cf46735af6c76150afcd8692e62c47ba8 100644 GIT binary patch delta 336 zcmbQIxImFNz?+$civa|lZ~ZfoSB3f6);|+XW`L>lN?_`XI*8gV$M}Q^%wT0X#=`u3 z>z~QzIJCg@Zw?m_z1fLVoLTVs)<0G=Ec*@185kJq7#J8lCkJraO|BB)s~0`x$aTm- zz~SQGIY|p%w@HX@y)d;yW5*`(8QT_b>GeFR!kC{QQ}=K6x;GX9PXvGK+i7fWUgh2M zJ>{az#TjYk8D`No@$+P**7{GdJna6!+O;?wMjm}n~_O`nTvrP>dDDgye1%jOfKZL2h*E*jllE^UUM+5#ODa6 k)A+nV-kQ9b&k9U`;0poM?)=v{;l7-#CQ!tt%L_6a08#&v{{R30 delta 334 zcmZ3WI8Tu`z?+$civa}Q?)p8ESB3e_uHO?)W`L>lN?_`XI*8gV$M}Q^%wT0X#=`t| z*YC;aIJCg@Zw?m_z1fLVoLTVguHROF;&pG9GB7aIF)%QAP7dI-n_MHnS1;P-$aTm- zg!Q}S(e`!HPD?wS!j%?Xm>TzB>tC;t?RnM9aDK4fKJ06E%**97E?$;G_(V0tUB5tx3(YYwJW_#DA> k2A>zmQetr1d7IM&1B#W)?065O}ur&qQ7o=BHc#Of;DRrp_yYsV^EJYO_3JA~TrL%+klq z@pS7St8?Fs!zN2|MAmnCO=RNe`4p9VW>U`6HOjYFYTQ4@Cw^ke^izW&Y6P->HAAX_i7<556WQ{u^qe;d_h1m}2!ziHL`ZsGi`GsLLs zSirh1PU~df{5WFw;^T_IT;nscKi)(UC8|7um{VLS~l~xpwr89XR`+h zOKm*$;ot%5tCpeBlUZJ#J6E5QkWedBf4q}v<*r_vu#K5X%+n>r=3F)q`nyB`}I$7RQ%ltF(Lsih$laJlD&O9C(p_Z30J5je!?#t4@ZeRX-*!+Lc z)hKrJfNs{r&$=&XcmGjwY5?y>r!KvJLMY^~%R{mgEP=d%ru`zpIN)PVCi^yuM!_-Tv1 zV@ucbac7P$OT4t3_gDBG%`5fHu!P3J07^Q_|8|twvN13u@-i@JO%fHIe27b`KC@gn zRH80#yQdoST@3+&H9`iS-p<_(Dhg9JMd-F(3ex#)ve$R{+%r>VF5%Yd(%zw+w_*pk zUX4TlwuJsg&nuqD{BM!}^I-pnANPEOyo}ct6cwev+w;Em-rJq;_tyXWeOaGD>Z5M+ zoy=uxE$**;IcMRnU~j(HdnQLKN6j(6Q5aeuE_sS6&FZMG(Ds|FCb%0ld7N&T)itqV za$3epc1ba|*e46~+9ru@?!R#Qwn_8$<&*c`c@WcvX-q5^ZBubqdQfn zWq#sH<$J56G<~lYM_H~|%Hv(cVH~o_;&jTL)~8ceTxm!%UZZtpv3JjuU#rX}o9qhp z7XEogZEJ|E+_mGJsyEDx-$bnVAiVT|@5Db*jZ=-D=8M)JRyr=Iox5a=@rwI( zr+QlyEcfo;yS4k^eY5T$A4iGOxRwC_t1{dsT>E41ObA)LKD$9WBx!n$c+JV_d2U{+ zCWbBP?lU48S+fiF^Jj1DTX^Ycm;dJNpX-wH;)}DU#mK6>6A$y@5n6Pl$X)Ej38uS?_&VY+dBN8;AGrj9-veQkA{wkW^4FhNT4(X@kKIchH{=cXw+-Vl;g zXP(mO&W?8;#!+{a*l%sP-R^$DPxjEq`-QpDQI~)3P)%Il!?*Femur2DBfnKQ{6{}uH`yFIw{9wa|JuO4zNa_!VIt8m_> zR}FStRmwV@TUe;DO~{dp-+m)=npo^1)mIZ|{>f5%Yhxu^`gTc1snEW48A}$gne~n( z`=jVS#?>o?zBBJ)J*n_nV{zc3n|2}>`6J@WnfGa)u$?@k+&1RBvex0r5d!YWBP2AXZ;2c3*nk>;tv;lfO>2T(GB7 zLtjcjaYfpyykxPgV6jue>vp$&b)CU|a-( zPkd}Mc+vGBVZ-SuM=HPEiQ2yVpZSqdrr)lv9*5vJO}SBEyw0w z43dgooceFliYNNLRew?g*I(GvX3G=&V!@vGt6$AJu(+L7#&bb2wIlZF4_)pxyGz059>Q^4o$W^Ut}P?tYFvjS1&zn%J(X45%*YsPq$(A z6)s^@S5~P4i9ng7nlj7xE_qa5^{+MV+2YG9+5YBuZ}UoYOy6c2y_D^bvv{*{$ZWMg zzUEEFEj#C3d%MV7|LPl^I2G$fzfNbUWyN}(sq+ubUT_1X+44!`7z?=B(y#DGdGY~C)%xrN zk?W;)>055ija_@>Rb$0$*04=-9^4WecqN#bdNw#Tq~sh}e=%zU+uL(%($WM!DW`Q# zve@|eNT2ZYhbm=4>Kl{Qk1_J7)jheoC2yA9rDeXe&2n#Td8wRxYfI*3_e;g^=fhPPDM?lX&K_r~loqy>gCMh1L~@$lJ69Tt6;- z^!Md;i8Dj4&$uM(E`5=GZSAhf5?9-edjfNVic62*RedE;GqcCA=fZ_@7wc7m!cOu9 zxk*kOn`7&vjb)D=GTQp2Y|?`BUOkF;EV@JzjGA%H%>V zuVdvePHxGw-dMZKtY&rY4y$ax9i`jmZHlRtGRUy_ZM4iYM(~5eAu0F%sSl1z)cHI( z?xAtIFZbE?2ruJF&SEbg-16p5d%Y*~PVj+yJ@YPlF3Hw@Jfq%(@3rk@&Se)Y=iU3B zu`PSTG^4ab#tuI=O!M4jZBlHp@^*^$rL?NshKF4PW}I?9+&1}I%qE`DycH3j*8aS9 zMC*Z+=G{{QCht^I+_!s*JeF(Qv&tu#_sMO6duwXgt93qaa7^P==PmY;fA+Urz^Y~c zhiROreNu9w&F@z9Po4M1yng3e^V{3ZEEnwd5$wz3d;RTO&+Lt*YH@03|J>Q=u_x*w z_w4re+*jg-W^)cYt#^)yotY^#?||s93oD*l2}emST$UbEoUG~1Grh95?-<*%3kh?s zf8;Jbz5k#AZ@Dt>m%ga z%rf{L#Y>c9g6B2$*b5f`r23Ep3;zmn^~JA*BUt~$PGw>|QR zDVKQz|H7SXMP`++;$?F-VAvke1r9y(PGEn)x9L>JyFBxp_CqPz3qy~rm~-%+ zHrL_Uf^yzFoVR)sby~O`nvN~l(7<)&XoLCVRSqAQ`!8F3iEmo4l1X;U0|l9dA0(w0 zS=Bj4XuUn&0!9sK+wv2s^n##t{IZXW|tE-PG$6{Z%>$W(L`Y$@UFPjxL(^+jQ2B zj29Ibzg6xDRtSoraL$D zFz4CCyIJ!TMbEDCYui)bsOk|w31TS>NQi|x$&y6a=pCGG%0(fNT_?P ztznkbV@carlU4-YePU>9wUFOcQ{CF@WWklKi*#hW__Eg>le-gWJIh1Lq}WBBr+mt! z9WPdtO=--0mU89F*M}NE9Tg=_H)%eo4;GU*z4I<3{Q9v8T<@JTc2DVLcex(%WBx;9 z^W5aRkjdL*rcdM2%j{dDblnCo<9mTl_gJB#I)?R@CGWiE{2_v4UhDadQ|<~SBvv$v+Of`G z&bMsk5#L#^!PR~oU03xFofIhjtU77>q%tW%1NGgkM0c(QH!Qf8;E zZ?pu8BCk((wF-#YyKk>K&-%mR&L2d7NUcrW$xwEx5P(*K<8Gq!q(~}Oo=M4NeMsS$tp zTZE^VK*ei$F2R4ZEN+BYEm1wTExN33exv@A*SEbMA6=&%RBRY0QO8nWfBeahYN=J0 zmWMth2ma`PGGm>sWk%o{KS|@zAHo;6*DpKSJ~^PnYf8}HkT0L&S59}=ab9SLk@;M7Qy{V6H*i&uwXv!9id>K)_175Kzp@xU1e&9|P$j
    %0NgIlbv;CLGPC092!L97`p{hl9>bffL&r-7ibEvzVxmo#{!a1(QZP0! ztH0QiH^Y6c;onUr*SvjQzy1Hec%$T>LpvmMG~x zoyn_;xOSi<;%2~Rz4{X|V#f`(J-F(ln7cD&r$EoOu%B^l8-oM%mW#}q-c{GWF?z~z z&5MtoCdO!bg&FE@3#TsL}IUwr3q#axZO^Y)l0t5sgC3f$6I zK;lip0LnU z(?e?;R6VA8TRkq>bj*70nam{h%SUWxoc~~dDExu7VA%BBiIVD5dtKG1I{k2UV)s|n zIsf+2)bbEXO`BCB5rK_gHH~hj%6fOltzT`UEOIR^IP~t9&Xp4~J14x1^zuuaQ$N4! z*3w1aDlhq6%v`l1UQOm9H^=qZb2nEpbaJZchprKOza(_Q7LF;GRjY5$vOZ;Y{BdVs zZ_>t7<d}Vh2a7lan+0$}I8EyOzu2O1X*yoj8&BoOkw@cM`;hQFQ?bOd- z{IZ#Uh?XUU?>Q`XVEsh-FV5m2j{0??`~95jU$NX4WoBsA{rA)M!QIgJe%zIH%L7il z-+FH@lkooFjD^+AvyFcgPrjbFE&TqQt;;_+eAms9D6X0%Q1MgA@BV=#tNOlA&vnlv z|EyhE9{=p&QJX(vW&Ij&SSHPDXSm5|8EgIGrQ0g^UHb1TBp=D9C-VNicJckOzP7W^ zAE>cfopY?0Kjf+8_+m-6>`F$B@ZJMwRnp>@$eA6~}Wju)`GQqKjUVrbB7Nw zGTp0}`nGA2_-BnezwNWvZ9kOTaw6*X5|7q*(kpKsWR{)FyM2DMBI~_|hv(W3U#@pA zu8(iqSe&3)Aa_hs_&1Nt;!EO{)0bDyD6o&6&1&Rx$d=*H{mH&+qV;@?Rv*GHPbA?*;x(WwDvjP=4vK^9KV)gOAe#%q0##sH|u?`FY->dvc$4?43SOuJ!nyH0~Fj zSHnzg;_f^!(+e|xxNrVDc?}`fhnznauotOcG}!DC-_$?1eL3GA9)I(iPdqitKJ!+5 zd$Jcb1i>hvcCV2V<`PNHX1$Rm7u_2EQvOr@dO`7Lwd*IFy4s6Xo?4;C|L50d*HN#IV{@5F2DY$R0d_wDz`hp;*U$UAnLl1=|+`doYO?fKuy?H9A= z%lMNX^%_&Z=BI4>$MJ95l_}{D?`SScjd(|cXl|P@1Kk=(Z%G>Sn(qA#UiIrTA^@oH4&uv;2G>uX7w3ejz{5eba z2TfZwWoi7f8*4ZC9t+Z)pW3mRBWQ_!>dI49l1C=E?>gK4ys_`x)AWsD=Ym_VIm}CE zh&yT(C%@prsY7Oubc$LoDK_#x{r<>g`Y%>b{d13UBK2n#_Vqmd^C|LNs!l;;j=+OZ zqiNlSTFE=t&3Ficlz~hUKcdyYtbBOt)n+Jj^7MX8(SzK2*e++59XG^bYdn4C<*?o^BV->1LD>9?sW zsvfosFyxavv--~Q=`Bk>y@=f7%%>9k^JUG9dFMmxmdAvahp*D|ebvA@lbO%klmE1b z`;sMXJzqFiQ_c{i>9@`*yDijcPAH8pcuWzvP- zPkeYM-0oabU$Ol@*S6w4HFFHMXVvqjsdk-HTA5Tp?fA-Rwohi#(HrDLVxnpY z&w9l_1@o46l>O^Fy8PqGPm$-I>pXkt{#j?L&1v=c2^LS8{>*UMm2C9VPVf7c<=S7j zxCZ%GM{Ud4#bvLkxYu9puKLqUw!te)0#}xtKM_$UWv`t4GvKGr>&hd4*Tj5zt|eOA z8S>?M%A$I|bDvthBK4+js&PE_>GP)*ACr~_CeJjL2o7)hvgJ+ZxcDYE!5wlLhL-_4<7k6>%UrB!N>dM z+Zzt;pUtHiYPaUuauLNfZu=`ZcXCOscI=H2?bbNBD~hLe$}EFlHxw&5vM(O*t7$s5 zX2K)!bSc55b&0z5W-U{WsjYdo+)XjH%=p*Ql^z~5jm2x<%urc!W_JHqRd)@=n1-&! z>{DHNy-e-%x-`0{UrRDsqLb+)Zymy^b$XH40qe+44c+kTN!c8$o4le|2L%`GS`=1( zK%`{R_lfbsdi@%)Q+PD4SCzAiAboEBjmW@U$)?|e;J-W;tULP7>KELAg50Nzo zS9Jzvo2~2BxV~<6aMU_(t?Szt#qZ&h54n~f@aK{1B!Q``UmbfV%x_nEXS-PK6|GgP zW*2FEStIyrT1>5JwOZ5KN;A!Lm(cCcZ(mNH^5p%zCRyKo_qJwxHq5=dm1EVd>%NQp zUCR~gckbpapZw*oW2*n^psU$Jldo&5iCHg{<o@1_n7p}g`>MV!E#}vIR^@vB^UIlB^!uIJ((0Za6KjLldRcs*#r(O?;Xu=ykL*)T zitJTmdy1tu8STDkzRqf6$NrYa_EurN z&+^HWvmV6#tC43jQq#{2diTEfN7TJZtqVRmtbQb2zahx#VA{lj=FrHcp&$9vG8|$S zvu(1Qk##yO`60Ww@4q$n(r4O~Lv?R5TwKjk$ZaWC&3CbwcdNSSyUYCUtD-k;y{Rzu zYT(R@?JWk%PuAY7I#avvQj2rQ4UXW8Il|BEw$5Cel5RY6R{r^4EC0?3OAWjDTIouf z9P_Mx*Zc2HLwV~{#a;f~Y`r;cYj*b3H;X3dSBI7v{<>kV_QifyY*W|U3;UPeOkLq) zp{Oc-IIC`n^q17=&D~RW&5TbJTy1u2m2CI^#Eey^%5?HS8MZ#q7O9^WWMjqgcLV3N z2h%^8*36w&)$d@xPcV}6amoLpl&AlhP=@ZTc5mTv-yF)yz!1*Gz#zvkSs_NDernk5 zVBv6y|8pmw&YQ;Kv_rGWt!EPVhDBe4gf=u}Y!qDUc;#M!=d>M@qRY)Ya^EJLPX6Cv z_hlo$Rq(~kbgQ|3^Q|t|ue|*J%`y$ojN|QdKF@t$^W1v>`%l(4?f?J#8O|{IMnXW* z)m<~Mua{7ryHGuSO17%)^4YW9;^uGo6y=#*|6$51*EZ*yU3sfj*RHsG*EN`nMZ{j+y8xtFIEB*O-3DLvz7HU80 z6lHr~v(-Uk*CsdD_*K)dmlQ`v3-4GYshuxnYMo`j?&amh+xDfde#91TZMFCWhme!E z@QYCPZB_MWSA}JXOj|o!$f|k51O5fviCmV8cd;Mc=^&)E+7`GrV%4^d3s*|-ioEEpwbIKkN#j|>z9o^b`TOzc(QOazAGA!Yi?gsf@o3S8is@1Jdyn6p zxmtQ@(~H?#ntC*9^7p(gtmiaVvYx)eAZqQha4w$CZLOJ)=k%RV^7}DAU82%uW4OHU z6_eogH-w+$EQ-_4*e3ViDC**=Um+zf$C#WmQgouO>3VDL(mJ?s;)}^Hv#cruOExt> zXJ)&(Zr66!!dMOCh@^y6t;GfIJM$_OUC&(W;$s$7yY#T zz*V*`=yjkVUrqDAY~Si_Sz@7Q^}^TQV!nIjYR%b@=Vw-hoyeZ{_FK-ft*eY*ZcoXW zy(FOiSx=Jd=GSVe5oOyv983SzdkDQa@uNQ4ae~9T-O&ji1_g71%pELajx*aV`6)fo zzv{R0qpQVfCugP_d^~q?#f4Wg7M>3AMnYAM?^2dLXFaK3Xz`Ql_`J((&g{K&pYW`h z-0aJe*p~isr^USjLtj0MvyCaQ%;(%Vx-xysgL8)aAK!NAI#zd`V{r#_-xP;Q-)2@+ zO0D~+P=AE!^W7_7Py7hdTJ-MGn&<31OKsNe>E^y3yza&B{oN~<#!uM!UFh=3*gf03 zPfye~>EV1>D|M{3pqK5|*-KlxrPohXo%>tv@+bjX9=e~WL>#^r?Z@qA9^`0}&zic^F zbLRcO*A*8YH_O-=NCE%LBVb-jz!Vd@GTc;@Q}7sJd!q z`-x>A_SG%hqqg7>+l+P#$p`JqdscULCf2FkI@#XWc4NaK8^*ev89(!9RXN75=Uhu+_|_SihFe~sO=g)zRu zNv_}G4}HIVkLPusS=XscIforDZ=dsKe);*5x7XcM?=vOtJR}vbve(A=2R~{7EN)%3 zz?GSSp`DF^!H|K0p*V5#bfY@Rbc%$T7CU%3h^y^4CNRU!;j<9)v#oz7n*?it>BL|c z5WRUta5f9)v#o!uj`-}WE1xVA5n3;M%8{$tK)~VR-#JMKwkozw+t#G5nY3_qRb$|C zS0CY%Do*+Lx12s-?|QtC*>zswp9gcx$^v*gKTgw`Wh@me?^ha{SY6ALv1Q+ZbBjSr}V-b1uX^Cdqm)Air_NIpXv#enZ@MdHZVdi3B zXJBAp06FzrgbB#)lXWBQ!E}D45tv>QX#uA1M|y*4-6$vU+!1)mOL;nZyMrGm1(~j*AwS2Pyh*`FeLh3j;#|Cj)~F$XX~~(s*j}glKIAkQ&g8)Lvl* zh6sBG263o7h+5J(S#mO?sPN=>(L!Luc5gwh5J5^Hcu8aHWce6fuv7hGq?yEwCpW~( zOkQs!K6!o&4_J6zj5O0KGpI1vWM4D>NwE+a{#a?I>$YH-0$Uz!SQs%dK$dDO(N2H5 zLx_Q4ogD*%0>nBnxuo&Jg~yM5 z&z~2}d?BUy{%FuPiLl85(>8fZ)vN587n1vFM_}&LLeaK9=^JSg-HU%SXYLbY))!%y z&oK;9%HH9sTeMHLws_%ml@l9m7prWpxUyk!R>|y^&6E00ZI226;X8Ga!kI@?5~RLK zUi-gNs($M&mlWP|(Q_*Pyx%?VS*X99dFA>f>rabUEoy6TwOToQvE80__6iqy7d91* zXD8A!zE623a`yAq{2c+-&L6pRgHB93dr9zvTth=7(Zr7YA3XYhwR@fctz~& zE4O9eM5E_t9z2%Nwd#uU^|KSRca@~xnizO?UErR=GsbuRIG8+*Qe8bGB;(4ti~sj+ zvF@GU_guub+E9FQo8No07x9J51OCGk8V3U?>7?68nMJTMFx2xhFlaGMHjELOe27b` z{$;UCt*Y~me>+bIV`}c1@ z!>o^{&6iT2zBReOKzh!?b>8QBCH8dRX8&rEUv#N{)5iC=L&7NoHaq+#xW^( z|FdNtd%Vm`zsI#nUSz1uVR!x+rS1G8_;$(U@+ZZ6@7!DVm8<&m_e}P!EemJfbaB6D zuq|SjXWKRYWj`BMM=xs;aE>(D=IqM4N<PZmgX3n!Pe*Ws9cP zsQ|e{AtA;g|LfD!i{IPLD^tCqwL-Yya_t=6N@HCgGxtkv&n$$Nb?~%bwIK#Hhz;9`TvH!uCGs|6e{@rzW!wQprM#G?2 z*|&8r-B@^Y*NJq+m7=!}G!)JVSd{ztu-{Ry4a$1*LO>#{p!0>dHHIw z&BkL=PiDTIBF!0CR8{T%+N`bMHj9_0XrW1qfU|OFvB4#sKYRtwm(HBoR+ksl$^0qS zC|Kw2jwxOdrv&CpB-XHo=p2j03Q|1qYr`o6Bvh_wo=x1v(pf9W1Poc;Rx(_6b{s&4&#QR&LH08PG& zPNJ{>bbj5U_dF#u=gWR`L!B}%wGPd`)F-YJ{G4v@kN1A_eA~%h7GKFuGws=`Ih_0g zEs3eDjmf!cEAbo4~2L-DY&OiSBUbpt-Yqz%BLfbT6h*a0FbvhzC z^`dKax5ufoJkB~3mNFWoq+6G9ESbwQS?YCaiSdRRJ$HFFW&hlz^{peq`eTPjwWfS6 zv+lOFvePz%Z&`Eq;GOjj>zQ~ngE;x3nR2%l-F>ro*A;i~(?()U_75JWUR=L`-%7Qy zpd|QMofnh+gzG%+u6)|A)=IC!%Vo=A>gTP_f8Mt^wbH-8hmmdTzWCx--y@q^eT_Pd zOjT{#V2Fd=wU9Ix&l42dD z&7IDEhsuPkEAzQarEJ%7ip5^uGGB-JhQLCX=)WO$Yad9=Tlk3TgX zcB=QweP%Il|2|!jOCB16;is#PJ7jMZEbYAby=KkHeNX1wKR&uLVs+Q#3fF_DE2bt+ zOFwY#W#?KO_nEtny}tfZN2e}Gc-p0~zDo|FadEeN@)p^zv}oOaiENns z{lS)qk9y9hUD%K5e%<>0=+2_HjyFH{P*Jtz}h-UxtfKMv@hjw89ZN~S$5eZl4mMn4O`mvh($HI!k2Jil` zb?e_@&Vgm-F{yzdU4VhU1!dEwd7 zJ#F8P&7Wx1`?A+w(X{9Hqx*}}ID&p!PMJP;KjWW0N`Gwb2R1FwZs9*)-=?vD^2_=> z#(BQ``2NX%yt=VMB75>vlRS^G3pZx1;hC&p>9diUanGX3UYoX--8PWp z@;15hPAI?Vqpr$5xn+qGwu>+9I$h^*m&54r4e@D{y&_hcP71vnzVIDS_}?zg=Nn97 zOnF|LJUY};aZE=>BdVZgOQMWjdvATqhm4@Ff+75gl@VVB#QNPU_H=wWG9%sY%+WxZ z*XwGtSkA{u9{u?4nBbm*r8DkY7zU+m=d7OSqTi>~Z2aIy>%ad_@{=zfb~>?XmlLa5 zrRBWn6%NAxmUJKF^jNa^M}9%Qb)^0;zL`pXKIq z=)>AOkZQ=~oY3qFW(I~!>LjFqcanvkC)cvb24!YEIHtOCD&2N*&M;_8;XS#p_|m-)^%%f0o* z148~vOJi(0;K8(Hnf-?Dxs{*yn!n#$`8h4^``P$C^`E2|)*Oj<=HQKxv|jk$V3L*7 zR%b}+GVMH$x~mbYTB}DiD{F;_VZWnRs>0RUVhw>*mvaji*>i91wwQmO1XbM zn9NaHyC-mu{adMNo~6B-cMG=&)?T=^+`2Qc*5a_lRW;M_@;i4I@g1CgQsOWNZ>{^5 z#ZrcfUl^~eskPJ_+}>(>IZ;O^*!!IV=dU$KBo2M8?UQ?cr)|=%WL4vy1D)B)$x$^v z+kI^%moG}GSw7F_^)}(#%d-z}zty&S^Rt%d^w*lFuP$e7ZriM%JnM)kBfrv`!Y>h= zbv+M{v()vpYF&yzhduAAMNc%le7j##ujx>ToRry|Ezc&Ut|&@A zIw}A3cC|3Z>mDz|+7=XwD_ZaJT_o|{;7MqzRJOwXwhw7ft#2gHZ09xdw#b~3{LA3| z{^kpce_FTuM5HMt-`@4|SoNAO^(p&L=I%YZZR<(KyQy6TCB+fj%Tw<3tTp~D#j~WnBa?QVd0lK` zX3)y^cu!yais*m6ZJ9e}XUy2P_5JdRSCV;yyCZAcR=z*Eq^+cS!bi6bAO5xf7AjZO zAL2dm$zY3PHOH<6(hp~S;<=*ERv@f{Y{Kuz21_b zy2kBB&B#vX$(o^jLa19wd3&O@h*~uFS|zuq zJm2C1CEhjd&VJx`A&nKk`ZB^A3+j?jH z#UrlH$Gf*}kH2)@Y}(?_zD4;wd=kpb)ShkZvpX%!#^xv!<;!v^}!@ z)-+gcTh&FOtAecLsI=}rVsA~ zY!2CcZR2*#)%kkj(j;G<$wfwfvo49YEHhilZnLk@Gdz6Daj%zoR|*zIndC+*Z=2>7 zSbF8E@Zx2L^DZvd>y*0cD|dOZ@UMU=MVl5+;c<`EK6Po~iw)1R-W-&@y0~+Rqp^F* zp#pc!&hEY}cgY!Per~?8@_m!!MJ5F**Ux6MOZ^yl_-$WVX)f2w4|Xlvyl+-Gl=Qa# zm$WN>T=vY}H1l*}=E?_?o}KtL>41^(x(#!dUkf%nYx^s4mb9G<*PXlj-%i{2)^Hl< z*%eC#J_uGAamcszU%DY4>a;rA*lp6M!wfYxEdCpNR$LTr&P<%4c{xfx^r5iMt!1r+ zxAcYTzo#__UH3m|%=7(ni}l^K-y2)r9o>9B$Y*KAGuC|uHthYa4RktuRBX3O}0L7SrGA8X%0`IdAw4kX6AB1!{XYffkC-?;j!hKsor ze6lOD3YTB@aDt!TB=MM}dnZqOE^IgFJgi+X=`8=ENUj zfB3xP>Zcz`^PaW1zV&D1`-hI&cbCgwot*e%n@3Uoe5NxS=54TaV9b=*r_Awh0tZj9 z+lN@k5662J6l~m*dSX-TG?qI5j!(-|%nrXaRlUo1_&e*_`IE)ZGt3nG!rt^q|Kv%x zpHkb7dj&Nei2fhY@!|TBgUc={>Kbl4yy^3Ao*KpY`(aZ0W$_bdb$>im|3UeOwc7Ff zmjlk86l|04K2)!AyyWdk$L^%kQ!`c`n%}YSud%P)oEE2$MN?iaUo`!{*It_>$s*f- zJ{SI2b7$(LyuGNNwj+GW+PxLY%if==S!=QTx8)!4$q)8x`k#Kww(+5GTh@oojGw%> z#cAB-5;9@*Yv!7neeBqT6``)Vr4mi`0!jawp4`1GxO|Cg<>M6vjA5^oR(1)lYl)X= zj&MG0&!b!t&KCMntau8eZQJae4u@@L|1{e#TE>vQFpOii*0pb*Pmbw#n*!IeqEIxGb$r|NqPPo_!#G?C6e`(xjJ9b6mw7E~YrP%`o`QQ|yx= zndqHZcKProwq=J;waqI1>HKVyMcYQ!^=Vw0r&Uk4CT!Vu>bp_T+@>PSr5E;ue6jAi zyU50`Q%s-#u~*=xuFTHXCMVsyU$uLy&m37@$oqI-{WQ<{kL8YKyS^-avRBghWVczz zqTVUYT}{4=9RiS#*=;vg$OyJB zesVc8`uzHa^)W9lr99^7GYs<-nwWdH{i29bG>5d_XBMv~v7c}2ZK!WOwCM?3M#{*CB8J*ztD&XdCW621Q{<++l=Z#jxnFH^h-rVuzNZ^7z zz3`Bq8}7YJ)iotlv~}WGHGjVuya-0y(T&H;_I(d(_0SR%2~B)wwW^>mAJ4dcUGr!AvJ6$}qPS=x2=(cCRuQ^XpJcBSM;7rWnl zR$*hfDo`iv=ebJ^_8sp`eeXW2obm3%hRU0ZEgGI{Muf5m90TO>o38R3Og~INHP^jp(t2@p{iFKpnI3Z!b|*0`*l^T-Kl`5DukL0l zo_{aG^>gpF-N6Zu%DHq)@)L^L>hnI`I{WR_?7iPa4C|MlHzn>{ny?;m<6*gDtY(q{n$YlY?6?6!9uzIuE=Dy#3j=dsS3h4-s| z-Mw&e!&8|%D;(;NTfT6%@KoWLTe4Q!l;PX)io>#E$v+iZ8DBo@UBDF0hZC&1&Rx$ab=xnnZmbd&z^f z2CnDxPuuU8y{Gt3o3p}z@%@ta_6Lbf36Jy_<{7jd{QQAq@^jmxd-tAx{4K7kN<{AS zEZqg_VbNDVR1`Kl$E-;^RBM0NK0t-*knjgb{wIEm64N^OvB+EV`^#2H&ddApMDmBv zbLkInBrE3qo7<>Ar%`{NPS82s7|Xzm^=9kmXv}H4yvL3!y(8!&Oa07K=MGt(zhS+i zWoxkY^!d&DngKm)#S>On=7`2Etv~U9uUpKF?|c2OiTsUtqPcjM&4<_L#aAYa|FMdl z*pOS(!`URmGSM6N=ZhcqPx@i8S?h-`fBLMSnm^Ju>Xu#n z8vWsRz3P(mhu^)Py8I}sYY?6E@1Q5=%km{l>Q$8guAB13KV`}N$)|p$8%6HdSN+Q^ z`I3Lhl6qC;zY9aI?Vot^m-3I>LBaD{>ox9AsXO=Rc+s5tRU*&TFU9@qUNhZ(>bFn# zQ}+IuIpvFe$`bqb|5GOX>p!DjulV|NrjBIq^jF1OTb^pN)N^{fSe{Xq;B_evibJFO!Bn!>GYkG zyYDscU22&8F!GJIb=n7uqseUVo*5?h*D$1w;Aig8FaM-|mg$ z@pkfRD_)Q!V>2UsXTLtD=hKUuE81l|mVLVX)4+EA>OX!vSG`*o5<2S&qp%UX%(O{z z(dG&l_&DXm3ZCZ?KP|W| z&#Bx~KD={%&77k$&+BTsd7fANv`EamS}%3ROK9rjO+UZ2%y}BJR403>&hiwU`)&F9 zi8~*d*hSc#j-2BEB~pY-yHjboqh$ZEctqYf#2IBHqu>g+VV~PA+t`Ic?REf zPtm!reEsg?sju?3g_QSum9+Pt-2D8w_St!}m)BpJ;v+m}WQmOeXN^Z?+mY=er z#_8CndgmVxZM+5F{*mqWe?0l=<~iph&m8W57O7P^&3~Ul;VIT1hMgtHQ!drUyvy_t zf0fz2WZt(eITuSr>ztgb=KJjOKee=aSGFThoTuDVH^peB{%q=b`uu6&=XQjUPHeLOD zr>iUjkpbmlRCkhD8f_A4}G zS)aT;A7g91xoFU;nuxRhnobeDbsvR_L`}k)rFLqG1vZs#mEh7eP5iRa`IEr4Mg6ir zS*AuR9@Rf*qU81WP*i;mhi0#D#99Adr&DjzzH|pqoM4o$_v?nCr^ifl`Pbfk0Zuy@ zMBVwdx}~OM)!h*Z6w_aOG{YnEQj1;L3Zal`u2UPzHwgtsty_2Wnm`!q)NNr)mpv$P zUHh&<^M%WM<^5_ga)G-vBm-95Kk#d><-HfL!;-Z*l2ZdBudZS_vRr&!{i=2E>^?sG zs2R~5D!lkwPK$t$jHubirc(kte%4{{!JAxtaRDS4A z{;sW9-<`W-^5(++RefDr%&+&Xdh7YmFK2R5hX3qKwr+P$>{}V8I;Z+Ib{A ziNd--=16&;t*NUwerWDitG_m%H|_AmRnu}BUW7L7XqD-=ZGW+|?bc+j?=Rbxuj<~s zl{4Ygs}(+bqMc?4e!7-p`^+vr^N^xePRq)SZJfpPZ=DI-w0Wk_+4fC!S@z3AXNG>+ z#j$nf@rGx~7r$5ghC0{ZWEHG0OWc8>OXr&%z^)tm@sEb^KAj#H>}DWKYko@lpK2b#(qxk$yfW z`pm=&FK}yGY~1(Qy}rr**vC6}eHMC3?4MKpzH;~Z%6FE#>;M10EzjWhK+aL$G^#8z zZsV#+1~Hqm&aTq&{5>&rTIKSbFyBKD>QB9T+IwkfbnEPF>1^@!LP1B{pDABnG3%@D z;wQJlYO@c(XYYhuUnV|x zQ?BXVEx(s&>Yv$Bblda_@4m7$&+7|>zgaJ1O0QValkK3(^MWUL(#}Hp2)@KUKb9%|+;rgEm(IOU-aqmXm6j>Ey+!wEMtfMs z47HA4Uf$yzf~(^u-Zp89kTA4Yy8I`ZL{WUQKxP14}bAI_wac^ z+|%^3Wpc%DdyoHImU(*D?B^*z!!{@FGWzVgEAQHqpI@f5aku=q60=K9_V}Goq3=JP z4Su=&CTrf3?o|_QY^HP6&$|5~zdO-Y^Lb&bgK3@H)V`hXQXW=BTdiGndRpf7JD=1R zI^4MKxMoTG(UP56R(>q2yFMiK->jaml=o^!BY&lcjnJD}sdpxAZPO0lc6!sxsNO0T zRk?<{%H>z~#vSV7tv+pVH|lVv-Gpr>r+jZmY?Dq~nq#%@es1^P_ZzodU>B?3?sf9k zs@Zv`pCy@|Kf<-_&;R!w33CmuOg3(^wm4(b@AM$}PU_4c8s%m!|qS+42NuLoQ!clSI_XZkq~rtB2wiF(0JPp8eO^ zoV(}i9R5Sx+|`xQ7Ke(?lpj)D!kAw!Q6HS6ZhClb$bW-f0_)4u*Dvo|cWznQtr@(3 zIy!GQ?9V^E!|rvy^Zc!aMPJL$tlxj+WsG$C?Fb*;jWdF0e~*v}pPed}v-ga*bohC8 zewO%!)+d)T#D99JdHK)kW_mKIXrgeG!@^hZ+^Ax81W<7kqJo4MiszXLsuA5$b zyX)+x6F*$0zh1xNYw+}JZuyNN2G=AwDpff2yw`63$Z1_Kx1>0+_sHhCb7ftQ9LS#U z7t7Kl@=3~fxj^e*{~U(Hju|JFJq2ZZCa>#mlwb`#{90sr{erCjD?DB(y(v#MGT2gY zBWy=K~`-C>D|Ca?%sk!nM3Pq*x)xWhlT=?qe z@4ldU+Qt_9*R}dTXrF7CFt2Ub+)GhULew3v`^Rz5|CTIN{WVj!q;2DzrRVk+x%Bk^ zXGbZ)HY*!Xgv>;2H`8JVFS~eR`;7_Axa;s)i23cV-;*x~Yk}xVAub?lvwKK33+J0% zzpYM8K6a*T^6rSx`rtDEv);O1I-b6P9;-q=`099{eH`@d?D^miT4w_djKU3!wlOIR zv!-8vAi%23%D$IY*Yvx$@}GoJ&Fr zYBt6tm6a)lCk1+@MI{w+1_*YnkDfClnjvHfci1^rh5&CyCJ|;X1_m|;1_qErr$w58 z)|E^?8)*;n!DRj@BQWg}WdWw^qrAcN*(fK(!V>Z5a9+?141B4;o^;v x!EUlcycW|}5YrV&F9!oW2{AA*)H5(Jc)|68!iqCu@`ezn$?^$OY|kS=G5}SIcqsq? diff --git a/deploy/root/images/body-background.png b/deploy/root/images/body-background.png new file mode 100644 index 0000000000000000000000000000000000000000..ece11eb20ac9dea8dbda6dfebbc134c78fd3b096 GIT binary patch literal 2381 zcmeAS@N?(olHy`uVBq!ia0y~yVBlh4U{>H@VqjpH+MlA%z`(#+;1OBOz`!jG!i)^F z=14FwaQydlaSW-r^)~wUrpFc>E+YT`AD=ysJ+foZ#@b<6FXn9iab`g;Wx{8u+fS4vxC8XzVC{AoxYd|Uc4~zW%JGN9p}}*9o~}v zY0gB0aEtKRah$i;&%D#*t(4KKlilHdLAw7{^!e_|JSXwA11cVclfs2Ct{re z|Bw9i{$nKJ{%(k$N zy!#^F8&sXlOR-%Labf3^Y)5JLW4BZ@j{ki#=^xj-Z^yq#Iqq+Mv?jG<(x+=xZQ9~@ z{MCCWCs|K!N}E^r^1-E_l?5rRhL&#_1(w`xSW>+vTAw-Qo^po71)UffHc{mh@Bhc# zFa4V?t@UYYzcMq2;!%h5yOeet%YQqN?)XV$fw7Es9@7NNXAcXDj~F~xK6=k3(Mirf z_WjP;Zzb>CIJfZEgg8ZoGYXmEQP)El7B%vEuz0iGsM=u~QN*xlVgmnx30qFRduUwn z^3r9VkfUms7Jf)u-xMU;9eDEhkMf0<-R1j|&awq_`gT2E zp(fk)T(T>E!=9yGE*uXQa?3citIW6-Ei8ECv&~YQ^B=e`Y?0d#7qDIsIQ~$3M->e@@)lIb}~ny5{_?GT*rL z9#4+G;Jjwii+}$bcoW2ShkRN0RQCz%lPN1Z{xKfZxtx>!Y;g`>{&N}Ab!Rt-JPLMX zTkWab*YQ|zO7g5{ldUWbo*WGhRx)#P3%w9{xi<@bnAp$u6MyjOy_;KSIWJ^0FuJnh>y zbn0Qf17SX!+V(jb3oow8H_3W)E5YK?taZC&dzSpRvRpI8#Yg0f(S*tO`5Zq<-a4Ic zqdR@CkIqe>3syGnO+CxzBz0#WlZHlRt4sX=d0}Mc2%(?hpKRqiXiHgHd4$nkgoarb{SxvQ-{z>!{dwamyj2 zzsuJoOidH5T{KPllO*dp%jaPVO;ct0Z(ED9F$qreOD^N74$w95=)8LGys$!IphM>B zaP7W@&aY=wgzTH9ZhY<8ri6uCcRuJ)v^b$yp*;B@!~G(S>CmG5#w%Hmv$QY3H=3^>-Yv9bYihGmd9t z*9At~qpNzOEN(LWv=HM968UmhLdN_-!M#({rqBLazpuqO;-+zEUcxDk{A;tF4bSyO zzji78e#&6Svl8J@#l_0)v48YuaqS6sR9U=N{no5R_KDup@`|2%Y&hHeQsIro z6JO2t7ak3m7g>yk5=jsefnx zrfJfr7T;+-9&b8v%7$G}X9&r~^>f{Q;Snw5$jWnhzOCR^(b=JHPJzj%&NS~jCll4n zve4j_gYn(#-b%~1i6(Q-itV{@{HlR(Z|_3~lVx@@xu=OYJ3QDda)kHUL67>U*%3)W zUy4i`wXX7>I&sfSDeaqgr}UMpI!P1G_-p4s9FpZCO<*tnBWB`LxYWtUEtt)<&lERj1NruXg*gE_MF%bWZe7i}h=sL>-(y^XPIH6A}Ga@4}v+ zNG;#4CVnTVoTVtBv}s@Tdl`whjO{}1783%l@}JJH%n~@?lQcxBaoYdduo3EV-(`aL3)$B9kP`CoZjVsPIV?OxA@oZlW3ubNyqX*xfO z{r#=W{IN=&U&`x7b-a`ofY8oWZH z#xm!moO;HWYm2;9xH&HAJm0YS8r$k9!O&fGS^2+zNA7->y^nPCZ{|<_<()3l>{EAp RGB7YOc)I$ztaD0e0sw=8iI@NY literal 0 HcmV?d00001 diff --git a/deploy/root/images/header-background.png b/deploy/root/images/header-background.png new file mode 100644 index 0000000000000000000000000000000000000000..93e4a49c3795da40ddee63af280a4a0fadffbb45 GIT binary patch literal 20847 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 Q0|Nttr>mdKI;Vst0K + + + + + Atmosphere REST Chat + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    Please input your name:
    +
    + +
    + +
    + +
    +
    +
    +
    + + + diff --git a/deploy/root/javascripts/application.js b/deploy/root/javascripts/application.js new file mode 100644 index 0000000000..9484b3b7b3 --- /dev/null +++ b/deploy/root/javascripts/application.js @@ -0,0 +1,93 @@ +var count = 0; +var app = { + url: 'http://localhost:9998/chat', + initialize: function() { + $('login-name').focus(); + app.listen(); + }, + listen: function() { + $('comet-frame').src = app.url + '?' + count; + count ++; + }, + login: function() { + var name = $F('login-name'); + if(! name.length > 0) { + $('system-message').style.color = 'red'; + $('login-name').focus(); + return; + } + $('system-message').style.color = '#2d2b3d'; + $('system-message').innerHTML = name + ':'; + + $('login-button').disabled = true; + $('login-form').style.display = 'none'; + $('message-form').style.display = ''; + + var query = + 'action=login' + + '&name=' + encodeURI($F('login-name')); + new Ajax.Request(app.url, { + postBody: query, + onSuccess: function() { + $('message').focus(); + } + }); + }, + post: function() { + var message = $F('message'); + if(!message > 0) { + return; + } + $('message').disabled = true; + $('post-button').disabled = true; + + var query = + 'action=post' + + '&name=' + encodeURI($F('login-name')) + + '&message=' + encodeURI(message); + new Ajax.Request(app.url, { + postBody: query, + method : 'post', + //requestHeaders: ['Content-Type', + // 'application/x-www-form-urlencoded; charset=UTF-8'], + onComplete: function() { + $('message').disabled = false; + $('post-button').disabled = false; + $('message').focus(); + $('message').value = ''; + } + }); + }, + update: function(data) { + var p = document.createElement('p'); + p.innerHTML = data.name + ':
    ' + data.message; + + $('display').appendChild(p); + + new Fx.Scroll('display').down(); + } +}; +var rules = { + '#login-name': function(elem) { + Event.observe(elem, 'keydown', function(e) { + if(e.keyCode == 13) { + $('login-button').focus(); + } + }); + }, + '#login-button': function(elem) { + elem.onclick = app.login; + }, + '#message': function(elem) { + Event.observe(elem, 'keydown', function(e) { + if(e.shiftKey && e.keyCode == 13) { + $('post-button').focus(); + } + }); + }, + '#post-button': function(elem) { + elem.onclick = app.post; + } +}; +Behaviour.addLoadEvent(app.initialize); +Behaviour.register(rules); diff --git a/deploy/root/javascripts/behaviour.js b/deploy/root/javascripts/behaviour.js new file mode 100644 index 0000000000..fdde861bba --- /dev/null +++ b/deploy/root/javascripts/behaviour.js @@ -0,0 +1,254 @@ +/* + Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work + of Simon Willison (see comments by Simon below). + + Description: + + Uses css selectors to apply javascript behaviours to enable + unobtrusive javascript in html documents. + + Usage: + + var myrules = { + 'b.someclass' : function(element){ + element.onclick = function(){ + alert(this.innerHTML); + } + }, + '#someid u' : function(element){ + element.onmouseover = function(){ + this.innerHTML = "BLAH!"; + } + } + }; + + Behaviour.register(myrules); + + // Call Behaviour.apply() to re-apply the rules (if you + // update the dom, etc). + + License: + + This file is entirely BSD licensed. + + More information: + + http://ripcord.co.nz/behaviour/ + +*/ + +var Behaviour = { + list : new Array, + + register : function(sheet){ + Behaviour.list.push(sheet); + }, + + start : function(){ + Behaviour.addLoadEvent(function(){ + Behaviour.apply(); + }); + }, + + apply : function(){ + for (h=0;sheet=Behaviour.list[h];h++){ + for (selector in sheet){ + list = document.getElementsBySelector(selector); + + if (!list){ + continue; + } + + for (i=0;element=list[i];i++){ + sheet[selector](element); + } + } + } + }, + + addLoadEvent : function(func){ + var oldonload = window.onload; + + if (typeof window.onload != 'function') { + window.onload = func; + } else { + window.onload = function() { + oldonload(); + func(); + } + } + } +} + +Behaviour.start(); + +/* + The following code is Copyright (C) Simon Willison 2004. + + document.getElementsBySelector(selector) + - returns an array of element objects from the current document + matching the CSS selector. Selectors can contain element names, + class names and ids and can be nested. For example: + + elements = document.getElementsBySelect('div#main p a.external') + + Will return an array of all 'a' elements with 'external' in their + class attribute that are contained inside 'p' elements that are + contained inside the 'div' element which has id="main" + + New in version 0.4: Support for CSS2 and CSS3 attribute selectors: + See http://www.w3.org/TR/css3-selectors/#attribute-selectors + + Version 0.4 - Simon Willison, March 25th 2003 + -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows + -- Opera 7 fails +*/ + +function getAllChildren(e) { + // Returns all children of element. Workaround required for IE5/Windows. Ugh. + return e.all ? e.all : e.getElementsByTagName('*'); +} + +document.getElementsBySelector = function(selector) { + // Attempt to fail gracefully in lesser browsers + if (!document.getElementsByTagName) { + return new Array(); + } + // Split selector in to tokens + var tokens = selector.split(' '); + var currentContext = new Array(document); + for (var i = 0; i < tokens.length; i++) { + token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');; + if (token.indexOf('#') > -1) { + // Token is an ID selector + var bits = token.split('#'); + var tagName = bits[0]; + var id = bits[1]; + var element = document.getElementById(id); + if (tagName && element.nodeName.toLowerCase() != tagName) { + // tag with that ID not found, return false + return new Array(); + } + // Set currentContext to contain just this element + currentContext = new Array(element); + continue; // Skip to next token + } + if (token.indexOf('.') > -1) { + // Token contains a class selector + var bits = token.split('.'); + var tagName = bits[0]; + var className = bits[1]; + if (!tagName) { + tagName = '*'; + } + // Get elements matching tag, filter them for class selector + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements; + if (tagName == '*') { + elements = getAllChildren(currentContext[h]); + } else { + elements = currentContext[h].getElementsByTagName(tagName); + } + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = new Array; + var currentContextIndex = 0; + for (var k = 0; k < found.length; k++) { + if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) { + currentContext[currentContextIndex++] = found[k]; + } + } + continue; // Skip to next token + } + // Code to deal with attribute selectors + if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { + var tagName = RegExp.$1; + var attrName = RegExp.$2; + var attrOperator = RegExp.$3; + var attrValue = RegExp.$4; + if (!tagName) { + tagName = '*'; + } + // Grab all of the tagName elements within current context + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements; + if (tagName == '*') { + elements = getAllChildren(currentContext[h]); + } else { + elements = currentContext[h].getElementsByTagName(tagName); + } + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = new Array; + var currentContextIndex = 0; + var checkFunction; // This function will be used to filter the elements + switch (attrOperator) { + case '=': // Equality + checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); }; + break; + case '~': // Match one of space seperated words + checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); }; + break; + case '|': // Match start with value followed by optional hyphen + checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); }; + break; + case '^': // Match starts with value + checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); }; + break; + case '$': // Match ends with value - fails with "Warning" in Opera 7 + checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); }; + break; + case '*': // Match ends with value + checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); }; + break; + default : + // Just test for existence of attribute + checkFunction = function(e) { return e.getAttribute(attrName); }; + } + currentContext = new Array; + var currentContextIndex = 0; + for (var k = 0; k < found.length; k++) { + if (checkFunction(found[k])) { + currentContext[currentContextIndex++] = found[k]; + } + } + // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue); + continue; // Skip to next token + } + + if (!currentContext[0]){ + return; + } + + // If we get here, token is JUST an element (not a class or ID selector) + tagName = token; + var found = new Array; + var foundCount = 0; + for (var h = 0; h < currentContext.length; h++) { + var elements = currentContext[h].getElementsByTagName(tagName); + for (var j = 0; j < elements.length; j++) { + found[foundCount++] = elements[j]; + } + } + currentContext = found; + } + return currentContext; +} + +/* That revolting regular expression explained +/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/ + \---/ \---/\-------------/ \-------/ + | | | | + | | | The value + | | ~,|,^,$,* or = + | Attribute + Tag +*/ diff --git a/deploy/root/javascripts/moo.fx.js b/deploy/root/javascripts/moo.fx.js new file mode 100644 index 0000000000..95c01f819a --- /dev/null +++ b/deploy/root/javascripts/moo.fx.js @@ -0,0 +1,136 @@ +//(c) 2006 Valerio Proietti (http://mad4milk.net). MIT-style license. +//moo.fx.js - depends on prototype.js OR prototype.lite.js +//version 2.0 + +var Fx = fx = {}; + +Fx.Base = function(){}; +Fx.Base.prototype = { + + setOptions: function(options){ + this.options = Object.extend({ + onStart: function(){}, + onComplete: function(){}, + transition: Fx.Transitions.sineInOut, + duration: 500, + unit: 'px', + wait: true, + fps: 50 + }, options || {}); + }, + + step: function(){ + var time = new Date().getTime(); + if (time < this.time + this.options.duration){ + this.cTime = time - this.time; + this.setNow(); + } else { + setTimeout(this.options.onComplete.bind(this, this.element), 10); + this.clearTimer(); + this.now = this.to; + } + this.increase(); + }, + + setNow: function(){ + this.now = this.compute(this.from, this.to); + }, + + compute: function(from, to){ + var change = to - from; + return this.options.transition(this.cTime, from, change, this.options.duration); + }, + + clearTimer: function(){ + clearInterval(this.timer); + this.timer = null; + return this; + }, + + _start: function(from, to){ + if (!this.options.wait) this.clearTimer(); + if (this.timer) return; + setTimeout(this.options.onStart.bind(this, this.element), 10); + this.from = from; + this.to = to; + this.time = new Date().getTime(); + this.timer = setInterval(this.step.bind(this), Math.round(1000/this.options.fps)); + return this; + }, + + custom: function(from, to){ + return this._start(from, to); + }, + + set: function(to){ + this.now = to; + this.increase(); + return this; + }, + + hide: function(){ + return this.set(0); + }, + + setStyle: function(e, p, v){ + if (p == 'opacity'){ + if (v == 0 && e.style.visibility != "hidden") e.style.visibility = "hidden"; + else if (e.style.visibility != "visible") e.style.visibility = "visible"; + if (window.ActiveXObject) e.style.filter = "alpha(opacity=" + v*100 + ")"; + e.style.opacity = v; + } else e.style[p] = v+this.options.unit; + } + +}; + +Fx.Style = Class.create(); +Fx.Style.prototype = Object.extend(new Fx.Base(), { + + initialize: function(el, property, options){ + this.element = $(el); + this.setOptions(options); + this.property = property.camelize(); + }, + + increase: function(){ + this.setStyle(this.element, this.property, this.now); + } + +}); + +Fx.Styles = Class.create(); +Fx.Styles.prototype = Object.extend(new Fx.Base(), { + + initialize: function(el, options){ + this.element = $(el); + this.setOptions(options); + this.now = {}; + }, + + setNow: function(){ + for (p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]); + }, + + custom: function(obj){ + if (this.timer && this.options.wait) return; + var from = {}; + var to = {}; + for (p in obj){ + from[p] = obj[p][0]; + to[p] = obj[p][1]; + } + return this._start(from, to); + }, + + increase: function(){ + for (var p in this.now) this.setStyle(this.element, p, this.now[p]); + } + +}); + +//Transitions (c) 2003 Robert Penner (http://www.robertpenner.com/easing/), BSD License. + +Fx.Transitions = { + linear: function(t, b, c, d) { return c*t/d + b; }, + sineInOut: function(t, b, c, d) { return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; } +}; \ No newline at end of file diff --git a/deploy/root/javascripts/moo.fx.pack.js b/deploy/root/javascripts/moo.fx.pack.js new file mode 100644 index 0000000000..a06656fb44 --- /dev/null +++ b/deploy/root/javascripts/moo.fx.pack.js @@ -0,0 +1,83 @@ +//by Valerio Proietti (http://mad4milk.net). MIT-style license. +//moo.fx.pack.js - depends on prototype.js or prototype.lite.js + moo.fx.js +//version 2.0 + +Fx.Scroll = Class.create(); +Fx.Scroll.prototype = Object.extend(new Fx.Base(), { + + initialize: function(el, options) { + this.element = $(el); + this.setOptions(options); + this.element.style.overflow = 'hidden'; + }, + + down: function(){ + return this.custom(this.element.scrollTop, this.element.scrollHeight-this.element.offsetHeight); + }, + + up: function(){ + return this.custom(this.element.scrollTop, 0); + }, + + increase: function(){ + this.element.scrollTop = this.now; + } + +}); + +//fx.Color, originally by Tom Jensen (http://neuemusic.com) MIT-style LICENSE. + +Fx.Color = Class.create(); +Fx.Color.prototype = Object.extend(new Fx.Base(), { + + initialize: function(el, property, options){ + this.element = $(el); + this.setOptions(options); + this.property = property.camelize(); + this.now = []; + }, + + custom: function(from, to){ + return this._start(from.hexToRgb(true), to.hexToRgb(true)); + }, + + setNow: function(){ + [0,1,2].each(function(i){ + this.now[i] = Math.round(this.compute(this.from[i], this.to[i])); + }.bind(this)); + }, + + increase: function(){ + this.element.style[this.property] = "rgb("+this.now[0]+","+this.now[1]+","+this.now[2]+")"; + } + +}); + +Object.extend(String.prototype, { + + rgbToHex: function(array){ + var rgb = this.match(new RegExp('([\\d]{1,3})', 'g')); + if (rgb[3] == 0) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (rgb[i]-0).toString(16); + hex.push(bit.length == 1 ? '0'+bit : bit); + } + var hexText = '#'+hex.join(''); + if (array) return hex; + else return hexText; + }, + + hexToRgb: function(array){ + var hex = this.match(new RegExp('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$')); + var rgb = []; + for (var i = 1; i < hex.length; i++){ + if (hex[i].length == 1) hex[i] += hex[i]; + rgb.push(parseInt(hex[i], 16)); + } + var rgbText = 'rgb('+rgb.join(',')+')'; + if (array) return rgb; + else return rgbText; + } + +}); \ No newline at end of file diff --git a/deploy/root/javascripts/prototype.js b/deploy/root/javascripts/prototype.js new file mode 100644 index 0000000000..0e85338bab --- /dev/null +++ b/deploy/root/javascripts/prototype.js @@ -0,0 +1,1781 @@ +/* Prototype JavaScript framework, version 1.4.0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.4.0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} +Object.extend(String.prototype, { + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(eval); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; + } +}); + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value >= (result || value)) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value <= (result || value)) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + iterator(value = collections.pluck(index)); + return value; + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + shift: function() { + var result = this[0]; + for (var i = 0; i < this.length - 1; i++) + this[i] = this[i + 1]; + this.length--; + return result; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) {} + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version]; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', + 'application/x-www-form-urlencoded'); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval(this.header('X-JSON')); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(child); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) { + var Element = new Object(); +} + +Object.extend(Element, { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +}); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + if (this.element.tagName.toLowerCase() == 'tbody') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
    '; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + element = $(element); + element.focus(); + if (element.select) + element.select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + findFirstElement: function(form) { + return Form.getElements(form).find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + Field.activate(Form.findFirstElement(form)); + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) { + var key = encodeURIComponent(parameter[0]); + if (key.length == 0) return; + + if (parameter[1].constructor != Array) + parameter[1] = [parameter[1]]; + + return parameter[1].map(function(value) { + return key + '=' + encodeURIComponent(value); + }).join('&'); + } + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value; + if (!value && !('value' in opt)) + value = opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = new Array(); + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) { + var optValue = opt.value; + if (!optValue && !('value' in opt)) + optValue = opt.text; + value.push(optValue); + } + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} \ No newline at end of file diff --git a/deploy/root/stylesheets/default.css b/deploy/root/stylesheets/default.css new file mode 100644 index 0000000000..716fc7ab59 --- /dev/null +++ b/deploy/root/stylesheets/default.css @@ -0,0 +1,54 @@ +body { + background-image: url(../images/body-background.png); + background-repeat: repeat-x; + background-color: #5c8098; +} +html, body, h1, h2 { + margin: 0px; + padding: 0px; +} +body, textarea, input { + font-size: 12px; + font-family: Verdana, Helvetica, Arial, sans-serif; + color: #2d2b3d; +} +#container { + text-align:center; +} +#container-inner { + margin-left: auto; + margin-right: auto; + text-align: justify; + width: 820px; +} +#header { + width: 820px; + height: 100px; + background-image: url(../images/header-background.png); + background-repeat: no-repeat; +} +#header h1 { + display: none; +} +#main { + height: 610px; + background-image: url(../images/main-background.png); + background-repeat: no-repeat; + text-align: left; + width: 740px; + padding: 30px 40px 20px 40px; +} +#display { + border: 1px solid #5c8098; + width: 740px; + height: 400px; + margin-bottom: 10px; + overflow-y: scroll; +} +#login-name { + width: 200px; +} +#message { + width: 740px; + height: 50px; +} diff --git a/kernel/src/main/scala/Kernel.scala b/kernel/src/main/scala/Kernel.scala index 0c8a75cf0e..eff1faae31 100644 --- a/kernel/src/main/scala/Kernel.scala +++ b/kernel/src/main/scala/Kernel.scala @@ -128,20 +128,21 @@ object Kernel extends Logging { val adapter = new ServletAdapter() - adapter.addInitParameter("com.sun.jersey.spi.container.ResourceFilters","org.atmosphere.core.AtmosphereFilter") - adapter.addInitParameter("com.sun.jersey.config.feature.Redirect", "true") - adapter.addInitParameter("com.sun.jersey.config.feature.ImplicitViewables", "true") + adapter.setHandleStaticResources(true) adapter.setServletInstance(new AkkaCometServlet) adapter.setContextPath(uri.getPath) adapter.setRootFolder(System.getenv("AKKA_HOME") + "/deploy/root") log.info("REST service root path: [" + adapter.getRootFolder + "] and context path [" + adapter.getContextPath + "] ") - + val ah = new com.sun.grizzly.arp.DefaultAsyncHandler + ah.addAsyncFilter(new com.sun.grizzly.comet.CometAsyncFilter) jerseySelectorThread = new SelectorThread jerseySelectorThread.setAlgorithmClassName(classOf[StaticStreamAlgorithm].getName) jerseySelectorThread.setPort(REST_PORT) jerseySelectorThread.setAdapter(adapter) + jerseySelectorThread.setEnableAsyncExecution(true) + jerseySelectorThread.setAsyncHandler(ah) jerseySelectorThread.listen log.info("REST service started successfully. Listening to port [" + REST_PORT + "]") diff --git a/kernel/src/main/scala/jersey/ActorComponentProviderFactory.scala b/kernel/src/main/scala/jersey/ActorComponentProviderFactory.scala index d2935f1a16..f763cb37ba 100644 --- a/kernel/src/main/scala/jersey/ActorComponentProviderFactory.scala +++ b/kernel/src/main/scala/jersey/ActorComponentProviderFactory.scala @@ -4,17 +4,20 @@ package se.scalablesolutions.akka.kernel.jersey -import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory -import com.sun.jersey.core.spi.component.ComponentContext +import kernel.Kernel +import javax.ws.rs.core.Context + +import com.sun.jersey.core.spi.component.ioc.{IoCComponentProvider,IoCComponentProviderFactory} +import com.sun.jersey.core.spi.component.{ComponentContext} import config.Configurator + class ActorComponentProviderFactory(val configurators: List[Configurator]) - extends IoCComponentProviderFactory { +extends IoCComponentProviderFactory { + override def getComponentProvider(clazz: Class[_]): IoCComponentProvider = getComponentProvider(null, clazz) - override def getComponentProvider(clazz: Class[_]): ActorComponentProvider = getComponentProvider(null, clazz) - - override def getComponentProvider(context: ComponentContext, clazz: Class[_]): ActorComponentProvider = { - new ActorComponentProvider(clazz, configurators) + override def getComponentProvider(context: ComponentContext, clazz: Class[_]): IoCComponentProvider = { + configurators.find(_.isDefined(clazz)).map(_ => new ActorComponentProvider(clazz, configurators)).getOrElse(null) } } \ No newline at end of file diff --git a/kernel/src/main/scala/jersey/AkkaServlet.scala b/kernel/src/main/scala/jersey/AkkaServlet.scala index 7ad412e254..0c23c955fe 100644 --- a/kernel/src/main/scala/jersey/AkkaServlet.scala +++ b/kernel/src/main/scala/jersey/AkkaServlet.scala @@ -8,14 +8,16 @@ import kernel.Kernel import config.ConfiguratorRepository import util.Logging -import com.sun.jersey.api.core.{DefaultResourceConfig, ResourceConfig} +import com.sun.jersey.api.core.{DefaultResourceConfig, ResourceConfig,ClasspathResourceConfig} import com.sun.jersey.spi.container.servlet.ServletContainer import com.sun.jersey.spi.container.WebApplication +import com.sun.jersey.server.impl.component.{IoCResourceFactory} + import javax.servlet.{ServletConfig} import javax.servlet.http.{HttpServletRequest,HttpServletResponse} -import org.atmosphere.cpr.{AtmosphereServlet,AtmosphereServletProcessor,AtmosphereEvent} +import org.atmosphere.cpr.{AtmosphereServlet,AtmosphereServletProcessor,AtmosphereEvent,DefaultBroadcaster} import org.atmosphere.cpr.AtmosphereServlet.{AtmosphereHandlerWrapper} import org.atmosphere.container.GrizzlyCometSupport import org.atmosphere.handler.ReflectorServletProcessor @@ -31,45 +33,50 @@ import scala.collection.jcl.Conversions._ class AkkaServlet extends ServletContainer with AtmosphereServletProcessor with Logging { override def initiate(rc: ResourceConfig, wa: WebApplication) = { - // super.initiate(rc, wa) - // log.info("Initializing akka servlet") + Kernel.boot // will boot if not already booted by 'main' val configurators = ConfiguratorRepository.getConfiguratorsFor(getServletContext) - val set = new HashSet[Class[_]] - for { - conf <- configurators - clazz <- conf.getComponentInterfaces - } set.add(clazz) + + rc.getClasses.addAll(configurators.flatMap(_.getComponentInterfaces)) + rc.getProperties.put("com.sun.jersey.spi.container.ResourceFilters","org.atmosphere.core.AtmosphereFilter") + //rc.getFeatures.put("com.sun.jersey.config.feature.Redirect", true) + //rc.getFeatures.put("com.sun.jersey.config.feature.ImplicitViewables",true) - wa.initiate( - new DefaultResourceConfig(set), - new ActorComponentProviderFactory(configurators)) + wa.initiate(rc,new ActorComponentProviderFactory(configurators)) } override def onMessage(event : AtmosphereEvent[HttpServletRequest,HttpServletResponse]) : AtmosphereEvent[_,_] = { - var isUsingStream = false - try { - event.getResponse.getWriter - } catch { - case e: IllegalStateException => isUsingStream = true - } + //log.info("onMessage: " + event.getMessage.toString) - if (isUsingStream){ - event.getResponse.getOutputStream.write(event.getMessage.toString.getBytes); - event.getResponse.getOutputStream.flush - } else { - event.getResponse.getWriter.write(event.getMessage.toString) - event.getResponse.getWriter.flush + if(event.getMessage ne null) + { + var isUsingStream = false + try { + event.getResponse.getWriter + } catch { + case e: IllegalStateException => isUsingStream = true + } + + if (isUsingStream){ + event.getResponse.getOutputStream.write(event.getMessage.toString.getBytes); + event.getResponse.getOutputStream.flush + } else { + event.getResponse.getWriter.write(event.getMessage.toString) + event.getResponse.getWriter.flush + } } + else + log.info(new NullPointerException, "Null event message :/") event } override def onEvent(event : AtmosphereEvent[HttpServletRequest,HttpServletResponse]) : AtmosphereEvent[_,_] = { - event.getRequest.setAttribute(classOf[org.atmosphere.cpr.AtmosphereEvent[_,_]].getName, event) - event.getRequest.setAttribute(classOf[AkkaServlet].getName, this) + //log.info("onEvent: " + event.getMessage) + event.getRequest.setAttribute(ReflectorServletProcessor.ATMOSPHERE_EVENT, event) + event.getRequest.setAttribute(ReflectorServletProcessor.ATMOSPHERE_HANDLER, this) service(event.getRequest, event.getResponse) @@ -78,24 +85,17 @@ class AkkaServlet extends ServletContainer with AtmosphereServletProcessor with } class AkkaCometServlet extends org.atmosphere.cpr.AtmosphereServlet with Logging - { +{ override def init(sconf : ServletConfig) = { + val servlet = new AkkaServlet - val cfg = new AtmosphereConfig + atmosphereHandlers.put("", new AtmosphereHandlerWrapper(servlet,new JerseyBroadcaster())) - atmosphereHandlers.put("", new AtmosphereHandlerWrapper(new AkkaServlet,new JerseyBroadcaster())) - - super.setCometSupport(new GrizzlyCometSupport(cfg)) + setCometSupport(new GrizzlyCometSupport(new AtmosphereConfig{ ah = servlet })) getCometSupport.init(sconf) - //Would call super.initAtmosphereServletProcessor(sconf) if they'd let me, but they don't so I roll my own - for(e <- atmosphereHandlers.entrySet){ - val h = e.getValue.atmosphereHandler - if(h.isInstanceOf[AtmosphereServletProcessor]) - (h.asInstanceOf[AtmosphereServletProcessor]).init(sconf) - } - + servlet.init(sconf) } override def loadAtmosphereDotXml(is : InputStream, urlc :URLClassLoader) = () //Hide it - } +} diff --git a/lib/akka-kernel-0.5.jar b/lib/akka-kernel-0.5.jar index 1000201938370c0de441af99d57ed09495969aeb..f515f106af39b6245968ca8eca6a439817e38791 100644 GIT binary patch delta 31681 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
    Xo2%PuiA@6|QsdY&ASm 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 delta 30310 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 diff --git a/lib/akka-util-java-0.5.jar b/lib/akka-util-java-0.5.jar index 4f60c3e94f2a53517ae4ec75ddb073f7ce7fa351..b564370ccade8b776fd696e96a96ca141c5d5658 100644 GIT binary patch delta 507 zcmX?San6D_z?+$civa}YZ2dElSA}`@);|+XW`L>la$xF%0f?Hc%xDUxqZu8*^gKoz zFnyQN8ANYZX7XSJGxC_7AdJl{4iLsSR;ZLCyBkELi^B%OILR3bVJLFTGJ~}{^4(@+ zp0oAOWO)HCFzqAY0-`rh7BFWPoW1pr)t7+p3riRn7^)c<7~Cc=6tJGGCBs)QddipU zkb!{1!@qNq7QAi~2)f`DuC(aF)V&9`$Sy7OP^rIgTY7r`dsFi=8I6x!pBt4$%P#oL z{5X;IENAb_wQsGvr@tPH35{dYHP@;B$!2kZgfj7%cT;P7K%0J(X&hzZCOlkbVxgJ}g(Jun?83JJ6+qOM^6 z9nkla$xF%0f?Hc%xDUxqZu8*^gKoz zFnyQN8ANYZX7XSJGxC_7AdJl{4iLsSR;ZLCyBkELi^B%OILR3bVJLFTGJ~}{^4(@+ zUbgG^WO)HCFzqAY0-`rh7BFWPT)OMGmG?EqD|%C z$Uwm1;@>$*3tqRGC?ze_77TphrEieyzEW1`qzYqxeoWoHe7!f8L62CM>-UA+a5iS^ z->&n5??u_(*T2p^dRbGyVDmSQ*2U`%@?U%NP}KQf%yh?_FMOOPZ(uvQa+lOCGp4T0 z+Dmg@eR;oa)|PxN7W)8iMkWzvaQLw>fZV)X#02Dt$@fI;!L)*?9+(akg#_9ZQCBek zj%Waw))(^u({*COVET$!GMKg!j|bCp#ACqpZ}CJh9WRjprVmL(gJ}iHOfcOeSpcU0 eOJ;$>YI2U06_{Qr6#}9sNnhZAh1}#D(q#bdg5`Mt diff --git a/samples-scala/src/main/scala/SimpleService.scala b/samples-scala/src/main/scala/SimpleService.scala index 3eb3256d31..439ac14db6 100644 --- a/samples-scala/src/main/scala/SimpleService.scala +++ b/samples-scala/src/main/scala/SimpleService.scala @@ -76,10 +76,6 @@ class Chat extends Actor with Logging{ makeTransactionRequired case class Chat(val who : String, val what : String,val msg : String) - //case object Suspend - - //private var hasStarted = false; - //private val storage = TransactionalState.newPersistentMap(CassandraStorageConfig()) override protected def postRestart(reason: AnyRef, config: Option[AnyRef]) = { println("Restarting due to: " + reason.asInstanceOf[Exception].getMessage) @@ -103,6 +99,7 @@ class Chat extends Actor with Logging{ case _ => throw new WebApplicationException(422) } } + case x => log.info("recieve unknown: " + x) } @Broadcast @@ -114,7 +111,7 @@ class Chat extends Actor with Logging{ } - class JsonpFilter extends BroadcastFilter[String] + class JsonpFilter extends BroadcastFilter[String] with Logging { val BEGIN_SCRIPT_TAG = "