From 074dc8fda6f634cc8c024a913d8033600b336b3a Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Oct 2012 09:04:43 +0000 Subject: initial commit. --- actions/get_connection.php | 21 + actions/get_details.php | 21 + actions/get_icons.php | 52 + actions/get_state.php | 21 + actions/get_statuses.php | 41 + actions/join_groupchat.php | 15 + actions/leave_groupchat.php | 12 + actions/save_state.php | 26 + classes/BeechatSync.php | 37 + enablechat.php | 8 + graphics/icons/bullet_arrow_down.png | Bin 0 -> 201 bytes graphics/icons/bullet_arrow_up.png | Bin 0 -> 201 bytes graphics/icons/bullet_black.png | Bin 0 -> 211 bytes graphics/icons/bullet_blue.png | Bin 0 -> 289 bytes graphics/icons/bullet_delete.png | Bin 0 -> 308 bytes graphics/icons/bullet_error.png | Bin 0 -> 454 bytes graphics/icons/bullet_green.png | Bin 0 -> 295 bytes graphics/icons/bullet_orange.png | Bin 0 -> 283 bytes graphics/icons/bullet_pink.png | Bin 0 -> 286 bytes graphics/icons/bullet_purple.png | Bin 0 -> 294 bytes graphics/icons/bullet_red.png | Bin 0 -> 287 bytes graphics/icons/bullet_star.png | Bin 0 -> 331 bytes graphics/icons/bullet_white.png | Bin 0 -> 201 bytes graphics/icons/bullet_yellow.png | Bin 0 -> 287 bytes graphics/icons/chat_icon.png | Bin 0 -> 456 bytes graphics/icons/cog_edit.png | Bin 0 -> 865 bytes graphics/icons/comment_edit.png | Bin 0 -> 644 bytes graphics/icons/emoticon_evilgrin.png | Bin 0 -> 727 bytes graphics/icons/emoticon_grin.png | Bin 0 -> 714 bytes graphics/icons/emoticon_happy.png | Bin 0 -> 731 bytes graphics/icons/emoticon_smile.png | Bin 0 -> 725 bytes graphics/icons/emoticon_surprised.png | Bin 0 -> 741 bytes graphics/icons/emoticon_tongue.png | Bin 0 -> 727 bytes graphics/icons/emoticon_unhappy.png | Bin 0 -> 723 bytes graphics/icons/emoticon_waii.png | Bin 0 -> 737 bytes graphics/icons/emoticon_wink.png | Bin 0 -> 712 bytes graphics/icons/heart.png | Bin 0 -> 749 bytes graphics/icons/house.png | Bin 0 -> 806 bytes graphics/icons/muc_icon.png | Bin 0 -> 592 bytes graphics/icons/notification_pink.png | Bin 0 -> 3140 bytes graphics/icons/pointer.png | Bin 0 -> 2833 bytes graphics/icons/resultset_next.png | Bin 0 -> 395 bytes graphics/icons/resultset_previous.png | Bin 0 -> 389 bytes graphics/icons/statuses.png | Bin 0 -> 5857 bytes graphics/icons/vcard.png | Bin 0 -> 533 bytes languages/en.php | 45 + languages/es.php | 43 + languages/fr.php | 32 + lib/beechat.php | 250 ++ manifest.xml | 16 + sounds/newmessage.wav | Bin 0 -> 39440 bytes start.php | 181 ++ views/default/beechat/beechat.js.php | 2468 ++++++++++++++++++++ views/default/beechat/beechat.php | 84 + views/default/beechat/beechat.userjs.php | 54 + views/default/beechat/screen.css.php | 672 ++++++ views/default/js/b64.js.php | 74 + views/default/js/jquery.cookie.min.js.php | 10 + .../default/js/jquery.localscroll-1.2.7-min.js.php | 9 + views/default/js/jquery.scrollTo-min.js.php | 11 + views/default/js/jquery.serialScroll-min.js.php | 10 + views/default/js/jquery.tools.min.js.php | 49 + views/default/js/json2.js.php | 476 ++++ views/default/js/md5.js.php | 261 +++ views/default/js/sha1.js.php | 207 ++ views/default/js/strophe.min.js.php | 1 + views/default/js/strophe.muc.js | 300 +++ views/default/js/strophe.muc.js.php | 300 +++ views/default/settings/beechat/edit.php | 31 + 69 files changed, 5838 insertions(+) create mode 100644 actions/get_connection.php create mode 100644 actions/get_details.php create mode 100644 actions/get_icons.php create mode 100644 actions/get_state.php create mode 100644 actions/get_statuses.php create mode 100644 actions/join_groupchat.php create mode 100644 actions/leave_groupchat.php create mode 100644 actions/save_state.php create mode 100644 classes/BeechatSync.php create mode 100644 enablechat.php create mode 100644 graphics/icons/bullet_arrow_down.png create mode 100644 graphics/icons/bullet_arrow_up.png create mode 100644 graphics/icons/bullet_black.png create mode 100644 graphics/icons/bullet_blue.png create mode 100644 graphics/icons/bullet_delete.png create mode 100644 graphics/icons/bullet_error.png create mode 100644 graphics/icons/bullet_green.png create mode 100644 graphics/icons/bullet_orange.png create mode 100644 graphics/icons/bullet_pink.png create mode 100644 graphics/icons/bullet_purple.png create mode 100644 graphics/icons/bullet_red.png create mode 100644 graphics/icons/bullet_star.png create mode 100644 graphics/icons/bullet_white.png create mode 100644 graphics/icons/bullet_yellow.png create mode 100644 graphics/icons/chat_icon.png create mode 100644 graphics/icons/cog_edit.png create mode 100644 graphics/icons/comment_edit.png create mode 100644 graphics/icons/emoticon_evilgrin.png create mode 100644 graphics/icons/emoticon_grin.png create mode 100644 graphics/icons/emoticon_happy.png create mode 100644 graphics/icons/emoticon_smile.png create mode 100644 graphics/icons/emoticon_surprised.png create mode 100644 graphics/icons/emoticon_tongue.png create mode 100644 graphics/icons/emoticon_unhappy.png create mode 100644 graphics/icons/emoticon_waii.png create mode 100644 graphics/icons/emoticon_wink.png create mode 100644 graphics/icons/heart.png create mode 100644 graphics/icons/house.png create mode 100644 graphics/icons/muc_icon.png create mode 100644 graphics/icons/notification_pink.png create mode 100644 graphics/icons/pointer.png create mode 100644 graphics/icons/resultset_next.png create mode 100644 graphics/icons/resultset_previous.png create mode 100644 graphics/icons/statuses.png create mode 100644 graphics/icons/vcard.png create mode 100644 languages/en.php create mode 100644 languages/es.php create mode 100644 languages/fr.php create mode 100644 lib/beechat.php create mode 100644 manifest.xml create mode 100644 sounds/newmessage.wav create mode 100644 start.php create mode 100644 views/default/beechat/beechat.js.php create mode 100644 views/default/beechat/beechat.php create mode 100644 views/default/beechat/beechat.userjs.php create mode 100644 views/default/beechat/screen.css.php create mode 100644 views/default/js/b64.js.php create mode 100644 views/default/js/jquery.cookie.min.js.php create mode 100644 views/default/js/jquery.localscroll-1.2.7-min.js.php create mode 100755 views/default/js/jquery.scrollTo-min.js.php create mode 100755 views/default/js/jquery.serialScroll-min.js.php create mode 100644 views/default/js/jquery.tools.min.js.php create mode 100644 views/default/js/json2.js.php create mode 100644 views/default/js/md5.js.php create mode 100644 views/default/js/sha1.js.php create mode 100644 views/default/js/strophe.min.js.php create mode 100644 views/default/js/strophe.muc.js create mode 100644 views/default/js/strophe.muc.js.php create mode 100755 views/default/settings/beechat/edit.php diff --git a/actions/get_connection.php b/actions/get_connection.php new file mode 100644 index 000000000..a31174179 --- /dev/null +++ b/actions/get_connection.php @@ -0,0 +1,21 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + header('Content-type: application/json'); + gatekeeper(); + + global $SESSION; + + if ($SESSION->offsetExists('beechat_conn')) + echo $SESSION->offsetGet('beechat_conn'); + + exit(); +?> diff --git a/actions/get_details.php b/actions/get_details.php new file mode 100644 index 000000000..4944fc4a9 --- /dev/null +++ b/actions/get_details.php @@ -0,0 +1,21 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + gatekeeper(); + header('Content-type: application/json'); + $user = $_SESSION['user']; + $t = array('username' => $user->username, + 'password' => $user->password); + + echo json_encode($t); + + exit(); +?> diff --git a/actions/get_icons.php b/actions/get_icons.php new file mode 100644 index 000000000..88e7bdd3b --- /dev/null +++ b/actions/get_icons.php @@ -0,0 +1,52 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + header('Content-type: application/json'); + gatekeeper(); + global $CONFIG; + + if (!empty($_POST['beechat_roster_items_usernames'])) + { + $rosterItemsUsernames = explode(',', $_POST['beechat_roster_items_usernames']); + /*foreach ($rosterItemsUsernames as $rosterItem) + { + }*/ + $userFriendsEntities = $_SESSION['user']->getFriends('', 0, 0); + + $res = array(); + foreach ($rosterItemsUsernames as $value) + { + $found = false; + $splitjid = explode('@', $value); + $jid_name = $splitjid[0]; + $jid_host = $splitjid[1]; + foreach ($userFriendsEntities as $friend) + { + if ((strtolower($friend->username) == strtolower($jid_name) && $jid_host == get_plugin_setting("domain", "beechat"))) + { + $res[$value] = array('small' => $friend->getIcon('small'), 'tiny' => $friend->getIcon('tiny')); + $found = true; + break; + } + } + if (!$found) { + $base = $CONFIG->wwwroot."mod/profile/graphics/default"; + $res[$value] = array('small' => $base."small.gif", 'tiny' => $base."tiny.gif"); + } + } + echo json_encode($res); + } + else + echo json_encode(null); + + exit(); + +?> diff --git a/actions/get_state.php b/actions/get_state.php new file mode 100644 index 000000000..6cfd2f725 --- /dev/null +++ b/actions/get_state.php @@ -0,0 +1,21 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + header('Content-type: application/json'); + gatekeeper(); + + global $SESSION; + + if ($SESSION->offsetExists('beechat_state')) + echo $SESSION->offsetGet('beechat_state'); + + exit(); +?> diff --git a/actions/get_statuses.php b/actions/get_statuses.php new file mode 100644 index 000000000..c328e44b7 --- /dev/null +++ b/actions/get_statuses.php @@ -0,0 +1,41 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + header('Content-type: application/json'); + gatekeeper(); + $usernames = get_input('beechat_roster_items_usernames'); + if (!empty($usernames)) + { + $iconSize = 'small'; + $rosterItemsUsernames = explode(',', $usernames); + $userFriendsEntities = $_SESSION['user']->getFriends('', count($rosterItemsUsernames), 0); + + $res = array(); + foreach ($rosterItemsUsernames as $value) + { + foreach ($userFriendsEntities as $friend) + { + if (strtolower($friend->username) == strtolower($value)) + { + $status = get_entities_from_metadata("state", "current", "object", "status", $friend->get('guid')); + $res[$value] = ($status != false) ? $status[0]->description : ''; + break; + } + } + } + echo json_encode($res); + } + else + echo json_encode(null); + + exit(); + +?> diff --git a/actions/join_groupchat.php b/actions/join_groupchat.php new file mode 100644 index 000000000..0d2d75c61 --- /dev/null +++ b/actions/join_groupchat.php @@ -0,0 +1,15 @@ +guid, 'groupchat', $group->guid)) { + error_log("joinen ok"); + add_entity_relationship($user->guid, 'groupchat', $group->guid); +} +} +echo "OK"; +error_log("join ok"); + +?> diff --git a/actions/leave_groupchat.php b/actions/leave_groupchat.php new file mode 100644 index 000000000..079ad4898 --- /dev/null +++ b/actions/leave_groupchat.php @@ -0,0 +1,12 @@ +guid, 'groupchat', $group->guid)) + remove_entity_relationship($user->guid, 'groupchat', $group->guid); +} +error_log("leave ok"); +echo "OK"; +?> diff --git a/actions/save_state.php b/actions/save_state.php new file mode 100644 index 000000000..f3a818f72 --- /dev/null +++ b/actions/save_state.php @@ -0,0 +1,26 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + gatekeeper(); + + global $SESSION; + + if (!empty($_POST['beechat_state'])) + { + $SESSION->offsetSet('beechat_state', get_input('beechat_state')); + } + elseif (!empty($_POST['beechat_conn'])) + { + $SESSION->offsetSet('beechat_conn', get_input('beechat_conn')); + } + + exit(); +?> diff --git a/classes/BeechatSync.php b/classes/BeechatSync.php new file mode 100644 index 000000000..e0a2f90b8 --- /dev/null +++ b/classes/BeechatSync.php @@ -0,0 +1,37 @@ +relationship == 'friendrequest') { + elgg_load_library('elgg:beechat'); + $friend = get_entity($relationship->guid_two); + // create friend request + ejabberd_friend_request(elgg_get_logged_in_user_entity(), $friend); + } + } + static function onFriendDelete($event, $object_type, $relationship) { + if ($relationship->relationship == 'friendrequest') { + elgg_load_library('elgg:beechat'); + $subject = get_entity($relationship->guid_two); + // here friend is guid_one because is the one initiating + $friend = get_entity($relationship->guid_one); + $friends = $friend->isFriendsWith($subject->guid); + if ($friends) { + // accept friend request + ejabberd_friend_accept(elgg_get_logged_in_user_entity(), $friend); + } else { + // decline friend request + ejabberd_friend_deny(elgg_get_logged_in_user_entity(), $friend); + } + } + elseif ($relationship->relationship == 'friend') { + elgg_load_library('elgg:beechat'); + $subject = get_entity($relationship->guid_one); + $friend = get_entity($relationship->guid_two); + // delete friendship + ejabberd_friend_remove(elgg_get_logged_in_user_entity(), $friend); + } + + } + +} diff --git a/enablechat.php b/enablechat.php new file mode 100644 index 000000000..f3449520c --- /dev/null +++ b/enablechat.php @@ -0,0 +1,8 @@ +chatenabled = true; + system_message(elgg_echo("beechat:enabled")); + } + forward($_SERVER['HTTP_REFERER']); +?> diff --git a/graphics/icons/bullet_arrow_down.png b/graphics/icons/bullet_arrow_down.png new file mode 100644 index 000000000..9b23c06d7 Binary files /dev/null and b/graphics/icons/bullet_arrow_down.png differ diff --git a/graphics/icons/bullet_arrow_up.png b/graphics/icons/bullet_arrow_up.png new file mode 100644 index 000000000..24df0f421 Binary files /dev/null and b/graphics/icons/bullet_arrow_up.png differ diff --git a/graphics/icons/bullet_black.png b/graphics/icons/bullet_black.png new file mode 100644 index 000000000..57619706d Binary files /dev/null and b/graphics/icons/bullet_black.png differ diff --git a/graphics/icons/bullet_blue.png b/graphics/icons/bullet_blue.png new file mode 100644 index 000000000..a7651ec8a Binary files /dev/null and b/graphics/icons/bullet_blue.png differ diff --git a/graphics/icons/bullet_delete.png b/graphics/icons/bullet_delete.png new file mode 100644 index 000000000..bd6271b24 Binary files /dev/null and b/graphics/icons/bullet_delete.png differ diff --git a/graphics/icons/bullet_error.png b/graphics/icons/bullet_error.png new file mode 100644 index 000000000..bca2b491f Binary files /dev/null and b/graphics/icons/bullet_error.png differ diff --git a/graphics/icons/bullet_green.png b/graphics/icons/bullet_green.png new file mode 100644 index 000000000..058ad261f Binary files /dev/null and b/graphics/icons/bullet_green.png differ diff --git a/graphics/icons/bullet_orange.png b/graphics/icons/bullet_orange.png new file mode 100644 index 000000000..fa63024e5 Binary files /dev/null and b/graphics/icons/bullet_orange.png differ diff --git a/graphics/icons/bullet_pink.png b/graphics/icons/bullet_pink.png new file mode 100644 index 000000000..0c9f73e3f Binary files /dev/null and b/graphics/icons/bullet_pink.png differ diff --git a/graphics/icons/bullet_purple.png b/graphics/icons/bullet_purple.png new file mode 100644 index 000000000..52ba5036b Binary files /dev/null and b/graphics/icons/bullet_purple.png differ diff --git a/graphics/icons/bullet_red.png b/graphics/icons/bullet_red.png new file mode 100644 index 000000000..0cd803115 Binary files /dev/null and b/graphics/icons/bullet_red.png differ diff --git a/graphics/icons/bullet_star.png b/graphics/icons/bullet_star.png new file mode 100644 index 000000000..fab774a32 Binary files /dev/null and b/graphics/icons/bullet_star.png differ diff --git a/graphics/icons/bullet_white.png b/graphics/icons/bullet_white.png new file mode 100644 index 000000000..a9af8d44b Binary files /dev/null and b/graphics/icons/bullet_white.png differ diff --git a/graphics/icons/bullet_yellow.png b/graphics/icons/bullet_yellow.png new file mode 100644 index 000000000..6469cea7e Binary files /dev/null and b/graphics/icons/bullet_yellow.png differ diff --git a/graphics/icons/chat_icon.png b/graphics/icons/chat_icon.png new file mode 100644 index 000000000..0e6d844bd Binary files /dev/null and b/graphics/icons/chat_icon.png differ diff --git a/graphics/icons/cog_edit.png b/graphics/icons/cog_edit.png new file mode 100644 index 000000000..47b75a456 Binary files /dev/null and b/graphics/icons/cog_edit.png differ diff --git a/graphics/icons/comment_edit.png b/graphics/icons/comment_edit.png new file mode 100644 index 000000000..73db110df Binary files /dev/null and b/graphics/icons/comment_edit.png differ diff --git a/graphics/icons/emoticon_evilgrin.png b/graphics/icons/emoticon_evilgrin.png new file mode 100644 index 000000000..817bd509b Binary files /dev/null and b/graphics/icons/emoticon_evilgrin.png differ diff --git a/graphics/icons/emoticon_grin.png b/graphics/icons/emoticon_grin.png new file mode 100644 index 000000000..fc60c5e1c Binary files /dev/null and b/graphics/icons/emoticon_grin.png differ diff --git a/graphics/icons/emoticon_happy.png b/graphics/icons/emoticon_happy.png new file mode 100644 index 000000000..6b7336e17 Binary files /dev/null and b/graphics/icons/emoticon_happy.png differ diff --git a/graphics/icons/emoticon_smile.png b/graphics/icons/emoticon_smile.png new file mode 100644 index 000000000..ade431851 Binary files /dev/null and b/graphics/icons/emoticon_smile.png differ diff --git a/graphics/icons/emoticon_surprised.png b/graphics/icons/emoticon_surprised.png new file mode 100644 index 000000000..4520cfc55 Binary files /dev/null and b/graphics/icons/emoticon_surprised.png differ diff --git a/graphics/icons/emoticon_tongue.png b/graphics/icons/emoticon_tongue.png new file mode 100644 index 000000000..ecafd2ffc Binary files /dev/null and b/graphics/icons/emoticon_tongue.png differ diff --git a/graphics/icons/emoticon_unhappy.png b/graphics/icons/emoticon_unhappy.png new file mode 100644 index 000000000..fd5d030ef Binary files /dev/null and b/graphics/icons/emoticon_unhappy.png differ diff --git a/graphics/icons/emoticon_waii.png b/graphics/icons/emoticon_waii.png new file mode 100644 index 000000000..458f93611 Binary files /dev/null and b/graphics/icons/emoticon_waii.png differ diff --git a/graphics/icons/emoticon_wink.png b/graphics/icons/emoticon_wink.png new file mode 100644 index 000000000..a631949b5 Binary files /dev/null and b/graphics/icons/emoticon_wink.png differ diff --git a/graphics/icons/heart.png b/graphics/icons/heart.png new file mode 100644 index 000000000..d9ee53e59 Binary files /dev/null and b/graphics/icons/heart.png differ diff --git a/graphics/icons/house.png b/graphics/icons/house.png new file mode 100644 index 000000000..fed62219f Binary files /dev/null and b/graphics/icons/house.png differ diff --git a/graphics/icons/muc_icon.png b/graphics/icons/muc_icon.png new file mode 100644 index 000000000..efdd60f12 Binary files /dev/null and b/graphics/icons/muc_icon.png differ diff --git a/graphics/icons/notification_pink.png b/graphics/icons/notification_pink.png new file mode 100644 index 000000000..f40c184f9 Binary files /dev/null and b/graphics/icons/notification_pink.png differ diff --git a/graphics/icons/pointer.png b/graphics/icons/pointer.png new file mode 100644 index 000000000..4e50a0f9a Binary files /dev/null and b/graphics/icons/pointer.png differ diff --git a/graphics/icons/resultset_next.png b/graphics/icons/resultset_next.png new file mode 100644 index 000000000..e252606d3 Binary files /dev/null and b/graphics/icons/resultset_next.png differ diff --git a/graphics/icons/resultset_previous.png b/graphics/icons/resultset_previous.png new file mode 100644 index 000000000..18f9cc109 Binary files /dev/null and b/graphics/icons/resultset_previous.png differ diff --git a/graphics/icons/statuses.png b/graphics/icons/statuses.png new file mode 100644 index 000000000..e409f61a9 Binary files /dev/null and b/graphics/icons/statuses.png differ diff --git a/graphics/icons/vcard.png b/graphics/icons/vcard.png new file mode 100644 index 000000000..c02f315d2 Binary files /dev/null and b/graphics/icons/vcard.png differ diff --git a/languages/en.php b/languages/en.php new file mode 100644 index 000000000..38f03be98 --- /dev/null +++ b/languages/en.php @@ -0,0 +1,45 @@ + 'Home', + + 'beechat:contacts:button' => 'Chat', + + 'beechat:availability:available' => 'Available', + 'beechat:availability:dnd' => 'Do not disturb', + 'beechat:availability:away' => 'Away', + 'beechat:availability:xa' => 'Extended away', + 'beechat:availability:offline' => 'Offline', + + 'beechat:connection:state:offline' => 'Offline', + 'beechat:connection:state:connecting' => 'Connecting...', + 'beechat:connection:state:authenticating' => 'Authenticating...', + 'beechat:connection:state:online' => 'Online', + 'beechat:connection:state:failed' => 'Failed', + 'beechat:connection:state:disconnecting' => 'Disconnecting...', + + 'beechat:chat:self' => 'Me', + 'beechat:chat:composing' => ' is typing.', + + 'beechat:box:minimize' => 'Minimize', + 'beechat:box:close' => 'Close', + 'beechat:box:showhide' => 'Show/Hide this chat window', + 'beechat:enabled' => 'Chat enabled', + 'beechat:disabled' => 'Chat disabled', + 'beechat:enablechat' => 'Enable chat', + 'beechat:disablechat' => 'Disable chat', + 'beechat:domain' => 'Chat domain', + 'beechat:groupdomain' => 'MUC domain', + 'beechat:chatroom' => 'Group chat', + 'beechat:dbname' => 'Database name', + 'beechat:dbhost' => 'Database host', + 'beechat:dbuser' => 'Database user', + 'beechat:dbuser' => 'notification:method:xmpp', + 'notification:method:xmpp' => 'Xmpp/Jabber', + 'beechat:dbpassword' => 'Database password', + 'beechat:xmlrpcip' => 'Ejabberd IP' + ); + +add_translation('en', $en_array); + +?> diff --git a/languages/es.php b/languages/es.php new file mode 100644 index 000000000..78f009ce9 --- /dev/null +++ b/languages/es.php @@ -0,0 +1,43 @@ + 'Home', + + 'beechat:contacts:button' => 'Chat', + + 'beechat:availability:available' => 'Disponible', + 'beechat:availability:dnd' => 'No molestar', + 'beechat:availability:away' => 'Fuera', + 'beechat:availability:xa' => 'Fuera bastante tiempo', + 'beechat:availability:offline' => 'Desconectado', + + 'beechat:connection:state:offline' => 'Desconectado', + 'beechat:connection:state:connecting' => 'Conectando...', + 'beechat:connection:state:authenticating' => 'Iniciando...', + 'beechat:connection:state:online' => 'Conectado', + 'beechat:connection:state:failed' => 'Fallo', + 'beechat:connection:state:disconnecting' => 'Desconectando...', + + 'beechat:chat:self' => 'Yo', + 'beechat:chat:composing' => ' esta escribiendo.', + + 'beechat:box:minimize' => 'Minimizar', + 'beechat:box:close' => 'Cerrar', + 'beechat:box:showhide' => 'Mostrar/Ocultar esta ventana de chat', + 'beechat:enabled' => 'Chat activado', + 'beechat:disabled' => 'Chat desactivado', + 'beechat:enablechat' => 'Activar chat', + 'beechat:disablechat' => 'Desactivar chat', + 'beechat:domain' => 'Dominio Chat', + 'beechat:groupdomain' => 'Dominio MUC', + 'beechat:chatroom' => 'Chat del grupo', + 'beechat:dbname' => 'Database name', + 'beechat:dbhost' => 'Database host', + 'beechat:dbuser' => 'Database user', + 'beechat:dbpassword' => 'Database password', + 'beechat:xmlrpcip' => 'Ejabberd IP' + ); + +add_translation('es', $es_array); + +?> diff --git a/languages/fr.php b/languages/fr.php new file mode 100644 index 000000000..58b0eac3a --- /dev/null +++ b/languages/fr.php @@ -0,0 +1,32 @@ + 'Accueil', + + 'beechat:contacts:button' => 'Chat', + + 'beechat:availability:available' => 'Disponible', + 'beechat:availability:dnd' => 'Ne pas déranger', + 'beechat:availability:away' => 'Absent', + 'beechat:availability:xa' => 'Absence prolongée', + 'beechat:availability:offline' => 'Hors ligne', + + 'beechat:connection:state:offline' => 'Hors ligne', + 'beechat:connection:state:connecting' => 'Connexion...', + 'beechat:connection:state:authenticating' => 'Authentification...', + 'beechat:connection:state:online' => 'En ligne', + 'beechat:connection:state:failed' => 'Échec', + 'beechat:connection:state:disconnecting' => 'Déconnexion...', + + 'beechat:chat:self' => 'Moi', + 'beechat:chat:composing' => ' est en train d\'écrire.', + + 'beechat:box:minimize' => 'Diminuer', + 'beechat:box:close' => 'Fermer', + 'beechat:box:showhide' => 'Montrer/Cacher cette fenêtre de chat' + + ); + +add_translation('fr', $fr_array); + +?> diff --git a/lib/beechat.php b/lib/beechat.php new file mode 100644 index 000000000..a7db64052 --- /dev/null +++ b/lib/beechat.php @@ -0,0 +1,250 @@ + 'utf-8'))); + + +function ejabberd_xmlrpc_send($request) +{ + $context = stream_context_create(array('http' => array( + 'method' => "POST", + 'header' => "User-Agent: XMLRPC::Client mod_xmlrpc\r\n" . + "Content-Type: text/xml\r\n" . + "Content-Length: ".strlen($request), + 'content' => $request + ))); + + $file = file_get_contents("http://".get_plugin_setting("xmlrpcip", "beechat").":4560/RPC2", false, $context); + + $response = xmlrpc_decode($file); + if (is_array($response) && xmlrpc_is_fault($response)) { + trigger_error("xmlrpc: $response[faultString] ($response[faultCode])"); + } else { + // print_r($response); + } +} + +function ejabberd_xmlrpc_command($command, $params) +{ + //error_log("send xmlrpc: ".$command); + $request = xmlrpc_encode_request($command, $params, (array('encoding' => 'utf-8'))); + return ejabberd_xmlrpc_send($request); +} + +function xmpp_escape($name) { + // http://xmpp.org/extensions/xep-0106.html#escaping + $name = str_replace(' ', '\\20', $name); + $name = str_replace('"', '\\22', $name); + $name = str_replace('&', '\\26', $name); + $name = str_replace("'", '\\27', $name); + $name = str_replace('/', '\\2f', $name); + $name = str_replace(';', '\\3a', $name); + $name = str_replace('<', '\\3c', $name); + $name = str_replace('>', '\\3e', $name); + $name = str_replace('@', '\\40', $name); + $name = str_replace('\\', '\\5c', $name); + return $name; +} + +class EjabberdMucRoom { + function __construct($group) { + $this->group = $group; + } + function setOption($name, $value) { + $group = $this->group; + $param=array("name"=>friendly_title($group->name), + "service"=>get_plugin_setting("groupdomain", "beechat"), + "option"=>$name, + "value"=>$value); + ejabberd_xmlrpc_command('muc_room_change_option', $param); + } + function addMember($member) { + //"outcast" | "none" | "member" | "admin" | "owner" + $group = $this->group; + if ($member->guid === $group->owner_guid) + $affiliation = "owner"; + elseif ($group->canEdit($member->guid)) + $affiliation = "admin"; + else + $affiliation = "member"; + $this->setAffiliation($member, $affiliation); + } + + function setAffiliation($member, $affiliation) { + $group = $this->group; + $param = array("name" => friendly_title($group->name), + "service" => get_plugin_setting("groupdomain", "beechat"), + "jid" => xmpp_escape($member->username) . '@' . get_plugin_setting("domain", "beechat"), + "affiliation" => $affiliation); + ejabberd_xmlrpc_command('muc_room_set_affiliation', $param); + //echo "set affiliation ".$member->username."
"; + } +} + +function ejabberd_create_group($group) +{ + //echo "creating " . $group->name . "
"; + // create room + $param=array("name"=>friendly_title($group->name), + "service"=>get_plugin_setting("groupdomain", "beechat"), + "server"=>get_plugin_setting("domain", "beechat")); + ejabberd_xmlrpc_command('create_muc_room', $param); + + // persistency + + $room = new EjabberdMucRoom($group); + $room->setOption("persistent", true); + $room->setOption("title", $group->name); + // open to public? + if ($group->isPublicMembership()) { + $room->setOption("members_only", false); + } + else + $room->setOption("members_only", true); + + if ($group->access_id === ACCESS_PUBLIC) { + $room->setOption("public_list", true); + $room->setOption("public", true); + } + else { + $room->setOption("public_list", false); + $room->setOption("public", false); + } + $members = $group->getMembers(0); + foreach($members as $member) { + $room->addMember($member); + } + $room->addMember(get_entity($group->owner_guid)); +} + +function ejabberd_destroy_group($group) +{ + $param=array("name"=>friendly_title($group->name), + "service"=>get_plugin_setting("groupdomain", "beechat"), + "server"=>get_plugin_setting("domain", "beechat")); + ejabberd_xmlrpc_command('delete_muc_room', $param); +} + +function ejabberd_getjid($user, $do_external=false) +{ + if ($user->foreign || ($do_external && $user->alias && get_plugin_usersetting("usealias", $user->guid,"openid_client"))) { + if ($user->foreign) + $webid = $user->webid; + else + $webid = $user->alias; + if (strpos($webid, 'http') === 0) { + // http or https addresses + $hostparts = parse_url($webid); + $urlparts = explode('/', $webid); + $host = $hostparts['host']; + $username = $urlparts[count($urlparts)-1]; + } else { + if (strpos($webid, ':') > 0) { + $webidparts = explode(':', $webid); + $hostparts = explode('@',$webidparts[1]); + } else { + $hostparts = explode('@',$webid); + } + $username = $hostparts[0]; + $host = $hostparts[1]; + } + } + else { + $username = $user->username; + $host = get_plugin_setting("domain", "beechat"); + } + return xmpp_escape($username) . '@' . $host; +} + +function ejabberd_friend_command($user, $friend, $command, $is_out) // $user adds $friend +{ + error_log(" * ".$friend->username."->".ejabberd_getjid($user)." ".$command); + if ($friend->foreign) { + error_log(" * beechat: friend is foreign!"); + return; + } + $param = array("user" => friendly_title($friend->username), + "server" => get_plugin_setting("domain", "beechat"), + "from" => ejabberd_getjid($user), + "subs" => $command); + if ($is_out) { + error_log("out"); + ejabberd_xmlrpc_command('send_roster_request_out', $param); + } + else { + $param['reason'] = 'unknown'; + ejabberd_xmlrpc_command('send_roster_request_in', $param); + } +} + + +function ejabberd_friend_request($user, $friend) // $user adds $friend +{ + error_log('ejabberd_friend_request'); + ejabberd_friend_command($friend, $user, 'subscribe', true); // out:$user : $friend + error_log('ejabberd_friend_requested'); +} +function ejabberd_friend_accept($user, $friend) // $user adds $friend +{ + error_log('ejabberd_friend_accept'); + ejabberd_friend_command($friend, $user, 'subscribed', true); + // following might be needed to have symmetry (and important for remote) + if ($friend->foreign) { + // following is needed for xmpp nodes + ejabberd_friend_command($friend, $user, 'subscribe', true); + } + // ejabberd_friend_command($friend, $user, 'subscribed', false); + // following can't be faked + if (!$friend->foreign) + ejabberd_friend_command($user, $friend, 'subscribed', true); + error_log('ejabberd_friend_accepted'); +} +function ejabberd_friend_deny($user, $friend) // $user adds $friend +{ + error_log('ejabberd_friedeny'); + ejabberd_friend_command($friend, $user, 'unsubscribed', true); +} +function ejabberd_friend_remove($user, $friend) // $user adds $friend +{ + error_log('ejabberd_friend_remove'); + if ($friend->foreign) { + ejabberd_friend_command($friend, $user, 'unsubscribed', true); + ejabberd_friend_command($friend, $user, 'unsubscribed', false); + } + else + ejabberd_friend_command($friend, $user, 'unsubscribed', false); + if (!$friend->foreign) + ejabberd_friend_command($user, $friend, 'unsubscribed', false); + error_log('ejabberd_friend_removed'); +} + +/*function ejabberd_send_chat($from, $to, $body) { // $user adds $friend + $param = array("body"=>$body, + "from"=>$from, + "to"=>$to); + ejabberd_xmlrpc_command('send_chat_message', $param); +}*/ + + +?> diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 000000000..8e880d305 --- /dev/null +++ b/manifest.xml @@ -0,0 +1,16 @@ + + + Beechat + Beechannels + Lorea dev + 1.8 + widget + XMPP chat for elgg. + http://www.elgg.org + See COPYRIGHT.txt + GNU General Public License version 2 + + elgg_release + 1.8 + + false + diff --git a/sounds/newmessage.wav b/sounds/newmessage.wav new file mode 100644 index 000000000..58cccd0e6 Binary files /dev/null and b/sounds/newmessage.wav differ diff --git a/start.php b/start.php new file mode 100644 index 000000000..2fe38b5d5 --- /dev/null +++ b/start.php @@ -0,0 +1,181 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + + GLOBAL $CONFIG; + + function beechat_create_group($event, $object_type, $object) + { + elgg_load_library('elgg:beechat'); + ejabberd_create_group($object); + } + + function beechat_delete_group($event, $object_type, $object) + { + elgg_load_library('elgg:beechat'); + ejabberd_destroy_group($object); + } + + function beechat_member_add($event, $object_type, $object) + { + if ($object->relationship === "member") { + elgg_load_library('elgg:beechat'); + $user = get_entity($object->guid_one); + $group = get_entity($object->guid_two); + $room = new EjabberdMucRoom($group); + $room->addMember($user); + } + } + + function beechat_member_delete($event, $object_type, $object) + { + if ($object->relationship === "member") { + elgg_load_library('elgg:beechat'); + $user = get_entity($object->guid_one); + $group = get_entity($object->guid_two); + $room = new EjabberdMucRoom($group); + $room->setAffiliation($user, "none"); + } + } + + function beechat_init() + { + $pluginspath = elgg_get_plugins_path(); + elgg_register_library('elgg:beechat', $pluginspath . 'beechat/lib/beechat.php'); + + elgg_register_event_handler('pagesetup', 'system', 'beechat_pagesetup'); + // group actions disabled for now + /*if (elgg_get_plugin_setting("groupdomain", "beechat")) { + register_elgg_event_handler('create', 'group', 'beechat_create_group'); + register_elgg_event_handler('delete', 'group', 'beechat_delete_group'); + } + register_elgg_event_handler('create', 'member', 'beechat_member_add'); + register_elgg_event_handler('delete', 'relationship', 'beechat_member_delete');*/ + + + $actions_path = $pluginspath . 'beechat/actions/'; + elgg_register_action('beechat/join_groupchat', $actions_path . 'join_groupchat.php'); + elgg_register_action('beechat/leave_groupchat', $actions_path . 'leave_groupchat.php'); + elgg_register_action('beechat/get_statuses', $actions_path . 'get_statuses.php'); + elgg_register_action('beechat/get_icons', $actions_path . 'get_icons.php'); + elgg_register_action('beechat/get_details', $actions_path . 'get_details.php'); + elgg_register_action('beechat/get_connection', $actions_path . 'get_connection.php'); + elgg_register_action('beechat/get_state', $actions_path . 'get_state.php'); + elgg_register_action('beechat/save_state', $actions_path . 'save_state.php'); + + /*register_elgg_event_handler('create', 'friendrequest', 'beechat_xmpp_add_friendx'); + #register_plugin_hook('action', 'friends/add', 'beechat_xmpp_add_friend', 1000); + register_plugin_hook('river_update', 'river_update', 'beechat_xmpp_approve_friendx'); + register_plugin_hook('river_update_foreign', 'river_update', 'beechat_xmpp_approve_friendx'); + #register_plugin_hook('action', 'friendrequest/approve', 'beechat_xmpp_approve_friend', 1000); + + + register_plugin_hook('action', 'friendrequest/decline', 'beechat_xmpp_decline_friend', 1000); + register_plugin_hook('action', 'friends/remove', 'beechat_xmpp_remove_friend', 1000);*/ + + // new friend sync + elgg_register_event_handler('delete', 'friend', array('BeechatSync', 'onFriendDelete')); + elgg_register_event_handler('create', 'friendrequest', array('BeechatSync', 'onFriendCreate')); + elgg_register_event_handler('delete', 'friendrequest', array('BeechatSync', 'onFriendDelete')); + + + + elgg_extend_view('js/initialise_elgg', 'js/json2.js'); + elgg_extend_view('js/initialise_elgg', 'js/jquery.cookie.min.js'); + elgg_extend_view('js/initialise_elgg', 'js/jquery.scrollTo-min.js'); + elgg_extend_view('js/initialise_elgg', 'js/jquery.serialScroll-min.js'); + elgg_extend_view('js/initialise_elgg', 'js/b64.js'); + elgg_extend_view('js/initialise_elgg', 'js/sha1.js'); + elgg_extend_view('js/initialise_elgg', 'js/md5.js'); + elgg_extend_view('js/initialise_elgg', 'js/strophe.min.js'); + elgg_extend_view('js/initialise_elgg', 'js/strophe.muc.js'); + elgg_extend_view('js/initialise_elgg', 'js/jquery.tools.min.js'); + elgg_extend_view('css', 'beechat/screen.css'); + elgg_extend_view('js/initialise_elgg', 'beechat/beechat.js'); + elgg_extend_view('page/elements/head', 'beechat/beechat.userjs'); + + elgg_extend_view('page/elements/foot', 'beechat/beechat'); + + $domain = elgg_get_plugin_setting("domain", "beechat"); + $group_domain = elgg_get_plugin_setting("groupdomain", "beechat"); + $dbname = elgg_get_plugin_setting("dbname", "beechat"); + $dbhost = elgg_get_plugin_setting("dbhost", "beechat"); + $dbuser = elgg_get_plugin_setting("dbuser", "beechat"); + $dbpassword = elgg_get_plugin_setting("dbpassword", "beechat"); + + global $CONFIG; + $CONFIG->chatsettings['domain'] = $domain; + $CONFIG->chatsettings['groupdomain'] = $group_domain; + + register_notification_handler('xmpp', 'beechat_notifications'); + // register_plugin_hook('notify:entity:message','object','beechat_notifications_msg'); + } + + function beechat_notifications($from, $to, $subject, $topic, $params = array()) { + ejabberd_send_chat($to, "
".$topic."
"); + } + + + function beechat_friendly_title($title) { + // need this because otherwise seems elgg + // gets in some problem trying to call the view + //$title = iconv('UTF-8', 'ASCII//TRANSLIT', $title); + $title = preg_replace("/[^\w ]/","",$title); + $title = str_replace(" ","-",$title); + $title = str_replace("--","-",$title); + $title = trim($title); + $title = strtolower($title); + return $title; + } + + function beechat_pagesetup() + { + global $CONFIG; + if (get_context() == 'groups' && isloggedin()) { + if (get_plugin_setting("groupdomain", "beechat")) { + $user = get_loggedin_user(); + $group = page_owner_entity(); + if (!$group || !($group instanceof ElggGroup)) + return; + if ($user->chatenabled && get_plugin_setting("groupdomain", "beechat")) { + if ($group->isPublicMembership() || $group->isMember($user)) + add_submenu_item(elgg_echo('beechat:chatroom'), "javascript:g_beechat_user.joinRoom('".beechat_friendly_title($group->name)."@".$CONFIG->chatsettings['groupdomain']."', '".$group->guid."')"); + } + } + } + elseif (get_context() == 'settings' && isloggedin()) { + if (get_loggedin_user()->chatenabled) { + add_submenu_item(elgg_echo('beechat:disablechat'), $CONFIG->wwwroot . "mod/beechat/disablechat.php"); + } + else + add_submenu_item(elgg_echo('beechat:enablechat'), $CONFIG->wwwroot . "mod/beechat/enablechat.php"); + } + } + + + function ejabberd_send_chat($user, $body) { // $user adds $friend + $from = 'notify@'.get_plugin_setting("domain", "beechat").'/net'; + if ($user->alias) { + + } + elgg_load_library('elgg:beechat'); + $to = ejabberd_getjid($user, true); + #xmlrpc_set_type(&$body, "base64"); + $param = array("body"=>$body, + "from"=>$from, + "to"=>$to); + ejabberd_xmlrpc_command('send_html_message', $param); + } + + + + +elgg_register_event_handler('init', 'system', 'beechat_init'); +?> diff --git a/views/default/beechat/beechat.js.php b/views/default/beechat/beechat.js.php new file mode 100644 index 000000000..3cdd29d12 --- /dev/null +++ b/views/default/beechat/beechat.js.php @@ -0,0 +1,2468 @@ +/** + * Beechat + * + * @package beechat + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Beechannels + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + +/** Globals + * + */ +g_beechat_user = null; +g_beechat_roster_items = null; +g_beechat_rooms = new Array(); + +function debugXMPP(msg) { + try { + //console.log(msg) + } + catch (err) { + } + //$('#layout_footer').html($('#layout_footer').html()+'
'+msg); +} + +/** Class: BeeChat + * An object container for all BeeChat mod functions + * + */ +BeeChat = { + BOSH_SERVICE: '/http-bind/', + DOMAIN: 'chatsettings['domain'] ?>', + RESOURCE: 'beebac', + INACTIVITY_PERIOD_LENGTH: 60, + + NS: { + CHAT_STATES: 'http://jabber.org/protocol/chatstates' + }, + + Message: { + Types: { + NORMAL: 'normal', + CHAT: 'chat', + GROUPCHAT: 'groupchat', + HEADLINE: 'headline', + ERROR: 'error' + }, + + ChatStates: { + COMPOSING: 'composing', + PAUSED: 'paused', + ACTIVE: 'active', + INACTIVE: 'inactive', + GONE: 'gone' + } + }, + + IQ: { + Types: { + GET: 'get', + RESULT: 'result', + SET: 'set', + ERROR: 'error' + } + }, + + Presence: { + Types: { + UNAVAILABLE: 'unavailable', + SUBSCRIBE: 'subscribe', + SUBSCRIBED: 'subscribed', + UNSUBSCRIBE: 'unsubscribe', + UNSUBSCRIBED: 'unsubscribed', + PROBE: 'probe', + ERROR: 'error' + }, + + ChildElements: { + SHOW: 'show', + STATUS: 'status', + PRIORITY: 'priority' + }, + + ShowElements: { + CHAT: 'chat', + DND: 'dnd', + AWAY: 'away', + XA: 'xa' + } + }, + + Roster: { + DEFAULT_GROUP: 'Contacts' + }, + + + Events: { + Identifiers: { + UPDATE_CONNECTION_STATE: 0, + UPDATE_ROSTER: 1, + RECV_PRESENCE: 2, + RECV_CHAT_MESSAGE: 3 + }, + Messages: { + ConnectionStates: { + CONNECTING: "", + AUTHENTICATING: "", + FAILED: "", + DISCONNECTING: "", + OFFLINE: "", + ONLINE: "" + } + } + } +}; + + +/** Class: BeeChat.Core + * An object container for all BeeChat Core functions + * + */ +BeeChat.Core = { + ReferenceTables: { + AvailabilityRates: { + AVAILABLE: 0, + ONLINE: 0, + CHAT: 0, + DND: 1, + AWAY: 2, + XA: 3, + UNAVAILABLE: 10, + OFFLINE: 10 + } + } +}; + + +/** Class: BeeChat.Core.User + * Create a BeeChat.Core.User object + * + * Parameters: + * (String) jid - The user's jabber id + * + * Returns: + * A new BeeChat.Core.User. + */ +BeeChat.Core.User = function(jid) +{ + if (!(this instanceof arguments.callee)) + return new BeeChat.Core.User(jid); + + /** Private members + * + */ + var _connection = null; + var _attached = false; + var _initialized = false; + var _jid = null; + var _roster = null; + var _msgTemp = []; + var _funcs = []; + + /** Constructor + * + */ + this.init = function(jid) + { + _jid = jid; + _roster = new BeeChat.Core.Roster(); + } + + /** Accessors + * + */ + this.getConnection = function() + { + return _connection; + } + + this.getJid = function() + { + return _jid; + } + + this.getRoster = function() + { + return _roster; + } + + this.isAttached = function() + { + return _attached; + } + + this.isInitialized = function() + { + return _initialized; + } + + /** Mutators + * + */ + this.setInitialized = function(isInitialized) + { + _initialized = isInitialized; + } + + /** Function: addObserver + * Add an observer for a specified type of event + * + * Parameters: + * (BeeChat.Events.Identifiers) eventType - The type of event to observer + * (Object) pFunc - A function to call when the event will be triggered + */ + this.addObserver = function(eventType, pFunc) + { + if (jQuery.inArray(pFunc, _funcs) == -1) { + if (!_funcs[eventType]) + _funcs[eventType] = []; + _funcs[eventType].push(pFunc); + } + } + + /** Function: removeObserver + * Remove an observer + * + * Parameters: + * (Object) pFunc - The registered function + */ + this.removeObserver = function(pFunc) + { + var index = null; + + for (var key in _funcs) { + if (typeof _funcs[key] != 'object') + continue; + if ((index = jQuery.inArray(pFunc, _funcs[key])) != -1) + _funcs.splice(index, 1); + } + } + + /** Function: connect + * Connect the user to the BOSH service + * + * Parameters: + * (String) password - The user's password + * + */ + this.connect = function(password) + { + debugXMPP('connect'); + if (_connection == null) + _connection = new Strophe.Connection(BeeChat.BOSH_SERVICE); + _connection.connect(_jid, password, _onConnect); + } + + /** Function: attach + * Attach user's connection to an existing XMPP session + * + * Parameters: + * (String) sid - The SID of the existing XMPP session + * (String) rid - The RID of the existing XMPP session + */ + this.attach = function(sid, rid) + { + if (_connection == null) { + _connection = new Strophe.Connection(BeeChat.BOSH_SERVICE); + } + _connection.attach(_jid, sid, rid, _onConnect); + _attached = true; + _onConnect(Strophe.Status.CONNECTED); + } + + /** Function: disconnect + * Disconnect the user from the BOSH service + * + */ + this.disconnect = function() + { + debugXMPP('disconnect'); + if (_connection != null) { + _connection.disconnect(); + _connection = null; + } + } + + /** Function: requestSessionPause + * Request a session pause to the server connection manager + * + */ + this.requestSessionPause = function() + { + var req = $build('body', { + rid: _connection.rid, + sid: _connection.sid, + pause: BeeChat.INACTIVITY_PERIOD_LENGTH, + xmlns: Strophe.NS.HTTPBIND + }); + + _attached = false; + _connection.send(req.tree()); + } + + /** Function: requestRoster + * Request a new roster to the server + * + */ + this.requestRoster = function() + { + var req = $iq({from: _jid, type: BeeChat.IQ.Types.GET}) + .c('query', {xmlns: Strophe.NS.ROSTER}); + + _connection.send(req.tree()); + } + + /** Function: sendInitialPresence + * Send initial presence to the server in order to signal availability for communications + * + */ + this.sendInitialPresence = function() + { + _connection.send($pres().tree()); + _initialized = true; + } + + /** Function: sendChatMessage + * Send a chat message to the server + * + * Parameters: + * (String) addressee - The addressee of the chat message + * (String) msg - The chat message + * + */ + this.sendChatMessage = function(addressee, msg, msgtype) + { + if (msgtype == null) + msgtype = BeeChat.Message.Types.CHAT; + var req = $msg({ + type: msgtype, + to: addressee, + from: _connection.jid + }).c('body').t(msg).up().c(BeeChat.Message.ChatStates.ACTIVE, {xmlns: BeeChat.NS.CHAT_STATES}); + + _connection.send(req.tree()); + } + + /** Function: sendChatStateMessage + * Send a chat state message to the server + * + * Parameters: + * (String) addressee - The addressee of the chat state message + * (BeeChat.Message.ChatsState) state - The chat state that will be send + * + */ + this.sendChatStateMessage = function(addressee, state) + { + var req = $msg({ + type: BeeChat.Message.Types.CHAT, + to: addressee, + from: _connection.jid + }).c(state, {xmlns: BeeChat.NS.CHAT_STATES}); + + _connection.send(req.tree()); + } + + /** Function: sendPresenceAvailabiliy + * Send a detailed presence stanza to the server + * + * Parameters: + * (BeeChat.Presence.ShowElements) availability - The availability status + * (String) details - Detailed status information + * + */ + this.sendPresenceAvailability = function(availability, details) + { + var req = $pres() + .c(BeeChat.Presence.ChildElements.SHOW).t(availability).up() + .c(BeeChat.Presence.ChildElements.STATUS).t(details).up() + .c(BeeChat.Presence.ChildElements.PRIORITY).t('1'); + + _connection.send(req.tree()); + } + + /** PrivateFunction: _fire + * Triggers registered funcs of registered observers for a specified type of event + * + */ + function _fire(eventType, data, scope) + { + if (_funcs[eventType] != undefined) { + for (var i = 0; i < _funcs[eventType].length; i++) + _funcs[eventType][i].call((scope || window), data); + } + } + this.joinRoom = function(roomname, room_guid) { + var roomJid = roomname; + _connection['muc'].join(roomJid, BeeChat.UI.Resources.Strings.ChatMessages.SELF, false, false, ''); + if (!(roomJid in g_beechat_rooms)) { + g_beechat_rooms[roomJid] = room_guid; + $.ajax({ + url: BeeChat.UI.addActionTokens(''+room_guid, '&'), + async: true }); + } + + + } + + this.reconnectRooms = function() { + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().each(function() { + if (roomJid in g_beechat_rooms) + delete g_beechat_rooms[roomJid]; + var contactBareJid = $(this).attr('bareJid'); + var isroom = ($(this).attr('isroom')=='true')?true:false; + if (isroom) { + _connection['muc'].join(contactBareJid, BeeChat.UI.Resources.Strings.ChatMessages.SELF, false, false, ''); + } + }); + } + + this.leaveRoom = function(roomJid) { + if (roomJid in g_beechat_rooms) { + $.ajax({ + url: BeeChat.UI.addActionTokens(''+g_beechat_rooms[roomJid], '&'), + async: true }); + + } + _connection['muc'].leave(roomJid, BeeChat.UI.Resources.Strings.ChatMessages.SELF, function(){}); + } + + /** PrivateFunction: _onConnect + * Connection state manager + * + * Parameters: + * (Strophe.Status) status - A Strophe connection status constant + * + */ + function _onConnect(status) + { + var msg = null; + + if (status == Strophe.Status.CONNECTING) +{ + msg = BeeChat.Events.Messages.ConnectionStates.CONNECTING; + } + else if (status == Strophe.Status.AUTHENTICATING) { + msg = BeeChat.Events.Messages.ConnectionStates.AUTHENTICATING; + } + else if (status == Strophe.Status.AUTHFAIL) + msg = BeeChat.Events.Messages.ConnectionStates.FAILED; + else if (status == Strophe.Status.CONNFAIL) + msg = BeeChat.Events.Messages.ConnectionStates.FAILED; + else if (status == Strophe.Status.DISCONNECTING) + msg = BeeChat.Events.Messages.ConnectionStates.DISCONNECTING; + else if (status == Strophe.Status.DISCONNECTED) + msg = BeeChat.Events.Messages.ConnectionStates.OFFLINE; + else if (status == Strophe.Status.CONNECTED) { + msg = BeeChat.Events.Messages.ConnectionStates.ONLINE; + _connection.addHandler(_onIQResult, null, 'iq', BeeChat.IQ.Types.RESULT, null, null); + _connection.addHandler(_onPresence, null, 'presence', null, null, null); + _connection.addHandler(_onMessageChat, null, 'message', BeeChat.Message.Types.CHAT, null, null); + _connection.addHandler(_onMessageChatRoom, null, 'message', BeeChat.Message.Types.GROUPCHAT, null, null); + } + + _fire(BeeChat.Events.Identifiers.UPDATE_CONNECTION_STATE, msg); + } + + /** PrivateFunction: _onIQResult + * Manage received IQ stanza of 'result' type + * + * Parameters: + * (XMLElement) iq - The iq stanza received + * + */ + function _onIQResult(iq) + { + _roster.updateFromIQResult(iq); + _fire(BeeChat.Events.Identifiers.UPDATE_ROSTER, _roster.getItems()); + + return true; + } + + /** PrivateFunction: _onPresence + * Manage received presence stanza + * + * Parameters: + * (XMLElement) presence - The presence stanza received + * + */ + function _onPresence(presence) + { + var xquery = presence.getElementsByTagName("x"); + debugXMPP('_onPresence'+xquery); + if (xquery.length > 0) + { + //Ignore MUC user protocol + for (var i = 0; i < xquery.length; i++) + { + var xmlns = xquery[i].getAttribute("xmlns"); + if (xmlns && xmlns.match(Strophe.NS.MUC + '#user')) + { + var contactBareJid = $(presence).attr('from').split('/')[0]; + var userNick = $(presence).attr('from').split('/')[1]; + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + if ($(presence).attr('type') != 'unavailable') { + BeeChat.UI.ChatBoxes.updateRoster(contactBareJid, userNick, presence); + } + else { + if (chatBoxElm.length) { + BeeChat.UI.ChatBoxes.updateRoster(contactBareJid, userNick, presence); + } + } + return true; + } + + if (xmlns && xmlns.match(Strophe.NS.MUC)) + { + var contactBareJid = $(presence).attr('from').split('/')[0]; + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + + if ($(presence).attr('type') != 'unavailable' && $(presence).attr('type') != 'error') { + if (chatBoxElm.length == 0) { + BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); + } + } + return true; + } + + } + } + + if (Strophe.getBareJidFromJid($(presence).attr('from')).toLowerCase() != Strophe.getBareJidFromJid(_jid).toLowerCase()) { + _roster.updateFromPresence(presence); + } + _fire(BeeChat.Events.Identifiers.RECV_PRESENCE, _roster.getOnlineItems()); + return true; + } + + /** PrivateFunction: _onMessageChat + * Manage received message stanza of 'chat' type + * + * Parameters: + * (XMLElement) message - The message stanza received + * + */ + function _onMessageChatRoom(message) + { + var roomJid = $(message).attr('from').split('/'); + +// BeeChat.UI.ChatBoxes.updateChatState($(message).attr('from'), message); + BeeChat.UI.ChatBoxes.update(roomJid[0], roomJid[1], Strophe.getText($(message).find('body')[0]), true); + + return true; + } + + function _onMessageChat(message) + { + var data = { + contactBareJid: Strophe.getBareJidFromJid($(message).attr('from')), + msg: message + }; + _msgTemp.push(data); + //alert("message"); + if (_initialized == true) { + for (var key in _msgTemp) { + if (typeof _msgTemp[key] != 'object') + continue; + _fire(BeeChat.Events.Identifiers.RECV_CHAT_MESSAGE, _msgTemp[key]); + _msgTemp.shift(); + } + } + + return true; + } + + this.init(jid); +}; + + +/** Constructor: BeeChat.Core.Roster + * Create a BeeChat.Core.Roster object + * + * Parameters: + * (Object) items - The roster's items in object notation + * + * Returns: + * A new BeeChat.Core.Roster. + */ +BeeChat.Core.Roster = function() +{ + if (!(this instanceof arguments.callee)) + return new BeeChat.Core.Roster(); + + /** Private members + * + */ + _items = null; + + + /** Constructor + * + */ + this.init = function() + { + _items = (arguments.length > 0) ? arguments[0] : {}; + } + + /** Accessors + * + */ + this.getItems = function() + { + return _items; + } + + /** Mutators + * + */ + this.setItems = function(items) + { + for (var key in items) { + _items[key] = new BeeChat.Core.RosterItem(items[key]); + } + } + + this.setIcons = function(icons) + { + if (_items) { + for (var key in icons) { + if (_items[key]) { + _items[key].icon_small = icons[key].small; + _items[key].icon_tiny = icons[key].tiny; + } + + /* if (_items[key]) { + _items[key].icon_small = icons[key].small; + _items[key].icon_tiny = icons[key].tiny; + }*/ + } + } + } + + this.setStatuses = function(statuses) + { + if (_items) { + for (var key in statuses) { + if (_items[key]) { + _items[key].status = statuses[key]; + } + } + } + } + + /** Function: updateFromIQResult + * Update the roster items from an IQ result stanza + * + * Parameters: + * (XMLElement) iq - The IQ result stanza + */ + this.updateFromIQResult = function(iq) + { + $(iq).find('item').each(function() { + var attr = { + bareJid: Strophe.getBareJidFromJid($(this).attr('jid')).toLowerCase(), + name: $(this).attr('name'), + subscription: $(this).attr('subscription'), + groups: [], + presences: {} + }; + + $(this).find('group').each(function() { + attr['groups'].push($(this).text()); + }); + + if (attr['groups'].length == 0) + attr['groups'].push(BeeChat.Roster.DEFAULT_GROUP); + + if (!_items[attr.bareJid]) + _items[attr.bareJid] = new BeeChat.Core.RosterItem(attr); + else { + _items[attr.bareJid].bareJid = attr.bareJid; + _items[attr.bareJid].name = attr.name; + _items[attr.bareJid].subscription = attr.subscription; + _items[attr.bareJid].groups = attr.groups; + } + }); + } + + /** Function: updateFromPresence + * Update the roster items from a presence stanza + * + * Parameters: + * (XMLElement) presence - The presence stanza + * + * Returns: + * (String) The bare jid of the roster item who updated his presence + */ + this.updateFromPresence = function(presence) + { + var jid = $(presence).attr('from').toLowerCase(); + var attr = { + bareJid: Strophe.getBareJidFromJid(jid), + name: null, + subscription: null, + groups: null, + presences: {} + }; + + attr.presences[jid] = {}; + attr.presences[jid].type = (!$(presence).attr('type')) ? 'available' : $(presence).attr('type'); + //alert($(presence).attr('from')+presence.toString()); + //alert("presencetype"+attr.presences[jid].type); + + if (attr.presences[jid].type == 'available') { + $(presence).children().each(function() { + if (this.tagName == BeeChat.Presence.ChildElements.SHOW) + attr.presences[jid].show = $(this).text(); + if (this.tagName == BeeChat.Presence.ChildElements.STATUS) + attr.presences[jid].status = $(this).text(); + }); + + if (!attr.presences[jid].show) + attr.presences[jid].show = 'chat'; + } else { + attr.presences[jid].show = 'offline'; + } + + if (!_items[attr.bareJid]) + _items[attr.bareJid] = new BeeChat.Core.RosterItem(attr); + else + _items[attr.bareJid].presences[jid] = attr.presences[jid]; + } + + /** Function: getOnlineItems + * + * + */ + this.getOnlineItems = function() + { + var sortedOnlineBareJid = []; + var sortedOnlineItems = {}; + + for (var key in _items) { + if (typeof _items[key] != 'object') + continue; + + var pres = _items[key].getStrongestPresence(); + + if (pres != null && pres.type == 'available') { + sortedOnlineBareJid.push(key); + } + } + + if (sortedOnlineBareJid.length > 1) { + sortedOnlineBareJid.sort(); + sortedOnlineBareJid.sort(statusSort); + } + + for (var key in sortedOnlineBareJid) { + sortedOnlineItems[sortedOnlineBareJid[key]] = _items[sortedOnlineBareJid[key]]; + } + + return (sortedOnlineItems); + } + + /** Function: getSizeOnlineItems + * Return the number of available items + * + * Returns: + * (int) The number of available items + */ + this.getSizeOnlineItems = function() + { + var n = 0; + + for (var key in _items) { + if (typeof _items[key] != 'object') + continue; + + var pres = _items[key].getStrongestPresence(); + + if (pres != null && pres.type == 'available') + ++n; + } + return (n); + } + + /** Function: getItemsUsernamesAsList + * + */ + this.getItemsUsernamesAsList = function() + { + var data = ''; + + for (var key in _items) { + if (typeof _items[key] != 'object') + continue; + data = data + Strophe.getBareJidFromJid(key) + ','; + // data = data + Strophe.getNodeFromJid(key) + ','; + } + + return (data); + } + + /** PrivateFunction: statusSort + * + */ + function statusSort(x, y) + { + var xPres = _items[x].getStrongestPresence(); + var yPres = _items[y].getStrongestPresence(); + + if (xPres != null && yPres != null) + return (BeeChat.Core.Roster.Utils.comparePresences(xPres, yPres)); + return (0); + } + + this.init(); +}; + +BeeChat.Core.Roster.Utils = { + + /** Function: comparePresences + * Compare the two presences x and y + * + * Parameters: + * (Object) xPres - The x presence in object notation + * (Object) yPres - The y presence in object notation + * + * Returns: + * 0 if presence are equal, 1 if x > y, -1 if y > x + * + * Note: + * Presences are tagged in the following order: + * ONLINE < DND < AWAY < XA < OFFLINE + * + */ + comparePresences: function(xPres, yPres) + { + var xRate = 0; + var yRate = 0; + + if (xPres.type == 'unavailable') + xRate += BeeChat.Core.ReferenceTables.AvailabilityRates[xPres.type.toUpperCase()]; + if (yPres.type == 'unavailable') + yRate += BeeChat.Core.ReferenceTables.AvailabilityRates[yPres.type.toUpperCase()]; + + if (xPres.show != null) + xRate += BeeChat.Core.ReferenceTables.AvailabilityRates[xPres.show.toUpperCase()]; + if (yPres.show != null) + yRate =+ BeeChat.Core.ReferenceTables.AvailabilityRates[yPres.show.toUpperCase()]; + + if (xRate > yRate) + return (1); + else if (xRate == yRate) + return (0); + return (-1); + } +}; + + +/** Constructor: BeeChat.Core.RosterItem + * Create a BeeChat.Core.RosterItem object + * + * Parameters: + * (Object) attr - The RosterItem's attributes in object notation + * + * Returns: + * A new BeeChat.Core.RosterItem. + */ +BeeChat.Core.RosterItem = function() +{ + this.bareJid = (arguments.length > 0) ? arguments[0].bareJid : null; + this.name = (arguments.length > 0) ? arguments[0].name : null; + this.subscription = (arguments.length > 0) ? arguments[0].subscription : null; + this.groups = (arguments.length > 0) ? arguments[0].groups : null; + this.presences = (arguments.length > 0) ? arguments[0].presences : null; + this.icon_small = (arguments.length > 0) ? arguments[0].icon_small : null; + this.icon_tiny = (arguments.length > 0) ? arguments[0].icon_tiny : null; + this.status = (arguments.length > 0) ? arguments[0].status : null; +}; +BeeChat.Core.RosterItem.prototype = { + /** Function: getStrongestPresence + * Return the strongest presence of the RosterItem + * + */ + getStrongestPresence: function() + { + var res = null; + + for (var key in this.presences) { + if (typeof this.presences[key] != 'object') + continue; + if (res == null) + res = this.presences[key]; + else + if (BeeChat.Core.Roster.Utils.comparePresences(this.presences[key], res) == -1) + res = this.presences[key]; + } + return (res); + } +}; + + +/** Class: BeeChat.UI + * An object container for all BeeChat UI functions + * + */ +BeeChat.UI = { + HAS_FOCUS: true, + + Resources: { + Paths: { + ICONS: 'url; ?>mod/beechat/graphics/icons/', + MEMBER_PROFILE: 'pg/profile/' + }, + + Sounds: { + NEW_MESSAGE: 'beechat_sounds_new_message' + }, + + /* + Cookies: { + DOMAIN: 'beechannels.com', + FILENAME_CONN: 'beechat_conn' + }, + */ + + Emoticons: { + FILENAME_SMILE: 'emoticon_smile.png', + FILENAME_UNHAPPY: 'emoticon_unhappy.png', + FILENAME_GRIN: 'emoticon_grin.png', + FILENAME_EVILGRIN: 'emoticon_evilgrin.png', + FILENAME_SURPRISED: 'emoticon_surprised.png', + FILENAME_TONGUE: 'emoticon_tongue.png', + FILENAME_WINK: 'emoticon_wink.png' + }, + + Strings: { + Availability: { + AVAILABLE: "", + CHAT: "", + ONLINE: "", + DND: "", + AWAY: "", + XA:"", + OFFLINE: "" + }, + + Contacts: { + BUTTON: "" + }, + + ChatMessages: { + SELF: "name; ?>", + COMPOSING: "" + }, + + Box: { + MINIMIZE: "", + CLOSE: "", + SHOWHIDE: "" + } + }, + + StyleClasses: { + Availability: { + Left: { + ONLINE: 'beechat_left_availability_chat', + DND: 'beechat_left_availability_dnd', + AWAY: 'beechat_left_availability_away', + XA: 'beechat_left_availability_xa', + OFFLINE: 'beechat_left_availability_offline', + ROOM: 'beechat_left_availability_room' + }, + + Right: { + ONLINE: 'beechat_right_availability_chat', + DND: 'beechat_right_availability_dnd', + AWAY: 'beechat_right_availability_away', + XA: 'beechat_right_availability_xa', + OFFLINE: 'beechat_right_availability_offline', + ROOM: 'beechat_right_availability_room' + }, + + Control: { + UP: 'beechat_availability_switcher_control_up', + DOWN: 'beechat_availability_switcher_control_down' + } + }, + + ChatBox: { + MAIN: 'beechat_chatbox', + MAINROOM: 'beechat_chatbox_room', + TOP: 'beechat_chatbox_top', + SUBTOP: 'beechat_chatbox_subtop', + TOP_ICON: 'beechat_chatbox_top_icon', + TOP_CONTROLS: 'beechat_chatbox_top_controls', + CONTENT: 'beechat_chatbox_content', + INPUT: 'beechat_chatbox_input', + BOTTOM: 'beechat_chatbox_bottom', + CONTROL: 'beechat_chatbox_control', + STATE: 'beechat_chatbox_state', + MESSAGE: 'beechat_chatbox_message', + MESSAGE_SENDER: 'beechat_chatbox_message_sender', + MESSAGE_DATE: 'beechat_chatbox_message_date', + CHATROOM: 'beechat_chatbox_chatroom', + ROOMROSTER: 'beechat_chatbox_roomroster', + ROSTER_ITEM: 'beechat_chatbox_roomrosteritem' + }, + + ScrollBox: { + SELECTED: 'beechat_scrollbox_selected' + }, + + BOX_CONTROL: 'beechat_box_control', + LABEL: 'beechat_label', + UNREAD_COUNT: 'beechat_unread_count' + }, + + Elements: { + ID_DIV_BAR: 'beechat', + ID_DIV_BAR_CENTER: 'beechat_center', + ID_DIV_BAR_RIGHT: 'beechat_right', + + ID_TOOLTIP_TRIGGER: 'beechat_tooltip_trigger', + + ID_SPAN_CONTACTS_BUTTON: 'beechat_contacts_button', + ID_SPAN_CLOSE_BOX: 'beechat_box_control_close', + + ID_DIV_CONTACTS: 'beechat_contacts', + ID_DIV_CONTACTS_CONTROLS: 'beechat_contacts_controls', + ID_SPAN_CONTACTS_CONTROL_MINIMIZE: 'beechat_contacts_control_minimize', + ID_DIV_CONTACTS_CONTENT: 'beechat_contacts_content', + ID_UL_CONTACTS_LIST: 'beechat_contacts_list', + + ID_DIV_AVAILABILITY_SWITCHER: 'beechat_availability_switcher', + ID_SPAN_AVAILABILITY_SWITCHER_CONTROL: 'beechat_availability_switcher_control', + ID_SPAN_CURRENT_AVAILABILITY: 'beechat_current_availability', + ID_UL_AVAILABILITY_SWITCHER_LIST: 'beechat_availability_switcher_list', + + ID_DIV_CHATBOXES: 'beechat_chatboxes', + + ID_DIV_SCROLLBOXES: 'beechat_scrollboxes' + } + }, + + + /** Function: initialize + * Initialize the BeeChat UI + * + */ + initialize: function(ts, token) + { + this.ts = ts; + this.token = token; + $('#' + BeeChat.UI.Resources.Elements.ID_TOOLTIP_TRIGGER).tooltip({ + offset: [-3, 8], + effect: 'fade' + }); + + $('#accountlinks').find('li').filter('[class=last]').bind('click', function() { + if (g_beechat_user != null) + g_beechat_user.disconnect(); + }); + + BeeChat.UI.AvailabilitySwitcher.initialize(BeeChat.Presence.ShowElements.CHAT); + BeeChat.UI.ContactsList.initialize(); + BeeChat.UI.ScrollBoxes.initialize(); + BeeChat.UI.loadConnection(); + }, + + /** Function: getUserDetails + * Retrieve user details + * + * Returns: + * User details in object notation. + * + */ + addActionTokens: function(url_string, sep) + { + if (sep == null) + sep = "?"; + return url_string + sep + "__elgg_ts="+this.ts + "&__elgg_token=" + this.token; + }, + + getUserDetails: function(cb_func) + { + var json = null; + var self = this; + + $.ajax({ + url: self.addActionTokens(''), + async: true, + dataType: 'json', + success: function(data) { + cb_func(data); + } + }); + + return (json); + }, + + /** Function: connect + * Create the user and connect him to the BOSH service + * + * Parameters: + * (Object) conn - Running connection informations in object notation + */ + connect: function() + { + var conn = (arguments.length > 0) ? arguments[0] : null; + var userDetails = { + jid: (conn != null) ? conn.jid : null, + password: null + } + var self = this; + //alert("connect"); + if (conn == null || (conn != null && conn.attached)) { + BeeChat.UI.getUserDetails(function(retrievedUserDetails) { + userDetails.jid = retrievedUserDetails.username + '@' + BeeChat.DOMAIN + '/' + BeeChat.RESOURCE; + userDetails.password = retrievedUserDetails.password; + self.connect_end(conn, userDetails) + }); + } + else + this.connect_end(conn, userDetails) + }, + + connect_end: function(conn, userDetails) + { + g_beechat_user = new BeeChat.Core.User(userDetails.jid); + g_beechat_user.addObserver(BeeChat.Events.Identifiers.UPDATE_CONNECTION_STATE, BeeChat.UI.updateConnectionStatus); + g_beechat_user.addObserver(BeeChat.Events.Identifiers.UPDATE_ROSTER, BeeChat.UI.onRosterUpdate); + g_beechat_user.addObserver(BeeChat.Events.Identifiers.RECV_PRESENCE, BeeChat.UI.ContactsList.update); + g_beechat_user.addObserver(BeeChat.Events.Identifiers.RECV_CHAT_MESSAGE, BeeChat.UI.onChatMessage); + + if (conn == null || (conn != null && conn.attached)) + g_beechat_user.connect(userDetails.password); + else + g_beechat_user.attach(conn.sid, conn.rid); + }, + + /** Function: disconnect + * Terminate the user's XMPP session + * + */ + disconnect: function() + { + g_beechat_user.disconnect(); + }, + + /** Function: updateConnectionStatus + * + */ + updateConnectionStatus: function(connStatusMsg) + { + BeeChat.UI.ContactsList.updateButtonText(connStatusMsg); + if (connStatusMsg == BeeChat.Events.Messages.ConnectionStates.ONLINE) { + if (!g_beechat_user.isAttached()) { + debugXMPP("not attached"); + BeeChat.UI.ScrollBoxes.isOpened = true; + g_beechat_user.requestRoster(); + g_beechat_user.reconnectRooms(); + //BeeChat.UI.ContactsList.toggleDisplay(); + $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).show(); + $('.' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + '>textarea').removeAttr('disabled'); + for (room_idx in g_user_rooms) { + var room = g_user_rooms[room_idx]; + var chatBox = BeeChat.UI.ChatBoxes.getChatBoxElm(room[0]); + if (chatBox.length == 0) { + g_beechat_user.joinRoom(room[0], room[1]) + } + } + + } + if (g_beechat_user.isAttached()) { + debugXMPP("attached"); + BeeChat.UI.loadState(); + } + + + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'online'); + BeeChat.UI.saveConnection(); + } + else if (connStatusMsg == BeeChat.Events.Messages.ConnectionStates.OFFLINE) { + var contactsBoxElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS); + + if (!contactsBoxElm.is(':hidden')) + BeeChat.UI.ContactsList.toggleDisplay(); + + $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).empty(); + BeeChat.UI.AvailabilitySwitcher.initialize(BeeChat.Presence.ShowElements.CHAT); + BeeChat.UI.ContactsList.updateButtonText(BeeChat.UI.Resources.Strings.Contacts.BUTTON); + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'offline'); + $('.' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + '>textarea').attr('disabled', 'true'); + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().hide(); + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children() + .attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()]); + g_beechat_user = null; + BeeChat.UI.saveConnection(); + } + }, + + /** Function: saveConnection + * Save connection informations (non sensible data) in $_SESSION. + * + */ + saveConnection: function() + { + var conn = null; + + if (g_beechat_user != null) { + var userConn = g_beechat_user.getConnection(); + + conn = { + 'jid': userConn.jid, + 'sid': userConn.sid, + 'rid': userConn.rid, + 'attached': g_beechat_user.isAttached() + }; + } + var self = this; + + $.ajax({ + type: 'POST', + async: false, + url: self.addActionTokens(''), + data: { beechat_conn: JSON.stringify(conn) } + }); + + /* + $.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN, null); + $.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN, JSON.stringify(conn), {path: '/', domain: BeeChat.UI.Resources.Cookies.DOMAIN}); + */ + }, + + /** Function: loadConnection + * Check if a connection already exists. In the case that a connection exists, + * this function triggers the connection process. + * + */ + loadConnection: function() + { + var self = this; + $.ajax({ + type: 'GET', + async: false, + cache: false, + dataType: 'json', + url: self.addActionTokens(''), + success: function(conn) { + if (conn != null) { + if (conn.attached) + BeeChat.UI.connect(); + else + BeeChat.UI.connect(conn); + } + }, + error: function() { + BeeChat.UI.connect(); + } + }); + + /* + var conn = JSON.parse($.cookie(BeeChat.UI.Resources.Cookies.FILENAME_CONN)); + + if (conn != null) { + if (conn.attached) + BeeChat.UI.connect(); + else + BeeChat.UI.connect(conn); + } else + BeeChat.UI.connect(); + */ + }, + + /** Function: saveState + * Save app state in $_SESSION + * + */ + saveState: function() + { + var self = this; + var currentAvailabilityClass = $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY).attr('class'); + var currentAvailability = currentAvailabilityClass.substr(currentAvailabilityClass.lastIndexOf('_') + 1); + + var data = { + availability: currentAvailability, + contacts: g_beechat_roster_items, + chats: {}, + contacts_list: { + minimized: $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS).is(':hidden') + } + }; + + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().each(function() { + var contactBareJid = $(this).attr('bareJid'); + //var contactBareJid = $(this).data('bareJid'); + var isroom = ($(this).attr('isroom') == 'true'); + if (isroom) + var roster = $(this).find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); + data.chats[contactBareJid] = { + 'html_content': escape($(this).children().filter('[bareJid=' + contactBareJid + ']').html()), + 'roster_content': isroom?escape(roster.html()):'', + 'isroom': $(this).attr('isroom'), + 'group_guid': (contactBareJid in g_beechat_rooms)?g_beechat_rooms[contactBareJid]:0, + 'minimized': $(this).is(':hidden'), + 'unread': BeeChat.UI.UnreadCountBox.getElm(contactBareJid).text() + }; + }); + + $.ajax({ + type: 'POST', + async: false, + url: self.addActionTokens(''), + data: { beechat_state: JSON.stringify(data) } + }); + }, + + /** Function: loadState + * Load app state from $_SESSION + * + */ + loadState: function() + { + var self = this; + $.ajax({ + type: 'GET', + async: true, + cache: false, + dataType: 'json', + url: self.addActionTokens(''), + error: function() { + alert('error getting state'); + }, + success: function(json) { + debugXMPP('loadState'); + BeeChat.UI.AvailabilitySwitcher.initialize(json.availability); + + if (!json.contacts_list.minimized) { + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS).show(); + BeeChat.UI.ContactsList.showedStyle(); + } + + g_beechat_user.getRoster().setItems(json.contacts); + self.loadRosterItemsIcons(); + self.loadRosterItemsStatuses(); + g_beechat_roster_items = g_beechat_user.getRoster().getItems(); + BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) + g_beechat_user.setInitialized(true); + + var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); + var scrollBoxElmToShow = null; + + // Load save chats + for (var key in json.chats) { + var isroom = (json.chats[key].isroom == 'true'); + if (isroom) + BeeChat.UI.ScrollBoxes.addRoom(key); + else + BeeChat.UI.ScrollBoxes.add(key); + + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(key); + chatBoxElm.hide(); + + if (!json.chats[key].minimized) { + scrollBoxElmToShow = BeeChat.UI.ScrollBoxes.getScrollBoxElm(key); + } + + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + key + ']'); + + chatBoxContentElm.append(unescape(json.chats[key].html_content)); + chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')}); + if (isroom) { + g_beechat_rooms[key] = json.chats[key].room_guid; + var rosterElm = chatBoxElm.find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); + rosterElm.append(unescape(json.chats[key].roster_content)); + } + + BeeChat.UI.UnreadCountBox.update(key, json.chats[key].unread); + } + if (scrollBoxElmToShow != null) + scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElmToShow)); + else + scrollBoxesElm.trigger('goto', 0); + + // g_beechat_user.sendPresenceAvailability(json.availability, ''); + BeeChat.UI.ScrollBoxes.isInitialized = true; + BeeChat.UI.ScrollBoxes.isOpened = true; + + for (var key in json.chats) { + if (json.chats[key].minimized) { + BeeChat.UI.ChatBoxes.getChatBoxElm(key).hide(); + BeeChat.UI.ScrollBoxes.unselect(key); + } + else { + BeeChat.UI.ChatBoxes.getChatBoxElm(key).show(); + BeeChat.UI.ScrollBoxes.select(key); + } + } + for (room_idx in g_user_rooms) { + var room = g_user_rooms[room_idx]; + var chatBox = BeeChat.UI.ChatBoxes.getChatBoxElm(room[0]); + if (chatBox.length == 0) { + g_beechat_user.joinRoom(room[0], room[1]) + } + } + + }, + error: function() { + BeeChat.UI.ContactsList.initialize(); + } + }); + }, + + /** Function: loadRosterItemsIcons + * + */ + loadRosterItemsIcons: function() + { + var data = g_beechat_user.getRoster().getItemsUsernamesAsList(); + var self = this; + + $.ajax({ + type: 'POST', + url: self.addActionTokens(''), + async: true, + cache: false, + data: {'beechat_roster_items_usernames': data}, + dataType: 'json', + success: function(json) { + g_beechat_user.getRoster().setIcons(json); + g_beechat_roster_items = g_beechat_user.getRoster().getItems(); + + BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) + } + }); + }, + + /** Function: loadRosterItemsStatuses + * + */ + loadRosterItemsStatuses: function() + { + var data = g_beechat_user.getRoster().getItemsUsernamesAsList(); +//alert(data) + var self = this; + $.ajax({ + type: 'POST', + url: self.addActionTokens(''), + async: true, + cache: false, + data: {'beechat_roster_items_usernames': data}, + dataType: 'json', + success: function(json) { + g_beechat_user.getRoster().setStatuses(json); + g_beechat_roster_items = g_beechat_user.getRoster().getItems(); + BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) + } + }); + }, + + /** Function: onRosterUpdate + * Notified by core on a roster update + * + */ + onRosterUpdate: function(rosterItems) + { + g_beechat_roster_items = rosterItems; + //alert("get roster"); + if (!g_beechat_user.isInitialized()) { + //alert("load roster" + rosterItems.length); + BeeChat.UI.loadRosterItemsStatuses(); + BeeChat.UI.loadRosterItemsIcons(); + g_beechat_user.sendInitialPresence(); + } + }, + + /** Function: onChatMessage + * + */ + onChatMessage: function(data) + { + if ($(data.msg).find('body').length == 0) { + BeeChat.UI.ChatBoxes.updateChatState(data.contactBareJid, data.msg); + } + else { + BeeChat.UI.ChatBoxes.update(data.contactBareJid, BeeChat.UI.Utils.getContactName(data.contactBareJid), Strophe.getText($(data.msg).find('body')[0])); + } + } +}; + + +/** Class: BeeChat.UI.Resources.ReferenceTables + * An object container for all reference tables + * + */ +BeeChat.UI.Resources.ReferenceTables = { + Styles: { + Availability: { + Left: { + AVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Left.ONLINE, + CHAT: BeeChat.UI.Resources.StyleClasses.Availability.Left.ONLINE, + DND: BeeChat.UI.Resources.StyleClasses.Availability.Left.DND, + AWAY: BeeChat.UI.Resources.StyleClasses.Availability.Left.AWAY, + XA: BeeChat.UI.Resources.StyleClasses.Availability.Left.XA, + UNAVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Left.OFFLINE, + OFFLINE: BeeChat.UI.Resources.StyleClasses.Availability.Left.OFFLINE, + ROOM: BeeChat.UI.Resources.StyleClasses.Availability.Left.ROOM + }, + + Right: { + AVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Right.ONLINE, + CHAT: BeeChat.UI.Resources.StyleClasses.Availability.Right.ONLINE, + DND: BeeChat.UI.Resources.StyleClasses.Availability.Right.DND, + AWAY: BeeChat.UI.Resources.StyleClasses.Availability.Right.AWAY, + XA: BeeChat.UI.Resources.StyleClasses.Availability.Right.XA, + UNAVAILABLE: BeeChat.UI.Resources.StyleClasses.Availability.Right.OFFLINE, + OFFLINE: BeeChat.UI.Resources.StyleClasses.Availability.Right.OFFLINE, + ROOM: BeeChat.UI.Resources.StyleClasses.Availability.Right.ROOM + } + } + } +}; + + +/** Class: BeeChat.UI.ContactsList + * An object container for all ContactsList functions + * + */ +BeeChat.UI.ContactsList = { + /** Function: initialize + * Initialize the contacts list by binding elements + * + */ + initialize: function() + { + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_CONTROL_MINIMIZE).unbind('click').bind('click', BeeChat.UI.ContactsList.toggleDisplay); + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).unbind('click').bind('click', function() { + if (g_beechat_user == null) + BeeChat.UI.connect(); + else + BeeChat.UI.ContactsList.toggleDisplay(); + }); + }, + + /** Function: update + * Update the contacts list content + * + * Parameters: + * (Object)(BeeChat.Core.RosterItem) onlineRosterItems - A hash of RosterItems in object notation + * + */ + update: function(onlineRosterItems) + { + var contactsListElm = $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST); + + contactsListElm.children().each(function() { + var contactBareJid = $(this).attr('bareJid'); + + if (g_beechat_roster_items != null) { + if ($.inArray(contactBareJid, onlineRosterItems) == -1) { + BeeChat.UI.ScrollBoxes.updateAvailability(contactBareJid); + $(this).remove(); + } + } + }); + + for (var key in onlineRosterItems) { + if (typeof onlineRosterItems[key] != 'object') + continue; + + var contactElm = contactsListElm.find('li').filter('[bareJid=' + key + ']'); + + if (contactElm.length == 0) { + contactElm = $('
  • ') + .attr('bareJid', key) + .append($('') + .attr('src', g_beechat_roster_items[key].icon_tiny)) + .append(BeeChat.UI.Utils.getTruncatedContactName(key, 25)) + .appendTo(contactsListElm) + .bind('click', function() { + if (!BeeChat.UI.ChatBoxes.getChatBoxElm($(this).attr('bareJid')).is(':visible')) { + BeeChat.UI.ContactsList.toggleDisplay(); + } + + BeeChat.UI.ScrollBoxes.add($(this).attr('bareJid'), false, true); + }); + } + + BeeChat.UI.ContactsList.updateContactAvailability(contactElm, key); + } + + BeeChat.UI.ContactsList.updateButtonText(BeeChat.UI.Resources.Strings.Contacts.BUTTON + ' (' + g_beechat_user.getRoster().getSizeOnlineItems() + ')'); + }, + + /** Function: updateContactAvailability + * + */ + updateContactAvailability: function(contactElm, contactBareJid) + { + // Update from contactsList + contactElm.attr('class', BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Right[g_beechat_roster_items[contactBareJid].getStrongestPresence().show.toUpperCase()]); + + // Update from scrollBoxes + BeeChat.UI.ScrollBoxes.updateAvailability(contactBareJid); + }, + + /** Function: updateButtonText + * + * + */ + updateButtonText: function(msg) + { + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).html(msg); + }, + + /** Function: toggleDisplay + * Toggle the contacts box display (hide | show) + * + */ + toggleDisplay: function() + { + var contactsBoxElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CONTACTS); + + contactsBoxElm.toggle(); + if (contactsBoxElm.is(':hidden')) { + BeeChat.UI.ContactsList.hiddenStyle(); + } else { + BeeChat.UI.ContactsList.showedStyle(); + } + $('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).hide(); + }, + + /** Function: hiddenStyle + * + */ + hiddenStyle: function() + { + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_RIGHT).css({'border-left': '1px solid #BBBBBB', 'border-right': '1px solid #BBBBBB', 'background-color': '#DDDDDD'}); + }, + + /** Function: showedStyle + * + */ + showedStyle: function() + { + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_RIGHT).css({'border-left': '1px solid #666666', 'border-right': '1px solid #666666', 'background-color': 'white'}); + } +}; + + +/** Class: BeeChat.UI.AvailabilitySwitcher + * An object container for all AvailabilitySwitcher functions + * + */ +BeeChat.UI.AvailabilitySwitcher = { + /** Function: initialize + * Initialize the availability switcher by setting the current user's availability + * and binding actions + * + */ + initialize: function(availability) + { + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY).unbind('click').bind('click', BeeChat.UI.AvailabilitySwitcher.toggleListDisplay); + + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_AVAILABILITY_SWITCHER_CONTROL).unbind('click').bind('click', BeeChat.UI.AvailabilitySwitcher.toggleListDisplay); + + $('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).find('li').each(function() { + $(this).unbind('click').bind('click', function() { + var availabilityClass = $(this).attr('class'); + var availability = availabilityClass.substr(availabilityClass.lastIndexOf('_') + 1); + + if (availability == 'offline') + BeeChat.UI.disconnect(); + else { + g_beechat_user.sendPresenceAvailability(availability, ''); + BeeChat.UI.AvailabilitySwitcher.update(availability); + $('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).hide('slow'); + $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).show('slow'); + } + }); + }); + BeeChat.UI.AvailabilitySwitcher.update(availability); + }, + + /** Function: update + * Update the current user's availability + * + * Parameters: + * (BeeChat.Presence.ShowElements) availability - The current user's availability + */ + update: function(availability) + { + var upperCasedAvailability = availability.toUpperCase(); + + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CURRENT_AVAILABILITY) + .attr('class', BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[upperCasedAvailability]) + .text(BeeChat.UI.Resources.Strings.Availability[upperCasedAvailability]); + + if (availability == 'chat') + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'online'); + else if (availability == 'xa' || availability == 'away') + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'away'); + else if (availability == 'dnd') + $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_CONTACTS_BUTTON).attr('class', 'dnd'); + }, + + /** Function: switchControlClass + * + */ + switchControlClass: function() + { + var switcherControlElm = $('#' + BeeChat.UI.Resources.Elements.ID_SPAN_AVAILABILITY_SWITCHER_CONTROL); + + if (switcherControlElm.attr('class') == BeeChat.UI.Resources.StyleClasses.Availability.Control.UP) + switcherControlElm.attr('class', BeeChat.UI.Resources.StyleClasses.Availability.Control.DOWN); + else + switcherControlElm.attr('class', BeeChat.UI.Resources.StyleClasses.Availability.Control.UP); + }, + + /** Function: toggleListDisplay + * + */ + toggleListDisplay: function() + { + BeeChat.UI.AvailabilitySwitcher.switchControlClass(); + $('#' + BeeChat.UI.Resources.Elements.ID_UL_CONTACTS_LIST).toggle('slow'); + $('#' + BeeChat.UI.Resources.Elements.ID_UL_AVAILABILITY_SWITCHER_LIST).toggle('slow'); + } +}; + + +/** Class: BeeChat.UI.ScrollBoxes + * An object container for all ScrollBoxes related functions + * + */ +BeeChat.UI.ScrollBoxes = { + isInitialized: false, + isOpened: false, + + /** Function: initialize + * + */ + initialize: function() { + var $prev = $('#beechat_center_prev'), + $next = $('#beechat_center_next'); + + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_BAR_CENTER).serialScroll({ + target: '#beechat_scrollboxes', + items: 'li', + prev: '#beechat_center_prev', + next: '#beechat_center_next', + axys: 'x', + start: 2, + step: -1, + interval: 0, + duration: 0, + cycle: false, + force: true, + jump: true, + lock: true, + lazy: true, + constant: true, + + onBefore: function(e, elem, $pane, $items, pos) { + $next.add($prev).hide(); + $prev.add($next).hide(); + if (pos != 0) { + $next.show(); + } + if (pos != $items.length - 1) + $prev.show(); + }, + + onAfter: function(elem) { + BeeChat.UI.ChatBoxes.takeStand($(elem).attr('bareJid')); + BeeChat.UI.ScrollBoxes.isInitialized = true; + } + }); + }, + + /** Function: add + * Add a scrollbox to the scrollboxes bar + * + */ + addRoom: function(contactBareJid) + { + debugXMPP('addRoom' + contactBareJid); + BeeChat.UI.ScrollBoxes.add(contactBareJid, true); + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + scrollBoxElm.attr('class', BeeChat.UI.Resources.StyleClasses.Availability.Left.ROOM); + }, + + add: function(contactBareJid, isroom) + { + var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); + var scrollBoxElm = scrollBoxesElm.find('ul').children().filter('[bareJid=' + contactBareJid + ']'); + + if (scrollBoxElm.length == 0) { + var availClass = null; + var pres = null; + if (g_beechat_roster_items != undefined) + pres = g_beechat_roster_items[contactBareJid] != null ? g_beechat_roster_items[contactBareJid].getStrongestPresence() : null; + + if (pres != null) + availClass = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[pres.show.toUpperCase()]; + else + availClass = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()]; + + scrollBoxElm = $('
  • ') + .attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + availClass) + .attr('bareJid', contactBareJid) + .attr('isroom', isroom?'true':'false') + .attr('title', BeeChat.UI.Resources.Strings.Box.SHOWHIDE) + .text(BeeChat.UI.Utils.getTruncatedContactName(contactBareJid, 11)) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.BOX_CONTROL) + .attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX) + .text('X') + .attr('title', BeeChat.UI.Resources.Strings.Box.CLOSE) + .bind('click', function() { + if (isroom) + g_beechat_user.leaveRoom(contactBareJid); + var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); + + BeeChat.UI.ChatBoxes.remove($(this).parent().attr('bareJid')); + scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(BeeChat.UI.ScrollBoxes.getSelectedScrollBoxElm())); + })); + + scrollBoxesElm.find('ul').append(scrollBoxElm); + BeeChat.UI.ChatBoxes.add(contactBareJid, isroom); + if (arguments.length == 3 && arguments[2]) + scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); + if (!isroom) { + BeeChat.UI.loadRosterItemsStatuses(); + BeeChat.UI.loadRosterItemsIcons(); + } + } else { + scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); + } + }, + + /** Function: remove + * + */ + remove: function(contactBareJid) + { + BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).remove(); + }, + + /** Function: unselect + * + */ + unselect: function(contactBareJid) + { + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + scrollBoxElm.attr('class', (scrollBoxElm.attr('class')).replace(/beechat_scrollbox_selected/, '')); + }, + + /** Function: select + * + */ + select: function(contactBareJid) + { + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + var scrollBoxElmClasses = scrollBoxElm.attr('class'); + + if (scrollBoxElmClasses.search(/beechat_scrollbox_selected/) == -1) + scrollBoxElm.attr('class', scrollBoxElmClasses + ' ' + BeeChat.UI.Resources.StyleClasses.ScrollBox.SELECTED); + }, + + /** Function: updateAvailability + * + */ + updateAvailability: function(contactBareJid) + { + var pres = g_beechat_roster_items[contactBareJid].getStrongestPresence(); + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + var scrollBoxElmClasses = scrollBoxElm.attr('class'); + var updatedAvailability = null; + + if (pres != null) + updatedAvailability = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[pres.show.toUpperCase()]; + else + updatedAvailability = BeeChat.UI.Resources.ReferenceTables.Styles.Availability.Left[BeeChat.Presence.Types.UNAVAILABLE.toUpperCase()]; + + if (scrollBoxElmClasses == undefined || scrollBoxElmClasses.search(/(beechat_left_availability_)/g) == -1) { + scrollBoxElm.attr('class', BeeChat.UI.Resources.StyleClasses.LABEL + ' ' + updatedAvailability); + } else { + updatedAvailability = updatedAvailability.replace(/(beechat_left_availability)/g, ''); + + scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_chat)/g, updatedAvailability); + scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_dnd)/g, updatedAvailability); + scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_away)/g, updatedAvailability); + scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_xa)/g, updatedAvailability); + scrollBoxElmClasses = scrollBoxElmClasses.replace(/(_offline)/g, updatedAvailability); + + scrollBoxElm.attr('class', scrollBoxElmClasses); + } + }, + + /** Function: getSelectedScrollBoxElm + * + */ + getSelectedScrollBoxElm: function(contactBareJid) + { + var elm = undefined; + + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().each(function() { + if ($(this).attr('class').search(/beechat_scrollbox_selected/) != -1) + elm = $(this); + }); + + return (elm); + }, + + /** Function: getScrollBoxElm + * + */ + getScrollBoxElm: function(contactBareJid) + { + return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().filter('[bareJid=' + contactBareJid + ']'); + } +}; + + +/** Class: BeeChat.UI.ChatBoxes + * An object container for all ChatBoxes related functions + * + */ +BeeChat.UI.ChatBoxes = { + dateLastComposing: {}, + lastTimedPauses: {}, + + /** Function: add + * + */ + add: function(contactBareJid, isroom) + { + var chatBoxes = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES); + + if ($(chatBoxes).children().filter('[bareJid=' + contactBareJid + ']').length == 0) { + var chatBox = $('
    ') + .attr('class', isroom ? BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN : BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN) + .attr('bareJid', contactBareJid) + .attr('isroom', isroom ? 'true' : 'false') + .hide(); + + var chatBoxTop = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP); + if (!isroom) + chatBoxTop.append($('') + .attr('href', BeeChat.UI.Resources.Paths.MEMBER_PROFILE + Strophe.getNodeFromJid(contactBareJid)) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP_ICON) + .attr('src', (g_beechat_roster_items != null && g_beechat_roster_items[contactBareJid] != undefined)?g_beechat_roster_items[contactBareJid].icon_small:''))) + chatBoxTop.append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.LABEL) + .html(isroom?BeeChat.UI.Utils.getTruncatedContactName(contactBareJid).split('@')[0]:'' + BeeChat.UI.Utils.getTruncatedContactName(contactBareJid) + '')) + .append($('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.TOP_CONTROLS) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTROL) + .attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX) + .text('X') + .attr('title', BeeChat.UI.Resources.Strings.Box.CLOSE) + .bind('click', function() { + if (isroom) + g_beechat_user.leaveRoom(contactBareJid); + BeeChat.UI.ChatBoxes.remove($(this).parent().parent().parent().attr('bareJid')); + })) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTROL) + .attr('id', BeeChat.UI.Resources.Elements.ID_SPAN_CLOSE_BOX) + .text('_') + .attr('title', BeeChat.UI.Resources.Strings.Box.MINIMIZE) + .css({'font-size': '1.6em', 'position': 'relative', 'line-height': '4px'}) + .bind('click', function() { + BeeChat.UI.ScrollBoxes.unselect($(this).parent().parent().parent().attr('bareJid')); + $(this).parent().parent().parent().fadeOut('slow'); + }))); + + var chatBoxSubTop = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.SUBTOP) + .append(BeeChat.UI.Utils.getTruncatedContactStatus((g_beechat_roster_items != null && g_beechat_roster_items[contactBareJid] != undefined && g_beechat_roster_items[contactBareJid].status != undefined) ? g_beechat_roster_items[contactBareJid].status : '')); + + var chatBoxContent = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTENT) + .attr('bareJid', contactBareJid); + + var chatBoxInput = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT) + .append($('') + .attr('bareJid', contactBareJid) + .bind('keypress', isroom?BeeChat.UI.ChatBoxes.onRoomTypingMessage:BeeChat.UI.ChatBoxes.onTypingMessage) + .bind('keyup', function(e) { + if ((e.keyCode ? e.keyCode : e.which) == 13) + $(this).val(''); + })); + + var chatBoxBottom = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.BOTTOM) + .append($('') + .append($(''))); + if (isroom) { + //var chatBoxBox = $('
    ') + // .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CHATROOM) + var chatBoxRoster = $('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER) + //chatBoxBox.append(chatBoxTop).append(chatBoxSubTop).append(chatBoxContent).append(chatBoxInput).append(chatBoxBottom) + //chatBox.append(chatBoxRoster).append(chatBoxBox).appendTo(chatBoxes); + chatBox.append(chatBoxTop).append(chatBoxSubTop).append(chatBoxContent).append(chatBoxInput).append(chatBoxBottom).append(chatBoxRoster).appendTo(chatBoxes); + } + else + chatBox.append(chatBoxTop).append(chatBoxSubTop).append(chatBoxContent).append(chatBoxInput).append(chatBoxBottom).appendTo(chatBoxes); + } + }, + + /** Function: takeStand + * + */ + takeStand: function(contactBareJid) + { + var chatBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children(); + var chatBoxElm = chatBoxesElm.filter('[bareJid=' + contactBareJid + ']'); + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + + if (!chatBoxElm.is(':hidden')) { + BeeChat.UI.ScrollBoxes.unselect(contactBareJid); + chatBoxElm.hide(); + } else { + // Hide all other chatboxes + $.each(chatBoxesElm.filter('[bareJid!=' + contactBareJid + ']'), function() { + BeeChat.UI.ScrollBoxes.unselect($(this).attr('bareJid')); + $(this).hide(); + }); + // Add selected scrollbox style + BeeChat.UI.ScrollBoxes.select(contactBareJid); + // Remove UnreadCountBox + BeeChat.UI.UnreadCountBox.remove(contactBareJid); + // Position the chatbox + var pos = scrollBoxElm.position().left - (chatBoxElm.width() - scrollBoxElm.width()) + 24; + chatBoxElm.css({'left': pos}); + if (!BeeChat.UI.ScrollBoxes.isOpened) + return; + chatBoxElm.show().css({'left': pos}); + // Scroll down the content of the chatbox + chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')}); + // Focus textarea + chatBoxElm.children().filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + ']').find('textarea').focus(); + } + }, + + /** Function: onTypingMessage + * + */ + onRoomTypingMessage: function(e) { + BeeChat.UI.ChatBoxes._onTypingMessage(e, true, this); + }, + + onTypingMessage: function(e) { + BeeChat.UI.ChatBoxes._onTypingMessage(e, false, this); + }, + + _onTypingMessage: function(e, isroom, self) + { + var keyCode = (e.keyCode) ? e.keyCode : e.which; + var contactBareJid = $(self).attr('bareJid'); + + var msgtype = BeeChat.Message.Types.CHAT; + if (isroom) + msgtype = BeeChat.Message.Types.GROUPCHAT; + + if (keyCode == 13 && $(self).val() != '') { + g_beechat_user.sendChatMessage(contactBareJid, jQuery.trim($(self).val()), msgtype); + if (!isroom) + BeeChat.UI.ChatBoxes.update(contactBareJid, BeeChat.UI.Utils.truncateString(BeeChat.UI.Resources.Strings.ChatMessages.SELF, 24), $(self).val(), isroom); + clearTimeout(BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid]); + BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid] = null; + } else { + var nowTime = new Date().getTime(); + + if (BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] == null || BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] + 2000 < nowTime) { + BeeChat.UI.ChatBoxes.dateLastComposing[contactBareJid] = nowTime; + g_beechat_user.sendChatStateMessage(contactBareJid, BeeChat.Message.ChatStates.COMPOSING); + } + + clearTimeout(BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid]); + BeeChat.UI.ChatBoxes.lastTimedPauses[contactBareJid] = setTimeout('g_beechat_user.sendChatStateMessage(\'' + contactBareJid + '\', BeeChat.Message.ChatStates.PAUSED)', 2000); + + var chatBoxTextAreaElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.INPUT + ']').find('textarea'); + chatBoxTextAreaElm.attr({scrollTop: chatBoxTextAreaElm.attr('scrollHeight')}); + } + }, + + updateRoster: function(contactBareJid, fromName, presence) + { + var availability = $(presence).attr('type'); + var item = $(presence).find('item'); + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + + if (chatBoxElm.length == 0) { + BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); + chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + } + + //var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + + var roster = chatBoxElm.find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); + if (availability == 'unavailable') { + roster.find('div').filter('[contactName='+fromName+']').remove(); + } + else { + var hasName = roster.find('div').filter('[contactName='+fromName+']'); + if (hasName.length == 0) { + roster.append($('
    ' + fromName + '
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.ROSTER_ITEM) + .attr('title', item.attr('affiliation') + '/' + item.attr('role')) + .attr('contactName', fromName)) + } + } + }, + + + /** Function: update + * + */ + update: function(contactBareJid, fromName, msg, isroom) + { + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + + if (chatBoxElm.length == 0) { + if (isroom) + BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); + else + BeeChat.UI.ScrollBoxes.add(contactBareJid); + chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + } + + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + + chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').remove(); + + var chatBoxLastMessageElm = $(chatBoxContentElm).find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE + ']').filter(':last'); + + if (chatBoxLastMessageElm && chatBoxLastMessageElm.find('span').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_SENDER + ']').text() == fromName) { + chatBoxLastMessageElm.append('

    ' + BeeChat.UI.Utils.getPrintableChatMessage(msg) + '

    '); + } else { + chatBoxContentElm.append($('
    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_SENDER) + .text(fromName)) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.MESSAGE_DATE) + .text(BeeChat.UI.Utils.getNowFormattedTime())) + .append('

    ' + BeeChat.UI.Utils.getPrintableChatMessage(msg) + '

    ')); + } + + chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')}); + + var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); + + if (BeeChat.UI.ScrollBoxes.isInitialized == false) { + scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); + } + + if (chatBoxElm.is(':hidden')) { + BeeChat.UI.UnreadCountBox.update(contactBareJid); +// if (BeeChat.UI.HAS_FOCUS) +// document.getElementById(BeeChat.UI.Resources.Sounds.NEW_MESSAGE).Play(); + } + +// if (!BeeChat.UI.HAS_FOCUS) +// document.getElementById(BeeChat.UI.Resources.Sounds.NEW_MESSAGE).Play(); + }, + + /** Function: updateChatState + * + */ + updateChatState: function(contactBareJid, msg) + { + var chatBoxContentElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[bareJid=' + contactBareJid + ']'); + + $(msg).children().each(function() { + if (this.tagName == BeeChat.Message.ChatStates.COMPOSING) { + if (chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').length == 0) { + $('

    ') + .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.STATE) + .html(BeeChat.UI.Utils.getContactName(contactBareJid) + BeeChat.UI.Resources.Strings.ChatMessages.COMPOSING + "
    ") + .appendTo(chatBoxContentElm); + } + } else if (this.tagName == BeeChat.Message.ChatStates.PAUSED) { + chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').remove(); + } + }); + chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')}); + }, + + /** Function: remove + * + */ + remove: function(contactBareJid) + { + BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).remove(); + BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).remove(); + }, + + /** Function: show + * + */ + show: function(contactBareJid) + { + BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).show(); + }, + + /** Function: hide + * + */ + hide: function(contactBareJid) + { + BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).hide(); + }, + + /** Function: getChatBoxElm + * + */ + getChatBoxElm: function(contactBareJid) + { + return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().filter('[bareJid=' + contactBareJid + ']'); + } +}; + +BeeChat.UI.UnreadCountBox = { + /** Function: add + * + */ + add: function(contactBareJid) + { + BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid) + .append($('') + .attr('class', BeeChat.UI.Resources.StyleClasses.UNREAD_COUNT)); + }, + + /** Function: remove + * + */ + remove: function(contactBareJid) + { + BeeChat.UI.UnreadCountBox.getElm(contactBareJid).remove(); + }, + + /** Function: update + * + */ + update: function(contactBareJid) + { + if (arguments.length > 1 && !arguments[1]) + return; + + var unreadCountBoxElm = BeeChat.UI.UnreadCountBox.getElm(contactBareJid); + if (unreadCountBoxElm.length == 0) { + BeeChat.UI.UnreadCountBox.add(contactBareJid); + unreadCountBoxElm = BeeChat.UI.UnreadCountBox.getElm(contactBareJid); + } + if (arguments.length == 1) { + var unreadCount = unreadCountBoxElm.text(); + unreadCountBoxElm.text(++unreadCount); + } else + unreadCountBoxElm.text(arguments[1]); + }, + + /** Function: getElm + * + */ + getElm: function(contactBareJid) + { + return BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid).find('span').filter('[class=' + BeeChat.UI.Resources.StyleClasses.UNREAD_COUNT +' ]'); + } +}; + +/** Class: BeeChat.UI.Utils + * An object container for all UI utilities functions + * + */ +BeeChat.UI.Utils = { + /** Function: getTruncatedContactName + * + */ + getTruncatedContactName: function(bareJid) + { + return (BeeChat.UI.Utils.truncateString(BeeChat.UI.Utils.getContactName(bareJid), (arguments.length == 2) ? arguments[1] : 21)); + }, + + /** Function: getTruncatedContactStatus + * + */ + getTruncatedContactStatus: function(contactStatus) + { + return (BeeChat.UI.Utils.truncateString(contactStatus, (arguments.length == 2 ? arguments[1] : 50))); + }, + + /** Function: getContactName + * + */ + getContactName: function(bareJid) + { + var contactName = bareJid; + + if (g_beechat_roster_items != null && g_beechat_roster_items[bareJid]) + contactName = g_beechat_roster_items[bareJid].name; + // no contact name so we show bareJid + if (!contactName || contactName == '') + contactName = bareJid; + + return (contactName); + }, + + /** Function: getPrintableChatMessage + * + */ + getPrintableChatMessage: function(msg) + { + var val = new String; + val = $('
    ' + msg + '
    '); + msg = val.text(); + + msg = jQuery.trim(msg); + msg = BeeChat.UI.Utils.replaceLinks(msg); + msg = BeeChat.UI.Utils.replaceSmileys(msg); + + return msg; + }, + + /** Function: getNowFormattedTime + * + */ + getNowFormattedTime: function() + { + var date = new Date(); + + var hours = date.getHours(); + var minutes = date.getMinutes(); + var seconds = date.getSeconds(); + + if (hours < 10) + hours = '0' + hours; + if (minutes < 10) + minutes = '0' + minutes; + if (seconds < 10) + seconds = '0' + seconds; + return (hours + ':' + minutes + ':' + seconds); + }, + + + /** Function: replaceSmileys + * Replace smileys founded in a string to beautiful icons :) + * + * Parameters: + * (String) str - The string containing smileys + * + */ + replaceSmileys: function(str) + { + str = str.replace(/(;\))/gi, ''); + str = str.replace(/(:\))/gi, ''); + str = str.replace(/(:\()/gi, ''); + str = str.replace(/(:D)/gi, ''); + str = str.replace(/(:o)/gi, ''); + str = str.replace(/(xD)/gi, ''); + str = str.replace(/(:p)/gi, ''); + + return (str); + }, + + /** Function: replaceLinks + * Transform links founded in a string to clickable links + * + * Parameters: + * (String) str - The string where will be replaced links + */ + replaceLinks: function(str) + { + var xpr = + /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; + + return (str.replace(xpr, '$1')); + }, + + /** Function: truncateString + * Truncate a string at a specified length + * + * Parameters: + * (String) str - The string to truncate + * (int) len - The maximum length of str + */ + truncateString: function(str, len) + { + if (str != null && str.length > len) + return ((str.substr(0, len) + '...')); + return (str); + } +}; + + +/** Executed when the DOM is ready + * + */ +function init_beechat(ts, token) { + if (typeof document.body.style.maxHeight === "undefined") { // IE6 + return; + } + + BeeChat.UI.initialize(ts, token); +} + +/** Window resizing + * + */ +$(window).resize(function() { + if (typeof document.body.style.maxHeight === "undefined") { // IE6 + return; + } + + $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().each(function() { + var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm($(this).attr('bareJid')); + var pos = scrollBoxElm.position().left - ($(this).width() - scrollBoxElm.width()) + 24; + + $(this).css({'left': pos}); + }); +}); + + +/** Executed when the page is unloaded + * + */ +$(window).unload(function() { + if (typeof document.body.style.maxHeight === "undefined") { // IE6 + return; + } + + if (!$('#beechat').length) + return; + + if (g_beechat_user != null) { + g_beechat_user.requestSessionPause(); + BeeChat.UI.saveState(); + } + + BeeChat.UI.saveConnection(); + }); + + +/** Check whether the BeeChat tab is active or not + * + */ +$(window).bind('blur', function() { + BeeChat.UI.HAS_FOCUS = false; + }); + +$(window).bind('focus', function() { + BeeChat.UI.HAS_FOCUS = true; + }); diff --git a/views/default/beechat/beechat.php b/views/default/beechat/beechat.php new file mode 100644 index 000000000..d1e9e17be --- /dev/null +++ b/views/default/beechat/beechat.php @@ -0,0 +1,84 @@ + + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + +if (isloggedin() && get_loggedin_user()->chatenabled && elgg_get_context() != 'admin') { +?> +
    +
    + +
    +

    +
    +
    +
    + +
      + +
      +
      + + + +
      +
      +
      + +
      + _ +
      +
      +
      +
      + + +
      +
      +
        +
          +
        • +
        • +
        • +
        • +
        • +
        +
        +
        + +
        +
        +
        +
        + + + + + + + + diff --git a/views/default/beechat/beechat.userjs.php b/views/default/beechat/beechat.userjs.php new file mode 100644 index 000000000..f147d8b8e --- /dev/null +++ b/views/default/beechat/beechat.userjs.php @@ -0,0 +1,54 @@ + diff --git a/views/default/beechat/screen.css.php b/views/default/beechat/screen.css.php new file mode 100644 index 000000000..05336ef8c --- /dev/null +++ b/views/default/beechat/screen.css.php @@ -0,0 +1,672 @@ +wwwroot; + +?> +/** + * Beechat + * + * @package beechat + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Beechannels + * @copyright Beechannels 2007-2010 + * @link http://beechannels.com/ + */ + +div#beechat { + display: block !important; + display: none; + position: fixed; + left: 1%; + right: 1%; + bottom: 0; + margin: 0; + padding: 0; + height: 20px; + z-index: 999; + + font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; + font-size: 0.9em; + color: #222222; + background-color: #DDDDDD; + border-top: 1px solid #BBBBBB; + border-left: 1px solid #BBBBBB; +} +div#beechat a img { + border: none; +} +div#beechat a { + text-decoration: none; +} +div#beechat img { + vertical-align: middle; +} +div#beechat a:hover { + text-decoration: underline; +} +.beechat_control { + cursor: pointer; + color: #CCCCFF; + font-size: 1.6em; +} +.beechat_control:hover { + color: white; +} +.beechat_box_control { + cursor: pointer; + color: #888888; + font-size: 1em; +} +.beechat_box_control:hover { + color: #222222; +} +.beechat_chatbox_control { + cursor: pointer; + color: #CCCCFF; + font-size: 1.6em; +} +.beechat_chatbox_control:hover { + color: white; +} +.beechat_label { + font-weight: bold; + font-size: 1.1em; +} + +/* +** - +** left side +** - +*/ +div#beechat_left { + position: absolute; + top: 0; + left: 0; + width: 116px; + height: 18px; + margin: 0; + padding: 1px 2px; +} + + +/* +** - +** right side +** - +*/ +div#beechat_right { + position: absolute; + top: 0; + right: 0; + width: 220px; + height: 20px; + margin: 0; + padding: 0 0 0 0; + + border-left: 1px solid #BBBBBB; + border-right: 1px solid #BBBBBB; +} +div#beechat_contacts { + position: absolute; + right: 0px; + bottom: 0; + width: 222px; + height: 240px; + margin: 0 auto 20px auto; + padding: 0; + display: none; + + background-color: white; +} +div#beechat_contacts_top { + color: white; + background-color: #193C60; + width: 220px; + height: 32px; + + border-top: 1px solid #0B2C4F; + border-left: 1px solid #0B2C4F; + border-right: 1px solid #0B2C4F; +} +div#beechat_contacts_top .beechat_label { + float: left; + height: 20px; + padding: 6px; +} +div#beechat_contacts_controls { + margin: 0; + padding: 0; +} +div#beechat_contacts_controls span#beechat_contacts_control_minimize { + position: relative; + top: -7px; + float: right; + display: block; + width: 20px; + height: 20px; + padding: 2px; + + font-size: 1.6em; + font-weigth: bold; + text-align: center; +} +span#beechat_contacts_button { + display: block; + width: 190px; + padding: 2px 6px 0 24px; + height: 18px; + cursor: pointer; + font-size: 1.1em; + font-weight: normal; + + background-image: url('mod/beechat/graphics/icons/statuses.png'); +} +span#beechat_contacts_button.online { + background-position: 4px -750px; + background-repeat: no-repeat; +} +span#beechat_contacts_button.dnd { + background-position: 4px -796px; + background-repeat: no-repeat; +} +span#beechat_contacts_button.away { + background-position: 4px -842px; + background-repeat: no-repeat; +} +span#beechat_contacts_button.offline { + background-position: 4px -888px; + background-repeat: no-repeat; +} +span#beechat_contacts_button:hover { + background-color: white; +} +div#beechat_availability_switcher { + width: 218px; + height: 24px; + margin: 0; + padding: 0 0 0 2px; + + background-color: #EEEEEE; + border-left: 1px solid #666666; + border-right: 1px solid #666666; + border-bottom: 1px solid #BBBBBB; +} +span#beechat_current_availability { + float: left; + padding: 4px 4px 4px 22px; + + font-weight: bold; + cursor: pointer; +} +span#beechat_current_availability:hover { + text-decoration: underline; +} +span#beechat_availability_switcher_control { + float: right; + width: 24px; + height: 20px; + cursor: pointer; +} +span.beechat_availability_switcher_control_up { + background: no-repeat 50% 50% url('mod/beechat/graphics/icons/bullet_arrow_up.png'); +} +span.beechat_availability_switcher_control_down { + background: no-repeat 50% 50% url('mod/beechat/graphics/icons/bullet_arrow_down.png'); +} +ul#beechat_availability_switcher_list { + display: none; + padding:0; + margin:0; + list-style:none; +} +ul#beechat_availability_switcher_list li { + margin: 0; + padding: 4px 4px 4px 24px; + + cursor: pointer; +} +ul#beechat_availability_switcher_list li:hover { + background-color: #EEEEEE; +} +div#beechat_contacts_content { + width: 220px; + height: 164px; + overflow: auto; + + border-left: 1px solid #666666; + border-right: 1px solid #666666; + background-color: white; +} +ul#beechat_contacts_list { + background-color: white; + padding:0; + margin:0; + list-style:none; +} +ul#beechat_contacts_list li img { + margin: 0 4px 0 0; + width: 25px; + height: 25px; +} +ul#beechat_contacts_list li { + margin: 0; + padding: 4px 4px 4px 6px; + + cursor: pointer; + color: #333; +} +ul#beechat_contacts_list li:hover { + background-color: #F5F6F8; + color: #333; +} +div#beechat_contacts_bottom { + width: 220px; + height: 18px; + + border-left: 1px solid #666666; + border-right: 1px solid #666666; +} +span#beechat_contacts_bottom_bar { + position: absolute; + display: block; + bottom: 0; + width: 210px; + height: 1px; + + background-color: #BBBBBB; + margin: auto 4px; +} + + +/* +** - +** center area +** - +*/ +div#beechat_center { + float: right; + display: block; + width: 586px; + height: 20px; + margin: 0 220px 0 100px; + *margin: 0 312px 0 100px; + padding: 0; +} +div#beechat_center .next, div#beechat_center .prev { + display: none; + + border-left: 1px solid #BBBBBB; + cursor: pointer; +} +div#beechat_center .next { + position: absolute; + right: 220px; + width: 24px; + height: 20px; + + background: no-repeat 50% url("mod/beechat/graphics/icons/resultset_next.png"); +} +div#beechat_center .prev { + position: absolute; + right: 872px; + width: 24px; + height: 20px; + + background: no-repeat 50% url("mod/beechat/graphics/icons/resultset_previous.png"); +} +div#beechat_scrollboxes { + float: right; + overflow: hidden; + width: 628px; + height: 21px; + margin: 0 24px 0 24px; + text-align: left; +} +div#beechat_scrollboxes ul { + width: 200000em; + list-style: none; + padding:0; + margin:0; +} +div#beechat_scrollboxes ul li { + float: right; + display: block; + width: 130px; + height: 20px; + padding: 1px 0 0 22px; + + cursor: pointer; + border-left: 1px solid #BBBBBB; +} +div#beechat_scrollboxes ul li:hover { + color: #000000; + background-color: white; +} +div#beechat_scrollboxes ul li.beechat_scrollbox_selected { + border-left: 1px solid #666666; + border-right: 1px solid #666666; + background-color: white; +} +div#beechat_scrollboxes ul li span.beechat_unread_count { + float: right; + display: block; + width: 16px; + height: 14px; + padding-top: 2px; + margin: 0 6px 0 0; + + text-align: center; + font-size: 0.7em; + color: white; + background: no-repeat 0% 50% url('mod/beechat/graphics/icons/notification_pink.png'); +} +div#beechat_scrollboxes ul li span#beechat_box_control_close { + float: right; + width: auto; + padding: 1px 4px; + height: 20px; +} + +/* +** -- +** availability classes +** -- +*/ +.beechat_left_availability_chat { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/bullet_green.png'); +} +.beechat_left_availability_dnd { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/bullet_delete.png'); +} +.beechat_left_availability_away { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/bullet_orange.png'); +} +.beechat_left_availability_xa { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/bullet_red.png'); +} +.beechat_left_availability_offline { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/bullet_black.png'); +} +.beechat_left_availability_room { + background: no-repeat 2% 50% url('mod/beechat/graphics/icons/muc_icon.png'); +} + + + +.beechat_right_availability_chat { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/bullet_green.png'); +} +.beechat_right_availability_dnd { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/bullet_delete.png'); +} +.beechat_right_availability_away { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/bullet_orange.png'); +} +.beechat_right_availability_xa { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/bullet_red.png'); +} +.beechat_right_availability_offline { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/bullet_black.png'); +} +.beechat_right_availability_room { + background: no-repeat 96% 50% url('mod/beechat/graphics/icons/muc_icon.png'); +} + +/* +** -- +** tooltips +** -- +*/ +div.tooltip.tooltipchat { + display: none; + padding: 4px; + width: auto; + background: transparent no-repeat left bottom url('mod/beechat/graphics/icons/pointer.png'); +} +div.tooltip.tooltipchat h3 { + margin: 0; + padding: 4px; + + font-weight: normal; + font-size: 0.9em; + color: white; + background-color: #222222; +} + + +/* +** -- +** chatboxes +** -- +*/ +div.beechat_chatbox { + position: absolute; + width: 240px; + height: 300px; + bottom: 25px; + margin: 0; + padding: 0; + + background-color: #DDDDDD; +} +div.beechat_chatbox a { + color: white; +} +div.beechat_chatbox a:hover { + text-decoration: underline; +} +div.beechat_chatbox_roomroster { + position: absolute; + width: 100px; + height: 276px; + left: -101px; + bottom: -2px; + margin: 0; + padding: 0; + overflow: auto; + + border: 1px solid #4B6C8F; + + background-color: #EEEEEE; +} +div.beechat_chatbox_roomrosteritem { + background-color: #FFFFFF; + margin: 3px; + padding-left: 2px; +} +div.beechat_chatbox_chatroom { + position: absolute; + width: 240px; + height: 300px; + left: 100px; + bottom: 0px; + margin: 0; + padding: 0; + + background-color: #DDDDDD; +} +div.beechat_chatbox_chatroom a { + color: white; +} +div.beechat_chatbox_chatroom a:hover { + text-decoration: underline; +} + +div.beechat_chatbox_room { + position: absolute; + width: 340px; + height: 300px; + bottom: 25px; + margin: 0; + padding: 0; + + background-color: #DDDDDD; +} +div.beechat_chatbox_room a { + color: white; +} +div.beechat_chatbox_room a:hover { + text-decoration: underline; +} +div.beechat_chatbox_top { + width: 238px; + height: 24px; + margin: 0; + padding: 0; + + font-size: 0.9em; + color: white; + background-color: #193C60; + border-top: 1px solid #0B2C4F; + border-left: 1px solid #0B2C4F; + border-right: 1px solid #0B2C4F; +} +div.beechat_chatbox_top .beechat_chatbox_top_icon { + position: absolute; + top: 4px; + left: 4px; + z-index: 2; + + widht: 50px; + height: 50px; +} +div.beechat_chatbox_top .beechat_label { + float: left; + height: 13px; + padding: 4px 6px 6px 6px; + + margin-left: 54px; +} +div.beechat_chatbox_top_controls { + margin: 0; + padding: 0; +} +div.beechat_chatbox_top_controls .beechat_chatbox_control { + float: right; + display: block; + width: 20px; + height: 19px; + padding: 2px; + margin: 0; + + font-size: 1.2em; + font-weight: bold; + text-align: center; +} +div.beechat_chatbox_subtop { + width: 172px; + height: 30px; + padding: 2px 6px 2px 60px; + + border-left: 1px solid #666666; + border-right: 1px solid #666666; + border-bottom: 1px solid #CCCCCC; + background-color: #DDDDDD; +} +div.beechat_chatbox_content { + width: 238px; + height: 202px; + margin: 0; + padding: 0; + overflow: auto; + + border-left: 1px solid #666666; + border-right: 1px solid #666666; + background-color: white; +} +div.beechat_chatbox_content div.beechat_chatbox_message { + width: auto; + height: auto; + margin: 0; + padding: 2px; + border-top: 1px solid #DDDDDD; +} +div.beechat_chatbox_message span.beechat_chatbox_message_sender { + position: relative; + top: 0; + left: 6px; + font-weight: bold; + font-size: 1em; +} +div.beechat_chatbox_message span.beechat_chatbox_message_date { + float: right; + margin: 0 6px 0 0; +} +div.beechat_chatbox_content a { + color: #003399; +} +div.beechat_chatbox_content a:hover { + text-decoration: underline; +} +div.beechat_chatbox_content p { + margin: 0; + padding: 2px 6px; +} +div.beechat_chatbox_content p.beechat_chatbox_state { + font-size: 1em; + color: #888888; +} +div.beechat_chatbox_input { + width: 238px; + height: 40px; + margin: 0; + padding: 0; + + border-top: 2px solid #BBBBBB; + border-left: 1px solid #666666; + border-right: 1px solid #666666; + background-color: #DDDDDD; +} +div.beechat_chatbox_input textarea { + width: 204px; + height: 32px; + max-width: 240px; + max-height: 40px; + padding: 4px 4px 4px 30px; + margin: auto; + overflow: hidden; + vertical-align: top; + resize: none; + + font-size: 1em; + font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; + outline: none; + border: none; + background: white no-repeat 4px 3px url('mod/beechat/graphics/icons/chat_icon.png'); +} +div.beechat_chatbox_input textarea:focus { + outline: none; + border: none; + background-color: white; +} +div.beechat_chatbox_bottom { + position: absolute; + width: 238px; + height: 1px; + + background-color: white; + border-left: 1px solid #666666; + border-right: 1px solid #666666; + border-bottom: 1px solid #666666; + z-index: 2; +} +div.beechat_chatbox_bottom span { + position: absolute; + display: block; + right: 0; + top: 0; + width: 152px; + height: 1px; + + border-bottom: 1px solid white; +} +div.beechat_chatbox_bottom span span { + position: absolute; + display: block; + width: 146px; + height: 1px; + right: 4px; + top: 0; + + border-bottom: 1px solid #BBBBBB; +} diff --git a/views/default/js/b64.js.php b/views/default/js/b64.js.php new file mode 100644 index 000000000..201bdbd7c --- /dev/null +++ b/views/default/js/b64.js.php @@ -0,0 +1,74 @@ +// This code was written by Tyler Akins and has been placed in the +// public domain. It would be nice if you left this header intact. +// Base64 code from Tyler Akins -- http://rumkin.com + +var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +/** + * Encodes a string in base64 + * @param {String} input The string to encode in base64. + */ +function encode64(input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } while (i < input.length); + + return output; +} + +/** + * Decodes a base64 string. + * @param {String} input The string to decode. + */ +function decode64(input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + } while (i < input.length); + + return output; +} diff --git a/views/default/js/jquery.cookie.min.js.php b/views/default/js/jquery.cookie.min.js.php new file mode 100644 index 000000000..cb09af984 --- /dev/null +++ b/views/default/js/jquery.cookie.min.js.php @@ -0,0 +1,10 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ +jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options=$.extend({},options);options.expires=-1;}var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;}expires='; expires='+date.toUTCString();}var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i ').attr(j,d).css({position:'absolute',top:$(window).scrollTop(),left:$(window).scrollLeft()});f[j]='';$('body').prepend(k);location=e.hash;k.remove();f[j]=d}h.scrollTo(f,b).trigger('notify.serialScroll',[f])}})(jQuery); \ No newline at end of file diff --git a/views/default/js/jquery.scrollTo-min.js.php b/views/default/js/jquery.scrollTo-min.js.php new file mode 100755 index 000000000..5e7877810 --- /dev/null +++ b/views/default/js/jquery.scrollTo-min.js.php @@ -0,0 +1,11 @@ +/** + * jQuery.ScrollTo - Easy element scrolling using jQuery. + * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com + * Dual licensed under MIT and GPL. + * Date: 5/25/2009 + * @author Ariel Flesler + * @version 1.4.2 + * + * http://flesler.blogspot.com/2007/10/jqueryscrollto.html + */ +;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery); \ No newline at end of file diff --git a/views/default/js/jquery.serialScroll-min.js.php b/views/default/js/jquery.serialScroll-min.js.php new file mode 100755 index 000000000..d716124f9 --- /dev/null +++ b/views/default/js/jquery.serialScroll-min.js.php @@ -0,0 +1,10 @@ +/* + * jQuery.SerialScroll - Animated scrolling of series + * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com + * Dual licensed under MIT and GPL. + * Date: 06/14/2009 + * @author Ariel Flesler + * @version 1.2.2 + * http://flesler.blogspot.com/2008/02/jqueryserialscroll.html + */ +;(function(a){var b=a.serialScroll=function(c){return a(window).serialScroll(c)};b.defaults={duration:1e3,axis:"x",event:"click",start:0,step:1,lock:!0,cycle:!0,constant:!0};a.fn.serialScroll=function(c){return this.each(function(){var t=a.extend({},b.defaults,c),s=t.event,i=t.step,r=t.lazy,e=t.target?this:document,u=a(t.target||this,e),p=u[0],m=t.items,h=t.start,g=t.interval,k=t.navigation,l;if(!r){m=d()}if(t.force){f({},h)}a(t.prev||[],e).bind(s,-i,q);a(t.next||[],e).bind(s,i,q);if(!p.ssbound){u.bind("prev.serialScroll",-i,q).bind("next.serialScroll",i,q).bind("goto.serialScroll",f)}if(g){u.bind("start.serialScroll",function(v){if(!g){o();g=!0;n()}}).bind("stop.serialScroll",function(){o();g=!1})}u.bind("notify.serialScroll",function(x,w){var v=j(w);if(v>-1){h=v}});p.ssbound=!0;if(t.jump){(r?u:d()).bind(s,function(v){f(v,j(v.target))})}if(k){k=a(k,e).bind(s,function(v){v.data=Math.round(d().length/k.length)*k.index(this);f(v,this)})}function q(v){v.data+=h;f(v,this)}function f(B,z){if(!isNaN(z)){B.data=z;z=p}var C=B.data,v,D=B.type,A=t.exclude?d().slice(0,-t.exclude):d(),y=A.length,w=A[C],x=t.duration;if(D){B.preventDefault()}if(g){o();l=setTimeout(n,t.interval)}if(!w){v=C<0?0:y-1;if(h!=v){C=v}else{if(!t.cycle){return}else{C=y-v-1}}w=A[C]}if(!w||t.lock&&u.is(":animated")||D&&t.onBefore&&t.onBefore(B,w,u,d(),C)===!1){return}if(t.stop){u.queue("fx",[]).stop()}if(t.constant){x=Math.abs(x/i*(h-C))}u.scrollTo(w,x,t).trigger("notify.serialScroll",[C])}function n(){u.trigger("next.serialScroll")}function o(){clearTimeout(l)}function d(){return a(m,p)}function j(w){if(!isNaN(w)){return w}var x=d(),v;while((v=x.index(w))==-1&&w!=p){w=w.parentNode}return v}})}})(jQuery); \ No newline at end of file diff --git a/views/default/js/jquery.tools.min.js.php b/views/default/js/jquery.tools.min.js.php new file mode 100644 index 000000000..1574af45b --- /dev/null +++ b/views/default/js/jquery.tools.min.js.php @@ -0,0 +1,49 @@ +/* + * jQuery Tools 1.2.2 - The missing UI library for the Web + * + * [tabs, tabs.slideshow, tooltip, tooltip.slide, tooltip.dynamic, scrollable, scrollable.autoscroll, scrollable.navigator, overlay] + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/ + * + * File generated: Mon Jun 07 08:32:38 GMT 2010 + */ +(function(c){function p(d,a,b){var e=this,l=d.add(this),h=d.find(b.tabs),j=a.jquery?a:d.children(a),i;h.length||(h=d.children());j.length||(j=d.parent().find(a));j.length||(j=c(a));c.extend(this,{click:function(f,g){var k=h.eq(f);if(typeof f=="string"&&f.replace("#","")){k=h.filter("[href*="+f.replace("#","")+"]");f=Math.max(h.index(k),0)}if(b.rotate){var n=h.length-1;if(f<0)return e.click(n,g);if(f>n)return e.click(0,g)}if(!k.length){if(i>=0)return e;f=b.initialIndex;k=h.eq(f)}if(f===i)return e; +g=g||c.Event();g.type="onBeforeClick";l.trigger(g,[f]);if(!g.isDefaultPrevented()){o[b.effect].call(e,f,function(){g.type="onClick";l.trigger(g,[f])});i=f;h.removeClass(b.current);k.addClass(b.current);return e}},getConf:function(){return b},getTabs:function(){return h},getPanes:function(){return j},getCurrentPane:function(){return j.eq(i)},getCurrentTab:function(){return h.eq(i)},getIndex:function(){return i},next:function(){return e.click(i+1)},prev:function(){return e.click(i-1)}});c.each("onBeforeClick,onClick".split(","), +function(f,g){c.isFunction(b[g])&&c(e).bind(g,b[g]);e[g]=function(k){c(e).bind(g,k);return e}});if(b.history&&c.fn.history){c.tools.history.init(h);b.event="history"}h.each(function(f){c(this).bind(b.event,function(g){e.click(f,g);return g.preventDefault()})});j.find("a[href^=#]").click(function(f){e.click(c(this).attr("href"),f)});if(location.hash)e.click(location.hash);else if(b.initialIndex===0||b.initialIndex>0)e.click(b.initialIndex)}c.tools=c.tools||{version:"1.2.2"};c.tools.tabs={conf:{tabs:"a", +current:"current",onBeforeClick:null,onClick:null,effect:"default",initialIndex:0,event:"click",rotate:false,history:false},addEffect:function(d,a){o[d]=a}};var o={"default":function(d,a){this.getPanes().hide().eq(d).show();a.call()},fade:function(d,a){var b=this.getConf(),e=b.fadeOutSpeed,l=this.getPanes();e?l.fadeOut(e):l.hide();l.eq(d).fadeIn(b.fadeInSpeed,a)},slide:function(d,a){this.getPanes().slideUp(200);this.getPanes().eq(d).slideDown(400,a)},ajax:function(d,a){this.getPanes().eq(0).load(this.getTabs().eq(d).attr("href"), +a)}},m;c.tools.tabs.addEffect("horizontal",function(d,a){m||(m=this.getPanes().eq(0).width());this.getCurrentPane().animate({width:0},function(){c(this).hide()});this.getPanes().eq(d).animate({width:m},function(){c(this).show();a.call()})});c.fn.tabs=function(d,a){var b=this.data("tabs");if(b)return b;if(c.isFunction(a))a={onBeforeClick:a};a=c.extend({},c.tools.tabs.conf,a);this.each(function(){b=new p(c(this),d,a);c(this).data("tabs",b)});return a.api?b:this}})(jQuery); +(function(d){function r(g,a){function p(f){var e=d(f);return e.length<2?e:g.parent().find(f)}var c=this,j=g.add(this),b=g.data("tabs"),h,l,m,n=false,o=p(a.next).click(function(){b.next()}),k=p(a.prev).click(function(){b.prev()});d.extend(c,{getTabs:function(){return b},getConf:function(){return a},play:function(){if(!h){var f=d.Event("onBeforePlay");j.trigger(f);if(f.isDefaultPrevented())return c;n=false;h=setInterval(b.next,a.interval);j.trigger("onPlay");b.next()}},pause:function(){if(!h)return c; +var f=d.Event("onBeforePause");j.trigger(f);if(f.isDefaultPrevented())return c;h=clearInterval(h);m=clearInterval(m);j.trigger("onPause")},stop:function(){c.pause();n=true}});d.each("onBeforePlay,onPlay,onBeforePause,onPause".split(","),function(f,e){d.isFunction(a[e])&&c.bind(e,a[e]);c[e]=function(s){return c.bind(e,s)}});if(a.autopause){var t=b.getTabs().add(o).add(k).add(b.getPanes());t.hover(function(){c.pause();l=clearInterval(l)},function(){n||(l=setTimeout(c.play,a.interval))})}if(a.autoplay)m= +setTimeout(c.play,a.interval);else c.stop();a.clickable&&b.getPanes().click(function(){b.next()});if(!b.getConf().rotate){var i=a.disabledClass;b.getIndex()||k.addClass(i);b.onBeforeClick(function(f,e){if(e){k.removeClass(i);e==b.getTabs().length-1?o.addClass(i):o.removeClass(i)}else k.addClass(i)})}}var q;q=d.tools.tabs.slideshow={conf:{next:".forward",prev:".backward",disabledClass:"disabled",autoplay:false,autopause:true,interval:3E3,clickable:true,api:false}};d.fn.slideshow=function(g){var a= +this.data("slideshow");if(a)return a;g=d.extend({},q.conf,g);this.each(function(){a=new r(d(this),g);d(this).data("slideshow",a)});return g.api?a:this}})(jQuery); +(function(f){function p(a,b,c){var h=c.relative?a.position().top:a.offset().top,e=c.relative?a.position().left:a.offset().left,i=c.position[0];h-=b.outerHeight()-c.offset[0];e+=a.outerWidth()+c.offset[1];var j=b.outerHeight()+a.outerHeight();if(i=="center")h+=j/2;if(i=="bottom")h+=j;i=c.position[1];a=b.outerWidth()+a.outerWidth();if(i=="center")e-=a/2;if(i=="left")e-=a;return{top:h,left:e}}function t(a,b){var c=this,h=a.add(c),e,i=0,j=0,m=a.attr("title"),q=n[b.effect],k,r=a.is(":input"),u=r&&a.is(":checkbox, :radio, select, :button"), +s=a.attr("type"),l=b.events[s]||b.events[r?u?"widget":"input":"def"];if(!q)throw'Nonexistent effect "'+b.effect+'"';l=l.split(/,\s*/);if(l.length!=2)throw"Tooltip: bad events configuration for "+s;a.bind(l[0],function(d){if(b.predelay){clearTimeout(i);j=setTimeout(function(){c.show(d)},b.predelay)}else c.show(d)}).bind(l[1],function(d){if(b.delay){clearTimeout(j);i=setTimeout(function(){c.hide(d)},b.delay)}else c.hide(d)});if(m&&b.cancelDefault){a.removeAttr("title");a.data("title",m)}f.extend(c, +{show:function(d){if(!e){if(m)e=f(b.layout).addClass(b.tipClass).appendTo(document.body).hide().append(m);else if(b.tip)e=f(b.tip).eq(0);else{e=a.next();e.length||(e=a.parent().next())}if(!e.length)throw"Cannot find tooltip for "+a;}if(c.isShown())return c;e.stop(true,true);var g=p(a,e,b);d=d||f.Event();d.type="onBeforeShow";h.trigger(d,[g]);if(d.isDefaultPrevented())return c;g=p(a,e,b);e.css({position:"absolute",top:g.top,left:g.left});k=true;q[0].call(c,function(){d.type="onShow";k="full";h.trigger(d)}); +g=b.events.tooltip.split(/,\s*/);e.bind(g[0],function(){clearTimeout(i);clearTimeout(j)});g[1]&&!a.is("input:not(:checkbox, :radio), textarea")&&e.bind(g[1],function(o){o.relatedTarget!=a[0]&&a.trigger(l[1].split(" ")[0])});return c},hide:function(d){if(!e||!c.isShown())return c;d=d||f.Event();d.type="onBeforeHide";h.trigger(d);if(!d.isDefaultPrevented()){k=false;n[b.effect][1].call(c,function(){d.type="onHide";k=false;h.trigger(d)});return c}},isShown:function(d){return d?k=="full":k},getConf:function(){return b}, +getTip:function(){return e},getTrigger:function(){return a}});f.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(d,g){f.isFunction(b[g])&&f(c).bind(g,b[g]);c[g]=function(o){f(c).bind(g,o);return c}})}f.tools=f.tools||{version:"1.2.2"};f.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,position:["top","center"],offset:[0,0],relative:false,cancelDefault:true,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave", +tooltip:"mouseenter,mouseleave"},layout:"
        ",tipClass:"tooltip"},addEffect:function(a,b,c){n[a]=[b,c]}};var n={toggle:[function(a){var b=this.getConf(),c=this.getTip();b=b.opacity;b<1&&c.css({opacity:b});c.show();a.call()},function(a){this.getTip().hide();a.call()}],fade:[function(a){var b=this.getConf();this.getTip().fadeTo(b.fadeInSpeed,b.opacity,a)},function(a){this.getTip().fadeOut(this.getConf().fadeOutSpeed,a)}]};f.fn.tooltip=function(a){var b=this.data("tooltip");if(b)return b;a=f.extend(true, +{},f.tools.tooltip.conf,a);if(typeof a.position=="string")a.position=a.position.split(/,?\s/);this.each(function(){b=new t(f(this),a);f(this).data("tooltip",b)});return a.api?b:this}})(jQuery); +(function(d){var i=d.tools.tooltip;d.extend(i.conf,{direction:"up",bounce:false,slideOffset:10,slideInSpeed:200,slideOutSpeed:200,slideFade:!d.browser.msie});var e={up:["-","top"],down:["+","top"],left:["-","left"],right:["+","left"]};i.addEffect("slide",function(g){var a=this.getConf(),f=this.getTip(),b=a.slideFade?{opacity:a.opacity}:{},c=e[a.direction]||e.up;b[c[1]]=c[0]+"="+a.slideOffset;a.slideFade&&f.css({opacity:0});f.show().animate(b,a.slideInSpeed,g)},function(g){var a=this.getConf(),f=a.slideOffset, +b=a.slideFade?{opacity:0}:{},c=e[a.direction]||e.up,h=""+c[0];if(a.bounce)h=h=="+"?"-":"+";b[c[1]]=h+"="+f;this.getTip().animate(b,a.slideOutSpeed,function(){d(this).hide();g.call()})})})(jQuery); +(function(g){function j(a){var c=g(window),d=c.width()+c.scrollLeft(),h=c.height()+c.scrollTop();return[a.offset().top<=c.scrollTop(),d<=a.offset().left+a.width(),h<=a.offset().top+a.height(),c.scrollLeft()>=a.offset().left]}function k(a){for(var c=a.length;c--;)if(a[c])return false;return true}var i=g.tools.tooltip;i.dynamic={conf:{classNames:"top right bottom left"}};g.fn.dynamic=function(a){if(typeof a=="number")a={speed:a};a=g.extend({},i.dynamic.conf,a);var c=a.classNames.split(/\s/),d;this.each(function(){var h= +g(this).tooltip().onBeforeShow(function(e,f){e=this.getTip();var b=this.getConf();d||(d=[b.position[0],b.position[1],b.offset[0],b.offset[1],g.extend({},b)]);g.extend(b,d[4]);b.position=[d[0],d[1]];b.offset=[d[2],d[3]];e.css({visibility:"hidden",position:"absolute",top:f.top,left:f.left}).show();f=j(e);if(!k(f)){if(f[2]){g.extend(b,a.top);b.position[0]="top";e.addClass(c[0])}if(f[3]){g.extend(b,a.right);b.position[1]="right";e.addClass(c[1])}if(f[0]){g.extend(b,a.bottom);b.position[0]="bottom";e.addClass(c[2])}if(f[1]){g.extend(b, +a.left);b.position[1]="left";e.addClass(c[3])}if(f[0]||f[2])b.offset[0]*=-1;if(f[1]||f[3])b.offset[1]*=-1}e.css({visibility:"visible"}).hide()});h.onBeforeShow(function(){var e=this.getConf();this.getTip();setTimeout(function(){e.position=[d[0],d[1]];e.offset=[d[2],d[3]]},0)});h.onHide(function(){var e=this.getTip();e.removeClass(a.classNames)});ret=h});return a.api?ret:this}})(jQuery); +(function(e){function n(f,c){var a=e(c);return a.length<2?a:f.parent().find(c)}function t(f,c){var a=this,l=f.add(a),g=f.children(),k=0,m=c.vertical;j||(j=a);if(g.length>1)g=e(c.items,f);e.extend(a,{getConf:function(){return c},getIndex:function(){return k},getSize:function(){return a.getItems().size()},getNaviButtons:function(){return o.add(p)},getRoot:function(){return f},getItemWrap:function(){return g},getItems:function(){return g.children(c.item).not("."+c.clonedClass)},move:function(b,d){return a.seekTo(k+ +b,d)},next:function(b){return a.move(1,b)},prev:function(b){return a.move(-1,b)},begin:function(b){return a.seekTo(0,b)},end:function(b){return a.seekTo(a.getSize()-1,b)},focus:function(){return j=a},addItem:function(b){b=e(b);if(c.circular){e(".cloned:last").before(b);e(".cloned:first").replaceWith(b.clone().addClass(c.clonedClass))}else g.append(b);l.trigger("onAddItem",[b]);return a},seekTo:function(b,d,h){if(c.circular&&b===0&&k==-1&&d!==0)return a;if(!c.circular&&b<0||b>a.getSize()||b<-1)return a; +var i=b;if(b.jquery)b=a.getItems().index(b);else i=a.getItems().eq(b);var q=e.Event("onBeforeSeek");if(!h){l.trigger(q,[b,d]);if(q.isDefaultPrevented()||!i.length)return a}i=m?{top:-i.position().top}:{left:-i.position().left};k=b;j=a;if(d===undefined)d=c.speed;g.animate(i,d,c.easing,h||function(){l.trigger("onSeek",[b])});return a}});e.each(["onBeforeSeek","onSeek","onAddItem"],function(b,d){e.isFunction(c[d])&&e(a).bind(d,c[d]);a[d]=function(h){e(a).bind(d,h);return a}});if(c.circular){var r=a.getItems().slice(-1).clone().prependTo(g), +s=a.getItems().eq(1).clone().appendTo(g);r.add(s).addClass(c.clonedClass);a.onBeforeSeek(function(b,d,h){if(!b.isDefaultPrevented())if(d==-1){a.seekTo(r,h,function(){a.end(0)});return b.preventDefault()}else d==a.getSize()&&a.seekTo(s,h,function(){a.begin(0)})});a.seekTo(0,0)}var o=n(f,c.prev).click(function(){a.prev()}),p=n(f,c.next).click(function(){a.next()});!c.circular&&a.getSize()>1&&a.onBeforeSeek(function(b,d){o.toggleClass(c.disabledClass,d<=0);p.toggleClass(c.disabledClass,d>=a.getSize()- +1)});c.mousewheel&&e.fn.mousewheel&&f.mousewheel(function(b,d){if(c.mousewheel){a.move(d<0?1:-1,c.wheelSpeed||50);return false}});c.keyboard&&e(document).bind("keydown.scrollable",function(b){if(!(!c.keyboard||b.altKey||b.ctrlKey||e(b.target).is(":input")))if(!(c.keyboard!="static"&&j!=a)){var d=b.keyCode;if(m&&(d==38||d==40)){a.move(d==38?-1:1);return b.preventDefault()}if(!m&&(d==37||d==39)){a.move(d==37?-1:1);return b.preventDefault()}}});e(a).trigger("onBeforeSeek",[c.initialIndex])}e.tools=e.tools|| +{version:"1.2.2"};e.tools.scrollable={conf:{activeClass:"active",circular:false,clonedClass:"cloned",disabledClass:"disabled",easing:"swing",initialIndex:0,item:null,items:".items",keyboard:true,mousewheel:false,next:".next",prev:".prev",speed:400,vertical:false,wheelSpeed:0}};var j;e.fn.scrollable=function(f){var c=this.data("scrollable");if(c)return c;f=e.extend({},e.tools.scrollable.conf,f);this.each(function(){c=new t(e(this),f);e(this).data("scrollable",c)});return f.api?c:this}})(jQuery); +(function(c){var g=c.tools.scrollable;g.autoscroll={conf:{autoplay:true,interval:3E3,autopause:true}};c.fn.autoscroll=function(d){if(typeof d=="number")d={interval:d};var b=c.extend({},g.autoscroll.conf,d),h;this.each(function(){var a=c(this).data("scrollable");if(a)h=a;var e,i,f=true;a.play=function(){if(!e){f=false;e=setInterval(function(){a.next()},b.interval);a.next()}};a.pause=function(){e=clearInterval(e)};a.stop=function(){a.pause();f=true};b.autopause&&a.getRoot().add(a.getNaviButtons()).hover(function(){a.pause(); +clearInterval(i)},function(){f||(i=setTimeout(a.play,b.interval))});b.autoplay&&setTimeout(a.play,b.interval)});return b.api?h:this}})(jQuery); +(function(d){function p(c,g){var h=d(g);return h.length<2?h:c.parent().find(g)}var m=d.tools.scrollable;m.navigator={conf:{navi:".navi",naviItem:null,activeClass:"active",indexed:false,idPrefix:null,history:false}};d.fn.navigator=function(c){if(typeof c=="string")c={navi:c};c=d.extend({},m.navigator.conf,c);var g;this.each(function(){function h(a,b,i){e.seekTo(b);if(j){if(location.hash)location.hash=a.attr("href").replace("#","")}else return i.preventDefault()}function f(){return k.find(c.naviItem|| +"> *")}function n(a){var b=d("<"+(c.naviItem||"a")+"/>").click(function(i){h(d(this),a,i)}).attr("href","#"+a);a===0&&b.addClass(l);c.indexed&&b.text(a+1);c.idPrefix&&b.attr("id",c.idPrefix+a);return b.appendTo(k)}function o(a,b){a=f().eq(b.replace("#",""));a.length||(a=f().filter("[href="+b+"]"));a.click()}var e=d(this).data("scrollable"),k=p(e.getRoot(),c.navi),q=e.getNaviButtons(),l=c.activeClass,j=c.history&&d.fn.history;if(e)g=e;e.getNaviButtons=function(){return q.add(k)};f().length?f().each(function(a){d(this).click(function(b){h(d(this), +a,b)})}):d.each(e.getItems(),function(a){n(a)});e.onBeforeSeek(function(a,b){var i=f().eq(b);!a.isDefaultPrevented()&&i.length&&f().removeClass(l).eq(b).addClass(l)});e.onAddItem(function(a,b){b=n(e.getItems().index(b));j&&b.history(o)});j&&f().history(o)});return c.api?g:this}})(jQuery); +(function(a){function t(d,b){var c=this,i=d.add(c),o=a(window),k,f,m,g=a.tools.expose&&(b.mask||b.expose),n=Math.random().toString().slice(10);if(g){if(typeof g=="string")g={color:g};g.closeOnClick=g.closeOnEsc=false}var p=b.target||d.attr("rel");f=p?a(p):d;if(!f.length)throw"Could not find Overlay: "+p;d&&d.index(f)==-1&&d.click(function(e){c.load(e);return e.preventDefault()});a.extend(c,{load:function(e){if(c.isOpened())return c;var h=q[b.effect];if(!h)throw'Overlay: cannot find effect : "'+b.effect+ +'"';b.oneInstance&&a.each(s,function(){this.close(e)});e=e||a.Event();e.type="onBeforeLoad";i.trigger(e);if(e.isDefaultPrevented())return c;m=true;g&&a(f).expose(g);var j=b.top,r=b.left,u=f.outerWidth({margin:true}),v=f.outerHeight({margin:true});if(typeof j=="string")j=j=="center"?Math.max((o.height()-v)/2,0):parseInt(j,10)/100*o.height();if(r=="center")r=Math.max((o.width()-u)/2,0);h[0].call(c,{top:j,left:r},function(){if(m){e.type="onLoad";i.trigger(e)}});g&&b.closeOnClick&&a.mask.getMask().one("click", +c.close);b.closeOnClick&&a(document).bind("click."+n,function(l){a(l.target).parents(f).length||c.close(l)});b.closeOnEsc&&a(document).bind("keydown."+n,function(l){l.keyCode==27&&c.close(l)});return c},close:function(e){if(!c.isOpened())return c;e=e||a.Event();e.type="onBeforeClose";i.trigger(e);if(!e.isDefaultPrevented()){m=false;q[b.effect][1].call(c,function(){e.type="onClose";i.trigger(e)});a(document).unbind("click."+n).unbind("keydown."+n);g&&a.mask.close();return c}},getOverlay:function(){return f}, +getTrigger:function(){return d},getClosers:function(){return k},isOpened:function(){return m},getConf:function(){return b}});a.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","),function(e,h){a.isFunction(b[h])&&a(c).bind(h,b[h]);c[h]=function(j){a(c).bind(h,j);return c}});k=f.find(b.close||".close");if(!k.length&&!b.close){k=a('
        ');f.prepend(k)}k.click(function(e){c.close(e)});b.load&&c.load()}a.tools=a.tools||{version:"1.2.2"};a.tools.overlay={addEffect:function(d, +b,c){q[d]=[b,c]},conf:{close:null,closeOnClick:true,closeOnEsc:true,closeSpeed:"fast",effect:"default",fixed:!a.browser.msie||a.browser.version>6,left:"center",load:false,mask:null,oneInstance:true,speed:"normal",target:null,top:"10%"}};var s=[],q={};a.tools.overlay.addEffect("default",function(d,b){var c=this.getConf(),i=a(window);if(!c.fixed){d.top+=i.scrollTop();d.left+=i.scrollLeft()}d.position=c.fixed?"fixed":"absolute";this.getOverlay().css(d).fadeIn(c.speed,b)},function(d){this.getOverlay().fadeOut(this.getConf().closeSpeed, +d)});a.fn.overlay=function(d){var b=this.data("overlay");if(b)return b;if(a.isFunction(d))d={onBeforeLoad:d};d=a.extend(true,{},a.tools.overlay.conf,d);this.each(function(){b=new t(a(this),d);s.push(b);a(this).data("overlay",b)});return d.api?b:this}})(jQuery); diff --git a/views/default/js/json2.js.php b/views/default/js/json2.js.php new file mode 100644 index 000000000..7ae503202 --- /dev/null +++ b/views/default/js/json2.js.php @@ -0,0 +1,476 @@ +/* + http://www.JSON.org/json2.js + 2009-06-29 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the object holding the key. + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. +*/ + +/*jslint evil: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +var JSON = JSON || {}; + +(function () { + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/. +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/views/default/js/md5.js.php b/views/default/js/md5.js.php new file mode 100644 index 000000000..4284f62bb --- /dev/null +++ b/views/default/js/md5.js.php @@ -0,0 +1,261 @@ +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} +function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} +function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} +function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } +function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } +function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + var olda, oldb, oldc, oldd; + for(var i = 0; i < x.length; i += 16) + { + olda = a; + oldb = b; + oldc = c; + oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return [a, b, c, d]; +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Calculate the HMAC-MD5, of a key and some data + */ +function core_hmac_md5(key, data) +{ + var bkey = str2binl(key); + if(bkey.length > 16) { bkey = core_md5(bkey, key.length * chrsz); } + + var ipad = new Array(16), opad = new Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str) +{ + var bin = []; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + { + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + } + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + { + str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); + } + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + var triplet, j; + for(var i = 0; i < binarray.length * 4; i += 3) + { + triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) | + (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) | + ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); + for(j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) { str += b64pad; } + else { str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); } + } + } + return str; +} diff --git a/views/default/js/sha1.js.php b/views/default/js/sha1.js.php new file mode 100644 index 000000000..db3bf0544 --- /dev/null +++ b/views/default/js/sha1.js.php @@ -0,0 +1,207 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} +function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} +function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} +function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} +function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} +function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} + +/* + * Perform a simple self-test to see if the VM is working + */ +function sha1_vm_test() +{ + return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; +} + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = new Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + var i, j, t, olda, oldb, oldc, oldd, olde; + for (i = 0; i < x.length; i += 16) + { + olda = a; + oldb = b; + oldc = c; + oldd = d; + olde = e; + + for (j = 0; j < 80; j++) + { + if (j < 16) { w[j] = x[i + j]; } + else { w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); } + t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return [a, b, c, d, e]; +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if (t < 20) { return (b & c) | ((~b) & d); } + if (t < 40) { return b ^ c ^ d; } + if (t < 60) { return (b & c) | (b & d) | (c & d); } + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * Calculate the HMAC-SHA1 of a key and some data + */ +function core_hmac_sha1(key, data) +{ + var bkey = str2binb(key); + if (bkey.length > 16) { bkey = core_sha1(bkey, key.length * chrsz); } + + var ipad = new Array(16), opad = new Array(16); + for (var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); + return core_sha1(opad.concat(hash), 512 + 160); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ +function str2binb(str) +{ + var bin = []; + var mask = (1 << chrsz) - 1; + for (var i = 0; i < str.length * chrsz; i += chrsz) + { + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); + } + return bin; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for (var i = 0; i < bin.length * 32; i += chrsz) + { + str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); + } + return str; +} + +/* + * Convert an array of big-endian words to a hex string. + */ +function binb2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of big-endian words to a base-64 string + */ +function binb2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + var triplet, j; + for (var i = 0; i < binarray.length * 4; i += 3) + { + triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) | + (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) | + ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); + for (j = 0; j < 4; j++) + { + if (i * 8 + j * 6 > binarray.length * 32) { str += b64pad; } + else { str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); } + } + } + return str; +} diff --git a/views/default/js/strophe.min.js.php b/views/default/js/strophe.min.js.php new file mode 100644 index 000000000..f0eb17906 --- /dev/null +++ b/views/default/js/strophe.min.js.php @@ -0,0 +1 @@ +var Base64=(function(){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var obj={encode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;do{chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else{if(isNaN(chr3)){enc4=64}}output=output+keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4)}while(i>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2)}if(enc4!=64){output=output+String.fromCharCode(chr3)}}while(i>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&65535)};var bit_rol=function(num,cnt){return(num<>>(32-cnt))};var str2binl=function(str){var bin=[];var mask=(1<>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32)}return bin};var binl2str=function(bin){var str="";var mask=(1<>5]>>>(i%32))&mask)}return str};var binl2hex=function(binarray){var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef";var str="";for(var i=0;i>2]>>((i%4)*8+4))&15)+hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&15)}return str};var binl2b64=function(binarray){var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var str="";var triplet,j;for(var i=0;i>2]>>8*(i%4))&255)<<16)|(((binarray[i+1>>2]>>8*((i+1)%4))&255)<<8)|((binarray[i+2>>2]>>8*((i+2)%4))&255);for(j=0;j<4;j++){if(i*8+j*6>binarray.length*32){str+=b64pad}else{str+=tab.charAt((triplet>>6*(3-j))&63)}}}return str};var md5_cmn=function(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)};var md5_ff=function(a,b,c,d,x,s,t){return md5_cmn((b&c)|((~b)&d),a,b,x,s,t)};var md5_gg=function(a,b,c,d,x,s,t){return md5_cmn((b&d)|(c&(~d)),a,b,x,s,t)};var md5_hh=function(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)};var md5_ii=function(a,b,c,d,x,s,t){return md5_cmn(c^(b|(~d)),a,b,x,s,t)};var core_md5=function(x,len){x[len>>5]|=128<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;var olda,oldb,oldc,oldd;for(var i=0;i16){bkey=core_md5(bkey,key.length*chrsz)}var ipad=new Array(16),opad=new Array(16);for(var i=0;i<16;i++){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}var hash=core_md5(ipad.concat(str2binl(data)),512+data.length*chrsz);return core_md5(opad.concat(hash),512+128)};var obj={hexdigest:function(s){return binl2hex(core_md5(str2binl(s),s.length*chrsz))},b64digest:function(s){return binl2b64(core_md5(str2binl(s),s.length*chrsz))},hash:function(s){return binl2str(core_md5(str2binl(s),s.length*chrsz))},hmac_hexdigest:function(key,data){return binl2hex(core_hmac_md5(key,data))},hmac_b64digest:function(key,data){return binl2b64(core_hmac_md5(key,data))},hmac_hash:function(key,data){return binl2str(core_hmac_md5(key,data))},test:function(){return MD5.hexdigest("abc")==="900150983cd24fb0d6963f7d28e17f72"}};return obj})();if(!Function.prototype.bind){Function.prototype.bind=function(obj){var func=this;return function(){return func.apply(obj,arguments)}}}if(!Function.prototype.prependArg){Function.prototype.prependArg=function(arg){var func=this;return function(){var newargs=[arg];for(var i=0;i/g,">");return text},xmlTextNode:function(text){text=Strophe.xmlescape(text);if(!Strophe._xmlGenerator){Strophe._xmlGenerator=Strophe._makeGenerator()}return Strophe._xmlGenerator.createTextNode(text)},getText:function(elem){if(!elem){return null}var str="";if(elem.childNodes.length===0&&elem.nodeType==Strophe.ElementType.TEXT){str+=elem.nodeValue}for(var i=0;i/g,"\\3e").replace(/@/g,"\\40")},unescapeNode:function(node){return node.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\")},getNodeFromJid:function(jid){if(jid.indexOf("@")<0){return null}return jid.split("@")[0]},getDomainFromJid:function(jid){var bare=Strophe.getBareJidFromJid(jid);if(bare.indexOf("@")<0){return bare}else{var parts=bare.split("@");parts.splice(0,1);return parts.join("@")}},getResourceFromJid:function(jid){var s=jid.split("/");if(s.length<2){return null}s.splice(0,1);return s.join("/")},getBareJidFromJid:function(jid){return jid.split("/")[0]},log:function(level,msg){return},debug:function(msg){this.log(this.LogLevel.DEBUG,msg)},info:function(msg){this.log(this.LogLevel.INFO,msg)},warn:function(msg){this.log(this.LogLevel.WARN,msg)},error:function(msg){this.log(this.LogLevel.ERROR,msg)},fatal:function(msg){this.log(this.LogLevel.FATAL,msg)},serialize:function(elem){var result;if(!elem){return null}if(typeof(elem.tree)==="function"){elem=elem.tree()}var nodeName=elem.nodeName;var i,child;if(elem.getAttribute("_realname")){nodeName=elem.getAttribute("_realname")}result="<"+nodeName;for(i=0;i0){result+=">";for(i=0;i"}else{result+="/>"}return result},_requestId:0,_connectionPlugins:{},addConnectionPlugin:function(name,ptype){Strophe._connectionPlugins[name]=ptype}};Strophe.Builder=function(name,attrs){if(name=="presence"||name=="message"||name=="iq"){if(attrs&&!attrs.xmlns){attrs.xmlns=Strophe.NS.CLIENT}else{if(!attrs){attrs={xmlns:Strophe.NS.CLIENT}}}}this.nodeTree=Strophe.xmlElement(name,attrs);this.node=this.nodeTree};Strophe.Builder.prototype={tree:function(){return this.nodeTree},toString:function(){return Strophe.serialize(this.nodeTree)},up:function(){this.node=this.node.parentNode;return this},attrs:function(moreattrs){for(var k in moreattrs){if(moreattrs.hasOwnProperty(k)){this.node.setAttribute(k,moreattrs[k])}}return this},c:function(name,attrs){var child=Strophe.xmlElement(name,attrs);this.node.appendChild(child);this.node=child;return this},cnode:function(elem){this.node.appendChild(elem);this.node=elem;return this},t:function(text){var child=Strophe.xmlTextNode(text);this.node.appendChild(child);return this}};Strophe.Handler=function(handler,ns,name,type,id,from,options){this.handler=handler;this.ns=ns;this.name=name;this.type=type;this.id=id;this.options=options||{matchbare:false};if(!this.options.matchBare){this.options.matchBare=false}if(this.options.matchBare){this.from=Strophe.getBareJidFromJid(from)}else{this.from=from}this.user=true};Strophe.Handler.prototype={isMatch:function(elem){var nsMatch;var from=null;if(this.options.matchBare){from=Strophe.getBareJidFromJid(elem.getAttribute("from"))}else{from=elem.getAttribute("from")}nsMatch=false;if(!this.ns){nsMatch=true}else{var self=this;Strophe.forEachChild(elem,null,function(elem){if(elem.getAttribute("xmlns")==self.ns){nsMatch=true}});nsMatch=nsMatch||elem.getAttribute("xmlns")==this.ns}if(nsMatch&&(!this.name||Strophe.isTagEqual(elem,this.name))&&(!this.type||elem.getAttribute("type")===this.type)&&(!this.id||elem.getAttribute("id")===this.id)&&(!this.from||from===this.from)){return true}return false},run:function(elem){var result=null;try{result=this.handler(elem)}catch(e){if(e.sourceURL){Strophe.fatal("error: "+this.handler+" "+e.sourceURL+":"+e.line+" - "+e.name+": "+e.message)}else{if(e.fileName){if(typeof(console)!="undefined"){console.trace();console.error(this.handler," - error - ",e,e.message)}Strophe.fatal("error: "+this.handler+" "+e.fileName+":"+e.lineNumber+" - "+e.name+": "+e.message)}else{Strophe.fatal("error: "+this.handler)}}throw e}return result},toString:function(){return"{Handler: "+this.handler+"("+this.name+","+this.id+","+this.ns+")}"}};Strophe.TimedHandler=function(period,handler){this.period=period;this.handler=handler;this.lastCalled=new Date().getTime();this.user=true};Strophe.TimedHandler.prototype={run:function(){this.lastCalled=new Date().getTime();return this.handler()},reset:function(){this.lastCalled=new Date().getTime()},toString:function(){return"{TimedHandler: "+this.handler+"("+this.period+")}"}};Strophe.Request=function(elem,func,rid,sends){this.id=++Strophe._requestId;this.xmlData=elem;this.data=Strophe.serialize(elem);this.origFunc=func;this.func=func;this.rid=rid;this.date=NaN;this.sends=sends||0;this.abort=false;this.dead=null;this.age=function(){if(!this.date){return 0}var now=new Date();return(now-this.date)/1000};this.timeDead=function(){if(!this.dead){return 0}var now=new Date();return(now-this.dead)/1000};this.xhr=this._newXHR()};Strophe.Request.prototype={getResponse:function(){var node=null;if(this.xhr.responseXML&&this.xhr.responseXML.documentElement){node=this.xhr.responseXML.documentElement;if(node.tagName=="parsererror"){Strophe.error("invalid response received");Strophe.error("responseText: "+this.xhr.responseText);Strophe.error("responseXML: "+Strophe.serialize(this.xhr.responseXML));throw"parsererror"}}else{if(this.xhr.responseText){Strophe.error("invalid response received");Strophe.error("responseText: "+this.xhr.responseText);Strophe.error("responseXML: "+Strophe.serialize(this.xhr.responseXML))}}return node},_newXHR:function(){var xhr=null;if(window.XMLHttpRequest){xhr=new XMLHttpRequest();if(xhr.overrideMimeType){xhr.overrideMimeType("text/xml")}}else{if(window.ActiveXObject){xhr=new ActiveXObject("Microsoft.XMLHTTP")}}xhr.onreadystatechange=this.func.prependArg(this);return xhr}};Strophe.Connection=function(service){this.service=service;this.jid="";this.rid=Math.floor(Math.random()*4294967295);this.sid=null;this.streamId=null;this.do_session=false;this.do_bind=false;this.timedHandlers=[];this.handlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[];this._idleTimeout=null;this._disconnectTimeout=null;this.authenticated=false;this.disconnecting=false;this.connected=false;this.errors=0;this.paused=false;this.hold=1;this.wait=60;this.window=5;this._data=[];this._requests=[];this._uniqueId=Math.round(Math.random()*10000);this._sasl_success_handler=null;this._sasl_failure_handler=null;this._sasl_challenge_handler=null;this._idleTimeout=setTimeout(this._onIdle.bind(this),100);for(var k in Strophe._connectionPlugins){if(Strophe._connectionPlugins.hasOwnProperty(k)){var ptype=Strophe._connectionPlugins[k];var F=function(){};F.prototype=ptype;this[k]=new F();this[k].init(this)}}};Strophe.Connection.prototype={reset:function(){this.rid=Math.floor(Math.random()*4294967295);this.sid=null;this.streamId=null;this.do_session=false;this.do_bind=false;this.timedHandlers=[];this.handlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[];this.authenticated=false;this.disconnecting=false;this.connected=false;this.errors=0;this._requests=[];this._uniqueId=Math.round(Math.random()*10000)},pause:function(){this.paused=true},resume:function(){this.paused=false},getUniqueId:function(suffix){if(typeof(suffix)=="string"||typeof(suffix)=="number"){return ++this._uniqueId+":"+suffix}else{return ++this._uniqueId+""}},connect:function(jid,pass,callback,wait,hold){this.jid=jid;this.pass=pass;this.connect_callback=callback;this.disconnecting=false;this.connected=false;this.authenticated=false;this.errors=0;this.wait=wait||this.wait;this.hold=hold||this.hold;this.domain=Strophe.getDomainFromJid(this.jid);var body=this._buildBody().attrs({to:this.domain,"xml:lang":"en",wait:this.wait,hold:this.hold,content:"text/xml; charset=utf-8",ver:"1.6","xmpp:version":"1.0","xmlns:xmpp":Strophe.NS.BOSH});this._changeConnectStatus(Strophe.Status.CONNECTING,null);this._requests.push(new Strophe.Request(body.tree(),this._onRequestStateChange.bind(this).prependArg(this._connect_cb.bind(this)),body.tree().getAttribute("rid")));this._throttledRequestHandler()},attach:function(jid,sid,rid,callback,wait,hold,wind){this.jid=jid;this.sid=sid;this.rid=rid;this.connect_callback=callback;this.domain=Strophe.getDomainFromJid(this.jid);this.authenticated=true;this.connected=true;this.wait=wait||this.wait;this.hold=hold||this.hold;this.window=wind||this.window;this._changeConnectStatus(Strophe.Status.ATTACHED,null)},xmlInput:function(elem){return},xmlOutput:function(elem){return},rawInput:function(data){return},rawOutput:function(data){return},send:function(elem){if(elem===null){return}if(typeof(elem.sort)==="function"){for(var i=0;i=0;i--){if(req==this._requests[i]){this._requests.splice(i,1)}}req.xhr.onreadystatechange=function(){};this._throttledRequestHandler()},_restartRequest:function(i){var req=this._requests[i];if(req.dead===null){req.dead=new Date()}this._processRequest(i)},_processRequest:function(i){var req=this._requests[i];var reqStatus=-1;try{if(req.xhr.readyState==4){reqStatus=req.xhr.status}}catch(e){Strophe.error("caught an error in _requests["+i+"], reqStatus: "+reqStatus)}if(typeof(reqStatus)=="undefined"){reqStatus=-1}var time_elapsed=req.age();var primaryTimeout=(!isNaN(time_elapsed)&&time_elapsed>Math.floor(Strophe.TIMEOUT*this.wait));var secondaryTimeout=(req.dead!==null&&req.timeDead()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait));var requestCompletedWithServerError=(req.xhr.readyState==4&&(reqStatus<1||reqStatus>=500));if(primaryTimeout||secondaryTimeout||requestCompletedWithServerError){if(secondaryTimeout){Strophe.error("Request "+this._requests[i].id+" timed out (secondary), restarting")}req.abort=true;req.xhr.abort();req.xhr.onreadystatechange=function(){};this._requests[i]=new Strophe.Request(req.xmlData,req.origFunc,req.rid,req.sends);req=this._requests[i]}if(req.xhr.readyState===0){Strophe.debug("request id "+req.id+"."+req.sends+" posting");req.date=new Date();try{req.xhr.open("POST",this.service,true)}catch(e2){Strophe.error("XHR open failed.");if(!this.connected){this._changeConnectStatus(Strophe.Status.CONNFAIL,"bad-service")}this.disconnect();return}var sendFunc=function(){req.xhr.send(req.data)};if(req.sends>1){var backoff=Math.pow(req.sends,3)*1000;setTimeout(sendFunc,backoff)}else{sendFunc()}req.sends++;this.xmlOutput(req.xmlData);this.rawOutput(req.data)}else{Strophe.debug("_processRequest: "+(i===0?"first":"second")+" request has readyState of "+req.xhr.readyState)}},_throttledRequestHandler:function(){if(!this._requests){Strophe.debug("_throttledRequestHandler called with undefined requests")}else{Strophe.debug("_throttledRequestHandler called with "+this._requests.length+" requests")}if(!this._requests||this._requests.length===0){return}if(this._requests.length>0){this._processRequest(0)}if(this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)=400){this._hitError(reqStatus);return}}var reqIs0=(this._requests[0]==req);var reqIs1=(this._requests[1]==req);if((reqStatus>0&&reqStatus<500)||req.sends>5){this._removeRequest(req);Strophe.debug("request id "+req.id+" should now be removed")}if(reqStatus==200){if(reqIs1||(reqIs0&&this._requests.length>0&&this._requests[0].age()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait))){this._restartRequest(0)}Strophe.debug("request id "+req.id+"."+req.sends+" got 200");func(req);this.errors=0}else{Strophe.error("request id "+req.id+"."+req.sends+" error "+reqStatus+" happened");if(reqStatus===0||(reqStatus>=400&&reqStatus<600)||reqStatus>=12000){this._hitError(reqStatus);if(reqStatus>=400&&reqStatus<500){this._changeConnectStatus(Strophe.Status.DISCONNECTING,null);this._doDisconnect()}}}if(!((reqStatus>0&&reqStatus<10000)||req.sends>5)){this._throttledRequestHandler()}}},_hitError:function(reqStatus){this.errors++;Strophe.warn("request errored, status: "+reqStatus+", number of errors: "+this.errors);if(this.errors>4){this._onDisconnectTimeout()}},_doDisconnect:function(){Strophe.info("_doDisconnect was called");this.authenticated=false;this.disconnecting=false;this.sid=null;this.streamId=null;this.rid=Math.floor(Math.random()*4294967295);if(this.connected){this._changeConnectStatus(Strophe.Status.DISCONNECTED,null);this.connected=false}this.handlers=[];this.timedHandlers=[];this.removeTimeds=[];this.removeHandlers=[];this.addTimeds=[];this.addHandlers=[]},_dataRecv:function(req){try{var elem=req.getResponse()}catch(e){if(e!="parsererror"){throw e}this.disconnect("strophe-parsererror")}if(elem===null){return}this.xmlInput(elem);this.rawInput(Strophe.serialize(elem));var i,hand;while(this.removeHandlers.length>0){hand=this.removeHandlers.pop();i=this.handlers.indexOf(hand);if(i>=0){this.handlers.splice(i,1)}}while(this.addHandlers.length>0){this.handlers.push(this.addHandlers.pop())}if(this.disconnecting&&this._requests.length===0){this.deleteTimedHandler(this._disconnectTimeout);this._disconnectTimeout=null;this._doDisconnect();return}var typ=elem.getAttribute("type");var cond,conflict;if(typ!==null&&typ=="terminate"){cond=elem.getAttribute("condition");conflict=elem.getElementsByTagName("conflict");if(cond!==null){if(cond=="remote-stream-error"&&conflict.length>0){cond="conflict"}this._changeConnectStatus(Strophe.Status.CONNFAIL,cond)}else{this._changeConnectStatus(Strophe.Status.CONNFAIL,"unknown")}this.disconnect();return}var self=this;Strophe.forEachChild(elem,null,function(child){var i,newList;newList=self.handlers;self.handlers=[];for(i=0;i0){cond="conflict"}this._changeConnectStatus(Strophe.Status.CONNFAIL,cond)}else{this._changeConnectStatus(Strophe.Status.CONNFAIL,"unknown")}return}if(!this.sid){this.sid=bodyWrap.getAttribute("sid")}if(!this.stream_id){this.stream_id=bodyWrap.getAttribute("authid")}var wind=bodyWrap.getAttribute("requests");if(wind){this.window=parseInt(wind,10)}var hold=bodyWrap.getAttribute("hold");if(hold){this.hold=parseInt(hold,10)}var wait=bodyWrap.getAttribute("wait");if(wait){this.wait=parseInt(wait,10)}var do_sasl_plain=false;var do_sasl_digest_md5=false;var do_sasl_anonymous=false;var mechanisms=bodyWrap.getElementsByTagName("mechanism");var i,mech,auth_str,hashed_auth_str;if(mechanisms.length>0){for(i=0;i0){jidNode=bind[0].getElementsByTagName("jid");if(jidNode.length>0){this.jid=Strophe.getText(jidNode[0]);if(this.do_session){this._addSysHandler(this._sasl_session_cb.bind(this),null,null,null,"_session_auth_2");this.send($iq({type:"set",id:"_session_auth_2"}).c("session",{xmlns:Strophe.NS.SESSION}).tree())}else{this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}}}else{Strophe.info("SASL binding failed.");this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}},_sasl_session_cb:function(elem){if(elem.getAttribute("type")=="result"){this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}else{if(elem.getAttribute("type")=="error"){Strophe.info("Session creation failed.");this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false}}return false},_sasl_failure_cb:function(elem){if(this._sasl_success_handler){this.deleteHandler(this._sasl_success_handler);this._sasl_success_handler=null}if(this._sasl_challenge_handler){this.deleteHandler(this._sasl_challenge_handler);this._sasl_challenge_handler=null}this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);return false},_auth2_cb:function(elem){if(elem.getAttribute("type")=="result"){this.authenticated=true;this._changeConnectStatus(Strophe.Status.CONNECTED,null)}else{if(elem.getAttribute("type")=="error"){this._changeConnectStatus(Strophe.Status.AUTHFAIL,null);this.disconnect()}}return false},_addSysTimedHandler:function(period,handler){var thand=new Strophe.TimedHandler(period,handler);thand.user=false;this.addTimeds.push(thand);return thand},_addSysHandler:function(handler,ns,name,type,id){var hand=new Strophe.Handler(handler,ns,name,type,id);hand.user=false;this.addHandlers.push(hand);return hand},_onDisconnectTimeout:function(){Strophe.info("_onDisconnectTimeout was called");var req;while(this._requests.length>0){req=this._requests.pop();req.abort=true;req.xhr.abort();req.xhr.onreadystatechange=function(){}}this._doDisconnect();return false},_onIdle:function(){var i,thand,since,newList;while(this.removeTimeds.length>0){thand=this.removeTimeds.pop();i=this.timedHandlers.indexOf(thand);if(i>=0){this.timedHandlers.splice(i,1)}}while(this.addTimeds.length>0){this.timedHandlers.push(this.addTimeds.pop())}var now=new Date().getTime();newList=[];for(i=0;i0&&!this.paused){body=this._buildBody();for(i=0;i0){time_elapsed=this._requests[0].age();if(this._requests[0].dead!==null){if(this._requests[0].timeDead()>Math.floor(Strophe.SECONDARY_TIMEOUT*this.wait)){this._throttledRequestHandler()}}if(time_elapsed>Math.floor(Strophe.TIMEOUT*this.wait)){Strophe.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(Strophe.TIMEOUT*this.wait)+" seconds since last activity");this._throttledRequestHandler()}}clearTimeout(this._idleTimeout);this._idleTimeout=setTimeout(this._onIdle.bind(this),100)}};if(callback){callback(Strophe,$build,$msg,$iq,$pres)}})(function(){window.Strophe=arguments[0];window.$build=arguments[1];window.$msg=arguments[2];window.$iq=arguments[3];window.$pres=arguments[4]}); \ No newline at end of file diff --git a/views/default/js/strophe.muc.js b/views/default/js/strophe.muc.js new file mode 100644 index 000000000..954ca8730 --- /dev/null +++ b/views/default/js/strophe.muc.js @@ -0,0 +1,300 @@ +/* +Plugin to implement the MUC extension. http://xmpp.org/extensions/xep-0045.html +*/ +/* jslint configuration: */ +/* global document, window, setTimeout, clearTimeout, console, + XMLHttpRequest, ActiveXObject, + Base64, MD5, + Strophe, $build, $msg, $iq, $pres +*/ + +Strophe.addConnectionPlugin('muc', { + _connection: null, + // The plugin must have the init function + /***Function + Initialize the MUC plugin. Sets the correct connection object and + extends the namesace. + */ + init: function(conn) { + this._connection = conn; + /* extend name space + * NS.MUC - XMPP Multi-user chat namespace + * from XEP 45. + * + */ + Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC+"#owner"); + Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC+"#admin"); + }, + /***Function + Join a multi-user chat room + Parameters: + (String) room - The multi-user chat room to join. + (String) nick - The nickname to use in the chat room. Optional + (Function) msg_handler_cb - The function call to handle messages from the + specified chat room. + (Function) pres_handler_cb - The function call back to handle presence + in the chat room. + (String) password - The optional password to use. (password protected + rooms only) + */ + join: function(room, nick, msg_handler_cb, pres_handler_cb, password) { + var room_nick = this.test_append_nick(room, nick); + var msg = $pres({from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + if (password) + { + var password_elem = Strophe.xmlElement("password", + [], + password); + msg.cnode(password_elem); + } + if (msg_handler_cb) + { + this._connection.addHandler(function(stanza) { + var from = stanza.getAttribute('from'); + var roomname = from.split("/"); + // filter on room name + if (roomname.length > 1 && roomname[0] == room) + { + return msg_handler_cb(stanza); + } + else + { + return true; + } + }, + null, + "message", + null, + null, + null); + } + if (pres_handler_cb) + { + this._connection.addHandler(function(stanza) { + var xquery = stanza.getElementsByTagName("x"); + if (xquery.length > 0) + { + //Handle only MUC user protocol + for (var i = 0; i < xquery.length; i++) + { + var xmlns = xquery[i].getAttribute("xmlns"); + + if (xmlns && xmlns.match(Strophe.NS.MUC)) + { + return pres_handler_cb(stanza); + } + } + } + return true; + }, + null, + "presence", + null, + null, + null); + } + this._connection.send(msg); + }, + /***Function + Leave a multi-user chat room + Parameters: + (String) room - The multi-user chat room to leave. + (String) nick - The nick name used in the room. + (Function) handler_cb - Optional function to handle the successful leave. + Returns: + iqid - The unique id for the room leave. + */ + leave: function(room, nick, handler_cb) { + var room_nick = this.test_append_nick(room, nick); + var presenceid = this._connection.getUniqueId(); + var presence = $pres({type: "unavailable", + id: presenceid, + from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + this._connection.addHandler(handler_cb, + null, + "presence", + null, + presenceid, + null); + this._connection.send(presence); + return presenceid; + }, + /***Function + Parameters: + (String) room - The multi-user chat room name. + (String) nick - The nick name used in the chat room. + (String) message - The message to send to the room. + Returns: + msgiq - the unique id used to send the message + */ + message: function(room, nick, message) { + var room_nick = this.test_append_nick(room, nick); + var msgid = this._connection.getUniqueId(); + var msg = $msg({to: room_nick, + from: this._connection.jid, + type: "groupchat", + id: msgid}).c("body", + {xmlns: Strophe.NS.CLIENT}).t(message); + msg.up().c("x", {xmlns: "jabber:x:event"}).c("composing"); + this._connection.send(msg); + return msgid; + }, + /***Function + Start a room configuration. + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to send the configuration request + */ + configure: function(room) { + //send iq to start room configuration + var config = $iq({to:room, + type: "get"}).c("query", + {xmlns: Strophe.NS.MUC_OWNER}); + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Cancel the room configuration + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to cancel the configuration. + */ + cancelConfigure: function(room) { + //send iq to start room configuration + var config = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", type: "cancel"}); + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Save a room configuration. + Parameters: + (String) room - The multi-user chat room name. + (Array) configarray - an array of form elements used to configure the room. + Returns: + id - the unique id used to save the configuration. + */ + saveConfiguration: function(room, configarray) { + var config = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", type: "submit"}); + for (var i = 0; i >= configarray.length; i++) { + config.cnode(configarray[i]); + } + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to create the chat room. + */ + createInstantRoom: function(room) { + var roomiq = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", + type: "submit"}); + return this._connection.sendIQ(roomiq.tree(), + function() {}, + function() {}); + }, + /*** + Set the topic of the chat room. + Parameters: + (String) room - The multi-user chat room name. + (String) topic - Topic message. + */ + setTopic: function(room, topic) { + var msg = $msg({to: room, + from: this._connection.jid, + type: "groupchat"}) + .c("subject", {xmlns: "jabber:client"}).t(topic); + this._connection.send(msg.tree()); + }, + /***Function + Changes the role and affiliation of a member of a MUC room. + The modification can only be done by a room moderator. An error will be + returned if the user doesn't have permission. + Parameters: + (String) room - The multi-user chat room name. + (String) nick - The nick name of the user to modify. + (String) role - The new role of the user. + (String) affiliation - The new affiliation of the user. + (String) reason - The reason for the change. + Returns: + iq - the id of the mode change request. + */ + modifyUser: function(room, nick, role, affiliation, reason) { + var item_attrs = {nick: Strophe.escapeNode(nick)}; + if (role !== null) + { + item_attrs.role = role; + } + if (affiliation !== null) + { + item_attrs.affiliation = affiliation; + } + var item = $build("item", item_attrs); + if (reason !== null) + { + item.cnode(Strophe.xmlElement("reason", reason)); + } + var roomiq = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}).cnode(item.tree()); + return this._connection.sendIQ(roomiq.tree(), + function() {}, + function() {}); + }, + /***Function + Change the current users nick name. + Parameters: + (String) room - The multi-user chat room name. + (String) user - The new nick name. + */ + changeNick: function(room, user) { + var room_nick = this.test_append_nick(room, user); + var presence = $pres({from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + this._connection.send(presence.tree()); + }, + /***Function + List all chat room available on a server. + Parameters: + (String) server - name of chat server. + (String) handle_cb - Function to call for room list return. + */ + listRooms: function(server, handle_cb) { + var iq = $iq({to: server, + from: this._connection.jid, + type: "get"}) + .c("query",{xmlns: Strophe.NS.DISCO_ITEMS}); + this._connection.sendIQ(iq, handle_cb, function(){}); + }, + test_append_nick: function(room, nick) { + var room_nick = room; + if (nick) + { + room_nick += "/" + Strophe.escapeNode(nick); + } + return room_nick; + } +}); \ No newline at end of file diff --git a/views/default/js/strophe.muc.js.php b/views/default/js/strophe.muc.js.php new file mode 100644 index 000000000..e10750d02 --- /dev/null +++ b/views/default/js/strophe.muc.js.php @@ -0,0 +1,300 @@ +/* +Plugin to implement the MUC extension. http://xmpp.org/extensions/xep-0045.html +*/ +/* jslint configuration: */ +/* global document, window, setTimeout, clearTimeout, console, + XMLHttpRequest, ActiveXObject, + Base64, MD5, + Strophe, $build, $msg, $iq, $pres +*/ + +Strophe.addConnectionPlugin('muc', { + _connection: null, + // The plugin must have the init function + /***Function + Initialize the MUC plugin. Sets the correct connection object and + extends the namesace. + */ + init: function(conn) { + this._connection = conn; + /* extend name space + * NS.MUC - XMPP Multi-user chat namespace + * from XEP 45. + * + */ + Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC+"#owner"); + Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC+"#admin"); + }, + /***Function + Join a multi-user chat room + Parameters: + (String) room - The multi-user chat room to join. + (String) nick - The nickname to use in the chat room. Optional + (Function) msg_handler_cb - The function call to handle messages from the + specified chat room. + (Function) pres_handler_cb - The function call back to handle presence + in the chat room. + (String) password - The optional password to use. (password protected + rooms only) + */ + join: function(room, nick, msg_handler_cb, pres_handler_cb, password) { + var room_nick = this.test_append_nick(room, nick); + var msg = $pres({from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + if (password) + { + var password_elem = Strophe.xmlElement("password", + [], + password); + msg.cnode(password_elem); + } + if (msg_handler_cb) + { + this._connection.addHandler(function(stanza) { + var from = stanza.getAttribute('from'); + var roomname = from.split("/"); + // filter on room name + if (roomname.length > 1 && roomname[0] == room) + { + return msg_handler_cb(stanza); + } + else + { + return true; + } + }, + null, + "message", + null, + null, + null); + } + if (pres_handler_cb) + { + this._connection.addHandler(function(stanza) { + var xquery = stanza.getElementsByTagName("x"); + if (xquery.length > 0) + { + //Handle only MUC user protocol + for (var i = 0; i < xquery.length; i++) + { + var xmlns = xquery[i].getAttribute("xmlns"); + + if (xmlns && xmlns.match(Strophe.NS.MUC)) + { + return pres_handler_cb(stanza); + } + } + } + return true; + }, + null, + "presence", + null, + null, + null); + } + this._connection.send(msg); + }, + /***Function + Leave a multi-user chat room + Parameters: + (String) room - The multi-user chat room to leave. + (String) nick - The nick name used in the room. + (Function) handler_cb - Optional function to handle the successful leave. + Returns: + iqid - The unique id for the room leave. + */ + leave: function(room, nick, handler_cb) { + var room_nick = this.test_append_nick(room, nick); + var presenceid = this._connection.getUniqueId(); + var presence = $pres({type: "unavailable", + id: presenceid, + from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + this._connection.addHandler(handler_cb, + null, + "presence", + null, + presenceid, + null); + this._connection.send(presence); + return presenceid; + }, + /***Function + Parameters: + (String) room - The multi-user chat room name. + (String) nick - The nick name used in the chat room. + (String) message - The message to send to the room. + Returns: + msgiq - the unique id used to send the message + */ + message: function(room, nick, message) { + var room_nick = this.test_append_nick(room, nick); + var msgid = this._connection.getUniqueId(); + var msg = $msg({to: room_nick, + from: this._connection.jid, + type: "groupchat", + id: msgid}).c("body", + {xmlns: Strophe.NS.CLIENT}).t(message); + msg.up().c("x", {xmlns: "jabber:x:event"}).c("composing"); + this._connection.send(msg); + return msgid; + }, + /***Function + Start a room configuration. + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to send the configuration request + */ + configure: function(room) { + //send iq to start room configuration + var config = $iq({to:room, + type: "get"}).c("query", + {xmlns: Strophe.NS.MUC_OWNER}); + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Cancel the room configuration + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to cancel the configuration. + */ + cancelConfigure: function(room) { + //send iq to start room configuration + var config = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", type: "cancel"}); + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Save a room configuration. + Parameters: + (String) room - The multi-user chat room name. + (Array) configarray - an array of form elements used to configure the room. + Returns: + id - the unique id used to save the configuration. + */ + saveConfiguration: function(room, configarray) { + var config = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", type: "submit"}); + for (var i = 0; i >= configarray.length; i++) { + config.cnode(configarray[i]); + } + var stanza = config.tree(); + return this._connection.sendIQ(stanza, + function(){}, + function(){}); + }, + /***Function + Parameters: + (String) room - The multi-user chat room name. + Returns: + id - the unique id used to create the chat room. + */ + createInstantRoom: function(room) { + var roomiq = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}) + .c("x", {xmlns: "jabber:x:data", + type: "submit"}); + return this._connection.sendIQ(roomiq.tree(), + function() {}, + function() {}); + }, + /*** + Set the topic of the chat room. + Parameters: + (String) room - The multi-user chat room name. + (String) topic - Topic message. + */ + setTopic: function(room, topic) { + var msg = $msg({to: room, + from: this._connection.jid, + type: "groupchat"}) + .c("subject", {xmlns: "jabber:client"}).t(topic); + this._connection.send(msg.tree()); + }, + /***Function + Changes the role and affiliation of a member of a MUC room. + The modification can only be done by a room moderator. An error will be + returned if the user doesn't have permission. + Parameters: + (String) room - The multi-user chat room name. + (String) nick - The nick name of the user to modify. + (String) role - The new role of the user. + (String) affiliation - The new affiliation of the user. + (String) reason - The reason for the change. + Returns: + iq - the id of the mode change request. + */ + modifyUser: function(room, nick, role, affiliation, reason) { + var item_attrs = {nick: Strophe.escapeNode(nick)}; + if (role !== null) + { + item_attrs.role = role; + } + if (affiliation !== null) + { + item_attrs.affiliation = affiliation; + } + var item = $build("item", item_attrs); + if (reason !== null) + { + item.cnode(Strophe.xmlElement("reason", reason)); + } + var roomiq = $iq({to: room, + type: "set"}) + .c("query", {xmlns: Strophe.NS.MUC_OWNER}).cnode(item.tree()); + return this._connection.sendIQ(roomiq.tree(), + function() {}, + function() {}); + }, + /***Function + Change the current users nick name. + Parameters: + (String) room - The multi-user chat room name. + (String) user - The new nick name. + */ + changeNick: function(room, user) { + var room_nick = this.test_append_nick(room, user); + var presence = $pres({from: this._connection.jid, + to: room_nick}) + .c("x",{xmlns: Strophe.NS.MUC}); + this._connection.send(presence.tree()); + }, + /***Function + List all chat room available on a server. + Parameters: + (String) server - name of chat server. + (String) handle_cb - Function to call for room list return. + */ + listRooms: function(server, handle_cb) { + var iq = $iq({to: server, + from: this._connection.jid, + type: "get"}) + .c("query",{xmlns: Strophe.NS.DISCO_ITEMS}); + this._connection.sendIQ(iq, handle_cb, function(){}); + }, + test_append_nick: function(room, nick) { + var room_nick = room; + if (nick) + { + room_nick += "/" + Strophe.escapeNode(nick); + } + return room_nick; + } +}); diff --git a/views/default/settings/beechat/edit.php b/views/default/settings/beechat/edit.php new file mode 100755 index 000000000..8f82834db --- /dev/null +++ b/views/default/settings/beechat/edit.php @@ -0,0 +1,31 @@ + +

        + + 'params[domain]','value' => $domain)); ?> + + + 'params[xmlrpcip]','value' => $xmlrpc_ip)); ?> + + 'params[dbname]','value' => $dbname)); ?> + + 'params[dbhost]','value' => $dbhost)); ?> + + 'params[dbuser]','value' => $dbuser)); ?> + + 'params[dbpassword]','value' => $dbpassword)); ?> + +

        + -- cgit v1.2.3 From fc9430d2665235b3a0d39504ecfa236e8d58c6e1 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 03:37:01 +0000 Subject: remove group chat menu. --- start.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/start.php b/start.php index 2fe38b5d5..b6cbc52fe 100644 --- a/start.php +++ b/start.php @@ -138,7 +138,7 @@ function beechat_pagesetup() { global $CONFIG; - if (get_context() == 'groups' && isloggedin()) { + /*if (get_context() == 'group_profile' && isloggedin()) { if (get_plugin_setting("groupdomain", "beechat")) { $user = get_loggedin_user(); $group = page_owner_entity(); @@ -150,7 +150,7 @@ } } } - elseif (get_context() == 'settings' && isloggedin()) { + else*/if (get_context() == 'settings' && isloggedin()) { if (get_loggedin_user()->chatenabled) { add_submenu_item(elgg_echo('beechat:disablechat'), $CONFIG->wwwroot . "mod/beechat/disablechat.php"); } -- cgit v1.2.3 From 4f3e170ec2f2cc6808bbb1452567fff22a9875a2 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 05:06:02 +0000 Subject: fix bareJid setting. --- views/default/beechat/beechat.js.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/views/default/beechat/beechat.js.php b/views/default/beechat/beechat.js.php index 3cdd29d12..51dbbcc08 100644 --- a/views/default/beechat/beechat.js.php +++ b/views/default/beechat/beechat.js.php @@ -1301,7 +1301,7 @@ BeeChat.UI = { if (isroom) var roster = $(this).find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); data.chats[contactBareJid] = { - 'html_content': escape($(this).children().filter('[bareJid=' + contactBareJid + ']').html()), + 'html_content': escape($(this).children().filter('[bareJid="' + contactBareJid + '"]').html()), 'roster_content': isroom?escape(roster.html()):'', 'isroom': $(this).attr('isroom'), 'group_guid': (contactBareJid in g_beechat_rooms)?g_beechat_rooms[contactBareJid]:0, @@ -1368,7 +1368,7 @@ BeeChat.UI = { scrollBoxElmToShow = BeeChat.UI.ScrollBoxes.getScrollBoxElm(key); } - var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + key + ']'); + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid="' + key + '"]'); chatBoxContentElm.append(unescape(json.chats[key].html_content)); chatBoxContentElm.attr({scrollTop: chatBoxContentElm.attr('scrollHeight')}); @@ -1571,7 +1571,7 @@ BeeChat.UI.ContactsList = { if (typeof onlineRosterItems[key] != 'object') continue; - var contactElm = contactsListElm.find('li').filter('[bareJid=' + key + ']'); + var contactElm = contactsListElm.find('li').filter('[bareJid="' + key + '"]'); if (contactElm.length == 0) { contactElm = $('
      • ') @@ -1796,7 +1796,7 @@ BeeChat.UI.ScrollBoxes = { add: function(contactBareJid, isroom) { var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); - var scrollBoxElm = scrollBoxesElm.find('ul').children().filter('[bareJid=' + contactBareJid + ']'); + var scrollBoxElm = scrollBoxesElm.find('ul').children().filter('[bareJid="' + contactBareJid + '"]'); if (scrollBoxElm.length == 0) { var availClass = null; @@ -1921,7 +1921,7 @@ BeeChat.UI.ScrollBoxes = { */ getScrollBoxElm: function(contactBareJid) { - return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().filter('[bareJid=' + contactBareJid + ']'); + return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES).find('ul').children().filter('[bareJid="' + contactBareJid + '"]'); } }; @@ -1941,7 +1941,7 @@ BeeChat.UI.ChatBoxes = { { var chatBoxes = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES); - if ($(chatBoxes).children().filter('[bareJid=' + contactBareJid + ']').length == 0) { + if ($(chatBoxes).children().filter('[bareJid="' + contactBareJid + '"]').length == 0) { var chatBox = $('
        ') .attr('class', isroom ? BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN : BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN) .attr('bareJid', contactBareJid) @@ -2024,8 +2024,8 @@ BeeChat.UI.ChatBoxes = { takeStand: function(contactBareJid) { var chatBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children(); - var chatBoxElm = chatBoxesElm.filter('[bareJid=' + contactBareJid + ']'); - var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + var chatBoxElm = chatBoxesElm.filter('[bareJid="' + contactBareJid + '"]'); + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid="' + contactBareJid + '"]'); var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); var scrollBoxElm = BeeChat.UI.ScrollBoxes.getScrollBoxElm(contactBareJid); @@ -2108,7 +2108,7 @@ BeeChat.UI.ChatBoxes = { chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); } - //var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + //var chatBoxContentElm = chatBoxElm.children().filter('[bareJid="' + contactBareJid + '"]'); var roster = chatBoxElm.find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); if (availability == 'unavailable') { @@ -2141,7 +2141,7 @@ BeeChat.UI.ChatBoxes = { chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); } - var chatBoxContentElm = chatBoxElm.children().filter('[bareJid=' + contactBareJid + ']'); + var chatBoxContentElm = chatBoxElm.children().filter('[bareJid="' + contactBareJid + '"]'); chatBoxContentElm.find('p').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.STATE + ']').remove(); @@ -2185,7 +2185,7 @@ BeeChat.UI.ChatBoxes = { */ updateChatState: function(contactBareJid, msg) { - var chatBoxContentElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[bareJid=' + contactBareJid + ']'); + var chatBoxContentElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid).children().filter('[bareJid="' + contactBareJid + '"]'); $(msg).children().each(function() { if (this.tagName == BeeChat.Message.ChatStates.COMPOSING) { @@ -2232,7 +2232,7 @@ BeeChat.UI.ChatBoxes = { */ getChatBoxElm: function(contactBareJid) { - return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().filter('[bareJid=' + contactBareJid + ']'); + return $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES).children().filter('[bareJid="' + contactBareJid + '"]'); } }; -- cgit v1.2.3 From b460e82dc1d6a87b93d27cf2ae6aa7bb71ca574e Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 05:06:19 +0000 Subject: removing groups functionality. --- start.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/start.php b/start.php index b6cbc52fe..125a2ddcf 100644 --- a/start.php +++ b/start.php @@ -61,8 +61,8 @@ $actions_path = $pluginspath . 'beechat/actions/'; - elgg_register_action('beechat/join_groupchat', $actions_path . 'join_groupchat.php'); - elgg_register_action('beechat/leave_groupchat', $actions_path . 'leave_groupchat.php'); + //elgg_register_action('beechat/join_groupchat', $actions_path . 'join_groupchat.php'); + //elgg_register_action('beechat/leave_groupchat', $actions_path . 'leave_groupchat.php'); elgg_register_action('beechat/get_statuses', $actions_path . 'get_statuses.php'); elgg_register_action('beechat/get_icons', $actions_path . 'get_icons.php'); elgg_register_action('beechat/get_details', $actions_path . 'get_details.php'); @@ -104,15 +104,15 @@ elgg_extend_view('page/elements/foot', 'beechat/beechat'); $domain = elgg_get_plugin_setting("domain", "beechat"); - $group_domain = elgg_get_plugin_setting("groupdomain", "beechat"); - $dbname = elgg_get_plugin_setting("dbname", "beechat"); + //$group_domain = elgg_get_plugin_setting("groupdomain", "beechat"); + /*$dbname = elgg_get_plugin_setting("dbname", "beechat"); $dbhost = elgg_get_plugin_setting("dbhost", "beechat"); $dbuser = elgg_get_plugin_setting("dbuser", "beechat"); - $dbpassword = elgg_get_plugin_setting("dbpassword", "beechat"); + $dbpassword = elgg_get_plugin_setting("dbpassword", "beechat");*/ global $CONFIG; $CONFIG->chatsettings['domain'] = $domain; - $CONFIG->chatsettings['groupdomain'] = $group_domain; + //$CONFIG->chatsettings['groupdomain'] = $group_domain; register_notification_handler('xmpp', 'beechat_notifications'); // register_plugin_hook('notify:entity:message','object','beechat_notifications_msg'); @@ -167,10 +167,10 @@ } elgg_load_library('elgg:beechat'); $to = ejabberd_getjid($user, true); - #xmlrpc_set_type(&$body, "base64"); - $param = array("body"=>$body, - "from"=>$from, - "to"=>$to); + //xmlrpc_set_type(&$body, "base64"); + $param = array("body" => $body, + "from" => $from, + "to" => $to); ejabberd_xmlrpc_command('send_html_message', $param); } -- cgit v1.2.3 From 05a44a5ab3dc25a35499f7e30b1df233751ded4a Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 05:06:39 +0000 Subject: removing group options. --- views/default/settings/beechat/edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/default/settings/beechat/edit.php b/views/default/settings/beechat/edit.php index 8f82834db..24dcd4e25 100755 --- a/views/default/settings/beechat/edit.php +++ b/views/default/settings/beechat/edit.php @@ -4,7 +4,7 @@ * @package Barters **/ $domain = get_plugin_setting("domain", "beechat"); - $group_domain = get_plugin_setting("groupdomain", "beechat"); + //$group_domain = get_plugin_setting("groupdomain", "beechat"); $xmlrpc_ip = get_plugin_setting("xmlrpcip", "beechat"); $dbname = get_plugin_setting("dbname", "beechat"); $dbhost = get_plugin_setting("dbhost", "beechat"); -- cgit v1.2.3 From 1aae8ffc67fc9c0fa55d79495d346f298eba345e Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 05:07:05 +0000 Subject: add migration script (for first time users of beechat). --- migrate.php | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 migrate.php diff --git a/migrate.php b/migrate.php new file mode 100644 index 000000000..20bee7973 --- /dev/null +++ b/migrate.php @@ -0,0 +1,88 @@ +dbname.';host='.$CONFIG->dbhost; +$dsn_ejabberd = 'mysql:dbname='.$dbname.';host='.$dbhost; + +$dbprefix = $CONFIG->dbprefix; + +$user = $dbuser; +$password = $dbpassword; + +$relationship_type = 'friend'; + +$counter = 0; + +try { + $dbh_elgg = new PDO($dsn_elgg, $CONFIG->dbuser, $CONFIG->dbpass); + + $sql = 'SELECT guid, name, username FROM '.$dbprefix.'users_entity'; + $sth = $dbh_elgg->prepare($sql); + $sth->execute(); + + $users = array(); + while ($row = $sth->fetch(PDO::FETCH_ASSOC)) + $users[$row['guid']] = $row; + + $sql = 'SELECT guid_one, guid_two FROM '.$dbprefix.'entity_relationships '; + $sql .= 'WHERE relationship = ?;'; + $sth = $dbh_elgg->prepare($sql); + + $sth->bindParam(1, $relationship_type); + $sth->execute(); + + $dbh_ejabberd = new PDO($dsn_ejabberd, $user, $password); + $dbh_ejabberd->beginTransaction(); + + while ($row = $sth->fetch(PDO::FETCH_ASSOC)) { + $sql = 'INSERT INTO rosterusers (username, jid, nick, subscription, ask, server, type) VALUES (?, ?, ?, ?, ?, ?, ?);'; + $sth_ejabberd = $dbh_ejabberd->prepare($sql); + + + $username = $users[$row['guid_one']]['username']; + $jid = $users[$row['guid_two']]['username'] . '@' . $jabber_domain; + $nick = $users[$row['guid_two']]['name']; + $subscription = 'B'; + $ask = 'N'; + $server = 'N'; + $type = 'item'; + + $sth_ejabberd->execute(array($username, $jid, $nick, $subscription, $ask, $server, $type)); + + $counter += 1; + if ($counter % 1000 == 0) { + //error_log( $username . ' registered ' . $jid . ' as a friend in his roster.' . "\n"); + error_log("importing relations into jabber: $counter"); + } + } + + $dbh_ejabberd->commit(); + + $dbh_elgg = null; + $dbh_ejabberd = null; +} catch (PDOException $e) { + if ($dbh_ejabberd != null) + $dbh_ejabberd->rollBack(); + echo $e->getMessage(); +} +?> + + -- cgit v1.2.3 From 8ed0cede5e2422b49327d3e47333032b2b666735 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Wed, 24 Oct 2012 06:24:56 +0000 Subject: fix icons sometimes dissapearing and set correct pointer to profile. --- views/default/beechat/beechat.js.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/views/default/beechat/beechat.js.php b/views/default/beechat/beechat.js.php index 51dbbcc08..1dacb6306 100644 --- a/views/default/beechat/beechat.js.php +++ b/views/default/beechat/beechat.js.php @@ -631,11 +631,6 @@ BeeChat.Core.Roster = function() _items[key].icon_small = icons[key].small; _items[key].icon_tiny = icons[key].tiny; } - - /* if (_items[key]) { - _items[key].icon_small = icons[key].small; - _items[key].icon_tiny = icons[key].tiny; - }*/ } } } @@ -912,7 +907,7 @@ BeeChat.UI = { Resources: { Paths: { ICONS: 'url; ?>mod/beechat/graphics/icons/', - MEMBER_PROFILE: 'pg/profile/' + MEMBER_PROFILE: 'profile/' }, Sounds: { @@ -1300,8 +1295,9 @@ BeeChat.UI = { var isroom = ($(this).attr('isroom') == 'true'); if (isroom) var roster = $(this).find('div').filter('[class=' + BeeChat.UI.Resources.StyleClasses.ChatBox.ROOMROSTER + ']'); + var html_content = $(this).children().filter('[bareJid="' + contactBareJid + '"]').html(); data.chats[contactBareJid] = { - 'html_content': escape($(this).children().filter('[bareJid="' + contactBareJid + '"]').html()), + 'html_content': escape(html_content), 'roster_content': isroom?escape(roster.html()):'', 'isroom': $(this).attr('isroom'), 'group_guid': (contactBareJid in g_beechat_rooms)?g_beechat_rooms[contactBareJid]:0, @@ -1344,7 +1340,7 @@ BeeChat.UI = { } g_beechat_user.getRoster().setItems(json.contacts); - self.loadRosterItemsIcons(); + self.loadRosterItemsIcons(false); self.loadRosterItemsStatuses(); g_beechat_roster_items = g_beechat_user.getRoster().getItems(); BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) @@ -1417,7 +1413,7 @@ BeeChat.UI = { /** Function: loadRosterItemsIcons * */ - loadRosterItemsIcons: function() + loadRosterItemsIcons: function(is_async) { var data = g_beechat_user.getRoster().getItemsUsernamesAsList(); var self = this; @@ -1425,7 +1421,7 @@ BeeChat.UI = { $.ajax({ type: 'POST', url: self.addActionTokens(''), - async: true, + async: is_async, cache: false, data: {'beechat_roster_items_usernames': data}, dataType: 'json', @@ -1472,7 +1468,7 @@ BeeChat.UI = { if (!g_beechat_user.isInitialized()) { //alert("load roster" + rosterItems.length); BeeChat.UI.loadRosterItemsStatuses(); - BeeChat.UI.loadRosterItemsIcons(); + BeeChat.UI.loadRosterItemsIcons(true); g_beechat_user.sendInitialPresence(); } }, @@ -1835,7 +1831,7 @@ BeeChat.UI.ScrollBoxes = { scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); if (!isroom) { BeeChat.UI.loadRosterItemsStatuses(); - BeeChat.UI.loadRosterItemsIcons(); + BeeChat.UI.loadRosterItemsIcons(true); } } else { scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); -- cgit v1.2.3 From add9814caac2fe102a951574fe5d8c40ec8b4237 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Mon, 9 Aug 2010 18:33:33 +0200 Subject: minor fix --- actions/save_state.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/actions/save_state.php b/actions/save_state.php index f3a818f72..42e429e4a 100644 --- a/actions/save_state.php +++ b/actions/save_state.php @@ -9,18 +9,21 @@ * @link http://beechannels.com/ */ - gatekeeper(); +// gatekeeper(); - global $SESSION; - - if (!empty($_POST['beechat_state'])) - { - $SESSION->offsetSet('beechat_state', get_input('beechat_state')); - } - elseif (!empty($_POST['beechat_conn'])) + if (isloggedin()) { - $SESSION->offsetSet('beechat_conn', get_input('beechat_conn')); - } - + + global $SESSION; + + if (!empty($_POST['beechat_state'])) + { + $SESSION->offsetSet('beechat_state', $_POST['beechat_state']); + } + elseif (!empty($_POST['beechat_conn'])) + { + $SESSION->offsetSet('beechat_conn', get_input('beechat_conn')); + } + } exit(); ?> -- cgit v1.2.3 From a6e20a9e85ac925de0ef59b4c69e5436f1661c5f Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Mon, 6 Sep 2010 17:27:31 +0200 Subject: fix error --- actions/get_statuses.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/get_statuses.php b/actions/get_statuses.php index c328e44b7..6f7620beb 100644 --- a/actions/get_statuses.php +++ b/actions/get_statuses.php @@ -16,7 +16,7 @@ { $iconSize = 'small'; $rosterItemsUsernames = explode(',', $usernames); - $userFriendsEntities = $_SESSION['user']->getFriends('', count($rosterItemsUsernames), 0); + $userFriendsEntities = $_SESSION['user']->getFriends('', 1000000000, 0); $res = array(); foreach ($rosterItemsUsernames as $value) -- cgit v1.2.3 From 71e189223b15882f836885623bd2255599c07469 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Thu, 25 Oct 2012 09:21:15 +0000 Subject: fix errors with jids with @, notices sometimes not showing and made things a bit more asynchronous. . --- views/default/beechat/beechat.js.php | 74 ++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/views/default/beechat/beechat.js.php b/views/default/beechat/beechat.js.php index 1dacb6306..09f4e8852 100644 --- a/views/default/beechat/beechat.js.php +++ b/views/default/beechat/beechat.js.php @@ -520,7 +520,7 @@ BeeChat.Core.User = function(jid) if ($(presence).attr('type') != 'unavailable' && $(presence).attr('type') != 'error') { if (chatBoxElm.length == 0) { - BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); + BeeChat.UI.ScrollBoxes.add(contactBareJid); } } return true; @@ -620,6 +620,15 @@ BeeChat.Core.Roster = function() { for (var key in items) { _items[key] = new BeeChat.Core.RosterItem(items[key]); + var contactBareJid = items[key].bareJid; + var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); + var status = items[key].status; + /*if (status != 'unavailable' && status != 'error') { + if (chatBoxElm.length == 0) { + BeeChat.UI.ScrollBoxes.add(contactBareJid); + } + }*/ + } } @@ -1341,7 +1350,7 @@ BeeChat.UI = { g_beechat_user.getRoster().setItems(json.contacts); self.loadRosterItemsIcons(false); - self.loadRosterItemsStatuses(); + self.loadRosterItemsStatuses(false); g_beechat_roster_items = g_beechat_user.getRoster().getItems(); BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) g_beechat_user.setInitialized(true); @@ -1349,7 +1358,7 @@ BeeChat.UI = { var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); var scrollBoxElmToShow = null; - // Load save chats + // Load saved chats for (var key in json.chats) { var isroom = (json.chats[key].isroom == 'true'); if (isroom) @@ -1358,6 +1367,7 @@ BeeChat.UI = { BeeChat.UI.ScrollBoxes.add(key); var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(key); + debugXMPP("load chat " + key); chatBoxElm.hide(); if (!json.chats[key].minimized) { @@ -1413,7 +1423,7 @@ BeeChat.UI = { /** Function: loadRosterItemsIcons * */ - loadRosterItemsIcons: function(is_async) + loadRosterItemsIcons: function(is_async, cb) { var data = g_beechat_user.getRoster().getItemsUsernamesAsList(); var self = this; @@ -1430,6 +1440,9 @@ BeeChat.UI = { g_beechat_roster_items = g_beechat_user.getRoster().getItems(); BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) + if (cb) { + cb(); + } } }); }, @@ -1437,7 +1450,7 @@ BeeChat.UI = { /** Function: loadRosterItemsStatuses * */ - loadRosterItemsStatuses: function() + loadRosterItemsStatuses: function(is_async, cb) { var data = g_beechat_user.getRoster().getItemsUsernamesAsList(); //alert(data) @@ -1445,7 +1458,7 @@ BeeChat.UI = { $.ajax({ type: 'POST', url: self.addActionTokens(''), - async: true, + async: true, // force cache: false, data: {'beechat_roster_items_usernames': data}, dataType: 'json', @@ -1453,6 +1466,9 @@ BeeChat.UI = { g_beechat_user.getRoster().setStatuses(json); g_beechat_roster_items = g_beechat_user.getRoster().getItems(); BeeChat.UI.ContactsList.update(g_beechat_user.getRoster().getOnlineItems()) + if (cb) { + cb(); + } } }); }, @@ -1467,9 +1483,11 @@ BeeChat.UI = { //alert("get roster"); if (!g_beechat_user.isInitialized()) { //alert("load roster" + rosterItems.length); - BeeChat.UI.loadRosterItemsStatuses(); - BeeChat.UI.loadRosterItemsIcons(true); - g_beechat_user.sendInitialPresence(); + BeeChat.UI.loadRosterItemsStatuses(true, + function() { BeeChat.UI.loadRosterItemsIcons(true, + function() {g_beechat_user.sendInitialPresence();}); }); + //BeeChat.UI.loadRosterItemsIcons(false); + //g_beechat_user.sendInitialPresence(); } }, @@ -1793,7 +1811,7 @@ BeeChat.UI.ScrollBoxes = { { var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); var scrollBoxElm = scrollBoxesElm.find('ul').children().filter('[bareJid="' + contactBareJid + '"]'); - + debugXMPP("add " + contactBareJid + " " + scrollBoxElm.length); if (scrollBoxElm.length == 0) { var availClass = null; var pres = null; @@ -1822,7 +1840,9 @@ BeeChat.UI.ScrollBoxes = { var scrollBoxesElm = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_SCROLLBOXES); BeeChat.UI.ChatBoxes.remove($(this).parent().attr('bareJid')); + BeeChat.UI.UnreadCountBox.remove($(this).parent().attr('bareJid')); scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(BeeChat.UI.ScrollBoxes.getSelectedScrollBoxElm())); + BeeChat.UI.saveState(); })); scrollBoxesElm.find('ul').append(scrollBoxElm); @@ -1830,8 +1850,7 @@ BeeChat.UI.ScrollBoxes = { if (arguments.length == 3 && arguments[2]) scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); if (!isroom) { - BeeChat.UI.loadRosterItemsStatuses(); - BeeChat.UI.loadRosterItemsIcons(true); + BeeChat.UI.loadRosterItemsStatuses(true, function () { BeeChat.UI.loadRosterItemsIcons(true); }); } } else { scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); @@ -1938,6 +1957,7 @@ BeeChat.UI.ChatBoxes = { var chatBoxes = $('#' + BeeChat.UI.Resources.Elements.ID_DIV_CHATBOXES); if ($(chatBoxes).children().filter('[bareJid="' + contactBareJid + '"]').length == 0) { + debugXMPP("create chatbox " + contactBareJid); var chatBox = $('
        ') .attr('class', isroom ? BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN : BeeChat.UI.Resources.StyleClasses.ChatBox.MAIN) .attr('bareJid', contactBareJid) @@ -1965,7 +1985,7 @@ BeeChat.UI.ChatBoxes = { .bind('click', function() { if (isroom) g_beechat_user.leaveRoom(contactBareJid); - BeeChat.UI.ChatBoxes.remove($(this).parent().parent().parent().attr('bareJid')); + BeeChat.UI.ChatBoxes.remove(contactBareJid); })) .append($('') .attr('class', BeeChat.UI.Resources.StyleClasses.ChatBox.CONTROL) @@ -1993,7 +2013,7 @@ BeeChat.UI.ChatBoxes = { .bind('keypress', isroom?BeeChat.UI.ChatBoxes.onRoomTypingMessage:BeeChat.UI.ChatBoxes.onTypingMessage) .bind('keyup', function(e) { if ((e.keyCode ? e.keyCode : e.which) == 13) - $(this).val(''); + $(this).attr('value', ''); })); var chatBoxBottom = $('
        ') @@ -2012,6 +2032,11 @@ BeeChat.UI.ChatBoxes = { else chatBox.append(chatBoxTop).append(chatBoxSubTop).append(chatBoxContent).append(chatBoxInput).append(chatBoxBottom).appendTo(chatBoxes); } + else { + /*debugXMPP("show chatbox " + contactBareJid); + var chatBox = $(chatBoxes).children().filter('[bareJid="' + contactBareJid + '"]'); + chatBox.show();*/ + } }, /** Function: takeStand @@ -2030,7 +2055,7 @@ BeeChat.UI.ChatBoxes = { chatBoxElm.hide(); } else { // Hide all other chatboxes - $.each(chatBoxesElm.filter('[bareJid!=' + contactBareJid + ']'), function() { + $.each(chatBoxesElm.filter('[bareJid!="' + contactBareJid + '"]'), function() { BeeChat.UI.ScrollBoxes.unselect($(this).attr('bareJid')); $(this).hide(); }); @@ -2100,7 +2125,8 @@ BeeChat.UI.ChatBoxes = { var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); if (chatBoxElm.length == 0) { - BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); + BeeChat.UI.ScrollBoxes.add(contactBareJid); + //BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); } @@ -2128,12 +2154,18 @@ BeeChat.UI.ChatBoxes = { update: function(contactBareJid, fromName, msg, isroom) { var chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); - + debugXMPP(contactBareJid + " " + msg + " " + chatBoxElm.length); if (chatBoxElm.length == 0) { - if (isroom) + if (isroom) { BeeChat.UI.ScrollBoxes.addRoom(contactBareJid); - else - BeeChat.UI.ScrollBoxes.add(contactBareJid); + BeeChat.UI.ChatBoxes.show(contactBareJid); + BeeChat.UI.ChatBoxes.takeStand(contactBareJid); + } + else { + BeeChat.UI.ScrollBoxes.add(contactBareJid,false,true); + // BeeChat.UI.ChatBoxes.show(contactBareJid); + BeeChat.UI.ChatBoxes.takeStand(contactBareJid); + } chatBoxElm = BeeChat.UI.ChatBoxes.getChatBoxElm(contactBareJid); } @@ -2166,7 +2198,9 @@ BeeChat.UI.ChatBoxes = { scrollBoxesElm.trigger('goto', scrollBoxesElm.find('ul').children().index(scrollBoxElm)); } + debugXMPP("about to update number!"); if (chatBoxElm.is(':hidden')) { + debugXMPP("update number!"); BeeChat.UI.UnreadCountBox.update(contactBareJid); // if (BeeChat.UI.HAS_FOCUS) // document.getElementById(BeeChat.UI.Resources.Sounds.NEW_MESSAGE).Play(); -- cgit v1.2.3 From bb3b8d432ee83764ab61b30a9f0c7d18f10f9a46 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Oct 2012 09:22:18 +0000 Subject: add the readme from beechat. --- README | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 000000000..5ff3f8467 --- /dev/null +++ b/README @@ -0,0 +1,23 @@ +Beechat the first XMPP chat for Elgg +==================================== + +Beechat is a facebook like chat for elgg using the XMPP protocol. It requires the XMPP serveur ejabberd. + +Installation +------------ + +French Documentation + +http://github.com/beechannels/beechat/wikis/guide-dinstallation + +English Documentation + +http://github.com/beechannels/beechat/wikis/setup-guide + +Feedback +-------- + +We are relying on the [GitHub issues tracker][issues] linked from above for +feedback. File bugs or other issues [here][issues]. + +[issues]: http://github.com/beechannels/beechat/issues -- cgit v1.2.3 From ca9e77c5dc802efb452a22e95441f8c9f0c6892d Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Thu, 25 Oct 2012 09:22:58 +0000 Subject: add group importing script. --- migrategroups.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 migrategroups.php diff --git a/migrategroups.php b/migrategroups.php new file mode 100644 index 000000000..4e3ef3f2b --- /dev/null +++ b/migrategroups.php @@ -0,0 +1,18 @@ +'group','limit'=>0)); +elgg_set_ignore_access(true); +foreach($groups as $group) { + echo "migrating " . $group->name . "
        "; + ejabberd_create_group($group); +} +echo "done!"; +elgg_set_ignore_access(false); + +?> -- cgit v1.2.3 From 6e6f43a5b7b89c5f1091158bbb19fec20eb1c075 Mon Sep 17 00:00:00 2001 From: Pablo Martin Date: Tue, 30 Oct 2012 12:45:58 +0000 Subject: add disablechat url. --- disablechat.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 disablechat.php diff --git a/disablechat.php b/disablechat.php new file mode 100644 index 000000000..38a440cf2 --- /dev/null +++ b/disablechat.php @@ -0,0 +1,8 @@ +chatenabled = false; + system_message(elgg_echo("beechat:disabled")); + } + forward($_SERVER['HTTP_REFERER']); +?> -- cgit v1.2.3 From 98f73419a691c2664e51aad4b28ed477feaba8ea Mon Sep 17 00:00:00 2001 From: hellekin Date: Sun, 4 Nov 2012 23:04:48 -0300 Subject: Fix deprecation warnings --- start.php | 2 +- views/default/beechat/beechat.userjs.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/start.php b/start.php index 125a2ddcf..045887744 100644 --- a/start.php +++ b/start.php @@ -150,7 +150,7 @@ } } } - else*/if (get_context() == 'settings' && isloggedin()) { + else*/if (elgg_get_context() == 'settings' && elgg_is_logged_in()) { if (get_loggedin_user()->chatenabled) { add_submenu_item(elgg_echo('beechat:disablechat'), $CONFIG->wwwroot . "mod/beechat/disablechat.php"); } diff --git a/views/default/beechat/beechat.userjs.php b/views/default/beechat/beechat.userjs.php index f147d8b8e..1a4d1565c 100644 --- a/views/default/beechat/beechat.userjs.php +++ b/views/default/beechat/beechat.userjs.php @@ -38,8 +38,8 @@ BeeChat.UI.Resources.Strings = { } g_user_rooms = new Array(); 'groupchat', 'relationship_guid' => $user->guid, 'inverse_relationship' => false, -- cgit v1.2.3 From 22479294531da254c0b9060afd5e2992c6db91e1 Mon Sep 17 00:00:00 2001 From: hellekin Date: Sat, 2 Mar 2013 13:53:41 -0300 Subject: Correct typos (thanks to d_urruti) --- views/default/beechat/screen.css.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/default/beechat/screen.css.php b/views/default/beechat/screen.css.php index 05336ef8c..930e60089 100644 --- a/views/default/beechat/screen.css.php +++ b/views/default/beechat/screen.css.php @@ -5,7 +5,7 @@ ?> /** * Beechat - * + * * @package beechat * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 * @author Beechannels @@ -147,7 +147,7 @@ div#beechat_contacts_controls span#beechat_contacts_control_minimize { padding: 2px; font-size: 1.6em; - font-weigth: bold; + font-weight: bold; text-align: center; } span#beechat_contacts_button { @@ -527,7 +527,7 @@ div.beechat_chatbox_top .beechat_chatbox_top_icon { left: 4px; z-index: 2; - widht: 50px; + width: 50px; height: 50px; } div.beechat_chatbox_top .beechat_label { -- cgit v1.2.3 From 001e536e85c23caf74dd3b88cec1c2984320acb3 Mon Sep 17 00:00:00 2001 From: Sem Date: Thu, 5 Sep 2013 17:45:55 +0200 Subject: Upgraded depracated function calls. --- actions/get_icons.php | 2 +- actions/join_groupchat.php | 2 +- actions/leave_groupchat.php | 2 +- actions/save_state.php | 2 +- disablechat.php | 4 ++-- enablechat.php | 4 ++-- lib/beechat.php | 30 ++++++++++++++--------------- start.php | 33 +++++++++++++++++--------------- views/default/beechat/beechat.php | 2 +- views/default/beechat/beechat.userjs.php | 2 +- views/default/settings/beechat/edit.php | 14 +++++++------- 11 files changed, 50 insertions(+), 47 deletions(-) diff --git a/actions/get_icons.php b/actions/get_icons.php index 88e7bdd3b..33d447e2e 100644 --- a/actions/get_icons.php +++ b/actions/get_icons.php @@ -30,7 +30,7 @@ $jid_host = $splitjid[1]; foreach ($userFriendsEntities as $friend) { - if ((strtolower($friend->username) == strtolower($jid_name) && $jid_host == get_plugin_setting("domain", "beechat"))) + if ((strtolower($friend->username) == strtolower($jid_name) && $jid_host == elgg_get_plugin_setting("domain", "beechat"))) { $res[$value] = array('small' => $friend->getIcon('small'), 'tiny' => $friend->getIcon('tiny')); $found = true; diff --git a/actions/join_groupchat.php b/actions/join_groupchat.php index 0d2d75c61..c694d7957 100644 --- a/actions/join_groupchat.php +++ b/actions/join_groupchat.php @@ -1,6 +1,6 @@ chatenabled = false; + if (elgg_is_logged_in()) { + elgg_get_logged_in_user_entity()->chatenabled = false; system_message(elgg_echo("beechat:disabled")); } forward($_SERVER['HTTP_REFERER']); diff --git a/enablechat.php b/enablechat.php index f3449520c..5d3de7e2a 100644 --- a/enablechat.php +++ b/enablechat.php @@ -1,7 +1,7 @@ chatenabled = true; + if (elgg_is_logged_in()) { + elgg_get_logged_in_user_entity()->chatenabled = true; system_message(elgg_echo("beechat:enabled")); } forward($_SERVER['HTTP_REFERER']); diff --git a/lib/beechat.php b/lib/beechat.php index a7db64052..bf002d648 100644 --- a/lib/beechat.php +++ b/lib/beechat.php @@ -35,7 +35,7 @@ function ejabberd_xmlrpc_send($request) 'content' => $request ))); - $file = file_get_contents("http://".get_plugin_setting("xmlrpcip", "beechat").":4560/RPC2", false, $context); + $file = file_get_contents("http://".elgg_get_plugin_setting("xmlrpcip", "beechat").":4560/RPC2", false, $context); $response = xmlrpc_decode($file); if (is_array($response) && xmlrpc_is_fault($response)) { @@ -73,8 +73,8 @@ class EjabberdMucRoom { } function setOption($name, $value) { $group = $this->group; - $param=array("name"=>friendly_title($group->name), - "service"=>get_plugin_setting("groupdomain", "beechat"), + $param=array("name"=>elgg_get_friendly_title($group->name), + "service"=>elgg_get_plugin_setting("groupdomain", "beechat"), "option"=>$name, "value"=>$value); ejabberd_xmlrpc_command('muc_room_change_option', $param); @@ -93,9 +93,9 @@ class EjabberdMucRoom { function setAffiliation($member, $affiliation) { $group = $this->group; - $param = array("name" => friendly_title($group->name), - "service" => get_plugin_setting("groupdomain", "beechat"), - "jid" => xmpp_escape($member->username) . '@' . get_plugin_setting("domain", "beechat"), + $param = array("name" => elgg_get_friendly_title($group->name), + "service" => elgg_get_plugin_setting("groupdomain", "beechat"), + "jid" => xmpp_escape($member->username) . '@' . elgg_get_plugin_setting("domain", "beechat"), "affiliation" => $affiliation); ejabberd_xmlrpc_command('muc_room_set_affiliation', $param); //echo "set affiliation ".$member->username."
        "; @@ -106,9 +106,9 @@ function ejabberd_create_group($group) { //echo "creating " . $group->name . "
        "; // create room - $param=array("name"=>friendly_title($group->name), - "service"=>get_plugin_setting("groupdomain", "beechat"), - "server"=>get_plugin_setting("domain", "beechat")); + $param=array("name"=>elgg_get_friendly_title($group->name), + "service"=>elgg_get_plugin_setting("groupdomain", "beechat"), + "server"=>elgg_get_plugin_setting("domain", "beechat")); ejabberd_xmlrpc_command('create_muc_room', $param); // persistency @@ -140,9 +140,9 @@ function ejabberd_create_group($group) function ejabberd_destroy_group($group) { - $param=array("name"=>friendly_title($group->name), - "service"=>get_plugin_setting("groupdomain", "beechat"), - "server"=>get_plugin_setting("domain", "beechat")); + $param=array("name"=>elgg_get_friendly_title($group->name), + "service"=>elgg_get_plugin_setting("groupdomain", "beechat"), + "server"=>elgg_get_plugin_setting("domain", "beechat")); ejabberd_xmlrpc_command('delete_muc_room', $param); } @@ -172,7 +172,7 @@ function ejabberd_getjid($user, $do_external=false) } else { $username = $user->username; - $host = get_plugin_setting("domain", "beechat"); + $host = elgg_get_plugin_setting("domain", "beechat"); } return xmpp_escape($username) . '@' . $host; } @@ -184,8 +184,8 @@ function ejabberd_friend_command($user, $friend, $command, $is_out) // $user add error_log(" * beechat: friend is foreign!"); return; } - $param = array("user" => friendly_title($friend->username), - "server" => get_plugin_setting("domain", "beechat"), + $param = array("user" => elgg_get_friendly_title($friend->username), + "server" => elgg_get_plugin_setting("domain", "beechat"), "from" => ejabberd_getjid($user), "subs" => $command); if ($is_out) { diff --git a/start.php b/start.php index 045887744..4e4e4bb40 100644 --- a/start.php +++ b/start.php @@ -82,7 +82,7 @@ // new friend sync elgg_register_event_handler('delete', 'friend', array('BeechatSync', 'onFriendDelete')); - elgg_register_event_handler('create', 'friendrequest', array('BeechatSync', 'onFriendCreate')); + //elgg_register_event_handler('create', 'friendrequest', array('BeechatSync', 'onFriendCreate')); elgg_register_event_handler('delete', 'friendrequest', array('BeechatSync', 'onFriendDelete')); @@ -138,30 +138,34 @@ function beechat_pagesetup() { global $CONFIG; - /*if (get_context() == 'group_profile' && isloggedin()) { - if (get_plugin_setting("groupdomain", "beechat")) { - $user = get_loggedin_user(); - $group = page_owner_entity(); + /*if (elgg_get_context() == 'group_profile' && elgg_is_logged_in()) { + if (elgg_get_plugin_setting("groupdomain", "beechat")) { + $user = elgg_get_logged_in_user_entity(); + $group = elgg_get_page_owner_entity(); if (!$group || !($group instanceof ElggGroup)) return; - if ($user->chatenabled && get_plugin_setting("groupdomain", "beechat")) { - if ($group->isPublicMembership() || $group->isMember($user)) - add_submenu_item(elgg_echo('beechat:chatroom'), "javascript:g_beechat_user.joinRoom('".beechat_friendly_title($group->name)."@".$CONFIG->chatsettings['groupdomain']."', '".$group->guid."')"); + if ($user->chatenabled && elgg_get_plugin_setting("groupdomain", "beechat")) { + if ($group->isPublicMembership() || $group->isMember($user)) { + $item = new ElggMenuItem('chatroom', elgg_echo('beechat:chatroom'), "javascript:g_beechat_user.joinRoom('".beechat_friendly_title($group->name)."@".$CONFIG->chatsettings['groupdomain']."', '".$group->guid."')"); + elgg_register_menu_item('page', 'item'); + } } } } else*/if (elgg_get_context() == 'settings' && elgg_is_logged_in()) { - if (get_loggedin_user()->chatenabled) { - add_submenu_item(elgg_echo('beechat:disablechat'), $CONFIG->wwwroot . "mod/beechat/disablechat.php"); - } - else - add_submenu_item(elgg_echo('beechat:enablechat'), $CONFIG->wwwroot . "mod/beechat/enablechat.php"); + $is_enabled = elgg_get_logged_in_user_entity()->chatenabled; + $action = $is_enabled ? 'disable' : 'enable'; + elgg_register_menu_item('page', array( + 'name' => 'beechat', + 'text'=> elgg_echo("beechat:{$action}chat"), + 'href' => $CONFIG->wwwroot . "mod/beechat/{$action}chat.php", + )); } } function ejabberd_send_chat($user, $body) { // $user adds $friend - $from = 'notify@'.get_plugin_setting("domain", "beechat").'/net'; + $from = 'notify@'.elgg_get_plugin_setting("domain", "beechat").'/net'; if ($user->alias) { } @@ -178,4 +182,3 @@ elgg_register_event_handler('init', 'system', 'beechat_init'); -?> diff --git a/views/default/beechat/beechat.php b/views/default/beechat/beechat.php index d1e9e17be..397d35f74 100644 --- a/views/default/beechat/beechat.php +++ b/views/default/beechat/beechat.php @@ -9,7 +9,7 @@ * @link http://beechannels.com/ */ -if (isloggedin() && get_loggedin_user()->chatenabled && elgg_get_context() != 'admin') { +if (elgg_is_logged_in() && elgg_get_logged_in_user_entity()->chatenabled && elgg_get_context() != 'admin') { ?>
        diff --git a/views/default/beechat/beechat.userjs.php b/views/default/beechat/beechat.userjs.php index 1a4d1565c..ed59b683f 100644 --- a/views/default/beechat/beechat.userjs.php +++ b/views/default/beechat/beechat.userjs.php @@ -46,7 +46,7 @@ if (elgg_is_logged_in()) { 'limit' => 0)); if (!empty($chatrooms)) { foreach($chatrooms as $chatroom) { - echo "g_user_rooms.push(['".beechat_friendly_title($chatroom->name)."@".get_plugin_setting("groupdomain", "beechat")."', '".$chatroom->guid."']);"; + echo "g_user_rooms.push(['".beechat_friendly_title($chatroom->name)."@".elgg_get_plugin_setting("groupdomain", "beechat")."', '".$chatroom->guid."']);"; } } } diff --git a/views/default/settings/beechat/edit.php b/views/default/settings/beechat/edit.php index 24dcd4e25..ec4ab08de 100755 --- a/views/default/settings/beechat/edit.php +++ b/views/default/settings/beechat/edit.php @@ -3,13 +3,13 @@ * Barter Plugin * @package Barters **/ - $domain = get_plugin_setting("domain", "beechat"); - //$group_domain = get_plugin_setting("groupdomain", "beechat"); - $xmlrpc_ip = get_plugin_setting("xmlrpcip", "beechat"); - $dbname = get_plugin_setting("dbname", "beechat"); - $dbhost = get_plugin_setting("dbhost", "beechat"); - $dbuser = get_plugin_setting("dbuser", "beechat"); - $dbpassword = get_plugin_setting("dbpassword", "beechat"); + $domain = elgg_get_plugin_setting("domain", "beechat"); + //$group_domain = elgg_get_plugin_setting("groupdomain", "beechat"); + $xmlrpc_ip = elgg_get_plugin_setting("xmlrpcip", "beechat"); + $dbname = elgg_get_plugin_setting("dbname", "beechat"); + $dbhost = elgg_get_plugin_setting("dbhost", "beechat"); + $dbuser = elgg_get_plugin_setting("dbuser", "beechat"); + $dbpassword = elgg_get_plugin_setting("dbpassword", "beechat"); ?>

        -- cgit v1.2.3 From 5dabe4f29393e01181f0a39c8ba3301993c79717 Mon Sep 17 00:00:00 2001 From: Sem Date: Fri, 8 Nov 2013 05:59:31 +0100 Subject: Bumped version 1.8.0 --- manifest.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/manifest.xml b/manifest.xml index 8e880d305..ad948fdb4 100644 --- a/manifest.xml +++ b/manifest.xml @@ -2,15 +2,14 @@ Beechat Beechannels + Lorea dev - 1.8 + 1.8.0 widget - XMPP chat for elgg. - http://www.elgg.org - See COPYRIGHT.txt + XMPP chat for Elgg. + https://lorea.org + (C) Beechanels 2009, Lorea 2009-2013 GNU General Public License version 2 elgg_release 1.8 - false -- cgit v1.2.3