2012-03-29 18:19:41 -05:00
|
|
|
/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */
|
2012-03-29 00:26:01 -05:00
|
|
|
|
|
|
|
( function () {
|
|
|
|
|
|
|
|
/*global window, document, Element, HTMLDocument */
|
|
|
|
/*jshint strict: false */
|
|
|
|
|
|
|
|
var doc = document;
|
|
|
|
|
|
|
|
// Add JS hook
|
|
|
|
window.ie = 8;
|
|
|
|
|
|
|
|
// Add defaultView property to document
|
|
|
|
doc.defaultView = window;
|
|
|
|
|
|
|
|
// Fake W3C events support
|
|
|
|
var translate = {
|
|
|
|
focus: 'focusin',
|
|
|
|
blur: 'focusout'
|
|
|
|
};
|
|
|
|
|
|
|
|
var returnTrue = function () { return true; };
|
|
|
|
var returnFalse = function () { return false; };
|
|
|
|
|
|
|
|
var toCopy = 'altKey ctrlKey metaKey shiftKey clientX clientY charCode keyCode'.split( ' ' );
|
|
|
|
|
|
|
|
var DOMEvent = function ( event ) {
|
|
|
|
var type = event.type,
|
|
|
|
doc = document,
|
|
|
|
target = event.srcElement || doc,
|
|
|
|
html = ( target.ownerDocument || doc ).documentElement,
|
|
|
|
l = toCopy.length,
|
|
|
|
property;
|
|
|
|
|
|
|
|
while ( l-- ) {
|
|
|
|
property = toCopy[l];
|
|
|
|
this[ property ] = event[ property ];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( type === 'propertychange' ) {
|
|
|
|
type = ( target.nodeName === 'INPUT' &&
|
|
|
|
target.type !== 'text' && target.type !== 'password' ) ?
|
|
|
|
'change' : 'input';
|
|
|
|
}
|
|
|
|
|
|
|
|
this.type = Object.keyOf( translate, type ) || type;
|
|
|
|
this.target = target;
|
|
|
|
this.pageX = event.clientX + html.scrollLeft;
|
|
|
|
this.pageY = event.clientY + html.scrollTop;
|
|
|
|
|
|
|
|
if ( event.button ) {
|
|
|
|
this.button = ( event.button & 4 ? 1 :
|
|
|
|
( event.button & 2 ? 2 : 0 ) );
|
|
|
|
this.which = this.button + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.relatedTarget = event.fromElement === target ?
|
|
|
|
event.toElement : event.fromElement;
|
|
|
|
this._event = event;
|
|
|
|
};
|
|
|
|
|
|
|
|
DOMEvent.prototype = {
|
|
|
|
constructor: DOMEvent,
|
|
|
|
isEvent: true,
|
|
|
|
preventDefault: function () {
|
|
|
|
this.isDefaultPrevented = returnTrue;
|
|
|
|
this._event.returnValue = false;
|
|
|
|
},
|
|
|
|
stopPropagation: function () {
|
|
|
|
this.isPropagationStopped = returnTrue;
|
|
|
|
this._event.cancelBubble = true;
|
|
|
|
},
|
|
|
|
isDefaultPrevented: returnFalse,
|
|
|
|
isPropagationStopped: returnFalse
|
|
|
|
};
|
|
|
|
|
|
|
|
// Add W3C event add/remove methods to elements and document.
|
|
|
|
[ doc, Element.prototype ].forEach(
|
|
|
|
function ( dom ) {
|
|
|
|
dom.addEventListener = function ( type, handler, capture ) {
|
|
|
|
var fn = handler._ie_handleEvent || ( handler._ie_handleEvent =
|
|
|
|
function () {
|
|
|
|
var event = new DOMEvent( window.event );
|
|
|
|
if ( typeof handler === 'object' ) {
|
|
|
|
handler.handleEvent( event );
|
|
|
|
} else {
|
|
|
|
handler.call( this, event );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
),
|
|
|
|
node = /paste|cut/.test( type ) ? this.body || this : this;
|
|
|
|
|
|
|
|
handler._ie_registeredCount = ( handler._ie_registeredCount || 0 ) + 1;
|
|
|
|
|
|
|
|
node.attachEvent( 'on' + ( translate[ type ] || type ), fn );
|
|
|
|
};
|
|
|
|
dom.addEventListener.isFake = true;
|
|
|
|
|
|
|
|
dom.removeEventListener = function ( type, handler, capture ) {
|
|
|
|
var fn = handler._ie_handleEvent,
|
|
|
|
node = /paste|cut/.test( type ) ? this.body || this : this;
|
|
|
|
if ( !( handler._ie_registeredCount -= 1 ) ) {
|
|
|
|
delete handler._ie_handleEvent;
|
|
|
|
}
|
|
|
|
if ( fn ) {
|
|
|
|
node.detachEvent( 'on' + ( translate[ type ] || type ), fn );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
dom.removeEventListener.isFake = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
// The events that we normally attach to the window object, IE8 wants on the
|
|
|
|
// body.
|
|
|
|
doc.defaultView.addEventListener = function ( type, handler, capture ) {
|
|
|
|
return doc.addEventListener( type, handler, capture );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Add textContent property to elements.
|
|
|
|
Object.defineProperty( Element.prototype, 'textContent', {
|
|
|
|
get: function () {
|
|
|
|
return this.innerText;
|
|
|
|
},
|
|
|
|
|
|
|
|
set: function ( text ) {
|
|
|
|
this.innerText = text;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Add compareDocumentPosition method to elements.
|
|
|
|
Element.prototype.compareDocumentPosition = function ( b ) {
|
|
|
|
if ( b.nodeType !== 1 ) { b = b.parentNode; }
|
|
|
|
var a = this,
|
|
|
|
different = ( a !== b ),
|
|
|
|
aIndex = a.sourceIndex,
|
|
|
|
bIndex = b.sourceIndex;
|
|
|
|
|
|
|
|
return ( different && a.contains( b ) ? 16 : 0 ) +
|
|
|
|
( different && b.contains( a ) ? 8 : 0 ) +
|
|
|
|
( aIndex < bIndex ? 4 : 0 ) +
|
|
|
|
( bIndex < aIndex ? 2 : 0 );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Add normalize method to document fragments
|
|
|
|
HTMLDocument.prototype.normalize = function () {
|
|
|
|
var children = this.childNodes,
|
|
|
|
l = children.length,
|
|
|
|
child;
|
|
|
|
|
|
|
|
while ( l-- ) {
|
|
|
|
child = children[l];
|
|
|
|
if ( child.nodeType === 1 ) {
|
|
|
|
child.normalize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-08-06 22:36:05 -05:00
|
|
|
}() );
|