summaryrefslogtreecommitdiffstats
path: root/autocomplete/js
diff options
context:
space:
mode:
Diffstat (limited to 'autocomplete/js')
-rw-r--r--autocomplete/js/acdropdown.js1622
-rw-r--r--autocomplete/js/getobject2.js126
-rw-r--r--autocomplete/js/ieselect.js85
-rw-r--r--autocomplete/js/modomevent3.js189
-rw-r--r--autocomplete/js/modomext.js219
-rw-r--r--autocomplete/js/modomt.js259
-rw-r--r--autocomplete/js/shBrushJScript.js22
-rw-r--r--autocomplete/js/shBrushXml.js61
-rw-r--r--autocomplete/js/shCore.js589
-rw-r--r--autocomplete/js/tabs2.js124
-rw-r--r--autocomplete/js/xmlextras.js149
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>&copy;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, '&lt;');
+
+ 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, '&lt;');
+
+ 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, '&amp;');
+ str = str.replace(/ /g, '&nbsp;');
+ str = str.replace(/</g, '&lt;');
+ str = str.replace(/\n/gm, '&nbsp;<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('&nbsp;<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