Showing posts with label webdevelopment. Show all posts
Showing posts with label webdevelopment. Show all posts

June 1, 2011

Writing JavaScript in 2011 - catching up with the latest trends

JavaScript has definitely bloomed during the last few years. I do remember the first time I heard of JavaScript in the late 90s - I wrote a small script that showed a random image (out of a static array) on a static HTML page that I tested in Netscape and IE5-or-so. Today people run JavaScript in top- and mid-range mobile devices, on their web browsers, on servers, on the Gnome3 desktop.

JavaScript is the only language for building an application for all major "smart" mobile devices from within a singular codebase. That, already, interests me enough to give a closer look on some modern JavaScript tools - and write my observations about them.

Foremost, testing JavaScript was something I had completely neglected before. If I was to write serious applications using JavaScript, I'd absolutely needed a way to write unit tests. Secondly, I wanted to have a look at CoffeeScript, which has had a lot of positive attention lately.

I started out by digging into the recent archives of JavaScriptWeekly newsletter. Out of a good number of testing tools, I selected to try out JsTestDriver. It is compact, requiring only a single jar file and a configuration file. The jar contains a small web server that is ran on the source code directory, and exposes a specific url that should be opened in the browsers that will run the JavaScript code to be tested. Cool! If you consider to try out JsTestDriver yourself, I recommend you checkout their SVN repository and compile the jar yourself - the jar file given in the example is outdated and does not contain all the features that the guides may refer to - for example, mocking a piece of HTML that the JavaScript modifies.

Mocking AJAX was out of my scope at this stage, for that you may find this article to be helpful.

For learning to use JsTestDriver, I chose to write a simple slideshow application that uses CSS3 transformations to change the pictures. The required JavaScript for this seemed simple enough, and I wanted to learn some new CSS tricks as well. ;) So, this is "bébé", written in a few days using jQuery-powered CoffeeScript. I started out by getting the basics of CoffeeScript, having it to load the images onto the page, and then wrote tests to see the pictures were actually loaded. Testing the user interface seems to be very difficult, due to differences in how different browsers behave under JsTestDriver. I set the picture position to absolute, since elsehow I could not get the CSS transition to appear smooth (and have the image to disappear without hiding it with JavaScript). CoffeeScript is pretty amazing, and works really well with jQuery. :)

The code for this, along with the JsTestDriver tests, can be found on Github. This seems to work reasonably well in Firefox 4, Chrome, Opera 11, Safari (and Mobile Safari on iOS) and Android browsers. Firefox 3 behaves correctly, it just doesn't show the transition effect. IE fails miserably, never showing anything except the first image. :/

Here are some nice pointers to related articles:

..and now for something different ..
PC emulator in the browser running Linux on JavaScript

March 7, 2011

HTML5 native audio support comparison

Here are the results of a quick test how various browsers on OS X 10.6 (and iPhone 3GS) play HTML5 <audio>.

UPDATE 25.5.2011: I updated the data and found that the audio support has become better in many browsers. I left in old data for comparison.

Browser / OS mp3 wav ogg
Android 2.2 X X X
Chrome 9.0.597 ok X1 ok
Chrome 11 ok X1 ok
Firefox 3.6.13 X ok X2
Firefox 4.0.1 X ok ok
iOS 4.2 ok X X
Opera 11.1 X ok3 ok
Safari 5.0.3 ok X X
Safari 5.0.5 ok ok3 X
  • 1    plays, but is buggy
  • 2    hangs on load
  • 3    is able to seek!

Likewise with <video>, there is a need to encode to many formats to support all browsers. I have no data of IE9. Unfortunately Android 2.2 cannot play any audio type at all! This is supposed to be fixed in Android 2.3. See this link for more information on HTML5 audio on Android. Also, Opera 11.1 could play ogg files, but I noticed that when they were encoded in higher bitrates, the playback stopped in the middle of the track, systematically. This seems to be fixed in Opera 11.11. Chrome buggyness on wav files appears upon seeking- the play stops and cannot be started again without reloading the page.

The tests were conducted by creating a very simple HTML5 document with this content:

      <!DOCTYPE html>
      <html>
      mp3: <audio src="test.mp3" controls></audio>
      wav: <audio src="test.wav" controls></audio>
      ogg: <audio src="02.ogg" controls></audio>
      </html>
    
The files were hosted (locally) from the same directory as the html document by ad-hoc Python web server:
      python -m SimpleHTTPServer
    

April 5, 2010

Comparison of Web Proxy Portlet, Portletbridge and html2jsr286

