TIL JS: Browser Wigglers

spec Dec 16, 2019

Anyone remember the early 2000s working with clunky web browsers? Occasionally you'd come across an indie site with an evil never ending alert box loop.

while (true) {alert('The joy that never ends');}


It took browser vendors a few years to catch on, allowing alert boxes to be closed after the first few iterations of the popup loop.

Paying homage to the developers before us, we've got another fun trick to reminisce over, utilising technology from the days of tables and iframes: Wiggling Browsers.

Long ago, browser vendors exposed the ability to reposition child windows. Today we make fun of this decision with a browser that randomly walks around your screen- often being difficult to close.

Can you imagine if those unsavoury video streaming sites used popups that moved around on their own playing sound? The maliciousness would likely utilise a click handler to recursively open a new window every time you missed clicking the "close" button, landing on the window's body content instead.


let lastMouseX = 0;
let lastMouseY = 0;
const generateWiggler = (context) => {
    window.addEventListener('mousemove', e => {
        lastMouseX = e.clientX;
        lastMouseY = e.clientY;
    });

    const win = context.open(
        location.href +'?'+(new Date().toString().replace(/\s/g, '_')),
        'Wiggly',
        'menubar=no,location=no,resizeable=no,personalbar=no,scrollbars=no,status=no,title=no,tab=no,chrome=yes,innerWidth=300;innerHeight=300;minimizable=no,dependent=no,alwaysRaised=yes,alwaysOnTop=yes,close=no',
    );
    let lastX = 500;
    let lastY = 500;
    let lastH = 500;
    let lastW = 500;
    const moveBugger = () => {
        if (win) {
            const RANGE = 20;
            const CHASE = 20;
            let left = lastX + Math.random() *RANGE - RANGE/2;
            let top = lastY + Math.random() * RANGE - RANGE/2;
            let width = lastH + Math.random() *RANGE - RANGE/2;
            let height = lastW + Math.random() * RANGE - RANGE/2;
            left += (lastMouseX > left) ? CHASE : -CHASE;
            top += (lastMouseY > top-100) ? CHASE : -CHASE;
            lastX = left;
            lastY = top;
            lastH = width;
            lastW = height;
            win.moveTo(left, top);
            win.resizeTo(width, height);
        }
    }
    window.addEventListener('click', generateWiggler.bind(window, window));
    if (win) {
        // Can we nest deeper into child windows?
        win.window.addEventListener('click', function(){
            generateWiggler(win.window);
        });
    }
    setInterval(moveBugger, 50);
    return win;
}
window.addEventListener(
   'click',
   generateWiggler.bind(window, window),
   {once: true}
);

Wisdom

The developers behind Wisdom, building amazing dev tools for web apps. We're logging every rage click, console log, network request, and stack trace, and redux action— with HTML replay.