mod_fdajax-0.9/0000755000175000017500000000000010652360322012107 5ustar greggregmod_fdajax-0.9/README0000644000175000017500000000013410650657625013002 0ustar greggregFor more information about FdAjax module please visit http://www.refwell.com/blog web site. mod_fdajax-0.9/LICENSE0000644000175000017500000000274210650376710013127 0ustar greggregCopyright (c) 2007, Grzegorz Daniluk, GD Consulting All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the GD Consulting nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mod_fdajax-0.9/src/0000755000175000017500000000000010652360363012703 5ustar greggregmod_fdajax-0.9/src/mod_fdajax_events.c0000640000175000017500000000560610641300132016514 0ustar greggreg#include "mod_fdajax_defs.h" unsigned int g_ev_mask_by_index[FDA_TYPES_MAX] = { FDA_EV_UNW, FDA_EV_GEN, FDA_EV_CHAT, FDA_EV_TOQ, FDA_EV_TWP, FDA_EV_SUO, FDA_EV_SUS, FDA_EV_SHO, FDA_EV_SHS, FDA_EV_SHC, FDA_EV_MES, FDA_EV_ORD, FDA_EV_CCD, FDA_EV_ITM, FDA_EV_LNE, FDA_EV_USR, FDA_GRP_MAIN, FDA_GRP_CHAT, FDA_GRP_QUES, FDA_GRP_ANSW, FDA_GRP_OFRS, FDA_GRP_PRIC, FDA_GRP_OPIN, FDA_GRP_USER, FDA_GRP_ORDS, FDA_GRP_GEIC, FDA_GRP_FEED, FDA_GRP_MESE, FDA_GRP_NETK, FDA_GRP_TASK, FDA_GRP_FRID, FDA_GRP_INFO }; char *g_ev_name_by_index[FDA_TYPES_MAX] = { "unw", "gen", "chat", "toq", "twp", "suo", "sus", "sho", "shs", "shc", "mes", "ord", "ccd", "itm", "lne", "usr", "main", "gchat", "ques", "answ", "ofrs", "pric", "opin", "users", "ords", "geic", "feed", "mese", "netk", "task", "frid", "info" }; int event_bit_to_index(unsigned int ev) { switch (ev) { case FDA_EV_UNW: return 0; case FDA_EV_GEN: return 1; case FDA_EV_CHAT: return 2; case FDA_EV_TOQ: return 3; case FDA_EV_TWP: return 4; case FDA_EV_SUO: return 5; case FDA_EV_SUS: return 6; case FDA_EV_SHO: return 7; case FDA_EV_SHS: return 8; case FDA_EV_SHC: return 9; case FDA_EV_MES: return 10; case FDA_EV_ORD: return 11; case FDA_EV_CCD: return 12; case FDA_EV_ITM: return 13; case FDA_EV_LNE: return 14; case FDA_EV_USR: return 15; case FDA_GRP_MAIN: return 16; case FDA_GRP_CHAT: return 17; case FDA_GRP_QUES: return 18; case FDA_GRP_ANSW: return 19; case FDA_GRP_OFRS: return 20; case FDA_GRP_PRIC: return 21; case FDA_GRP_OPIN: return 22; case FDA_GRP_USER: return 23; case FDA_GRP_ORDS: return 24; case FDA_GRP_GEIC: return 25; case FDA_GRP_FEED: return 26; case FDA_GRP_MESE: return 27; case FDA_GRP_NETK: return 28; case FDA_GRP_TASK: return 29; case FDA_GRP_FRID: return 30; case FDA_GRP_INFO: return 31; default: assert(0); } } int event_find_index_by_name(char *s) { int i; if (NULL == s) { return -1; } for (i = 0; i < FDA_TYPES_MAX; i++) { printf("%d %s %s\n", i, s, g_ev_name_by_index[i]); if (strcmp(s, g_ev_name_by_index[i]) == 0) { return i; } } return -1; } int event_check_ids(win_info_p win, mes_info_p mes, int ev_nr) { int win_i, mes_i, ret = FALSE; if (0 == win->ev.ids_len[ev_nr]) { /* zero means any id */ ret = TRUE; } else if (0 == mes->ev.ids_len[ev_nr]) { /* ??? */ ret = TRUE; } else { /* TRUE if win ids set include any of id from mes set */ for (mes_i = 0; (!ret) && (mes_i < mes->ev.ids_len[ev_nr]); mes_i++) { for (win_i = 0; win_i < win->ev.ids_len[ev_nr]; win_i++) { if (mes->ev.ids[ev_nr][mes_i] == win->ev.ids[ev_nr][win_i]) { ret = TRUE; break; } } } } return ret; } mod_fdajax-0.9/src/mod_fdajax_peercall.c0000640000175000017500000002650110650365730017013 0ustar greggreg#line 1 "mod_fdajax_peercall.rl" #include #include #include #include "mod_fdajax_defs.h" #line 18 "mod_fdajax_peercall.rl" #line 13 "mod_fdajax_peercall.c" static const int fdamod_peercall_start = 1; static const int fdamod_peercall_first_final = 48; static const int fdamod_peercall_error = 0; static const int fdamod_peercall_en_main = 1; #line 21 "mod_fdajax_peercall.rl" int mod_fdajax_cinit(int *pcs) { int cs = 0; #line 26 "mod_fdajax_peercall.c" { cs = fdamod_peercall_start; } #line 26 "mod_fdajax_peercall.rl" *pcs = cs; return 1; } int mod_fdajax_cexec(int *pcs, char *start, size_t len) { char *p, *pe; int cs = *pcs; assert(*(start + len) == 0); p = start; pe = start + len + 1; #line 44 "mod_fdajax_peercall.c" { if ( p == pe ) goto _out; switch ( cs ) { case 1: switch( (*p) ) { case 34: goto st2; case 45: goto st6; } if ( 48 <= (*p) && (*p) <= 57 ) goto st7; goto st0; st0: goto _out0; st2: if ( ++p == pe ) goto _out2; case 2: switch( (*p) ) { case 34: goto st3; case 92: goto st47; case 127: goto st0; } if ( 0 <= (*p) && (*p) <= 31 ) goto st0; goto st2; st3: if ( ++p == pe ) goto _out3; case 3: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } goto st0; st48: if ( ++p == pe ) goto _out48; case 48: goto st0; st4: if ( ++p == pe ) goto _out4; case 4: switch( (*p) ) { case 32: goto st4; case 44: goto st5; } goto st0; st5: if ( ++p == pe ) goto _out5; case 5: switch( (*p) ) { case 32: goto st5; case 34: goto st2; case 45: goto st6; } if ( 48 <= (*p) && (*p) <= 57 ) goto st7; goto st0; st6: if ( ++p == pe ) goto _out6; case 6: if ( 48 <= (*p) && (*p) <= 57 ) goto st7; goto st0; st7: if ( ++p == pe ) goto _out7; case 7: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st28; goto st0; st8: if ( ++p == pe ) goto _out8; case 8: if ( 48 <= (*p) && (*p) <= 57 ) goto st9; goto st0; st9: if ( ++p == pe ) goto _out9; case 9: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st10; goto st0; st10: if ( ++p == pe ) goto _out10; case 10: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st11; goto st0; st11: if ( ++p == pe ) goto _out11; case 11: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st12; goto st0; st12: if ( ++p == pe ) goto _out12; case 12: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st13; goto st0; st13: if ( ++p == pe ) goto _out13; case 13: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st14; goto st0; st14: if ( ++p == pe ) goto _out14; case 14: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st15; goto st0; st15: if ( ++p == pe ) goto _out15; case 15: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st16; goto st0; st16: if ( ++p == pe ) goto _out16; case 16: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st17; goto st0; st17: if ( ++p == pe ) goto _out17; case 17: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st18; goto st0; st18: if ( ++p == pe ) goto _out18; case 18: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st19; goto st0; st19: if ( ++p == pe ) goto _out19; case 19: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st20; goto st0; st20: if ( ++p == pe ) goto _out20; case 20: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st21; goto st0; st21: if ( ++p == pe ) goto _out21; case 21: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st22; goto st0; st22: if ( ++p == pe ) goto _out22; case 22: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st23; goto st0; st23: if ( ++p == pe ) goto _out23; case 23: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st24; goto st0; st24: if ( ++p == pe ) goto _out24; case 24: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st25; goto st0; st25: if ( ++p == pe ) goto _out25; case 25: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st26; goto st0; st26: if ( ++p == pe ) goto _out26; case 26: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st27; goto st0; st27: if ( ++p == pe ) goto _out27; case 27: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto st3; goto st0; st28: if ( ++p == pe ) goto _out28; case 28: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st29; goto st0; st29: if ( ++p == pe ) goto _out29; case 29: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st30; goto st0; st30: if ( ++p == pe ) goto _out30; case 30: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st31; goto st0; st31: if ( ++p == pe ) goto _out31; case 31: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st32; goto st0; st32: if ( ++p == pe ) goto _out32; case 32: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st33; goto st0; st33: if ( ++p == pe ) goto _out33; case 33: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st34; goto st0; st34: if ( ++p == pe ) goto _out34; case 34: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st35; goto st0; st35: if ( ++p == pe ) goto _out35; case 35: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st36; goto st0; st36: if ( ++p == pe ) goto _out36; case 36: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st37; goto st0; st37: if ( ++p == pe ) goto _out37; case 37: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st38; goto st0; st38: if ( ++p == pe ) goto _out38; case 38: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st39; goto st0; st39: if ( ++p == pe ) goto _out39; case 39: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st40; goto st0; st40: if ( ++p == pe ) goto _out40; case 40: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st41; goto st0; st41: if ( ++p == pe ) goto _out41; case 41: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st42; goto st0; st42: if ( ++p == pe ) goto _out42; case 42: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st43; goto st0; st43: if ( ++p == pe ) goto _out43; case 43: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st44; goto st0; st44: if ( ++p == pe ) goto _out44; case 44: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st45; goto st0; st45: if ( ++p == pe ) goto _out45; case 45: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } if ( 48 <= (*p) && (*p) <= 57 ) goto st46; goto st0; st46: if ( ++p == pe ) goto _out46; case 46: switch( (*p) ) { case 0: goto st48; case 32: goto st4; case 44: goto st5; case 46: goto st8; } goto st0; st47: if ( ++p == pe ) goto _out47; case 47: switch( (*p) ) { case 34: goto st2; case 92: goto st2; case 102: goto st2; case 110: goto st2; case 114: goto st2; case 116: goto st2; } goto st0; } _out0: cs = 0; goto _out; _out2: cs = 2; goto _out; _out3: cs = 3; goto _out; _out48: cs = 48; goto _out; _out4: cs = 4; goto _out; _out5: cs = 5; goto _out; _out6: cs = 6; goto _out; _out7: cs = 7; goto _out; _out8: cs = 8; goto _out; _out9: cs = 9; goto _out; _out10: cs = 10; goto _out; _out11: cs = 11; goto _out; _out12: cs = 12; goto _out; _out13: cs = 13; goto _out; _out14: cs = 14; goto _out; _out15: cs = 15; goto _out; _out16: cs = 16; goto _out; _out17: cs = 17; goto _out; _out18: cs = 18; goto _out; _out19: cs = 19; goto _out; _out20: cs = 20; goto _out; _out21: cs = 21; goto _out; _out22: cs = 22; goto _out; _out23: cs = 23; goto _out; _out24: cs = 24; goto _out; _out25: cs = 25; goto _out; _out26: cs = 26; goto _out; _out27: cs = 27; goto _out; _out28: cs = 28; goto _out; _out29: cs = 29; goto _out; _out30: cs = 30; goto _out; _out31: cs = 31; goto _out; _out32: cs = 32; goto _out; _out33: cs = 33; goto _out; _out34: cs = 34; goto _out; _out35: cs = 35; goto _out; _out36: cs = 36; goto _out; _out37: cs = 37; goto _out; _out38: cs = 38; goto _out; _out39: cs = 39; goto _out; _out40: cs = 40; goto _out; _out41: cs = 41; goto _out; _out42: cs = 42; goto _out; _out43: cs = 43; goto _out; _out44: cs = 44; goto _out; _out45: cs = 45; goto _out; _out46: cs = 46; goto _out; _out47: cs = 47; goto _out; _out: {} } #line 39 "mod_fdajax_peercall.rl" *pcs = cs; return 1; } int mod_fdajax_cfinish(int *pcs) { int cs = *pcs; #line 683 "mod_fdajax_peercall.c" #line 48 "mod_fdajax_peercall.rl" *pcs = cs; if (cs == fdamod_peercall_error) { return -1; } else if (cs >= fdamod_peercall_first_final) { return 1; } return 0; } mod_fdajax-0.9/src/mod_fdajax_chat.c0000640000175000017500000000214310641300132016120 0ustar greggreg#include "mod_fdajax_defs.h" enum gdc_cmd_t chat_add_peer(user_info_p user, int peer_id) { size_t i; enum gdc_cmd_t ret = cmdr_cuser_too_many; for(i = 0; i < PEERS_MAX; i++) { if (ret == cmdr_cuser_too_many) { if (user->peers[i] == 0) { user->peers[i] = peer_id; ret = cmdr_chat_peer_add; } } else if (ret == cmdr_chat_peer_add) { /* make sure there's no duplicates */ if (user->peers[i] == peer_id) { user->peers[i] = 0; } } else { assert(0); } } return ret; } enum gdc_cmd_t chat_rm_peer(user_info_p user, int peer_id) { size_t i; for(i = 0; i < PEERS_MAX; i++) { if (user->peers[i] == peer_id) { user->peers[i] = 0; return cmdr_chat_peer_rm_1; } } return cmdr_cuser_not_found; } int chat_access_peer(user_info_p user, int peer_id) { size_t i; for(i = 0; i < PEERS_MAX; i++) { if (user->peers[i] == peer_id) { return TRUE; } } return FALSE; } mod_fdajax-0.9/src/mod_fdajax.c0000640000175000017500000014472510650374173015156 0ustar greggreg#include "mod_fdajax_defs.h" /* Code generated with Ragel v. 5.22 */ /* ragel mod_fdajax_parser.rl | rlgen-cd -G2 -o mod_fdajax_parser.c */ /* ragel mod_fdajax_peercall.rl | rlgen-cd -G2 -o mod_fdajax_peercall.c */ /* strings sent to browser as response */ char *g_answer[] = { "CMD_OK", /* 0 */ "MEM_RESOURCES_PROBLEM", /* 1 */ "NOT_IN_CHAT", /* 2 */ "MESSAGE_SENT", /* 3 */ "USER_NOT_LOGGED", /* 4 */ "ALREADY_LOGGED", /* 5 */ "LOGIN_OK", /* 6 */ "LOGOUT_OK", /* 7 */ "USER_NOT_FOUND", /* 8 */ "CHAT_PEER_ADD", /* 9 */ "CHAT_PEER_RM_1", /* 10 */ "CHAT_PEER_RM_2", /* 11 */ "CUSER_NOT_FOUND", /* 12 */ "CUSER_TOO_MANY", /* 13 */ "WRONG_SYNTAX", /* 14 */ "USER_ACTIVE", /* 15 */ "LOGIN_BAD_ID", /* 16 */ "LOGIN_OLD_SESS", /* 17 */ "GRP_NOT_FOUND" /* 18 */ }; char g_timeval_buf[64]; char *tv2s(struct timeval atv) { char dt[32]; strftime(dt, sizeof(dt), "%F %T", gmtime(&(atv.tv_sec))); sprintf(g_timeval_buf, "%s:%ld", dt, atv.tv_usec); return g_timeval_buf; } void buffer_append_nl(buffer *buf) { if (buf->used > 1 && buf->ptr[buf->used - 2] != '\n') { buffer_append_string(buf, "\n"); } } /* handle plugin config and check values */ SETDEFAULTS_FUNC(mod_fdajax_set_defaults) { plugin_data *p = p_d; data_string *ds; size_t j, i = 0; int k; config_values_t cv[] = { { "fdajax.ext", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */ { "fdajax.admin_ips", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 1 */ { "fdajax.mes_live_max", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 2 */ { "fdajax.win_timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 3 */ { "fdajax.log_level", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 4 */ { "fdajax.log_security", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 5 */ { "fdajax.js_peer_func", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 6 */ { "fdajax.js_logout_code", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 7 */ { "fdajax.js_maxwin_code", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 8 */ { "fdajax.merge_messages", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 9 */ { "fdajax.js_nocookies", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */ { "fdajax.js_notfound", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */ { "fdajax.js_relogin", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 12 */ { "fdajax.js_redirect", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 13 */ { "fdajax.session_cookie", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 14 */ { "fdajax.send_redirects", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 15 */ { "fdajax.check_user_ip", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 16 */ { "fdajax.js_alert_id_func", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 17 */ { "fdajax.unw_prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 18 */ { "fdajax.send_pings", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 19 */ { "fdajax.js_ping_code", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 20 */ { "fdajax.allow_guests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 21 */ { "fdajax.js_no_guests", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 22 */ { "fdajax.html_begin", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 23 */ { "fdajax.allow_peer_call", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 24 */ { "fdajax.js_grp_peer_func", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 25 */ { "fdajax.admin_password", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 26 */ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; if (!p) return HANDLER_ERROR; p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); for (i = 0; i < srv->config_context->used; i++) { plugin_config *s; s = calloc(1, sizeof(plugin_config)); s->ext = buffer_init(); buffer_copy_string(s->ext, "fdajax"); s->admin_ips = array_init(); s->allow_peer_call = array_init(); s->mes_live_max = 500; s->log_level = LOG_LEVEL_NORMAL; s->log_security = LOG_LEVEL_AVG; s->js_peer_func = buffer_init(); s->js_grp_peer_func = buffer_init(); s->js_logout_code = buffer_init(); s->js_maxwin_code = buffer_init(); s->merge_messages = TRUE; s->send_redirects = TRUE; s->check_user_ip = TRUE; s->send_pings = 0; s->allow_guests = TRUE; s->js_nocookies_code = buffer_init(); s->js_notfound_code = buffer_init(); s->js_relogin_func = buffer_init(); s->js_redirect_func = buffer_init(); s->js_alert_id_func = buffer_init(); s->js_ping_code = buffer_init(); s->js_no_guests = buffer_init(); s->unw_prefix = buffer_init(); s->session_cookie = buffer_init(); s->html_begin = buffer_init(); s->admin_password = buffer_init(); buffer_copy_string(s->js_peer_func, "js_peer_func"); buffer_copy_string(s->js_grp_peer_func, "js_grp_peer_func"); buffer_copy_string(s->js_logout_code, "js_logout_code();"); buffer_copy_string(s->js_maxwin_code, "js_maxwin_code();"); buffer_copy_string(s->js_nocookies_code, "js_nocookies_code();"); buffer_copy_string(s->js_notfound_code, "js_notfound_code();"); buffer_copy_string(s->js_relogin_func, "js_relogin_func"); buffer_copy_string(s->js_redirect_func, "js_redirect_func"); buffer_copy_string(s->js_alert_id_func, "js_alert_id_func"); buffer_copy_string(s->js_ping_code, "js_ping_code();"); buffer_copy_string(s->js_no_guests, "js_no_guests();"); buffer_copy_string(s->unw_prefix, "unw."); buffer_copy_string(s->session_cookie, "_session_id"); buffer_copy_string(s->html_begin, FDA_HTML_BEGIN); cv[0].destination = s->ext; cv[1].destination = s->admin_ips; cv[2].destination = &(s->mes_live_max); cv[3].destination = &(s->win_timeout); cv[4].destination = &(s->log_level); cv[5].destination = &(s->log_security); cv[6].destination = s->js_peer_func; cv[7].destination = s->js_logout_code; cv[8].destination = s->js_maxwin_code; cv[9].destination = &(s->merge_messages); cv[10].destination = s->js_nocookies_code; cv[11].destination = s->js_notfound_code; cv[12].destination = s->js_relogin_func; cv[13].destination = s->js_redirect_func; cv[14].destination = s->session_cookie; cv[15].destination = &(s->send_redirects); cv[16].destination = &(s->check_user_ip); cv[17].destination = s->js_alert_id_func; cv[18].destination = s->unw_prefix; cv[19].destination = &(s->send_pings); cv[20].destination = s->js_ping_code; cv[21].destination = &(s->allow_guests); cv[22].destination = s->js_no_guests; cv[23].destination = s->html_begin; cv[24].destination = s->allow_peer_call; cv[25].destination = s->js_grp_peer_func; cv[26].destination = s->admin_password; p->config_storage[i] = s; if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { return HANDLER_ERROR; } /* convert ip addresses only once */ if (0 == i) { for (j = 0; j < s->admin_ips->used; j++) { if (s->admin_ips->data[j]->type != TYPE_STRING) { log_error_write(srv, __FILE__, __LINE__, "s", "admin_ips must contain strings"); return HANDLER_ERROR; } ds = (data_string *)s->admin_ips->data[j]; p->admin_allowed_ips[p->admin_allowed_used++].s_addr = inet_addr(ds->value->ptr); if (p->admin_allowed_ips[p->admin_allowed_used - 1].s_addr == INADDR_NONE) { log_error_write(srv, __FILE__, __LINE__, "ss", "admin_ips has invalid addr: ", ds->value->ptr); return HANDLER_ERROR; } } if (p->admin_allowed_used == 0) { log_error_write(srv, __FILE__, __LINE__, "s", "admin_ips should have at least one addr"); return HANDLER_ERROR; } p->allow_peer_call_mask = 0; for (j = 0; j < s->allow_peer_call->used; j++) { if (s->allow_peer_call->data[j]->type != TYPE_STRING) { log_error_write(srv, __FILE__, __LINE__, "s", "allow_peer_call must contain strings"); return HANDLER_ERROR; } ds = (data_string *)s->allow_peer_call->data[j]; k = event_find_index_by_name(ds->value->ptr); if (-1 == k) { log_error_write(srv, __FILE__, __LINE__, "ss", "allow_peer_call has invalid name: ", ds->value->ptr); return HANDLER_ERROR; } p->allow_peer_call_mask |= g_ev_mask_by_index[k]; } p->merge_messages = s->merge_messages; p->send_redirects = s->send_redirects; p->check_user_ip = s->check_user_ip; p->log_security = s->log_security; p->log_level = s->log_level; p->mes_live_max = s->mes_live_max * 1000; p->win_timeout = s->win_timeout * 1000; p->send_pings = s->send_pings; p->allow_guests = s->allow_guests; buffer_copy_string_buffer(p->js_peer_func, s->js_peer_func); buffer_copy_string_buffer(p->js_grp_peer_func, s->js_grp_peer_func); buffer_copy_string_buffer(p->js_logout_code, s->js_logout_code); buffer_copy_string_buffer(p->js_maxwin_code, s->js_maxwin_code); buffer_copy_string_buffer(p->js_nocookies_code, s->js_nocookies_code); buffer_copy_string_buffer(p->js_notfound_code, s->js_notfound_code); buffer_copy_string_buffer(p->js_relogin_func, s->js_relogin_func); buffer_copy_string_buffer(p->js_redirect_func, s->js_redirect_func); buffer_copy_string_buffer(p->js_alert_id_func, s->js_alert_id_func); buffer_copy_string_buffer(p->js_ping_code, s->js_ping_code); buffer_copy_string_buffer(p->unw_prefix, s->unw_prefix); buffer_copy_string_buffer(p->session_cookie, s->session_cookie); buffer_copy_string_buffer(p->js_no_guests, s->js_no_guests); buffer_copy_string_buffer(p->html_begin, s->html_begin); if (s->admin_password->used > 0) { buffer_copy_string_buffer(p->admin_password, s->admin_password); } } } return HANDLER_GO_ON; } #define PATCH(x) p->conf.x = s->x; static int mod_fdajax_patch_connection(server *srv, connection *con, plugin_data *p) { plugin_config *s = p->config_storage[0]; UNUSED(srv); UNUSED(con); PATCH(ext); return 0; } #undef PATCH /* init the plugin data */ INIT_FUNC(mod_fdajax_init) { plugin_data *p; int i; p = calloc(1, sizeof(*p)); p->match_buf = buffer_init(); p->js_peer_func = buffer_init(); p->js_grp_peer_func = buffer_init(); p->js_logout_code = buffer_init(); p->js_maxwin_code = buffer_init(); p->js_nocookies_code = buffer_init(); p->js_notfound_code = buffer_init(); p->js_relogin_func = buffer_init(); p->js_redirect_func = buffer_init(); p->js_alert_id_func = buffer_init(); p->js_ping_code = buffer_init(); p->js_no_guests = buffer_init(); p->unw_prefix = buffer_init(); p->session_cookie = buffer_init(); p->html_begin = buffer_init(); p->admin_password = buffer_init(); p->next_check_dcons = FDA_CHECK_CON_INTERVAL; p->users_by_sess = NULL; p->users_by_id = NULL; p->admin_allowed_used = 0; p->allow_peer_call_mask = 0; bzero(p->admin_allowed_ips, sizeof(p->admin_allowed_ips)); for (i = 0; i < FDA_MAX_GROUPS; i++) { group_init(&(p->groups[i]), i); } return p; } /* detroy the plugin data */ FREE_FUNC(mod_fdajax_free) { plugin_data *p = p_d; size_t i; if (!p) { return HANDLER_GO_ON; } if (p->config_storage) { for (i = 0; i < srv->config_context->used; i++) { plugin_config *s = p->config_storage[i]; if (!s) continue; buffer_free(s->ext); buffer_free(s->js_peer_func); buffer_free(s->js_grp_peer_func); buffer_free(s->js_logout_code); buffer_free(s->js_maxwin_code); buffer_free(s->js_nocookies_code); buffer_free(s->js_notfound_code); buffer_free(s->js_relogin_func); buffer_free(s->js_redirect_func); buffer_free(s->js_alert_id_func); buffer_free(s->js_ping_code); buffer_free(s->js_no_guests); buffer_free(s->unw_prefix); buffer_free(s->session_cookie); buffer_free(s->html_begin); buffer_free(s->admin_password); array_free(s->admin_ips); array_free(s->allow_peer_call); free(s); } free(p->config_storage); } buffer_free(p->match_buf); buffer_free(p->js_peer_func); buffer_free(p->js_grp_peer_func); buffer_free(p->js_logout_code); buffer_free(p->js_maxwin_code); buffer_free(p->js_nocookies_code); buffer_free(p->js_notfound_code); buffer_free(p->js_relogin_func); buffer_free(p->js_redirect_func); buffer_free(p->js_alert_id_func); buffer_free(p->js_ping_code); buffer_free(p->js_no_guests); buffer_free(p->unw_prefix); buffer_free(p->session_cookie); buffer_free(p->html_begin); buffer_free(p->admin_password); users_free(srv, p); free(p); return HANDLER_GO_ON; } int is_tcp_socket_open(server *srv, plugin_data *p, connection *con) { #ifdef USE_TCP_INFO struct tcp_info tinfo; unsigned int len = sizeof(tinfo); if (!getsockopt(con->fd, SOL_TCP, TCP_INFO, &tinfo, &len)) { if (!(tinfo.tcpi_state == TCP_CLOSE_WAIT || tinfo.tcpi_state == TCP_CLOSE || tinfo.tcpi_state == TCP_LAST_ACK || tinfo.tcpi_state == TCP_CLOSING || tinfo.tcpi_state == TCP_TIME_WAIT || tinfo.tcpi_state == TCP_FIN_WAIT1 || tinfo.tcpi_state == TCP_FIN_WAIT2 )) { return TRUE; } } else { log_info(srv, __FILE__, __LINE__, "sd", "getsockopt error ", errno); } #else fd_set rset, eset; struct timeval tv; int retval; char sbuf[1]; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&rset); FD_ZERO(&eset); FD_SET(con->fd, &rset); FD_SET(con->fd, &eset); retval = select(con->fd + 1, &rset, 0, &eset, &tv); if (-1 == retval) { log_info(srv, __FILE__, __LINE__, "sd", "select error ", errno); } else { if (FD_ISSET(con->fd, &eset)) { return FALSE; } if (FD_ISSET(con->fd, &rset)) { retval = read(con->fd, sbuf, 1); if (retval > 0) { log_info(srv, __FILE__, __LINE__, "sd", "is_tcp_socket_open serious error", con->fd); } return FALSE; } return TRUE; } #endif return FALSE; } static void make_sock_keep_alive(server *srv, connection *con) { int opt; unsigned int len = sizeof(opt); opt = 1; if (setsockopt(con->fd, SOL_SOCKET, SO_KEEPALIVE, &opt, len)) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "setsockopt error"); } } static void set_con_header(server *srv, plugin_data *p, connection *con) { UNUSED(p); if (0 != con->file_started) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "set_con_header file_started error"); } response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); response_header_overwrite(srv, con, CONST_STR_LEN("Pragma"), CONST_STR_LEN("no-cache")); response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_STR_LEN("Thu, 19 Nov 1981 08:52:00 GMT")); response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_STR_LEN("no-store, no-cache, must-revalidate, post-check=0, pre-check=0")); con->http_status = 200; con->file_started = 1; } void con_set_response(server *srv, plugin_data *p, connection *con, buffer *resp, int st) { buffer *b; UNUSED(p); if (1 != con->file_started) { set_con_header(srv, p, con); } if (0 != con->file_finished) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "set_con_resonse file_finished error"); } b = chunkqueue_get_append_buffer(con->write_queue); if (st) { BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_BEGIN); } buffer_append_string_buffer(b, resp); if (st) { BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_END); } http_chunk_append_mem(srv, con, NULL, 0); con->file_finished = 1; joblist_append(srv, con); } void con_prepare_response(server *srv, plugin_data *p, connection *con, int st) { buffer *b; UNUSED(p); if (1 != con->file_started) { set_con_header(srv, p, con); } if (0 != con->file_finished) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "con_prepare_response file_finished error"); } if (st) { b = chunkqueue_get_append_buffer(con->write_queue); BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_BEGIN); } } void con_finalize_response(server *srv, plugin_data *p, connection *con, int st) { buffer *b; UNUSED(p); if (st) { b = chunkqueue_get_append_buffer(con->write_queue); BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_END); } con->file_finished = 1; joblist_append(srv, con); } void con_redirect_to(server *srv, plugin_data *p, connection *con, int redir_to, int st) { char s[256]; con_prepare_response(srv, p, con, st); http_chunk_append_buffer(srv, con, p->js_redirect_func); sprintf(s, "(%d);", redir_to); http_chunk_append_mem(srv, con, s, strlen(s) + 1); http_chunk_append_mem(srv, con, NULL, 0); con_finalize_response(srv, p, con, st); } static int mod_fdajax_return_as_text(server *srv, connection *con, plugin_data *p, char *text) { buffer *b = chunkqueue_get_append_buffer(con->write_queue); UNUSED(p); buffer_append_string(b, text); response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); con->http_status = 200; con->file_finished = 1; return 0; } static handler_t mod_fdajax_con_reset(server *srv, connection *con, void *p_d) { plugin_data *p = p_d; win_info_p win; user_info_p user; size_t i; int found = FALSE; UNUSED(p); UNUSED(srv); if (NULL == con->plugin_ctx[p->id]) { return HANDLER_GO_ON; } win = con->plugin_ctx[p->id]; con->plugin_ctx[p->id] = NULL; if (win->con != con) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "con_reset win con error"); return HANDLER_GO_ON; } if(NULL == (user = win->owner)) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "con_reset owner is NULL error"); return HANDLER_GO_ON; } for(i = 0; i < WINDOWS_MAX; i++) { if (user->windows[i] == win) { log_avg(srv, __FILE__, __LINE__, "bsdsd", con->dst_addr_buf, "con_reset dispose uid", user->user_id, "win_id", win->win_id ); win->con = NULL; found = TRUE; } } if (!found) { log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "con_reset not found error"); } return HANDLER_GO_ON; } static handler_t mod_fdajax_con_close(server *srv, connection *con, void *p_d) { plugin_data *p = p_d; win_info_p win; if (NULL != (win = con->plugin_ctx[p->id])) { log_error_write(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "con_close win_id", win->win_id); return HANDLER_GO_ON; } return HANDLER_GO_ON; } static int check_dead_cons(server *srv, plugin_data *p, user_info_p user) { size_t i; int count = 0; struct timeval now; gettimeofday(&now, 0); for (i = 0; i < WINDOWS_MAX; i++) { if (NULL != user->windows[i] && NULL != user->windows[i]->con) { if (is_tcp_socket_open(srv, p, user->windows[i]->con)) { if (p->send_pings > 0) { if (user->windows[i]->created_at.tv_sec < now.tv_sec - p->send_pings) { window_append_string_buffer(user->windows[i], p->js_ping_code); window_flush(srv, p, user->windows[i]); user->windows[i]->con->file_finished = 1; } } } else { /* remote side has closed connection */ connection *dcon = user->windows[i]->con; log_avg(srv, __FILE__, __LINE__, "bs", dcon->dst_addr_buf, "check_dead_cons close"); dcon->plugin_ctx[p->id] = NULL; connection_set_state(srv, dcon, CON_STATE_ERROR); joblist_append(srv, dcon); window_free(p, user->windows[i]); user->windows[i] = NULL; count++; } } } return count; } TRIGGER_FUNC(mod_fdajax_trigger) { plugin_data *p = p_d; user_info_p user; int count = 0; if (p->next_check_dcons > 0) { /* trigger is executed once a second */ p->next_check_dcons--; group_remove_old_mes(srv, p); } else { p->next_check_dcons = FDA_CHECK_CON_INTERVAL; for (user = p->users_by_sess; user != NULL; user = user->hh_sess.next) { count += check_dead_cons(srv, p, user); } if (count > 0) { log_info(srv, __FILE__, __LINE__, "sd", "trigger closed_windows " , count); } } return HANDLER_GO_ON; } static char *find_cookie_val(char *name, char *s, int *len) { char *g, *nc, *st; if (NULL != (g = strstr(s, name))) { for (nc = g + strlen(name); *nc == ' ' || *nc == '\t'; nc++); if (*nc == '=') { st = ++nc; while (isalnum(*nc)) nc++; if (nc > st) { *len = nc - st; return st; } } } return NULL; } static void extract_cookies(server *srv, connection *con, plugin_data *p, user_request_p req) { data_string *ds; UNUSED(srv); UNUSED(p); if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { char *st; int len; if ((st = find_cookie_val(p->session_cookie->ptr, ds->value->ptr, &len))) { strncpy(req->sess_id_cookie, st, min(len, SESS_ID_LEN_MAX - 1)); req->sess_id_cookie[min(len, SESS_ID_LEN_MAX - 1)] = 0; } } } static void find_www_nr(server *srv, connection *con, plugin_data *p, user_request_p req) { if (con->request.http_host && con->request.http_host->ptr) { char *s = con->request.http_host->ptr; if (*s && *s == 's' && (strncmp(s, "secure", sizeof("secure") - 1) == 0)) { req->www_id = WINDOWS_MAX - 1; req->force_old_close = TRUE; return; } while (*s && (*s == 'w' || (*s >= '0' && *s <= '9'))) { if (isdigit(*s)) { req->www_id = *s - '0'; if (req->www_id > WINDOWS_MAX) { req->www_id = WINDOWS_MAX - 1; } break; } s++; } } else { if (con->dst_addr.ipv4.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { log_high(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "http_host not present"); } } } static void free_request_resources(user_request_p req) { if (req->mes) { buffer_free(req->mes); req->mes = NULL; } if (req->req_sess_id) { buffer_free(req->req_sess_id); req->req_sess_id = NULL; } } /* main commands handle function */ static int mod_fdajax_handle(server *srv, connection *con, plugin_data *p) { enum auth_problem_t auth_problem; user_request_t req; user_info_p user, peer; grp_info_p grp; win_info_p win; mes_info_p mes; size_t i; int redirect, found, count, slot; buffer *b; char *ps; enum cmd_res_t answer; /* parse query */ mod_fdajax_pinit(&req); mod_fdajax_pexec(&req, con->uri.query->ptr, con->uri.query->used - 1); if (mod_fdajax_pfinish(&req) < 1) { free_request_resources(&req); con->http_status = 500; log_high(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "URI parser error"); return HANDLER_FINISHED; } extract_cookies(srv, con, p, &req); find_www_nr(srv, con, p, &req); if (req.cmd == cmd_none) { security_avg(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "security: cmd_not_set"); free_request_resources(&req); con->http_status = 500; return HANDLER_FINISHED; } if (req.cmd == cmd_chatsig || req.cmd == cmd_wait || req.cmd == cmd_cancel || req.cmd == cmd_stream) { /* this is user space command */ user = NULL; if (strlen(req.sess_id_cookie) == 0) { auth_problem = authp_null_cookie; security_avg(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "security: auth_user sess_id_cookie empty"); } else { user = user_find_by_sess(p, req.sess_id_cookie); if (user) { user = user_auth(srv, con, p, user, &req, &auth_problem); } else { if (req.user_id != 0) { auth_problem = authp_user_not_found; } else { if (p->allow_guests) { user = user_create_guest(con, &req); user_attach(srv, p, user); } else { auth_problem = authp_no_guests; } } } } if (NULL == user) { switch (auth_problem) { case authp_null_userid: con->http_status = 500; break; case authp_null_cookie: con_set_response(srv, p, con, p->js_nocookies_code, req.win_st); log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "auth: nocookies uid ", req.user_id); break; case authp_user_not_found: con_set_response(srv, p, con, p->js_notfound_code, req.win_st); log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "auth: not_found uid ", req.user_id); break; case authp_ip_addr: con_prepare_response(srv, p, con, req.win_st); b = chunkqueue_get_append_buffer(con->write_queue); buffer_append_string_buffer(b, p->js_relogin_func); buffer_append_string(b, "('ipaddr');"); http_chunk_append_mem(srv, con, NULL, 0); con_finalize_response(srv, p, con, req.win_st); log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "auth: relogin_ipaddr uid ", req.user_id); break; case authp_sessid: con_prepare_response(srv, p, con, req.win_st); b = chunkqueue_get_append_buffer(con->write_queue); buffer_append_string_buffer(b, p->js_relogin_func); buffer_append_string(b, "('sessid');"); http_chunk_append_mem(srv, con, NULL, 0); con_finalize_response(srv, p, con, req.win_st); log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "auth: relogin_sessid uid ", req.user_id); break; case authp_no_guests: con_set_response(srv, p, con, p->js_no_guests, req.win_st); log_high(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "auth: no_guests"); break; } } else { switch (req.cmd) { case cmd_chatsig: if (1 != req.ev.count || NULL == req.mes || 0 == req.mes->used) { con->http_status = 500; break; } i = event_bit_to_index(req.ev.types); if (i < FDA_GRP_START) { if (0 == user->user_id || 0 == req.peer_id) { log_high(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:chatsig wrong parameters"); con->http_status = 500; break; } if (!chat_access_peer(user, req.peer_id)) { answer = cmdr_not_in_chat; } else { peer = user_find_by_id(p, req.peer_id); if (!peer) { answer = cmdr_user_not_logged; } else { if (!(mes = message_init_peer(srv, p, user, &req))) { answer = cmdr_wrong_syntax; } else { message_remove_old(srv, p, &(peer->mes_list)); answer = message_push(srv, p, peer, mes); window_flush_all(srv, p, peer); } } } } else { grp = group_find(p, req.ev.types); if (!grp) { answer = cmdr_grp_not_found; } else { if (!(mes = message_init_peer(srv, p, user, &req))) { answer = cmdr_wrong_syntax; } else { message_grp_push(srv, p, grp, mes); answer = cmdr_ok; } } } con_prepare_response(srv, p, con, req.win_st); http_chunk_append_mem(srv, con, g_answer[answer], strlen(g_answer[answer]) + 1); http_chunk_append_mem(srv, con, NULL, 0); con_finalize_response(srv, p, con, req.win_st); log_avg(srv, __FILE__, __LINE__, "bss", con->dst_addr_buf, "cmd:chatsig answer ", g_answer[answer]); break; case cmd_wait: if (req.ev.types == 0 || req.win_id == 0) { con->http_status = 500; break; } message_remove_old(srv, p, &(user->mes_list)); window_remove_old(srv, p, con, user); win = window_find(con, user, &req); if ((NULL != win) && (NULL != win->con) && (win->con != con)) { log_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "cmd:wait same_win_id", win->win_id); con->http_status = 500; break; } if (win) { win->ev = req.ev; if (NULL == win->con) { win->con = con; } else { assert(win->con == con); } } else { redirect = window_should_redirect(srv, p, con, user, &req); if (redirect != -1) { con_redirect_to(srv, p, con, redirect, req.win_st); break; } if (-1 == (slot = window_find_slot(user))) { log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "cmd:wait not empty slot uid", req.user_id); con_set_response(srv, p, con, p->js_maxwin_code, req.win_st); break; } win = window_init(p, con, user, &req, fda_win_chunked, slot); } con->mode = p->id; con->plugin_ctx[p->id] = win; answer = message_send_pending(srv, p, user->mes_list.first_mes, win); if (win->ev.types & FDA_EV_UNW) { if (message_check_unsend(srv, p, user, win) > 0) { answer = cmdr_mes_sent; } alert_push(srv, p, user); } window_check_groups(srv, p, win); count = win->send_count; window_flush_all(srv, p, user); if (win->send_count > count) { log_avg(srv, __FILE__, __LINE__, "bsdsd", con->dst_addr_buf, "cmd:wait exit uid ", req.user_id, " port ", ntohs(con->dst_addr.ipv4.sin_port)); break; } /* register win to handle when event arrives. set also keep-alive for socket to make sure that disconnected socket will be detected and sweeped by trigger */ make_sock_keep_alive(srv, con); log_avg(srv, __FILE__, __LINE__, "bsdsdsdss", con->dst_addr_buf, "cmd:wait wait uid", req.user_id, "win_id", req.win_id, "www_id", req.www_id, "sync_tv", req.tv.tv_sec > 0 ? tv2s(req.tv) : "not_set"); free_request_resources(&req); return HANDLER_WAIT_FOR_EVENT; case cmd_stream: if (req.ev.types == 0 || req.win_id == 0) { con->http_status = 500; break; } message_remove_old(srv, p, &(user->mes_list)); window_remove_old(srv, p, con, user); win = window_find(con, user, &req); if (NULL != win) { if (NULL == win->con) { win->ev = req.ev; win->con = con; } else { log_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "cmd:stream same_win_id", win->win_id); con->http_status = 500; break; } } else { redirect = window_should_redirect(srv, p, con, user, &req); if (redirect != -1) { con_redirect_to(srv, p, con, redirect, req.win_st); break; } if (-1 == (slot = window_find_slot(user))) { log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "cmd:stream not empty slot uid", req.user_id); con_set_response(srv, p, con, p->js_maxwin_code, req.win_st); break; } win = window_init(p, con, user, &req, fda_win_stream, slot); } con->mode = p->id; con->plugin_ctx[p->id] = win; make_sock_keep_alive(srv, con); /* send http header */ con_prepare_response(srv, p, con, 0); b = chunkqueue_get_append_buffer(con->write_queue); buffer_append_string_buffer(b, p->html_begin); buffer_append_nl(b); http_chunk_append_mem(srv, con, NULL, 0); answer = message_send_pending(srv, p, user->mes_list.first_mes, win); if (win->ev.types & FDA_EV_UNW) { /* check if there is unsend message, this win can receive it */ if (message_check_unsend(srv, p, user, win) > 0) { answer = cmdr_mes_sent; } alert_push(srv, p, user); } window_check_groups(srv, p, win); window_flush_all(srv, p, user); log_avg(srv, __FILE__, __LINE__, "bsdsdsdss", con->dst_addr_buf, "cmd:stream wait uid", req.user_id, "win_id", req.win_id, "www_id", req.www_id, "sync_tv", req.tv.tv_sec > 0 ? tv2s(req.tv) : "not_set"); free_request_resources(&req); return HANDLER_FINISHED; case cmd_cancel: if (0 == req.win_id && 0 == req.alert_id) { con->http_status = 500; break; } if (req.win_id > 0) { found = FALSE; if (NULL != (win = window_find(con, user, &req))) { if (win->con) { con_prepare_response(srv, p, win->con, 0); http_chunk_append_mem(srv, win->con, NULL, 0); con_finalize_response(srv, p, win->con, 0); window_close(srv, p, user, win, NULL); found = TRUE; } } } else { found = alert_cancel(user, req.alert_id); } con_prepare_response(srv, p, con, req.win_st); if (req.mes && (req.mes->used > 0) && (strncmp(req.mes->ptr, "noresult", sizeof("noresult") - 1) == 0)) { /* nothing to send */ } else { ps = found ? "CLOSED" : "NOT_FOUND"; http_chunk_append_mem(srv, con, ps, strlen(ps) + 1); } http_chunk_append_mem(srv, con, NULL, 0); con_finalize_response(srv, p, con, req.win_st); log_avg(srv, __FILE__, __LINE__, "bsdsdss", con->dst_addr_buf, "cmd:cancel uid", user->user_id, "win_id", req.win_id, "result", found ? "closed" : "not_found"); break; default: log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "user command error"); con->http_status = 500; break; } } } else { /* this is admin space command */ int is_admin = FALSE; int open_win_count; for (i = 0; i < p->admin_allowed_used; i++) { if (p->admin_allowed_ips[i].s_addr == con->dst_addr.ipv4.sin_addr.s_addr) { is_admin = TRUE; break; } } if (p->admin_password->used > 0) { if (0 != strcmp(p->admin_password->ptr, req.admin_passwd)) { is_admin = FALSE; } } if (!is_admin) { security_avg(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "security: attempt to exec admin cmd"); con->http_status = 500; } else { switch (req.cmd) { case cmd_check_user: if (req.user_id == 0) { log_info(srv, __FILE__, __LINE__, "s", "cmd:check_user bad_params"); con->http_status = 500; break; } open_win_count = 0; user = user_find_by_id(p, req.user_id); if (user) { open_win_count = user_check(srv, p, con, user); if (open_win_count > 0) { answer = cmdr_user_active; } else { user_detach(srv, p, user); user_free(srv, p, con, user); answer = cmdr_logout_ok; } } else { answer = cmdr_user_not_found; } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsdsdss", con->dst_addr_buf, "cmd:check_user uid ", req.user_id, " open_windows ", open_win_count, " result ", g_answer[answer]); break; case cmd_login: if (req.user_id == 0 || req.ipaddr.s_addr == INADDR_NONE || req.req_sess_id == NULL || req.req_sess_id->used > SESS_ID_LEN_MAX) { log_info(srv, __FILE__, __LINE__, "s", "cmd:login bad_params"); con->http_status = 500; break; } user = user_find_by_id(p, req.user_id); if (user) { user_update_addr_and_sess(p, user, &req); answer = cmdr_already_logged; log_high(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "cmd:login update uid ", user->user_id); } else { user = user_find_by_sess(p, req.req_sess_id->ptr); if (user) { if (0 == user->user_id) { user_update_id_and_ipaddr(p, user, &req); answer = cmdr_login_old_sess; } else { answer = cmdr_login_bad_id; } } else { user = user_login(&req); user_attach(srv, p, user); answer = cmdr_login_ok; } } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsdss", con->dst_addr_buf, "cmd:login uid ", req.user_id, " result ", g_answer[answer]); break; case cmd_logout: if (req.user_id == 0) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:logout bad_params"); con->http_status = 500; break; } user = user_find_by_id(p, req.user_id); if (user) { user_detach(srv, p, user); user_free(srv, p, con, user); answer = cmdr_logout_ok; } else { answer = cmdr_user_not_found; } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsdss", con->dst_addr_buf, "cmd:logout uid ", req.user_id, " result ", g_answer[answer]); break; case cmd_addchat: if (req.user_id == 0 || req.peer_id == 0) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:addchat bad_params"); con->http_status = 500; break; } user = user_find_by_id(p, req.user_id); peer = user_find_by_id(p, req.peer_id); if (!user || !peer) { answer = cmdr_user_not_found; } else { if (cmdr_chat_peer_add == (answer = chat_add_peer(user, peer->user_id))) { if (cmdr_chat_peer_add != (answer = chat_add_peer(peer, user->user_id))) { /* clean first user's chat list */ chat_rm_peer(user, peer->user_id); } } } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsdss", con->dst_addr_buf, "cmd:addchat uid ", req.user_id, " result ", g_answer[answer]); break; case cmd_rmchat: if (req.user_id == 0 || req.peer_id == 0) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:rmchat bad_params"); con->http_status = 500; break; } user = user_find_by_id(p, req.user_id); peer = user_find_by_id(p, req.peer_id); if (!user) { answer = cmdr_user_not_found; } else { answer = chat_rm_peer(user, req.peer_id); } if (peer) { if (cmdr_chat_peer_rm_1 == chat_rm_peer(peer, req.user_id)) { if (cmdr_chat_peer_rm_1 == answer) { answer = cmdr_chat_peer_rm_2; } else if (cmdr_user_not_found == answer) { answer = cmdr_chat_peer_rm_1; } } } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsdss", con->dst_addr_buf, "cmd:rmchat uid ", req.user_id, " result ", g_answer[answer]); break; case cmd_push: if (NULL == req.mes || 0 == req.mes->used || 1 != req.ev.count) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:push wrong_parameters"); con->http_status = 500; break; } i = event_bit_to_index(req.ev.types); if (i < FDA_GRP_START) { if (0 == req.peer_id) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:push wrong_parameters"); con->http_status = 500; break; } peer = user_find_by_id(p, req.peer_id); if (!peer) { answer = cmdr_user_not_logged; } else { message_remove_old(srv, p, &(peer->mes_list)); mes = message_init(&req); message_push(srv, p, peer, mes); alert_push(srv, p, peer); window_flush_all(srv, p, peer); answer = cmdr_ok; } } else { grp = group_find(p, req.ev.types); if (!grp) { answer = cmdr_grp_not_found; } else { message_remove_old(srv, p, &(grp->mes_list)); mes = message_init(&req); message_grp_push(srv, p, grp, mes); answer = cmdr_ok; } } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsssd", con->dst_addr_buf, "cmd:push result ", g_answer[answer], " uid ", req.peer_id); break; case cmd_alert: if (req.peer_id == 0 || NULL == req.mes || 0 == req.mes->used) { log_info(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "cmd:alert wrong_parameters"); con->http_status = 500; break; } peer = user_find_by_id(p, req.peer_id); if (!peer) { answer = cmdr_user_not_logged; } else { message_remove_old(srv, p, &(peer->mes_list)); alert_add(srv, p, con, peer, &req); alert_push(srv, p, peer); window_flush_all(srv, p, peer); answer = cmdr_ok; } mod_fdajax_return_as_text(srv, con, p, g_answer[answer]); log_avg(srv, __FILE__, __LINE__, "bsssd", con->dst_addr_buf, "cmd:alert result ", g_answer[answer], " uid ", req.peer_id); break; case cmd_info: mod_fdajax_info(srv, p, con); con->http_status = 200; con->file_finished = 1; break; default: log_error_write(srv, __FILE__, __LINE__, "bs", con->dst_addr_buf, "unrecognized admin command"); con->http_status = 500; break; } } } free_request_resources(&req); if (0 == con->http_status) { con->http_status = 200; } return HANDLER_FINISHED; } URIHANDLER_FUNC(mod_fdajax_uri_handler) { plugin_data *p = p_d; int s_len; int ct_len; UNUSED(srv); if (con->uri.path->used == 0) return HANDLER_GO_ON; mod_fdajax_patch_connection(srv, con, p); s_len = con->uri.path->used - 1; ct_len = p->conf.ext->used - 1; if (ct_len > 0 && s_len >= ct_len && 0 == strncmp(con->uri.path->ptr + s_len - ct_len, p->conf.ext->ptr, ct_len)) { return mod_fdajax_handle(srv, con, p); } /* not found */ return HANDLER_GO_ON; } SUBREQUEST_FUNC(mod_fdajax_subrequest) { plugin_data *p = p_d; if (NULL == con->plugin_ctx[p->id]) { return HANDLER_GO_ON; } if (con->file_finished) { /* file_finished is set by push_message func */ return HANDLER_FINISHED; } log_error_write(srv, __FILE__, __LINE__, "s", "subrequest not finished"); return HANDLER_WAIT_FOR_EVENT; } /* this function is called at dlopen() time and inits the callbacks */ int mod_fdajax_plugin_init(plugin *p) { p->version = LIGHTTPD_VERSION_ID; p->name = buffer_init_string("fdajax"); p->connection_reset = mod_fdajax_con_reset; p->handle_connection_close = mod_fdajax_con_close; p->handle_trigger = mod_fdajax_trigger; p->init = mod_fdajax_init; p->handle_uri_clean = mod_fdajax_uri_handler; p->handle_subrequest = mod_fdajax_subrequest; p->set_defaults = mod_fdajax_set_defaults; p->cleanup = mod_fdajax_free; p->data = NULL; return 0; } mod_fdajax-0.9/src/mod_fdajax_alerts.c0000640000175000017500000000543310641300132016500 0ustar greggreg#include "mod_fdajax_defs.h" void alert_free_slot(user_info_p user, size_t i) { if (user->alerts[i].id > 0) { user->alerts[i].id = 0; if (user->alerts[i].mes) { buffer_free(user->alerts[i].mes); user->alerts[i].mes = NULL; } } } unsigned int alert_max_id(user_info_p user) { unsigned int ret = 0; size_t i; for (i = 0; i < ALERTS_MAX; i++) { if (user->alerts[i].id > ret) { ret = user->alerts[i].id; } } return ret; } int alert_cancel(user_info_p user, unsigned int id) { size_t i; if (0 == id) { return FALSE; } for (i = 0; i < ALERTS_MAX; i++) { if (user->alerts[i].id == id) { alert_free_slot(user, i); return TRUE; } } return FALSE; } size_t alert_find_slot(user_info_p user) { size_t i, j = 0, min_id = UINT_MAX; for (i = 0; i < ALERTS_MAX; i++) { if (user->alerts[i].id == 0) { return i; } if (user->alerts[i].id < min_id) { j = i; min_id = user->alerts[j].id; } } alert_free_slot(user, j); return j; } int alert_add(server *srv, plugin_data *p, connection *con, user_info_p user, user_request_p req) { size_t i; alert_info_p palert; UNUSED(srv); UNUSED(p); UNUSED(con); i = alert_find_slot(user); palert = &(user->alerts[i]); palert->id = ++(user->last_alert); palert->mes = req->mes; req->mes = NULL; return TRUE; } int alert_add_from_mes(server *srv, plugin_data *p, user_info_p user, mes_info_p mes) { size_t i; alert_info_p palert; UNUSED(srv); UNUSED(p); i = alert_find_slot(user); palert = &(user->alerts[i]); palert->id = ++(user->last_alert); palert->mes = buffer_init(); buffer_append_string_buffer(palert->mes, p->unw_prefix); buffer_append_string_buffer(palert->mes, mes->mes); return TRUE; } int alert_append(server *srv, plugin_data *p, user_info_p user, buffer *buf, unsigned int last_id) { size_t i; int count = 0; UNUSED(srv); for (i = 0; i < ALERTS_MAX; i++) { if (user->alerts[i].id > last_id) { buffer_append_nl(buf); buffer_append_string_buffer(buf, p->js_alert_id_func); buffer_append_string(buf, "("); buffer_append_long(buf, user->alerts[i].id); buffer_append_string(buf, ");\n"); buffer_append_string_buffer(buf, user->alerts[i].mes); count++; } } return count; } enum gdc_cmd_t alert_push(server *srv, plugin_data *p, user_info_p user) { win_info_p win; size_t i; unsigned int maid = alert_max_id(user); UNUSED(srv); UNUSED(p); if (0 == maid) { return cmdr_ok; } for(i = 0; i < WINDOWS_MAX; i++) { win = user->windows[i]; if (NULL == win || NULL == win->con || ((win->ev.types & FDA_EV_UNW) == 0) || win->last_alert >= maid) { continue; } alert_append(srv, p, user, window_get_buffer(win), win->last_alert); win->last_alert = maid; } return cmdr_mes_sent; } mod_fdajax-0.9/src/mod_fdajax_windows.c0000640000175000017500000002310110650141571016702 0ustar greggreg#include "mod_fdajax_defs.h" win_info_p window_init(plugin_data *p, connection *con, user_info_p user, user_request_p req, enum fda_win_type win_type, int slot) { struct timeval now, back, from_point; unsigned int bits; win_info_p win; size_t i; win = calloc(1, sizeof(win_info_t)); if (!win) { return NULL; } win->win_id = req->win_id; win->win_st = req->win_st; win->www_id = req->www_id; win->win_type = win_type; win->owner = user; user->windows[slot] = win; win->con = con; win->to_send = NULL; win->send_count = 0; win->last_alert = 0; gettimeofday(&now, 0); win->created_at = now; if (req->tv.tv_sec > 0) { from_point = req->tv; } else { from_point = now; back.tv_sec = 1; back.tv_usec = 0; timeval_sub(from_point, back); } win->last_send = from_point; win->ev = req->ev; for (i = 0; i < FDA_TYPES_MAX; i++) { win->last_mes_at[i] = from_point; } for (i = FDA_GRP_START; i < FDA_GRP_END; i++) { bits = g_ev_mask_by_index[i]; if (win->ev.types & bits) { group_add_window(group_find(p, bits), win); } } return win; } void window_free(plugin_data *p, win_info_p win) { unsigned int bits; int i; for (i = FDA_GRP_START; i < FDA_GRP_END; i++) { bits = g_ev_mask_by_index[i]; if (win->ev.types & bits) { group_rm_window(group_find(p, bits), win); } } free(win); } int window_find_slot(user_info_p user) { int i; for (i = 0; i < WINDOWS_MAX; i++) { if (NULL == user->windows[i]) { return i; } } return -1; } win_info_p window_find(connection *con, user_info_p user, user_request_p req) { size_t i; UNUSED(con); for (i = 0; i < WINDOWS_MAX; i++) { if (user->windows[i] && (req->win_id == user->windows[i]->win_id)) { assert(user->windows[i]->owner == user); return user->windows[i]; } } return FALSE; } void window_close_all(server *srv, plugin_data *p, connection *con, user_info_p user) { win_info_p win; size_t i; for (i = 0; i < WINDOWS_MAX; i++) { win = user->windows[i]; if (win) { log_avg(srv, __FILE__, __LINE__, "ssdsd", (con == NULL) ? "0.0.0.0" : con->dst_addr_buf->ptr, "close_win uid ", user->user_id, " win_id ", win->win_id); if (win->con) { if (0 == win->con->file_finished) { con_set_response(srv, p, win->con, p->js_logout_code, win->win_st); } win->con->plugin_ctx[p->id] = NULL; } window_free(p, win); user->windows[i] = NULL; } } } void window_close(server *srv, plugin_data *p, user_info_p user, win_info_p win, buffer *close_message) { size_t i; for (i = 0; i < WINDOWS_MAX; i++) { if (user->windows[i] && (win->win_id == user->windows[i]->win_id)) { if (win->con) { if (0 == win->con->file_finished) { con_set_response(srv, p, win->con, close_message ? close_message : p->js_logout_code, win->win_st); } win->con->plugin_ctx[p->id] = NULL; } window_free(p, win); user->windows[i] = NULL; return; } } } int window_remove_old(server *srv, plugin_data *p, connection *con, user_info_p user) { struct timeval now; size_t i; int left_count = 0; gettimeofday(&now, NULL); UNUSED(srv); UNUSED(p); for (i = 0; i < WINDOWS_MAX; i++) { if (NULL == user->windows[i]) { continue; } if (NULL != user->windows[i]->con) { if (!is_tcp_socket_open(srv, p, user->windows[i]->con)) { /* remote side has closed connection */ connection *dcon = user->windows[i]->con; log_avg(srv, __FILE__, __LINE__, "bsdss", con->dst_addr_buf, "rm_ow closed win_id", user->windows[i]->win_id, "c_at", tv2s(user->windows[i]->created_at)); dcon->plugin_ctx[p->id] = NULL; connection_set_state(srv, dcon, CON_STATE_ERROR); joblist_append(srv, dcon); window_free(p, user->windows[i]); user->windows[i] = NULL; } else { left_count++; } } else { if (window_is_old(user->windows[i], now, p->win_timeout)) { window_free(p, user->windows[i]); user->windows[i] = NULL; } else { left_count++; } } } return left_count; } void window_update_last_send(win_info_p win, struct timeval tv) { if (timeval_less(win->last_send, tv)) { win->last_send = tv; } } int window_is_old(win_info_p win, struct timeval now, unsigned long win_timeout) { double diff = ((now.tv_sec - win->last_send.tv_sec) * 1000000) + now.tv_usec - win->last_send.tv_usec; return (diff > win_timeout) ? TRUE : FALSE; } buffer *window_get_buffer(win_info_p win) { if (NULL == win->to_send) { win->to_send = buffer_init(); buffer_prepare_append(win->to_send, 4096); } return win->to_send; } void window_append_string_buffer(win_info_p win, buffer *sb) { buffer_append_string_buffer(window_get_buffer(win), sb); } void window_append_string(win_info_p win, char *s) { buffer_append_string(window_get_buffer(win), s); } win_info_p window_first_with_unw(server *srv, plugin_data *p, user_info_p user) { win_info_p win; int i; UNUSED(srv); UNUSED(p); for(i = 0; i < WINDOWS_MAX; i++) { win = user->windows[i]; if (NULL != win && NULL != win->con && (win->ev.types & FDA_EV_UNW) != 0) { return win; } } return NULL; } int window_can_receive(win_info_p win, mes_info_p mes, int check_time) { int ev_nr; if (mes->ev.types & win->ev.types) { ev_nr = event_bit_to_index(mes->ev.types); if (check_time && (!timeval_less(win->last_mes_at[ev_nr], mes->created_at))) { return FALSE; } if (event_check_ids(win, mes, ev_nr)) { return TRUE; } } return FALSE; } int window_check_groups(server *srv, plugin_data *p, win_info_p win) { unsigned int bits; grp_info_p grp; int i; for (i = FDA_GRP_START; i < FDA_GRP_END; i++) { bits = g_ev_mask_by_index[i]; if (win->ev.types & bits) { grp = group_find(p, bits); message_send_pending(srv, p, grp->mes_list.first_mes, win); } } return 0; } int window_flush_all(server *srv, plugin_data *p, user_info_p user) { int i; for(i = 0; i < WINDOWS_MAX; i++) { if (NULL != user->windows[i]) { window_flush(srv, p, user->windows[i]); } } return 0; } int window_flush(server *srv, plugin_data *p, win_info_p win) { struct timeval now; buffer *b; if (NULL == win->con || NULL == win->to_send) { return FALSE; } switch (win->win_type) { case fda_win_chunked: con_set_response(srv, p, win->con, win->to_send, win->win_st); break; case fda_win_stream: b = chunkqueue_get_append_buffer(win->con->write_queue); if (1 == win->win_st) { BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_BEGIN); } buffer_append_string_buffer(b, win->to_send); if (1 == win->win_st) { buffer_append_nl(b); BUFFER_APPEND_STRING_CONST(b, SCRIPT_JS_END); } http_chunk_append_mem(srv, win->con, NULL, 0); joblist_append(srv, win->con); break; } buffer_free(win->to_send); win->to_send = NULL; gettimeofday(&now, 0); window_update_last_send(win, now); win->send_count++; win->owner->send_count++; return TRUE; } win_info_p window_find_oldest(user_info_p user) { win_info_p win; int j, i = 0; while (i < WINDOWS_MAX && NULL == (win = user->windows[i])) { i++; } if (NULL == win) { return NULL; } for (j = i + 1; j < WINDOWS_MAX; j++) { if (user->windows[j]) { if (timeval_less(user->windows[j]->created_at, win->created_at)) { win = user->windows[j]; } } } return win; } int window_should_redirect(server *srv, plugin_data *p, connection *con, user_info_p user, user_request_p req) { char slot[WINDOWS_MAX] = { 1, 1, 1, 1, 1 }; win_info_p oldest_win; size_t i, j; int redir = 0, redir_to = -1; UNUSED(con); for (i = 0; i < WINDOWS_MAX; i++) { if (user->windows[i]) { slot[user->windows[i]->www_id] = 0; if (req->www_id == user->windows[i]->www_id) { if (p->send_redirects && (0 == req->force_old_close)) { redir = 1; } else { window_close(srv, p, user, user->windows[i], p->js_maxwin_code); return -1; } } } } if (!redir) { return -1; } for (j = 0; j < WINDOWS_MAX; j++) { if (slot[j]) { redir_to = j; break; } } if (-1 == redir_to) { oldest_win = window_find_oldest(user); redir_to = oldest_win->www_id; window_close(srv, p, user, oldest_win, p->js_maxwin_code); if (redir_to == req->www_id) { /* No need to redirect. The new window has the same win id. */ return -1; } } return redir_to; } mod_fdajax-0.9/src/mod_fdajax_defs.h0000640000175000017500000004174210650371161016151 0ustar greggreg#ifndef MOD_FDAJAX_DEF_H #define MOD_FDAJAX_DEF_H #include #include #include #include #include #include #include #include #include #include "base.h" #include "log.h" #include "buffer.h" #include "joblist.h" #include "http_chunk.h" #include "connections.h" #include "response.h" #include "splaytree.h" #include "plugin.h" #include "uthash.h" #if defined(__linux__) #define USE_TCP_INFO 1 #endif #define TRUE 1 #define FALSE 0 #define min(a,b) ((a) < (b) ? (a) : (b)) #define timeval_less(t1, t2) ((t1.tv_sec < t2.tv_sec) || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec)) #define timeval_sub(t1, t2) do { t1.tv_sec -= t2.tv_sec; \ if (t1.tv_usec < t2.tv_usec) \ { t1.tv_sec -= 1; t1.tv_usec += 1000000 - t2.tv_usec; } \ else { t1.tv_usec -= t2.tv_usec; } } while (0) #define LOG_LEVEL_NONE 0 #define LOG_LEVEL_NORMAL 1 #define LOG_LEVEL_AVG 2 #define LOG_LEVEL_HIGH 3 #define log_info if (p->log_level >= LOG_LEVEL_NORMAL) log_error_write #define log_avg if (p->log_level >= LOG_LEVEL_AVG) log_error_write #define log_high if (p->log_level >= LOG_LEVEL_HIGH) log_error_write #define security_info if (p->log_security >= LOG_LEVEL_NORMAL) log_error_write #define security_avg if (p->log_security >= LOG_LEVEL_AVG) log_error_write #define security_high if (p->log_security >= LOG_LEVEL_HIGH) log_error_write #define FDA_CHECK_CON_INTERVAL 30 #define FDA_TYPES_MAX 32 #define FDA_EV_START 1 #define FDA_EV_END 15 #define FDA_EV_MAX 16 #define FDA_EV_UNW 0x00000001 /* recevie unwanted and alerts */ #define FDA_EV_GEN 0x00000002 #define FDA_EV_CHAT 0x00000004 #define FDA_EV_TOQ 0x00000008 #define FDA_EV_TWP 0x00000010 #define FDA_EV_SUO 0x00000020 #define FDA_EV_SUS 0x00000040 #define FDA_EV_SHO 0x00000080 #define FDA_EV_SHS 0x00000100 #define FDA_EV_SHC 0x00000200 #define FDA_EV_MES 0x00000400 #define FDA_EV_ORD 0x00000800 #define FDA_EV_CCD 0x00001000 #define FDA_EV_ITM 0x00002000 #define FDA_EV_LNE 0x00004000 #define FDA_EV_USR 0x00008000 #define FDA_MAX_GROUPS 16 #define FDA_GRP_START 16 #define FDA_GRP_END 31 #define FDA_GRP_MAIN 0x00010000 #define FDA_GRP_CHAT 0x00020000 #define FDA_GRP_QUES 0x00040000 #define FDA_GRP_ANSW 0x00080000 #define FDA_GRP_OFRS 0x00100000 #define FDA_GRP_PRIC 0x00200000 #define FDA_GRP_OPIN 0x00400000 #define FDA_GRP_USER 0x00800000 #define FDA_GRP_ORDS 0x01000000 #define FDA_GRP_GEIC 0x02000000 #define FDA_GRP_FEED 0x04000000 #define FDA_GRP_MESE 0x08000000 #define FDA_GRP_NETK 0x10000000 #define FDA_GRP_TASK 0x20000000 #define FDA_GRP_FRID 0x40000000 #define FDA_GRP_INFO 0x80000000 #define FDA_EV_UNW_INDEX 0 #define FDA_EV_GEN_INDEX 1 #define FDA_EV_CHAT_INDEX 2 #define FDA_EV_TOQ_INDEX 3 #define FDA_EV_TWP_INDEX 4 #define FDA_EV_SUO_INDEX 5 #define FDA_EV_SUS_INDEX 6 #define FDA_EV_SHO_INDEX 7 #define FDA_EV_SHS_INDEX 8 #define FDA_EV_SHC_INDEX 9 #define FDA_EV_MES_INDEX 10 #define FDA_EV_ORD_INDEX 11 #define FDA_EV_CCD_INDEX 12 #define FDA_EV_ITM_INDEX 13 #define FDA_EV_LNE_INDEX 14 #define FDA_EV_USR_INDEX 15 #define FDA_GRP_MAIN_INDEX 16 #define FDA_GRP_CHAT_INDEX 17 #define FDA_GRP_QUES_INDEX 18 #define FDA_GRP_ANSW_INDEX 19 #define FDA_GRP_OFRS_INDEX 20 #define FDA_GRP_PRIC_INDEX 21 #define FDA_GRP_OPIN_INDEX 22 #define FDA_GRP_USER_INDEX 23 #define FDA_GRP_ORDS_INDEX 24 #define FDA_GRP_GEIC_INDEX 25 #define FDA_GRP_FEED_INDEX 26 #define FDA_GRP_MESE_INDEX 27 #define FDA_GRP_NETK_INDEX 28 #define FDA_GRP_TASK_INDEX 29 #define FDA_GRP_FRID_INDEX 30 #define FDA_GRP_INFO_INDEX 31 #define FDA_IDS_MAX 16 #define SCRIPT_JS_BEGIN "\n" #define FDA_HTML_BEGIN "FdAjax\n" /* convert index to mask */ extern unsigned int g_ev_mask_by_index[FDA_TYPES_MAX]; extern char *g_ev_name_by_index[FDA_TYPES_MAX]; /* FDALive module commands */ enum gdc_cmd_t { cmd_none = 0, cmd_wait, cmd_stream, cmd_push, cmd_alert, cmd_cancel, cmd_chatsig, cmd_check_user, cmd_login, cmd_logout, cmd_info, cmd_addchat, cmd_rmchat }; /* commands results */ enum cmd_res_t { cmdr_ok = 0, cmdr_mem_res_error = 1, cmdr_not_in_chat = 2, cmdr_mes_sent = 3, cmdr_user_not_logged = 4, cmdr_already_logged = 5, cmdr_login_ok = 6, cmdr_logout_ok = 7, cmdr_user_not_found = 8, cmdr_chat_peer_add = 9, cmdr_chat_peer_rm_1 = 10, cmdr_chat_peer_rm_2 = 11, cmdr_cuser_not_found = 12, cmdr_cuser_too_many = 13, cmdr_wrong_syntax = 14, cmdr_user_active = 15, cmdr_login_bad_id = 16, cmdr_login_old_sess = 17, cmdr_grp_not_found = 18 }; enum auth_problem_t { authp_null_userid = 0, authp_user_not_found = 1, authp_ip_addr = 2, authp_null_cookie = 3, authp_sessid = 4, authp_no_guests = 5 }; typedef enum auth_problem_t* auth_problem_p; /* Info about one user's browser window */ struct user_info_s; struct events_info_s { unsigned int types; int ids[FDA_EV_MAX][FDA_IDS_MAX]; unsigned char ids_len[FDA_EV_MAX]; unsigned char count; }; typedef struct events_info_s events_info_t; typedef struct events_info_s* evetns_info_p; enum fda_win_type { fda_win_chunked = 0, fda_win_stream = 1 }; struct win_info_s { int win_id; int win_st; int www_id; int send_count; unsigned int last_alert; enum fda_win_type win_type; struct user_info_s *owner; connection *con; buffer *to_send; events_info_t ev; struct timeval created_at; struct timeval last_send; struct timeval last_mes_at[FDA_TYPES_MAX]; }; typedef struct win_info_s win_info_t; typedef struct win_info_s* win_info_p; /* A message to a user */ struct mes_info_s { buffer *mes; events_info_t ev; int send_count; int to_remove; int amode; struct timeval created_at; struct mes_info_s *next, *prev; }; typedef struct mes_info_s mes_info_t; typedef struct mes_info_s* mes_info_p; struct mes_list_s { mes_info_p first_mes; mes_info_p last_mes; }; typedef struct mes_list_s mes_list_t; typedef struct mes_list_s* mes_list_p; /* An alert to a user */ struct alert_info_s { unsigned int id; buffer *mes; struct timeval created_at; }; typedef struct alert_info_s alert_info_t; typedef struct alert_info_s* alert_info_p; #define PEERS_MAX 20 #define WINDOWS_MAX 5 #define ALERTS_MAX 10 #define SESS_ID_LEN_MAX 128 #define PASSWORD_MAX 128 /* Info about logged user */ struct user_info_s { int user_id; struct in_addr ipaddr; char sess_id[SESS_ID_LEN_MAX]; struct timeval created_at; int send_count; int send_peer_count; unsigned int last_alert; mes_list_t mes_list; int peers[PEERS_MAX]; alert_info_t alerts[ALERTS_MAX]; win_info_p windows[WINDOWS_MAX]; UT_hash_handle hh_sess, hh_id; }; typedef struct user_info_s user_info_t; typedef struct user_info_s* user_info_p; /* Groups info */ struct win_node_s { win_info_p win; struct win_node_s *next; struct win_node_s *prev; }; typedef struct win_node_s win_node_t; typedef struct win_node_s* win_node_p; struct grp_info_s { int grp_id; mes_list_t mes_list; win_node_p first_node; win_node_p last_node; }; typedef struct grp_info_s grp_info_t; typedef struct grp_info_s* grp_info_p; /* Parsed user's request */ struct user_request_s { int cs; enum gdc_cmd_t cmd; events_info_t ev; struct timeval tv; int user_id; int peer_id; int win_id; int win_st; int www_id; unsigned int alert_id; unsigned int amode; int force_old_close; buffer *mes; struct in_addr ipaddr; buffer *req_sess_id; char sess_id_cookie[SESS_ID_LEN_MAX]; char admin_passwd[PASSWORD_MAX]; }; typedef struct user_request_s user_request_t; typedef struct user_request_s* user_request_p; typedef struct { buffer *ext; buffer *js_peer_func; buffer *js_grp_peer_func; buffer *js_logout_code; buffer *js_maxwin_code; buffer *js_nocookies_code; buffer *js_notfound_code; buffer *js_relogin_func; buffer *js_redirect_func; buffer *js_alert_id_func; buffer *js_ping_code; buffer *js_no_guests; buffer *unw_prefix; buffer *session_cookie; buffer *html_begin; buffer *admin_password; array *admin_ips; array *allow_peer_call; unsigned short mes_live_max; unsigned short win_timeout; unsigned short log_level; unsigned short log_security; unsigned short merge_messages; unsigned short send_redirects; unsigned short check_user_ip; unsigned short send_pings; unsigned short allow_guests; } plugin_config; #define ALLOWED_MAX 100 typedef struct { PLUGIN_DATA; buffer *match_buf; plugin_config **config_storage; plugin_config conf; buffer *js_peer_func; buffer *js_grp_peer_func; buffer *js_logout_code; buffer *js_maxwin_code; buffer *js_nocookies_code; buffer *js_notfound_code; buffer *js_relogin_func; buffer *js_redirect_func; buffer *js_alert_id_func; buffer *js_ping_code; buffer *js_no_guests; buffer *unw_prefix; buffer *session_cookie; buffer *html_begin; buffer *admin_password; int log_security; int log_level; int mes_live_max; int win_timeout; int next_check_dcons; int merge_messages; int send_redirects; int check_user_ip; int send_pings; int allow_guests; unsigned int allow_peer_call_mask; struct in_addr admin_allowed_ips[ALLOWED_MAX]; size_t admin_allowed_used; user_info_p users_by_sess; user_info_p users_by_id; grp_info_t groups[FDA_MAX_GROUPS]; } plugin_data; int mod_fdajax_pinit(user_request_p req); int mod_fdajax_pexec(user_request_p req, char *start, size_t len); int mod_fdajax_pfinish(user_request_p req); int mod_fdajax_cinit(int *pcs); int mod_fdajax_cexec(int *pcs, char *start, size_t len); int mod_fdajax_cfinish(int *pcs); int mod_fdajax_info(server *srv, plugin_data *p, connection *con); void con_set_response(server *srv, plugin_data *p, connection *con, buffer *resp, int st); void con_prepare_response(server *srv, plugin_data *p, connection *con, int st); void con_finalize_response(server *srv, plugin_data *p, connection *con, int st); void buffer_append_nl(buffer *buf); char *tv2s(struct timeval atv); int is_tcp_socket_open(server *srv, plugin_data *p, connection *con); user_info_p user_login(user_request_p req); user_info_p user_create_guest(connection *con, user_request_p req); void user_update_addr_and_sess(plugin_data *p, user_info_p user, user_request_p req); void user_update_id_and_ipaddr(plugin_data *p, user_info_p user, user_request_p req); void user_free(server *srv, plugin_data *p, connection *con, user_info_p user); user_info_p user_find_by_sess(plugin_data *p, char *s); user_info_p user_find_by_id(plugin_data *p, int user_id); void user_attach(server *srv, plugin_data *p, user_info_p new_user); void user_detach(server *srv, plugin_data *p, user_info_p user); void users_free(server *srv, plugin_data *p); user_info_p user_auth(server *srv, connection *con, plugin_data *p, user_info_p user, user_request_p req, auth_problem_p preason); int user_check(server *srv, plugin_data *p, connection *con, user_info_p user); void alert_free_slot(user_info_p user, size_t i); unsigned int alert_max_id(user_info_p user); int alert_cancel(user_info_p user, unsigned int id); size_t alert_find_slot(user_info_p user); int alert_add(server *srv, plugin_data *p, connection *con, user_info_p user, user_request_p req); int alert_add_from_mes(server *srv, plugin_data *p, user_info_p user, mes_info_p mes); int alert_append(server *srv, plugin_data *p, user_info_p user, buffer *buf, unsigned int last_id); enum gdc_cmd_t alert_push(server *srv, plugin_data *p, user_info_p user); enum gdc_cmd_t chat_add_peer(user_info_p user, int peer_id); enum gdc_cmd_t chat_rm_peer(user_info_p user, int peer_id); int chat_access_peer(user_info_p user, int peer_id); mes_info_p message_init(user_request_p req); mes_info_p message_init_peer(server *srv, plugin_data *p, user_info_p user, user_request_p req); void message_free(mes_info_p mes); void message_list_init(mes_list_p list); void message_attach(mes_list_p list, mes_info_p mes); void message_detach(mes_list_p list, mes_info_p mes); void message_remove_all(mes_list_p list); void message_remove_old(server *srv, plugin_data *p, mes_list_p list); int message_append_to_win(server *srv, plugin_data *p, win_info_p win, mes_info_p mes, int ev_index, int nl); int message_append_as_unwanted(server *srv, plugin_data *p, win_info_p win, mes_info_p mes); enum cmd_res_t message_send_pending(server *srv, plugin_data *p, mes_info_p mes, win_info_p win); int message_handle_unsend(server *srv, plugin_data *p, user_info_p user, mes_info_p mes, win_info_p recv_win); int message_check_unsend(server *srv, plugin_data *p, user_info_p user, win_info_p recv_win); enum gdc_cmd_t message_push(server *srv, plugin_data *p, user_info_p user, mes_info_p mes); int message_grp_push(server *srv, plugin_data *p, grp_info_p grp, mes_info_p mes); win_info_p window_find(connection *con, user_info_p user, user_request_p req); int window_should_redirect(server *srv, plugin_data *p, connection *con, user_info_p user, user_request_p req); win_info_p window_init(plugin_data *p, connection *con, user_info_p user, user_request_p req, enum fda_win_type win_type, int slot); void window_free(plugin_data *p, win_info_p win); int window_find_slot(user_info_p user); void window_close_all(server *srv, plugin_data *p, connection *con, user_info_p user); void window_close(server *srv, plugin_data *p, user_info_p user, win_info_p win, buffer *close_message); int window_remove_old(server *srv, plugin_data *p, connection *con, user_info_p user); void window_update_last_send(win_info_p win, struct timeval tv); int window_is_old(win_info_p win, struct timeval now, unsigned long win_timeout); buffer * window_get_buffer(win_info_p win); void window_append_string(win_info_p win, char *s); void window_append_string_buffer(win_info_p win, buffer *sb); win_info_p window_first_with_unw(server *srv, plugin_data *p, user_info_p user); int window_can_receive(win_info_p win, mes_info_p mes, int check_time); int window_check_groups(server *srv, plugin_data *p, win_info_p win); int window_flush_all(server *srv, plugin_data *p, user_info_p user); int window_flush(server *srv, plugin_data *p, win_info_p win); int event_bit_to_index(unsigned int ev); int event_check_ids(win_info_p win, mes_info_p mes, int ev_nr); int event_find_index_by_name(char *s); void group_init(grp_info_p grp, int i); grp_info_p group_find(plugin_data *p, unsigned int ev); void group_add_window(grp_info_p grp, win_info_p win); void group_rm_window(grp_info_p grp, win_info_p win); void group_remove_old_mes(server *srv, plugin_data *p); #endif mod_fdajax-0.9/src/uthash.h0000644000175000017500000011334210650177505014356 0ustar greggreg/* Copyright (c) 2003-2006, Troy Hanson http://uthash.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* memcmp,strlen */ #ifndef UTHASH_H #define UTHASH_H #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #define uthash_bkt_malloc(sz) malloc(sz) /* malloc fcn for UT_hash_bucket's */ #define uthash_bkt_free(ptr) free(ptr) /* free fcn for UT_hash_bucket's */ #define uthash_tbl_malloc(sz) malloc(sz) /* malloc fcn for UT_hash_table */ #define uthash_tbl_free(ptr) free(ptr) /* free fcn for UT_hash_table */ #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ #define uthash_expand_fyi(tbl) /* can be defined to log expands */ /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ #define HASH_FIND(hh,head,keyptr,keylen_in,out) \ do { \ out=head; \ if (head) { \ (head)->hh.tbl->key = (char*)(keyptr); \ (head)->hh.tbl->keylen = keylen_in; \ HASH_FCN((head)->hh.tbl->key,(head)->hh.tbl->keylen, \ (head)->hh.tbl->num_buckets,(head)->hh.tbl->bkt, \ (head)->hh.tbl->i, (head)->hh.tbl->j,(head)->hh.tbl->k); \ HASH_FIND_IN_BKT(hh, (head)->hh.tbl->buckets[ (head)->hh.tbl->bkt], \ keyptr,keylen_in,out); \ } \ } while (0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ add->hh.next = NULL; \ add->hh.key = (char*)keyptr; \ add->hh.keylen = keylen_in; \ add->hh.elmt = add; \ if (!(head)) { \ head = add; \ (head)->hh.prev = NULL; \ (head)->hh.tbl = (UT_hash_table*)uthash_tbl_malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ (head)->hh.tbl->name = #head; \ (head)->hh.tbl->tail = &(add->hh); \ (head)->hh.tbl->noexpand = 0; \ (head)->hh.tbl->hash_q = 1; \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->num_items = 0; \ (head)->hh.tbl->hho = ((long)(&add->hh) - (long)(add)); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_bkt_malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ } else { \ (head)->hh.tbl->tail->next = add; \ add->hh.prev = (head)->hh.tbl->tail->elmt; \ (head)->hh.tbl->tail = &(add->hh); \ } \ (head)->hh.tbl->num_items++; \ add->hh.tbl = (head)->hh.tbl; \ (head)->hh.tbl->key = (char*)keyptr; \ (head)->hh.tbl->keylen = keylen_in; \ HASH_FCN((head)->hh.tbl->key,(head)->hh.tbl->keylen, \ (head)->hh.tbl->num_buckets, \ (head)->hh.tbl->bkt, \ (head)->hh.tbl->i, (head)->hh.tbl->j, (head)->hh.tbl->k ); \ HASH_ADD_TO_BKT(hh,(head)->hh.tbl->buckets[(head)->hh.tbl->bkt],add); \ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ HASH_FSCK(head); \ } while(0) #define HASH_DELETE(hh,head,delptr) \ do { \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ uthash_bkt_free((head)->hh.tbl->buckets ); \ uthash_tbl_free((head)->hh.tbl); \ head = NULL; \ } else { \ if ((delptr) == (head)->hh.tbl->tail->elmt) { \ (head)->hh.tbl->tail = (void*)(((long)((delptr)->hh.prev)) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)(((long)((delptr)->hh.prev)) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ head = (delptr)->hh.next; \ } \ if ((delptr)->hh.next) { \ ((UT_hash_handle*)(((long)((delptr)->hh.next)) + \ (head)->hh.tbl->hho))->prev = (delptr)->hh.prev; \ } \ (head)->hh.tbl->key = (char*)((delptr)->hh.key); \ (head)->hh.tbl->keylen = (delptr)->hh.keylen; \ HASH_FCN((head)->hh.tbl->key,(head)->hh.tbl->keylen, \ (head)->hh.tbl->num_buckets,(head)->hh.tbl->bkt, \ (head)->hh.tbl->i,(head)->hh.tbl->j,(head)->hh.tbl->k ); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[(head)->hh.tbl->bkt], \ delptr); \ (head)->hh.tbl->num_items--; \ } \ HASH_FSCK(head); \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield,strlen(add->strfield),add) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. * This function misuses fields in UT_hash_table for its bookkeeping variables. */ #ifdef HASH_DEBUG #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) #define HASH_FSCK(head) \ do { \ if (head) { \ (head)->hh.tbl->keylen = 0; /* item counter */ \ for( (head)->hh.tbl->bkt_i = 0; \ (head)->hh.tbl->bkt_i < (head)->hh.tbl->num_buckets; \ (head)->hh.tbl->bkt_i++) \ { \ (head)->hh.tbl->bkt_ideal = 0; /* bkt item counter */ \ (head)->hh.tbl->hh = \ (head)->hh.tbl->buckets[(head)->hh.tbl->bkt_i].hh_head; \ (head)->hh.tbl->key = NULL; /* hh_prev */ \ while ((head)->hh.tbl->hh) { \ if ((head)->hh.tbl->key != \ (char*)((head)->hh.tbl->hh->hh_prev)) { \ HASH_OOPS("invalid hh_prev %x, actual %x\n", \ (head)->hh.tbl->hh->hh_prev, \ (head)->hh.tbl->key ); \ } \ (head)->hh.tbl->bkt_ideal++; \ (head)->hh.tbl->key = (char*)((head)->hh.tbl->hh); \ (head)->hh.tbl->hh = (head)->hh.tbl->hh->hh_next; \ } \ (head)->hh.tbl->keylen += (head)->hh.tbl->bkt_ideal; \ if ((head)->hh.tbl->buckets[(head)->hh.tbl->bkt_i].count \ != (head)->hh.tbl->bkt_ideal) { \ HASH_OOPS("invalid bucket count %d, actual %d\n", \ (head)->hh.tbl->buckets[(head)->hh.tbl->bkt_i].count, \ (head)->hh.tbl->bkt_ideal); \ } \ } \ if ((head)->hh.tbl->keylen != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid hh item count %d, actual %d\n", \ (head)->hh.tbl->num_items, (head)->hh.tbl->keylen ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ (head)->hh.tbl->keylen = 0; /* item counter */ \ (head)->hh.tbl->key = NULL; /* app prev */ \ (head)->hh.tbl->hh = &(head)->hh; \ while ((head)->hh.tbl->hh) { \ (head)->hh.tbl->keylen++; \ if ((head)->hh.tbl->key !=(char*)((head)->hh.tbl->hh->prev)) {\ HASH_OOPS("invalid prev %x, actual %x\n", \ (head)->hh.tbl->hh->prev, \ (head)->hh.tbl->key ); \ } \ (head)->hh.tbl->key = (head)->hh.tbl->hh->elmt; \ (head)->hh.tbl->hh = ( (head)->hh.tbl->hh->next ? \ (UT_hash_handle*)((long)((head)->hh.tbl->hh->next) + \ (head)->hh.tbl->hho) \ : NULL ); \ } \ if ((head)->hh.tbl->keylen != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid app item count %d, actual %d\n", \ (head)->hh.tbl->num_items, (head)->hh.tbl->keylen ); \ } \ } \ } while (0) #else #define HASH_FSCK(head) #endif /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ (head)->hh.tbl->keylen = fieldlen; \ write(HASH_EMIT_KEYS, &((head)->hh.tbl->keylen), sizeof(int)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); #else #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkins unless specified e.g. DHASH_FUNCTION=HASH_SAX */ #ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN #endif /* The Bernstein hash function, used in Perl prior to v5.6 */ #define HASH_BER(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 0; \ while (keylen--) bkt = (bkt * 33) + *key++; \ bkt &= (num_bkts-1); /* SAX/FNV/OAT/JEN/JSW hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/hashing.html (thanks Julienne Walker) */ #define HASH_SAX(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 0; \ for(i=0; i < keylen; i++) \ bkt ^= (bkt << 5) + (bkt >> 2) + key[i]; \ bkt &= (num_bkts-1); #define HASH_FNV(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 2166136261UL; \ for(i=0; i < keylen; i++) \ bkt = (bkt * 16777619) ^ key[i]; \ bkt &= (num_bkts-1); #define HASH_OAT(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 0; \ for(i=0; i < keylen; i++) { \ bkt += key[i]; \ bkt += (bkt << 10); \ bkt ^= (bkt >> 6); \ } \ bkt += (bkt << 3); \ bkt ^= (bkt >> 11); \ bkt += (bkt << 15); \ bkt &= (num_bkts-1); #define HASH_JEN_MIX(a,b,c) \ { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } #define HASH_JEN(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 0xfeedbeef; \ i = j = 0x9e3779b9; \ k = keylen; \ while (k >= 12) { \ i += (key[0] + ( (unsigned)key[1] << 8 ) \ + ( (unsigned)key[2] << 16 ) \ + ( (unsigned)key[3] << 24 ) ); \ j += (key[4] + ( (unsigned)key[5] << 8 ) \ + ( (unsigned)key[6] << 16 ) \ + ( (unsigned)key[7] << 24 ) ); \ bkt += (key[8] + ( (unsigned)key[9] << 8 ) \ + ( (unsigned)key[10] << 16 ) \ + ( (unsigned)key[11] << 24 ) ); \ \ HASH_JEN_MIX(i, j, bkt); \ \ key += 12; \ k -= 12; \ } \ bkt += keylen; \ switch ( k ) { \ case 11: bkt += ( (unsigned)key[10] << 24 ); \ case 10: bkt += ( (unsigned)key[9] << 16 ); \ case 9: bkt += ( (unsigned)key[8] << 8 ); \ case 8: j += ( (unsigned)key[7] << 24 ); \ case 7: j += ( (unsigned)key[6] << 16 ); \ case 6: j += ( (unsigned)key[5] << 8 ); \ case 5: j += key[4]; \ case 4: i += ( (unsigned)key[3] << 24 ); \ case 3: i += ( (unsigned)key[2] << 16 ); \ case 2: i += ( (unsigned)key[1] << 8 ); \ case 1: i += key[0]; \ } \ HASH_JEN_MIX(i, j, bkt); \ bkt &= (num_bkts-1); #define HASH_JSW(key,keylen,num_bkts,bkt,i,j,k) \ bkt = 16777551; \ for(i=0; i < keylen; i++) { \ bkt = (bkt << 1 | bkt >> 31) ^ \ *(int*)((long)( \ "\xe9\x81\x51\xe4\x84\x9d\x32\xd9\x2d\xda\xca\x94\xa7\x85\x1e" \ "\x28\xfe\xa3\x18\x60\x28\x45\xa6\x48\x67\xdb\xd5\xa2\x91\x4d" \ "\x1a\x2f\x97\x37\x82\xd8\xe9\x1c\xb7\x7b\x3c\xa5\x4c\x23\x2" \ "\x42\x85\x20\x78\x6c\x6\x67\x6f\xa5\xcb\x53\x8c\xe1\x1f\x12" \ "\x66\xcb\xa0\xbe\x47\x59\x8\x20\xd5\x31\xd9\xdc\xcc\x27\xc3" \ "\x4d\x8\x9f\xb3\x50\x8\x90\x4f\x1f\x20\x60\xb8\xe2\x7b\x63" \ "\x49\xc0\x64\xc7\xaf\xc9\x81\x9c\x5f\x7d\x45\xc5\xe4\xe4\x86" \ "\xaf\x1a\x15\x6c\x9b\xc3\x7c\xc5\x88\x2b\xf3\xd9\x72\x76\x47" \ "\x56\xe6\x8c\xd1\x6c\x94\x41\x59\x4d\xe2\xd7\x44\x9a\x55\x5e" \ "\xee\x9d\x7c\x8f\x21\x57\x10\x77\xf7\x4b\xd8\x7e\xc0\x4d\xba" \ "\x1f\x96\x2a\x60\x13\xae\xab\x58\x70\xe5\x23\x62\x2b\x63\xb6" \ "\x42\x8e\x8f\x57\xf2\xfa\x47\x37\x91\xac\x11\x3d\x9a\x85\x73" \ "\x9e\x39\x65\xc8\xd4\x5b\xaa\x35\x72\x5f\x40\x31\x9a\xb0\xdd" \ "\xa9\x2c\x16\xa3\x32\xef\xcb\x8c\x80\x33\x60\xd\x85\xce\x22" \ "\x8c\x28\x6\x7f\xff\xf6\x8a\x5f\x21\x8e\xf2\xd0\xd9\x63\x66" \ "\x22\xe8\xe6\x3\x39\xfd\x10\x69\xce\x6c\xc4\xde\xf3\x87\x56" \ "\xc8\x4a\x31\x51\x58\xc5\x62\x30\x8e\xd\xd5\x2f\x7c\x24\xca" \ "\xd1\x12\x1b\x3a\x3e\x95\x99\xa\x7\xc1\x83\xd0\x4f\x97\x8c" \ "\xf1\xb0\x9c\xd8\xb9\x72\xd7\x3e\x6b\x66\x83\x8e\xe9\x86\xad" \ "\xfa\xc2\xe\x4\xb5\x7b\x5d\x0\xbc\x47\xbe\x4\x69\xfa\xd1" \ "\x29\x5c\x77\x38\xfc\x88\xeb\xd5\xe1\x17\x54\xf6\xe5\xb3\xae" \ "\xc7\x14\xb6\x4b\xa6\x42\x4b\xa3\xdf\xa5\xcf\xdb\xad\xcd\x2c" \ "\xa3\x3\x13\xc0\x42\x5d\x6e\x3c\xfe\xd8\xeb\xa7\x96\x47\x2b" \ "\x61\xb3\x70\xc9\x6d\xff\x1a\x82\x65\xdc\x92\x4b\x1a\x52\x75" \ "\xa5\x61\x55\x2b\xe\x7\xde\x1e\x71\xc5\x12\x34\x59\x4f\x19" \ "\x2\x9\xb6\x5\xe6\x7b\xad\xb6\x92\xfb\x84\x32\xf1\x45\x6c" \ "\xec\x1a\xcb\x39\x32\x2\x47\x51\xd6\xc8\x9d\xd0\xb1\xdb\xa8" \ "\x90\x4c\x65\x5a\x77\x1f\xca\x74\x8e\x3b\xce\x76\x55\x8b\x78" \ "\x3c\xf3\x19\x8f\xe1\xc3\xa9\x8a\xc8\xf3\x14\x30\x4e\x77\xe9" \ "\xd5\x6a\xcb\x96\x2f\x31\x35\xff\x6b\x10\x92\xf7\xc4\x33\xb8" \ "\x76\x35\x6\xf\x82\x1c\xfa\x1f\x92\x47\xa1\xf9\x7e\xe5\x51" \ "\xee\x63\xaa\x9a\x38\xa3\xa1\x86\xbf\xf0\xe8\x29\xe1\x19\x83" \ "\xff\x36\x3c\x26\x15\x89\x36\x22\x93\x41\x3e\x63\x36\x34\x4c" \ "\xda\x18\xd4\x18\xd8\xc8\x8a\x10\x1f\x14\x4c\x7f\x79\xfc\x46" \ "\xbb\xc8\x24\x51\xc7\xe4\xfb\xc0\x78\xb1\xe9\xac\xf1\x3d\x55" \ "\x51\x9c\x8\xf0\xa6\x3\xcb\x91\xc6\xf4\xe2\xd4\xe5\x18\x61" \ "\xfc\x8f\x8a\xce\x89\x33\xcd\xf\x7d\x50\xa0\x7d\x3f\xac\x49" \ "\xe1\x71\x92\xc7\x8d\xc0\xd0\x6e\xe4\xf7\xcd\xc1\x47\x9f\x99" \ "\xd5\x7\x20\xad\x64\xdb\xab\x44\xd4\x8\xc6\x9a\xa4\xa7\x7c" \ "\x9b\x13\xe4\x9c\x88\xec\xc4\xcb\xe1\x3f\x5\x5\xf\xd\x3a" \ "\x75\xed\xfa\xc0\x23\x34\x74\xfd\xca\x1c\x74\x77\x29\xc8\xb6" \ "\xe2\xbb\xa1\xa\x2e\xae\x65\x3e\xcb\xf5\x5e\xe0\x29\x4c\xfa" \ "\xab\x35\xea\x7\x9f\xb3\x3b\x9c\x4e\x86\xe8\x5b\x76\x11\xf1" \ "\xbf\x7f\x73\x34\x71\x9\x2d\x2a\x60\x8f\x14\x12\xba\x26\x84" \ "\xb9\x94\xa9\x59\x38\x25\xfd\x77\xc3\xe5\x86\xc4\x3\xda\x32" \ "\x30\xd8\x84\x81\x83\x14\x8c\x24\xee\x51\xa9\x92\x61\xb2\xeb" \ "\xce\xac\x34\xc1\xad\x24\x74\xce\xf9\xce\x5c\xfd\x45\x69\x1d" \ "\xc6\xc2\xaf\x7c\x8d\x5\x52\xb5\x88\x2f\x9f\xee\x6b\x5f\xbd" \ "\xfe\x22\x6\x47\xa2\xc8\x25\x37\x67\x44\x4c\xe\xfe\x7e\x5a" \ "\x36\x7f\x18\x83\x8f\x82\x87\x3b\xbf\xb8\xd2\x37\xff\x52\x60" \ "\xb5\xf3\xd\x20\x80\xcc\xb2\x7a\xdd\xc2\x94\xbc\xe3\xb1\x87" \ "\x3e\x49\x57\xcc\xe9\x5a\xea\xb4\xe\xdf\xa6\x8f\x70\x60\x32" \ "\xb\x7d\x74\xf5\x46\xb6\x93\xc2\x5\x92\x72\xfc\xd9\xd2\xe5" \ "\x90\x36\x2a\xd4\xf9\x50\x33\x52\xa5\xcc\xcf\x14\x9e\xdc\x4f" \ "\xb7\x7d\xcf\x25\xdb\xc0\x46\xdb\xea\xe\x27\xc8\x18\x40\x39" \ "\xbd\xec\x48\xa3\xfa\x87\xa3\x18\x68\xfc\x7a\x44\xa8\xc5\x8c" \ "\x45\x81\x70\x72\x14\x70\xf9\x40\xc8\xe7\x41\xcb\xde\xd\x4e" \ "\x35\x4d\xcd\xe2\x40\xa3\x2e\xbb\xb7\x50\x6c\x26\xb8\xbe\x2a" \ "\x36\x8e\x23\xb\xa\xfe\xed\xa\xe7\xa0\x16\x73\xad\x24\x51" \ "\x7f\xda\x9d\xd7\x9f\x18\xe6\xa8\xe4\x98\xbc\x62\x77\x55\x60" \ "\x88\x16\x25\xbf\x95\xad\xea\xe1\x87\x18\x35\x9e\x7c\x51\xee" \ "\xc0\x80\x8b\xb8\x37\xfd\x95\xfe\x87\x15\xf4\x97\xd5\x61\x4f" \ "\x97\xfa\xaf\x48\xd\x5b\x84\x2d\xdb\x15\xf2\xb4\x17\x4f\x41" \ "\x31\x58\x32\x93\xc1\x52\x34\xa6\x17\xd\x56\x5\xee\xfb\xfb" \ "\x2d\x69\x14\xbe\x24\x94\x8\xb0\xfc\x9f\x2\x95\x88\x7d\xd6" \ "\xe7\xa4\x5b\xbb\xf2\x7d\xd8\xa5\xd2\x7c\x9\x62\x22\x5\x53" \ "\xd0\x67\xeb\x68\xfc\x82\x80\xf\xc9\x73\x76\x36\xb8\x13\x9f" \ "\xb1\xf1\xee\x61\x12\xe7\x5d\x75\x65\xb8\x84\x17\xb\x7b\x28" \ "\x4c\xb7\xda\xbb" ) \ + ( (unsigned char)key[i] * sizeof(int) )); \ } \ bkt &= (num_bkts-1); /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(hh,head,keyptr,keylen_in,out) \ out = (head.hh_head) ? (head.hh_head->elmt) : NULL; \ while (out) { \ if (out->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ } \ out= (out->hh.hh_next) ? (out->hh.hh_next->elmt) : NULL; \ } /* add an item to a bucket */ #define HASH_ADD_TO_BKT(hh,head,add) \ head.count++; \ add->hh.hh_next = head.hh_head; \ add->hh.hh_prev = NULL; \ if (head.hh_head) head.hh_head->hh_prev = &add->hh; \ head.hh_head=&add->hh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && add->hh.tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS(add->hh.tbl) \ } /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,delptr) \ (head).count--; \ if ((head).hh_head->elmt == delptr) { \ (head).hh_head = delptr->hh.hh_next; \ } \ if (delptr->hh.hh_prev) { \ delptr->hh.hh_prev->hh_next = delptr->hh.hh_next; \ } \ if (delptr->hh.hh_next) { \ delptr->hh.hh_next->hh_prev = delptr->hh.hh_prev; \ } #define HASH_EXPAND_BUCKETS(tbl) \ tbl->new_buckets = (UT_hash_bucket*)uthash_bkt_malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!tbl->new_buckets) { uthash_fatal( "out of memory"); } \ memset(tbl->new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->bkt_ideal= (tbl->num_items / tbl->num_buckets*2) + \ ((tbl->num_items % (tbl->num_buckets*2)) ? 1 : 0);\ tbl->sum_of_deltas = 0; \ for(tbl->bkt_i = 0; tbl->bkt_i < tbl->num_buckets; tbl->bkt_i++) \ { \ tbl->hh = tbl->buckets[ tbl->bkt_i ].hh_head; \ while (tbl->hh) { \ tbl->hh_nxt = tbl->hh->hh_next; \ tbl->key = tbl->hh->key; \ tbl->keylen = tbl->hh->keylen; \ HASH_FCN(tbl->key,tbl->keylen,tbl->num_buckets*2,tbl->bkt,\ tbl->i,tbl->j,tbl->k); \ tbl->newbkt = &(tbl->new_buckets[ tbl->bkt ]); \ if (++(tbl->newbkt->count) > tbl->bkt_ideal) { \ tbl->sum_of_deltas++; \ tbl->newbkt->expand_mult = tbl->newbkt->count / \ tbl->bkt_ideal; \ } \ tbl->hh->hh_prev = NULL; \ tbl->hh->hh_next = tbl->newbkt->hh_head; \ if (tbl->newbkt->hh_head) tbl->newbkt->hh_head->hh_prev = \ tbl->hh; \ tbl->newbkt->hh_head = tbl->hh; \ tbl->hh = tbl->hh_nxt; \ } \ } \ tbl->num_buckets *= 2; \ uthash_bkt_free( tbl->buckets ); \ tbl->buckets = tbl->new_buckets; \ tbl->new_hash_q = 1-(tbl->sum_of_deltas * 1.0 / tbl->num_items); \ if (tbl->hash_q < 0.5 && tbl->new_hash_q < 0.5) { \ tbl->noexpand=1; \ uthash_noexpand_fyi(tbl); \ } \ tbl->hash_q = tbl->new_hash_q; \ uthash_expand_fyi(tbl); /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ #define HASH_SORT(head,cmpfcn) \ if (head) { \ (head)->hh.tbl->insize = 1; \ (head)->hh.tbl->looping = 1; \ (head)->hh.tbl->list = &((head)->hh); \ while ((head)->hh.tbl->looping) { \ (head)->hh.tbl->p = (head)->hh.tbl->list; \ (head)->hh.tbl->list = NULL; \ (head)->hh.tbl->tale = NULL; \ (head)->hh.tbl->nmerges = 0; \ while ((head)->hh.tbl->p) { \ (head)->hh.tbl->nmerges++; \ (head)->hh.tbl->q = (head)->hh.tbl->p; \ (head)->hh.tbl->psize = 0; \ for ( (head)->hh.tbl->i = 0; \ (head)->hh.tbl->i < (head)->hh.tbl->insize; \ (head)->hh.tbl->i++ ) { \ (head)->hh.tbl->psize++; \ (head)->hh.tbl->q = (((head)->hh.tbl->q->next) ? \ ((void*)(((long)((head)->hh.tbl->q->next)) + \ (head)->hh.tbl->hho)) : NULL); \ if (! ((head)->hh.tbl->q) ) break; \ } \ (head)->hh.tbl->qsize = (head)->hh.tbl->insize; \ while (((head)->hh.tbl->psize > 0) || \ (((head)->hh.tbl->qsize > 0) && (head)->hh.tbl->q )) { \ if ((head)->hh.tbl->psize == 0) { \ (head)->hh.tbl->e = (head)->hh.tbl->q; \ (head)->hh.tbl->q = (((head)->hh.tbl->q->next) ? \ ((void*)(((long)((head)->hh.tbl->q->next)) + \ (head)->hh.tbl->hho)) : NULL); \ (head)->hh.tbl->qsize--; \ } else if ( ((head)->hh.tbl->qsize == 0) || \ !((head)->hh.tbl->q) ) { \ (head)->hh.tbl->e = (head)->hh.tbl->p; \ (head)->hh.tbl->p = (((head)->hh.tbl->p->next) ? \ ((void*)(((long)((head)->hh.tbl->p->next)) + \ (head)->hh.tbl->hho)) : NULL); \ (head)->hh.tbl->psize--; \ } else if (( \ cmpfcn((head)->hh.tbl->p->elmt,(head)->hh.tbl->q->elmt)) \ <= 0) { \ (head)->hh.tbl->e = (head)->hh.tbl->p; \ (head)->hh.tbl->p = (((head)->hh.tbl->p->next) ? \ ((void*)(((long)((head)->hh.tbl->p->next)) + \ (head)->hh.tbl->hho)) : NULL); \ (head)->hh.tbl->psize--; \ } else { \ (head)->hh.tbl->e = (head)->hh.tbl->q; \ (head)->hh.tbl->q = (((head)->hh.tbl->q->next) ? \ ((void*)(((long)((head)->hh.tbl->q->next)) + \ (head)->hh.tbl->hho)) : NULL); \ (head)->hh.tbl->qsize--; \ } \ if ( (head)->hh.tbl->tale ) { \ (head)->hh.tbl->tale->next = (((head)->hh.tbl->e) ? \ ((head)->hh.tbl->e->elmt) : NULL); \ } else { \ (head)->hh.tbl->list = (head)->hh.tbl->e; \ } \ (head)->hh.tbl->e->prev = (((head)->hh.tbl->tale) ? \ ((head)->hh.tbl->tale->elmt) : NULL); \ (head)->hh.tbl->tale = (head)->hh.tbl->e; \ } \ (head)->hh.tbl->p = (head)->hh.tbl->q; \ } \ (head)->hh.tbl->tale->next = NULL; \ if ( (head)->hh.tbl->nmerges <= 1 ) { \ (head)->hh.tbl->looping=0; \ (head)->hh.tbl->tail = (head)->hh.tbl->tale; \ (head) = (head)->hh.tbl->list->elmt; \ } \ (head)->hh.tbl->insize *= 2; \ } \ HASH_FSCK(head); \ } typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; unsigned expand_mult; } UT_hash_bucket; typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets; unsigned num_items; int noexpand; /* when set, inhibits expansion of buckets for this hash */ double hash_q; /* measures the evenness of the items among buckets (0-1) */ struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ char *name; /* macro-stringified name of list head, used by libut */ int hho; /* scratch */ unsigned bkt; char *key; int keylen; unsigned i,j,k; /* scratch for bucket expansion */ UT_hash_bucket *new_buckets, *newbkt; struct UT_hash_handle *hh, *hh_nxt; unsigned bkt_i, bkt_ideal, sum_of_deltas; double new_hash_q; /* scratch for sort */ int looping,nmerges,insize,psize,qsize; struct UT_hash_handle *p, *q, *e, *list, *tale; } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *elmt; /* ptr to enclosing element */ void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ int keylen; /* enclosing struct's key len */ } UT_hash_handle; #endif /* UTHASH_H */ mod_fdajax-0.9/src/mod_fdajax_groups.c0000640000175000017500000000305010650106220016520 0ustar greggreg#include "mod_fdajax_defs.h" void group_init(grp_info_p grp, int i) { grp->grp_id = i; message_list_init(&(grp->mes_list)); grp->first_node = grp->last_node = NULL; } grp_info_p group_find(plugin_data *p, unsigned int ev) { int i = event_bit_to_index(ev); if (i >= FDA_GRP_START && i <= FDA_GRP_END) { return &(p->groups[i - FDA_GRP_START]); } else { return NULL; } } void group_add_window(grp_info_p grp, win_info_p win) { win_node_p node = malloc(sizeof(win_node_t)); if (!node) { return; } node->win = win; node->next = node->prev = NULL; if (NULL == grp->first_node) { grp->first_node = grp->last_node = node; return; } grp->last_node->next = node; node->prev = grp->last_node; grp->last_node = node; } void group_rm_window(grp_info_p grp, win_info_p win) { win_node_p node = grp->first_node;; while (node && node->win != win) { node = node->next; } if (!node) { return; } if (grp->first_node == node) { grp->first_node = node->next; } if (grp->last_node == node) { grp->last_node = node->prev; } if (node->next) { node->next->prev = node->prev; } if (node->prev) { node->prev->next = node->next; } node->next = node->prev = NULL; free(node); } void group_remove_old_mes(server *srv, plugin_data *p) { grp_info_p grp; int i; for (i = 0; i < FDA_MAX_GROUPS; i++) { grp = &(p->groups[i]); message_remove_old(srv, p, &(grp->mes_list)); } } mod_fdajax-0.9/src/mod_fdajax_peercall.rl0000640000175000017500000000162010641300132017162 0ustar greggreg#include #include #include #include "mod_fdajax_defs.h" %%{ machine fdamod_peercall; num = (( '-' )? digit {1,20} ( '.' digit {1,20} )? ) ; allowed = any -- (cntrl | 127 | "\"" | "\\"); str_char = allowed | ( "\\" ("\"" | "\\" | "n" | "t" | "f" | "r" )); str = "\"" str_char * "\""; arg = num | str ; main := arg (' '* ',' ' '* arg )* 0 ; }%% %% write data; int mod_fdajax_cinit(int *pcs) { int cs = 0; %% write init; *pcs = cs; return 1; } int mod_fdajax_cexec(int *pcs, char *start, size_t len) { char *p, *pe; int cs = *pcs; assert(*(start + len) == 0); p = start; pe = start + len + 1; %% write exec; *pcs = cs; return 1; } int mod_fdajax_cfinish(int *pcs) { int cs = *pcs; %% write eof; *pcs = cs; if (cs == fdamod_peercall_error) { return -1; } else if (cs >= fdamod_peercall_first_final) { return 1; } return 0; } mod_fdajax-0.9/src/mod_fdajax_parser.c0000640000175000017500000033223110650371255016517 0ustar greggreg#line 1 "mod_fdajax_parser.rl" #include #include #include #include "mod_fdajax_defs.h" #define INIT_EVENT(mask, index) req->ev.count++; req->ev.types |= mask; cur_ev_nr = index; req->ev.ids_len[index] = 0 #define CUR_ID_TAB_LEN req->ev.ids_len[cur_ev_nr] #line 155 "mod_fdajax_parser.rl" #line 16 "mod_fdajax_parser.c" static const int fdamod_parser_start = 1; static const int fdamod_parser_first_final = 399; static const int fdamod_parser_error = 0; static const int fdamod_parser_en_main = 1; #line 158 "mod_fdajax_parser.rl" int mod_fdajax_pinit(user_request_p req) { int cs = 0; #line 29 "mod_fdajax_parser.c" { cs = fdamod_parser_start; } #line 163 "mod_fdajax_parser.rl" req->cs = cs; req->cmd = 0; req->ev.types = 0; req->ev.count = 0; req->tv.tv_sec = 0; req->tv.tv_usec = 0; req->win_id = 0; req->win_st = 0; req->www_id = 0; req->alert_id = 0; req->amode = 0; req->force_old_close = 0; req->user_id = 0; req->peer_id = 0; req->ipaddr.s_addr = INADDR_NONE; req->mes = NULL; req->req_sess_id = NULL; req->sess_id_cookie[0] = 0; req->admin_passwd[0] = 0; return 1; } int mod_fdajax_pexec(user_request_p req, char *start, size_t len) { char *p, *pe, *mark = 0, *buf = 0; unsigned char phex = 0, hex = 0; unsigned int cur_int = 0; unsigned int ip_addr = 0; size_t j, *ppos = 0; int cur_ev_nr = 0; int cs = req->cs; assert(*(start + len) == 0); p = start; pe = start + len + 1; #line 70 "mod_fdajax_parser.c" { if ( p == pe ) goto _out; switch ( cs ) { tr31: #line 139 "mod_fdajax_parser.rl" { if (req->admin_passwd[0]) { goto _out1; } j = min(p - mark, PASSWORD_MAX - 1); strncpy(req->admin_passwd, mark, j); req->admin_passwd[j] = 0; } goto st1; tr42: #line 21 "mod_fdajax_parser.rl" { req->alert_id = cur_int; } goto st1; tr58: #line 22 "mod_fdajax_parser.rl" { req->amode = cur_int; } goto st1; tr88: #line 34 "mod_fdajax_parser.rl" { req->cmd = cmd_addchat; } goto st1; tr93: #line 27 "mod_fdajax_parser.rl" { req->cmd = cmd_alert; } goto st1; tr101: #line 29 "mod_fdajax_parser.rl" { req->cmd = cmd_cancel; } goto st1; tr110: #line 36 "mod_fdajax_parser.rl" { req->cmd = cmd_chatsig; } goto st1; tr114: #line 30 "mod_fdajax_parser.rl" { req->cmd = cmd_check_user; } goto st1; tr119: #line 33 "mod_fdajax_parser.rl" { req->cmd = cmd_info; } goto st1; tr126: #line 31 "mod_fdajax_parser.rl" { req->cmd = cmd_login; } goto st1; tr130: #line 32 "mod_fdajax_parser.rl" { req->cmd = cmd_logout; } goto st1; tr135: #line 26 "mod_fdajax_parser.rl" { req->cmd = cmd_push; } goto st1; tr143: #line 35 "mod_fdajax_parser.rl" { req->cmd = cmd_rmchat; } goto st1; tr150: #line 28 "mod_fdajax_parser.rl" { req->cmd = cmd_stream; } goto st1; tr155: #line 25 "mod_fdajax_parser.rl" { req->cmd = cmd_wait; } goto st1; tr163: #line 23 "mod_fdajax_parser.rl" { req->force_old_close = cur_int; } goto st1; tr191: #line 88 "mod_fdajax_parser.rl" { if (0xff < cur_int) goto _out1; ip_addr = ip_addr | (cur_int << 0); req->ipaddr.s_addr = ip_addr; ip_addr = 0; } goto st1; tr234: #line 115 "mod_fdajax_parser.rl" { buf[(*ppos)++] = 0; } goto st1; tr245: #line 105 "mod_fdajax_parser.rl" { hex = hex | phex; buf[(*ppos)++] = hex; } #line 115 "mod_fdajax_parser.rl" { buf[(*ppos)++] = 0; } goto st1; tr256: #line 16 "mod_fdajax_parser.rl" { req->peer_id = cur_int; } goto st1; tr272: #line 19 "mod_fdajax_parser.rl" { req->tv.tv_sec = cur_int; } goto st1; tr289: #line 130 "mod_fdajax_parser.rl" { if (req->req_sess_id) { goto _out1; } req->req_sess_id = buffer_init(); buffer_copy_string_len(req->req_sess_id, mark, p - mark); } goto st1; tr315: #line 67 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ANSW, FDA_GRP_ANSW_INDEX); } goto st1; tr323: #line 58 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } goto st1; tr331: #line 38 "mod_fdajax_parser.rl" { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } goto st1; tr347: #line 48 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } goto st1; tr356: #line 74 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FEED, FDA_GRP_FEED_INDEX); } goto st1; tr362: #line 78 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FRID, FDA_GRP_FRID_INDEX); } goto st1; tr371: #line 65 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_CHAT, FDA_GRP_CHAT_INDEX); } goto st1; tr378: #line 73 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_GEIC, FDA_GRP_GEIC_INDEX); } goto st1; tr382: #line 47 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } goto st1; tr391: #line 79 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_INFO, FDA_GRP_INFO_INDEX); } goto st1; tr396: #line 59 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } goto st1; tr403: #line 60 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } goto st1; tr412: #line 64 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MAIN, FDA_GRP_MAIN_INDEX); } goto st1; tr417: #line 56 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } goto st1; tr423: #line 75 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MESE, FDA_GRP_MESE_INDEX); } goto st1; tr430: #line 76 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_NETK, FDA_GRP_NETK_INDEX); } goto st1; tr439: #line 68 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OFRS, FDA_GRP_OFRS_INDEX); } goto st1; tr445: #line 70 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OPIN, FDA_GRP_OPIN_INDEX); } goto st1; tr450: #line 57 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } goto st1; tr456: #line 72 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ORDS, FDA_GRP_ORDS_INDEX); } goto st1; tr463: #line 69 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_PRIC, FDA_GRP_PRIC_INDEX); } goto st1; tr470: #line 66 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_QUES, FDA_GRP_QUES_INDEX); } goto st1; tr479: #line 55 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } goto st1; tr484: #line 53 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } goto st1; tr489: #line 54 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } goto st1; tr496: #line 51 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } goto st1; tr501: #line 52 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } goto st1; tr511: #line 77 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_TASK, FDA_GRP_TASK_INDEX); } goto st1; tr516: #line 49 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } goto st1; tr522: #line 50 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } goto st1; tr530: #line 46 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } goto st1; tr539: #line 71 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_USER, FDA_GRP_USER_INDEX); } goto st1; tr543: #line 61 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } goto st1; tr553: #line 20 "mod_fdajax_parser.rl" { req->tv.tv_usec = cur_int; } goto st1; tr569: #line 15 "mod_fdajax_parser.rl" { req->user_id = cur_int; } goto st1; tr588: #line 17 "mod_fdajax_parser.rl" { req->win_id = cur_int; } goto st1; tr602: #line 18 "mod_fdajax_parser.rl" { req->win_st = cur_int; } goto st1; st1: if ( ++p == pe ) goto _out1; case 1: #line 345 "mod_fdajax_parser.c" switch( (*p) ) { case 95: goto st2; case 97: goto st4; case 99: goto st51; case 102: goto st116; case 105: goto st132; case 109: goto st183; case 112: goto st191; case 115: goto st209; case 116: goto st230; case 117: goto st339; case 119: goto st369; } goto st0; st0: goto _out0; st2: if ( ++p == pe ) goto _out2; case 2: if ( (*p) == 61 ) goto st3; goto st0; st3: if ( ++p == pe ) goto _out3; case 3: switch( (*p) ) { case 0: goto st399; case 38: goto st1; } goto st0; tr30: #line 139 "mod_fdajax_parser.rl" { if (req->admin_passwd[0]) { goto _out399; } j = min(p - mark, PASSWORD_MAX - 1); strncpy(req->admin_passwd, mark, j); req->admin_passwd[j] = 0; } goto st399; tr41: #line 21 "mod_fdajax_parser.rl" { req->alert_id = cur_int; } goto st399; tr57: #line 22 "mod_fdajax_parser.rl" { req->amode = cur_int; } goto st399; tr87: #line 34 "mod_fdajax_parser.rl" { req->cmd = cmd_addchat; } goto st399; tr92: #line 27 "mod_fdajax_parser.rl" { req->cmd = cmd_alert; } goto st399; tr100: #line 29 "mod_fdajax_parser.rl" { req->cmd = cmd_cancel; } goto st399; tr109: #line 36 "mod_fdajax_parser.rl" { req->cmd = cmd_chatsig; } goto st399; tr113: #line 30 "mod_fdajax_parser.rl" { req->cmd = cmd_check_user; } goto st399; tr118: #line 33 "mod_fdajax_parser.rl" { req->cmd = cmd_info; } goto st399; tr125: #line 31 "mod_fdajax_parser.rl" { req->cmd = cmd_login; } goto st399; tr129: #line 32 "mod_fdajax_parser.rl" { req->cmd = cmd_logout; } goto st399; tr134: #line 26 "mod_fdajax_parser.rl" { req->cmd = cmd_push; } goto st399; tr142: #line 35 "mod_fdajax_parser.rl" { req->cmd = cmd_rmchat; } goto st399; tr149: #line 28 "mod_fdajax_parser.rl" { req->cmd = cmd_stream; } goto st399; tr154: #line 25 "mod_fdajax_parser.rl" { req->cmd = cmd_wait; } goto st399; tr162: #line 23 "mod_fdajax_parser.rl" { req->force_old_close = cur_int; } goto st399; tr190: #line 88 "mod_fdajax_parser.rl" { if (0xff < cur_int) goto _out399; ip_addr = ip_addr | (cur_int << 0); req->ipaddr.s_addr = ip_addr; ip_addr = 0; } goto st399; tr232: #line 115 "mod_fdajax_parser.rl" { buf[(*ppos)++] = 0; } goto st399; tr243: #line 105 "mod_fdajax_parser.rl" { hex = hex | phex; buf[(*ppos)++] = hex; } #line 115 "mod_fdajax_parser.rl" { buf[(*ppos)++] = 0; } goto st399; tr255: #line 16 "mod_fdajax_parser.rl" { req->peer_id = cur_int; } goto st399; tr271: #line 19 "mod_fdajax_parser.rl" { req->tv.tv_sec = cur_int; } goto st399; tr288: #line 130 "mod_fdajax_parser.rl" { if (req->req_sess_id) { goto _out399; } req->req_sess_id = buffer_init(); buffer_copy_string_len(req->req_sess_id, mark, p - mark); } goto st399; tr313: #line 67 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ANSW, FDA_GRP_ANSW_INDEX); } goto st399; tr321: #line 58 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } goto st399; tr329: #line 38 "mod_fdajax_parser.rl" { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } goto st399; tr345: #line 48 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } goto st399; tr354: #line 74 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FEED, FDA_GRP_FEED_INDEX); } goto st399; tr360: #line 78 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FRID, FDA_GRP_FRID_INDEX); } goto st399; tr369: #line 65 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_CHAT, FDA_GRP_CHAT_INDEX); } goto st399; tr376: #line 73 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_GEIC, FDA_GRP_GEIC_INDEX); } goto st399; tr380: #line 47 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } goto st399; tr389: #line 79 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_INFO, FDA_GRP_INFO_INDEX); } goto st399; tr394: #line 59 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } goto st399; tr401: #line 60 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } goto st399; tr410: #line 64 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MAIN, FDA_GRP_MAIN_INDEX); } goto st399; tr415: #line 56 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } goto st399; tr421: #line 75 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MESE, FDA_GRP_MESE_INDEX); } goto st399; tr428: #line 76 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_NETK, FDA_GRP_NETK_INDEX); } goto st399; tr437: #line 68 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OFRS, FDA_GRP_OFRS_INDEX); } goto st399; tr443: #line 70 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OPIN, FDA_GRP_OPIN_INDEX); } goto st399; tr448: #line 57 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } goto st399; tr454: #line 72 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ORDS, FDA_GRP_ORDS_INDEX); } goto st399; tr461: #line 69 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_PRIC, FDA_GRP_PRIC_INDEX); } goto st399; tr468: #line 66 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_QUES, FDA_GRP_QUES_INDEX); } goto st399; tr477: #line 55 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } goto st399; tr482: #line 53 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } goto st399; tr487: #line 54 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } goto st399; tr494: #line 51 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } goto st399; tr499: #line 52 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } goto st399; tr509: #line 77 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_TASK, FDA_GRP_TASK_INDEX); } goto st399; tr514: #line 49 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } goto st399; tr520: #line 50 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } goto st399; tr528: #line 46 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } goto st399; tr537: #line 71 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_USER, FDA_GRP_USER_INDEX); } goto st399; tr541: #line 61 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } goto st399; tr552: #line 20 "mod_fdajax_parser.rl" { req->tv.tv_usec = cur_int; } goto st399; tr568: #line 15 "mod_fdajax_parser.rl" { req->user_id = cur_int; } goto st399; tr587: #line 17 "mod_fdajax_parser.rl" { req->win_id = cur_int; } goto st399; tr601: #line 18 "mod_fdajax_parser.rl" { req->win_st = cur_int; } goto st399; st399: if ( ++p == pe ) goto _out399; case 399: #line 647 "mod_fdajax_parser.c" goto st0; st4: if ( ++p == pe ) goto _out4; case 4: switch( (*p) ) { case 100: goto st5; case 108: goto st18; case 109: goto st36; } goto st0; st5: if ( ++p == pe ) goto _out5; case 5: if ( (*p) == 109 ) goto st6; goto st0; st6: if ( ++p == pe ) goto _out6; case 6: if ( (*p) == 105 ) goto st7; goto st0; st7: if ( ++p == pe ) goto _out7; case 7: if ( (*p) == 110 ) goto st8; goto st0; st8: if ( ++p == pe ) goto _out8; case 8: if ( (*p) == 95 ) goto st9; goto st0; st9: if ( ++p == pe ) goto _out9; case 9: if ( (*p) == 112 ) goto st10; goto st0; st10: if ( ++p == pe ) goto _out10; case 10: if ( (*p) == 97 ) goto st11; goto st0; st11: if ( ++p == pe ) goto _out11; case 11: if ( (*p) == 115 ) goto st12; goto st0; st12: if ( ++p == pe ) goto _out12; case 12: if ( (*p) == 115 ) goto st13; goto st0; st13: if ( ++p == pe ) goto _out13; case 13: if ( (*p) == 119 ) goto st14; goto st0; st14: if ( ++p == pe ) goto _out14; case 14: if ( (*p) == 100 ) goto st15; goto st0; st15: if ( ++p == pe ) goto _out15; case 15: if ( (*p) == 61 ) goto st16; goto st0; st16: if ( ++p == pe ) goto _out16; case 16: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr29; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr29; } else goto tr29; goto st0; tr29: #line 127 "mod_fdajax_parser.rl" { mark = p; } goto st17; st17: if ( ++p == pe ) goto _out17; case 17: #line 759 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr30; case 38: goto tr31; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st17; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st17; } else goto st17; goto st0; st18: if ( ++p == pe ) goto _out18; case 18: if ( (*p) == 101 ) goto st19; goto st0; st19: if ( ++p == pe ) goto _out19; case 19: if ( (*p) == 114 ) goto st20; goto st0; st20: if ( ++p == pe ) goto _out20; case 20: if ( (*p) == 116 ) goto st21; goto st0; st21: if ( ++p == pe ) goto _out21; case 21: if ( (*p) == 95 ) goto st22; goto st0; st22: if ( ++p == pe ) goto _out22; case 22: if ( (*p) == 105 ) goto st23; goto st0; st23: if ( ++p == pe ) goto _out23; case 23: if ( (*p) == 100 ) goto st24; goto st0; st24: if ( ++p == pe ) goto _out24; case 24: if ( (*p) == 61 ) goto st25; goto st0; st25: if ( ++p == pe ) goto _out25; case 25: if ( 48 <= (*p) && (*p) <= 57 ) goto tr40; goto st0; tr40: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st26; st26: if ( ++p == pe ) goto _out26; case 26: #line 839 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr43; goto st0; tr43: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st27; st27: if ( ++p == pe ) goto _out27; case 27: #line 855 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr44; goto st0; tr44: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st28; st28: if ( ++p == pe ) goto _out28; case 28: #line 871 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr45; goto st0; tr45: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st29; st29: if ( ++p == pe ) goto _out29; case 29: #line 887 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr46; goto st0; tr46: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st30; st30: if ( ++p == pe ) goto _out30; case 30: #line 903 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr47; goto st0; tr47: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st31; st31: if ( ++p == pe ) goto _out31; case 31: #line 919 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr48; goto st0; tr48: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st32; st32: if ( ++p == pe ) goto _out32; case 32: #line 935 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr49; goto st0; tr49: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st33; st33: if ( ++p == pe ) goto _out33; case 33: #line 951 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr50; goto st0; tr50: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st34; st34: if ( ++p == pe ) goto _out34; case 34: #line 967 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr51; goto st0; tr51: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st35; st35: if ( ++p == pe ) goto _out35; case 35: #line 983 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr41; case 38: goto tr42; } goto st0; st36: if ( ++p == pe ) goto _out36; case 36: if ( (*p) == 111 ) goto st37; goto st0; st37: if ( ++p == pe ) goto _out37; case 37: if ( (*p) == 100 ) goto st38; goto st0; st38: if ( ++p == pe ) goto _out38; case 38: if ( (*p) == 101 ) goto st39; goto st0; st39: if ( ++p == pe ) goto _out39; case 39: if ( (*p) == 61 ) goto st40; goto st0; st40: if ( ++p == pe ) goto _out40; case 40: if ( 48 <= (*p) && (*p) <= 57 ) goto tr56; goto st0; tr56: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st41; st41: if ( ++p == pe ) goto _out41; case 41: #line 1034 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr59; goto st0; tr59: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st42; st42: if ( ++p == pe ) goto _out42; case 42: #line 1050 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr60; goto st0; tr60: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st43; st43: if ( ++p == pe ) goto _out43; case 43: #line 1066 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr61; goto st0; tr61: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st44; st44: if ( ++p == pe ) goto _out44; case 44: #line 1082 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr62; goto st0; tr62: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st45; st45: if ( ++p == pe ) goto _out45; case 45: #line 1098 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr63; goto st0; tr63: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st46; st46: if ( ++p == pe ) goto _out46; case 46: #line 1114 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr64; goto st0; tr64: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st47; st47: if ( ++p == pe ) goto _out47; case 47: #line 1130 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr65; goto st0; tr65: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st48; st48: if ( ++p == pe ) goto _out48; case 48: #line 1146 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr66; goto st0; tr66: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st49; st49: if ( ++p == pe ) goto _out49; case 49: #line 1162 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr67; goto st0; tr67: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st50; st50: if ( ++p == pe ) goto _out50; case 50: #line 1178 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr57; case 38: goto tr58; } goto st0; st51: if ( ++p == pe ) goto _out51; case 51: if ( (*p) == 109 ) goto st52; goto st0; st52: if ( ++p == pe ) goto _out52; case 52: if ( (*p) == 100 ) goto st53; goto st0; st53: if ( ++p == pe ) goto _out53; case 53: if ( (*p) == 61 ) goto st54; goto st0; st54: if ( ++p == pe ) goto _out54; case 54: switch( (*p) ) { case 97: goto st55; case 99: goto st67; case 105: goto st83; case 108: goto st87; case 112: goto st95; case 114: goto st99; case 115: goto st106; case 119: goto st112; } goto st0; st55: if ( ++p == pe ) goto _out55; case 55: switch( (*p) ) { case 100: goto st56; case 108: goto st63; } goto st0; st56: if ( ++p == pe ) goto _out56; case 56: if ( (*p) == 100 ) goto st57; goto st0; st57: if ( ++p == pe ) goto _out57; case 57: if ( (*p) == 95 ) goto st58; goto st0; st58: if ( ++p == pe ) goto _out58; case 58: if ( (*p) == 99 ) goto st59; goto st0; st59: if ( ++p == pe ) goto _out59; case 59: if ( (*p) == 104 ) goto st60; goto st0; st60: if ( ++p == pe ) goto _out60; case 60: if ( (*p) == 97 ) goto st61; goto st0; st61: if ( ++p == pe ) goto _out61; case 61: if ( (*p) == 116 ) goto st62; goto st0; st62: if ( ++p == pe ) goto _out62; case 62: switch( (*p) ) { case 0: goto tr87; case 38: goto tr88; } goto st0; st63: if ( ++p == pe ) goto _out63; case 63: if ( (*p) == 101 ) goto st64; goto st0; st64: if ( ++p == pe ) goto _out64; case 64: if ( (*p) == 114 ) goto st65; goto st0; st65: if ( ++p == pe ) goto _out65; case 65: if ( (*p) == 116 ) goto st66; goto st0; st66: if ( ++p == pe ) goto _out66; case 66: switch( (*p) ) { case 0: goto tr92; case 38: goto tr93; } goto st0; st67: if ( ++p == pe ) goto _out67; case 67: switch( (*p) ) { case 97: goto st68; case 104: goto st73; } goto st0; st68: if ( ++p == pe ) goto _out68; case 68: if ( (*p) == 110 ) goto st69; goto st0; st69: if ( ++p == pe ) goto _out69; case 69: if ( (*p) == 99 ) goto st70; goto st0; st70: if ( ++p == pe ) goto _out70; case 70: if ( (*p) == 101 ) goto st71; goto st0; st71: if ( ++p == pe ) goto _out71; case 71: if ( (*p) == 108 ) goto st72; goto st0; st72: if ( ++p == pe ) goto _out72; case 72: switch( (*p) ) { case 0: goto tr100; case 38: goto tr101; } goto st0; st73: if ( ++p == pe ) goto _out73; case 73: switch( (*p) ) { case 97: goto st74; case 101: goto st80; } goto st0; st74: if ( ++p == pe ) goto _out74; case 74: if ( (*p) == 116 ) goto st75; goto st0; st75: if ( ++p == pe ) goto _out75; case 75: if ( (*p) == 95 ) goto st76; goto st0; st76: if ( ++p == pe ) goto _out76; case 76: if ( (*p) == 115 ) goto st77; goto st0; st77: if ( ++p == pe ) goto _out77; case 77: if ( (*p) == 105 ) goto st78; goto st0; st78: if ( ++p == pe ) goto _out78; case 78: if ( (*p) == 103 ) goto st79; goto st0; st79: if ( ++p == pe ) goto _out79; case 79: switch( (*p) ) { case 0: goto tr109; case 38: goto tr110; } goto st0; st80: if ( ++p == pe ) goto _out80; case 80: if ( (*p) == 99 ) goto st81; goto st0; st81: if ( ++p == pe ) goto _out81; case 81: if ( (*p) == 107 ) goto st82; goto st0; st82: if ( ++p == pe ) goto _out82; case 82: switch( (*p) ) { case 0: goto tr113; case 38: goto tr114; } goto st0; st83: if ( ++p == pe ) goto _out83; case 83: if ( (*p) == 110 ) goto st84; goto st0; st84: if ( ++p == pe ) goto _out84; case 84: if ( (*p) == 102 ) goto st85; goto st0; st85: if ( ++p == pe ) goto _out85; case 85: if ( (*p) == 111 ) goto st86; goto st0; st86: if ( ++p == pe ) goto _out86; case 86: switch( (*p) ) { case 0: goto tr118; case 38: goto tr119; } goto st0; st87: if ( ++p == pe ) goto _out87; case 87: if ( (*p) == 111 ) goto st88; goto st0; st88: if ( ++p == pe ) goto _out88; case 88: if ( (*p) == 103 ) goto st89; goto st0; st89: if ( ++p == pe ) goto _out89; case 89: switch( (*p) ) { case 105: goto st90; case 111: goto st92; } goto st0; st90: if ( ++p == pe ) goto _out90; case 90: if ( (*p) == 110 ) goto st91; goto st0; st91: if ( ++p == pe ) goto _out91; case 91: switch( (*p) ) { case 0: goto tr125; case 38: goto tr126; } goto st0; st92: if ( ++p == pe ) goto _out92; case 92: if ( (*p) == 117 ) goto st93; goto st0; st93: if ( ++p == pe ) goto _out93; case 93: if ( (*p) == 116 ) goto st94; goto st0; st94: if ( ++p == pe ) goto _out94; case 94: switch( (*p) ) { case 0: goto tr129; case 38: goto tr130; } goto st0; st95: if ( ++p == pe ) goto _out95; case 95: if ( (*p) == 117 ) goto st96; goto st0; st96: if ( ++p == pe ) goto _out96; case 96: if ( (*p) == 115 ) goto st97; goto st0; st97: if ( ++p == pe ) goto _out97; case 97: if ( (*p) == 104 ) goto st98; goto st0; st98: if ( ++p == pe ) goto _out98; case 98: switch( (*p) ) { case 0: goto tr134; case 38: goto tr135; } goto st0; st99: if ( ++p == pe ) goto _out99; case 99: if ( (*p) == 109 ) goto st100; goto st0; st100: if ( ++p == pe ) goto _out100; case 100: if ( (*p) == 95 ) goto st101; goto st0; st101: if ( ++p == pe ) goto _out101; case 101: if ( (*p) == 99 ) goto st102; goto st0; st102: if ( ++p == pe ) goto _out102; case 102: if ( (*p) == 104 ) goto st103; goto st0; st103: if ( ++p == pe ) goto _out103; case 103: if ( (*p) == 97 ) goto st104; goto st0; st104: if ( ++p == pe ) goto _out104; case 104: if ( (*p) == 116 ) goto st105; goto st0; st105: if ( ++p == pe ) goto _out105; case 105: switch( (*p) ) { case 0: goto tr142; case 38: goto tr143; } goto st0; st106: if ( ++p == pe ) goto _out106; case 106: if ( (*p) == 116 ) goto st107; goto st0; st107: if ( ++p == pe ) goto _out107; case 107: if ( (*p) == 114 ) goto st108; goto st0; st108: if ( ++p == pe ) goto _out108; case 108: if ( (*p) == 101 ) goto st109; goto st0; st109: if ( ++p == pe ) goto _out109; case 109: if ( (*p) == 97 ) goto st110; goto st0; st110: if ( ++p == pe ) goto _out110; case 110: if ( (*p) == 109 ) goto st111; goto st0; st111: if ( ++p == pe ) goto _out111; case 111: switch( (*p) ) { case 0: goto tr149; case 38: goto tr150; } goto st0; st112: if ( ++p == pe ) goto _out112; case 112: if ( (*p) == 97 ) goto st113; goto st0; st113: if ( ++p == pe ) goto _out113; case 113: if ( (*p) == 105 ) goto st114; goto st0; st114: if ( ++p == pe ) goto _out114; case 114: if ( (*p) == 116 ) goto st115; goto st0; st115: if ( ++p == pe ) goto _out115; case 115: switch( (*p) ) { case 0: goto tr154; case 38: goto tr155; } goto st0; st116: if ( ++p == pe ) goto _out116; case 116: if ( (*p) == 111 ) goto st117; goto st0; st117: if ( ++p == pe ) goto _out117; case 117: if ( (*p) == 114 ) goto st118; goto st0; st118: if ( ++p == pe ) goto _out118; case 118: if ( (*p) == 99 ) goto st119; goto st0; st119: if ( ++p == pe ) goto _out119; case 119: if ( (*p) == 101 ) goto st120; goto st0; st120: if ( ++p == pe ) goto _out120; case 120: if ( (*p) == 61 ) goto st121; goto st0; st121: if ( ++p == pe ) goto _out121; case 121: if ( 48 <= (*p) && (*p) <= 57 ) goto tr161; goto st0; tr161: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st122; st122: if ( ++p == pe ) goto _out122; case 122: #line 1731 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr164; goto st0; tr164: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st123; st123: if ( ++p == pe ) goto _out123; case 123: #line 1747 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr165; goto st0; tr165: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st124; st124: if ( ++p == pe ) goto _out124; case 124: #line 1763 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr166; goto st0; tr166: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st125; st125: if ( ++p == pe ) goto _out125; case 125: #line 1779 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr167; goto st0; tr167: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st126; st126: if ( ++p == pe ) goto _out126; case 126: #line 1795 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr168; goto st0; tr168: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st127; st127: if ( ++p == pe ) goto _out127; case 127: #line 1811 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr169; goto st0; tr169: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st128; st128: if ( ++p == pe ) goto _out128; case 128: #line 1827 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr170; goto st0; tr170: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st129; st129: if ( ++p == pe ) goto _out129; case 129: #line 1843 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr171; goto st0; tr171: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st130; st130: if ( ++p == pe ) goto _out130; case 130: #line 1859 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr172; goto st0; tr172: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st131; st131: if ( ++p == pe ) goto _out131; case 131: #line 1875 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr162; case 38: goto tr163; } goto st0; st132: if ( ++p == pe ) goto _out132; case 132: if ( (*p) == 112 ) goto st133; goto st0; st133: if ( ++p == pe ) goto _out133; case 133: if ( (*p) == 95 ) goto st134; goto st0; st134: if ( ++p == pe ) goto _out134; case 134: if ( (*p) == 97 ) goto st135; goto st0; st135: if ( ++p == pe ) goto _out135; case 135: if ( (*p) == 100 ) goto st136; goto st0; st136: if ( ++p == pe ) goto _out136; case 136: if ( (*p) == 100 ) goto st137; goto st0; st137: if ( ++p == pe ) goto _out137; case 137: if ( (*p) == 114 ) goto st138; goto st0; st138: if ( ++p == pe ) goto _out138; case 138: if ( (*p) == 61 ) goto st139; goto st0; st139: if ( ++p == pe ) goto _out139; case 139: if ( 48 <= (*p) && (*p) <= 57 ) goto tr180; goto st0; tr180: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st140; st140: if ( ++p == pe ) goto _out140; case 140: #line 1947 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr182; goto st0; tr181: #line 85 "mod_fdajax_parser.rl" { if (0xff < cur_int) goto _out141; ip_addr = ip_addr | (cur_int << 24); } goto st141; st141: if ( ++p == pe ) goto _out141; case 141: #line 1961 "mod_fdajax_parser.c" if ( 48 <= (*p) && (*p) <= 57 ) goto tr183; goto st0; tr183: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st142; st142: if ( ++p == pe ) goto _out142; case 142: #line 1975 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr185; goto st0; tr184: #line 86 "mod_fdajax_parser.rl" { if (0xff < cur_int) goto _out143; ip_addr = ip_addr | (cur_int << 16); } goto st143; st143: if ( ++p == pe ) goto _out143; case 143: #line 1989 "mod_fdajax_parser.c" if ( 48 <= (*p) && (*p) <= 57 ) goto tr186; goto st0; tr186: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st144; st144: if ( ++p == pe ) goto _out144; case 144: #line 2003 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr188; goto st0; tr187: #line 87 "mod_fdajax_parser.rl" { if (0xff < cur_int) goto _out145; ip_addr = ip_addr | (cur_int << 8); } goto st145; st145: if ( ++p == pe ) goto _out145; case 145: #line 2017 "mod_fdajax_parser.c" if ( 48 <= (*p) && (*p) <= 57 ) goto tr189; goto st0; tr189: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st146; st146: if ( ++p == pe ) goto _out146; case 146: #line 2031 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr192; goto st0; tr192: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st147; st147: if ( ++p == pe ) goto _out147; case 147: #line 2047 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr193; goto st0; tr193: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st148; st148: if ( ++p == pe ) goto _out148; case 148: #line 2063 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr194; goto st0; tr194: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st149; st149: if ( ++p == pe ) goto _out149; case 149: #line 2079 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr195; goto st0; tr195: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st150; st150: if ( ++p == pe ) goto _out150; case 150: #line 2095 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr196; goto st0; tr196: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st151; st151: if ( ++p == pe ) goto _out151; case 151: #line 2111 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr197; goto st0; tr197: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st152; st152: if ( ++p == pe ) goto _out152; case 152: #line 2127 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr198; goto st0; tr198: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st153; st153: if ( ++p == pe ) goto _out153; case 153: #line 2143 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr199; goto st0; tr199: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st154; st154: if ( ++p == pe ) goto _out154; case 154: #line 2159 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr200; goto st0; tr200: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st155; st155: if ( ++p == pe ) goto _out155; case 155: #line 2175 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr190; case 38: goto tr191; } goto st0; tr188: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st156; st156: if ( ++p == pe ) goto _out156; case 156: #line 2189 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr201; goto st0; tr201: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st157; st157: if ( ++p == pe ) goto _out157; case 157: #line 2203 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr202; goto st0; tr202: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st158; st158: if ( ++p == pe ) goto _out158; case 158: #line 2217 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr203; goto st0; tr203: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st159; st159: if ( ++p == pe ) goto _out159; case 159: #line 2231 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr204; goto st0; tr204: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st160; st160: if ( ++p == pe ) goto _out160; case 160: #line 2245 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr205; goto st0; tr205: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st161; st161: if ( ++p == pe ) goto _out161; case 161: #line 2259 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr206; goto st0; tr206: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st162; st162: if ( ++p == pe ) goto _out162; case 162: #line 2273 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr207; goto st0; tr207: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st163; st163: if ( ++p == pe ) goto _out163; case 163: #line 2287 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; if ( 48 <= (*p) && (*p) <= 57 ) goto tr208; goto st0; tr208: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st164; st164: if ( ++p == pe ) goto _out164; case 164: #line 2301 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr187; goto st0; tr185: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st165; st165: if ( ++p == pe ) goto _out165; case 165: #line 2313 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr209; goto st0; tr209: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st166; st166: if ( ++p == pe ) goto _out166; case 166: #line 2327 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr210; goto st0; tr210: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st167; st167: if ( ++p == pe ) goto _out167; case 167: #line 2341 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr211; goto st0; tr211: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st168; st168: if ( ++p == pe ) goto _out168; case 168: #line 2355 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr212; goto st0; tr212: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st169; st169: if ( ++p == pe ) goto _out169; case 169: #line 2369 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr213; goto st0; tr213: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st170; st170: if ( ++p == pe ) goto _out170; case 170: #line 2383 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr214; goto st0; tr214: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st171; st171: if ( ++p == pe ) goto _out171; case 171: #line 2397 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr215; goto st0; tr215: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st172; st172: if ( ++p == pe ) goto _out172; case 172: #line 2411 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; if ( 48 <= (*p) && (*p) <= 57 ) goto tr216; goto st0; tr216: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st173; st173: if ( ++p == pe ) goto _out173; case 173: #line 2425 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr184; goto st0; tr182: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st174; st174: if ( ++p == pe ) goto _out174; case 174: #line 2437 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr217; goto st0; tr217: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st175; st175: if ( ++p == pe ) goto _out175; case 175: #line 2451 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr218; goto st0; tr218: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st176; st176: if ( ++p == pe ) goto _out176; case 176: #line 2465 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr219; goto st0; tr219: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st177; st177: if ( ++p == pe ) goto _out177; case 177: #line 2479 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr220; goto st0; tr220: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st178; st178: if ( ++p == pe ) goto _out178; case 178: #line 2493 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr221; goto st0; tr221: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st179; st179: if ( ++p == pe ) goto _out179; case 179: #line 2507 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr222; goto st0; tr222: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st180; st180: if ( ++p == pe ) goto _out180; case 180: #line 2521 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr223; goto st0; tr223: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st181; st181: if ( ++p == pe ) goto _out181; case 181: #line 2535 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; if ( 48 <= (*p) && (*p) <= 57 ) goto tr224; goto st0; tr224: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st182; st182: if ( ++p == pe ) goto _out182; case 182: #line 2549 "mod_fdajax_parser.c" if ( (*p) == 46 ) goto tr181; goto st0; st183: if ( ++p == pe ) goto _out183; case 183: if ( (*p) == 101 ) goto st184; goto st0; st184: if ( ++p == pe ) goto _out184; case 184: if ( (*p) == 115 ) goto st185; goto st0; st185: if ( ++p == pe ) goto _out185; case 185: if ( (*p) == 61 ) goto st186; goto st0; st186: if ( ++p == pe ) goto _out186; case 186: switch( (*p) ) { case 0: goto st0; case 37: goto tr229; case 38: goto st0; case 43: goto tr230; } goto tr228; tr228: #line 92 "mod_fdajax_parser.rl" { if (req->mes) { goto _out187; } req->mes = buffer_init(); /* TODO is mem allocated ? */ buffer_prepare_append(req->mes, len); buf = req->mes->ptr; ppos = &(req->mes->used); } #line 109 "mod_fdajax_parser.rl" { buf[(*ppos)++] = (*p); } goto st187; tr230: #line 92 "mod_fdajax_parser.rl" { if (req->mes) { goto _out187; } req->mes = buffer_init(); /* TODO is mem allocated ? */ buffer_prepare_append(req->mes, len); buf = req->mes->ptr; ppos = &(req->mes->used); } #line 112 "mod_fdajax_parser.rl" { buf[(*ppos)++] = ' '; } goto st187; tr231: #line 109 "mod_fdajax_parser.rl" { buf[(*ppos)++] = (*p); } goto st187; tr235: #line 112 "mod_fdajax_parser.rl" { buf[(*ppos)++] = ' '; } goto st187; tr242: #line 105 "mod_fdajax_parser.rl" { hex = hex | phex; buf[(*ppos)++] = hex; } #line 109 "mod_fdajax_parser.rl" { buf[(*ppos)++] = (*p); } goto st187; tr246: #line 105 "mod_fdajax_parser.rl" { hex = hex | phex; buf[(*ppos)++] = hex; } #line 112 "mod_fdajax_parser.rl" { buf[(*ppos)++] = ' '; } goto st187; st187: if ( ++p == pe ) goto _out187; case 187: #line 2657 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr232; case 37: goto st188; case 38: goto tr234; case 43: goto tr235; } goto tr231; tr229: #line 92 "mod_fdajax_parser.rl" { if (req->mes) { goto _out188; } req->mes = buffer_init(); /* TODO is mem allocated ? */ buffer_prepare_append(req->mes, len); buf = req->mes->ptr; ppos = &(req->mes->used); } goto st188; tr244: #line 105 "mod_fdajax_parser.rl" { hex = hex | phex; buf[(*ppos)++] = hex; } goto st188; st188: if ( ++p == pe ) goto _out188; case 188: #line 2689 "mod_fdajax_parser.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr236; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto tr238; } else goto tr237; goto st0; tr236: #line 121 "mod_fdajax_parser.rl" { phex = (*p) - '0'; } goto st189; tr237: #line 120 "mod_fdajax_parser.rl" { phex = (*p) - 'A' + 10; } goto st189; tr238: #line 119 "mod_fdajax_parser.rl" { phex = (*p) - 'a' + 10; } goto st189; st189: if ( ++p == pe ) goto _out189; case 189: #line 2715 "mod_fdajax_parser.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr239; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto tr241; } else goto tr240; goto st0; tr239: #line 102 "mod_fdajax_parser.rl" { hex = phex << 4; } #line 121 "mod_fdajax_parser.rl" { phex = (*p) - '0'; } goto st190; tr240: #line 102 "mod_fdajax_parser.rl" { hex = phex << 4; } #line 120 "mod_fdajax_parser.rl" { phex = (*p) - 'A' + 10; } goto st190; tr241: #line 102 "mod_fdajax_parser.rl" { hex = phex << 4; } #line 119 "mod_fdajax_parser.rl" { phex = (*p) - 'a' + 10; } goto st190; st190: if ( ++p == pe ) goto _out190; case 190: #line 2753 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr243; case 37: goto tr244; case 38: goto tr245; case 43: goto tr246; } goto tr242; st191: if ( ++p == pe ) goto _out191; case 191: if ( (*p) == 101 ) goto st192; goto st0; st192: if ( ++p == pe ) goto _out192; case 192: if ( (*p) == 101 ) goto st193; goto st0; st193: if ( ++p == pe ) goto _out193; case 193: if ( (*p) == 114 ) goto st194; goto st0; st194: if ( ++p == pe ) goto _out194; case 194: if ( (*p) == 95 ) goto st195; goto st0; st195: if ( ++p == pe ) goto _out195; case 195: if ( (*p) == 105 ) goto st196; goto st0; st196: if ( ++p == pe ) goto _out196; case 196: if ( (*p) == 100 ) goto st197; goto st0; st197: if ( ++p == pe ) goto _out197; case 197: if ( (*p) == 61 ) goto st198; goto st0; st198: if ( ++p == pe ) goto _out198; case 198: if ( 48 <= (*p) && (*p) <= 57 ) goto tr254; goto st0; tr254: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st199; st199: if ( ++p == pe ) goto _out199; case 199: #line 2827 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr257; goto st0; tr257: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st200; st200: if ( ++p == pe ) goto _out200; case 200: #line 2843 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr258; goto st0; tr258: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st201; st201: if ( ++p == pe ) goto _out201; case 201: #line 2859 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr259; goto st0; tr259: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st202; st202: if ( ++p == pe ) goto _out202; case 202: #line 2875 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr260; goto st0; tr260: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st203; st203: if ( ++p == pe ) goto _out203; case 203: #line 2891 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr261; goto st0; tr261: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st204; st204: if ( ++p == pe ) goto _out204; case 204: #line 2907 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr262; goto st0; tr262: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st205; st205: if ( ++p == pe ) goto _out205; case 205: #line 2923 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr263; goto st0; tr263: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st206; st206: if ( ++p == pe ) goto _out206; case 206: #line 2939 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr264; goto st0; tr264: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st207; st207: if ( ++p == pe ) goto _out207; case 207: #line 2955 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr265; goto st0; tr265: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st208; st208: if ( ++p == pe ) goto _out208; case 208: #line 2971 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr255; case 38: goto tr256; } goto st0; st209: if ( ++p == pe ) goto _out209; case 209: if ( (*p) == 101 ) goto st210; goto st0; st210: if ( ++p == pe ) goto _out210; case 210: switch( (*p) ) { case 99: goto st211; case 115: goto st223; } goto st0; st211: if ( ++p == pe ) goto _out211; case 211: if ( (*p) == 61 ) goto st212; goto st0; st212: if ( ++p == pe ) goto _out212; case 212: if ( 48 <= (*p) && (*p) <= 57 ) goto tr270; goto st0; tr270: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st213; st213: if ( ++p == pe ) goto _out213; case 213: #line 3017 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr273; goto st0; tr273: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st214; st214: if ( ++p == pe ) goto _out214; case 214: #line 3033 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr274; goto st0; tr274: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st215; st215: if ( ++p == pe ) goto _out215; case 215: #line 3049 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr275; goto st0; tr275: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st216; st216: if ( ++p == pe ) goto _out216; case 216: #line 3065 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr276; goto st0; tr276: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st217; st217: if ( ++p == pe ) goto _out217; case 217: #line 3081 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr277; goto st0; tr277: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st218; st218: if ( ++p == pe ) goto _out218; case 218: #line 3097 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr278; goto st0; tr278: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st219; st219: if ( ++p == pe ) goto _out219; case 219: #line 3113 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr279; goto st0; tr279: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st220; st220: if ( ++p == pe ) goto _out220; case 220: #line 3129 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr280; goto st0; tr280: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st221; st221: if ( ++p == pe ) goto _out221; case 221: #line 3145 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr281; goto st0; tr281: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st222; st222: if ( ++p == pe ) goto _out222; case 222: #line 3161 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr271; case 38: goto tr272; } goto st0; st223: if ( ++p == pe ) goto _out223; case 223: if ( (*p) == 115 ) goto st224; goto st0; st224: if ( ++p == pe ) goto _out224; case 224: if ( (*p) == 95 ) goto st225; goto st0; st225: if ( ++p == pe ) goto _out225; case 225: if ( (*p) == 105 ) goto st226; goto st0; st226: if ( ++p == pe ) goto _out226; case 226: if ( (*p) == 100 ) goto st227; goto st0; st227: if ( ++p == pe ) goto _out227; case 227: if ( (*p) == 61 ) goto st228; goto st0; st228: if ( ++p == pe ) goto _out228; case 228: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr287; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr287; } else goto tr287; goto st0; tr287: #line 127 "mod_fdajax_parser.rl" { mark = p; } goto st229; st229: if ( ++p == pe ) goto _out229; case 229: #line 3225 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr288; case 38: goto tr289; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st229; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st229; } else goto st229; goto st0; st230: if ( ++p == pe ) goto _out230; case 230: if ( (*p) == 121 ) goto st231; goto st0; st231: if ( ++p == pe ) goto _out231; case 231: if ( (*p) == 112 ) goto st232; goto st0; st232: if ( ++p == pe ) goto _out232; case 232: if ( (*p) == 101 ) goto st233; goto st0; st233: if ( ++p == pe ) goto _out233; case 233: if ( (*p) == 115 ) goto st234; goto st0; st234: if ( ++p == pe ) goto _out234; case 234: if ( (*p) == 61 ) goto st235; goto st0; tr316: #line 67 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ANSW, FDA_GRP_ANSW_INDEX); } goto st235; tr325: #line 58 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } goto st235; tr334: #line 38 "mod_fdajax_parser.rl" { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } goto st235; tr349: #line 48 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } goto st235; tr357: #line 74 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FEED, FDA_GRP_FEED_INDEX); } goto st235; tr363: #line 78 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FRID, FDA_GRP_FRID_INDEX); } goto st235; tr372: #line 65 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_CHAT, FDA_GRP_CHAT_INDEX); } goto st235; tr379: #line 73 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_GEIC, FDA_GRP_GEIC_INDEX); } goto st235; tr384: #line 47 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } goto st235; tr392: #line 79 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_INFO, FDA_GRP_INFO_INDEX); } goto st235; tr398: #line 59 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } goto st235; tr405: #line 60 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } goto st235; tr413: #line 64 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MAIN, FDA_GRP_MAIN_INDEX); } goto st235; tr420: #line 56 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } goto st235; tr424: #line 75 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MESE, FDA_GRP_MESE_INDEX); } goto st235; tr431: #line 76 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_NETK, FDA_GRP_NETK_INDEX); } goto st235; tr440: #line 68 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OFRS, FDA_GRP_OFRS_INDEX); } goto st235; tr446: #line 70 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OPIN, FDA_GRP_OPIN_INDEX); } goto st235; tr453: #line 57 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } goto st235; tr457: #line 72 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ORDS, FDA_GRP_ORDS_INDEX); } goto st235; tr464: #line 69 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_PRIC, FDA_GRP_PRIC_INDEX); } goto st235; tr471: #line 66 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_QUES, FDA_GRP_QUES_INDEX); } goto st235; tr481: #line 55 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } goto st235; tr486: #line 53 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } goto st235; tr491: #line 54 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } goto st235; tr498: #line 51 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } goto st235; tr503: #line 52 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } goto st235; tr512: #line 77 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_TASK, FDA_GRP_TASK_INDEX); } goto st235; tr518: #line 49 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } goto st235; tr524: #line 50 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } goto st235; tr532: #line 46 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } goto st235; tr540: #line 71 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_USER, FDA_GRP_USER_INDEX); } goto st235; tr545: #line 61 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } goto st235; st235: if ( ++p == pe ) goto _out235; case 235: #line 3416 "mod_fdajax_parser.c" switch( (*p) ) { case 97: goto st236; case 99: goto st242; case 102: goto st261; case 103: goto st268; case 105: goto st277; case 108: goto st283; case 109: goto st286; case 110: goto st293; case 111: goto st297; case 112: goto st307; case 113: goto st311; case 115: goto st315; case 116: goto st323; case 117: goto st331; } goto st0; st236: if ( ++p == pe ) goto _out236; case 236: if ( (*p) == 110 ) goto st237; goto st0; st237: if ( ++p == pe ) goto _out237; case 237: if ( (*p) == 115 ) goto st238; goto st0; st238: if ( ++p == pe ) goto _out238; case 238: if ( (*p) == 119 ) goto st239; goto st0; st239: if ( ++p == pe ) goto _out239; case 239: switch( (*p) ) { case 0: goto tr313; case 37: goto tr314; case 38: goto tr315; case 124: goto tr316; } goto st0; tr314: #line 67 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ANSW, FDA_GRP_ANSW_INDEX); } goto st240; tr355: #line 74 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FEED, FDA_GRP_FEED_INDEX); } goto st240; tr361: #line 78 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_FRID, FDA_GRP_FRID_INDEX); } goto st240; tr370: #line 65 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_CHAT, FDA_GRP_CHAT_INDEX); } goto st240; tr377: #line 73 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_GEIC, FDA_GRP_GEIC_INDEX); } goto st240; tr390: #line 79 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_INFO, FDA_GRP_INFO_INDEX); } goto st240; tr411: #line 64 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MAIN, FDA_GRP_MAIN_INDEX); } goto st240; tr422: #line 75 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_MESE, FDA_GRP_MESE_INDEX); } goto st240; tr429: #line 76 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_NETK, FDA_GRP_NETK_INDEX); } goto st240; tr438: #line 68 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OFRS, FDA_GRP_OFRS_INDEX); } goto st240; tr444: #line 70 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_OPIN, FDA_GRP_OPIN_INDEX); } goto st240; tr455: #line 72 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_ORDS, FDA_GRP_ORDS_INDEX); } goto st240; tr462: #line 69 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_PRIC, FDA_GRP_PRIC_INDEX); } goto st240; tr469: #line 66 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_QUES, FDA_GRP_QUES_INDEX); } goto st240; tr510: #line 77 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_TASK, FDA_GRP_TASK_INDEX); } goto st240; tr538: #line 71 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_GRP_USER, FDA_GRP_USER_INDEX); } goto st240; st240: if ( ++p == pe ) goto _out240; case 240: #line 3534 "mod_fdajax_parser.c" if ( (*p) == 55 ) goto st241; goto st0; st241: if ( ++p == pe ) goto _out241; case 241: switch( (*p) ) { case 67: goto st235; case 99: goto st235; } goto st0; st242: if ( ++p == pe ) goto _out242; case 242: switch( (*p) ) { case 99: goto st243; case 104: goto st258; } goto st0; st243: if ( ++p == pe ) goto _out243; case 243: if ( (*p) == 100 ) goto st244; goto st0; st244: if ( ++p == pe ) goto _out244; case 244: switch( (*p) ) { case 0: goto tr321; case 37: goto tr322; case 38: goto tr323; case 44: goto tr324; case 124: goto tr325; } goto st0; tr322: #line 58 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } goto st245; tr330: #line 38 "mod_fdajax_parser.rl" { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } goto st245; tr346: #line 48 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } goto st245; tr381: #line 47 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } goto st245; tr395: #line 59 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } goto st245; tr402: #line 60 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } goto st245; tr416: #line 56 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } goto st245; tr449: #line 57 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } goto st245; tr478: #line 55 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } goto st245; tr483: #line 53 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } goto st245; tr488: #line 54 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } goto st245; tr495: #line 51 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } goto st245; tr500: #line 52 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } goto st245; tr515: #line 49 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } goto st245; tr521: #line 50 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } goto st245; tr529: #line 46 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } goto st245; tr542: #line 61 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } goto st245; st245: if ( ++p == pe ) goto _out245; case 245: #line 3653 "mod_fdajax_parser.c" switch( (*p) ) { case 50: goto st246; case 55: goto st241; } goto st0; st246: if ( ++p == pe ) goto _out246; case 246: switch( (*p) ) { case 67: goto st247; case 99: goto st247; } goto st0; tr324: #line 58 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } goto st247; tr332: #line 38 "mod_fdajax_parser.rl" { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } goto st247; tr348: #line 48 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } goto st247; tr383: #line 47 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } goto st247; tr397: #line 59 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } goto st247; tr404: #line 60 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } goto st247; tr418: #line 56 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } goto st247; tr451: #line 57 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } goto st247; tr480: #line 55 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } goto st247; tr485: #line 53 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } goto st247; tr490: #line 54 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } goto st247; tr497: #line 51 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } goto st247; tr502: #line 52 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } goto st247; tr517: #line 49 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } goto st247; tr523: #line 50 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } goto st247; tr531: #line 46 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } goto st247; tr544: #line 61 "mod_fdajax_parser.rl" { INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } goto st247; st247: if ( ++p == pe ) goto _out247; case 247: #line 3746 "mod_fdajax_parser.c" if ( 48 <= (*p) && (*p) <= 57 ) goto tr328; goto st0; tr328: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st248; st248: if ( ++p == pe ) goto _out248; case 248: #line 3760 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr333; goto st0; tr333: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st249; st249: if ( ++p == pe ) goto _out249; case 249: #line 3779 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr335; goto st0; tr335: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st250; st250: if ( ++p == pe ) goto _out250; case 250: #line 3798 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr336; goto st0; tr336: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st251; st251: if ( ++p == pe ) goto _out251; case 251: #line 3817 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr337; goto st0; tr337: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st252; st252: if ( ++p == pe ) goto _out252; case 252: #line 3836 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr338; goto st0; tr338: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st253; st253: if ( ++p == pe ) goto _out253; case 253: #line 3855 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr339; goto st0; tr339: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st254; st254: if ( ++p == pe ) goto _out254; case 254: #line 3874 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr340; goto st0; tr340: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st255; st255: if ( ++p == pe ) goto _out255; case 255: #line 3893 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr341; goto st0; tr341: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st256; st256: if ( ++p == pe ) goto _out256; case 256: #line 3912 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr342; goto st0; tr342: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st257; st257: if ( ++p == pe ) goto _out257; case 257: #line 3931 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr329; case 37: goto tr330; case 38: goto tr331; case 44: goto tr332; case 124: goto tr334; } goto st0; st258: if ( ++p == pe ) goto _out258; case 258: if ( (*p) == 97 ) goto st259; goto st0; st259: if ( ++p == pe ) goto _out259; case 259: if ( (*p) == 116 ) goto st260; goto st0; st260: if ( ++p == pe ) goto _out260; case 260: switch( (*p) ) { case 0: goto tr345; case 37: goto tr346; case 38: goto tr347; case 44: goto tr348; case 124: goto tr349; } goto st0; st261: if ( ++p == pe ) goto _out261; case 261: switch( (*p) ) { case 101: goto st262; case 114: goto st265; } goto st0; st262: if ( ++p == pe ) goto _out262; case 262: if ( (*p) == 101 ) goto st263; goto st0; st263: if ( ++p == pe ) goto _out263; case 263: if ( (*p) == 100 ) goto st264; goto st0; st264: if ( ++p == pe ) goto _out264; case 264: switch( (*p) ) { case 0: goto tr354; case 37: goto tr355; case 38: goto tr356; case 124: goto tr357; } goto st0; st265: if ( ++p == pe ) goto _out265; case 265: if ( (*p) == 105 ) goto st266; goto st0; st266: if ( ++p == pe ) goto _out266; case 266: if ( (*p) == 100 ) goto st267; goto st0; st267: if ( ++p == pe ) goto _out267; case 267: switch( (*p) ) { case 0: goto tr360; case 37: goto tr361; case 38: goto tr362; case 124: goto tr363; } goto st0; st268: if ( ++p == pe ) goto _out268; case 268: switch( (*p) ) { case 99: goto st269; case 101: goto st273; } goto st0; st269: if ( ++p == pe ) goto _out269; case 269: if ( (*p) == 104 ) goto st270; goto st0; st270: if ( ++p == pe ) goto _out270; case 270: if ( (*p) == 97 ) goto st271; goto st0; st271: if ( ++p == pe ) goto _out271; case 271: if ( (*p) == 116 ) goto st272; goto st0; st272: if ( ++p == pe ) goto _out272; case 272: switch( (*p) ) { case 0: goto tr369; case 37: goto tr370; case 38: goto tr371; case 124: goto tr372; } goto st0; st273: if ( ++p == pe ) goto _out273; case 273: switch( (*p) ) { case 105: goto st274; case 110: goto st276; } goto st0; st274: if ( ++p == pe ) goto _out274; case 274: if ( (*p) == 99 ) goto st275; goto st0; st275: if ( ++p == pe ) goto _out275; case 275: switch( (*p) ) { case 0: goto tr376; case 37: goto tr377; case 38: goto tr378; case 124: goto tr379; } goto st0; st276: if ( ++p == pe ) goto _out276; case 276: switch( (*p) ) { case 0: goto tr380; case 37: goto tr381; case 38: goto tr382; case 44: goto tr383; case 124: goto tr384; } goto st0; st277: if ( ++p == pe ) goto _out277; case 277: switch( (*p) ) { case 110: goto st278; case 116: goto st281; } goto st0; st278: if ( ++p == pe ) goto _out278; case 278: if ( (*p) == 102 ) goto st279; goto st0; st279: if ( ++p == pe ) goto _out279; case 279: if ( (*p) == 111 ) goto st280; goto st0; st280: if ( ++p == pe ) goto _out280; case 280: switch( (*p) ) { case 0: goto tr389; case 37: goto tr390; case 38: goto tr391; case 124: goto tr392; } goto st0; st281: if ( ++p == pe ) goto _out281; case 281: if ( (*p) == 109 ) goto st282; goto st0; st282: if ( ++p == pe ) goto _out282; case 282: switch( (*p) ) { case 0: goto tr394; case 37: goto tr395; case 38: goto tr396; case 44: goto tr397; case 124: goto tr398; } goto st0; st283: if ( ++p == pe ) goto _out283; case 283: if ( (*p) == 110 ) goto st284; goto st0; st284: if ( ++p == pe ) goto _out284; case 284: if ( (*p) == 101 ) goto st285; goto st0; st285: if ( ++p == pe ) goto _out285; case 285: switch( (*p) ) { case 0: goto tr401; case 37: goto tr402; case 38: goto tr403; case 44: goto tr404; case 124: goto tr405; } goto st0; st286: if ( ++p == pe ) goto _out286; case 286: switch( (*p) ) { case 97: goto st287; case 101: goto st290; } goto st0; st287: if ( ++p == pe ) goto _out287; case 287: if ( (*p) == 105 ) goto st288; goto st0; st288: if ( ++p == pe ) goto _out288; case 288: if ( (*p) == 110 ) goto st289; goto st0; st289: if ( ++p == pe ) goto _out289; case 289: switch( (*p) ) { case 0: goto tr410; case 37: goto tr411; case 38: goto tr412; case 124: goto tr413; } goto st0; st290: if ( ++p == pe ) goto _out290; case 290: if ( (*p) == 115 ) goto st291; goto st0; st291: if ( ++p == pe ) goto _out291; case 291: switch( (*p) ) { case 0: goto tr415; case 37: goto tr416; case 38: goto tr417; case 44: goto tr418; case 101: goto st292; case 124: goto tr420; } goto st0; st292: if ( ++p == pe ) goto _out292; case 292: switch( (*p) ) { case 0: goto tr421; case 37: goto tr422; case 38: goto tr423; case 124: goto tr424; } goto st0; st293: if ( ++p == pe ) goto _out293; case 293: if ( (*p) == 101 ) goto st294; goto st0; st294: if ( ++p == pe ) goto _out294; case 294: if ( (*p) == 116 ) goto st295; goto st0; st295: if ( ++p == pe ) goto _out295; case 295: if ( (*p) == 107 ) goto st296; goto st0; st296: if ( ++p == pe ) goto _out296; case 296: switch( (*p) ) { case 0: goto tr428; case 37: goto tr429; case 38: goto tr430; case 124: goto tr431; } goto st0; st297: if ( ++p == pe ) goto _out297; case 297: switch( (*p) ) { case 102: goto st298; case 112: goto st301; case 114: goto st304; } goto st0; st298: if ( ++p == pe ) goto _out298; case 298: if ( (*p) == 114 ) goto st299; goto st0; st299: if ( ++p == pe ) goto _out299; case 299: if ( (*p) == 115 ) goto st300; goto st0; st300: if ( ++p == pe ) goto _out300; case 300: switch( (*p) ) { case 0: goto tr437; case 37: goto tr438; case 38: goto tr439; case 124: goto tr440; } goto st0; st301: if ( ++p == pe ) goto _out301; case 301: if ( (*p) == 105 ) goto st302; goto st0; st302: if ( ++p == pe ) goto _out302; case 302: if ( (*p) == 110 ) goto st303; goto st0; st303: if ( ++p == pe ) goto _out303; case 303: switch( (*p) ) { case 0: goto tr443; case 37: goto tr444; case 38: goto tr445; case 124: goto tr446; } goto st0; st304: if ( ++p == pe ) goto _out304; case 304: if ( (*p) == 100 ) goto st305; goto st0; st305: if ( ++p == pe ) goto _out305; case 305: switch( (*p) ) { case 0: goto tr448; case 37: goto tr449; case 38: goto tr450; case 44: goto tr451; case 115: goto st306; case 124: goto tr453; } goto st0; st306: if ( ++p == pe ) goto _out306; case 306: switch( (*p) ) { case 0: goto tr454; case 37: goto tr455; case 38: goto tr456; case 124: goto tr457; } goto st0; st307: if ( ++p == pe ) goto _out307; case 307: if ( (*p) == 114 ) goto st308; goto st0; st308: if ( ++p == pe ) goto _out308; case 308: if ( (*p) == 105 ) goto st309; goto st0; st309: if ( ++p == pe ) goto _out309; case 309: if ( (*p) == 99 ) goto st310; goto st0; st310: if ( ++p == pe ) goto _out310; case 310: switch( (*p) ) { case 0: goto tr461; case 37: goto tr462; case 38: goto tr463; case 124: goto tr464; } goto st0; st311: if ( ++p == pe ) goto _out311; case 311: if ( (*p) == 117 ) goto st312; goto st0; st312: if ( ++p == pe ) goto _out312; case 312: if ( (*p) == 101 ) goto st313; goto st0; st313: if ( ++p == pe ) goto _out313; case 313: if ( (*p) == 115 ) goto st314; goto st0; st314: if ( ++p == pe ) goto _out314; case 314: switch( (*p) ) { case 0: goto tr468; case 37: goto tr469; case 38: goto tr470; case 124: goto tr471; } goto st0; st315: if ( ++p == pe ) goto _out315; case 315: switch( (*p) ) { case 104: goto st316; case 117: goto st320; } goto st0; st316: if ( ++p == pe ) goto _out316; case 316: switch( (*p) ) { case 99: goto st317; case 111: goto st318; case 115: goto st319; } goto st0; st317: if ( ++p == pe ) goto _out317; case 317: switch( (*p) ) { case 0: goto tr477; case 37: goto tr478; case 38: goto tr479; case 44: goto tr480; case 124: goto tr481; } goto st0; st318: if ( ++p == pe ) goto _out318; case 318: switch( (*p) ) { case 0: goto tr482; case 37: goto tr483; case 38: goto tr484; case 44: goto tr485; case 124: goto tr486; } goto st0; st319: if ( ++p == pe ) goto _out319; case 319: switch( (*p) ) { case 0: goto tr487; case 37: goto tr488; case 38: goto tr489; case 44: goto tr490; case 124: goto tr491; } goto st0; st320: if ( ++p == pe ) goto _out320; case 320: switch( (*p) ) { case 111: goto st321; case 115: goto st322; } goto st0; st321: if ( ++p == pe ) goto _out321; case 321: switch( (*p) ) { case 0: goto tr494; case 37: goto tr495; case 38: goto tr496; case 44: goto tr497; case 124: goto tr498; } goto st0; st322: if ( ++p == pe ) goto _out322; case 322: switch( (*p) ) { case 0: goto tr499; case 37: goto tr500; case 38: goto tr501; case 44: goto tr502; case 124: goto tr503; } goto st0; st323: if ( ++p == pe ) goto _out323; case 323: switch( (*p) ) { case 97: goto st324; case 111: goto st327; case 119: goto st329; } goto st0; st324: if ( ++p == pe ) goto _out324; case 324: if ( (*p) == 115 ) goto st325; goto st0; st325: if ( ++p == pe ) goto _out325; case 325: if ( (*p) == 107 ) goto st326; goto st0; st326: if ( ++p == pe ) goto _out326; case 326: switch( (*p) ) { case 0: goto tr509; case 37: goto tr510; case 38: goto tr511; case 124: goto tr512; } goto st0; st327: if ( ++p == pe ) goto _out327; case 327: if ( (*p) == 113 ) goto st328; goto st0; st328: if ( ++p == pe ) goto _out328; case 328: switch( (*p) ) { case 0: goto tr514; case 37: goto tr515; case 38: goto tr516; case 44: goto tr517; case 124: goto tr518; } goto st0; st329: if ( ++p == pe ) goto _out329; case 329: if ( (*p) == 112 ) goto st330; goto st0; st330: if ( ++p == pe ) goto _out330; case 330: switch( (*p) ) { case 0: goto tr520; case 37: goto tr521; case 38: goto tr522; case 44: goto tr523; case 124: goto tr524; } goto st0; st331: if ( ++p == pe ) goto _out331; case 331: switch( (*p) ) { case 110: goto st332; case 115: goto st334; } goto st0; st332: if ( ++p == pe ) goto _out332; case 332: if ( (*p) == 119 ) goto st333; goto st0; st333: if ( ++p == pe ) goto _out333; case 333: switch( (*p) ) { case 0: goto tr528; case 37: goto tr529; case 38: goto tr530; case 44: goto tr531; case 124: goto tr532; } goto st0; st334: if ( ++p == pe ) goto _out334; case 334: switch( (*p) ) { case 101: goto st335; case 114: goto st338; } goto st0; st335: if ( ++p == pe ) goto _out335; case 335: if ( (*p) == 114 ) goto st336; goto st0; st336: if ( ++p == pe ) goto _out336; case 336: if ( (*p) == 115 ) goto st337; goto st0; st337: if ( ++p == pe ) goto _out337; case 337: switch( (*p) ) { case 0: goto tr537; case 37: goto tr538; case 38: goto tr539; case 124: goto tr540; } goto st0; st338: if ( ++p == pe ) goto _out338; case 338: switch( (*p) ) { case 0: goto tr541; case 37: goto tr542; case 38: goto tr543; case 44: goto tr544; case 124: goto tr545; } goto st0; st339: if ( ++p == pe ) goto _out339; case 339: if ( (*p) == 115 ) goto st340; goto st0; st340: if ( ++p == pe ) goto _out340; case 340: if ( (*p) == 101 ) goto st341; goto st0; st341: if ( ++p == pe ) goto _out341; case 341: switch( (*p) ) { case 99: goto st342; case 114: goto st354; } goto st0; st342: if ( ++p == pe ) goto _out342; case 342: if ( (*p) == 61 ) goto st343; goto st0; st343: if ( ++p == pe ) goto _out343; case 343: if ( 48 <= (*p) && (*p) <= 57 ) goto tr551; goto st0; tr551: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st344; st344: if ( ++p == pe ) goto _out344; case 344: #line 4718 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr554; goto st0; tr554: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st345; st345: if ( ++p == pe ) goto _out345; case 345: #line 4734 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr555; goto st0; tr555: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st346; st346: if ( ++p == pe ) goto _out346; case 346: #line 4750 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr556; goto st0; tr556: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st347; st347: if ( ++p == pe ) goto _out347; case 347: #line 4766 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr557; goto st0; tr557: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st348; st348: if ( ++p == pe ) goto _out348; case 348: #line 4782 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr558; goto st0; tr558: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st349; st349: if ( ++p == pe ) goto _out349; case 349: #line 4798 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr559; goto st0; tr559: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st350; st350: if ( ++p == pe ) goto _out350; case 350: #line 4814 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr560; goto st0; tr560: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st351; st351: if ( ++p == pe ) goto _out351; case 351: #line 4830 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr561; goto st0; tr561: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st352; st352: if ( ++p == pe ) goto _out352; case 352: #line 4846 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr562; goto st0; tr562: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st353; st353: if ( ++p == pe ) goto _out353; case 353: #line 4862 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr552; case 38: goto tr553; } goto st0; st354: if ( ++p == pe ) goto _out354; case 354: if ( (*p) == 95 ) goto st355; goto st0; st355: if ( ++p == pe ) goto _out355; case 355: if ( (*p) == 105 ) goto st356; goto st0; st356: if ( ++p == pe ) goto _out356; case 356: if ( (*p) == 100 ) goto st357; goto st0; st357: if ( ++p == pe ) goto _out357; case 357: if ( (*p) == 61 ) goto st358; goto st0; st358: if ( ++p == pe ) goto _out358; case 358: if ( 48 <= (*p) && (*p) <= 57 ) goto tr567; goto st0; tr567: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st359; st359: if ( ++p == pe ) goto _out359; case 359: #line 4913 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr570; goto st0; tr570: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st360; st360: if ( ++p == pe ) goto _out360; case 360: #line 4929 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr571; goto st0; tr571: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st361; st361: if ( ++p == pe ) goto _out361; case 361: #line 4945 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr572; goto st0; tr572: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st362; st362: if ( ++p == pe ) goto _out362; case 362: #line 4961 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr573; goto st0; tr573: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st363; st363: if ( ++p == pe ) goto _out363; case 363: #line 4977 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr574; goto st0; tr574: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st364; st364: if ( ++p == pe ) goto _out364; case 364: #line 4993 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr575; goto st0; tr575: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st365; st365: if ( ++p == pe ) goto _out365; case 365: #line 5009 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr576; goto st0; tr576: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st366; st366: if ( ++p == pe ) goto _out366; case 366: #line 5025 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr577; goto st0; tr577: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st367; st367: if ( ++p == pe ) goto _out367; case 367: #line 5041 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr578; goto st0; tr578: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st368; st368: if ( ++p == pe ) goto _out368; case 368: #line 5057 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr568; case 38: goto tr569; } goto st0; st369: if ( ++p == pe ) goto _out369; case 369: if ( (*p) == 105 ) goto st370; goto st0; st370: if ( ++p == pe ) goto _out370; case 370: if ( (*p) == 110 ) goto st371; goto st0; st371: if ( ++p == pe ) goto _out371; case 371: if ( (*p) == 95 ) goto st372; goto st0; st372: if ( ++p == pe ) goto _out372; case 372: switch( (*p) ) { case 105: goto st373; case 115: goto st386; } goto st0; st373: if ( ++p == pe ) goto _out373; case 373: if ( (*p) == 100 ) goto st374; goto st0; st374: if ( ++p == pe ) goto _out374; case 374: if ( (*p) == 61 ) goto st375; goto st0; st375: if ( ++p == pe ) goto _out375; case 375: if ( 48 <= (*p) && (*p) <= 57 ) goto tr586; goto st0; tr586: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st376; st376: if ( ++p == pe ) goto _out376; case 376: #line 5124 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr589; goto st0; tr589: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st377; st377: if ( ++p == pe ) goto _out377; case 377: #line 5140 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr590; goto st0; tr590: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st378; st378: if ( ++p == pe ) goto _out378; case 378: #line 5156 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr591; goto st0; tr591: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st379; st379: if ( ++p == pe ) goto _out379; case 379: #line 5172 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr592; goto st0; tr592: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st380; st380: if ( ++p == pe ) goto _out380; case 380: #line 5188 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr593; goto st0; tr593: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st381; st381: if ( ++p == pe ) goto _out381; case 381: #line 5204 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr594; goto st0; tr594: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st382; st382: if ( ++p == pe ) goto _out382; case 382: #line 5220 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr595; goto st0; tr595: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st383; st383: if ( ++p == pe ) goto _out383; case 383: #line 5236 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr596; goto st0; tr596: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st384; st384: if ( ++p == pe ) goto _out384; case 384: #line 5252 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr597; goto st0; tr597: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st385; st385: if ( ++p == pe ) goto _out385; case 385: #line 5268 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr587; case 38: goto tr588; } goto st0; st386: if ( ++p == pe ) goto _out386; case 386: if ( (*p) == 116 ) goto st387; goto st0; st387: if ( ++p == pe ) goto _out387; case 387: if ( (*p) == 61 ) goto st388; goto st0; st388: if ( ++p == pe ) goto _out388; case 388: if ( 48 <= (*p) && (*p) <= 57 ) goto tr600; goto st0; tr600: #line 13 "mod_fdajax_parser.rl" { cur_int = 0; } #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st389; st389: if ( ++p == pe ) goto _out389; case 389: #line 5305 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr603; goto st0; tr603: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st390; st390: if ( ++p == pe ) goto _out390; case 390: #line 5321 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr604; goto st0; tr604: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st391; st391: if ( ++p == pe ) goto _out391; case 391: #line 5337 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr605; goto st0; tr605: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st392; st392: if ( ++p == pe ) goto _out392; case 392: #line 5353 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr606; goto st0; tr606: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st393; st393: if ( ++p == pe ) goto _out393; case 393: #line 5369 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr607; goto st0; tr607: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st394; st394: if ( ++p == pe ) goto _out394; case 394: #line 5385 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr608; goto st0; tr608: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st395; st395: if ( ++p == pe ) goto _out395; case 395: #line 5401 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr609; goto st0; tr609: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st396; st396: if ( ++p == pe ) goto _out396; case 396: #line 5417 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr610; goto st0; tr610: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st397; st397: if ( ++p == pe ) goto _out397; case 397: #line 5433 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr611; goto st0; tr611: #line 13 "mod_fdajax_parser.rl" { cur_int = cur_int * 10 + ((*p) - '0'); } goto st398; st398: if ( ++p == pe ) goto _out398; case 398: #line 5449 "mod_fdajax_parser.c" switch( (*p) ) { case 0: goto tr601; case 38: goto tr602; } goto st0; } _out1: cs = 1; goto _out; _out0: cs = 0; goto _out; _out2: cs = 2; goto _out; _out3: cs = 3; goto _out; _out399: cs = 399; goto _out; _out4: cs = 4; goto _out; _out5: cs = 5; goto _out; _out6: cs = 6; goto _out; _out7: cs = 7; goto _out; _out8: cs = 8; goto _out; _out9: cs = 9; goto _out; _out10: cs = 10; goto _out; _out11: cs = 11; goto _out; _out12: cs = 12; goto _out; _out13: cs = 13; goto _out; _out14: cs = 14; goto _out; _out15: cs = 15; goto _out; _out16: cs = 16; goto _out; _out17: cs = 17; goto _out; _out18: cs = 18; goto _out; _out19: cs = 19; goto _out; _out20: cs = 20; goto _out; _out21: cs = 21; goto _out; _out22: cs = 22; goto _out; _out23: cs = 23; goto _out; _out24: cs = 24; goto _out; _out25: cs = 25; goto _out; _out26: cs = 26; goto _out; _out27: cs = 27; goto _out; _out28: cs = 28; goto _out; _out29: cs = 29; goto _out; _out30: cs = 30; goto _out; _out31: cs = 31; goto _out; _out32: cs = 32; goto _out; _out33: cs = 33; goto _out; _out34: cs = 34; goto _out; _out35: cs = 35; goto _out; _out36: cs = 36; goto _out; _out37: cs = 37; goto _out; _out38: cs = 38; goto _out; _out39: cs = 39; goto _out; _out40: cs = 40; goto _out; _out41: cs = 41; goto _out; _out42: cs = 42; goto _out; _out43: cs = 43; goto _out; _out44: cs = 44; goto _out; _out45: cs = 45; goto _out; _out46: cs = 46; goto _out; _out47: cs = 47; goto _out; _out48: cs = 48; goto _out; _out49: cs = 49; goto _out; _out50: cs = 50; goto _out; _out51: cs = 51; goto _out; _out52: cs = 52; goto _out; _out53: cs = 53; goto _out; _out54: cs = 54; goto _out; _out55: cs = 55; goto _out; _out56: cs = 56; goto _out; _out57: cs = 57; goto _out; _out58: cs = 58; goto _out; _out59: cs = 59; goto _out; _out60: cs = 60; goto _out; _out61: cs = 61; goto _out; _out62: cs = 62; goto _out; _out63: cs = 63; goto _out; _out64: cs = 64; goto _out; _out65: cs = 65; goto _out; _out66: cs = 66; goto _out; _out67: cs = 67; goto _out; _out68: cs = 68; goto _out; _out69: cs = 69; goto _out; _out70: cs = 70; goto _out; _out71: cs = 71; goto _out; _out72: cs = 72; goto _out; _out73: cs = 73; goto _out; _out74: cs = 74; goto _out; _out75: cs = 75; goto _out; _out76: cs = 76; goto _out; _out77: cs = 77; goto _out; _out78: cs = 78; goto _out; _out79: cs = 79; goto _out; _out80: cs = 80; goto _out; _out81: cs = 81; goto _out; _out82: cs = 82; goto _out; _out83: cs = 83; goto _out; _out84: cs = 84; goto _out; _out85: cs = 85; goto _out; _out86: cs = 86; goto _out; _out87: cs = 87; goto _out; _out88: cs = 88; goto _out; _out89: cs = 89; goto _out; _out90: cs = 90; goto _out; _out91: cs = 91; goto _out; _out92: cs = 92; goto _out; _out93: cs = 93; goto _out; _out94: cs = 94; goto _out; _out95: cs = 95; goto _out; _out96: cs = 96; goto _out; _out97: cs = 97; goto _out; _out98: cs = 98; goto _out; _out99: cs = 99; goto _out; _out100: cs = 100; goto _out; _out101: cs = 101; goto _out; _out102: cs = 102; goto _out; _out103: cs = 103; goto _out; _out104: cs = 104; goto _out; _out105: cs = 105; goto _out; _out106: cs = 106; goto _out; _out107: cs = 107; goto _out; _out108: cs = 108; goto _out; _out109: cs = 109; goto _out; _out110: cs = 110; goto _out; _out111: cs = 111; goto _out; _out112: cs = 112; goto _out; _out113: cs = 113; goto _out; _out114: cs = 114; goto _out; _out115: cs = 115; goto _out; _out116: cs = 116; goto _out; _out117: cs = 117; goto _out; _out118: cs = 118; goto _out; _out119: cs = 119; goto _out; _out120: cs = 120; goto _out; _out121: cs = 121; goto _out; _out122: cs = 122; goto _out; _out123: cs = 123; goto _out; _out124: cs = 124; goto _out; _out125: cs = 125; goto _out; _out126: cs = 126; goto _out; _out127: cs = 127; goto _out; _out128: cs = 128; goto _out; _out129: cs = 129; goto _out; _out130: cs = 130; goto _out; _out131: cs = 131; goto _out; _out132: cs = 132; goto _out; _out133: cs = 133; goto _out; _out134: cs = 134; goto _out; _out135: cs = 135; goto _out; _out136: cs = 136; goto _out; _out137: cs = 137; goto _out; _out138: cs = 138; goto _out; _out139: cs = 139; goto _out; _out140: cs = 140; goto _out; _out141: cs = 141; goto _out; _out142: cs = 142; goto _out; _out143: cs = 143; goto _out; _out144: cs = 144; goto _out; _out145: cs = 145; goto _out; _out146: cs = 146; goto _out; _out147: cs = 147; goto _out; _out148: cs = 148; goto _out; _out149: cs = 149; goto _out; _out150: cs = 150; goto _out; _out151: cs = 151; goto _out; _out152: cs = 152; goto _out; _out153: cs = 153; goto _out; _out154: cs = 154; goto _out; _out155: cs = 155; goto _out; _out156: cs = 156; goto _out; _out157: cs = 157; goto _out; _out158: cs = 158; goto _out; _out159: cs = 159; goto _out; _out160: cs = 160; goto _out; _out161: cs = 161; goto _out; _out162: cs = 162; goto _out; _out163: cs = 163; goto _out; _out164: cs = 164; goto _out; _out165: cs = 165; goto _out; _out166: cs = 166; goto _out; _out167: cs = 167; goto _out; _out168: cs = 168; goto _out; _out169: cs = 169; goto _out; _out170: cs = 170; goto _out; _out171: cs = 171; goto _out; _out172: cs = 172; goto _out; _out173: cs = 173; goto _out; _out174: cs = 174; goto _out; _out175: cs = 175; goto _out; _out176: cs = 176; goto _out; _out177: cs = 177; goto _out; _out178: cs = 178; goto _out; _out179: cs = 179; goto _out; _out180: cs = 180; goto _out; _out181: cs = 181; goto _out; _out182: cs = 182; goto _out; _out183: cs = 183; goto _out; _out184: cs = 184; goto _out; _out185: cs = 185; goto _out; _out186: cs = 186; goto _out; _out187: cs = 187; goto _out; _out188: cs = 188; goto _out; _out189: cs = 189; goto _out; _out190: cs = 190; goto _out; _out191: cs = 191; goto _out; _out192: cs = 192; goto _out; _out193: cs = 193; goto _out; _out194: cs = 194; goto _out; _out195: cs = 195; goto _out; _out196: cs = 196; goto _out; _out197: cs = 197; goto _out; _out198: cs = 198; goto _out; _out199: cs = 199; goto _out; _out200: cs = 200; goto _out; _out201: cs = 201; goto _out; _out202: cs = 202; goto _out; _out203: cs = 203; goto _out; _out204: cs = 204; goto _out; _out205: cs = 205; goto _out; _out206: cs = 206; goto _out; _out207: cs = 207; goto _out; _out208: cs = 208; goto _out; _out209: cs = 209; goto _out; _out210: cs = 210; goto _out; _out211: cs = 211; goto _out; _out212: cs = 212; goto _out; _out213: cs = 213; goto _out; _out214: cs = 214; goto _out; _out215: cs = 215; goto _out; _out216: cs = 216; goto _out; _out217: cs = 217; goto _out; _out218: cs = 218; goto _out; _out219: cs = 219; goto _out; _out220: cs = 220; goto _out; _out221: cs = 221; goto _out; _out222: cs = 222; goto _out; _out223: cs = 223; goto _out; _out224: cs = 224; goto _out; _out225: cs = 225; goto _out; _out226: cs = 226; goto _out; _out227: cs = 227; goto _out; _out228: cs = 228; goto _out; _out229: cs = 229; goto _out; _out230: cs = 230; goto _out; _out231: cs = 231; goto _out; _out232: cs = 232; goto _out; _out233: cs = 233; goto _out; _out234: cs = 234; goto _out; _out235: cs = 235; goto _out; _out236: cs = 236; goto _out; _out237: cs = 237; goto _out; _out238: cs = 238; goto _out; _out239: cs = 239; goto _out; _out240: cs = 240; goto _out; _out241: cs = 241; goto _out; _out242: cs = 242; goto _out; _out243: cs = 243; goto _out; _out244: cs = 244; goto _out; _out245: cs = 245; goto _out; _out246: cs = 246; goto _out; _out247: cs = 247; goto _out; _out248: cs = 248; goto _out; _out249: cs = 249; goto _out; _out250: cs = 250; goto _out; _out251: cs = 251; goto _out; _out252: cs = 252; goto _out; _out253: cs = 253; goto _out; _out254: cs = 254; goto _out; _out255: cs = 255; goto _out; _out256: cs = 256; goto _out; _out257: cs = 257; goto _out; _out258: cs = 258; goto _out; _out259: cs = 259; goto _out; _out260: cs = 260; goto _out; _out261: cs = 261; goto _out; _out262: cs = 262; goto _out; _out263: cs = 263; goto _out; _out264: cs = 264; goto _out; _out265: cs = 265; goto _out; _out266: cs = 266; goto _out; _out267: cs = 267; goto _out; _out268: cs = 268; goto _out; _out269: cs = 269; goto _out; _out270: cs = 270; goto _out; _out271: cs = 271; goto _out; _out272: cs = 272; goto _out; _out273: cs = 273; goto _out; _out274: cs = 274; goto _out; _out275: cs = 275; goto _out; _out276: cs = 276; goto _out; _out277: cs = 277; goto _out; _out278: cs = 278; goto _out; _out279: cs = 279; goto _out; _out280: cs = 280; goto _out; _out281: cs = 281; goto _out; _out282: cs = 282; goto _out; _out283: cs = 283; goto _out; _out284: cs = 284; goto _out; _out285: cs = 285; goto _out; _out286: cs = 286; goto _out; _out287: cs = 287; goto _out; _out288: cs = 288; goto _out; _out289: cs = 289; goto _out; _out290: cs = 290; goto _out; _out291: cs = 291; goto _out; _out292: cs = 292; goto _out; _out293: cs = 293; goto _out; _out294: cs = 294; goto _out; _out295: cs = 295; goto _out; _out296: cs = 296; goto _out; _out297: cs = 297; goto _out; _out298: cs = 298; goto _out; _out299: cs = 299; goto _out; _out300: cs = 300; goto _out; _out301: cs = 301; goto _out; _out302: cs = 302; goto _out; _out303: cs = 303; goto _out; _out304: cs = 304; goto _out; _out305: cs = 305; goto _out; _out306: cs = 306; goto _out; _out307: cs = 307; goto _out; _out308: cs = 308; goto _out; _out309: cs = 309; goto _out; _out310: cs = 310; goto _out; _out311: cs = 311; goto _out; _out312: cs = 312; goto _out; _out313: cs = 313; goto _out; _out314: cs = 314; goto _out; _out315: cs = 315; goto _out; _out316: cs = 316; goto _out; _out317: cs = 317; goto _out; _out318: cs = 318; goto _out; _out319: cs = 319; goto _out; _out320: cs = 320; goto _out; _out321: cs = 321; goto _out; _out322: cs = 322; goto _out; _out323: cs = 323; goto _out; _out324: cs = 324; goto _out; _out325: cs = 325; goto _out; _out326: cs = 326; goto _out; _out327: cs = 327; goto _out; _out328: cs = 328; goto _out; _out329: cs = 329; goto _out; _out330: cs = 330; goto _out; _out331: cs = 331; goto _out; _out332: cs = 332; goto _out; _out333: cs = 333; goto _out; _out334: cs = 334; goto _out; _out335: cs = 335; goto _out; _out336: cs = 336; goto _out; _out337: cs = 337; goto _out; _out338: cs = 338; goto _out; _out339: cs = 339; goto _out; _out340: cs = 340; goto _out; _out341: cs = 341; goto _out; _out342: cs = 342; goto _out; _out343: cs = 343; goto _out; _out344: cs = 344; goto _out; _out345: cs = 345; goto _out; _out346: cs = 346; goto _out; _out347: cs = 347; goto _out; _out348: cs = 348; goto _out; _out349: cs = 349; goto _out; _out350: cs = 350; goto _out; _out351: cs = 351; goto _out; _out352: cs = 352; goto _out; _out353: cs = 353; goto _out; _out354: cs = 354; goto _out; _out355: cs = 355; goto _out; _out356: cs = 356; goto _out; _out357: cs = 357; goto _out; _out358: cs = 358; goto _out; _out359: cs = 359; goto _out; _out360: cs = 360; goto _out; _out361: cs = 361; goto _out; _out362: cs = 362; goto _out; _out363: cs = 363; goto _out; _out364: cs = 364; goto _out; _out365: cs = 365; goto _out; _out366: cs = 366; goto _out; _out367: cs = 367; goto _out; _out368: cs = 368; goto _out; _out369: cs = 369; goto _out; _out370: cs = 370; goto _out; _out371: cs = 371; goto _out; _out372: cs = 372; goto _out; _out373: cs = 373; goto _out; _out374: cs = 374; goto _out; _out375: cs = 375; goto _out; _out376: cs = 376; goto _out; _out377: cs = 377; goto _out; _out378: cs = 378; goto _out; _out379: cs = 379; goto _out; _out380: cs = 380; goto _out; _out381: cs = 381; goto _out; _out382: cs = 382; goto _out; _out383: cs = 383; goto _out; _out384: cs = 384; goto _out; _out385: cs = 385; goto _out; _out386: cs = 386; goto _out; _out387: cs = 387; goto _out; _out388: cs = 388; goto _out; _out389: cs = 389; goto _out; _out390: cs = 390; goto _out; _out391: cs = 391; goto _out; _out392: cs = 392; goto _out; _out393: cs = 393; goto _out; _out394: cs = 394; goto _out; _out395: cs = 395; goto _out; _out396: cs = 396; goto _out; _out397: cs = 397; goto _out; _out398: cs = 398; goto _out; _out: {} } #line 199 "mod_fdajax_parser.rl" req->cs = cs; return 1; } int mod_fdajax_pfinish(user_request_p req) { int cs = req->cs; #line 5869 "mod_fdajax_parser.c" #line 208 "mod_fdajax_parser.rl" req->cs = cs; if (req->cs == fdamod_parser_error) { return -1; } else if (req->cs >= fdamod_parser_first_final) { return 1; } return 0; } mod_fdajax-0.9/src/mod_fdajax_parser.rl0000640000175000017500000001717110650371237016715 0ustar greggreg#include #include #include #include "mod_fdajax_defs.h" #define INIT_EVENT(mask, index) req->ev.count++; req->ev.types |= mask; cur_ev_nr = index; req->ev.ids_len[index] = 0 #define CUR_ID_TAB_LEN req->ev.ids_len[cur_ev_nr] %%{ machine fdamod_parser; uint = digit{1,10} >{ cur_int = 0; } @{ cur_int = cur_int * 10 + (fc - '0'); } ; user_id = 'user_id=' uint %{ req->user_id = cur_int; } ; peer_id = 'peer_id=' uint %{ req->peer_id = cur_int; } ; win_id = 'win_id=' uint %{ req->win_id = cur_int; } ; win_st = 'win_st=' uint %{ req->win_st = cur_int; } ; sec = 'sec=' uint %{ req->tv.tv_sec = cur_int; } ; usec = 'usec=' uint %{ req->tv.tv_usec = cur_int; } ; alert_id = 'alert_id=' uint %{ req->alert_id = cur_int; } ; amode = 'amode=' uint %{ req->amode = cur_int; } ; force = 'force=' uint %{ req->force_old_close = cur_int; } ; cmd = 'cmd=' ( 'wait' %{ req->cmd = cmd_wait; } | 'push' %{ req->cmd = cmd_push; } | 'alert' %{ req->cmd = cmd_alert; } | 'stream' %{ req->cmd = cmd_stream; } | 'cancel' %{ req->cmd = cmd_cancel; } | 'check' %{ req->cmd = cmd_check_user; } | 'login' %{ req->cmd = cmd_login; } | 'logout' %{ req->cmd = cmd_logout; } | 'info' %{ req->cmd = cmd_info; } | 'add_chat' %{ req->cmd = cmd_addchat; } | 'rm_chat' %{ req->cmd = cmd_rmchat; } | 'chat_sig' %{ req->cmd = cmd_chatsig; } ) ; action add_id { if (CUR_ID_TAB_LEN < FDA_IDS_MAX) { req->ev.ids[cur_ev_nr][CUR_ID_TAB_LEN++] = cur_int; } else { CUR_ID_TAB_LEN = 0; } } ev_model = ('unw' %{ INIT_EVENT(FDA_EV_UNW, FDA_EV_UNW_INDEX); } | 'gen' %{ INIT_EVENT(FDA_EV_GEN, FDA_EV_GEN_INDEX); } | 'chat' %{ INIT_EVENT(FDA_EV_CHAT, FDA_EV_CHAT_INDEX); } | 'toq' %{ INIT_EVENT(FDA_EV_TOQ, FDA_EV_TOQ_INDEX); } | 'twp' %{ INIT_EVENT(FDA_EV_TWP, FDA_EV_TWP_INDEX); } | 'suo' %{ INIT_EVENT(FDA_EV_SUO, FDA_EV_SUO_INDEX); } | 'sus' %{ INIT_EVENT(FDA_EV_SUS, FDA_EV_SUS_INDEX); } | 'sho' %{ INIT_EVENT(FDA_EV_SHO, FDA_EV_SHO_INDEX); } | 'shs' %{ INIT_EVENT(FDA_EV_SHS, FDA_EV_SHS_INDEX); } | 'shc' %{ INIT_EVENT(FDA_EV_SHC, FDA_EV_SHC_INDEX); } | 'mes' %{ INIT_EVENT(FDA_EV_MES, FDA_EV_MES_INDEX); } | 'ord' %{ INIT_EVENT(FDA_EV_ORD, FDA_EV_ORD_INDEX); } | 'ccd' %{ INIT_EVENT(FDA_EV_CCD, FDA_EV_CCD_INDEX); } | 'itm' %{ INIT_EVENT(FDA_EV_ITM, FDA_EV_ITM_INDEX); } | 'lne' %{ INIT_EVENT(FDA_EV_LNE, FDA_EV_LNE_INDEX); } | 'usr' %{ INIT_EVENT(FDA_EV_USR, FDA_EV_USR_INDEX); } ) ( ('%2C' | '%2c' | ',') uint %add_id ) * ; ev_group = ('main' %{ INIT_EVENT(FDA_GRP_MAIN, FDA_GRP_MAIN_INDEX); } | 'gchat' %{ INIT_EVENT(FDA_GRP_CHAT, FDA_GRP_CHAT_INDEX); } | 'ques' %{ INIT_EVENT(FDA_GRP_QUES, FDA_GRP_QUES_INDEX); } | 'answ' %{ INIT_EVENT(FDA_GRP_ANSW, FDA_GRP_ANSW_INDEX); } | 'ofrs' %{ INIT_EVENT(FDA_GRP_OFRS, FDA_GRP_OFRS_INDEX); } | 'pric' %{ INIT_EVENT(FDA_GRP_PRIC, FDA_GRP_PRIC_INDEX); } | 'opin' %{ INIT_EVENT(FDA_GRP_OPIN, FDA_GRP_OPIN_INDEX); } | 'users' %{ INIT_EVENT(FDA_GRP_USER, FDA_GRP_USER_INDEX); } | 'ords' %{ INIT_EVENT(FDA_GRP_ORDS, FDA_GRP_ORDS_INDEX); } | 'geic' %{ INIT_EVENT(FDA_GRP_GEIC, FDA_GRP_GEIC_INDEX); } | 'feed' %{ INIT_EVENT(FDA_GRP_FEED, FDA_GRP_FEED_INDEX); } | 'mese' %{ INIT_EVENT(FDA_GRP_MESE, FDA_GRP_MESE_INDEX); } | 'netk' %{ INIT_EVENT(FDA_GRP_NETK, FDA_GRP_NETK_INDEX); } | 'task' %{ INIT_EVENT(FDA_GRP_TASK, FDA_GRP_TASK_INDEX); } | 'frid' %{ INIT_EVENT(FDA_GRP_FRID, FDA_GRP_FRID_INDEX); } | 'info' %{ INIT_EVENT(FDA_GRP_INFO, FDA_GRP_INFO_INDEX); } ) ; ev_type = ev_model | ev_group; ev_types = ('types=' ev_type (('%7C' | '%7c' | '|') ev_type) * ) ; # IP address in host byte order ipaddr = 'ip_addr=' uint %{ if (0xff < cur_int) fbreak; ip_addr = ip_addr | (cur_int << 24); } '.' uint %{ if (0xff < cur_int) fbreak; ip_addr = ip_addr | (cur_int << 16); } '.' uint %{ if (0xff < cur_int) fbreak; ip_addr = ip_addr | (cur_int << 8); }'.' uint %{ if (0xff < cur_int) fbreak; ip_addr = ip_addr | (cur_int << 0); req->ipaddr.s_addr = ip_addr; ip_addr = 0; } ; # Decode url encoded string action init_mes { if (req->mes) { fbreak; } req->mes = buffer_init(); /* TODO is mem allocated ? */ buffer_prepare_append(req->mes, len); buf = req->mes->ptr; ppos = &(req->mes->used); } action init_hex { hex = phex << 4; } action finish_hex { hex = hex | phex; buf[(*ppos)++] = hex; } action append_char { buf[(*ppos)++] = fc; } action append_sp { buf[(*ppos)++] = ' '; } action finish_mes { buf[(*ppos)++] = 0; } hex = [a-f] @{ phex = fc - 'a' + 10; } | [A-F] @{ phex = fc - 'A' + 10; } | [0-9] @{ phex = fc - '0'; } ; mes = 'mes=' ( ('%' hex %init_hex hex %finish_hex ) | ('+' @append_sp ) | ([^&%+\0] @append_char) ) + >init_mes %finish_mes ; action set_mark { mark = fpc; } action copy_sessid { if (req->req_sess_id) { fbreak; } req->req_sess_id = buffer_init(); buffer_copy_string_len(req->req_sess_id, mark, fpc - mark); } sessid = 'sess_id=' [a-zA-Z0-9]+ >set_mark %copy_sessid ; action copy_admin_passwd { if (req->admin_passwd[0]) { fbreak; } j = min(fpc - mark, PASSWORD_MAX - 1); strncpy(req->admin_passwd, mark, j); req->admin_passwd[j] = 0; } admin_passwd = 'admin_passwd=' [a-zA-Z0-9]+ >set_mark %copy_admin_passwd ; dummy = '_=' ; arg = cmd | user_id | peer_id | win_id | win_st | ev_types | mes | sessid | ipaddr | sec | usec | alert_id | force | amode | admin_passwd | dummy ; main := arg ('&' arg)* 0 ; }%% %% write data; int mod_fdajax_pinit(user_request_p req) { int cs = 0; %% write init; req->cs = cs; req->cmd = 0; req->ev.types = 0; req->ev.count = 0; req->tv.tv_sec = 0; req->tv.tv_usec = 0; req->win_id = 0; req->win_st = 0; req->www_id = 0; req->alert_id = 0; req->amode = 0; req->force_old_close = 0; req->user_id = 0; req->peer_id = 0; req->ipaddr.s_addr = INADDR_NONE; req->mes = NULL; req->req_sess_id = NULL; req->sess_id_cookie[0] = 0; req->admin_passwd[0] = 0; return 1; } int mod_fdajax_pexec(user_request_p req, char *start, size_t len) { char *p, *pe, *mark = 0, *buf = 0; unsigned char phex = 0, hex = 0; unsigned int cur_int = 0; unsigned int ip_addr = 0; size_t j, *ppos = 0; int cur_ev_nr = 0; int cs = req->cs; assert(*(start + len) == 0); p = start; pe = start + len + 1; %% write exec; req->cs = cs; return 1; } int mod_fdajax_pfinish(user_request_p req) { int cs = req->cs; %% write eof; req->cs = cs; if (req->cs == fdamod_parser_error) { return -1; } else if (req->cs >= fdamod_parser_first_final) { return 1; } return 0; } mod_fdajax-0.9/src/mod_fdajax_users.c0000640000175000017500000001203710650106167016361 0ustar greggreg#include "mod_fdajax_defs.h" user_info_p user_login(user_request_p req) { user_info_p user = calloc(1, sizeof(user_info_t)); if (!user) { return NULL; } user->user_id = req->user_id; user->ipaddr.s_addr = htonl(req->ipaddr.s_addr); strncpy(user->sess_id, req->req_sess_id->ptr, min(SESS_ID_LEN_MAX - 1, req->req_sess_id->used)); user->sess_id[min(SESS_ID_LEN_MAX - 1, req->req_sess_id->used)] = 0; gettimeofday(&(user->created_at), 0); user->send_count = 0; user->send_peer_count = 0; user->last_alert = 0; bzero(user->alerts, sizeof(user->alerts)); message_list_init(&(user->mes_list)); return user; } user_info_p user_create_guest(connection *con, user_request_p req) { user_info_p user = calloc(1, sizeof(user_info_t)); if (!user) { return NULL; } user->user_id = 0; user->ipaddr.s_addr = con->dst_addr.ipv4.sin_addr.s_addr; strcpy(user->sess_id, req->sess_id_cookie); gettimeofday(&(user->created_at), 0); user->send_count = 0; user->send_peer_count = 0; user->last_alert = 0; bzero(user->alerts, sizeof(user->alerts)); message_list_init(&(user->mes_list)); return user; } void user_update_addr_and_sess(plugin_data *p, user_info_p user, user_request_p req) { user->ipaddr.s_addr = htonl(req->ipaddr.s_addr); if (strcmp(user->sess_id, req->req_sess_id->ptr) != 0) { HASH_DELETE(hh_sess, p->users_by_sess, user); strncpy(user->sess_id, req->req_sess_id->ptr, min(SESS_ID_LEN_MAX - 1, req->req_sess_id->used)); user->sess_id[min(SESS_ID_LEN_MAX - 1, req->req_sess_id->used)] = 0; HASH_ADD(hh_sess, p->users_by_sess, sess_id, strlen(user->sess_id), user); } } void user_update_id_and_ipaddr(plugin_data *p, user_info_p user, user_request_p req) { UNUSED(p); user->user_id = req->user_id; user->ipaddr.s_addr = htonl(req->ipaddr.s_addr); if (user->user_id > 0) { HASH_ADD(hh_id, p->users_by_id, user_id, sizeof(int), user); } } void user_free(server *srv, plugin_data *p, connection *con, user_info_p user) { message_remove_all(&(user->mes_list)); window_close_all(srv, p, con, user); free(user); } void users_free(server *srv, plugin_data *p) { user_info_p user; UNUSED(srv); log_info(srv, __FILE__, __LINE__, "s", "free_users"); while (NULL != (user = p->users_by_sess)) { user_detach(srv, p, user); user_free(srv, p, NULL, user); } } user_info_p user_find_by_sess(plugin_data *p, char *s) { user_info_p user; if (NULL == s) { return NULL; } HASH_FIND(hh_sess, p->users_by_sess, s, (int)strlen(s), user); return user; } user_info_p user_find_by_id(plugin_data *p, int user_id) { user_info_p user; if (0 == user_id) { return NULL; } HASH_FIND(hh_id, p->users_by_id, &user_id, sizeof(int), user); return user; } void user_attach(server *srv, plugin_data *p, user_info_p new_user) { UNUSED(srv); if (NULL == new_user) { return; } if (new_user->user_id > 0) { HASH_ADD(hh_id, p->users_by_id, user_id, sizeof(int), new_user); } HASH_ADD(hh_sess, p->users_by_sess, sess_id, strlen(new_user->sess_id), new_user); } void user_detach(server *srv, plugin_data *p, user_info_p old_user) { UNUSED(srv); if (old_user->user_id > 0) { HASH_DELETE(hh_id, p->users_by_id, old_user); } HASH_DELETE(hh_sess, p->users_by_sess, old_user); } user_info_p user_auth(server *srv, connection *con, plugin_data *p, user_info_p user, user_request_p req, auth_problem_p preason) { if (user->user_id > 0) { if (req->user_id == 0 || req->user_id != user->user_id) { *preason = authp_null_userid; security_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "security: auth_user wrong uid", user->user_id, "req_uid", req->user_id); return NULL; } } else { if (req->user_id != 0) { *preason = authp_null_userid; security_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "security: auth_user guest cannot have uid ", req->user_id); return NULL; } } if (p->check_user_ip) { if (con->dst_addr.ipv4.sin_addr.s_addr != user->ipaddr.s_addr) { *preason = authp_ip_addr; security_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "security: auth_user ip check failed uid ", user->user_id); return NULL; } } if (strcmp(req->sess_id_cookie, user->sess_id) != 0) { *preason = authp_sessid; security_avg(srv, __FILE__, __LINE__, "bsd", con->dst_addr_buf, "security: auth_user sess_id different uid", user->user_id); return NULL; } return user; } int user_check(server *srv, plugin_data *p, connection *con, user_info_p user) { int open_win_count; message_remove_old(srv, p, &(user->mes_list)); open_win_count = window_remove_old(srv, p, con, user); return open_win_count; } mod_fdajax-0.9/src/mod_fdajax_messages.c0000640000175000017500000001617310650141505017027 0ustar greggreg#include "mod_fdajax_defs.h" mes_info_p message_init(user_request_p req) { mes_info_p mes = malloc(sizeof(mes_info_t)); if (!mes) { return NULL; } mes->mes = req->mes; req->mes = NULL; gettimeofday(&mes->created_at, NULL); mes->next = NULL; mes->prev = NULL; mes->send_count = 0; mes->to_remove = 0; mes->amode = req->amode; mes->ev = req->ev; return mes; } mes_info_p message_init_peer(server *srv, plugin_data *p, user_info_p user, user_request_p req) { int cs, ev_nr; buffer *js_call; mes_info_p mes = malloc(sizeof(mes_info_t)); UNUSED(srv); if (!mes) { return NULL; } gettimeofday(&mes->created_at, NULL); mes->next = NULL; mes->prev = NULL; mes->mes = NULL; mes->send_count = 0; mes->to_remove = 0; mes->amode = req->amode; mes->ev = req->ev; if (req->ev.count != 1 || (mes->ev.types & p->allow_peer_call_mask) == 0) { message_free(mes); return NULL; } ev_nr = event_bit_to_index(req->ev.types); if (ev_nr < FDA_GRP_START && mes->ev.ids_len[ev_nr] != 1) { message_free(mes); return NULL; } /* check posted params syntax */ mod_fdajax_cinit(&cs); mod_fdajax_cexec(&cs, req->mes->ptr, req->mes->used - 1); if (mod_fdajax_cfinish(&cs) < 1) { message_free(mes); return NULL; } /* build js function call */ js_call = buffer_init(); buffer_prepare_append(js_call, 32 + p->js_peer_func->used + req->mes->used); if (ev_nr < FDA_GRP_START) { buffer_copy_string_buffer(js_call, p->js_peer_func); } else { buffer_copy_string_buffer(js_call, p->js_grp_peer_func); } buffer_append_string(js_call, "("); buffer_append_long(js_call, user->user_id); buffer_append_string(js_call, ",\""); buffer_append_string(js_call, g_ev_name_by_index[ev_nr]); buffer_append_string(js_call, "\","); if (ev_nr < FDA_GRP_START) { buffer_append_long(js_call, mes->ev.ids[ev_nr][0]); buffer_append_string(js_call, ","); } buffer_append_string_buffer(js_call, req->mes); buffer_append_string(js_call, ");"); mes->mes = js_call; user->send_peer_count++; return mes; } void message_free(mes_info_p mes) { if (mes->mes) { buffer_free(mes->mes); } free(mes); } void message_list_init(mes_list_p list) { list->first_mes = list->last_mes = NULL; } void message_attach(mes_list_p list, mes_info_p mes) { if (NULL == list->first_mes) { list->first_mes = list->last_mes = mes; return; } assert(NULL != list->last_mes); list->last_mes->next = mes; mes->prev = list->last_mes; list->last_mes = mes; } void message_detach(mes_list_p list, mes_info_p mes) { if (list->first_mes == mes) { list->first_mes = mes->next; } if (list->last_mes == mes) { list->last_mes = mes->prev; } if (mes->next) { mes->next->prev = mes->prev; } if (mes->prev) { mes->prev->next = mes->next; } mes->next = mes->prev = NULL; } void message_remove_all(mes_list_p list) { mes_info_p pm2, pm = list->first_mes; while (pm) { pm2 = pm->next; message_free(pm); pm = pm2; } list->first_mes = list->last_mes = NULL; } int message_is_old(mes_info_p mes, struct timeval now, int mes_live_max) { double diff = ((now.tv_sec - mes->created_at.tv_sec) * 1000000) + now.tv_usec - mes->created_at.tv_usec; return (diff > mes_live_max) ? TRUE : FALSE; } void message_remove_old(server *srv, plugin_data *p, mes_list_p list) { struct timeval now; mes_info_p mes, next; UNUSED(srv); gettimeofday(&now, NULL); mes = list->first_mes; while (mes) { if (mes->to_remove || message_is_old(mes, now, p->mes_live_max)) { next = mes->next; message_detach(list, mes); message_free(mes); mes = next; } else { mes = mes->next; } } } int message_append_to_win(server *srv, plugin_data *p, win_info_p win, mes_info_p mes, int ev_index, int nl) { buffer *buf = window_get_buffer(win); UNUSED(srv); UNUSED(p); win->last_mes_at[ev_index] = mes->created_at; mes->send_count++; if (nl) { buffer_append_nl(buf); } buffer_append_string_buffer(buf, mes->mes); return 1; } int message_append_as_unwanted(server *srv, plugin_data *p, win_info_p win, mes_info_p mes) { buffer *buf = window_get_buffer(win); buffer_append_nl(buf); buffer_append_string_buffer(buf, p->unw_prefix); message_append_to_win(srv, p, win, mes, FDA_EV_UNW_INDEX, 0); return TRUE; } enum cmd_res_t message_send_pending(server *srv, plugin_data *p, mes_info_p mes, win_info_p win) { while (mes) { if (window_can_receive(win, mes, TRUE)) { message_append_to_win(srv, p, win, mes, event_bit_to_index(mes->ev.types), 1); if (!p->merge_messages) { break; } } mes = mes->next; } return cmdr_ok; } int message_handle_unsend(server *srv, plugin_data *p, user_info_p user, mes_info_p mes, win_info_p recv_win) { win_info_p win; size_t i; if (0 < mes->send_count) { return 0; } for(i = 0; i < WINDOWS_MAX; i++) { if (NULL != user->windows[i]) { if (window_can_receive(user->windows[i], mes, FALSE)) { return 0; } } } switch (mes->amode) { case 0: alert_add_from_mes(srv, p, user, mes); mes->to_remove = 1; break; case 1: if (NULL == recv_win) { win = window_first_with_unw(srv, p, user); } else { win = recv_win; } if (NULL != win) { message_append_as_unwanted(srv, p, win, mes); } break; case 2: default: mes->to_remove = 1; break; } return 1; } int message_check_unsend(server *srv, plugin_data *p, user_info_p user, win_info_p recv_win) { mes_info_p mes; UNUSED(srv); UNUSED(p); mes = user->mes_list.first_mes; while (mes) { if (mes->send_count == 0) { message_handle_unsend(srv, p, user, mes, recv_win); } mes = mes->next; } return 0; } enum gdc_cmd_t message_push(server *srv, plugin_data *p, user_info_p user, mes_info_p mes) { win_info_p win; size_t i; message_attach(&(user->mes_list), mes); for(i = 0; i < WINDOWS_MAX; i++) { win = user->windows[i]; if (NULL == win || NULL == win->con) { continue; } message_send_pending(srv, p, user->mes_list.first_mes, win); } if (0 == mes->send_count) { message_handle_unsend(srv, p, user, mes, NULL); } return cmdr_ok; } int message_grp_push(server *srv, plugin_data *p, grp_info_p grp, mes_info_p mes) { win_node_p node = grp->first_node; message_attach(&(grp->mes_list), mes); while(node) { if (node->win->con) { message_send_pending(srv, p, grp->mes_list.first_mes, node->win); window_flush(srv, p, node->win); } node = node->next; } return 0; } mod_fdajax-0.9/src/mod_fdajax_info.c0000640000175000017500000002460110650656570016163 0ustar greggreg#include "mod_fdajax_defs.h" char *tv2s(struct timeval atv); int print_user(buffer *b, user_info_p user) { win_info_p win; int first; size_t i, j, k; BUFFER_APPEND_STRING_CONST(b, ""); buffer_append_long(b, user->user_id); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, "IP address: "); buffer_append_string(b, inet_ntoa(user->ipaddr)); BUFFER_APPEND_STRING_CONST(b, "  Created at: "); buffer_append_string(b, tv2s(user->created_at)); BUFFER_APPEND_STRING_CONST(b, "
Peers: "); first = TRUE; for(i = 0; i < PEERS_MAX; i++) { if (user->peers[i] != 0) { first = FALSE; buffer_append_long(b, user->peers[i]); BUFFER_APPEND_STRING_CONST(b, " "); } } if (first) { BUFFER_APPEND_STRING_CONST(b, "Empty"); } BUFFER_APPEND_STRING_CONST(b, "  To peer: "); buffer_append_long(b, user->send_peer_count); BUFFER_APPEND_STRING_CONST(b, "  Total recv: "); buffer_append_long(b, user->send_count); BUFFER_APPEND_STRING_CONST(b, "" "\n"); for(i = 0; i < WINDOWS_MAX; i++) { win = user->windows[i]; if (NULL == win) { continue; } BUFFER_APPEND_STRING_CONST(b, ""); } BUFFER_APPEND_STRING_CONST(b, "
Win IDModePortEventsCountAlert
"); buffer_append_long(b, win->win_id); BUFFER_APPEND_STRING_CONST(b, ""); switch (win->win_type) { case fda_win_chunked: BUFFER_APPEND_STRING_CONST(b, "chunked"); break; case fda_win_stream: BUFFER_APPEND_STRING_CONST(b, "stream"); } BUFFER_APPEND_STRING_CONST(b, ""); if (win->con) { buffer_append_long(b, ntohs(win->con->dst_addr.ipv4.sin_port)); } else { BUFFER_APPEND_STRING_CONST(b, " "); } BUFFER_APPEND_STRING_CONST(b, ""); first = TRUE; for (k = 0; k < FDA_TYPES_MAX; k++) { if (win->ev.types & g_ev_mask_by_index[k]) { if (first) { first = FALSE; } else { BUFFER_APPEND_STRING_CONST(b, " | "); } buffer_append_string(b, g_ev_name_by_index[k]); BUFFER_APPEND_STRING_CONST(b, " "); for (j = 0; j < win->ev.ids_len[k]; j++) { buffer_append_long(b, win->ev.ids[k][j]); BUFFER_APPEND_STRING_CONST(b, " "); } } } BUFFER_APPEND_STRING_CONST(b, ""); buffer_append_long(b, win->send_count); BUFFER_APPEND_STRING_CONST(b, ""); buffer_append_long(b, win->last_alert); BUFFER_APPEND_STRING_CONST(b, "
"); return 0; } int mod_fdajax_info(server *srv, plugin_data *p, connection *con) { user_info_p user; size_t i; buffer *b; b = chunkqueue_get_append_buffer(con->write_queue); BUFFER_COPY_STRING_CONST(b, "\n" "\n" "\n" "\n" "FdAjax Module Status\n"); BUFFER_APPEND_STRING_CONST(b, "\n"); BUFFER_APPEND_STRING_CONST(b, "\n" "\n"); BUFFER_APPEND_STRING_CONST(b, "
"); BUFFER_APPEND_STRING_CONST(b, "

Full-duplex Ajax Module Version 0.9

"); BUFFER_APPEND_STRING_CONST(b, "

Configuration

"); BUFFER_APPEND_STRING_CONST(b, "\n"); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, ""); BUFFER_APPEND_STRING_CONST(b, "
ParameterValue
mes_live_max (ms)"); buffer_append_long(b, p->mes_live_max / 1000); BUFFER_APPEND_STRING_CONST(b, "
win_timeout (ms)"); buffer_append_long(b, p->win_timeout / 1000); BUFFER_APPEND_STRING_CONST(b, "
session_cookie"); buffer_append_string_buffer(b, p->session_cookie); BUFFER_APPEND_STRING_CONST(b, "
allow_guests"); buffer_append_string(b, p->allow_guests ? "enable" : "disable"); BUFFER_APPEND_STRING_CONST(b, "
send_redirects"); buffer_append_string(b, p->send_redirects ? "enable" : "disable"); BUFFER_APPEND_STRING_CONST(b, "
merge_messages"); buffer_append_string(b, p->merge_messages ? "enable" : "disable"); BUFFER_APPEND_STRING_CONST(b, "
log_level"); buffer_append_long(b, p->log_level); BUFFER_APPEND_STRING_CONST(b, "
log_security"); buffer_append_long(b, p->log_security); BUFFER_APPEND_STRING_CONST(b, "
js_peer_func"); buffer_append_string_buffer(b, p->js_peer_func); BUFFER_APPEND_STRING_CONST(b, "
js_grp_peer_func"); buffer_append_string_buffer(b, p->js_grp_peer_func); BUFFER_APPEND_STRING_CONST(b, "
js_logout_code"); buffer_append_string_buffer(b, p->js_logout_code); BUFFER_APPEND_STRING_CONST(b, "
js_maxwin_code"); buffer_append_string_buffer(b, p->js_maxwin_code); BUFFER_APPEND_STRING_CONST(b, "
js_nocookies"); buffer_append_string_buffer(b, p->js_nocookies_code); BUFFER_APPEND_STRING_CONST(b, "
js_notfound"); buffer_append_string_buffer(b, p->js_notfound_code); BUFFER_APPEND_STRING_CONST(b, "
js_relogin"); buffer_append_string_buffer(b, p->js_relogin_func); BUFFER_APPEND_STRING_CONST(b, "
js_redirect"); buffer_append_string_buffer(b, p->js_redirect_func); BUFFER_APPEND_STRING_CONST(b, "
js_alert_id_func"); buffer_append_string_buffer(b, p->js_alert_id_func); BUFFER_APPEND_STRING_CONST(b, "
js_no_guests"); buffer_append_string_buffer(b, p->js_no_guests); BUFFER_APPEND_STRING_CONST(b, "
js_ping_code"); buffer_append_string_buffer(b, p->js_ping_code); BUFFER_APPEND_STRING_CONST(b, "
send_pings"); buffer_append_long(b, p->send_pings); BUFFER_APPEND_STRING_CONST(b, "
unw_prefix"); buffer_append_string_buffer(b, p->unw_prefix); BUFFER_APPEND_STRING_CONST(b, "
allow_peer_call"); for (i = 0; i < FDA_TYPES_MAX; i++) { if (p->allow_peer_call_mask & g_ev_mask_by_index[i]) { buffer_append_string(b, g_ev_name_by_index[i]); BUFFER_APPEND_STRING_CONST(b, " "); } } BUFFER_APPEND_STRING_CONST(b, "
check_user_ip"); buffer_append_string(b, p->check_user_ip ? "enable" : "disable"); BUFFER_APPEND_STRING_CONST(b, "
admin_password"); buffer_append_string(b, p->admin_password->used > 0 ? "set" : "not set"); BUFFER_APPEND_STRING_CONST(b, "
admin_ips"); for (i = 0; i < p->admin_allowed_used; i++) { buffer_append_string(b, inet_ntoa(p->admin_allowed_ips[i])); BUFFER_APPEND_STRING_CONST(b, " "); } BUFFER_APPEND_STRING_CONST(b, "
"); BUFFER_APPEND_STRING_CONST(b, "

Logged Users

"); BUFFER_APPEND_STRING_CONST(b, "\n"); for (user = p->users_by_sess; user != NULL; user = user->hh_sess.next) { print_user(b, user); } BUFFER_APPEND_STRING_CONST(b, "
User IDData
"); BUFFER_APPEND_STRING_CONST(b, "

Copyright © 2007 GDC / Refwell" " | Blog

"); BUFFER_APPEND_STRING_CONST(b, "
"); BUFFER_APPEND_STRING_CONST(b, "
"); BUFFER_APPEND_STRING_CONST(b, "
\n"); response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); return 0; } mod_fdajax-0.9/AUTHORS0000644000175000017500000000004410650177506013165 0ustar greggregGrzegorz Daniluk mod_fdajax-0.9/INSTALL0000644000175000017500000000211110652360163013136 0ustar greggregFdAjax module version 0.9, Thu, Jul 22, 2007 FdAjax short compilation and installation doc (http://www.refwell.com/blog). 1. Download and unpack Lighttpd 1.4.15 sources (http://www.lighttpd.net/download/). 2. Copy FdAjax source files to Lighttpd src directory. 3. Run ./configure 3a. You can enable other configure options, e.g. --with-openssl 4. Run make 5. Run ./configure --enable-maintainer-mode 6. Add the following lines to src/Makefile.am file (http://trac.lighttpd.net/trac/wiki/HowToWriteALighttpdPlugin). lib_LTLIBRARIES += mod_fdajax.la mod_fdajax_la_SOURCES = mod_fdajax.c mod_fdajax_parser.c mod_fdajax_peercall.c mod_fdajax_info.c mod_fdajax_users.c mod_fdajax_alerts.c mod_fdajax_chat.c mod_fdajax_messages.c mod_fdajax_windows.c mod_fdajax_groups.c mod_fdajax_events.c mod_fdajax_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined mod_fdajax_la_LIBADD = $(common_libadd) 7. Run make 7a. Make sure that new Makefile files were generated. In case of problems with compilation download and install latest automake and autoconf packages. 8. Run make install mod_fdajax-0.9/COPYING0000644000175000017500000000274210650377013013152 0ustar greggregCopyright (c) 2007, Grzegorz Daniluk, GD Consulting All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the GD Consulting nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mod_fdajax-0.9/examples/0000755000175000017500000000000010652360363013732 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/0000755000175000017500000000000010652360363016303 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/0000755000175000017500000000000010652360363020077 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/doc/0000755000175000017500000000000010652360363020644 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/doc/README_FOR_APP0000644000175000017500000000027410650177505022737 0ustar greggregUse this README file to introduce your application and point to useful places in the API for learning more. Run "rake appdoc" to generate API documentation for your models and controllers.mod_fdajax-0.9/examples/rubyonrails/minichat/README0000644000175000017500000001750110650177506020766 0ustar greggreg== Welcome to Rails Rails is a web-application and persistence framework that includes everything needed to create database-backed web-applications according to the Model-View-Control pattern of separation. This pattern splits the view (also called the presentation) into "dumb" templates that are primarily responsible for inserting pre-built data in between HTML tags. The model contains the "smart" domain objects (such as Account, Product, Person, Post) that holds all the business logic and knows how to persist themselves to a database. The controller handles the incoming requests (such as Save New Account, Update Product, Show Post) by manipulating the model and directing data to the view. In Rails, the model is handled by what's called an object-relational mapping layer entitled Active Record. This layer allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in link:files/vendor/rails/activerecord/README.html. The controller and view are handled by the Action Pack, which handles both layers by its two parts: Action View and Action Controller. These two layers are bundled in a single package due to their heavy interdependence. This is unlike the relationship between the Active Record and Action Pack that is much more separate. Each of these packages can be used independently outside of Rails. You can read more about Action Pack in link:files/vendor/rails/actionpack/README.html. == Getting started 1. At the command prompt, start a new rails application using the rails command and your application name. Ex: rails myapp (If you've downloaded rails in a complete tgz or zip, this step is already done) 2. Change directory into myapp and start the web server: script/server (run with --help for options) 3. Go to http://localhost:3000/ and get "Welcome aboard: You’re riding the Rails!" 4. Follow the guidelines to start developing your application == Web Servers By default, Rails will try to use Mongrel and lighttpd if they are installed, otherwise Rails will use the WEBrick, the webserver that ships with Ruby. When you run script/server, Rails will check if Mongrel exists, then lighttpd and finally fall back to WEBrick. This ensures that you can always get up and running quickly. Mongrel is a Ruby-based webserver with a C-component (which requires compilation) that is suitable for development and deployment of Rails applications. If you have Ruby Gems installed, getting up and running with mongrel is as easy as: gem install mongrel. More info at: http://mongrel.rubyforge.org If Mongrel is not installed, Rails will look for lighttpd. It's considerably faster than Mongrel and WEBrick and also suited for production use, but requires additional installation and currently only works well on OS X/Unix (Windows users are encouraged to start with Mongrel). We recommend version 1.4.11 and higher. You can download it from http://www.lighttpd.net. And finally, if neither Mongrel or lighttpd are installed, Rails will use the built-in Ruby web server, WEBrick. WEBrick is a small Ruby web server suitable for development, but not for production. But of course its also possible to run Rails on any platform that supports FCGI. Apache, LiteSpeed, IIS are just a few. For more information on FCGI, please visit: http://wiki.rubyonrails.com/rails/pages/FastCGI == Debugging Rails Have "tail -f" commands running on the server.log and development.log. Rails will automatically display debugging and runtime information to these files. Debugging info will also be shown in the browser on requests from 127.0.0.1. == Breakpoints Breakpoint support is available through the script/breakpointer client. This means that you can break out of execution at any point in the code, investigate and change the model, AND then resume execution! Example: class WeblogController < ActionController::Base def index @posts = Post.find(:all) breakpoint "Breaking out from the list" end end So the controller will accept the action, run the first line, then present you with a IRB prompt in the breakpointer window. Here you can do things like: Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint' >> @posts.inspect => "[#nil, \"body\"=>nil, \"id\"=>\"1\"}>, #\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]" >> @posts.first.title = "hello from a breakpoint" => "hello from a breakpoint" ...and even better is that you can examine how your runtime objects actually work: >> f = @posts.first => #nil, "body"=>nil, "id"=>"1"}> >> f. Display all 152 possibilities? (y or n) Finally, when you're ready to resume execution, you press CTRL-D == Console You can interact with the domain model by starting the console through script/console. Here you'll have all parts of the application configured, just like it is when the application is running. You can inspect domain models, change values, and save to the database. Starting the script without arguments will launch it in the development environment. Passing an argument will specify a different environment, like script/console production. To reload your controllers and models after launching the console run reload! To reload your controllers and models after launching the console run reload! == Description of contents app Holds all the code that's specific to this particular application. app/controllers Holds controllers that should be named like weblogs_controller.rb for automated URL mapping. All controllers should descend from ApplicationController which itself descends from ActionController::Base. app/models Holds models that should be named like post.rb. Most models will descend from ActiveRecord::Base. app/views Holds the template files for the view that should be named like weblogs/index.rhtml for the WeblogsController#index action. All views use eRuby syntax. app/views/layouts Holds the template files for layouts to be used with views. This models the common header/footer method of wrapping views. In your views, define a layout using the layout :default and create a file named default.rhtml. Inside default.rhtml, call <% yield %> to render the view using this layout. app/helpers Holds view helpers that should be named like weblogs_helper.rb. These are generated for you automatically when using script/generate for controllers. Helpers can be used to wrap functionality for your views into methods. config Configuration files for the Rails environment, the routing map, the database, and other dependencies. components Self-contained mini-applications that can bundle together controllers, models, and views. db Contains the database schema in schema.rb. db/migrate contains all the sequence of Migrations for your schema. doc This directory is where your application documentation will be stored when generated using rake doc:app lib Application specific libraries. Basically, any kind of custom code that doesn't belong under controllers, models, or helpers. This directory is in the load path. public The directory available for the web server. Contains subdirectories for images, stylesheets, and javascripts. Also contains the dispatchers and the default HTML files. This should be set as the DOCUMENT_ROOT of your web server. script Helper scripts for automation and generation. test Unit and functional tests along with fixtures. When using the script/generate scripts, template test files will be generated for you and placed in this directory. vendor External libraries that the application depends on. Also includes the plugins subdirectory. This directory is in the load path. mod_fdajax-0.9/examples/rubyonrails/minichat/log/0000755000175000017500000000000010652360363020660 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/config/0000755000175000017500000000000010652360363021344 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/config/database.yml0000644000175000017500000000164110650177505023637 0ustar greggreg# MySQL (default setup). Versions 4.1 and 5.0 are recommended. # # Install the MySQL driver: # gem install mysql # On MacOS X: # gem install mysql -- --include=/usr/local/lib # On Windows: # gem install mysql # Choose the win32 build. # Install MySQL and put its /bin directory on your path. # # And be sure to use new-style password hashing: # http://dev.mysql.com/doc/refman/5.0/en/old-client.html development: adapter: mysql database: minichat_development username: root password: host: localhost # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. test: adapter: mysql database: minichat_test username: root password: host: localhost production: adapter: mysql database: minichat_production username: root password: host: localhost mod_fdajax-0.9/examples/rubyonrails/minichat/config/lighttpd.conf0000644000175000017500000000635510650177505024045 0ustar greggreg# Default configuration file for the lighttpd web server # Start using ./script/server lighttpd server.bind = "0.0.0.0" server.port = 3000 server.modules = ( "mod_rewrite", "mod_accesslog", "mod_fdajax", "mod_fastcgi", "mod_compress", "mod_expire" ) server.error-handler-404 = "/dispatch.fcgi" server.pid-file = CWD + "/tmp/pids/lighttpd.pid" server.document-root = CWD + "/public/" server.errorlog = CWD + "/log/lighttpd.error.log" accesslog.filename = CWD + "/log/lighttpd.access.log" url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" ) compress.filetype = ( "text/plain", "text/html", "text/css", "text/javascript" ) compress.cache-dir = CWD + "/tmp/cache" expire.url = ( "/favicon.ico" => "access 3 days", "/images/" => "access 3 days", "/stylesheets/" => "access 3 days", "/javascripts/" => "access 3 days" ) # Change *-procs to 2 if you need to use Upload Progress or other tasks that # *need* to execute a second request while the first is still pending. fastcgi.server = ( ".fcgi" => ( "localhost" => ( "min-procs" => 1, "max-procs" => 1, "socket" => CWD + "/tmp/sockets/fcgi.socket", "bin-path" => CWD + "/public/dispatch.fcgi", "bin-environment" => ( "RAILS_ENV" => "development" ) ) ) ) mimetype.assign = ( ".css" => "text/css", ".gif" => "image/gif", ".htm" => "text/html", ".html" => "text/html", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".js" => "text/javascript", ".png" => "image/png", ".swf" => "application/x-shockwave-flash", ".txt" => "text/plain" ) # Making sure file uploads above 64k always work when using IE or Safari # For more information, see http://trac.lighttpd.net/trac/ticket/360 $HTTP["useragent"] =~ "^(.*MSIE.*)|(.*AppleWebKit.*)$" { server.max-keep-alive-requests = 0 } # Full-Duplex Ajax module configuration fdajax.ext = "fdajax" fdajax.admin_ips = ( "127.0.0.1", "192.168.0.110" ) fdajax.allow_peer_call = ( "chat", "gchat" ) fdajax.allow_guests = "enable" fdajax.mes_live_max = 5000 fdajax.win_timeout = 5000 fdajax.log_level = 3 fdajax.log_security = 3 fdajax.send_pings = 0 fdajax.js_no_guests = "fdajax.no_guests();" fdajax.js_peer_func = "fdajax.peer_call" fdajax.js_grp_peer_func = "fdajax.grp_peer_call" fdajax.js_logout_code = "fdajax.stoploop();" fdajax.js_maxwin_code = "fdajax.maxwin();" fdajax.js_nocookies = "fdajax.nocookies();" fdajax.js_ping_code = "fdajax.ping();" fdajax.js_notfound = "fdajax.notfound();" fdajax.js_relogin = "fdajax.relogin" fdajax.js_redirect = "fdajax.redirect" fdajax.js_alert_id_func = "unw.set_alert_id" fdajax.unw_prefix = "unw." fdajax.session_cookie = "_minichat_session_id" fdajax.merge_messages = "enable" fdajax.check_user_ip = "enable" fdajax.send_redirects = "enable" fdajax.html_begin = "FdAjax Stream" mod_fdajax-0.9/examples/rubyonrails/minichat/config/boot.rb0000644000175000017500000000301510650177505022635 0ustar greggreg# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb unless defined?(RAILS_ROOT) root_path = File.join(File.dirname(__FILE__), '..') unless RUBY_PLATFORM =~ /(:?mswin|mingw)/ require 'pathname' root_path = Pathname.new(root_path).cleanpath(true).to_s end RAILS_ROOT = root_path end unless defined?(Rails::Initializer) if File.directory?("#{RAILS_ROOT}/vendor/rails") require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" else require 'rubygems' environment_without_comments = IO.readlines(File.dirname(__FILE__) + '/environment.rb').reject { |l| l =~ /^#/ }.join environment_without_comments =~ /[^#]RAILS_GEM_VERSION = '([\d.]+)'/ rails_gem_version = $1 if version = defined?(RAILS_GEM_VERSION) ? RAILS_GEM_VERSION : rails_gem_version # Asking for 1.1.6 will give you 1.1.6.5206, if available -- makes it easier to use beta gems rails_gem = Gem.cache.search('rails', "~>#{version}.0").sort_by { |g| g.version.version }.last if rails_gem gem "rails", "=#{rails_gem.version.version}" require rails_gem.full_gem_path + '/lib/initializer' else STDERR.puts %(Cannot find gem for Rails ~>#{version}.0: Install the missing gem with 'gem install -v=#{version} rails', or change environment.rb to define RAILS_GEM_VERSION with your desired version. ) exit 1 end else gem "rails" require 'initializer' end end Rails::Initializer.run(:set_load_path) end mod_fdajax-0.9/examples/rubyonrails/minichat/config/routes.rb0000644000175000017500000000171210650177505023215 0ustar greggregActionController::Routing::Routes.draw do |map| # The priority is based upon order of creation: first created -> highest priority. # Sample of regular route: # map.connect 'products/:id', :controller => 'catalog', :action => 'view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' # This route can be invoked with purchase_url(:id => product.id) # You can have the root of your site routed by hooking up '' # -- just remember to delete public/index.html. # map.connect '', :controller => "welcome" # Allow downloading Web Service WSDL as a file with an extension # instead of a file named 'wsdl' map.connect ':controller/service.wsdl', :action => 'wsdl' # Install the default route as the lowest priority. map.connect ':controller/:action/:id.:format' map.connect ':controller/:action/:id' end mod_fdajax-0.9/examples/rubyonrails/minichat/config/environment.rb0000644000175000017500000000456210650177505024246 0ustar greggreg# Be sure to restart your web server when you modify this file. # Uncomment below to force Rails into production mode when # you don't control web/app server and can't set it the proper way # ENV['RAILS_ENV'] ||= 'production' # Specifies gem version of Rails to use when vendor/rails is not present RAILS_GEM_VERSION = '1.2.1' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') Rails::Initializer.run do |config| # Settings in config/environments/* take precedence over those specified here # Skip frameworks you're not going to use (only works if using vendor/rails) # config.frameworks -= [ :action_web_service, :action_mailer ] # Only load the plugins named here, by default all plugins in vendor/plugins are loaded # config.plugins = %W( exception_notification ssl_requirement ) # Add additional load paths for your own custom dirs # config.load_paths += %W( #{RAILS_ROOT}/extras ) # Force all environments to use the same logger level # (by default production uses :info, the others :debug) # config.log_level = :debug # Use the database for sessions instead of the file system # (create the session table with 'rake db:sessions:create') # config.action_controller.session_store = :active_record_store # Use SQL instead of Active Record's schema dumper when creating the test database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql # Activate observers that should always be running # config.active_record.observers = :cacher, :garbage_collector # Make Active Record use UTC-base instead of local time # config.active_record.default_timezone = :utc # See Rails::Configuration for more options end # Add new inflection rules using the following format # (all these examples are active by default): # Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register "application/x-mobile", :mobile # Include your application configuration belowmod_fdajax-0.9/examples/rubyonrails/minichat/config/environments/0000755000175000017500000000000010652360363024073 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/config/environments/development.rb0000644000175000017500000000161610650177505026750 0ustar greggreg# Settings specified here will take precedence over those in config/environment.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Enable the breakpoint server that script/breakpointer connects to config.breakpoint_server = true # Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_controller.perform_caching = false config.action_view.cache_template_extensions = false config.action_view.debug_rjs = true # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false mod_fdajax-0.9/examples/rubyonrails/minichat/config/environments/test.rb0000644000175000017500000000152510650177505025404 0ustar greggreg# Settings specified here will take precedence over those in config/environment.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_controller.perform_caching = false # Tell ActionMailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :testmod_fdajax-0.9/examples/rubyonrails/minichat/config/environments/production.rb0000644000175000017500000000137310650177505026614 0ustar greggreg# Settings specified here will take precedence over those in config/environment.rb # The production environment is meant for finished, "live" apps. # Code is not reloaded between requests config.cache_classes = true # Use a different logger for distributed setups # config.logger = SyslogLogger.new # Full error reports are disabled and caching is turned on config.action_controller.consider_all_requests_local = false config.action_controller.perform_caching = true # Enable serving of images, stylesheets, and javascripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false mod_fdajax-0.9/examples/rubyonrails/minichat/public/0000755000175000017500000000000010652360363021355 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/public/404.html0000644000175000017500000000166310650177506022563 0ustar greggreg The page you were looking for doesn't exist (404)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

mod_fdajax-0.9/examples/rubyonrails/minichat/public/dispatch.fcgi0000755000175000017500000000153510650177506024020 0ustar greggreg#!/usr/local/bin/ruby # # You may specify the path to the FastCGI crash log (a log of unhandled # exceptions which forced the FastCGI instance to exit, great for debugging) # and the number of requests to process before running garbage collection. # # By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log # and the GC period is nil (turned off). A reasonable number of requests # could range from 10-100 depending on the memory footprint of your app. # # Example: # # Default log path, normal GC behavior. # RailsFCGIHandler.process! # # # Default log path, 50 requests between GC. # RailsFCGIHandler.process! nil, 50 # # # Custom log path, normal GC behavior. # RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' # require File.dirname(__FILE__) + "/../config/environment" require 'fcgi_handler' RailsFCGIHandler.process! mod_fdajax-0.9/examples/rubyonrails/minichat/public/500.html0000644000175000017500000000165510650177506022561 0ustar greggreg We're sorry, but something went wrong

We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.

mod_fdajax-0.9/examples/rubyonrails/minichat/public/index.html0000644000175000017500000000064610650177506023363 0ustar greggreg Minichat FdAjax example

Minichat FdAjax example

Create users
Minichat
mod_fdajax-0.9/examples/rubyonrails/minichat/public/images/0000755000175000017500000000000010652360363022622 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/public/images/rails.png0000644000175000017500000000337310650177505024452 0ustar greggreg‰PNG  IHDR2@o ÔIgAMAÖØÔOX2tEXtSoftwareAdobe ImageReadyqÉe<ÀPLTE¸I8éͰ·w|"¦%Ï•ŠµUH˜"óåÛ°¦¥ÿÿÿ’'+‹6BÈtjÚ¤‘µ;4® (Ы¤‰ÃiH°*,õëã¶zxÉ|VìÕ¾ûõñøïéÞ¶­¿QOסr”GH²2/ÎaêÌÆ¤<5ºFC².7ÅrLìÙÔßµ“û÷õ©Äf]ªI=ïÜÉòàÓ¤\XåÄ¡¿aD¿[U½X>æÃºþýüœ00®%,ýú÷ÚñeiûøúŸPKùóðÅae†"­ ™/pÁIDATxÚ”×[c¢J `®–«xEEDETª¢`=¥ðÿÿÕIf@©û´ypw-_33„„(¥Ûៈ…@éPt]UU]7?üŽU'ð_¹.I’* T CÕ•¬¿aÑçqæ‘eøÙ?+‚åÙ¶$ _L@õ Ùy3ú­d-5Ï›þ€‘OWâ$W” ¢?ÂØ,M.G%ÀoAƒ¤@R©<$a$;–ËåéNc”›Ñܜßý~–‚+"6d¥(°0$ç !!¥%ó´Õ´©–öbÒ®WVÆ ]y‘sD¶Ó §ôZl\}X#í²ž¶½!ñ–¾ÅÔ1`eO’+¿²ôû¦¦íÞ M x’CKNâñ)>Ÿ ›¦iªM(½ÉAÁ‰»R8Îf?ƒ{göNqÜKïpÝ6ž/e²”ÍðF ÏâêJK®4Y÷z :ÓðšÆsS&Úøl\ Ìâ>“(¡Ó/G$ÌœN£àâÓãÜ4eyÙÏ!@òL¢39Mg³ãxÌ  ž!II@ˆ AàŽf 94Â*¤dO‚^І#¾Ã–†Œúga…„pdYgE’˜ƒã‘@±Œ$Ù|>'KHƒ¤‚ëñj/ð Æ@KÓí­ÞÉâiæs(=XÚHn6DáaØÖq qs}ø ±Çˆ´A•ªà!Û<©ÍÉ G©‘ØE ÁÏ€X< #nKÏ+¢A9mLšŽñr‰ýÌ’›»/mØ‘CËé´Aš™Hö3$%fK[=Im:3Ï›•÷IY¢40H”¼ˆ7‡ºYnAS[ºs “Þï» 7ƒã>íY¯<ÒÓ°s]ØMB ^} J÷vßíX¢é5ð邏Ɗ!Í™Q¢Qº7°Ðo,Q9˜Ià_º»!ñ|ÔŽK ¾ò§MÊ;©áHŠ¢s§ù¦Y˜(JÖËåN[‰nFå€ÑÛ|W¬,ˆ@~=²€î?µçy]“ì—¯,"+ì>ç·É>òì_H€(-YA[›M~õ†É~ëÏX=Ñê²%®.–ñÖOö!FÅ ÙÖòE`V@ç—ëÍ(¯Eöª²!8]rA߈\{û‹4Æ+Öà³'Q­¬|#&ÔiÀ‚çHCÔÃçJÏÛ +:¦Sgtf•,ÉŽóñMÞÛ©f½ ÇÔyÃIà@äò;Ù]v‡“á$„ö‹r¢øŽ#«Ã÷…Q‚[i…£3ƒ^Tá|‰ˆ,Õ¡öNLCÞÏÚD´jlÁøˆ‰ì¦($ùë„°½©ÁWg1ÝNG"Vt.;Ó÷tÄ!+¿@È`ºZëõÚmHU‰>>þJC.D6f ÁCâ äÃÙþž\W¶}Lâ­›P;dD–¯îêÊÌ6ííF¿sr²Å^Bì†T'xúbññ׋AšØí£¿^³bî<47aEêY¸ »~ö þ˜I/‚׋ÐÐÙ(aHÊsõ aÀ÷-Ñó\Ï+lèI÷ºH$©ú³‚¡c5[IÖxpž*µDßbCÝ>;¹à_·—¤ú†žœDÚ€õËšhðõÔH^ä?^ºQ²ðºÏÅOxt£•$³æÖvHICÙ§ô'k®rHïßâç Þ;N “È?û=Ì@ö¦ÄÉÐ]1r§{h黆,^äêû8i;dëC·˜!!µ ¤BRµ$â…$']‚[‘k$å ì‡§r ÃM‹.î¸6¦ò½£N4›­á°#ËRwˆóEËK‚Ä~uÉ b6És§¡ÍÞ`E·uX柒N¢$£…‡EÂwÆyúûR+FªÏÏ…¸xüDµ÷x¬ÔÃã‘ë«Çã€Áúƒ [÷[_%òBKj(;WÕñíT‡O,#yÁêëM¿Ø+\c$[m‚_؉öpÅ!åS¬I£v£âÁóèì+¸pH©°ø—ÿˆ ñMø Þ¶3ÕeIEND®B`‚mod_fdajax-0.9/examples/rubyonrails/minichat/public/favicon.ico0000644000175000017500000000000010650177506023467 0ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/public/.htaccess0000644000175000017500000000234210650177506023157 0ustar greggreg# General Apache options AddHandler fastcgi-script .fcgi AddHandler cgi-script .cgi Options +FollowSymLinks +ExecCGI # If you don't want Rails to look in certain directories, # use the following rewrite rules so that Apache won't rewrite certain requests # # Example: # RewriteCond %{REQUEST_URI} ^/notrails.* # RewriteRule .* - [L] # Redirect all requests not available on the filesystem to Rails # By default the cgi dispatcher is used which is very slow # # For better performance replace the dispatcher with the fastcgi one # # Example: # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] RewriteEngine On # If your Rails application is accessed via an Alias directive, # then you MUST also set the RewriteBase in this htaccess file. # # Example: # Alias /myrailsapp /path/to/myrailsapp/public # RewriteBase /myrailsapp RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.cgi [QSA,L] # In case Rails experiences terminal errors # Instead of displaying this message you can supply a file here which will be rendered instead # # Example: # ErrorDocument 500 /500.html ErrorDocument 500 "

Application error

Rails application failed to start properly"mod_fdajax-0.9/examples/rubyonrails/minichat/public/robots.txt0000644000175000017500000000014310650177506023427 0ustar greggreg# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt filemod_fdajax-0.9/examples/rubyonrails/minichat/public/stylesheets/0000755000175000017500000000000010652360363023731 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/public/stylesheets/screen.css0000644000175000017500000000062610650177506025731 0ustar greggreg #chat { margin: 2em; } #chat_output { overflow: auto; width: 50em; height: 15em; border: 1px solid #999; margin: 1em 0 1em 0; padding-left: 0px;} #chat input#message { list-style: none; width: 45em; margin: 0px; } .chat_message { list-style: none; clear: both; padding: 1px; margin: 1px; background-color: #f5f5f5; } .chat_message span { float: left; width: 8em; text-align: right; margin-right: 0.5em; } mod_fdajax-0.9/examples/rubyonrails/minichat/public/stylesheets/scaffold.css0000644000175000017500000000220010650177506026221 0ustar greggregbody { background-color: #fff; color: #333; } body, p, ol, ul, td { font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 18px; } pre { background-color: #eee; padding: 10px; font-size: 11px; } a { color: #000; } a:visited { color: #666; } a:hover { color: #fff; background-color:#000; } .fieldWithErrors { padding: 2px; background-color: red; display: table; } #errorExplanation { width: 400px; border: 2px solid red; padding: 7px; padding-bottom: 12px; margin-bottom: 20px; background-color: #f0f0f0; } #errorExplanation h2 { text-align: left; font-weight: bold; padding: 5px 5px 5px 15px; font-size: 12px; margin: -7px; background-color: #c00; color: #fff; } #errorExplanation p { color: #333; margin-bottom: 0; padding: 5px; } #errorExplanation ul li { font-size: 12px; list-style: square; } div.uploadStatus { margin: 5px; } div.progressBar { margin: 5px; } div.progressBar div.border { background-color: #fff; border: 1px solid grey; width: 100%; } div.progressBar div.background { background-color: #333; height: 18px; width: 0%; } mod_fdajax-0.9/examples/rubyonrails/minichat/public/dispatch.cgi0000755000175000017500000000073710650177506023655 0ustar greggreg#!/usr/local/bin/ruby require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired require "dispatcher" ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) Dispatcher.dispatchmod_fdajax-0.9/examples/rubyonrails/minichat/public/dispatch.rb0000755000175000017500000000073710650177506023516 0ustar greggreg#!/usr/local/bin/ruby require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired require "dispatcher" ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) Dispatcher.dispatchmod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/0000755000175000017500000000000010652360363023706 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/dragdrop.js0000644000175000017500000007352610650177506026066 0ustar greggreg// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ if(typeof Effect == 'undefined') throw("dragdrop.js requires including script.aculo.us' effects.js library"); var Droppables = { drops: [], remove: function(element) { this.drops = this.drops.reject(function(d) { return d.element==$(element) }); }, add: function(element) { element = $(element); var options = Object.extend({ greedy: true, hoverclass: null, tree: false }, arguments[1] || {}); // cache containers if(options.containment) { options._containers = []; var containment = options.containment; if((typeof containment == 'object') && (containment.constructor == Array)) { containment.each( function(c) { options._containers.push($(c)) }); } else { options._containers.push($(containment)); } } if(options.accept) options.accept = [options.accept].flatten(); Element.makePositioned(element); // fix IE options.element = element; this.drops.push(options); }, findDeepestChild: function(drops) { deepest = drops[0]; for (i = 1; i < drops.length; ++i) if (Element.isParent(drops[i].element, deepest.element)) deepest = drops[i]; return deepest; }, isContained: function(element, drop) { var containmentNode; if(drop.tree) { containmentNode = element.treeNode; } else { containmentNode = element.parentNode; } return drop._containers.detect(function(c) { return containmentNode == c }); }, isAffected: function(point, element, drop) { return ( (drop.element!=element) && ((!drop._containers) || this.isContained(element, drop)) && ((!drop.accept) || (Element.classNames(element).detect( function(v) { return drop.accept.include(v) } ) )) && Position.within(drop.element, point[0], point[1]) ); }, deactivate: function(drop) { if(drop.hoverclass) Element.removeClassName(drop.element, drop.hoverclass); this.last_active = null; }, activate: function(drop) { if(drop.hoverclass) Element.addClassName(drop.element, drop.hoverclass); this.last_active = drop; }, show: function(point, element) { if(!this.drops.length) return; var affected = []; if(this.last_active) this.deactivate(this.last_active); this.drops.each( function(drop) { if(Droppables.isAffected(point, element, drop)) affected.push(drop); }); if(affected.length>0) { drop = Droppables.findDeepestChild(affected); Position.within(drop.element, point[0], point[1]); if(drop.onHover) drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); Droppables.activate(drop); } }, fire: function(event, element) { if(!this.last_active) return; Position.prepare(); if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) if (this.last_active.onDrop) this.last_active.onDrop(element, this.last_active.element, event); }, reset: function() { if(this.last_active) this.deactivate(this.last_active); } } var Draggables = { drags: [], observers: [], register: function(draggable) { if(this.drags.length == 0) { this.eventMouseUp = this.endDrag.bindAsEventListener(this); this.eventMouseMove = this.updateDrag.bindAsEventListener(this); this.eventKeypress = this.keyPress.bindAsEventListener(this); Event.observe(document, "mouseup", this.eventMouseUp); Event.observe(document, "mousemove", this.eventMouseMove); Event.observe(document, "keypress", this.eventKeypress); } this.drags.push(draggable); }, unregister: function(draggable) { this.drags = this.drags.reject(function(d) { return d==draggable }); if(this.drags.length == 0) { Event.stopObserving(document, "mouseup", this.eventMouseUp); Event.stopObserving(document, "mousemove", this.eventMouseMove); Event.stopObserving(document, "keypress", this.eventKeypress); } }, activate: function(draggable) { if(draggable.options.delay) { this._timeout = setTimeout(function() { Draggables._timeout = null; window.focus(); Draggables.activeDraggable = draggable; }.bind(this), draggable.options.delay); } else { window.focus(); // allows keypress events if window isn't currently focused, fails for Safari this.activeDraggable = draggable; } }, deactivate: function() { this.activeDraggable = null; }, updateDrag: function(event) { if(!this.activeDraggable) return; var pointer = [Event.pointerX(event), Event.pointerY(event)]; // Mozilla-based browsers fire successive mousemove events with // the same coordinates, prevent needless redrawing (moz bug?) if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; this._lastPointer = pointer; this.activeDraggable.updateDrag(event, pointer); }, endDrag: function(event) { if(this._timeout) { clearTimeout(this._timeout); this._timeout = null; } if(!this.activeDraggable) return; this._lastPointer = null; this.activeDraggable.endDrag(event); this.activeDraggable = null; }, keyPress: function(event) { if(this.activeDraggable) this.activeDraggable.keyPress(event); }, addObserver: function(observer) { this.observers.push(observer); this._cacheObserverCallbacks(); }, removeObserver: function(element) { // element instead of observer fixes mem leaks this.observers = this.observers.reject( function(o) { return o.element==element }); this._cacheObserverCallbacks(); }, notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' if(this[eventName+'Count'] > 0) this.observers.each( function(o) { if(o[eventName]) o[eventName](eventName, draggable, event); }); if(draggable.options[eventName]) draggable.options[eventName](draggable, event); }, _cacheObserverCallbacks: function() { ['onStart','onEnd','onDrag'].each( function(eventName) { Draggables[eventName+'Count'] = Draggables.observers.select( function(o) { return o[eventName]; } ).length; }); } } /*--------------------------------------------------------------------------*/ var Draggable = Class.create(); Draggable._dragging = {}; Draggable.prototype = { initialize: function(element) { var defaults = { handle: false, reverteffect: function(element, top_offset, left_offset) { var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, queue: {scope:'_draggable', position:'end'} }); }, endeffect: function(element) { var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, queue: {scope:'_draggable', position:'end'}, afterFinish: function(){ Draggable._dragging[element] = false } }); }, zindex: 1000, revert: false, scroll: false, scrollSensitivity: 20, scrollSpeed: 15, snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } delay: 0 }; if(!arguments[1] || typeof arguments[1].endeffect == 'undefined') Object.extend(defaults, { starteffect: function(element) { element._opacity = Element.getOpacity(element); Draggable._dragging[element] = true; new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); } }); var options = Object.extend(defaults, arguments[1] || {}); this.element = $(element); if(options.handle && (typeof options.handle == 'string')) this.handle = this.element.down('.'+options.handle, 0); if(!this.handle) this.handle = $(options.handle); if(!this.handle) this.handle = this.element; if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { options.scroll = $(options.scroll); this._isScrollChild = Element.childOf(this.element, options.scroll); } Element.makePositioned(this.element); // fix IE this.delta = this.currentDelta(); this.options = options; this.dragging = false; this.eventMouseDown = this.initDrag.bindAsEventListener(this); Event.observe(this.handle, "mousedown", this.eventMouseDown); Draggables.register(this); }, destroy: function() { Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); Draggables.unregister(this); }, currentDelta: function() { return([ parseInt(Element.getStyle(this.element,'left') || '0'), parseInt(Element.getStyle(this.element,'top') || '0')]); }, initDrag: function(event) { if(typeof Draggable._dragging[this.element] != 'undefined' && Draggable._dragging[this.element]) return; if(Event.isLeftClick(event)) { // abort on form elements, fixes a Firefox issue var src = Event.element(event); if(src.tagName && ( src.tagName=='INPUT' || src.tagName=='SELECT' || src.tagName=='OPTION' || src.tagName=='BUTTON' || src.tagName=='TEXTAREA')) return; var pointer = [Event.pointerX(event), Event.pointerY(event)]; var pos = Position.cumulativeOffset(this.element); this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); Draggables.activate(this); Event.stop(event); } }, startDrag: function(event) { this.dragging = true; if(this.options.zindex) { this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); this.element.style.zIndex = this.options.zindex; } if(this.options.ghosting) { this._clone = this.element.cloneNode(true); Position.absolutize(this.element); this.element.parentNode.insertBefore(this._clone, this.element); } if(this.options.scroll) { if (this.options.scroll == window) { var where = this._getWindowScroll(this.options.scroll); this.originalScrollLeft = where.left; this.originalScrollTop = where.top; } else { this.originalScrollLeft = this.options.scroll.scrollLeft; this.originalScrollTop = this.options.scroll.scrollTop; } } Draggables.notify('onStart', this, event); if(this.options.starteffect) this.options.starteffect(this.element); }, updateDrag: function(event, pointer) { if(!this.dragging) this.startDrag(event); Position.prepare(); Droppables.show(pointer, this.element); Draggables.notify('onDrag', this, event); this.draw(pointer); if(this.options.change) this.options.change(this); if(this.options.scroll) { this.stopScrolling(); var p; if (this.options.scroll == window) { with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } } else { p = Position.page(this.options.scroll); p[0] += this.options.scroll.scrollLeft + Position.deltaX; p[1] += this.options.scroll.scrollTop + Position.deltaY; p.push(p[0]+this.options.scroll.offsetWidth); p.push(p[1]+this.options.scroll.offsetHeight); } var speed = [0,0]; if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); this.startScrolling(speed); } // fix AppleWebKit rendering if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); Event.stop(event); }, finishDrag: function(event, success) { this.dragging = false; if(this.options.ghosting) { Position.relativize(this.element); Element.remove(this._clone); this._clone = null; } if(success) Droppables.fire(event, this.element); Draggables.notify('onEnd', this, event); var revert = this.options.revert; if(revert && typeof revert == 'function') revert = revert(this.element); var d = this.currentDelta(); if(revert && this.options.reverteffect) { this.options.reverteffect(this.element, d[1]-this.delta[1], d[0]-this.delta[0]); } else { this.delta = d; } if(this.options.zindex) this.element.style.zIndex = this.originalZ; if(this.options.endeffect) this.options.endeffect(this.element); Draggables.deactivate(this); Droppables.reset(); }, keyPress: function(event) { if(event.keyCode!=Event.KEY_ESC) return; this.finishDrag(event, false); Event.stop(event); }, endDrag: function(event) { if(!this.dragging) return; this.stopScrolling(); this.finishDrag(event, true); Event.stop(event); }, draw: function(point) { var pos = Position.cumulativeOffset(this.element); if(this.options.ghosting) { var r = Position.realOffset(this.element); pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; } var d = this.currentDelta(); pos[0] -= d[0]; pos[1] -= d[1]; if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; } var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); if(this.options.snap) { if(typeof this.options.snap == 'function') { p = this.options.snap(p[0],p[1],this); } else { if(this.options.snap instanceof Array) { p = p.map( function(v, i) { return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) } else { p = p.map( function(v) { return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) } }} var style = this.element.style; if((!this.options.constraint) || (this.options.constraint=='horizontal')) style.left = p[0] + "px"; if((!this.options.constraint) || (this.options.constraint=='vertical')) style.top = p[1] + "px"; if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering }, stopScrolling: function() { if(this.scrollInterval) { clearInterval(this.scrollInterval); this.scrollInterval = null; Draggables._lastScrollPointer = null; } }, startScrolling: function(speed) { if(!(speed[0] || speed[1])) return; this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; this.lastScrolled = new Date(); this.scrollInterval = setInterval(this.scroll.bind(this), 10); }, scroll: function() { var current = new Date(); var delta = current - this.lastScrolled; this.lastScrolled = current; if(this.options.scroll == window) { with (this._getWindowScroll(this.options.scroll)) { if (this.scrollSpeed[0] || this.scrollSpeed[1]) { var d = delta / 1000; this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); } } } else { this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; } Position.prepare(); Droppables.show(Draggables._lastPointer, this.element); Draggables.notify('onDrag', this); if (this._isScrollChild) { Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; if (Draggables._lastScrollPointer[0] < 0) Draggables._lastScrollPointer[0] = 0; if (Draggables._lastScrollPointer[1] < 0) Draggables._lastScrollPointer[1] = 0; this.draw(Draggables._lastScrollPointer); } if(this.options.change) this.options.change(this); }, _getWindowScroll: function(w) { var T, L, W, H; with (w.document) { if (w.document.documentElement && documentElement.scrollTop) { T = documentElement.scrollTop; L = documentElement.scrollLeft; } else if (w.document.body) { T = body.scrollTop; L = body.scrollLeft; } if (w.innerWidth) { W = w.innerWidth; H = w.innerHeight; } else if (w.document.documentElement && documentElement.clientWidth) { W = documentElement.clientWidth; H = documentElement.clientHeight; } else { W = body.offsetWidth; H = body.offsetHeight } } return { top: T, left: L, width: W, height: H }; } } /*--------------------------------------------------------------------------*/ var SortableObserver = Class.create(); SortableObserver.prototype = { initialize: function(element, observer) { this.element = $(element); this.observer = observer; this.lastValue = Sortable.serialize(this.element); }, onStart: function() { this.lastValue = Sortable.serialize(this.element); }, onEnd: function() { Sortable.unmark(); if(this.lastValue != Sortable.serialize(this.element)) this.observer(this.element) } } var Sortable = { SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, sortables: {}, _findRootElement: function(element) { while (element.tagName != "BODY") { if(element.id && Sortable.sortables[element.id]) return element; element = element.parentNode; } }, options: function(element) { element = Sortable._findRootElement($(element)); if(!element) return; return Sortable.sortables[element.id]; }, destroy: function(element){ var s = Sortable.options(element); if(s) { Draggables.removeObserver(s.element); s.droppables.each(function(d){ Droppables.remove(d) }); s.draggables.invoke('destroy'); delete Sortable.sortables[s.element.id]; } }, create: function(element) { element = $(element); var options = Object.extend({ element: element, tag: 'li', // assumes li children, override with tag: 'tagname' dropOnEmpty: false, tree: false, treeTag: 'ul', overlap: 'vertical', // one of 'vertical', 'horizontal' constraint: 'vertical', // one of 'vertical', 'horizontal', false containment: element, // also takes array of elements (or id's); or false handle: false, // or a CSS class only: false, delay: 0, hoverclass: null, ghosting: false, scroll: false, scrollSensitivity: 20, scrollSpeed: 15, format: this.SERIALIZE_RULE, onChange: Prototype.emptyFunction, onUpdate: Prototype.emptyFunction }, arguments[1] || {}); // clear any old sortable with same element this.destroy(element); // build options for the draggables var options_for_draggable = { revert: true, scroll: options.scroll, scrollSpeed: options.scrollSpeed, scrollSensitivity: options.scrollSensitivity, delay: options.delay, ghosting: options.ghosting, constraint: options.constraint, handle: options.handle }; if(options.starteffect) options_for_draggable.starteffect = options.starteffect; if(options.reverteffect) options_for_draggable.reverteffect = options.reverteffect; else if(options.ghosting) options_for_draggable.reverteffect = function(element) { element.style.top = 0; element.style.left = 0; }; if(options.endeffect) options_for_draggable.endeffect = options.endeffect; if(options.zindex) options_for_draggable.zindex = options.zindex; // build options for the droppables var options_for_droppable = { overlap: options.overlap, containment: options.containment, tree: options.tree, hoverclass: options.hoverclass, onHover: Sortable.onHover } var options_for_tree = { onHover: Sortable.onEmptyHover, overlap: options.overlap, containment: options.containment, hoverclass: options.hoverclass } // fix for gecko engine Element.cleanWhitespace(element); options.draggables = []; options.droppables = []; // drop on empty handling if(options.dropOnEmpty || options.tree) { Droppables.add(element, options_for_tree); options.droppables.push(element); } (this.findElements(element, options) || []).each( function(e) { // handles are per-draggable var handle = options.handle ? $(e).down('.'+options.handle,0) : e; options.draggables.push( new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); Droppables.add(e, options_for_droppable); if(options.tree) e.treeNode = element; options.droppables.push(e); }); if(options.tree) { (Sortable.findTreeElements(element, options) || []).each( function(e) { Droppables.add(e, options_for_tree); e.treeNode = element; options.droppables.push(e); }); } // keep reference this.sortables[element.id] = options; // for onupdate Draggables.addObserver(new SortableObserver(element, options.onUpdate)); }, // return all suitable-for-sortable elements in a guaranteed order findElements: function(element, options) { return Element.findChildren( element, options.only, options.tree ? true : false, options.tag); }, findTreeElements: function(element, options) { return Element.findChildren( element, options.only, options.tree ? true : false, options.treeTag); }, onHover: function(element, dropon, overlap) { if(Element.isParent(dropon, element)) return; if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { return; } else if(overlap>0.5) { Sortable.mark(dropon, 'before'); if(dropon.previousSibling != element) { var oldParentNode = element.parentNode; element.style.visibility = "hidden"; // fix gecko rendering dropon.parentNode.insertBefore(element, dropon); if(dropon.parentNode!=oldParentNode) Sortable.options(oldParentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element); } } else { Sortable.mark(dropon, 'after'); var nextElement = dropon.nextSibling || null; if(nextElement != element) { var oldParentNode = element.parentNode; element.style.visibility = "hidden"; // fix gecko rendering dropon.parentNode.insertBefore(element, nextElement); if(dropon.parentNode!=oldParentNode) Sortable.options(oldParentNode).onChange(element); Sortable.options(dropon.parentNode).onChange(element); } } }, onEmptyHover: function(element, dropon, overlap) { var oldParentNode = element.parentNode; var droponOptions = Sortable.options(dropon); if(!Element.isParent(dropon, element)) { var index; var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); var child = null; if(children) { var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); for (index = 0; index < children.length; index += 1) { if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { offset -= Element.offsetSize (children[index], droponOptions.overlap); } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { child = index + 1 < children.length ? children[index + 1] : null; break; } else { child = children[index]; break; } } } dropon.insertBefore(element, child); Sortable.options(oldParentNode).onChange(element); droponOptions.onChange(element); } }, unmark: function() { if(Sortable._marker) Sortable._marker.hide(); }, mark: function(dropon, position) { // mark on ghosting only var sortable = Sortable.options(dropon.parentNode); if(sortable && !sortable.ghosting) return; if(!Sortable._marker) { Sortable._marker = ($('dropmarker') || Element.extend(document.createElement('DIV'))). hide().addClassName('dropmarker').setStyle({position:'absolute'}); document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); } var offsets = Position.cumulativeOffset(dropon); Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); if(position=='after') if(sortable.overlap == 'horizontal') Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); else Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); Sortable._marker.show(); }, _tree: function(element, options, parent) { var children = Sortable.findElements(element, options) || []; for (var i = 0; i < children.length; ++i) { var match = children[i].id.match(options.format); if (!match) continue; var child = { id: encodeURIComponent(match ? match[1] : null), element: element, parent: parent, children: [], position: parent.children.length, container: $(children[i]).down(options.treeTag) } /* Get the element containing the children and recurse over it */ if (child.container) this._tree(child.container, options, child) parent.children.push (child); } return parent; }, tree: function(element) { element = $(element); var sortableOptions = this.options(element); var options = Object.extend({ tag: sortableOptions.tag, treeTag: sortableOptions.treeTag, only: sortableOptions.only, name: element.id, format: sortableOptions.format }, arguments[1] || {}); var root = { id: null, parent: null, children: [], container: element, position: 0 } return Sortable._tree(element, options, root); }, /* Construct a [i] index for a particular node */ _constructIndex: function(node) { var index = ''; do { if (node.id) index = '[' + node.position + ']' + index; } while ((node = node.parent) != null); return index; }, sequence: function(element) { element = $(element); var options = Object.extend(this.options(element), arguments[1] || {}); return $(this.findElements(element, options) || []).map( function(item) { return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; }); }, setSequence: function(element, new_sequence) { element = $(element); var options = Object.extend(this.options(element), arguments[2] || {}); var nodeMap = {}; this.findElements(element, options).each( function(n) { if (n.id.match(options.format)) nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; n.parentNode.removeChild(n); }); new_sequence.each(function(ident) { var n = nodeMap[ident]; if (n) { n[1].appendChild(n[0]); delete nodeMap[ident]; } }); }, serialize: function(element) { element = $(element); var options = Object.extend(Sortable.options(element), arguments[1] || {}); var name = encodeURIComponent( (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); if (options.tree) { return Sortable.tree(element, arguments[1]).children.map( function (item) { return [name + Sortable._constructIndex(item) + "[id]=" + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); }).flatten().join('&'); } else { return Sortable.sequence(element, arguments[1]).map( function(item) { return name + "[]=" + encodeURIComponent(item); }).join('&'); } } } // Returns true if child is contained within element Element.isParent = function(child, element) { if (!child.parentNode || child == element) return false; if (child.parentNode == element) return true; return Element.isParent(child.parentNode, element); } Element.findChildren = function(element, only, recursive, tagName) { if(!element.hasChildNodes()) return null; tagName = tagName.toUpperCase(); if(only) only = [only].flatten(); var elements = []; $A(element.childNodes).each( function(e) { if(e.tagName && e.tagName.toUpperCase()==tagName && (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) elements.push(e); if(recursive) { var grandchildren = Element.findChildren(e, only, recursive, tagName); if(grandchildren) elements.push(grandchildren); } }); return (elements.length>0 ? elements.flatten() : []); } Element.offsetSize = function (element, type) { return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; } mod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/application.js0000644000175000017500000000022510650177506026551 0ustar greggreg// Place your application-specific JavaScript functions and classes here // This file is automatically included by javascript_include_tag :defaults mod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/fdajax.js0000644000175000017500000000721210650177506025506 0ustar greggreg/* Full-duplex Ajax module for Lighttpd, version 0.8 * (c) 2007 Grzegorz Daniluk /*--------------------------------------------------------------------------*/ var fdajax = { server_url: "/live.fdajax", run_loop: false, user_id: 0, win_id: 0, ev_types: "", cur_req: null, from_sec: 0, from_usec: 0, first: true, waitForEvent: function(user_id, ev_types, sec, usec) { this.user_id = user_id; this.win_id = Math.floor(Math.random() * 2147483646 + 1); this.ev_types = ev_types; this.from_sec = sec; this.from_usec = usec; Event.observe(window, "load", fdajax.startloop); }, redirect: function(www_id) { fdajax.cancel(); alert("Do not open a second window or configure www1, www2, etc addresses in your application."); window.location = "/minichat/login"; }, relogin: function(reason) { fdajax.cancel(); if (reason == "ipaddr") { alert("Please log in once again, your IP address has changed."); } else if (reason == "sessid") { alert("Please log in once again, your session id is incorrect."); } window.location = "/minichat/login"; }, nocookies: function() { fdajax.cancel(); }, notfound: function() { fdajax.cancel(); alert("You are not logged to FdAjax module."); window.location = "/minichat/login"; }, cancel: function() { fdajax.run_loop = false; if (fdajax.cur_req) { if (fdajax.cur_req.transport && fdajax.cur_req.transport.readyState > 0) { fdajax.cur_req.transport.onreadystatechange = function() {}; fdajax.cur_req.transport.abort(); new Ajax.Request(fdajax.server_url, { method: 'get', asynchronous: false, parameters: 'cmd=cancel' + '&user_id=' + fdajax.user_id + '&win_id=' + fdajax.win_id }); } fdajax.cur_req.transport = null; fdajax.cur_req = null; } return false; }, send_request: function() { if (!fdajax.run_loop) { return; } var opt = { onSuccess: function(resp) { fdajax.cur_req = null; try { eval(resp.responseText); } catch (e) {} if (fdajax.run_loop) { setTimeout("fdajax.send_request();", 50); } }, onFailure: function(req) { fdajax.cur_req = null; setTimeout("fdajax.send_request();", 10000); }, method: 'get', parameters: "cmd=wait&user_id=" + fdajax.user_id + "&win_id=" + fdajax.win_id + "&types=" + fdajax.ev_types }; if (fdajax.first) { fdajax.first = false; opt.parameters += "&sec=" + fdajax.from_sec + "&usec=" + fdajax.from_usec; } fdajax.cur_req = new Ajax.Request(fdajax.server_url, opt); }, startloop: function() { fdajax.run_loop = true; Event.observe(window, "unload", fdajax.cancel); setTimeout("fdajax.send_request();", 1000); }, stoploop: function() { if (fdajax.run_loop) { fdajax.run_loop = false; alert("You have been logged out from FdAjax module."); window.location = "/minichat/login"; } }, maxwin: function() { if (fdajax.run_loop) { fdajax.run_loop = false; alert("Too many open windows. This window has lost the connection to FdAjax module."); } }, no_guests: function () { alert("Guest users not allowed."); }, peer_call: function(peer_id, ev, ob_id, par1) { }, grp_peer_call: function (peer_id, ev, par1) { }, ping: function() { // In case of chunked mode the ping function might be empty } }; mod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/controls.js0000644000175000017500000007035710650177506026126 0ustar greggreg// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan) // (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com) // Contributors: // Richard Livsey // Rahul Bhargava // Rob Wills // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ // Autocompleter.Base handles all the autocompletion functionality // that's independent of the data source for autocompletion. This // includes drawing the autocompletion menu, observing keyboard // and mouse events, and similar. // // Specific autocompleters need to provide, at the very least, // a getUpdatedChoices function that will be invoked every time // the text inside the monitored textbox changes. This method // should get the text for which to provide autocompletion by // invoking this.getToken(), NOT by directly accessing // this.element.value. This is to allow incremental tokenized // autocompletion. Specific auto-completion logic (AJAX, etc) // belongs in getUpdatedChoices. // // Tokenized incremental autocompletion is enabled automatically // when an autocompleter is instantiated with the 'tokens' option // in the options parameter, e.g.: // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); // will incrementally autocomplete with a comma as the token. // Additionally, ',' in the above example can be replaced with // a token array, e.g. { tokens: [',', '\n'] } which // enables autocompletion on multiple tokens. This is most // useful when one of the tokens is \n (a newline), as it // allows smart autocompletion after linebreaks. if(typeof Effect == 'undefined') throw("controls.js requires including script.aculo.us' effects.js library"); var Autocompleter = {} Autocompleter.Base = function() {}; Autocompleter.Base.prototype = { baseInitialize: function(element, update, options) { this.element = $(element); this.update = $(update); this.hasFocus = false; this.changed = false; this.active = false; this.index = 0; this.entryCount = 0; if(this.setOptions) this.setOptions(options); else this.options = options || {}; this.options.paramName = this.options.paramName || this.element.name; this.options.tokens = this.options.tokens || []; this.options.frequency = this.options.frequency || 0.4; this.options.minChars = this.options.minChars || 1; this.options.onShow = this.options.onShow || function(element, update){ if(!update.style.position || update.style.position=='absolute') { update.style.position = 'absolute'; Position.clone(element, update, { setHeight: false, offsetTop: element.offsetHeight }); } Effect.Appear(update,{duration:0.15}); }; this.options.onHide = this.options.onHide || function(element, update){ new Effect.Fade(update,{duration:0.15}) }; if(typeof(this.options.tokens) == 'string') this.options.tokens = new Array(this.options.tokens); this.observer = null; this.element.setAttribute('autocomplete','off'); Element.hide(this.update); Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); }, show: function() { if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (navigator.userAgent.indexOf('Opera')<0) && (Element.getStyle(this.update, 'position')=='absolute')) { new Insertion.After(this.update, ''); this.iefix = $(this.update.id+'_iefix'); } if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); }, fixIEOverlapping: function() { Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); this.iefix.style.zIndex = 1; this.update.style.zIndex = 2; Element.show(this.iefix); }, hide: function() { this.stopIndicator(); if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); if(this.iefix) Element.hide(this.iefix); }, startIndicator: function() { if(this.options.indicator) Element.show(this.options.indicator); }, stopIndicator: function() { if(this.options.indicator) Element.hide(this.options.indicator); }, onKeyPress: function(event) { if(this.active) switch(event.keyCode) { case Event.KEY_TAB: case Event.KEY_RETURN: this.selectEntry(); Event.stop(event); case Event.KEY_ESC: this.hide(); this.active = false; Event.stop(event); return; case Event.KEY_LEFT: case Event.KEY_RIGHT: return; case Event.KEY_UP: this.markPrevious(); this.render(); if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); return; case Event.KEY_DOWN: this.markNext(); this.render(); if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); return; } else if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return; this.changed = true; this.hasFocus = true; if(this.observer) clearTimeout(this.observer); this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); }, activate: function() { this.changed = false; this.hasFocus = true; this.getUpdatedChoices(); }, onHover: function(event) { var element = Event.findElement(event, 'LI'); if(this.index != element.autocompleteIndex) { this.index = element.autocompleteIndex; this.render(); } Event.stop(event); }, onClick: function(event) { var element = Event.findElement(event, 'LI'); this.index = element.autocompleteIndex; this.selectEntry(); this.hide(); }, onBlur: function(event) { // needed to make click events working setTimeout(this.hide.bind(this), 250); this.hasFocus = false; this.active = false; }, render: function() { if(this.entryCount > 0) { for (var i = 0; i < this.entryCount; i++) this.index==i ? Element.addClassName(this.getEntry(i),"selected") : Element.removeClassName(this.getEntry(i),"selected"); if(this.hasFocus) { this.show(); this.active = true; } } else { this.active = false; this.hide(); } }, markPrevious: function() { if(this.index > 0) this.index-- else this.index = this.entryCount-1; this.getEntry(this.index).scrollIntoView(true); }, markNext: function() { if(this.index < this.entryCount-1) this.index++ else this.index = 0; this.getEntry(this.index).scrollIntoView(false); }, getEntry: function(index) { return this.update.firstChild.childNodes[index]; }, getCurrentEntry: function() { return this.getEntry(this.index); }, selectEntry: function() { this.active = false; this.updateElement(this.getCurrentEntry()); }, updateElement: function(selectedElement) { if (this.options.updateElement) { this.options.updateElement(selectedElement); return; } var value = ''; if (this.options.select) { var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); } else value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); var lastTokenPos = this.findLastToken(); if (lastTokenPos != -1) { var newValue = this.element.value.substr(0, lastTokenPos + 1); var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); if (whitespace) newValue += whitespace[0]; this.element.value = newValue + value; } else { this.element.value = value; } this.element.focus(); if (this.options.afterUpdateElement) this.options.afterUpdateElement(this.element, selectedElement); }, updateChoices: function(choices) { if(!this.changed && this.hasFocus) { this.update.innerHTML = choices; Element.cleanWhitespace(this.update); Element.cleanWhitespace(this.update.down()); if(this.update.firstChild && this.update.down().childNodes) { this.entryCount = this.update.down().childNodes.length; for (var i = 0; i < this.entryCount; i++) { var entry = this.getEntry(i); entry.autocompleteIndex = i; this.addObservers(entry); } } else { this.entryCount = 0; } this.stopIndicator(); this.index = 0; if(this.entryCount==1 && this.options.autoSelect) { this.selectEntry(); this.hide(); } else { this.render(); } } }, addObservers: function(element) { Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); Event.observe(element, "click", this.onClick.bindAsEventListener(this)); }, onObserverEvent: function() { this.changed = false; if(this.getToken().length>=this.options.minChars) { this.startIndicator(); this.getUpdatedChoices(); } else { this.active = false; this.hide(); } }, getToken: function() { var tokenPos = this.findLastToken(); if (tokenPos != -1) var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); else var ret = this.element.value; return /\n/.test(ret) ? '' : ret; }, findLastToken: function() { var lastTokenPos = -1; for (var i=0; i lastTokenPos) lastTokenPos = thisTokenPos; } return lastTokenPos; } } Ajax.Autocompleter = Class.create(); Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { initialize: function(element, update, url, options) { this.baseInitialize(element, update, options); this.options.asynchronous = true; this.options.onComplete = this.onComplete.bind(this); this.options.defaultParams = this.options.parameters || null; this.url = url; }, getUpdatedChoices: function() { entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken()); this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry; if(this.options.defaultParams) this.options.parameters += '&' + this.options.defaultParams; new Ajax.Request(this.url, this.options); }, onComplete: function(request) { this.updateChoices(request.responseText); } }); // The local array autocompleter. Used when you'd prefer to // inject an array of autocompletion options into the page, rather // than sending out Ajax queries, which can be quite slow sometimes. // // The constructor takes four parameters. The first two are, as usual, // the id of the monitored textbox, and id of the autocompletion menu. // The third is the array you want to autocomplete from, and the fourth // is the options block. // // Extra local autocompletion options: // - choices - How many autocompletion choices to offer // // - partialSearch - If false, the autocompleter will match entered // text only at the beginning of strings in the // autocomplete array. Defaults to true, which will // match text at the beginning of any *word* in the // strings in the autocomplete array. If you want to // search anywhere in the string, additionally set // the option fullSearch to true (default: off). // // - fullSsearch - Search anywhere in autocomplete array strings. // // - partialChars - How many characters to enter before triggering // a partial match (unlike minChars, which defines // how many characters are required to do any match // at all). Defaults to 2. // // - ignoreCase - Whether to ignore case when autocompleting. // Defaults to true. // // It's possible to pass in a custom function as the 'selector' // option, if you prefer to write your own autocompletion logic. // In that case, the other options above will not apply unless // you support them. Autocompleter.Local = Class.create(); Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { initialize: function(element, update, array, options) { this.baseInitialize(element, update, options); this.options.array = array; }, getUpdatedChoices: function() { this.updateChoices(this.options.selector(this)); }, setOptions: function(options) { this.options = Object.extend({ choices: 10, partialSearch: true, partialChars: 2, ignoreCase: true, fullSearch: false, selector: function(instance) { var ret = []; // Beginning matches var partial = []; // Inside matches var entry = instance.getToken(); var count = 0; for (var i = 0; i < instance.options.array.length && ret.length < instance.options.choices ; i++) { var elem = instance.options.array[i]; var foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase()) : elem.indexOf(entry); while (foundPos != -1) { if (foundPos == 0 && elem.length != entry.length) { ret.push("
  • " + elem.substr(0, entry.length) + "" + elem.substr(entry.length) + "
  • "); break; } else if (entry.length >= instance.options.partialChars && instance.options.partialSearch && foundPos != -1) { if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { partial.push("
  • " + elem.substr(0, foundPos) + "" + elem.substr(foundPos, entry.length) + "" + elem.substr( foundPos + entry.length) + "
  • "); break; } } foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : elem.indexOf(entry, foundPos + 1); } } if (partial.length) ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) return "
      " + ret.join('') + "
    "; } }, options || {}); } }); // AJAX in-place editor // // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor // Use this if you notice weird scrolling problems on some browsers, // the DOM might be a bit confused when this gets called so do this // waits 1 ms (with setTimeout) until it does the activation Field.scrollFreeActivate = function(field) { setTimeout(function() { Field.activate(field); }, 1); } Ajax.InPlaceEditor = Class.create(); Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; Ajax.InPlaceEditor.prototype = { initialize: function(element, url, options) { this.url = url; this.element = $(element); this.options = Object.extend({ paramName: "value", okButton: true, okText: "ok", cancelLink: true, cancelText: "cancel", savingText: "Saving...", clickToEditText: "Click to edit", okText: "ok", rows: 1, onComplete: function(transport, element) { new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); }, onFailure: function(transport) { alert("Error communicating with the server: " + transport.responseText.stripTags()); }, callback: function(form) { return Form.serialize(form); }, handleLineBreaks: true, loadingText: 'Loading...', savingClassName: 'inplaceeditor-saving', loadingClassName: 'inplaceeditor-loading', formClassName: 'inplaceeditor-form', highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, highlightendcolor: "#FFFFFF", externalControl: null, submitOnBlur: false, ajaxOptions: {}, evalScripts: false }, options || {}); if(!this.options.formId && this.element.id) { this.options.formId = this.element.id + "-inplaceeditor"; if ($(this.options.formId)) { // there's already a form with that name, don't specify an id this.options.formId = null; } } if (this.options.externalControl) { this.options.externalControl = $(this.options.externalControl); } this.originalBackground = Element.getStyle(this.element, 'background-color'); if (!this.originalBackground) { this.originalBackground = "transparent"; } this.element.title = this.options.clickToEditText; this.onclickListener = this.enterEditMode.bindAsEventListener(this); this.mouseoverListener = this.enterHover.bindAsEventListener(this); this.mouseoutListener = this.leaveHover.bindAsEventListener(this); Event.observe(this.element, 'click', this.onclickListener); Event.observe(this.element, 'mouseover', this.mouseoverListener); Event.observe(this.element, 'mouseout', this.mouseoutListener); if (this.options.externalControl) { Event.observe(this.options.externalControl, 'click', this.onclickListener); Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); } }, enterEditMode: function(evt) { if (this.saving) return; if (this.editing) return; this.editing = true; this.onEnterEditMode(); if (this.options.externalControl) { Element.hide(this.options.externalControl); } Element.hide(this.element); this.createForm(); this.element.parentNode.insertBefore(this.form, this.element); if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField); // stop the event to avoid a page refresh in Safari if (evt) { Event.stop(evt); } return false; }, createForm: function() { this.form = document.createElement("form"); this.form.id = this.options.formId; Element.addClassName(this.form, this.options.formClassName) this.form.onsubmit = this.onSubmit.bind(this); this.createEditField(); if (this.options.textarea) { var br = document.createElement("br"); this.form.appendChild(br); } if (this.options.okButton) { okButton = document.createElement("input"); okButton.type = "submit"; okButton.value = this.options.okText; okButton.className = 'editor_ok_button'; this.form.appendChild(okButton); } if (this.options.cancelLink) { cancelLink = document.createElement("a"); cancelLink.href = "#"; cancelLink.appendChild(document.createTextNode(this.options.cancelText)); cancelLink.onclick = this.onclickCancel.bind(this); cancelLink.className = 'editor_cancel'; this.form.appendChild(cancelLink); } }, hasHTMLLineBreaks: function(string) { if (!this.options.handleLineBreaks) return false; return string.match(/
    /i); }, convertHTMLLineBreaks: function(string) { return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); }, createEditField: function() { var text; if(this.options.loadTextURL) { text = this.options.loadingText; } else { text = this.getText(); } var obj = this; if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { this.options.textarea = false; var textField = document.createElement("input"); textField.obj = this; textField.type = "text"; textField.name = this.options.paramName; textField.value = text; textField.style.backgroundColor = this.options.highlightcolor; textField.className = 'editor_field'; var size = this.options.size || this.options.cols || 0; if (size != 0) textField.size = size; if (this.options.submitOnBlur) textField.onblur = this.onSubmit.bind(this); this.editField = textField; } else { this.options.textarea = true; var textArea = document.createElement("textarea"); textArea.obj = this; textArea.name = this.options.paramName; textArea.value = this.convertHTMLLineBreaks(text); textArea.rows = this.options.rows; textArea.cols = this.options.cols || 40; textArea.className = 'editor_field'; if (this.options.submitOnBlur) textArea.onblur = this.onSubmit.bind(this); this.editField = textArea; } if(this.options.loadTextURL) { this.loadExternalText(); } this.form.appendChild(this.editField); }, getText: function() { return this.element.innerHTML; }, loadExternalText: function() { Element.addClassName(this.form, this.options.loadingClassName); this.editField.disabled = true; new Ajax.Request( this.options.loadTextURL, Object.extend({ asynchronous: true, onComplete: this.onLoadedExternalText.bind(this) }, this.options.ajaxOptions) ); }, onLoadedExternalText: function(transport) { Element.removeClassName(this.form, this.options.loadingClassName); this.editField.disabled = false; this.editField.value = transport.responseText.stripTags(); Field.scrollFreeActivate(this.editField); }, onclickCancel: function() { this.onComplete(); this.leaveEditMode(); return false; }, onFailure: function(transport) { this.options.onFailure(transport); if (this.oldInnerHTML) { this.element.innerHTML = this.oldInnerHTML; this.oldInnerHTML = null; } return false; }, onSubmit: function() { // onLoading resets these so we need to save them away for the Ajax call var form = this.form; var value = this.editField.value; // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... // to be displayed indefinitely this.onLoading(); if (this.options.evalScripts) { new Ajax.Request( this.url, Object.extend({ parameters: this.options.callback(form, value), onComplete: this.onComplete.bind(this), onFailure: this.onFailure.bind(this), asynchronous:true, evalScripts:true }, this.options.ajaxOptions)); } else { new Ajax.Updater( { success: this.element, // don't update on failure (this could be an option) failure: null }, this.url, Object.extend({ parameters: this.options.callback(form, value), onComplete: this.onComplete.bind(this), onFailure: this.onFailure.bind(this) }, this.options.ajaxOptions)); } // stop the event to avoid a page refresh in Safari if (arguments.length > 1) { Event.stop(arguments[0]); } return false; }, onLoading: function() { this.saving = true; this.removeForm(); this.leaveHover(); this.showSaving(); }, showSaving: function() { this.oldInnerHTML = this.element.innerHTML; this.element.innerHTML = this.options.savingText; Element.addClassName(this.element, this.options.savingClassName); this.element.style.backgroundColor = this.originalBackground; Element.show(this.element); }, removeForm: function() { if(this.form) { if (this.form.parentNode) Element.remove(this.form); this.form = null; } }, enterHover: function() { if (this.saving) return; this.element.style.backgroundColor = this.options.highlightcolor; if (this.effect) { this.effect.cancel(); } Element.addClassName(this.element, this.options.hoverClassName) }, leaveHover: function() { if (this.options.backgroundColor) { this.element.style.backgroundColor = this.oldBackground; } Element.removeClassName(this.element, this.options.hoverClassName) if (this.saving) return; this.effect = new Effect.Highlight(this.element, { startcolor: this.options.highlightcolor, endcolor: this.options.highlightendcolor, restorecolor: this.originalBackground }); }, leaveEditMode: function() { Element.removeClassName(this.element, this.options.savingClassName); this.removeForm(); this.leaveHover(); this.element.style.backgroundColor = this.originalBackground; Element.show(this.element); if (this.options.externalControl) { Element.show(this.options.externalControl); } this.editing = false; this.saving = false; this.oldInnerHTML = null; this.onLeaveEditMode(); }, onComplete: function(transport) { this.leaveEditMode(); this.options.onComplete.bind(this)(transport, this.element); }, onEnterEditMode: function() {}, onLeaveEditMode: function() {}, dispose: function() { if (this.oldInnerHTML) { this.element.innerHTML = this.oldInnerHTML; } this.leaveEditMode(); Event.stopObserving(this.element, 'click', this.onclickListener); Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); if (this.options.externalControl) { Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); } } }; Ajax.InPlaceCollectionEditor = Class.create(); Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); Object.extend(Ajax.InPlaceCollectionEditor.prototype, { createEditField: function() { if (!this.cached_selectTag) { var selectTag = document.createElement("select"); var collection = this.options.collection || []; var optionTag; collection.each(function(e,i) { optionTag = document.createElement("option"); optionTag.value = (e instanceof Array) ? e[0] : e; if((typeof this.options.value == 'undefined') && ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true; if(this.options.value==optionTag.value) optionTag.selected = true; optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); selectTag.appendChild(optionTag); }.bind(this)); this.cached_selectTag = selectTag; } this.editField = this.cached_selectTag; if(this.options.loadTextURL) this.loadExternalText(); this.form.appendChild(this.editField); this.options.callback = function(form, value) { return "value=" + encodeURIComponent(value); } } }); // Delayed observer, like Form.Element.Observer, // but waits for delay after last key input // Ideal for live-search fields Form.Element.DelayedObserver = Class.create(); Form.Element.DelayedObserver.prototype = { initialize: function(element, delay, callback) { this.delay = delay || 0.5; this.element = $(element); this.callback = callback; this.timer = null; this.lastValue = $F(this.element); Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); }, delayedListener: function(event) { if(this.lastValue == $F(this.element)) return; if(this.timer) clearTimeout(this.timer); this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); this.lastValue = $F(this.element); }, onTimerEvent: function() { this.timer = null; this.callback(this.element, $F(this.element)); } }; mod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/effects.js0000644000175000017500000011247010650177506025673 0ustar greggreg// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) // Contributors: // Justin Palmer (http://encytemedia.com/) // Mark Pilgrim (http://diveintomark.org/) // Martin Bialasinki // // script.aculo.us is freely distributable under the terms of an MIT-style license. // For details, see the script.aculo.us web site: http://script.aculo.us/ // converts rgb() and #xxx to #xxxxxx format, // returns self (or first argument) if not convertable String.prototype.parseColor = function() { var color = '#'; if(this.slice(0,4) == 'rgb(') { var cols = this.slice(4,this.length-1).split(','); var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); } else { if(this.slice(0,1) == '#') { if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); if(this.length==7) color = this.toLowerCase(); } } return(color.length==7 ? color : (arguments[0] || this)); } /*--------------------------------------------------------------------------*/ Element.collectTextNodes = function(element) { return $A($(element).childNodes).collect( function(node) { return (node.nodeType==3 ? node.nodeValue : (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); }).flatten().join(''); } Element.collectTextNodesIgnoreClass = function(element, className) { return $A($(element).childNodes).collect( function(node) { return (node.nodeType==3 ? node.nodeValue : ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? Element.collectTextNodesIgnoreClass(node, className) : '')); }).flatten().join(''); } Element.setContentZoom = function(element, percent) { element = $(element); element.setStyle({fontSize: (percent/100) + 'em'}); if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); return element; } Element.getOpacity = function(element){ element = $(element); var opacity; if (opacity = element.getStyle('opacity')) return parseFloat(opacity); if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if(opacity[1]) return parseFloat(opacity[1]) / 100; return 1.0; } Element.setOpacity = function(element, value){ element= $(element); if (value == 1){ element.setStyle({ opacity: (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0 }); if(/MSIE/.test(navigator.userAgent) && !window.opera) element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); } else { if(value < 0.00001) value = 0; element.setStyle({opacity: value}); if(/MSIE/.test(navigator.userAgent) && !window.opera) element.setStyle( { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+value*100+')' }); } return element; } Element.getInlineOpacity = function(element){ return $(element).style.opacity || ''; } Element.forceRerendering = function(element) { try { element = $(element); var n = document.createTextNode(' '); element.appendChild(n); element.removeChild(n); } catch(e) { } }; /*--------------------------------------------------------------------------*/ Array.prototype.call = function() { var args = arguments; this.each(function(f){ f.apply(this, args) }); } /*--------------------------------------------------------------------------*/ var Effect = { _elementDoesNotExistError: { name: 'ElementDoesNotExistError', message: 'The specified DOM element does not exist, but is required for this effect to operate' }, tagifyText: function(element) { if(typeof Builder == 'undefined') throw("Effect.tagifyText requires including script.aculo.us' builder.js library"); var tagifyStyle = 'position:relative'; if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1'; element = $(element); $A(element.childNodes).each( function(child) { if(child.nodeType==3) { child.nodeValue.toArray().each( function(character) { element.insertBefore( Builder.node('span',{style: tagifyStyle}, character == ' ' ? String.fromCharCode(160) : character), child); }); Element.remove(child); } }); }, multiple: function(element, effect) { var elements; if(((typeof element == 'object') || (typeof element == 'function')) && (element.length)) elements = element; else elements = $(element).childNodes; var options = Object.extend({ speed: 0.1, delay: 0.0 }, arguments[2] || {}); var masterDelay = options.delay; $A(elements).each( function(element, index) { new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); }); }, PAIRS: { 'slide': ['SlideDown','SlideUp'], 'blind': ['BlindDown','BlindUp'], 'appear': ['Appear','Fade'] }, toggle: function(element, effect) { element = $(element); effect = (effect || 'appear').toLowerCase(); var options = Object.extend({ queue: { position:'end', scope:(element.id || 'global'), limit: 1 } }, arguments[2] || {}); Effect[element.visible() ? Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); } }; var Effect2 = Effect; // deprecated /* ------------- transitions ------------- */ Effect.Transitions = { linear: Prototype.K, sinoidal: function(pos) { return (-Math.cos(pos*Math.PI)/2) + 0.5; }, reverse: function(pos) { return 1-pos; }, flicker: function(pos) { return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; }, wobble: function(pos) { return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; }, pulse: function(pos, pulses) { pulses = pulses || 5; return ( Math.round((pos % (1/pulses)) * pulses) == 0 ? ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) ); }, none: function(pos) { return 0; }, full: function(pos) { return 1; } }; /* ------------- core effects ------------- */ Effect.ScopedQueue = Class.create(); Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { initialize: function() { this.effects = []; this.interval = null; }, _each: function(iterator) { this.effects._each(iterator); }, add: function(effect) { var timestamp = new Date().getTime(); var position = (typeof effect.options.queue == 'string') ? effect.options.queue : effect.options.queue.position; switch(position) { case 'front': // move unstarted effects after this effect this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { e.startOn += effect.finishOn; e.finishOn += effect.finishOn; }); break; case 'with-last': timestamp = this.effects.pluck('startOn').max() || timestamp; break; case 'end': // start effect after last queued effect has finished timestamp = this.effects.pluck('finishOn').max() || timestamp; break; } effect.startOn += timestamp; effect.finishOn += timestamp; if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) this.effects.push(effect); if(!this.interval) this.interval = setInterval(this.loop.bind(this), 40); }, remove: function(effect) { this.effects = this.effects.reject(function(e) { return e==effect }); if(this.effects.length == 0) { clearInterval(this.interval); this.interval = null; } }, loop: function() { var timePos = new Date().getTime(); this.effects.invoke('loop', timePos); } }); Effect.Queues = { instances: $H(), get: function(queueName) { if(typeof queueName != 'string') return queueName; if(!this.instances[queueName]) this.instances[queueName] = new Effect.ScopedQueue(); return this.instances[queueName]; } } Effect.Queue = Effect.Queues.get('global'); Effect.DefaultOptions = { transition: Effect.Transitions.sinoidal, duration: 1.0, // seconds fps: 25.0, // max. 25fps due to Effect.Queue implementation sync: false, // true for combining from: 0.0, to: 1.0, delay: 0.0, queue: 'parallel' } Effect.Base = function() {}; Effect.Base.prototype = { position: null, start: function(options) { this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); this.currentFrame = 0; this.state = 'idle'; this.startOn = this.options.delay*1000; this.finishOn = this.startOn + (this.options.duration*1000); this.event('beforeStart'); if(!this.options.sync) Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).add(this); }, loop: function(timePos) { if(timePos >= this.startOn) { if(timePos >= this.finishOn) { this.render(1.0); this.cancel(); this.event('beforeFinish'); if(this.finish) this.finish(); this.event('afterFinish'); return; } var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); var frame = Math.round(pos * this.options.fps * this.options.duration); if(frame > this.currentFrame) { this.render(pos); this.currentFrame = frame; } } }, render: function(pos) { if(this.state == 'idle') { this.state = 'running'; this.event('beforeSetup'); if(this.setup) this.setup(); this.event('afterSetup'); } if(this.state == 'running') { if(this.options.transition) pos = this.options.transition(pos); pos *= (this.options.to-this.options.from); pos += this.options.from; this.position = pos; this.event('beforeUpdate'); if(this.update) this.update(pos); this.event('afterUpdate'); } }, cancel: function() { if(!this.options.sync) Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).remove(this); this.state = 'finished'; }, event: function(eventName) { if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); if(this.options[eventName]) this.options[eventName](this); }, inspect: function() { return '#'; } } Effect.Parallel = Class.create(); Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { initialize: function(effects) { this.effects = effects || []; this.start(arguments[1]); }, update: function(position) { this.effects.invoke('render', position); }, finish: function(position) { this.effects.each( function(effect) { effect.render(1.0); effect.cancel(); effect.event('beforeFinish'); if(effect.finish) effect.finish(position); effect.event('afterFinish'); }); } }); Effect.Event = Class.create(); Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), { initialize: function() { var options = Object.extend({ duration: 0 }, arguments[0] || {}); this.start(options); }, update: Prototype.emptyFunction }); Effect.Opacity = Class.create(); Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); // make this work on IE on elements without 'layout' if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout)) this.element.setStyle({zoom: 1}); var options = Object.extend({ from: this.element.getOpacity() || 0.0, to: 1.0 }, arguments[1] || {}); this.start(options); }, update: function(position) { this.element.setOpacity(position); } }); Effect.Move = Class.create(); Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); var options = Object.extend({ x: 0, y: 0, mode: 'relative' }, arguments[1] || {}); this.start(options); }, setup: function() { // Bug in Opera: Opera returns the "real" position of a static element or // relative element that does not have top/left explicitly set. // ==> Always set top and left for position relative elements in your stylesheets // (to 0 if you do not need them) this.element.makePositioned(); this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); this.originalTop = parseFloat(this.element.getStyle('top') || '0'); if(this.options.mode == 'absolute') { // absolute movement, so we need to calc deltaX and deltaY this.options.x = this.options.x - this.originalLeft; this.options.y = this.options.y - this.originalTop; } }, update: function(position) { this.element.setStyle({ left: Math.round(this.options.x * position + this.originalLeft) + 'px', top: Math.round(this.options.y * position + this.originalTop) + 'px' }); } }); // for backwards compatibility Effect.MoveBy = function(element, toTop, toLeft) { return new Effect.Move(element, Object.extend({ x: toLeft, y: toTop }, arguments[3] || {})); }; Effect.Scale = Class.create(); Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { initialize: function(element, percent) { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); var options = Object.extend({ scaleX: true, scaleY: true, scaleContent: true, scaleFromCenter: false, scaleMode: 'box', // 'box' or 'contents' or {} with provided values scaleFrom: 100.0, scaleTo: percent }, arguments[2] || {}); this.start(options); }, setup: function() { this.restoreAfterFinish = this.options.restoreAfterFinish || false; this.elementPositioning = this.element.getStyle('position'); this.originalStyle = {}; ['top','left','width','height','fontSize'].each( function(k) { this.originalStyle[k] = this.element.style[k]; }.bind(this)); this.originalTop = this.element.offsetTop; this.originalLeft = this.element.offsetLeft; var fontSize = this.element.getStyle('font-size') || '100%'; ['em','px','%','pt'].each( function(fontSizeType) { if(fontSize.indexOf(fontSizeType)>0) { this.fontSize = parseFloat(fontSize); this.fontSizeType = fontSizeType; } }.bind(this)); this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; this.dims = null; if(this.options.scaleMode=='box') this.dims = [this.element.offsetHeight, this.element.offsetWidth]; if(/^content/.test(this.options.scaleMode)) this.dims = [this.element.scrollHeight, this.element.scrollWidth]; if(!this.dims) this.dims = [this.options.scaleMode.originalHeight, this.options.scaleMode.originalWidth]; }, update: function(position) { var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); if(this.options.scaleContent && this.fontSize) this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); }, finish: function(position) { if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle); }, setDimensions: function(height, width) { var d = {}; if(this.options.scaleX) d.width = Math.round(width) + 'px'; if(this.options.scaleY) d.height = Math.round(height) + 'px'; if(this.options.scaleFromCenter) { var topd = (height - this.dims[0])/2; var leftd = (width - this.dims[1])/2; if(this.elementPositioning == 'absolute') { if(this.options.scaleY) d.top = this.originalTop-topd + 'px'; if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; } else { if(this.options.scaleY) d.top = -topd + 'px'; if(this.options.scaleX) d.left = -leftd + 'px'; } } this.element.setStyle(d); } }); Effect.Highlight = Class.create(); Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); this.start(options); }, setup: function() { // Prevent executing on elements not in the layout flow if(this.element.getStyle('display')=='none') { this.cancel(); return; } // Disable background image during the effect this.oldStyle = { backgroundImage: this.element.getStyle('background-image') }; this.element.setStyle({backgroundImage: 'none'}); if(!this.options.endcolor) this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); if(!this.options.restorecolor) this.options.restorecolor = this.element.getStyle('background-color'); // init color calculations this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); }, update: function(position) { this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); }, finish: function() { this.element.setStyle(Object.extend(this.oldStyle, { backgroundColor: this.options.restorecolor })); } }); Effect.ScrollTo = Class.create(); Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); this.start(arguments[1] || {}); }, setup: function() { Position.prepare(); var offsets = Position.cumulativeOffset(this.element); if(this.options.offset) offsets[1] += this.options.offset; var max = window.innerHeight ? window.height - window.innerHeight : document.body.scrollHeight - (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight); this.scrollStart = Position.deltaY; this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; }, update: function(position) { Position.prepare(); window.scrollTo(Position.deltaX, this.scrollStart + (position*this.delta)); } }); /* ------------- combination effects ------------- */ Effect.Fade = function(element) { element = $(element); var oldOpacity = element.getInlineOpacity(); var options = Object.extend({ from: element.getOpacity() || 1.0, to: 0.0, afterFinishInternal: function(effect) { if(effect.options.to!=0) return; effect.element.hide().setStyle({opacity: oldOpacity}); }}, arguments[1] || {}); return new Effect.Opacity(element,options); } Effect.Appear = function(element) { element = $(element); var options = Object.extend({ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), to: 1.0, // force Safari to render floated elements properly afterFinishInternal: function(effect) { effect.element.forceRerendering(); }, beforeSetup: function(effect) { effect.element.setOpacity(effect.options.from).show(); }}, arguments[1] || {}); return new Effect.Opacity(element,options); } Effect.Puff = function(element) { element = $(element); var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position'), top: element.style.top, left: element.style.left, width: element.style.width, height: element.style.height }; return new Effect.Parallel( [ new Effect.Scale(element, 200, { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], Object.extend({ duration: 1.0, beforeSetupInternal: function(effect) { Position.absolutize(effect.effects[0].element) }, afterFinishInternal: function(effect) { effect.effects[0].element.hide().setStyle(oldStyle); } }, arguments[1] || {}) ); } Effect.BlindUp = function(element) { element = $(element); element.makeClipping(); return new Effect.Scale(element, 0, Object.extend({ scaleContent: false, scaleX: false, restoreAfterFinish: true, afterFinishInternal: function(effect) { effect.element.hide().undoClipping(); } }, arguments[1] || {}) ); } Effect.BlindDown = function(element) { element = $(element); var elementDimensions = element.getDimensions(); return new Effect.Scale(element, 100, Object.extend({ scaleContent: false, scaleX: false, scaleFrom: 0, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, restoreAfterFinish: true, afterSetup: function(effect) { effect.element.makeClipping().setStyle({height: '0px'}).show(); }, afterFinishInternal: function(effect) { effect.element.undoClipping(); } }, arguments[1] || {})); } Effect.SwitchOff = function(element) { element = $(element); var oldOpacity = element.getInlineOpacity(); return new Effect.Appear(element, Object.extend({ duration: 0.4, from: 0, transition: Effect.Transitions.flicker, afterFinishInternal: function(effect) { new Effect.Scale(effect.element, 1, { duration: 0.3, scaleFromCenter: true, scaleX: false, scaleContent: false, restoreAfterFinish: true, beforeSetup: function(effect) { effect.element.makePositioned().makeClipping(); }, afterFinishInternal: function(effect) { effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); } }) } }, arguments[1] || {})); } Effect.DropOut = function(element) { element = $(element); var oldStyle = { top: element.getStyle('top'), left: element.getStyle('left'), opacity: element.getInlineOpacity() }; return new Effect.Parallel( [ new Effect.Move(element, {x: 0, y: 100, sync: true }), new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend( { duration: 0.5, beforeSetup: function(effect) { effect.effects[0].element.makePositioned(); }, afterFinishInternal: function(effect) { effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); } }, arguments[1] || {})); } Effect.Shake = function(element) { element = $(element); var oldStyle = { top: element.getStyle('top'), left: element.getStyle('left') }; return new Effect.Move(element, { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { new Effect.Move(effect.element, { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { effect.element.undoPositioned().setStyle(oldStyle); }}) }}) }}) }}) }}) }}); } Effect.SlideDown = function(element) { element = $(element).cleanWhitespace(); // SlideDown need to have the content of the element wrapped in a container element with fixed height! var oldInnerBottom = element.down().getStyle('bottom'); var elementDimensions = element.getDimensions(); return new Effect.Scale(element, 100, Object.extend({ scaleContent: false, scaleX: false, scaleFrom: window.opera ? 0 : 1, scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, restoreAfterFinish: true, afterSetup: function(effect) { effect.element.makePositioned(); effect.element.down().makePositioned(); if(window.opera) effect.element.setStyle({top: ''}); effect.element.makeClipping().setStyle({height: '0px'}).show(); }, afterUpdateInternal: function(effect) { effect.element.down().setStyle({bottom: (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, afterFinishInternal: function(effect) { effect.element.undoClipping().undoPositioned(); effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } }, arguments[1] || {}) ); } Effect.SlideUp = function(element) { element = $(element).cleanWhitespace(); var oldInnerBottom = element.down().getStyle('bottom'); return new Effect.Scale(element, window.opera ? 0 : 1, Object.extend({ scaleContent: false, scaleX: false, scaleMode: 'box', scaleFrom: 100, restoreAfterFinish: true, beforeStartInternal: function(effect) { effect.element.makePositioned(); effect.element.down().makePositioned(); if(window.opera) effect.element.setStyle({top: ''}); effect.element.makeClipping().show(); }, afterUpdateInternal: function(effect) { effect.element.down().setStyle({bottom: (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, afterFinishInternal: function(effect) { effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom}); effect.element.down().undoPositioned(); } }, arguments[1] || {}) ); } // Bug in opera makes the TD containing this element expand for a instance after finish Effect.Squish = function(element) { return new Effect.Scale(element, window.opera ? 1 : 0, { restoreAfterFinish: true, beforeSetup: function(effect) { effect.element.makeClipping(); }, afterFinishInternal: function(effect) { effect.element.hide().undoClipping(); } }); } Effect.Grow = function(element) { element = $(element); var options = Object.extend({ direction: 'center', moveTransition: Effect.Transitions.sinoidal, scaleTransition: Effect.Transitions.sinoidal, opacityTransition: Effect.Transitions.full }, arguments[1] || {}); var oldStyle = { top: element.style.top, left: element.style.left, height: element.style.height, width: element.style.width, opacity: element.getInlineOpacity() }; var dims = element.getDimensions(); var initialMoveX, initialMoveY; var moveX, moveY; switch (options.direction) { case 'top-left': initialMoveX = initialMoveY = moveX = moveY = 0; break; case 'top-right': initialMoveX = dims.width; initialMoveY = moveY = 0; moveX = -dims.width; break; case 'bottom-left': initialMoveX = moveX = 0; initialMoveY = dims.height; moveY = -dims.height; break; case 'bottom-right': initialMoveX = dims.width; initialMoveY = dims.height; moveX = -dims.width; moveY = -dims.height; break; case 'center': initialMoveX = dims.width / 2; initialMoveY = dims.height / 2; moveX = -dims.width / 2; moveY = -dims.height / 2; break; } return new Effect.Move(element, { x: initialMoveX, y: initialMoveY, duration: 0.01, beforeSetup: function(effect) { effect.element.hide().makeClipping().makePositioned(); }, afterFinishInternal: function(effect) { new Effect.Parallel( [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), new Effect.Scale(effect.element, 100, { scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) ], Object.extend({ beforeSetup: function(effect) { effect.effects[0].element.setStyle({height: '0px'}).show(); }, afterFinishInternal: function(effect) { effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); } }, options) ) } }); } Effect.Shrink = function(element) { element = $(element); var options = Object.extend({ direction: 'center', moveTransition: Effect.Transitions.sinoidal, scaleTransition: Effect.Transitions.sinoidal, opacityTransition: Effect.Transitions.none }, arguments[1] || {}); var oldStyle = { top: element.style.top, left: element.style.left, height: element.style.height, width: element.style.width, opacity: element.getInlineOpacity() }; var dims = element.getDimensions(); var moveX, moveY; switch (options.direction) { case 'top-left': moveX = moveY = 0; break; case 'top-right': moveX = dims.width; moveY = 0; break; case 'bottom-left': moveX = 0; moveY = dims.height; break; case 'bottom-right': moveX = dims.width; moveY = dims.height; break; case 'center': moveX = dims.width / 2; moveY = dims.height / 2; break; } return new Effect.Parallel( [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) ], Object.extend({ beforeStartInternal: function(effect) { effect.effects[0].element.makePositioned().makeClipping(); }, afterFinishInternal: function(effect) { effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } }, options) ); } Effect.Pulsate = function(element) { element = $(element); var options = arguments[1] || {}; var oldOpacity = element.getInlineOpacity(); var transition = options.transition || Effect.Transitions.sinoidal; var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; reverser.bind(transition); return new Effect.Opacity(element, Object.extend(Object.extend({ duration: 2.0, from: 0, afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } }, options), {transition: reverser})); } Effect.Fold = function(element) { element = $(element); var oldStyle = { top: element.style.top, left: element.style.left, width: element.style.width, height: element.style.height }; element.makeClipping(); return new Effect.Scale(element, 5, Object.extend({ scaleContent: false, scaleX: false, afterFinishInternal: function(effect) { new Effect.Scale(element, 1, { scaleContent: false, scaleY: false, afterFinishInternal: function(effect) { effect.element.hide().undoClipping().setStyle(oldStyle); } }); }}, arguments[1] || {})); }; Effect.Morph = Class.create(); Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); if(!this.element) throw(Effect._elementDoesNotExistError); var options = Object.extend({ style: '' }, arguments[1] || {}); this.start(options); }, setup: function(){ function parseColor(color){ if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; color = color.parseColor(); return $R(0,2).map(function(i){ return parseInt( color.slice(i*2+1,i*2+3), 16 ) }); } this.transforms = this.options.style.parseStyle().map(function(property){ var originalValue = this.element.getStyle(property[0]); return $H({ style: property[0], originalValue: property[1].unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), targetValue: property[1].unit=='color' ? parseColor(property[1].value) : property[1].value, unit: property[1].unit }); }.bind(this)).reject(function(transform){ return ( (transform.originalValue == transform.targetValue) || ( transform.unit != 'color' && (isNaN(transform.originalValue) || isNaN(transform.targetValue)) ) ) }); }, update: function(position) { var style = $H(), value = null; this.transforms.each(function(transform){ value = transform.unit=='color' ? $R(0,2).inject('#',function(m,v,i){ return m+(Math.round(transform.originalValue[i]+ (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) : transform.originalValue + Math.round( ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit; style[transform.style] = value; }); this.element.setStyle(style); } }); Effect.Transform = Class.create(); Object.extend(Effect.Transform.prototype, { initialize: function(tracks){ this.tracks = []; this.options = arguments[1] || {}; this.addTracks(tracks); }, addTracks: function(tracks){ tracks.each(function(track){ var data = $H(track).values().first(); this.tracks.push($H({ ids: $H(track).keys().first(), effect: Effect.Morph, options: { style: data } })); }.bind(this)); return this; }, play: function(){ return new Effect.Parallel( this.tracks.map(function(track){ var elements = [$(track.ids) || $$(track.ids)].flatten(); return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) }); }).flatten(), this.options ); } }); Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage', 'backgroundPosition', 'backgroundRepeat', 'borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderCollapse', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderSpacing', 'borderTopColor', 'borderTopStyle', 'borderTopWidth', 'bottom', 'captionSide', 'clear', 'clip', 'color', 'content', 'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction', 'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight', 'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight', 'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity', 'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore', 'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes', 'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress', 'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top', 'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows', 'width', 'wordSpacing', 'zIndex']; Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; String.prototype.parseStyle = function(){ var element = Element.extend(document.createElement('div')); element.innerHTML = '

    '; var style = element.down().style, styleRules = $H(); Element.CSS_PROPERTIES.each(function(property){ if(style[property]) styleRules[property] = style[property]; }); var result = $H(); styleRules.each(function(pair){ var property = pair[0], value = pair[1], unit = null; if(value.parseColor('#zzzzzz') != '#zzzzzz') { value = value.parseColor(); unit = 'color'; } else if(Element.CSS_LENGTH.test(value)) var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/), value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null; result[property.underscore().dasherize()] = $H({ value:value, unit:unit }); }.bind(this)); return result; }; Element.morph = function(element, style) { new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {})); return element; }; ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( function(f) { Element.Methods[f] = Element[f]; } ); Element.Methods.visualEffect = function(element, effect, options) { s = effect.gsub(/_/, '-').camelize(); effect_class = s.charAt(0).toUpperCase() + s.substring(1); new Effect[effect_class](element, options); return $(element); }; Element.addMethods();mod_fdajax-0.9/examples/rubyonrails/minichat/public/javascripts/prototype.js0000644000175000017500000021313410650177506026320 0ustar greggreg/* Prototype JavaScript framework, version 1.5.0 * (c) 2005-2007 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.5.0', BrowserFeatures: { XPath: !!document.evaluate }, 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 (var property in source) { destination[property] = source[property]; } return destination; } Object.extend(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; } }, keys: function(object) { var keys = []; for (var property in object) keys.push(property); return keys; }, values: function(object) { var values = []; for (var property in object) values.push(object[property]); return values; }, clone: function(object) { return Object.extend({}, object); } }); 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, args = $A(arguments), object = args.shift(); return function(event) { return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); } } 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, length = arguments.length; i < 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() { this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, stop: function() { if (!this.timer) return; clearInterval(this.timer); this.timer = null; }, onTimerEvent: function() { if (!this.currentlyExecuting) { try { this.currentlyExecuting = true; this.callback(this); } finally { this.currentlyExecuting = false; } } } } String.interpret = function(value){ return value == null ? '' : String(value); } Object.extend(String.prototype, { gsub: function(pattern, replacement) { var result = '', source = this, match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { result += source.slice(0, match.index); result += String.interpret(replacement(match)); source = source.slice(match.index + match[0].length); } else { result += source, source = ''; } } return result; }, sub: function(pattern, replacement, count) { replacement = this.gsub.prepareReplacement(replacement); count = count === undefined ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; return replacement(match); }); }, scan: function(pattern, iterator) { this.gsub(pattern, iterator); return this; }, truncate: function(length, truncation) { length = length || 30; truncation = truncation === undefined ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : this; }, strip: function() { return this.replace(/^\s+/, '').replace(/\s+$/, ''); }, 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(function(script) { return eval(script) }); }, 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.length > 1 ? $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) : div.childNodes[0].nodeValue) : ''; }, toQueryParams: function(separator) { var match = this.strip().match(/([^?#]*)(#.*)?$/); if (!match) return {}; return match[1].split(separator || '&').inject({}, function(hash, pair) { if ((pair = pair.split('='))[0]) { var name = decodeURIComponent(pair[0]); var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; if (hash[name] !== undefined) { if (hash[name].constructor != Array) hash[name] = [hash[name]]; if (value) hash[name].push(value); } else hash[name] = value; } return hash; }); }, toArray: function() { return this.split(''); }, succ: function() { return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); }, camelize: function() { var parts = this.split('-'), len = parts.length; if (len == 1) return parts[0]; var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0]; for (var i = 1; i < len; i++) camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized; }, capitalize: function(){ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); }, underscore: function() { return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); }, dasherize: function() { return this.gsub(/_/,'-'); }, inspect: function(useDoubleQuotes) { var escapedString = this.replace(/\\/g, '\\\\'); if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; else return "'" + escapedString.replace(/'/g, '\\\'') + "'"; } }); String.prototype.gsub.prepareReplacement = function(replacement) { if (typeof replacement == 'function') return replacement; var template = new Template(replacement); return function(match) { return template.evaluate(match) }; } String.prototype.parseQuery = String.prototype.toQueryParams; var Template = Class.create(); Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; Template.prototype = { initialize: function(template, pattern) { this.template = template.toString(); this.pattern = pattern || Template.Pattern; }, evaluate: function(object) { return this.template.gsub(this.pattern, function(match) { var before = match[1]; if (before == '\\') return match[2]; return before + String.interpret(object[match[3]]); }); } } 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; } return this; }, eachSlice: function(number, iterator) { var index = -number, slices = [], array = this.toArray(); while ((index += number) < array.length) slices.push(array.slice(index, index+number)); return slices.map(iterator); }, 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 = false; 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 || Prototype.K)(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; }, inGroupsOf: function(number, fillWith) { fillWith = fillWith === undefined ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; }); }, 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.map(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 (result == undefined || value >= result) result = value; }); return result; }, min: function(iterator) { var result; this.each(function(value, index) { value = (iterator || Prototype.K)(value, index); if (result == undefined || value < result) 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.map(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.map(); }, 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) { return iterator(collections.pluck(index)); }); }, size: function() { return this.toArray().length; }, 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, length = iterable.length; i < length; i++) results.push(iterable[i]); return results; } } Object.extend(Array.prototype, Enumerable); if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; Object.extend(Array.prototype, { _each: function(iterator) { for (var i = 0, length = this.length; i < 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 != null; }); }, flatten: function() { return this.inject([], function(array, value) { return array.concat(value && 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, length = this.length; i < length; i++) if (this[i] == object) return i; return -1; }, reverse: function(inline) { return (inline !== false ? this : this.toArray())._reverse(); }, reduce: function() { return this.length > 1 ? this : this[0]; }, uniq: function() { return this.inject([], function(array, value) { return array.include(value) ? array : array.concat([value]); }); }, clone: function() { return [].concat(this); }, size: function() { return this.length; }, inspect: function() { return '[' + this.map(Object.inspect).join(', ') + ']'; } }); Array.prototype.toArray = Array.prototype.clone; function $w(string){ string = string.strip(); return string ? string.split(/\s+/) : []; } if(window.opera){ Array.prototype.concat = function(){ var array = []; for(var i = 0, length = this.length; i < length; i++) array.push(this[i]); for(var i = 0, length = arguments.length; i < length; i++) { if(arguments[i].constructor == Array) { for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) array.push(arguments[i][j]); } else { array.push(arguments[i]); } } return array; } } var Hash = function(obj) { Object.extend(this, obj || {}); }; Object.extend(Hash, { toQueryString: function(obj) { var parts = []; this.prototype._each.call(obj, function(pair) { if (!pair.key) return; if (pair.value && pair.value.constructor == Array) { var values = pair.value.compact(); if (values.length < 2) pair.value = values.reduce(); else { key = encodeURIComponent(pair.key); values.each(function(value) { value = value != undefined ? encodeURIComponent(value) : ''; parts.push(key + '=' + encodeURIComponent(value)); }); return; } } if (pair.value == undefined) pair[1] = ''; parts.push(pair.map(encodeURIComponent).join('=')); }); return parts.join('&'); } }); Object.extend(Hash.prototype, Enumerable); Object.extend(Hash.prototype, { _each: function(iterator) { for (var key in this) { var value = this[key]; if (value && value == Hash.prototype[key]) 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(this, function(mergedHash, pair) { mergedHash[pair.key] = pair.value; return mergedHash; }); }, remove: function() { var result; for(var i = 0, length = arguments.length; i < length; i++) { var value = this[arguments[i]]; if (value !== undefined){ if (result === undefined) result = value; else { if (result.constructor != Array) result = [result]; result.push(value) } } delete this[arguments[i]]; } return result; }, toQueryString: function() { return Hash.toQueryString(this); }, inspect: function() { return '#'; } }); function $H(object) { if (object && object.constructor == Hash) return object; return new Hash(object); }; 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; while (this.include(value)) { iterator(value); value = value.succ(); } }, 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 XMLHttpRequest()}, function() {return new ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')} ) || false; }, activeRequestCount: 0 } Ajax.Responders = { responders: [], _each: function(iterator) { this.responders._each(iterator); }, register: function(responder) { if (!this.include(responder)) this.responders.push(responder); }, unregister: function(responder) { this.responders = this.responders.without(responder); }, dispatch: function(callback, request, transport, json) { this.each(function(responder) { if (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, contentType: 'application/x-www-form-urlencoded', encoding: 'UTF-8', parameters: '' } Object.extend(this.options, options || {}); this.options.method = this.options.method.toLowerCase(); if (typeof this.options.parameters == 'string') this.options.parameters = this.options.parameters.toQueryParams(); } } Ajax.Request = Class.create(); Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; Ajax.Request.prototype = Object.extend(new Ajax.Base(), { _complete: false, initialize: function(url, options) { this.transport = Ajax.getTransport(); this.setOptions(options); this.request(url); }, request: function(url) { this.url = url; this.method = this.options.method; var params = this.options.parameters; if (!['get', 'post'].include(this.method)) { // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } params = Hash.toQueryString(params); if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_=' // when GET, append parameters to URL if (this.method == 'get' && params) this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params; try { Ajax.Responders.dispatch('onCreate', this, this.transport); this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); if (this.options.asynchronous) setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); this.transport.onreadystatechange = this.onStateChange.bind(this); this.setRequestHeaders(); var body = this.method == 'post' ? (this.options.postBody || params) : null; this.transport.send(body); /* Force Firefox to handle ready state 4 for synchronous requests */ if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange(); } catch (e) { this.dispatchException(e); } }, onStateChange: function() { var readyState = this.transport.readyState; if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState); }, setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version, 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; if (this.method == 'post') { headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); /* Force "Connection: close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */ if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) headers['Connection'] = 'close'; } // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; if (typeof extras.push == 'function') for (var i = 0, length = extras.length; i < length; i += 2) headers[extras[i]] = extras[i+1]; else $H(extras).each(function(pair) { headers[pair.key] = pair.value }); } for (var name in headers) this.transport.setRequestHeader(name, headers[name]); }, success: function() { return !this.transport.status || (this.transport.status >= 200 && this.transport.status < 300); }, respondToReadyState: function(readyState) { var state = Ajax.Request.Events[readyState]; var transport = this.transport, json = this.evalJSON(); if (state == 'Complete') { try { this._complete = true; (this.options['on' + this.transport.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(transport, json); } catch (e) { this.dispatchException(e); } if ((this.getHeader('Content-type') || 'text/javascript').strip(). match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) this.evalResponse(); } try { (this.options['on' + state] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on' + state, this, transport, json); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } }, getHeader: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) { return null } }, evalJSON: function() { try { var json = this.getHeader('X-JSON'); return json ? eval('(' + json + ')') : null; } catch (e) { return null } }, evalResponse: function() { try { return eval(this.transport.responseText); } catch (e) { this.dispatchException(e); } }, 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.container = { success: (container.success || 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, param) { this.updateContent(); onComplete(transport, param); }).bind(this); this.request(url); }, updateContent: function() { var receiver = this.container[this.success() ? 'success' : 'failure']; var response = this.transport.responseText; if (!this.options.evalScripts) response = response.stripScripts(); if (receiver = $(receiver)) { if (this.options.insertion) new this.options.insertion(receiver, response); else receiver.update(response); } if (this.success()) { 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.options.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); } }); function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (typeof element == 'string') element = document.getElementById(element); return Element.extend(element); } if (Prototype.BrowserFeatures.XPath) { document._getElementsByXPath = function(expression, parentElement) { var results = []; var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, length = query.snapshotLength; i < length; i++) results.push(query.snapshotItem(i)); return results; }; } document.getElementsByClassName = function(className, parentElement) { if (Prototype.BrowserFeatures.XPath) { var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; return document._getElementsByXPath(q, parentElement); } else { var children = ($(parentElement) || document.body).getElementsByTagName('*'); var elements = [], child; for (var i = 0, length = children.length; i < length; i++) { child = children[i]; if (Element.hasClassName(child, className)) elements.push(Element.extend(child)); } return elements; } }; /*--------------------------------------------------------------------------*/ if (!window.Element) var Element = new Object(); Element.extend = function(element) { if (!element || _nativeExtensions || element.nodeType == 3) return element; if (!element._extended && element.tagName && element != window) { var methods = Object.clone(Element.Methods), cache = Element.extend.cache; if (element.tagName == 'FORM') Object.extend(methods, Form.Methods); if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName)) Object.extend(methods, Form.Element.Methods); Object.extend(methods, Element.Methods.Simulated); for (var property in methods) { var value = methods[property]; if (typeof value == 'function' && !(property in element)) element[property] = cache.findOrStore(value); } } element._extended = true; return element; }; Element.extend.cache = { findOrStore: function(value) { return this[value] = this[value] || function() { return value.apply(null, [this].concat($A(arguments))); } } }; Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, toggle: function(element) { element = $(element); Element[Element.visible(element) ? 'hide' : 'show'](element); return element; }, hide: function(element) { $(element).style.display = 'none'; return element; }, show: function(element) { $(element).style.display = ''; return element; }, remove: function(element) { element = $(element); element.parentNode.removeChild(element); return element; }, update: function(element, html) { html = typeof html == 'undefined' ? '' : html.toString(); $(element).innerHTML = html.stripScripts(); setTimeout(function() {html.evalScripts()}, 10); return element; }, replace: function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); if (element.outerHTML) { element.outerHTML = html.stripScripts(); } else { var range = element.ownerDocument.createRange(); range.selectNodeContents(element); element.parentNode.replaceChild( range.createContextualFragment(html.stripScripts()), element); } setTimeout(function() {html.evalScripts()}, 10); return element; }, inspect: function(element) { element = $(element); var result = '<' + element.tagName.toLowerCase(); $H({'id': 'id', 'className': 'class'}).each(function(pair) { var property = pair.first(), attribute = pair.last(); var value = (element[property] || '').toString(); if (value) result += ' ' + attribute + '=' + value.inspect(true); }); return result + '>'; }, recursivelyCollect: function(element, property) { element = $(element); var elements = []; while (element = element[property]) if (element.nodeType == 1) elements.push(Element.extend(element)); return elements; }, ancestors: function(element) { return $(element).recursivelyCollect('parentNode'); }, descendants: function(element) { return $A($(element).getElementsByTagName('*')); }, immediateDescendants: function(element) { if (!(element = $(element).firstChild)) return []; while (element && element.nodeType != 1) element = element.nextSibling; if (element) return [element].concat($(element).nextSiblings()); return []; }, previousSiblings: function(element) { return $(element).recursivelyCollect('previousSibling'); }, nextSiblings: function(element) { return $(element).recursivelyCollect('nextSibling'); }, siblings: function(element) { element = $(element); return element.previousSiblings().reverse().concat(element.nextSiblings()); }, match: function(element, selector) { if (typeof selector == 'string') selector = new Selector(selector); return selector.match($(element)); }, up: function(element, expression, index) { return Selector.findElement($(element).ancestors(), expression, index); }, down: function(element, expression, index) { return Selector.findElement($(element).descendants(), expression, index); }, previous: function(element, expression, index) { return Selector.findElement($(element).previousSiblings(), expression, index); }, next: function(element, expression, index) { return Selector.findElement($(element).nextSiblings(), expression, index); }, getElementsBySelector: function() { var args = $A(arguments), element = $(args.shift()); return Selector.findChildElements(element, args); }, getElementsByClassName: function(element, className) { return document.getElementsByClassName(className, element); }, readAttribute: function(element, name) { element = $(element); if (document.all && !window.opera) { var t = Element._attributeTranslations; if (t.values[name]) return t.values[name](element, name); if (t.names[name]) name = t.names[name]; var attribute = element.attributes[name]; if(attribute) return attribute.nodeValue; } return element.getAttribute(name); }, getHeight: function(element) { return $(element).getDimensions().height; }, getWidth: function(element) { return $(element).getDimensions().width; }, classNames: function(element) { return new Element.ClassNames(element); }, hasClassName: function(element, className) { if (!(element = $(element))) return; var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true; return false; }, addClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).add(className); return element; }, removeClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).remove(className); return element; }, toggleClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); return element; }, observe: function() { Event.observe.apply(Event, arguments); return $A(arguments).first(); }, stopObserving: function() { Event.stopObserving.apply(Event, arguments); return $A(arguments).first(); }, // removes whitespace-only text node children cleanWhitespace: function(element) { element = $(element); var node = element.firstChild; while (node) { var nextNode = node.nextSibling; if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node); node = nextNode; } return element; }, empty: function(element) { return $(element).innerHTML.match(/^\s*$/); }, descendantOf: function(element, ancestor) { element = $(element), ancestor = $(ancestor); while (element = element.parentNode) if (element == ancestor) return true; return false; }, scrollTo: function(element) { element = $(element); var pos = Position.cumulativeOffset(element); window.scrollTo(pos[0], pos[1]); return element; }, getStyle: function(element, style) { element = $(element); if (['float','cssFloat'].include(style)) style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat'); style = style.camelize(); var value = element.style[style]; if (!value) { if (document.defaultView && document.defaultView.getComputedStyle) { var css = document.defaultView.getComputedStyle(element, null); value = css ? css[style] : null; } else if (element.currentStyle) { value = element.currentStyle[style]; } } if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none')) value = element['offset'+style.capitalize()] + 'px'; if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) if (Element.getStyle(element, 'position') == 'static') value = 'auto'; if(style == 'opacity') { if(value) return parseFloat(value); if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if(value[1]) return parseFloat(value[1]) / 100; return 1.0; } return value == 'auto' ? null : value; }, setStyle: function(element, style) { element = $(element); for (var name in style) { var value = style[name]; if(name == 'opacity') { if (value == 1) { value = (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0; if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); } else if(value == '') { if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); } else { if(value < 0.00001) value = 0; if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+value*100+')'; } } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat'; element.style[name.camelize()] = value; } return element; }, getDimensions: function(element) { element = $(element); var display = $(element).getStyle('display'); if (display != 'none' && display != null) // Safari bug 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; var originalDisplay = els.display; els.visibility = 'hidden'; els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; els.display = originalDisplay; 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; } } return element; }, 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 = ''; } return element; }, makeClipping: function(element) { element = $(element); if (element._overflow) return element; element._overflow = element.style.overflow || 'auto'; if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden'; return element; }, undoClipping: function(element) { element = $(element); if (!element._overflow) return element; element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; element._overflow = null; return element; } }; Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf}); Element._attributeTranslations = {}; Element._attributeTranslations.names = { colspan: "colSpan", rowspan: "rowSpan", valign: "vAlign", datetime: "dateTime", accesskey: "accessKey", tabindex: "tabIndex", enctype: "encType", maxlength: "maxLength", readonly: "readOnly", longdesc: "longDesc" }; Element._attributeTranslations.values = { _getAttr: function(element, attribute) { return element.getAttribute(attribute, 2); }, _flag: function(element, attribute) { return $(element).hasAttribute(attribute) ? attribute : null; }, style: function(element) { return element.style.cssText.toLowerCase(); }, title: function(element) { var node = element.getAttributeNode('title'); return node.specified ? node.nodeValue : null; } }; Object.extend(Element._attributeTranslations.values, { href: Element._attributeTranslations.values._getAttr, src: Element._attributeTranslations.values._getAttr, disabled: Element._attributeTranslations.values._flag, checked: Element._attributeTranslations.values._flag, readonly: Element._attributeTranslations.values._flag, multiple: Element._attributeTranslations.values._flag }); Element.Methods.Simulated = { hasAttribute: function(element, attribute) { var t = Element._attributeTranslations; attribute = t.names[attribute] || attribute; return $(element).getAttributeNode(attribute).specified; } }; // IE is missing .innerHTML support for TABLE-related elements if (document.all && !window.opera){ Element.Methods.update = function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); var tagName = element.tagName.toUpperCase(); if (['THEAD','TBODY','TR','TD'].include(tagName)) { var div = document.createElement('div'); switch (tagName) { case 'THEAD': case 'TBODY': div.innerHTML = '' + html.stripScripts() + '
    '; depth = 2; break; case 'TR': div.innerHTML = '' + html.stripScripts() + '
    '; depth = 3; break; case 'TD': div.innerHTML = '
    ' + html.stripScripts() + '
    '; depth = 4; } $A(element.childNodes).each(function(node){ element.removeChild(node) }); depth.times(function(){ div = div.firstChild }); $A(div.childNodes).each( function(node){ element.appendChild(node) }); } else { element.innerHTML = html.stripScripts(); } setTimeout(function() {html.evalScripts()}, 10); return element; } }; Object.extend(Element, Element.Methods); var _nativeExtensions = false; if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) { var className = 'HTML' + tag + 'Element'; if(window[className]) return; var klass = window[className] = {}; klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__; }); Element.addMethods = function(methods) { Object.extend(Element.Methods, methods || {}); function copy(methods, destination, onlyIfAbsent) { onlyIfAbsent = onlyIfAbsent || false; var cache = Element.extend.cache; for (var property in methods) { var value = methods[property]; if (!onlyIfAbsent || !(property in destination)) destination[property] = cache.findOrStore(value); } } if (typeof HTMLElement != 'undefined') { copy(Element.Methods, HTMLElement.prototype); copy(Element.Methods.Simulated, HTMLElement.prototype, true); copy(Form.Methods, HTMLFormElement.prototype); [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) { copy(Form.Element.Methods, klass.prototype); }); _nativeExtensions = true; } } 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) { var tagName = this.element.tagName.toUpperCase(); if (['TBODY', 'TR'].include(tagName)) { 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($A(this).concat(classNameToAdd).join(' ')); }, remove: function(classNameToRemove) { if (!this.include(classNameToRemove)) return; this.set($A(this).without(classNameToRemove).join(' ')); }, toString: function() { return $A(this).join(' '); } }; Object.extend(Element.ClassNames.prototype, Enumerable); var Selector = Class.create(); Selector.prototype = { initialize: function(expression) { this.params = {classNames: []}; this.expression = expression.toString().strip(); this.parseExpression(); this.compileMatcher(); }, parseExpression: function() { function abort(message) { throw 'Parse error in selector: ' + message; } if (this.expression == '') abort('empty expression'); var params = this.params, expr = this.expression, match, modifier, clause, rest; while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { params.attributes = params.attributes || []; params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); expr = match[1]; } if (expr == '*') return this.params.wildcard = true; while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { modifier = match[1], clause = match[2], rest = match[3]; switch (modifier) { case '#': params.id = clause; break; case '.': params.classNames.push(clause); break; case '': case undefined: params.tagName = clause.toUpperCase(); break; default: abort(expr.inspect()); } expr = rest; } if (expr.length > 0) abort(expr.inspect()); }, buildMatchExpression: function() { var params = this.params, conditions = [], clause; if (params.wildcard) conditions.push('true'); if (clause = params.id) conditions.push('element.readAttribute("id") == ' + clause.inspect()); if (clause = params.tagName) conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); if ((clause = params.classNames).length > 0) for (var i = 0, length = clause.length; i < length; i++) conditions.push('element.hasClassName(' + clause[i].inspect() + ')'); if (clause = params.attributes) { clause.each(function(attribute) { var value = 'element.readAttribute(' + attribute.name.inspect() + ')'; var splitValueBy = function(delimiter) { return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; } switch (attribute.operator) { case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; case '|=': conditions.push( splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() ); break; case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; case '': case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break; default: throw 'Unknown operator ' + attribute.operator + ' in selector'; } }); } return conditions.join(' && '); }, compileMatcher: function() { this.match = new Function('element', 'if (!element.tagName) return false; \ element = $(element); \ return ' + this.buildMatchExpression()); }, findElements: function(scope) { var element; if (element = $(this.params.id)) if (this.match(element)) if (!scope || Element.childOf(element, scope)) return [element]; scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); var results = []; for (var i = 0, length = scope.length; i < length; i++) if (this.match(element = scope[i])) results.push(Element.extend(element)); return results; }, toString: function() { return this.expression; } } Object.extend(Selector, { matchElements: function(elements, expression) { var selector = new Selector(expression); return elements.select(selector.match.bind(selector)).map(Element.extend); }, findElement: function(elements, expression, index) { if (typeof expression == 'number') index = expression, expression = false; return Selector.matchElements(elements, expression || '*')[index || 0]; }, findChildElements: function(element, expressions) { return expressions.map(function(expression) { return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) { var selector = new Selector(expr); return results.inject([], function(elements, result) { return elements.concat(selector.findElements(result || element)); }); }); }).flatten(); } }); function $$() { return Selector.findChildElements(document, $A(arguments)); } var Form = { reset: function(form) { $(form).reset(); return form; }, serializeElements: function(elements, getHash) { var data = elements.inject({}, function(result, element) { if (!element.disabled && element.name) { var key = element.name, value = $(element).getValue(); if (value != undefined) { if (result[key]) { if (result[key].constructor != Array) result[key] = [result[key]]; result[key].push(value); } else result[key] = value; } } return result; }); return getHash ? data : Hash.toQueryString(data); } }; Form.Methods = { serialize: function(form, getHash) { return Form.serializeElements(Form.getElements(form), getHash); }, getElements: function(form) { return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) { if (Form.Element.Serializers[child.tagName.toLowerCase()]) elements.push(Element.extend(child)); return elements; } ); }, getInputs: function(form, typeName, name) { form = $(form); var inputs = form.getElementsByTagName('input'); if (!typeName && !name) return $A(inputs).map(Element.extend); for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { var input = inputs[i]; if ((typeName && input.type != typeName) || (name && input.name != name)) continue; matchingInputs.push(Element.extend(input)); } return matchingInputs; }, disable: function(form) { form = $(form); form.getElements().each(function(element) { element.blur(); element.disabled = 'true'; }); return form; }, enable: function(form) { form = $(form); form.getElements().each(function(element) { element.disabled = ''; }); return form; }, findFirstElement: function(form) { return $(form).getElements().find(function(element) { return element.type != 'hidden' && !element.disabled && ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); }); }, focusFirstElement: function(form) { form = $(form); form.findFirstElement().activate(); return form; } } Object.extend(Form, Form.Methods); /*--------------------------------------------------------------------------*/ Form.Element = { focus: function(element) { $(element).focus(); return element; }, select: function(element) { $(element).select(); return element; } } Form.Element.Methods = { serialize: function(element) { element = $(element); if (!element.disabled && element.name) { var value = element.getValue(); if (value != undefined) { var pair = {}; pair[element.name] = value; return Hash.toQueryString(pair); } } return ''; }, getValue: function(element) { element = $(element); var method = element.tagName.toLowerCase(); return Form.Element.Serializers[method](element); }, clear: function(element) { $(element).value = ''; return element; }, present: function(element) { return $(element).value != ''; }, activate: function(element) { element = $(element); element.focus(); if (element.select && ( element.tagName.toLowerCase() != 'input' || !['button', 'reset', 'submit'].include(element.type) ) ) element.select(); return element; }, disable: function(element) { element = $(element); element.disabled = true; return element; }, enable: function(element) { element = $(element); element.blur(); element.disabled = false; return element; } } Object.extend(Form.Element, Form.Element.Methods); var Field = Form.Element; var $F = Form.Element.getValue; /*--------------------------------------------------------------------------*/ Form.Element.Serializers = { input: function(element) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': return Form.Element.Serializers.inputSelector(element); default: return Form.Element.Serializers.textarea(element); } }, inputSelector: function(element) { return element.checked ? element.value : null; }, textarea: function(element) { return element.value; }, select: function(element) { return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element); }, selectOne: function(element) { var index = element.selectedIndex; return index >= 0 ? this.optionValue(element.options[index]) : null; }, selectMany: function(element) { var values, length = element.length; if (!length) return null; for (var i = 0, values = []; i < length; i++) { var opt = element.options[i]; if (opt.selected) values.push(this.optionValue(opt)); } return values; }, optionValue: function(opt) { // extend element because hasAttribute may not be native return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; } } /*--------------------------------------------------------------------------*/ 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(); var changed = ('string' == typeof this.lastValue && 'string' == typeof value ? this.lastValue != value : String(this.lastValue) != String(value)); if (changed) { 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() { Form.getElements(this.element).each(this.registerCallback.bind(this)); }, registerCallback: function(element) { if (element.type) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': Event.observe(element, 'click', this.onElementEvent.bind(this)); break; default: 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, KEY_HOME: 36, KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, 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, length = Event.observers.length; i < length; i++) { Event.stopObserving.apply(this, Event.observers[i]); Event.observers[i][0] = null; } Event.observers = false; }, observe: function(element, name, observer, useCapture) { element = $(element); useCapture = useCapture || false; if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent)) name = 'keydown'; Event._observeAndCache(element, name, observer, useCapture); }, stopObserving: function(element, name, observer, useCapture) { 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) { try { element.detachEvent('on' + name, observer); } catch (e) {} } } }); /* prevent memory leaks in IE */ if (navigator.appVersion.match(/\bMSIE\b/)) 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) { if(element.tagName=='BODY') break; var 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; }, 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 { if (!window.opera || element.tagName=='BODY') { 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]; } } Element.addMethods();mod_fdajax-0.9/examples/rubyonrails/minichat/vendor/0000755000175000017500000000000010652360363021374 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/vendor/plugins/0000755000175000017500000000000010652360363023055 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/db/0000755000175000017500000000000010652360363020464 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/db/schema.rb0000644000175000017500000000063210650177505022254 0ustar greggreg# This file is autogenerated. Instead of editing this file, please use the # migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. ActiveRecord::Schema.define(:version => 1) do create_table "users", :force => true do |t| t.column "name", :string t.column "password", :string t.column "login_state", :string end end mod_fdajax-0.9/examples/rubyonrails/minichat/db/migrate/0000755000175000017500000000000010652360363022114 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/db/migrate/001_create_users.rb0000644000175000017500000000040710650177505025510 0ustar greggregclass CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.column :name, :string t.column :password, :string t.column :login_state, :string end end def self.down drop_table :users end end mod_fdajax-0.9/examples/rubyonrails/minichat/Rakefile0000644000175000017500000000046310650177506021552 0ustar greggreg# Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require(File.join(File.dirname(__FILE__), 'config', 'boot')) require 'rake' require 'rake/testtask' require 'rake/rdoctask' require 'tasks/rails' mod_fdajax-0.9/examples/rubyonrails/minichat/script/0000755000175000017500000000000010652360363021403 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/script/runner0000755000175000017500000000014010650177505022637 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/runner'mod_fdajax-0.9/examples/rubyonrails/minichat/script/about0000755000175000017500000000013710650177505022446 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/about'mod_fdajax-0.9/examples/rubyonrails/minichat/script/destroy0000755000175000017500000000014110650177505023020 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/destroy'mod_fdajax-0.9/examples/rubyonrails/minichat/script/plugin0000755000175000017500000000014010650177505022624 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/plugin'mod_fdajax-0.9/examples/rubyonrails/minichat/script/generate0000755000175000017500000000014210650177505023122 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/generate'mod_fdajax-0.9/examples/rubyonrails/minichat/script/process/0000755000175000017500000000000010652360363023061 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/script/process/reaper0000755000175000017500000000015410650177505024267 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../config/boot' require 'commands/process/reaper' mod_fdajax-0.9/examples/rubyonrails/minichat/script/process/spawner0000755000175000017500000000015510650177505024471 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../config/boot' require 'commands/process/spawner' mod_fdajax-0.9/examples/rubyonrails/minichat/script/process/inspector0000755000175000017500000000015710650177505025022 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../config/boot' require 'commands/process/inspector' mod_fdajax-0.9/examples/rubyonrails/minichat/script/server0000755000175000017500000000014010650177505022634 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/server'mod_fdajax-0.9/examples/rubyonrails/minichat/script/breakpointer0000755000175000017500000000014610650177505024021 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/breakpointer'mod_fdajax-0.9/examples/rubyonrails/minichat/script/console0000755000175000017500000000014110650177505022771 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../config/boot' require 'commands/console'mod_fdajax-0.9/examples/rubyonrails/minichat/script/performance/0000755000175000017500000000000010652360363023704 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/script/performance/benchmarker0000755000175000017500000000016510650177505026117 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../config/boot' require 'commands/performance/benchmarker' mod_fdajax-0.9/examples/rubyonrails/minichat/script/performance/profiler0000755000175000017500000000016210650177505025455 0ustar greggreg#!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../config/boot' require 'commands/performance/profiler' mod_fdajax-0.9/examples/rubyonrails/minichat/app/0000755000175000017500000000000010652360363020657 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/controllers/0000755000175000017500000000000010652360363023225 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/controllers/minichat_controller.rb0000644000175000017500000000376010650177505027621 0ustar greggregclass MinichatController < ApplicationController before_filter :authorize, :only => [:index, :new_message, :logout] def login session[:user_id] = nil if request.post? user = User.authenticate(params[:name], params[:password]) if user session[:user_id] = user.id cmd = "cmd=login&user_id=" + user.id.to_s + "&sess_id=" + session.session_id + "&ip_addr=" + request.remote_ip logger.info Net::HTTP.get_response('127.0.0.1', '/live.fdajax?' + cmd, 3000).body redirect_to(:action => "index" ) else flash[:notice] = "Invalid user/password combination" end end end def logout cmd = "cmd=logout&user_id=" + session[:user_id].to_s logger.info Net::HTTP.get_response('127.0.0.1', '/live.fdajax?' + cmd, 3000).body User.logout(session[:user_id]) session[:user_id] = nil flash[:notice] = "Logged out" redirect_to("/") end def index @created = Time.now @user = User.find(session[:user_id]) @others = User.find(:all, :conditions => ["login_state = 'in' AND id != ? ", @user.id]).map {|u| u.name } end def new_message @user = User.find(session[:user_id]) @new_message = params[:message] respond_to do |wants| wants.js do render :update do |page| page.insert_html :bottom, "chat_output", :partial => "new_message" page << "$('chat_output').scrollTop = $('chat_output').scrollHeight;" page << "Field.clear('message');" page << "Field.focus('message');" end end end User.find(:all, :conditions => ["login_state = 'in' AND id != ? ", @user.id]).each do |peer| cmd = "cmd=push&types=chat&peer_id=" + peer.id.to_s + "&mes=" + CGI::escape(response.body) logger.info Net::HTTP.get_response('127.0.0.1', '/live.fdajax?' + cmd, 3000).body end end private def authorize unless User.find_by_id(session[:user_id]) flash[:notice] = "Please log in" redirect_to(:action => "login" ) end end end mod_fdajax-0.9/examples/rubyonrails/minichat/app/controllers/application.rb0000644000175000017500000000051710650177505026062 0ustar greggreg# Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. class ApplicationController < ActionController::Base # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_minichat_session_id' end mod_fdajax-0.9/examples/rubyonrails/minichat/app/controllers/admin_controller.rb0000644000175000017500000000206710650177505027114 0ustar greggregclass AdminController < ApplicationController def index list render :action => 'list' end # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :action => :list } def list @user_pages, @users = paginate :users, :per_page => 10 end def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = 'User was successfully created.' redirect_to :action => 'list' else render :action => 'new' end end def edit @user = User.find(params[:id]) end def update @user = User.find(params[:id]) if @user.update_attributes(params[:user]) flash[:notice] = 'User was successfully updated.' redirect_to :action => 'show', :id => @user else render :action => 'edit' end end def destroy User.find(params[:id]).destroy redirect_to :action => 'list' end end mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/0000755000175000017500000000000010652360363022014 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/views/layouts/0000755000175000017500000000000010652360363023514 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/views/layouts/minichat.rhtml0000644000175000017500000000105110650177505026357 0ustar greggreg Minichat with FdAjax <%= stylesheet_link_tag "scaffold" , "screen" , :media => "all" %> <%= javascript_include_tag "prototype" %> <%= javascript_include_tag "fdajax" %> <%= javascript_include_tag "application" %> <% if flash[:notice] -%>
    <%= flash[:notice] %>
    <% end -%> <%= yield :layout %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/layouts/admin.rhtml0000644000175000017500000000072410650177505025661 0ustar greggreg Admin: <%= controller.action_name %> <%= stylesheet_link_tag 'scaffold' %>

    <%= flash[:notice] %>

    <%= yield %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/minichat/0000755000175000017500000000000010652360363023610 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/views/minichat/login.rhtml0000644000175000017500000000046410650177505025776 0ustar greggreg
    Please Log In <% form_tag do %>

    <%= text_field_tag :name, params[:name] %>

    <%= password_field_tag :password, params[:password] %>

    <%= submit_tag "Login" %>

    <% end %>
    mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/minichat/index.rhtml0000644000175000017500000000123410650177505025771 0ustar greggreg

    Hello <%= @user.name %> in Minichat FdAjax example

    <% if @others.size > 0 -%> Currently the following users are in this chat session: <%= @others.to_sentence %> <% else -%> There are no others users in this chat session. <% end -%>
    <% form_remote_tag :url => { :action => "new_message" } do -%> <% end -%>
    <%= link_to "Logout", :action => "logout" %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/minichat/_new_message.rhtml0000644000175000017500000000013210650177505027312 0ustar greggreg
  • <%=h @user.name %>: <%=h @new_message %>
  • mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/0000755000175000017500000000000010652360363023104 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/edit.rhtml0000644000175000017500000000036610650177505025110 0ustar greggreg

    Editing user

    <% form_tag :action => 'update', :id => @user do %> <%= render :partial => 'form' %> <%= submit_tag 'Edit' %> <% end %> <%= link_to 'Show', :action => 'show', :id => @user %> | <%= link_to 'Back', :action => 'list' %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/new.rhtml0000644000175000017500000000025510650177505024751 0ustar greggreg

    New user

    <% form_tag :action => 'create' do %> <%= render :partial => 'form' %> <%= submit_tag "Create" %> <% end %> <%= link_to 'Back', :action => 'list' %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/_form.rhtml0000644000175000017500000000040110650177505025253 0ustar greggreg<%= error_messages_for 'user' %>


    <%= text_field 'user', 'name' %>


    <%= password_field 'user', 'password' %>

    mod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/list.rhtml0000644000175000017500000000151410650177505025132 0ustar greggreg

    Listing users

    <% for column in User.content_columns %> <% end %> <% for user in @users %> <% for column in User.content_columns %> <% end %> <% end %>
    <%= column.human_name %>
    <%=h user.send(column.name) %><%= link_to 'Show', :action => 'show', :id => user %> <%= link_to 'Edit', :action => 'edit', :id => user %> <%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %>
    <%= link_to 'Previous page', { :page => @user_pages.current.previous } if @user_pages.current.previous %> <%= link_to 'Next page', { :page => @user_pages.current.next } if @user_pages.current.next %>
    <%= link_to 'New user', :action => 'new' %>
    Main pagemod_fdajax-0.9/examples/rubyonrails/minichat/app/views/admin/show.rhtml0000644000175000017500000000034210650177505025135 0ustar greggreg<% for column in User.content_columns %>

    <%= column.human_name %>: <%=h @user.send(column.name) %>

    <% end %> <%= link_to 'Edit', :action => 'edit', :id => @user %> | <%= link_to 'Back', :action => 'list' %> mod_fdajax-0.9/examples/rubyonrails/minichat/app/models/0000755000175000017500000000000010652360363022142 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/models/user.rb0000644000175000017500000000074510650177505023455 0ustar greggregclass User < ActiveRecord::Base validates_inclusion_of :login_state, :in => ["in","out"], :allow_nil => true def self.authenticate(name, password) user = self.find_by_name(name) if user if user.password != password user = nil else user.login_state = "in" user.save user end end end def self.logout(user_id) if user = self.find_by_id(user_id) user.login_state = "out" user.save end end end mod_fdajax-0.9/examples/rubyonrails/minichat/app/helpers/0000755000175000017500000000000010652360363022321 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/app/helpers/minichat_helper.rb0000644000175000017500000000003210650177505025776 0ustar greggregmodule MinichatHelper end mod_fdajax-0.9/examples/rubyonrails/minichat/app/helpers/application_helper.rb0000644000175000017500000000016310650177505026512 0ustar greggreg# Methods added to this helper will be available to all templates in the application. module ApplicationHelper end mod_fdajax-0.9/examples/rubyonrails/minichat/app/helpers/admin_helper.rb0000644000175000017500000000002710650177505025276 0ustar greggregmodule AdminHelper end mod_fdajax-0.9/examples/rubyonrails/minichat/components/0000755000175000017500000000000010652360363022264 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/tmp/0000755000175000017500000000000010652360363020677 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/tmp/cache/0000755000175000017500000000000010652360363021742 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/tmp/pids/0000755000175000017500000000000010652360363021636 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/tmp/sockets/0000755000175000017500000000000010652360363022352 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/tmp/sessions/0000755000175000017500000000000010652360363022545 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/lib/0000755000175000017500000000000010652360363020645 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/lib/tasks/0000755000175000017500000000000010652360363021772 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/0000755000175000017500000000000010652360363021056 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/mocks/0000755000175000017500000000000010652360363022172 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/mocks/development/0000755000175000017500000000000010652360363024514 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/mocks/test/0000755000175000017500000000000010652360363023151 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/fixtures/0000755000175000017500000000000010652360363022727 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/fixtures/users.yml0000644000175000017500000000014310650177505024613 0ustar greggreg# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 two: id: 2 mod_fdajax-0.9/examples/rubyonrails/minichat/test/unit/0000755000175000017500000000000010652360363022035 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/unit/user_test.rb0000644000175000017500000000027710650177505024407 0ustar greggregrequire File.dirname(__FILE__) + '/../test_helper' class UserTest < Test::Unit::TestCase fixtures :users # Replace this with your real tests. def test_truth assert true end end mod_fdajax-0.9/examples/rubyonrails/minichat/test/functional/0000755000175000017500000000000010652360363023220 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/functional/admin_controller_test.rb0000644000175000017500000000340310650177505030141 0ustar greggregrequire File.dirname(__FILE__) + '/../test_helper' require 'admin_controller' # Re-raise errors caught by the controller. class AdminController; def rescue_action(e) raise e end; end class AdminControllerTest < Test::Unit::TestCase fixtures :users def setup @controller = AdminController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @first_id = users(:first).id end def test_index get :index assert_response :success assert_template 'list' end def test_list get :list assert_response :success assert_template 'list' assert_not_nil assigns(:users) end def test_show get :show, :id => @first_id assert_response :success assert_template 'show' assert_not_nil assigns(:user) assert assigns(:user).valid? end def test_new get :new assert_response :success assert_template 'new' assert_not_nil assigns(:user) end def test_create num_users = User.count post :create, :user => {} assert_response :redirect assert_redirected_to :action => 'list' assert_equal num_users + 1, User.count end def test_edit get :edit, :id => @first_id assert_response :success assert_template 'edit' assert_not_nil assigns(:user) assert assigns(:user).valid? end def test_update post :update, :id => @first_id assert_response :redirect assert_redirected_to :action => 'show', :id => @first_id end def test_destroy assert_nothing_raised { User.find(@first_id) } post :destroy, :id => @first_id assert_response :redirect assert_redirected_to :action => 'list' assert_raise(ActiveRecord::RecordNotFound) { User.find(@first_id) } end end mod_fdajax-0.9/examples/rubyonrails/minichat/test/functional/minichat_controller_test.rb0000644000175000017500000000075210650177505030651 0ustar greggregrequire File.dirname(__FILE__) + '/../test_helper' require 'minichat_controller' # Re-raise errors caught by the controller. class MinichatController; def rescue_action(e) raise e end; end class MinichatControllerTest < Test::Unit::TestCase def setup @controller = MinichatController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end # Replace this with your real tests. def test_truth assert true end end mod_fdajax-0.9/examples/rubyonrails/minichat/test/integration/0000755000175000017500000000000010652360363023401 5ustar greggregmod_fdajax-0.9/examples/rubyonrails/minichat/test/test_helper.rb0000644000175000017500000000244510650177505023730 0ustar greggregENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' class Test::Unit::TestCase # Transactional fixtures accelerate your tests by wrapping each test method # in a transaction that's rolled back on completion. This ensures that the # test database remains unchanged so your fixtures don't have to be reloaded # between every test method. Fewer database queries means faster tests. # # Read Mike Clark's excellent walkthrough at # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting # # Every Active Record database supports transactions except MyISAM tables # in MySQL. Turn off transactional fixtures in this case; however, if you # don't care one way or the other, switching from MyISAM to InnoDB tables # is recommended. self.use_transactional_fixtures = true # Instantiated fixtures are slow, but give you @david where otherwise you # would need people(:david). If you don't want to migrate your existing # test cases which use the @david style and don't mind the speed hit (each # instantiated fixtures translates to a database query per test method), # then set this back to true. self.use_instantiated_fixtures = false # Add more helper methods to be used by all tests here... end mod_fdajax-0.9/examples/php/0000755000175000017500000000000010652360363014521 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/0000755000175000017500000000000010652360363017170 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/README0000644000175000017500000000017410650177505020054 0ustar greggregTo start this example execute following command: lighttpd -D -f lighttpd.conf Then open this page: http://localhost:3000 mod_fdajax-0.9/examples/php/hydeparkchat/log/0000755000175000017500000000000010652360363017751 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/lighttpd.conf0000644000175000017500000000632610650177505021667 0ustar greggreg# Default configuration file for the lighttpd web server # Start using ./script/server lighttpd server.bind = "0.0.0.0" server.port = 3000 server.modules = ( "mod_rewrite", "mod_accesslog", "mod_fdajax", "mod_fastcgi", "mod_compress", "mod_expire" ) server.pid-file = CWD + "/tmp/pids/lighttpd.pid" server.document-root = CWD + "/public/" server.errorlog = CWD + "/log/lighttpd.error.log" accesslog.filename = CWD + "/log/lighttpd.access.log" url.rewrite = ( "^/$" => "index.php" ) compress.filetype = ( "text/plain", "text/html", "text/css", "text/javascript" ) compress.cache-dir = CWD + "/tmp/cache" expire.url = ( "/favicon.ico" => "access 3 days", "/images/" => "access 3 days", "/stylesheets/" => "access 3 days", "/javascripts/" => "access 3 days" ) fastcgi.server = ( ".php" => (( "bin-path" => "/usr/bin/php5-cgi", "socket" => CWD + "/tmp/sockets/php.socket", "max-procs" => 2, "bin-environment" => ( "PHP_FCGI_CHILDREN" => "2", "PHP_FCGI_MAX_REQUESTS" => "10000" ), "bin-copy-environment" => ( "PATH", "SHELL", "USER" ), "broken-scriptfilename" => "enable" ))) mimetype.assign = ( ".css" => "text/css", ".gif" => "image/gif", ".htm" => "text/html", ".html" => "text/html", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".js" => "text/javascript", ".png" => "image/png", ".swf" => "application/x-shockwave-flash", ".txt" => "text/plain" ) # Making sure file uploads above 64k always work when using IE or Safari # For more information, see http://trac.lighttpd.net/trac/ticket/360 $HTTP["useragent"] =~ "^(.*MSIE.*)|(.*AppleWebKit.*)$" { server.max-keep-alive-requests = 0 } # Full-Duplex Ajax module configuration fdajax.ext = "fdajax" fdajax.admin_ips = ( "127.0.0.1", "192.168.0.110" ) fdajax.allow_peer_call = ( "chat", "gchat" ) fdajax.allow_guests = "enable" fdajax.mes_live_max = 5000 fdajax.win_timeout = 5000 fdajax.log_level = 3 fdajax.log_security = 3 fdajax.send_pings = 0 fdajax.js_no_guests = "fdajax.no_guests();" fdajax.js_peer_func = "fdajax.peer_call" fdajax.js_grp_peer_func = "fdajax.grp_peer_call" fdajax.js_logout_code = "fdajax.stoploop();" fdajax.js_maxwin_code = "fdajax.maxwin();" fdajax.js_nocookies = "fdajax.nocookies();" fdajax.js_ping_code = "fdajax.ping();" fdajax.js_notfound = "fdajax.notfound();" fdajax.js_relogin = "fdajax.relogin" fdajax.js_redirect = "fdajax.redirect" fdajax.js_alert_id_func = "unw.set_alert_id" fdajax.unw_prefix = "unw." fdajax.session_cookie = "PHPSESSID" fdajax.merge_messages = "enable" fdajax.check_user_ip = "enable" fdajax.send_redirects = "enable" fdajax.html_begin = "FdAjax Stream" mod_fdajax-0.9/examples/php/hydeparkchat/public/0000755000175000017500000000000010652360363020446 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/public/index.php0000644000175000017500000000454010650177505022273 0ustar greggreg

    Hyde Park Chat FdAjax example

    My nickname:
    FdAjax Module Status mod_fdajax-0.9/examples/php/hydeparkchat/public/javascripts/0000755000175000017500000000000010652360363022777 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/public/javascripts/fdajax.js0000644000175000017500000000717010650177505024601 0ustar greggreg/* Full-duplex Ajax module for Lighttpd, version 0.8 * (c) 2007 Grzegorz Daniluk /*--------------------------------------------------------------------------*/ var fdajax = { server_url: "/live.fdajax", run_loop: false, user_id: 0, win_id: 0, ev_types: "", cur_req: null, from_sec: 0, from_usec: 0, first: true, waitForEvent: function(user_id, ev_types, sec, usec) { this.user_id = user_id; this.win_id = Math.floor(Math.random() * 2147483646 + 1); this.ev_types = ev_types; this.from_sec = sec; this.from_usec = usec; Event.observe(window, "load", fdajax.startloop); }, redirect: function(www_id) { fdajax.cancel(); alert("Do not open a second window or configure www1, www2, etc addresses in your application."); window.location = "/"; }, relogin: function(reason) { fdajax.cancel(); if (reason == "ipaddr") { alert("Please log in once again, your IP address has changed."); } else if (reason == "sessid") { alert("Please log in once again, your session id is incorrect."); } window.location = "/"; }, nocookies: function() { fdajax.cancel(); }, notfound: function() { fdajax.cancel(); alert("You are not logged to FdAjax module."); window.location = "/"; }, cancel: function() { fdajax.run_loop = false; if (fdajax.cur_req) { if (fdajax.cur_req.transport && fdajax.cur_req.transport.readyState > 0) { fdajax.cur_req.transport.onreadystatechange = function() {}; fdajax.cur_req.transport.abort(); new Ajax.Request(fdajax.server_url, { method: 'get', asynchronous: false, parameters: 'cmd=cancel' + '&user_id=' + fdajax.user_id + '&win_id=' + fdajax.win_id }); } fdajax.cur_req.transport = null; fdajax.cur_req = null; } return false; }, send_request: function() { if (!fdajax.run_loop) { return; } var opt = { onSuccess: function(resp) { fdajax.cur_req = null; try { eval(resp.responseText); } catch (e) {} if (fdajax.run_loop) { setTimeout("fdajax.send_request();", 50); } }, onFailure: function(req) { fdajax.cur_req = null; setTimeout("fdajax.send_request();", 10000); }, method: 'get', parameters: "cmd=wait&force=1&user_id=" + fdajax.user_id + "&win_id=" + fdajax.win_id + "&types=" + fdajax.ev_types }; if (fdajax.first) { fdajax.first = false; if (fdajax.from_sec > 0) { opt.parameters += "&sec=" + fdajax.from_sec + "&usec=" + fdajax.from_usec; } } fdajax.cur_req = new Ajax.Request(fdajax.server_url, opt); }, startloop: function() { fdajax.run_loop = true; Event.observe(window, "unload", fdajax.cancel); setTimeout("fdajax.send_request();", 1000); }, stoploop: function() { if (fdajax.run_loop) { fdajax.run_loop = false; alert("You have been logged out from FdAjax module."); window.location = "/"; } }, maxwin: function() { if (fdajax.run_loop) { fdajax.run_loop = false; alert("Too many open windows. This window has lost the connection to FdAjax module."); } }, no_guests: function () { alert("Guest users not allowed."); }, peer_call: function(peer_id, ev, ob_id, par1) { }, grp_peer_call: function (peer_id, ev, par1) { }, ping: function() { // In case of chunked mode the ping function might be empty } }; mod_fdajax-0.9/examples/php/hydeparkchat/public/javascripts/prototype.js0000644000175000017500000021313410650177505025410 0ustar greggreg/* Prototype JavaScript framework, version 1.5.0 * (c) 2005-2007 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.5.0', BrowserFeatures: { XPath: !!document.evaluate }, 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 (var property in source) { destination[property] = source[property]; } return destination; } Object.extend(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; } }, keys: function(object) { var keys = []; for (var property in object) keys.push(property); return keys; }, values: function(object) { var values = []; for (var property in object) values.push(object[property]); return values; }, clone: function(object) { return Object.extend({}, object); } }); 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, args = $A(arguments), object = args.shift(); return function(event) { return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments))); } } 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, length = arguments.length; i < 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() { this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, stop: function() { if (!this.timer) return; clearInterval(this.timer); this.timer = null; }, onTimerEvent: function() { if (!this.currentlyExecuting) { try { this.currentlyExecuting = true; this.callback(this); } finally { this.currentlyExecuting = false; } } } } String.interpret = function(value){ return value == null ? '' : String(value); } Object.extend(String.prototype, { gsub: function(pattern, replacement) { var result = '', source = this, match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { result += source.slice(0, match.index); result += String.interpret(replacement(match)); source = source.slice(match.index + match[0].length); } else { result += source, source = ''; } } return result; }, sub: function(pattern, replacement, count) { replacement = this.gsub.prepareReplacement(replacement); count = count === undefined ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; return replacement(match); }); }, scan: function(pattern, iterator) { this.gsub(pattern, iterator); return this; }, truncate: function(length, truncation) { length = length || 30; truncation = truncation === undefined ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : this; }, strip: function() { return this.replace(/^\s+/, '').replace(/\s+$/, ''); }, 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(function(script) { return eval(script) }); }, 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.length > 1 ? $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) : div.childNodes[0].nodeValue) : ''; }, toQueryParams: function(separator) { var match = this.strip().match(/([^?#]*)(#.*)?$/); if (!match) return {}; return match[1].split(separator || '&').inject({}, function(hash, pair) { if ((pair = pair.split('='))[0]) { var name = decodeURIComponent(pair[0]); var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; if (hash[name] !== undefined) { if (hash[name].constructor != Array) hash[name] = [hash[name]]; if (value) hash[name].push(value); } else hash[name] = value; } return hash; }); }, toArray: function() { return this.split(''); }, succ: function() { return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); }, camelize: function() { var parts = this.split('-'), len = parts.length; if (len == 1) return parts[0]; var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0]; for (var i = 1; i < len; i++) camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized; }, capitalize: function(){ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); }, underscore: function() { return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); }, dasherize: function() { return this.gsub(/_/,'-'); }, inspect: function(useDoubleQuotes) { var escapedString = this.replace(/\\/g, '\\\\'); if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; else return "'" + escapedString.replace(/'/g, '\\\'') + "'"; } }); String.prototype.gsub.prepareReplacement = function(replacement) { if (typeof replacement == 'function') return replacement; var template = new Template(replacement); return function(match) { return template.evaluate(match) }; } String.prototype.parseQuery = String.prototype.toQueryParams; var Template = Class.create(); Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; Template.prototype = { initialize: function(template, pattern) { this.template = template.toString(); this.pattern = pattern || Template.Pattern; }, evaluate: function(object) { return this.template.gsub(this.pattern, function(match) { var before = match[1]; if (before == '\\') return match[2]; return before + String.interpret(object[match[3]]); }); } } 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; } return this; }, eachSlice: function(number, iterator) { var index = -number, slices = [], array = this.toArray(); while ((index += number) < array.length) slices.push(array.slice(index, index+number)); return slices.map(iterator); }, 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 = false; 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 || Prototype.K)(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; }, inGroupsOf: function(number, fillWith) { fillWith = fillWith === undefined ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; }); }, 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.map(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 (result == undefined || value >= result) result = value; }); return result; }, min: function(iterator) { var result; this.each(function(value, index) { value = (iterator || Prototype.K)(value, index); if (result == undefined || value < result) 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.map(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.map(); }, 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) { return iterator(collections.pluck(index)); }); }, size: function() { return this.toArray().length; }, 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, length = iterable.length; i < length; i++) results.push(iterable[i]); return results; } } Object.extend(Array.prototype, Enumerable); if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; Object.extend(Array.prototype, { _each: function(iterator) { for (var i = 0, length = this.length; i < 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 != null; }); }, flatten: function() { return this.inject([], function(array, value) { return array.concat(value && 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, length = this.length; i < length; i++) if (this[i] == object) return i; return -1; }, reverse: function(inline) { return (inline !== false ? this : this.toArray())._reverse(); }, reduce: function() { return this.length > 1 ? this : this[0]; }, uniq: function() { return this.inject([], function(array, value) { return array.include(value) ? array : array.concat([value]); }); }, clone: function() { return [].concat(this); }, size: function() { return this.length; }, inspect: function() { return '[' + this.map(Object.inspect).join(', ') + ']'; } }); Array.prototype.toArray = Array.prototype.clone; function $w(string){ string = string.strip(); return string ? string.split(/\s+/) : []; } if(window.opera){ Array.prototype.concat = function(){ var array = []; for(var i = 0, length = this.length; i < length; i++) array.push(this[i]); for(var i = 0, length = arguments.length; i < length; i++) { if(arguments[i].constructor == Array) { for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) array.push(arguments[i][j]); } else { array.push(arguments[i]); } } return array; } } var Hash = function(obj) { Object.extend(this, obj || {}); }; Object.extend(Hash, { toQueryString: function(obj) { var parts = []; this.prototype._each.call(obj, function(pair) { if (!pair.key) return; if (pair.value && pair.value.constructor == Array) { var values = pair.value.compact(); if (values.length < 2) pair.value = values.reduce(); else { key = encodeURIComponent(pair.key); values.each(function(value) { value = value != undefined ? encodeURIComponent(value) : ''; parts.push(key + '=' + encodeURIComponent(value)); }); return; } } if (pair.value == undefined) pair[1] = ''; parts.push(pair.map(encodeURIComponent).join('=')); }); return parts.join('&'); } }); Object.extend(Hash.prototype, Enumerable); Object.extend(Hash.prototype, { _each: function(iterator) { for (var key in this) { var value = this[key]; if (value && value == Hash.prototype[key]) 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(this, function(mergedHash, pair) { mergedHash[pair.key] = pair.value; return mergedHash; }); }, remove: function() { var result; for(var i = 0, length = arguments.length; i < length; i++) { var value = this[arguments[i]]; if (value !== undefined){ if (result === undefined) result = value; else { if (result.constructor != Array) result = [result]; result.push(value) } } delete this[arguments[i]]; } return result; }, toQueryString: function() { return Hash.toQueryString(this); }, inspect: function() { return '#'; } }); function $H(object) { if (object && object.constructor == Hash) return object; return new Hash(object); }; 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; while (this.include(value)) { iterator(value); value = value.succ(); } }, 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 XMLHttpRequest()}, function() {return new ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')} ) || false; }, activeRequestCount: 0 } Ajax.Responders = { responders: [], _each: function(iterator) { this.responders._each(iterator); }, register: function(responder) { if (!this.include(responder)) this.responders.push(responder); }, unregister: function(responder) { this.responders = this.responders.without(responder); }, dispatch: function(callback, request, transport, json) { this.each(function(responder) { if (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, contentType: 'application/x-www-form-urlencoded', encoding: 'UTF-8', parameters: '' } Object.extend(this.options, options || {}); this.options.method = this.options.method.toLowerCase(); if (typeof this.options.parameters == 'string') this.options.parameters = this.options.parameters.toQueryParams(); } } Ajax.Request = Class.create(); Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; Ajax.Request.prototype = Object.extend(new Ajax.Base(), { _complete: false, initialize: function(url, options) { this.transport = Ajax.getTransport(); this.setOptions(options); this.request(url); }, request: function(url) { this.url = url; this.method = this.options.method; var params = this.options.parameters; if (!['get', 'post'].include(this.method)) { // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } params = Hash.toQueryString(params); if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_=' // when GET, append parameters to URL if (this.method == 'get' && params) this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params; try { Ajax.Responders.dispatch('onCreate', this, this.transport); this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); if (this.options.asynchronous) setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); this.transport.onreadystatechange = this.onStateChange.bind(this); this.setRequestHeaders(); var body = this.method == 'post' ? (this.options.postBody || params) : null; this.transport.send(body); /* Force Firefox to handle ready state 4 for synchronous requests */ if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange(); } catch (e) { this.dispatchException(e); } }, onStateChange: function() { var readyState = this.transport.readyState; if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState); }, setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version, 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; if (this.method == 'post') { headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); /* Force "Connection: close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */ if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) headers['Connection'] = 'close'; } // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; if (typeof extras.push == 'function') for (var i = 0, length = extras.length; i < length; i += 2) headers[extras[i]] = extras[i+1]; else $H(extras).each(function(pair) { headers[pair.key] = pair.value }); } for (var name in headers) this.transport.setRequestHeader(name, headers[name]); }, success: function() { return !this.transport.status || (this.transport.status >= 200 && this.transport.status < 300); }, respondToReadyState: function(readyState) { var state = Ajax.Request.Events[readyState]; var transport = this.transport, json = this.evalJSON(); if (state == 'Complete') { try { this._complete = true; (this.options['on' + this.transport.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(transport, json); } catch (e) { this.dispatchException(e); } if ((this.getHeader('Content-type') || 'text/javascript').strip(). match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) this.evalResponse(); } try { (this.options['on' + state] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on' + state, this, transport, json); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } }, getHeader: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) { return null } }, evalJSON: function() { try { var json = this.getHeader('X-JSON'); return json ? eval('(' + json + ')') : null; } catch (e) { return null } }, evalResponse: function() { try { return eval(this.transport.responseText); } catch (e) { this.dispatchException(e); } }, 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.container = { success: (container.success || 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, param) { this.updateContent(); onComplete(transport, param); }).bind(this); this.request(url); }, updateContent: function() { var receiver = this.container[this.success() ? 'success' : 'failure']; var response = this.transport.responseText; if (!this.options.evalScripts) response = response.stripScripts(); if (receiver = $(receiver)) { if (this.options.insertion) new this.options.insertion(receiver, response); else receiver.update(response); } if (this.success()) { 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.options.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); } }); function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (typeof element == 'string') element = document.getElementById(element); return Element.extend(element); } if (Prototype.BrowserFeatures.XPath) { document._getElementsByXPath = function(expression, parentElement) { var results = []; var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, length = query.snapshotLength; i < length; i++) results.push(query.snapshotItem(i)); return results; }; } document.getElementsByClassName = function(className, parentElement) { if (Prototype.BrowserFeatures.XPath) { var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; return document._getElementsByXPath(q, parentElement); } else { var children = ($(parentElement) || document.body).getElementsByTagName('*'); var elements = [], child; for (var i = 0, length = children.length; i < length; i++) { child = children[i]; if (Element.hasClassName(child, className)) elements.push(Element.extend(child)); } return elements; } }; /*--------------------------------------------------------------------------*/ if (!window.Element) var Element = new Object(); Element.extend = function(element) { if (!element || _nativeExtensions || element.nodeType == 3) return element; if (!element._extended && element.tagName && element != window) { var methods = Object.clone(Element.Methods), cache = Element.extend.cache; if (element.tagName == 'FORM') Object.extend(methods, Form.Methods); if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName)) Object.extend(methods, Form.Element.Methods); Object.extend(methods, Element.Methods.Simulated); for (var property in methods) { var value = methods[property]; if (typeof value == 'function' && !(property in element)) element[property] = cache.findOrStore(value); } } element._extended = true; return element; }; Element.extend.cache = { findOrStore: function(value) { return this[value] = this[value] || function() { return value.apply(null, [this].concat($A(arguments))); } } }; Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, toggle: function(element) { element = $(element); Element[Element.visible(element) ? 'hide' : 'show'](element); return element; }, hide: function(element) { $(element).style.display = 'none'; return element; }, show: function(element) { $(element).style.display = ''; return element; }, remove: function(element) { element = $(element); element.parentNode.removeChild(element); return element; }, update: function(element, html) { html = typeof html == 'undefined' ? '' : html.toString(); $(element).innerHTML = html.stripScripts(); setTimeout(function() {html.evalScripts()}, 10); return element; }, replace: function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); if (element.outerHTML) { element.outerHTML = html.stripScripts(); } else { var range = element.ownerDocument.createRange(); range.selectNodeContents(element); element.parentNode.replaceChild( range.createContextualFragment(html.stripScripts()), element); } setTimeout(function() {html.evalScripts()}, 10); return element; }, inspect: function(element) { element = $(element); var result = '<' + element.tagName.toLowerCase(); $H({'id': 'id', 'className': 'class'}).each(function(pair) { var property = pair.first(), attribute = pair.last(); var value = (element[property] || '').toString(); if (value) result += ' ' + attribute + '=' + value.inspect(true); }); return result + '>'; }, recursivelyCollect: function(element, property) { element = $(element); var elements = []; while (element = element[property]) if (element.nodeType == 1) elements.push(Element.extend(element)); return elements; }, ancestors: function(element) { return $(element).recursivelyCollect('parentNode'); }, descendants: function(element) { return $A($(element).getElementsByTagName('*')); }, immediateDescendants: function(element) { if (!(element = $(element).firstChild)) return []; while (element && element.nodeType != 1) element = element.nextSibling; if (element) return [element].concat($(element).nextSiblings()); return []; }, previousSiblings: function(element) { return $(element).recursivelyCollect('previousSibling'); }, nextSiblings: function(element) { return $(element).recursivelyCollect('nextSibling'); }, siblings: function(element) { element = $(element); return element.previousSiblings().reverse().concat(element.nextSiblings()); }, match: function(element, selector) { if (typeof selector == 'string') selector = new Selector(selector); return selector.match($(element)); }, up: function(element, expression, index) { return Selector.findElement($(element).ancestors(), expression, index); }, down: function(element, expression, index) { return Selector.findElement($(element).descendants(), expression, index); }, previous: function(element, expression, index) { return Selector.findElement($(element).previousSiblings(), expression, index); }, next: function(element, expression, index) { return Selector.findElement($(element).nextSiblings(), expression, index); }, getElementsBySelector: function() { var args = $A(arguments), element = $(args.shift()); return Selector.findChildElements(element, args); }, getElementsByClassName: function(element, className) { return document.getElementsByClassName(className, element); }, readAttribute: function(element, name) { element = $(element); if (document.all && !window.opera) { var t = Element._attributeTranslations; if (t.values[name]) return t.values[name](element, name); if (t.names[name]) name = t.names[name]; var attribute = element.attributes[name]; if(attribute) return attribute.nodeValue; } return element.getAttribute(name); }, getHeight: function(element) { return $(element).getDimensions().height; }, getWidth: function(element) { return $(element).getDimensions().width; }, classNames: function(element) { return new Element.ClassNames(element); }, hasClassName: function(element, className) { if (!(element = $(element))) return; var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true; return false; }, addClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).add(className); return element; }, removeClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).remove(className); return element; }, toggleClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); return element; }, observe: function() { Event.observe.apply(Event, arguments); return $A(arguments).first(); }, stopObserving: function() { Event.stopObserving.apply(Event, arguments); return $A(arguments).first(); }, // removes whitespace-only text node children cleanWhitespace: function(element) { element = $(element); var node = element.firstChild; while (node) { var nextNode = node.nextSibling; if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node); node = nextNode; } return element; }, empty: function(element) { return $(element).innerHTML.match(/^\s*$/); }, descendantOf: function(element, ancestor) { element = $(element), ancestor = $(ancestor); while (element = element.parentNode) if (element == ancestor) return true; return false; }, scrollTo: function(element) { element = $(element); var pos = Position.cumulativeOffset(element); window.scrollTo(pos[0], pos[1]); return element; }, getStyle: function(element, style) { element = $(element); if (['float','cssFloat'].include(style)) style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat'); style = style.camelize(); var value = element.style[style]; if (!value) { if (document.defaultView && document.defaultView.getComputedStyle) { var css = document.defaultView.getComputedStyle(element, null); value = css ? css[style] : null; } else if (element.currentStyle) { value = element.currentStyle[style]; } } if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none')) value = element['offset'+style.capitalize()] + 'px'; if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) if (Element.getStyle(element, 'position') == 'static') value = 'auto'; if(style == 'opacity') { if(value) return parseFloat(value); if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if(value[1]) return parseFloat(value[1]) / 100; return 1.0; } return value == 'auto' ? null : value; }, setStyle: function(element, style) { element = $(element); for (var name in style) { var value = style[name]; if(name == 'opacity') { if (value == 1) { value = (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0; if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); } else if(value == '') { if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,''); } else { if(value < 0.00001) value = 0; if(/MSIE/.test(navigator.userAgent) && !window.opera) element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+value*100+')'; } } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat'; element.style[name.camelize()] = value; } return element; }, getDimensions: function(element) { element = $(element); var display = $(element).getStyle('display'); if (display != 'none' && display != null) // Safari bug 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; var originalDisplay = els.display; els.visibility = 'hidden'; els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; els.display = originalDisplay; 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; } } return element; }, 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 = ''; } return element; }, makeClipping: function(element) { element = $(element); if (element._overflow) return element; element._overflow = element.style.overflow || 'auto'; if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden'; return element; }, undoClipping: function(element) { element = $(element); if (!element._overflow) return element; element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; element._overflow = null; return element; } }; Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf}); Element._attributeTranslations = {}; Element._attributeTranslations.names = { colspan: "colSpan", rowspan: "rowSpan", valign: "vAlign", datetime: "dateTime", accesskey: "accessKey", tabindex: "tabIndex", enctype: "encType", maxlength: "maxLength", readonly: "readOnly", longdesc: "longDesc" }; Element._attributeTranslations.values = { _getAttr: function(element, attribute) { return element.getAttribute(attribute, 2); }, _flag: function(element, attribute) { return $(element).hasAttribute(attribute) ? attribute : null; }, style: function(element) { return element.style.cssText.toLowerCase(); }, title: function(element) { var node = element.getAttributeNode('title'); return node.specified ? node.nodeValue : null; } }; Object.extend(Element._attributeTranslations.values, { href: Element._attributeTranslations.values._getAttr, src: Element._attributeTranslations.values._getAttr, disabled: Element._attributeTranslations.values._flag, checked: Element._attributeTranslations.values._flag, readonly: Element._attributeTranslations.values._flag, multiple: Element._attributeTranslations.values._flag }); Element.Methods.Simulated = { hasAttribute: function(element, attribute) { var t = Element._attributeTranslations; attribute = t.names[attribute] || attribute; return $(element).getAttributeNode(attribute).specified; } }; // IE is missing .innerHTML support for TABLE-related elements if (document.all && !window.opera){ Element.Methods.update = function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); var tagName = element.tagName.toUpperCase(); if (['THEAD','TBODY','TR','TD'].include(tagName)) { var div = document.createElement('div'); switch (tagName) { case 'THEAD': case 'TBODY': div.innerHTML = '' + html.stripScripts() + '
    '; depth = 2; break; case 'TR': div.innerHTML = '' + html.stripScripts() + '
    '; depth = 3; break; case 'TD': div.innerHTML = '
    ' + html.stripScripts() + '
    '; depth = 4; } $A(element.childNodes).each(function(node){ element.removeChild(node) }); depth.times(function(){ div = div.firstChild }); $A(div.childNodes).each( function(node){ element.appendChild(node) }); } else { element.innerHTML = html.stripScripts(); } setTimeout(function() {html.evalScripts()}, 10); return element; } }; Object.extend(Element, Element.Methods); var _nativeExtensions = false; if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) { var className = 'HTML' + tag + 'Element'; if(window[className]) return; var klass = window[className] = {}; klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__; }); Element.addMethods = function(methods) { Object.extend(Element.Methods, methods || {}); function copy(methods, destination, onlyIfAbsent) { onlyIfAbsent = onlyIfAbsent || false; var cache = Element.extend.cache; for (var property in methods) { var value = methods[property]; if (!onlyIfAbsent || !(property in destination)) destination[property] = cache.findOrStore(value); } } if (typeof HTMLElement != 'undefined') { copy(Element.Methods, HTMLElement.prototype); copy(Element.Methods.Simulated, HTMLElement.prototype, true); copy(Form.Methods, HTMLFormElement.prototype); [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) { copy(Form.Element.Methods, klass.prototype); }); _nativeExtensions = true; } } 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) { var tagName = this.element.tagName.toUpperCase(); if (['TBODY', 'TR'].include(tagName)) { 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($A(this).concat(classNameToAdd).join(' ')); }, remove: function(classNameToRemove) { if (!this.include(classNameToRemove)) return; this.set($A(this).without(classNameToRemove).join(' ')); }, toString: function() { return $A(this).join(' '); } }; Object.extend(Element.ClassNames.prototype, Enumerable); var Selector = Class.create(); Selector.prototype = { initialize: function(expression) { this.params = {classNames: []}; this.expression = expression.toString().strip(); this.parseExpression(); this.compileMatcher(); }, parseExpression: function() { function abort(message) { throw 'Parse error in selector: ' + message; } if (this.expression == '') abort('empty expression'); var params = this.params, expr = this.expression, match, modifier, clause, rest; while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { params.attributes = params.attributes || []; params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); expr = match[1]; } if (expr == '*') return this.params.wildcard = true; while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { modifier = match[1], clause = match[2], rest = match[3]; switch (modifier) { case '#': params.id = clause; break; case '.': params.classNames.push(clause); break; case '': case undefined: params.tagName = clause.toUpperCase(); break; default: abort(expr.inspect()); } expr = rest; } if (expr.length > 0) abort(expr.inspect()); }, buildMatchExpression: function() { var params = this.params, conditions = [], clause; if (params.wildcard) conditions.push('true'); if (clause = params.id) conditions.push('element.readAttribute("id") == ' + clause.inspect()); if (clause = params.tagName) conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); if ((clause = params.classNames).length > 0) for (var i = 0, length = clause.length; i < length; i++) conditions.push('element.hasClassName(' + clause[i].inspect() + ')'); if (clause = params.attributes) { clause.each(function(attribute) { var value = 'element.readAttribute(' + attribute.name.inspect() + ')'; var splitValueBy = function(delimiter) { return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; } switch (attribute.operator) { case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; case '|=': conditions.push( splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() ); break; case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; case '': case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break; default: throw 'Unknown operator ' + attribute.operator + ' in selector'; } }); } return conditions.join(' && '); }, compileMatcher: function() { this.match = new Function('element', 'if (!element.tagName) return false; \ element = $(element); \ return ' + this.buildMatchExpression()); }, findElements: function(scope) { var element; if (element = $(this.params.id)) if (this.match(element)) if (!scope || Element.childOf(element, scope)) return [element]; scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); var results = []; for (var i = 0, length = scope.length; i < length; i++) if (this.match(element = scope[i])) results.push(Element.extend(element)); return results; }, toString: function() { return this.expression; } } Object.extend(Selector, { matchElements: function(elements, expression) { var selector = new Selector(expression); return elements.select(selector.match.bind(selector)).map(Element.extend); }, findElement: function(elements, expression, index) { if (typeof expression == 'number') index = expression, expression = false; return Selector.matchElements(elements, expression || '*')[index || 0]; }, findChildElements: function(element, expressions) { return expressions.map(function(expression) { return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) { var selector = new Selector(expr); return results.inject([], function(elements, result) { return elements.concat(selector.findElements(result || element)); }); }); }).flatten(); } }); function $$() { return Selector.findChildElements(document, $A(arguments)); } var Form = { reset: function(form) { $(form).reset(); return form; }, serializeElements: function(elements, getHash) { var data = elements.inject({}, function(result, element) { if (!element.disabled && element.name) { var key = element.name, value = $(element).getValue(); if (value != undefined) { if (result[key]) { if (result[key].constructor != Array) result[key] = [result[key]]; result[key].push(value); } else result[key] = value; } } return result; }); return getHash ? data : Hash.toQueryString(data); } }; Form.Methods = { serialize: function(form, getHash) { return Form.serializeElements(Form.getElements(form), getHash); }, getElements: function(form) { return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) { if (Form.Element.Serializers[child.tagName.toLowerCase()]) elements.push(Element.extend(child)); return elements; } ); }, getInputs: function(form, typeName, name) { form = $(form); var inputs = form.getElementsByTagName('input'); if (!typeName && !name) return $A(inputs).map(Element.extend); for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { var input = inputs[i]; if ((typeName && input.type != typeName) || (name && input.name != name)) continue; matchingInputs.push(Element.extend(input)); } return matchingInputs; }, disable: function(form) { form = $(form); form.getElements().each(function(element) { element.blur(); element.disabled = 'true'; }); return form; }, enable: function(form) { form = $(form); form.getElements().each(function(element) { element.disabled = ''; }); return form; }, findFirstElement: function(form) { return $(form).getElements().find(function(element) { return element.type != 'hidden' && !element.disabled && ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); }); }, focusFirstElement: function(form) { form = $(form); form.findFirstElement().activate(); return form; } } Object.extend(Form, Form.Methods); /*--------------------------------------------------------------------------*/ Form.Element = { focus: function(element) { $(element).focus(); return element; }, select: function(element) { $(element).select(); return element; } } Form.Element.Methods = { serialize: function(element) { element = $(element); if (!element.disabled && element.name) { var value = element.getValue(); if (value != undefined) { var pair = {}; pair[element.name] = value; return Hash.toQueryString(pair); } } return ''; }, getValue: function(element) { element = $(element); var method = element.tagName.toLowerCase(); return Form.Element.Serializers[method](element); }, clear: function(element) { $(element).value = ''; return element; }, present: function(element) { return $(element).value != ''; }, activate: function(element) { element = $(element); element.focus(); if (element.select && ( element.tagName.toLowerCase() != 'input' || !['button', 'reset', 'submit'].include(element.type) ) ) element.select(); return element; }, disable: function(element) { element = $(element); element.disabled = true; return element; }, enable: function(element) { element = $(element); element.blur(); element.disabled = false; return element; } } Object.extend(Form.Element, Form.Element.Methods); var Field = Form.Element; var $F = Form.Element.getValue; /*--------------------------------------------------------------------------*/ Form.Element.Serializers = { input: function(element) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': return Form.Element.Serializers.inputSelector(element); default: return Form.Element.Serializers.textarea(element); } }, inputSelector: function(element) { return element.checked ? element.value : null; }, textarea: function(element) { return element.value; }, select: function(element) { return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element); }, selectOne: function(element) { var index = element.selectedIndex; return index >= 0 ? this.optionValue(element.options[index]) : null; }, selectMany: function(element) { var values, length = element.length; if (!length) return null; for (var i = 0, values = []; i < length; i++) { var opt = element.options[i]; if (opt.selected) values.push(this.optionValue(opt)); } return values; }, optionValue: function(opt) { // extend element because hasAttribute may not be native return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; } } /*--------------------------------------------------------------------------*/ 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(); var changed = ('string' == typeof this.lastValue && 'string' == typeof value ? this.lastValue != value : String(this.lastValue) != String(value)); if (changed) { 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() { Form.getElements(this.element).each(this.registerCallback.bind(this)); }, registerCallback: function(element) { if (element.type) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': Event.observe(element, 'click', this.onElementEvent.bind(this)); break; default: 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, KEY_HOME: 36, KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, 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, length = Event.observers.length; i < length; i++) { Event.stopObserving.apply(this, Event.observers[i]); Event.observers[i][0] = null; } Event.observers = false; }, observe: function(element, name, observer, useCapture) { element = $(element); useCapture = useCapture || false; if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent)) name = 'keydown'; Event._observeAndCache(element, name, observer, useCapture); }, stopObserving: function(element, name, observer, useCapture) { 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) { try { element.detachEvent('on' + name, observer); } catch (e) {} } } }); /* prevent memory leaks in IE */ if (navigator.appVersion.match(/\bMSIE\b/)) 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) { if(element.tagName=='BODY') break; var 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; }, 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 { if (!window.opera || element.tagName=='BODY') { 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]; } } Element.addMethods();mod_fdajax-0.9/examples/php/hydeparkchat/tmp/0000755000175000017500000000000010652360363017770 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/tmp/cache/0000755000175000017500000000000010652360363021033 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/tmp/pids/0000755000175000017500000000000010652360363020727 5ustar greggregmod_fdajax-0.9/examples/php/hydeparkchat/tmp/sockets/0000755000175000017500000000000010652360363021443 5ustar greggreg