diff --git a/Makefile b/Makefile index 8d40e44..28275bc 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,19 @@ -##### - SYSTEM = Linux HOME = /home/tong/projetcs/hxmpp -##### +DEBUG=true -HX_JABBER_SRC = jabber/*.hx jabber/client/*.hx jabber/component/*.hx jabber/file/*.hx jabber/jingle/*.hx jabber/stream/*.hx jabber/tool/*.hx jabber/file/*.hx jabber/file/io/*.hx +HX_JABBER_SRC = jabber/*.hx jabber/client/*.hx jabber/component/*.hx jabber/file/*.hx jabber/jingle/*.hx jabber/stream/*.hx jabber/tool/*.hx jabber/file/*.hx jabber/file/io/*.hx jabber/remoting/*.hx HX_XMPP_SRC = xmpp/*.hx HX_SRC = $(HX_JABBER_SRC) $(HX_XMPP_SRC) HX_CP = -cp ../core/ -##### - TESTS_SRC = test/*.hx TESTS_CP = -cp test/ TEST_PATH = bin/tests +TEST_XMPP_FLAGS = -main TestXMPP -debug $(HX_CP) $(TESTS_CP) +TEST_JABBER_FLAGS = -main TestJabber -debug $(HX_CP) $(TESTS_CP) PATH_XMPP = $(TEST_PATH)/test_xmpp TEST_XMPP_JS = $(PATH_XMPP).js TEST_XMPP_SWF = $(PATH_XMPP).swf @@ -27,32 +25,19 @@ TEST_JABBER_SWF = $(PATH_JABBER).swf TEST_JABBER_NEKO = $(PATH_JABBER).n TEST_JABBER_PHP = $(TEST_PATH)/test_jabber.php -TEST_XMPP_FLAGS = -main TestXMPP $(HX_CP) $(TESTS_CP) -TEST_JABBER_FLAGS = -main TestJabber $(HX_CP) $(TESTS_CP) - -##### - NDLL = ndll/$(SYSTEM)/sha1.ndll NDLL_OBJECTS = util/sha1.o NDLL_NEKO_FLAGS = -fPIC -shared -L/usr/lib/neko -lneko -lz -ldl NDLL_LOCAL_FLAGS = -DLINUX -DXP_UNIX=1 -NDLL_FLAGS = $(NDLL_NEKO_FLAGS) $(NDLL_LOCAL_FLAGS) $(NDLL_OBJECTS) -o $(NDLL) - -##### +NDLL_FLAGS = $(NDLL_NEKO_FLAGS) $(NDLL_LOCAL_FLAGS) $(NDLL_OBJECTS) SWF_SOCKETBRIDGE = bin/f9_socketbridge.swf SWF_SOCKETBRIDGE_SRC = jabber/tool/SocketBridge.hx -##### - -DOC = doc/api/api.xml DOC_SRC = $(HX_JABBER_SRC ) $(HX_XMPP_SRC) doc/api/template.xml -#DOC_CLASSES = jabber.BlockList jabber.BOB jabber.BOBListener jabber.BOSHConnection jabber.Chat jabber.ChatStateNotification jabber.EntityCapabilities jabber.JID jabber.JIDUtil jabber.LastActivity jabber.LastActivityListener jabber.MessageListener jabber.Ping jabber.Pong jabber.PrivacyLists jabber.PubSub jabber.PersonalEvent jabber.PersonalEventListener jabber.ServiceDiscovery jabber.ServiceDiscoveryListener jabber.SocketConnection jabber.SoftwareVersion jabber.XMPPDebug jabber.XMPPError jabber.client.Account jabber.client.MUChat jabber.client.NonSASLAuthentication jabber.client.Roster jabber.client.SASLAuthentication jabber.client.Stream jabber.client.VCardTemp jabber.component.Stream xmpp.Bind xmpp.ChatState xmpp.ChatStateExtension xmpp.Compression xmpp.DataForm xmpp.DateTime xmpp.Delayed xmpp.Error xmpp.ErrorCondition xmpp.IQ xmpp.MUC xmpp.PlainPacket xmpp.Presence xmpp.PrivacyLists xmpp.SASL xmpp.XHTML net.sasl.AnonymousMechanism net.sasl.PlainMechanism net.sasl.MD5Mechanism - -##### TEMP_NAME = test -TEMP_MAIN = TestServiceDiscovery +TEMP_MAIN = TestBOSH TEMP_SRC = $(HX_SRC) test/jabber/*.hx TEMP_FLAGS = $(HX_CP) -cp test/jabber -D XMPP_DEBUG -D JABBER_DEBUG TEMP_NEKO = bin/$(TEMP_NAME).n @@ -60,19 +45,9 @@ TEMP_SWF = bin/$(TEMP_NAME).swf TEMP_JS = bin/$(TEMP_NAME).js TEMP_PHP = bin/test.php -##### - -all : $(SWF_SOCKETBRIDGE) \ - $(NDLL) \ - $(DOC) \ - $(TEMP_NEKO) \ - $(TEMP_SWF) \ - $(TEMP_JS) \ - $(TEMP_PHP) \ - $(TEST_XMPP_JS) $(TEST_XMPP_SWF) $(TEST_XMPP_NEKO) $(TEST_XMPP_CPP) $(TEST_XMPP_PHP) \ - $(TEST_JABBER_JS) $(TEST_JABBER_SWF) $(TEST_JABBER_NEKO) $(TEST_JABBER_PHP) \ - #$(SWC) \ - +all : $(TEMP_NEKO) $(TEMP_SWF) $(TEMP_JS) \ + $(SWF_SOCKETBRIDGE) $(NDLL) \ + #$(SWC) \ $(TEMP_NEKO) : $(TEMP_SRC) haxe -neko $(TEMP_NEKO) -main $(TEMP_MAIN) $(TEMP_FLAGS) @@ -83,52 +58,42 @@ $(TEMP_JS) : $(TEMP_SRC) $(TEMP_PHP) : $(TEMP_SRC) haxe -php bin --php-front test.php -main $(TEMP_MAIN) $(TEMP_FLAGS) - -$(TEST_XMPP_JS) : $(HX_SRC) $(TESTS_SRC) +tests : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_XMPP_FLAGS) -js $(TEST_XMPP_JS) -$(TEST_XMPP_SWF) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_XMPP_FLAGS) -swf9 $(TEST_XMPP_SWF) -$(TEST_XMPP_NEKO) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_XMPP_FLAGS) -neko $(TEST_XMPP_NEKO) -$(TEST_XMPP_PHP) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_XMPP_FLAGS) -php $(TEST_PATH) --php-front test_xmpp.php -$(TEST_JABBER_JS) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_JABBER_FLAGS) -js $(TEST_JABBER_JS) -$(TEST_JABBER_SWF) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_JABBER_FLAGS) -swf9 $(TEST_JABBER_SWF) -$(TEST_JABBER_NEKO) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_JABBER_FLAGS) -neko $(TEST_JABBER_NEKO) -$(TEST_JABBER_PHP) : $(HX_SRC) $(TESTS_SRC) haxe $(TEST_JABBER_FLAGS) -php $(TEST_PATH) --php-front test_jabber.php - $(NDLL) : $(NDLL_OBJECTS) - $(CC) $(NDLL_FLAGS) - + $(CC) $(NDLL_FLAGS) -o $@ $(SWF_SOCKETBRIDGE) : $(SWF_SOCKETBRIDGE_SRC) haxe -swf-header 0:0:60:000000 -swf9 $@ -main FlashSocketBridge -cp util/ --no-traces --flash-strict - #$(SWC) : # haxe -swf9 bin/hxmpp.swc -cp lib/ -D JABBER_DEBUG --no-traces \ # jabber.client.Stream - -$(DOC) : $(DOC_SRC) - #find jabber/ xmpp/ -name "*.hx" | sed -e 's/\//./g' -e 's/\.hx//' > temp; - #paste -s -d' ' temp > Makefile.inc - ##sed -i '1i CLASSES=' Makefile.inc - haxe -js temp.js -xml $(DOC) -cp lib/ \ - jabber.BlockList jabber.BOB jabber.BOBListener jabber.BOSHConnection jabber.Chat jabber.ChatStateNotification jabber.EntityCapabilities jabber.JID jabber.JIDUtil jabber.LastActivity jabber.LastActivityListener jabber.MessageListener jabber.Ping jabber.Pong jabber.PrivacyLists jabber.PubSub jabber.PersonalEvent jabber.PersonalEventListener jabber.ServiceDiscovery jabber.ServiceDiscoveryListener jabber.SocketConnection jabber.SoftwareVersion jabber.XMPPDebug jabber.XMPPError jabber.client.Account jabber.client.MUChat jabber.client.NonSASLAuthentication jabber.client.Roster jabber.client.SASLAuthentication jabber.client.Stream jabber.client.VCardTemp jabber.component.Stream xmpp.Bind xmpp.ChatState xmpp.ChatStateExtension xmpp.Compression xmpp.DataForm xmpp.DateTime xmpp.Delayed xmpp.Error xmpp.ErrorCondition xmpp.IQ xmpp.MUC xmpp.PlainPacket xmpp.Presence xmpp.PrivacyLists xmpp.SASL xmpp.XHTML net.sasl.AnonymousMechanism net.sasl.PlainMechanism net.sasl.MD5Mechanism \ +doc : $(DOC_SRC) Makefile + haxe -js temp.js -xml doc/api/api.xml -cp lib/ \ + jabber.BlockList jabber.BOB jabber.BOBListener jabber.BOSHConnection jabber.Chat jabber.ChatStateNotification jabber.EntityCapabilities jabber.JID jabber.JIDUtil jabber.LastActivity jabber.LastActivityListener jabber.MessageListener jabber.Ping jabber.Pong jabber.PrivacyLists jabber.PubSub jabber.PersonalEvent jabber.PersonalEventListener jabber.ServiceDiscovery jabber.ServiceDiscoveryListener jabber.SocketConnection jabber.SoftwareVersion jabber.XMPPDebug jabber.XMPPError jabber.client.Account jabber.client.MUChat jabber.client.NonSASLAuthentication jabber.client.Roster jabber.client.SASLAuthentication jabber.client.Stream jabber.client.VCard jabber.component.Stream xmpp.Bind xmpp.ChatState xmpp.ChatStateExtension xmpp.Compression xmpp.DataForm xmpp.DateTime xmpp.Delayed xmpp.Error xmpp.ErrorCondition xmpp.IQ xmpp.MUC xmpp.PlainPacket xmpp.Presence xmpp.PrivacyLists xmpp.SASL xmpp.XHTML net.sasl.AnonymousMechanism net.sasl.PlainMechanism net.sasl.MD5Mechanism \ + -D JABBER_SOCKETBRIDGE \ -D XMPP_DEBUG \ - -D JABBER_DEBUG \ - -D JABBER_SOCKETBRIDGE; \ - cd doc/api && haxedoc api.xml -f jabber -f jabber.tool -f xmpp -f net -f crypt -f util -f error - + -D JABBER_DEBUG;\ + cd doc/api; \ + haxedoc api.xml -f jabber -f jabber.tool -f xmpp -f net -f crypt -f util -f error; \ + cd -; rm temp.js; echo OK clean : rm util/*.o - -.PHONY: all clean +.PHONY: all tests doc clean + +##find jabber/ xmpp/ -name "*.hx" | sed -e 's/\//./g' -e 's/\.hx//' > temp; +##paste -s -d' ' temp > Makefile.inc +##sed -i '1i CLASSES=' Makefile.inc + \ No newline at end of file diff --git a/bin/samples/client.html b/bin/samples/client.html index 5bac949..a6daa4d 100644 --- a/bin/samples/client.html +++ b/bin/samples/client.html @@ -20,13 +20,19 @@ <div id="f9bridge">NO FLASHPLAYER DETECTED</div> <div id="haxe:trace"></div> -<script type="text/javascript">swfobject.embedSWF("../f9_socketbridge.swf","f9bridge","0","0","9.0.0");</script> +<script type="text/javascript"> +swfobject.embedSWF("../f9_socketbridge.swf","f9bridge","100","100","9.0.0"); +</script> <script type="text/javascript"> console.log("HXMPP"); -jabber.Lib.initSocketBridge(); -jabber.XMPPDebug.redirectTraces(); +jabber.SocketBridgeConnection.init("f9bridge"); +//jabber.Lib.initSocketBridge(); +//jabber.XMPPDebug.redirectTraces(); + +console.log("FIN"); + var stream; diff --git a/bin/swfobject.js b/bin/swfobject.js index 79b5d07..d8f59ca 100644 --- a/bin/swfobject.js +++ b/bin/swfobject.js @@ -1 +1 @@ -var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}(); \ No newline at end of file +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}(); \ No newline at end of file diff --git a/bin/tests/test.html b/bin/tests/test.html index cc96cc4..95e2ca6 100644 --- a/bin/tests/test.html +++ b/bin/tests/test.html @@ -17,7 +17,7 @@ </tr> </table> <script type="text/javascript"> -swfobject.embedSWF("test_xmpp.swf","swf","800","1200","9"); +swfobject.embedSWF("test_xmpp.swf","swf","300","1200","9"); </script> <script type="text/javascript" src="test_xmpp.js"/></script> </body> diff --git a/doc.hxml b/doc.hxml index d15a3e0..db2c7a7 100644 --- a/doc.hxml +++ b/doc.hxml @@ -32,7 +32,7 @@ jabber.client.NonSASLAuthentication jabber.client.Roster jabber.client.SASLAuthentication jabber.client.Stream -jabber.client.VCardTemp +jabber.client.VCard jabber.component.Stream xmpp.Bind xmpp.ChatState diff --git a/doc/api/template.xml b/doc/api/template.xml index cd1e3b6..f7e08bd 100644 --- a/doc/api/template.xml +++ b/doc/api/template.xml @@ -2,7 +2,7 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> -<meta name="keywords" content="haxe,xmpp,jabber,documentation,api,open source,library,lgpl,flash,flashplayer,neko,realtime,framework,pubsub,muchat,roster,jingle,sasl,pep,"/> +<meta name="keywords" content="haxe,xmpp,jabber,documentation,api,open source,library,lgpl,flash,flashplayer,neko,realtime,framework,pubsub,muchat,roster,jingle,sasl,pep"/> <meta name="description" content="Open source LGPL licensed haXe library for creating XMPP/jabber based clients and components"/> <meta name="author" content="disktree"/> <title>HXMPP-API</title> diff --git a/jabber/BOSHConnection.hx b/jabber/BOSHConnection.hx index 8386b24..d7c75d7 100644 --- a/jabber/BOSHConnection.hx +++ b/jabber/BOSHConnection.hx @@ -27,12 +27,14 @@ import flash.events.SecurityErrorEvent; #end //TODO - // timeout timer (?) + + // timeout timer (?), added but needed? + // polling - /// multiple streams over one connection) + /// multiple streams over one connection // secure! // secure keys - // pause + // pause -> test /** <p> @@ -71,18 +73,20 @@ class BOSHConnection extends jabber.stream.Connection { var rid : Int; var requestCount : Int; var requestQueue : Array<String>; - var responseTimer : util.Timer; + var responseTimer : Timer; var responseQueue : Array<Xml>; var pollingEnabled : Bool; var pauseEnabled : Bool; var pauseTimer : Timer; var inactivity : Int; var maxPause : Int; + var timeoutTimer : Timer; + var timeoutOffset : Int; public function new( host : String, path : String, hold : Int = 1, wait : Int = 30, - secure : Bool = true, + secure : Bool = false, maxConcurrentRequests : Int = 2 ) { super( host ); this.path = path; @@ -93,6 +97,7 @@ class BOSHConnection extends jabber.stream.Connection { initialized = false; pauseEnabled = false; pollingEnabled = true; + timeoutOffset = 25;//TODO } /** @@ -227,12 +232,23 @@ class BOSHConnection extends jabber.stream.Connection { l.addEventListener( SecurityErrorEvent.SECURITY_ERROR, handleHTTPError ); l.load( r ); #end + if( timeoutTimer != null ) + timeoutTimer.stop(); + timeoutTimer = new Timer( (wait*1000)+(timeoutOffset*1000) ); + timeoutTimer.run = handleTimeout; return true; } + function handleTimeout() { + //trace("TIMEOUT TIMEOUT TIMEOUT TIMEOUT "); + timeoutTimer.stop(); + cleanup(); + __onError( "BOSH timeout" ); + } + /* function handleHTTPStatus( s : Int ) { - //trace( "handleHTTPStatus "+s ); + trace( "handleHTTPStatus "+s ); } */ @@ -255,6 +271,9 @@ class BOSHConnection extends jabber.stream.Connection { return; } requestCount--; + if( timeoutTimer != null ) { + timeoutTimer.stop(); + } if( connected ) { switch( x.get( "type" ) ) { case "terminate" : @@ -297,13 +316,15 @@ class BOSHConnection extends jabber.stream.Connection { return; } wait = Std.parseInt( x.get( "wait" ) ); + /* var t = x.get( "ver" ); if( t != null && t != BOSH_VERSION ) { cleanup(); __onError( "Invalid BOSH version ("+t+")" ); return; } - t = null; + */ + var t = null; t = x.get( "maxpause" ); if( t != null ) { maxPause = Std.parseInt( t )*1000; @@ -337,7 +358,7 @@ class BOSHConnection extends jabber.stream.Connection { } function resetResponseProcessor() { - if( responseQueue.length > 0 ) { + if( responseQueue != null && responseQueue.length > 0 ) { responseTimer.stop(); responseTimer = new Timer( 0 ); responseTimer.run = processResponse; @@ -372,6 +393,7 @@ class BOSHConnection extends jabber.stream.Connection { } function cleanup() { + timeoutTimer.stop(); responseTimer.stop(); connected = initialized = false; sid = null; diff --git a/jabber/JIDUtil.hx b/jabber/JIDUtil.hx index ff21a17..972df90 100644 --- a/jabber/JIDUtil.hx +++ b/jabber/JIDUtil.hx @@ -23,6 +23,8 @@ package jabber; */ class JIDUtil { + public static inline var MAX_PARTSIZE = 1023; + #if JABBER_DEBUG public static var EREG = ~/[A-Z0-9._%-]+@[A-Z0-9.-]+(\.[A-Z]{3}?)?(\/[A-Z0-9._%-])?/i; #else @@ -36,7 +38,7 @@ class JIDUtil { if( !EREG.match( t ) ) return false; for( p in getParts( t ) ) - if( p.length > jabber.JID.MAX_PART_SIZE ) + if( p.length > MAX_PARTSIZE ) return false; return true; } @@ -54,8 +56,7 @@ class JIDUtil { public static function parseDomain( t : String ) : String { var i1 = t.indexOf( "@" ) + 1; var i2 = t.indexOf( "/" ); - if( i2 == -1 ) return t.substr( i1 ); - return t.substr( i1, i2-i1 ); + return ( i2 == -1 ) ? t.substr( i1 ) : t.substr( i1, i2-i1 ); } /** @@ -63,8 +64,7 @@ class JIDUtil { */ public static function parseResource( t : String ) : String { var i = t.indexOf( "/" ); - if( i != -1 ) return t.substr( i+1 ); - return null; + return ( i == -1 ) ? null : t.substr( i+1 ); } /** @@ -72,8 +72,7 @@ class JIDUtil { */ public static function parseBare( t : String ) : String { var i = t.indexOf( "/" ); - if( i != -1 ) return t.substr( 0, i ); - return t; + return ( i == -1 ) ? t : t.substr( 0, i ); } /** @@ -91,7 +90,14 @@ class JIDUtil { if( hasResource( jid ) ) p.push( parseResource( jid ) ); return p; } - + + /** + */ + public static function splitBare( jid : String ) : Array<String> { + var i = jid.indexOf( "/" ); + return ( i == -1 ) ? [jid] : [ jid.substr( 0, i ), jid.substr( i+1 ) ]; + } + /** <p> Escapes the node portion of a JID according to "JID Escaping" (XEP-0106).<br/> diff --git a/jabber/Lib.hx b/jabber/Lib.hx index 47f39f7..71dcc1d 100644 --- a/jabber/Lib.hx +++ b/jabber/Lib.hx @@ -40,6 +40,7 @@ class Lib { trace( "Socket bridge hopefuly initialized" ); #end } + #end } diff --git a/jabber/Ping.hx b/jabber/Ping.hx index 0286be0..7906d72 100644 --- a/jabber/Ping.hx +++ b/jabber/Ping.hx @@ -29,15 +29,15 @@ class Ping { public static var defaultInterval = 60000; - public dynamic function onResponse( entity : String ) : Void; - public dynamic function onTimeout( entity : String ) : Void; + public dynamic function onResponse( jid : String ) : Void; + public dynamic function onTimeout( jid : String ) : Void; public dynamic function onError( e : XMPPError ) : Void; public var stream(default,null) : Stream; /** Ping interval ms */ public var interval : Int; /** The pinged target entity */ - public var target : String; + public var target : String; //public var target : Array<String>; //hm?? /** Indicates if the ping interval is running */ public var active(default,null) : Bool; @@ -53,9 +53,9 @@ class Ping { } /** - Starts the ping interval. + Starts ping packet sending interval. */ - public function start() { + public function run() { #if !php active = true; send( target ); diff --git a/jabber/PubSub.hx b/jabber/PubSub.hx index 1f67b69..f4c70a6 100644 --- a/jabber/PubSub.hx +++ b/jabber/PubSub.hx @@ -18,15 +18,16 @@ package jabber; /** + PubSub client implementation.<br/> <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060: Publish-Subscribe</a> */ class PubSub { public dynamic function onNodeCreate( node : String ) : Void; public dynamic function onNodeDelete( node : String ) : Void; - public dynamic function onSubscribe( subscription : xmpp.pubsub.Subscription ) : Void; + public dynamic function onSubscribe( sub : xmpp.pubsub.Subscription ) : Void; public dynamic function onUnsubscribe( node : String ) : Void; - public dynamic function onSubscriptions( subscriptions : xmpp.pubsub.Subscriptions ) : Void; + public dynamic function onSubscriptions( subs : xmpp.pubsub.Subscriptions ) : Void; public dynamic function onPublish( node : String, item : xmpp.pubsub.Item ) : Void; public dynamic function onItems( items : xmpp.pubsub.Items ) : Void; public dynamic function onAffiliations( a : xmpp.pubsub.Affiliations ) : Void; @@ -93,9 +94,9 @@ class PubSub { */ public function subscribe( node : String ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); - var xt = new xmpp.PubSub(); - xt.subscribe = { jid : stream.jidstr, node : node }; - iq.x = xt; + var x = new xmpp.PubSub(); + x.subscribe = { jid : stream.jidstr, node : node }; + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onSubscribe( xmpp.PubSub.parse( r.x.toXml() ).subscription ); @@ -105,11 +106,13 @@ class PubSub { /** Unsubscribe from the given pubsub node. */ - public function unsubscribe( node : String, ?subid : String ) { + public function unsubscribe( node : String, ?jid : String, ?subid : String ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); - var xt = new xmpp.PubSub(); - xt.unsubscribe = { jid : stream.jidstr , node : node, subid : subid }; - iq.x = xt; + var x = new xmpp.PubSub(); + x.unsubscribe = { jid : ( jid != null ) ? jid : stream.jidstr , + node : node, + subid : subid }; + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onUnsubscribe( node ); @@ -121,15 +124,29 @@ class PubSub { */ public function loadSubscriptions( ?node : String ) { var iq = new xmpp.IQ( null, null, service ); - var xt = new xmpp.PubSub(); - xt.subscriptions = new xmpp.pubsub.Subscriptions( node ); - iq.x = xt; + var x = new xmpp.PubSub(); + x.subscriptions = new xmpp.pubsub.Subscriptions( node ); + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onSubscriptions( xmpp.PubSub.parse( r.x.toXml() ).subscriptions ); } ); } + //TODO + /* + public function loadSubConfig() { + <iq type='get' + from='francisco@denmark.lit/barracks' + to='pubsub.shakespeare.lit' + id='options1'> + <pubsub xmlns='http://jabber.org/protocol/pubsub'> + <options node='princely_musings' jid='francisco@denmark.lit'/> + </pubsub> +</iq> + } + */ + /** Load list of affiliations for all nodes at the service. */ @@ -150,13 +167,13 @@ class PubSub { */ public function loadItems( node : String, ?subid : String, ?maxItems : Int, ?ids : Array<String> ) { var iq = new xmpp.IQ( null, null, service ); - var xt = new xmpp.PubSub(); - xt.items = new xmpp.pubsub.Items( node, subid, maxItems ); + var x = new xmpp.PubSub(); + x.items = new xmpp.pubsub.Items( node, subid, maxItems ); if( ids != null ) { for( id in ids ) - xt.items.add( new xmpp.pubsub.Item( id ) ); + x.items.add( new xmpp.pubsub.Item( id ) ); } - iq.x = xt; + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onItems( xmpp.PubSub.parse( r.x.toXml() ).items ); @@ -169,9 +186,9 @@ class PubSub { */ public function retract( retract : xmpp.pubsub.Retract ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); - var xt = new xmpp.PubSub(); - xt.retract = retract; - iq.x = xt; + var x = new xmpp.PubSub(); + x.retract = retract; + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onRetract( retract ); @@ -184,9 +201,9 @@ class PubSub { */ public function purge( node : String ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); - var xt = new xmpp.PubSubOwner(); - xt.purge = node; - iq.x = xt; + var x = new xmpp.PubSubOwner(); + x.purge = node; + iq.x = x; var me = this; sendIQ( iq, function(r:xmpp.IQ) { me.onPurge( node ); @@ -198,11 +215,11 @@ class PubSub { */ public function publish( node : String, item : xmpp.pubsub.Item, ?options : xmpp.DataForm ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); - var xt = new xmpp.PubSub(); + var x = new xmpp.PubSub(); var p = new xmpp.pubsub.Publish( node ); p.add( item ); - xt.publish = p; - iq.x = xt; + x.publish = p; + iq.x = x; // TODO check options ? if( options != null ) { var po = Xml.createElement( "publish-options" ); diff --git a/jabber/ServiceDiscoveryListener.hx b/jabber/ServiceDiscoveryListener.hx index aeabb9e..afc4b59 100644 --- a/jabber/ServiceDiscoveryListener.hx +++ b/jabber/ServiceDiscoveryListener.hx @@ -29,6 +29,9 @@ class ServiceDiscoveryListener { public var stream(default,null) : Stream; public var identities : Array<xmpp.disco.Identity>; + //public dynamic function onInfoQuery( iq : xmpp.IQ ) : Void; + //public dynamic function onItemQuery( iq : xmpp.IQ ) : Void; + public function new( stream : Stream, ?identities : Array<xmpp.disco.Identity> ) { if( !stream.features.add( xmpp.disco.Info.XMLNS ) || !stream.features.add( xmpp.disco.Items.XMLNS ) ) @@ -40,14 +43,26 @@ class ServiceDiscoveryListener { } function handleInfoQuery( iq : xmpp.IQ ) { // return identities and stream features + /* + if( onInfoQuery != null ) { + onInfoQuery(); + return; + } + */ var r = new xmpp.IQ( xmpp.IQType.result, iq.id, iq.from, stream.jidstr ); r.x = new xmpp.disco.Info( identities, Lambda.array( stream.features ) ); stream.sendData( r.toString() ); } function handleItemsQuery( iq : xmpp.IQ ) { + /* + if( onItemQuery != null ) { + onItemQuery(); + return; + } + */ var r : xmpp.IQ; - // HACK + // TODO (HACK) if( Reflect.hasField( stream, "items" ) ) { // component stream .. return local stream items r = new xmpp.IQ( xmpp.IQType.result, iq.id, iq.from, Reflect.field( stream, "serviceName" ) ); r.x = Reflect.field( stream, "items" ); diff --git a/jabber/SocketConnection.hx b/jabber/SocketConnection.hx index 407d684..8af8f86 100644 --- a/jabber/SocketConnection.hx +++ b/jabber/SocketConnection.hx @@ -196,17 +196,17 @@ class SocketConnection extends jabber.stream.Connection { function sockConnectHandler( e : Event ) { connected = true; - onConnect(); + __onConnect(); } function sockDisconnectHandler( e : Event ) { connected = false; - onDisconnect(); + __onDisconnect(); } function sockErrorHandler( e ) { connected = false; - onError( e ); + __onError( e ); } function sockDataHandler( e : ProgressEvent ) { @@ -214,7 +214,7 @@ class SocketConnection extends jabber.stream.Connection { var b = haxe.io.Bytes.ofData( buf ); if( b.length > maxBufSize ) throw "Max buffer size reached ("+maxBufSize+")"; - if( onData( b, 0, b.length ) > 0 ) + if( __onData( b, 0, b.length ) > 0 ) buf = new flash.utils.ByteArray(); } @@ -272,17 +272,17 @@ class SocketConnection extends jabber.stream.Connection { function sockConnectHandler() { connected = true; - onConnect(); + __onConnect(); } function sockDisconnectHandler() { connected = false; - onDisconnect(); + __onDisconnect(); } function sockErrorHandler( m : String ) { connected = false; - onError( m ); + __onError( m ); } function sockDataHandler( t : String ) { @@ -316,7 +316,8 @@ class Socket { public function new() { var id : Int = SocketBridgeConnection.createSocket( this ); - if( id < 0 ) "Error creating socket"; + if( id < 0 ) + throw "Error creating socket on socket bridge"; this.id = id; } @@ -367,7 +368,12 @@ class SocketBridgeConnection { public static function createSocket( s : Socket ) { - var id : Int = untyped js.Lib.document.getElementById( bridgeId ).createSocket(); + var id : Int = -1; + try { + id = untyped js.Lib.document.getElementById( bridgeId ).createSocket(); + } catch( e : Dynamic ) { + return -1; + } sockets.set( id, s ); return id; } @@ -381,6 +387,9 @@ class SocketBridgeConnection { s = null; } } + + public function destroyAllSockets() {} + */ static function handleConnect( id : Int ) { diff --git a/jabber/Stream.hx b/jabber/Stream.hx index 9dfa6ee..4ddcbc0 100644 --- a/jabber/Stream.hx +++ b/jabber/Stream.hx @@ -25,7 +25,7 @@ import xmpp.filter.PacketIDFilter; import util.XmlUtil; import util.Base64; -/* +/* private typedef TDataFilter = { function filterData( t : haxe.io.Bytes ) : haxe.io.Bytes; } @@ -75,10 +75,11 @@ class Stream { public var version : Bool; //Indicates if the version number of the XMPP stream ("1.0") should get added to the stream opening XML element. //public var dataFilters : List<TDataFilter>; //public var dataInterceptors : List<TDataInterceptor>; + /** Indicates if this streams connection is a http connection */ + public var http(default,null) : Bool; var collectors : List<PacketCollector>; // public var packetCollectors : Array<TPacketCollector>; var interceptors : List<TPacketInterceptor>; // public var packetInterceptors : Array<TPacketCollector>; - var isBOSH : Bool; var numPacketsSent : Int; //var numPacketsRecieved : Int; @@ -91,7 +92,7 @@ class Stream { version = true; collectors = new List(); interceptors = new List(); - isBOSH = false; + http = false; numPacketsSent = 0; //dataFilters = new List(); //dataInterceptors = new List(); @@ -118,7 +119,8 @@ class Stream { cnx.__onData = processData; cnx.__onError = errorHandler; } - isBOSH = ( Type.getClassName( Type.getClass( cnx ) ) == "jabber.BOSHConnection" ); + //HACK + http = ( Type.getClassName( Type.getClass( cnx ) ) == "jabber.BOSHConnection" ); return cnx; } @@ -149,7 +151,7 @@ class Stream { */ public function close( ?disconnect = false ) { if( status == StreamStatus.open ) { - if( !isBOSH ) sendData( xmpp.Stream.CLOSE ); + if( !http ) sendData( xmpp.Stream.CLOSE ); status = StreamStatus.closed; } if( disconnect ) @@ -305,6 +307,7 @@ class Stream { return -1; } //TODO + /* if( xmpp.Stream.REGEXP_ERROR.match( t ) ) { //if( ~/stream:error/.match( t ) ) { var err : xmpp.StreamError = null; @@ -319,6 +322,7 @@ class Stream { close( true ); return -1; } + */ switch( status ) { case closed : return -1;//buflen; //hm? diff --git a/jabber/XMPPError.hx b/jabber/XMPPError.hx index 3067f23..86c18bb 100644 --- a/jabber/XMPPError.hx +++ b/jabber/XMPPError.hx @@ -17,6 +17,30 @@ */ package jabber; +class XMPPError extends xmpp.Error { + + public var dispatcher(default,null) : Dynamic; + public var from(default,null) : String; + + public function new( dispatcher : Dynamic, p : xmpp.Packet ) { + var e = p.errors[0]; + if( e == null ) + throw "Packet has no errors"; + super( e.type, e.code, e.name, e.text ); + this.dispatcher = dispatcher; + this.from = p.from; + } + + #if JABBER_DEBUG + public override function toString() : String { + return "XMPPError( "+from+", "+name+", "+code+", "+text+" )"; + } + #end + +} + + +/* //TODO remove (?) class XMPPError { @@ -47,3 +71,4 @@ class XMPPError { #end } +*/ diff --git a/jabber/client/SASLAuthentication.hx b/jabber/client/SASLAuthentication.hx index d46f535..d5696a7 100644 --- a/jabber/client/SASLAuthentication.hx +++ b/jabber/client/SASLAuthentication.hx @@ -23,12 +23,13 @@ import xmpp.IQType; import xmpp.filter.PacketNameFilter; import xmpp.filter.FilterGroup; +// try another mechanism on fail (?) + /** Responsible for authenticating a client account using SASL, - binding the resource to the connection and establishing a session with the server.<br> + binding the resource to the connection and establishing a session with the server.<br/> <a href="http://xmpp.org/rfcs/rfc3920.html#sasl">RFC3920-SASL</a><br/> <a href="http://xmpp.org/rfcs/rfc3920.html#bind">RFC3920-BIND</a><br/> - http://www.ietf.org/mail-archive/web/isms/current/msg00063.html */ class SASLAuthentication extends Authentication { @@ -36,7 +37,7 @@ class SASLAuthentication extends Authentication { /** Used SASL method */ public var handshake(default,null) : net.sasl.Handshake; - /** Available mechanisms ids (from server) */ + /** Available mechanisms ids (server) */ public var mechanisms(default,null) : Array<String>; //public var negotiated(default,null) : Bool; @@ -98,14 +99,13 @@ class SASLAuthentication extends Authentication { f.add( new PacketNameFilter( ~/temporary-auth-failure/ ) ); c_fail = new PacketCollector( [cast f], handleSASLFailed ); stream.addCollector( c_fail ); - // collect success + // collect success response c_success = new PacketCollector( [cast new PacketNameFilter( ~/success/ )], handleSASLSuccess ); stream.addCollector( c_success ); - // collect challenge + // collect challenge response c_challenge = new PacketCollector( [cast new PacketNameFilter( ~/challenge/ )], handleSASLChallenge, true ); stream.addCollector( c_challenge ); - // send init auth - //trace("############## "+stream.jid ); + // init auth var t = handshake.mechanism.createAuthenticationText( stream.jid.node, stream.jid.domain, password ); if( t != null ) t = util.Base64.encode( t ); return stream.sendData( xmpp.SASL.createAuthXml( handshake.mechanism.id, t ).toString() ) != null; diff --git a/jabber/client/Stream.hx b/jabber/client/Stream.hx index f251d5a..ec6db02 100644 --- a/jabber/client/Stream.hx +++ b/jabber/client/Stream.hx @@ -53,9 +53,12 @@ class Stream extends jabber.Stream { } override function processStreamInit( t : String, buflen : Int ) : Int { - if( isBOSH ) { + if( http ) { var sx = Xml.parse( t ).firstElement(); var sf = sx.firstElement(); + #if XMPP_DEBUG + jabber.XMPPDebug.inc( sf.toString() ); + #end parseStreamFeatures( sf ); status = StreamStatus.open; onOpen(); @@ -112,7 +115,7 @@ class Stream extends jabber.Stream { override function connectHandler() { status = StreamStatus.pending; // TODO avoid HACK - if( !isBOSH ) { + if( !http ) { sendData( xmpp.Stream.createOpenStream( xmpp.Stream.XMLNS_CLIENT, jid.domain, version, lang ) ); cnx.read( true ); // start reading input } else { diff --git a/jabber/component/Stream.hx b/jabber/component/Stream.hx index 7747185..9534505 100644 --- a/jabber/component/Stream.hx +++ b/jabber/component/Stream.hx @@ -74,12 +74,16 @@ class Stream extends jabber.Stream { } override function connectHandler() { - sendData( xmpp.Stream.createOpenStream( xmpp.Stream.XMLNS_COMPONENT, subdomain ) ); + var t = sendData( xmpp.Stream.createOpenStream( xmpp.Stream.XMLNS_COMPONENT, subdomain ) ); + #if XMPP_DEBUG + //jabber.XMPPDebug.out( t ); + #end status = jabber.StreamStatus.pending; cnx.read( true ); } override function processStreamInit( t : String, len : Int ) { + trace(t); var i = t.indexOf( ">" ); if( i == -1 ) return 0; diff --git a/jabber/remoting/Connection.hx b/jabber/remoting/Connection.hx index f4ae7c2..8c9d89b 100644 --- a/jabber/remoting/Connection.hx +++ b/jabber/remoting/Connection.hx @@ -89,7 +89,7 @@ class Connection implements AsyncConnection, implements Dynamic<AsyncConnection> /** */ - public static function connect( stream : jabber.Stream, target : String ) { + public static function create( stream : jabber.Stream, target : String ) { return new Connection( stream, target, [], function(e) throw e ); } diff --git a/jabber/remoting/Host.hx b/jabber/remoting/Host.hx index 1de7877..2030fd4 100644 --- a/jabber/remoting/Host.hx +++ b/jabber/remoting/Host.hx @@ -19,6 +19,15 @@ package jabber.remoting; import haxe.remoting.Context; +//TODO +/* +enum Accept { + none; + whitelist( jids : List<String> ); + all; +} +*/ + /** haXe/XMPP remoting host.<br/> <a href="http://haxe.org/doc/remoting">haXe-remoting</a> @@ -29,10 +38,12 @@ class Host { public var client(default,null) : String; public var ctx : Context; public var stream(default,null) : jabber.Stream; - + //public var accept : Accept; + public function new( stream : jabber.Stream, ctx : Context ) { this.stream = stream; this.ctx = ctx; + //this.accept = ( accept == null ) ? Accept.all : accept; stream.features.add( xmpp.HXR.XMLNS ); stream.collect( [cast new xmpp.filter.IQFilter( xmpp.HXR.XMLNS, null, xmpp.IQType.get )], handleIQ, true ); } diff --git a/jabber/tool/SocketBridge.hx b/jabber/tool/SocketBridge.hx index dea135b..64432c5 100644 --- a/jabber/tool/SocketBridge.hx +++ b/jabber/tool/SocketBridge.hx @@ -17,7 +17,8 @@ */ package jabber.tool; -#if flash9 +#if flash + import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; @@ -32,14 +33,14 @@ private class Socket extends flash.net.Socket { } } -class SocketBridge extends flash.display.Sprite { +class SocketBridge extends flash.display.Sprite { // why? extend? static var defaultBridgeContext = "jabber.SocketBridgeConnection"; var ctx : String; var sockets : IntHash<Socket>; - function new( ctx : String ) { + function new( ?ctx : String ) { super(); this.ctx = ( ctx != null ) ? ctx : defaultBridgeContext; init(); @@ -48,17 +49,15 @@ class SocketBridge extends flash.display.Sprite { function init() { sockets = new IntHash(); if( ExternalInterface.available ) { - try { - ExternalInterface.addCallback( "createSocket", createSocket ); - ExternalInterface.addCallback( "destroySocket", destroySocket ); - ExternalInterface.addCallback( "connect", connect ); - ExternalInterface.addCallback( "disconnect", disconnect ); - //ExternalInterface.addCallback( "destroy", destroy ); - ExternalInterface.addCallback( "send", send ); - } catch( e : Dynamic ) { - trace( e ); - throw e; - } + ExternalInterface.addCallback( "createSocket", createSocket ); + ExternalInterface.addCallback( "destroySocket", destroySocket ); + ExternalInterface.addCallback( "connect", connect ); + ExternalInterface.addCallback( "disconnect", disconnect ); + //ExternalInterface.addCallback( "destroy", destroy ); + //ExternalInterface.addCallback( "destroyAll", destroyAll ); + ExternalInterface.addCallback( "send", send ); + } else { + throw "Unable to initialize external connection on socket bridge"; } } @@ -142,4 +141,4 @@ class SocketBridge extends flash.display.Sprite { } -#end // flash9 +#end // flash diff --git a/samples/ClientDemo.as b/samples/ClientDemo.as index 28f106c..25ac730 100644 --- a/samples/ClientDemo.as +++ b/samples/ClientDemo.as @@ -22,7 +22,7 @@ package { import jabber.client.Roster; /** - Example usage of the HXMPP library. + Basic XMPP client exmaple. */ public class ClientDemo extends MovieClip { diff --git a/samples/ClientDemo.hx b/samples/ClientDemo.hx index 5a36296..b924459 100644 --- a/samples/ClientDemo.hx +++ b/samples/ClientDemo.hx @@ -1,10 +1,10 @@ -import jabber.ServiceDiscovery; import jabber.SocketConnection; +import jabber.ServiceDiscovery; import jabber.client.NonSASLAuthentication; import jabber.client.Stream; import jabber.client.Roster; -import jabber.client.VCardTemp; +import jabber.client.VCard; /** Basic jabber client. @@ -12,12 +12,10 @@ import jabber.client.VCardTemp; class ClientDemo { static function main() { - #if flash flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE; flash.Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT; #end - #if JABBER_SOCKETBRIDGE jabber.SocketBridgeConnection.initDelayed( "f9bridge", init ); #else @@ -27,13 +25,12 @@ class ClientDemo { static var stream : Stream; static var roster : Roster; - static var service : ServiceDiscovery; - static var vcard : VCardTemp; + static var disco : ServiceDiscovery; + static var vcard : VCard; static function init() { stream = new Stream( new jabber.JID( "hxmpp@disktree" ), new SocketConnection( "127.0.0.1", 5222 ) ); - stream.onError = function(?e) { trace( "Stream error: "+e ); }; - stream.onClose = function() { trace( "Stream to: "+stream.jid.domain+" closed." ); } ; + stream.onClose = function(?e) { trace( "Stream to: "+stream.jid.domain+" closed." ); } ; stream.onOpen = function() { trace( "XMPP stream to "+stream.jid.domain+" opened" ); /* @@ -61,11 +58,11 @@ class ClientDemo { trace( "Logged in as "+ stream.jid.node+" at "+stream.jid.domain ); // load server disco infos - service = new ServiceDiscovery( stream ); - service.onInfo = handleDiscoInfo; - service.onItems = handleDiscoItems; - service.discoverItems( stream.jid.domain ); - service.discoverInfo( stream.jid.domain ); + disco = new ServiceDiscovery( stream ); + disco.onInfo = handleDiscoInfo; + disco.onItems = handleDiscoItems; + disco.discoverItems( stream.jid.domain ); + disco.discoverInfo( stream.jid.domain ); // load roster roster = new jabber.client.Roster( stream ); @@ -74,7 +71,7 @@ class ClientDemo { roster.onLoad = handleRosterLoad; // load own vcard - vcard = new jabber.client.VCardTemp( stream ); + vcard = new jabber.client.VCard( stream ); vcard.onLoad = function(node,vc) { if( node == null ) trace( "VCard loaded." ); diff --git a/samples/ComponentDemo.hx b/samples/ComponentDemo.hx index 7508394..357007d 100644 --- a/samples/ComponentDemo.hx +++ b/samples/ComponentDemo.hx @@ -16,8 +16,8 @@ class ComponentDemo { stream.onOpen = function() { trace( "XMPP stream opened.", "info" ); }; - stream.onError = function(?m) { trace( "Stream error, "+m ); } ; - stream.onClose = function() { trace( "Stream closed." ); } ; + //stream.onError = function(?m) { trace( "Stream error, "+m ); } ; + stream.onClose = function(?e) { trace( "Stream closed." ); } ; stream.onConnect = function() { trace( "Component connected. Have fun!", "info" ); } diff --git a/samples/SendMessage.hx b/samples/SendMessage.hx index b784eec..0b3f5c6 100644 --- a/samples/SendMessage.hx +++ b/samples/SendMessage.hx @@ -8,6 +8,9 @@ import php.Sys; import cpp.Sys; #end +/** + Login and send message.period. +*/ class SendMessage { static var stream : Stream; @@ -16,6 +19,7 @@ class SendMessage { trace( "Sending message ..." ); stream.sendMessage( "reciever@domain.net/Resource", "Test message" ); trace( "Message sent." ); + stream.close( true ); Sys.exit(0); } diff --git a/test/TestJID.hx b/test/TestJID.hx index 2e57361..a6702c6 100644 --- a/test/TestJID.hx +++ b/test/TestJID.hx @@ -8,6 +8,7 @@ class TestJID extends haxe.unit.TestCase { #if JABBER_DEBUG assertFalse( JIDUtil.isValid( "aaa" ) ); assertFalse( JIDUtil.isValid( "nodedomain.net" ) ); + assertFalse( JIDUtil.isValid( "nodedomain.at" ) ); assertTrue( JIDUtil.isValid( "node@domain" ) ); assertTrue( JIDUtil.isValid( "node@domain/Resource" ) ); assertTrue( JIDUtil.isValid( "node@domain.net/Resource" ) ); diff --git a/test/TestXMPP.hx b/test/TestXMPP.hx index 7ead9ff..170edac 100644 --- a/test/TestXMPP.hx +++ b/test/TestXMPP.hx @@ -46,7 +46,7 @@ class TestXMPP { r.add( new TestXMPPRoster() ); r.add( new TestXMPPSoftwareVersion() ); r.add( new TestXMPPSoftwareVersion() ); - r.add( new TestXMPPVCard() ); +//TODO r.add( new TestXMPPVCard() ); // r.add( new TestXMPPMUC() ); // r.add( new TestXMPPRPC() ); diff --git a/test/TestXMPPPacket.hx b/test/TestXMPPPacket.hx index bdafdb9..8a1ba74 100644 --- a/test/TestXMPPPacket.hx +++ b/test/TestXMPPPacket.hx @@ -37,8 +37,8 @@ class TestMessagePacket extends haxe.unit.TestCase { assertEquals( m.to, "tong@igniterealtime.org" ); assertEquals( m.id, "ab01a" ); assertEquals( m.body, "abc" ); - */ + var x = Xml.parse( ' <message to="hxmpp@disktree"> <body>Wow, I'm green with envy!</body> @@ -57,7 +57,6 @@ class TestMessagePacket extends haxe.unit.TestCase { assertEquals( 'Wow, I'm green with envy!', m.body ); assertEquals( 1, m.properties.length ); } - } diff --git a/test/TestXMPPPubSub.hx b/test/TestXMPPPubSub.hx index d74d573..3902bc5 100644 --- a/test/TestXMPPPubSub.hx +++ b/test/TestXMPPPubSub.hx @@ -4,6 +4,15 @@ */ class TestXMPPPubSub extends haxe.unit.TestCase { + /* + public function testCreatePubSub() { + var ps = new xmpp.PubSub(); + ps.subscribe = { node : "nodename", jid : "myjid@server.net" }; + var x = ps.toXml(); + trace(x); + } + */ + public function testParsePubSub() { // test subscribe diff --git a/test/TestXMPPVCard.hx b/test/TestXMPPVCard.hx index b657fad..1eb5fc6 100644 --- a/test/TestXMPPVCard.hx +++ b/test/TestXMPPVCard.hx @@ -1,14 +1,6 @@ class TestXMPPVCard extends haxe.unit.TestCase { - /* - public function testCreate() { - var vc = new xmpp.VCard(); - vc.n = untyped { family : "Saint-Andre" }; - assertEquals( "Saint-Andre", vc.n.family ); - } - */ - public function testParse() { var x = Xml.parse('<vCard xmlns="vcard-temp"> <FN>Peter Saint-Andre</FN> diff --git a/util/FlashSocketBridge.hx b/util/FlashSocketBridge.hx index c5938bd..27ab04f 100644 --- a/util/FlashSocketBridge.hx +++ b/util/FlashSocketBridge.hx @@ -2,7 +2,7 @@ import jabber.tool.SocketBridge; /** - Flash9+ socket bridge for javascript applications. + Flash9+ socket bridge SWF for javascript applications. */ class FlashSocketBridge extends jabber.tool.SocketBridge { @@ -12,7 +12,7 @@ class FlashSocketBridge extends jabber.tool.SocketBridge { var cm = new flash.ui.ContextMenu(); cm.hideBuiltInItems(); flash.Lib.current.contextMenu = cm; - new FlashSocketBridge( flash.Lib.current.loaderInfo.parameters.ctx ); + new SocketBridge( flash.Lib.current.loaderInfo.parameters.ctx ); } } diff --git a/utilities.hxml b/utilities.hxml index c0654cd..93554c3 100644 --- a/utilities.hxml +++ b/utilities.hxml @@ -1,5 +1,5 @@ -##### SWF9 socket bridge +##### SWF socket bridge -cp util/ -cp lib/ -swf-version 9 diff --git a/www/index.html b/www/index.html index 8d42c56..2b4f47b 100644 --- a/www/index.html +++ b/www/index.html @@ -21,20 +21,19 @@ <tr> <td class="menu"></td> <td class="content"> + <h3> - HXMPP is an open source haXe library for building XMPP based clients and components,<br/> - targetting flash9+, javascript, neko, php and c++ (beta). + Open source haXe library for building XMPP/jabber based clients and components. </h3> <h2 id="source">Source code.</h2> <div> - Source code can be cloned from our GIT respository: - <pre class="command">git clone git://83.64.208.21/hxmpp.git</pre> + Source code can be cloned from our GIT respository at git://83.64.208.21/hxmpp.git<br/> Or <a href="http://disktree.spektral.at/git/?a=summary&p=hxmpp">browsed online</a>.<br/> </div> <h2>XEPs implemented.</h2> - The <a href="http://xmpp.org/extensions">XEPs</a> marked with an asterisk already got used in a project but are in a experimental state. + <a href="http://xmpp.org/extensions">XEPs</a> marked with an asterisk already got used in a project but are in a experimental state. <ul> <li><a href="http://xmpp.org/extensions/xep-0004.html">XEP-0004 Data Forms</a></li> <li><a href="http://xmpp.org/extensions/xep-0012.html">XEP-0012 LastActivity</a></li> @@ -64,13 +63,13 @@ <h2>Installation/Usage.</h2> <div> Refer to the sample and test source code.<br/> - For use with the nekoVM you have to place /ndll/[YOUR-OS]/sha1.ndll somewhere reachable. + For use with nekoVM you have to place /ndll/[YOUR-OS]/sha1.ndll somewhere reachable. <p> - <b>Known compiler flags:</b> + <b>Compiler flags:</b> </p> <ul> <li class="biglist"><b>XMPP_DEBUG</b><br/> - Prints the XML input/output stream.<br/> + Prints the XMPP/XML input/output streams.<br/> <ul> <li>On flash/js firebug gets used if detected.</li> <li>On terminal targets output gets colored.</li> @@ -91,7 +90,7 @@ <h2>Issues.</h2> <div> - Report any issues to the issue tracker at <a href="http://code.google.com/p/hxmpp/issues/list">code.google.com</a>, or send an IM. + Report any issues to the issue tracker at <a href="http://code.google.com/p/hxmpp/issues/list">code.google.com</a>, or send a IM. </div> <h2>License.</h2> @@ -122,5 +121,6 @@ </td> </tr> -</table> -<div id="footer">© 2009 disktree.net</div> +</table><!-- +<div id="footer">© 2009 <a href="http://disktree.net">disktree.net</a></div> +--> \ No newline at end of file diff --git a/www/style.css b/www/style.css index 1f09b78..9a3afa9 100644 --- a/www/style.css +++ b/www/style.css @@ -1,96 +1,107 @@ * { - padding : 0 0 0 0; + padding: 0 0 0 0; } body { - margin : 0 0 0 0; - font-family : arial, verdana, sans-serif; - font-size : small; - background-color: #222222; - color: #999999; + margin: 0 0 0 0; + font-family: arial, verdana, sans-serif; + font-size: 11pt; + font-size-adjust: 0.46; + color: #666666; + background-color: white; } a img { - border: 0px; + border: 0px; } a { - color: #999999; - margin-right: 2px; + color: #666666; + margin-right: 2px; } a:hover { - color: #FFFFFF; + color: #fff; + background-color: #666666; } -.main { - width : 100%; +h3 { + font-size: 20pt; + font-family: "Franklin Gothic Heavy"; + margin-right: 100px; + margin-bottom: -12px; } -.main tr.banner { - background-image : url(img/banner_bg.png); - background-repeat : repeat-x; - height : 110px; +h2 { + font-size: 17pt; + font-family: "Franklin Gothic Heavy"; + letter-spacing: -1px; + margin-top: 40px; + margin-bottom: 2px; } -.main { - width : 100%; - vertical-align: top; +ul { + margin-left: 26px; } -.main img { - padding-left: 30px; - padding-top: 10px; +li { + padding-top: 3px; } -.content { - padding-left: 30px; - padding-bottom: 60px; +li.biglist { + padding-bottom: 10px; } -.command { - margin-top: 0px; - margin-bottom: 0px; - color: #aaaaaa; +.main { + width: 100%; } -h2 { - color: #222222; - font-size : 16pt; - letter-spacing: -1px; - color: #aaaaaa; - margin-top: 40px; - margin-bottom: 2px; +.main tr.banner { + /* + background-image: url(img/banner_bg.png); + background-repeat: repeat-x; + */ + height: 110px; } -h3 { - color: #bbbbbb; +.main { + width: 100%; + vertical-align: top; } -ul { - margin-left: 26px; +.main img { + padding-left: 30px; + padding-top: 10px; } -li { - padding-top: 3px; +.content { + padding-left: 30px; + padding-bottom: 60px; } -li.biglist { - padding-bottom: 10px; +.command { + margin-top: 0px; + margin-bottom: 0px; } #footer { - font-size: 9pt; - text-decoration: none; - position: fixed; - width: 100%; - height: 16px; - background-color: #333333; - color : #222222; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 10px; - bottom: 0; - z-index: 1; + font-size: 9pt; + text-decoration: none; + position: fixed; + width: 100%; + height: 12px; + background-color: #444444; + color: #444; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 10px; + bottom: 0; + z-index: 1; + -moz-box-shadow: -8px 0px 32px #777777, 0px 0px 10px #555555; +} + +#footer a { + color: #444; + text-decoration: none; } diff --git a/xmpp/Error.hx b/xmpp/Error.hx index 3a33f59..f866aef 100644 --- a/xmpp/Error.hx +++ b/xmpp/Error.hx @@ -22,13 +22,15 @@ package xmpp; */ class Error { - public static inline var XMLNS = "urn:ietf:params:xml:ns:xmpp-stanzas"; + public static var XMLNS = "urn:ietf:params:xml:ns:xmpp-stanzas"; public var type : ErrorType; public var code : Null<Int>; public var name : String; public var conditions : Array<{name:String,xmlns:String}>; public var text : String; + /** Custom (non XMPP) field to */ + //public var from : String; public function new( ?type : xmpp.ErrorType, ?code : Null<Int>, ?name : String, ?text : String ) { this.type = type; @@ -47,15 +49,14 @@ class Error { n.set( "xmlns", XMLNS ); x.addChild( n ); } - //TODO - /* - for( c in conditions ) { + if( conditions != null ) { + for( c in conditions ) + x.addChild( util.XmlUtil.createElement( c.name, c.xmlns ) ); } - */ return x; } - public inline function toString() : String { + public function toString() : String { return toXml().toString(); } diff --git a/xmpp/IQ.hx b/xmpp/IQ.hx index 9d150e8..7fd14cd 100644 --- a/xmpp/IQ.hx +++ b/xmpp/IQ.hx @@ -30,7 +30,7 @@ class IQ extends Packet { public function new( ?type : IQType, ?id : String, ?to : String, ?from ) { super( to, from, id ); _type = xmpp.PacketType.iq; - this.type = if( type != null ) type else xmpp.IQType.get; + this.type = ( type != null ) ? type : xmpp.IQType.get; } public override function toXml(): Xml { @@ -62,9 +62,9 @@ class IQ extends Packet { Creates a '<query xmlns="namspace"/>' xml tag. */ public static inline function createQueryXml( ns : String ) : Xml { - var q = Xml.createElement( "query" ); - q.set( "xmlns", ns ); - return q; + var x = Xml.createElement( "query" ); + x.set( "xmlns", ns ); + return x; } /** diff --git a/xmpp/PacketElement.hx b/xmpp/PacketElement.hx index c75c6ba..c57f80b 100644 --- a/xmpp/PacketElement.hx +++ b/xmpp/PacketElement.hx @@ -17,6 +17,7 @@ */ package xmpp; +//TODO TPacketElement typedef PacketElement = { function toXml() : Xml; } diff --git a/xmpp/Presence.hx b/xmpp/Presence.hx index 4e725c7..3fa02b2 100644 --- a/xmpp/Presence.hx +++ b/xmpp/Presence.hx @@ -40,18 +40,15 @@ class Presence extends Packet { } function setStatus( s : String ) : String { - if( s == null ) - return status = s; - if( s.length == 0 || s.length > 1023 ) - throw "Invalid presence status size "+s.length; - return status = s; + return status = ( ( s == null || s == "" ) ? null : ( s.length > 1023 ) ? s.substr( 0, 1023 ) : s ); } public override function toXml() : Xml { var x = super.addAttributes( Xml.createElement( "presence" ) ); if( type != null ) x.set( "type", Type.enumConstructor( type ) ); if( show != null ) x.addChild( XmlUtil.createElement( "show", Type.enumConstructor( show ) ) ); - if( status != null && status != "" ) x.addChild( XmlUtil.createElement( "status", status ) ); + //if( status != null && status != "" ) x.addChild( XmlUtil.createElement( "status", status ) ); + if( status != null ) x.addChild( XmlUtil.createElement( "status", status ) ); if( priority != null ) x.addChild( XmlUtil.createElement( "priority", Std.string( priority ) ) ); return x; } diff --git a/xmpp/PrivacyList.hx b/xmpp/PrivacyList.hx index a66c340..66eed6b 100644 --- a/xmpp/PrivacyList.hx +++ b/xmpp/PrivacyList.hx @@ -22,13 +22,11 @@ class PrivacyList { public var name : String; public var items : Array<xmpp.privacylist.Item>; - public function new( name : String ) { this.name = name; items = new Array(); } - public function toXml() : Xml { var x = Xml.createElement( "list" ); x.set( "name", name ); @@ -36,14 +34,14 @@ class PrivacyList { return x; } - public inline function toString() : String { return toXml().toString(); } - + public inline function toString() : String { + return toXml().toString(); + } public static function parse( x : Xml ) : xmpp.PrivacyList { var p = new xmpp.PrivacyList( x.get( "name" ) ); - for( e in x.elementsNamed( "item" ) ) { + for( e in x.elementsNamed( "item" ) ) p.items.push( xmpp.privacylist.Item.parse( e ) ); - } return p; } diff --git a/xmpp/PubSub.hx b/xmpp/PubSub.hx index 301edb4..30e7f51 100644 --- a/xmpp/PubSub.hx +++ b/xmpp/PubSub.hx @@ -22,73 +22,56 @@ class PubSub { public static var XMLNS = xmpp.NS.PROTOCOL+"/pubsub"; public var subscribe : { node : String, jid : String }; - public var unsubscribe : { node : String, jid : String, subid : String }; + public var options : xmpp.pubsub.Options; + public var affiliations : xmpp.pubsub.Affiliations; public var create : String; public var configure : xmpp.DataForm; - public var subscription : xmpp.pubsub.Subscription; - public var subscriptions : xmpp.pubsub.Subscriptions; public var items : xmpp.pubsub.Items; public var publish : xmpp.pubsub.Publish; public var retract : xmpp.pubsub.Retract; - public var affiliations : xmpp.pubsub.Affiliations; - public var options : xmpp.pubsub.Options; + public var subscription : xmpp.pubsub.Subscription; + public var subscriptions : xmpp.pubsub.Subscriptions; + //public var default : { node : String, type : NodeType }; + public var unsubscribe : { node : String, jid : String, subid : String }; - public function new() { - } + public function new() {} public function toXml() : Xml { var x = Xml.createElement( "pubsub" ); x.set( "xmlns", XMLNS ); - if( subscribe != null ) { + var c = if( subscribe != null ) { var e = Xml.createElement( "subscribe" ); e.set( "jid", subscribe.jid ); if( subscribe.node != null ) e.set( "node", subscribe.node ); - x.addChild( e ); - return x; - } - if( unsubscribe != null ) { + e; + } else if( unsubscribe != null ) { var e = Xml.createElement( "unsubscribe" ); e.set( "jid", unsubscribe.jid ); if( unsubscribe.node != null ) e.set( "node", unsubscribe.node ); if( unsubscribe.subid != null ) e.set( "subid", unsubscribe.subid ); - x.addChild( e ); - return x; - } - if( create != null ) { + e; + } else if( create != null ) { var e = Xml.createElement( "create" ); e.set( "node", create ); - x.addChild( e ); - var c = Xml.createElement( "configure" ); - if( configure != null ) - c.addChild( configure.toXml() ); - e.addChild( c ); - return x; - } - if( subscription != null ) { - x.addChild( subscription.toXml() ); - return x; - } - if( subscriptions != null ) { - x.addChild( subscriptions.toXml() ); - return x; - } - if( publish != null ) { - x.addChild( publish.toXml() ); - return x; - } - if( items != null ) { - x.addChild( items.toXml() ); - return x; - } - if( retract != null ) { - x.addChild( retract.toXml() ); - return x; - } - if( affiliations != null ) { - x.addChild( affiliations.toXml() ); - return x; + var conf = Xml.createElement( "configure" ); + if( configure != null ) conf.addChild( configure.toXml() ); + e.addChild( conf ); + e; + } else if( subscription != null ) { + subscription.toXml(); + } else if( subscriptions != null ) { + subscriptions.toXml(); + } else if( publish != null ) { + publish.toXml(); + } else if( items != null ) { + items.toXml(); + } else if( retract != null ) { + retract.toXml(); + } else if( affiliations != null ) { + affiliations.toXml(); } - return null; + if( c != null ) x.addChild( c ); + return x; } public inline function toString() : String { diff --git a/xmpp/PubSubEvent.hx b/xmpp/PubSubEvent.hx index 3b4e487..a417fcc 100644 --- a/xmpp/PubSubEvent.hx +++ b/xmpp/PubSubEvent.hx @@ -19,7 +19,7 @@ package xmpp; class PubSubEvent { - public static inline var XMLNS = xmpp.PubSub.XMLNS+"#event"; + public static var XMLNS = PubSub.XMLNS+"#event"; public var items : xmpp.pubsub.Items; public var configuration : { form : xmpp.DataForm, node : String }; diff --git a/xmpp/PubSubOwner.hx b/xmpp/PubSubOwner.hx index 3f0cf18..a94f9f6 100644 --- a/xmpp/PubSubOwner.hx +++ b/xmpp/PubSubOwner.hx @@ -19,7 +19,7 @@ package xmpp; class PubSubOwner { - public static var XMLNS = xmpp.PubSub.XMLNS+"#owner"; + public static var XMLNS = PubSub.XMLNS+"#owner"; /** Set to "" to add a empty delete element */ public var delete : String; diff --git a/xmpp/VCard.hx b/xmpp/VCard.hx index c8f7acf..7cfaf26 100644 --- a/xmpp/VCard.hx +++ b/xmpp/VCard.hx @@ -85,6 +85,110 @@ class VCard { var x = Xml.createElement( NODENAME ); x.set( "xmlns", XMLNS ); if( fn != null ) x.addChild( XmlUtil.createElement( "FN", fn ) ); + if( n != null ) { + var _n = Xml.createElement( "N" ); + if( n.family != null ) _n.addChild( XmlUtil.createElement( "FAMILY", n.family ) ); + if( n.given != null ) _n.addChild( XmlUtil.createElement( "GIVEN", n.given ) ); + if( n.middle != null ) _n.addChild( XmlUtil.createElement( "MIDDLE", n.middle ) ); + if( n.prefix != null ) _n.addChild( XmlUtil.createElement( "PREFIX", n.prefix ) ); + if( n.suffix != null ) _n.addChild( XmlUtil.createElement( "SUFFIX", n.suffix ) ); + x.addChild( _n ); + } + if( nickname != null ) x.addChild( XmlUtil.createElement( "NN", nickname ) ); + if( photo != null ) { + var p = Xml.createElement( "PHOTO" ); + p.addChild( XmlUtil.createElement( "TYPE", photo.type ) ); + p.addChild( XmlUtil.createElement( "BINVAL", photo.binval ) ); + x.addChild( p ); + } + if( birthday != null ) x.addChild( XmlUtil.createElement( "BDAY", birthday ) ); + for( address in addresses ) { + var a = Xml.createElement( "ADR" ); + if( address.home != null ) a.addChild( XmlUtil.createElement( "HOME", address.home ) ); + if( address.work != null ) a.addChild( XmlUtil.createElement( "WORK", address.work ) ); + if( address.postal != null ) a.addChild( XmlUtil.createElement( "POSTAL", address.postal ) ); + if( address.parcel != null ) a.addChild( XmlUtil.createElement( "PARCEL", address.parcel ) ); + if( address.pref != null ) a.addChild( XmlUtil.createElement( "PREF", address.pref ) ); + if( address.pobox != null ) a.addChild( XmlUtil.createElement( "POBOX", address.pobox ) ); + if( address.extadd != null ) a.addChild( XmlUtil.createElement( "EXTADD", address.extadd ) ); + if( address.street != null ) a.addChild( XmlUtil.createElement( "STREET", address.street ) ); + if( address.locality!=null ) a.addChild( XmlUtil.createElement( "LOCALITY", address.locality ) ); + if( address.region != null ) a.addChild( XmlUtil.createElement( "REGION", address.region ) ); + if( address.pcode != null ) a.addChild( XmlUtil.createElement( "PCODE", address.pcode ) ); + if( address.ctry != null ) a.addChild( XmlUtil.createElement( "CTRY", address.ctry ) ); + x.addChild( a ); + } + if( label != null ) { + var l = Xml.createElement( "LABEL" ); + if( label.home != null ) l.addChild( XmlUtil.createElement( "HOME", label.home ) ); + if( label.work != null ) l.addChild( XmlUtil.createElement( "HOME", label.work ) ); + if( label.postal != null ) l.addChild( XmlUtil.createElement( "HOME", label.postal ) ); + if( label.parcel != null ) l.addChild( XmlUtil.createElement( "HOME", label.parcel ) ); + if( label.pref != null ) l.addChild( XmlUtil.createElement( "HOME", label.pref ) ); + if( label.line != null ) l.addChild( XmlUtil.createElement( "HOME", label.line ) ); + x.addChild( l ); + } + if( line != null ) x.addChild( XmlUtil.createElement( "LINE", line ) ); + for( tel in tels ) { + var t = Xml.createElement( "TEL" ); + if( tel.number != null ) t.addChild( XmlUtil.createElement( "NUMBER", tel.number ) ); + if( tel.home != null ) t.addChild( XmlUtil.createElement( "HOME", tel.home ) ); + if( tel.work != null ) t.addChild( XmlUtil.createElement( "WORK", tel.work ) ); + if( tel.voice != null ) t.addChild( XmlUtil.createElement( "VOICE", tel.voice ) ); + if( tel.fax != null ) t.addChild( XmlUtil.createElement( "FAX", tel.fax ) ); + if( tel.pager != null ) t.addChild( XmlUtil.createElement( "PAGER", tel.pager ) ); + if( tel.msg != null ) t.addChild( XmlUtil.createElement( "MSG", tel.msg ) ); + if( tel.cell != null ) t.addChild( XmlUtil.createElement( "CELL", tel.cell ) ); + if( tel.video != null ) t.addChild( XmlUtil.createElement( "VIDEO", tel.video ) ); + if( tel.bbs != null ) t.addChild( XmlUtil.createElement( "BBS", tel.bbs ) ); + if( tel.modem != null ) t.addChild( XmlUtil.createElement( "MODEM", tel.modem ) ); + if( tel.isdn != null ) t.addChild( XmlUtil.createElement( "ISDN", tel.isdn ) ); + if( tel.pcs != null ) t.addChild( XmlUtil.createElement( "PCS", tel.pcs ) ); + if( tel.pref != null ) t.addChild( XmlUtil.createElement( "PREF", tel.pref ) ); + x.addChild( t ); + } + if( email != null ) { + var e = Xml.createElement( "EMAIL" ); + if( email.home != null ) e.addChild( XmlUtil.createElement( "HOME", email.home ) ); + if( email.work != null ) e.addChild( XmlUtil.createElement( "WORK", email.work ) ); + if( email.internet != null ) e.addChild( XmlUtil.createElement( "INTERNET", email.internet ) ); + if( email.pref != null ) e.addChild( XmlUtil.createElement( "PREF", email.pref ) ); + if( email.x400 != null ) e.addChild( XmlUtil.createElement( "X400", email.x400 ) ); + if( email.userid != null ) e.addChild( XmlUtil.createElement( "USERID", email.userid ) ); + x.addChild( e ); + } + if( jid != null ) x.addChild( XmlUtil.createElement( "JABBERID", jid ) ); + if( mailer != null ) x.addChild( XmlUtil.createElement( "MAILER", mailer ) ); + if( tz != null ) x.addChild( XmlUtil.createElement( "TZ", tz ) ); + if( geo != null ) { + var g = Xml.createElement( "GEO" ); + g.addChild( XmlUtil.createElement( "LAT", Std.string( geo.lat ) ) ); + g.addChild( XmlUtil.createElement( "LON", Std.string( geo.lon ) ) ); + x.addChild( g ); + } + if( title != null ) x.addChild( XmlUtil.createElement( "TITLE", title ) ); + if( role != null ) x.addChild( XmlUtil.createElement( "ROLE", role ) ); + if( logo != null ) { + var l = Xml.createElement( "LOGO" ); + l.addChild( XmlUtil.createElement( "TYPE", logo.type ) ); + l.addChild( XmlUtil.createElement( "BINVAL", logo.binval ) ); + x.addChild( l ); + } + if( org != null ) { + var o = Xml.createElement( "ORG" ); + if( org.orgname != null ) o.addChild( XmlUtil.createElement( "NAME", org.orgname ) ); + if( org.orgunit != null ) o.addChild( XmlUtil.createElement( "UNIT", org.orgunit ) ); + x.addChild( o ); + } + if( note != null ) x.addChild( XmlUtil.createElement( "NOTE", note ) ); + if( prodid != null ) x.addChild( XmlUtil.createElement( "PRODID", prodid ) ); + if( url != null ) x.addChild( XmlUtil.createElement( "URL", url ) ); + if( desc != null ) x.addChild( XmlUtil.createElement( "DESC", desc ) ); + return x; + /* + var x = Xml.createElement( NODENAME ); + x.set( "xmlns", XMLNS ); + if( fn != null ) x.addChild( XmlUtil.createElement( "FN", fn ) ); if( n != null ) x.addChild( createTypedefXml( "N", n ) ); if( nickname != null ) x.addChild( XmlUtil.createElement( "NICKNAME", nickname ) ); if( photo != null ) x.addChild( createTypedefXml( "PHOTO", photo ) ); @@ -112,6 +216,7 @@ class VCard { if( url != null ) x.addChild( XmlUtil.createElement( "URL", url ) ); if( desc != null ) x.addChild( XmlUtil.createElement( "DESC", desc ) ); return x; + */ } public inline function toString() : String { @@ -125,6 +230,7 @@ class VCard { } */ + /* function createTypedefXml<T>( name : String, e : T ) : Xml { var x = Xml.createElement( name ); for( f in Reflect.fields( e ) ) { @@ -135,10 +241,146 @@ class VCard { } return x; } + */ public static function parse( x : Xml ) : xmpp.VCard { var vc = new xmpp.VCard(); for( node in x.elements() ) { + + switch( node.nodeName ) { + case "FN" : vc.fn = node.firstChild().nodeValue; + case "N" : + vc.n = { family:null, given:null, middle:null, prefix:null, suffix:null }; + for( n in node.elements() ) { + var value : String = null; + try { + var fc = n.firstChild(); + if( vc != null ) value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "FAMILY" : vc.n.family = value; + case "GIVEN" : vc.n.given = value; + case "MIDDLE" : vc.n.middle = value; + case "PREFIX" : vc.n.prefix = value; + case "SUFFIX" : vc.n.suffix = value; + } + } + } + //case "NICKNAME" : trace("#############################");vc.nickName = node.firstChild().nodeValue; + case "PHOTO" : vc.photo = parsePhoto( node ); + case "BDAY" : vc.birthday = node.firstChild().nodeValue; + case "ADR" : + var adr : Address = untyped {}; + for( n in node.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "HOME" : adr.home = value; + case "WORK" : adr.work = value; + case "POSTAL" : adr.postal = value; + case "PARCEL" : adr.parcel = value; + //case "DOM/INTL" : + case "PREF" : adr.pref = value; + case "POBOX" : adr.pobox = value; + case "EXTADD" : adr.extadd = value; + case "STREET" : adr.street = value; + case "LOCALITY" : adr.locality = value; + case "REGION" : adr.region = value; + case "PCODE" : adr.pcode = value; + case "CTRY" : adr.ctry = value; + } + } + } + vc.addresses.push( adr ); + case "LABEL" : + //TODO + + case "LINE" : vc.line = node.firstChild().nodeValue; + case "TEL" : + var tel : Tel = untyped {}; + for( n in node.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "NUMBER" : tel.number = value; + case "HOME" : tel.home = value; + case "WORK" : tel.work = value; + case "VOICE" : tel.voice = value; + case "FAX" : tel.fax = value; + case "PAGER" : tel.pager = value; + case "MSG" : tel.msg = value; + case "CELL" : tel.cell = value; + case "VIDEO" : tel.video = value; + case "BBS" : tel.bbs = value; + case "MODEM" : tel.modem = value; + case "ISDN" : tel.isdn = value; + case "PCS" : tel.pcs = value; + case "PREF" : tel.pref = value; + } + } + } + vc.tels.push( tel ); + case "EMAIL" : + vc.email = untyped {}; + for( n in node.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "HOME" : vc.email.home = value; + case "WORK" : vc.email.work = value; + case "INTERNET" : vc.email.internet = value; + case "PREF" : vc.email.pref = value; + case "X400" : vc.email.x400 = value; + case "USERID" : vc.email.userid = value; + } + } + } + case "JABBERID" : vc.jid = node.firstChild().nodeValue; + case "MAILER" : vc.mailer = node.firstChild().nodeValue; + case "TZ" : vc.tz = node.firstChild().nodeValue; + case "GEO" : + vc.geo = untyped {}; + for( n in node.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value == null ) throw "Invalid vcard tz"; + switch( n.nodeName ) { + case "LAT" : vc.geo.lat = Std.parseInt( value ); + case "LON" : vc.geo.lon = Std.parseInt( value ); + } + } + case "TITLE" : vc.title = node.firstChild().nodeValue; + case "ROLE" : vc.role = node.firstChild().nodeValue; + case "LOGO" : vc.logo = parsePhoto( node ); + case "AGENT" : + //TODO + + case "ORG" : + vc.org = untyped {}; + for( n in node.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "ORGNAME" : vc.org.orgname = value; + case "ORGUNIT" : vc.org.orgunit = value; + } + } + } + case "NOTE" : vc.note = node.firstChild().nodeValue; + case "PRODID" : vc.prodid = node.firstChild().nodeValue; + //......... + case "URL" : vc.url = node.firstChild().nodeValue; + case "DESC" : vc.desc = node.firstChild().nodeValue; + } + } + return vc; + /* + var vc = new xmpp.VCard(); + for( node in x.elements() ) { switch( node.nodeName ) { case "FN" : vc.fn = node.firstChild().nodeValue; case "N" : reflectTypedef( vc.n = untyped {}, node ); @@ -176,17 +418,40 @@ class VCard { } } return vc; + */ } + /* static function reflectTypedef<T>( e : T, x : Xml ) : T { for( n in x.elements() ) { var v : String = null; - try v = n.firstChild().nodeValue catch( e : Dynamic ) {} + try { + var c = n.firstChild(); + if( c != null ) v = c.nodeValue; + } catch( e : Dynamic ) { + trace(e); + } if( v != null ) { Reflect.setField( e, n.nodeName.toLowerCase(), v ); } } return e; } + */ + + static function parsePhoto( x : Xml ) : xmpp.vcard.Photo { + var photo = untyped {}; + for( n in x.elements() ) { + var value : String = null; + try { value = n.firstChild().nodeValue; } catch( e : Dynamic ) {} + if( value != null ) { + switch( n.nodeName ) { + case "TYPE" : photo.type = value; + case "BINVAL" : photo.binval = value; + } + } + } + return photo; + } } diff --git a/xmpp/privacylist/Item.hx b/xmpp/privacylist/Item.hx index ce2a56e..5149c8b 100644 --- a/xmpp/privacylist/Item.hx +++ b/xmpp/privacylist/Item.hx @@ -40,7 +40,7 @@ class Item { return x; } - public function toString() : String { + public inline function toString() : String { return toXml().toString(); } diff --git a/xmpp/pubsub/Affiliation.hx b/xmpp/pubsub/Affiliation.hx index 439fbea..1d36ed3 100644 --- a/xmpp/pubsub/Affiliation.hx +++ b/xmpp/pubsub/Affiliation.hx @@ -34,7 +34,7 @@ class Affiliation { return x; } - public static function parse( x : Xml) : Affiliation { + public static inline function parse( x : Xml) : Affiliation { return new Affiliation( x.get( "node" ), Type.createEnum( AffiliationState, x.get( "affiliation" ) ) ); } diff --git a/xmpp/pubsub/Item.hx b/xmpp/pubsub/Item.hx index 344642c..c0f67f3 100644 --- a/xmpp/pubsub/Item.hx +++ b/xmpp/pubsub/Item.hx @@ -20,20 +20,20 @@ package xmpp.pubsub; class Item { public var id : String; + public var payload : Xml; // TODO String ? /** The node attribute is allowed (required!) in pubsub-event namespace only! */ public var node : String; - public var payload : Xml; // TODO String ? - public function new( ?id : String, ?payload : Xml, ?node : String ) { + public function new( ?id : String, ?payload : Xml/*, ?node : String*/ ) { this.id = id; this.payload = payload; - this.node = node; + //this.node = node; } public function toXml() : Xml { var x = Xml.createElement( "item" ); if( id != null ) x.set( "id", id ); - if( node != null ) x.set( "node", node ); + //if( node != null ) x.set( "node", node ); if( payload != null ) x.addChild( payload ); return x; } @@ -43,9 +43,9 @@ class Item { } public static function parse( x : Xml ) : Item { - var payload = x.firstElement(); - if( payload == null ) payload = x.firstChild(); - return new Item( x.get( "id" ), payload, x.get( "node" ) ); + var pl = x.firstElement(); + if( pl == null ) pl = x.firstChild(); + return new Item( x.get( "id" ), pl/*, x.get( "node" )*/ ); } } diff --git a/xmpp/pubsub/Options.hx b/xmpp/pubsub/Options.hx index 7e1c006..ad89f9c 100644 --- a/xmpp/pubsub/Options.hx +++ b/xmpp/pubsub/Options.hx @@ -33,6 +33,7 @@ class Options { public function toXml() : Xml { var x = Xml.createElement( "options" ); + if( jid != null ) x.set( "jid", jid ); if( node != null ) x.set( "node", node ); if( subid != null ) x.set( "subid", subid ); if( form != null ) x.addChild( form.toXml() ); diff --git a/xmpp/pubsub/Publish.hx b/xmpp/pubsub/Publish.hx index fb2103f..63d3504 100644 --- a/xmpp/pubsub/Publish.hx +++ b/xmpp/pubsub/Publish.hx @@ -24,9 +24,9 @@ class Publish extends List<Item> { public function new( node : String, ?items : Iterable<Item> ) { super(); this.node = node; - if( items!= null ) - for( i in items ) - add( i ); + if( items!= null ) { + for( i in items ) add( i ); + } } public function toXml() : Xml {