There are at least three different JSR 168 / 286 portlet projects that have a similar target: to allow custom web apps and arbitrary web content be accessible in portlets.

I am the author of "Rails-portlet" and it's alive - I just updated the setup guide. It all started when I needed to develop a webapp for Liferay, and I wanted to do it with Rails. html2jsr286 is not an indication of the NIH syndrome, I just now learned of their existance. I inspected their source code, and this is a quick run-down of their features and pondering of future direction.

These are the common features in all three projects:

  • Getting content from a downstream site
  • Proxying of remote resources (e.g. images, Flash etc.)
  • Regular expression defining which URL's are in the portlet and which should be regular links
  • Rewriting CSS urls
  • Moving Javascript and CSS links out of the head
  • Session cookie support
All three have the same shortcoming concerning Ajax: the urls are not being rewritten so that XHR from the browser is not catched by the portlet.

WebProxyPortlet is being developed mainly for uPortal, and

..it provides mechanisms for connecting to and rendering HTML with options for clipping, maintaining session information, handling cookies. Proxied content is rendered within the portlet window. Web Proxy Portlet is often used to incorporate web content or applications that are built and run in non-Java environments allowing a site flexibility for integrating with many different technologies.

Sources of portletbridge

$ mkdir portletbridge
$ cd portletbridge/
$ cvs -z3 -d:pserver:anonymous@portletbridge.cvs.sourceforge.net:/cvsroot/portletbridge co -P .
Sources of WebProxyPortlet
$ svn co https://www.ja-sig.org/svn/portlets/WebproxyPortlet/trunk/ WebproxyPortlet
Sources of html2jsr286
$ git clone git@github.com:lamikae/html2jsr286.git

My impression after a while looking through the sources is that WebProxyPortlet is the most advanced, and has a number of nice features, especially in ways of user authentication and portlet configuration through the user interface.

Considering code cohesion and the number of Java classes: WebProxyPortlet has 58, Portletbridge 51 and html2jsr286 only 10 Java source files. Here are links to their main view methods:

void renderContent(final RenderRequest request, final RenderResponse response) in WebProxyPortlet.java
void doView(final RenderRequest request, final RenderResponse response) in BridgeViewPortlet.java
void render(RenderRequest request, RenderResponse response) in Rails286Portlet.java

WebProxyPortlet works in JSR 168 containers and supports a variety of authentication techniques, handles caching, has pluggable Java classes for custom request filtering and page processing. On top of this is uses a whole lot of JavaBeans and JSPs that make the portlet configurable from the GUI in the portlet config mode. I am not sure how much runtime overhead this accouts to, and how useful it is to let users select the HTML parser the portlet is going to use. Page processing is implemented by chaining up SAX filters.

Some criticism must be given; there are virtually no unit tests and there seems to be some code repetition and lots of "boilerplate" code (which is quite difficult to neutralize in Java) and somehow it just hurts me that the renderContent() method is 374 lines long. It could use some refactoring.

Portletbridge seems to have stalled active development some years ago, but there seems to be some recent code cleanup in progress, according to CVS logs.. It probably is doing what it's supposed to, feature-wise it seems to be close on par with html2jsr286, and it runs on JSR 168 portals. Page processing is done by XSLT, a feature that I really like.

html2jsr286 and Rails-portlet are strong in that they offer a toolchain for a Rails developer to get quickly into deployment with as much automation as possible. The other two projects look like they are more tuned to serve the portal administrator instead of the development team. The Rails-portlet project tools can also work without Rails, but then the deployment gets more encumbered, requiring more dirty work with Java and XML. Rails-portlet is targeting for web app developers who want to keep a healthy distance to the J2EE stack and "get things done" quickly.

html2jsr286 passes the Liferay UID in request headers, with a unique authentication mechanism. It can also handle Liferay GID – feature that is missing from the other two portlets. It is, however, restricted for JSR 286 portals, as it makes use of portlet filters, which were introduced only in JSR 286. The rationale behind this is to improve code coherence (there are no technical reasons that would demand using filters). JSR 286 container will, however, be needed for the XMLPortletRequest feature. The portlet is being used on at least two production sites, and in practise is doing fairly well. Page processing is done by HTML Parser, which does a decent job but has shortcomings that I would like to address with XSLT, and this is what Portletbridges is doing.

Nonetheless, I am considering a rational move to leverage WebProxyPortlet in Rails-portlet, and it seems that the first step is to get it running on Liferay and uPortal, hosting the portlet test bench.

