<!-- Copyright (C) 2002-2004 Opera Software ASA. -->
<html>
<head>
<style>
.posted { color: blue }
body { font: 12pt sans-serif; white-space: -pre-wrap;}
</style>
<script>
/* JavaScript console.

   Facilities used by this script:

      opera.errorIndex()
         Returns the index of the last error message.  This index is monotonically
         increasing (which limits us to about 2^53 errors per Opera session)

      opera.errorMessage(i)
         Returns the error message at index i.  The value returned may be #f, if
         that message has been flushed from the cache.

      opera.clearErrorMessages()
	     Clear all messages from the queue.  This operation is restricted: it can
		 only be executed in documents that come from a file: URL.

      opera.openInSourceViewer(url)
         Show the URL in the source viewer.  This operation is restricted: it can
	     only be executed in documents that come from a file: URL.


   Facilities available to user scripts:

      opera.postError(msg,...)
         Use from your own scripts to print debug statements to the console
         window.  Each 'msg' is printed as a separate message in the console.
*/
   
var lastErrorIndex = -1;
var showFromIndex = -1;
var msg_div;

function init()
{
    msg_div = document.getElementById("messages");
    if (msg_div)
        setInterval( "pollForErrors()", 1000 );
    else
        alert( "Error loading console." );
}

function pollForErrors()
{
    function create_link(m)
    {
        function to_escape(ch)
        {
            function to_hex(ch)
            {
                return "0123456789abcdef".charAt(ch);
            }

            if (/\w/.test (ch))
                return ch;
            else
            {
                var code = ch.charCodeAt(0);

                if (code < 256)
                    return "\\x" + to_hex((code >> 4) & 0xf) + to_hex(code & 0xf);
                else
                    return "\\u" + to_hex((code >> 12) & 0xf) + to_hex((code >> 8) & 0xf)
                                 + to_hex((code >> 4) & 0xf) + to_hex(code & 0xf);
            }
        }
        
        /* Quotes inside m must be handled specially because we do not want
           the ones we introduce to change their meaning.  The single quote
           inside the attribute is tricky because entities inside the URL
           are expanded late. */
        return '<a title="View source" href="javascript:opera.openInSourceViewer(\'' +
               m.replace( /./g, to_escape ) +   // escape everything
               '\')">' + m + '</a>';
    }

    function htmlify( msg )
    {
        var s = document.createElement( "SPAN" );
        newmsg = msg.replace( /&/g, "&amp;" ).
                     replace( /</g, "&lt;" ).
                     replace( />/g, "&gt;" ).
                     replace( /https?:\/\/\S+/g, create_link ).
                     replace( /file:\/\/(?:\S|(?:[ ](?=[^\n\r]*\.)))+/g, create_link );
        if (newmsg.match(/^\s*POSTED/))
            newmsg = "<span class='posted'>" + 
                     newmsg.replace(/^\s*POSTED\s+Unknown thread\s*/,"") + 
                     "</span>";
        s.innerHTML = newmsg;
        return s;
    }

    var n = opera.errorIndex();
    if (n > lastErrorIndex && n > showFromIndex)
    {
        for ( var i=Math.max(showFromIndex+1,lastErrorIndex+1) ; i <= n ; i++ )
        {
            var msg = opera.errorMessage(i);
            if (msg)
            {
                var emsg = document.createElement( "PRE" );
		if (!navigator.userAgent.match(/linux/i))    // hack
		    emsg.style.fontSize = "smaller";
	        emsg.appendChild( htmlify( msg ) );
                msg_div.appendChild( emsg );
                msg_div.appendChild( document.createElement( "HR" ) );
            }
        }
        lastErrorIndex = n;
    }
}

function reset()
{
	opera.clearErrorMessages();
	lastErrorIndex = -1;
	showFromIndex = -1;
    msg_div.innerText = "";
}
</script>
</head>

<body onload="init()">
<div id="messages">&nbsp;</div>
</body>

</html>

