/**
* @constructor
* @param input Reference to watched input element. Text input expected.
* @param callBack Event handler. Function will be called on input change. Current value of input will be passed as 1st argument.
* @param object Set variable this in called event handler, if event handler is non-static.
* @param interval Set watch interval. Default is 200ms.
* @class Instance of InputWatch watches input element and call event handler on input change.
*/
function InputWatch(input, callBack, object, interval) {
if (interval==undefined)
// 200ms interval by default
interval = 200;
/** @private */ this.input = input;
/** @private */ this.callBack = callBack;
/** @private */ this.object = object;
/** @private */ this.lastVal = this.input.value;
var cbInternal = function() {
var val = this.input.value;
if (val != this.lastVal) {
this.lastVal = val;
this.callBack.call(this.object, val);
}
}
var cbInternalWrapper = function() {
cbInternal.call(arguments.callee.object);
}
cbInternalWrapper.object = this;
window.setInterval(cbInternalWrapper, interval);
}
/**
* @constructor
* @param searchStr Sting to search.
* @class Search text in text.
*/
function SearchEngine(searchStr) {
/**
* Escape regular expressions in text
* @param text Text to escape.
* @return Escaped text.
* @type String
* @private
*/
SearchEngine.prototype.escapeRegExp = function(text) {
text = text.replace(/\\/g, '\\\\');
text = text.replace(/\^/g, '\\^');
text = text.replace(/\$/g, '\\$');
text = text.replace(/\./g, '\\.');
text = text.replace(/\*/g, '\\*');
text = text.replace(/\+/g, '\\+');
text = text.replace(/\?/g, '\\?');
text = text.replace(/\=/g, '\\=');
text = text.replace(/\!/g, '\\!');
text = text.replace(/\:/g, '\\:');
text = text.replace(/\|/g, '\\|');
text = text.replace(/\//g, '\\/');
text = text.replace(/\(/g, '\\(');
text = text.replace(/\)/g, '\\)');
text = text.replace(/\[/g, '\\[');
text = text.replace(/\]/g, '\\]');
text = text.replace(/\{/g, '\\{');
text = text.replace(/\}/g, '\\}');
return text;
}
/**
* @private
*/
SearchEngine.prototype.escapePunctation = function(text) {
text = text.replace(/[aá]/g, '[aá]');
text = text.replace(/[cč]/g, '[cč]');
text = text.replace(/[dď]/g, '[dď]');
text = text.replace(/[eéě]/g, '[eéě]');
text = text.replace(/[ií]/g, '[ií]');
text = text.replace(/[nň]/g, '[nň]');
text = text.replace(/[oó]/g, '[oó]');
text = text.replace(/[rř]/g, '[rř]');
text = text.replace(/[sš]/g, '[sš]');
text = text.replace(/[tť]/g, '[tť]');
text = text.replace(/[uúů]/g, '[uúů]');
text = text.replace(/[yý]/g, '[yý]');
text = text.replace(/[zž]/g, '[zž]');
return text;
}
/** @private */ this.empty = (searchStr==undefined || searchStr.length==0);
if (!this.empty) {
var pattern = searchStr;
pattern = this.escapeRegExp(pattern); // Escape special chars
pattern = this.escapePunctation(pattern); // Escape punctation
pattern = '('+pattern+')'; // Mark re subgroup (for substitutions)
/** @private */ this.re = new RegExp(pattern, 'gi');
}
/**
* Search pattern in given text.
* @param text Text to search in.
* @return Return true if pattern was matched.
* @type bool
*/
SearchEngine.prototype.isMatch = function(text) {
return !this.empty && (-1!= text.search(this.re));
}
}
/**
* @constructor
* @class Experimental! Will be documented later.
*/
function SearchEngineChain(searchStr) {
/** @private */ this.list = new Array();
// Decomposite input to words using white spaces as separator
var decomp = searchStr.split(/ +/);
for (var i=0; iXMLHttp object.
* (browser independency layer)
* @return Return instance of XMLHttp object
*/
function createXmlHttp() {
var xmlHttp = null;
try {
xmlHttp = new XMLHttpRequest();
}
catch(e) {
try {
xmlHttp = new ActiveXObject('Microsoft.XMLHttp');
}
catch(e) { }
}
return xmlHttp;
}
/**
* Define DOM element's innerText property
* if not already defined.
* (browser independency layer)
*/
function patchInnerText() {
if(typeof(HTMLElement) == "undefined" || typeof(document.documentElement.innerText) == "string")
return;
HTMLElement.prototype.__defineSetter__("innerText", function(text) {
while (this.hasChildNodes())
this.removeChild(this.firstChild);
this.appendChild(document.createTextNode(text));
});
HTMLElement.prototype.__defineGetter__("innerText", function() {
return this.textContent;
});
}
/**
* Dump object content to #jsLog block on page.
* (useful for debug purposes)
*/
function dump(object) {
if (null==object)
return;
log = document.getElementById('jsLog');
if (null==log)
return;
var h1 = document.createElement('h1');
h1.innerHTML = 'Dump';
log.appendChild(h1);
var text = new String;
for(tmp in object)
text += '' + tmp + ': ' + object[tmp] + '
\n';
var p = document.createElement('p');
p.innerHTML = text;
log.appendChild(p);
}
/**
* @constructor
* @class Experimental! Will be documented later.
*/
function PropStorage(obj, propList) {
/** @private */ this.map = new Object;
for (var i=0; i