Firefox 2.x / Linux image scaling

Why does image scaling seem to be so bad in Firefox 2 on Linux?

For one of our web apps we want to show static pixmap images of chemical depictions. Depending on the context we want to show those depictions at different sizes, and we don't want to create and cache too many renderings. We'd rather create one fairly large rendering and have the browser scale it down as needed.

For users who are running Firefox/Win or Firefox/Mac this works fairly well, if the images aren't scaled down too much. (Otherwise lines get too thin, as you'd expect.) But for Firefox/Linux users, the results look horrible.

ff_mac.png ff_linux.png
Firefox/Mac Firefox/Linux

What's up with that? Is there any way to control how Firefox downscales images, to get better quality?

Perhaps not. Or not yet, at least. Acts of Volition has an entry comparing image resizing in Firefox 2.x and Firefox 3. Paraphrasing:
The Cairo graphics library will power Firefox 3.
In Firefox 2, if you tell the browser to resize an image it will do so, but not with any of the smoothness that you would see if you had resized the image in an application like Photoshop or the Gimp.

Now, in Firefox 3.0 Alpha 1, resizing an image like this actually produces a smoothly sized image.

JavaScriptTemplates

JavaScriptTemplates offers template-driven formatting of web-page content, using JavaScript.

It will be fun to try this out. I often need to build web pages in which some of the content is created dynamically, via Ajax requests. The JavaScript which transforms the incoming JSON data to HTML tables can be painful to maintain. But I can't use server-side templating because I don't want to reload the entire page.

JavaScriptTemplates seem to offer a way around this. Not sure how one goes about previewing the templates, which are embedded in hidden textareas. Much to learn...

It will be really interesting to see how this, together with Naneau or Jester, changes development of dynamic web apps.

After the First Blush

Hm, this is a little troublesome:

     var myStr = "Hello ${customer.first} ${customer.last}, Welcome back!";
     // Using the process() method is easy...
     result = myStr.process(data);

Do they really pollute JavaScript Strings with a process method?

Yes, they do...

String.prototype.process ( contextObject, optionalFlags )

As a convenience, the String prototype is enhanced with a process() method. It parses the String as a template and invokes process(). The arguments are the same as for templateObject.process().

socket.getfqdn() ignores changes to /etc/hosts

I thought that was the problem, anyway. I'd edited /etc/hosts, changing the fake fully-qualified domain name of my host. Yet, when I launched Python and tried to get the domain name, it still returned the value which had originally been in /etc/hosts:

>>> import socket
>>> socket.getfqdn()


Short answer: after making a change to /etc/hosts, don't forget to flush the lookup daemon's cache:
sudo lookupd -flushcache

Safari Bookmark management

This Mac OS X Hint is helping me learn more about bookmark management in Safari.[1] For example, here's a JS bookmarklet that searches for the selected text in Google, displaying the result in a new window:

javascript:x=escape(window.getSelection().getRangeAt(0));window.open("http://www.google.com/search?q="+x, "_googTab");

I'm not sure about the easiest way to create a new bookmarklet in Safari's Bookmarks bar. So for now I just use the + button to add whatever web page I'm currently viewing; then click the Bookmarks icon, select the new bookmark, change its name, and replace its address w. the JavaScript for the bookmarklet.

Assigning Shortcuts

How do you assign shortcuts to bookmarks? Another hint shows how to do so without having to use the System Preferences => Keyboard and Mouse => Keyboard Shortcuts panel.

  $ defaults write com.apple.Safari NSUserKeyEquivalents '{"Google in New Tab"="@$G";}'

Opening in New Tabs?

Hm... So by using JavaScript bookmarklets, could I implement the 'Search in Google in New Tab' feature for which I've been pining?

Alas, it may be possible, but I don't know how to do it. Once I've put the bookmarklet in my bookmars bar, it doesn't matter whether I left-click or right-click and select "Open in New Tab"; I always get a new window. And if I change the JavaScript to set the current location rather than open a new window, then it always overwrites the current page.

It's too bad that (AFAIK) JavaScript does not yet recognize that many browsers support tabs.



[1]I've missed years of hints and from all over the web that show how to create search bookmarklets, for a host of search engines.) And of course Firefox has a much cooler keymarks facility, which Bob DuCharme explained way back in 2004.

Subversion, Bazaar and Mac document bundles

Subversion has problems dealing with Mac applications which store their documents as bundles (directory trees). The first is that such bundles may contain an icon preview file, "Icon\r", whose filename contains a carriage return. The second is that the bundle may contain files representing e.g. pasted graphics, which come and go as the document is edited. Subversion cannot, as far as I know, add and remove such nested files without user intervention.

Some applications, like OmniGraffle, offer a workaround for the hierarchical document structure. Other applications do not, e.g. LineForm, and VoodooPad, and Apple's own KeyNote and TextEdit.

