<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w
+3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>pmchatter</title>
<script type="text/javascript">
const PM_URL = 'http://www.perlmonks.org/';
const SEC = 1000;
var cookie = {
data: {},
parse: function( str ) {
this.data = {};
var record = str.split( /\s*;\s*/ );
for( var i = 0; i < record.length; ++i ) {
var kv = record[ i ].split( /=/ );
this.data[ decodeURIComponent( kv[ 0 ] ) ] = decodeURIComp
+onent( kv[ 1 ] );
}
},
get: function( key ) {
return ( this.data[ key ] != undefined ) ? this.data[ key ] :
+'';
}
};
function XMLHttpRequestCallback( req, obj ) {
this.req = req;
this.obj = obj;
return this;
}
XMLHttpRequestCallback.prototype = {
handleEvent: function() {
if( this.req.readyState != 4 ) return;
try{ decodeURIComponent( cookie.parse( this.req.getResponseHea
+der( 'Set-Cookie' ) ) ); }
catch( e ) { }
this.obj.callback( this.req.responseXML );
}
};
function query2url( base_url, query ) {
var url = [ base_url ];
var param = [];
for( var i in query ) {
param.push( [ encodeURIComponent( i ), encodeURIComponent( que
+ry[ i ] ) ].join( '=' ) );
}
if( param.length ) {
url.push( param.join( ';' ) );
}
return url.join( '?' );
}
function make_request( obj, params ) {
netscape.security.PrivilegeManager.enablePrivilege( 'UniversalBrow
+serRead' );
var req = null;
try {
req = new ActiveXObject( 'Msxml2.XMLHTTP' );
}
catch( e ) {
try {
req = new ActiveXObject( 'Microsoft.XMLHTTP' );
}
catch( e ) { }
}
if( ! req && typeof XMLHttpRequest != 'undefined' ) {
req = new XMLHttpRequest();
}
req.open( 'GET', query2url( PM_URL, params ) );
req.onreadystatechange = new XMLHttpRequestCallback( req, obj );
var userpass = cookie.get( 'userpass' );
if( userpass.length ) {
req.setRequestHeader( 'Cookie', 'userpass=' + encodeURICompone
+nt( userpass ) );
}
req.send( null );
}
var login = {
exec: function() {
var p = {
node_id: 106,
op: 'login',
// ticker: 'yes',
user: document.getElementById( 'user' ).value,
passwd: document.getElementById( 'pass' ).value
};
if( ! ( p.user.length && p.passwd.length ) ) return;
make_request( this, p );
document.getElementById( 'login' ).disabled = true;
},
callback: function() {
if( cookie.get( 'userpass' ).indexOf( document.getElementById(
+ 'user' ).value ) != 0 ) {
document.getElementById( 'pass' ).value = '';
}
else {
document.getElementById( 'auth-controls' ).style.display =
+ 'none';
document.getElementById( 'talk-controls' ).style.display =
+ '';
document.getElementById( 'message' ).focus();
}
document.getElementById( 'login' ).disabled = false;
}
};
var load_chat = {
exec: function() {
var p = { node_id: 207304 };
make_request( this, p );
document.getElementById( 'refresh' ).disabled = true;
},
callback: function ( doc ) {
netscape.security.PrivilegeManager.enablePrivilege( 'Universal
+XPConnect' );
var chatter = document.getElementById( 'chatter' );
var msgs = doc.getElementsByTagName( 'message' );
var _read = function( i, tag ) { return msgs[ i ].getElementsB
+yTagName( tag )[ 0 ].firstChild.nodeValue };
var autoscroll = chatter.scrollTop == ( chatter.scrollHeight -
+ chatter.clientHeight );
for( var i = 0; i < msgs.length ; ++i ) {
if( ! document.getElementById( 'msgid:' + _read( i, 'messa
+ge_id' ) ) ) {
var msg = _read( i, 'text' );
var emote = msg.indexOf( '/me ' ) == 0;
var author = document.createElement( 'a' );
author.href = query2url( PM_URL, { node_id: _read( i,
+'user_id' ) } );
author.appendChild( document.createTextNode( _read( i,
+ 'author' ) ) );
var dt = document.createElement( 'dt' );
dt.className = emote ? 'emote' : '';
dt.appendChild( author );
if( ! emote ) dt.appendChild( document.createTextNode(
+ ':' ) );
var dd = document.createElement( 'dd' );
dd.id = 'msgid:' + _read( i, 'message_id' );
dd.className = emote ? 'emote' : '';
dd.appendChild( document.createTextNode( emote ? msg.s
+ubstr( 3 ) : msg ) );
chatter.appendChild( dt );
chatter.appendChild( dd );
if( autoscroll ) chatter.scrollTop = chatter.scrollHei
+ght;
}
}
document.getElementById( 'refresh' ).disabled = false;
},
interval_handle: null,
auto: function() {
var newstate = ( this.interval_handle == null ); // toggle
if( arguments.length == 1 ) newstate = arguments[ 0 ]; // set
if( newstate ) {
if( this.interval_handle == null ) {
this.exec();
this.interval_handle = window.setInterval( 'load_chat.
+exec()', 10 * SEC );
}
}
else {
if( this.interval_handle != null ) window.clearInterval( t
+his.interval_handle );
this.interval_handle = null;
}
document.getElementById( 'auto' ).checked = newstate;
}
};
var send = {
exec: function() {
var p = {
node_id: 106,
op: 'message',
message: document.getElementById( 'message' ).value
};
if( ! p.message.length ) return;
make_request( this, p );
document.getElementById( 'send' ).disabled = true;
document.getElementById( 'message' ).value = '';
},
callback: function() {
load_chat.exec();
document.getElementById( 'message' ).focus();
document.getElementById( 'send' ).disabled = false;
}
};
</script>
<style type="text/css">
html { height: 100%; margin: 0; }
body { margin: 0; padding: 1em; }
div { display: inline; }
dl { border: 2px inset ThreeDFace; height: 480px; overflow: auto; marg
+in: 10px 0; padding: 1em; }
.emote { font-style: italic; }
</style>
</head>
<body onload="load_chat.auto( 1 );">
<div id="controls">
<div id="auth-controls">
user: <input id="user" size="10" type="text" value="" />
pass: <input id="pass" size="10" type="password" value=""
+/>
<button id="login" onclick="login.exec()">login</button>
</div>
<div id="talk-controls" style="display: none;">
<input id="message" size="100" maxlength="255" type="text"
+ value="" />
<button id="send" onclick="send.exec()">send</button>
</div>
<div id="load-controls">
<button id="refresh" onclick="load_chat.exec()">refresh</b
+utton>
<label><input id="auto" type="checkbox" value="1" onchange
+="load_chat.auto()" />auto</label>
</div>
</div>
<dl id="chatter"></dl>
</body>
</html>