<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -151,11 +151,11 @@ Object.extend(Event, (function() {
   function getEventID(element) {
     // Event ID is stored as the 0th index in a one-item array so that it
     // won't get copied to a new node when cloneNode is called.
+    if (element === window) return 1;
     if (element._prototypeEventID) return element._prototypeEventID[0];
-    arguments.callee.id = arguments.callee.id || 1;
-    
-    return element._prototypeEventID = [++arguments.callee.id];
+    return element._prototypeEventID = [arguments.callee.id++];
   }
+  getEventID.id = 2;
   
   function getDOMEventName(eventName) {
     if (eventName &amp;&amp; eventName.include(':')) return &quot;dataavailable&quot;;
@@ -166,6 +166,17 @@ Object.extend(Event, (function() {
     return cache[id] = cache[id] || { };
   }
   
+  function addEventDispatcher(element, eventName, dispatchWrapper) {
+    var wrappers = getWrappersForEventName(getEventID(element), eventName);
+    if (!wrappers.dispatcher) {
+      wrappers.dispatcher = function(event) {
+        wrappers.invoke('call', null, event);
+      };
+      if(dispatchWrapper) wrappers.dispatcher = wrappers.dispatcher.wrap(dispatchWrapper);
+      element.attachEvent(&quot;on&quot; + getDOMEventName(eventName), wrappers.dispatcher);
+    }
+  }
+  
   function getWrappersForEventName(id, eventName) {
     var c = getCacheForID(id);
     return c[eventName] = c[eventName] || [];
@@ -203,7 +214,9 @@ Object.extend(Event, (function() {
   function destroyWrapper(id, eventName, handler) {
     var c = getCacheForID(id);
     if (!c[eventName]) return false;
+    var d = c[eventName].dispatcher;
     c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+    c[eventName].dispatcher = d;
   }
   
   // Loop through all elements and remove all handlers on page unload. IE
@@ -237,13 +250,32 @@ Object.extend(Event, (function() {
     // IE also doesn't fire the unload event if the page is navigated away
     // from before it's done loading. Workaround adapted from
     // http://blog.moxiecode.com/2008/04/08/unload-event-never-fires-in-ie/.
-    window.attachEvent(&quot;onbeforeunload&quot;, onBeforeUnload);        
+    window.attachEvent(&quot;onbeforeunload&quot;, onBeforeUnload);
+    
+    // Ensure window onload is fired after &quot;dom:loaded&quot;
+    addEventDispatcher(window, 'load', function(proceed, event) {
+    	if(document.loaded){
+    	  proceed(event);
+    	} else {
+    	  arguments.callee.defer(event);
+    	}
+    });
+    
+    // Ensure window onresize is fired only once per resize
+    addEventDispatcher(window, 'resize', function(proceed, event) {
+      var callee = arguments.callee, dimensions = document.viewport.getDimensions();
+      if (dimensions.width != callee.prevWidth || dimensions.height != callee.prevHeight){
+        callee.prevWidth  = dimensions.width;
+        callee.prevHeight = dimensions.height;
+        proceed(event);
+      }
+    });
   }
   
   // Safari has a dummy event handler on page unload so that it won't
   // use its bfcache. Safari &lt;= 3.1 has an issue with restoring the &quot;document&quot;
   // object when page is returned to via the back button using its bfcache.
-  if (Prototype.Browser.WebKit) {
+  else if (Prototype.Browser.WebKit) {
     window.addEventListener('unload', Prototype.emptyFunction, false);
   }
     
@@ -258,7 +290,7 @@ Object.extend(Event, (function() {
       if (element.addEventListener) {
         element.addEventListener(name, wrapper, false);
       } else {
-        element.attachEvent(&quot;on&quot; + name, wrapper);
+        addEventDispatcher(element, eventName);
       }
       
       return element;
@@ -287,12 +319,16 @@ Object.extend(Event, (function() {
       
       if (element.removeEventListener) {
         element.removeEventListener(name, wrapper, false);
+        destroyWrapper(id, eventName, handler); 
       } else {
-        element.detachEvent(&quot;on&quot; + name, wrapper);
+        destroyWrapper(id, eventName, handler);
+        var wrappers = getWrappersForEventName(id, eventName); 
+        if (!wrappers.length) { 
+          element.detachEvent(&quot;on&quot; + name, wrappers.dispatcher); 
+          wrappers.dispatcher = null; 
+        } 
       }
       
-      destroyWrapper(id, eventName, handler);
-      
       return element;
     },
   
@@ -341,7 +377,7 @@ Object.extend(document, {
 
 (function() {
   /* Support for the DOMContentLoaded event is based on work by Dan Webb, 
-     Matthias Miller, Dean Edwards and John Resig. */
+     Matthias Miller, Dean Edwards, John Resig and Diego Perini. */
 
   var timer;
   
@@ -353,26 +389,41 @@ Object.extend(document, {
   }
   
   if (document.addEventListener) {
-    if (Prototype.Browser.WebKit) {
-      timer = window.setInterval(function() {
-        if (/loaded|complete/.test(document.readyState))
-          fireContentLoadedEvent();
-      }, 0);
-      
-      Event.observe(window, &quot;load&quot;, fireContentLoadedEvent);
-      
-    } else {
-      document.addEventListener(&quot;DOMContentLoaded&quot;, 
-        fireContentLoadedEvent, false);
-    }
+    document.addEventListener(&quot;DOMContentLoaded&quot;, function() {
+      // Ensure all stylesheets are loaded, solves Opera issue
+      if (Prototype.Browser.Opera &amp;&amp; 
+          $A(document.styleSheets).any(function(s) { return s.disabled }))
+        return arguments.callee.defer();
+      fireContentLoadedEvent();
+    }, false);
     
   } else {
-    document.write(&quot;&lt;script id=__onDOMContentLoaded defer src=//:&gt;&lt;\/script&gt;&quot;);
-    $(&quot;__onDOMContentLoaded&quot;).onreadystatechange = function() { 
-      if (this.readyState == &quot;complete&quot;) {
-        this.onreadystatechange = null; 
+    document.attachEvent(&quot;onreadystatechange&quot;, function() {
+      if (document.readyState == &quot;complete&quot;) {
+        document.detachEvent(&quot;onreadystatechange&quot;, arguments.callee);
         fireContentLoadedEvent();
       }
-    }; 
+    });
+    
+    if (window == top) {
+      timer = setInterval(function() {
+        try {
+          document.documentElement.doScroll(&quot;left&quot;);
+        } catch(e) { return }
+        fireContentLoadedEvent();
+      }, 10);
+    }
+  }
+  
+  // Only WebKit nightly builds support DOMContentLoaded
+  if (Prototype.Browser.WebKit) {
+    timer = setInterval(function() {
+      if (/loaded|complete/.test(document.readyState) &amp;&amp;
+          document.styleSheets.length == $$('style, link[rel=&quot;stylesheet&quot;]').length)
+        fireContentLoadedEvent();
+    }, 10);
   }
+  
+  // Worst case fallback... 
+  Event.observe(window, &quot;load&quot;, fireContentLoadedEvent); 
 })();</diff>
      <filename>src/event.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>c5f71a6e391fe647d81b4a4fdbcf54b64fbc88a3</id>
    </parent>
  </parents>
  <author>
    <name>jdalton</name>
    <email>john.david.dalton@gmail.com</email>
  </author>
  <url>http://github.com/sstephenson/prototype/commit/1cd1075e81ffb29e53bfa52bb256f36a958a0b92</url>
  <id>1cd1075e81ffb29e53bfa52bb256f36a958a0b92</id>
  <committed-date>2008-05-19T13:25:54-07:00</committed-date>
  <authored-date>2008-05-06T19:12:05-07:00</authored-date>
  <message>Add specific check for opera before the stylesheet disabled check in the dom:loaded detection.</message>
  <tree>5b564656eb0aebfd5032c1edb23328f3a008f4e2</tree>
  <committer>
    <name>Andrew Dupont</name>
    <email>prototype@andrewdupont.net</email>
  </committer>
</commit>
