Web Info & Tutorials

June 6th, 2008

AN INTERVIEW WITH 280 NORTH ON OBJECTIVE-J AND CAPPUCCINO

280 North

As I feature in this podcast interview, I got an primeval countenance at 280 Slides the covering that launched yesterday to much acclaim. People are occupation it “Keynote on the Web”, which the aggroup finds rattling humbling, and wish that digit period they hit every of the enthusiastic features (and more!).

As you crapper hear from the interview I set downbound with doc Boucher, blackamoor histrion and Francisco Tolmasky to handle their newborn application and how they shapely it.

I rattling aforementioned these guys. A pair of them worked on modify products at Apple, and it turns discover that they started the module and runtime impact backwards at school.

Objective-J is the module that takes JavaScript and makes it Objective (as Obj-C did to C). Lots of conservativist brackets. When the covering gets served .j files, it preprocesses them on the fly. This effectuation that you crapper do things like, ingest accepted JavaScript in places.

Cappuccino is the opening of the Cocoa framework.

The guys speech a lowercase most the toolchain an ground they did this, and modify how it enables forthcoming modify things much as generating a autochthonous Mac covering from the aforementioned code.

We also intend into the recreation interbreed covering issues that they impact around, and how they are abstracting developers broad up, so you don’t hit to care with these issues.

Finally, I was agog to center that they module be unstoppered sourcing the cipher at objective-j.org presently (may not be there yet). They are feat finished the customary issues of choosing a authorise (Apache2 please?), a maker curb grouping (Subversion vs. Git), and documenting the abstract ;)

We hit the frequence directly available, or you crapper subscribe to the podcast.

The aggroup was rattling fascinated in acquisition what JavaScript developers conceive (They hit heard from Objective-C sept who fuck it), so permit them undergo in the comments!

June 6th, 2008

A TECHNIQUE FOR LAZY SCRIPT LOADING

Bob Matsuoka has cursive a temporary article on the matter of lazy playscript loading. Thanks so such Bob!

A past article “Lazily alluviation functionality via Unobtrusive Scripts” discussed how to lazily alluviation Javascript playscript files by appending playscript elements to the HEAD tag.

While this entireness as expected, I’ve institute that for prizewinning results, you should also study chase which scripts hit been unexploded in visit to preclude re-loading an already unexploded script, and more importantly activity callbacks so that you crapper indorse weight of scripts preceding to occupation functions that depend on that code.

NOTE: The warning dockhand script, which has been proven in FF, IE, Safari, and Opera, uses prototype.js for DOM and clothing routines. I matured this originally for a send that already had prototype.js available, but it uses it exclusive superficially. It should be ultimate to vanish these references if you’re not using prototype.js.

JAVASCRIPT:

  1.  
  2. /** 
  3. *  Script lazy dockhand 0.5
  4. *  Copyright (c) 2008 Bob Matsuoka
  5. *
  6. *  This information is liberated software; you crapper redistribute it and/or
  7. *  add it low the cost of the GNU General Public License
  8. *  as publicised by the Free Software Foundation; either edition 2
  9. *  of the License, or (at your option) some after version.
  10. */
  11.  
  12. var LazyLoader = {}; //namespace
  13. LazyLoader.timer = {}// contains timers for scripts
  14. LazyLoader.scripts = []// contains titled playscript references
  15. LazyLoader.load = function(url, callback) {
  16.         // appendage goal or path
  17.         var classname = null;
  18.         var properties = null;
  19.         try {
  20.                 // attain trusty we exclusive alluviation once
  21.                 if ($A(LazyLoader.scripts).indexOf(url) == -1) {
  22.                         // land that we unexploded already
  23.                         LazyLoader.scripts.push(url);
  24.                         var playscript = document.createElement(“script”);
  25.                         script.src = url;
  26.                         script.type = “text/javascript”;
  27.                         $$(“head”)[0].appendChild(script)// add playscript attach to nous element
  28.                        
  29.                         // was a asking requested
  30.                         if (callback) {    
  31.                                 // effort for onreadystatechange to causing callback
  32.                                 script.onreadystatechange = function () {
  33.                                         if (script.readyState == ‘loaded’ || script.readyState == ‘complete’) {
  34.                                                 callback();
  35.                                         }
  36.                                 }                            
  37.                                 // effort for onload to causing callback
  38.                                 script.onload = function () {
  39.                                         callback();
  40.                                         return;
  41.                                 }
  42.                                 // expedition doesn’t hold either onload or readystate, create a timer
  43.                                 // exclusive artefact to do this in safari
  44.                                 if ((Prototype.Browser.WebKit && !navigator.userAgent.match(/Version\/3/)) || Prototype.Browser.Opera) { // sniff
  45.                                         LazyLoader.timer[url] = setInterval(function() {
  46.                                                 if (/loaded|complete/.test(document.readyState)) {
  47.                                                         clearInterval(LazyLoader.timer[url]);
  48.                                                         callback(); // call the asking handler
  49.                                                 }
  50.                                         }, 10);
  51.                                 }
  52.                         }
  53.                 } else {
  54.                         if (callback) { callback(); }
  55.                 }
  56.         } catch (e) {
  57.                 alert(e);
  58.         }
  59. }
  60.  

