Snippets code from my daily experience

July 18, 2009

Discontinue extensions support for some applications

Filed under: extension, firefox, flock, komodo, kompozer, seamonkey — dafi @ 4:46 pm

Before publish new updates for my extensions I try to test them on every application declared supported on install.rdf, this is a very expensive activity when a specific extension runs on different kind of applications and versions.

I add support for a new application (e.g browser, email client, multimedia applet)

  • when I use the application itself and I need the extension functionality on it
  • when other users ask to me

Now I must decide to drop support for some applications and for specific versions to simplify my release tests cycle.

In some cases it’s easy to decide, for example Firefox 2.x is no longer supported by Mozilla and users continuing to use it are braves or simply fools.

Supporting SeaMonkey 1.x is very hard for me, no special technical problems SM is a very good product but I simply don’t use it.
Instead I’m a satisfied SeaMonkey 2.0 user since alpha1 version.

Supporting Flock, the “social” browser, is easy due to the fact is very compatible with Firefox 3.x but sometimes little differences caused me headaches.
I think to drop support for extensions not Flock centric considering the decision taken from its team last December

Komodo 4.x is no longer upgraded by ActiveState but many people continues to use it, Komodo has a commercial version, KomodoIDE, and not all users purchased the upgrade (me too) so it is very difficult to drop the very old 4.x architecture.

NVU is dead but many users continue to use it also if its sibling/son Kompozer should be strong preferred.

What specifically means “discontinue support”

I would to remove specific tricky code present in extensions to make them cleaner but this can be a bad solution, regressions are always possible so the cure can be worse than the disease…

Removing SeaMonkey 1.x support will make my extension build system cleaner no longer install.js, contents.rdf  and informations present both in install.rdf and chrome.manifest, obviously I don’t discard support only to remove a couple of configuration files but I consider it another complication.

So, “discontinue support” for me means moving attention and energies on applications (and versions) I can test easily, on application I daily use, on applications I receive feedback from other users.

April 12, 2009

Should Komodo macros have to support auto update? (Sunday Thought)

Filed under: komodo, macro, sunday_thought — dafi @ 1:00 am
Tags: , , , , ,

The Komodo macro ecosystem grows quickly and many state-of-art macros born every day.

I’ve already said in the past that Komodo macro environment is powerful like Microsoft VBA although it has many lacks (like UI creation).

I would have a similar environment on every Mozilla based application something like a KoMonkey or GreaseModo :P (Komodo macros plus GreaseMonkey).

Macros become more complex and the authors release many revisions thanks to community feedback but today it is difficult to stay tuned when new versions are published.

Adding an update checker to KPZ files is possible but not easy, many technical aspects must be considered.

Today the best approach consists to pack macros like extensions (XPI files) but developers need deeper knowledge and this should be frustrating.

I’m sure the Komodo macros are at the beginning of a radical evolution

April 1, 2009

Colored file tabs for Komodo

Filed under: extension, komodo, macro, openkomodo, xul — dafi @ 1:37 pm

A couple of months ago I wrote a Komodo macro allowing the editor view tabs to be colored based on user defined color schemes, when the macro became stable I published it on Komodo community forum.

Amazingly the macro received more feedback so I decided to ‘convert’ it to an XUL extension.

Komodo macros are fantastic but they don’t allow to create complex UIs so moving them to XPI become a necessary step.

Now ColorTab is ready and can be downloaded from here.

The original name was KolorTab, the ‘K’ letter used to remember Komodo but I’ve decided to use a more tradictional name :P

ColorTab look&feel

ColorTab look&feel

March 25, 2009

Komodo maintenant parle Français (Komodo now speaks French)

Filed under: babelzilla, komodo, localization, openkomodo — dafi @ 6:25 pm

The Babelzilla Team is proud to present the (unofficial) Komodo French localization.

Komodo 5.1 has been released, it contains many cool features and the Babelzilla guys have completed the FIRST localization, the first one.

You can find further details at French Mozilla blog and the installation instructions at BabelWiki

A special thanks goes to Goofy that coordinated the L10N work.

Thanks guys, you made the world a better place without linguistic barrier.

March 1, 2009

Adding CSS Color Preview Tooltip to Komodo

Filed under: komodo, nsIDOMCSSPrimitiveValue, openkomodo, scintilla, xul — dafi @ 12:36 pm

Do you know Firebug? Uh no? Well please make a jump in twentieth century then return here :P

Firebug has many great features but I love the color preview tooltip, from CSS Tab moving the mouse over a CSS color expression you will see a little box filled with the color found under the mouse pointer.