Next big step would be to work on Ajax support, by carrying out ideas from these posts to implement XMLPortletRequest.

January 23, 2010

Mathematical discourse on the web

Consider explaining mathematics on the web for someone. The tools to use are quite nifty. Algebra needs distinguishable symbols, geometry some other control methods. Even simple formulas are not so simple: I have a friend who recommended I should try to mix MathFlow with webMathematica and offered me a developer platform. This post is not so much as on the display of formulas as it is about my personal experience of mathematical expression on the web. Mathematica feels like a nice language. I had help for learning it from an experienced notebook / jsp writer, another friend. With his teaching I could quickly learn the essentials constructs of Mathematica's functional style to do simple experimentation and mix it in jsp. WebMathematica3 is a Java servlet package with the necessary backend kernel connectivity and a taglib for the developer. Worked out-of-the-box on OSX – Linux server requires 1 extra step for Xvnc. The taglib is quite usable, with three basic types of components: Manipulate is not quite as swift as it is in native Mathematica. The image does not follow the slider before the click is released. The network and server would be stressed for serving many concurrent users..

MathFlow is an input mechanism to essentially decrease the learning curve to input mathematical notation into the web. It is a Java applet that seems to work on all major OSes given that the moon is in correct orientation and system Java has not crucially changed. Icedtea6 Java plugin on Ubuntu worked too. MathFlow is proprietary software, this was an evaluation license. To be able to test it on a private server so that clients other than localhost can see it, was possible by recompiling the jar with a custom evaluation license. I could not find any open source alternatives, and this software seems capable of doing the job right now. Ideally, modern-day alternative could be written in JavaScript.. maybe compatible with MathJax..

The output formula is in MathML, and it can be captured to webMathematica input, in JavaScript, using for example the MooTools toolkit to do an XHR and update the page:

var mml = document.SampleSimpleEditorApplet.getMathML();
   params = 'fun='+URLescape(mml);
   var req = new Request.HTML({
     method: 'post',
     url: '_action.jsp?'+params,
     encoding: 'iso8859-15',
     onRequest: function() {},
     update: $('div.output'),
     onComplete: function(response) {}
   }).send();


This would send the contents of the editor applet to _action.jsp in request parameter fun, and the XHR would update the page. This _action.jsp in webMathematica could..
<%@ page contentType="text/xml"%>
<%@ taglib uri="http://www.wolfram.com/msp" prefix="msp" %>

<msp:evaluate>
  MSPFormat[
    MSPToExpression[$$fun],
    TraditionalForm
    ]
</msp:evaluate>
.. generate an image of the formula in traditional mathematical notation. Notice the $$fun variable, which is parsed by the webMathematica backend. In case where the formula has variables, it is possible to parse it in the "delayed" form:
SetDelayed[
    f[x_],
    Evaluate[
      MSPToExpression[
        $$fun,
        MathMLForm
      ]
    ]
  ];
Or plot it, notice the use of MSPBlock ..
MSPBlock[
    {$fun},
    MSPShow[
      Plot[
  
        $fun,
        {x, -2*Pi, 2*Pi},
        ImageSize->{600,500}

      ]]]

So you can build all sorts of elaborate user interfaces on top of these building blocks. This is just an example of plotting the user input formula. He shouldn't need to learn LaTeX or any other new notation to input the mathematics into the computer.

The mathematica magician can work with the Wolfram Workbench to write Mathematica code, and still work in a familiar notebook environment.

The web developer has a similar view to produce the 3D applet, where the MSPLive3D module creates the HTML code for the Java applet.
Needs["Talo3D`"];

...

  MSPLive3D[
    Graphics3D[
     {
      RGBColor[0, 0, 1],
      Thickness[0.005],
      Map[Line, house]
     },
     Boxed -> False
    ]
  ]

This is LiveGraphics3D generated by webMathematica3 on Safari. The house is rotatible. =) The original .nb was cc'd to me by Jyrki Kajala a few years ago. Quite recently he taught me about Mathematica packages, and .m files, and how the notebook can load the package. The package can now be subjected to functional testing and also included to webMathematica JSP. The tools have a certain good feel of dynamicity. Some issues, here and there, but it would be very interesting to build various use scenarios ..

December 28, 2009

EtherPad and co-ment

I was sitting in a train for a few hours, with the source code of EtherPad (Apache License 2.0) and co-ment (GNU Affero GPL 3) on my MacBook. I had just done the initial checkout before the trip - I was very excited to look how these two open source code editors work. EtherPad was just being acquired by Google, apparantly to get more professional people to work on the Wave. Real-time collaborative editing seems to be the new paradigm for web user interfaces.

