February 12, 2007

Searching a local directory from Gecko

Earlier today, I realized I need to search the local file system from Verbosio. There's really no such capabilities in native mozilla.org code. So, I built a basic file search capability on my own, and checked it in to Verbosio.

See the Full Article section for more details. (I also introduce a new way to implement multiple XPCOM components in a single JavaScript file.)

Local file system searches in Verbosio (patch) (requires JSLib, and my ECMA debug script).

Here's some sample code using the file search service:

testFileSearch.js

Simply put, you can search for properties of files and directories (which JSLib's File and Dir classes implement), as well as the contents of files for a specific string.

You can specify more than one set of criteria. Everything within a set of criteria must match for the file search to accept a file. However, if a file passes one or more sets of criteria on the file search, the file search accepts the file. (Logical AND tests within a criteria set, logical OR tests between criteria sets.) So you can do different searches simultaneously.

The first argument of searchDirectory is the local path of the file you want to search. The second argument is true if you want to search sub-directories as well, or false if you don't.

The filterProperty method of a search criteria set lets you define a property name and the value it must have (as a string). The filterContents method requires that any matching file have the first argument (a string) in its contents.

Whenever a contents match is included, you can get the lines where the match happens. Each result has a getLineNumbers() method, which returns an object with line numbers you can feed into getLine(aLineNumber).

Finally, because there may be multiple criteria sets, each result also has a criteriaIndex property, indicating which criteria the result matched first (in order of their being added to the search service).

As for the new JavaScript component structure: I really have gotten tired of having a bunch of related JavaScript components duplicate the same boilerplate code over and over again, when they can all share the same space. So I created a new JavaScript component template, and organized it so the module code comes first. Then I added a special addConstructor() method to the module code, so individual components could just call that one line, and the module would recognize them. Since Gecko parses the entire component file before trying to call NSGetModule, everything still works. Best of all, I now have a simple template to drop new JavaScript components into the file.

Feedback, including suggestions for improvement, is welcome!

Posted by WeirdAl at February 12, 2007 11:26 PM
Comments

Won't that leak like http://weblogs.mozillazine.org/weirdal/archives/016751.html ?

(From Alex: Gavin thinks it probably would, but for now, I'm not too worried. It's 0.1-ish code. By the way, there's no reason to be anonymous on this. :-) )

Posted by: Anonymous at February 13, 2007 10:31 AM

The way you put several JS components in a single file is not exactly new, as even I figured it out two years ago :)

(From Alex: True, but no one has really documented it.)

Posted by: Nickolay Ponomarev at March 10, 2007 9:00 PM