Created
August 7, 2012 13:35
-
-
Save ryankinal/3285409 to your computer and use it in GitHub Desktop.
My chat script (client side)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| Chat: A factory for multi-room chat clients. | |
| methods: | |
| create(container, rooms) | |
| - container is the ID of the element in which to build the chat interface | |
| - rooms is either an encrypted enrollment ID or an array of room definitions | |
| - returns a ChatClient (described below) | |
| **/ | |
| var Chat = (function() { | |
| /** | |
| ChatUser: Represents a user in the activeUsers list | |
| in any given room. There may be multiple ChatUsers | |
| that represent the same user, but in a different room. | |
| members: | |
| elem - the <li> element that contains user information | |
| ignore - the anchor that allows the user to be (un)ignored | |
| text - the user's name as a text node | |
| id - the user's studentID | |
| lastMessageSent - time since the user last sent a message | |
| roomID - the room that the user sent the last message to | |
| methods: | |
| update(data) | |
| - data is an object containing user data | |
| - studentID | |
| - username | |
| - lastMessageSent - time since the last message the user sent (negative number) | |
| - roomID - the room that the user sent the last message to | |
| - ignored - whether the current user has ignored this user | |
| - returns undefined | |
| **/ | |
| var ChatUser = { | |
| update: function(p_data) | |
| { | |
| if (!this.elem) | |
| { | |
| this.elem = document.createElement('li'); | |
| this.ignore = document.createElement('a'); | |
| this.text = document.createTextNode(p_data.username || 'guest'); | |
| /** stop ignoring yourself **/ | |
| /** stop ignoring yourself **/ | |
| if (!p_data.isSelf) | |
| { | |
| this.elem.appendChild(this.ignore); | |
| } | |
| this.elem.appendChild(this.text); | |
| this.ignore.studentID = p_data.studentID; | |
| this.ignoreText = document.createTextNode('block'); | |
| this.ignore.appendChild(this.ignoreText); | |
| this.ignore.title = 'block this user'; | |
| this.ignore.className = 'block'; | |
| this.lastMessageSent = 0; | |
| } | |
| this.id = p_data.studentID; | |
| this.lastMessageSent = p_data.lastMessageSent; | |
| this.username = p_data.username; | |
| this.roomID = p_data.roomID; | |
| if (p_data.ignored) | |
| { | |
| this.ignoreText.nodeValue = 'unblock'; | |
| this.ignore.title = 'unblock this user'; | |
| this.ignore.className = 'unblock'; | |
| } | |
| else | |
| { | |
| this.ignoreText.nodeValue = 'block'; | |
| this.ignore.title = 'block this user'; | |
| this.ignore.className = 'block'; | |
| } | |
| if (this.roomID && (this.lastMessageSent || this.lastMessageSent === 0) && this.lastMessageSent > -30) | |
| { | |
| this.elem.className = 'chat-user-active'; | |
| } | |
| else | |
| { | |
| this.elem.className = 'chat-user-inactive'; | |
| } | |
| } | |
| }; | |
| var ChatRoom = { | |
| /** | |
| handleClicks returns a function to be used as an event handler on the | |
| room's container element. That function then handles all clicks within | |
| that element, checking on classNames to determine how to handle the click. | |
| **/ | |
| handleClicks: function(room) | |
| { | |
| // Create callback creates a callback to be used with ChatService webmethods | |
| var createCallback = function(username, message, failureCallback) | |
| { | |
| failureCallback = failureCallback || function() {}; | |
| return function(p_data) | |
| { | |
| if (p_data) | |
| { | |
| room.addMessage({ | |
| username: username, | |
| body: message | |
| }); | |
| room.commitMessages(); | |
| } | |
| else | |
| { | |
| failureCallback(); | |
| } | |
| } | |
| }, | |
| ignoreFailure = createCallback('system', 'There was a problem blocking the user. Please try again.'), | |
| ignoreSuccess = createCallback('system', 'User blocked.', ignoreFailure), | |
| unignoreFailure = createCallback('system', 'There was a problem unblocking the user. Please try again.'), | |
| unignoreSuccess = createCallback('system', 'User unblocked.', unignoreFailure), | |
| flagFailure = createCallback('system', 'There was a problem flagging the message. Please try again.'), | |
| flagSuccess = createCallback('system', 'Message flagged.', flagFailure); | |
| return function(p_e) | |
| { | |
| p_e = p_e || window.event; | |
| var target = p_e.target || p_e.srcElement, | |
| id = target.id; | |
| switch (target.className) | |
| { | |
| case 'block': | |
| ChatService.ignoreUser( | |
| target.studentID, | |
| ignoreSuccess, | |
| ignoreFailure | |
| ); | |
| target.firstChild.nodeValue = 'unblock'; | |
| target.className = 'unblock'; | |
| target.title = 'unblock this user'; | |
| break; | |
| case 'unblock': | |
| ChatService.ignoreUser( | |
| target.studentID, | |
| unignoreSuccess, | |
| unignoreFailure | |
| ); | |
| target.firstChild.nodeValue = 'block'; | |
| target.className = 'block'; | |
| target.title = 'block this user'; | |
| break; | |
| case 'flag': | |
| ChatService.flagMessage( | |
| target.messageID, | |
| flagSuccess, | |
| flagFailure | |
| ); | |
| target.className = 'flagged'; | |
| break; | |
| case 'active-users-help': | |
| $('#active-users-help').show().siblings().hide().end().parent().data('open')(); | |
| break; | |
| } | |
| } | |
| }, | |
| show: function() | |
| { | |
| this.elem.style.display = 'block'; | |
| }, | |
| hide: function() | |
| { | |
| this.elem.style.display = 'none'; | |
| }, | |
| /** | |
| addMessage creates a DocumentFragment if none exists, builds a message | |
| element, and adds that element to the document fragment. In order | |
| for the documentfragment to be appended to the document, commitMessages() | |
| must be called. | |
| **/ | |
| addMessage: function(p_message) | |
| { | |
| this.fragment = this.fragment || document.createDocumentFragment(); | |
| var elem = document.createElement('div'), | |
| username = document.createElement('div'), | |
| message = document.createElement('div'), | |
| flag = document.createElement('a'), | |
| body = p_message.body; | |
| flag.title = 'flag this message as inappropriate'; | |
| flag.className = 'flag'; | |
| flag.messageID = p_message.id; | |
| body = body.replace(p_message.username, '{name}'); | |
| body = body.replace('{name}', p_message.username); | |
| if (p_message.username !== 'system' && !p_message.isSelf) | |
| { | |
| message.appendChild(flag); | |
| } | |
| message.appendChild(document.createTextNode(body)); | |
| message.className = 'body'; | |
| username.appendChild(document.createTextNode(p_message.username || 'guest')); | |
| username.className = 'username'; | |
| elem.className = 'message'; | |
| elem.appendChild(username); | |
| elem.appendChild(message); | |
| if (p_message.username === 'system') | |
| { | |
| elem.className += ' system'; | |
| } | |
| if (p_message.lastMessageSent) | |
| { | |
| this.lastMessageSent = new Date(p_message.lastMessageSent); | |
| } | |
| else | |
| { | |
| delete this.lastMessageSent; | |
| } | |
| this.fragment.appendChild(elem); | |
| }, | |
| /** | |
| "flushes the buffer" by appending the room's document | |
| fragment to the document, if the fragment exists. | |
| The fragment is then removed from the object. | |
| **/ | |
| commitMessages: function() | |
| { | |
| var lms, str, year, pm; | |
| if (this.fragment && this.fragment.childNodes.length > 0) | |
| { | |
| if (this.lastMessageSent) | |
| { | |
| year = this.lastMessageSent.getYear(); | |
| year = (year > 2000) ? year : year + 1900; | |
| pm = (this.lastMessageSent.getHours() >= 12); | |
| minutes = this.lastMessageSent.getMinutes(); | |
| minutes = (minutes < 10) ? '0' + minutes : minutes; | |
| str = 'Last message sent on ' + | |
| (this.lastMessageSent.getMonth() + 1) + '/' + | |
| this.lastMessageSent.getDate() + '/' + | |
| year + ' at ' + | |
| (this.lastMessageSent.getHours() % 12 || 12) + ':' + | |
| minutes + | |
| (pm ? ' pm' : ' am') + | |
| ' (eastern) - showing one hour of messages'; | |
| lms = document.createElement('div'); | |
| lms.className = 'message last-sent'; | |
| lms.appendChild(document.createTextNode(str)); | |
| this.fragment.appendChild(lms); | |
| delete this.lastMessageSent; | |
| } | |
| else if (this.tab.className.indexOf('new') < 0 && this.tab.className.indexOf('active') < 0) | |
| { | |
| this.tab.className += ' new'; | |
| } | |
| this.messages.insertBefore(this.fragment, this.bottom); | |
| if (!this.scrolling) | |
| { | |
| $(this.messages).scrollTo(this.bottom); | |
| } | |
| delete this.fragment; | |
| } | |
| }, | |
| scrollToBottom: function() | |
| { | |
| $(this.messages).scrollTo(this.bottom); | |
| this.scrolling = false; | |
| }, | |
| /** | |
| removes all users from the active users list | |
| **/ | |
| clearUsers: function() | |
| { | |
| var users = this.activeUsers; | |
| while (users.childNodes.length) | |
| { | |
| users.removeChild(users.firstChild); | |
| } | |
| }, | |
| /** | |
| If the given user does not exist in the element list, | |
| it is created. It is then updated and re-appended. | |
| **/ | |
| addUser: function(p_user) | |
| { | |
| if (!this.users) | |
| { | |
| this.users = {}; | |
| } | |
| if (!this.users[p_user.studentID]) | |
| { | |
| this.users[p_user.studentID] = Object.create(ChatUser); | |
| } | |
| this.users[p_user.studentID].update(p_user); | |
| this.activeUsers.appendChild(this.users[p_user.studentID].elem); | |
| }, | |
| /** | |
| Builds all necessary members and elements for this room | |
| **/ | |
| initialize: function(p_room) | |
| { | |
| var element = document.createElement('div'), | |
| activeUsers = document.createElement('div'), | |
| usersHeader = document.createElement('h4'), | |
| usersList = document.createElement('ul'), | |
| messages = document.createElement('div'), | |
| bottom = document.createElement('div'), | |
| newMessage = document.createElement('span'), | |
| tab = document.createElement('li'); | |
| element.className = 'room'; | |
| element.id = 'room' + p_room.id; | |
| messages.className = 'messages'; | |
| bottom.className = 'bottom'; | |
| bottom.id = 'bottom' + p_room.id; | |
| usersHeader.appendChild(document.createTextNode('Active users')); | |
| usersHeader.className = 'active-users-help'; | |
| activeUsers.className = 'chat-active-users'; | |
| activeUsers.appendChild(usersHeader); | |
| activeUsers.appendChild(usersList); | |
| messages.appendChild(bottom); | |
| element.appendChild(activeUsers); | |
| element.appendChild(messages); | |
| newMessage.title = 'There is a new message'; | |
| newMessage.appendChild(document.createTextNode('*')); | |
| tab.appendChild(newMessage); | |
| tab.appendChild(document.createTextNode(p_room.name)); | |
| tab.className = 'chat-tab'; | |
| tab.id = 'chat-tab' + p_room.id; | |
| tab.title = p_room.description; | |
| this.id = p_room.id; | |
| this.elem = element; | |
| this.tab = tab; | |
| this.elem.onclick = this.handleClicks(this); | |
| this.description = p_room.description; | |
| this.name = p_room.name; | |
| this.bottom = bottom; | |
| this.activeUsers = usersList; | |
| this.messages = messages; | |
| this.scrolling = false; | |
| this.messages.onscroll = (function(self) { | |
| return function(p_e) { | |
| if (self.messages.scrollTop < self.messages.scrollHeight - self.messages.offsetHeight) | |
| { | |
| self.scrolling = true | |
| } | |
| else | |
| { | |
| self.scrolling = false; | |
| } | |
| } | |
| })(this); | |
| this.hide(); | |
| } | |
| }; | |
| var ChatClient = { | |
| /** | |
| If passed a string as the first argument, gets a list of | |
| rooms related to that enrollment ID from the server, | |
| and re-calls this method. With an array of objects | |
| representing rooms. | |
| If passed an array as the first argument, it creates a | |
| new ChatRoom for each element, and initializes it as | |
| necessary. | |
| **/ | |
| setRooms: function(p_arg, self) | |
| { | |
| var i, element, tab, bottom, activeUsers, usersList, room, messages, fragment, newMesage, roomIDs = []; | |
| self = self || this; | |
| if (p_arg) | |
| { | |
| if (typeof p_arg === 'object' && p_arg.length) | |
| { | |
| fragment = document.createDocumentFragment(); | |
| self.rooms = {}; | |
| for (i = 0; i < p_arg.length; i++) | |
| { | |
| roomIDs.push(p_arg[i].id); | |
| room = Object.create(ChatRoom); | |
| room.initialize(p_arg[i]); | |
| self.rooms[p_arg[i].id] = room; | |
| self.tabs.appendChild(room.tab); | |
| fragment.appendChild(room.elem); | |
| } | |
| self.output.appendChild(fragment); | |
| self.activeRoom = self.rooms[p_arg[i - 1].id]; | |
| self.activeRoom.show(); | |
| self.tabs.lastChild.className += ' active'; | |
| ChatService.initialize( | |
| roomIDs.join(','), | |
| self.messagesSuccess(self), | |
| self.messagesFail(self) | |
| ); | |
| self.getActiveUsers(self); | |
| } | |
| else | |
| { | |
| ChatService.getRoomsByEnrollmentID(p_arg, function(data) { self.setRooms(data, self); }); | |
| } | |
| } | |
| }, | |
| messagesSuccess: function(context) | |
| { | |
| var s = [], | |
| self = context || this; | |
| return function(p_data) | |
| { | |
| var i, j, room, l, data, leetFilter = {'l': '1', 'e': '3', 't': '7', 'a': '4', 'i': '1', 'o': '0'}, rex, teh = /the/gi, cks = /(cks|ck)/gi; | |
| if (p_data && p_data.length) | |
| { | |
| l = p_data.length; | |
| for (i = 0; i < l; ++i) | |
| { | |
| data = p_data[i]; | |
| if (self.leet) | |
| { | |
| data.body = data.body.replace(teh, 'teh'); | |
| data.body = data.body.replace(cks, 'x'); | |
| for (j in leetFilter) | |
| { | |
| rex = new RegExp(j, 'gi'); | |
| data.body = data.body.replace(rex, leetFilter[j]); | |
| } | |
| } | |
| self.rooms[data.roomID].addMessage(data); | |
| } | |
| self.commitMessages(); | |
| self.pollInterval = 1000; | |
| self.activeRoom.tab.className = 'chat-tab active'; | |
| } | |
| else | |
| { | |
| // If there is no data, we want to increase the poll interval, | |
| // so we don't tax the server too severely. Five polls at the | |
| // same interval means an increase of 1 second in the interval | |
| if (++(self.counter) > 5) | |
| { | |
| self.pollInterval += (self.pollInterval < 10000) ? 1000 : 0; | |
| self.counter = 0; | |
| } | |
| } | |
| if (self.polling) | |
| { | |
| // make sure the timeout is cleared so | |
| // we're not doubling up on the polling | |
| if (self.messageTimeout) | |
| { | |
| clearTimeout(self.messageTimeout); | |
| } | |
| self.messageTimeout = setTimeout(self.getMessages(self), self.pollInterval); | |
| } | |
| }; | |
| }, | |
| messagesFail: function(context) | |
| { | |
| var self = context || this; | |
| return function() | |
| { | |
| // Failure could mean a lot of things, but in any | |
| // case, we don't want to tax the server with useless | |
| // poll requests, so we increase the interval every | |
| // time this happens, but set the counter to 0 | |
| if (self.messageTimeout) | |
| { | |
| clearTimeout(self.messageTimeout); | |
| } | |
| self.pollInterval += (self.pollInterval < 10000) ? 1000 : 0; | |
| self.messageTimeout = setTimeout(self.getMessages(self), self.pollInterval); | |
| self.counter = 0; | |
| } | |
| }, | |
| scrollAllToBottom: function() | |
| { | |
| var i; | |
| for (i in this.rooms) | |
| { | |
| if (this.rooms.hasOwnProperty(i)) | |
| { | |
| this.rooms[i].scrollToBottom(); | |
| } | |
| } | |
| }, | |
| /** | |
| Gets messages for all rooms, and passes those messages | |
| off to each individual room to be buffered as necessary. | |
| Once all messages are processed, commitMessages is called, | |
| which flushes the buffer of each room, thus displaying the messages. | |
| **/ | |
| getMessages: function(context) | |
| { | |
| var s = [], | |
| self = context || this; | |
| return function() | |
| { | |
| var i; // join all room IDs into a string to be passed as an argument | |
| for (i in this.rooms) | |
| { | |
| if (this.rooms.hasOwnProperty(i)) | |
| { | |
| s.push(i); | |
| } | |
| } | |
| ChatService.getMessages( | |
| s.join(','), | |
| self.messagesSuccess(self), | |
| self.messagesFail(self) | |
| ); | |
| } | |
| }, | |
| // Flush all output buffers in all rooms | |
| commitMessages: function() | |
| { | |
| var i, rooms = this.rooms; | |
| for (i in rooms) | |
| { | |
| if (rooms.hasOwnProperty(i)) | |
| { | |
| rooms[i].commitMessages(); | |
| } | |
| } | |
| }, | |
| // Gets all active users for all rooms every 10 seconds | |
| // if a user is active (has sent polls), but has not | |
| // sent any messages, then roomID will be null, and | |
| // the user should be added to all rooms | |
| getActiveUsers: function(context) | |
| { | |
| var s = [], | |
| self = context || this; | |
| return function() | |
| { | |
| var i; | |
| for (i in self.rooms) | |
| { | |
| if (self.rooms.hasOwnProperty(i)) | |
| { | |
| s.push(i); | |
| } | |
| } | |
| ChatService.getActiveUsers( | |
| s.join(','), | |
| function(p_data) | |
| { | |
| var i, room, l, data; | |
| if (p_data && p_data.length) | |
| { | |
| self.clearAllUsers(); | |
| l = p_data.length; | |
| for (i = 0; i < l; ++i) | |
| { | |
| data = p_data[i]; | |
| if (p_data[i].roomID) | |
| { | |
| self.rooms[data.roomID].addUser(data); | |
| } | |
| else | |
| { | |
| self.addUserToAllRooms(data); | |
| } | |
| } | |
| } | |
| if (self.polling) | |
| { | |
| self.usersTimeout = setTimeout(self.getActiveUsers(self), 10000); | |
| } | |
| }, | |
| function() | |
| { | |
| self.usersTimeout = setTimeout(self.getActiveUsers(self), 10000); | |
| } | |
| ); | |
| } | |
| }, | |
| clearAllUsers: function() | |
| { | |
| var i; | |
| for (i in this.rooms) | |
| { | |
| if (this.rooms.hasOwnProperty(i)) | |
| { | |
| this.rooms[i].clearUsers(); | |
| } | |
| } | |
| }, | |
| addUserToAllRooms: function(p_user) | |
| { | |
| var i; | |
| for (i in this.rooms) | |
| { | |
| if (this.rooms.hasOwnProperty(i)) | |
| { | |
| this.rooms[i].addUser(p_user); | |
| } | |
| } | |
| }, | |
| /** | |
| start polling for messages and users | |
| **/ | |
| startPoll: function() | |
| { | |
| var self = this; | |
| this.stopPoll(); | |
| this.polling = true; | |
| this.getMessages(this)(); | |
| this.getActiveUsers(this)(); | |
| setTimeout(function() { | |
| $(self.activeRoom.messages).scrollTo(self.activeRoom.bottom); | |
| }, platform.animationSpeed / 2); | |
| }, | |
| /** | |
| stop all polling for messages and users | |
| **/ | |
| stopPoll: function() | |
| { | |
| if (this.messageTimeout) | |
| { | |
| clearTimeout(this.messageTimeout) | |
| } | |
| if (this.usersTimeout) | |
| { | |
| clearTimeout(this.usersTimeout); | |
| } | |
| this.polling = false; | |
| this.pollInterval = 1000; | |
| }, | |
| /** | |
| sets which room is the active room | |
| This is mostly called from the click handler | |
| **/ | |
| setActiveRoom: function(p_id) | |
| { | |
| if (this.rooms[p_id]) | |
| { | |
| var i; | |
| this.activeRoom = this.rooms[p_id]; | |
| for (i in this.rooms) | |
| { | |
| if (this.rooms.hasOwnProperty(i)) | |
| { | |
| this.rooms[i].hide(); | |
| } | |
| } | |
| this.activeRoom.show(); | |
| this.activeRoom.tab.className = 'chat-tab active'; | |
| if (!this.scrolling) | |
| { | |
| $(this.activeRoom.messages).scrollTo(this.activeRoom.bottom); | |
| } | |
| } | |
| }, | |
| /** | |
| Sends a message to the active room | |
| **/ | |
| sendMessage: function() | |
| { | |
| var message = this.input.value, | |
| self = this; | |
| if (message && message !== '') | |
| { | |
| if (message === '/1337') | |
| { | |
| if (this.leet) | |
| { | |
| this.leet = false; | |
| this.activeRoom.addMessage({ | |
| 'username': 'system', | |
| 'body': 'leet hacks disabled' | |
| }); | |
| this.activeRoom.commitMessages(); | |
| } | |
| else | |
| { | |
| this.leet = true; | |
| this.activeRoom.addMessage({ | |
| 'username': 'system', | |
| 'body': '1337 h4x 3n4bl3d' | |
| }); | |
| this.activeRoom.commitMessages(); | |
| } | |
| this.input.value = ''; | |
| return false; | |
| } | |
| this.input.value = ''; | |
| platform.inactivity.update(); | |
| ChatService.sendMessage( | |
| self.activeRoom.id, | |
| message, | |
| function(p_data) | |
| { | |
| // Since we know there's data, | |
| // we might as well reset the poll timer | |
| // and go get it | |
| if (this.messageTimeout) | |
| { | |
| clearTimeout(self.messageTimeout); | |
| } | |
| self.pollInterval = 0; | |
| self.getMessages(self)(); | |
| self.input.value = ''; | |
| }, | |
| function() | |
| { | |
| self.error('There was a problem sending your message. Please try again.'); | |
| self.input.value = message; | |
| } | |
| ); | |
| } | |
| }, | |
| error: function(p_message) | |
| { | |
| self.activeRoom.addMessage({ | |
| username: 'system', | |
| body: p_message | |
| }); | |
| }, | |
| /** | |
| Returns a function which is used as a click handler. | |
| This click handler handles all clicks for the entire | |
| chat client via delegation. | |
| **/ | |
| handleClicks: function(chat) | |
| { | |
| return function(p_e) | |
| { | |
| p_e = p_e || window.event; | |
| var target = p_e.target || p_e.srcElement, | |
| className = target.className, | |
| id = target.id.replace('chat-tab', ''), | |
| tabs, | |
| i; | |
| if (platform && platform.inactivity) | |
| { | |
| platform.inactivity.update(); | |
| } | |
| switch (target.className) | |
| { | |
| case 'chat-send': | |
| chat.sendMessage(); | |
| break; | |
| case 'chat-rooms-help': | |
| $('#chat-rooms-help').show().siblings().hide().end().parent().data('open')(); | |
| break; | |
| case 'chat-tab': | |
| case 'chat-tab new': | |
| chat.setActiveRoom(id); | |
| tabs = target.parentNode.getElementsByTagName('li'); | |
| for (i = 0; i < tabs.length; i++) | |
| { | |
| tabs[i].className = tabs[i].className.replace(/active/g, '').replace(/(^\s+|\s+$)/g, '').replace(/(\s{2,})/g, ' '); | |
| } | |
| target.className += ' active'; | |
| break; | |
| } | |
| } | |
| }, | |
| /** | |
| Set all necessary values for the client. | |
| Sets up event handlers for the client. | |
| **/ | |
| initialize: function(p_container, p_rooms) | |
| { | |
| var self = this, | |
| roomsLabel = document.createElement('li'); | |
| roomsLabel.appendChild(document.createTextNode('Chat rooms:')); | |
| roomsLabel.className = 'chat-rooms-help'; | |
| this.counter = 0; | |
| this.container = document.getElementById(p_container); | |
| if (!this.container) | |
| { | |
| return false; | |
| } | |
| this.container.onclick = this.handleClicks(self); | |
| this.input = document.createElement('input'); | |
| this.input.type = 'text'; | |
| this.input.className = 'chat-input'; | |
| this.input.onkeypress = function(p_e) | |
| { | |
| p_e = p_e || window.event; | |
| var which = p_e.which || p_e.keyCode; | |
| if (which === 13) | |
| { | |
| self.sendMessage(); | |
| return false; | |
| } | |
| } | |
| this.send = document.createElement('input'); | |
| this.send.type = 'button'; | |
| this.send.value = 'Send'; | |
| this.send.className = 'chat-send'; | |
| this.notifications = document.createElement('div'); | |
| this.notifications.className = 'chat-notifications'; | |
| this.tabs = document.createElement('ul'); | |
| this.tabs.className = 'chat-tabs header'; | |
| this.controls = document.createElement('div'); | |
| this.controls.className = 'chat-controls'; | |
| this.output = document.createElement('div'); | |
| this.output.className = 'chat-output'; | |
| this.tabs.appendChild(roomsLabel); | |
| this.setRooms(p_rooms); | |
| this.controls.appendChild(this.input); | |
| this.controls.appendChild(this.send); | |
| this.controls.appendChild(this.notifications); | |
| this.container.appendChild(this.tabs); | |
| this.container.appendChild(this.output); | |
| this.container.appendChild(this.controls); | |
| } | |
| }; | |
| // This return defines the Factory interface | |
| // Since "create" returns a ChatClient, all | |
| // methods of ChatClient are availabe to the | |
| // returned object | |
| return { | |
| create: function(p_container, p_rooms, p_init) | |
| { | |
| var client = Object.create(ChatClient); | |
| if (p_init || p_init === 'undefined') | |
| { | |
| client.initialize(p_container, p_rooms); | |
| } | |
| return client; | |
| } | |
| }; | |
| }()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment