Apr 25

Translate: Select any text in the browser and have it convert to English (or your language)

Ajax, Google, JavaScript, Tech with tags: , , 7 Comments »

Translate Bookmarklet

I really liked getting the Ajax Language API out into developers hands as god knows we shouldn’t have to worry about translations. Now we can use the API and have the Google back-end do all of the work.

I have recently had a couple of scenarios where I really wanted a quick translation. I had a few twitter messages pass through my stream in French and Spanish. I had the answer to some technical issues show up on foreign forums.

So, I decided to create a Translate bookmarklet that allows me to select any foreign text, click on the bookmark, and a little window pops up with the English translation if it can work it out. Automatic translation is far from perfect yet, but for many scenarios you can easily get the gist (e.g. you wouldn’t want to automatically convert a book).

This is how I created the bookmarklet:

The source

First, I have the raw JavaScript source that will become the bookmarklet. There are a few sections of the code. First, we setup a method that will go off and call the Ajax Language API, passing in the translation and language that we want. This is where you would change the language code for non-English.

if (!window['apiLoaded']) {
  window.apiLoaded = function() {
    var language = "en";
    var text = window.getSelection().toString();
    if (text) {
      google.load("language", "1", { "callback" : function() {
        google.language.detect(text, function(dresult) {
          if (!dresult.error && dresult.language) {
            google.language.translate(text, dresult.language, language, function(tresult) {
              if (tresult.translation) {
                translationWindow(tresult, dresult);
              } else {
                alert('No translation found for "' + text + '" guessing the language: ' + dresult.language);
              }
            });
          }
        });
      }});
    }
  };
}

Then we setup a method that is able to display a window showing the result. I used the Prototype UI Window object if available, and good old alert() if not:

if (!window['translationWindow']) {
  window.translationWindow = function(tresult, dresult) {
    if (window['UI']) {
      new UI.Window({theme:  "black_hud",
                   shadow: true, 
                   width:  350,
                   height: 100}).setContent("<div style='padding:6px'>" + tresult.translation + "</div>")
                   .setHeader("English Translation")
                   .setFooter("Language detected: " + dresult.language)
                   .center({top: 20}).show();
    } else {
      alert(tresult.translation + " [lang = " + dresult.language + "]");
    }
  }
}

Next, we load the Prototype UI window code, and accompanying CSS resources by dynamically adding the resources to the DOM:

if (!window['UI']) {
  var pw = document.createElement('script');
  pw.src = 'http://almaer.com/downloads/protowindow/protowin.js';
  pw.type = "text/javascript";
  document.getElementsByTagName('body')[0].appendChild(pw);
 
  var pwdefault = document.createElement('link');
  pwdefault.setAttribute('rel', 'stylesheet');
  pwdefault.setAttribute('type', 'text/css');
  pwdefault.setAttribute('href', 'http://almaer.com/downloads/protowindow/themes/window.css');
  document.getElementsByTagName('body')[0].appendChild(pwdefault);
 
  var pwblack = document.createElement('link');
  pwblack.setAttribute('rel', 'stylesheet');
  pwblack.setAttribute('type', 'text/css');
  pwblack.setAttribute('href', 'http://almaer.com/downloads/protowindow/themes/black_hud.css');
  document.getElementsByTagName('body')[0].appendChild(pwblack);
}

Finally, we load the Google API loader, and use the dynamic loading option with the ?callback=apiLoaded. This kicks off the main driver that we saw first, and if it is already loaded we call it directly (for multiple translations on the same page).

if (!window['google']) {
  var s = document.createElement('script');
  s.src = 'http://www.google.com/jsapi?callback=apiLoaded';
  s.type = "text/javascript";
  document.getElementsByTagName('body')[0].appendChild(s);
} else {
  apiLoaded();
};

“Compilation”

This is the raw form, and we need to get the bookmarklet form, which you can just use right away if you are wanting English. For this, I use John Grubber’s makebookmarklet Perl script to do the conversion.

The Server

The Prototype UI code lives on the server, so I put a striped down version over there which just contains a combined Prototype + Window JavaScript file, and just the one theme CSS set.

In Action

Unsure what I am talking about? Just watch it in action:

UPDATE: I also implemented Twitter Translate to automatically convert tweets to your language.

Apr 07

Web Archeology: Java Pluglet API

Ajax, Java, Tech, Web Browsing with tags: , 3 Comments »

Stone Henge-esque

Even since Ben and I looked at the notes for the first version of Mozilla that supported XMLHttpRequest, which suddenly took the technology from “Some ActiveX for IE” to “Ajax”, I have been interested in hidden technologies that maybe never made it. In those notes for that release we saw no mention of XMLHttpRelease, but technology such as FIXptr was prominently mentioned.

Also, something interesting about Ajax is exactly the fact that the technology was available since 1997, but didn’t make it big until many more Dilbert calendars later.

This points to the fact that there may be some hidden gems in the past that could also be resurrected in the now! As I look back in time, I thought I would talk about any that interest me in some way. Hence, the Web Archeology set of postings. If there is a technology that I am missing, please let me know!

Today I am going to talk about the Java Pluglet API. This technology is part of the Blackwood project at Mozilla, where it was created in 1999 by Igor Kushnirskiy & Akhil Arora.

Let’s walk back to 1999 for a second. Imagine working on Mozilla in a world where you had to futz with a lot of XPCOM and C++ to build things. XUL came about a way to reach out via more Web-y technology to get work done (XML, JavaScript, CSS, etc). In 1999, Java was a sexy language, and everyone was getting ready for fantastic server side Java with great technology like EJB ;)

What if the Java developers could get in on the browser action and develop rich plugins for Mozilla? This is where the Java Pluglet API comes in. It allows you to do just that, mimicking the C++ side of the house:

It was a conscious design decision to have the Pluglet API resemble its C++ counterpart as much as possible, while being able to reflect all of its functionality to Java, so that Plug-in writers will not have to learn yet another API. This concern, in our opinion, outweighed other alternatives which offered a cleaner, more Java-like look. Support for other Plug-in APIs can be easily added by contributing adaptors.

How you register the pluglet is via mime types. You could create application/wicked-cool and when that comes back from the server, Mozilla will say “hmm, I don’t understand this mime type, Pluglet Engine do you?”

At a high level the idea of writing extensions in Java makes total sense to me. It is obviously cross platform, but still low level enough, with a huge library set to get a lot done.

Isn’t this dead?

Probably? Ed Burns did step up to the plate though and reenergized the project recently. As part of the resurrection you can now interface directly between the Java side and JavaScript itself.

If you squint a little, you see an interesting plugin path for the browser. I often say that I would love for Gears to be made using Java instead of C++!

Jan 30

Rotating Java and JavaScript on the Server

Ajax, Comic, Java, JavaScript, Tech 24 Comments »

Rotating Java and JavaScript on the Server

I was chatting with someone about how, in 2008, you could build an application with GWT on the client side, and Rhino on Rails on the server side, and how that would mean flipping the roles of Java and JavaScript. Of course, this would be a flip BACK to the past:

Netscape LiveWire enables developers to create, modify, and maintain online sites and applications through a simple drag-and-drop, point-and-click environment. The environment uses the Java programming language and a Java-based scripting language to enable developers to create and execute Live Objects, or interactive multimedia content, within their applications.

Jan 21

Feeling Agile

Ajax, Comic, Tech with tags: , No Comments »

Feeling Agile

Toonlet uses Dojo 0.4.x and Flash. It is definitely in beta. I had to use Opera to allow me to select a person (both Firefox and Safari didn’t work). But that will get ironed out, and it is fun!

Jan 20

Watching for the expiration of JavaScript domains

Ajax, Tech with tags: 1 Comment »

The perl.com porn site redirect exploit isn’t new.

We tend to often trust the people that we load JavaScript from too much. So many new startups require you to just include that little tidbit of JavaScript. “Just copy and paste this somewhere on your blog”.

Of course, if the site gets compromised in anyway you are loading script from the Bad Guys. If you are a bad guy what are you doing? Looking for third parties that offer services that people embed, and watching like a hawk to see them mess up their DNS so you can pounce. You have automated systems to do this.

Watch out, and let’s get together to work out a possible solution, whether it be short term or longer.

Jan 04

The Zed Shaw Interview

Ajax, Ruby, Tech with tags: , , , 2 Comments »

Rob kindly kicked in some podcasting time when he was at RailsConf, and I sat on the content for far too long. It didn’t really fit right on Ajaxian, since Zed only talks about Ajax a little bit, but it was fun content and I wanted to get it out there, so I finally published the interview with Zed Shaw on the Rails community, the role of the Enterprise, the state of Ajax, JRuby and Rubinius, documentation, tests, tooling, the role of patents in software, and a whole lot of opinion.

it is interesting to listen to Zed in the wake of his Rails rant, as you see some of the seeds of that rant, but hearing them with a real voice is a lot different to the harsh medium of the pen. It is softer to hear someone jabber on, even if he still swears and has very strong opinions indeed.

People like to pick sides, but I am trying not too. There is some truth in there, and things that the Rails community can learn from at the very least. Then again, I haven’t been personally abused in his rant so it is easier for me to take than someone who was directly attacked.

A few quotes:

  • On Semantic Web: Einsteins brain on a crack whores body isn’t going to happen
  • I’m waiting for someone to blind-side the entire Web stack
  • Some people hate me, but love Mongrel
  • Where is the XP for managers

Listen to the interview directly, or subscribe to the podcast.

Dec 27

Gears Future APIs: Messaging API

Ajax, Gears, Google, Tech with tags: , , 2 Comments »

Once you start delving into the WorkerPool API, you quickly see how a common pattern would be using it as a messaging system. As it stands, it looks like an Open Web version of Erlang processes.

Scott Hess wrote up his thoughts on a more formal Messaging API based on WorkerPool:

Gears WorkerPool has two pieces, the part about running a bit of JS asynchronously, and the part about trading messages with that JS. This API may be composable from more basic bits. The messaging bit could be used in other contexts, such as implementing something like WhatWG’s postMessage().

Aside: What is WhatWG’s postMessage?

postMessage is “a messaging system that allows documents to communicate with each other regardless of their source domain, in a way designed to not enable cross-site scripting attacks.”

Here is an example:

For example, if document A contains an object element that contains document B, and
script in document A calls postMessage() on document B, then a
message event will be fired on that element, marked as originating from
document A. The script in document A might look like:

var o = document.getElementsByTagName('object')[0];
o.contentWindow.postMessage('Hello world');

To register an event handler for incoming events, the script would use
addEventListener() (or similar mechanisms). For
example, the script in document B might look like:

document.addEventListener('message', receiver, false);
function receiver(e) {
  if (e.domain == 'example.com') {
    if (e.data == 'Hello world') {
      e.source.postMessage('Hello');
    } else {
      alert(e.data);
    }
  }
}

This script first checks the domain is the expected domain, and then
looks at the message, which it either displays to the user, or responds
to by sending a message back to the document which sent the message in
the first place.

Back to the Gears Messaging API

Scott gives an example of the messaging API, starting with an end point:

var port = google.gears.factory.create('beta.messageport', '1.0');
port.onmessage = function(port, msg, sender) {
  alert("message: " + msg);
};
port.listen("name");   // Omit for anonymous listener.

and having a way to send it a message:

var port = google.gears.factory.create('beta.messageport', '1.0');
port.open("name");
port.sendMessage("hello there");

To enable cross domain, you can post.open(name, domain), and on the other side, you have to allow it via something like port.allowCrossOrigin(["www.good.com", "www.angelic.com"]);.

I am excited about a messaging API, as I think that it fits into the way in which we are developing new Web applications. Having an asynchronous queue that allows me to replay work (e.g. offline), and work nicely with Comet based interactions, would be great. We can reuse all that we have learned from other event based systems, and Gregor can rename his book and be happy!

Other Future APIs

Disclaimer: This is early days, and who knows what the final API will look like, or if it will even make it. Do you have ideas for cool Gears that make the Web better? Let us know!.

Dec 26

Interviewed on GWT, Gears, Java, and JavaScript

Ajax, Gears, Google, Tech with tags: , 1 Comment »

I had the pleasure of finally meeting Didier Girard. I seem to run across Didier’s work every week or so, but for some reason we haven’t had a chance to meet face to face, until JavaPolis.

Didier sat down with me to talk about GWT, Gears, Java, and JavaScript, and I gave my honest opinions.

You can listen to my ramblings below. Let me know if you have any thoughts on opinions!

Dec 20

ChartMaker: Ext 2 UI on top of the Google Chart API

Ajax, Tech with tags: , , 5 Comments »

I had an 11 hour flight from London to SFO. What was I going to do? I had a couple of books with me. The in-flight movies were average, and even in business class they didn’t have the on-demand system, so if you missed the start you had to wait for the next go around. I poked around in a DVD store and couldn’t find anything to interest me, so I ended up grabbing ‘Heroes’ since I had never seen it. I was put off by the “Save the cheerleader, save the world” commercials, but figured if it was half decent then there was a lot of material (e.g. time) to cover.

So, I popped in the DVD, and whilst I watched, I opened up Firefox and Textmate.

I have been wanting to play around with the new Ext 2.0 release, and also with the GWT-Ext package. Unfortunately, that module isn’t using Ext 2.0 quite yet (almost!), so I decided to do a first rev of the tool with straight Ext 2.

I found the new Google Chart API to be a little addicting, and some people have asked if there was a tool for people to create charts, instead of having to munge with URLs.

A common use case is to dynamically generate the charts on the fly, and then it makes sense to just build the URls and you are done. But, what if you wanted to sit back and just throw out a chart or two?

This is where ChartMaker (code) comes in.

The tool has you fill out core information about the graph or chart that you want to create (e.g. size and title), you then choose the type of chart in the tabs, and you fill out the data needed for that type of chart. You can click on the “seed data” button to see sample data, and when you are done tweaking it, you click on “GET CHART”. That action causes a preview to be loaded below, and you get given the URL in a text box that you can copy and paste.

It is a little rough around the edges in that I wanted to let you tab though fields and have an easy way to add rows of data (instead of just using a crude textarea). I also need to make it so that all of the data can be expressed through the UI (e.g. marker types, colors, fills, etc) which isn’t the case now.

I really enjoyed Ext 2. They did a great job, and with more documentation and such to come, I think it is a great library for building these desktop-like environments.

The UI was basically defined via:

init: function() {
  var header  = headerSection();
  var center  = centerSection();
  var preview = previewSection();
 
  var viewport = new Ext.Viewport({
    layout: 'border',
    items: [header, center, preview]
  });
}

Then each section used the “region” metadata to tell the system where to place it. You are also able to do things like tell the system you can be moved around, collapsible, and more.

So, the result of a few hours with Ext 2 with no access to the online docs and you get this:

Dec 19

Gears Future APIs: Image Manipulation API

Ajax, Gears, Google, Tech 10 Comments »

I said in my recent post on Gears being about more than offline that I would talk about some fun future APIs.

The Gears project is open source, and is really being held out in the open, which means that you can check it out and contribute. We want Gears to be community open source, as opposed to just using open source as the way code gets out there. There is a big difference. Poke around the Wiki to see more.

Back to the API. The Image Manipulation API provides a way to manipulate images though client-side JavaScript:

This is a module to give Javascript a way to resize, crop and compose images together on the client side. This will allow, for example, images to be resized into a web-friendly format before being uploaded to a photo album. Another use is for composition of images together as an efficient alternative to server-side composition or CSS layering. Yet another use is for basic photo editing – a user can edit a photo with instantly applied changes before uploading it to the server.

The module is fairly simple, and has the following API:

var image = google.gears.factory.create('beta.image', '1.0');
 
void open(blob)
Blob blob(type)
void resize(width, height)
void crop(x, y, width, height)
int width()
int height()
void rotate(degrees)
void flipHorizontal()
void flipVertical()
void drawImage(image, x, y)
void close()

Having this functionality available natively in the browser would be very cool indeed, and could open up the doors for some interesting ideas.

Other Future APIs

Disclaimer: This is early days, and who knows what the final API will look like, and how far it goes. Do you have ideas for cool Gears that make the Web better? Let us know!.

UPDATE: Ray Cromwell of Timepedia thinks that we should be more ambitious. There are some great thoughts in there, and this is the type of feedback that we really look forward too. We haven’t even begun here, so feedback now will hope us having something a lot better when all is said and done..

Loading...