diff --git a/.project b/.project new file mode 100644 index 0000000..7518269 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Ajax IM 3.41 + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/CONTRIB b/CONTRIB new file mode 100644 index 0000000..7f22243 --- /dev/null +++ b/CONTRIB @@ -0,0 +1,65 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + ++---------------------------------------------------------------------+ +| Contributions | ++---------------------------------------------------------------------+ +|== Source Code ======================================================| +| | +| * Joshua Gross | +| Started the AjaxIM project. Created all releases up to 3.3 alone! | +| - Framework | +| - Everything not listed | +| | +| * Benjamin Hutchins | +| Joined the AjaxIM project at version 3.3 and helped give the | +| entire project a push. | +| - Auto away | +| - Buddy profiles | +| - Buddy icons | +| - Lingo replacement | +| - Context/RightClick menus | +| - Status changes in chats | +| - Update.php | +| - Various other contributions | +| | +| | +|== Language Packs ===================================================| +| | +| Contributor Language | +| ------------------------------------------------------------------- | +| * Hilton Perantunes Brazilian Portuguese | +| * JulesJ (http://www.julesj.nl/blog/) Dutch | +| * Léonard Beaud French | +| * YNStudios.com German | +| * Matteo Cisilino (http://www.sitonerd.com) Italian | +| * Mayu Shimizu (http://www.myudesign.com) Japanese | +| * Taekyuni (http://www.gaerae.com) Korean | +| * Behrouz Pooladrag (http://www.iflashlord.com) Persian (Farsi) | +| * Grigoriy Korolev Russian | +| * ??? Simplified Chinese | +| * Victor Ortega Spanish | +| * Meo Meo? Vietnamese | +| * Feyzullah Ceylan (http://www.gencsinsen.com) Turkish | +| * ??? Arabic | +| * ??? Bulgarian | +| * Pedro Morgado Portugal Portuguese | +| * Steven Yeh Traditional Chinese | +| | +| | +|== Libraries ========================================================| +| | +| Contributor Library | +| ------------------------------------------------------------------- | +| * Sam Stephenson Prototype | +| * Sébastien Gruhier Prototype Window Class | +| * Scott Schiller SoundManager2 | +| * Dan Webb Prototype DomReady | +| * Paul Johnston MD5 Algorithms | +| | ++---------------------------------------------------------------------+ diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..38697aa --- /dev/null +++ b/INSTALL @@ -0,0 +1,25 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +Installation +----------------------------------- +1. Configure SQL information in config-sample.php + +2. Rename config-sample.php to config.php + +3. Configure options in config.js (in the 'js' folder) + +4. Upload all files to your server. + +5. CHMOD buddyicons/ to 0777. + +6. Run install.php in your browser of choice and follow the instructions. + +7. Delete install.php and update.php! + +8. Done! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fc09182 --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +Copyright (c) 2009, Joshua Gross +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the Ajax IM nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..8cc4162 --- /dev/null +++ b/README @@ -0,0 +1,19 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +About +----------------------------------- +ajax im ("asynchronous javascript and xml instant messenger") is a browser-based instant messaging client. It uses the XMLHTTPRequest object in JavaScript to send and receive commands to and from the server. No refreshing of the page is ever needed for this "web application" to work, as everything is updated in real-time via JavaScript. + +In versions 2 and up, no XML is actually used (instead, it has been replaced with "JSON"), but for brand purposes, the name has been kept. It still uses the XMLHTTPRequest object, so the name does hold some validity. + +Credits +----------------------------------- +ajax im makes use of a number of Javascript libraries and functions to build its functionality. All such code is labeled and copyrighted to their creators. + +All other code is copyright (c) unwieldy studios / Joshua Gross diff --git a/README.md b/README.md index 2b193b2..62e9b7f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,60 @@ -AjaxIM341 -========= +# Ajax IM 3.41 -instant messaging framework v3.41 (PHP) +## What is Ajax IM 3.41? + +Ajax IM ("Asynchronous Javascript And Xml Instant Messenger") is a browser-based +instant messaging client. It uses the XMLHTTPRequest object in JavaScript to send +and receive commands to and from the server. No refreshing of the page is ever +needed for this "web application" to work, as everything is updated in real-time +via JavaScript. + +Ajax IM 3.41 is based on client-side JavaScript and PHP. Ajax IM 4.0 is a "from +the ground up" rewrite that uses client-side JavaScript and Node.js (server-side +JavaScript). Ajax IM 4.0 does not use PHP now. + +Ajax IM 3.41 is made available here because there is still interest in this older +code and it is the basis for some code forks (e.g. ajaximrpg). It is useful for +reference. + +## Installation + +1. Create a MySQL database + +2. Configure SQL information in config-sample.php + +3. Rename config-sample.php to config.php + +4. Configure options in config.js (in the 'js' folder) + +5. Upload all files to your server. + +6. CHMOD buddyicons/ to 0777. + +7. Run install.php in your browser of choice and follow the instructions. + +8. Delete install.php and update.php! + +9. Done! + +## License + +Copyright (c) 2009, Joshua Gross +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of the Ajax IM nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/UPDATES b/UPDATES new file mode 100644 index 0000000..25062c3 --- /dev/null +++ b/UPDATES @@ -0,0 +1,250 @@ +version 3.41 +------------------------- +- Buddy List + > Fixed buddy removal + +- General + > Other minor fixes + +version 3.4 +------------------------- +- General + > Fixed popup.php Include Path, Bold, Italic, and Underline errors (Issue #116, Issue #111, Issue #91). + > Added option to disable the register ability. + > Multiple releases (YUI Compression, Full Source). + +- Buddy List + > Blocked buddies are now blocked when they should be (Issue #112). + > Added buddy icons (Issue #92). + > Added context/right-click menus (Issue #12). + > Added buddy profiles (Issue #13). + +- Instant Messaging + > Added Lingo-Replacement feature, can be used with multiple languages (Issue #127). + +- Chat + > Buddy status changes are shown in chat window. + > Custom timestamps now used in chat as well. + +- Admin + > User search now lists users' emails. + > Created update.php to update your AjaxIM installation from version 3.3 to 3.4. + > Created test-uploads.php to allow you to test your server for the ability to upload files. + > Created php.ini.sample. If you need a php.ini, just rename this to php.ini. + +- Miscellaneous + > Added auto-away/auto-idle feature (Issue #124). + > Fixed use of &, <, and > symbols (Issue #101). + > Fixed use of new lines (Issue #118). + > Added Shift+Enter shortcut to add a newline. + > Various minor issues. + + +version 3.3 +------------------------- +- General + > No more PHP file for languages, all language information is stored in Javascript (Issues #40 & 61) + > Language files are loaded dynamically and can be switched by user before login (Issues #40 & 61) + > index.php is now index.html, as there is now no PHP in the index file + +- Buddy List + > Fixed issue regarding buddies and letter casing (Issue #38) + +- Instant Messaging + > Sounds fixed (Issue #42) + > Timestamp format is now fully configurable (Issue #16) + +- Chat + > Selecting/hovering over users in the chatlist fixed (Issue #81) + > Rooms can now be predefined for the "Join Room" chatlist (Issue #78) + +- Admin + > Added previously nonexistent "Make Admin" PHP function (Issue #24) + +- Miscellaneous + > Fixed error when "Sign On" button clicked a second time (Issue #3) + > Various minor issues (Issue #60) + > Page title is now modifiable via config.js (Issue #21) + + +version 3.22 +------------------------- +- Buddy List + > "Remove buddy" fixed + +- Chat + > Room list style issue fixed + +- Miscellaneous + > "Register" dialog title now changes to proper language + > Users can register and login with characters of any case (upper/lower) and it will automatically be fixed + +- Admin + > Fixed error involving alternate languages and the "Search Type" field + +version 3.21 +------------------------- +- Miscellaneous + > Missed a couple of strings for localization + > Fixed issue with installer on some hosts (e.g., GoDaddy) + > Login/Register/Forgot Pass no longer produce error in IE7 + +version 3.2 +------------------------- +- General + > MAJOR overhaul of the code -- everything (PHP and JS) is now object-oriented instead of procedural + > Many functions modified to make better use of the Prototype library + > Multiple language support (need translators!) + > PHP-based sessions implemented, so the username and password isn't sent on every request + > Many minor GUI changes + > Buttons no longer separate images; buttons are now boilerplate images + text + > Code commented more thoroughly + > Proper theming system -- themes are bundled into folders instead of all over the place + > New dark theme! + +- Instant Messaging + > Popout window now more stable + +- Buddy List + > Fixed issue with selecting another buddy after deleting one + > Buddylist database structure converted to be in a separate table + > Ability to block/unblock users + +- Chat + > Userlist added, now displays all users in a chatroom + > Room list added to the "join room" dialog + > System modified to fix potential bug of grabbing multiples of the same message from the database + +- Admin Panel + > Basic (beta) admin panel added. Supports searching for users, banning, kicking, and making/removing admin + +- Miscellaneous + > Fixed numerous small bugs + +version 3.1 +------------------------- +- General + > More user-friendly install script + > Database table names should no longer conflict with existing tables in a database + +- Instant Messaging + > Full unicode support! + +- Miscellaneous + > Fixed numerous small bugs + > Optimized script + > New JSON PHP class + > Minor memory leak fixed + +version 3.0 +------------------------- +- General + > Event-based system replaces sending buddylist to client each ping + > Windows can be focused and defocused + > Away message choices now have icons (for usability) + > Completely replaced login/registration/forgot password screen + > Toolbars have mouseover & mousedown images (for usability) + > No more modal windows (preventing you from doing anything else while they were open -- Add Buddy, etc) + +- User status + > "Friends only" mode so only users on the user's buddylist can contact the user + > "Invisible" mode lets the user look as if he/she is offline, but can still chat + +- Chatrooms + > Finally! Multi-user chatrooms. + > Joined chatrooms appear as groups on the buddylist, with the chatroom users in that group + +- Instant Messaging + > Font sizes! + > Font colors! + > Emoticon list + > Textbox is now multiline for better readability + +- Detachable windows + > Click the "detach" button (next to the "minimize" button) to popout the IM/chatroom to a separate window + +- Bug fixes + > Fixed auto-url linking + > IM length limit of 1500 characters set (prevents enormous MySQL inserts) + > No more login screen scrollbars issue in Safari + > Minimize button on buddylist moved to less awkard location + +version 2.53 +------------------------- +- Bug fixes + > Non-stop away message sending issue when IMing yourself + +version 2.52 +------------------------- +- Client/Server Communication + > Modified XMLHTTPRequest object creation, should improve speed in the browser + +version 2.51 +------------------------- +- Bug fixes + > Fixed minor scrolling and focus issues in IM windows + +version 2.5 +------------------------- +- Bug fixes + > Won't send blank IM messages + > Away message list no longer falls behind the buddylist + > Fixed the "Remove User/Group window not appearing" issue + > Links in IM sessions now open in a new window, instead of the same window + > Various other small bugs and code cleanup + +- Instant Messaging + > IM sounds: sounds when a message is received or sent + > Emoticons! + > Ability to change the text font + +version 2.02 +------------------------- +- Safari support! +- IM window focus issue fixed +- Dialog alert style bug fixed + +version 2.01 +------------------------- +- Opera support! +- Enter key works on login form now + +version 2.0 +------------------------- +- Better windowing system + > Less clunky + > Resizable windows + > Smoother movement + +- Updated buddy list + > Removed drag/drop (didn't work well) + > Groups! + > Mouse over instead of selection + > Window auto-resizes and moves when browser is resized + +- Chat + > History - shows past conversations with a person throughout the same session + > Timestamp simplified + +- General + > Removed "menu" + > Menu functions added to buddy list window + +- Javascript + > Replaced XML with JSON (bandwidth-saving/faster processing) + > Many, many bugfixes + > Configurable options added + > Fixed major issue of lagginess when IMing with many buddies + +- PHP + > Cleaned up source + > XML replaced with JSON (see Javascript section) + > Bugfixes + +- MySQL + > Buddylists stored using JSON (for groups) + + +version 1.0 +------------------------- +- Initial Release diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..3e8e1b4 --- /dev/null +++ b/admin.php @@ -0,0 +1,177 @@ +json = new JSON_obj(); + + $this->username = $_SESSION['username']; + $this->password = $_SESSION['password']; + + if($this->checkInfo($this->username, $this->password)) { + switch($call) { + case 'search': + print $this->search(strtolower($_POST['by']), $_POST['for']); + break; + + case 'kick': + print $this->kickUser($_POST['user']); + break; + + case 'ban': + print $this->banUser($_POST['user']); + break; + + case 'admin': + print $this->adminUser($_POST['user']); + break; + } + } + } + + /** + * Searches the user database by the method specified, for the keyword specified + * + * @return void + * @author Joshua Gross + **/ + function search($by, $for) { + if($by != 'email' && $by != 'username') return '[]'; + + $search_query = mysql_query('SELECT username, email, last_ip, last_ping, is_online, admin, banned FROM ' . SQL_PREFIX . 'users WHERE ' . $by . ' LIKE \'' . mysql_real_escape_string(str_replace('*', '%', $for)) . '\''); + + $found = array(); + while($row = mysql_fetch_assoc($search_query)) { + $found[] = array('username'=>$row['username'], 'email'=>$row['email'], 'lastKnownIP'=>$row['last_ip'], 'lastActive'=>$row['last_ping'], + 'currentStatus'=>$row['is_online'], 'banned'=>($row['banned']==1?'true':'false'), 'admin'=>($row['admin']==1?'true':'false')); + } + + return $this->json->encode($found); + } + + /** + * Kick the user from the server (log him off) + * + * @return "kicked" + * @author Joshua Gross + **/ + function kickUser($user) { + mysql_query('INSERT INTO ' . SQL_PREFIX . "messages (message, type, sender, recipient, stamp) VALUES ('kick', 'server', '{$this->username}', '" . mysql_real_escape_string($user) . "', '" . time() . "')"); + return 'kicked'; + } + + /** + * Ban & kick the user from the server + * + * @return "true" if banned, "false" if unbanned, "no_such_user" if the user doesn't exist + * @author Joshua Gross + **/ + function banUser($user) { + $ban_status = mysql_query('SELECT banned FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($user) . '\''); + if(mysql_num_rows($ban_status) == 0) + return 'no_such_user'; + + $is = mysql_fetch_assoc($ban_status); + if($is['banned'] == 1) { + mysql_query('UPDATE ' . SQL_PREFIX . 'users SET banned=0 WHERE username=\'' . mysql_real_escape_string($user) . '\''); + return 'false'; + } else { + $this->kickUser(mysql_real_escape_string($user)); + mysql_query('UPDATE ' . SQL_PREFIX . 'users SET banned=1 WHERE username=\'' . mysql_real_escape_string($user) . '\''); + return 'true'; + } + } + + /** + * Toggle on/off the admin status of a user. + * + * @return "on" if now an admin, "off" if not, "no_such_user" if the user doesn't exist + * @author Joshua Gross + **/ + function adminUser($user) { + $admin_status = mysql_query('SELECT admin FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($user) . '\''); + if(mysql_num_rows($admin_status) == 0) + return 'no_such_user'; + + $is = mysql_fetch_assoc($admin_status); + if($is['admin'] == 1) { + mysql_query('UPDATE ' . SQL_PREFIX . 'users SET admin=0 WHERE username=\'' . mysql_real_escape_string($user) . '\''); + return 'false'; + } else { + mysql_query('UPDATE ' . SQL_PREFIX . 'users SET admin=1 WHERE username=\'' . mysql_real_escape_string($user) . '\''); + return 'true'; + } + } + + /** + * Check to see if the supplied user information is valid, and if so return specific information. + * + * @return false if information is invalid, array of data otherwise + * @author Joshua Gross + **/ + function checkInfo($username, $password, $return=array()) { + if(count($return) > 0) + $columns = implode(',', $return); + else + $columns = 'id'; + + $username = mysql_real_escape_string($username); + $password = mysql_real_escape_string($password); + + $query = mysql_query('SELECT ' . $columns . ' FROM ' . SQL_PREFIX . 'users WHERE username=\'' . $username . '\' AND password=\'' . $password . '\' LIMIT 1'); + + if(mysql_num_rows($query) > 0) + return mysql_fetch_assoc($query); + else + return false; + } +} + +$admin = new Ajax_IM_Admin($_POST['call']); +?> +You don't want to be here...(this is not the admin panel!) \ No newline at end of file diff --git a/ajax_im.php b/ajax_im.php new file mode 100644 index 0000000..1356b6d --- /dev/null +++ b/ajax_im.php @@ -0,0 +1,893 @@ +json = new JSON_obj(); + + $this->username = $_SESSION['username']; + $this->password = $_SESSION['password']; + + // run the garbage collector (chance run) + $this->gc(); + + // figure out which action we need to execute, + // then execute it and print the output + switch($call) { + case 'login': + print $this->login(strtolower($_POST['username']), $_POST['password']); + break; + + case 'logout': + print $this->logout(); + break; + + case 'ping': + print $this->ping($_POST['away']); + break; + + case 'send': + print $this->send($_POST['recipient'], $_POST['message'], $_POST['font'], $_POST['fontsize'], $_POST['fontcolor'], $_POST['bold'], $_POST['italic'], $_POST['underline'], $_POST['chatroom']); + break; + + case 'addbuddy': + print $this->addBuddy(strtolower($_POST['username']), $_POST['group']); + break; + + case 'removebuddy': + print $this->removeBuddy($_POST['username']); + break; + + case 'blockbuddy': + print $this->blockBuddy($_POST['username'], ($_POST['status']?$_POST['status']:0)); + break; + + case 'removegroup': + print $this->removeGroup($_POST['group']); + break; + + case 'register': + print $this->register($_POST['username'], $_POST['password'], $_POST['email']); + break; + + case 'isuser': + print $this->isUser(strtolower($_POST['username'])); + break; + + case 'reset': + print $this->reset($_POST['email']); + break; + + case 'pwdchange': + print $this->passwordChange($_POST['password'], $_POST['newpwd']); + break; + + case 'joinroom': + print $this->joinRoom($_POST['room']); + break; + + case 'leaveroom': + print $this->leaveRoom($_POST['room']); + break; + + case 'roomlist': + print $this->roomList(); + break; + + case 'changeicon': + print $this->changeIcon(); + break; + + case 'changeprofile': + print $this->changeProfile($_POST['profile']); + break; + + case 'getprofile': + print $this->getProfile($_POST['user']); + break; + } + } + + /** + * Logs the user in and sets the session for the user. + * + * @return JSON object of buddies/blocked users if it usr was successfully logged in, error string otherwise + * @author Joshua Gross + **/ + function login($username, $password) { + $user = $this->checkInfo($username, $password, array('admin', 'banned')); + if(!$user) return 'invalid'; + if($user['banned'] == 1) return 'banned'; + + $_SESSION['username'] = $username; + $_SESSION['password'] = $password; + $_SESSION['admin'] = $user['admin']; + + $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=1, last_ip=\'' . $_SERVER['REMOTE_ADDR'] . '\' WHERE username=\'' . $username . '\''); + + $buddylist = $this->getBuddylist($username, false); + $blocklist = $this->getBlocklist($username); + + $this->userEvent($username, $buddylist, 'status', array('status'=>1)); + + $buddylist = $this->getBuddylistOnline($username); + if(count($buddylist) > 0) + $output['buddy'] = $this->json->encode($buddylist); + else + $output['buddy'] = array(); + + $output['blocked'] = $this->json->encode($blocklist); + + $output['admin'] = $user['admin']; + + return $this->json->encode($output); + } + + /** + * Logs the user out and destroys the session. + * + * @return String 'logged_out' + * @author Joshua Gross + **/ + function logout() { + if(!$this->checkInfo($this->username, $this->password)) return 'invalid'; + + $buddylist = $this->getBuddylist($this->username, false); + + $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); + + $in_chatrooms = mysql_query('SELECT room FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\''); + while($row = mysql_fetch_assoc($in_chatrooms)) { + $buddylist['users'] = $this->getChatlist($row['room']); + $this->userEvent($this->username, $buddylist, 'chat', array('action'=>'left', 'room'=>$row['room'])); + } + + $exit_rooms = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\''); + + $notify_buddies = $this->userEvent($this->username, $buddylist, 'status', array('status'=>0)); + + $_SESSION = array(); + if (isset($_COOKIE[session_name()])) setcookie(session_name(), '', time()-42000, '/'); + session_destroy(); + + return 'logged_out'; + } + + /** + * Checks the database for new messages and events. + * + * @return JSON object of new messages/events if any, otherwise nothing + * @author Joshua Gross + **/ + function ping($away) { + $user = $this->checkInfo($this->username, $this->password, array('is_online', 'last_ping')); + if(!$user) { + $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); + return 'not_logged_in'; + } + + $buddylist = $this->getBuddylist($this->username, false); + + $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=\'' . mysql_real_escape_string($away + 1) . '\', last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); + if($user['is_online'] != ($away + 1)) $this->userEvent($this->username, $buddylist, 'status', array('status'=>($away + 1))); + + foreach($buddylist as $group => $users) { + $user_count = count($users); + + $reverse_list = array(); + for($i = 0; $i < $user_count; $i++) + $reverse_list[$users[$i]] = $group; + } + + $query = mysql_query('SELECT id, message, type, sender, recipient FROM ' . SQL_PREFIX . 'messages WHERE (recipient=\'' . mysql_real_escape_string($this->username) . '\') GROUP BY sender, message, recipient ORDER BY id ASC'); + + $i=0; $j=0; + $to_delete = array(); + $output = array(); + while ($row = mysql_fetch_assoc($query)) { + if(strpos($row['type'], 'msg') !== false) { + if($row['sender'] != $this->username || $row['sender'] == $row['recipient']) { + $output['messages'][$i++] = array('message' => $row['message'], + 'sender' => $row['sender'], + 'recipient' => $row['recipient'], + 'chatroom' => ($row['type'] == 'chatmsg' ? 1 : 0)); + + $to_delete[] = $row['id']; + } + } else if($row['type'] == 'event') { + $output['events'][$j++] = array('event' => $row['message'], + 'sender' => $row['sender'], + 'recipient' => $row['recipient']); + + $event = explode(',', $row['message']); + if($event[0] == 'status') $output['events'][$j-1]['group'] = $reverse_list[$row['sender']]; + + $to_delete[] = $row['id']; + } else if($row['type'] == 'server') { + switch($row['message']) { + case 'kick': + $this->logout(); + print 'not_logged_in'; + break; + } + + $to_delete[] = $row['id']; + } + } + + if(count($to_delete) > 0) + $delete_new = mysql_query('DELETE FROM ' . SQL_PREFIX . 'messages WHERE id IN(' . implode(',', $to_delete) . ')'); + + return $this->json->encode($output); + } + + /** + * Sends a message to another user. + * + * @return String 'sent' if successful, error string otherwise + * @author Joshua Gross + **/ + function send($to, $message, $font, $font_size, $font_color, $bold, $italic, $underline, $is_chat) { + $to = mysql_real_escape_string($to); + + if(!$this->checkInfo($this->username, $this->password)) { + $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); + return 'not_logged_in'; + } + + $is_online = $this->isOnline($to); + if($is_online > 0 || $is_chat == 'true') { + if($is_online == 100) { + $check_friendship = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . strtolower($to) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\')'); + if(mysql_num_rows($check_friendship) == 0) + return 'not_online'; + } + + $check_blocked = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . strtolower($to) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\''); + if(mysql_num_rows($check_blocked) > 0) + return 'not_online'; + + $check_blocked = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . strtolower($to) . '\' AND user=\'' . mysql_real_escape_string($this->username) . '\''); + if(mysql_num_rows($check_blocked) > 0) + return 'not_online'; + + if(strlen(trim($message)) > 0 && strlen($message) <= 1500) { + $message = ('') . + ($bold == 'true' ? '' : '') . ($italic == 'true' ? '' : '') . ($underline == 'true' ? '' : '') . + $message . + ($bold == 'true' ? '' : '') . ($italic == 'true' ? '' : '') . ($underline == 'true' ? '' : '') . + (''); + + if($is_chat == 'true') { + $where_to_send = $this->getChatlist($to); + + $to_insert = ''; + foreach($where_to_send as $username) + if($username != $this->username) $to_insert .= "('" . mysql_real_escape_string($message) . "', 'chatmsg', '" . $to . '.' . mysql_real_escape_string($this->username) . "', '" . strtolower($username) . "', " . time() . "),"; + + $to_insert = substr($to_insert, 0, strlen($to_insert) - 1); + } else { + $to_insert = "('" . mysql_real_escape_string($message) . "', 'msg', '" . mysql_real_escape_string($this->username) . "', '" . strtolower($to) . "', " . time() . ")"; + } + + $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'messages (message, type, sender, recipient, stamp) VALUES ' . $to_insert); + } else { + if(strlen($message) > 1500) + return 'too_long'; + } + + return 'sent'; + } else { + return 'not_online'; + } + } + + /** + * Adds the buddy to the user's buddylist, if possible. + * + * @return String 'added' if successful, error string otherwise + * @author Joshua Gross + **/ + function addBuddy($username, $group) { + if(!$this->checkInfo($this->username, $this->password)) return 'not_added'; + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); + + if(mysql_num_rows($query) == 0) { + $add_buddy = mysql_query('INSERT INTO ' . SQL_PREFIX . 'buddylists (user, buddy, `group`) VALUES(\'' . mysql_real_escape_string($this->username) . '\', \'' . mysql_real_escape_string($username) . '\', \'' . mysql_real_escape_string($group) . '\')'); + return 'added'; + } else { + return 'already_on_buddylist'; + } + } + + /** + * Removes the buddy from the user's buddylist, if possible. + * + * @return String 'removed' if successful, error string otherwise + * @author Joshua Gross + **/ + function removeBuddy($username) { + if(!$this->checkInfo($this->username, $this->password)) return 'not_removed'; + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); + + if(mysql_num_rows($query) > 0) { + $remove_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\''); + return 'removed'; + } else { + return 'no_user_on_buddylist'; + } + } + + /** + * Blocks the user from being able to contact the user if blocked. Unblocks the user if blocked. + * + * @return String 'blocked' if not blocked, 'unblocked' if blocked, 'not_blocked' on error + * @author Joshua Gross + **/ + function blockBuddy($username, $status) { + if(!$this->checkInfo($this->username, $this->password)) return 'not_blocked'; + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); + + if(mysql_num_rows($query) == 0) { + $block_buddy = mysql_query('INSERT INTO ' . SQL_PREFIX . 'blocklists (user, buddy) VALUES(\'' . mysql_real_escape_string($this->username) . '\', \'' . mysql_real_escape_string($username) . '\')'); + + $this->userEvent($this->username, array('block'=>array(mysql_real_escape_string($username))), 'status', array('status'=>0)); + return 'blocked'; + } else { + $unblock_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); + + $this->userEvent($this->username, array('block'=>array(mysql_real_escape_string($username))), 'status', array('status'=>mysql_real_escape_string($status))); + return 'unblocked'; + } + } + + /** + * Removes the group (and all buddies of group) from a user's buddylist. + * + * @return String 'removed' if successful, error string otherwise + * @author Joshua Gross + **/ + function removeGroup($group) { + if(!$this->checkInfo($this->username, $this->password)) return 'not_removed'; + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND `group`=\'' . mysql_real_escape_string($group) . '\' LIMIT 1'); + if(mysql_num_rows($query) > 0) { + $remove_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND `group`=\'' . mysql_real_escape_string($group) . '\''); + return 'removed'; + } else { + return 'no_group_on_buddylist'; + } + } + + /** + * Registers a user. + * + * @return String 'registered' if successful, error string otherwise + * @author Joshua Gross + **/ + function register($username, $password, $email) { + $username = strtolower($username); + + if(preg_match('/^[a-z0-9_\\d]+$/', $username) !== false && strlen($username) >= 3 && strlen($username) <= 16) { + if(preg_match('/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/', $email) !== false) { + if(strlen($password) >= 6 && strlen($password) <= 20) { + if(mysql_num_rows(mysql_query('SELECT email FROM ' . SQL_PREFIX . 'users WHERE email=\'' . mysql_real_escape_string($email) . '\'')) == 0) { + $query = mysql_query('SELECT username FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); + if(mysql_num_rows($query) == 0) { + $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'users (username, password, email) VALUES (\'' . mysql_real_escape_string($username) . '\', \'' . md5($password) . '\', \'' . mysql_real_escape_string($email) . '\')'); + print 'user_registered'; + } else { + print 'username_taken'; + } + } else { + print 'email_already_used'; + } + } else { + print 'password_bad_length'; + } + } else { + print 'invalid_email'; + } + } else { + print 'username_bad'; + } + } + + /** + * Check if a certain user exists (only works when authenticated). + * + * @return String 'exists' if successful, error string otherwise + * @author Joshua Gross + **/ + function isUser($username) { + if(!$this->checkInfo($this->username, $this->password)) return 'not_logged_in'; + + $query = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); + + if(mysql_num_rows($query) > 0) { + $userinfo = mysql_fetch_assoc($query); + + if($userinfo['is_online'] == 100) { + $check_friendship = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($username) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\')'); + + if(mysql_num_rows($check_friendship) == 0) return '0'; + else return $userinfo['is_online']; + } else { + return $userinfo['is_online']; + } + } else { + return 'not_exists'; + } + } + + /** + * Resets a user's password based on their email address. + * + * @return String 'reset' if successful, 'no_email_on_record' otherwise + * @author Joshua Gross + **/ + function reset($email) { + $email = urldecode($email); + + $query = mysql_query('SELECT email FROM ' . SQL_PREFIX . 'users WHERE email=\'' . mysql_real_escape_string($email) . '\''); + if(mysql_num_rows($query) > 0) { + $new_pass = $this->generatePassword(); + $query = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET password=\'' . md5($new_pass) . '\' WHERE email=\'' . mysql_real_escape_string($email) . '\''); + mail($email, 'Your Reset Password', "You requested that your password be reset, your new password is below.\n\nNew Password: $new_pass", 'From: Reset Password '); + return 'pw_reset'; + } else { + return 'no_email_on_record'; + } + } + + /** + * Changes the user's password. + * + * @return String 'changed' if successful, error string otherwise + * @author Joshua Gross + **/ + function passwordChange($password, $new_password) { + if(!$this->checkInfo($this->username, $password)) return 'invalid_pw'; + + if(strlen($new_password) >= 6 && strlen($new_password) <= 20) { + $query = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET password=\'' . md5($new_password) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); + return 'pw_changed'; + } else { + return 'password_bad_length'; + } + } + + /** + * Adds a user to a chatroom. + * + * @return String 'joined' if successful, error string otherwise + * @author Joshua Gross + **/ + function joinRoom($room) { + $room = mysql_real_escape_string(strtolower($room)); + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND room=\'' . $room . '\''); + + if(mysql_num_rows($query) > 0) { + return 'already_joined'; + } else { + if(preg_match('/^[^a-z0-9_\d]+$/', $room) == false) { + $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'chats (room, user) VALUES (\'' . $room . '\', \'' . mysql_real_escape_string($this->username) . '\')'); + + $output['users'] = $this->getChatlist($room); + $notify_buddies = $this->userEvent($this->username, $output, 'chat', array('action'=>'join', 'room'=>$room)); + + return $this->json->encode($output); + } else { + return 'invalid_chars'; + } + } + } + + /** + * Removes a user from a chatroom. + * + * @return String 'left' if successful, 'not_left' otherwise + * @author Joshua Gross + **/ + function leaveRoom($room) { + $room = mysql_real_escape_string(strtolower($room)); + + $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND room=\'' . $room . '\'') ; + + if(mysql_num_rows($query) > 0) { + $row = mysql_fetch_assoc($query); + $query = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE id=\'' . $row['id'] . '\''); + + $output['users'] = $this->getChatlist($room); + $notify_buddies = $this->userEvent($this->username, $output, 'chat', array('action'=>'left', 'room'=>$room)); + + return 'left'; + } else { + return 'not_left'; + } + } + + /** + * Retrieves a list of room names and returns them to the user as a JSON object. + * + * @return JSON object + * @author Joshua Gross + **/ + function roomList() { + $rooms_query = mysql_query('SELECT room FROM ' . SQL_PREFIX . 'chats GROUP BY room ORDER BY room ASC'); + + $rooms = array(); + while($row = mysql_fetch_assoc($rooms_query)) + $rooms[] = $row['room']; + + return $this->json->encode($rooms); + } + + /** + * Proccesses the upload of the new Buddy Icon for the user. + * + * @return JSON object + * @author Benjamin Hutchins + **/ + function changeIcon() { + global $maxBuddyIconSize; + + if (!isset($maxBuddyIconSize) || $maxBuddyIconSize == 0) { + return "unkown"; + } + + /* + @ini_set('file_uploads', 'On'); + @ini_set('upload_max_filesize', $maxBuddyIconSize.'M'); + @ini_set('post_max_size', $maxBuddyIconSize.'M'); + */ + + $allowed_types = array("image/x-ms-bmp", "image/x-icon", "image/jpeg", "image/x-png", "image/gif", "image/png", "image/tiff"); + $allowed_files = array('jpeg', 'jpg', 'jpe', 'bmp', 'png', 'gif', 'ico', "tif", "tiff"); + + if (empty($_FILES['icon']['tmp_name'])) { + return "nofile"; + } + if ($_FILES['icon']['size'] > $maxBuddyIconSize*1024) { + return "size"; + } + if (!in_array($_FILES['icon']['type'], $allowed_types)) { + return "bad_type"; + } + $filename = $_FILES['icon']['name']; + $extension = strtolower(end(explode(".", $filename))); + if (!in_array($extension, $allowed_files)) { + return "bad_extension"; + } + if (move_uploaded_file($_FILES['icon']['tmp_name'], "./buddyicons/".$this->username.".".$extension)) { + if (mysql_query('UPDATE ' . SQL_PREFIX . 'users SET buddyicon=\'' . mysql_real_escape_string($extension) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\'')) { + return "success"; + } else { + return "unkown"; + } + } else { + return "unkown"; + } + } + + /** + * Updates a user's profile. + * + * @return success value + * @author Benjamin Hutchins + **/ + function changeProfile($profile) { + if (mysql_query('UPDATE ' . SQL_PREFIX . 'users SET profile=\'' . mysql_real_escape_string(strip_tags($profile)) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\'')) { + return 'success'; + } else { + return 'failed'; + } + } + + /** + * Returns a user's profile. + * + * @return HTML content + * @author Benjamin Hutchins + **/ + function getProfile($username) { + $query = mysql_query('SELECT profile FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); + + $result = mysql_fetch_assoc($query); + return $result['profile']; + } + + /* Begin private functions */ + + /** + * Return a user's status. + * + * @return Integer representing user's status + * @author Joshua Gross + **/ + function isOnline($username) { + $query = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); + + $result = mysql_fetch_assoc($query); + return $result['is_online']; + } + + /** + * Check to see if the supplied user information is valid, and if so return specific information. + * + * @return false if information is invalid, array of data otherwise + * @author Joshua Gross + **/ + function checkInfo($username, $password, $return=array()) { + if(count($return) > 0) + $columns = implode(',', $return); + else + $columns = 'id'; + + $username = mysql_real_escape_string($username); + $password = mysql_real_escape_string($password); + + $query = mysql_query('SELECT ' . $columns . ' FROM ' . SQL_PREFIX . 'users WHERE username=\'' . $username . '\' AND password=\'' . $password . '\' LIMIT 1'); + + if(mysql_num_rows($query) > 0) + return mysql_fetch_assoc($query); + else + return false; + } + + /** + * Retrieves a list of users in a specific chatroom. + * + * @return Array of users + * @author Joshua Gross + **/ + function getChatlist($room) { + $query = mysql_query('SELECT DISTINCT user FROM ' . SQL_PREFIX . 'chats WHERE room=\'' . mysql_real_escape_string(strtolower($room)) . '\''); + + while ($row = mysql_fetch_assoc($query)) + $userlist[]=$row['user']; + return $userlist; + } + + /** + * Retrieves a list of all of the user's buddies. + * + * @return Array of buddies by group + * @author Joshua Gross + * @update Benjamin Hutchins - returns none-blocked buddies if $inc_blocked = false + **/ + function getBuddylist($username, $inc_blocked=true) { + $username = mysql_real_escape_string($username); + + $query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy AS buddy, `group` FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . $username . '\' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\')' . ($inc_blocked ? "" : ' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\')')); + + $buddylist = array(); + while($row = mysql_fetch_assoc($query)) + $buddylist[$row['group']][] = $row['buddy']; + + return $buddylist; + } + + /** + * Retrieves a list of the user's buddies that are online (with any status). + * + * @return Array of buddies by group with status information + * @author Joshua Gross + * @update Benjamin Hutchins - only returns buddies that did not block user. + **/ + function getBuddylistOnline($username) { + $username = mysql_real_escape_string($username); + + //$query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy, `group`, buddyicon, is_online FROM ' . SQL_PREFIX . 'buddylists LEFT JOIN ' . SQL_PREFIX . 'users ON ' . SQL_PREFIX . 'buddylists.buddy = ' . SQL_PREFIX . 'users.username WHERE ' . SQL_PREFIX . 'buddylists.user=\'' . $username . '\' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\')'); + $query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy, `group`, buddyicon, is_online, ' . SQL_PREFIX . 'buddylists.buddy IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\') AS blocked FROM ' . SQL_PREFIX . 'buddylists LEFT JOIN ' . SQL_PREFIX . 'users ON ' . SQL_PREFIX . 'buddylists.buddy = ' . SQL_PREFIX . 'users.username WHERE ' . SQL_PREFIX . 'buddylists.user=\'' . $username . '\''); + + $buddylist = array(); + while($row = mysql_fetch_assoc($query)) { + $buddylist[$row['group']][] = array('username'=>$row['buddy'], 'icon'=>$row['buddyicon'], 'is_online'=>($row['blocked'] ? 0 : $row['is_online'])); + } + return $buddylist; + } + + /** + * Retrieves the list of blocked buddies from the database. + * + * @return Array of buddies + * @author Joshua Gross + **/ + function getBlocklist($username) { + $username = mysql_real_escape_string($username); + + $query = mysql_query('SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\''); + + $blocklist = array(); + while($row = mysql_fetch_assoc($query)) + $blocklist[] = $row['buddy']; + + return $blocklist; + } + + /** + * Event handler for status or chat status updates. + * + * @return void + * @author Joshua Gross + **/ + function userEvent($username, $buddylist, $event, $args) { + $username = mysql_real_escape_string($username); + + switch($event) { + case 'chat': + $users = $buddylist['users']; + $users_str = @implode("','", $users); + + $query = mysql_query('SELECT username, is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(\'' . $users_str . '\') AND is_online > 0 ORDER BY username ASC'); + + while ($row = mysql_fetch_assoc($query)) + if(strlen($to_insert[$row['username']]) == 0) $to_insert[$row['username']] = mysql_real_escape_string($event . ',' . $args['action'] . ',' . $args['room']); + break; + + case 'status': + if($args['status'] == 100) { + $args['status'] = 0; // we're going to do this backwards + // instead of broadcasting a positive message to our buddies + // we will send a negative (offline) message to all our non-buddies + // who have us on their buddylist + $query_string = 'username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE buddy=\'' . $username . '\') AND ' . + 'username NOT IN(\''; + } else { + $query_string = '(username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE buddy=\'' . $username . '\') AND username NOT IN(SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\')) OR ' . + 'username IN(\''; + } + + if(count($buddylist) == 0) $buddylist[''] = array(''); + + foreach($buddylist as $group => $users) { + $users_str = implode("','", $users); + + $query = mysql_query('SELECT username, is_online FROM ' . SQL_PREFIX . 'users WHERE (' . $query_string . $users_str . '\')) GROUP BY username'); + + while($row = mysql_fetch_assoc($query)) { + if(in_array($row['username'], $users) !== false) { + if($row['is_online'] == 100) { + $friend_query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . $row['username'] . '\' AND buddy=\'' . $username . '\' LIMIT 1'); + if(mysql_num_rows($friend_query) == 0) $row['is_online'] = 0; + } + } + + if($row['is_online'] != 0 && strlen($to_insert[$row['username']]) == 0) $to_insert[$row['username']] = mysql_real_escape_string($event . ',' . $args['status']); + } + } + break; + } + + if(count($to_insert) > 0) { + $time_cur = time(); + foreach($to_insert as $user => $evt) + $insert_str .= "('" . $evt . "', 'event', '" . $username . "', '" . mysql_real_escape_string($user) . "', " . $time_cur . "),"; + + $insert_str = substr($insert_str, 0, strlen($insert_str) - 1); + $query = @mysql_query('INSERT INTO ' . SQL_PREFIX . 'messages (message, type, sender, recipient, stamp) VALUES ' . $insert_str); + } + } + + /** + * Generates a random string of the specified length (default = 10). + * + * @return String + * @author Joshua Gross + **/ + function generatePassword($length=10) { + $randstr=''; + srand((double)microtime()*1000000); + + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + while(strlen($randstr)<$length) { + $randstr.=substr($chars,(rand()%(strlen($chars))),1); + } + return $randstr; + } + + /** + * Garbage collector. Resets users who have been inactive for more than 5 minutes. + * + * @return void + * @author Joshua Gross + **/ + function gc() { + // cleanup logged-in users in database? [30% chance] + if(rand(1, 100) <= 30) { + // yes, cleanup! // + $expire_time = time() - 30; // idle for more than 30 seconds? + + $cleanup_event = mysql_query('SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0'); + if(mysql_num_rows($cleanup_event) > 0) { + while($row = mysql_fetch_assoc($cleanup_event)) + $notify_buddies = $this->userEvent($row['username'], $this->getBuddylist($row['username']), 'status', array('status'=>0)); + } + + $cleanup_event2 = mysql_query('SELECT user, room FROM ' . SQL_PREFIX . 'chats WHERE user IN(SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0)'); + if(mysql_num_rows($cleanup_event2) > 0) { + while($row = mysql_fetch_assoc($cleanup_event2)) { + $room = mysql_query('SELECT user FROM ' . SQL_PREFIX . 'chats WHERE room=\'' . $row['room'] . '\''); + + if(mysql_num_rows($room) > 0) { + while($row2 = mysql_fetch_assoc($room)) + $chatusers['users'][] = $row2['user']; + } + + $notify_chatusers = $this->userEvent($row['user'], $chatusers, 'chat', array('action'=>'left', 'room'=>$row['room'])); + } + } + + $cleanup_chats = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE user IN(SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0)'); + $cleanup_msgs = mysql_query('DELETE FROM ' . SQL_PREFIX . 'messages WHERE stamp < ' . (time() - 300)); + $cleanup = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0 WHERE last_ping < ' . $expire_time . ' AND is_online > 0'); + } + } +} + +$ajax_im = new Ajax_IM($_POST['call']); + +mysql_close(); +?> diff --git a/config-sample.php b/config-sample.php new file mode 100644 index 0000000..309fd9b --- /dev/null +++ b/config-sample.php @@ -0,0 +1,21 @@ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..220e506 --- /dev/null +++ b/index.html @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+    +    +    +    +    +    +    +
+
+ Arial + Comic Sans MS + Courier New + Garamond + Georgia + Impact + Tahoma + Times New Roman + Verdana +
+
+ 8 + 10 + 12 + 14 + 16 + 18 + 20 + 22 + 24 +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+
+ + diff --git a/install.php b/install.php new file mode 100644 index 0000000..ea74343 --- /dev/null +++ b/install.php @@ -0,0 +1,237 @@ + + + + + + ajax im - installation + + + + +

ajax im

+ +
+

before you begin...

+ Did you remember to: + +
+ +
+
+

first admin account

+ + This will be the first account registered on ajax im. It will automatically be set to be an admin account. + + + + +
+ +
+

ready?

+ + +
+
+ +
+

installing...

+
\n"; + $problem = true; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + $error = true; + } + } else { + mysql_query('ALTER TABLE `'.SQL_PREFIX.'messages` CHANGE `message` `message` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL'); + print "Table '".SQL_PREFIX."messages' added successfully!

\n"; + } + + $table_users = 'CREATE TABLE `'.SQL_PREFIX.'users` ( `username` varchar(32), `password` varchar(32), `email` text, `is_online` int(11) default \'0\', `last_ping` text, `last_ip` varchar(15), `banned` tinyint(1) default \'0\', `admin` tinyint(1) default \'0\', `buddyicon` varchar(4) NOT NULL default \'none\', `profile` text, `id` bigint(20) unsigned NOT NULL auto_increment, UNIQUE KEY `id` (`id`), UNIQUE `username` (`username`) ) ;'; + if(!mysql_query($table_users)) { + if(mysql_errno() == 1050) { + print "Table '".SQL_PREFIX."users' already exists! If you had a version of ajax im less than 3.2 installed on this database, please delete the table and then run this script again, otherwise ignore this error.

\n"; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + $error = true; + } + } else { + print "Table '".SQL_PREFIX."users' added successfully!

\n"; + } + + $table_chats = 'CREATE TABLE `'.SQL_PREFIX.'chats` ( `room` text, `user` text, `id` bigint(20) unsigned NOT NULL auto_increment, UNIQUE KEY `id` (`id`) ) ;'; + if(!mysql_query($table_chats)) { + if(mysql_errno() == 1050) { + print "Table '".SQL_PREFIX."chats' already exists! If you had a version of ajax im less than 3.0 installed on this database, please delete the table and then run this script again, otherwise ignore this error.

\n"; + $problem = true; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + $error = true; + } + } else { + mysql_query('ALTER TABLE `'.SQL_PREFIX.'chats` CHANGE `room` `room` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL'); + print "Table '".SQL_PREFIX."chats' added successfully!

\n"; + } + + $table_buddylists = 'CREATE TABLE `'.SQL_PREFIX.'buddylists` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `user` VARCHAR( 100 ) NOT NULL, `buddy` VARCHAR( 100 ) NOT NULL, `group` VARCHAR( 100 ) NOT NULL, INDEX ( `user` , `group` )) ENGINE = MYISAM ;'; + if(!mysql_query($table_buddylists)) { + if(mysql_errno() == 1050) { + print "Table '".SQL_PREFIX."buddylists' already exists! If you had a version of ajax im less than 3.2 installed on this database, please delete the table and then run this script again, otherwise ignore this error.

\n"; + $problem = true; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + $error = true; + } + } else { + print "Table '".SQL_PREFIX."buddylists' added successfully!

\n"; + } + + $table_blocklists = 'CREATE TABLE `'.SQL_PREFIX.'blocklists` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `user` VARCHAR( 100 ) NOT NULL, `buddy` VARCHAR( 100 ) NOT NULL, INDEX ( `user` , `buddy` )) ENGINE = MYISAM ;'; + if(!mysql_query($table_blocklists)) { + if(mysql_errno() == 1050) { + print "Table '".SQL_PREFIX."blocklists' already exists! If you had a version of ajax im less than 3.2 installed on this database, please delete the table and then run this script again, otherwise ignore this error.

\n"; + $problem = true; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + $error = true; + } + } else { + print "Table '".SQL_PREFIX."blocklists' added successfully!

\n"; + } + + $add_user = 'INSERT INTO `'.SQL_PREFIX.'users` (username, password, email, admin) VALUES (\'' . mysql_real_escape_string($_POST['username']) . '\', \'' . mysql_real_escape_string(md5($_POST['password'])) . '\', \'' . mysql_real_escape_string($_POST['email']) . '\', 1)'; + if(!mysql_query($add_user)) { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

\n"); + print "Unable to add the first user! This likely means there was some other issue during installation.

\n"; + $error = true; + } else { + print "First/admin user registered!

\n"; + } + + if ($maxBuddyIconSize > 0) { + if (trim(substr(sprintf('%o', fileperms('./buddyicons/')), -4)) != 777) { + $error = true; + print "File permissions::

CHMOD buddyicons/ to 0777

"; + } else { + print "You have change permissions of buddyicons/

"; + } + } + + mysql_close(); + ?> +
+ +
+

status

+ here. Please be sure to delete install.php and update.php!'; + ?> +
+ + + diff --git a/is_online/README b/is_online/README new file mode 100644 index 0000000..4e4b6dd --- /dev/null +++ b/is_online/README @@ -0,0 +1,16 @@ +/////////////////////////////////// +// ajax im 3.4 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +The is_online.php script allows you to display a users status as an image. It is very simple to use. + +To use: +1. Upload the is_online.php script and accompanying images folder to your server. +2. To display a user's status, insert this line anywhere: + + + Replace [pathtoscript] with the path to the script and [username] with the username you want to display the status of. diff --git a/is_online/images/away.gif b/is_online/images/away.gif new file mode 100644 index 0000000..746e738 Binary files /dev/null and b/is_online/images/away.gif differ diff --git a/is_online/images/offline.gif b/is_online/images/offline.gif new file mode 100644 index 0000000..93f22cb Binary files /dev/null and b/is_online/images/offline.gif differ diff --git a/is_online/images/online.gif b/is_online/images/online.gif new file mode 100644 index 0000000..9218efb Binary files /dev/null and b/is_online/images/online.gif differ diff --git a/is_online/is_online.php b/is_online/is_online.php new file mode 100644 index 0000000..84e9dd4 --- /dev/null +++ b/is_online/is_online.php @@ -0,0 +1,41 @@ + diff --git a/js/admin.js b/js/admin.js new file mode 100644 index 0000000..7ffb669 --- /dev/null +++ b/js/admin.js @@ -0,0 +1,457 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +/** + * Object to hold all Admin Windows as variables + * + * @author Joshua Gross + **/ +var AdminWindows = { + /** + * Display window to allow admin to search for users + * + * @author Joshua Gross + **/ + userSearch: function() { + var userSearchWin; + if($('admin-userSearch')) { + Windows.getWindow('admin-userSearch').toFront(); + return; + } + + userSearchWin = new Window({id: 'admin-userSearch', className: "dialog", width: 250, height: 110, resizable: true, + title: Languages.get('admin-admin') + ' - ' + Languages.get('admin-userSearch'), draggable: true, closable: true, maximizable: false, minimizable: true, detachable: false, + minWidth: 250, minHeight: 110, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + userSearchWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + userSearchWin.getContent().innerHTML = '
' + Languages.get('admin-chooseByAndSearch') + '
\ +
\ +
' + Languages.get('admin-searchType') + ':
\ +
\ +
' + Languages.get('search') + ':
\ + \ +
' + + ButtonCtl.create(Languages.get('search'), 'Admin.findUser($(\'admin-searchType\').value, $(\'admin-search\').value);') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'admin-userSearch\');') + + '
'; + + $('admin-searchButtons').setStyle({position: 'absolute', + top: '105px', + left: '32px'}); + + userSearchWin.setDestroyOnClose(); + userSearchWin.showCenter(); + }, + + /** + * On admin window resize, fix elements within window + * + * @arguments + * win - window to be resized + * + * @author Joshua Gross + **/ + handleResize: function(win) { + switch(win.getId().replace(/admin-/, '')) { + case 'userSearch': + if($('admin-userSearchResults')) { + $('admin-userSearchResults').setStyle({'width': win.getSize()['width'] + 'px'}); + $('admin-userSearchResults').parentNode.setStyle({'width': win.getSize()['width'] + 'px'}); + $('admin-userExecFunctions').setStyle({'left': ((win.getSize()['width'] - $('admin-userExecFunctions').getWidth()) / 2) + 'px'}); + } + + $('admin-searchButtons').setStyle({'left': ((win.getSize()['width'] - $('admin-searchButtons').getWidth()) / 2) + 'px'}); + break; + } + } +} + + +/** + * Handle all Admin requests + * + * @author Joshua Gross + **/ +var Admin = { + // current selected user from the user-search-results list + selectedUser: null, + + /** + * Finds and displays users searched for by the admin + * + * @author Joshua Gross + * @update Benjamin Hutchins + * - User's email be displayed. + **/ + findUser: function(searchType, search) { + var xhConn = new XHConn(); + + xhConn.connect(adminPingTo, "POST", "call=search&by="+searchType+"&for="+search, function(xh) { + if(xh.responseText == 'access_denied') return Admin.noAccess(); + + if($('admin-userSearchResults')) + $('admin-userSearchResults').parentNode.parentNode.removeChild($('admin-userSearchResults').parentNode); + + var results = xh.responseText.parseJSON(); + var resultsTable = ''; + resultsTable += ''; + + for(var i=0; i' + results[i].username + '' + + '' + '' + + ''; + } + resultsTable += '
' + Languages.get('username') + '' + Languages.get('email') + '' + Languages.get('admin-lastKnownIP') + '' + Languages.get('admin-lastActive') + '' + Languages.get('admin-status') + '' + Languages.get('admin-banned') + '' + Languages.get('admin-admin') + '
' + results[i].email + '' + results[i].lastKnownIP + '' + lastActive + '' + results[i].currentStatus + '' + results[i].banned + '' + results[i].admin + '
'; + + var userSearch = Windows.getWindow('admin-userSearch') + userSearch.setSize(500, 232); + userSearch.options.minWidth = 500; + userSearch.options.minHeight = 232; + userSearch.showCenter(false); + userSearch.getContent().innerHTML += resultsTable; + + if(!$('admin-userExecFunctions')) { + userSearch.getContent().innerHTML += '
' + + ButtonCtl.create(Languages.get('admin-kick'), 'Admin.kickUser(Admin.selectedUser.getElementsByTagName(\'td\')[0].innerHTML);') + + ButtonCtl.create(Languages.get('admin-ban'), 'Admin.banUser(Admin.selectedUser.getElementsByTagName(\'td\')[0].innerHTML);', 'admin-banButton') + + ButtonCtl.create(Languages.get('admin-makeAdmin'), 'Admin.toggleAdmin(Admin.selectedUser.getElementsByTagName(\'td\')[0].innerHTML);', 'admin-makeAdminButton') + + '
'; + + $('admin-userExecFunctions').setStyle({position: 'absolute', + top: '195px', + left: '83px'}); + } + + $('admin-searchButtons').innerHTML = ButtonCtl.create(Languages.get('searchAgain'), 'Admin.findUser($(\'admin-searchType\').value, $(\'admin-search\').value);') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'admin-userSearch\');'); + + + $('admin-searchButtons').setStyle({position: 'absolute', + top: '225px', + left: '130px'}); + + var t = new ScrollableTable($('admin-userSearchResults'), 100, 500); + t = new SortableTable($('admin-userSearchResults')); + + $('admin-searchType').value = searchType; + $('admin-search').value = search; + }); + }, + + /** + * Sends request to server to ban user + * + * @arguments + * user - user to be banned + * + * @author Joshua Gross + **/ + banUser: function(user) { + var xhConn = new XHConn(); + + xhConn.connect(adminPingTo, "POST", "call=ban&user="+user, function(xh) { + if(xh.responseText == 'access_denied') return Admin.noAccess(); + + Admin.selectedUser.getElementsByTagName('td')[4].innerHTML = xh.responseText; + $('admin-banButton').innerHTML = (xh.responseText=='true'?Languages.get('admin-unban'):Languages.get('admin-ban')); + }); + }, + + /** + * Sends request to server to kick a user offline + * + * @arguments + * user - user to be kicked + * + * @author Joshua Gross + **/ + kickUser: function(user) { + var xhConn = new XHConn(); + + xhConn.connect(adminPingTo, "POST", "call=kick&user="+user, function(xh) { + if(xh.responseText == 'access_denied') return Admin.noAccess(); + + Admin.selectedUser.getElementsByTagName('td')[3].innerHTML = '0'; + }); + }, + + /** + * Toggles a user's admin rights + * + * @arguments + * user - user to be toggled + * + * @author Joshua Gross + **/ + toggleAdmin: function(user) { + var xhConn = new XHConn(); + + xhConn.connect(adminPingTo, "POST", "call=admin&user="+user, function(xh) { + if(xh.responseText == 'access_denied') return Admin.noAccess(); + + Admin.selectedUser.getElementsByTagName('td')[5].innerHTML = xh.responseText; + $('admin-makeAdminButton').innerHTML = (xh.responseText=='true'?Languages.get('admin-removeAdmin'):Languages.get('admin-makeAdmin')); + }); + }, + + /** + * Add hover effect to an element + * + * @arguments + * el - element to have effect added + * + * @author Joshua Gross + **/ + findUserListHover: function(el) { + Element.addClassName(el, 'listHover').removeClassName('listSelected').removeClassName('listNotSelected'); + }, + + /** + * Remove hover effect added by Admin.findUserListHover + * + * @arguments + * el - element to have effect removed + * + * @author Joshua Gross + **/ + findUserListDefault: function(el) { + if(el != Admin.selectedUser) Element.addClassName(el, 'listNotSelected').removeClassName('listSelected').removeClassName('listHover'); + else Element.addClassName(el, 'listSelected').removeClassName('listNotSelected').removeClassName('listHover'); + }, + + /** + * Change Admin.selectedUser to the user clicked by the admin + * + * @arguments + * el - list element to turn into selected + * + * @author Joshua Gross + **/ + findUserListSelect: function(el) { + if(Admin.selectedUser) Element.addClassName(Admin.selectedUser, 'listNotSelected').removeClassName('listSelected').removeClassName('listHover'); + Element.addClassName(el, 'listSelected').removeClassName('listNotSelected').removeClassName('listHover'); + Admin.selectedUser = el; + + if(el.getElementsByTagName('td')[4].innerHTML == 'true') + $('admin-banButton').innerHTML = Languages.get('admin-unban'); + else + $('admin-banButton').innerHTML = Languages.get('admin-ban'); + + if(el.getElementsByTagName('td')[5].innerHTML == 'true') + $('admin-makeAdminButton').innerHTML = Languages.get('admin-removeAdmin'); + else + $('admin-makeAdminButton').innerHTML = Languages.get('admin-makeAdmin'); + } +}; + +/** +* +* Scrollable HTML table +* http://www.webtoolkit.info/ +* +**/ +function ScrollableTable (tableEl, tableHeight, tableWidth) { + + this.initIEengine = function () { + + this.containerEl.style.overflowY = 'auto'; + if (this.tableEl.parentElement.clientHeight - this.tableEl.offsetHeight < 0) { + this.tableEl.style.width = this.newWidth - this.scrollWidth +'px'; + } else { + this.containerEl.style.overflowY = 'hidden'; + this.tableEl.style.width = this.newWidth +'px'; + } + + if (this.thead) { + var trs = this.thead.getElementsByTagName('tr'); + for (x=0; x= (this.newHeight - (headHeight + footHeight))) { + this.tbody.style.overflow = '-moz-scrollbars-vertical'; + for (x=0; x]+>/g,''); + } + + this.getParent = function (el, pTagName) { + if (el == null) return null; + else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) + return el; + else + return this.getParent(el.parentNode, pTagName); + } + + this.sort = function (cell) { + + var column = cell.cellIndex; + var itm = this.getInnerText(this.tbody[0].rows[1].cells[column]); + var sortfn = this.sortCaseInsensitive; + + if (itm.match(/\d\d[-]+\d\d[-]+\d\d\d\d/)) sortfn = this.sortDate; // date format mm-dd-yyyy + if (itm.replace(/^\s+|\s+$/g,"").match(/^[\d\.]+$/)) sortfn = this.sortNumeric; + + this.sortColumnIndex = column; + + var newRows = new Array(); + for (j = 0; j < this.tbody[0].rows.length; j++) { + newRows[j] = this.tbody[0].rows[j]; + } + + newRows.sort(sortfn); + + if (cell.getAttribute("sortdir") == 'down') { + newRows.reverse(); + cell.setAttribute('sortdir','up'); + } else { + cell.setAttribute('sortdir','down'); + } + + for (i=0;i 0)) return; + + if (sortSection && sortSection[0].rows && sortSection[0].rows.length > 0) { + var sortRow = sortSection[0].rows[0]; + } else { + return; + } + + for (var i=0; i0?siteName:document.title); +var blinkerTimer; +var pingTimer; +var newWin, newWinRcvd; +var windowButtons; +var smilies = []; +var soundManager; + + +/** + * Before the window is 'unloaded', confirm the user wants to leave + * + * @author Joshua Gross + **/ +window.onbeforeunload = function(event) { + event = event || window.event; + if(event && loggedIn) { + var text = Languages.get('onunload'); + event.returnValue = text; + window.onbeforeunload = function() { }; + return text; + } +} + + +/** + * After all content and images for the web page is loaded, + * run some functions + * + * @author Joshua Gross + **/ +window.onload = function() { + Windows.addObserver({ onResize: IM.handleResize }); + Windows.addObserver({ onClose: IM.handleClose }); + Windows.addObserver({ onMaximize: IM.handleResize }); + Windows.addObserver({ onMinimize: IM.handleMinimize }); + + // initialize the sound manager + soundManager = new SoundManager(); + soundManager.onload = function() { + soundManager.createSound({id: 'msg_in', url: './sounds/msg_in.mp3', autoLoad: true}); + soundManager.createSound({id: 'msg_out', url: './sounds/msg_out.mp3', autoLoad: true}); + soundManager.play('msg_out'); + }; + soundManager.beginDelayedInit(); + + // attach event + // before window is unloaded, remove sound manager + Element.observe(window, 'beforeunload', soundManager.destruct); + + // center modal + setTimeout(function() { recenterModal(null); }, 1000); + + // on window resize, recenter modal + Event.observe(window, 'resize', recenterModal); + + // on window unload, logout the user + Event.observe(window, 'unload', function() { if(loggedIn) System.logout(); }); + + // clear all inputs + clearInputs(); + + // replace status images with theme-based images + $('statusList').getElementsBySelector('img').each(function(el) { + el.src = el.src.replace(/images/g, 'themes/' + theme); + }); + + // initialize Context Menus + Context.loaded(); + + // hook mousedown for status list + var dOMD = (document.onmousedown ? document.onmousedown : new Function()); + document.onmousedown = window.onmousedown = function(e) { + showHide(e); + dOMD(e); + } + + // if the user wants to disable register, hide the button + if (!allowNewUsers) { + $$('.registerObject').each(function(el) { + el.remove(); + }); + // then fix the buttons for login + $('login_dialog_links').setStyle({width:'190px'}); + } + + // show login + Dialogs.login(); +}; + + +/** + * After all content for the web page is loaded, + * load some more stuff. + * + * @author Joshua Gross + **/ +Event.onReady(function() { + var getEmoteHTML = new XHConn(); + getEmoteHTML.connect('themes/' + theme +'/emoticons/emoticons.html', 'GET', '', function(xh) { + document.body.innerHTML += xh.responseText; + + var getEmoteJS = new XHConn(); + getEmoteJS.connect('themes/' + theme +'/emoticons/emoticons.js', 'GET', '', function(xh) { + window.smilies = xh.responseText.parseJSON(); + }); + }); + + // load language file + var s = document.createElement('script'); + s.src = 'languages/' + languageOptions[0][0] + '/lang.js?' + (new Date()).getTime(); + s.type = 'text/javascript'; + document.getElementsByTagName('head').item(0).appendChild(s); + + // if lingo is enabled + if (useLingo) { + // load the lingo file + var l = document.createElement('script'); + l.src = 'languages/' + languageOptions[0][0] + '/lingo.js?' + (new Date()).getTime(); + l.type = 'text/javascript'; + document.getElementsByTagName('head').item(0).appendChild(l); + } + + // if there is more than one language installed on the server, show them as options + if(languageOptions.length > 1) { + for(var i=0; i' + languageOptions[i][1] + ' | '; + + $('languageList').innerHTML = $('languageList').innerHTML.substring(0, $('languageList').innerHTML.length - 3); + } +}); + + +/** + * Clear the value of input elements + * + * @author Joshua Gross + **/ +function clearInputs() { + var formInputs = document.getElementsByTagName('input'); + for (var i=0; i 10 ? '...' : '') + '"'; + blinkerTimer = setTimeout("titlebarBlink('"+name+"', '"+message+"', 2, "+chatroom+")", 1000); + } else if(alter == 2) { + document.title = defaultTitle; + blinkerTimer = setTimeout("titlebarBlink('"+name+"', '"+message+"', 0, "+chatroom+")", 1000); + } +} + + +/** + * Toggle the variable 'titlebarBlinker' to true/false + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ +function blinkerOn(onoff) { + titlebarBlinker = (onoff == true ? true : false); +} + + +/** + * Button effects for browsers without ":" support + * + * @arguments + * el - element to affect + * + * @author Joshua Gross + **/ +function buttonHover(el) { + var newsrc = el.src; + newsrc = newsrc.replace(/_hover/, ''); + el.src = newsrc.replace(/\.png/, '_hover.png'); +} +function buttonDown(el) { + el.src = el.src.replace(/_hover\.png/, '_down.png'); +} +function buttonNormal(el) { + el.src = el.src.replace(/\_hover.png/, '.png').replace(/\_down.png/, '.png'); +} + + +/** + * Check to see is an email is valid + * + * @arguments + * email - email to check + * + * @author Joshua Gross + * @updated Benjamin Hutchins + * @return true if email is valid, false otherwise + **/ +function checkEmailAddr(email) { + var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; + return filter.test(email); +} + + +/** + * Generates a random string + * + * @arguments + * length - length of string to be created + * + * @author Joshua Gross + * @return random string + **/ +function randomString(length) { + var chars = "abcdefghijklmnopqrstuvwxyz1234567890"; + var pass = ""; + var charLength = chars.length; + + for(x=0;x 0) { + do { + if (this[i] === search_term) { + return true; + } + } while (i--); + } + return false; +} + + +/** + * Checks to see if a string is alphanumeric (only letters and numbers) + * + * @author Joshua Gross + * @return true if string is alphanumeric, false otherwise + **/ +String.prototype.isAlphaNumeric = function() {return /^[A-Za-z0-9_\d]+$/.test (this)}; + + +/** + * Load the theme stylesheet + **/ +var loadCSS = document.createElement("link"); +loadCSS.setAttribute("rel", "stylesheet") +loadCSS.setAttribute("type", "text/css") +loadCSS.setAttribute("href", 'themes/' + theme + '/style.css') +if (typeof loadCSS != "undefined") + document.getElementsByTagName("head")[0].appendChild(loadCSS); diff --git a/js/browser.js b/js/browser.js new file mode 100644 index 0000000..50f49f7 --- /dev/null +++ b/js/browser.js @@ -0,0 +1,47 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Class to handle browser requests + **/ +var Browser = { + /** + * Get the width of the client browser + * + * @author Joshua Gross + * @return Document Width + **/ + width: function() { + if (self.innerWidth) { + return self.innerWidth; + } else if (document.documentElement && document.documentElement.clientWidth) { + return document.documentElement.clientWidth; + } else if (document.body) { + return document.body.clientWidth; + } + return 630; + }, + + /** + * Get the height of the client browser + * + * @author Joshua Gross + * @return Document Height + **/ + height: function() { + if (self.innerWidth) { + return self.innerHeight; + } else if (document.documentElement && document.documentElement.clientWidth) { + return document.documentElement.clientHeight; + } else if (document.body) { + return document.body.clientHeight; + } + return 470; + } +}; diff --git a/js/buddylist.js b/js/buddylist.js new file mode 100644 index 0000000..5618f90 --- /dev/null +++ b/js/buddylist.js @@ -0,0 +1,428 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Class to handle buddylist events + * + * @author Joshua Gross + **/ +var Buddylist = { + buddyListWin: null, // buddy list window + + /** + * Process the creation of the buddy list window + * + * @author Joshua Gross + **/ + create: function() { + Event.observe(window, 'resize', Buddylist.fixBuddyList); + + if(!$('bl')) { + this.buddyListWin = new Window({id: 'bl', className: "dialog", width: 210, height: (Browser.height() - 60), zIndex: 100, resizable: true, title: Languages.get('buddyList'), draggable: true, closable: false, maximizable: false, detachable: false, minWidth: 205, minHeight: 150, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + this.buddyListWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + } + + this.buddyListWin.getContent().innerHTML = '
' + + '' + Languages.get('addBuddyButton') + '' + + '' + Languages.get('removeBuddyButton') + '' + + '' + Languages.get('IMAnyoneButton') + '' + + '' + Languages.get('joinChatroomButton') + '' + + '' + Languages.get('changeSettingsButton') + '' + + '' + Languages.get('toggleSoundButton') + '' + + (typeof(Status) != 'undefined' ? '' : '') + + '
' + Languages.get('signOff') + '
'; + Event.observe(this.buddyListWin.getContent(), 'contextmenu', function() { return false; }); + + $('bl_minimize').setStyle({left: (this.buddyListWin.getSize()['width'] - 21) + 'px'}); + + this.sizeBuddyList(); + + this.buddyListWin.showCenter(false, (((Browser.height()-40) / 2) - (this.buddyListWin.getSize()['height'] / 2)), (buddyListLoc == 0 ? 10 : (Browser.width() - this.buddyListWin.getSize()['width'] - 10))); + this.buddyListWin.toFront(); + + this.list = {}; + this.listObjects = {}; + this.blocked = {}; + }, + + /** + * Destroy the buddy list window + * + * @author Joshua Gross + **/ + destroy: function() { + this.buddyListWin.destroy(); + }, + + /** + * Reposition buddylist + * + * @author Joshua Gross + **/ + fixBuddyList: function() { + if(Buddylist.buddyListWin.isVisible()) { + Buddylist.buddyListWin.setSize(210, (Browser.height() - 60)); + Buddylist.buddyListWin.setLocation((((Browser.height()-40) / 2) - (Buddylist.buddyListWin.getSize()['height'] / 2)), (buddyListLoc == 0 ? 10 : (Browser.width() - Buddylist.buddyListWin.getSize()['width'] - 10))); + Buddylist.sizeBuddyList(); + } + }, + + /** + * Resize buddylist + * + * @author Joshua Gross + **/ + sizeBuddyList: function() { + $('blContainer').setStyle({width: (this.buddyListWin.getSize()['width'] - 8) + 'px', + height: (this.buddyListWin.getSize()['height'] - 95) + 'px'}); + + $('blBottomToolbar').setStyle({width: (this.buddyListWin.getSize()['width'] - 8) + 'px', + top: (this.buddyListWin.getSize()['height'] - 7) + 'px'}); + + $('bl_minimize').setStyle({left: (this.buddyListWin.getSize()['width'] - 21) + 'px'}); + }, + + /** + * Add new buddy to the list + * + * @arguments + * username - user's username + * groupname - group the user is in + * + * @author Joshua Gross + **/ + addNewBuddy: function(username, groupname) { + username = username.toLowerCase(); + if(!inArray(Buddylist.list, username) && (!Buddylist.listObjects[username] || !$(Buddylist.listObjects[username].obj))) { + var xhConn = new XHConn(); + + xhConn.connect(pingTo, "POST", "call=isuser&username="+username, function(xh) { + if(xh.responseText == 'not_exists') { + $('newbuddy_error_msg').innerHTML = Languages.get('noSuchUser'); + } else { + if(!$(groupname.replace(/\s/, '_') + '_group')) { + Buddylist.addGroup(groupname); + Buddylist.list[groupname] = []; + } + + Buddylist.addBuddy(username, 'Offline', 'none'); + + if(parseInt(xh.responseText) == 0) { + Buddylist.moveBuddy(username, 'Offline'); + $(Buddylist.listObjects[username].img).src = 'themes/' + theme + '/offline.png'; + } else if(parseInt(xh.responseText) == 2) { + Buddylist.moveBuddy(username, groupname); + $(Buddylist.listObjects[username].img).src = 'themes/' + theme + '/away.png'; + } else { + Buddylist.moveBuddy(username, groupname); + $(Buddylist.listObjects[username].img).src = 'themes/' + theme + '/online.png'; + } + + Buddylist.list[groupname][username] = {'username': username, 'blocked': false, 'status': parseInt(xh.responseText)}; + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=addbuddy&username="+username+'&group='+groupname, null); + + Windows.close('newBuddy'); + } + }); + } else { + $('newbuddy_error_msg').innerHTML = Languages.get('alreadyOnBuddylist'); + } + }, + + /** + * Add buddy to the list + * + * @arguments + * username - username of the buddy we're adding + * groupname - the group the buddy is in + * buddyicon - the buddy's buddyiocn + * + * @author Joshua Gross + * update Benjamin Hutchins + **/ + addBuddy: function(username, groupname, buddyicon) { + if(!$(groupname.replace(/\s/, '_') + '_group')) this.addGroup(groupname); + var groupList = $(groupname.replace(/\s/, '_') + '_group'); + var iconsrc = (buddyicon=='none'?defaultIcon:pathToIcons+username+'.'+buddyicon); + + var randId = Math.floor(Math.random()*1000000000); + while($(randId + '_blItem')) + randId = Math.floor(Math.random()*1000000000); + + groupList.innerHTML += '
  • ' + (useIcons&&showInList?(defaultIcon==""&&buddyicon=='none'?'':''):'') + '     '+username+'
  • '; + + Buddylist.listObjects[username] = {}; + Buddylist.listObjects[username].obj = randId + '_blItem'; + Buddylist.listObjects[username].img = randId + '_blImg'; + Buddylist.listObjects[username].icon = buddyicon; + Buddylist.listObjects[username].group = groupname; + + $(Buddylist.listObjects[username].obj).setStyle({listStyleType: 'none'}); + }, + + /** + * Move a buddy from one group to another + * + * @arguments + * username - username of the buddy we're moving + * groupname - new group name + * + * @author Joshua Gross + **/ + moveBuddy: function(username, groupname) { + if(groupname == null) return; + if($(Buddylist.listObjects[username].obj).parentNode == $(groupname.replace(/\s/, '_') + '_group')) return; + if(!$(groupname.replace(/\s/, '_') + '_group')) this.addGroup(groupname); + + var group = $(groupname.replace(/\s/, '_') + '_group') + + group.insertBefore($(Buddylist.listObjects[username].obj), null); + }, + + /** + * Add a new group the buddylist window + * + * @arguments + * groupname - group to add + * + * @author Joshua Gross + **/ + addGroup: function(groupname) { + var bList = $('buddylist'); + bList.innerHTML = (groupname=='Offline' ? bList.innerHTML : '') + '
  •   ' + groupname + + (groupname!='Offline' ? ' ' : '') + '
  • ' + "\n" + '
      ' + (groupname!='Offline' ? bList.innerHTML : ''); + }, + + /** + * Remove buddy from the buddylist permanently + * + * @arguments + * username - buddy we're removin + * + * @author Joshua Gross + **/ + deleteBuddy: function(username) { + if(username.indexOf('_group') != -1) { + this.deleteGroup(username.substring(0, username.length - 6)); + return; + } + + var usernam = username; + + var ingroup = null; + for (var group in this.list) { + if(typeof(this.list[group][username]) !== 'undefined' && this.list[group][username].username == username) { + ingroup = group; + break; + } + } + + var buddyToRmv = $(Buddylist.listObjects[username].obj); + + if(typeof(buddyToRmv) !== 'undefined') { + buddyToRmv.parentNode.removeChild(buddyToRmv); + if(this.list[ingroup]) { + this.list[ingroup][username] = null; + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=removebuddy&username="+username, null); + + } + Dialog.closeInfo(); + } + }, + + /** + * Process the blocking of a buddy + * + * @arguments + * username - the buddy to be blocked + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + blockBuddy: function(username) { + var isBlocked = this.blocked.inArray(username); + if(isBlocked) { + for(var i=0; i= 2 ? 'themes/' + theme + '/away.png' : 'themes/' + theme + '/offline.png'))); + if(!blockedBuddyStatus && isBlocked) { + Buddylist.moveBuddy(username, Languages.get('offline')); + } + break; + } + } + }, + + /** + * Remove a group from the buddylist permanently + * + * @arguments + * groupname - group to be removes + * + * @author Joshua Gross + **/ + deleteGroup: function(groupname) { + var groupNoSpaces = groupname.replace(/\s/, '_'); + var groupToRmv = $(groupNoSpaces+"_group"); + var groupTop = $(groupNoSpaces+"_groupTop"); + + if(typeof(groupToRmv) !== 'undefined') { + groupToRmv.parentNode.removeChild(groupToRmv); + groupTop.parentNode.removeChild(groupTop); + + for(var i=0;i 0) { + try { + var el = $(Buddylist.listObjects[curSelected].obj); + Element.addClassName(el, 'listNotSelected'); + Element.removeClassName(el, 'listSelected'); + Element.removeClassName(el, 'listHover'); + } catch(e) { } + } + + curSelected = username; + + var oel = $(Buddylist.listObjects[curSelected].obj); + Element.addClassName(oel, 'listSelected'); + Element.removeClassName(oel, 'listNotSelected'); + Element.removeClassName(oel, 'listHover'); + } + return false; + }, + + /** + * Process double clicks, open the IM window + * + * @author Joshua Gross + **/ + onBuddyDblClick: function() { + if(curSelected.length > 0) { + if(typeof(IM.windows[curSelected]) == 'undefined') { + IM.create(curSelected, curSelected); + } else { + if(IM.windows[curSelected].detached) { + if(IM.windows[curSelected].popup.closed) { + IM.windows[curSelected] = IM.windows[curSelected].old; + IM.windows[curSelected].show(); + } else { + IM.windows[curSelected].popup.focus(); + } + } else if(!IM.windows[curSelected].isVisible()) { + IM.windows[curSelected].show(); + IM.windows[curSelected].toFront(); + setTimeout("scrollToBottom('" + IM.windows[curSelected].getId() + "_rcvd')", 125); + setTimeout("$('" + IM.windows[curSelected].getId() + "_sendBox').focus();", 250); + } else { + IM.windows[curSelected].toFront(); + setTimeout("$('" + IM.windows[curSelected].getId() + "_sendBox').focus();", 250); + } + } + } + } +}; diff --git a/js/buttonctl.js b/js/buttonctl.js new file mode 100644 index 0000000..84e7bfd --- /dev/null +++ b/js/buttonctl.js @@ -0,0 +1,76 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Button control class + */ +var ButtonCtl = { + /** + * Create a button/link wrapper + * + * @arguments + * text - innerHTML for link + * action - onClick action + * id - element ID to apply (if none is supplied, none is set) + * + * @author Joshua Gross + **/ + create: function(text, action, id) { + return '' + text + ''; + }, + + /** + * Create a submit input button wrapper + * + * @arguments + * text - value for input + * id - element ID to apply (if none is supplied, none is set) + * + * @authro Benjamin Hutchins + **/ + createSubmit: function(text, id) { + return ''; + }, + + /** + * Effect to apply to 'el' (element) on mouseover + * + * @arguments + * el - element to affect + * + * @author Joshua Gross + **/ + hover: function(el) { + el.className = 'stdButton btnHover'; + }, + + /** + * Effect to apply to 'el' (element) on mousedown + * + * @arguments + * el - element to affect + * + * @author Joshua Gross + **/ + down: function(el) { + el.className = 'stdButton btnDown'; + }, + + /** + * Restore 'el' (element) to normal on mouseout + * + * @arguments + * el - element to affect + * + * @author Joshua Gross + **/ + normal: function(el) { + el.className = 'stdButton'; + } +}; diff --git a/js/chat.js b/js/chat.js new file mode 100644 index 0000000..7e3e270 --- /dev/null +++ b/js/chat.js @@ -0,0 +1,362 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Chatroom Class + **/ +var Chatroom = { + windows: {}, // JavaScript object to store all chatroom windows + + /** + * Create a new chatroom + * + * @arguments + * name - chatroom name + * imTitle - window title, default is chatroom name + * + * @author Joshua Gross + **/ + create: function(name, imTitle) { + var imLeft = Math.round(Math.random()*(Browser.width()-360))+'px'; + var imTop = Math.round(Math.random()*(Browser.height()-400))+'px'; + + var winId = randomString(32) + '_chat'; + + this.windows[name] = new ChatWindow({id: winId, className: "dialog", width: 475, height: 340, top: imTop, left: imLeft, resizable: true, title: imTitle, draggable: true, detachable: false, minWidth: 475, minHeight: 150, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + this.windows[name].setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + this.windows[name].getContent().innerHTML = '
      ' + "\n" + + '
      ' + "\n" + + '
      ' + Languages.get('bold') + ' ' + + '' + Languages.get('italic') + ' '+ + '' + Languages.get('underline') + '
      ' + + ' Tahoma' + + ' 12' + + '
      ' + + ' ' + + "\n" + '
      '; + + this.windows[name].setRoom(name); + + $(winId + '_userlist').setStyle({left: (this.windows[name].getSize().width - 155) + 'px', height: (this.windows[name].getSize().height - 12) + 'px'}); + $(winId + '_rcvd').setStyle({marginTop: '5px', height: (this.windows[name].getSize().height - 103) + 'px', width: (this.windows[name].getSize().width - 170) + 'px'}); + $(winId + '_toolbar').setStyle({top: (this.windows[name].getSize().height - 73) + 'px', width: (this.windows[name].getSize().width - 170) + 'px'}); + $(winId + '_setFont').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontSize').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColor').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColorColor').setStyle({backgroundColor: '#000'}); + $(winId + '_insertEmoticon').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + + var sendBox = $(winId + '_sendBox'); + sendBox.setStyle({top: (this.windows[name].getSize().height - 45) + 'px', + left: '2px', + width: (this.windows[name].getSize().width - 175) + 'px', + fontWeight: '400', + fontStyle: 'normal', + textDecoration: 'none'}); + + this.windows[name].show(); + this.windows[name].toFront(); + Windows.focusedWindow = this.windows[name]; + setTimeout("$('"+winId+"_sendBox').focus();", 250); + }, + + /** + * Process chatroom window resize + * + * @arguments + * name - chatroom name + * + * @author Joshua Gross + **/ + handleResize: function(name) { + var winId = this.windows[name].getId(); + + $(winId + '_userlist').setStyle({left: (this.windows[name].getSize().width - 155) + 'px', height: (this.windows[name].getSize().height - 12) + 'px'}); + $(winId + '_rcvd').setStyle({height: (this.windows[name].getSize().height - 103) + 'px', width: (this.windows[name].getSize().width - 170) + 'px'}); + $(winId + '_toolbar').setStyle({top: (this.windows[name].getSize().height - 73) + 'px', width: (this.windows[name].getSize().width - 170) + 'px'}); + $(winId + '_setFont').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontSize').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColor').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColorColor').setStyle({backgroundColor: '#000'}); + $(winId + '_insertEmoticon').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_sendBox').setStyle({top: (this.windows[name].getSize().height - 45) + 'px', left: '2px', width: (this.windows[name].getSize().width - 175) + 'px'}); + }, + + /** + * Send request to server to enter a chatroom + * + * @argument + * room - room name user is entering + * + * @author Joshua Gross + **/ + join: function(room) { + room = room.toLowerCase(); + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=joinroom&room="+room, + function(xh) { + if(xh.responseText.indexOf('"') == -1) { + switch(xh.responseText) { + case 'already_joined': + $('newroom_error_msg').innerHTML = Languages.get('alreadyInRoom').replace('%1', room); + break; + case 'room_is_user': + $('newroom_error_msg').innerHTML = Languages.get('invalidRoom'); + break; + case 'invalid_chars': + $('newroom_error_msg').innerHTML = Languages.get('invalidRoomChars'); + break; + } + } else { + if(!$(room + '_im')) { + Chatroom.create(room, room); + } else { + if(!Chatroom.windows[room].isVisible()) { + Chatroom.windows[room].show(); + setTimeout("scrollToBottom('" + room + "_rcvd')", 125); + } + } + var users = xh.responseText.parseJSON().users; + for(var i=0; i '+username+''; + $(username+'_'+this.room+'_chatUser').setStyle({listStyleType: 'none'}); + }, + + /** + * Remove a user from the chatroom user list + * + * @arguments + * username - user to remove + * + * @author Joshua Gross + **/ + deleteUser: function(username) { + var toDelete = $(username + '_' + this.room + '_chatUser'); + if(typeof(toDelete) !== 'undefined') + toDelete.parentNode.removeChild(toDelete); + }, + + /** + * Process mouseover and mousout calls for the user list + * + * @arguments + * sel - element + * username - user's username + * selected - is mouse over or did it go out + * + * @author Joshua Gross + **/ + selectUser: function(sel, username, selected) { + if(selected === false) { + if(this.curSelected != username) { + try { + Element.addClassName(sel, 'listNotSelected'); + Element.removeClassName(sel, 'listSelected'); + Element.removeClassName(sel, 'listHover'); + } catch(e) { } + } else { + Element.addClassName(sel, 'listSelected'); + Element.removeClassName(sel, 'listNotSelected'); + Element.removeClassName(sel, 'listHover'); + } + } else { + Element.addClassName(sel, 'listHover'); + Element.removeClassName(sel, 'listSelected'); + Element.removeClassName(sel, 'listNotSelected'); + } + }, + + /** + * Process event when a user is clicked + * + * @arguments + * username - the username of the user clicked + * + * @author Josh Gross + **/ + clickUser: function(username) { + if(this.curSelected.length > 0) { + try { + var el = $(this.curSelected + '_' + this.room + '_chatUser'); + Element.addClassName(el, 'listNotSelected'); + Element.removeClassName(el, 'listSelected'); + Element.removeClassName(el, 'listHover'); + } catch(e) { } + } + + this.curSelected = username; + + var oel = $(this.curSelected + '_' + this.room + '_chatUser'); + Element.addClassName(oel, 'listSelected'); + Element.removeClassName(oel, 'listNotSelected'); + Element.removeClassName(oel, 'listHover'); + }, + + /** + * On DoubleClick of a user from the chatroom user + * list, start a private IM with him/her. + * + * @author Joshua Gross + **/ + onUserDblClick: function() { + if(this.curSelected.length > 0) { + if(typeof(IM.windows[this.curSelected]) == 'undefined') { + IM.create(this.curSelected, this.curSelected); + } else { + if(!IM.windows[this.curSelected].isVisible()) { + IM.windows[this.curSelected].show(); + IM.windows[this.curSelected].toFront(); + setTimeout("scrollToBottom('" + IM.windows[this.curSelected].getId() + "_rcvd')", 125); + setTimeout("$('" + IM.windows[this.curSelected].getId() + "_sendBox').focus();", 250); + } else { + IM.windows[this.curSelected].toFront(); + setTimeout("$('" + IM.windows[this.curSelected].getId() + "_sendBox').focus();", 250); + } + } + } + } +}); + + +/** + * Class to handle the window of the chat rooms + **/ +var ChatroomList = { + curSelected: '', // current selected chat room + + /** + * Get list of chat rooms that exist + * + * @author Joshua Gross + **/ + get: function(applyTo) { + var xhConn = new XHConn(); + + xhConn.connect(pingTo, "POST", "call=roomlist", function(xh) { + var rooms = xh.responseText.parseJSON(); + + applyTo.innerHTML = '
      • '; + + if(rooms.length > 0 || predefRooms.length > 0) { + for(var i=0; i' + rooms[i] + ''; + } + } + + for(var i=0; i' + predefRooms[i] + ''; + } + } + } else { + applyTo.innerHTML += '
      • ' + Languages.get('noRoomsExist') + '
      • '; + } + applyTo.innerHTML += '
      '; + }); + }, + + /** + * Proccess mouseover and mouseout of list items + * + * @arguments + * sel - list element + * roomname - chatroom name + * selected - did mouse go over or out + * + * @author Joshua Gross + **/ + selectRoom: function(sel, roomname, selected) { + if(selected === false) { + if(this.curSelected != roomname) { + try { + Element.addClassName(sel, 'listNotSelected').removeClassName('listSelected').removeClassName('listHover'); + } catch(e) { } + } else { + Element.addClassName(sel, 'listSelected').removeClassName('listNotSelected').removeClassName('listHover'); + } + } else { + Element.addClassName(sel, 'listHover').removeClassName('listSelected').removeClassName('listNotSelected'); + } + }, + + /** + * Process the clicking of a room + * + * @arguments + * roomname - room that was clicked + * + * @author Joshua Gross + **/ + clickRoom: function(roomname) { + if(this.curSelected.length > 0) { + try { + Element.addClassName($('chatroom_list_' + hex_md5(this.curSelected)), 'listNotSelected').removeClassName('listSelected').removeClassName('listHover'); + } catch(e) { } + } + + this.curSelected = roomname; + $('roomname').value = roomname; + + Element.addClassName($('chatroom_list_' + hex_md5(roomname)), 'listSelected').removeClassName('listNotSelected').removeClassName('listHover'); + } +}; diff --git a/js/config.js b/js/config.js new file mode 100644 index 0000000..e48f8b5 --- /dev/null +++ b/js/config.js @@ -0,0 +1,110 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +// Configuration // + +// Title // +var siteName = 'ajax im'; // Name of your site (appears as the page title). + // If '', then the title will be used from the index file. + +// Registration // +var allowNewUsers = true; // Enable/Disable open registration + +// Languages // +// Format: [ +// ['folderName', 'properName'], +// ['language2Folder', 'Language 2 Proper Name'], +// ... +// ] +// Note: The first language will be used as the default language. +var languageOptions = [ + ['english', 'English'] + ]; + +// Theme Settings // +var theme = 'dark'; // ajax im theme +var alertWidth = 400; // alert window width + +// Notification // +var useBlinker = true; // Show new message in titlebar when window isn't active. +var blinkSpeed = 1000; // How fast to change between the titles when "blinking" (in milliseconds). +var pulsateTitles = true; // Pulsate (blink) IM window titles on new IM when they are not the active window. +var audioNotify = true; // By default, play sounds upon getting an IM? + +// Server // +var pingFrequency = 2500; // How often to ping the server (in milliseconds). Best range between 2500 and 3500 ms. +var pingTo = 'ajax_im.php'; // The file that is the "server". +var adminPingTo = 'admin.php'; // The "server" script for admin functions. +var blockedBuddyStatus = false; // Show blocked buddies' status. + +// Windows // +var imWidth = 310; // Default IM window width +var imHeight = 335; // Default IM window height +var imDetachable = true; // Enable/Disable ability to detach IM windows from the application +var buddyListLoc = 1; // Default buddylist location: 0=left, 1=right (of window) + +// Timeouts // +var idleTime = 15; // How long until a user goes idle from now sending any messages (in minutes). + // If 0, feature not used. + +// Lingo Text-Replacement // +var useLingo = true; // Automated text replacement for messaging. Will replace typos and shorthand, + // as defined in the current language's lingo.js file, with the proper replacement + // text. +var lingoPunction = [ // Punction the can be placed at the end of a word/setence. + [" ", " "], // Format: [RegularExpression, Real] + ["\\.\\.", ".."], + ["\\.\\.\\.", "..."], + ["\\.\\.\\.\\.", "...."], + ["\\.\\.\\.\\.\\.", "....."], + ["\\.", "."], + [",", ","], + [";", ";"], + ["\\!", "!"], + ["\\?", "?"] + ]; + +// Buddy Icons // +var useIcons = true; // Enable/Disable use of buddy icons +var pathToIcons = './buddyicons/';// Path to buddy icons, include trailing slash. +var showInList = false; // Enable/Disable showing of buddy icons in the buddy list +var vanishingIcons = true; // Enable/Disable the hiding of the buddy icons in a chat +var vanishingSpeed = 10000; // Show the buddy icon for X amount until it is hidden (in milliseconds). +var defaultIcon = ''; // Location of image to use when no buddy icon is availible + // If blank, no default icon is used + + +// Messaging History // +var imHistory = true; // Retain conversations with buddies throughout the session? + // How it works: If an IM window is closed an imHistory is true, + // next time that IM window is opened (during the same session!), + // the old chat text will be there + +// Chatrooms // +var predefRooms = []; // Define preset rooms that will always exist when a user views the "Join Room" list. + // Format: ['room1', 'room2', ...] + +// Timestamp Format // +// This is the timestamp format used to note when an IM was received. +/* M = month, Jan - Dec + * m = month, 01 - 12, with prepended 0 (01, 02, ...) + * u = month, 1 - 12, without prepended 0 (1, 2, ...) + * d = day, 01 - 31, with prepended 0 (01, 02, ...) + * x = day, 1 - 31, without prepended 0 (1, 2, ...) + * Y = year, 4 digits (eg: 2008) + * y = year, 2 digits (eg: 08) + * H = hours, 24-hour format with prepended 0 (01, 02, ...) + * h = hours, 12-hour format without prepended 0 (1, 2, ...) + * Q = hours, 24-hour format without prepended 0 (1, 2, ...) + * q = hours, 12-hour format with prepended 0 (01, 02, ...) + * i = minutes + * s = seconds + * a = am/pm + * A = AM/PM + */ +var timestamp = '[h:i:s a]'; diff --git a/js/context.js b/js/context.js new file mode 100644 index 0000000..a5e8fd5 --- /dev/null +++ b/js/context.js @@ -0,0 +1,146 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Handle all right-click menus for buddy list + * + * @author Benjamin Hutchins + **/ +var Context = { + currentUser: null, // current user that the menu is being shown for + lastClicked: null, // last user that was right-clicked + + /** + * On window load, apply new observes + * + * @author Benjamin Hutchins + **/ + loaded: function() { + if (typeof document.oncontextmenu != 'undefined') { + document.oncontextmenu = Context.oncontextmenu; + } else { + window.oncontextmenu = Context.oncontextmenu; + } + + document.onmousedown = window.onmousedown = Context.onmousedown; + }, + + /** + * onClick of 'Get Info', open the users' profile. + * + * @author Benjamin Hutchins + **/ + profile: function() { + $('divContext').style.display = 'none'; + if(typeof(Profile.windows[Context.currentUser]) == 'undefined') { + Profile.create(Context.currentUser, Context.currentUser); + } else { + if(!Profile.windows[Context.currentUser].isVisible()) { + Profile.windows[Context.currentUser].show(); + Profile.windows[Context.currentUser].toFront(); + } else { + Profile.windows[Context.currentUser].toFront(); + } + } + }, + + /** + * onClick of 'IM', open the conversation window with the user. + * + * @author Benjamin Hutchins + **/ + createIM: function() { + $('divContext').style.display = 'none'; + if(typeof(IM.windows[Context.currentUser]) == 'undefined') { + IM.create(Context.currentUser, Context.currentUser); + } else { + if(IM.windows[Context.currentUser].detached) { + if(IM.windows[Context.currentUser].popup.closed) { + IM.windows[Context.currentUser] = IM.windows[Context.currentUser].old; + IM.windows[Context.currentUser].show(); + } else { + IM.windows[Context.currentUser].popup.focus(); + } + } else if(!IM.windows[Context.currentUser].isVisible()) { + IM.windows[Context.currentUser].show(); + IM.windows[Context.currentUser].toFront(); + setTimeout("scrollToBottom('" + IM.windows[Context.currentUser].getId() + "_rcvd')", 125); + setTimeout("$('" + IM.windows[Context.currentUser].getId() + "_sendBox').focus();", 250); + } else { + IM.windows[Context.currentUser].toFront(); + setTimeout("$('" + IM.windows[Context.currentUser].getId() + "_sendBox').focus();", 250); + } + } + }, + + /** + * onClick of 'Block' or 'Unblock', toggle the user's blocked status. + * + * @author Benjamin Hutchins + **/ + blockBuddy: function() { + $('divContext').style.display = 'none'; + Dialogs.blockBuddy(Context.currentUser); + }, + + /** + * onClick of 'Remove', remove the user from the friend's list. + * + * @author Benjamin Hutchins + **/ + removeBuddy: function() { + $('divContext').style.display = 'none'; + Dialogs.removeBuddy(Context.currentUser); + }, + + /** + * Global onContextMenu handler + * + * @author Benjamin Hutchins + **/ + oncontextmenu: function (event) { + if (loggedIn && Context.lastClicked != null) { + event = event || window.event; + + Context.currentUser = Context.lastClicked; + var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop; + var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft; + + $('divContext').style.display = 'none'; + var group = Buddylist.listObjects[Context.currentUser].group; + $('contextBlock').innerHTML = (typeof Buddylist.list[group] != 'undefined' && Buddylist.list[group][Context.currentUser].blocked == true ? Languages.get('contextUnblock') : Languages.get('contextBlock')); + Element.setStyle($('divContext'), { + left: (event.clientX + scrollLeft - 5) + 'px', + top: (event.clientY + scrollTop - 5) + 'px', + zIndex: Windows.maxZIndex + 20, + display: 'block' + }); + + Context.lastClicked = null; + return false; + } else if ($('divContext')) { + $('divContext').style.display = 'none'; + } + }, + + /** + * Global onMouseDown handler, hide right-click menu, + * as long as it wasn't a right click. + * + * @author Benjamin Hutchins + **/ + onmousedown: function (event) { + if (loggedIn) { + event = event || window.event; + if (event.button != 2 && event.button != 3) { + setTimeout("$('divContext').style.display='none';", 100); + } + } + } +}; diff --git a/js/dialogs.js b/js/dialogs.js new file mode 100644 index 0000000..118a6d3 --- /dev/null +++ b/js/dialogs.js @@ -0,0 +1,405 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Dialog and windows class + * + * @author Joshua Gross + **/ +var Dialogs = { + /** + * Display login modal + * + * @author Joshua Gross + **/ + login: function() { + clearInputs(); + $('login_error_msg').innerHTML = ''; + this.mainDialogShow('login'); + this.currentMainDialog = 'login'; + setTimeout("try { $('username').focus(); } catch(e) { }", 1125); + }, + + /** + * Display register modal + * + * @author Joshua Gross + **/ + register: function() { + clearInputs(); + $('register_error_msg').innerHTML = ''; + Dialogs.mainDialogShow('register'); + this.currentMainDialog = 'register'; + setTimeout("try { $('newusername').focus(); } catch(e) { }", 505); + }, + + /** + * Display forgot password modal + * + * @author Joshua Gross + **/ + forgotPass: function() { + clearInputs(); + $('forgotpass_error_msg').innerHTML = ''; + Dialogs.mainDialogShow('forgotPass'); + this.currentMainDialog = 'forgotPass'; + setTimeout("try { $('resetto').focus(); } catch(e) { }", 505); + }, + + /** + * Display main dialog + * + * @author Joshua Gross + **/ + mainDialogShow: function(dialog) { + if(this.currentMainDialog) Element.setStyle(this.currentMainDialog + 'Dialog', {'display': 'none'}); + Element.setStyle(dialog + 'Dialog', {'display': 'block'}); + }, + + /** + * New IM window, or IM Anyone. Displays a window to enter a + * username in attempt to message a new friend. + * + * @author Joshua Gross + **/ + newIM: function() { + var newIMWin; + if($('newIM')) { + Windows.getWindow('newIM').toFront(); + return; + } + + newIMWin = new Window({id: 'newIM', className: "dialog", width: 240, height: 120, resizable: false, title: Languages.get('newIM'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 120, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + newIMWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + newIMWin.getContent().innerHTML = '
      ' + Languages.get('newIMPlease') + '
      \ +   \ +
      \ +
      ' + Languages.get('username') + ':
      \ +
      \ +
      ' + + ButtonCtl.create(Languages.get('openIM'), 'IM.newIMWindow();') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'newIM\');') + + '
      '; + + $('newim_buttons').setStyle({position: 'absolute', top: '110px', left: '25px'}); + newIMWin.setDestroyOnClose(); + newIMWin.showCenter(); + setTimeout("$('sendto').focus();", 125); + }, + + /** + * Display a window that will allow the user + * to enter a name for a chat room to be created. + * + * @author Joshua Gross + **/ + newRoom: function() { + var newRoomWin; + if($('newRoom')) { + Windows.getWindow('newRoom').toFront(); + return; + } + + newRoomWin = new Window({id: 'newRoom', className: "dialog", width: 240, height: 300, resizable: false, title: Languages.get('newRoom'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 120, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + newRoomWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + newRoomWin.getContent().innerHTML = '
      ' + Languages.get('newRoomPlease') + '
      \ +   \ +
      \ +
      ' + Languages.get('roomname') + ':
      \ +
      \ +
      \ +
      ' + + ButtonCtl.create(Languages.get('joinRoom'), 'Chatroom.join($(\'roomname\').value);') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'newRoom\');') + + '
      '; + + $('newroom_buttons').setStyle({position: 'absolute', top: '290px', left: '25px'}); + + ChatroomList.get($('newroom_room_list')); + + newRoomWin.setDestroyOnClose(); + newRoomWin.showCenter(); + setTimeout("$('roomname').focus();", 125); + }, + + /** + * Display a window to allow the user to enter another + * buddy's username and a group name to have the user added + * to the user's buddylist. + * + * @author Joshua Gross + **/ + newBuddy: function() { + var newBuddyWin; + if($('newBuddy')) { + Windows.getWindow('newBuddy').toFront(); + return; + } + + newBuddyWin = new Window({id: 'newBuddy', className: "dialog", width: 240, height: 160, resizable: false, title: Languages.get('newBuddy'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 120, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + newBuddyWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + newBuddyWin.getContent().innerHTML = '
      ' + Languages.get('newBuddyPlease') + '
      \ +   \ +
      \ +
      ' + Languages.get('username') + ':

      \ +
      ' + Languages.get('addtogroup') + ':
      \ +
      \ +
      ' + + ButtonCtl.create(Languages.get('add'), 'Buddylist.addNewBuddy($(\'newBuddyUsername\').value, $(\'newBuddyGroup\').value);') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'newBuddy\');') + + '
      '; + + $('newbuddy_buttons').setStyle({position: 'absolute', top: '150px', left: '25px'}); + + newBuddyWin.setDestroyOnClose(); + newBuddyWin.showCenter(); + setTimeout("$('newBuddyUsername').focus();", 125); + }, + + /** + * Display a window to confirm the removal of a buddy. + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + removeBuddy: function(username) { + var delBuddyWin; + + if (typeof username == 'undefined') + var username = curSelected; + + if(username == '' || username.length == 0) + return; + + if($('delBuddy')) { + Windows.getWindow('delBuddy').toFront(); + return; + } + + delBuddyWin = new Window({id: 'delBuddy', className: "dialog", width: 240, height: 70, resizable: false, title: Languages.get('removeBuddy'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight:70, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + delBuddyWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + delBuddyWin.getContent().innerHTML = '
      ' + Languages.get('removeBuddyAreYouSure').replace('%1', username) + '
      \ +
      ' + + ButtonCtl.create(Languages.get('ok'), 'Buddylist.deleteBuddy(\'' + username + '\');Windows.close(\'delBuddy\');') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'delBuddy\');') + + '
      '; + + $('delbuddy_buttons').setStyle({position: 'absolute', top: '60px', left: '25px'}); + + delBuddyWin.setDestroyOnClose(); + delBuddyWin.showCenter(); + }, + + /** + * Display a window to confirm the blocking/unblocking + * of a buddy. + * + * @author Joshua Gross + **/ + blockBuddy: function(buddy) { + var blockBuddyWin; + + if($('blockBuddy')) { + Windows.getWindow('blockBuddy').toFront(); + return; + } + + blockBuddyWin = new Window({id: 'blockBuddy', className: "dialog", width: 240, height: 70, resizable: false, title: Languages.get('blockBuddy'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight:70, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + blockBuddyWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + blockBuddyWin.getContent().innerHTML = '
      ' + (Buddylist.blocked.inArray(buddy) ? Languages.get('unblockBuddyAreYouSure').replace('%1', buddy) : Languages.get('blockBuddyAreYouSure').replace('%1', buddy)) + '
      \ +
      ' + + ButtonCtl.create(Languages.get('ok'), 'Buddylist.blockBuddy(\'' + buddy + '\');Windows.close(\'blockBuddy\');') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'blockBuddy\');') + + '
      '; + + $('blockbuddy_buttons').setStyle({position: 'absolute', top: '60px', left: '25px'}); + + blockBuddyWin.setDestroyOnClose(); + blockBuddyWin.showCenter(); + }, + + /** + * Display a window to confirm the removal of an + * entire buddy group. + * + * @author Joshua Gross + **/ + removeGroup: function(group) { + var delGroupWin; + if($('delGroup')) { + Windows.getWindow('delGroup').toFront(); + return; + } + + delGroupWin = new Window({id: 'delGroup', className: "dialog", width: 240, height: 70, resizable: false, title: Languages.get('removeGroup'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight:70, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + delGroupWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + delGroupWin.getContent().innerHTML = '
      ' + Languages.get('removeGroupAreYouSure').replace('%1', group) + '
      \ +
      ' + + ButtonCtl.create(Languages.get('ok'), 'Buddylist.deleteGroup(\'' + group + '\');Windows.close(\'delGroup\');') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'delGroup\');') + + '
      '; + + $('delgroup_buttons').setStyle({position: 'absolute', top: '60px', left: '25px'}); + + delGroupWin.setDestroyOnClose(); + delGroupWin.showCenter(); + }, + + /** + * Display a window to show the available settings + * that the user can change. + * + * @author Benjamin Hutchins + **/ + changeSettings: function() { + var changeSettings; + if($('changeSettings')) { + Windows.getWindow('changeSettings').toFront(); + return; + } + + changeSettings = new Window({id: 'changeSettings', className: "dialog", width: 300, height: 160, resizable: false, title: Languages.get('changeSettings'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 150, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + changeSettings.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + changeSettings.getContent().innerHTML = '
      ' + Languages.get('changeSettingsInstructions') + '
      \ +
      ' + + ButtonCtl.create(Languages.get('changeSettingsPassword'), 'Dialogs.changePass();if($(\'changeSettings\')){Windows.close(\'changeSettings\');}') + + ButtonCtl.create(Languages.get('changeSettingsProfile'), 'Dialogs.changeProfile();if($(\'changeSettings\')){Windows.close(\'changeSettings\');}') + + (useIcons ? ButtonCtl.create(Languages.get('changeSettingsBuddyicon'), 'Dialogs.changeIcon();if($(\'changeSettings\')){Windows.close(\'changeSettings\');}') : '') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'changeSettings\');') + + '
      '; + + $('changesettings_buttons').setStyle({position: 'absolute', top: '60px', left: '85px'}); + + changeSettings.setDestroyOnClose(); + changeSettings.showCenter(); + }, + + /** + * Display a window to allow the user to change + * their buddy profile. + * + * @author Benjamin Hutchins + **/ + changeProfile: function() { + var changeProfileWin; + if($('changeProfile')) { + Windows.getWindow('changeProfile').toFront(); + return; + } + + changeProfileWin = new Window({id: 'changeProfile', className: "dialog", width: 300, height: 250, resizable: false, title: Languages.get('changeProfile'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 240, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + changeProfileWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + changeProfileWin.getContent().innerHTML = '
      ' + Languages.get('changeProfileInstructions') + '
      \ +   \ + \ +
      ' + + ButtonCtl.create(Languages.get('change'), 'System.changeProfile();') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'changeProfile\');') + + '
      '; + + $('changeprofile_buttons').setStyle({position: 'absolute', top: '245px', left: '55px'}); + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=getprofile&user="+user, + function(xh) { + $('changeprofile_textarea').value = xh.responseText; + } + ); + + changeProfileWin.setDestroyOnClose(); + changeProfileWin.showCenter(); + }, + + /** + * Display a window to allow the user to upload + * a new buddy icon. + * + * @author Benjamin Hutchins + **/ + changeIcon: function () { + if(!useIcons) return; + + var changeIconWin; + if($('changeIcon')) { + Windows.getWindow('changeIcon').toFront(); + return; + } + + changeIconWin = new Window({id: 'changeIcon', className: "dialog", width: 300, height: 160, resizable: false, title: Languages.get('changeBuddyicon'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 120, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + changeIconWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + changeIconWin.getContent().innerHTML = '
      ' + Languages.get('changeBuddyiconInstructions') + '
      \ +   \ +
      \ + \ + \ +
      ' + + ButtonCtl.createSubmit(Languages.get('change')) + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'changeIcon\');') + + '' + + '' + + '
      '; + + $('changeicon_buttons').setStyle({position: 'absolute', top: '150px', left: '55px'}); + + changeIconWin.setDestroyOnClose(); + changeIconWin.showCenter(); + }, + + /** + * Display a window to allow the user to change + * their password. + * + * @author Joshua Gross + **/ + changePass: function() { + var changePassWin; + if($('changePass')) { + Windows.getWindow('changePass').toFront(); + return; + } + + changePassWin = new Window({id: 'changePass', className: "dialog", width: 300, height: 160, resizable: false, title: Languages.get('changePassword'), draggable: true, closable: true, maximizable: false, minimizable: false, detachable: false, minWidth: 240, minHeight: 120, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + changePassWin.setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + changePassWin.getContent().innerHTML = '
      ' + Languages.get('changePasswordInstructions') + '
      \ +   \ +
      \ +
      ' + Languages.get('currentPassword') + ':

      \ +
      ' + Languages.get('newPassword') + ':
      \ +
      ' + Languages.get('confirmPassword') + ':
      \ +
      \ +
      ' + + ButtonCtl.create(Languages.get('change'), 'System.changePass();') + + ButtonCtl.create(Languages.get('cancel'), 'Windows.close(\'changePass\');') + + '
      '; + + $('changepass_buttons').setStyle({position: 'absolute', top: '150px', left: '55px'}); + + changePassWin.setDestroyOnClose(); + changePassWin.showCenter(); + setTimeout("$('currentpw').focus();", 125); + } +}; diff --git a/js/effects.js b/js/effects.js new file mode 100644 index 0000000..d57727e --- /dev/null +++ b/js/effects.js @@ -0,0 +1,11 @@ +// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ +String.prototype.parseColor=function(){var A="#";if(this.slice(0,4)=="rgb("){var C=this.slice(4,this.length-1).split(",");var B=0;do{A+=parseInt(C[B]).toColorPart()}while(++B<3)}else{if(this.slice(0,1)=="#"){if(this.length==4){for(var B=1;B<4;B++){A+=(this.charAt(B)+this.charAt(B)).toLowerCase()}}if(this.length==7){A=this.toLowerCase()}}}return(A.length==7?A:(arguments[0]||this))};Element.collectTextNodes=function(A){return $A($(A).childNodes).collect(function(B){return(B.nodeType==3?B.nodeValue:(B.hasChildNodes()?Element.collectTextNodes(B):""))}).flatten().join("")};Element.collectTextNodesIgnoreClass=function(A,B){return $A($(A).childNodes).collect(function(C){return(C.nodeType==3?C.nodeValue:((C.hasChildNodes()&&!Element.hasClassName(C,B))?Element.collectTextNodesIgnoreClass(C,B):""))}).flatten().join("")};Element.setContentZoom=function(A,B){A=$(A);A.setStyle({fontSize:(B/100)+"em"});if(Prototype.Browser.WebKit){window.scrollBy(0,0)}return A};Element.getInlineOpacity=function(A){return $(A).style.opacity||""};Element.forceRerendering=function(A){try{A=$(A);var C=document.createTextNode(" ");A.appendChild(C);A.removeChild(C)}catch(B){}};var Effect={_elementDoesNotExistError:{name:"ElementDoesNotExistError",message:"The specified DOM element does not exist, but is required for this effect to operate"},Transitions:{linear:Prototype.K,sinoidal:function(A){return(-Math.cos(A*Math.PI)/2)+0.5},reverse:function(A){return 1-A},flicker:function(A){var A=((-Math.cos(A*Math.PI)/4)+0.75)+Math.random()/4;return A>1?1:A},wobble:function(A){return(-Math.cos(A*Math.PI*(9*A))/2)+0.5},pulse:function(B,A){A=A||5;return(((B%(1/A))*A).round()==0?((B*A*2)-(B*A*2).floor()):1-((B*A*2)-(B*A*2).floor()))},spring:function(A){return 1-(Math.cos(A*4.5*Math.PI)*Math.exp(-A*6))},none:function(A){return 0},full:function(A){return 1}},DefaultOptions:{duration:1,fps:100,sync:false,from:0,to:1,delay:0,queue:"parallel"},tagifyText:function(A){var B="position:relative";if(Prototype.Browser.IE){B+=";zoom:1"}A=$(A);$A(A.childNodes).each(function(C){if(C.nodeType==3){C.nodeValue.toArray().each(function(D){A.insertBefore(new Element("span",{style:B}).update(D==" "?String.fromCharCode(160):D),C)});Element.remove(C)}})},multiple:function(B,C){var E;if(((typeof B=="object")||Object.isFunction(B))&&(B.length)){E=B}else{E=$(B).childNodes}var A=Object.extend({speed:0.1,delay:0},arguments[2]||{});var D=A.delay;$A(E).each(function(G,F){new C(G,Object.extend(A,{delay:F*A.speed+D}))})},PAIRS:{"slide":["SlideDown","SlideUp"],"blind":["BlindDown","BlindUp"],"appear":["Appear","Fade"]},toggle:function(B,C){B=$(B);C=(C||"appear").toLowerCase();var A=Object.extend({queue:{position:"end",scope:(B.id||"global"),limit:1}},arguments[2]||{});Effect[B.visible()?Effect.PAIRS[C][1]:Effect.PAIRS[C][0]](B,A)}};Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;Effect.ScopedQueue=Class.create(Enumerable,{initialize:function(){this.effects=[];this.interval=null},_each:function(A){this.effects._each(A)},add:function(B){var C=new Date().getTime();var A=Object.isString(B.options.queue)?B.options.queue:B.options.queue.position;switch(A){case"front":this.effects.findAll(function(D){return D.state=="idle"}).each(function(D){D.startOn+=B.finishOn;D.finishOn+=B.finishOn});break;case"with-last":C=this.effects.pluck("startOn").max()||C;break;case"end":C=this.effects.pluck("finishOn").max()||C;break}B.startOn+=C;B.finishOn+=C;if(!B.options.queue.limit||(this.effects.length=this.startOn){if(C>=this.finishOn){this.render(1);this.cancel();this.event("beforeFinish");if(this.finish){this.finish()}this.event("afterFinish");return }var B=(C-this.startOn)/this.totalTime,A=(B*this.totalFrames).round();if(A>this.currentFrame){this.render(B);this.currentFrame=A}}},cancel:function(){if(!this.options.sync){Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).remove(this)}this.state="finished"},event:function(A){if(this.options[A+"Internal"]){this.options[A+"Internal"](this)}if(this.options[A]){this.options[A](this)}},inspect:function(){var A=$H();for(property in this){if(!Object.isFunction(this[property])){A.set(property,this[property])}}return"#"}});Effect.Parallel=Class.create(Effect.Base,{initialize:function(A){this.effects=A||[];this.start(arguments[1])},update:function(A){this.effects.invoke("render",A)},finish:function(A){this.effects.each(function(B){B.render(1);B.cancel();B.event("beforeFinish");if(B.finish){B.finish(A)}B.event("afterFinish")})}});Effect.Tween=Class.create(Effect.Base,{initialize:function(C,F,E){C=Object.isString(C)?$(C):C;var B=$A(arguments),D=B.last(),A=B.length==5?B[3]:null;this.method=Object.isFunction(D)?D.bind(C):Object.isFunction(C[D])?C[D].bind(C):function(G){C[D]=G};this.start(Object.extend({from:F,to:E},A||{}))},update:function(A){this.method(A)}});Effect.Event=Class.create(Effect.Base,{initialize:function(){this.start(Object.extend({duration:0},arguments[0]||{}))},update:Prototype.emptyFunction});Effect.Opacity=Class.create(Effect.Base,{initialize:function(B){this.element=$(B);if(!this.element){throw (Effect._elementDoesNotExistError)}if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}var A=Object.extend({from:this.element.getOpacity()||0,to:1},arguments[1]||{});this.start(A)},update:function(A){this.element.setOpacity(A)}});Effect.Move=Class.create(Effect.Base,{initialize:function(B){this.element=$(B);if(!this.element){throw (Effect._elementDoesNotExistError)}var A=Object.extend({x:0,y:0,mode:"relative"},arguments[1]||{});this.start(A)},setup:function(){this.element.makePositioned();this.originalLeft=parseFloat(this.element.getStyle("left")||"0");this.originalTop=parseFloat(this.element.getStyle("top")||"0");if(this.options.mode=="absolute"){this.options.x=this.options.x-this.originalLeft;this.options.y=this.options.y-this.originalTop}},update:function(A){this.element.setStyle({left:(this.options.x*A+this.originalLeft).round()+"px",top:(this.options.y*A+this.originalTop).round()+"px"})}});Effect.MoveBy=function(B,A,C){return new Effect.Move(B,Object.extend({x:C,y:A},arguments[3]||{}))};Effect.Scale=Class.create(Effect.Base,{initialize:function(B,C){this.element=$(B);if(!this.element){throw (Effect._elementDoesNotExistError)}var A=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:"box",scaleFrom:100,scaleTo:C},arguments[2]||{});this.start(A)},setup:function(){this.restoreAfterFinish=this.options.restoreAfterFinish||false;this.elementPositioning=this.element.getStyle("position");this.originalStyle={};["top","left","width","height","fontSize"].each(function(B){this.originalStyle[B]=this.element.style[B]}.bind(this));this.originalTop=this.element.offsetTop;this.originalLeft=this.element.offsetLeft;var A=this.element.getStyle("font-size")||"100%";["em","px","%","pt"].each(function(B){if(A.indexOf(B)>0){this.fontSize=parseFloat(A);this.fontSizeType=B}}.bind(this));this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;this.dims=null;if(this.options.scaleMode=="box"){this.dims=[this.element.offsetHeight,this.element.offsetWidth]}if(/^content/.test(this.options.scaleMode)){this.dims=[this.element.scrollHeight,this.element.scrollWidth]}if(!this.dims){this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth]}},update:function(A){var B=(this.options.scaleFrom/100)+(this.factor*A);if(this.options.scaleContent&&this.fontSize){this.element.setStyle({fontSize:this.fontSize*B+this.fontSizeType})}this.setDimensions(this.dims[0]*B,this.dims[1]*B)},finish:function(A){if(this.restoreAfterFinish){this.element.setStyle(this.originalStyle)}},setDimensions:function(A,D){var E={};if(this.options.scaleX){E.width=D.round()+"px"}if(this.options.scaleY){E.height=A.round()+"px"}if(this.options.scaleFromCenter){var C=(A-this.dims[0])/2;var B=(D-this.dims[1])/2;if(this.elementPositioning=="absolute"){if(this.options.scaleY){E.top=this.originalTop-C+"px"}if(this.options.scaleX){E.left=this.originalLeft-B+"px"}}else{if(this.options.scaleY){E.top=-C+"px"}if(this.options.scaleX){E.left=-B+"px"}}}this.element.setStyle(E)}});Effect.Highlight=Class.create(Effect.Base,{initialize:function(B){this.element=$(B);if(!this.element){throw (Effect._elementDoesNotExistError)}var A=Object.extend({startcolor:"#ffff99"},arguments[1]||{});this.start(A)},setup:function(){if(this.element.getStyle("display")=="none"){this.cancel();return }this.oldStyle={};if(!this.options.keepBackgroundImage){this.oldStyle.backgroundImage=this.element.getStyle("background-image");this.element.setStyle({backgroundImage:"none"})}if(!this.options.endcolor){this.options.endcolor=this.element.getStyle("background-color").parseColor("#ffffff")}if(!this.options.restorecolor){this.options.restorecolor=this.element.getStyle("background-color")}this._base=$R(0,2).map(function(A){return parseInt(this.options.startcolor.slice(A*2+1,A*2+3),16)}.bind(this));this._delta=$R(0,2).map(function(A){return parseInt(this.options.endcolor.slice(A*2+1,A*2+3),16)-this._base[A]}.bind(this))},update:function(A){this.element.setStyle({backgroundColor:$R(0,2).inject("#",function(B,C,D){return B+((this._base[D]+(this._delta[D]*A)).round().toColorPart())}.bind(this))})},finish:function(){this.element.setStyle(Object.extend(this.oldStyle,{backgroundColor:this.options.restorecolor}))}});Effect.ScrollTo=function(D){var C=arguments[1]||{},B=document.viewport.getScrollOffsets(),E=$(D).cumulativeOffset(),A=(window.height||document.body.scrollHeight)-document.viewport.getHeight();if(C.offset){E[1]+=C.offset}return new Effect.Tween(null,B.top,E[1]>A?A:E[1],C,function(F){scrollTo(B.left,F.round())})};Effect.Fade=function(C){C=$(C);var A=C.getInlineOpacity();var B=Object.extend({from:C.getOpacity()||1,to:0,afterFinishInternal:function(D){if(D.options.to!=0){return }D.element.hide().setStyle({opacity:A})}},arguments[1]||{});return new Effect.Opacity(C,B)};Effect.Appear=function(B){B=$(B);var A=Object.extend({from:(B.getStyle("display")=="none"?0:B.getOpacity()||0),to:1,afterFinishInternal:function(C){C.element.forceRerendering()},beforeSetup:function(C){C.element.setOpacity(C.options.from).show()}},arguments[1]||{});return new Effect.Opacity(B,A)};Effect.Puff=function(B){B=$(B);var A={opacity:B.getInlineOpacity(),position:B.getStyle("position"),top:B.style.top,left:B.style.left,width:B.style.width,height:B.style.height};return new Effect.Parallel([new Effect.Scale(B,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new Effect.Opacity(B,{sync:true,to:0})],Object.extend({duration:1,beforeSetupInternal:function(C){Position.absolutize(C.effects[0].element)},afterFinishInternal:function(C){C.effects[0].element.hide().setStyle(A)}},arguments[1]||{}))};Effect.BlindUp=function(A){A=$(A);A.makeClipping();return new Effect.Scale(A,0,Object.extend({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(B){B.element.hide().undoClipping()}},arguments[1]||{}))};Effect.BlindDown=function(B){B=$(B);var A=B.getDimensions();return new Effect.Scale(B,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:A.height,originalWidth:A.width},restoreAfterFinish:true,afterSetup:function(C){C.element.makeClipping().setStyle({height:"0px"}).show()},afterFinishInternal:function(C){C.element.undoClipping()}},arguments[1]||{}))};Effect.SwitchOff=function(B){B=$(B);var A=B.getInlineOpacity();return new Effect.Appear(B,Object.extend({duration:0.4,from:0,transition:Effect.Transitions.flicker,afterFinishInternal:function(C){new Effect.Scale(C.element,1,{duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetup:function(D){D.element.makePositioned().makeClipping()},afterFinishInternal:function(D){D.element.hide().undoClipping().undoPositioned().setStyle({opacity:A})}})}},arguments[1]||{}))};Effect.DropOut=function(B){B=$(B);var A={top:B.getStyle("top"),left:B.getStyle("left"),opacity:B.getInlineOpacity()};return new Effect.Parallel([new Effect.Move(B,{x:0,y:100,sync:true}),new Effect.Opacity(B,{sync:true,to:0})],Object.extend({duration:0.5,beforeSetup:function(C){C.effects[0].element.makePositioned()},afterFinishInternal:function(C){C.effects[0].element.hide().undoPositioned().setStyle(A)}},arguments[1]||{}))};Effect.Shake=function(D){D=$(D);var B=Object.extend({distance:20,duration:0.5},arguments[1]||{});var E=parseFloat(B.distance);var C=parseFloat(B.duration)/10;var A={top:D.getStyle("top"),left:D.getStyle("left")};return new Effect.Move(D,{x:E,y:0,duration:C,afterFinishInternal:function(F){new Effect.Move(F.element,{x:-E*2,y:0,duration:C*2,afterFinishInternal:function(G){new Effect.Move(G.element,{x:E*2,y:0,duration:C*2,afterFinishInternal:function(H){new Effect.Move(H.element,{x:-E*2,y:0,duration:C*2,afterFinishInternal:function(I){new Effect.Move(I.element,{x:E*2,y:0,duration:C*2,afterFinishInternal:function(J){new Effect.Move(J.element,{x:-E,y:0,duration:C,afterFinishInternal:function(K){K.element.undoPositioned().setStyle(A)}})}})}})}})}})}})};Effect.SlideDown=function(C){C=$(C).cleanWhitespace();var A=C.down().getStyle("bottom");var B=C.getDimensions();return new Effect.Scale(C,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:window.opera?0:1,scaleMode:{originalHeight:B.height,originalWidth:B.width},restoreAfterFinish:true,afterSetup:function(D){D.element.makePositioned();D.element.down().makePositioned();if(window.opera){D.element.setStyle({top:""})}D.element.makeClipping().setStyle({height:"0px"}).show()},afterUpdateInternal:function(D){D.element.down().setStyle({bottom:(D.dims[0]-D.element.clientHeight)+"px"})},afterFinishInternal:function(D){D.element.undoClipping().undoPositioned();D.element.down().undoPositioned().setStyle({bottom:A})}},arguments[1]||{}))};Effect.SlideUp=function(C){C=$(C).cleanWhitespace();var A=C.down().getStyle("bottom");var B=C.getDimensions();return new Effect.Scale(C,window.opera?0:1,Object.extend({scaleContent:false,scaleX:false,scaleMode:"box",scaleFrom:100,scaleMode:{originalHeight:B.height,originalWidth:B.width},restoreAfterFinish:true,afterSetup:function(D){D.element.makePositioned();D.element.down().makePositioned();if(window.opera){D.element.setStyle({top:""})}D.element.makeClipping().show()},afterUpdateInternal:function(D){D.element.down().setStyle({bottom:(D.dims[0]-D.element.clientHeight)+"px"})},afterFinishInternal:function(D){D.element.hide().undoClipping().undoPositioned();D.element.down().undoPositioned().setStyle({bottom:A})}},arguments[1]||{}))};Effect.Squish=function(A){return new Effect.Scale(A,window.opera?1:0,{restoreAfterFinish:true,beforeSetup:function(B){B.element.makeClipping()},afterFinishInternal:function(B){B.element.hide().undoClipping()}})};Effect.Grow=function(C){C=$(C);var B=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.full},arguments[1]||{});var A={top:C.style.top,left:C.style.left,height:C.style.height,width:C.style.width,opacity:C.getInlineOpacity()};var G=C.getDimensions();var H,F;var E,D;switch(B.direction){case"top-left":H=F=E=D=0;break;case"top-right":H=G.width;F=D=0;E=-G.width;break;case"bottom-left":H=E=0;F=G.height;D=-G.height;break;case"bottom-right":H=G.width;F=G.height;E=-G.width;D=-G.height;break;case"center":H=G.width/2;F=G.height/2;E=-G.width/2;D=-G.height/2;break}return new Effect.Move(C,{x:H,y:F,duration:0.01,beforeSetup:function(I){I.element.hide().makeClipping().makePositioned()},afterFinishInternal:function(I){new Effect.Parallel([new Effect.Opacity(I.element,{sync:true,to:1,from:0,transition:B.opacityTransition}),new Effect.Move(I.element,{x:E,y:D,sync:true,transition:B.moveTransition}),new Effect.Scale(I.element,100,{scaleMode:{originalHeight:G.height,originalWidth:G.width},sync:true,scaleFrom:window.opera?1:0,transition:B.scaleTransition,restoreAfterFinish:true})],Object.extend({beforeSetup:function(J){J.effects[0].element.setStyle({height:"0px"}).show()},afterFinishInternal:function(J){J.effects[0].element.undoClipping().undoPositioned().setStyle(A)}},B))}})};Effect.Shrink=function(C){C=$(C);var B=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.none},arguments[1]||{});var A={top:C.style.top,left:C.style.left,height:C.style.height,width:C.style.width,opacity:C.getInlineOpacity()};var F=C.getDimensions();var E,D;switch(B.direction){case"top-left":E=D=0;break;case"top-right":E=F.width;D=0;break;case"bottom-left":E=0;D=F.height;break;case"bottom-right":E=F.width;D=F.height;break;case"center":E=F.width/2;D=F.height/2;break}return new Effect.Parallel([new Effect.Opacity(C,{sync:true,to:0,from:1,transition:B.opacityTransition}),new Effect.Scale(C,window.opera?1:0,{sync:true,transition:B.scaleTransition,restoreAfterFinish:true}),new Effect.Move(C,{x:E,y:D,sync:true,transition:B.moveTransition})],Object.extend({beforeStartInternal:function(G){G.effects[0].element.makePositioned().makeClipping()},afterFinishInternal:function(G){G.effects[0].element.hide().undoClipping().undoPositioned().setStyle(A)}},B))};Effect.Pulsate=function(C){C=$(C);var B=arguments[1]||{};var A=C.getInlineOpacity();var E=B.transition||Effect.Transitions.sinoidal;var D=function(F){return E(1-Effect.Transitions.pulse(F,B.pulses))};D.bind(E);return new Effect.Opacity(C,Object.extend(Object.extend({duration:2,from:0,afterFinishInternal:function(F){F.element.setStyle({opacity:A})}},B),{transition:D}))};Effect.Fold=function(B){B=$(B);var A={top:B.style.top,left:B.style.left,width:B.style.width,height:B.style.height};B.makeClipping();return new Effect.Scale(B,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(C){new Effect.Scale(B,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(D){D.element.hide().undoClipping().setStyle(A)}})}},arguments[1]||{}))};Effect.Morph=Class.create(Effect.Base,{initialize:function(C){this.element=$(C);if(!this.element){throw (Effect._elementDoesNotExistError)}var A=Object.extend({style:{}},arguments[1]||{});if(!Object.isString(A.style)){this.style=$H(A.style)}else{if(A.style.include(":")){this.style=A.style.parseStyle()}else{this.element.addClassName(A.style);this.style=$H(this.element.getStyles());this.element.removeClassName(A.style);var B=this.element.getStyles();this.style=this.style.reject(function(D){return D.value==B[D.key]});A.afterFinishInternal=function(D){D.element.addClassName(D.options.style);D.transforms.each(function(E){D.element.style[E.style]=""})}}}this.start(A)},setup:function(){function A(B){if(!B||["rgba(0, 0, 0, 0)","transparent"].include(B)){B="#ffffff"}B=B.parseColor();return $R(0,2).map(function(C){return parseInt(B.slice(C*2+1,C*2+3),16)})}this.transforms=this.style.map(function(G){var F=G[0],E=G[1],D=null;if(E.parseColor("#zzzzzz")!="#zzzzzz"){E=E.parseColor();D="color"}else{if(F=="opacity"){E=parseFloat(E);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}}else{if(Element.CSS_LENGTH.test(E)){var C=E.match(/^([\+\-]?[0-9\.]+)(.*)$/);E=parseFloat(C[1]);D=(C.length==3)?C[2]:null}}}var B=this.element.getStyle(F);return{style:F.camelize(),originalValue:D=="color"?A(B):parseFloat(B||0),targetValue:D=="color"?A(E):E,unit:D}}.bind(this)).reject(function(B){return((B.originalValue==B.targetValue)||(B.unit!="color"&&(isNaN(B.originalValue)||isNaN(B.targetValue))))})},update:function(A){var D={},B,C=this.transforms.length;while(C--){D[(B=this.transforms[C]).style]=B.unit=="color"?"#"+(Math.round(B.originalValue[0]+(B.targetValue[0]-B.originalValue[0])*A)).toColorPart()+(Math.round(B.originalValue[1]+(B.targetValue[1]-B.originalValue[1])*A)).toColorPart()+(Math.round(B.originalValue[2]+(B.targetValue[2]-B.originalValue[2])*A)).toColorPart():(B.originalValue+(B.targetValue-B.originalValue)*A).toFixed(3)+(B.unit===null?"":B.unit)}this.element.setStyle(D,true)}});Effect.Transform=Class.create({initialize:function(A){this.tracks=[];this.options=arguments[1]||{};this.addTracks(A)},addTracks:function(A){A.each(function(B){B=$H(B);var C=B.values().first();this.tracks.push($H({ids:B.keys().first(),effect:Effect.Morph,options:{style:C}}))}.bind(this));return this},play:function(){return new Effect.Parallel(this.tracks.map(function(A){var D=A.get("ids"),C=A.get("effect"),B=A.get("options");var E=[$(D)||$$(D)].flatten();return E.map(function(F){return new C(F,Object.extend({sync:true},B))})}).flatten(),this.options)}});Element.CSS_PROPERTIES=$w("backgroundColor backgroundPosition borderBottomColor borderBottomStyle borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth borderRightColor borderRightStyle borderRightWidth borderSpacing borderTopColor borderTopStyle borderTopWidth bottom clip color fontSize fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop markerOffset maxHeight maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft paddingRight paddingTop right textIndent top width wordSpacing zIndex");Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.__parseStyleElement=document.createElement("div");String.prototype.parseStyle=function(){var B,A=$H();if(Prototype.Browser.WebKit){B=new Element("div",{style:this}).style}else{String.__parseStyleElement.innerHTML='
      ';B=String.__parseStyleElement.childNodes[0].style}Element.CSS_PROPERTIES.each(function(C){if(B[C]){A.set(C,B[C])}});if(Prototype.Browser.IE&&this.include("opacity")){A.set("opacity",this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1])}return A};if(document.defaultView&&document.defaultView.getComputedStyle){Element.getStyles=function(B){var A=document.defaultView.getComputedStyle($(B),null);return Element.CSS_PROPERTIES.inject({},function(C,D){C[D]=A[D];return C})}}else{Element.getStyles=function(B){B=$(B);var A=B.currentStyle,C;C=Element.CSS_PROPERTIES.inject({},function(D,E){D[E]=A[E];return D});if(!C.opacity){C.opacity=B.getOpacity()}return C}}Effect.Methods={morph:function(A,B){A=$(A);new Effect.Morph(A,Object.extend({style:B},arguments[2]||{}));return A},visualEffect:function(C,E,B){C=$(C);var D=E.dasherize().camelize(),A=D.charAt(0).toUpperCase()+D.substring(1);new Effect[A](C,B);return C},highlight:function(B,A){B=$(B);new Effect.Highlight(B,A);return B}};$w("fade appear grow shrink fold blindUp blindDown slideUp slideDown pulsate shake puff squish switchOff dropOut").each(function(A){Effect.Methods[A]=function(C,B){C=$(C);Effect[A.charAt(0).toUpperCase()+A.substring(1)](C,B);return C}});$w("getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles").each(function(A){Effect.Methods[A]=Element[A]});Element.addMethods(Effect.Methods) \ No newline at end of file diff --git a/js/im.basic.js b/js/im.basic.js new file mode 100644 index 0000000..9abf415 --- /dev/null +++ b/js/im.basic.js @@ -0,0 +1,584 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * AjaxIM Class + * + * @author Joshua Gross + **/ +var AjaxIM = { + windows: {}, // JavaScript object to hold all IM windows + sendBoxWithFocus: null, // current box that has focus + + /** + * Create new IM window + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + create: function(name, imTitle) { + var buddyicon = typeof Buddylist.listObjects[name] == 'undefined' ? 'none' : Buddylist.listObjects[name].icon; + var iconsrc = (buddyicon=='none'?defaultIcon:pathToIcons+name+'.'+buddyicon); + var imLeft = Math.round(Math.random()*(Browser.width()-360))+'px'; + var imTop = Math.round(Math.random()*(Browser.height()-400))+'px'; + + var winId = randomString(32) + '_im'; + + this.windows[name] = new IMWindow({id: winId, className: "dialog", width: 320, height: 335, top: imTop, left: imLeft, resizable: true, title: imTitle, draggable: true, detachable: imDetachable, minWidth: 320, minHeight: 150, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + this.windows[name].setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + + this.windows[name].getContent().innerHTML = '
      ' + + '' + Languages.get('addBuddyButton') + ' ' + + '' + + '
      ' + + (useIcons?(defaultIcon==""&&buddyicon=="none"?'':'Buddy Icon'):'') + + '
      ' + "\n" + + '
      ' + Languages.get('bold') + ' ' + + '' + Languages.get('italic') + ' '+ + '' + Languages.get('underline') + '
      ' + + ' Tahoma' + + ' 12' + + '
      ' + + ' ' + + "\n" + '
      '; + + this.windows[name].setUsername(name); + + $(winId + '_rcvd').setStyle({height: (this.windows[name].getSize().height - 135) + 'px', width: (this.windows[name].getSize().width - 10) + 'px'}); + $(winId + '_toolbar').setStyle({top: (this.windows[name].getSize().height - 73) + 'px', width: (this.windows[name].getSize().width - 10) + 'px'}); + $(winId + '_setFont').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontSize').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColor').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_setFontColorColor').setStyle({backgroundColor: '#000'}); + $(winId + '_insertEmoticon').setStyle({top: (this.windows[name].getSize().height - 65) + 'px'}); + $(winId + '_sendBox').setStyle({top: (this.windows[name].getSize().height - 45) + 'px', left: '2px', width: (this.windows[name].getSize().width - 16) + 'px', fontWeight: '400', fontStyle: 'normal', textDecoration: 'none'}); + + this.windows[name].show(); + this.windows[name].toFront(); + Windows.focusedWindow = this.windows[name]; + setTimeout("$('"+winId+"_sendBox').focus();", 250); + if (vanishingIcons){setTimeout("if($('buddyIcon_"+name+"')){$('buddyIcon_"+name+"').hide();}", vanishingSpeed);} + }, + + /** + * Sends a message to the server + * + * @arguments + * username - who the message is being sent to + * message - the message to send + * chatroom - (bool) is this a chatroom + * isBold - (bool) is the message bolded + * isItalic - (bool) is the message italicized + * isUnderline - (bool) is the message underlined + * fontName - font family for the message + * fontSize - font size for the message + * fontColor - font color for the message + * + * @author Joshua Gross + **/ + sendMessage: function(username, message, chatroom, isBold, isItalic, isUnderline, fontName, fontSize, fontColor) { + var xhConn = new XHConn(); + + xhConn.connect(pingTo, "POST", "call=send&recipient="+username+"&chatroom="+chatroom+"&bold="+isBold+"&italic="+isItalic+"&underline="+isUnderline+"&font="+fontName+"&fontsize="+fontSize+"&fontcolor="+fontColor+"&message="+encodeURIComponent(message), + function(xh) { + var error = null; + + switch(xh.responseText) { + case 'sent': + // do nothing + break; + + case 'sent_offline': + error = Languages.get('notifySentButOffline'); + break; + + case 'not_online': + error = Languages.get('errorNotLoggedIn'); + break; + + case 'too_long': + error = Languages.get('errorMsgTooLong'); + break; + + case 'not_logged_in': + if (typeof System != 'undefined') { + System.logout(); + } else { + self.opener.System.logout(); + } + break; + + default: + error = Languages.get('errorUnknown'); + break; + } + + if(chatroom == 'true') + Chatroom.windows[username].sendResult(message, isBold, isItalic, isUnderline, fontName, fontSize, fontColor, error); + else + IM.windows[username].sendResult(message, isBold, isItalic, isUnderline, fontName, fontSize, fontColor, error); + } + ); + + if(audioNotify == true) soundManager.play('msg_out'); + }, + + /** + * Replaces emotes with images + * + * @arguments + * str - the message to run replaces on + * itemsList - array of emotes + **/ + emoteReplace: function(str, itemsList) { + var r; + for(var s in itemsList) { + if(str.indexOf(s) > -1) + str = str.replace(new RegExp(regExpEscape(s), 'g'), '' + itemsList[s] + ''); + } + return str; + }, + + /** + * Start a new message with a user that might not be in your buddy list, + * ran via Dialogs.newIM() + * + * @author Joshua Gross + **/ + newIMWindow: function() { + if($('sendto').value.replace(/^\s*|\s*$/g,"").length > 0) { + var toWhom = $('sendto').value; + + if(typeof(this.windows[toWhom]) == 'undefined') { + this.create(toWhom, toWhom); + } else { + if(!this.windows[toWhom].isVisible()) { + this.windows[toWhom].show(); + setTimeout("scrollToBottom('" + this.windows[toWhom].getId() + "_rcvd')", 125); + } + } + + Windows.close('newIM'); + this.windows[toWhom].toFront(); + setTimeout("$('" + this.windows[toWhom].getId() + "_sendBox').focus()", 125); + } else { + $('newim_error_msg').innerHTML = Languages.get('newIMProper'); + } + }, + + /** + * @author Joshua Gross + **/ + handleClose: function(eventName, win) { + if(win.getId().indexOf('_im') == -1 && win.getId().indexOf('_chat') == -1) return; + + if(typeof(win.room) !== 'undefined') Chatroom.leave(win.room); + + var rcvdBox = $(win.getId() + '_rcvd'); + if(imHistory == true) { + rcvdBox.innerHTML = '' + + rcvdBox.innerHTML.replace(new RegExp('\(' + Languages.get('autoreply') + ':\)/g'), Languages.get('autoreply') + ':').replace(/<(?![Bb][Rr] ?\/?)([^>]+)>/ig, '') + + "\n"; + } else { + rcvdBox.innerHTML = ''; + } + }, + + /** + * @author Joshua Gross + **/ + handleMinimize: function(eventName, win) { + if(win.getId().indexOf('_im') == -1) return; + + var curIM = $(win.getId() + '_rcvd'); + curIM.scrollTop = curIM.scrollHeight - curIM.clientHeight + 6; + }, + + /** + * Create a timestamp to use in a chat window based off the + * configuration variable 'timestamp' + * + * @author Joshua Gross + **/ + createTimestamp: function() { + Stamp = new Date(); + var tH = String(Stamp.getHours()); var ti = String(Stamp.getMinutes()); var ts = String(Stamp.getSeconds()); + var th = tH > 12 ? tH - 12 : tH; var ta = tH > 12 ? 'pm' : 'am'; var tA = tH > 12 ? 'PM' : 'AM'; + var td = String(Stamp.getDate()); var tm = String(Stamp.getMonth() + 1); + var tM = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'July', 'Aug', 'Sep', 'Nov', 'Dec'][tm - 1]; + var tY = String(Stamp.getFullYear()); var ty = tY.substring(2); + + tu = tm; tx = td; tQ = tH; + + tH = (tH.length > 1) ? tH : "0"+tH; ti = (ti.length > 1) ? ti : "0"+ti; + tq = (th.length > 1) ? th : "0"+th; ts = (ts.length > 1) ? ts : "0"+ts; + td = (td.length > 1) ? td : "0"+td; tm = (tm.length > 1) ? tm : "0"+tm; + if(typeof timestamp == 'undefined') { + timestamp = self.opener.timestamp; + } + return timestamp.replace(/H/, tH).replace(/h/, th).replace(/i/, ti).replace(/s/, ts) + .replace(/d/, td).replace(/Y/, tY).replace(/y/, ty).replace(/m/, tm) + .replace(/u/, tu).replace(/x/, tx).replace(/Q/, tQ).replace(/q/, tq) + .replace(/a/, ta).replace(/A/, tA).replace(/M/, tM); + }, + + /** + * Append status changes to chat window + * + * @author Benjamin Hutchins + **/ + notifyUser: function(username, error) { + if(typeof(IM.windows[username]) != 'undefined') { + if(IM.windows[username].isVisible()) { + IM.windows[username].sendResult('', '', '', '', '', '', '', error); + } + } + }, + + /** + * Add effects to a buddy icon. + * + * @arguments + * el - buddy icon element + * + * @author Benjamin Hutchins + **/ + buddyIconHover: function(el) { + /*var clone = new Element('img', { + 'src': $(el).src, + // 'id': $(el).id + '_clone', + // 'class': 'buddyIconClone', + // 'alt': '' // valid XHTML + }).insert(Element.getOffsetParent(el), 'content'); //.setStyle({'position': 'absolute', 'top': el.offsetTop, 'left': el.offsetLeft}); + //clonePosition(clone, el, {setLeft:true, setTop:true});*/ + }, + + /** + * Restore effects set by IM.buddyIconHover back to 'Normal' + * + * @arguments + * el - buddy icon element + * + * @author Benjamin Hutchins + **/ + buddyIconNormal: function(el) { + if ($(el.id + '_clone')) { + $(el.id + '_clone').remove(); + } + } +}; + + +/** + * A class to mantain an IM Window's guts. + * + * @author Joshua Gross + **/ +var AjaxIMWindow = Class.create(); +Object.extend(AjaxIMWindow.prototype, Window.prototype); +Object.extend(AjaxIMWindow.prototype, { + /** + * Set the class' username variable + * + * @author Joshua Gross + **/ + setUsername: function(username) { + this.username = username; + }, + + send: function() { + // do nothing here. + }, + + /** + * After a message is sent to the server via IM.sendMessage(), + * this function is ran to append the message to the user's window + * + * @arguments + * message - the message to send + * isBold - (bool) is the message bolded + * isItalic - (bool) is the message italicized + * isUnderline - (bool) is the message underlined + * fontName - font family for the message + * fontSize - font size for the message + * fontColor - font color for the message + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + sendResult: function(message, isBold, isItalic, isUnderline, fontName, fontSize, fontColor, result) { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + var rcvdBox = $(winId + '_rcvd'); + + if(result != null) { + rcvdBox.innerHTML = rcvdBox.innerHTML + '' + result + '
      '; + } + + if(trim(message).length > 0) { + message = message.replace(//g, '\n').replace(//g, '>').replace(/<([^>]+)>/ig, '').replace(/\n/g, '
      ').replace(/(\s|\n|>|^)(\w+:\/\/[^<\s\n]+)/, '$1$2'); + message = IM.emoteReplace(message, smilies); + if(message.replace(/<([^>]+)>/ig, '').indexOf('/me') == 0) + rcvdBox.innerHTML = rcvdBox.innerHTML + "" + IM.createTimestamp() + " " + user + ' ' + message.replace(/<([^>]+)>/ig, '').replace(/\/me/, '') + "
      \n"; + else + rcvdBox.innerHTML = rcvdBox.innerHTML + "" + IM.createTimestamp() + " " + user + ": " + (isBold == 'true' ? "" : "") + (isItalic == 'true' ? "" : "") + (isUnderline == 'true' ? "" : "") + message + (isBold == 'true' ? "" : "") + (isItalic == 'true' ? "" : "") + (isUnderline == 'true' ? "" : "") + "
      \n"; + } + + scrollToBottom(winId + '_rcvd'); + }, + + /** + * @author Joshua Gross + **/ + toggleBold: function() { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.hide(); // horrah weird Opera 9 input refresh! + if(sendBox.style.fontWeight == '400') { + $(winId + '_bold').src = 'themes/' + theme + '/window/bold_on.png'; + sendBox.setStyle({fontWeight: '700'}); + } else { + sendBox.setStyle({fontWeight: '400'}); + $(winId + '_bold').src = 'themes/' + theme + '/window/bold_off.png'; + } + sendBox.show(); // horrah weird Opera 9 input refresh! + setTimeout("$('" + winId + "_sendBox').focus();", 125); + }, + + /** + * @author Joshua Gross + **/ + toggleItalic: function() { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.hide(); // horrah weird Opera 9 input refresh! + if(sendBox.style.fontStyle == 'normal') { + sendBox.setStyle({fontStyle: 'italic'}); + $(winId + '_italic').src = 'themes/' + theme + '/window/italic_on.png'; + } else { + sendBox.setStyle({fontStyle: 'normal'}); + $(winId + '_italic').src = 'themes/' + theme + '/window/italic_off.png'; + } + sendBox.show(); // horrah weird Opera 9 input refresh! + setTimeout("$('" + winId + "_sendBox').focus();", 125); + }, + + /** + * @author Joshua Gross + **/ + toggleUnderline: function() { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.hide(); // horrah weird Opera 9 input refresh! + if(sendBox.style.textDecoration == 'none') { + sendBox.setStyle({textDecoration: 'underline'}); + $(winId + '_underline').src = 'themes/' + theme + '/window/underline_on.png'; + } else { + sendBox.setStyle({textDecoration: 'none'}); + $(winId + '_underline').src = 'themes/' + theme + '/window/underline_off.png'; + } + sendBox.show(); // horrah weird Opera 9 input refresh! + setTimeout("$('" + winId + "_sendBox').focus();", 125); + }, + + /** + * @author Joshua Gross + **/ + toggleFontList: function() { + var fL = $('fontsList'); + var fLBtn = $(this.getId() + '_setFont'); + + $('emoticonList', 'fontColorList', 'fontSizeList').invoke('hide'); + + if($('fontsList').style.display == 'block') { + fL.hide(); + } else { + fL.setStyle({left: Position.cumulativeOffset(fLBtn)[0] + 'px', + top: (Position.cumulativeOffset(fLBtn)[1] + Element.getHeight(fLBtn) - 1) + 'px', + zIndex: Windows.maxZIndex + 20, + display: 'block'}); + + IM.active = this; + } + }, + + /** + * @author Joshua Gross + **/ + toggleFontSizeList: function() { + var fsL = $('fontSizeList'); + var fsLBtn = $(this.getId() + '_setFontSize'); + + $('emoticonList', 'fontsList', 'fontColorList').invoke('hide'); + + if($('fontSizeList').style.display == 'block') { + $('fontSizeList').setStyle({display: 'none'}); + } else { + fsL.setStyle({left: Position.cumulativeOffset(fsLBtn)[0] + 'px', + top: (Position.cumulativeOffset(fsLBtn)[1] + Element.getHeight(fsLBtn) - 1) + 'px', + zIndex: Windows.maxZIndex + 20, + display: 'block'}); + + IM.active = this; + } + }, + + /** + * @author Joshua Gross + **/ + toggleEmoticonList: function() { + var eL = $('emoticonList'); + var eLBtn = $(this.getId() + '_insertEmoticon'); + + $('fontsList', 'fontSizeList', 'fontColorList').invoke('hide'); + + if($('emoticonList').style.display == 'block') { + $('emoticonList').setStyle({display: 'none'}); + } else { + eL.setStyle({left: Position.cumulativeOffset(eLBtn)[0] + 'px', + top: (Position.cumulativeOffset(eLBtn)[1] + Element.getHeight(eLBtn) - 1) + 'px', + zIndex: Windows.maxZIndex + 20, + display: 'block'}); + + IM.active = this; + } + }, + + /** + * @author Joshua Gross + **/ + toggleFontColorList: function() { + var fcL = $('fontColorList'); + var fcLBtn = $(this.getId() + '_setFontColor'); + + $('fontsList', 'fontSizeList', 'emoticonList').invoke('hide'); + + if($('fontColorList').style.display == 'block') { + $('fontColorList').setStyle({display: 'none'}); + } else { + fcL.setStyle({left: Position.cumulativeOffset(fcLBtn)[0] + 'px', + top: (Position.cumulativeOffset(fcLBtn)[1] + Element.getHeight(fcLBtn) - 1) + 'px', + zIndex: Windows.maxZIndex + 20, + display: 'block'}); + + IM.active = this; + } + }, + + /** + * @author Joshua Gross + **/ + setFont: function(fontname) { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.hide(); + sendBox.setStyle({fontFamily: fontname + ', sans-serif'}); + sendBox.show(); + + $(winId + '_setFont').innerHTML = fontname; + setTimeout("$('" + winId + "_sendBox').focus();", 125); + this.toggleFontList(''); + }, + + /** + * @author Joshua Gross + **/ + setFontSize: function(size) { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.hide(); + sendBox.setStyle({fontSize: size + 'px'}); + sendBox.show(); + + $(winId + '_setFontSize').innerHTML = size; + setTimeout("$('" + winId + "_sendBox').focus();", 125); + this.toggleFontSizeList(''); + }, + + /** + * @author Joshua Gross + **/ + setFontColor: function(color) { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.setStyle({color: color}); + + $(winId + '_setFontColorColor').setStyle({backgroundColor: color}); + setTimeout("$('" + winId + "_sendBox').focus();", 125); + this.toggleFontColorList(''); + }, + + /** + * Adds text to a windows' message box + * + * @author Joshua Gross + **/ + insertText: function(tti) { + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + sendBox.value += tti; + setTimeout("$('" + winId + "_sendBox').focus();", 125); + this.toggleEmoticonList(); + return false; + }, + + /** + * Checks for pressing on 'Return' or 'Enter' + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + keyHandler: function(event) { + event = event || window.event; + var asc = document.all ? event.keyCode : event.which; + var shift = event.shiftKey; + + if(useLingo) { + var message = $(this.getId() + '_sendBox').value; + if(trim(message).length > 0) { + for(var i=0; i 0) { + var message = sendBox.value; + sendBox.value = ''; + IM.sendMessage((chatroom == 'true' ? this.room : this.username), message.replace(/&/g, "&").replace(//g, '>').replace(/\n/g, "
      "), chatroom, isBold, isItalic, isUnderline, fontName, fontSize, fontColor); + + Status.lastIM = new Date().getTime(); + if (typeof(Status) != 'undefined' && Status.wasSetAutoAway) { + Status.set(1, Languages.get('available')); + } + } + + scrollToBottom(winId + '_rcvd'); + sendBox.focus(); + } +}); diff --git a/js/languages.js b/js/languages.js new file mode 100644 index 0000000..93605cc --- /dev/null +++ b/js/languages.js @@ -0,0 +1,196 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Language class + * + * @author Joshua Gross + * @update Benjamin Hutchins + * - Added to popup + * - Added lingo-replacement + **/ +var Languages = { + current: '', // current language being used + previous: '', // previous language used + available: languageOptions, // list of available languages + loaded: [], // list of languages loaded + dictionary: {}, // dictionary of languages + lingodict: {}, // dictionary of lingo-replacements + + + /** + * Load a new language + * + * @arguments + * language - the language to be loaded + * + * @author Joshua Gross + * @update Benjamin Hutchins + * - Loads lingo dictionary for language as well + **/ + load: function(language) { + for(var i=0; i -1) break; + + langItem = langItem[i].substring(5); + + var langText = Languages.get(langItem); + var oldLangText = Languages.get(langItem, Languages.previous); + + var preprocessEl = $(document.createElement('div')); + preprocessEl.setStyle({display: 'none'}); + preprocessEl.innerHTML = oldLangText + ''; + document.body.appendChild(preprocessEl); + + oldLangText = preprocessEl.innerHTML; + + if(el.className.indexOf('langinsert-post') > -1 && el.innerHTML.indexOf(oldLangText) == -1) + el.innerHTML += Languages.get(langItem); + else if(el.className.indexOf('langinsert-clear') > -1) + el.innerHTML = Languages.get(langItem); + else if(el.className.indexOf('langinsert-pre') > -1 && el.innerHTML.indexOf(oldLangText) == -1) + el.innerHTML = Languages.get(langItem) + el.innerHTML; + else { + if(el.innerHTML.length == 0) { + el.innerHTML = langText; + return; + } + + if(langText.indexOf('%1') > -1) { + langText = langText.split(/%1/); + oldLangText = preprocessEl.innerHTML.split(/%1/); + + el.innerHTML = el.innerHTML.replace(oldLangText[0], langText[0]).replace(oldLangText[1], langText[1]); + } else + el.innerHTML = el.innerHTML.replace(oldLangText, langText); + } + + document.body.removeChild(preprocessEl); + }); + }, + + /** + * Get the text to show for a language + **/ + get: function(text, language) { + if(language != null && language.length == 0) + return -1; + + return Languages.dictionary[language != null ? language : Languages.current][text]; + }, + + /** + * Removed lingo-text from a message + * + * @arguments + * message - the message entered by the user + * last - last punction character + * + * @author Benjamin Hutchins + * @return none-lingo message + **/ + lingoReplace: function(message, last) { + var exp = RegExp(last[0]+"$"); + var mostof = message.replace(exp,""); + var word = trim(mostof.substring(mostof.lastIndexOf(" "), mostof.length)).replace(exp,""); + mostof = mostof.substring(0, mostof.length-word.length); + return mostof + Languages.lingo(word) + last[1]; + }, + + /** + * Runs a single word through the lingo-dictionary + * + * @arguments + * text - word to try and replace + * + * @author Benjamin Hutchins + * @return none-lingo text if availible, else returns text + **/ + lingo: function(text, language) { + if(language != null && language.length == 0) + return text; + language = language != null ? language : Languages.current; + if (typeof Languages.lingodict[language] != 'undefined') { + if (typeof Languages.lingodict[language][text.toLowerCase()] != 'undefined') { + return Languages.lingodict[language][text.toLowerCase()]; + } + } + return text; + } +}; diff --git a/js/popup.js b/js/popup.js new file mode 100644 index 0000000..f194910 --- /dev/null +++ b/js/popup.js @@ -0,0 +1,79 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + +/** + * IM Class + * + * @author Joshua Gross + **/ +var IM = { + /** + * Handle resize of window + * + * @author Joshua Gross + **/ + handleResize: function(e) { + var rcvdBox = $(winName + '_rcvd'); + rcvdBox.style.height = (browserHeight() - 133) + 'px'; + rcvdBox.style.width = (browserWidth() - 15) + 'px'; + + $(winName + '_toolbar').style.top = (browserHeight() - 93) + 'px'; + $(winName + '_toolbar').style.width = (browserWidth() - 10) + 'px'; + $(winName + '_setFont').style.top = (browserHeight() - 85) + 'px'; + $(winName + '_setFontSize').style.top = (browserHeight() - 85) + 'px'; + $(winName + '_setFontColor').style.top = (browserHeight() - 85) + 'px'; + $(winName + '_insertEmoticon').style.top = (browserHeight() - 85) + 'px'; + $(winName + '_sendBox').style.top = (browserHeight() - 65) + 'px'; + $(winName + '_sendBox').style.width = (browserWidth() - 16) + 'px'; + + rcvdBox.scrollTop = rcvdBox.scrollHeight - rcvdBox.clientHeight + 6; + } +}; +Object.extend(IM, AjaxIM); + +/** + * A class to mantain an IM Window's guts. + * + * @author Joshua Gross + **/ +var IMWindow = Class.create(AjaxIMWindow); +IMWindow.addMethods({ + /** + * Checks to see if there is a message, if there is, + * send it to the server. + * + * @author Joshua Gross + * @update Benjamin Hitchins + **/ + send: function($super) { + $super(); + var winId = this.getId(); + var sendBox = $(winId + '_sendBox'); + + var isBold = (sendBox.style.fontWeight == '400' ? 'false' : 'true'); + var isItalic = (sendBox.style.fontStyle == 'normal' ? 'false' : 'true'); + var isUnderline = (sendBox.style.textDecoration == 'none' ? 'false' : 'true'); + var fontName = $(winId + '_setFont').innerHTML; + var fontSize = $(winId + '_setFontSize').innerHTML; + var fontColor = $(winId + '_setFontColorColor').style.backgroundColor; + + if(trim(sendBox.value).length > 0) { + var message = sendBox.value; + sendBox.value = ''; + IM.sendMessage(this.username, message.replace(/&/g, "&").replace(//g, '>').replace(/\n/g, "
      "), '', isBold, isItalic, isUnderline, fontName, fontSize, fontColor); + + self.opener.Status.lastIM = new Date().getTime(); + if (typeof(Status) != 'undefined' && self.opener.Status.wasSetAutoAway) { + self.opener.Status.set(1, Languages.get('available')); + } + } + + scrollToBottom(winId + '_rcvd'); + sendBox.focus(); + } +}); diff --git a/js/profile.js b/js/profile.js new file mode 100644 index 0000000..6d5bc75 --- /dev/null +++ b/js/profile.js @@ -0,0 +1,71 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Handle all requests that deal with a users' profile + * + * @author Benjamin Hutchins + **/ +var Profile = { + windows: {}, // store all existent windows + + /** + * Create new window for a user's profile, + * load the user profile and append it inside the window + * + * @arguments + * name - username of user we're getting the profile of + * title - title for window, default is the user's username + * + * @author Benjamin Hutchins + **/ + create: function(name, title) { + var winLeft = Math.round(Math.random()*(Browser.width()-360))+'px'; + var winTop = Math.round(Math.random()*(Browser.height()-400))+'px'; + + var winId = randomString(32) + '_profile'; + + this.windows[name] = new Window({id: winId, className: "dialog", width: 320, height: 335, top: winTop, left: winLeft, resizable: true, title: title, draggable: true, detachable: false, minWidth: 320, minHeight: 150, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}}); + + this.windows[name].setConstraint(true, {left: 0, right: 0, top: 0, bottom: 0}); + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=getprofile&user="+name, + function(xh) { + Profile.windows[name].getContent().innerHTML = '
      ' + + (xh.responseText == "" ? Languages.get('hasNoProfile') : xh.responseText) + '
      ' + + '
      ' + + ButtonCtl.create(Languages.get('update'), 'Profile.update(\''+name+'\');') + + '
      '; + }.bind(name) + ); + //this.windows[name].setDestroyOnClose(); + this.windows[name].show(); + this.windows[name].toFront(); + Windows.focusedWindow = this.windows[name]; + }, + + /** + * Force-update a user's profile + * + * @arguments + * name - user's username + * + * @author Benjamin Hutchins + **/ + update: function(name) { + if ($(name+'_userProfile')) { + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=getprofile&user="+name, + function(xh) { + $(name+'_userProfile').innerHTML = (xh.responseText == "" ? Languages.get('hasNoProfile') : xh.responseText); + } + ); + } + } +}; diff --git a/js/prototype.js b/js/prototype.js new file mode 100644 index 0000000..949fa30 --- /dev/null +++ b/js/prototype.js @@ -0,0 +1,8 @@ +/* Prototype JavaScript framework, version 1.6.0.2 + * (c) 2005-2008 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * + *--------------------------------------------------------------------------*/ +var Prototype={Version:"1.6.0.2",Browser:{IE:!!(window.attachEvent&&!window.opera),Opera:!!window.opera,WebKit:navigator.userAgent.indexOf("AppleWebKit/")>-1,Gecko:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")==-1,MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)},BrowserFeatures:{XPath:!!document.evaluate,ElementExtensions:!!window.HTMLElement,SpecificElementExtensions:document.createElement("div").__proto__&&document.createElement("div").__proto__!==document.createElement("form").__proto__},ScriptFragment:"]*>([\\S\\s]*?)<\/script>",JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(A){return A}};if(Prototype.Browser.MobileSafari){Prototype.BrowserFeatures.SpecificElementExtensions=false}var Class={create:function(){var E=null,D=$A(arguments);if(Object.isFunction(D[0])){E=D.shift()}function A(){this.initialize.apply(this,arguments)}Object.extend(A,Class.Methods);A.superclass=E;A.subclasses=[];if(E){var B=function(){};B.prototype=E.prototype;A.prototype=new B;E.subclasses.push(A)}for(var C=0;C0){if(B=D.match(E)){A+=D.slice(0,B.index);A+=String.interpret(C(B));D=D.slice(B.index+B[0].length)}else{A+=D,D=""}}return A},sub:function(C,A,B){A=this.gsub.prepareReplacement(A);B=Object.isUndefined(B)?1:B;return this.gsub(C,function(D){if(--B<0){return D[0]}return A(D)})},scan:function(B,A){this.gsub(B,A);return String(this)},truncate:function(B,A){B=B||30;A=Object.isUndefined(A)?"...":A;return this.length>B?this.slice(0,B-A.length)+A:String(this)},strip:function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,"")},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,"img"),"")},extractScripts:function(){var B=new RegExp(Prototype.ScriptFragment,"img");var A=new RegExp(Prototype.ScriptFragment,"im");return(this.match(B)||[]).map(function(C){return(C.match(A)||["",""])[1]})},evalScripts:function(){return this.extractScripts().map(function(script){return eval(script)})},escapeHTML:function(){var A=arguments.callee;A.text.data=this;return A.div.innerHTML},unescapeHTML:function(){var A=new Element("div");A.innerHTML=this.stripTags();return A.childNodes[0]?(A.childNodes.length>1?$A(A.childNodes).inject("",function(B,C){return B+C.nodeValue}):A.childNodes[0].nodeValue):""},toQueryParams:function(B){var A=this.strip().match(/([^?#]*)(#.*)?$/);if(!A){return{}}return A[1].split(B||"&").inject({},function(E,F){if((F=F.split("="))[0]){var C=decodeURIComponent(F.shift());var D=F.length>1?F.join("="):F[0];if(D!=undefined){D=decodeURIComponent(D)}if(C in E){if(!Object.isArray(E[C])){E[C]=[E[C]]}E[C].push(D)}else{E[C]=D}}return E})},toArray:function(){return this.split("")},succ:function(){return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1)},times:function(A){return A<1?"":new Array(A+1).join(this)},camelize:function(){var D=this.split("-"),A=D.length;if(A==1){return D[0]}var C=this.charAt(0)=="-"?D[0].charAt(0).toUpperCase()+D[0].substring(1):D[0];for(var B=1;B-1},startsWith:function(A){return this.indexOf(A)===0},endsWith:function(A){var B=this.length-A.length;return B>=0&&this.lastIndexOf(A)===B},empty:function(){return this==""},blank:function(){return/^\s*$/.test(this)},interpolate:function(A,B){return new Template(this,B).evaluate(A)}});if(Prototype.Browser.WebKit||Prototype.Browser.IE){Object.extend(String.prototype,{escapeHTML:function(){return this.replace(/&/g,"&").replace(//g,">")},unescapeHTML:function(){return this.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}})}String.prototype.gsub.prepareReplacement=function(B){if(Object.isFunction(B)){return B}var A=new Template(B);return function(C){return A.evaluate(C)}};String.prototype.parseQuery=String.prototype.toQueryParams;Object.extend(String.prototype.escapeHTML,{div:document.createElement("div"),text:document.createTextNode("")});with(String.prototype.escapeHTML){div.appendChild(text)}var Template=Class.create({initialize:function(A,B){this.template=A.toString();this.pattern=B||Template.Pattern},evaluate:function(A){if(Object.isFunction(A.toTemplateReplacements)){A=A.toTemplateReplacements()}return this.template.gsub(this.pattern,function(D){if(A==null){return""}var F=D[1]||"";if(F=="\\"){return D[2]}var B=A,G=D[3];var E=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;D=E.exec(G);if(D==null){return F}while(D!=null){var C=D[1].startsWith("[")?D[2].gsub("\\\\]","]"):D[1];B=B[C];if(null==B||""==D[3]){break}G=G.substring("["==D[3]?D[1].length:D[0].length);D=E.exec(G)}return F+String.interpret(B)})}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable={each:function(C,B){var A=0;C=C.bind(B);try{this._each(function(E){C(E,A++)})}catch(D){if(D!=$break){throw D}}return this},eachSlice:function(D,C,B){C=C?C.bind(B):Prototype.K;var A=-D,E=[],F=this.toArray();while((A+=D)=A){A=E}});return A},min:function(C,B){C=C?C.bind(B):Prototype.K;var A;this.each(function(E,D){E=C(E,D);if(A==null||EC?1:0}).pluck("value")},toArray:function(){return this.map()},zip:function(){var B=Prototype.K,A=$A(arguments);if(Object.isFunction(A.last())){B=A.pop()}var C=[this].concat(A).map($A);return this.map(function(E,D){return B(C.pluck(D))})},size:function(){return this.toArray().length},inspect:function(){return"#"}};Object.extend(Enumerable,{map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,filter:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray,every:Enumerable.all,some:Enumerable.any});function $A(C){if(!C){return[]}if(C.toArray){return C.toArray()}var B=C.length||0,A=new Array(B);while(B--){A[B]=C[B]}return A}if(Prototype.Browser.WebKit){$A=function(C){if(!C){return[]}if(!(Object.isFunction(C)&&C=="[object NodeList]")&&C.toArray){return C.toArray()}var B=C.length||0,A=new Array(B);while(B--){A[B]=C[B]}return A}}Array.from=$A;Object.extend(Array.prototype,Enumerable);if(!Array.prototype._reverse){Array.prototype._reverse=Array.prototype.reverse}Object.extend(Array.prototype,{_each:function(B){for(var A=0,C=this.length;A1?this:this[0]},uniq:function(A){return this.inject([],function(D,C,B){if(0==B||(A?D.last()!=C:!D.include(C))){D.push(C)}return D})},intersect:function(A){return this.uniq().findAll(function(B){return A.detect(function(C){return B===C})})},clone:function(){return[].concat(this)},size:function(){return this.length},inspect:function(){return"["+this.map(Object.inspect).join(", ")+"]"},toJSON:function(){var A=[];this.each(function(B){var C=Object.toJSON(B);if(!Object.isUndefined(C)){A.push(C)}});return"["+A.join(", ")+"]"}});if(Object.isFunction(Array.prototype.forEach)){Array.prototype._each=Array.prototype.forEach}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(C,A){A||(A=0);var B=this.length;if(A<0){A=B+A}for(;A"},toJSON:function(){return Object.toJSON(this.toObject())},clone:function(){return new Hash(this)}}})());Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;Hash.from=$H;var ObjectRange=Class.create(Enumerable,{initialize:function(C,A,B){this.start=C;this.end=A;this.exclusive=B},_each:function(A){var B=this.start;while(this.include(B)){A(B);B=B.succ()}},include:function(A){if(A1&&!((A==4)&&this._complete)){this.respondToReadyState(this.transport.readyState)}},setRequestHeaders:function(){var E={"X-Requested-With":"XMLHttpRequest","X-Prototype-Version":Prototype.Version,"Accept":"text/javascript, text/html, application/xml, text/xml, */*"};if(this.method=="post"){E["Content-type"]=this.options.contentType+(this.options.encoding?"; charset="+this.options.encoding:"");if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){E["Connection"]="close"}}if(typeof this.options.requestHeaders=="object"){var C=this.options.requestHeaders;if(Object.isFunction(C.push)){for(var B=0,D=C.length;B=200&&A<300)},getStatus:function(){try{return this.transport.status||0}catch(A){return 0}},respondToReadyState:function(A){var C=Ajax.Request.Events[A],B=new Ajax.Response(this);if(C=="Complete"){try{this._complete=true;(this.options["on"+B.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(B,B.headerJSON)}catch(D){this.dispatchException(D)}var E=B.getHeader("Content-type");if(this.options.evalJS=="force"||(this.options.evalJS&&this.isSameOrigin()&&E&&E.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))){this.evalResponse()}}try{(this.options["on"+C]||Prototype.emptyFunction)(B,B.headerJSON);Ajax.Responders.dispatch("on"+C,this,B,B.headerJSON)}catch(D){this.dispatchException(D)}if(C=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}},isSameOrigin:function(){var A=this.url.match(/^\s*https?:\/\/[^\/]*/);return !A||(A[0]=="#{protocol}//#{domain}#{port}".interpolate({protocol:location.protocol,domain:document.domain,port:location.port?":"+location.port:""}))},getHeader:function(A){try{return this.transport.getResponseHeader(A)||null}catch(B){return null}},evalResponse:function(){try{return eval((this.transport.responseText||"").unfilterJSON())}catch(e){this.dispatchException(e)}},dispatchException:function(A){(this.options.onException||Prototype.emptyFunction)(this,A);Ajax.Responders.dispatch("onException",this,A)}});Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"];Ajax.Response=Class.create({initialize:function(C){this.request=C;var D=this.transport=C.transport,A=this.readyState=D.readyState;if((A>2&&!Prototype.Browser.IE)||A==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(D.responseText);this.headerJSON=this._getHeaderJSON()}if(A==4){var B=D.responseXML;this.responseXML=Object.isUndefined(B)?null:B;this.responseJSON=this._getResponseJSON()}},status:0,statusText:"",getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||""}catch(A){return""}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders()}catch(A){return null}},getResponseHeader:function(A){return this.transport.getResponseHeader(A)},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders()},_getHeaderJSON:function(){var A=this.getHeader("X-JSON");if(!A){return null}A=decodeURIComponent(escape(A));try{return A.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin())}catch(B){this.request.dispatchException(B)}},_getResponseJSON:function(){var A=this.request.options;if(!A.evalJSON||(A.evalJSON!="force"&&!(this.getHeader("Content-type")||"").include("application/json"))||this.responseText.blank()){return null}try{return this.responseText.evalJSON(A.sanitizeJSON||!this.request.isSameOrigin())}catch(B){this.request.dispatchException(B)}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,A,C,B){this.container={success:(A.success||A),failure:(A.failure||(A.success?null:A))};B=Object.clone(B);var D=B.onComplete;B.onComplete=(function(E,F){this.updateContent(E.responseText);if(Object.isFunction(D)){D(E,F)}}).bind(this);$super(C,B)},updateContent:function(D){var C=this.container[this.success()?"success":"failure"],A=this.options;if(!A.evalScripts){D=D.stripScripts()}if(C=$(C)){if(A.insertion){if(Object.isString(A.insertion)){var B={};B[A.insertion]=D;C.insert(B)}else{A.insertion(C,D)}}else{C.update(D)}}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,A,C,B){$super(B);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=A;this.url=C;this.start()},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent()},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments)},updateComplete:function(A){if(this.options.decay){this.decay=(A.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=A.responseText}this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency)},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options)}});function $(B){if(arguments.length>1){for(var A=0,D=[],C=arguments.length;A';delete C.name;return Element.writeAttribute(document.createElement(D),C)}if(!B[D]){B[D]=Element.extend(document.createElement(D))}return Element.writeAttribute(B[D].cloneNode(false),C)};Object.extend(this.Element,A||{})}).call(window);Element.cache={};Element.Methods={visible:function(A){return $(A).style.display!="none"},toggle:function(A){A=$(A);Element[Element.visible(A)?"hide":"show"](A);return A},hide:function(A){$(A).style.display="none";return A},show:function(A){$(A).style.display="";return A},remove:function(A){A=$(A);A.parentNode.removeChild(A);return A},update:function(A,B){A=$(A);if(B&&B.toElement){B=B.toElement()}if(Object.isElement(B)){return A.update().insert(B)}B=Object.toHTML(B);A.innerHTML=B.stripScripts();B.evalScripts.bind(B).defer();return A},replace:function(B,C){B=$(B);if(C&&C.toElement){C=C.toElement()}else{if(!Object.isElement(C)){C=Object.toHTML(C);var A=B.ownerDocument.createRange();A.selectNode(B);C.evalScripts.bind(C).defer();C=A.createContextualFragment(C.stripScripts())}}B.parentNode.replaceChild(C,B);return B},insert:function(C,E){C=$(C);if(Object.isString(E)||Object.isNumber(E)||Object.isElement(E)||(E&&(E.toElement||E.toHTML))){E={bottom:E}}var D,F,B,G;for(var A in E){D=E[A];A=A.toLowerCase();F=Element._insertionTranslations[A];if(D&&D.toElement){D=D.toElement()}if(Object.isElement(D)){F(C,D);continue}D=Object.toHTML(D);B=((A=="before"||A=="after")?C.parentNode:C).tagName.toUpperCase();G=Element._getContentFromAnonymousElement(B,D.stripScripts());if(A=="top"||A=="after"){G.reverse()}G.each(F.curry(C));D.evalScripts.bind(D).defer()}return C},wrap:function(B,C,A){B=$(B);if(Object.isElement(C)){$(C).writeAttribute(A||{})}else{if(Object.isString(C)){C=new Element(C,A)}else{C=new Element("div",C)}}if(B.parentNode){B.parentNode.replaceChild(C,B)}C.appendChild(B);return C},inspect:function(B){B=$(B);var A="<"+B.tagName.toLowerCase();$H({"id":"id","className":"class"}).each(function(F){var E=F.first(),C=F.last();var D=(B[E]||"").toString();if(D){A+=" "+C+"="+D.inspect(true)}});return A+">"},recursivelyCollect:function(A,C){A=$(A);var B=[];while(A=A[C]){if(A.nodeType==1){B.push(Element.extend(A))}}return B},ancestors:function(A){return $(A).recursivelyCollect("parentNode")},descendants:function(A){return $(A).select("*")},firstDescendant:function(A){A=$(A).firstChild;while(A&&A.nodeType!=1){A=A.nextSibling}return $(A)},immediateDescendants:function(A){if(!(A=$(A).firstChild)){return[]}while(A&&A.nodeType!=1){A=A.nextSibling}if(A){return[A].concat($(A).nextSiblings())}return[]},previousSiblings:function(A){return $(A).recursivelyCollect("previousSibling")},nextSiblings:function(A){return $(A).recursivelyCollect("nextSibling")},siblings:function(A){A=$(A);return A.previousSiblings().reverse().concat(A.nextSiblings())},match:function(B,A){if(Object.isString(A)){A=new Selector(A)}return A.match($(B))},up:function(B,D,A){B=$(B);if(arguments.length==1){return $(B.parentNode)}var C=B.ancestors();return Object.isNumber(D)?C[D]:Selector.findElement(C,D,A)},down:function(B,C,A){B=$(B);if(arguments.length==1){return B.firstDescendant()}return Object.isNumber(C)?B.descendants()[C]:B.select(C)[A||0]},previous:function(B,D,A){B=$(B);if(arguments.length==1){return $(Selector.handlers.previousElementSibling(B))}var C=B.previousSiblings();return Object.isNumber(D)?C[D]:Selector.findElement(C,D,A)},next:function(C,D,B){C=$(C);if(arguments.length==1){return $(Selector.handlers.nextElementSibling(C))}var A=C.nextSiblings();return Object.isNumber(D)?A[D]:Selector.findElement(A,D,B)},select:function(){var A=$A(arguments),B=$(A.shift());return Selector.findChildElements(B,A)},adjacent:function(){var A=$A(arguments),B=$(A.shift());return Selector.findChildElements(B.parentNode,A).without(B)},identify:function(B){B=$(B);var C=B.readAttribute("id"),A=arguments.callee;if(C){return C}do{C="anonymous_element_"+A.counter++}while($(C));B.writeAttribute("id",C);return C},readAttribute:function(C,A){C=$(C);if(Prototype.Browser.IE){var B=Element._attributeTranslations.read;if(B.values[A]){return B.values[A](C,A)}if(B.names[A]){A=B.names[A]}if(A.include(":")){return(!C.attributes||!C.attributes[A])?null:C.attributes[A].value}}return C.getAttribute(A)},writeAttribute:function(E,C,F){E=$(E);var B={},D=Element._attributeTranslations.write;if(typeof C=="object"){B=C}else{B[C]=Object.isUndefined(F)?true:F}for(var A in B){C=D.names[A]||A;F=B[A];if(D.values[A]){C=D.values[A](E,F)}if(F===false||F===null){E.removeAttribute(C)}else{if(F===true){E.setAttribute(C,C)}else{E.setAttribute(C,F)}}}return E},getHeight:function(A){return $(A).getDimensions().height},getWidth:function(A){return $(A).getDimensions().width},classNames:function(A){return new Element.ClassNames(A)},hasClassName:function(A,B){if(!(A=$(A))){return }var C=A.className;return(C.length>0&&(C==B||new RegExp("(^|\\s)"+B+"(\\s|$)").test(C)))},addClassName:function(A,B){if(!(A=$(A))){return }if(!A.hasClassName(B)){A.className+=(A.className?" ":"")+B}return A},removeClassName:function(A,B){if(!(A=$(A))){return }A.className=A.className.replace(new RegExp("(^|\\s+)"+B+"(\\s+|$)")," ").strip();return A},toggleClassName:function(A,B){if(!(A=$(A))){return }return A[A.hasClassName(B)?"removeClassName":"addClassName"](B)},cleanWhitespace:function(B){B=$(B);var C=B.firstChild;while(C){var A=C.nextSibling;if(C.nodeType==3&&!/\S/.test(C.nodeValue)){B.removeChild(C)}C=A}return B},empty:function(A){return $(A).innerHTML.blank()},descendantOf:function(D,C){D=$(D),C=$(C);var F=C;if(D.compareDocumentPosition){return(D.compareDocumentPosition(C)&8)===8}if(D.sourceIndex&&!Prototype.Browser.Opera){var E=D.sourceIndex,B=C.sourceIndex,A=C.nextSibling;if(!A){do{C=C.parentNode}while(!(A=C.nextSibling)&&C.parentNode)}if(A&&A.sourceIndex){return(E>B&&E","",1],TBODY:["","
      ",2],TR:["","
      ",3],TD:["
      ","
      ",4],SELECT:["",1]}};(function(){Object.extend(this.tags,{THEAD:this.tags.TBODY,TFOOT:this.tags.TBODY,TH:this.tags.TD})}).call(Element._insertionTranslations);Element.Methods.Simulated={hasAttribute:function(A,C){C=Element._attributeTranslations.has[C]||C;var B=$(A).getAttributeNode(C);return B&&B.specified}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);if(!Prototype.BrowserFeatures.ElementExtensions&&document.createElement("div").__proto__){window.HTMLElement={};window.HTMLElement.prototype=document.createElement("div").__proto__;Prototype.BrowserFeatures.ElementExtensions=true}Element.extend=(function(){if(Prototype.BrowserFeatures.SpecificElementExtensions){return Prototype.K}var A={},B=Element.Methods.ByTag;var C=Object.extend(function(F){if(!F||F._extendedByPrototype||F.nodeType!=1||F==window){return F}var D=Object.clone(A),E=F.tagName,H,G;if(B[E]){Object.extend(D,B[E])}for(H in D){G=D[H];if(Object.isFunction(G)&&!(H in F)){F[H]=G.methodize()}}F._extendedByPrototype=Prototype.emptyFunction;return F},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(A,Element.Methods);Object.extend(A,Element.Methods.Simulated)}}});C.refresh();return C})();Element.hasAttribute=function(A,B){if(A.hasAttribute){return A.hasAttribute(B)}return Element.Methods.Simulated.hasAttribute(A,B)};Element.addMethods=function(C){var I=Prototype.BrowserFeatures,D=Element.Methods.ByTag;if(!C){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{"FORM":Object.clone(Form.Methods),"INPUT":Object.clone(Form.Element.Methods),"SELECT":Object.clone(Form.Element.Methods),"TEXTAREA":Object.clone(Form.Element.Methods)})}if(arguments.length==2){var B=C;C=arguments[1]}if(!B){Object.extend(Element.Methods,C||{})}else{if(Object.isArray(B)){B.each(H)}else{H(B)}}function H(F){F=F.toUpperCase();if(!Element.Methods.ByTag[F]){Element.Methods.ByTag[F]={}}Object.extend(Element.Methods.ByTag[F],C)}function A(L,K,F){F=F||false;for(var N in L){var M=L[N];if(!Object.isFunction(M)){continue}if(!F||!(N in K)){K[N]=M.methodize()}}}function E(L){var F;var K={"OPTGROUP":"OptGroup","TEXTAREA":"TextArea","P":"Paragraph","FIELDSET":"FieldSet","UL":"UList","OL":"OList","DL":"DList","DIR":"Directory","H1":"Heading","H2":"Heading","H3":"Heading","H4":"Heading","H5":"Heading","H6":"Heading","Q":"Quote","INS":"Mod","DEL":"Mod","A":"Anchor","IMG":"Image","CAPTION":"TableCaption","COL":"TableCol","COLGROUP":"TableCol","THEAD":"TableSection","TFOOT":"TableSection","TBODY":"TableSection","TR":"TableRow","TH":"TableCell","TD":"TableCell","FRAMESET":"FrameSet","IFRAME":"IFrame"};if(K[L]){F="HTML"+K[L]+"Element"}if(window[F]){return window[F]}F="HTML"+L+"Element";if(window[F]){return window[F]}F="HTML"+L.capitalize()+"Element";if(window[F]){return window[F]}window[F]={};window[F].prototype=document.createElement(L).__proto__;return window[F]}if(I.ElementExtensions){A(Element.Methods,HTMLElement.prototype);A(Element.Methods.Simulated,HTMLElement.prototype,true)}if(I.SpecificElementExtensions){for(var J in Element.Methods.ByTag){var G=E(J);if(Object.isUndefined(G)){continue}A(D[J],G.prototype)}}Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh){Element.extend.refresh()}Element.cache={}};document.viewport={getDimensions:function(){var A={};var C=Prototype.Browser;$w("width height").each(function(E){var B=E.capitalize();A[E]=(C.WebKit&&!document.evaluate)?self["inner"+B]:(C.Opera)?document.body["client"+B]:document.documentElement["client"+B]});return A},getWidth:function(){return this.getDimensions().width},getHeight:function(){return this.getDimensions().height},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop)}};var Selector=Class.create({initialize:function(A){this.expression=A.strip();this.compileMatcher()},shouldUseXPath:function(){if(!Prototype.BrowserFeatures.XPath){return false}var A=this.expression;if(Prototype.Browser.WebKit&&(A.include("-of-type")||A.include(":empty"))){return false}if((/(\[[\w-]*?:|:checked)/).test(this.expression)){return false}return true},compileMatcher:function(){if(this.shouldUseXPath()){return this.compileXPathMatcher()}var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m;if(Selector._cache[e]){this.matcher=Selector._cache[e];return }this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in ps){p=ps[i];if(m=e.match(p)){this.matcher.push(Object.isFunction(c[i])?c[i](m):new Template(c[i]).evaluate(m));e=e.replace(m[0],"");break}}}this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join("\n"));Selector._cache[this.expression]=this.matcher},compileXPathMatcher:function(){var E=this.expression,F=Selector.patterns,B=Selector.xpath,D,A;if(Selector._cache[E]){this.xpath=Selector._cache[E];return }this.matcher=[".//*"];while(E&&D!=E&&(/\S/).test(E)){D=E;for(var C in F){if(A=E.match(F[C])){this.matcher.push(Object.isFunction(B[C])?B[C](A):new Template(B[C]).evaluate(A));E=E.replace(A[0],"");break}}}this.xpath=this.matcher.join("");Selector._cache[this.expression]=this.xpath},findElements:function(A){A=A||document;if(this.xpath){return document._getElementsByXPath(this.xpath,A)}return this.matcher(A)},match:function(H){this.tokens=[];var L=this.expression,A=Selector.patterns,E=Selector.assertions;var B,D,F;while(L&&B!==L&&(/\S/).test(L)){B=L;for(var I in A){D=A[I];if(F=L.match(D)){if(E[I]){this.tokens.push([I,Object.clone(F)]);L=L.replace(F[0],"")}else{return this.findElements(document).include(H)}}}}var K=true,C,J;for(var I=0,G;G=this.tokens[I];I++){C=G[0],J=G[1];if(!Selector.assertions[C](H,J)){K=false;break}}return K},toString:function(){return this.expression},inspect:function(){return"#"}});Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:"/following-sibling::*",tagName:function(A){if(A[1]=="*"){return""}return"[local-name()='"+A[1].toLowerCase()+"' or local-name()='"+A[1].toUpperCase()+"']"},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(A){A[1]=A[1].toLowerCase();return new Template("[@#{1}]").evaluate(A)},attr:function(A){A[1]=A[1].toLowerCase();A[3]=A[5]||A[6];return new Template(Selector.xpath.operators[A[2]]).evaluate(A)},pseudo:function(A){var B=Selector.xpath.pseudos[A[1]];if(!B){return""}if(Object.isFunction(B)){return B(A)}return new Template(Selector.xpath.pseudos[A[1]]).evaluate(A)},operators:{"=":"[@#{1}='#{3}']","!=":"[@#{1}!='#{3}']","^=":"[starts-with(@#{1}, '#{3}')]","$=":"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']","*=":"[contains(@#{1}, '#{3}')]","~=":"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]","|=":"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{"first-child":"[not(preceding-sibling::*)]","last-child":"[not(following-sibling::*)]","only-child":"[not(preceding-sibling::* or following-sibling::*)]","empty":"[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]","checked":"[@checked]","disabled":"[@disabled]","enabled":"[not(@disabled)]","not":function(B){var H=B[6],G=Selector.patterns,A=Selector.xpath,E,C;var F=[];while(H&&E!=H&&(/\S/).test(H)){E=H;for(var D in G){if(B=H.match(G[D])){C=Object.isFunction(A[D])?A[D](B):new Template(A[D]).evaluate(B);F.push("("+C.substring(1,C.length-1)+")");H=H.replace(B[0],"");break}}}return"[not("+F.join(" and ")+")]"},"nth-child":function(A){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",A)},"nth-last-child":function(A){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",A)},"nth-of-type":function(A){return Selector.xpath.pseudos.nth("position() ",A)},"nth-last-of-type":function(A){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",A)},"first-of-type":function(A){A[6]="1";return Selector.xpath.pseudos["nth-of-type"](A)},"last-of-type":function(A){A[6]="1";return Selector.xpath.pseudos["nth-last-of-type"](A)},"only-of-type":function(A){var B=Selector.xpath.pseudos;return B["first-of-type"](A)+B["last-of-type"](A)},nth:function(E,C){var F,G=C[6],B;if(G=="even"){G="2n+0"}if(G=="odd"){G="2n+1"}if(F=G.match(/^(\d+)$/)){return"["+E+"= "+F[1]+"]"}if(F=G.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(F[1]=="-"){F[1]=-1}var D=F[1]?Number(F[1]):1;var A=F[2]?Number(F[2]):0;B="[((#{fragment} - #{b}) mod #{a} = 0) and ((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(B).evaluate({fragment:E,a:D,b:A})}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c); c = false;',className:'n = h.className(n, r, "#{1}", c); c = false;',id:'n = h.id(n, r, "#{1}", c); c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',attr:function(A){A[3]=(A[5]||A[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(A)},pseudo:function(A){if(A[6]){A[6]=A[6].replace(/"/g,'\\"')}return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(A)},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:{laterSibling:/^\s*~\s*/,child:/^\s*>\s*/,adjacent:/^\s*\+\s*/,descendant:/^\s/,tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,id:/^#([\w\-\*]+)(\b|$)/,className:/^\.([\w\-\*]+)(\b|$)/,pseudo:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,attrPresence:/^\[([\w]+)\]/,attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/},assertions:{tagName:function(A,B){return B[1].toUpperCase()==A.tagName.toUpperCase()},className:function(A,B){return Element.hasClassName(A,B[1])},id:function(A,B){return A.id===B[1]},attrPresence:function(A,B){return Element.hasAttribute(A,B[1])},attr:function(B,C){var A=Element.readAttribute(B,C[1]);return A&&Selector.operators[C[2]](A,C[5]||C[6])}},handlers:{concat:function(B,A){for(var C=0,D;D=A[C];C++){B.push(D)}return B},mark:function(A){var D=Prototype.emptyFunction;for(var B=0,C;C=A[B];B++){C._countedByPrototype=D}return A},unmark:function(A){for(var B=0,C;C=A[B];B++){C._countedByPrototype=undefined}return A},index:function(A,D,G){A._countedByPrototype=Prototype.emptyFunction;if(D){for(var B=A.childNodes,E=B.length-1,C=1;E>=0;E--){var F=B[E];if(F.nodeType==1&&(!G||F._countedByPrototype)){F.nodeIndex=C++}}}else{for(var E=0,C=1,B=A.childNodes;F=B[E];E++){if(F.nodeType==1&&(!G||F._countedByPrototype)){F.nodeIndex=C++}}}},unique:function(B){if(B.length==0){return B}var D=[],E;for(var C=0,A=B.length;C0?[A]:[]}return $R(1,C).inject([],function(D,E){if(0==(E-A)%B&&(E-A)/B>=0){D.push(E)}return D})},nth:function(A,L,N,K,C){if(A.length==0){return[]}if(L=="even"){L="2n+0"}if(L=="odd"){L="2n+1"}var J=Selector.handlers,I=[],B=[],E;J.mark(A);for(var H=0,D;D=A[H];H++){if(!D.parentNode._countedByPrototype){J.index(D.parentNode,K,C);B.push(D.parentNode)}}if(L.match(/^\d+$/)){L=Number(L);for(var H=0,D;D=A[H];H++){if(D.nodeIndex==L){I.push(D)}}}else{if(E=L.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(E[1]=="-"){E[1]=-1}var O=E[1]?Number(E[1]):1;var M=E[2]?Number(E[2]):0;var P=Selector.pseudos.getIndices(O,M,A.length);for(var H=0,D,F=P.length;D=A[H];H++){for(var G=0;G+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(C){A.push(C[1].strip())});return A},matchElements:function(F,G){var E=$$(G),D=Selector.handlers;D.mark(E);for(var C=0,B=[],A;A=F[C];C++){if(A._countedByPrototype){B.push(A)}}D.unmark(E);return B},findElement:function(B,C,A){if(Object.isNumber(C)){A=C;C=false}return Selector.matchElements(B,C||"*")[A||0]},findChildElements:function(E,G){G=Selector.split(G.join(","));var D=[],F=Selector.handlers;for(var C=0,B=G.length,A;C1)?F.unique(D):D}});if(Prototype.Browser.IE){Object.extend(Selector.handlers,{concat:function(B,A){for(var C=0,D;D=A[C];C++){if(D.tagName!=="!"){B.push(D)}}return B},unmark:function(A){for(var B=0,C;C=A[B];B++){C.removeAttribute("_countedByPrototype")}return A}})}function $$(){return Selector.findChildElements(document,$A(arguments))}var Form={reset:function(A){$(A).reset();return A},serializeElements:function(G,B){if(typeof B!="object"){B={hash:!!B}}else{if(Object.isUndefined(B.hash)){B.hash=true}}var C,F,A=false,E=B.submit;var D=G.inject({},function(H,I){if(!I.disabled&&I.name){C=I.name;F=$(I).getValue();if(F!=null&&(I.type!="submit"||(!A&&E!==false&&(!E||C==E)&&(A=true)))){if(C in H){if(!Object.isArray(H[C])){H[C]=[H[C]]}H[C].push(F)}else{H[C]=F}}}return H});return B.hash?D:Object.toQueryString(D)}};Form.Methods={serialize:function(B,A){return Form.serializeElements(Form.getElements(B),A)},getElements:function(A){return $A($(A).getElementsByTagName("*")).inject([],function(B,C){if(Form.Element.Serializers[C.tagName.toLowerCase()]){B.push(Element.extend(C))}return B})},getInputs:function(G,C,D){G=$(G);var A=G.getElementsByTagName("input");if(!C&&!D){return $A(A).map(Element.extend)}for(var E=0,H=[],F=A.length;E=0}).sortBy(function(D){return D.tabIndex}).first();return A?A:C.find(function(D){return["input","select","textarea"].include(D.tagName.toLowerCase())})},focusFirstElement:function(A){A=$(A);A.findFirstElement().activate();return A},request:function(B,A){B=$(B),A=Object.clone(A||{});var D=A.parameters,C=B.readAttribute("action")||"";if(C.blank()){C=window.location.href}A.parameters=B.serialize(true);if(D){if(Object.isString(D)){D=D.toQueryParams()}Object.extend(A.parameters,D)}if(B.hasAttribute("method")&&!A.method){A.method=B.method}return new Ajax.Request(C,A)}};Form.Element={focus:function(A){$(A).focus();return A},select:function(A){$(A).select();return A}};Form.Element.Methods={serialize:function(A){A=$(A);if(!A.disabled&&A.name){var B=A.getValue();if(B!=undefined){var C={};C[A.name]=B;return Object.toQueryString(C)}}return""},getValue:function(A){A=$(A);var B=A.tagName.toLowerCase();return Form.Element.Serializers[B](A)},setValue:function(A,B){A=$(A);var C=A.tagName.toLowerCase();Form.Element.Serializers[C](A,B);return A},clear:function(A){$(A).value="";return A},present:function(A){return $(A).value!=""},activate:function(A){A=$(A);try{A.focus();if(A.select&&(A.tagName.toLowerCase()!="input"||!["button","reset","submit"].include(A.type))){A.select()}}catch(B){}return A},disable:function(A){A=$(A);A.blur();A.disabled=true;return A},enable:function(A){A=$(A);A.disabled=false;return A}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(A,B){switch(A.type.toLowerCase()){case"checkbox":case"radio":return Form.Element.Serializers.inputSelector(A,B);default:return Form.Element.Serializers.textarea(A,B)}},inputSelector:function(A,B){if(Object.isUndefined(B)){return A.checked?A.value:null}else{A.checked=!!B}},textarea:function(A,B){if(Object.isUndefined(B)){return A.value}else{A.value=B}},select:function(D,A){if(Object.isUndefined(A)){return this[D.type=="select-one"?"selectOne":"selectMany"](D)}else{var C,F,G=!Object.isArray(A);for(var B=0,E=D.length;B=0?this.optionValue(B.options[A]):null},selectMany:function(D){var A,E=D.length;if(!E){return null}for(var C=0,A=[];C<\/script>");$("__onDOMContentLoaded").onreadystatechange=function(){if(this.readyState=="complete"){this.onreadystatechange=null;A()}}}})();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(A,B){return Element.insert(A,{before:B})},Top:function(A,B){return Element.insert(A,{top:B})},Bottom:function(A,B){return Element.insert(A,{bottom:B})},After:function(A,B){return Element.insert(A,{after:B})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(B,A,C){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(B,A,C)}this.xcomp=A;this.ycomp=C;this.offset=Element.cumulativeOffset(B);return(C>=this.offset[1]&&C=this.offset[0]&&A=this.offset[1]&&this.ycomp=this.offset[0]&&this.xcomp0})._each(A)},set:function(A){this.element.className=A},add:function(A){if(this.include(A)){return }this.set($A(this).concat(A).join(" "))},remove:function(A){if(!this.include(A)){return }this.set($A(this).without(A).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);Element.addMethods() \ No newline at end of file diff --git a/js/sm2.js b/js/sm2.js new file mode 100644 index 0000000..265f7c0 --- /dev/null +++ b/js/sm2.js @@ -0,0 +1,12 @@ +/* + SoundManager 2: Javascript Sound for the Web + -------------------------------------------- + http://www.schillmania.com/projects/soundmanager2/ + + Copyright (c) 2007, Scott Schiller. All rights reserved. + Code licensed under the BSD License: + http://www.schillmania.com/projects/soundmanager2/license.txt + + V2.0b.20070415 +*/ +function SoundManager(B,A){var C=this;this.version="V2.0b.20070415";this.url=(B||"soundmanager2.swf");this.debugMode=false;this.useConsole=true;this.consoleOnly=false;this.nullURL="data/null.mp3";this.defaultOptions={"autoLoad":false,"stream":true,"autoPlay":false,"onid3":null,"onload":null,"whileloading":null,"onplay":null,"whileplaying":null,"onstop":null,"onfinish":null,"onbeforefinish":null,"onbeforefinishtime":5000,"onbeforefinishcomplete":null,"onjustbeforefinish":null,"onjustbeforefinishtime":200,"multiShot":true,"pan":0,"volume":100};this.allowPolling=true;this.enabled=false;this.o=null;this.id=(A||"sm2movie");this.oMC=null;this.sounds=[];this.soundIDs=[];this.isIE=(navigator.userAgent.match(/MSIE/));this.isSafari=(navigator.userAgent.match(/safari/i));this.debugID="soundmanager-debug";this._debugOpen=true;this._didAppend=false;this._appendSuccess=false;this._didInit=false;this._disabled=false;this._hasConsole=(typeof console!="undefined"&&typeof console.log!="undefined");this._debugLevels=!C.isSafari?["debug","info","warn","error"]:["log","log","log","log"];this.getMovie=function(D){return C.isIE?window[D]:(C.isSafari?document[D+"-embed"]:document.getElementById(D+"-embed"))};this.loadFromXML=function(D){try{C.o._loadFromXML(D)}catch(E){C._failSafely();return true}};this.createSound=function(D){if(!C._didInit){throw new Error("soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods")}if(arguments.length==2){D={"id":arguments[0],"url":arguments[1]}}var E=C._mergeObjects(D);C._writeDebug('soundManager.createSound(): "'+E.id+'" ('+E.url+")",1);if(C._idCheck(E.id,true)){C._writeDebug("sound "+E.id+" already defined - exiting",2);return false}C.sounds[E.id]=new SMSound(C,E);C.soundIDs[C.soundIDs.length]=E.id;try{C.o._createSound(E.id,E.onjustbeforefinishtime)}catch(F){C._failSafely();return true}if(E.autoLoad||E.autoPlay){C.sounds[E.id].load(E)}if(E.autoPlay){C.sounds[E.id].playState=1}};this.destroySound=function(D){if(!C._idCheck(D)){return false}for(var E=C.soundIDs.length;E--;){if(C.soundIDs[E]==D){delete C.soundIDs[E];continue}}C.sounds[D].unload();delete C.sounds[D]};this.load=function(D,E){if(!C._idCheck(D)){return false}C.sounds[D].load(E)};this.unload=function(D){if(!C._idCheck(D)){return false}C.sounds[D].unload()};this.play=function(D,E){if(!C._idCheck(D)){if(typeof E!="Object"){E={url:E}}if(E&&E.url){C._writeDebug('soundController.play(): attempting to create "'+D+'"',1);E.id=D;C.createSound(E)}else{return false}}C.sounds[D].play(E)};this.start=this.play;this.setPosition=function(D,E){if(!C._idCheck(D)){return false}C.sounds[D].setPosition(E)};this.stop=function(D){if(!C._idCheck(D)){return false}C._writeDebug("soundManager.stop("+D+")",1);C.sounds[D].stop()};this.stopAll=function(){C._writeDebug("soundManager.stopAll()",1);for(var D in C.sounds){if(C.sounds[D] instanceof SMSound){C.sounds[D].stop()}}};this.pause=function(D){if(!C._idCheck(D)){return false}C.sounds[D].pause()};this.resume=function(D){if(!C._idCheck(D)){return false}C.sounds[D].resume()};this.togglePause=function(D){if(!C._idCheck(D)){return false}C.sounds[D].togglePause()};this.setPan=function(D,E){if(!C._idCheck(D)){return false}C.sounds[D].setPan(E)};this.setVolume=function(E,D){if(!C._idCheck(E)){return false}C.sounds[E].setVolume(D)};this.setPolling=function(D){if(!C.o||!C.allowPolling){return false}C._writeDebug("soundManager.setPolling("+D+")");C.o._setPolling(D)};this.disable=function(){if(C._disabled){return false}C._disabled=true;C._writeDebug("soundManager.disable(): Disabling all functions - future calls will return false.",1);for(var D=C.soundIDs.length;D--;){C._disableObject(C.sounds[C.soundIDs[D]])}C.initComplete();C._disableObject(C)};this.getSoundById=function(E,F){if(!E){throw new Error("SoundManager.getSoundById(): sID is null/undefined")}var D=C.sounds[E];if(!D&&!F){C._writeDebug('"'+E+'" is an invalid sound ID.',2)}return D};this.onload=function(){soundManager._writeDebug("Warning: soundManager.onload() is undefined.",2)};this.onerror=function(){};this._idCheck=this.getSoundById;this._disableObject=function(E){for(var D in E){if(typeof E[D]=="function"&&typeof E[D]._protected=="undefined"){E[D]=function(){return false}}}D=null};this._failSafely=function(){var F="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html";var G="You may need to whitelist this location/domain eg. file:///C:/ or C:/ or mysite.com, or set ALWAYS ALLOW under the Flash Player Global Security Settings page. Note that this seems to apply only to file system viewing.";var E='view/edit';var D='FPGSS';if(!C._disabled){C._writeDebug("soundManager: JS->Flash communication failed. Possible causes: flash/browser security restrictions ("+E+"), insufficient browser/plugin support, or .swf not found",2);C._writeDebug("Verify that the movie path of "+C.url+' is correct (test link)',1);if(C._didAppend){if(!document.domain){C._writeDebug("Loading from local file system? (document.domain appears to be null, this URL path may need to be added to 'trusted locations' in "+D+")",1);C._writeDebug("Possible security/domain restrictions ("+E+"), should work when served by http on same domain",1)}}C.disable()}};this._createMovie=function(F,E){if(C._didAppend&&C._appendSuccess){return false}if(window.location.href.indexOf("debug=1")+1){C.debugMode=true}C._didAppend=true;var J=['',''];var M='
      -
      ';var K='
      ';var I="soundManager._createMovie(): appendChild/innerHTML set failed. Serving application/xhtml+xml MIME type? Browser may be enforcing strict rules, not allowing write to innerHTML. (PS: If so, this means your commitment to XML validation is going to break stuff now, because this part isn't finished yet. ;))";var G='
      '+J[C.isIE?0:1]+"
      "+(C.debugMode&&((!C._hasConsole||!C.useConsole)||(C.useConsole&&C._hasConsole&&!C.consoleOnly))&&!document.getElementById(C.debugID)?"x"+K+M:"");var D=(document.body?document.body:document.getElementsByTagName("div")[0]);if(D){C.oMC=document.createElement("div");C.oMC.className="movieContainer";C.oMC.style.position="absolute";C.oMC.style.left="-256px";C.oMC.style.width="1px";C.oMC.style.height="1px";try{D.appendChild(C.oMC);C.oMC.innerHTML=J[C.isIE?0:1];C._appendSuccess=true}catch(L){throw new Error(I)}if(!document.getElementById(C.debugID)&&((!C._hasConsole||!C.useConsole)||(C.useConsole&&C._hasConsole&&!C.consoleOnly))){var N=document.createElement("div");N.id=C.debugID;N.style.display=(C.debugMode?"block":"none");if(C.debugMode){try{var H=document.createElement("div");D.appendChild(H);H.innerHTML=M}catch(L){throw new Error(I)}}D.appendChild(N)}D=null}C._writeDebug("-- SoundManager 2 Version "+C.version.substr(1)+" --",1);C._writeDebug('soundManager._createMovie(): trying to load '+E+"",1)};this._writeDebug=function(D,I){if(!C.debugMode){return false}if(C._hasConsole&&C.useConsole){console[C._debugLevels[I]||"log"](D);if(C.useConsoleOnly){return true}}var H="soundmanager-debug";try{var G=document.getElementById(H);if(!G){return false}var F=document.createElement("div");F.innerHTML=D;G.insertBefore(F,G.firstChild)}catch(E){}G=null};this._writeDebug._protected=true;this._writeDebugAlert=function(D){alert(D)};if(window.location.href.indexOf("debug=alert")+1){C.debugMode=true;C._writeDebug=C._writeDebugAlert}this._toggleDebug=function(){var E=document.getElementById(C.debugID);var D=document.getElementById(C.debugID+"-toggle");if(!E){return false}if(C._debugOpen){D.innerHTML="+";E.style.display="none"}else{D.innerHTML="-";E.style.display="block"}C._debugOpen=!C._debugOpen};this._toggleDebug._protected=true;this._debug=function(){C._writeDebug("soundManager._debug(): sounds by id/url:",0);for(var E=0,D=C.soundIDs.length;Etest URL]'));A.loaded=E;A.loadSuccess=E;A.readyState=E?3:2;if(A.options.onload){A.options.onload.apply(A)}};this._onbeforefinish=function(){if(!A.didBeforeFinish){A.didBeforeFinish=true;if(A.options.onbeforefinish){A.options.onbeforefinish.apply(A)}}};this._onjustbeforefinish=function(E){if(!A.didJustBeforeFinish){A.didJustBeforeFinish=true;if(A.options.onjustbeforefinish){A.options.onjustbeforefinish.apply(A)}}};this._onfinish=function(){D._writeDebug('SMSound._onfinish(): "'+A.sID+'"');A.playState=0;A.paused=false;if(A.options.onfinish){A.options.onfinish.apply(A)}if(A.options.onbeforefinishcomplete){A.options.onbeforefinishcomplete.apply(A)}A.setPosition(0);A.didBeforeFinish=false;A.didJustBeforeFinish=false}} \ No newline at end of file diff --git a/js/status.js b/js/status.js new file mode 100644 index 0000000..312f0ae --- /dev/null +++ b/js/status.js @@ -0,0 +1,91 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Handles user status changes + **/ +var Status = { + state: 0, // current status + awayMessage: '', // away message + wasSetAutoAway: false, // did you get set as away because you were being antisocial? + lastIM: null, // timestamp of the last IM you sent + + /** + * Change your status + * + * @arguments + * status - status [0=online, 1=away, 99=friends only, 49=invisible] + * away_msg - away message to use + * + * @author Joshua Gross + **/ + set: function(status, away_msg) { + lastIM = new Date().getTime(); + if(status == 1) { // away + this.state = 1; + this.awayMessage = away_msg; + $('curStatus').innerHTML = this.awayMessage.substring(0, 30) + (this.awayMessage.length > 30 ? '...' : ''); + } else { // back + this.state = status; // 0 for avail, 99 for "friends only", 49 for "invisible" + this.awayMessage = ''; + $('curStatus').innerHTML = away_msg; + } + + $('statusList').hide(); + }, + + /** + * Display entry box to allow the user to enter + * a custom away message. + * + * @author Joshua Gross + **/ + customAway: function() { + $('curStatus').hide(); + $('customStatus').show().focus(); + }, + + /** + * Handle keyboard entires on customStatus. + * + * @arguments + * event - sent by browser + * + * @author Joshua Gross + **/ + processCustomAway: function(event) { + event = event || event.window; + var asc = document.all ? event.keyCode : event.which; + + if(asc == 13) { + awayMessage = $('customStatus').value; + $('curStatus').innerHTML = awayMessage.substring(0, 30) + (awayMessage.length > 30 ? '...' : ''); + $('curStatus').show(); + $('customStatus').hide(); + + Status.set(1, awayMessage); + } + return asc != 13; + }, + + /** + * Display/Hide the status drop down list + * + * @author Joshua Gross + **/ + toggleStatusList: function() { + var sL = $('statusList'); + if(sL.style.display == 'block') { + sL.hide(); + if(sL.style.zIndex > Windows.maxZIndex) Windows.maxZIndex = sL.style.zIndex; + } else { + Element.setStyle(sL, {left: parseInt(Buddylist.buddyListWin.getLocation()['left']) + $('statusSettings').offsetLeft + $('blTopToolbar').offsetLeft + 'px', top: parseInt(Buddylist.buddyListWin.getLocation()['top']) + $('statusSettings').offsetTop + $('blTopToolbar').offsetTop + $('statusSettings').offsetHeight + 'px', zIndex: Windows.maxZIndex + 20, display: 'block'}); + } + } +}; diff --git a/js/system.js b/js/system.js new file mode 100644 index 0000000..f5f7bd5 --- /dev/null +++ b/js/system.js @@ -0,0 +1,611 @@ +/////////////////////////////////// +// ajax im 3.41 // +// AJAX Instant Messenger // +// Copyright (c) 2006-2008 // +// http://www.ajaxim.com/ // +// Do not remove this notice // +/////////////////////////////////// + + +/** + * Handles session and most requests to the server + * + **/ +var System = { + /** + * Checks to see if a login is valid and, + * if so logs the user in, else it shows an error. + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + login: function(u, p) { + var username = (u ? u : $('username').value); + var password = (p ? p : $('password').value); + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=login&username="+username+"&password="+hex_md5(password), + function(xh) { + if(xh.responseText == 'invalid' || xh.responseText == 'banned') { + $('login_error_msg').innerHTML = (xh.responseText == 'invalid' ? Languages.get('incorrectInfo') : Languages.get('userBanned')); + $('login_error_msg').show(); + new Effect.Shake('modal'); + } else { + loggedIn = true; + user = username; + pass = hex_md5(password); + defaultTitle = document.title = document.title + ': ' + user; + + $('languageList').hide(); + + if(typeof(Buddylist) != 'undefined') { + Buddylist.create(); + + if(trim(xh.responseText).length == 0) System.logout(); + + var response = xh.responseText.parseJSON(); + + pingTimer = setInterval('System.ping()', pingFrequency); + $('modal').hide(); + + if(response.blocked && response.blocked.length > 0) { + var blockList = response.blocked.parseJSON(); + Buddylist.blocked = blockList; + } else { + Buddylist.blocked = {}; + } + + var buddy; + if(response.buddy && response.buddy.length > 0) { + var budList = response.buddy.parseJSON(); + for(var group in budList) { + if(!$(group.replace(/\s/, '_')+'_group') && group != 'toJSONString') Buddylist.addGroup(group); + if(!Buddylist.list[group]) Buddylist.list[group] = {}; + for(i=0; i'; + $('admin-button').setStyle({'position':'absolute', 'left': '0', 'top': '0'}); + } + + Event.observe(document, 'focus', function() { blinkerOn(false); }); + Event.observe(window, 'focus', function() { blinkerOn(false); }); + + Event.observe(document, 'blur', function() { blinkerOn(true); }); + Event.observe(window, 'blur', function() { blinkerOn(true); }); + + Event.observe(document, 'keypress', + function(event) { + event = event || window.event; + if(Windows.focusedWindow.getId().indexOf('_im') != -1 && IM.sendBoxWithFocus == null) { + var sB = $(Windows.focusedWindow.getId() + '_sendBox'); + sB.focus(); sB.value += String.fromCharCode(event.charCode); + } + } + ); + + Event.stopObserving(window, 'resize', recenterModal); + Status.lastIM = new Date().getTime(); + System.ping(); + } + } + ); + }, + + /** + * Check for press of 'return' or 'enter' and run 'func' + * + * @author Benjamin Hutchins + **/ + keyHandler: function(event, func) { + event = event || window.event; + var asc = document.all ? event.keyCode : event.which; + if(asc == 13 && typeof func == 'function') func(); + return asc != 13; + }, + + /** + * Log out the user + * + * @author Joshua Gross + **/ + logout: function() { + if(user == '' || pass == '') return; + var xmlhttp=false; + /*@cc_on @*/ + /*@if (@_jscript_version >= 5) + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } + @end @*/ + if (!xmlhttp && typeof XMLHttpRequest!='undefined') { + xmlhttp = new XMLHttpRequest(); + } + xmlhttp.open('POST', pingTo, false); + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xmlhttp.send('call=logout'); + + clearTimeout(pingTimer); + + defaultTitle = document.title = document.title.replace(': ' + user, ''); + user = ''; + pass = ''; + loggedIn = false; + + if(typeof(Status) != 'undefined') { + Status.state = 0; + Status.awayMessage = ''; + } + Element.stopObserving(window, 'resize', recenterModal); + + if(typeof(Buddylist) != 'undefined') Buddylist.destroy(); + + for(var name in IM.windows) { + if(typeof(IM.windows[name].getId) != 'undefined' && typeof($(IM.windows[name].getId())) != 'undefined') { + try { + if(IM.windows[name].detached) + IM.windows[name].popup.close(); + else + IM.windows[name].destroy(); + } catch(e) { } + } + } + + for(var name in Chatroom.windows) { + if(typeof(Chatroom.windows[name].getId) != 'undefined' && typeof($(Chatroom.windows[name].getId())) != 'undefined') { + try { + Chatroom.windows[name].destroy(); + } catch(e) { } + } + } + + if($('admin-userSearch')) + Windows.getWindow('admin-userSearch').destroy(); + + Dialog.alert('' + Languages.get('signedOff') + '', + { windowParameters: {className:'alert', width:alertWidth, height: 85}, + okLabel: Languages.get('reconnect'), + ok:function(win) { + try { + window.location.reload(); + } catch(e) { } + } + } + ); + }, + + /** + * Processes register requests + * + * @author Jostua Gross + **/ + register: function() { + // if registration is disabled, don't do anything + if (!allowNewUsers) { + return; + } + + var error = ''; + + var registerButton = $('register_button'); + Event.stopObserving(registerButton, 'click', System.register); + + if(($('newpassword').value == $('newpassword2').value)) { + if(checkEmailAddr($('newemail').value)) { + if($('newpassword').value.length >= 6 && $('newpassword').value.length <= 20) { + if($('newusername').value.isAlphaNumeric() && $('newusername').value.length >= 3 && $('newusername').value.length <= 16) { + var xhConn = new XHConn(); + + var username = $('newusername').value.toLowerCase(); + var password = $('newpassword').value; + var email = $('newemail').value; + xhConn.connect(pingTo, "POST", "call=register&username="+username+"&password="+password+"&email="+email, + function(xh) { + switch(xh.responseText) { + case 'user_registered': + Dialog.alert('' + Languages.get('registerSuccess') + '
      ', + {windowParameters: {className:'alert', width:alertWidth}, + ok:function(win) { clearInputs(); Dialog.closeInfo(); Dialogs.login(); }}); + Event.observe(registerButton, 'click', System.register); + return; + case 'username_taken': + error = Languages.get('registerUsernameTaken'); + break; + case 'username_bad': + error = Languages.get('registerUsernameBad'); + break; + case 'password_bad_length': + error = Languages.get('registerPasswordShort'); + break; + case 'invalid_email': + error = Languages.get('registerInvalidEmail'); + break; + case 'email_already_used': + error = Languages.get('registerEmailTaken'); + break; + default: + error = Languages.get('registerFailed'); + } + + $('register_error_msg').innerHTML = error; + $('register_error_msg').setStyle({display: 'block'}); + + new Effect.Shake('modal'); + Event.observe(registerButton, 'click', System.register); + }); + return; + } else { + error = Languages.get('registerUsernameBad'); + } + } else { + error = Languages.get('registerPasswordShort'); + } + } else { + error = Languages.get('registerInvalidEmail'); + } + } else { + error = Languages.get('registerPasswordsMatch'); + } + + $('register_error_msg').innerHTML = error; + $('register_error_msg').setStyle({display: 'block'}); + + new Effect.Shake('modal'); + + Event.observe(registerButton, 'click', System.register); + }, + + /** + * Check how long a user has been idle, + * if they've been idle more than idleTime allows, + * set them as away. + * + * @author Benjamin Hutchins + **/ + idle: function() { + var timeStamp = new Date().getTime() - (idleTime * 60 * 1000); + if (Status.lastIM < timeStamp && typeof(Status) != 'undefined' && Status.state == 0) { + Status.set(1, Languages.get('away')); + Status.wasSetAutoAway = true; + } + }, + + /** + * The heart of this script, + * ping the server for new events and messages + * + * @author Joshua Gross + **/ + ping: function(initial) { + // if auto-away is enabled, check the idle timer + if (idleTime > 0) + System.idle(); + + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=ping&away="+(typeof(Status) != 'undefined' ? Status.state : 0)+(initial == true ? '&initial=true' : ''), + function(xh) { + var i; + + if((typeof xh.status != 'undefined' && xh.status!=200) || xh.responseText == 'not_logged_in') { + System.logout(); + return; + } + + if(trim(xh.responseText).length == 0) return; + + var response = xh.responseText.parseJSON(); + + var from, data, chatroom; + var messageCount = (typeof(response.messages) !== 'undefined' ? response.messages.length : 0); + for(i=0; i|^)(\w+:\/\/[^<\s\n]+)/, '$1$2'); + data = IM.emoteReplace(data, smilies); + + if(data.replace(/<([^>]+)>/ig, '').indexOf('/me') == 0) + curIM.innerHTML += "" + IM.createTimestamp() + " " + from + ' ' + data.replace(/<([^>]+)>/ig, '').replace(/\/me/, '') + "
      \n"; + else + curIM.innerHTML += "" + IM.createTimestamp() + " " + from + ": " + data + "
      \n"; + curIM.scrollTop = curIM.scrollHeight - curIM.clientHeight + 6; + + if(!initial) { + if(curIM.innerHTML.toLowerCase().replace(/<\S[^>]*>/g, '').indexOf(user.toLowerCase()+': (' + Languages.get('autoreply').toLowerCase() + ')') == -1 && typeof(Status) != 'undefined' && Status.state == 1 && who == from) { + var fontName = $(winId + '_setFont').innerHTML; + var fontSize = $(winId + '_setFontSize').innerHTML; + var fontColor = $(winId + '_setFontColorColor').style.backgroundColor; + window[chatroom ? 'Chatroom' : 'IM'].sendMessage(from, '(' + Languages.get('autoreply') + ') ' + Status.awayMessage, false, false, false, fontName, fontSize, fontColor); + } + + if(Windows.getFocusedWindow().getId() != window[chatroom ? 'Chatroom' : 'IM'].windows[who].getId() && pulsateTitles == true) { + new Effect.Pulsate(window[chatroom ? 'Chatroom' : 'IM'].windows[who].getId() + '_top'); + } + + if(titlebarBlinker == true && useBlinker == true) { + clearTimeout(blinkerTimer); + blinkerTimer = setTimeout("titlebarBlink('"+who+"', \""+data.replace(/\"/, '\"').replace(/<([^>]+)>/ig, '')+"\", 0, "+chatroom+")", blinkSpeed); + } + } + + curIM = null; + } + + if(messageCount > 0 && audioNotify == true) soundManager.play('msg_in'); + + from = null; data = null; + var group = '', buddy = '', event = ''; + var eventCount = (typeof(response.events) !== 'undefined' ? response.events.length : 0); + + for(i=0; i" + IM.createTimestamp() + " "+from+" " + Languages.get('hasJoined') + "
      "; + scrollToBottom(Chatroom.windows[event[2]].getId()+"_rcvd"); + } else if(event[1] == 'left') { + if(typeof(Chatroom.windows[event[2]]) != 'undefined') Chatroom.windows[event[2]].deleteUser(from); + rcvdBox.innerHTML = rcvdBox.innerHTML + "" + IM.createTimestamp() + " "+from+" " + Languages.get('hasLeft') + "
      "; + scrollToBottom(Chatroom.windows[event[2]].getId()+"_rcvd"); + } + break; + } + + event = null; + } + + from = null; data = null; who = null; + } + ); + + xhConn = null; + }, + + /** + * Update a user's budddy profile + * + * @author Benjamin Hutchins + **/ + changeProfile: function() { + var profile = $('changeprofile_textarea').value, error = ''; + if(profile.replace(/\s/g, "") != "") { + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=changeprofile&profile="+encodeURIComponent(profile), + function(xh) { + if(xh.responseText == 'success') { + Dialog.closeInfo(); + Dialog.alert('' + Languages.get('changeProfileSuccess') + '
      ', + {windowParameters: {className:'alert', width:alertWidth, height:85}, + ok: function(win) { Dialog.closeInfo(); Windows.close('changeProfile'); } }); + } else { + error = Languages.get('changeProfileFailed'); + } + + if(error.length > 0) { + $('changeprofile_error_msg').innerHTML = error; + } + } + ); + } else { + error = Languages.get('changeProfileEmpty'); + } + if(error.length > 0) { + $('changeprofile_error_msg').innerHTML = error; + } + }, + + /** + * Update a users's buddy icon + * + * @author Benjamin Hutchins + **/ + changeIcon: function() { + // get the iframe as a variable + var i = $('changeicon_iframe'); + if (i.contentDocument) { + var d = i.contentDocument; + } else if (i.contentWindow) { + var d = i.contentWindow.document; + } else { + var d = window.frames['changeicon_iframe'].document; + } + + // if the iframe was never processed, then return empty + if (d.location.href == "about:blank") { + return; + } + + // handle returns from the server + var error = '', response = d.body.innerHTML; + if(response == 'success'){ + Dialog.closeInfo(); + Dialog.alert(''+Languages.get('changeBuddyiconSuccess')+'
      ',{windowParameters:{className:'alert',width:alertWidth,height:85},ok:function(win){Dialog.closeInfo();Windows.close('changeIcon');}}); + } else if (response == 'nofile') { + error = Languages.get('changeIconSelectFile'); + } else if (response == 'size') { + error = Languages.get('changeIconSize'); + } else if (response == 'bad_type') { + error = Languages.get('changeIconBadType'); + } else if (response == 'bad_extension') { + error = Languages.get('changeIconBadExtension'); + } else { + error = Languages.get('changeIconFailed'); + } + + // if there was an error, show it + if(error.length > 0) { + $('changeicon_error_msg').innerHTML = error; + } + }, + + /** + * Change a user's password + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + changePass: function() { + var currentPw = $('currentpw').value, newPw = $('newpw').value, error = ''; + + if(hex_md5(currentPw) == pass) { + if(newPw == $('confirmpw').value) { + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=pwdchange&username="+user+"&password="+hex_md5(currentPw)+"&newpwd="+newPw, + function(xh) { + if(xh.responseText == 'pw_changed') { + Dialog.closeInfo(); + Dialog.alert('' + Languages.get('changeSuccess') + '
      ', {windowParameters: {className:'alert', width:alertWidth, height:85}, ok: function(win) { Dialog.closeInfo(); Windows.close('changePass'); setTimeout('System.logout();', 250); } }); + } else if(xh.responseText == 'invalid_pw') { + error = Languages.get('currentPassInvalid'); + $('currentpw').value = ''; + } else if(xh.responseText == 'password_bad_length') { + error = Languages.get('changePasswordShort'); + $('newpw').value = ''; + $('confirmpw').value = ''; + } else { + error = Languages.get('changeFailed'); + } + if(error.length > 0) { + $('changepass_error_msg').innerHTML = error; + } + } + ); + } else { + error = Languages.get('changeNoMatch'); + } + } else { + error = Languages.get('currentPassInvalid'); + } + if(error.length > 0) { + $('changepass_error_msg').innerHTML = error; + } + }, + + /** + * Reset a user's password to something new because they forgot it + * + * @author Joshua Gross + * @update Benjamin Hutchins + **/ + resetPass: function() { + var xhConn = new XHConn(); + xhConn.connect(pingTo, "POST", "call=reset&email="+encodeURIComponent($('resetto').value), + function(xh) { + var error = ''; + if(xh.responseText == 'pw_reset') { + Dialog.alert('' + Languages.get('newPasswordEmailed').replace('%1', $('resetto').value) + '
      ', {windowParameters: {className:'alert', width:alertWidth}, ok:function(win) { clearInputs(); Dialog.closeInfo(); Dialogs.login(); }}); + } else if(xh.responseText == 'no_email_on_record') { + error = Languages.get('noEmailOnRecord'); + } else { + error = Languages.get('problemResetting'); + } + + if (error.length > 0) { + $('forgotpass_error_msg').innerHTML = error; + $('forgotpass_error_msg').setStyle({display: 'block'}); + new Effect.Shake('modal'); + } + } + ); + } +}; diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 0000000..8085c32 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,309 @@ +/* + * 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. + */ +var hexcase=0;var b64pad="";var chrsz=8;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));} +function md5_vm_test() +{return hex_md5("abc")=="900150983cd24fb0d6963f7d28e17f72";} +function core_md5(x,len) +{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;for(var i=0;i16)bkey=core_md5(bkey,key.length*chrsz);var ipad=Array(16),opad=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);} +function safe_add(x,y) +{var lsw=(x&0xFFFF)+(y&0xFFFF);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xFFFF);} +function bit_rol(num,cnt) +{return(num<>>(32-cnt));} +function str2binl(str) +{var bin=Array();var mask=(1<>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32);return bin;} +function binl2str(bin) +{var str="";var mask=(1<>5]>>>(i%32))&mask);return str;} +function binl2hex(binarray) +{var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef";var str="";for(var i=0;i>2]>>((i%4)*8+4))&0xF)+ +hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&0xF);} +return str;} +function binl2b64(binarray) +{var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var str="";for(var i=0;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(var 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;} + +/* + json + 2006-04-28 + + This file adds these methods to JavaScript: + + object.toJSONString() + + This method produces a JSON text from an object. The + object must not contain any cyclical references. + + array.toJSONString() + + This method produces a JSON text from an array. The + array must not contain any cyclical references. + + string.parseJSON() + + This method parses a JSON text to produce an object or + array. It will return false if there is an error. +*/ +(function () { + var m = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + s = { + array: function (x) { + var a = ['['], b, f, i, l = x.length, v; + for (i = 0; i < l; i += 1) { + v = x[i]; + f = s[typeof v]; + if (f) { + v = f(v); + if (typeof v == 'string') { + if (b) { + a[a.length] = ','; + } + a[a.length] = v; + b = true; + } + } + } + a[a.length] = ']'; + return a.join(''); + }, + 'boolean': function (x) { + return String(x); + }, + 'null': function (x) { + return "null"; + }, + number: function (x) { + return isFinite(x) ? String(x) : 'null'; + }, + object: function (x) { + if (x) { + if (x instanceof Array) { + return s.array(x); + } + var a = ['{'], b, f, i, v; + for (i in x) { + v = x[i]; + f = s[typeof v]; + if (f) { + v = f(v); + if (typeof v == 'string') { + if (b) { + a[a.length] = ','; + } + a.push(s.string(i), ':', v); + b = true; + } + } + } + a[a.length] = '}'; + return a.join(''); + } + return 'null'; + }, + string: function (x) { + if (/["\\\x00-\x1f]/.test(x)) { + x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) { + var c = m[b]; + if (c) { + return c; + } + c = b.charCodeAt(); + return '\\u00' + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }); + } + return '"' + x + '"'; + } + }; + + Object.prototype.toJSONString = function () { + return s.object(this); + }; + + Array.prototype.toJSONString = function () { + return s.array(this); + }; +})(); + +String.prototype.parseJSON = function () { + try { + return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( + this.replace(/"(\\.|[^"\\])*"/g, ''))) && + eval('(' + this + ')'); + } catch (e) { + return false; + } +}; + +/** XHConn - Simple XMLHTTP Interface - bfults@gmail.com - 2005-04-08 ** + ** Code licensed under Creative Commons Attribution-ShareAlike License ** + ** http://creativecommons.org/licenses/by-sa/2.0/ **/ +function XHConn() +{ + var xmlhttp, bComplete = false; + xmlhttp = XHRFactory.getInstance(); + if (!xmlhttp) return null; + this.connect = function(sURL, sMethod, sVars, fnDone) + { + if (!xmlhttp) return false; + bComplete = false; + sMethod = sMethod.toUpperCase(); + + try { + if (sMethod == "GET") + { + xmlhttp.open(sMethod, sURL+"?"+sVars, true); + sVars = ""; + } + else + { + xmlhttp.open(sMethod, sURL, true); + xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1"); + xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + } + xmlhttp.onreadystatechange = function(){ + if (xmlhttp.readyState == 4 && !bComplete) + { + bComplete = true; + if(fnDone != null) fnDone(xmlhttp); + XHRFactory.release(xmlhttp); + }}; + xmlhttp.send(sVars); + } + catch(z) { return false; } + return true; + }; + return this; +} + + +/** XHRFactory ** + ** This class from: http://blogs.pathf.com/agileajax/2006/08/object_pooling_.html **/ +var XHRFactory = (function(){ + // static private member + var stack = new Array(); + var poolSize = 10; + + var nullFunction = function() {}; // for nuking the onreadystatechange + + // private static methods + + function createXHR() { + if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } else if (window.ActiveXObject) { + return new ActiveXObject('Microsoft.XMLHTTP') + } + } + + // cache a few for use + for (var i = 0; i < poolSize; i++) { + stack.push(createXHR()); + } + + // shared instance methods + return ({ + release:function(xhr){ + xhr.onreadystatechange = nullFunction; + stack.push(xhr); + }, + getInstance:function(){ + if (stack.length < 1) { + return createXHR(); + } else { + return stack.pop(); + } + }, + toString:function(){ + return "stack size = " + stack.length; + } + }); +})(); + +// Adapted from DOM Ready extension by Dan Webb +// http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype +// which was based on work by Matthias Miller, Dean Edwards and John Resig +// +// Usage: +// +// Event.onReady(callbackFunction); +Object.extend(Event, { + _domReady : function() { + if (arguments.callee.done) return; + arguments.callee.done = true; + + if (Event._timer) clearInterval(Event._timer); + + Event._readyCallbacks.each(function(f) { f() }); + Event._readyCallbacks = null; + + }, + onReady : function(f) { + if (!this._readyCallbacks) { + var domReady = this._domReady; + + if (domReady.done) return f(); + + if (document.addEventListener) + document.addEventListener("DOMContentLoaded", domReady, false); + + /*@cc_on @*/ + /*@if (@_win32) + var dummy = location.protocol == "https:" ? "https://javascript:void(0)" : "javascript:void(0)"; + document.write(" + + + + + + + + + + + + +
      + 8 + 10 + 12 + 14 + 16 + 18 + 20 + 22 + 24 +
      +
      + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + diff --git a/soundmanager2.swf b/soundmanager2.swf new file mode 100644 index 0000000..18e4af7 Binary files /dev/null and b/soundmanager2.swf differ diff --git a/sounds/msg_in.mp3 b/sounds/msg_in.mp3 new file mode 100644 index 0000000..5c92b03 Binary files /dev/null and b/sounds/msg_in.mp3 differ diff --git a/sounds/msg_out.mp3 b/sounds/msg_out.mp3 new file mode 100644 index 0000000..56e393f Binary files /dev/null and b/sounds/msg_out.mp3 differ diff --git a/test-uploads.php b/test-uploads.php new file mode 100644 index 0000000..090521b --- /dev/null +++ b/test-uploads.php @@ -0,0 +1,85 @@ + + + + + ajax im - test upload max size + + + + +

      ajax im

      +
      +

      uploads not working?

      +

      If your uploads aren't working, try looking at the below reasons?

      + \$maxBuddyIconSize is set to 0 (zero), please set it to a higher value."; + } else if (trim(substr(sprintf('%o', fileperms('buddyicons/')), -4)) != 777) { + print "The directory buddyicons/ is not writeable, please CHMOD it to 0777."; + } else if (ini_get('file_uploads') == 0) { + if (file_exists('php.ini')) { + print "File uploads are not supported on your server."; + } else { + @ini_set('file_uploads', 'On'); + if (ini_get('file_uploads') == 0) { + print "PHP cannot use ini_set to allow file uploads. Try creating a file called php.ini in the parent directory with the following contents:

      file_uploads = On\nupload_max_filesize = {$maxBuddyIconSize}M\npost_max_size = {$maxBuddyIconSize}M
      "; + } else { + $continue = true; + } + } + } else { + $continue = true; + } + + if (isset($continue)) { + $upload_max_filesize = substr(ini_get('upload_max_filesize'), 0, -1); + $post_max_size = substr(ini_get('post_max_size'), 0, -1); + + if ($upload_max_filesize == 0 || $post_max_size == 0) { + print "Your max upload size is 0 (zero), please increase it."; + } else { + if ($upload_max_filesize >= ini_get('post_max_size')) { + $max = 'upload_max_filesize'; + } else { + $max = 'post_max_size'; + } + + print "Things look good on your server, your max upload size is:
      " . ini_get('post_max_size') . "

      If this value to too low, say, below 2MBs, then most images will be to large to be uploaded. Please keep that in mind."; + print "

      Other misc. information:
      +-------------------------------+---------------------|                          
      +| PHP Configuration Variable    | Suggested value     |
      ++-------------------------------+---------------------|
      +| max_execution_time = " . space_fix(ini_get('max_execution_time'), 8) . " | >= 30               |
      +| max_input_time = " . space_fix(ini_get('max_input_time'), 12) . " | ~ 60                |
      ++-------------------------------+---------------------|
      +
      "; + } + } + ?> +
      + + diff --git a/themes/dark/alert/bottom-left-c.gif b/themes/dark/alert/bottom-left-c.gif new file mode 100644 index 0000000..531acdc Binary files /dev/null and b/themes/dark/alert/bottom-left-c.gif differ diff --git a/themes/dark/alert/bottom-middle.gif b/themes/dark/alert/bottom-middle.gif new file mode 100644 index 0000000..d4ce3be Binary files /dev/null and b/themes/dark/alert/bottom-middle.gif differ diff --git a/themes/dark/alert/bottom-right-c.gif b/themes/dark/alert/bottom-right-c.gif new file mode 100644 index 0000000..2164c22 Binary files /dev/null and b/themes/dark/alert/bottom-right-c.gif differ diff --git a/themes/dark/alert/button-close-focus.gif b/themes/dark/alert/button-close-focus.gif new file mode 100644 index 0000000..99f635c Binary files /dev/null and b/themes/dark/alert/button-close-focus.gif differ diff --git a/themes/dark/alert/button-max-focus.gif b/themes/dark/alert/button-max-focus.gif new file mode 100644 index 0000000..1708a1e Binary files /dev/null and b/themes/dark/alert/button-max-focus.gif differ diff --git a/themes/dark/alert/button-min-focus.gif b/themes/dark/alert/button-min-focus.gif new file mode 100644 index 0000000..ff69d1b Binary files /dev/null and b/themes/dark/alert/button-min-focus.gif differ diff --git a/themes/dark/alert/frame-left.gif b/themes/dark/alert/frame-left.gif new file mode 100644 index 0000000..543f13d Binary files /dev/null and b/themes/dark/alert/frame-left.gif differ diff --git a/themes/dark/alert/frame-right.gif b/themes/dark/alert/frame-right.gif new file mode 100644 index 0000000..5d7afef Binary files /dev/null and b/themes/dark/alert/frame-right.gif differ diff --git a/themes/dark/alert/left-top.gif b/themes/dark/alert/left-top.gif new file mode 100644 index 0000000..8373aaa Binary files /dev/null and b/themes/dark/alert/left-top.gif differ diff --git a/themes/dark/alert/right-top.gif b/themes/dark/alert/right-top.gif new file mode 100644 index 0000000..77cf65e Binary files /dev/null and b/themes/dark/alert/right-top.gif differ diff --git a/themes/dark/alert/top-middle.gif b/themes/dark/alert/top-middle.gif new file mode 100644 index 0000000..9cab17d Binary files /dev/null and b/themes/dark/alert/top-middle.gif differ diff --git a/themes/dark/away.png b/themes/dark/away.png new file mode 100644 index 0000000..9c5d98c Binary files /dev/null and b/themes/dark/away.png differ diff --git a/themes/dark/blocked.png b/themes/dark/blocked.png new file mode 100644 index 0000000..7465346 Binary files /dev/null and b/themes/dark/blocked.png differ diff --git a/themes/dark/emoticons/00.png b/themes/dark/emoticons/00.png new file mode 100644 index 0000000..4357860 Binary files /dev/null and b/themes/dark/emoticons/00.png differ diff --git a/themes/dark/emoticons/09 - ooh.png b/themes/dark/emoticons/09 - ooh.png new file mode 100644 index 0000000..1ff2481 Binary files /dev/null and b/themes/dark/emoticons/09 - ooh.png differ diff --git a/themes/dark/emoticons/11 - crazy.png b/themes/dark/emoticons/11 - crazy.png new file mode 100644 index 0000000..43b68cd Binary files /dev/null and b/themes/dark/emoticons/11 - crazy.png differ diff --git a/themes/dark/emoticons/13 - geek.png b/themes/dark/emoticons/13 - geek.png new file mode 100644 index 0000000..dc9f48c Binary files /dev/null and b/themes/dark/emoticons/13 - geek.png differ diff --git a/themes/dark/emoticons/14 - devil.png b/themes/dark/emoticons/14 - devil.png new file mode 100644 index 0000000..a1b3f3e Binary files /dev/null and b/themes/dark/emoticons/14 - devil.png differ diff --git a/themes/dark/emoticons/15 - doh.png b/themes/dark/emoticons/15 - doh.png new file mode 100644 index 0000000..f146a91 Binary files /dev/null and b/themes/dark/emoticons/15 - doh.png differ diff --git a/themes/dark/emoticons/16 - XD.png b/themes/dark/emoticons/16 - XD.png new file mode 100644 index 0000000..43b8f07 Binary files /dev/null and b/themes/dark/emoticons/16 - XD.png differ diff --git a/themes/dark/emoticons/18 - brb.png b/themes/dark/emoticons/18 - brb.png new file mode 100644 index 0000000..a096a7e Binary files /dev/null and b/themes/dark/emoticons/18 - brb.png differ diff --git a/themes/dark/emoticons/Emoticons.txt b/themes/dark/emoticons/Emoticons.txt new file mode 100644 index 0000000..19161b4 --- /dev/null +++ b/themes/dark/emoticons/Emoticons.txt @@ -0,0 +1,3 @@ +These emoticons were created by and are Copyrighted (c) MazeNL77 + +http://mazenl77.deviantart.com/ \ No newline at end of file diff --git a/themes/dark/emoticons/angry.png b/themes/dark/emoticons/angry.png new file mode 100644 index 0000000..2496cd2 Binary files /dev/null and b/themes/dark/emoticons/angry.png differ diff --git a/themes/dark/emoticons/cool.png b/themes/dark/emoticons/cool.png new file mode 100644 index 0000000..64cc1ea Binary files /dev/null and b/themes/dark/emoticons/cool.png differ diff --git a/themes/dark/emoticons/cry.png b/themes/dark/emoticons/cry.png new file mode 100644 index 0000000..9ccb884 Binary files /dev/null and b/themes/dark/emoticons/cry.png differ diff --git a/themes/dark/emoticons/embarassed.png b/themes/dark/emoticons/embarassed.png new file mode 100644 index 0000000..825a79a Binary files /dev/null and b/themes/dark/emoticons/embarassed.png differ diff --git a/themes/dark/emoticons/emoticons.html b/themes/dark/emoticons/emoticons.html new file mode 100644 index 0000000..e17dfcf --- /dev/null +++ b/themes/dark/emoticons/emoticons.html @@ -0,0 +1,21 @@ +
      + + + + + + + + + + + + + + + + + + +
      +
      \ No newline at end of file diff --git a/themes/dark/emoticons/emoticons.js b/themes/dark/emoticons/emoticons.js new file mode 100644 index 0000000..b157a98 --- /dev/null +++ b/themes/dark/emoticons/emoticons.js @@ -0,0 +1 @@ +{":)": "smile.png", ":-)": "smile.png", ":D": "grin.png", ":-D": "grin.png", ";)": "wink.png", ";-)": "wink.png", ":[": "embarassed.png", ":-[": "embarassed.png", ":(": "sad.png", ":-(": "sad.png", ":'(": "cry.png", ":'-(": "cry.png", "8-)": "cool.png", ":angry:": "angry.png", ":|": "serious.png", ":-|": "serious.png", ":P": "tongue.png", ":-P": "tongue.png", ":heart:": "heart.png"} \ No newline at end of file diff --git a/themes/dark/emoticons/grin.png b/themes/dark/emoticons/grin.png new file mode 100644 index 0000000..f11070b Binary files /dev/null and b/themes/dark/emoticons/grin.png differ diff --git a/themes/dark/emoticons/heart.png b/themes/dark/emoticons/heart.png new file mode 100644 index 0000000..88bfc1e Binary files /dev/null and b/themes/dark/emoticons/heart.png differ diff --git a/themes/dark/emoticons/mini_smile.gif b/themes/dark/emoticons/mini_smile.gif new file mode 100644 index 0000000..d0126a7 Binary files /dev/null and b/themes/dark/emoticons/mini_smile.gif differ diff --git a/themes/dark/emoticons/sad.png b/themes/dark/emoticons/sad.png new file mode 100644 index 0000000..9fa4e41 Binary files /dev/null and b/themes/dark/emoticons/sad.png differ diff --git a/themes/dark/emoticons/serious.png b/themes/dark/emoticons/serious.png new file mode 100644 index 0000000..a22f090 Binary files /dev/null and b/themes/dark/emoticons/serious.png differ diff --git a/themes/dark/emoticons/silly.png b/themes/dark/emoticons/silly.png new file mode 100644 index 0000000..610478f Binary files /dev/null and b/themes/dark/emoticons/silly.png differ diff --git a/themes/dark/emoticons/smile.png b/themes/dark/emoticons/smile.png new file mode 100644 index 0000000..ca6db15 Binary files /dev/null and b/themes/dark/emoticons/smile.png differ diff --git a/themes/dark/emoticons/tongue.png b/themes/dark/emoticons/tongue.png new file mode 100644 index 0000000..c08dea5 Binary files /dev/null and b/themes/dark/emoticons/tongue.png differ diff --git a/themes/dark/emoticons/wink.png b/themes/dark/emoticons/wink.png new file mode 100644 index 0000000..0b4afac Binary files /dev/null and b/themes/dark/emoticons/wink.png differ diff --git a/themes/dark/logo.png b/themes/dark/logo.png new file mode 100644 index 0000000..c8cadb7 Binary files /dev/null and b/themes/dark/logo.png differ diff --git a/themes/dark/modal/background.png b/themes/dark/modal/background.png new file mode 100644 index 0000000..9ee12a6 Binary files /dev/null and b/themes/dark/modal/background.png differ diff --git a/themes/dark/noicon.gif b/themes/dark/noicon.gif new file mode 100644 index 0000000..4363f76 Binary files /dev/null and b/themes/dark/noicon.gif differ diff --git a/themes/dark/offline.png b/themes/dark/offline.png new file mode 100644 index 0000000..c8e36bd Binary files /dev/null and b/themes/dark/offline.png differ diff --git a/themes/dark/online.png b/themes/dark/online.png new file mode 100644 index 0000000..a9909d7 Binary files /dev/null and b/themes/dark/online.png differ diff --git a/themes/dark/style.css b/themes/dark/style.css new file mode 100644 index 0000000..ed22d5c --- /dev/null +++ b/themes/dark/style.css @@ -0,0 +1,977 @@ +/**** GENERAL ****/ + html,body{ + width: 100%; + height: 100%; + overflow: hidden; + } + + body { + margin: 0px; + padding: 0px; + background-color: #101114; + background-image: url(logo.png); + background-position: center center; + background-repeat: no-repeat; + background-attachment: fixed; + width: 100%; + } + + div { + margin: 0px; + padding: 0px; + } + + a { color: #c6c8cc; } + + input, textarea { + margin: 2px 4px 2px 4px; + border: 1px solid #dddcd8; + font-size: 12px; + } + + .rcvdMessages, input { + font-family: Tahoma, Verdana, Arial, sans-serif; + } + + .rcvdMessages { + display: block; + position: absolute; + left: 5px; + right: 10px; + margin-top: 37px; + padding-top: 2px; + padding-left: 2px; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + background-color: #efefef; + overflow: auto; + font-size: 11px; + text-align: left; + color: #000; + } + + .rcvdMessages a { + color: #5c78cb; + } + + .inputText { + position: absolute; + left: 5px; + right: 10px; + margin-top: 5px; + height: 50px; + border: 1px solid #bfbcb8; + padding: 3px; + font-family: Tahoma, sans-serif; + } + + .userToolbar { + position: absolute; + left: 5px; + margin-top: 3px; + height: 32px; + } + + .imToolbar { + position: absolute; + left: 5px; + right: 10px; + height: 25px; + margin-top: 5px; + } + + .toolbarButton { + cursor: pointer; + margin-right: 1px; + } + + img.buddyIcon { + max-width: 50px; + max-height: 50px; + _width: 50px; + _height: 50px; + position: absolute; + right: 10px; + z-index: 800; + margin-top: 40px; + } + + .chatUserList { + position: absolute; + display: block; + width: 150px; + margin-top: 5px; + background-color: #efefef; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + } + + .errorMsg { + display: block; + width: 100%; + padding: 5px 0 10px 0; + color: #ff0000; + font-weight: bold; + text-align: center; + } + + + .userA { color: #8f3838; } + + .userB { color: #30407b; } + + .imHistory { color: #aaa; } + + .imError { + color: #ff0000; + font-weight: 700; + } + + ul.sortable li { position: relative; } + + ul.box { + list-style-type: none; + padding: 0px; + margin: 0px; + width: 100%; + cursor: default; + } + + ul.box li { + color: #333; + vertical-align: middle; + font-family: Tahoma, Arial, sans-serif; + font-size: 12px; + padding: 5px 3px 1px 3px; + margin: 0; + list-style-type: none; + } + + ul.group { + margin-left: 0px; + padding-left: 0px; + } + + ul.group li { + padding: 0; + margin: 0; + } + + div#blContainer { + display: block; + position: absolute; + left: 5px; + right: 8px; + margin-top: 66px; + background-color: #efefef; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + } + + div#blTopToolbar { + display: block; + position: absolute; + left: 5px; + right: 8px; + height: 56px; + margin-top: 5px; + text-align: left; + overflow: hidden; + } + + div#blBottomToolbar { + display: block; + position: absolute; + left: 5px; + right: 8px; + height: 41px; + margin-top: 5px; + text-align: right; + overflow: hidden; + } + + div#statusSettings { + display: block; + margin-top: 2px; + } + + a.setFontLink { + position: absolute; + left: 105px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 87px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #272728; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #42464b; + overflow: hidden; + color: #c6c8cc; + } + + a.insertEmoticonLink { + position: absolute; + left: 284px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 26px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #272728; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #42464b; + overflow: hidden; + } + + a.setFontSizeLink { + position: absolute; + left: 205px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 26px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #272728; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #42464b; + overflow: hidden; + color: #c6c8cc; + } + + a.setFontColorLink { + position: absolute; + left: 244px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 26px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #272728; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #42464b; + overflow: hidden; + } + + a#curStatus { + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 180px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color: #272728; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #42464b; + overflow: hidden; + color: #c6c8cc; + } + + a#curStatus:hover { + border: 1px solid #bfbcb8; + } + + div.itemList { + display: none; + position: absolute; + border: 1px solid #42464b; + background-color: #272728; + z-index: 1000; + color: #c6c8cc; + } + + div.itemList a { + padding: 1px 3px 1px 3px; + display: block; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color: #272728; + text-decoration: none; + } + + div.itemList a:hover { + background-color: #373b41; + } + + div#statusList { + width: 165px; + } + + div#fontSizeList { + width: 28px; + } + + div#fontSizeList a { + width: 22px; + } + + div#fontsList { + width: 89px; + overflow: hidden; + } + + div#fontsList a { + width: 120px; + } + + input#customStatus { + position: absolute; + padding: 1px; + border: 1px solid #000; + margin: 0px; + font-size: 11px; + width: 114px; + } + + div#divContext { + width: 96px; + } + + div#divContext a { + padding: 3px 0 3px 4px; + } + + .listSelected, .listHover { + color: #000; + } + + .listNotSelected { + background-color: #efefef; + color: #333; + } + + .listSelected { + background-color: #d0dae6; + } + + .listHover { + background-color: #e1ebf7; + } + + div#newroom_room_list { + display: block; + overflow: auto; + width: 187px; + height: 165px; + border: 1px solid #000; + background-color: #efefef; + cursor: default; + font-size: 11px; + color: #333; + } + + div#languageList { + position: absolute; + display: block; + font-family: Tahoma, Arial, sans-serif; + font-size: 11px; + color: #fff; + width: 500px; + margin-left: -250px; + left: 50%; + bottom: 10px; + text-align: center; + } + + .buddyicon { + list-style-type: none; + height: 30px; + clear: both; + } + .buddyicon img.blIcon { + float: right; + max-height: 25px; + max-width: 25px; + margin-top: 2.5px; + _height: 25px; + _width: 25px; + } + + #changesettings_buttons .stdButton { + padding-left: 4px; + padding-right: 4px; + display: block; + clear: both; + margin: 3px auto 0px auto; + background: #373B41; + width: 135px; + } + + #changesettings_buttons .btnHover { + background: #454A51; + } + + #changesettings_buttons .btnDown { + background: #2C2F34; + } + + .userProfile { + padding: 10px; + } + + .updateProfile { + position: absolute; + bottom: 10px; + right: 10px; + } +/**** END GENERAL ****/ + + +/**** WINDOWS ****/ + .overlay_dialog { + background-color: #ddd; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; + } + + .overlay___invisible__ { + background-color: #ddd; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + } + + .dialog_nw { + width: 9px; + height: 23px; + background: transparent url(window/top_left.png) no-repeat 0 0; + } + + .dialog_n { + background: transparent url(window/top_mid.png) repeat-x 0 0; + height: 23px; + } + + .dialog_ne { + width: 9px; + height: 23px; + background: transparent url(window/top_right.png) no-repeat 0 0; + } + + .dialog_nw_inactive { + width: 9px; + height: 23px; + background: transparent url(window/top_left_inactive.png) no-repeat 0 0; + } + + .dialog_n_inactive { + background: transparent url(window/top_mid_inactive.png) repeat-x 0 0; + height: 23px; + } + + .dialog_ne_inactive { + width: 9px; + height: 23px; + background: transparent url(window/top_right_inactive.png) no-repeat 0 0; + } + + .dialog_e { + width: 2px; + background: transparent url(window/center_right.png) repeat-y 0 0; + } + + .dialog_w { + width: 2px; + background: transparent url(window/center_left.png) repeat-y 0 0; + } + + .dialog_sw { + width: 9px; + height: 15px; + background: transparent url(window/bottom_left.png) no-repeat 0 0; + } + + .dialog_s { + background: transparent url(window/bottom_mid.png) repeat-x 0 0; + height: 15px; + } + + .dialog_se { + width: 9px; + height: 15px; + background: transparent url(window/bottom_right.png) no-repeat 0 0; + } + + .dialog_sizer { + width: 9px; + height: 15px; + background: transparent url(window/sizer.png) no-repeat 0 0; + cursor:se-resize; + } + + .dialog_close { + width: 17px; + height: 17px; + background: transparent url(window/close.png) no-repeat 0 0; + position:absolute; + top:3px; + right:8px; + cursor:pointer; + z-index:2000; + } + + .dialog_minimize { + width: 17px; + height: 17px; + background: transparent url(window/minimize.png) no-repeat 0 0; + position:absolute; + top:3px; + right:49px; + cursor:pointer; + z-index:2000; + } + + .dialog_detach { + width: 17px; + height: 17px; + background: transparent url(window/detach.png) no-repeat 0 0; + position:absolute; + top:3px; + right:70px; + cursor:pointer; + z-index:2000; + } + + .dialog_maximize { + width: 17px; + height: 17px; + background: transparent url(window/maximize.png) no-repeat 0 0; + position:absolute; + top:3px; + right:28px; + cursor:pointer; + z-index:2000; + } + + .dialog_close_inactive { + width: 17px; + height: 17px; + background: transparent url(window/close_inactive.png) no-repeat 0 0; + position:absolute; + top:3px; + right:8px; + cursor:pointer; + z-index:2000; + } + + .dialog_minimize_inactive { + width: 17px; + height: 17px; + background: transparent url(window/minimize_inactive.png) no-repeat 0 0; + position:absolute; + top:3px; + right:49px; + cursor:pointer; + z-index:2000; + } + + .dialog_detach_inactive { + width: 17px; + height: 17px; + background: transparent url(window/detach_inactive.png) no-repeat 0 0; + position:absolute; + top:3px; + right:70px; + cursor:pointer; + z-index:2000; + } + + .dialog_maximize_inactive { + width: 17px; + height: 17px; + background: transparent url(window/maximize_inactive.png) no-repeat 0 0; + position:absolute; + top:3px; + right:28px; + cursor:pointer; + z-index:2000; + } + + .dialog_title { + float:left; + height:14px; + font-size:12px; + text-align:left; + width:100%; + font-family: Tahoma, Arial, sans-serif; + font-weight: bold; + font-size: 11px; + color:#efefef; + } + + .dialog_content { + overflow:hidden; + color: #fefefe; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color:#1f2022; + padding: 0; + } + + .top_draggable, .bottom_draggable { + cursor:default; + } + + .status_bar { + padding: 0px; + margin: -5px 0px 0px 0px; + font-size:10px; + color: #ffffff; + } + .status_bar input{ + font-size:12px; + } + /* DO NOT CHANGE THESE VALUES*/ + .dialog { + display: block; + position: absolute; + } + + .dialog table.table_window { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + margin: 0px; + padding:0px; + } + + .dialog table.table_window td , .dialog table.table_window th { + padding: 0; + } + + .dialog .title_window { + -moz-user-select:none; + } + + .stdButton { + display: block; + float: left; + width: 95px; + height: 23px; + background: transparent url(window/button_normal.png) no-repeat; + font-family: Tahoma, Verdana, Arial, sans-serif; + font-size: 12px; + text-decoration: none; + text-align: center; + padding-top: 5px; + border:none; + color: #ffffff; + } + + input.stdButton { + padding-top: 0px; + padding-bottom: 5px; + height:30px; + margin:0px; + } + + .btnHover { + background-image: url(window/button_hover.png); + } + + .btnDown { + width: 93px; + height: 22px; + background-image: url(window/button_down.png); + padding-top: 6px; + padding-left: 2px; + } + + .dialog_label, .dialog_input { + padding: 10px; + color: #000; + text-align: right; + float: left; + width: 150px; + font-size: 14px; + font-weight: bold; + } + + .dialog_error { + padding: 2px 0 0; + margin: 0; + font-size: 11px; + font-weight: bold; + text-align: right; + float: left; + } + + .dialog_long_label { + padding: 10px; + color: #000; + text-align: center; + width: 100%; + font-size: 14px; + font-weight: bold; + } + + .dialog_links { + display: block; + font-size: 14px; + font-weight: bold; + color: #000; + padding: 10px; + text-align: center; + margin: 0px auto; + } + + .dialog_modal_title { + font-size: 18px; + color: #000; + margin-bottom: 15px; + width: 100%; + text-align: center; + } + + .dialog_input { + width: 150px; + } + + .dialog_error { + width: 100%; + text-align: center; + color: #F00; + } + + .dialog_input input { + width: 100%; + font-weight: normal; + } +/**** END WINDOWS ****/ + + +/**** LOGIN SCREEN ****/ + div#modal span.dialog_modal_title { color: #fff; } + + div#modal span.dialog_label { width: 140px; } + + .modalFrame { + position: absolute; + display: block; + width: 375px; + height: 263px; + text-align: center; + background-image: url(modal/background.png); + background-repeat: no-repeat; + cursor: default; + filter:alpha(opacity=95); + -moz-opacity: 0.95; + opacity: 0.95; + } + + .modalFrame input { + cursor: text; + } + + .modalFrame p { + font: 14px Verdana, Tahoma, Arial, sans-serif; + margin: 0; + color: #fff; + } + + .modalFrame .dialog_label{ + padding-left: 0; + color: #fff; + } + + .modalFrame a { + cursor: default; + } + + div#loginDialog { + padding-top: 55px; + } + + div#forgotPassDialog { + padding-top: 80px; + } + + div#registerDialog { + margin-top: 15px; + } +/**** END LOGIN SCREEN ****/ + + +/**** ALERT DIALOGS ****/ + .overlay_alert { + background-color: #ccc; + filter:alpha(opacity=10); + -moz-opacity: 0.1; + opacity: 0.1; + z-index: 2; + } + + .alert_nw { + background: transparent url(alert/left-top.gif) no-repeat 0 0; + width:10px; + height:25px; + } + + .alert_n { + background: transparent url(alert/top-middle.gif) repeat-x 0 0; + height:25px; + } + + .alert_ne { + background: transparent url(alert/right-top.gif) no-repeat 0 0; + width:10px; + height:25px; + } + + .alert_w { + background: transparent url(alert/frame-left.gif) repeat-y top left; + width:7px; + } + + .alert_e { + background: transparent url(alert/frame-right.gif) repeat-y top right; + width:7px; + } + + .alert_sw { + background: transparent url(alert/bottom-left-c.gif) no-repeat 0 0; + width:7px; + height:7px; + } + + .alert_s { + background: transparent url(alert/bottom-middle.gif) repeat-x 0 0; + height:7px; + } + + .alert_se, .alert_sizer { + background: transparent url(alert/bottom-right-c.gif) no-repeat 0 0; + width:7px; + height:7px; + } + + .alert_sizer { + cursor:se-resize; + } + + .alert_close { + width: 23px; + height: 23px; + background: transparent url(alert/button-close-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:11px; + cursor:pointer; + z-index:1000; + } + + .alert_minimize { + width: 23px; + height: 23px; + background: transparent url(alert/button-min-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:55px; + cursor:pointer; + z-index:1000; + } + + .alert_maximize { + width: 23px; + height: 23px; + background: transparent url(alert/button-max-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:33px; + cursor:pointer; + z-index:1000; + } + + .alert_title { + float:left; + height:14px; + font-size:14px; + text-align:center; + margin-top:2px; + width:100%; + color:#123456; + } + + .alert_content { + overflow:hidden; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background:#FDFDFD; + } + + .alert_window { + overflow:hidden; + border:1px solid #F00; + background: #FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:390px; + z-index: 1; + } + + .alert_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; + overflow:hidden; + } + + .alert_buttons { + text-align:center; + width:100%; + } + + .alert_buttons input { + width:20%; + margin:10px; + } + + .alert_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background: #FFF url(alert/progress.gif) no-repeat center center + } +/**** END ALERT DIALOGS ****/ diff --git a/themes/dark/window/addbuddy.png b/themes/dark/window/addbuddy.png new file mode 100644 index 0000000..b743492 Binary files /dev/null and b/themes/dark/window/addbuddy.png differ diff --git a/themes/dark/window/addbuddy_down.png b/themes/dark/window/addbuddy_down.png new file mode 100644 index 0000000..6039574 Binary files /dev/null and b/themes/dark/window/addbuddy_down.png differ diff --git a/themes/dark/window/addbuddy_hover.png b/themes/dark/window/addbuddy_hover.png new file mode 100644 index 0000000..7318709 Binary files /dev/null and b/themes/dark/window/addbuddy_hover.png differ diff --git a/themes/dark/window/admin.png b/themes/dark/window/admin.png new file mode 100644 index 0000000..1fb3e54 Binary files /dev/null and b/themes/dark/window/admin.png differ diff --git a/themes/dark/window/arrow.png b/themes/dark/window/arrow.png new file mode 100644 index 0000000..10d7427 Binary files /dev/null and b/themes/dark/window/arrow.png differ diff --git a/themes/dark/window/arrow_up.png b/themes/dark/window/arrow_up.png new file mode 100644 index 0000000..dccc02b Binary files /dev/null and b/themes/dark/window/arrow_up.png differ diff --git a/themes/dark/window/audio_off.png b/themes/dark/window/audio_off.png new file mode 100644 index 0000000..933a09e Binary files /dev/null and b/themes/dark/window/audio_off.png differ diff --git a/themes/dark/window/audio_on.png b/themes/dark/window/audio_on.png new file mode 100644 index 0000000..4592fd0 Binary files /dev/null and b/themes/dark/window/audio_on.png differ diff --git a/themes/dark/window/block.png b/themes/dark/window/block.png new file mode 100644 index 0000000..f189b50 Binary files /dev/null and b/themes/dark/window/block.png differ diff --git a/themes/dark/window/block_down.png b/themes/dark/window/block_down.png new file mode 100644 index 0000000..0935e55 Binary files /dev/null and b/themes/dark/window/block_down.png differ diff --git a/themes/dark/window/block_hover.png b/themes/dark/window/block_hover.png new file mode 100644 index 0000000..b965263 Binary files /dev/null and b/themes/dark/window/block_hover.png differ diff --git a/themes/dark/window/bold_off.png b/themes/dark/window/bold_off.png new file mode 100644 index 0000000..6eb504e Binary files /dev/null and b/themes/dark/window/bold_off.png differ diff --git a/themes/dark/window/bold_off_hover.png b/themes/dark/window/bold_off_hover.png new file mode 100644 index 0000000..0c480d6 Binary files /dev/null and b/themes/dark/window/bold_off_hover.png differ diff --git a/themes/dark/window/bold_on.png b/themes/dark/window/bold_on.png new file mode 100644 index 0000000..e440571 Binary files /dev/null and b/themes/dark/window/bold_on.png differ diff --git a/themes/dark/window/bold_on_hover.png b/themes/dark/window/bold_on_hover.png new file mode 100644 index 0000000..0c480d6 Binary files /dev/null and b/themes/dark/window/bold_on_hover.png differ diff --git a/themes/dark/window/bottom_left.png b/themes/dark/window/bottom_left.png new file mode 100644 index 0000000..419e98a Binary files /dev/null and b/themes/dark/window/bottom_left.png differ diff --git a/themes/dark/window/bottom_mid.png b/themes/dark/window/bottom_mid.png new file mode 100644 index 0000000..1ba5578 Binary files /dev/null and b/themes/dark/window/bottom_mid.png differ diff --git a/themes/dark/window/bottom_right.png b/themes/dark/window/bottom_right.png new file mode 100644 index 0000000..36044b9 Binary files /dev/null and b/themes/dark/window/bottom_right.png differ diff --git a/themes/dark/window/bottom_right_resize.png b/themes/dark/window/bottom_right_resize.png new file mode 100644 index 0000000..7b1e8f4 Binary files /dev/null and b/themes/dark/window/bottom_right_resize.png differ diff --git a/themes/dark/window/button_down.png b/themes/dark/window/button_down.png new file mode 100644 index 0000000..648102e Binary files /dev/null and b/themes/dark/window/button_down.png differ diff --git a/themes/dark/window/button_hover.png b/themes/dark/window/button_hover.png new file mode 100644 index 0000000..91126b9 Binary files /dev/null and b/themes/dark/window/button_hover.png differ diff --git a/themes/dark/window/button_normal.png b/themes/dark/window/button_normal.png new file mode 100644 index 0000000..5e3804f Binary files /dev/null and b/themes/dark/window/button_normal.png differ diff --git a/themes/dark/window/center_left.png b/themes/dark/window/center_left.png new file mode 100644 index 0000000..7c5b9be Binary files /dev/null and b/themes/dark/window/center_left.png differ diff --git a/themes/dark/window/center_right.png b/themes/dark/window/center_right.png new file mode 100644 index 0000000..e359da3 Binary files /dev/null and b/themes/dark/window/center_right.png differ diff --git a/themes/dark/window/changepassword.png b/themes/dark/window/changepassword.png new file mode 100644 index 0000000..4d686c7 Binary files /dev/null and b/themes/dark/window/changepassword.png differ diff --git a/themes/dark/window/changepassword_down.png b/themes/dark/window/changepassword_down.png new file mode 100644 index 0000000..2d22b68 Binary files /dev/null and b/themes/dark/window/changepassword_down.png differ diff --git a/themes/dark/window/changepassword_hover.png b/themes/dark/window/changepassword_hover.png new file mode 100644 index 0000000..4507467 Binary files /dev/null and b/themes/dark/window/changepassword_hover.png differ diff --git a/themes/dark/window/close.png b/themes/dark/window/close.png new file mode 100644 index 0000000..0025754 Binary files /dev/null and b/themes/dark/window/close.png differ diff --git a/themes/dark/window/close_inactive.png b/themes/dark/window/close_inactive.png new file mode 100644 index 0000000..2b82aa6 Binary files /dev/null and b/themes/dark/window/close_inactive.png differ diff --git a/themes/dark/window/detach.png b/themes/dark/window/detach.png new file mode 100644 index 0000000..a9bac1e Binary files /dev/null and b/themes/dark/window/detach.png differ diff --git a/themes/dark/window/detach_inactive.png b/themes/dark/window/detach_inactive.png new file mode 100644 index 0000000..2b82aa6 Binary files /dev/null and b/themes/dark/window/detach_inactive.png differ diff --git a/themes/dark/window/imanyone.png b/themes/dark/window/imanyone.png new file mode 100644 index 0000000..d6d8ced Binary files /dev/null and b/themes/dark/window/imanyone.png differ diff --git a/themes/dark/window/imanyone_down.png b/themes/dark/window/imanyone_down.png new file mode 100644 index 0000000..9a9e9fb Binary files /dev/null and b/themes/dark/window/imanyone_down.png differ diff --git a/themes/dark/window/imanyone_hover.png b/themes/dark/window/imanyone_hover.png new file mode 100644 index 0000000..2bca04c Binary files /dev/null and b/themes/dark/window/imanyone_hover.png differ diff --git a/themes/dark/window/italic_off.png b/themes/dark/window/italic_off.png new file mode 100644 index 0000000..315f145 Binary files /dev/null and b/themes/dark/window/italic_off.png differ diff --git a/themes/dark/window/italic_off_hover.png b/themes/dark/window/italic_off_hover.png new file mode 100644 index 0000000..d54e08b Binary files /dev/null and b/themes/dark/window/italic_off_hover.png differ diff --git a/themes/dark/window/italic_on.png b/themes/dark/window/italic_on.png new file mode 100644 index 0000000..08766f9 Binary files /dev/null and b/themes/dark/window/italic_on.png differ diff --git a/themes/dark/window/italic_on_hover.png b/themes/dark/window/italic_on_hover.png new file mode 100644 index 0000000..d54e08b Binary files /dev/null and b/themes/dark/window/italic_on_hover.png differ diff --git a/themes/dark/window/joinroom.png b/themes/dark/window/joinroom.png new file mode 100644 index 0000000..1cd1256 Binary files /dev/null and b/themes/dark/window/joinroom.png differ diff --git a/themes/dark/window/joinroom_down.png b/themes/dark/window/joinroom_down.png new file mode 100644 index 0000000..df9c783 Binary files /dev/null and b/themes/dark/window/joinroom_down.png differ diff --git a/themes/dark/window/joinroom_hover.png b/themes/dark/window/joinroom_hover.png new file mode 100644 index 0000000..01bbdad Binary files /dev/null and b/themes/dark/window/joinroom_hover.png differ diff --git a/themes/dark/window/maximize.png b/themes/dark/window/maximize.png new file mode 100644 index 0000000..d4a0448 Binary files /dev/null and b/themes/dark/window/maximize.png differ diff --git a/themes/dark/window/maximize_inactive.png b/themes/dark/window/maximize_inactive.png new file mode 100644 index 0000000..2b82aa6 Binary files /dev/null and b/themes/dark/window/maximize_inactive.png differ diff --git a/themes/dark/window/minimize.png b/themes/dark/window/minimize.png new file mode 100644 index 0000000..2759136 Binary files /dev/null and b/themes/dark/window/minimize.png differ diff --git a/themes/dark/window/minimize_inactive.png b/themes/dark/window/minimize_inactive.png new file mode 100644 index 0000000..2b82aa6 Binary files /dev/null and b/themes/dark/window/minimize_inactive.png differ diff --git a/themes/dark/window/removebuddy.png b/themes/dark/window/removebuddy.png new file mode 100644 index 0000000..c9594ff Binary files /dev/null and b/themes/dark/window/removebuddy.png differ diff --git a/themes/dark/window/removebuddy_down.png b/themes/dark/window/removebuddy_down.png new file mode 100644 index 0000000..9b6760c Binary files /dev/null and b/themes/dark/window/removebuddy_down.png differ diff --git a/themes/dark/window/removebuddy_hover.png b/themes/dark/window/removebuddy_hover.png new file mode 100644 index 0000000..945ee1e Binary files /dev/null and b/themes/dark/window/removebuddy_hover.png differ diff --git a/themes/dark/window/signoff.png b/themes/dark/window/signoff.png new file mode 100644 index 0000000..8f8c440 Binary files /dev/null and b/themes/dark/window/signoff.png differ diff --git a/themes/dark/window/signoff_down.png b/themes/dark/window/signoff_down.png new file mode 100644 index 0000000..6a36304 Binary files /dev/null and b/themes/dark/window/signoff_down.png differ diff --git a/themes/dark/window/signoff_hover.png b/themes/dark/window/signoff_hover.png new file mode 100644 index 0000000..4161cc8 Binary files /dev/null and b/themes/dark/window/signoff_hover.png differ diff --git a/themes/dark/window/sizer.png b/themes/dark/window/sizer.png new file mode 100644 index 0000000..7b1e8f4 Binary files /dev/null and b/themes/dark/window/sizer.png differ diff --git a/themes/dark/window/smallx.png b/themes/dark/window/smallx.png new file mode 100644 index 0000000..a422c63 Binary files /dev/null and b/themes/dark/window/smallx.png differ diff --git a/themes/dark/window/smallx_hover.png b/themes/dark/window/smallx_hover.png new file mode 100644 index 0000000..5a8a00f Binary files /dev/null and b/themes/dark/window/smallx_hover.png differ diff --git a/themes/dark/window/top_left.png b/themes/dark/window/top_left.png new file mode 100644 index 0000000..47ccd01 Binary files /dev/null and b/themes/dark/window/top_left.png differ diff --git a/themes/dark/window/top_left_inactive.png b/themes/dark/window/top_left_inactive.png new file mode 100644 index 0000000..1cd8fbf Binary files /dev/null and b/themes/dark/window/top_left_inactive.png differ diff --git a/themes/dark/window/top_mid.png b/themes/dark/window/top_mid.png new file mode 100644 index 0000000..543a4da Binary files /dev/null and b/themes/dark/window/top_mid.png differ diff --git a/themes/dark/window/top_mid_inactive.png b/themes/dark/window/top_mid_inactive.png new file mode 100644 index 0000000..cdcb015 Binary files /dev/null and b/themes/dark/window/top_mid_inactive.png differ diff --git a/themes/dark/window/top_right.png b/themes/dark/window/top_right.png new file mode 100644 index 0000000..192b8d2 Binary files /dev/null and b/themes/dark/window/top_right.png differ diff --git a/themes/dark/window/top_right_inactive.png b/themes/dark/window/top_right_inactive.png new file mode 100644 index 0000000..707524a Binary files /dev/null and b/themes/dark/window/top_right_inactive.png differ diff --git a/themes/dark/window/underline_off.png b/themes/dark/window/underline_off.png new file mode 100644 index 0000000..830b2a4 Binary files /dev/null and b/themes/dark/window/underline_off.png differ diff --git a/themes/dark/window/underline_off_hover.png b/themes/dark/window/underline_off_hover.png new file mode 100644 index 0000000..df47b64 Binary files /dev/null and b/themes/dark/window/underline_off_hover.png differ diff --git a/themes/dark/window/underline_on.png b/themes/dark/window/underline_on.png new file mode 100644 index 0000000..77434d3 Binary files /dev/null and b/themes/dark/window/underline_on.png differ diff --git a/themes/dark/window/underline_on_hover.png b/themes/dark/window/underline_on_hover.png new file mode 100644 index 0000000..df47b64 Binary files /dev/null and b/themes/dark/window/underline_on_hover.png differ diff --git a/themes/default/alert/bottom-left-c.gif b/themes/default/alert/bottom-left-c.gif new file mode 100644 index 0000000..531acdc Binary files /dev/null and b/themes/default/alert/bottom-left-c.gif differ diff --git a/themes/default/alert/bottom-middle.gif b/themes/default/alert/bottom-middle.gif new file mode 100644 index 0000000..d4ce3be Binary files /dev/null and b/themes/default/alert/bottom-middle.gif differ diff --git a/themes/default/alert/bottom-right-c.gif b/themes/default/alert/bottom-right-c.gif new file mode 100644 index 0000000..2164c22 Binary files /dev/null and b/themes/default/alert/bottom-right-c.gif differ diff --git a/themes/default/alert/button-close-focus.gif b/themes/default/alert/button-close-focus.gif new file mode 100644 index 0000000..99f635c Binary files /dev/null and b/themes/default/alert/button-close-focus.gif differ diff --git a/themes/default/alert/button-max-focus.gif b/themes/default/alert/button-max-focus.gif new file mode 100644 index 0000000..1708a1e Binary files /dev/null and b/themes/default/alert/button-max-focus.gif differ diff --git a/themes/default/alert/button-min-focus.gif b/themes/default/alert/button-min-focus.gif new file mode 100644 index 0000000..ff69d1b Binary files /dev/null and b/themes/default/alert/button-min-focus.gif differ diff --git a/themes/default/alert/frame-left.gif b/themes/default/alert/frame-left.gif new file mode 100644 index 0000000..543f13d Binary files /dev/null and b/themes/default/alert/frame-left.gif differ diff --git a/themes/default/alert/frame-right.gif b/themes/default/alert/frame-right.gif new file mode 100644 index 0000000..5d7afef Binary files /dev/null and b/themes/default/alert/frame-right.gif differ diff --git a/themes/default/alert/left-top.gif b/themes/default/alert/left-top.gif new file mode 100644 index 0000000..8373aaa Binary files /dev/null and b/themes/default/alert/left-top.gif differ diff --git a/themes/default/alert/right-top.gif b/themes/default/alert/right-top.gif new file mode 100644 index 0000000..77cf65e Binary files /dev/null and b/themes/default/alert/right-top.gif differ diff --git a/themes/default/alert/top-middle.gif b/themes/default/alert/top-middle.gif new file mode 100644 index 0000000..9cab17d Binary files /dev/null and b/themes/default/alert/top-middle.gif differ diff --git a/themes/default/away.png b/themes/default/away.png new file mode 100644 index 0000000..105a44a Binary files /dev/null and b/themes/default/away.png differ diff --git a/themes/default/blocked.png b/themes/default/blocked.png new file mode 100644 index 0000000..6b69348 Binary files /dev/null and b/themes/default/blocked.png differ diff --git a/themes/default/emoticons/14_pleeaase.gif b/themes/default/emoticons/14_pleeaase.gif new file mode 100644 index 0000000..61c4033 Binary files /dev/null and b/themes/default/emoticons/14_pleeaase.gif differ diff --git a/themes/default/emoticons/Emoticons.txt b/themes/default/emoticons/Emoticons.txt new file mode 100644 index 0000000..19161b4 --- /dev/null +++ b/themes/default/emoticons/Emoticons.txt @@ -0,0 +1,3 @@ +These emoticons were created by and are Copyrighted (c) MazeNL77 + +http://mazenl77.deviantart.com/ \ No newline at end of file diff --git a/themes/default/emoticons/angel.gif b/themes/default/emoticons/angel.gif new file mode 100644 index 0000000..84cbffa Binary files /dev/null and b/themes/default/emoticons/angel.gif differ diff --git a/themes/default/emoticons/angry.gif b/themes/default/emoticons/angry.gif new file mode 100644 index 0000000..905e139 Binary files /dev/null and b/themes/default/emoticons/angry.gif differ diff --git a/themes/default/emoticons/annoyed.gif b/themes/default/emoticons/annoyed.gif new file mode 100644 index 0000000..334aee2 Binary files /dev/null and b/themes/default/emoticons/annoyed.gif differ diff --git a/themes/default/emoticons/confused.gif b/themes/default/emoticons/confused.gif new file mode 100644 index 0000000..5a4e14b Binary files /dev/null and b/themes/default/emoticons/confused.gif differ diff --git a/themes/default/emoticons/cool.gif b/themes/default/emoticons/cool.gif new file mode 100644 index 0000000..8786a9a Binary files /dev/null and b/themes/default/emoticons/cool.gif differ diff --git a/themes/default/emoticons/cry.gif b/themes/default/emoticons/cry.gif new file mode 100644 index 0000000..e7f76da Binary files /dev/null and b/themes/default/emoticons/cry.gif differ diff --git a/themes/default/emoticons/devil.gif b/themes/default/emoticons/devil.gif new file mode 100644 index 0000000..f1513b2 Binary files /dev/null and b/themes/default/emoticons/devil.gif differ diff --git a/themes/default/emoticons/embarassed.gif b/themes/default/emoticons/embarassed.gif new file mode 100644 index 0000000..1aab1f2 Binary files /dev/null and b/themes/default/emoticons/embarassed.gif differ diff --git a/themes/default/emoticons/emoticons.html b/themes/default/emoticons/emoticons.html new file mode 100644 index 0000000..d3a756e --- /dev/null +++ b/themes/default/emoticons/emoticons.html @@ -0,0 +1,25 @@ +
      + + + + + + + + + + + + + + + + + + + + + + +
      +
      \ No newline at end of file diff --git a/themes/default/emoticons/emoticons.js b/themes/default/emoticons/emoticons.js new file mode 100644 index 0000000..ec26604 --- /dev/null +++ b/themes/default/emoticons/emoticons.js @@ -0,0 +1 @@ +{":)": "smile.gif", ":-)": "smile.gif", ":D": "grin.gif", ":-D": "grin.gif", ";)": "wink.gif", ";-)": "wink.gif", ":[": "embarassed.gif", ":-[": "embarassed.gif", ":*": "love.gif", ":-*": "love.gif", ":(": "sad.gif", ":-(": "sad.gif", ":'(": "cry.gif", ":'-(": "cry.gif", "8-)": "cool.gif", ":angry:": "angry.gif", ":O": "surprised.gif", ":-O": "surprised.gif", ":|": "serious.gif", ":-|": "serious.gif", ":-S": "sick.gif", ":P": "tongue.gif", ":-P": "tongue.gif", ":heart:": "heart.gif", ":brokenheart:": "heartbroken.gif"} \ No newline at end of file diff --git a/themes/default/emoticons/grin.gif b/themes/default/emoticons/grin.gif new file mode 100644 index 0000000..f4d6313 Binary files /dev/null and b/themes/default/emoticons/grin.gif differ diff --git a/themes/default/emoticons/heart.gif b/themes/default/emoticons/heart.gif new file mode 100644 index 0000000..48f1bb5 Binary files /dev/null and b/themes/default/emoticons/heart.gif differ diff --git a/themes/default/emoticons/heartbroken.gif b/themes/default/emoticons/heartbroken.gif new file mode 100644 index 0000000..81e10ea Binary files /dev/null and b/themes/default/emoticons/heartbroken.gif differ diff --git a/themes/default/emoticons/love.gif b/themes/default/emoticons/love.gif new file mode 100644 index 0000000..825c7c2 Binary files /dev/null and b/themes/default/emoticons/love.gif differ diff --git a/themes/default/emoticons/mini_smile.gif b/themes/default/emoticons/mini_smile.gif new file mode 100644 index 0000000..d0126a7 Binary files /dev/null and b/themes/default/emoticons/mini_smile.gif differ diff --git a/themes/default/emoticons/ninja.gif b/themes/default/emoticons/ninja.gif new file mode 100644 index 0000000..5fd210f Binary files /dev/null and b/themes/default/emoticons/ninja.gif differ diff --git a/themes/default/emoticons/phone.gif b/themes/default/emoticons/phone.gif new file mode 100644 index 0000000..8545322 Binary files /dev/null and b/themes/default/emoticons/phone.gif differ diff --git a/themes/default/emoticons/sad.gif b/themes/default/emoticons/sad.gif new file mode 100644 index 0000000..749bb93 Binary files /dev/null and b/themes/default/emoticons/sad.gif differ diff --git a/themes/default/emoticons/serious.gif b/themes/default/emoticons/serious.gif new file mode 100644 index 0000000..5badb3d Binary files /dev/null and b/themes/default/emoticons/serious.gif differ diff --git a/themes/default/emoticons/sick.gif b/themes/default/emoticons/sick.gif new file mode 100644 index 0000000..2e6b335 Binary files /dev/null and b/themes/default/emoticons/sick.gif differ diff --git a/themes/default/emoticons/smile.gif b/themes/default/emoticons/smile.gif new file mode 100644 index 0000000..b745e03 Binary files /dev/null and b/themes/default/emoticons/smile.gif differ diff --git a/themes/default/emoticons/surprised.gif b/themes/default/emoticons/surprised.gif new file mode 100644 index 0000000..f2b5d7b Binary files /dev/null and b/themes/default/emoticons/surprised.gif differ diff --git a/themes/default/emoticons/tongue.gif b/themes/default/emoticons/tongue.gif new file mode 100644 index 0000000..feb2f6c Binary files /dev/null and b/themes/default/emoticons/tongue.gif differ diff --git a/themes/default/emoticons/wink.gif b/themes/default/emoticons/wink.gif new file mode 100644 index 0000000..aa87f7e Binary files /dev/null and b/themes/default/emoticons/wink.gif differ diff --git a/themes/default/logo.jpg b/themes/default/logo.jpg new file mode 100644 index 0000000..c9be14c Binary files /dev/null and b/themes/default/logo.jpg differ diff --git a/themes/default/logo.png b/themes/default/logo.png new file mode 100644 index 0000000..c3b40bf Binary files /dev/null and b/themes/default/logo.png differ diff --git a/themes/default/modal/background.png b/themes/default/modal/background.png new file mode 100644 index 0000000..a4421b9 Binary files /dev/null and b/themes/default/modal/background.png differ diff --git a/themes/default/modal/background_orig.jpg b/themes/default/modal/background_orig.jpg new file mode 100644 index 0000000..aae0d69 Binary files /dev/null and b/themes/default/modal/background_orig.jpg differ diff --git a/themes/default/noicon.gif b/themes/default/noicon.gif new file mode 100644 index 0000000..4363f76 Binary files /dev/null and b/themes/default/noicon.gif differ diff --git a/themes/default/offline.png b/themes/default/offline.png new file mode 100644 index 0000000..102854f Binary files /dev/null and b/themes/default/offline.png differ diff --git a/themes/default/online.png b/themes/default/online.png new file mode 100644 index 0000000..7fb2459 Binary files /dev/null and b/themes/default/online.png differ diff --git a/themes/default/style.css b/themes/default/style.css new file mode 100644 index 0000000..a838bec --- /dev/null +++ b/themes/default/style.css @@ -0,0 +1,955 @@ +/**** GENERAL ****/ + html,body{ + width: 100%; + height: 100%; + overflow: hidden; + } + + body { + margin: 0px; + padding: 0px; + background-color: #e3eaf3; + background-image: url(logo.png); + background-position: center center; + background-repeat: no-repeat; + background-attachment: fixed; + width: 100%; + } + + div { + margin: 0px; + padding: 0px; + } + + a { color: #333; } + + input, textarea { + margin: 2px 4px 2px 4px; + border: 1px solid #dddcd8; + font-size: 12px; + } + + .rcvdMessages, input { + font-family: Tahoma, Verdana, Arial, sans-serif; + } + + .rcvdMessages { + display: block; + position: absolute; + left: 5px; + right: 10px; + margin-top: 37px; + padding-top: 2px; + padding-left: 2px; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + background-color: #fff; + overflow: auto; + font-size: 11px; + text-align: left; + } + + .rcvdMessages a { + color: #5c78cb; + } + + .inputText { + position: absolute; + left: 5px; + right: 10px; + margin-top: 5px; + height: 50px; + border: 1px solid #bfbcb8; + padding: 3px; + font-family: Tahoma, sans-serif; + } + + .userToolbar { + position: absolute; + left: 5px; + margin-top: 3px; + height: 32px; + } + + .imToolbar { + position: absolute; + left: 5px; + right: 10px; + margin-top: 5px; + height: 16px; + } + + .toolbarButton { + cursor: pointer; + } + + img.buddyIcon { + max-width: 50px; + max-height: 50px; + _width: 50px; + _height: 50px; + position: absolute; + right: 10px; + z-index: 800; + margin-top: 40px; + } + + .toolbarSpacer img { + border-right: 2px solid #bfbcb8; + } + + .chatUserList { + position: absolute; + display: block; + width: 150px; + margin-top: 5px; + background-color: #fff; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + } + + .errorMsg { + display: block; + width: 100%; + padding: 5px 0 10px 0; + color: #ff0000; + font-weight: bold; + text-align: center; + } + + + .userA { color: #8f3838; } + + .userB { color: #30407b; } + + .imHistory { color: #aaa; } + + .imError { + color: #ff0000; + font-weight: 700; + } + + ul.sortable li { position: relative; } + + ul.box { + list-style-type: none; + padding: 0px; + margin: 0px; + width: 100%; + cursor: default; + } + + ul.box li { + color: #333; + vertical-align: middle; + font-family: Tahoma, Arial, sans-serif; + font-size: 12px; + padding: 5px 3px 1px 3px; + margin: 0; + } + + ul.group { + margin-left: 0px; + padding-left: 0px; + } + + ul.group li { + padding: 0; + margin: 0; + } + + div#blContainer { + display: block; + position: absolute; + left: 5px; + right: 8px; + margin-top: 66px; + background-color: #fff; + border-width: 1px; + border-style: solid; + border-color: #bfbcb8 #e0dcd8 #e0dcd8 #bfbcb8; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + } + + div#blTopToolbar { + display: block; + position: absolute; + left: 5px; + right: 8px; + height: 56px; + margin-top: 5px; + text-align: left; + overflow: hidden; + } + + div#blBottomToolbar { + display: block; + position: absolute; + left: 5px; + right: 8px; + height: 41px; + margin-top: 5px; + text-align: right; + overflow: hidden; + } + + div#statusSettings { + display: block; + margin-top: 2px; + } + + a.setFontLink { + position: absolute; + left: 105px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 85px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #ebe6e1; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #bfbcb8; + overflow: hidden; + } + + a.insertEmoticonLink { + position: absolute; + left: 284px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 24px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #ebe6e1; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #bfbcb8; + overflow: hidden; + } + + a.setFontSizeLink { + position: absolute; + left: 205px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 24px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #ebe6e1; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #bfbcb8; + overflow: hidden; + } + + a.setFontColorLink { + position: absolute; + left: 244px; + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 24px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + vertical-align: middle; + background-color: #ebe6e1; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #bfbcb8; + overflow: hidden; + } + + a#curStatus { + display: block; + -moz-outline-style: none; + text-decoration: none; + width: 165px; + height: 14px; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color: #ebe6e1; + padding: 2px; + background-image: url(window/arrow.png); + background-position: center right; + background-repeat: no-repeat; + border: 1px solid #ebe6e1; + overflow: hidden; + } + + a#curStatus:hover { + border: 1px solid #bfbcb8; + } + + div.itemList { + display: none; + position: absolute; + border: 1px solid #bfbcb8; + background-color: #ebe6e1; + z-index: 1000; + } + + div.itemList a { + padding: 1px 3px 1px 3px; + display: block; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color: #ebe6e1; + text-decoration: none; + } + + div.itemList a:hover { + background-color: #e1ebf7; + } + + div#statusList { + width: 165px; + } + + div#fontSizeList { + width: 28px; + } + + div#fontSizeList a { + width: 22px; + } + + div#fontsList { + width: 89px; + overflow: hidden; + } + + div#fontsList a { + width: 120px; + } + + input#customStatus { + position: absolute; + padding: 1px; + border: 1px solid #000; + margin: 0px; + font-size: 11px; + width: 114px; + } + + div#divContext { + width: 96px; + } + + div#divContext a { + padding: 3px 0 3px 4px; + } + + .listSelected, .listHover { + color: #000; + } + + .listNotSelected { + background-color: #fff; + color: #333; + } + + .listSelected { + background-color: #d0dae6; + } + + .listHover { + background-color: #e1ebf7; + } + + div#newroom_room_list { + display: block; + overflow: auto; + width: 187px; + height: 165px; + border: 1px solid #000; + background-color: #fff; + cursor: default; + font-size: 11px; + } + + div#languageList { + position: absolute; + display: block; + font-family: Tahoma, Arial, sans-serif; + font-size: 11px; + color: #333; + width: 500px; + margin-left: -250px; + left: 50%; + bottom: 10px; + text-align: center; + } + + .buddyicon { + list-style-type: none; + height: 30px; + clear: both; + } + .buddyicon img.blIcon { + float: right; + max-height: 25px; + max-width: 25px; + margin-top: 2.5px; + _height: 25px; + _width: 25px; + } + + #changesettings_buttons .stdButton { + padding-left: 4px; + padding-right: 4px; + display: block; + clear: both; + margin: 3px auto 0px auto; + background: transparent; + width: 135px; + } + + #changesettings_buttons .btnHover { + background: transparent; + text-decoration: underline; + } + + #changesettings_buttons .btnDown { + background: transparent; + } + + .userProfile { + padding: 10px; + } + + .updateProfile { + position: absolute; + bottom: 10px; + right: 10px; + } +/**** END GENERAL ****/ + + +/**** WINDOWS ****/ + .overlay_dialog { + background-color: #666666; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; + } + + .overlay___invisible__ { + background-color: #666666; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + } + + .dialog_nw { + width: 9px; + height: 23px; + background: transparent url(window/top_left.gif) no-repeat 0 0; + } + + .dialog_n { + background: transparent url(window/top_mid.gif) repeat-x 0 0; + height: 23px; + } + + .dialog_ne { + width: 9px; + height: 23px; + background: transparent url(window/top_right.gif) no-repeat 0 0; + } + + .dialog_nw_inactive { + width: 9px; + height: 23px; + background: transparent url(window/top_left_inactive.gif) no-repeat 0 0; + } + + .dialog_n_inactive { + background: transparent url(window/top_mid_inactive.gif) repeat-x 0 0; + height: 23px; + } + + .dialog_ne_inactive { + width: 9px; + height: 23px; + background: transparent url(window/top_right_inactive.gif) no-repeat 0 0; + } + + .dialog_e { + width: 2px; + background: transparent url(window/center_right.gif) repeat-y 0 0; + } + + .dialog_w { + width: 2px; + background: transparent url(window/center_left.gif) repeat-y 0 0; + } + + .dialog_sw { + width: 9px; + height: 19px; + background: transparent url(window/bottom_left.gif) no-repeat 0 0; + } + + .dialog_s { + background: transparent url(window/bottom_mid.gif) repeat-x 0 0; + height: 19px; + } + + .dialog_se { + width: 9px; + height: 19px; + background: transparent url(window/bottom_right.gif) no-repeat 0 0; + } + + .dialog_sizer { + width: 9px; + height: 19px; + background: transparent url(window/sizer.gif) no-repeat 0 0; + cursor:se-resize; + } + + .dialog_close { + width: 17px; + height: 17px; + background: transparent url(window/close.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:8px; + cursor:pointer; + z-index:2000; + } + + .dialog_minimize { + width: 17px; + height: 17px; + background: transparent url(window/minimize.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:49px; + cursor:pointer; + z-index:2000; + } + + .dialog_detach { + width: 17px; + height: 17px; + background: transparent url(window/detach.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:70px; + cursor:pointer; + z-index:2000; + } + + .dialog_maximize { + width: 17px; + height: 17px; + background: transparent url(window/maximize.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:28px; + cursor:pointer; + z-index:2000; + } + + .dialog_close_inactive { + width: 17px; + height: 17px; + background: transparent url(window/close_inactive.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:8px; + cursor:pointer; + z-index:2000; + } + + .dialog_minimize_inactive { + width: 17px; + height: 17px; + background: transparent url(window/minimize_inactive.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:49px; + cursor:pointer; + z-index:2000; + } + + .dialog_detach_inactive { + width: 17px; + height: 17px; + background: transparent url(window/detach_inactive.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:70px; + cursor:pointer; + z-index:2000; + } + + .dialog_maximize_inactive { + width: 17px; + height: 17px; + background: transparent url(window/maximize_inactive.gif) no-repeat 0 0; + position:absolute; + top:3px; + right:28px; + cursor:pointer; + z-index:2000; + } + + .dialog_title { + float:left; + height:14px; + font-size:12px; + text-align:center; + width:100%; + font-family: Tahoma, Arial, sans-serif; + font-weight: bold; + font-size: 11px; + color:#ebe6e1; + } + + .dialog_content { + overflow:hidden; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color:#ebe6e1; + padding: 0; + } + + .top_draggable, .bottom_draggable { + cursor: default; + } + + .status_bar { + font-size:12px; + } + .status_bar input{ + font-size:12px; + } + /* DO NOT CHANGE THESE VALUES*/ + .dialog { + display: block; + position: absolute; + } + + .dialog table.table_window { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + margin: 0px; + padding:0px; + } + + .dialog table.table_window td , .dialog table.table_window th { + padding: 0; + } + + .dialog .title_window { + -moz-user-select:none; + } + + .stdButton { + display: block; + float: left; + width: 95px; + height: 23px; + background-image: url(window/button_normal.png); + font-family: Tahoma, Verdana, Arial, sans-serif; + font-size: 12px; + text-decoration: none; + text-align: center; + padding-top: 5px; + color:#333; + } + + input.stdButton { + padding-top: 0px; + padding-bottom: 5px; + height:30px; + margin:0px; + } + + .btnHover { + background-image: url(window/button_hover.png); + } + + .btnDown { + width: 93px; + height: 22px; + background-image: url(window/button_down.png); + padding-top: 6px; + padding-left: 2px; + } + + .dialog_label, .dialog_input, .dialog_error { + padding: 10px; + color: #000; + text-align: right; + float: left; + width: 150px; + font-size: 14px; + font-weight: bold; + } + + .dialog_long_label { + padding: 10px; + color: #000; + text-align: center; + width: 100%; + font-size: 14px; + font-weight: bold; + } + + .dialog_links { + display: block; + font-size: 14px; + font-weight: bold; + color: #000; + padding: 10px; + text-align: center; + margin: 0px auto; + } + + .dialog_modal_title { + font-size: 18px; + color: #000; + margin-bottom: 15px; + width: 100%; + text-align: center; + } + + .dialog_input { + width: 150px; + } + + .dialog_error { + width: 100%; + text-align: center; + color: #F00; + } + + .dialog_input input { + width: 100%; + font-weight: normal; + } +/**** END WINDOWS ****/ + +/**** LOGIN SCREEN ****/ + .modalFrame { + display: none; + position: absolute; + display: block; + width: 762px; + height: 529px; + margin: 0px auto; + padding-top: 140px; + text-align: center; + background-image: url(modal/background.png); + background-repeat: no-repeat; + cursor: default; + } + + .modalFrame input { + cursor: text; + } + + .modalFrame p { + font-family: Verdana, Tahoma, Arial, sans-serif; + font-size: 14px; + margin: 3px; + } + + .modalFrame .dialog_label{ + padding-left: 190px; + } + + .modalFrame a { + cursor: default; + } + + div#loginDialog { + padding-top: 35px; + } + + div#forgotPassDialog { + padding-top: 60px; + } + + div#registerDialog { + margin-top: -15px; + } +/**** END LOGIN SCREEN ****/ + + +/**** ALERT DIALOGS ****/ + .overlay_alert { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; + z-index: 2; + } + + .alert_nw { + background: transparent url(alert/left-top.gif) no-repeat 0 0; + width:10px; + height:25px; + } + + .alert_n { + background: transparent url(alert/top-middle.gif) repeat-x 0 0; + height:25px; + } + + .alert_ne { + background: transparent url(alert/right-top.gif) no-repeat 0 0; + width:10px; + height:25px; + } + + .alert_w { + background: transparent url(alert/frame-left.gif) repeat-y top left; + width:7px; + } + + .alert_e { + background: transparent url(alert/frame-right.gif) repeat-y top right; + width:7px; + } + + .alert_sw { + background: transparent url(alert/bottom-left-c.gif) no-repeat 0 0; + width:7px; + height:7px; + } + + .alert_s { + background: transparent url(alert/bottom-middle.gif) repeat-x 0 0; + height:7px; + } + + .alert_se, .alert_sizer { + background: transparent url(alert/bottom-right-c.gif) no-repeat 0 0; + width:7px; + height:7px; + } + + .alert_sizer { + cursor:se-resize; + } + + .alert_close { + width: 23px; + height: 23px; + background: transparent url(alert/button-close-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:11px; + cursor:pointer; + z-index:1000; + } + + .alert_minimize { + width: 23px; + height: 23px; + background: transparent url(alert/button-min-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:55px; + cursor:pointer; + z-index:1000; + } + + .alert_maximize { + width: 23px; + height: 23px; + background: transparent url(alert/button-max-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:33px; + cursor:pointer; + z-index:1000; + } + + .alert_title { + float:left; + height:14px; + font-size:14px; + text-align:center; + margin-top:2px; + width:100%; + color:#123456; + } + + .alert_content { + overflow:hidden; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background:#FDFDFD; + } + + .alert_window { + overflow:hidden; + border:1px solid #F00; + background: #FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:390px; + z-index: 1; + } + + .alert_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; + overflow:hidden; + } + + .alert_buttons { + text-align:center; + width:100%; + } + + .alert_buttons input { + width:20%; + margin:10px; + } + + .alert_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background: #FFF url(alert/progress.gif) no-repeat center center + } +/**** END ALERT DIALOGS ****/ diff --git a/themes/default/window/addbuddy.png b/themes/default/window/addbuddy.png new file mode 100644 index 0000000..cd93040 Binary files /dev/null and b/themes/default/window/addbuddy.png differ diff --git a/themes/default/window/addbuddy_down.png b/themes/default/window/addbuddy_down.png new file mode 100644 index 0000000..6ef0c90 Binary files /dev/null and b/themes/default/window/addbuddy_down.png differ diff --git a/themes/default/window/addbuddy_hover.png b/themes/default/window/addbuddy_hover.png new file mode 100644 index 0000000..ca7b94b Binary files /dev/null and b/themes/default/window/addbuddy_hover.png differ diff --git a/themes/default/window/arrow.png b/themes/default/window/arrow.png new file mode 100644 index 0000000..7bc6a02 Binary files /dev/null and b/themes/default/window/arrow.png differ diff --git a/themes/default/window/arrow_up.png b/themes/default/window/arrow_up.png new file mode 100644 index 0000000..2ec1ba8 Binary files /dev/null and b/themes/default/window/arrow_up.png differ diff --git a/themes/default/window/audio_off.png b/themes/default/window/audio_off.png new file mode 100644 index 0000000..71ec591 Binary files /dev/null and b/themes/default/window/audio_off.png differ diff --git a/themes/default/window/audio_on.png b/themes/default/window/audio_on.png new file mode 100644 index 0000000..8ebf9aa Binary files /dev/null and b/themes/default/window/audio_on.png differ diff --git a/themes/default/window/away.png b/themes/default/window/away.png new file mode 100644 index 0000000..105a44a Binary files /dev/null and b/themes/default/window/away.png differ diff --git a/themes/default/window/block.png b/themes/default/window/block.png new file mode 100644 index 0000000..764277b Binary files /dev/null and b/themes/default/window/block.png differ diff --git a/themes/default/window/block_down.png b/themes/default/window/block_down.png new file mode 100644 index 0000000..f64de28 Binary files /dev/null and b/themes/default/window/block_down.png differ diff --git a/themes/default/window/block_hover.png b/themes/default/window/block_hover.png new file mode 100644 index 0000000..8c35f5e Binary files /dev/null and b/themes/default/window/block_hover.png differ diff --git a/themes/default/window/bold_off.png b/themes/default/window/bold_off.png new file mode 100644 index 0000000..894f1e9 Binary files /dev/null and b/themes/default/window/bold_off.png differ diff --git a/themes/default/window/bold_off_hover.png b/themes/default/window/bold_off_hover.png new file mode 100644 index 0000000..8dc0013 Binary files /dev/null and b/themes/default/window/bold_off_hover.png differ diff --git a/themes/default/window/bold_on.png b/themes/default/window/bold_on.png new file mode 100644 index 0000000..3d405dc Binary files /dev/null and b/themes/default/window/bold_on.png differ diff --git a/themes/default/window/bold_on_hover.png b/themes/default/window/bold_on_hover.png new file mode 100644 index 0000000..e56018c Binary files /dev/null and b/themes/default/window/bold_on_hover.png differ diff --git a/themes/default/window/bottom_left.gif b/themes/default/window/bottom_left.gif new file mode 100644 index 0000000..4c73d35 Binary files /dev/null and b/themes/default/window/bottom_left.gif differ diff --git a/themes/default/window/bottom_mid.gif b/themes/default/window/bottom_mid.gif new file mode 100644 index 0000000..9205d30 Binary files /dev/null and b/themes/default/window/bottom_mid.gif differ diff --git a/themes/default/window/bottom_right.gif b/themes/default/window/bottom_right.gif new file mode 100644 index 0000000..8d002ee Binary files /dev/null and b/themes/default/window/bottom_right.gif differ diff --git a/themes/default/window/bottom_right_resize.gif b/themes/default/window/bottom_right_resize.gif new file mode 100644 index 0000000..649b0d8 Binary files /dev/null and b/themes/default/window/bottom_right_resize.gif differ diff --git a/themes/default/window/button_down.png b/themes/default/window/button_down.png new file mode 100644 index 0000000..f047fbd Binary files /dev/null and b/themes/default/window/button_down.png differ diff --git a/themes/default/window/button_hover.png b/themes/default/window/button_hover.png new file mode 100644 index 0000000..09de4c8 Binary files /dev/null and b/themes/default/window/button_hover.png differ diff --git a/themes/default/window/button_normal.png b/themes/default/window/button_normal.png new file mode 100644 index 0000000..603e4df Binary files /dev/null and b/themes/default/window/button_normal.png differ diff --git a/themes/default/window/center_left.gif b/themes/default/window/center_left.gif new file mode 100644 index 0000000..79e7a1c Binary files /dev/null and b/themes/default/window/center_left.gif differ diff --git a/themes/default/window/center_right.gif b/themes/default/window/center_right.gif new file mode 100644 index 0000000..554c55c Binary files /dev/null and b/themes/default/window/center_right.gif differ diff --git a/themes/default/window/changepassword.png b/themes/default/window/changepassword.png new file mode 100644 index 0000000..ff9b523 Binary files /dev/null and b/themes/default/window/changepassword.png differ diff --git a/themes/default/window/changepassword_down.png b/themes/default/window/changepassword_down.png new file mode 100644 index 0000000..d2a20f5 Binary files /dev/null and b/themes/default/window/changepassword_down.png differ diff --git a/themes/default/window/changepassword_hover.png b/themes/default/window/changepassword_hover.png new file mode 100644 index 0000000..f8d914e Binary files /dev/null and b/themes/default/window/changepassword_hover.png differ diff --git a/themes/default/window/close.gif b/themes/default/window/close.gif new file mode 100644 index 0000000..00b76a2 Binary files /dev/null and b/themes/default/window/close.gif differ diff --git a/themes/default/window/close_inactive.gif b/themes/default/window/close_inactive.gif new file mode 100644 index 0000000..cb1e4ba Binary files /dev/null and b/themes/default/window/close_inactive.gif differ diff --git a/themes/default/window/detach.gif b/themes/default/window/detach.gif new file mode 100644 index 0000000..f56a442 Binary files /dev/null and b/themes/default/window/detach.gif differ diff --git a/themes/default/window/detach_inactive.gif b/themes/default/window/detach_inactive.gif new file mode 100644 index 0000000..26a14c2 Binary files /dev/null and b/themes/default/window/detach_inactive.gif differ diff --git a/themes/default/window/hideoffline.png b/themes/default/window/hideoffline.png new file mode 100644 index 0000000..34e795d Binary files /dev/null and b/themes/default/window/hideoffline.png differ diff --git a/themes/default/window/imanyone.png b/themes/default/window/imanyone.png new file mode 100644 index 0000000..da833c0 Binary files /dev/null and b/themes/default/window/imanyone.png differ diff --git a/themes/default/window/imanyone_down.png b/themes/default/window/imanyone_down.png new file mode 100644 index 0000000..1d8eb0e Binary files /dev/null and b/themes/default/window/imanyone_down.png differ diff --git a/themes/default/window/imanyone_hover.png b/themes/default/window/imanyone_hover.png new file mode 100644 index 0000000..801790f Binary files /dev/null and b/themes/default/window/imanyone_hover.png differ diff --git a/themes/default/window/italic_off.png b/themes/default/window/italic_off.png new file mode 100644 index 0000000..b24e714 Binary files /dev/null and b/themes/default/window/italic_off.png differ diff --git a/themes/default/window/italic_off_hover.png b/themes/default/window/italic_off_hover.png new file mode 100644 index 0000000..9bc7175 Binary files /dev/null and b/themes/default/window/italic_off_hover.png differ diff --git a/themes/default/window/italic_on.png b/themes/default/window/italic_on.png new file mode 100644 index 0000000..f7ae133 Binary files /dev/null and b/themes/default/window/italic_on.png differ diff --git a/themes/default/window/italic_on_hover.png b/themes/default/window/italic_on_hover.png new file mode 100644 index 0000000..9d9bd90 Binary files /dev/null and b/themes/default/window/italic_on_hover.png differ diff --git a/themes/default/window/joinroom.png b/themes/default/window/joinroom.png new file mode 100644 index 0000000..80cd148 Binary files /dev/null and b/themes/default/window/joinroom.png differ diff --git a/themes/default/window/joinroom_down.png b/themes/default/window/joinroom_down.png new file mode 100644 index 0000000..9be4732 Binary files /dev/null and b/themes/default/window/joinroom_down.png differ diff --git a/themes/default/window/joinroom_hover.png b/themes/default/window/joinroom_hover.png new file mode 100644 index 0000000..a3095e1 Binary files /dev/null and b/themes/default/window/joinroom_hover.png differ diff --git a/themes/default/window/maximize.gif b/themes/default/window/maximize.gif new file mode 100644 index 0000000..088c252 Binary files /dev/null and b/themes/default/window/maximize.gif differ diff --git a/themes/default/window/maximize_inactive.gif b/themes/default/window/maximize_inactive.gif new file mode 100644 index 0000000..8f60ca1 Binary files /dev/null and b/themes/default/window/maximize_inactive.gif differ diff --git a/themes/default/window/minimize.gif b/themes/default/window/minimize.gif new file mode 100644 index 0000000..e142194 Binary files /dev/null and b/themes/default/window/minimize.gif differ diff --git a/themes/default/window/minimize_inactive.gif b/themes/default/window/minimize_inactive.gif new file mode 100644 index 0000000..dbf4c40 Binary files /dev/null and b/themes/default/window/minimize_inactive.gif differ diff --git a/themes/default/window/offline.png b/themes/default/window/offline.png new file mode 100644 index 0000000..102854f Binary files /dev/null and b/themes/default/window/offline.png differ diff --git a/themes/default/window/online.png b/themes/default/window/online.png new file mode 100644 index 0000000..7fb2459 Binary files /dev/null and b/themes/default/window/online.png differ diff --git a/themes/default/window/overlay.png b/themes/default/window/overlay.png new file mode 100644 index 0000000..0ac83e3 Binary files /dev/null and b/themes/default/window/overlay.png differ diff --git a/themes/default/window/removebuddy.png b/themes/default/window/removebuddy.png new file mode 100644 index 0000000..ad2f5a5 Binary files /dev/null and b/themes/default/window/removebuddy.png differ diff --git a/themes/default/window/removebuddy_down.png b/themes/default/window/removebuddy_down.png new file mode 100644 index 0000000..794ce83 Binary files /dev/null and b/themes/default/window/removebuddy_down.png differ diff --git a/themes/default/window/removebuddy_hover.png b/themes/default/window/removebuddy_hover.png new file mode 100644 index 0000000..62978f0 Binary files /dev/null and b/themes/default/window/removebuddy_hover.png differ diff --git a/themes/default/window/resize.gif b/themes/default/window/resize.gif new file mode 100644 index 0000000..c440702 Binary files /dev/null and b/themes/default/window/resize.gif differ diff --git a/themes/default/window/signoff.png b/themes/default/window/signoff.png new file mode 100644 index 0000000..b9a3813 Binary files /dev/null and b/themes/default/window/signoff.png differ diff --git a/themes/default/window/signoff_down.png b/themes/default/window/signoff_down.png new file mode 100644 index 0000000..08a08d4 Binary files /dev/null and b/themes/default/window/signoff_down.png differ diff --git a/themes/default/window/signoff_hover.png b/themes/default/window/signoff_hover.png new file mode 100644 index 0000000..8471c83 Binary files /dev/null and b/themes/default/window/signoff_hover.png differ diff --git a/themes/default/window/sizer.gif b/themes/default/window/sizer.gif new file mode 100644 index 0000000..649b0d8 Binary files /dev/null and b/themes/default/window/sizer.gif differ diff --git a/themes/default/window/smallx.png b/themes/default/window/smallx.png new file mode 100644 index 0000000..a422c63 Binary files /dev/null and b/themes/default/window/smallx.png differ diff --git a/themes/default/window/smallx_hover.png b/themes/default/window/smallx_hover.png new file mode 100644 index 0000000..5a8a00f Binary files /dev/null and b/themes/default/window/smallx_hover.png differ diff --git a/themes/default/window/top_left.gif b/themes/default/window/top_left.gif new file mode 100644 index 0000000..0e7e0dd Binary files /dev/null and b/themes/default/window/top_left.gif differ diff --git a/themes/default/window/top_left_inactive.gif b/themes/default/window/top_left_inactive.gif new file mode 100644 index 0000000..8a6713a Binary files /dev/null and b/themes/default/window/top_left_inactive.gif differ diff --git a/themes/default/window/top_mid.gif b/themes/default/window/top_mid.gif new file mode 100644 index 0000000..d53c692 Binary files /dev/null and b/themes/default/window/top_mid.gif differ diff --git a/themes/default/window/top_mid_inactive.gif b/themes/default/window/top_mid_inactive.gif new file mode 100644 index 0000000..4f655d4 Binary files /dev/null and b/themes/default/window/top_mid_inactive.gif differ diff --git a/themes/default/window/top_right.gif b/themes/default/window/top_right.gif new file mode 100644 index 0000000..c5cbd93 Binary files /dev/null and b/themes/default/window/top_right.gif differ diff --git a/themes/default/window/top_right_inactive.gif b/themes/default/window/top_right_inactive.gif new file mode 100644 index 0000000..640b15e Binary files /dev/null and b/themes/default/window/top_right_inactive.gif differ diff --git a/themes/default/window/underline_off.png b/themes/default/window/underline_off.png new file mode 100644 index 0000000..78322ea Binary files /dev/null and b/themes/default/window/underline_off.png differ diff --git a/themes/default/window/underline_off_hover.png b/themes/default/window/underline_off_hover.png new file mode 100644 index 0000000..92f5bbd Binary files /dev/null and b/themes/default/window/underline_off_hover.png differ diff --git a/themes/default/window/underline_on.png b/themes/default/window/underline_on.png new file mode 100644 index 0000000..d35a3d9 Binary files /dev/null and b/themes/default/window/underline_on.png differ diff --git a/themes/default/window/underline_on_hover.png b/themes/default/window/underline_on_hover.png new file mode 100644 index 0000000..870518d Binary files /dev/null and b/themes/default/window/underline_on_hover.png differ diff --git a/update.php b/update.php new file mode 100644 index 0000000..9ff498d --- /dev/null +++ b/update.php @@ -0,0 +1,153 @@ + + + + + ajax im - update version 3.3 to 3.x + + + + +

      ajax im

      + +
      +

      before you begin...

      +
        +
      • are you sure you are updating, not installing?
      • + CHMOD buddyicons/ to 0777, it is at: '. substr(sprintf('%o', fileperms('./buddyicons/')), -4) .'!'; } ?> +
      +
      + +
      +
      +

      ready?

      + + +
      +
      + +
      +

      updating...

      +
      \n"; + } else { + print("A MySQL error occured: (" . mysql_errno() . ") " . mysql_error() . "

      \n"); + $error = true; + } + } else { + print "Table '".SQL_PREFIX."users' altered successfully!

      \n"; + } + + if ($maxBuddyIconSize > 0) { + if (trim(substr(sprintf('%o', fileperms('./buddyicons/')), -4)) != 777) { + $error = true; + print "File permissions::

      CHMOD buddyicons/ to 0777

      "; + } else { + print "You have change permissions of buddyicons/

      "; + } + } + + mysql_close(); + ?> +
      + +
      +

      status

      + here. Please be sure to delete install.php and update.php!'; + ?> +
      + + +