Both projects, naturally, use JavaScript for transacting with the DOM. EtherPad handles page updates with Comet techniques. Neither come with verbose description of their inner workings, but the EtherPad authors have written a nice post (in the source code repository) that reveals the essential magic ingredient:

"The crazy idea here, which seems to have originated with Dutch programmer Marijn Haverbeke, is to take advantage of a browser feature called "design mode" (or "content editable"), a mode which allows the user to directly edit an HTML document. This feature has quietly been added to all major browsers over time. In fact, it's what GMail uses to let users compose rich-text e-mail. The advantages of basing an editor on a design-mode buffer are that such a buffer has a full DOM (document model), which allows arbitrary styling and swapping of parts of the document, and that native editing operations (selection, copy/paste) are mapped by the browser onto operations on the DOM.
...
The key is to treat the DOM as a hugely complicated I/O device between you and the browser, and carefully make rules to constrain it. The plus side is that once you've systematically beat design mode into submission, you can have an unmatched degree of scalability and nativity."
The server-side is handled by Scala, Java and JavaScript. Huh?
"This enabled us to be more productive by writing all of EtherPad in the same language, and shuttle data between the client, server, and database all using JavaScript objects."
The data persistance model is not very conventional either:
"EtherPad stores all its data in the AppJet Database, which automatically scales and caches itself in memory as necessary. This makes it fast to implement EtherPad features, fast to change storage models, and fast to serve requests in production."
The code looks very professional and clean, albeit difficult to grok to develop new features. As an interesting note, the included documents describe the changeset to look something like:
Z:5g>1|5=2p=v*4*5+1$x
"This changeset, together with the pool, represents inserting a bold letter "x" into the middle of a line."
This is achieved by JavaScript:
function handleUserChanges() {
  ...
   var userChangesData = editor.prepareUserChangeset();
   if (userChangesData.changeset) {
     lastCommitTime = t;
     state = "COMMITTING";
     stateMessage = {type:"USER_CHANGES", baseRev:rev,
                     changeset:userChangesData.changeset,
                     apool: userChangesData.apool };
     stateMessageSocketId = socketId;
     sendMessage(stateMessage);
     sentMessage = true;
     callbacks.onInternalAction("commitPerformed");
   }
 ...
 }
...and the changeset can be traced back to function "compose()":
Changeset.compose = function(cs1, cs2, pool) {
   var unpacked1 = Changeset.unpack(cs1);
   var unpacked2 = Changeset.unpack(cs2);
   ...
   var bankAssem = Changeset.stringAssembler();

   var newOps = Changeset.applyZip(unpacked1.ops, 0, unpacked2.ops, 0, function(op1, op2, opOut) {

     var op1code = op1.opcode;
     var op2code = op2.opcode;
     if (op1code == '+' && op2code == '-') {
       bankIter1.skip(Math.min(op1.chars, op2.chars));
     }
     Changeset._slicerZipperFunc(op1, op2, opOut, pool);
     if (opOut.opcode == '+') {
       if (op2code == '+') {
           bankAssem.append(bankIter2.take(opOut.chars));
       }
       else {
           bankAssem.append(bankIter1.take(opOut.chars));
       }
     }

   });

   return Changeset.pack(len1, len3, newOps, bankAssem.toString());
 };

So overall, EtherPad looks very promising, but difficult to tailor for specific needs.

Co-ment, in the other hand, is a simpler solution. "co-ment® makes it possible for you to write or upload your own texts, submit them for comments and process the comments."

It also uses JavaScript on client-side and Python with Django on the server. The magic is not as advanced; it uses a DOM manipulation API (Beautiful Soup), and happily ignores standard design patterns by mixing views and request/response mechanism control structures with inline SQL. In other words: it is written with more traditional technology, but in a way that makes it difficult to maintain.

The source codes of either project are definitely beneficial to read and learn from. Unfortunately the lack of architectural documentation makes this a tedious task.

UPDATE: LWN comments on EtherPad

November 17, 2009

Recent advances in WWW technologies and the new generation of user interfaces

Many new technologies for the web have emerged during the year 2009. Google Wave, HTML5 and the increasing importance of JavaScript are the driving on the internet, but the mobile device is a growing market where Qt and Android look to provide the best SDKs for iPhone competition. JavaScript engines have been making significant improvements in performance, and V8 makes the Chrome browser a playground of innovation.

