Web Info & Tutorials

February 8th, 2008

JQUERY 1.2.3: SUPPORT FOR AIR, NAMESPACING

The jQuery team announced today the release of jQuery v1.2.3. Primarily a bug fix for v1.2.2, this new release also includes new features to make it compatible with the Adobe AIR runtime and SDK:

The primary purpose of this release was to fix a couple outstanding bugs from the jQuery 1.2.2 release. Specifically, this release is now compatible with Adobe AIR, will be included in Drupal 6, and will be the base for jQuery UI 1.5. Additionally, a couple minor features, for plugin developers, were included in this release.

Another notable feature is the enhancement of the namespaced event methods, specifically unbind(), which now allows you to remove all bound events that match a particular namespace.:

LANGUAGE:
$("div").bind("click.plugin", function(){});
$("div").bind("mouseover.plugin", function(){});
$("div").unbind(".plugin"); // All handlers removed

You can download this new jQuery release via the following links:

jQuery 1.2.3:

If you wish to checkout the full release from the Subversion repository, you can do so by following the instructions and checking out the source from the following location:

svn co http://jqueryjs.googlecode.com/svn/tags/1.2.3
February 8th, 2008

ARCLITE: ARC FOR JAVASCRIPT

Jonathan Tang has fallen into the Arc fun and took some time to fully implement it in JavaScript.

It differs from Paul's implementation:

  • Supports Unicode, at least as well as JavaScript supports it.
  • There are very few I/O primitives - the ones that do exist write to the string "Eval.stdout", which can be tested and reset as necessary.
  • I started work on a FFI but abandoned it so I could get back to my real projects. :-) The plan was to add 'jscall' and 'jsref' special forms that act as the function-call and object/array indexing operations, respectively. You can use Types.to_js() and Types.to_arc() to convert Arc values back and forth to JavaScript, along with the Types.* constructors themselves.
  • String objects are immutable, because JavaScript does not offer mutable strings. (= (a-string 0) new-char) returns the new string, but does not modify the old one. A few functions in arclib have been redefined to account for this; see the #arclitelib element in this page's source.
  • (set foo 1) operates in the lexical environment instead of always setting a global. It still sets a global if it can't find the symbol in the lexical environment. This is necessary for the Arc library to function.
  • Tagged data items (eg. macros) can be called and set like their underlying data type.
  • Continuations are not implemented. I had started on a CPS-based interpreter, but then realized that JavaScript lacks tail-call optimization and has a recursion limit of 1000 calls, which'll make any CPS-transformation blow the stack.
  • Macros are looked up in the lexical environment, and are expanded right before the form is evaluated rather than when it is defined. This opens up a couple possibilities:
    1. You can theoretically have first-class macros; if you pass a macro value to a function, then the body of that function is expanded using the definition of the passed-in macro.
    2. You can have lexical macros. If you already have a binding defined in a function, then (mac ...) will set that binding rather than adding a new one to the global environment. This only applies if a binding already exists; if not, (mac ...) will create one in the global environment, just like the reference implementation.
  • Other than this, the interpreter seems to execute arc.arc fine. Since arc.arc is considered the specification for Arc, I guess this means that ArcLite is a fully-conforming implementation. There may be a few bugs though; most functions are not well-tested, and I had to write my own reader implementation and primitive data types instead of piggybacking off Scheme.
  • Don't expect a speed-demon. This is an AST-interpreter running on top of an interpreted language that's roughly 1000x slower than C. I'm surprised it works at all.

Paul also put out an Arc Challenge:

Write a web program such that:

  • The first page of the program displays nothing but a text box and a submit button. You enter some arbitrary text and press the submit button, which takes you to …
  • The second page is nothing but a single link labeled “click here”. The URL linked to must not contain the text entered in the first step (i.e. you are not supposed to pass the text as a parameter on the link). Clicking the link takes you to …
  • The third page which contains “You said: XXX” (where XXX is the text you entered in the first step).