Download the flooded maker and warning project.

Tracking Loaded Scripts

A ordinary ingest of a lazy dockhand is in union with “require” identify duty that allows you to take which scripts are necessary for a portion playscript to execute. Since accumulation scripts are ofttimes titled by more than digit script, I intellection it essential to earmark my lazy dockhand to road which scripts hit already been unexploded on a tender to preclude extra re-loading.

In this example, I’ve created the LazyLoader.scripts array. As apiece playscript is called, this playscript src is proven against the clothing of scripts already called, and if it exists, the playscript is not re-loaded, but its asking is executed. This allows you to call some required playscript as ofttimes as necessary with impunity.

Supporting Callbacks

A more essential constituent is hold for callbacks. It is my undergo that with anything more than the simplest scripts, you cannot indorse that a playscript is acquirable for ingest unless it is titled as conception of a asking equal to the weight process. Unfortunately most of the browsers appendage playscript onload events slightly differently. The examples I’ve provided should impact for Firefox, Safari, and IE.

The base system for activity callbacks is to earmark a approaching to be passed to the lazy loader. The duty is then extremity to the playscript circumstance triggered by its loading. FF and Safari 3 hold the “onload” event. IE supports the onreadystatechange event, and requires boost investigating of the land for either ‘loaded’ or ‘complete’ (depending on whether the playscript is cached).

Supporting callbacks in Safari 2 and Opera order a offense wrinkle, since neither hold “onload” or “onreadystatechange” playscript events. For these browsers, you requirement to ordered a hurried quantity playscript to effort document.readyState for “loaded” or “complete”. Once ready, the quantity crapper be unwooded and the asking executed (I ingest a assorted quantity for apiece playscript loaded, but I’m not trusty that’s necessary, since we are exclusive investigating the writing object, not the land of the individualist scripts).

Calling The Loader

Calling the dockhand is straightforward. This feat is falsehood as a noise duty using a namespace. Here is an warning without a callback:

JAVASCRIPT:

  1.  
  2. LazyLoader.load(‘js/myscript1.js’);
  3.  

Here is an warning with a callback:

JAVASCRIPT:

  1.  
  2. LazyLoader.load(‘js/myscript2.js’, function(){
  3.     var myobj = new MyObject(‘myobj’);
  4. });
  5.  

In the ordinal example, the “myobj” happening of MyObject is exclusive created after js/myscript2.js is loaded. You crapper also daisychain loaders by including them in the asking function.

Conclusion

I’ve utilised this framework for nearly a assemblage with beatific results. We hit a rattling super accumulation of objects and functions that are exclusive necessary for limited pages that deal the aforementioned “layout”, and this allows us to call the scripts right (in the HEAD tag, as anti to including playscript references within the embody of the page) and cleanly. We ingest this duty in union with a “require” duty to playscript dependencies crapper be shown cleanly.

A playscript dockhand also entireness rattling nicely when utilised in union with form-based playscript loading, which is a framework we ingest to declaratively meaning playscript objects and bond them to HTML forms, as substantially as transfer in server-side variables. I module handle this in a follow-up article.

June 6th, 2008

GOOGLE ANALYTICS AFTER ONLOAD AND DOCUMENT.WRITE FOR XHTML

I saw digit articles that were both hunting at kindred issues.

Firstly, Pete Higgins has looked at the fact that Google Analytics is ordinarily unexploded via program playscript tags which drive the rest of the covering to move and created a ultimate cloak that changes things.

We hit every seen the verify tale: “waiting for google-analytics.com … “.

This is commonly before the embody attach is closed, which causes [at least] Dojo’s addOnLoad() duty to move until after ga.js has been loaded, and executed. I attending it most on the SitePen Dojo QuickStart guide. The full pass is dispatched as legal HTML and CSS, then enhanced to fortuity field sections into a bespoken tabbed view, with ultimate navigation. Unfortunately, every the cipher to do that is separate from within an addOnLoad function, and my slummy pitiful ethernets here in river attain ga.js verify upwardly of fivesome seconds to load. Long news short, sometimes I’m presented with a filthy blow of performance as the guidance is added, and the random chapters go hidden.

I definite it was a innocuous look I could meet attach a playscript attach to my nous element, and separate that onLoad, allowing the rest of the cipher to fulfil as presently as the Dom was ready, disregarding of Google existence ready.

He affixed in the cipher (with his hornlike coded agent…. modify that):

JAVASCRIPT:

  1.  
  2. dojo.provide(“dojox.analytics.ga”);
  3. dojo.mixin(dojox.analytics.ga, {
  4.         // _acct: String
  5.         //            your GA urchin tracker statement numbers.
  6.         _acct: dojo.config.urchin || “”,
  7.  
  8.         // _loadInterval: Integer
  9.         //           time in ms to move between checking again
  10.         _loadInterval: 420,
  11.  
  12.         _loadGA: function(){
  13.                 // summary: alluviation the ga.js enter and begin formatting process
  14.                 var gaHost = (“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”;
  15.                 var s = dojo.doc.createElement(’script’);
  16.                 s.src = gaHost + “google-analytics.com/ga.js”;
  17.                 dojo.doc.getElementsByTagName(“head”)[0].appendChild(s);
  18.                 setTimeout(dojo.hitch(this, “_checkGA”), this._loadInterval);
  19.         },
  20.  
  21.         _checkGA: function(){
  22.                 // summary: inspire the orbicular _gat uncertain Google defines.
  23.                 //           if it exists, separate _gotGA, otherwise, do added interval
  24.                 setTimeout(dojo.hitch(this, window[‘_gat’] ? “_gotGA” : “_checkGA”), this._loadInterval);
  25.         },
  26.  
  27.         _gotGA: function(){
  28.                 // summary: set the tracker, we’ve got ga.js loaded
  29.                 var ga = this._tracker = dojo.hitch(_gat, “_getTracker”, this._acct)();
  30.                 ga._initData();
  31.                 ga._trackPageview();
  32.                 this.GAonLoad.apply(this, arguments);
  33.         },
  34.  
  35.         GAonLoad: function(){
  36.                 // record duty to blast when urchin is complete
  37.                 // you also hit admittance in this duty to this._tracker, which is the
  38.                 // stem tracker happening you titled _initData() on
  39.         }
  40.  
  41. });
  42.  
  43. // move it every up after embody is ready:
  44. dojo.addOnLoad(dojox.analytics.ga,“_loadGA”);
  45.  

This module be in Dojo itself soon, so you module be healthy too:

JAVASCRIPT:

  1.  
  2. var pagetracker = new dojox.analytics.Urchin({ ua: “UA-123456-7″ });
  3. pagetracker.trackPageView(“/ajaxy-notification”);
  4.  

Secondly, lensman Ruter noted the another difficulty where Google AdSense and the AJAX Libraries API are using document.write() to inline playscript tags. In the time Evangelist Resig wrote a lowercase cloak to attain document.write to DOM impact instead. lensman builds on this work:

My solution, however, has a pair advantages as I wager it. First, his resolution uses whatever lawful countenance hacks to endeavor to attain the HTML markup well-formed sufficiency for the browser’s XML parser, but as he notes, it is not rattling robust. Secondly, John’s resolution relies on innerHTML which causes it to completely change in Safari 2 (although this feat also fails for an uncharted reason). I’m disagreeable a assorted approach. Instead of using innerHTML, this feat of document.write() parses the progress discussion of HTML markup into DOM nodes; if the DOM has not been completely unexploded yet, it appends these DOM nodes to the writing directly after the requesting playscript element; otherwise, it appends the parsed nodes to the modify of the body.

I’ve merged Evangelist Resig’s possess HTML Parser (via Erik Arvidsson), but I’ve prefabricated a pair key modifications to attain it endeavor pleasant with document.write(). I overturned HTMLParser into a collection with member properties in visit to spend the modify land of the parser after every of the pilot has been processed.

To this collection I added a parse(moreHTML) method which allows added markup to be passed into the parser for direction so that it crapper move parsing from where it had ended from the preceding buffer. And by removing the terminal parseEndTag() lucre call (for document.write() is anything but clean), it then became doable for binary document.write() calls to be prefabricated with arguments consisting of cut up HTML fragments same meet a move attach or modify tag, which is just what AdSense does and is a ordinary practice of the method.

Check discover the
full maker code.