(That's not quite true. The VoodooPad Lua Plugin Snippets page shows a Lua plugin which handles the hierarchical document problem by automatically adding new documents, removing deleted documents, and committing changes, for a designated directory.)

Does bzr handle either of these problems more gracefully than subversion?

Testing shows that bzr handles "Icon\r" with aplomb. However, it does not automatically add any new nested files to the repository. It's up to you to add them manually, just as in subversion.

Bug with jQuery 1.1.2, Interface 1.2, Slider with fractions

I have a Slider with fractions and an onSlide handler. Sometimes when the handler is invoked, the reported value for xProc seems to be "lagging" -- it seems to be the value from just before the slider jumped to its current position.

Here's a fragment demonstrating the problem:

        <div id="slider_frame">
            <div id="bar">
                <div id="indicator" class="Indicator"></div>
            </div>
        </div>
        <p id="msg"></p>
...
                onSlide: function(xProc, yProc, x, y) {
                    var fraction = x / this.dragCfg.containerMaxx;
                    var nearest = Math.round(x / 4) * 4;
                    var expected = Math.round(nearest * 100 / this.dragCfg.containerMaxx);
                    $("#msg").html("Expected " + expected + ", got " + xProc);

In the web app where I've encountered this problem, I'm working around it by recomputing the xProc value inside the onSlide handler:
    xProc = parseInt(x * 100 / this.dragCfg.containerMaxx);


Here's a more complete example:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>interactive_problem_demo</title>
        <style type="text/css" media="screen">
            #slider_frame {
                border: 1px inset;
                position: relative;
                width: 300px;
                height: 12px;
            }
            #bar {
                position: absolute;
                width: 300px;
                height: 12px;
                background-color: #99a;
            }
            #indicator {
                position: absolute;
                width: 6px;
                height: 12px;
                background-color: #eef;
            }
            #msg {
                max-width: 300px;
            }
            .Good {
                background-color: #0f0;
            }
            .Bad {
                background-color: #f99;
            }
        </style>
    </head>
    <body>
        <div id="slider_frame">
            <div id="bar">
                <div id="indicator" class="Indicator"></div>
            </div>
        </div>
        <p id="msg" class="Good">Please click in the trough.</p>

    <script src="../../../shared/js/jquery/jquery.js" type="text/javascript" charset="utf-8"></script>
    <script src="../../../shared/js/jquery/interface.js" type="text/javascript" charset="utf-8"></script>
    <script src="../../../shared/js/jquery/dimensions.js" type="text/javascript" charset="utf-8"></script>

    <script type="text/javascript" charset="utf-8">
        <!--
        $(document).ready(function() {
            var f = 5;
            var slider = $("#bar").Slider({
                accept: "#indicator",
                fractions: f,
                onSlide: function(xProc, yProc, x, y) {
                    var fraction = x / this.dragCfg.containerMaxx;
                    var expected = Math.round(100 * fraction / (f - 1)) * (f - 1);
                    $("#msg").html("Expected " + expected + ", got " + xProc);
                    $("#msg").removeClass("Good Bad");
                    $("#msg").addClass(xProc == expected ? "Good" : "Bad");
                }
            })
        });
        //-->
    </script>
    </body>
</html>

Mail.app, pasted graphics, and Windows recipients

[Draft]

Summary

When composing in Mail.app:

  • if you attach a file, its format is preserved
  • If you paste a screen capture, some capture formats will be translated to TIFF
  • Some Windows users cannot view TIFF mail attachments
  • This behavior seems to apply to other OS X applications as well
Here's a table showing how Mail.app translates pasted graphics, under Mac OS X 10.4.9:
Screen Capture Pasted Format
GIF TIFF
JPG TIFF
PDF PDF
PNG PNG
TIFF TIFF

Gory Details

If I paste screenshots into my Mail.app messages, some Windows recipients cannot see those screenshots. When sending to these recipients I have to use a much more tedious process:
  1. Save screenshot to file
  2. Compose mail
  3. Click "Attach"
  4. Browse to saved file
Others are dealing with the same problem. Witness this thread at macosxhints.com.

Is the problem that the pasted graphics are set to display inline? (Content-Disposition: inline) No. No matter how I make an attachment, whether through pasting or through the Attach button, Mail.app always sets Content-Disposition to inline. And Windows users can see some attachments.

Is there anything relevant in ~/Library/Preferences/com.apple.mail.plist? Not as far as I can tell.

I have changed my default screen capture format, following the instructions in this macosxhints article:
    defaults write com.apple.screencapture type format
killall SystemUIServer

My format is set to jpeg. That seems to be the problem. Mail.app translates pasted JPEG images to TIFF. Attached JPEG images retain their format.

I'm not sure about the reasons for this, but Preview.app seems to confirm the following weirdness: If you do a screen capture to the clipboard, some formats such as JPG get converted to PICT. If you do the screen capture to a file, then the format you specify is the format used in the capture file.

Textmate: "Snippet Commands" and Placeholders

Draft

Textmate snippets are chunks of templated text, sprinkled with placeholders of the form
${1:default value}
When you invoke a snippet, it injects text into the current document, and it lets you tab through all of the placeholder fields and edit their values.

Sometimes you need to generate a lot of stubbed-out files in one go, e.g. when creating a Firefox extension. Snippets aren't so useful here, but Textmate commands are. At their simplest these are just scripts (pick a language; I like Python) which you invoke from within Textmate.

It sure would be nice to be able to use placeholders in those stubbed-out files, and to use Textmate as a sort of form editor. For example, the install.rdf file in a Firefox extension bundle has about eight fields which you might want to edit. You can generate default values for these fields when stubbing out the bundle, but several of them (e.g. the bundle ID, or your real-world name) might require customization.

There's a really simple way to create a Textmate command that lets you do placeholder editing on any file.

Open Textmate's bundle editor. Create a new bundle. Name it Fill in the blanks. In the command editor pane, set Save: to Current File. Put this text into the Command(s): text area:
cat "$TM_FILEPATH"
Set Input: to Selected Text or Document. Set Output: to Insert as Snippet.

Save your changes by selecting a different bundle in the bundle editor.

Now imagine you have written a script which generates a stub file. Wherever the file contains a value that you might want to change manually, put that value inside a placeholder, e.g.
${1:default value}
Run the script to generate your stub file. Open the stub in Textmate. Select all of the text, then invoke your "Fill in the blanks" bundle.

Voila! The contents of your stub file have not changed, but now you can tab from one placeholder field to the next, editing the values which your stub generator provided.

sigh

So many words for a simple procedure. I should put up a screencast on the Om OS X blog...