Trying to implement a scrollback limiter/culler in the client

64 views
Skip to first unread message

Ragnar

unread,
Oct 22, 2012, 9:14:21 PM10/22/12
to phudbase-...@googlegroups.com
I figure probably the best place to inject such a thing is inside of ow_Write in client.js but I can't seem to get it to successfully match either a linefeed or a linereturn (\n & \r) using regex.  If I use a line like this:

var incomingLines = text.match(/\r/g);

It'll return incomingLines as null, for testing I also tried swapping out the \r for A and caught them as expected so I'm not sure what the issue is.  Even after I've found a way to keep a running tally of lines I'm not quite sure how to crop the top off of the backscroll but the ideal goal is to just start cutting off anything over say 1000 lines.  Right now the client will just infinitely grow that scrollback outward at increasing browser CPU & memory usage.

Michael Elford

unread,
Oct 23, 2012, 3:48:53 AM10/23/12
to phudbase-...@googlegroups.com
I haven't dug into this yet, but check out trim_ow just below ow_write. It looks to me that the code there is supposed to do what you are describing. Because ow_write doesn't add the text into its own numbered elements within output it isn't working. I don't have the code in front of me, but I'm reasonably sure if you fix ow_write trim_ow will start working for you. It won't do lines, just messages but that should be no real problem, or you can modify as required.

Sent from my iPad

Michael Elford

unread,
Oct 23, 2012, 4:02:52 PM10/23/12
to phudbase-...@googlegroups.com
Here's what you need to do to get trim_ow working with messages.  You could do the same with lines with what you've tested above if you'd prefer.  All changes are in client.js

On line 13/14, I set initial values to the vars:
var num_msgs=0;
var next_del=0;

You should also play around with msg_limit (set it low initially to see it work, then set it how you want)  Eventually I plan on letting this be user configurable based on the device they're accessing from (i.e. good computer they might want a large buffer, lesser device, smaller).  The server doesn't care how big the buffer is on the client...

Here's the updated ow_write and trim_ow functions.  Essentially I wrapped each message's write in it's own Div class.  Then trim_ow removed the "#" from the elem variable and prepended a "." in the actual remove statement.

function ow_Write(text)
{
        var objDiv = window.top.document.getElementById("output");
        var elem = "msg" + num_msgs;

        text = "<div class='"+elem+"'>"+text+"</div>";
        objDiv.innerHTML += text;

        trim_ow();

        num_msgs++;

        if (prevent_autoscroll == true) return;

        objDiv.scrollTop = objDiv.scrollHeight;
}

function trim_ow()
{
        var elem;
        if (num_msgs >= msg_limit)
        {
                elem = ".msg" + next_del;

                $(elem).remove();

                next_del++;
        }
}



Ragnar

unread,
Oct 24, 2012, 6:18:41 AM10/24/12
to phudbase-...@googlegroups.com
Looks good I'll try adding that this evening, btw I got a command-recall method going so that you can use the up/down arrows to scroll back and forth through your last ten inputted commands using the following:

in client.js adding these near the top as globals:
// Command recall variables
var lastCommands = new Array(); // Initially setting up the array
var commandRecall = -1;         // Needed to track for each up/down arrow
var input_limit = 10;           // Remember the last 10 inputs so ideally arrows can cycle them

Then adding this new function:
function keyPressed(value)
{
//      ow_Write("KEY PRESS:  "+value);
        switch(value)
        {
                case 38:
                        if (commandRecall < 10 && lastCommands[commandRecall+1])
                        {
                                commandRecall++;
                                document.getElementById("user_input").value = lastCommands[commandRecall];
                        }
                        break;
                case 40:
                        if (commandRecall > 0 && lastCommands[commandRecall-1])
                        {
                                commandRecall--;
                                document.getElementById("user_input").value = lastCommands[commandRecall];
                        }
                        break;
        }
}

Then adding this instead the line that clears the user input inside of the send() function:
        if (s)
        {
                for (n = input_limit; n >= 0; n--)
                {
                        if (n > 0 && lastCommands[n-1])
                                lastCommands[n] = lastCommands[n-1];
                        if (n == 0)
                                lastCommands[n] = s;
                }
        }
        document.getElementById("user_input").value = "";
        commandRecall = -1;

and finally adding some keystroke capturing event hooks into the index.php:

                document.addEventListener('keydown', function(event)
                {
                        document.getElementById("user_input").focus();
                        if (event.keyCode == 38)
                        {
                                keyPressed(event.keyCode);
                        }
                        else if (event.keyCode == 40)
                        {
                                keyPressed(event.keyCode);
                        }
                });

Net result is you can up or down arrow through your last ten commands ala typical mud client or shell :)

Ragnar

unread,
Oct 24, 2012, 6:21:54 AM10/24/12
to phudbase-...@googlegroups.com
Oh right and one other added bonus of that is you'll notice the refocusing on keystrokes too inside of that event handler for them, that way you'll pretty much always start inputting into the command line if you're current window focus is the browser rather then needing to click specifically inside of it first which is quite handy.

Michael Elford

unread,
Oct 24, 2012, 6:46:04 AM10/24/12
to phudbase-...@googlegroups.com

Great, thankyou!!  I was planning on adding move commands to the numpad, looks like an addition to your code would do the trick.

Michael Elford

unread,
Oct 24, 2012, 11:53:40 PM10/24/12
to phudbase-...@googlegroups.com
Thanks works great, should work better for mobile too (I've removed the setfocus out of sendDirect) as it constantly brought up the mobile keyboard.

I've modified your keyPressed function so that when you down arrow past the latest command it blanks the field.

                case 40:
                        if (commandRecall > 0 && lastCommands[commandRecall-1])
                        {
                                commandRecall--;
                                document.getElementById("user_input").value = lastCommands[commandRecall];
                        }
                        else
                        {
                                commandRecall =-1;
                                document.getElementById("user_input").value = "";
                        }

Reply all
Reply to author
Forward
0 new messages