Stefan Hayden

Shift + Ctrl + Alt + S
Archive for the 'resources' Category

yarg. why is this so hard?

  1. Start > type “regedit” > hit enter
  2. go to HKEY_LOCAL_MACHINE\SOFTWARE\Classes\mailto\shell\open\command\
  3. Edit (default) to “C:\Users\*username*\AppData\Local\Google\Chrome\Application\chrome.exe” https://mail.google.com/mail?extsrc=mailto&url=%1
  4. make sure to replace *username* with your username

Took me two years to find it but go to your nearest ssh app and do a quick “vimtutor“. It’s the best tutorial I have found because you learn by doing not by reading and memorizing.

Update: jdalton has what looks like a great improvement on my attempt below. Read below to learn about the problem but look at jdalton’s script to see what is now the current best way to implement a solution.

Update (August 5th, 2008): There was an update to the JavaScript below to better handle IE firing off the ready state.

Warning!: Due to a Prototype bug This code is not reliable in any version of IE. This bug is expected to be fixed in Prototype 1.6.0.3.


So the YUI blog had a great post on how javascript blocks downloads and makes the page take longer to load. This is because any JS file can modify the DOM and so the DOM can’t be ready until all JS files have loaded.

Flugpo uses Prototype and not YUI and so to get the speed benefits I needed to build my own Bells and whistles. The problem is that once you load the JS files asynchronously any onDOMReady function will fire before all the JS files download. This is a problem for any inline function calls that have dependencies on other JS files.

Using the Prototype based onDOMReady extension I have created an onJSReady function that checks that all JS files have been loaded. The function needs to know 2 things. How many JS files there are and how many have currently been loaded. When those two number match the even fires and runs any code that is waiting.


/**
 * A modified version of Stefan Hayden's onJSReady Prototype plugin. 
 * http://www.stefanhayden.com/blog/2008/07/29/javascript-event-onjsready-fires-when-all-js-files-have-loaded/
 *
 * @author John-David Dalton 
 * @usage
 *   Prototype.include(['test1.js','test2.js','test3.js']); // array
 *   Prototype.include('test1.js', 'test2.js', 'test3.js'); // separate arguments OR
 *   Prototype.include('test1.js,test2.js,test3.js');       // comma separated string OR 
 *
 *   document.observe('scripts:loaded', function(){ dependent_on_external_js() });
 */
Prototype.include = Object.extend(
  function() {
    var callee = arguments.callee,
     head = document.getElementsByTagName('HEAD')[0],
     args = Array.prototype.slice.call(arguments, 0);

    args._each(function(files) {
      if (Object.isString(files))
        files = files.split(',');
      
      callee.total += files.length;
      files._each(function(file) {
        head.appendChild(
          new Element('script', { type: 'text/javascript', src: file.strip() })
        )
        .observe('readystatechange', function () {
          if (!this.loaded && /^(loaded|complete)$/.test(this.readyState)) {
            this.loaded = true;
            callee.downloaded++;
          }
        })
        .observe('load', function () {
          if (this.loaded) return;
          this.loaded = true;
          callee.downloaded++;
        }); // end observers
      }); // end files _each 
    }); // end args _each
  }, 
  {
    total: 0,
    downloaded: 0
  }
);

(function() {
  var timer;
  function ready() {
    if (arguments.callee.done) return;
    clearInterval(timer);
    arguments.callee.done = true;
    document.fire('scripts:loaded');
  }
  
  timer = setInterval(function() {
    var i = Prototype.include;
    if (i.total && i.downloaded === i.total) ready();
  }, 10);
})();


This is old... ignore this.
window.Total_JS_Files;
window.Downloaded_JS_Files = 0;

function include_js(files) {
	var js=new Array();
	window.Total_JS_Files = files.length;
	
	for(var i=0; i < files.length; i++) { 
		
	    var html_doc = document.getElementsByTagName('head')[0];
	    js[i] = document.createElement('script');
	    js[i].setAttribute('type', 'text/javascript');
	    js[i].setAttribute('src', files[i]);
	    html_doc.appendChild(js[i]);
	
	    js[i].onreadystatechange = function () {
	        if (js[i].readyState == 'complete') {
	            //alert('JS onreadystate fired ');
	            window.Downloaded_JS_Files += 1;
	        }
	    }
	
	    js[i].onload = function () {
	        //alert('JS onload fired ');
	            window.Downloaded_JS_Files += 1;
	    }
    }
    return false;
}//include_js


Object.extend(Event, {
  timeout : function() {
	alert('asd');
  },
  jsReady : function() {
  
    if (arguments.callee.done) {return;}
    arguments.callee.done = true;
		
	Event._NreadyCallbacks.each(function(f) { f(); });
	Event._NreadyCallbacks = null;
		
  },
  onJSReady : function(f) {
    if (!this._NreadyCallbacks) {
      var jsReady = this.jsReady;
      
      if (jsReady.done) {return f();} 
        
		function jsTest() {
			if(window.Downloaded_JS_Files == window.Total_JS_Files) { 
				//setTimeout(jsReady,1);
				jsReady();
			}
			Event._Ntimer = setTimeout(jsTest,1); 
		}
		Event._Ntimer = setTimeout(jsTest,10); 
        
        //Event.observe(window, 'load', jsReady);
        Event._NreadyCallbacks =  [];
    }
    Event._NreadyCallbacks.push(f);
  }
});
  

To implement this the only JS that needs to load is prototype and these two functions above. Then you just need to load the URLs for the JS files and fire off the include_js function.


var js_paths = new Array;
js_paths[js_paths.length] = '/path/to/js/one.js';
js_paths[js_paths.length] = '/path/to/js/two.js';
js_paths[js_paths.length] = '/path/to/js/three.js';

include_js(js_paths);
Prototype.include(js_paths);

Once all of the JS files have loaded then just like onDOMReady the onJSReady code will fire.


Event.onJSReady(function () { dependent_on_external_js(); });
 document.observe('scripts:loaded', function(){ dependent_on_external_js() });
 

Act 1 of Dr. Horrible’s Sing-Along Blog is out and it’s awesome. Totally buying the DVD.

Copilot, the app that lets you easily remote control another’s computer for user support, is now 100% free on the weekends. And they have a generous definition of weekend. 8pm EST (GMT-5) Friday night to 2am EST Monday morning.

Currently I’m in love with the idea behind Jaxer which is a server that lets you run javascript both on the client and server. Not sure when or if I’ll get a chance to play with this but the screencasts have me enamored.

There seems to be a lot of good articles recently about how to raise smart kids. About how telling them they are smart is different them telling them the amount of effort they put in makes them smart. To a point I definitely suffered from this as a kid and I still struggle with it today. It’s hard to relearn to just put on foot in front of the other.

Intense Debate seems like a cool new service. You can install it on your site as a commenting system to replace the default system in popular systems like blogger and wordpress. It seems to integrate pretty well with the ability to import and export comments and just a lot of work was put in to not seem like a silo stealing your information.

The functionality seems a little over kill for small site like mine but I do like the benefit of knowing more about who is leaving comments. I can’t see my self being an early adopter but if this catches on and tons of people use it I would not be opposed to setting it up.

I’ve been ignoring openid for a while. For no good reason really. Yesterday I turned my site in to my own openid. With just a little html I can now use my url to log in to any openid website. everyone should do this.

Want to be an expert on databases but don’t know where to start? Introduction to Databases for the Web is a really great article with very plain language that will teach any one the basics.

OMG… photoshop can auto crop and straighten photos scanned in on a flat bed scanner! I will not forget this.

Wikipedia: List of Web Page Layout Engines

Really great, small, fast PDF viewer: Sumatra PDF

Very cool RegEx tool. Expression in top text in the second textarea and results appear on the bottom. They even have a build in quick reference sheet. Slowly I’m getting a good handle on how regex really works.

~1,167 die trying to immigrate to Spain illegally. Spain owns two tiny cities on the coast of northern Morocco, Ceuta and Melilla, which are also popular way for Subsaharans to illegally enter the EU. The EU funded ~$70 million to build some very hardcore fences. Which is sad but it’s also nice to see America’s not the meanest when it comes to immigration.