Paul implemented this via:

[lisp]
(defop said req
(aform [w/link (pr "you said: " (arg _ "foo"))
(pr "click here")]
(input "foo")
(submit)))
[lisp]

Many others have thrown their hat in the ring too, including Jim Weirich:

RUBY:
Conversation.interact do |io|
  text = io.ask
  io.pause("click here")
  io.tell("You said: #{text}")
end
February 8th, 2008

REFACTORING YOUR JAVASCRIPT FOR FUN AND PROFIT

Our newest Ajaxian Chris Heilmann - London Yahoo! - has written a piece on his blog covering five things to do to a script before handing it over to the next developer.

He walks through a refactoring experience:

Let’s say the job was to add small link to every DIV in a document with the class collapsible that would show and hide the DIV. The first thing to do would be to use a library to get around the issues of cross-browser event handling. Let’s not concentrate on that for the moment but go for old school onevent handlers as we’re talking about different things here.

The code starts off as:

JAVASCRIPT:
collapser = function(){
  var secs = document.getElementsByTagName('div');
  for(var i=0;i<secs .length;i++){
    if(secs[i].className.indexOf('collapsible')!==-1){
      var p = document.createElement('p');
      var a = document.createElement('a');
      a.setAttribute('href','#');
      a.onclick = function(){
        var sec = this.parentNode.nextSibling;
        if(sec.style.display === none'){
          sec.style.display = '
block';
          this.firstChild.nodeValue = '
collapse'
        } else {
          sec.style.display = '
none';
          this.firstChild.nodeValue = '
expand'
        }
        return false;
      };
      a.appendChild(document.createTextNode('
expand'));
      p.appendChild(a);
      secs[i].style.display = '
none';
      secs[i].parentNode.insertBefore(p,secs[i]);
    }
  }
}();
 

and then he walks through some steps:

  • Step 1: Remove look and feel
  • Step 2: Remove obvious speed issues
  • Step 3: Removing every label and name from the functional code
  • Step 4: Use human-readable variable and method names
  • Step 5: Comment, sign and possibly eliminate the last remaining clash with other scripts
  • Which has you ending up with:

    JAVASCRIPT:
    //  Collapse and expand section of the page with a certain class
    //  written by Christian Heilmann, 07/01/08
    (function(){

      // Configuration, change CSS class names and labels here
      var config = {
        indicatorClass : 'collapsible',
        collapsedClass : 'collapsed',
        collapseLabel : 'collapse',
        expandLabel : 'expand'
      }

      var sections = document.getElementsByTagName('div');
      for(var i=0,j=sections.length;i<j ;i++){
        if(sections[i].className.indexOf(config.indicatorClass)!==-1){
          sections[i].className += ' ' + config.collapsedClass;
          var paragraph = document.createElement('p');
          var triggerLink = document.createElement('a');
          triggerLink.setAttribute('href','#');
          triggerLink.onclick = toggleSection;
          triggerLink.appendChild(document.createTextNode(config.expandLabel));
          paragraph.appendChild(triggerLink);
          sections[i].parentNode.insertBefore(paragraph,sections[i]);
        }
      }
      function toggleSection(){
        var section = this.parentNode.nextSibling;
        if(section.className.indexOf(config.collapsedClass)!==-1){
          section.className = section.className.replace(' ' + config.collapsedClass,'');
          this.firstChild.nodeValue = config.collapseLabel
        } else {
          section.className += ' ' + config.collapsedClass;
          this.firstChild.nodeValue = config.expandLabel
        }
        return false;
      }
     

February 8th, 2008

HIDE AN IMAGE IN HTML?

Erik Kastner created something a little bizarre at 2am (beer involved?). He built an image hider using the CSS3 ::selection pseudo-element.

You mouse over the text and a hidden image reveals itself. Time for some silly hide and seek games!

CSS 3 selection