Every time I edit CSS (and HTML) files from Komodo subconsciously I move mouse over a color waiting to see the tooltip but nothing happens :(

I’ve realized a macro can do this job so I’ve written ColorInfoTip that adds to Komodo the ability to show colored tooltip.

Some technical detail

This is a macro! No need to create extensions, the Komodo macro ecosystem is very cool and powerful.

The tooltip is a scintilla Call tip accessible from Komodo API.

The CSS color string can be written using many syntaxes like #RRGGBB or rgb(R,G,B) instead of reinventing the wheel and write the parser I’ve used the getRGBColorValue standard DOM method.

I discovered Scintilla uses BBGGRR color format instead of RRGGBB so the CSSRGBColor components have been converted to be Scintilla compliant.

Known problems

The macro isn’t perfect and any help is welcomed

  • Sometimes the tooltip doesn’t close especially changing editor view
  • Moving mouse quickly doesn’t update the color (fixed)
  • fill here the bug you found

ColorInfoTip.kpz

You can download the macro from ColorInfoTip.kpz then open the file from Komodo to install

January 20, 2009

Posting syntax highlighted code on wordpress.com using Komodo macro

Soon or later any blogger talking about software development will post some snippet of code.

To make code more cool and attractive he/she will use syntax highlight.

There are many alternatives for many blog platforms like Pygments, GeSHI, CodeHighlighter, WP-Syntax and so on.

This blog is hosted on the free version of WordPress.com, it doesn’t allow to use any plugin or user-defined CSS so adding sexy code is very difficult.

Komodo has the ability to print to HTML files code with the syntax highlighted, this feature is fully accessible from APIs so I’ve written a macro that

  • make CSS style inline replacing HTML class with corresponding style attributes
  • copy to clipboard (using the new Komodo 5 clipboard helper library) in HTML format so user can paste directly on Visual WordPress mode

Below you find the macro source code obviously highlighted by itself :P

How to get the selected text (or the whole Komodo view) converted to HTML

The variable str at end contains the converted HTML

var view = ko.views.manager.currentView;

var tmpFileSvc = Components.classes["@activestate.com/koFileService;1"]
                 .getService(Components.interfaces.koIFileService)
fname = tmpFileSvc.makeTempName(".html");

var lang = view.document.languageObj;
var forceColor = true;
var selectionOnly = view.selection != "";
var schemeService = Components.classes['@activestate.com/koScintillaSchemeService;1'].getService();
schemeService.convertToHTMLFile(view.scimoz,
                                view.document.displayPath,
                                view.document.language,
                                lang.styleBits,
                                view.document.encoding.python_encoding_name,
                                fname,
                                selectionOnly,
                                forceColor);

var file = Components.classes["@activestate.com/koFileEx;1"]
        .createInstance(Components.interfaces.koIFileEx)
file.URI = ko.uriparse.localPathToURI(fname);
file.open('rb');
var str = file.readfile();
file.close();

Applying the replace to str

Nothing really interesting, simply the replace method is called many times to make CSS style inline inside span tags

Copy to clipboard in HTML format

Komodo 5 allows to interact with clipboard wrapping XPCOM services, these APIs allow to copy in the so called HTML flavor so content preserves styles and colors.

xtk.include("clipboard");

var transferable = xtk.clipboard.addTextDataFlavor("text/html", str);
transferable = xtk.clipboard.addTextDataFlavor("text/unicode", str, transferable);
xtk.clipboard.copyFromTransferable(transferable);

That’s all folks

After running this macro on a Komodo view you can paste directly on WordPress Visual editor and obtain your beautiful code.

Using HTML flavor you can paste into any application able to accept Special Formats like Microsoft Word or OpenOffice Writer.

The full macro source code can be found on Macro SVN repository

January 17, 2009

Rumbling about VisualDiffer

Filed under: komodo, xul — dafi @ 12:34 pm

After many months I’ve started again to work on VisualDiffer the most complex extension I ever realized.

Developing VisualDiffer is an exciting task at least for two reasons

  • Deeper level XUL usage to create complex user interfaces
  • Attention to code performances to make application more reactive

At this time the UI doesn’t present any special widget but I’ve some idea about line position sliders and comparison file results, they will be very fun to implement.

The implementation has a bottleneck in the Javascript sort function.

While VisualDiffer only runs on Komodo I’ve tried to run the directories sort routines on Firefox with TraceMonkey enabled and I noticed some speedup, nothing so amazing but with deep file trees  (~600 directories and ~2000 files) TraceMonkey completes in 10-20% less time (very good!!).

Due to the fact Komodo is based on Python, it should be easier to write core sort routines directly in Python, I will do it very soon.

VisualDiffer features list (in my mind)  is very long but the already implemented is a very short subset.

I think it is mandatory to adopt the Release Early, Release Often strategy otherwise I’ll release the next version in 2030.

A couple of new functionalities are complete

  • 2369618 quick comparing two open files selecting them from View Tab context menu (released)
  • 2515481 set two different base folders from Directory Panel (not released)

At this time I’ve abandoned the idea to add the three-file compare view I want to add many little time saver features like

  • copy/move folders from Folder sides
  • rename folders/files
  • reload changed files
  • syntax highlight (this should be easy within Komodo)
  • in place edit (no need to switch between Komodo and VisualDiffer)

December 22, 2008

Downloading protected resources using nsIChannel and friends

Filed under: babelzilla, extension, komodo, macro, nsIChannel, nsIStreamListener — dafi @ 2:35 pm

A couple of days ago I needed to automate file downloading from a service, a very trivial task in every programming language (or using wget).

The little complication was represented by the web based authentication mechanism (userid/password) needed to access to files.
Determining which files to download and their usage (unzipping and picking files) required some specific business logic, nothing really complicated but very annoying.

After a while I realized this job can be done using Javascript and XPCOM and here I would share the solution based on nsIChannel.

What is does

  • the service uses userid and password to login
  • login to the service using HTTP POST method, it simulates an HTML <form/> submission
  • store the cookies sent from server. They contains credentials login data, cookies usage is a prerequisite in our scenario
  • reuse login data to download protected resources

Example usage

Suppose you want to automate download of extensions stored on AMO’s sandbox, you must login first so this use-case is perfect for us.
Someone can consider this approach ugly, web services or Remora API are better but here I only want to demonstrate how to use nsIChannel.

Let’s start…

You can write the Javascript code shown below to download my extension RichFeedButton (dropped on sandbox an year ago)

var amoUsername = "dafi@localhost";
var amoPassword = "my_secret_code";
downloadProtectedResource(
   "https://addons.mozilla.org/it/firefox/users/login",

   "data[Login][email]=" + amoUsername + "&data[Login][password]" + amoPassword,

   "https://addons.mozilla.org/en-US/firefox/downloads/file/33926/richfeedbutton-0.0.21-fx.xpi",

   "/tmp/richfeedbutton-0.0.21-fx.xpi");

where our downloadProtectedResource function signature is shown below

function downloadProtectedResource(loginUrl, postData, resourceUrl, destPathName) { ... }

Nothing special, simply we need to know the HTML input names used for userid and password (ie data[Login][email] and data[Login][password]) and pass them in postData argument.

The downloadProtectedResource interacts with nsIChannel (nsIHttpChannel) and other XPCOM object

function downloadProtectedResource(loginUrl, postData, resourceUrl, destPathName) {
   var httpChannel = makeHttpChannel(loginUrl); // create an object nsIHttpChannel
   var stream = makeStringStream(postData); // create an object nsIStringInputStream
   setChannelPostData(httpChannel, stream); // fill data using nsIUploadChannel

   // downloader saves data on disk
   var downloader = new Downloader(resourceUrl, destPathName);
   // make a login then passes cookies to downloader object
   var cookieListener = new CookieRetrieverListener(downloader);

   // start authentication and download
   httpChannel.asyncOpen(cookieListener, null);
}

The object Downloader and CookieRetrieverListener implement the nsIStreamListener interface.

The cookieListener after obtaining cookies aborts the operation because we don’t need all server output, then it calls the downloader.

function CookieRetrieverListener(downloader) {
   this.downloader = downloader;
   this.cookies = "";
}

CookieRetrieverListener.prototype = {
   onStartRequest: function(request, ctx) {
         var channel = request.QueryInterface(Components.interfaces.nsIHttpChannel);
         this.cookies = channel.getRequestHeader("Cookie");

         // no need more data
         throw Components.results.NS_ERROR_ABORT;
   },

   onDataAvailable : function(request, context, inputStream, offset, count) {
   },

   onStopRequest: function(request, ctx, status) {
      this.downloader.cookies = this.cookies;
      this.downloader.start();
   }
}

Another way to use this code consists to download localizations from BabelZilla as shown below.
BabelZilla requires many parameters on query string :?


var bzUsername = "dafi_duck";
var bzPassword = "my_secret_code";
var bzItemId = "88";
var bzExtId = "4432";
downloadProtectedResource("http://www.babelzilla.org/index.php",
                 "op2=login&lang=english&message=0"
                        + "&option=ipblogin&task=login&0b14737c5ade1f7697a8f81b33b0bacf=1"
                        + "&option=com_frontpage&Itemid=1"
                        + "&username=" + bzUsername
                        + "&passwd=" + bzPassword,
                 "http://www.babelzilla.org/index.php?option=com_wts&type=downloadtar"
                        + "&Itemid=" + bzItemId
                        + "&extension=" + bzExtId,
                 "/tmp/vsw.tar.gz");

nsIChannel.asyncOpen

Accessing to cookies received from server requires to use nsIStreamListener available only in asynchronous open calls.

This needs to start the download only when cookies are surely retrieved, this is achieved using the nsIRequestObserver.onStopRequest, any better idea is very appreciated.

Complete code

The complete code contains a few of helper functions (reading binary stream, saving file) and is available on SVN, it’s ready to be executed as Komodo macro simply setting userid and password.

December 13, 2008

Komodo French Localization coming soon

Filed under: babelzilla, komodo, localization — dafi @ 10:56 am

This morning I’ve found a couple of emails coming from my BabelZilla forum subscriptions, after reading them I went to WTS homepage where I saw the image shown below.

komodo-locale

Fantastic! The French localization is completed, 2016 strings translated!

When I asked to BabelZilla guys to localize Komodo I could not imagine they did it so quickly.

Many activities must be coordinated with ActiveState team

  • Remove all hardcoded strings (amazingly new code continues to be written with hard-coded strings!!! 8O :???: )
  • Establish a time deadline to froze new strings added to trunks (this can drastically simplify localization cycle)
  • Lang Pack release process and better integration with code development lifecycle

But be calm dafi :P … one step at a time

I want to say thanks to Goofy, the BabelZilla Super Mod, and Pedro the Italian localizer that helped me from the beginning, they helped me to “extract” hard-coded strings and prepare patches to submit.
A big “thank you” goes to all localizers (especially the French community) for dedicating time and passion to this work.

Technically speaking an installable French lang pack is already ready for KomodoEdit v5.0.2, French team are completing the quality test and everybody can help them.

Who want to see Komodo in French can register on Babelzilla and read more at Komodo Lang Pack forum thread…

… and Goofy has already localized in French my extension TabSwitcher

November 21, 2008

Komodo ViewAbout

Filed under: extension, komodo, mozilla, openkomodo, xul — dafi @ 7:42 pm

After reading ViewAbout post written by Gary Kwong I was curious to see what Komodo should have shown.

Komodo doesn’t require to write an extension to implement a similar feature, it is sufficient to write a macro ;)