I have been silently learning Python with PyQt4 that along with QtDesigner make a good combination of tools for cross-platform GUI development. PyQt4 on the other hand did not agree on new licensing with Nokia, and now there is a new Python Qt4 library emerging: PySide. PySide is an important effort and Python -the language- is looking very promising for a number of reasons.

This exciting iframe below presents Your World of Text, a co-editor which is a prime example of what is possible with modern technology, but this is just a sneak preview of the possibilities that are opening up for developers. Not just on the web but also on the desktop. This demo is produced by Andrew Badr using jQuery, a few lines of custom JavaScript and Django, the Python framework.

In 10 years we may have an Ajax X-server.

The Google Wave videos (check also the playlist) are also inspiring. Google Wave provides a same kind of technology as the demo above, but the codebase is not the same.

The "Wave" that Google presented is under the hood essentially an XML document. The Google Wave Federation Protocol defines the operational transformation layer for sharing the document and mitigating live updates between all wave providers. This works not unlike Git, and all geeks agree how fabulous Git is. As an analogue, Wave provides to non-techie fellow humans (communicate, share) what Git does for code hackers (code, share). Just in a very cool way that code hackers too can appreciate. The protocol is open to contributions by the broader community with the goal to continue to improve how humans share information, together. Even across language barriers!

So in the very near future, we can have live co-editing in multimedia documents with indesign publication / forking / remixing mechanism. The environment, then .. will it be only the web?

The trio: HTML5, CSS3 and JavaScript, has matured and provides a solid base for new generation of dynamic user interfaces. The Amiga Workbench Emulator is a showcase of JavaScript UI and Qt Labs demonstrates the power of HTML5+CSS3 that only works on WebKit browsers (Safari, Konqueror, Chrome). There is no particular Javascript code that switches the items, everything is done by CSS.

Any defences for the plain old desktop apps? Other than terminals, text/video/etc editors, games, mission-critical tasks, CPU/GPU-intensive 3D apps, ... Oh yes. I for one find it somehow silly to overload a web browser with all of this. One of the reasons why web apps got widly popular at some stage is that they are not locked into one physical computer and that the user can change from operating system to another. Reality hits back in the form of browser inconsistencies and especially by the well-known fact that the single most used browser is completely incapacitated by todays standards (IE6 - 23,4% of all browsers in October 2009).

When I started using QtDesigner and Python I was fairly delighted how well they work together. Nice IDE to design the GUI and the UI widgets can be imported and instantiated in my Python code. This is a win for the Qt app. Qt implements the concept of signals and slots, which provide a way to connect asynchronous events (signal) to call a method (slot). For a web app, this would be possible with JavaScript XHR, but there is no "API", since this concept is a bit foreign in the web world. This is a win for the Qt app. The layout of a QFrame is very rigid, unlike HTML+CSS which can be extremely fluid. This is a win for the web app. It also is quite sensible to use accessor objects for inserting data onto a table, but I have to say it feels a bit silly to write 10-20 lines of boilerblate code instead of just iterating over an array and setting a few CSS classes to ones liking? This is a win for the web app. Σ: Qt web = 2. Both have unique strengths.

Indeed, the web hosts many exotic UIs without overall consistency, whereas the desktop look and feel is pretty much standard with a limited set of widgets, uniform in appearance and function across all applications. That is user-friendly. In some sense it is nice to provide the administrator a single install file and the user an icon on the desktop (or Dock) to click on to access the application. A desktop application may also have access to the hardware and external devices such as USB cameras. An everyday internet browser, enhanced for secure anonymous browsing, should never have these privileges.

Mozilla Prism is a small independent browser window and it already is my favourite way to read GMail and Facebook, but the full potential of desktop integration is not used. Prism uses the Gecko engine, whereas Qt4 provides a QtWebKit module that is capable of loading and rendering web pages with the help of the WebKit browser engine.

I will continue in part #2 on my ideas how desktop and web technologies could build on top of each other's strengths.

November 15, 2009

Chrome Experiments paint the canvas with the future

This is one of my favourites from the Chrome Experiments. Colorscube by Dean McNamee. Best run on the Chrome browser.

It reminds me of the movie Cube. In this demo you can't actually zoom into the cube, but the controls make possible to rotate the cube on the canvas element.

The user interface on this demo, for example, show the power of HTML5 and modern JavaScript technologies. The user experience in the Chrome Experiments is good also on modern touchpads.

This will open up new technologies for developers also on the desktop - and today the most promising tech looks to be Qt. The desktop is a tremendous playground, not just the browser where the drag is one de-facto breed of browsers.