diff options
Diffstat (limited to 'autocomplete/js')
-rw-r--r-- | autocomplete/js/acdropdown.js | 1622 | ||||
-rw-r--r-- | autocomplete/js/getobject2.js | 126 | ||||
-rw-r--r-- | autocomplete/js/ieselect.js | 85 | ||||
-rw-r--r-- | autocomplete/js/modomevent3.js | 189 | ||||
-rw-r--r-- | autocomplete/js/modomext.js | 219 | ||||
-rw-r--r-- | autocomplete/js/modomt.js | 259 | ||||
-rw-r--r-- | autocomplete/js/shBrushJScript.js | 22 | ||||
-rw-r--r-- | autocomplete/js/shBrushXml.js | 61 | ||||
-rw-r--r-- | autocomplete/js/shCore.js | 589 | ||||
-rw-r--r-- | autocomplete/js/tabs2.js | 124 | ||||
-rw-r--r-- | autocomplete/js/xmlextras.js | 149 |
11 files changed, 3445 insertions, 0 deletions
diff --git a/autocomplete/js/acdropdown.js b/autocomplete/js/acdropdown.js new file mode 100644 index 0000000..c5ad240 --- /dev/null +++ b/autocomplete/js/acdropdown.js @@ -0,0 +1,1622 @@ +// +// This script was created +// by Mircho Mirev +// mo /mo@momche.net/ +// Copyright (c) 2004-2005 Mircho Mirev +// +// :: feel free to use it BUT +// :: if you want to use this code PLEASE send me a note +// :: and please keep this disclaimer intact +// + +function cAutocomplete( sInputId ) +{ + this.init( sInputId ) +} + +cAutocomplete.CS_NAME = 'Autocomplete component' +cAutocomplete.CS_OBJ_NAME = 'AC_COMPONENT' +cAutocomplete.CS_LIST_PREFIX = 'ACL_' +cAutocomplete.CS_BUTTON_PREFIX = 'ACB_' +cAutocomplete.CS_INPUT_PREFIX = 'AC_' +cAutocomplete.CS_HIDDEN_INPUT_PREFIX = 'ACH_' +cAutocomplete.CS_INPUT_CLASSNAME = 'dropdown' + +cAutocomplete.CB_AUTOINIT = true + +cAutocomplete.CB_AUTOCOMPLETE = false + +cAutocomplete.CB_FORCECORRECT = false + +//the separator when autocompleting multiple values +cAutocomplete.CB_MATCHSUBSTRING = false +cAutocomplete.CS_SEPARATOR = ',' + +//the separator of associative arrays +cAutocomplete.CS_ARRAY_SEPARATOR = ',' + +//match the input string only against the begining of the strings +//or anywhere in the string +cAutocomplete.CB_MATCHSTRINGBEGIN = true + +cAutocomplete.CN_OFFSET_TOP = 2 +cAutocomplete.CN_OFFSET_LEFT = -1 + +cAutocomplete.CN_LINE_HEIGHT = 19 +cAutocomplete.CN_NUMBER_OF_LINES = 10 +cAutocomplete.CN_HEIGHT_FIX = 2 + +cAutocomplete.CN_CLEAR_TIMEOUT = 300 +cAutocomplete.CN_SHOW_TIMEOUT = 400 +cAutocomplete.CN_REMOTE_SHOW_TIMEOUT = 1000 +cAutocomplete.CN_MARK_TIMEOUT = 400 + +cAutocomplete.hListDisplayed = null +cAutocomplete.nCount = 0 + +cAutocomplete.autoInit = function() +{ + var nI = 0 + var hACE = null + var sLangAtt + + for( nI = 0; nI < document.getElementsByTagName( 'INPUT' ).length; nI++ ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].type.toLowerCase() == 'text' ) + { + sLangAtt = document.getElementsByTagName( 'INPUT' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'INPUT' )[ nI ].id == null || document.getElementsByTagName( 'INPUT' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'INPUT' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'INPUT' )[ nI ].id ) + } + } + } + + var nTALength = document.getElementsByTagName( 'TEXTAREA' ).length + for( nI = 0; nI < nTALength; nI++ ) + { + sLangAtt = document.getElementsByTagName( 'TEXTAREA' )[ nI ].getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id == null || document.getElementsByTagName( 'TEXTAREA' )[ nI ].id.length == 0 ) + { + document.getElementsByTagName( 'TEXTAREA' )[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( document.getElementsByTagName( 'TEXTAREA' )[ nI ].id ) + } + } + + + var nSelectsLength = document.getElementsByTagName( 'SELECT' ).length + var aSelect = null + for( nI = 0; nI < nSelectsLength; nI++ ) + { + aSelect = document.getElementsByTagName( 'SELECT' )[ nI ] + sLangAtt = aSelect.getAttribute( 'acdropdown' ) + if( sLangAtt != null && sLangAtt.length > 0 ) + { + if( aSelect.id == null || aSelect.id.length == 0 ) + { + aSelect.id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount + } + hACE = new cAutocomplete( aSelect.id ) + nSelectsLength-- + nI-- + } + } +} + +if( cAutocomplete.CB_AUTOINIT ) +{ + if( window.attachEvent ) + { + window.attachEvent( 'onload', cAutocomplete.autoInit ) + } + else if( window.addEventListener ) + { + window.addEventListener( 'load', cAutocomplete.autoInit, false ) + } +} + +cAutocomplete.prototype.init = function( sInputId ) +{ + this.sInputId = sInputId + this.sListId = cAutocomplete.CS_LIST_PREFIX + sInputId + + this.sObjName = cAutocomplete.CS_OBJ_NAME + '_obj_' + (cAutocomplete.nCount++) + this.hObj = this.sObjName + + this.hActiveSelection = null + this.nSelectedItemIdx = -1 + + //the value of the input before the list is displayed + this.sLastActiveValue = '' + this.sActiveValue = '' + this.bListDisplayed = false + this.nItemsDisplayed = 0 + + //if I transform a select option or the supplied array is associative I create a hidden input + //with the name of the original input and replace the original input's name + this.bAssociative = false + this.sHiddenInputId = null + this.bHasButton = false + + //the actual data + this.aData = null + //the search array object + this.aSearchData = new Array() + this.bSorted = false + + //the length of the last matched typed string + this.nLastMatchLength = 0 + + this.bForceCorrect = cAutocomplete.CB_FORCECORRECT + var sForceCorrect = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_forcecorrect' ) + if( sForceCorrect != null && sForceCorrect.length > 0 ) + { + this.bForceCorrect = eval( sForceCorrect ) + } + + //match a only from the beginning or anywhere in the values + this.bMatchBegin = cAutocomplete.CB_MATCHSTRINGBEGIN + var sMatchBegin = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchbegin' ) + if( sMatchBegin != null && sMatchBegin.length > 0 ) + { + this.bMatchBegin = eval( sMatchBegin ) + } + //match substrings separated by cAutocomplete.CS_SEPARATOR + this.bMatchSubstring = cAutocomplete.CB_MATCHSUBSTRING + var sMatchSubstring = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_matchsubstring' ) + if( sMatchSubstring != null && sMatchSubstring.length > 0 ) + { + this.bMatchSubstring = true + } + + //autocomplete with the first option from the list + this.bAutoComplete = cAutocomplete.CB_AUTOCOMPLETE + this.bAutocompleted = false + var sAutoComplete = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_complete' ) + if( sAutoComplete != null && sAutoComplete.length > 0 ) + { + this.bAutoComplete = eval( sAutoComplete ) + } + //format function + this.formatOptions = null + var sFormatFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_format' ) + if( sFormatFunction != null && sFormatFunction.length > 0 ) + { + this.formatOptions = eval( sFormatFunction ) + } + //onselect callback function - get called when a new option is selected, either by changing the focus in the list by using the keyboard or by + //clicking on it with the mouse + this.onSelect = null + var sOnSelectFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_onselect' ) + if( sOnSelectFunction != null && sOnSelectFunction.length > 0 ) + { + this.onSelect = eval( sOnSelectFunction ) + } + + //onchange callback function - get called when a new option is selected by clicking on it or by pressing enter + //almost the same as onselect, but will get activated on + /* + this.onChange = null + var sOnSelectFunction = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_onselect' ) + if( sOnSelectFunction != null && sOnSelectFunction.length > 0 ) + { + this.onSelect = eval( sOnSelectFunction ) + } + */ + + //I assume that we always have the associative type + //you can turn it off only with the autocomplete_assoc=false attribute + this.bAssociative = true + var sAssociative = document.getElementById( this.sInputId ).getAttribute( 'autocomplete_assoc' ) + if( sAssociative != null && sAssociative.length > 0 ) + { + if( sAssociative == 'false' ) + { + this.bAssociative = false + } + } + + //if we have remote list then we postpone the list creation + if( this.getListArrayType() != 'url' ) + { + this.bRemoteList = false + } + else + { + this.bRemoteList = true + this.sListURL = this.getListURL() + this.hXMLHttp = XmlHttp.create() + } + this.initListArray() + this.initListContainer() + //this.createList() + this.initInput() + + eval( this.hObj + '= this' ) +} + +cAutocomplete.prototype.initInput = function() +{ + var hInput = document.getElementById( this.sInputId ) + hInput.hAutocomplete = this + var hContainer = document.getElementById( this.sListId ) + hContainer.hAutocomplete = this + + //any element ( and it's children ) with display:none have offset values of 0 ( in mozilla ) + var nWidth = hInput.offsetWidth + if( !nWidth || nWidth == 0 ) + { + //any element ( and it's children ) with display:none have offset values of 0 ( in mozilla ) + var hOWInput = hInput.cloneNode( true ) + hOWInput.style.position = 'absolute' + hOWInput.style.top = '-1000px' + document.body.appendChild( hOWInput ) + var nWidth = hOWInput.offsetWidth + document.body.removeChild( hOWInput ) + } + + var sInputName = hInput.name + var hForm = hInput.form + var bHasButton = false + var sHiddenValue = hInput.value + var sValue = hInput.type.toLowerCase() == 'text' ? hInput.value : '' + + var sHasButton = hInput.getAttribute( 'autocomplete_button' ) + if( sHasButton != null && sHasButton.length > 0 ) + { + bHasButton = true + } + + //if it is a select - I unconditionally add a button + if( hInput.type.toLowerCase() == 'select-one' ) + { + bHasButton = true + if( hInput.selectedIndex >= 0 ) + { + sHiddenValue = hInput.options[ hInput.selectedIndex ].value + sValue = hInput.options[ hInput.selectedIndex ].text + } + } + + //this is the case when the control is a transformed select or the list supplied is of the type - key,value not only values + if( hForm ) + { + var hHiddenInput = document.createElement( 'INPUT' ) + hHiddenInput.id = cAutocomplete.CS_HIDDEN_INPUT_PREFIX + this.sInputId + hHiddenInput.type = 'hidden' + hForm.appendChild( hHiddenInput ) + + if( this.bAssociative ) + { + hHiddenInput.name = sInputName + hInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hHiddenInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + + hHiddenInput.value = sHiddenValue + this.sHiddenInputId = hHiddenInput.id + } + + if( bHasButton ) + { + this.bHasButton = true + + var hInputContainer = document.createElement( 'DIV' ) + hInputContainer.className = 'acinputContainer' + hInputContainer.style.width = nWidth + + var hInputButton = document.createElement( 'INPUT' ) + hInputButton.id = cAutocomplete.CS_BUTTON_PREFIX + this.sInputId + hInputButton.type = 'button' + hInputButton.className = 'button' + hInputButton.tabIndex = hInput.tabIndex + 1 + hInputButton.hAutocomplete = this + + var hNewInput = document.createElement( 'INPUT' ) + if( this.bAssociative ) + { + hNewInput.name = cAutocomplete.CS_INPUT_PREFIX + sInputName + } + else + { + hNewInput.name = sInputName + } + + hNewInput.type = 'text' + hNewInput.value = sValue + hNewInput.style.width = nWidth-22 + hNewInput.className = cAutocomplete.CS_INPUT_CLASSNAME + hNewInput.tabIndex = hInput.tabIndex + hNewInput.hAutocomplete = this + + hInputContainer.appendChild( hNewInput ) + hInputContainer.appendChild( hInputButton ) + + hInput.parentNode.replaceChild( hInputContainer, hInput ) + + hNewInput.id = this.sInputId + hInput = hNewInput + } + + if( hInput.attachEvent ) + { + hInput.attachEvent( 'onkeyup', cAutocomplete.onInputKeyUp ) + hInput.attachEvent( 'onkeyup', cAutocomplete.saveCaretPosition ) + hInput.attachEvent( 'onkeydown', cAutocomplete.onInputKeyDown ) + hInput.attachEvent( 'onblur', cAutocomplete.onInputBlur ) + hInput.attachEvent( 'onfocus', cAutocomplete.onInputFocus ) + + if( hInputButton ) + { + hInputButton.attachEvent( 'onclick', cAutocomplete.onButtonClick ) + } + } + else if( hInput.addEventListener ) + { + hInput.addEventListener( 'keyup', cAutocomplete.onInputKeyUp, false ) + hInput.addEventListener( 'keyup', cAutocomplete.saveCaretPosition, false ) + hInput.addEventListener( 'keydown', cAutocomplete.onInputKeyDown, false ) + hInput.addEventListener( 'keypress', cAutocomplete.onInputKeyPress, false ) + hInput.addEventListener( 'blur', cAutocomplete.onInputBlur, false ) + hInput.addEventListener( 'focus', cAutocomplete.onInputFocus, false ) + + if( hInputButton ) + { + hInputButton.addEventListener( 'click', cAutocomplete.onButtonClick, false ) + } + } + + //I don't need the standard autocomplete + hInput.setAttribute( 'autocomplete', 'OFF' ) + + if( hForm ) + { + if( hForm.attachEvent ) + { + hForm.attachEvent( 'onsubmit', cAutocomplete.onFormSubmit ) + } + else if( hForm.addEventListener ) + { + hForm.addEventListener( 'submit', cAutocomplete.onFormSubmit, false ) + } + } +} + +cAutocomplete.prototype.initListContainer = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.createElement( 'DIV' ) + hContainer.className = 'autocomplete_holder' + hContainer.id = this.sListId + hContainer.style.zIndex = 10000 + cAutocomplete.nCount + hContainer.hAutocomplete = this + + var hFirstBorder = document.createElement( 'DIV' ) + hFirstBorder.className = 'autocomplete_firstborder' + var hSecondBorder = document.createElement( 'DIV' ) + hSecondBorder.className = 'autocomplete_secondborder' + + var hList = document.createElement( 'UL' ) + hList.className = 'autocomplete' + + hSecondBorder.appendChild( hList ) + hFirstBorder.appendChild( hSecondBorder ) + hContainer.appendChild( hFirstBorder ) + document.body.appendChild( hContainer ) + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onblur', cAutocomplete.onListBlur ) + hContainer.attachEvent( 'onfocus', cAutocomplete.onListFocus ) + } + else if( hInput.addEventListener ) + { + hContainer.addEventListener( 'blur', cAutocomplete.onListBlur, false ) + hContainer.addEventListener( 'focus', cAutocomplete.onListFocus, false ) + } + + + if( hContainer.attachEvent ) + { + hContainer.attachEvent( 'onclick', cAutocomplete.onItemClick ) + } + else if( hContainer.addEventListener ) + { + hContainer.addEventListener( 'click', cAutocomplete.onItemClick, false ) + } +} + +cAutocomplete.prototype.createList = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[0] + if( hList ) + { + hList = hList.parentNode.removeChild( hList ) + while( hList.hasChildNodes() ) + { + hList.removeChild( hList.childNodes[ 0 ] ) + } + } + + var hListItem = null + var hListItemLink = null + var hArrKey = null + var sArrEl = null + + var hArr = this.aData + var nI = 0 + var sRealText + for( hArrKey in hArr ) + { + sArrEl = hArr[ hArrKey ] + hListItem = document.createElement( 'LI' ) + hListItemLink = document.createElement( 'A' ) + hListItemLink.setAttribute( 'itemvalue', hArrKey ) + + /* so you can attach data to the element */ + /* it's a hack but seems to work */ + if(sArrEl.split) { + var sArrData = sArrEl.split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( sArrData.length > 1 ) + { + this.aData[ hArrKey ] = sArrData[ 0 ] + hListItemLink.setAttribute( 'itemdata', sArrEl.substring( sArrEl.indexOf( cAutocomplete.CS_ARRAY_SEPARATOR ) + 1 ) ) + sRealText = sArrData[ 0 ] + } + else + { + sRealText = sArrEl + } + /* end of attach data to the element */ + + hListItemLink.href = '#' + hListItemLink.appendChild( document.createTextNode( sRealText ) ) + hListItemLink.realText = sRealText + if( nI == this.nSelectedItemIdx ) + { + this.hActiveSelection = hListItemLink + this.hActiveSelection.className = 'selected' + } + hListItem.appendChild( hListItemLink ) + hList.appendChild( hListItem ) + this.aSearchData[ nI++ ] = sRealText.toLowerCase() + } + } + var hSecondBorder = hContainer.firstChild.firstChild + hSecondBorder.appendChild( hList ) + this.bListUpdated = false +} + +/* list array functions */ + +cAutocomplete.prototype.initListArray = function() +{ + var hInput = document.getElementById( this.sInputId ) + var hArr = null + + if( hInput.type.toLowerCase() == 'select-one' ) + { + hArr = new Object() + for( var nI = 0; nI < hInput.options.length; nI++ ) + { + hArrKey = hInput.options.item( nI ).value + sArrEl = hInput.options.item( nI ).text + hArr[ hArrKey ] = sArrEl + if( hInput.options.item( nI ).selected ) + { + this.nSelectedItemIdx = nI + } + } + } + else + { + var sAA = hInput.getAttribute( 'autocomplete_list' ) + var sAAS = hInput.getAttribute( 'autocomplete_list_sort' ) + + var sArrayType = this.getListArrayType() + + switch( sArrayType ) + { + case 'array' : hArr = eval( sAA.substring( 6 ) ) + break + + case 'list' : hArr = new Array() + var hTmpArray = sAA.substring( 5 ).split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + this.bAssociative = false + } + else + { + hArr[ aValueArr[ 0 ] ] = aValueArr[ 1 ] + } + } + break + } + if( sAAS != null && eval( sAAS ) ) + { + this.bSorted = true + this.aData = hArr.sort() + hArr = hArr.sort() + } + } + this.setArray( hArr ) +} + +cAutocomplete.prototype.setArray = function( sArray ) +{ + if( typeof sArray == 'string' ) + { + this.aData = eval( sArray ) + } + else + { + this.aData = sArray + } + this.bListUpdated = true +} + +//use this function to change the list of autocomplete values to a new one +//supply as an argument the name as a literal of an JS array object +//well things changed - you can supply an actual array too +cAutocomplete.prototype.setListArray = function( sArray ) +{ + this.setArray( sArray ) + this.updateAndShowList() +} + +cAutocomplete.prototype.getListArrayType = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'array:' ) >= 0 ) + { + return 'array' + } + else if( sAA.indexOf( 'list:' ) >= 0 ) + { + return 'list' + } + else if( sAA.indexOf( 'url:' ) >= 0 ) + { + return 'url' + } + } +} + +cAutocomplete.prototype.getListURL = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sAA = hInput.getAttribute( 'autocomplete_list' ) + if( sAA != null && sAA.length > 0 ) + { + if( sAA.indexOf( 'url:' ) >= 0 ) + { + return sAA.substring( 4 ) + } + } +} + +cAutocomplete.prototype.setListURL = function( sURL ) +{ + this.sListURL = sURL; +} + +cAutocomplete.prototype.onXmlHttpLoad = function() +{ + if( this.hXMLHttp.readyState == 4 ) + { + var hError = this.hXMLHttp.parseError + if( hError && hError.errorCode != 0 ) + { + alert( hError.reason ) + } + else + { + this.afterRemoteLoad() + } + } +} + +cAutocomplete.prototype.loadListArray = function() +{ + var sURL = this.sListURL + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + sStartWith = sStartWith.replace( /^\s/, '' ) + sStartWith = sStartWith.replace( /\s$/, '' ) + if( sURL.indexOf( '[S]' ) >= 0 ) + { + sURL = sURL.replace( '[S]', sStartWith ) + } + else + { + sURL += this.sActiveValue + } + this.hXMLHttp.open( 'GET', sURL, true ) + + var hAC = this + this.hXMLHttp.onreadystatechange = function() { hAC.onXmlHttpLoad() } + this.hXMLHttp.send( null ) +} + +cAutocomplete.prototype.afterRemoteLoad = function() +{ + var hInput = document.getElementById( this.sInputId ) + + var hArr = new Array() + var hTmpArray = this.hXMLHttp.responseText.split( '|' ) + var aValueArr + for( hKey in hTmpArray ) + { + if(hTmpArray[ hKey ].split) { + aValueArr = hTmpArray[ hKey ].split( cAutocomplete.CS_ARRAY_SEPARATOR ) + if( aValueArr.length == 1 ) + { + hArr[ hKey ] = hTmpArray[ hKey ] + } + else + { + hArr[ aValueArr[ 0 ] ] = hTmpArray[ hKey ].substr( hTmpArray[ hKey ].indexOf( cAutocomplete.CS_ARRAY_SEPARATOR ) + 1 ) + } + } + } + + hInput.className = '' + hInput.readonly = false + hInput.value = this.sActiveValue + this.setListArray( hArr ) +} + +/**/ + +cAutocomplete.prototype.prepareList = function( bFullList ) +{ + var hInput = document.getElementById( this.sInputId ) + this.sActiveValue = hInput.value + if( this.bRemoteList ) + { + hInput.readonly = true + } + + //check if this was invoked by a key that did not change the value + var sST = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sLST = this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) + + if( sLST != sST || bFullList || !this.bListDisplayed || this.bMatchSubstring ) + { + if( this.bRemoteList ) + { + hInput.className = 'search' + hInput.value = 'please wait...' + this.loadListArray() + return + } + this.updateAndShowList( bFullList ) + } +} + +cAutocomplete.prototype.updateAndShowList = function( bFullList ) +{ + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hInput = document.getElementById( this.sInputId ) + + if( this.bListUpdated ) + { + this.createList() + } + + //stupid hack just for speed + var sST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) : this.sActiveValue + var sLST = this.bMatchSubstring ? this.getStringForAutocompletion( this.sLastActiveValue, this.nInsertPoint ) : this.sLastActiveValue + + //nothing changed since last type - maybe only function keys were pressed + //this is the case when for example the down key was pressed + if( sST == sLST ) + { + if( !this.bMatchSubstring ) + { + bFullList = true + } + } + this.filterOptions( bFullList ) + + if( this.nItemsDisplayed == 0 ) + { + if( this.bForceCorrect ) + { + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, '' ) + cAutocomplete.markInputRange( hInput, this.nLastMatchLength, aPos[0] ) + } + } + + this.sLastActiveValue = this.sActiveValue + + if( this.nItemsDisplayed > 0 ) + { + if( !bFullList || this.bMatchSubstring ) + { + this.deselectOption() + } + if( this.bAutoComplete && this.nItemsDisplayed == 1 ) + { + //test if we have a full match i.e. the user typed the entire value + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + var sItemText = hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ].realText + if( sStartWith.toLowerCase() == sItemText.toLowerCase() ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + this.hideOptions() + //and do not show the list + return + } + } + if( this.bAutoComplete && !bFullList ) + { + this.selectOption( hList.getElementsByTagName( 'LI' )[ this.nFirstDisplayed ].getElementsByTagName( 'A' )[ 0 ] ) + } + this.showList() + } + else + { + this.clearList() + } +} + +cAutocomplete.prototype.showList = function() +{ + if( cAutocomplete.hListDisplayed ) + { + cAutocomplete.hListDisplayed.clearList() + } + var hInput = document.getElementById( this.sInputId ) + var nTop = cDomObject.getOffsetParam( hInput, 'offsetTop' ) + var nLeft = cDomObject.getOffsetParam( hInput, 'offsetLeft' ) + var hContainer = document.getElementById( this.sListId ) + + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + if( this.bHasButton ) + { + hContainer.style.width = document.getElementById( this.sInputId ).parentNode.offsetWidth + } + else + { + hContainer.style.width = document.getElementById( this.sInputId ).offsetWidth + } + var nNumLines = ( this.nItemsDisplayed < cAutocomplete.CN_NUMBER_OF_LINES ) ? this.nItemsDisplayed : cAutocomplete.CN_NUMBER_OF_LINES; + hList.style.height = nNumLines * cAutocomplete.CN_LINE_HEIGHT + cAutocomplete.CN_HEIGHT_FIX + 'px' + + hContainer.style.top = nTop + hInput.offsetHeight + cAutocomplete.CN_OFFSET_TOP + 'px' + hContainer.style.left = nLeft + cAutocomplete.CN_OFFSET_LEFT + 'px' + + hContainer.style.display = 'none' + hContainer.style.visibility = 'visible' + hContainer.style.display = 'block' + + cAutocomplete.hListDisplayed = this + this.bListDisplayed = true +} + +cAutocomplete.prototype.binarySearch = function( sFilter ) +{ + var nLow = 0 + var nHigh = this.aSearchData.length - 1 + var nMid + var nTry, nLastTry + var sData + var nLen = sFilter.length + + var lastTry + + while ( nLow <= nHigh ) + { + nMid = ( nLow + nHigh ) / 2 + nTry = ( nMid < 1 ) ? 0 : parseInt( nMid ) + + sData = this.aSearchData[ nTry ].substr( 0, nLen ) + + if ( sData < sFilter ) + { + nLow = nTry + 1 + continue + } + if ( sData > sFilter ) + { + nHigh = nTry - 1 + continue + } + if ( sData == sFilter ) + { + nHigh = nTry - 1 + nLastTry = nTry + continue + } + return nTry + } + + if ( typeof ( nLastTry ) != "undefined" ) + { + return nLastTry + } + else + { + return null + } +} + +cAutocomplete.prototype.getStringForAutocompletion = function( sString, nPos ) +{ + if( sString == null || sString.length == 0 ) + { + return '' + } + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S*)(\s*)(\,?)$/g, '$3' ) + return sStr + } + else + { + return sString + } +} + +cAutocomplete.prototype.insertString = function( sString, nPos, sInsert ) +{ + if( this.bMatchSubstring ) + { + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert+'$4$5' ) + sStr = sString.substr( 0, nStartPos ) + sStr + sString.substr( nEndPos ) + return sStr + } + else + { + return sInsert + } +} + +cAutocomplete.prototype.getInsertPos = function( sString, nPos, sInsert ) +{ + nPos = nPos == null ? 0 : nPos + var nStartPos = sString.lastIndexOf( cAutocomplete.CS_SEPARATOR, nPos - 1 ) + nStartPos = nStartPos < 0 ? 0 : nStartPos + var nEndPos = sString.indexOf( cAutocomplete.CS_SEPARATOR, nPos ) + nEndPos = nEndPos < 0 ? sString.length : nEndPos + var sStr = sString.substr( nStartPos, nEndPos - nStartPos ) + sStr = sStr.replace( /^(\,?)(\s*)(\S?[\S\s]*\S?)(\s*)(\,?)$/g, '$1$2'+sInsert ) + return [ nPos, nStartPos + sStr.length ] +} + +cAutocomplete.prototype.filterOptions = function( bShowAll ) +{ + if( this.hActiveSelection && !bShowAll ) + { + this.hActiveSelection.className = '' + } + if( typeof bShowAll == 'undefined' ) + { + bShowAll = false + } + + var hInput = document.getElementById( this.sInputId ) + + var sStartWith = this.getStringForAutocompletion( this.sActiveValue, this.nInsertPoint ) + if( bShowAll ) + { + sStartWith = '' + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + var hLinkItem = null + var nCount = 0 + + var hParent = hList.parentNode + var hList = hList.parentNode.removeChild( hList ) + var hTItems = hList.childNodes + + this.nItemsDisplayed = 0 + + if( sStartWith.length == 0 ) + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + } + + nCount = nItemsLength + + if( nItemsLength > 0 ) + { + this.nFirstDisplayed = 0 + this.nLastDisplayed = nItemsLength - 1 + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + } + + //this.nLastMatchLength = 0 + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + else + { + this.nFirstDisplayed = this.nLastDisplayed = -1 + sStartWith = sStartWith.toLowerCase() + var bEnd = false + if( this.bSorted && this.bMatchBegin ) + { + var nStartAt = this.binarySearch( sStartWith ) + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( nI >= nStartAt && !bEnd ) + { + if( !bEnd && this.aSearchData[ nI ].indexOf( sStartWith ) != 0 ) + { + bEnd = true + continue + } + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + else + { + for( var nI = 0; nI < nItemsLength; nI++ ) + { + hTItems[ nI ].style.display = 'none' + if( ( this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) == 0 ) || ( !this.bMatchBegin && this.aSearchData[ nI ].indexOf( sStartWith ) >= 0 ) ) + { + if( this.formatOptions ) + { + hTItems[ nI ].childNodes[0].innerHTML = this.formatOptions( hTItems[ nI ].childNodes[0].realText, nI ) + } + hTItems[ nI ].style.display = 'block' + nCount++ + if( this.nFirstDisplayed < 0 ) + { + this.nFirstDisplayed = nI + } + this.nLastDisplayed = nI + } + } + } + + if( nCount > 0 ) + { + //this.nLastMatchLength = this.sActiveValue.length + var aPos = this.getInsertPos( this.sActiveValue, this.nInsertPoint, sStartWith ) + this.nLastMatchLength = aPos[0] + } + } + hParent.appendChild( hList ) + this.nItemsDisplayed = nCount +} + +cAutocomplete.prototype.hideOptions = function() +{ + var hContainer = document.getElementById( this.sListId ) + hContainer.style.visibility = 'hidden' + hContainer.style.display = 'none' + cAutocomplete.hListDisplayed = null +} + +cAutocomplete.prototype.markAutocompletedValue = function() +{ + var hInput = document.getElementById( this.sInputId ) + var sValue = this.hActiveSelection.realText + if( this.bMatchSubstring ) + { + var aPos = this.getInsertPos( this.sLastActiveValue, this.nInsertPoint, sValue ) + var nStartPos = aPos[ 0 ] + var nEndPos = aPos[ 1 ] + } + else + { + var nStartPos = this.nInsertPoint + var nEndPos = sValue.length + } + this.nStartAC = nStartPos + this.nEndAC = nEndPos + + if( this.hMarkRangeTimeout != null ) + { + clearTimeout( this.hMarkRangeTimeout ) + } + this.hMarkRangeTimeout = setTimeout( function() { + cAutocomplete.markInputRange2( hInput.id ) + } + , cAutocomplete.CN_MARK_TIMEOUT ) + //cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + +cAutocomplete.prototype.selectOptionByIndex = function( nOptionIndex ) +{ + if( this.bListUpdated ) + { + this.createList() + } + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + if( nOptionIndex >=0 && nOptionIndex < nItemsLength ) + { + this.selectOption( hList.childNodes[ nOptionIndex ].getElementsByTagName( 'A' )[ 0 ] ) + } +} + +cAutocomplete.prototype.selectOptionByValue = function( sValue ) +{ + if( this.bListUpdated ) + { + this.createList() + } + + sValue = sValue.toLowerCase() + + var hContainer = document.getElementById( this.sListId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var nItemsLength = hList.childNodes.length + + var nSelectedIndex = -1 + for( var nI = 0; nI < nItemsLength; nI++ ) + { + if( this.aSearchData[ nI ].indexOf( sValue ) == 0 ) + { + nSelectedIndex = nI + } + } + if( nSelectedIndex >=0 ) + { + this.selectOption( hList.childNodes[ nSelectedIndex ].getElementsByTagName( 'A' )[ 0 ] ) + } +} + +cAutocomplete.prototype.selectOption = function( hNewOption ) +{ + if( this.hActiveSelection ) + { + if( this.hActiveSelection == hNewOption ) + { + return + } + else + { + this.hActiveSelection.className = '' + } + } + this.hActiveSelection = hNewOption + var hInput = document.getElementById( this.sInputId ) + if( this.hActiveSelection != null ) + { + if( this.sHiddenInputId != null ) + { + if( this.bMatchSubstring ) + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + else + { + document.getElementById( this.sHiddenInputId ).value = this.hActiveSelection.getAttribute( 'itemvalue' ) + } + } + + this.hActiveSelection.className = 'selected' + if( this.bAutoComplete ) + { + hInput.value = this.insertString( this.sLastActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + this.bAutocompleted = true + this.markAutocompletedValue() + } + else + { + var aPos = this.getInsertPos( this.sLastActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + hInput.value = this.insertString( this.sActiveValue, this.nInsertPoint, this.hActiveSelection.realText ) + //cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + cAutocomplete.setInputCaretPosition( hInput, aPos[ 1 ] ) + } + + this.sActiveValue = hInput.value + + if( this.onSelect ) + { + this.onSelect() + } + } + else + { + hInput.value = this.sActiveValue + cAutocomplete.setInputCaretPosition( hInput, this.nInsertPoint ) + } +} + +cAutocomplete.prototype.deselectOption = function( ) +{ + if( this.hActiveSelection != null ) + { + this.hActiveSelection.className = '' + this.hActiveSelection = null + } +} + +cAutocomplete.prototype.clearList = function() +{ + //this.deselectOption() + this.hideOptions() + this.bListDisplayed = false +} + +cAutocomplete.prototype.getPrevDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.length - 1 ) + } + else + { + hItem = getPrevNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.previousSibling + } + return null +} + +cAutocomplete.prototype.getNextDisplayedItem = function( hItem ) +{ + if( hItem == null ) + { + var hContainer = document.getElementById( this.sListId ) + hItem = hContainer.getElementsByTagName( 'UL' )[ 0 ].childNodes.item( 0 ) + } + else + { + hItem = getNextNodeSibling( hItem.parentNode ) + } + while( hItem != null ) + { + if( hItem.style.display == 'block' ) + { + return hItem + } + hItem = hItem.nextSibling + } + return null +} + +cAutocomplete.onInputKeyDown = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hContainer = document.getElementById( hAC.sListId ) + var hInput = document.getElementById( hAC.sInputId ) + var hList = hContainer.getElementsByTagName( 'UL' )[ 0 ] + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null && hAC.bListDisplayed ) + { + var hLI = null + var hLINext = null + //the new active selection + if( ( hEvent.keyCode == 13 ) || ( hEvent.keyCode == 27 ) ) + { + var bItemSelected = hEvent.keyCode == 13 ? true : false + hAC.clearList() + } + if( hEvent.keyCode == 38 ) + { + //up key pressed + hLINext = hAC.getPrevDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop < 5 && hLINext.offsetTop > hList.offsetHeight ) + { + hList.scrollTop = hList.scrollHeight - hList.offsetHeight + } + if( hLINext.offsetTop - hList.scrollTop < 0 ) + { + hList.scrollTop -= hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + else if ( hEvent.keyCode == 40 ) + { + //down key pressed + hLINext = hAC.getNextDisplayedItem( hAC.hActiveSelection ) + if( hLINext != null ) + { + hAC.selectOption( hLINext.childNodes.item(0) ) + if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES ) + { + if( hList.scrollTop > 0 && hList.scrollTop > hLINext.offsetTop ) + { + hList.scrollTop = 0 + } + if( Math.abs( hLINext.offsetTop - hList.scrollTop - hList.offsetHeight ) < 5 ) + { + hList.scrollTop += hLINext.offsetHeight + } + } + } + else + { + hAC.selectOption( null ) + } + } + } + if( hInput.form ) + { + hInput.form.bLocked = true + } + if ( hEvent.keyCode == 13 || hEvent.keyCode == 27 || hEvent.keyCode == 38 || hEvent.keyCode == 40 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyPress = function ( hEvent ) +{ + if ( hEvent.keyCode == 13 || hEvent.keyCode == 38 || hEvent.keyCode == 40 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } +} + +cAutocomplete.onInputKeyUp = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + //if we press the keys for up down enter or escape skip showing the list + switch( hEvent.keyCode ) + { + case 8 : if( hAC.bAutoComplete && hAC.bAutocompleted ) + { + hAC.bAutocompleted = false + return false + } + break + case 38 : + case 40 : if( hAC.bListDisplayed ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + case 13 : + case 32 : + case 46 : + //case 37 : + //case 39 : + case 35 : + case 36 : break; + default : if( hEvent.keyCode < 48 ) + { + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false + } + break + } + + if( hAC.hMarkRangeTimeout != null ) + { + clearTimeout( hAC.hMarkRangeTimeout ) + } + + if( hAC.hShowTimeout ) + { + clearTimeout( hAC.hShowTimeout ) + hAC.hShowTimeout = null + } + var nTimeout = hAC.bRemoteList ? cAutocomplete.CN_REMOTE_SHOW_TIMEOUT : cAutocomplete.CN_SHOW_TIMEOUT + hAC.hShowTimeout = setTimeout( function(){ hAC.prepareList() }, nTimeout ) +} + +cAutocomplete.onInputBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.form ) + { + hElement.form.bLocked = false + } + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( function(){ hAC.clearList() }, cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onInputFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.saveCaretPosition = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + + //there is something weird about hitting up and down keys in a textarea + if( hEvent.keyCode != 38 && hEvent.keyCode != 40 ) + { + hAC.nInsertPoint = cAutocomplete.getInputCaretPosition( hInput ) + } +} + +cAutocomplete.getInputCaretPosition = function( hInput ) +{ + if( typeof hInput.selectionStart != 'undefined' ) + { + if( hInput.selectionStart == hInput.selectionEnd ) + { + return hInput.selectionStart + } + else + { + return hInput.selectionStart + } + } + else if( hInput.createTextRange ) + { + var hSelRange = document.selection.createRange() + if( hInput.tagName.toLowerCase() == 'textarea' ) + { + var hSelBefore = hSelRange.duplicate() + var hSelAfter = hSelRange.duplicate() + hSelRange.moveToElementText( hInput ) + hSelBefore.setEndPoint( 'StartToStart', hSelRange ) + return hSelBefore.text.length + } + else + { + hSelRange.moveStart( 'character', -1*hInput.value.length ) + var nLen = hSelRange.text.length + return nLen + } + } + return null +} + +cAutocomplete.setInputCaretPosition = function( hInput, nPosition ) +{ + if ( hInput.setSelectionRange ) + { + hInput.setSelectionRange( nPosition ,nPosition ) + } + else if ( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.moveStart( 'character', nPosition ) + hRange.moveEnd( 'character', nPosition ) + hRange.collapse(true) + hRange.select() + } +} + +cAutocomplete.markInputRange = function( hInput, nStartPos, nEndPos ) +{ + if( hInput.setSelectionRange ) + { + hInput.focus() + hInput.setSelectionRange( nStartPos, nEndPos ) + } + else if( hInput.createTextRange ) + { + var hRange = hInput.createTextRange() + hRange.collapse(true) + hRange.moveStart( 'character', nStartPos ) + hRange.moveEnd( 'character', nEndPos - nStartPos ) + hRange.select() + } +} + +cAutocomplete.markInputRange2 = function( sInputId ) +{ + var hInput = document.getElementById( sInputId ) + var nStartPos = hInput.hAutocomplete.nStartAC + var nEndPos = hInput.hAutocomplete.nEndAC + cAutocomplete.markInputRange( hInput, nStartPos, nEndPos ) +} + + +cAutocomplete.onListBlur = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( !hAC.hClearTimeout ) + { + hAC.hClearTimeout = setTimeout( function() { hAC.clearList() }, cAutocomplete.CN_CLEAR_TIMEOUT ) + } +} + +cAutocomplete.onListFocus = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + hElement = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hAC = hElement.hAutocomplete + if( hAC.hClearTimeout ) + { + clearTimeout( hAC.hClearTimeout ) + hAC.hClearTimeout = null + } +} + +cAutocomplete.onItemClick = function( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hContainer = getParentByProperty( hElement, 'className', 'autocomplete_holder' ) + var hEl = getParentByTagName( hElement, 'A' ) + if( hContainer != null ) + { + var hAC = hContainer.hAutocomplete + hAC.selectOption( hEl ) + document.getElementById( hAC.sInputId ).focus() + hAC.clearList() + } + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + hEvent.cancelBubble = true + hEvent.returnValue = false + return false +} + +cAutocomplete.onButtonClick = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + var hAC = hElement.hAutocomplete + var hInput = document.getElementById( hAC.sInputId ) + if( hInput.disabled ) + { + return + } + hAC.prepareList( true ) + var hInput = document.getElementById( hAC.sInputId ) + hInput.focus() +} + +cAutocomplete.onFormSubmit = function ( hEvent ) +{ + if( hEvent == null ) + { + hEvent = window.event + } + var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget + if( hElement.bLocked ) + { + hElement.bLocked = false + hEvent.returnValue = false + if( hEvent.preventDefault ) + { + hEvent.preventDefault() + } + return false + } +} diff --git a/autocomplete/js/getobject2.js b/autocomplete/js/getobject2.js new file mode 100644 index 0000000..d8125c5 --- /dev/null +++ b/autocomplete/js/getobject2.js @@ -0,0 +1,126 @@ +//misc objects +//a simple encapsulation object +//used to query widths and heights + +function cDomObject( sId ) +{ + if( bw.dom || bw.ie ) + { + this.hElement = document.getElementById( sId ) + this.hStyle = this.hElement.style + } +} + +cDomObject.prototype.getWidth = function( ) +{ + return cDomObject.getWidth( this.hElement ) +} + +cDomObject.getWidth = function( hElement ) +{ + if( hElement.currentStyle ) + { + var nWidth = parseInt( hElement.currentStyle.width ) + if( isNaN( nWidth ) ) + { + return parseInt( hElement.offsetWidth ) + } + else + { + return nWidth + } + } + else + { + return parseInt( hElement.offsetWidth ) + } +} + +cDomObject.prototype.getHeight = function( ) +{ + return cDomObject.getHeight( this.hElement ) +} + +cDomObject.getHeight = function( hElement ) +{ + if( hElement.currentStyle ) + { + var nHeight = parseInt( hElement.currentStyle.height ) + if( isNaN( nHeight ) ) + { + return parseInt( hElement.offsetHeight ) + } + else + { + return nHeight + } + } + else + { + return parseInt( hElement.offsetHeight ) + } +} + +cDomObject.prototype.getLeft = function() +{ + return cDomObject.getLeft( this.hElement ) +} + +cDomObject.getLeft = function( hElement ) +{ + return parseInt( hElement.offsetLeft ) +} + +cDomObject.prototype.getTop = function( ) +{ + return cDomObject.getTop( this.hElement ) +} + +cDomObject.getTop = function( hElement ) +{ + return parseInt( hElement.offsetTop ) +} + + +// used to get the absolute position of an relativeli position element +// by accumulating the offset parameters +// example +// cDomObject.getOffsetParam( hElement,'offsetLeft' ) + +cDomObject.getOffsetParam = function( hElement, sParam, hLimitParent ) +{ + var nRes = 0 + if( hLimitParent == null ) + { + hLimitParent = document.body.parentElement + } + while( hElement != hLimitParent ) + { + nRes += eval( 'hElement.' + sParam ) + if( !hElement.offsetParent ) { break } + hElement = hElement.offsetParent + } + return nRes +} + + +// used to get the absolute position of an relativeli position element +// by accumulating the scroll offset parameters +// example +// cDomObject.getScrollOffset( hElement,'Left' ) + +cDomObject.getScrollOffset = function( hElement, sParam, hLimitParent ) +{ + nRes = 0 + if( hLimitParent == null ) + { + hLimitParent = document.body.parentElement + } + while( hElement != hLimitParent ) + { + nRes += eval( 'hElement.scroll' + sParam ) + if( !hElement.offsetParent ) { break } + hElement = hElement.parentNode + } + return nRes +}
\ No newline at end of file diff --git a/autocomplete/js/ieselect.js b/autocomplete/js/ieselect.js new file mode 100644 index 0000000..1715580 --- /dev/null +++ b/autocomplete/js/ieselect.js @@ -0,0 +1,85 @@ +function Property(name, value) { + this.name = name; + this.value = value; +} + +var defaultSelectProps = new Array(); + +defaultSelectProps[defaultSelectProps.length] = new Property("VariousPropertyBits", "726624571"); +defaultSelectProps[defaultSelectProps.length] = new Property("DisplayStyle", "7"); +defaultSelectProps[defaultSelectProps.length] = new Property("FontName", "Arial"); +defaultSelectProps[defaultSelectProps.length] = new Property("FontHeight", "200"); +defaultSelectProps[defaultSelectProps.length] = new Property("ShowDropButtonWhen", "2"); +defaultSelectProps[defaultSelectProps.length] = new Property("FontHeight", "200"); +defaultSelectProps[defaultSelectProps.length] = new Property("ScrollBars", "0"); + +function replaceIESelect(id, selectProps) { + if (selectProps==null) selectProps = defaultSelectProps; + if (document.all&&document.getElementById) { + var sel = document.getElementById(id); + var parent = sel.parentNode; + + var obj = document.createElement("object"); + var paramSuccess = true; + + try { + for (var j in selectProps) { + var param = document.createElement("param"); + param.setAttribute("name", selectProps[j].name); + param.setAttribute("value", selectProps[j].value); + obj.appendChild(param); + } + } catch(er) { + paramSuccess = false; + } + + with (obj) { + setAttribute("classid","clsid:8BD21D30-EC42-11CE-9E0D-00AA006002F3"); + setAttribute("id", "comp_" + sel.name); + setAttribute("width", sel.offsetWidth); + setAttribute("height", sel.offsetHeight); + if (!paramSuccess) Style=2; + } + + var input = document.createElement("input"); + with (input) { + setAttribute("id", sel.name); + setAttribute("name", sel.name); + setAttribute("type", "hidden"); + setAttribute("value", obj.name); + } + + obj.options = new Array(); + + for (var j=0; j<sel.options.length; j++) { + obj.options[sel.options[j].text] = sel.options[j].value; + } + + obj.input = input; + obj.input.value = obj.options[obj.value]; + + for (var j in obj.options) { + obj.additem(j); + } + + selText = sel.options[sel.selectedIndex].text; + + parent.replaceChild(obj, sel); + parent.appendChild(input); + + obj.value = selText; + obj.style.position = "relative"; + obj.style.top = "0.3em"; + obj.style.zIndex = "-1"; + } +} + +function replaceAllIESelects() { + if (document.getElementById) { + var sels = document.getElementsByTagName("SELECT"); + for( var nI = 0; nI < sels.length; nI++ ) + { + replaceIESelect(sels[nI].id); + } + } +} diff --git a/autocomplete/js/modomevent3.js b/autocomplete/js/modomevent3.js new file mode 100644 index 0000000..7a548b3 --- /dev/null +++ b/autocomplete/js/modomevent3.js @@ -0,0 +1,189 @@ +// +// This script was created +// by Mircho Mirev +// mo /mo@momche.net/ +// +// :: feel free to use it BUT +// :: if you want to use this code PLEASE send me a note +// :: and please keep this disclaimer intact +// + +//define the cEvent object +cDomEvent = { + e : null, + type : '', + button : 0, + key : 0, + x : 0, + y : 0, + pagex : 0, + pagey : 0, + target : null, + from : null, + to : null +} + +cDomEvent.init = function( e ) +{ + if( window.event ) e = window.event + this.e = e + this.type = e.type + this.button = ( e.which ) ? e.which : e.button + this.key = ( e.which ) ? e.which : e.keyCode + this.target = ( e.srcElement ) ? e.srcElement : e.originalTarget + this.currentTarget = ( e.currentTarget ) ? e.currentTarget : e.srcElement + this.from = ( e.originalTarget ) ? e.originalTarget : ( e.fromElement ) ? e.fromElement : null + this.to = ( e.currentTarget ) ? e.currentTarget : ( e.toElement ) ? e.toElement : null + this.x = ( e.layerX ) ? e.layerX : ( e.offsetX ) ? e.offsetX : null + this.y = ( e.layerY ) ? e.layerY : ( e.offsetY ) ? e.offsetY : null + this.screenX = e.screenX + this.screenY = e.screenY + this.pageX = ( e.pageX ) ? e.pageX : e.x + document.body.scrollLeft + this.pageY = ( e.pageY ) ? e.pageY : e.y + document.body.scrollTop +} + +cDomEvent.getEvent = function( e ) +{ + if( window.event ) e = window.event + return { + e: e, + type: e.type, + button: ( e.which ) ? e.which : e.button, + key: ( e.which ) ? e.which : e.keyCode, + target: ( e.srcElement ) ? e.srcElement : e.originalTarget, + currentTarget: ( e.currentTarget ) ? e.currentTarget : e.srcElement, + from: ( e.originalTarget ) ? e.originalTarget : ( e.fromElement ) ? e.fromElement : null, + to: ( e.currentTarget ) ? e.currentTarget : ( e.toElement ) ? e.toElement : null, + x: ( e.layerX ) ? e.layerX : ( e.offsetX ) ? e.offsetX : null, + y: ( e.layerY ) ? e.layerY : ( e.offsetY ) ? e.offsetY : null, + screenX: e.screenX, + screenY: e.screenY, + pageX: ( e.pageX ) ? e.pageX : ( e.clientX + ( document.documentElement.scrollLeft || document.body.scrollLeft ) ), + pageY: ( e.pageY ) ? e.pageY : ( e.clientY + ( document.documentElement.scrollTop || document.body.scrollTop ) ) + } +} + +cDomEvent.cancelEvent = function( e ) +{ + if( e.preventDefault ) + { + e.preventDefault() + } + e.returnValue = false + e.cancelBubble = true + return false +} + +cDomEvent.addEvent = function( hElement, sEvent, handler, bCapture ) +{ + if( hElement.addEventListener ) + { + hElement.addEventListener( sEvent, handler, bCapture ) + return true + } + else if( hElement.attachEvent ) + { + return hElement.attachEvent( 'on'+sEvent, handler ) + } + else if( document.all || hElement.captureEvents ) + { + if( hElement.captureEvents ) eval( 'hElement.captureEvents( Event.'+sEvent.toUpperCase()+' )' ) + eval( 'hElement.on'+sEvent+' = '+handler ) + } + else + { + alert('Not implemented yet!') + } +} + +cDomEvent.encapsulateEvent = function( hHandler ) +{ + return function ( hEvent ) + { + hEvent = cDomEvent.getEvent( hEvent ) + hHandler.call( hEvent.target, hEvent.e ) + } +} + +cDomEvent.addEvent2 = function( hElement, sEvent, handler, bCapture ) +{ + if( hElement ) + { + if( hElement.addEventListener ) + { + hElement.addEventListener( sEvent, cDomEvent.encapsulateEvent( handler ), bCapture ) + return true + } + else if( hElement.attachEvent ) + { + return hElement.attachEvent( 'on'+sEvent, cDomEvent.encapsulateEvent( handler ) ) + } + else + { + alert('Not implemented yet!') + } + } + else + { + //alert( 'wrong' ) + } +} + +cDomEvent.addCustomEvent2 = function( hElement, sEvent, handler ) +{ + if( hElement ) + { + hElement[ sEvent ] = handler + } + else + { + //alert( 'wrong' ) + } +} + +cDomEvent.removeEvent = function( hElement, sEvent, handler, bCapture ) +{ + if( hElement.addEventListener ) + { + hElement.removeEventListener( sEvent, handler, bCapture ) + return true + } + else if( hElement.attachEvent ) + { + return hElement.detachEvent( 'on'+sEvent, handler ) + } + else if( document.all || hElement.captureEvents ) + { + eval( 'hElement.on'+sEvent+' = null' ) + } + else + { + alert('Not implemented yet!') + } +} + + +//Mouse button mapper object +function MouseButton() +{ + if( document.layers ) + { + this.left = 1 + this.middle = 2 + this.right = 3 + } + else if( document.all ) + { + this.left = 1 + this.middle = 4 + this.right = 2 + } + else //hopefully this is mozilla case + { + this.left = 0 + this.middle = 1 + this.right = 2 + } +} + +var MB = new MouseButton()
\ No newline at end of file diff --git a/autocomplete/js/modomext.js b/autocomplete/js/modomext.js new file mode 100644 index 0000000..f914292 --- /dev/null +++ b/autocomplete/js/modomext.js @@ -0,0 +1,219 @@ +//
+// This script was created
+// by Mircho Mirev
+// mo /mo@momche.net/
+//
+// :: feel free to use it BUT
+// :: if you want to use this code PLEASE send me a note
+// :: and please keep this disclaimer intact
+//
+
+// This in fact is a simple dom iterator
+// requires: mobrowser.js
+
+function cDomExtension( hParent, aSelectors, hInitFunction )
+{
+ this.hParent = hParent
+ this.aSelectors = aSelectors
+ this.hInitFunction = hInitFunction
+}
+
+cDomExtensionManager =
+{
+ aExtensions : new Array()
+}
+
+cDomExtensionManager.register = function( hDomExtension )
+{
+ cDomExtensionManager.aExtensions.push( hDomExtension )
+}
+
+cDomExtensionManager.initSelector = function( hParent, sSelector, hInitFunction )
+{
+ var hSelectorRegEx
+ var hAttributeRegEx
+ var aSelectorData
+ var aAttributeData
+ var sAttribute
+
+ hSelectorRegEx = /([a-z0-9_]*)\[?([^\]]*)\]?/i
+ hAttributeRegEx = /([a-z0-9_]*)([\*\^\$]?)(=?)(([a-z0-9_=]*))/i
+
+ if( hSelectorRegEx.test( sSelector ) && !/[@#\.]/.test( sSelector ) )
+ {
+ aSelectorData = hSelectorRegEx.exec( sSelector )
+ if( aSelectorData[ 1 ] != '' )
+ {
+ hGroup = hParent.getElementsByTagName( aSelectorData[ 1 ].toLowerCase() )
+ for( nI = 0; nI < hGroup.length; nI ++ )
+ {
+ hGroup[ nI ].markExt = true
+ }
+ for( nI = 0; nI < hGroup.length; nI ++ )
+ {
+ if( !hGroup[ nI ].markExt )
+ {
+ continue
+ }
+ else
+ {
+ hGroup[ nI ].markExt = false
+ }
+ if( aSelectorData[ 2 ] == '' )
+ {
+ if( hGroup[ nI ].tagName.toLowerCase() == aSelectorData[ 1 ].toLowerCase() )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ else
+ {
+ aAttributeData = hAttributeRegEx.exec( aSelectorData[ 2 ] )
+ if( aAttributeData[ 1 ] == 'class' )
+ {
+ sAttribute = hGroup[ nI ].className
+ }
+ else
+ {
+ sAttribute = hGroup[ nI ].getAttribute( aAttributeData[ 1 ] )
+ }
+ if( sAttribute != null && sAttribute.length > 0 )
+ {
+ if( aAttributeData[ 3 ] == '=' )
+ {
+ if( aAttributeData[ 2 ] == '' )
+ {
+ if( sAttribute == aAttributeData[4] )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ else
+ {
+ switch( aAttributeData[ 2 ] )
+ {
+ case '^' : if( sAttribute.indexOf( aAttributeData[ 4 ] ) == 0 )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ break
+ case '$' : if( sAttribute.lastIndexOf( aAttributeData[ 4 ] ) == sAttribute.length - aAttributeData[ 4 ].length )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ break
+ case '*' : if( sAttribute.indexOf( aAttributeData[ 4 ] ) >= 0 )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ break
+ }
+ }
+ }
+ else
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ }
+ }
+ //we have the new implementation - css3 style selectors, so return
+ return
+ }
+ }
+
+
+ hSelectorRegEx = /([a-z0-9_]*)([\.#@]?)([a-z0-9_=~]*)/i
+ hAttributeRegEx = /([a-z0-9_]*)([=~])?([a-z0-9_]*)/i
+ aSelectorData = hSelectorRegEx.exec( sSelector )
+
+ if( aSelectorData[ 1 ] != '' )
+ {
+ var hGroup = hParent.getElementsByTagName( aSelectorData[ 1 ] )
+ for( nI = 0; nI < hGroup.length; nI ++ )
+ {
+ hGroup[ nI ].markExt = true
+ }
+ for( nI = 0; nI < hGroup.length; nI ++ )
+ {
+ if( !hGroup[ nI ].markExt )
+ {
+ continue
+ }
+ else
+ {
+ hGroup[ nI ].markExt = false
+ }
+ if( aSelectorData[ 2 ] != '' )
+ {
+ switch( aSelectorData[ 2 ] )
+ {
+ case '.' : if( hGroup[ nI ].className == aSelectorData[ 3 ] )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ break
+
+ case '#' : if( hGroup[ nI ].id == aSelectorData[ 3 ] )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ break
+
+ case '@' : aAttributeData = hAttributeRegEx.exec( aSelectorData[ 3 ] )
+ sAttribute = hGroup[ nI ].getAttribute( aAttributeData[ 1 ] )
+ if( sAttribute != null && sAttribute.length > 0 )
+ {
+ if( aAttributeData[ 3 ] != '' )
+ {
+ if( aAttributeData[ 2 ] == '=' )
+ {
+ if( sAttribute == aAttributeData[ 3 ] )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ else /* the case is like ~ */
+ {
+ if( sAttribute.indexOf( aAttributeData[ 3 ] ) >= 0 )
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ }
+ else
+ {
+ hInitFunction( hGroup[ nI ] )
+ }
+ }
+ break
+ }
+ }
+ }
+ }
+
+}
+
+cDomExtensionManager.initialize = function()
+{
+ var hDomExtension = null
+ var aSelectors
+
+ for( var nKey in cDomExtensionManager.aExtensions )
+ {
+ aSelectors = cDomExtensionManager.aExtensions[ nKey ].aSelectors
+ for( var nKey2 in aSelectors )
+ {
+ cDomExtensionManager.initSelector( cDomExtensionManager.aExtensions[ nKey ].hParent, aSelectors[ nKey2 ], cDomExtensionManager.aExtensions[ nKey ].hInitFunction )
+ }
+ }
+}
+
+if( window.addEventListener )
+{
+ window.addEventListener( 'load', cDomExtensionManager.initialize, false )
+}
+else if( window.attachEvent )
+{
+ window.attachEvent( 'onload', cDomExtensionManager.initialize )
+}
diff --git a/autocomplete/js/modomt.js b/autocomplete/js/modomt.js new file mode 100644 index 0000000..2987ae8 --- /dev/null +++ b/autocomplete/js/modomt.js @@ -0,0 +1,259 @@ +//
+// This script was created
+// by Mircho Mirev
+// mo /mo@momche.net/
+//
+// :: feel free to use it BUT
+// :: if you want to use this code PLEASE send me a note
+// :: and please keep this disclaimer intact
+//
+
+if ( document.ELEMENT_NODE == null )
+{
+ document.ELEMENT_NODE = 1
+ document.TEXT_NODE = 3
+}
+
+
+function getSubNodeByName( hNode, sNodeName )
+{
+ if( hNode != null )
+ {
+ var nNc = 0
+ var nC = 0
+ var hNodeChildren = hNode.childNodes
+ var hCNode = null
+ while( nC < hNodeChildren.length )
+ {
+ hCNode = hNodeChildren.item( nC++ )
+ if( ( hCNode.nodeType == 1 ) && ( hCNode.nodeName.toLowerCase() == sNodeName ) )
+ {
+ return hCNode
+ }
+ }
+ }
+ return null
+}
+
+function getPrevNodeSibling( hNode )
+{
+ if( hNode != null )
+ {
+ do {
+ hNode = hNode.previousSibling
+ } while( hNode != null && hNode.nodeType != 1 )
+ return hNode
+ }
+}
+
+function getNextNodeSibling( hNode )
+{
+ if( hNode != null )
+ {
+ do {
+ hNode = hNode.nextSibling
+ } while( hNode != null && hNode.nodeType != 1 )
+ return hNode
+ }
+}
+
+function getLastSubNodeByName( hNode, sNodeName )
+{
+ if( hNode != null )
+ {
+ var nNc = 0
+ var nC = 0
+ var hNodeChildren = hNode.childNodes
+ var hCNode = null
+ var nLength = hNodeChildren.length - 1
+ while( nLength >=0 )
+ {
+ hCNode = hNodeChildren.item( nLength )
+ if( ( hCNode.nodeType == 1 ) && ( hCNode.nodeName.toLowerCase() == sNodeName ) )
+ {
+ return hCNode
+ }
+ nLength--
+ }
+ }
+ return null
+}
+
+function getSubNodeByProperty( hNode, sProperty, sPropValue )
+{
+ if( hNode != null )
+ {
+ var nNc = 0
+ var nC = 0
+ var hNodeChildren = hNode.childNodes
+ var hCNode = null
+ var sAttribute
+ var hProp
+ sPropValue = sPropValue.toLowerCase()
+ while( nC < hNodeChildren.length )
+ {
+ hCNode = hNodeChildren.item( nC++ )
+ if( hCNode.nodeType == document.ELEMENT_NODE )
+ {
+ hProp = eval( 'hCNode.'+sProperty )
+ if( typeof( sPropValue ) != 'undefined' )
+ {
+ if( hProp.toLowerCase() == sPropValue )
+ {
+ return hCNode
+ }
+ }
+ else
+ {
+ return hCNode
+ }
+ }
+ nNc++
+ }
+ }
+ return null
+}
+
+function findAttribute( hNode, sAtt )
+{
+ sAtt = sAtt.toLowerCase()
+ for( var nI = 0; nI < hNode.attributes.length; nI++ )
+ {
+ if( hNode.attributes.item( nI ).nodeName.toLowerCase() == sAtt )
+ {
+ return hNode.attributes.item( nI ).nodeValue
+ }
+ }
+ return null
+}
+
+function getSubNodeByAttribute( hNode, sAtt, sAttValue )
+{
+ if( hNode != null )
+ {
+ var nNc = 0
+ var nC = 0
+ var hNodeChildren = hNode.childNodes
+ var hCNode = null
+ var sAttribute
+ sAttValue = sAttValue.toLowerCase()
+ while( nC < hNodeChildren.length )
+ {
+ hCNode = hNodeChildren.item( nC++ )
+ if( hCNode.nodeType == document.ELEMENT_NODE )
+ {
+ sAttribute = hCNode.getAttribute( sAtt )
+ if( sAttribute && sAttribute.toLowerCase() == sAttValue )
+ return hCNode
+ }
+ nNc++
+ }
+ }
+ return null
+}
+
+function getLastSubNodeByAttribute( hNode, sAtt, sAttValue )
+{
+ if( hNode != null )
+ {
+ var nNc = 0
+ var nC = 0
+ var hNodeChildren = hNode.childNodes
+ var hCNode = null
+ var nLength = hNodeChildren.length - 1
+ while( nLength >= 0 )
+ {
+ hCNode = hNodeChildren.item( nLength )
+ if( hCNode.nodeType == document.ELEMENT_NODE )
+ {
+ sAttribute = hCNode.getAttribute( sAtt )
+ if( sAttribute && sAttribute.toLowerCase() == sAttValue )
+ return hCNode
+ }
+ nLength--
+ }
+ }
+ return null
+}
+
+function getParentByTagName( hNode, sParentTagName )
+{
+ while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) )
+ {
+ if( hNode.tagName == sParentTagName )
+ {
+ return hNode
+ }
+ hNode = hNode.parentNode
+ }
+ return null
+}
+
+function getParentByAttribute( hNode, sAtt, sAttValue )
+{
+ while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) )
+ {
+ //opera strangely returns non null result sometimes
+ var sAttr = hNode.getAttribute( sAtt )
+ if( sAttr != null && sAttr.toString().length > 0 )
+ {
+ if( sAttValue !== null )
+ {
+ if( sAttr == sAttValue )
+ {
+ return hNode
+ }
+ }
+ else
+ {
+ return hNode
+ }
+ }
+ hNode = hNode.parentNode
+ }
+ return null
+}
+
+function getParentByProperty( hNode, sProperty, sPropValue )
+{
+ while( ( hNode.tagName ) && !( /(body|html)/i.test( hNode.tagName ) ) )
+ {
+ //opera strangely returns non null result sometimes
+ var hProp = eval( 'hNode.'+sProperty )
+ if( hProp != null && hProp.toString().length > 0 )
+ {
+ if( sPropValue !== null )
+ {
+ if( hProp == sPropValue )
+ {
+ return hNode
+ }
+ }
+ else
+ {
+ return hNode
+ }
+ }
+ hNode = hNode.parentNode
+ }
+ return null
+}
+
+
+function getNodeText( hNode )
+{
+ if( hNode == null )
+ {
+ return ''
+ }
+ var sRes
+ if( hNode.hasChildNodes() )
+ {
+ sRes = hNode.childNodes.item(0).nodeValue
+ }
+ else
+ {
+ sRes = hNode.text
+ }
+ return sRes
+}
\ No newline at end of file diff --git a/autocomplete/js/shBrushJScript.js b/autocomplete/js/shBrushJScript.js new file mode 100644 index 0000000..e61a767 --- /dev/null +++ b/autocomplete/js/shBrushJScript.js @@ -0,0 +1,22 @@ +dp.sh.Brushes.JScript = function()
+{
+ var keywords = 'abstract boolean break byte case catch char class const continue debugger ' +
+ 'default delete do double else enum export extends false final finally float ' +
+ 'for function goto if implements import in instanceof int interface long native ' +
+ 'new null package private protected public return short static super switch ' +
+ 'synchronized this throw throws transient true try typeof var void volatile while with';
+
+ this.regexList = [
+ { regex: new RegExp('//.*$', 'gm'), css: 'comment' }, // one line comments
+ { regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'), css: 'comment' }, // multiline comments
+ { regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'), css: 'string' }, // double quoted strings
+ { regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'), css: 'string' }, // single quoted strings
+ { regex: new RegExp('^\\s*#.*', 'gm'), css: 'preprocessor' }, // preprocessor tags like #region and #endregion
+ { regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' } // keywords
+ ];
+
+ this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.JScript.prototype = new dp.sh.Highlighter();
+dp.sh.Brushes.JScript.Aliases = ['js', 'jscript', 'javascript'];
diff --git a/autocomplete/js/shBrushXml.js b/autocomplete/js/shBrushXml.js new file mode 100644 index 0000000..941ad57 --- /dev/null +++ b/autocomplete/js/shBrushXml.js @@ -0,0 +1,61 @@ +dp.sh.Brushes.Xml = function()
+{
+ this.CssClass = 'dp-xml';
+}
+
+dp.sh.Brushes.Xml.prototype = new dp.sh.Highlighter();
+dp.sh.Brushes.Xml.Aliases = ['xml', 'xhtml', 'xslt', 'html', 'xhtml'];
+
+dp.sh.Brushes.Xml.prototype.ProcessRegexList = function()
+{
+ function push(array, value)
+ {
+ array[array.length] = value;
+ }
+
+ /* If only there was a way to get index of a group within a match, the whole XML
+ could be matched with the expression looking something like that:
+
+ (<!\[CDATA\[\s*.*\s*\]\]>)
+ | (<!--\s*.*\s*?-->)
+ | (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)*
+ | (</?)(.*?)(/?>)
+ */
+ var index = 0;
+ var match = null;
+ var regex = null;
+
+ // Match CDATA in the following format <![ ... [ ... ]]>
+ // <\!\[[\w\s]*?\[(.|\s)*?\]\]>
+ this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'cdata');
+
+ // Match comments
+ // <!--\s*.*\s*?-->
+ this.GetMatches(new RegExp('<!--\\s*.*\\s*?-->', 'gm'), 'comments');
+
+ // Match attributes and their values
+ // (\w+)\s*=\s*(".*?"|\'.*?\'|\w+)*
+ regex = new RegExp('([\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'gm');
+ while((match = regex.exec(this.code)) != null)
+ {
+ push(this.matches, new dp.sh.Match(match[1], match.index, 'attribute'));
+
+ // if xml is invalid and attribute has no property value, ignore it
+ if(match[2] != undefined)
+ {
+ push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'attribute-value'));
+ }
+ }
+
+ // Match opening and closing tag brackets
+ // </*\?*(?!\!)|/*\?*>
+ this.GetMatches(new RegExp('</*\\?*(?!\\!)|/*\\?*>', 'gm'), 'tag');
+
+ // Match tag names
+ // </*\?*\s*(\w+)
+ regex = new RegExp('</*\\?*\\s*([\\w-\.]+)', 'gm');
+ while((match = regex.exec(this.code)) != null)
+ {
+ push(this.matches, new dp.sh.Match(match[1], match.index + match[0].indexOf(match[1]), 'tag-name'));
+ }
+}
diff --git a/autocomplete/js/shCore.js b/autocomplete/js/shCore.js new file mode 100644 index 0000000..e53e02c --- /dev/null +++ b/autocomplete/js/shCore.js @@ -0,0 +1,589 @@ +/**
+ * Code Syntax Highlighter. Version 1.1.0
+ * Copyright (C) 2004 Dream Projections Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ **
+ * Usage example:
+ *
+ * <script src="shCore.js" language="javascript"></script>
+ * <script src="shBrushXml.js" language="javascript"></script>
+ *
+ * <textarea name="code" language="html">
+ * <img src="myimage.gif" border="0">
+ * </textarea>
+ *
+ * <script>dp.SyntaxHighlighter.HighlightAll('code', 'value');</script>
+ *
+ **
+ * History:
+ * 1.1.0 - March 23rd, 2005
+ * - split brushes into separate files
+ * - now works in Safari
+ * - added missing strings to PHP matches
+ *
+ * 1.0.4 - February 2nd, 2005
+ * - added Delphi & Python
+ * - multi-line comments fixed
+ * - language name can be set through w3c valid 'class' attribute
+ * - HighlightAll(name, [showGutter], [showTools])
+ *
+ * 1.0.3 - December 31th, 2004 (added PHP & SQL)
+ * 1.0.2 - December 28th, 2004 (refactoring with namespaces)
+ * 1.0.1 - December 14th, 2004
+ * 1.0.0 - November 13th, 2004
+ */
+
+// create namespaces
+var dp = {
+ sh : // dp.sh
+ {
+ Utils : {}, // dp.sh.Utils
+ Brushes : {} // dp.sh.Brushes
+ }
+};
+
+dp.sh.Config = {
+ Version : '1.1.0',
+ About : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><div class="para title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</div><div class="para"><a href="http://www.dreamprojections.com/sh/?ref=about" target="_blank">http://www.dreamprojections.com/SyntaxHighlighter</a></div>©2004-2005 Dream Projections Inc. All right reserved.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>'
+};
+
+dp.SyntaxHighlighter = dp.sh;
+
+
+
+// opens a new windows and puts the original unformatted source code inside.
+dp.sh.Utils.ViewSource = function(sender)
+{
+ var code = sender.parentNode.originalCode;
+ var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=1');
+
+ code = code.replace(/</g, '<');
+
+ wnd.document.write('<pre>' + code + '</pre>');
+ wnd.document.close();
+}
+
+// copies the original source code in to the clipboard (IE only)
+dp.sh.Utils.ToClipboard = function(sender)
+{
+ var code = sender.parentNode.originalCode;
+
+ // This works only for IE. There's a way to make it work with Mozilla as well,
+ // but it requires security settings changed on the client, which isn't by
+ // default, so 99% of users won't have it working anyways.
+ if(window.clipboardData)
+ {
+ window.clipboardData.setData('text', code);
+
+ alert('The code is in your clipboard now.');
+ }
+}
+
+// creates an invisible iframe, puts the original source code inside and prints it
+dp.sh.Utils.PrintSource = function(sender)
+{
+ var td = sender.parentNode;
+ var code = td.processedCode;
+ var iframe = document.createElement('IFRAME');
+ var doc = null;
+ var wnd =
+
+ // this hides the iframe
+ iframe.style.cssText = 'position:absolute; width:0px; height:0px; left:-5px; top:-5px;';
+
+ td.appendChild(iframe);
+
+ doc = iframe.contentWindow.document;
+ code = code.replace(/</g, '<');
+
+ doc.open();
+ doc.write('<pre>' + code + '</pre>');
+ doc.close();
+
+ iframe.contentWindow.focus();
+ iframe.contentWindow.print();
+
+ td.removeChild(iframe);
+}
+
+dp.sh.Utils.About = function()
+{
+ var wnd = window.open('', '_blank', 'dialog, width=320, height=150');
+ var doc = wnd.document;
+
+ var styles = document.getElementsByTagName('style');
+ var links = document.getElementsByTagName('link');
+
+ doc.write(dp.sh.Config.About.replace('{V}', dp.sh.Config.Version));
+
+ // copy over ALL the styles from the parent page
+ for(var i = 0; i < styles.length; i++)
+ doc.write('<style>' + styles[i].innerHTML + '</style>');
+
+ for(var i = 0; i < links.length; i++)
+ if(links[i].rel.toLowerCase() == 'stylesheet')
+ doc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
+
+ doc.close();
+ wnd.focus();
+}
+
+
+
+
+
+// creates a new match object
+dp.sh.Match = function(value, index, css)
+{
+ this.value = value;
+ this.index = index;
+ this.length = value.length;
+ this.css = css;
+}
+
+
+
+
+
+dp.sh.Highlighter = function()
+{
+ this.addGutter = true;
+ this.addControls = true;
+ this.tabsToSpaces = true;
+}
+
+// static callback for the match sorting
+dp.sh.Highlighter.SortCallback = function(m1, m2)
+{
+ // sort matches by index first
+ if(m1.index < m2.index)
+ return -1;
+ else if(m1.index > m2.index)
+ return 1;
+ else
+ {
+ // if index is the same, sort by length
+ if(m1.length < m2.length)
+ return -1;
+ else if(m1.length > m2.length)
+ return 1;
+ }
+ return 0;
+}
+
+// gets a list of all matches for a given regular expression
+dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
+{
+ var index = 0;
+ var match = null;
+
+ while((match = regex.exec(this.code)) != null)
+ {
+ this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
+ }
+}
+
+dp.sh.Highlighter.prototype.AddBit = function(str, css)
+{
+ var span = document.createElement('span');
+
+ str = str.replace(/&/g, '&');
+ str = str.replace(/ /g, ' ');
+ str = str.replace(/</g, '<');
+ str = str.replace(/\n/gm, ' <br>');
+
+ // when adding a piece of code, check to see if it has line breaks in it
+ // and if it does, wrap individual line breaks with span tags
+ if(css != null)
+ {
+ var regex = new RegExp('<br>', 'gi');
+
+ if(regex.test(str))
+ {
+ var lines = str.split(' <br>');
+
+ str = '';
+
+ for(var i = 0; i < lines.length; i++)
+ {
+ span = document.createElement('SPAN');
+ span.className = css;
+ span.innerHTML = lines[i];
+
+ this.div.appendChild(span);
+
+ // don't add a <BR> for the last line
+ if(i + 1 < lines.length)
+ {
+ this.div.appendChild(document.createElement('BR'));
+ }
+ }
+ }
+ else
+ {
+ span.className = css;
+ span.innerHTML = str;
+ this.div.appendChild(span);
+ }
+ }
+ else
+ {
+ span.innerHTML = str;
+ this.div.appendChild(span);
+ }
+}
+
+// checks if one match is inside another
+dp.sh.Highlighter.prototype.IsInside = function(match)
+{
+ if(match == null || match.length == 0)
+ {
+ return;
+ }
+
+ for(var i = 0; i < this.matches.length; i++)
+ {
+ var c = this.matches[i];
+
+ if(c == null)
+ {
+ continue;
+ }
+
+ if((match.index > c.index) && (match.index <= c.index + c.length))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+dp.sh.Highlighter.prototype.ProcessRegexList = function()
+{
+ for(var i = 0; i < this.regexList.length; i++)
+ {
+ this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
+ }
+}
+
+dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
+{
+ var lines = code.split('\n');
+ var result = '';
+ var tabSize = 4;
+ var tab = '\t';
+
+ // This function inserts specified amount of spaces in the string
+ // where a tab is while removing that given tab.
+ function InsertSpaces(line, pos, count)
+ {
+ var left = line.substr(0, pos);
+ var right = line.substr(pos + 1, line.length); // pos + 1 will get rid of the tab
+ var spaces = '';
+
+ for(var i = 0; i < count; i++)
+ {
+ spaces += ' ';
+ }
+
+ return left + spaces + right;
+ }
+
+ // This function process one line for 'smart tabs'
+ function ProcessLine(line, tabSize)
+ {
+ if(line.indexOf(tab) == -1)
+ {
+ return line;
+ }
+
+ var pos = 0;
+
+ while((pos = line.indexOf(tab)) != -1)
+ {
+ // This is pretty much all there is to the 'smart tabs' logic.
+ // Based on the position within the line and size of a tab,
+ // calculate the amount of spaces we need to insert.
+ var spaces = tabSize - pos % tabSize;
+
+ line = InsertSpaces(line, pos, spaces);
+ }
+
+ return line;
+ }
+
+ // Go through all the lines and do the 'smart tabs' magic.
+ for(var i = 0; i < lines.length; i++)
+ {
+ var line = lines[i];
+ result += ProcessLine(line, tabSize) + '\n';
+ }
+
+ return result;
+}
+
+dp.sh.Highlighter.prototype.SwitchToTable = function()
+{
+ // Safari fix: for some reason lowercase <br> isn't getting picked up, even though 'i' is set
+ var lines = this.div.innerHTML.split(/<BR>/gi);
+ var row = null;
+ var cell = null;
+ var html = '';
+ var pipe = ' | ';
+
+ // creates an anchor to a utility
+ function UtilHref(util, text)
+ {
+ return '<a href="#" onclick="dp.sh.Utils.' + util + '(this); return false;">' + text + '</a>';
+ }
+
+ row = this.table.insertRow(-1);
+
+ if(this.addGutter == true)
+ {
+ cell = row.insertCell(-1);
+ cell.className = 'tools-corner';
+ }
+
+ if(this.addControls == true)
+ {
+ cell = row.insertCell(-1);
+
+ cell.originalCode = this.originalCode;
+ cell.processedCode = this.code;
+
+ cell.className = 'tools';
+ cell.innerHTML = UtilHref('ViewSource', 'view plain') + pipe + UtilHref('PrintSource', 'print');
+
+ if(window.clipboardData)
+ {
+ cell.innerHTML += pipe + UtilHref('ToClipboard', 'copy to clipboard');
+ }
+
+ cell.innerHTML += pipe + UtilHref('About', '?');
+ }
+
+ for(var i = 0; i < lines.length - 1; i++)
+ {
+ row = this.table.insertRow(-1);
+
+ if(this.addGutter == true)
+ {
+ cell = row.insertCell(-1);
+ cell.className = 'gutter';
+ cell.innerHTML = i + 1;
+ }
+
+ cell = row.insertCell(-1);
+ cell.className = 'line';
+ cell.innerHTML = lines[i];
+ }
+
+ this.div.innerHTML = '';
+}
+
+dp.sh.Highlighter.prototype.Highlight = function(code)
+{
+ // This function strips all new lines and spaces
+ // from the beging and end of the string .
+ function Trim(str)
+ {
+ var begining = new RegExp('^[\\s\\n]', 'g');
+ var end = new RegExp('[\\s\\n]$', 'g');
+
+ while(begining.test(str))
+ {
+ str = str.substr(1);
+ }
+
+ while(end.test(str))
+ {
+ str = str.substr(0, str.length - 1);
+ }
+
+ return str;
+ }
+
+ // This function returns a portions of the string
+ // from pos1 to pos2 inclusive.
+ function Copy(string, pos1, pos2)
+ {
+ return string.substr(pos1, pos2 - pos1);
+ }
+
+ var pos = 0;
+
+ this.originalCode = code;
+ this.code = Trim(code);
+ this.div = document.createElement('DIV');
+ this.table = document.createElement('TABLE');
+ this.matches = new Array();
+
+ if(this.CssClass != null)
+ {
+ this.table.className = this.CssClass;
+ }
+
+ // replace tabs with spaces
+ if(this.tabsToSpaces == true)
+ {
+ this.code = this.ProcessSmartTabs(this.code);
+ }
+
+ this.table.border = 0;
+ this.table.cellSpacing = 0;
+ this.table.cellPadding = 0;
+
+ this.ProcessRegexList();
+
+ // if no matches found, do nothing
+ if(this.matches.length == 0)
+ {
+ return;
+ }
+
+ // sort the matches
+ this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
+
+ // The following loop checks to see if any of the matches are inside
+ // of other matches. This process would get rid of highligting strings
+ // inside comments, keywords inside strings and so on.
+ for(var i = 0; i < this.matches.length; i++)
+ {
+ if(this.IsInside(this.matches[i]))
+ {
+ this.matches[i] = null;
+ }
+ }
+
+ // Finally, go through the final list of matches and pull the all
+ // together adding everything in between that isn't a match.
+ for(var i = 0; i < this.matches.length; i++)
+ {
+ var match = this.matches[i];
+
+ if(match == null || match.length == 0)
+ {
+ continue;
+ }
+
+ this.AddBit(Copy(this.code, pos, match.index), null);
+ this.AddBit(match.value, match.css);
+
+ pos = match.index + match.length;
+ }
+
+ this.AddBit(this.code.substr(pos), null);
+
+ this.SwitchToTable();
+}
+
+dp.sh.Highlighter.prototype.GetKeywords = function(str)
+{
+ return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
+}
+
+// highlightes all elements identified by name and gets source code from specified property
+dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */)
+{
+ var elements = document.getElementsByName(name);
+ var highlighter = null;
+ var registered = new Object();
+ var propertyName = 'value';
+
+ function FindValue()
+ {
+ var a = arguments;
+
+ for(var i = 0; i < a.length; i++)
+ if(a[i] != null && ((typeof(a[i]) == 'string' && a[i] != '') || (typeof(a[i]) == 'object' && a[i].value != '')))
+ return a[i];
+
+ return null;
+ }
+
+ if(elements == null)
+ {
+ return;
+ }
+
+ // if showGutter isn't set, default to TRUE
+ if(showGutter == null)
+ {
+ showGutter = true;
+ }
+
+ // if showControls isn't set, default to TRUE
+ if(showControls == null)
+ {
+ showControls = true;
+ }
+
+ // register all brushes
+ for(var brush in dp.sh.Brushes)
+ {
+ var aliases = dp.sh.Brushes[brush].Aliases;
+
+ if(aliases == null)
+ {
+ continue;
+ }
+
+ for(var i = 0; i < aliases.length; i++)
+ {
+ registered[aliases[i]] = brush;
+ }
+ }
+
+ for(var i = 0; i < elements.length; i++)
+ {
+ var element = elements[i];
+ var language = FindValue(element.attributes['class'], element.className, element.attributes['language'], element.language);
+
+ if(language == null)
+ continue;
+
+ if(language.value)
+ language = language.value;
+
+ language = (language + '').toLowerCase();
+
+ if(registered[language] == null)
+ {
+ continue;
+ }
+
+ // instantiate a brush
+ highlighter = new dp.sh.Brushes[registered[language]]();
+
+ // hide the original element
+ element.style.display = 'none';
+
+ highlighter.addGutter = showGutter;
+ highlighter.addControls = showControls;
+ highlighter.Highlight(element[propertyName]);
+
+ // place the result table inside a div
+ var div = document.createElement('DIV');
+
+ div.className = 'dp-highlighter';
+ div.appendChild(highlighter.table);
+
+ element.parentNode.insertBefore(div, element);
+ }
+}
diff --git a/autocomplete/js/tabs2.js b/autocomplete/js/tabs2.js new file mode 100644 index 0000000..9d196c8 --- /dev/null +++ b/autocomplete/js/tabs2.js @@ -0,0 +1,124 @@ +/* +* mo's Tabs script +* +* mo@momche.net +* please keep this disclaimer and send me a message if you intend to use the script +*/ +cMoTabs = new Object() + +cMoTabs.getTabGroup = function( hElement ) +{ + return getParentByTagName( hElement, 'UL' ) +} + +cMoTabs.getTabElement = function( hElement ) +{ + if( hElement == null ) + { + return null + } + try + { + if( typeof hElement.tagName == 'undefined' ) return null + } + catch( hException ) + { + return null + } + return getParentByProperty( hElement, 'className', 'tab' ) +} + + +cMoTabs.setActiveTabElement = function( hTabElement ) +{ + if( hTabElement == null ) + { + return + } + hTabElement.className = 'tabactive' + var hView = document.getElementById( hTabElement.getAttribute( 'tabview' ) ) + if( hView ) + { + hView.style.display = 'block' + } +} + +cMoTabs.setInactiveTabElement = function( hTabElement ) +{ + if( hTabElement == null ) + { + return + } + hTabElement.className = 'tab' + var hView = document.getElementById( hTabElement.getAttribute( 'tabview' ) ) + if( hView ) + { + hView.style.display = 'none' + } +} + +cMoTabs.doTab = function( e ) +{ + cDomEvent.init( e ) + var hTabElement = null + + if( e.type.indexOf( 'keypress' ) > -1 ) + { + if( e.keyCode != 13 ) + { + return + } + } + + hTabElement = cMoTabs.getTabElement( cDomEvent.target ) + + if ( hTabElement != null ) + { + //var hLink = getSubNodeByName( hTabElement, 'a' ) + //hLink.blur() + var hGroup = cMoTabs.getTabGroup( hTabElement ) + if( hGroup.hAcvtiveElm == null ) + { + var hActiveTab = getSubNodeByProperty( hTabElement.parentNode, 'className', 'tabactive' ) + } + else + { + var hActiveTab = hGroup.hAcvtiveElm + } + if( hActiveTab == hTabElement ) + { + } + else + { + cMoTabs.setInactiveTabElement( hActiveTab ) + cMoTabs.setActiveTabElement( hTabElement ) + hGroup.hAcvtiveElm = hTabElement + } + } + return true +} + +cMoTabs.doTabClick = function( e ) +{ + cDomEvent.init( e ) + if( e.preventDefault ) + { + e.preventDefault() + } + e.cancelBubble = false + e.returnValue = false + return false +} + +cMoTabs.init = function( hListItem ) +{ + var hLink = getSubNodeByName( hListItem, 'a' ) + cDomEvent.addEvent( hLink, 'activate', cMoTabs.doTab, false ) + cDomEvent.addEvent( hLink, 'focus', cMoTabs.doTab, false ) + cDomEvent.addEvent( hLink, 'mousedown', cMoTabs.doTab, false ) + cDomEvent.addEvent( hLink, 'keypress', cMoTabs.doTab, false ) + cDomEvent.addEvent( hLink, 'click', cMoTabs.doTabClick, false ) +} + + +cDomExtensionManager.register( new cDomExtension( document, [ "li[tabview]" ], cMoTabs.init ) ) diff --git a/autocomplete/js/xmlextras.js b/autocomplete/js/xmlextras.js new file mode 100644 index 0000000..0c3cec0 --- /dev/null +++ b/autocomplete/js/xmlextras.js @@ -0,0 +1,149 @@ +//<script>
+//////////////////
+// Helper Stuff //
+//////////////////
+
+// used to find the Automation server name
+function getDomDocumentPrefix() {
+ if (getDomDocumentPrefix.prefix)
+ return getDomDocumentPrefix.prefix;
+
+ var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
+ var o;
+ for (var i = 0; i < prefixes.length; i++) {
+ try {
+ // try to create the objects
+ o = new ActiveXObject(prefixes[i] + ".DomDocument");
+ return getDomDocumentPrefix.prefix = prefixes[i];
+ }
+ catch (ex) {};
+ }
+
+ throw new Error("Could not find an installed XML parser");
+}
+
+function getXmlHttpPrefix() {
+ if (getXmlHttpPrefix.prefix)
+ return getXmlHttpPrefix.prefix;
+
+ var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
+ var o;
+ for (var i = 0; i < prefixes.length; i++) {
+ try {
+ // try to create the objects
+ o = new ActiveXObject(prefixes[i] + ".XmlHttp");
+ return getXmlHttpPrefix.prefix = prefixes[i];
+ }
+ catch (ex) {};
+ }
+
+ throw new Error("Could not find an installed XML parser");
+}
+
+//////////////////////////
+// Start the Real stuff //
+//////////////////////////
+
+
+// XmlHttp factory
+function XmlHttp() {}
+
+XmlHttp.create = function () {
+ try {
+ if (window.XMLHttpRequest) {
+ var req = new XMLHttpRequest();
+
+ // some versions of Moz do not support the readyState property
+ // and the onreadystate event so we patch it!
+ if (req.readyState == null) {
+ req.readyState = 1;
+ req.addEventListener("load", function () {
+ req.readyState = 4;
+ if (typeof req.onreadystatechange == "function")
+ req.onreadystatechange();
+ }, false);
+ }
+
+ return req;
+ }
+ if (window.ActiveXObject) {
+ return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
+ }
+ }
+ catch (ex) {}
+ // fell through
+ throw new Error("Your browser does not support XmlHttp objects");
+};
+
+// XmlDocument factory
+function XmlDocument() {}
+
+XmlDocument.create = function () {
+ try {
+ // DOM2
+ if (document.implementation && document.implementation.createDocument) {
+ var doc = document.implementation.createDocument("", "", null);
+
+ // some versions of Moz do not support the readyState property
+ // and the onreadystate event so we patch it!
+ if (doc.readyState == null) {
+ doc.readyState = 1;
+ doc.addEventListener("load", function () {
+ doc.readyState = 4;
+ if (typeof doc.onreadystatechange == "function")
+ doc.onreadystatechange();
+ }, false);
+ }
+
+ return doc;
+ }
+ if (window.ActiveXObject)
+ return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
+ }
+ catch (ex) {}
+ throw new Error("Your browser does not support XmlDocument objects");
+};
+
+// Create the loadXML method and xml getter for Mozilla
+if (window.DOMParser &&
+ window.XMLSerializer &&
+ window.Node && Node.prototype && Node.prototype.__defineGetter__) {
+
+ // XMLDocument did not extend the Document interface in some versions
+ // of Mozilla. Extend both!
+ //XMLDocument.prototype.loadXML =
+ Document.prototype.loadXML = function (s) {
+
+ // parse the string to a new doc
+ var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
+
+ // remove all initial children
+ while (this.hasChildNodes())
+ this.removeChild(this.lastChild);
+
+ // insert and import nodes
+ for (var i = 0; i < doc2.childNodes.length; i++) {
+ this.appendChild(this.importNode(doc2.childNodes[i], true));
+ }
+ };
+
+
+ /*
+ * xml getter
+ *
+ * This serializes the DOM tree to an XML String
+ *
+ * Usage: var sXml = oNode.xml
+ *
+ */
+ // XMLDocument did not extend the Document interface in some versions
+ // of Mozilla. Extend both!
+ /*
+ XMLDocument.prototype.__defineGetter__("xml", function () {
+ return (new XMLSerializer()).serializeToString(this);
+ });
+ */
+ Document.prototype.__defineGetter__("xml", function () {
+ return (new XMLSerializer()).serializeToString(this);
+ });
+}
\ No newline at end of file |