📜 ⬆️ ⬇️

An example of using a telnet server in firefox

Every time they say “oh! The new chromium has become even faster, and the new opera is even more melodic, ”in response, I ask a simple question:“ Do you have a telnet server in your browser? But in firefox - there is ", - after which adherents of other religions understand that propaganda is useless.

This post will discuss how to 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. First, the screenshot should be full-sized, and not cropped by viewport. Secondly, I do not really want to write without the need for low-level languages.

Among others, the use of khtml2png and pairs from xwd + imagemagic was considered, but the khtml3 renderer was godlessly buggy, and the second option was not as trivial as we would like.
')
If everything revolves around the browser, then it is necessary either to add code to the browser, or to influence the browser from an external program. In the process of finding a solution, a wonderful Screen grab plugin was found ! , who was shooting the necessary options for screenshots and it only remained to 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 a success, and after viewing the inspiring screencast about managing firefox from emacs, a draft of the code was written quite quickly.

The idea is simple to impossible - on the fly, the function of opening a screengrab file is patched, and then one of the functions of the plugin is called and, accordingly, the screenshot is saved directly to the file without any questions to the user.

Later the code turned into this:
var ScreenshotSaver = { <br>
lambda: null , // EventListener <br>
mixin: null , // our file opener <br>
pure: null , // screengrab's file opener <br>
answer: 42, // to check `this' validity <br>
} ;<br>
<br>
ScreenshotSaver.assert = function (bool) { <br>
if (!bool) { <br>
repl.print( 'assertion failed' );<br>
repl.print( arguments .callee.caller);<br>
} <br>
} ;<br>
<br>
ScreenshotSaver.save = function (url, fpath) { <br>
this ._install_onload(fpath);<br>
window .content. location .href = url;<br>
} ;<br>
<br>
ScreenshotSaver._install_onload = function (fpath) { <br>
this .assert( this .lambda === null );<br>
<br>
// Looks like hack, but I need valid `this' in _dump_screenshot <br>
// I need this.lambda to be precise. <br>
this .lambda = function (ev) { <br>
repl.print( 'ScreenshotSaver: some `load \' event catched...' );<br>
if (!ev.target.mIsBusy)<br>
ScreenshotSaver._dump_screenshot(fpath);<br>
} ;<br>
window .getBrowser().addEventListener( "load" , this .lambda, false );<br>
} ;<br>
<br>
ScreenshotSaver._uninstall_onload = function () { <br>
this .assert( this .lambda !== null );<br>
window .getBrowser().removeEventListener( "load" , this .lambda, false );<br>
this .lambda = null ;<br>
} ;<br>
<br>
ScreenshotSaver._dump_screenshot = function (fpath) { <br>
this .assert( this .answer === 42);<br>
this .assert( this .lambda !== null );<br>
<br>
repl.print( 'ScreenshotSaver._dump_screenshot starts' );<br>
/* Wanna deregister handler from itself? Here are some useless links: <br>
* http://code.activestate.com/recipes/576366/ <br>
* http://en.wikipedia.org/wiki/Fixed_point_combinator <br>
* eval:"repl.print(arguments.callee)" */ <br>
this ._uninstall_onload();<br>
<br>
this ._install_screengrab_mixin(fpath);<br>
Screengrab.grabCompleteDocument();<br>
this ._uninstall_screengrab_mixin();<br>
<br>
repl.print( 'ScreenshotSaver._dump_screenshot exits' );<br>
} ;<br>
<br>
ScreenshotSaver._install_screengrab_mixin = function (fpath) { <br>
this .assert( this .mixin === null && this .pure === null );<br>
<br>
this .mixin = function (defaultName) { <br>
var file = Components.classes [ "@mozilla.org/file/local;1" ] .<br>
createInstance(Components.interfaces.nsILocalFile);<br>
file.initWithPath(fpath);<br>
return file;<br>
} <br>
<br>
this .pure = SGNsUtils.askUserForFile;<br>
SGNsUtils.askUserForFile = this .mixin;<br>
} ;<br>
<br>
ScreenshotSaver._uninstall_screengrab_mixin = function () { <br>
this .assert(SGNsUtils.askUserForFile === this .mixin);<br>
this .assert( this .mixin !== null && this .pure !== null );<br>
<br>
SGNsUtils.askUserForFile = this .pure;<br>
this .pure = null ;<br>
this .mixin = null ;<br>
} ;<br>

Download the file here .

Loading such an “extension” on the fly is no less trivial:
 $ firefox &
 $ telnet localhost 4242 # 4242 - the port on which mozrepl is listening
 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? Anyhow, from automated testing of websites and an “interactive console” when developing plug-ins for firefox to www-bots, which will be practically indistinguishable from people without Turing test.

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

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

Source: https://habr.com/ru/post/49581/


All Articles