Another abandoned server code base... this is kind of an ancestor of taskrambler.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

728 lines
14 KiB

/*
# Movable Type (r) Open Source (C) 2003-2010 Six Apart, Ltd.
# This program is distributed under the terms of the
# GNU General Public License, version 2.
#
# $Id: tc.js 3455 2009-02-23 02:29:31Z auno $
*/
/*
--------------------------------------------------------------------------------
TC
core utility class
--------------------------------------------------------------------------------
*/
/* dummy constructor */
TC = function()
{
}
/* static variables */
TC.matchShortWords = /\b(\S*)\b/gi;
TC.matchLeadingSpace = /^\s+/;
TC.matchTrailingSpace = /\s+$/;
TC.matchSpace = /\s+/g;
/* utility methods */
TC.defined = function( x )
{
try
{
if( typeof x != "undefined" )
return true;
}
catch( e ) {}
return false;
}
TC.inspect = function( x )
{
var t = "";
for( var i in x )
t += i + " = " + x[ i ] + "<br />";
return t;
}
TC.elementOrId = function( element )
{
if( !element )
return null;
if( typeof element == "string" )
element = document.getElementById( element );
return element;
}
TC.applyFunction = function( elements, func )
{
if( !elements )
return;
for( var i in elements )
{
var element = elements[ i ];
if( !element )
continue;
func( element );
}
}
TC.attachWindowEvent = function( eventName, func )
{
var onEventName = 'on' + eventName;
var old = window[onEventName];
if( typeof old != 'function' )
window[onEventName] = func;
else
{
window[onEventName] = function( evt )
{
old( evt );
return func( evt );
};
}
}
TC.attachLoadEvent = function( func )
{
TC.attachWindowEvent('load', func);
}
TC.attachBeforeUnloadEvent = function( func )
{
var old = window.onbeforeunload;
if( typeof old != 'function' )
window.onbeforeunload = func;
else
{
window.onbeforeunload = function( evt )
{
old( evt );
return func( evt );
};
}
}
TC.attachDocumentEvent = function( element, eventName, func, recurse )
{
if( !element || !element.document )
return;
var doc = element.document;
TC.attachEvent( doc, eventName, func );
if( !recurse )
return;
// get frames
var elements = [];
if( doc.frames )
{
for( var i in doc.frames );
elements[ elements.length ] = doc.frames[ i ];
}
// get iframes
var iframes = doc.getElementsByTagName( "iframe" ) || [];
for( var i in iframes )
elements[ elements.length ] = iframes[ i ];
// attach event handler
for( var i in elements )
{
if( !elements[ i ] || !elements[ i ].contentWindow )
continue;
TC.attachDocumentEvent( elements[ i ].contentWindow, eventName, func, recurse );
}
}
TC.attachEvent = function( element, eventName, func )
{
element = TC.elementOrId( element );
if( !element )
return;
if( element.addEventListener )
element.addEventListener( eventName, func, true );
else if( element.attachEvent )
element.attachEvent( "on" + eventName, func );
else
element[ "on" + eventName ] = func;
}
TC.detachEvent = function( element, eventName, func )
{
element = TC.elementOrId( element );
if( !element )
return;
if( element.removeEventListener )
element.removeEventListener( eventName, func, true );
else if( element.detachEvent )
element.detachEvent( "on" + eventName, func );
else
element[ "on" + eventName ] = null;
}
TC.stopEvent = function( evt )
{
evt = evt || event;
// moz
if( evt.preventDefault )
evt.preventDefault();
if( evt.stopPropagation )
evt.stopPropagation();
// ie
if( TC.defined( evt.returnValue ) )
{
evt.cancelBubble = true;
evt.returnValue = false;
}
return false;
}
TC.allowTabs = function( element )
{
element = TC.elementOrId( element );
TC.attachEvent( element, "keypress", TC.allowTabs.keyPress );
TC.attachEvent( element, "keydown", TC.allowTabs.keyDown );
}
TC.allowTabs.keyPress = function( evt )
{
evt = evt || event;
var element = evt.target || evt.srcElement;
if( evt.keyCode == 9 )
{
return TC.stopEvent( evt );
}
return true;
}
TC.allowTabs.keyDown = function( evt )
{
evt = evt || event;
var element = evt.target || evt.srcElement;
if( evt.keyCode == 9 )
{
TC.setSelectionValue( element, "\t" );
return false;
}
return true;
}
TC.allowHover = function( element )
{
element = TC.elementOrId( element );
TC.attachEvent( element, "mouseover", TC.allowHover.mouseOver );
TC.attachEvent( element, "mouseout", TC.allowHover.mouseOut );
}
TC.allowHover.mouseOver = function( evt )
{
evt = evt || event;
var element = evt.target || evt.srcElement;
TC.addClassName( element, "hover" );
}
TC.allowHover.mouseOut = function( evt )
{
evt = evt || event;
var element = evt.target || evt.srcElement;
TC.removeClassName( element, "hover" );
}
/* text and selection related methods */
TC.getSelection = function( element )
{
var doc = TC.getOwnerDocument( element );
var win = TC.getOwnerWindow( doc );
if( win.getSelection )
return win.getSelection();
else if( doc.getSelection )
return doc.getSelection();
else if( doc.selection )
return doc.selection;
return null;
}
TC.getCaretPosition = function( element )
{
var doc = TC.getOwnerDocument( element );
if (doc.selection) {
var range = doc.selection.createRange();
var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
if (!isCollapsed)
range.collapse(true);
var b = range.getBookmark();
return b.charCodeAt(2) - 2;
} else if (element.selectionStart != 'undefined') {
return element.selectionStart;
}
return null;
}
TC.setCaretPosition = function( element, pos )
{
if (element.createTextRange) {
var range = element.createTextRange();
range.collapse(true);
range.moveStart("character", pos);
range.select();
return true;
} else {
element.selectionStart = pos;
element.selectionEnd = pos;
return true;
}
return false;
}
TC.createRange = function( selection, element )
{
var doc = TC.getOwnerDocument( element );
if( selection && selection.getRangeAt )
return selection.getRangeAt( 0 );
else if( selection && selection.createRange )
return selection.createRange();
else if( doc.createRange )
return doc.createRange();
return null;
}
TC.extractElementText = function( element )
{
element = TC.elementOrId( element );
if( !element || element.nodeType == 8 ) // ignore html comments
return '';
var tagName = element.tagName ? element.tagName.toLowerCase() : '';
if( tagName == 'input' || tagName == 'textarea' )
return '';
var text = element.nodeValue != null ? element.nodeValue : '';
for( var i = 0; i < element.childNodes.length; i++ )
text += TC.extractElementText( element.childNodes[ i ] );
return text;
}
TC.setSelectionValue = function( element, value )
{
element = TC.elementOrId( element );
var scrollFromBottom = element.scrollHeight - element.scrollTop;
// msie
if( document.selection )
{
element.focus();
document.selection.createRange().text = value;
}
// mozilla
else
{
var length = element.textLength;
var start = element.selectionStart;
var end = element.selectionEnd;
element.value = element.value.substring( 0, start ) +
value + element.value.substring( end, length );
element.caretPos = start + length;
element.selectionStart = start + value.length;
element.selectionEnd = start + value.length;
}
element.scrollTop = element.scrollHeight - scrollFromBottom;
}
TC.normalizeWords = function( text )
{
text = text.toLowerCase();
var originalWords = text.match( matchShortWords );
var exists = new Array();
var words = new Array();
for( i = 0; i < originalWords.length; i++ )
{
if( exists[ originalWords[ i ] ] )
continue;
exists[ originalWords[ i ] ] = 1;
words[ words.length ] = originalWords[ i ];
}
words.sort();
return words;
}
/* dom methods */
TC.getOwnerDocument = function( element )
{
if( !element )
return document;
if( element.ownerDocument )
return element.ownerDocument;
if( element.getElementById )
return element
return document;
}
TC.getOwnerWindow = function( element )
{
if( !element )
return window;
// msie
if( element.parentWindow )
return element.parentWindow;
// mozilla
var doc = TC.getOwnerDocument( element );
if( doc && doc.defaultView )
return doc.defaultView;
return window;
}
TC.getElementsByTagAndClassName = function( tagName, className, root )
{
root = TC.elementOrId( root );
if( !root )
root = document;
var allElements = root.getElementsByTagName( tagName );
var elements = [];
for( var i = 0; i < allElements.length; i++ )
{
var element = allElements[ i ];
if( !element )
continue;
if( TC.hasClassName( element, className ) )
elements[ elements.length ] = element;
}
return elements;
}
TC.getElementsByClassName = function( className, root )
{
return TC.getElementsByTagAndClassName( "*", className, root );
}
TC.getParentByTagName = function( element, tagName )
{
tagName = tagName.toLowerCase();
var parent = element.parentNode;
while( parent )
{
if( parent.tagName && parent.tagName.toLowerCase() == tagName )
return parent;
parent = parent.parentNode;
}
return null;
}
TC.inlineDisplays =
{
"inline" : 1,
"inline-block" : 1
}
TC.isInlineNode = function( node )
{
/* text nodes are inline */
if( node.nodeType == 3 )
return true;
/* document nodes are non-inline */
if( node.nodeType == 9 )
return false;
/* all non-element nodes are inline */
if( node.nodeType != 1 )
return true;
/* br elements are not inline */
if( node.tagName && node.tagName.toLowerCase() == "br" )
return false;
/* examine the style property of the inline node */
var d = TC.getStyle( node, "display" );
if( TC.inlineDisplays[ d ] )
return true;
/* assume non-inline */
return false;
}
TC.getPreviousTextNode = function( node, inline )
{
var up = false;
while( node )
{
if( !up && node.lastChild )
{
node = node.lastChild; // down
up = false;
}
else if( node.previousSibling )
{
node = node.previousSibling; // left
up = false;
}
else if( node.parentNode )
{
node = node.parentNode; // up
up = true;
}
else
return null; // borked
if( node.nodeType == 3 )
return node;
if( inline && !TC.isInlineNode( node ) )
return null;
}
return null;
}
TC.getNextTextNode = function( node, inline )
{
var up = false;
while( node )
{
if( !up && node.firstChild )
{
node = node.firstChild; // down
up = false;
}
else if( node.nextSibling )
{
node = node.nextSibling; // right
up = false;
}
else if( node.parentNode )
{
node = node.parentNode; // up
up = true;
}
else
return null; // borked
if( node.nodeType == 3 )
return node;
if( inline && !TC.isInlineNode( node ) )
return null;
}
return null;
}
TC.setAttributes = function( element, attr )
{
element = TC.elementOrId( element );
if( !element || !attr )
return;
for( var a in attr )
element.setAttribute( a, attr[ a ] );
}
// this and the following classname functions honor w3c case-sensitive classnames
TC.hasClassName = function( element, className )
{
if( !element || !element.className || !className )
return false;
var classNames = element.className.split( TC.matchSpace );
for( var i = 0; i < classNames.length; i++ )
{
if( classNames[ i ] == className )
return true;
}
return false;
}
TC.getClassNames = function( e ) {
if( !e || !e.className )
return [];
return e.className.split( /\s+/g );
}
TC.addClassName = function( e, cn ) {
if( !e || !cn )
return false;
var cs = TC.getClassNames( e );
for( var i = 0; i < cs.length; i++ ) {
if( cs[ i ] == cn )
return true;
}
cs.push( cn );
e.className = cs.join( " " );
return false;
}
TC.removeClassName = function( e, cn ) {
var r = false;
if( !e || !e.className || !cn )
return r;
var cs = (e.className && e.className.length)
? e.className.split( /\s+/g )
: [];
var ncs = [];
/* support regex */
if( cn instanceof RegExp ) {
for( var i = 0; i < cs.length; i++ ) {
if ( cn.test( cs[ i ] ) ) {
r = true;
continue;
}
ncs.push( cs[ i ] );
}
} else {
for( var i = 0; i < cs.length; i++ ) {
if( cs[ i ] == cn ) {
r = true;
continue;
}
ncs.push( cs[ i ] );
}
}
if( r )
e.className = ncs.join( " " );
return r;
}
TC.getComputedStyle = function( e )
{
if( e.currentStyle )
return e.currentStyle;
var style = {};
var owner = TC.getOwnerDocument( e );
if( owner && owner.defaultView && owner.defaultView.getComputedStyle ) {
try {
style = owner.defaultView.getComputedStyle( e, null );
} catch( e ) {}
}
return style;
}
TC.getStyle = function( element, property )
{
element = TC.elementOrId( element );
var style;
if( window.getComputedStyle )
style = window.getComputedStyle( element, null ).getPropertyValue( property );
else if( element.currentStyle )
style = element.currentStyle[ property ];
return style;
}
TC.setStyle = function( element, style )
{
element = TC.elementOrId( element );
if( !element || !element.style || !style )
return;
for( var s in style )
element.style[ s ] = style[ s ];
}
TC.getAbsolutePosition = function( element )
{
element = TC.elementOrId( element );
var pos = { "left" : 0, "top" : 0 };
if( !element )
return pos;
while( element )
{
pos.left += element.offsetLeft;
pos.top += element.offsetTop;
element = element.offsetParent;
}
return pos;
}
TC.getAbsoluteCursorPosition = function( evt )
{
evt = evt || event;
// get basic position
var pos =
{
x: evt.clientX,
y: evt.clientY
};
// ie
if( document.documentElement && TC.defined( document.documentElement.scrollLeft ) )
{
pos.x += document.documentElement.scrollLeft;
pos.y += document.documentElement.scrollTop;
}
// safari
else if( TC.defined( window.scrollX ) )
{
pos.x += window.scrollX;
pos.y += window.scrollX;
}
// opera
else if( document.body && TC.defined( document.body.scrollLeft ) )
{
pos.x += document.body.scrollLeft;
pos.y += document.body.scrollTop;
}
return pos;
}
/* array methods */
TC.scramble = function( array )
{
var length = array.length;
for( var i = 0; i < length; i++ )
{
var a = Math.floor( Math.random() * length );
var b = Math.floor( Math.random() * length );
var temp = array[ a ];
array[ a ] = array[ b ];
array[ b ] = temp;
}
}