Index: examples.tac =================================================================== --- examples.tac (revision 12985) +++ examples.tac (working copy) @@ -54,7 +54,6 @@ from nestedsequence import nestedsequence from fragments import fragments from macros import macros - from chatola import chatola from i18n import i18n, xmli18n from cal import cal from tabbed import tabbed @@ -66,6 +65,7 @@ from athenademo import typeahead from athenademo import widgets from athenademo import benchmark + from athenademo import chatola except ImportError, e: if str(e).find('No module named') != -1: msg = """ @@ -152,7 +152,6 @@ xul_nevow=xul_nevow.createResource(), advanced_manualform=advanced_manualform.Page(), liveanimal=liveanimal.createResource(), - chatola=chatola.createResource(), http_auth=http_auth.AuthorizationRequired(), most_basic=most_basic.root, logout_guard=logout_guard.createResource(), @@ -172,7 +171,7 @@ formless_tests=testformless.formless_tests, fragments=fragments.Root(), macros=macros.Root(), - typeahead=typeahead.DataEntry(), + typeahead=typeahead.DataEntry(), ) def child_calculator(self, ctx): @@ -181,6 +180,9 @@ def child_widgets(self, ctx): return widgets.WidgetPage(None, None) + def child_chatola(self, ctx): + return chatola.ChatolaPage(None, None) + def child_benchmark(self, ctx): return benchmark.Benchmark(400, 20) chatola.py: from twisted.python import util from twisted.internet import reactor from nevow import athena, loaders, static, inevow class TheRoom: """Holds information about the chat room.""" topic = u"Topic is not set yet." clients = [] theRoom = TheRoom() class ChatElement(athena.LiveElement): """I am a chatting element.""" jsClass = u"Chatola.Chat" docFactory = loaders.xmlfile(util.sibpath( __file__, "chatola.html")) nickname = u"guest" room = theRoom def disconnect(self, reason): """This client left the chat room.""" self.room.clients.remove(self) self.sendEvent(u"*** %s left." % self.nickname) def join(self): """Client-side informs the element that it has joined the room.""" self.room.clients.append(self) self.sendEvent(u"*** %s joined." % self.nickname) # set topic reactor.callLater( 0, self.callRemote, 'setTopic', self.room.topic) # remove client if it disconnects d = self.page.notifyOnDisconnect() d.addErrback(self.disconnect) athena.expose(join) def setNickname(self, nickname): """Set nickname of the chatter.""" self.sendEvent(u"*** %s changed nickname to %s" % ( self.nickname, nickname)) self.nickname = nickname athena.expose(setNickname) def setTopic(self, newTopic): """Set topic.""" self.room.topic = newTopic self.sendEvent(u"*** %s changed topic to %s" % ( self.nickname, newTopic)) self.sendCall('setTopic', newTopic) athena.expose(setTopic) def sayLine(self, line): if not line: return self.sendEvent(u"<%s> %s" % (self.nickname, line)) athena.expose(sayLine) def sendEvent(self, event): """Send event to all clients.""" self.sendCall('publish', unicode(event)) def sendCall(self, function, *args): for client in self.room.clients: client.callRemote(function, *args) class ChatolaPage(athena.LivePage): docFactory = loaders.xmlstr("""\
""") addSlash = True child_css = static.File(util.sibpath( __file__, 'chatola.css')) def __init__(self, *a, **kw): super(ChatolaPage, self).__init__(*a, **kw) self.jsModules.mapping[u'Chatola'] = util.sibpath( __file__, 'chatola.js') self.clients = [] def render_chat(self, ctx, data): e = ChatElement() e.setFragmentParent(self) return e chatola.js: // import Nevow.Athena Chatola.Chat = Nevow.Athena.Widget.subclass('Chatola.Chat'); Chatola.Chat.methods( function __init__(self, node) { Chatola.Chat.upcall(self, '__init__', node); self.callRemote('join'); }, function publish(self, event) { var br = document.createElement('br'); var tt = document.createElement('tt'); tt.appendChild(document.createTextNode(event)); var node = self.nodeById("events"); node.appendChild(tt); node.appendChild(br); }, function setTopic(self, topic) { var node = self.nodeById("topic"); node.value = topic; }, function nickChanged(self, event, data) { var node = self.nodeById("nick"); self.callRemote('setNickname', node.value); }, function topicChanged(self, event, data) { var node = self.nodeById("topic"); self.callRemote('setTopic', node.value); }, function lineEntered(self, event, data) { var node = self.nodeById("line"); self.callRemote('sayLine', node.value); node.value = ""; } ); chatola.html:
Nick: say:
chatola.css: table { table-layout: fixed; width: 800px; }