Telnet server example in firefox

    Every time they say to me “oh! the new chromium is even faster and the new opera is even more melodic ”, in response I ask a simple question:“ Does your browser have a telnet server? ” But in firefox - it is, ”after which followers of other religions understand that propaganda is useless.

    In this article, we will talk about how you can expand and manage the fire fox from other applications through the aforementioned telnet server implemented by the mozrepl plugin . As an example, I will show how to implement the function of creating a screenshot of the site with minimal effort.

    But first, a few additional preconditions. Firstly, the screenshot should be full-sized, and not cropped by viewport. Secondly, I don’t really want to write unnecessarily in low-level languages.

    Among others, options for using khtml2png and pairs from xwd + imagemagic were considered, but the renderer khtml3 was shamelessly buggy, and the second option was not as trivial as we would like.

    If everything revolves around the browser, then you need to either add code to the browser, or work on the browser from an external program. In the process of finding a solution, a wonderful Screen grab plugin was found !who took the necessary screenshots and could only learn how to manage this plugin. Remembering that in the case of OpenOffice, this functionality can be obtained using the ability to test the user interface, I went in search of test plugins. The search was successful and after watching an inspiring screencast about managing firefox from emacs, a draft code was written quite quickly.

    The idea is simple to impossible - on-the-fly the function of opening the screengrab file is patched, after which one of the plug-in functions is called up and, accordingly, the screenshot is saved directly to the file without any questions to the user.

    As a result, the code turned into this:
    var ScreenshotSaver = {

        lambda: null, // EventListener

        mixin:  null, // our file opener

        pure:   null, // screengrab's file opener

        answer: 42,   // to check `this' validity

    };



    ScreenshotSaver.assert = function(bool) {

        if (!bool) {

            repl.print('assertion failed');

            repl.print(arguments.callee.caller);

        }

    };



    ScreenshotSaver.save = function(url, fpath) {

        this._install_onload(fpath);

        window.content.location.href = url;

    };



    ScreenshotSaver._install_onload = function(fpath) {

        this.assert(this.lambda === null);



        // Looks like hack, but I need valid `this' in _dump_screenshot

        // I need this.lambda to be precise.

        this.lambda = function(ev) {

            repl.print('ScreenshotSaver: some `load\' event catched...');

            if (!ev.target.mIsBusy)

                ScreenshotSaver._dump_screenshot(fpath);

        };

        window.getBrowser().addEventListener("load", this.lambda, false);

    };



    ScreenshotSaver._uninstall_onload = function() {

        this.assert(this.lambda !== null);

        window.getBrowser().removeEventListener("load", this.lambda, false);

        this.lambda = null;

    };



    ScreenshotSaver._dump_screenshot = function(fpath) {

        this.assert(this.answer === 42);

        this.assert(this.lambda !== null);



        repl.print('ScreenshotSaver._dump_screenshot starts');

        /* Wanna deregister handler from itself? Here are some useless links:

         * http://code.activestate.com/recipes/576366/

         * http://en.wikipedia.org/wiki/Fixed_point_combinator

         * eval:"repl.print(arguments.callee)" */

        this._uninstall_onload();



        this._install_screengrab_mixin(fpath);

        Screengrab.grabCompleteDocument();

        this._uninstall_screengrab_mixin();



        repl.print('ScreenshotSaver._dump_screenshot exits');

    };



    ScreenshotSaver._install_screengrab_mixin = function(fpath) {

        this.assert(this.mixin === null && this.pure === null);



        this.mixin = function(defaultName) {

            var file = Components.classes["@mozilla.org/file/local;1"].

                            createInstance(Components.interfaces.nsILocalFile);

            file.initWithPath(fpath);

            return file;

        }



        this.pure = SGNsUtils.askUserForFile;

        SGNsUtils.askUserForFile = this.mixin;

    };



    ScreenshotSaver._uninstall_screengrab_mixin = function() {

        this.assert(SGNsUtils.askUserForFile === this.mixin);

        this.assert(this.mixin !== null && this.pure !== null);



        SGNsUtils.askUserForFile = this.pure;

        this.pure = null;

        this.mixin = null;

    };


    You can download the file here .

    Loading such an "extension" on the fly is no less trivial:
    $ firefox &
    $ telnet localhost 4242 # 4242 — порт, на котором слушает mozrepl
    repl> repl.load('file:///home/luser/ScreenshotSaver.js');
    repl> ScreenshotSaver.save('http://habrahabr.ru', '/tmp/habr.png');
    repl> ScreenshotSaver.save('http://linux.org.ru', '/tmp/lor.png');
    

    After that, two corresponding screenshots appear in / tmp.

    How else can mozrepl be used? Yes, anything - from automated testing of websites and the "interactive console" when developing plugins for firefox to www-bots, which will be practically indistinguishable from people without a Turing test.

    UPD: thanks for the karma, moved the topic to the "fire fox".

    Of the open questions, for example, error handling and hiding the vertical scrollbar remain. At a resolution of 1024x768, the screenshot made in this way will have a width of 1009px, i.e. will be already on the width of the scrollbar - 15px.

    Also popular now: