0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 15:23:29 -05:00
Squire/source/ie8dom.js
2012-04-02 15:55:33 +10:00

157 lines
No EOL
4.5 KiB
JavaScript

/* Copyright © 2011-2012 by Neil Jenkins. Licensed under the MIT license. */
( 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();
}
}
};
}() );