So I’ve written the code that adds a popup menu inside Help menu and amazing it worked immediately :D

The macro can be triggered at startup but the menu will be added only on first open window because Komodo doesn’t have a “on open new window” macro event but it can be easily simulated adding a listener.

The code shown below is the complete Komodo Javascript macro, nothing else is necessary. (EDIT Thanks to Mook to point me how to remove the hardcoded abouts list)

aboutview


var abouts = [];
for (var c in Components.classes) {
    var m = c.split(/=/);
    if (m[0] == "@mozilla.org/network/protocol/about;1?what") {
        if (m[1]) {
            abouts.push(m[1]);
        }
    }
}

var menuAbouts = document.createElement("menu");
menuAbouts.setAttribute("label", "All abouts:");

var menuAboutsPopup = document.createElement("menupopup");
menuAbouts.appendChild(menuAboutsPopup);

var helpMenuSeparator = document.getElementById("menu_helpShowKeybindings").nextSibling;
var helpMenu = helpMenuSeparator.parentNode;
helpMenu.insertBefore(menuAbouts, helpMenuSeparator);

for (i in abouts) {
    var menuitem = document.createElement("menuitem");
    menuitem.id = abouts[i];
    menuitem.openAbout = openAbout;
    menuitem.setAttribute("label", abouts[i]);
    menuitem.setAttribute("oncommand", "this.openAbout('" + abouts[i] + "')");
    menuAboutsPopup.appendChild(menuitem);
}

function openAbout(about) {
    var docSvc = Components.classes['@activestate.com/koDocumentService;1']
                    .getService(Components.interfaces.koIDocumentService);
    var doc = docSvc.createDocumentFromURI("about:" + about);
    ko.views.manager.topView.createViewFromDocument(doc, "browser");
}

Next Page »

Blog at WordPress.com.