rbrindley: branch rbrindley/astman_revamp r4526 - /team/rbrindley/astman_reva...

SVN commits to the Asterisk-GUI project asterisk-gui-commits at lists.digium.com
Thu Feb 19 14:02:43 CST 2009


Author: rbrindley
Date: Thu Feb 19 14:02:43 2009
New Revision: 4526

URL: http://svn.digium.com/svn-view/asterisk-gui?view=rev&rev=4526
Log:
copied astman.js to astman2.js

Added:
    team/rbrindley/astman_revamp/config/js/astman2.js   (with props)

Added: team/rbrindley/astman_revamp/config/js/astman2.js
URL: http://svn.digium.com/svn-view/asterisk-gui/team/rbrindley/astman_revamp/config/js/astman2.js?view=auto&rev=4526
==============================================================================
--- team/rbrindley/astman_revamp/config/js/astman2.js (added)
+++ team/rbrindley/astman_revamp/config/js/astman2.js Thu Feb 19 14:02:43 2009
@@ -1,0 +1,3157 @@
+/*
+ * Asterisk-GUI	- an Asterisk configuration interface
+ *
+ * Javascript functions for accessing manager over HTTP and Some UI components/functions used in AsteriskGUI.
+ *
+ * Copyright (C) 2006-2008, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ * Pari Nannapaneni <pari at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ *
+ */
+
+_$ = function(x){
+	if ( typeof x != 'string' ){ return null ;}
+	try{
+		return document.getElementById(x); 
+	}catch(err){ return null; }
+};
+
+// Some custom methods to Array Objects
+	Array.prototype.replaceAB = function(a, b) { // return new array with all instances of a replaced with b
+		var x =[];
+		for(var i=0, j = this.length ; i < j; i++ ){
+			if( this[i] === a ){
+				x.push(b);
+			}else{
+				x.push(this[i]);
+			}
+		}
+		return x;
+	};
+
+	Array.prototype.lastValue = function(){
+		// [0,1,2]
+		return (this.length)? this[this.length - 1] : null;
+	};
+
+	Array.prototype.replaceLastWith = function(a){
+		if( this.length )
+			this[this.length - 1] = a ;
+	}
+
+	Array.prototype.contains = function(str) {
+		return this.indexOf(str) != -1 ;
+	};
+
+	Array.prototype.containsLike = function(str) {
+		return this.indexOfLike(str) != -1;
+	};
+	
+	Array.prototype.each = function(iterator) {
+		for(var i=0 , j = this.length; i < j ; i++ ){
+			iterator(this[i] , i);
+		}
+	};
+
+	Array.prototype.forEach = function(iterator) { // call a function on each element and update the element with the returned value
+		var i = this.length;
+		while (i--) {
+			this[i] = iterator(this[i] , i);
+		}
+	};
+	
+	Array.prototype.firstAvailable = function(start) {
+		start = (!start)? 1 : Number( start );
+		if(!this.length)
+			return start;
+		for( var y=0, x=[], z=this.length ; y < z ; y++ ){
+			var NT = Number(this[y]) ;
+			if( NT < start )
+				continue;
+			x.push(NT);
+		}
+		if( !x.length )
+			return start;
+		while(true){
+			if( x.contains(start) ){
+				start++;
+			}else{
+				return start;
+			}
+		}
+	};
+
+	Array.prototype.removeFirst = function(){ // opposite of push - removes the first element of the array
+		this.splice(0,1);
+	};
+
+	Array.prototype.removeLast = function(){ // removes the last element of the array
+		this.pop();
+	};
+	
+	if(!Array.indexOf){
+		Array.prototype.indexOf = function(a){
+			var i = this.length;
+			while (i--) {
+				if( this[i] === a ){
+					return i;
+				}
+			}
+			return -1;
+		}
+	}
+
+	Array.prototype.indexOfLike = function( searchString ){
+		if(!searchString.length){ return -1; }
+		for(var i=0; i < this.length; i++ ){ if( this[i].beginsWith(searchString) ){ return i ; } }
+		return -1 ;
+	};
+
+	Array.prototype.lastIndexOfLike = function( searchString ){
+		if(!searchString.length){ return -1;}
+		var i = this.length;
+		while (i--) {
+			if( typeof this[i] == 'string' && this[i].beginsWith(searchString) ){ return i; }
+		}
+		return -1 ;
+	};
+
+	Array.prototype.push_IfNotPresent = function( a ){
+		if(!this.contains(a)) this.push(a);
+	};
+	
+	Array.prototype.sortNumbers = function() {
+		return this.sort(function(a,b){return a - b});
+	};
+	
+	Array.prototype.withOut = function(e) {
+		var x =[];
+		if( typeof e == 'string' || typeof e == 'number' ){
+			var y = [e];
+		}else if( e instanceof Array ){
+			var y = e;
+		}else{
+			return this;
+		}
+
+		for( var a =0 ; a < y.length ; a++ ){
+			var b = y[a];
+			for( var i=0, j=this.length ; i < j ; i++ ){
+				if( !(this[i] === b) && !y.contains(this[i]) && !x.contains(this[i]) ){
+					x.push(this[i]);
+				}
+			}
+		}
+
+		return x ;
+	};
+
+// String Manipulation, and other custom methods for String Objects
+	String.prototype.addZero = function(){
+		return ( Number(this) < 10)? "0" + this : this;
+	};
+
+	String.prototype.afterChar = function(k){
+		if(k.length > 1){ alert('String.afterChar() should be used with a single character'); return null;}
+		var v = this.indexOf(k);
+		if( v == -1){ return ''; }
+		return this.substring(v+1);
+	};
+
+	String.prototype.afterStr = function(x){
+		if( !this.contains(x) ){ return ''; }
+		if(x.length == 1){ return this.afterChar(x); }
+		var pos = this.indexOf(x) + x.length ;
+		return this.substr(pos);
+	};
+
+	String.prototype.beforeChar = function(k){
+		if(k.length > 1){ 
+			alert('String.beforeChar() should be used with a single character');
+			return null;
+		}
+		var v = this.indexOf(k);
+		if( v == -1){ return ''; }
+		return this.substring(0,v);
+	};
+
+	String.prototype.beforeStr = function(x){
+		var r = this.afterStr(x);
+		return this.withOut(x+r);
+	};
+
+	String.prototype.beginsWith = function(a){
+		return this.length>=a.length && this.substring(0,a.length)==a
+	};
+
+	String.prototype.betweenXY = function(X,Y){
+		if(X.length > 1 || Y.length > 1){ alert('String.betweenXY() accepts single character arguments'); return null;}
+		var t = this.afterChar(X);
+		return t.beforeChar(Y);
+	};
+
+	String.prototype.bold_X = function(x){
+		if(x==''){return this ;}
+		var position = this.toLowerCase().indexOf( x.toLowerCase() ) ;
+		if (position == -1){ return this; }
+		var c = this.substr( position , x.length );
+		return  this.replace( c, "<B>" + c + "</B>" , "" );
+	};
+	
+	String.prototype.camelize = function(){
+	    var parts = this.split(' '), len = parts.length;
+		var camelized = '';
+	    for (var i = 0; i < len; i++)
+	      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1) + ' ';
+	    return camelized;
+	};
+
+	String.prototype.capitalizeFirstChar = function() {
+		return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+	};
+
+	String.prototype.contains=function(a){
+		return this.indexOf(a)!=-1;
+	};
+
+	String.prototype.endsWith=function(a){
+		return this.length >= a.length && this.substring(this.length-a.length)==a
+	};
+
+	String.prototype.escapeHTML = function() {
+		var a = document.createTextNode(this);
+		var b = document.createElement('div');
+		b.appendChild(a);
+		return b.innerHTML;
+	};
+
+	String.prototype.isAstTrue = function () {
+		return ["yes", "true", "y", "t", "1", "on"].contains(this.toLowerCase().trim());
+	};
+
+	String.prototype.getNoOp = function(){
+		return ( this.toLowerCase().indexOf('noop(') == -1 ) ? '' : this.betweenXY('(',')') ; // todo: handle multiple ')'s
+	};
+
+	String.prototype.guiMetaData = function(){
+		return this + ' ; GUI metadata';
+	};
+
+	String.prototype.isValueInBetween = function (a,b) {
+		a = Number(a);
+		b = Number(b);
+		var c = Number(this) , a1 = Math.min(a,b) , b1 = Math.max(a,b);
+		return ( c >= a1 && c <= b1 ) ? true : false ;
+	};
+
+	String.prototype.lChop = function(c){ // chop a string from the beginning of the string
+		if(this.beginsWith(c)){
+			return this.substr(c.length);
+		}
+		return this;
+	};
+
+	String.prototype.rChop = function(c){ // chop a string from the end of the string
+		if( this.indexOf(c) == -1 || !this.endsWith(c) ){
+			return String(this); //actually we should be doing 'return this;' but for some reason firebug is reporting the returned string as an object
+		}
+		return this.substr( 0, this.length - c.length);
+	};
+
+	String.prototype.replaceXY = function(X,Y){
+		return this.split(X).join(Y);
+	};
+
+	String.prototype.nl2br = function(){ // replace new lines with <BR>
+		return this.split('\n').join('<BR>');
+	};
+
+	String.prototype.strip = function(){
+		try {
+			return this.replace(/^\s+|\s+$/g, "");
+		} catch(e) {
+			return s;
+		}
+	};
+
+	String.prototype.times = function(a){
+		return ( a < 1 ) ? '' : new Array(a+1).join(this);
+	};
+
+	String.prototype.stripTags = function() {
+		return this.replace(/<\/?[^>]+>/gi, '');
+	}
+
+	String.prototype.trim = function(){ // alias to strip
+		return this.strip();
+	};
+
+	String.prototype.withOut = function(k){
+		return this.split(k).join('');
+	};
+
+
+Number.prototype.addZero = function(){
+	return ( this < 10)? "0" + String(this) : String(this);
+};
+
+Number.prototype.isValueInBetween = function (a,b) {
+	a = Number(a);
+	b = Number(b);
+	var a1 = Math.min(a,b) , b1 = Math.max(a,b);
+	return ( this >= a1 && this <= b1 ) ? true : false ;
+};
+
+Number.prototype.guiMetaData = function(){
+	return String(this) + ' ; GUI metadata';
+};
+
+// The ASTGUI Object - global varibles and various core GUI component functions
+var ASTGUI = {
+	includeContexts: [], // updated below
+
+	globals: {
+		providerUrl: './js/providers.js', // ASTGUI.globals.providerUrl
+		firmwareVersionUrl: 'https://gui-dl.digium.com/aa50/fw_version.js', // ASTGUI.globals.firmwareVersionUrl
+		appname : 'Asterisk GUI',
+		lang : 'en',
+		GUI_DB : 'astgui', // name of the ASTDB database used by GUI -- ASTGUI.globals.GUI_DB
+		msg_notLoggedIn: 'Message: Authentication Required',
+		configfile : 'guipreferences.conf', // will be created if the file does not exist , ASTGUI.globals.configfile
+		g729RegInfo: 'g729reginfo.conf', // ASTGUI.globals.g729RegInfo, the sessionData.directories.script_Registerg729 script will read this file to generate tab delimited file
+		hwcfgFile: 'gui_confighw.conf', // file to store configured hardware information, to detect hardware changes
+		dahdiIncludeFile: 'dahdi_guiread.conf', // file that will be used to read zaptel.conf or dahdi/system.conf , ASTGUI.globals.dahdiIncludeFile
+		dahdiScanOutput: 'dahdi_scan.conf', // file that will be used to read output from ztscan or dahdi_scan, ASTGUI.globals.dahdiScanOutput
+		pingInterval : 5000,
+		app_factoryReset : '/bin/reset_config', // ASTGUI.globals.app_factoryReset
+		fnf : 'ERROR:FNF',
+		obcidstr : 'GLOBAL_OUTBOUNDCID', // ASTGUI.globals.obcidstr
+		obcidNamestr : 'GLOBAL_OUTBOUNDCIDNAME', // ASTGUI.globals.obcidNamestr
+		obcidUsrPrefix : 'CID_', // ASTGUI.globals.obcidUsrPrefix
+		sbcid_1 : 's,1,ExecIf($[ "${CALLERID(num)}"="" ],SetCallerPres,unavailable)', // ASTGUI.globals.sbcid_1
+		sbcid_2 : 's,2,ExecIf($[ "${CALLERID(num)}"="" ],Set,CALLERID(all)=unknown <0000000>)',
+		timeservers: [ 'north-america.pool.ntp.org', 'asia.pool.ntp.org', 'europe.pool.ntp.org', 'oceania.pool.ntp.org', 'south-america.pool.ntp.org' ],
+		version : '2.0' // gui version
+	},
+
+	contexts: {
+		guitools : 'asterisk_guitools', // gui tools context
+		dialtrunks : 'trunkdial-failover-0.3', // trunkdial macro with failback trunk and setcid, ASTGUI.contexts.dialtrunks
+		CONFERENCES : 'conferences', // ASTGUI.contexts.CONFERENCES
+		QUEUES : 'queues', //ASTGUI.contexts.QUEUES
+		TrunkDIDPrefix : 'DID_', // context for trunks -  - ASTGUI.contexts.TrunkDIDPrefix 
+		TrunkDefaultSuffix : '_default', // ASTGUI.contexts.TrunkDefaultSuffix - to create 'DID_trunk_default' that will be included in [DID_trunk]
+		RingGroupPrefix: 'ringroups-custom-', // ASTGUI.contexts.RingGroupPrefix 
+		RingGroupExtensions: 'ringgroups', // ASTGUI.contexts.RingGroupExtensions
+		PageAnExtension :'page_an_extension', // ASTGUI.contexts.PageAnExtension
+		PageGroups : 'pagegroups', // ASTGUI.contexts.PageGroups
+		TimeBasedRulePrefix: 'timebasedrule-custom-', // ASTGUI.contexts.TimeBasedRulePrefix 
+		TimeIntervalPrefix: 'timeinterval_', // ASTGUI.contexts.TimeIntervalPrefix
+		VoiceMenuPrefix: 'voicemenu-custom-', // ASTGUI.contexts.VoiceMenuPrefix
+		VoiceMenuExtensions: 'voicemenus', // ASTGUI.contexts.VoiceMenuExtensions
+		VoiceMailGroups: 'voicemailgroups', // ASTGUI.contexts.VoiceMailGroups
+		Directory: 'directory', // ASTGUI.contexts.Directory
+		CallingRulePrefix : 'CallingRule_', // context for calling rules being with - ASTGUI.contexts.CallingRulePrefix 
+		CallingPlanPrefix: 'DLPN_', // context for DialPlans -- ASTGUI.contexts.CallingPlanPrefix
+		gtalkIncomingContext: 'gtalk_incoming_', // ASTGUI.contexts.gtalkIncomingContext
+		skypeIncomingContext: 'skype_incoming_', // ASTGUI.contexts.skypeIncomingContext
+		mohdirPrefix : 'guimohdir_' // ASTGUI.contexts.mohdirPrefix
+		// music on hold directories created by gui will have this prefix
+		// also post_mappings definitions in http.conf will have this name
+	},
+
+	errorCodes:{
+		'AG101':'Aborting Upload : Action not defined for upload Form <BR>' + 
+			'Please set the Form action in the parent page via onUploadForm_beforeUploading()',
+		'AG102':'Disabling all Upload forms in the gui: <BR>' +
+			'Either post_mappings or post_mappings->uploads is not defined in http.conf',
+		'AG150':' SyncActions being used for more than 5 actions'
+	},
+
+	ASTDB:{
+		updateKey : function( k ){ 
+			// ASTGUI.ASTDB.updateKey( { dbname: 'astgui', key : 'keyname', keyvalue : 'keyvalue' } );
+			// dbname is optional, defaults to ASTGUI.globals.GUI_DB
+			// 	returns true if success, false otherwise
+			if( !k.hasOwnProperty('dbname') ){
+				k.dbname = ASTGUI.globals.GUI_DB ;
+			}
+
+			var s = ASTGUI.cliCommand('database put '+ k.dbname + ' ' + k.key + ' ' + k.keyvalue );
+			if(s.contains('successfully')) return true;
+			return false;
+		},
+
+		deleteKey : function( k ){
+			// ASTGUI.ASTDB.deleteKey( { dbname: 'astgui', key : 'keyname' } );
+			// dbname is optional, defaults to ASTGUI.globals.GUI_DB
+			// 	returns true if success, false otherwise
+			if( !k.hasOwnProperty('dbname') ){
+				k.dbname = ASTGUI.globals.GUI_DB ;
+			}
+
+			var s = ASTGUI.cliCommand('database del '+ k.dbname + ' ' + k.key);
+			if(s.contains('entry removed')) return true;
+			return false;
+		},
+
+
+		getKey : function(k){
+			// ASTGUI.ASTDB.getKey( { dbname: 'astgui', key : 'keyname' } );
+			// dbname is optional, defaults to ASTGUI.globals.GUI_DB
+			// returns null if key is not found, otherwise returns the key-value 
+			if( !k.hasOwnProperty('dbname') ){
+				k.dbname = ASTGUI.globals.GUI_DB ;
+			}
+
+			var s = ASTGUI.cliCommand('database get '+ k.dbname + ' ' + k.key);
+			if( s.contains('entry not found')) return null;
+			var op = ASTGUI.parseCLIResponse( s );
+			op = op.trim();
+			op = op.withOut('Value:')
+			return op.trim();
+		},
+
+		getAllKeys : function(k){
+			// ASTGUI.ASTDB.getAllKeys( { dbname: 'astgui' } );
+			// dbname is optional, defaults to ASTGUI.globals.GUI_DB
+			// returns an object with all the keys in the database as properties and key-values as propertyvalues
+			// returns a null if database not found
+
+			if( !k.hasOwnProperty('dbname') ){
+				k.dbname = ASTGUI.globals.GUI_DB ;
+			}
+
+			var db_keys = {};
+			var tmp_dbpath = '/' + k.dbname + '/' ;
+			var s = ASTGUI.cliCommand('database show '+ k.dbname);
+
+			if(s.contains('entry not found')) return null;
+			var op = ASTGUI.parseCLIResponse( s );
+			if( op.trim() == ''){ return {}; }
+
+			var tmp_lines = op.trim().split('\n');
+			tmp_lines.each( function(this_line){
+				var this_line = this_line.withOut(tmp_dbpath);
+				var this_key = this_line.beforeChar(':').trim();
+				var this_keyVal = this_line.afterChar(':').trim();
+				db_keys[ this_key ] =  this_keyVal ;
+			});
+
+			return db_keys;
+		}
+	},
+
+	checkRequiredFields: function( fields ){
+		// fields is an array of fieldnames or elements
+		if(!ASTGUI.isArray(fields)){
+			return true;
+		}
+		for(var g=0; g < fields.length ; g++ ){
+			var field = fields[g];
+			if(typeof field =='string'){
+				field = _$(field); 
+			}
+			var required = $(field).attr('required');
+			if( required && required.isAstTrue() ){
+				var x = field.value.trim() ;
+				var pcn = ( field.className ) ? field.className : '' ;
+				if( !x ){
+					ASTGUI.feedback( { msg:'Required Field', showfor:2 } );
+					field.className = 'inputValidationFailed';
+					setTimeout( function(){ field.className = pcn ; } , 4000 );
+					try{ field.focus(); }catch(e){}
+					return false;
+				}
+			}
+		}
+		return true;
+	},
+
+	cliCommand : function(cmd) { 
+		// ASTGUI.cliCommand(cmd);
+		//	Execute an asterisk CLI command and return the output
+		if( typeof cmd != 'string' ) {
+			ASTGUI.Log.Warn( 'cliCommand: Expecting cmd as String' );
+			return '';
+		}
+		ASTGUI.Log.Debug("Executing manager command : '" + cmd + "'");
+		return makeSyncRequest ( { action :'command', command: cmd } );
+	},
+
+	getUser_DeviceStatus : function( usr ){ 
+		// ASTGUI.getUser_DeviceStatus(usr) 
+		//	Get the DeviceStatus for a UserExtension
+		if( typeof usr == 'number' ) usr = String(usr);
+		if( typeof usr != 'string' ){
+			ASTGUI.Log.Warn( 'getUser_DeviceStatus: Expecting usr as String' );
+			return 'U';
+		}
+		var t = makeSyncRequest({ action :'ExtensionState', Exten: usr }) ;
+		if( t.contains('Status: 0') ) return 'F' ; // No Device is Busy/InUse
+		if( t.contains('Status: 1') ) return 'B' ; // 1 or more devices InUse
+		if( t.contains('Status: 2') ) return 'B' ; // All Devices Busy
+		if( t.contains('Status: 4') ) return 'U' ; // All Devices Unavailable/Unregistered
+		if( t.contains('Status: 8') ) return 'R' ; // All Devices Ringing
+		return null;
+	},
+
+	getUser_DeviceStatus_Image : function( usr ){
+		// ASTGUI.getUser_DeviceStatus_Image(usr) 
+		//	Get the DeviceStatus Image for a UserExtension
+		var s =  this.getUser_DeviceStatus(usr) ;
+		switch(s){
+			case 'F': // No Device is Busy/InUse
+				return "<img src='images/status_green.png' border=0>";
+				break ;
+			case 'B': // Busy
+				return "<img src='images/status_red.png' border=0>";
+				break ;
+			case 'R': // Ringing
+				return "<img src='images/status_orange.png' border=0>";
+				break ;
+			case 'U': // UnAvailable
+			default :
+				return "<img src='images/status_gray.png' border=0>";
+				break ;
+		}
+	},
+
+	mailboxCount : function(mbox){
+		// ASTGUI.mailboxCount(mbox)
+		//	returns the number of New/Old Voicemail Messages for a user
+		//	returns an object "{count_new: 1, count_old: 2}"
+
+		var tr = { count_new:0 , count_old : 0 };
+		if( typeof mbox == 'number' ) mbox = String(mbox);
+		if( typeof mbox != 'string' ){
+			ASTGUI.Log.Warn( 'mailboxCount: Expecting mbox as String' );
+			return tr;
+		}
+		if(!mbox.contains('@')){ mbox = mbox + '@default' ; }
+		var t = makeSyncRequest ( { action :'MailboxCount', Mailbox: mbox } );
+		try{
+			var lines = t.split('\n');
+			lines.each(function( this_line){
+				if(!this_line.contains('Messages:') ) return;
+				this_line = this_line.trim();
+				if( this_line.contains('NewMessages:') ){
+					tr.count_new = Number(this_line.afterChar(':').trim());
+				}
+				if( this_line.contains('OldMessages:') ){
+					tr.count_old = Number(this_line.afterChar(':').trim());
+				}
+			});
+		}finally{
+			return tr;
+		}
+	},
+
+	doTransfer : function(from, to) {
+		// ASTGUI.doTransfer(from, to)
+		//	issue channel redirect
+		ASTGUI.Log.Debug("About to transfer " + from + " to " + to);
+		return makeSyncRequest ( { action :'redirect', channel :from, exten :to, context :'default', priority :'1' } );
+	},
+
+	doHangup : function(chan) {
+		// ASTGUI.doHangup(chan)
+		//	Hangsup a given channel
+		ASTGUI.Log.Debug("Executing hangup on channel : '" + chan + "'");
+		return makeSyncRequest ( { action :'hangup', channel: chan } );
+	},
+
+	cookies: {
+		getCookie: function(x){ // ASTGUI.cookies.getCookie('username')
+			var ck = top.document.cookie; // mansession_id="6f3fadcb"; username=admin
+			if( ck.indexOf( x + '=' ) == -1 ){
+				return '';
+			}
+			var cookies = ck.split(';');
+			for(var y=0; y < cookies.length; y++){
+				cookies[y] = cookies[y].strip();
+				if( cookies[y].beginsWith(x +'=') ){
+					return cookies[y].split( x + '=' )[1] ;
+				}
+			}
+			return '';
+		},
+
+		setCookie: function(x , y){ // ASTGUI.cookies.setCookie( 'something' , 'valueofSomething' );
+			var tmp = x + '=' + y + '; path = /' ;
+			top.document.cookie = tmp;
+		},
+
+		removeCookie: function(x){
+			top.document.cookie = x + '=somevalue; expires=Fri, 22 Oct 1999 00:00:00 UTC; path=/' ;
+		},
+
+		clearCookies: function(){  // ASTGUI.cookies.clearCookies()
+			top.document.cookie = '';
+		}
+	},
+
+	cloneObject: function(a){ // ASTGUI.cloneObject(obj)
+		if(ASTGUI.isArray(a)){
+			return [].concat(a);
+		}
+		if( typeof a != 'object' ){
+			return a;
+		}
+		var b = new ASTGUI.customObject ;
+		for( var i in a ){
+			if( a.hasOwnProperty(i) ){
+				b[i] = ASTGUI.toCustomObject( a[i] );
+			}
+		}
+		return b;
+	},
+
+	CODECSLIST: {
+		getSelectedCodecs : function(el){ // ASTGUI.CODECSLIST.getSelectedCodecs(el);
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			var s = [];
+			el.CODECS_SELECTEDORDER.each(function(codec){
+				var t = codec.trim();
+				if(t != ''){ s.push(codec); }
+			});
+			return s.join(',') ;
+		},
+
+		populateCodecsList : function(el){ // ASTGUI.CODECSLIST.populateCodecsList(el);
+		// create codecs check boxes inside el and bind events to each checkbox such that the selected codecs 
+			var r =  'codecs_chkbx_class' + Math.round( 10000 * Math.random() );
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			el.checkboxClass = r;
+			el.CODECS_SELECTEDORDER = [];
+			ASTGUI.domActions.populateCheckBoxes(el , parent.sessionData.listOfCodecs , r);
+			$('.' + r).click(
+				function() {
+					if(this.checked){
+						el.CODECS_SELECTEDORDER.push(this.value);
+						return;
+					}
+					var t = el.CODECS_SELECTEDORDER.withOut(this.value);
+					el.CODECS_SELECTEDORDER = t ;
+					return ;
+				}
+			);
+		},
+
+		selectCodecs : function(el, codecs){ // ASTGUI.CODECSLIST.selectCodecs(el, codecs);
+			// el is the element in which codec checkboxes are populated, codecs is the codecs string
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			if( codecs == 'all' ){
+				ASTGUI.domActions.CheckAll(el.checkboxClass);
+				el.CODECS_SELECTEDORDER = ASTGUI.domActions.get_checked(el.checkboxClass);
+			}else{
+				if( codecs.trim() == '' ){
+					el.CODECS_SELECTEDORDER = [] ;
+				}else{
+					el.CODECS_SELECTEDORDER = ( codecs.contains(',') ) ? codecs.split(',') : codecs;
+				}
+				ASTGUI.domActions.checkSelected( el.checkboxClass , el.CODECS_SELECTEDORDER ) ;
+			}
+		}
+	},
+
+	COMBOBOX: function (a,w){		// Usage - ASTGUI.COMBOBOX.call( element , OptionsArray, width(Optional)  );
+		// this.comboDiv - the div element created
+		// this.comboOptions - the array of options
+		var e = this;
+		$(e).autocomplete(a, { width: w } );
+	},
+
+	customObject : function(){
+		//	eliminates the need of 'hasOwnProperty' to read this objects propeties, look for this objects prototype below.
+		if ( !(this instanceof ASTGUI.customObject) ) { return new ASTGUI.customObject(); }
+	},
+
+	TABLE : function(a){
+		if(!a) return;
+		if ( !(this instanceof ASTGUI.TABLE) ) { return new ASTGUI.TABLE(a); }
+		this.TableElement = ( typeof a == 'string' ) ? _$(a) : a ;
+		this.TableRow = null ;
+	},
+
+	toCustomObject : function(a){// if a is a native object returns an ASTGUI.customObject version of a
+		if( ASTGUI.isArray(a) || a === null || typeof a =='number' || typeof a =='string' || typeof a =='boolean' || typeof a != 'object' ) return a;
+
+		var b = new ASTGUI.customObject ;
+		for( var i in a ){ if( a.hasOwnProperty(i) ){
+			b[i] = ASTGUI.toCustomObject( a[i] );
+		}}
+		return b;
+	},
+
+	Log: {
+		doLog: function(msg, color){
+			if(!top.sessionData.DEBUG_MODE ){ return true; }
+			if( typeof msg == 'object' ){
+				msg = 'OBJECT : ' + ASTGUI.getObjectPropertiesAsString(msg) ;
+			}
+
+			var now = new Date();
+			var h = now.getHours().addZero() + ':' + now.getMinutes().addZero() + ':' + now.getSeconds().addZero() ;
+			if( top.sessionData.DEBUG_LOG.length > 250 ){
+				top.sessionData.DEBUG_LOG = top.sessionData.DEBUG_LOG.slice(0,50);
+			}
+			top.sessionData.DEBUG_LOG.unshift( h + ' <font color='+ color +'>' + msg + '</font>' );
+		},
+
+		Ajax: function(msg){ // ASTGUI.Log.Ajax(msg);
+			if ( top.sessionData.DEBUG_WHICH.Ajax == true ) this.doLog( msg , '#96997C' );
+		},
+
+		Debug: function( msg ){ // ASTGUI.Log.Debug();
+			if ( top.sessionData.DEBUG_WHICH.Debug == true ) this.doLog( msg , '#4C9996' );
+		},
+
+		Error: function( msg ){ // ASTGUI.Log.Error();
+			if( !msg || !top.sessionData || !top.sessionData.DEBUG_WHICH.Error ) return;
+			if( msg.length <=5 && ASTGUI.errorCodes[msg] ){
+				this.doLog( '<B>' + ASTGUI.errorCodes[msg] + '</B>' , '#992b23' );
+			}else{
+				this.doLog( '<B>' + msg + '</B>' , '#992b23' );
+			}
+		},
+
+		Console: function( msg ){ // ASTGUI.Log.Console();
+			if( top.sessionData.DEBUG_WHICH.Console == true && window.console && window.console.firebug ) console.log ( msg );
+		},
+
+		Info: function( msg ){ // ASTGUI.Log.Info(msg);
+			if( top.sessionData.DEBUG_WHICH.Info == true ) this.doLog( msg , '#9A9A9A' );
+		},
+
+		Warn: function( msg ){ // ASTGUI.Log.Warn( msg );
+			if( top.sessionData.DEBUG_WHICH.Warn == true ) this.doLog( msg , '#F47A00' );
+		}
+	},
+
+	dialog : {
+		defaultMessage : 'Loading ...',
+		load_iframe : function(msg){
+			top.alertframename = "alertiframe" ;
+			top.alertmsg = msg ;
+			var h,_hs;
+			if( !top.document.getElementById(top.alertframename)){
+				h= top.document.createElement("IFRAME");
+				h.setAttribute("id", top.alertframename );
+				h.setAttribute("ALLOWTRANSPARENCY", "true");
+				_hs = h.style ;
+				_hs.position="absolute";
+				_hs.left= 0;
+				_hs.top= 0;
+				_hs.width= '100%';
+				_hs.height= '100%';
+				_hs.zIndex = 9999 ;
+				h.src = "guialert.html" ;
+				h.frameBorder="0";
+				h.scrolling="no";
+				_hs.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=90)';
+				//h.style.MozOpacity = .90;
+				top.document.body.appendChild(h);
+			}else{
+				top.document.getElementById( top.alertframename ).contentWindow.update( );
+				top.document.getElementById( top.alertframename ).style.display = "";
+			}
+		},
+
+		waitWhile : function(msg){
+			// ASTGUI.dialog.waitWhile('Saving...');
+			//	use this dialog when you want to inform the user about an action in progress - Ex: 'Saving...' or 'Applying CHanges..' or 'Reloading Asteisk...' etc
+			if ( typeof msg != 'string') return;
+			top.alertmsgtype = 2 ;
+			this.load_iframe(msg);
+		},
+
+		alertmsg : function(msg){
+			// ASTGUI.dialog.alertmsg('Some Alert Message');
+			//	Display custom alert message with an 'Ok' button	
+			if ( typeof msg != 'string') return;
+			top.alertmsgtype = 1 ;
+			this.load_iframe(msg);
+		},
+
+		hide : function(){
+			// ASTGUI.dialog.hide();
+			// Hide the dialog message, use this when you want to hide the 'waitWhile' message
+			try{
+				top.document.getElementById( top.alertframename ).style.display = "none";
+			} catch (err){ }
+		},
+
+		show : function(){
+			try{
+				top.document.getElementById( top.alertframename ).style.display = '';
+			} catch (err){ }
+		}
+	},
+
+	domActions: {
+		alignBbelowA: function(a,b, offsetLeft, offsetTop ){
+			// ASTGUI.domActions.alignBbelowA( element1, element2 )
+			//	Moves/Aligns Element-B below Element-A
+			//	You can further control the position by sending additional offset parameters (optional)
+			try{
+			if ( typeof a == 'string'){ a = _$(a) ; }
+			if ( typeof b == 'string'){ b = _$(a) ; }
+			b.style.position = 'absolute';
+			var tmp_left = a.offsetLeft;
+			var tmp_top = a.offsetTop + a.offsetHeight;
+			var tmp_parent = a;
+	
+			while(tmp_parent.offsetParent != document.body){
+				tmp_parent = tmp_parent.offsetParent;
+				tmp_left += tmp_parent.offsetLeft;
+				tmp_top += tmp_parent.offsetTop;
+			}
+			b.style.left = tmp_left + ( offsetLeft || 0 );
+			b.style.top = tmp_top + (offsetTop || 1);
+			}catch(err){
+				ASTGUI.Log.Error(err.description);
+			}
+		},
+
+		alignBontopofA: function(a,b){
+			// ASTGUI.domActions.alignBontopofA();
+			//	set Element-B's co-ordinates to those of Element-A
+			try{
+				if ( typeof a == 'string'){ a = _$(a) ; }
+				if ( typeof b == 'string'){ b = _$(b) ; }
+				ASTGUI.domActions.alignBbelowA(a,b);
+				b.style.top = b.style.top - a.offsetHeight ;
+			}catch(err){
+				ASTGUI.Log.Error(err.description);
+			}
+		},
+
+		CheckAll: function(x){ // check all checkboxes of class x - ASTGUI.domActions.CheckAll();
+			var y = $("." + x) ;
+			for(var g=0, h = y.length; g < h; g++){
+				y[g].checked = true;
+			}
+		},
+
+		disableAllofClass: function(x){ // disable all fields of class x
+			var y = $("." + x) ;
+			for(var g=0, h = y.length; g < h; g++){
+				y[g].disabled = true;
+			}
+		},
+
+		checkIf_isAstTrue: function(el, str){ // ASTGUI.domActions.checkIf_isAstTrue(el,str);
+			if ( typeof str != 'string' ){ return; }
+			if ( typeof el == 'string' ){ el = _$(el); }
+			el.checked = ( str.isAstTrue() ) ? true:false ;
+		},
+
+		checkSelected: function(x,y){ // ASTGUI.domActions.checkSelected( 'class', [val1,val2,...]);
+			// x is class of checkboxes, y is an array of values, this functions checks a checkbox if it its value is present in array 'y'
+			//try{
+				var y_copy = ASTGUI.cloneObject(y);
+				var chbs = $( "." + x ) ; //jquery selector
+				for( var g=0, h = chbs.length; g < h  ; g++ ) {
+					chbs[g].checked = ( y_copy.contains(chbs[g].value) ) ? true : false;
+				}
+			//}catch(err){ }
+		},
+
+		disableSelected: function(x,y){	// disable some fields (whose "values" (not names or ids) are in array y), of class x 
+			// ASTGUI.domActions.disableSelected( 'class', [1,2] );
+			var chbs = $( "." + x ) ; //jquery selector
+			for( var g=0, h = chbs.length; g < h  ; g++ ) {
+				chbs[g].disabled = ( y.contains(chbs[g].value) ) ? true : false ;
+			}
+		},
+
+		clear_table: function(h){ // ASTGUI.domActions.clear_table($el)
+			ASTGUI.domActions.removeAllChilds(h);
+		},
+
+		findPos: function (el){ // returns the 'el.left, el.top' in pixels of a given element
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			var curleft = curtop = 0;
+			if (el.offsetParent) {
+				do {
+					curleft += el.offsetLeft;
+					curtop += el.offsetTop;
+				} while (el = el.offsetParent);
+			}
+			return { cleft: curleft, ctop:curtop } ;
+		},
+
+		get_checked: function (x){ // returns an array of selected checkbox values  from a set of checkboxes of class x
+			var chk = [] ;
+			var y = $( "." + x ) ; //jquery selector
+			for( var g=0, h = y.length; g < h  ; g++){
+				if(y[g].checked){
+					chk.push( y[g].value );
+				}
+			}
+			return chk;
+		},
+
+		removeAllChilds: function(x){ // ASTGUI.domActions.removeAllChilds(el);
+			if ( typeof x == 'string'){ x = _$(x) ; }
+			while(x.firstChild){
+				x.removeChild(x.firstChild);
+			}
+		},
+
+		setTextbox_DefaultValue: function(el, defval){ // usage :: ASTGUI.domActions.setTextbox_DefaultValue(el, "Default Value") ;
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			el.defaultValue = defval;
+			el.value = defval;
+			$(el).focus(
+				function(){
+					if( this.value == this.defaultValue ){
+						this.value = '' ;
+					};
+				}
+			).blur(
+				function () {
+					if( this.value == '' ){
+						this.value = this.defaultValue ;
+					}
+				}
+			);
+		},
+
+		tr_addCell: function(tr, nc){ // usage :: ASTGUI.domActions.tr_addCell( el, { html:'newCell Text' , align:'center', width:'20px' }  )
+			try{
+			var ih = nc.html; delete nc.html;
+			var newcell = tr.insertCell( tr.cells.length );
+			if( nc.id ){ newcell.id = nc.id ; delete nc.id; }
+			newcell.innerHTML = ih;
+			if( nc.onclickFunction && typeof nc.onclickFunction == "function" ){
+				ASTGUI.events.add( newcell , 'click' , nc.onclickFunction ) ;
+				$(newcell).css('cursor', 'pointer');
+				delete nc.onclickFunction;
+			}
+			for( var k in nc){
+				if( nc.hasOwnProperty(k) ){
+					if(k.toLowerCase() == 'colspan'){
+						newcell.colSpan = nc[k];
+					}else{
+						newcell[k] = nc[k];
+					}
+				}
+			}
+			}catch(err){
+				ASTGUI.Log.Error(err.description);
+			}
+		},
+
+		unCheckAll: function(x){ // uncheck all checkboxes of class x
+			var y = $("." + x) ; //jquery selector
+			for(var g=0, h = y.length; g < h; g++){
+				y[g].checked = false;
+			}
+		},
+
+		populateCheckBoxes: function( div, values, ofclass, withBR){ // ASTGUI.domActions.populateCheckBoxes(div, values, ofclass);
+			// represent 'array values' OR 'Object values' as a list of checkboxes of class 'ofclass' as childnodes of element 'div'
+			// Ex: values = { '1':'One', '1':'Two' } or values = [1,2]
+			try{
+			var c = {};
+			if(ASTGUI.isArray(values)){
+				values.each( function(tv){ c[tv] = tv; } );
+			}else{
+				c = values;
+			}
+			if ( typeof div == 'string'){ div = _$(div) ; }
+			for(var d in c){
+				if(c.hasOwnProperty(d)){
+					var nbr = document.createElement( 'SPAN' ) ;
+					var lbl = document.createElement( 'label' ) ;
+						var ncbx = document.createElement('input') ;
+							ncbx.type = 'checkbox' ;
+							ncbx.value = d ;
+							ncbx.id = Math.round(10000*Math.random()) + '_' + d ;
+							ncbx.className = ofclass ;
+						var span = document.createElement('SPAN') ;
+						
+						span.innerHTML = (withBR) ? c[d] + '&nbsp;<BR>' : c[d] + '&nbsp;' ;
+						
+					lbl.appendChild( ncbx ) ;
+					lbl.appendChild( span ) ;
+					//var tmp_span = document.createElement('SPAN') ; tmp_span.innerHTML = '&#173;'; //tmp_span.innerHTML = '&#173;';
+					nbr.appendChild(lbl) ;
+					div.appendChild( nbr ) ;
+				}
+			}
+			}catch(err){
+				ASTGUI.Log.Error(err.description);
+			}
+		},
+
+		showHideByCheckBox: function(chk , el){ // ASTGUI.domActions.showHideByCheckBox (chk, el) ;
+			if ( typeof chk == 'string'){ chk = _$(chk) ; }
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			chk.updateStatus = function(){ el.style.display = (chk.checked)?'':'none'; } ;
+			ASTGUI.events.add( chk, 'click' , chk.updateStatus );
+		},
+
+		showHideClassByCheckBox: function(chk , cLass , reverse_behaviour){ // ASTGUI.domActions.showHideClassByCheckBox(chk, cLass) ;
+			if ( typeof chk == 'string'){ chk = _$(chk) ; }
+			chk.updateStatus = function(){
+				if(reverse_behaviour ){
+					if(chk.checked){
+						$('.'+cLass).hide();
+					}else{
+						$('.'+cLass).show();
+					}
+				}else{
+					if(chk.checked){
+						$('.'+cLass).show();
+					}else{
+						$('.'+cLass).hide();
+					}
+				}
+			};
+			ASTGUI.events.add( chk, 'click' , chk.updateStatus );
+		},
+
+		enableDisableByCheckBox: function(chk , el, reverse_behaviour) { // ASTGUI.domActions.enableDisableByCheckBox (chk, el) ;
+			// this function can also use for radio boxes
+			if ( typeof chk == 'string'){ chk = _$(chk) ; }
+			if ( typeof el == 'string'){ el = _$(el) ; }
+			if( ASTGUI.isArray(el) ){
+				chk.updateStatus = function(){
+					el.each( function(el_this){
+						if ( typeof el_this == 'string'){ el_this = _$(el_this) ; }
+						if(!reverse_behaviour){
+							el_this.disabled = !(chk.checked);
+						}else{
+							el_this.disabled = chk.checked;
+						}
+					});
+					
+				};
+			}else{
+				if(!reverse_behaviour){
+					chk.updateStatus = function(){ el.disabled = !(chk.checked) } ;
+				}else{
+					chk.updateStatus = function(){ el.disabled = chk.checked; } ;
+				}
+			}
+
+			ASTGUI.events.add( chk, 'click' , chk.updateStatus );
+		}
+	},
+
+	events: {
+		getTarget: function(x){
+			x = x || window.event;
+			return x.target || x.srcElement;
+		},
+		add: function(a,b,c){ // a is element , b is event (string) , c is the function 
+			if ( typeof a == 'string'){ a = _$(a) ; }
+			if($.browser.msie){
+				a.attachEvent('on'+b, c);
+				return;
+			}
+			if(a.addEventListener){
+				a.addEventListener(b, c, false);
+				return;
+			}
+			a['on'+b] = c ;
+		},
+		remove: function(a,b,c){
+			if ( typeof a == 'string'){ a = _$(a) ; }
+			if($.browser.msie){
+				a.detachEvent('on'+b, c);
+				return;
+			}
+			if(a.removeEventListener){
+				a.removeEventListener(b, c, false);
+				return;
+			}
+			a['on'+b] = null ;
+		}
+	},
+
+	feedback : function( fb ){
+		// usage  ::  ASTGUI.feedback( { msg:'your message here', showfor:2, color:'#000000', bgcolor:'#FFFFFF' } );
+		top.miscFunctions.setFeedback(fb);
+	},
+
+	getFieldValue : function(el){ // ASTGUI.getFieldValue(el)
+		if( !el ){ return ''; }
+		if ( typeof el == 'string'){ el = _$(el) ; }
+		switch(el.type){
+			case 'checkbox':
+				return (el.checked) ? 'yes':'no' ;
+				break;
+			case 'radio':
+				return (el.checked) ? el.value : '' ;
+				break;
+			case 'select-one':
+				return el.value ; //.trim()
+				break;
+
+			case 'text':
+			case 'textarea':
+			case 'password':
+			default:
+				return el.value.trim() ;
+				break;
+		}
+		return '';
+	},
+
+	getObjectPropertiesAsString : function(a){ // takes an object and returns all its properties, values as a string
+		var ar = [];
+		for(var d in a){
+			if(!a.hasOwnProperty(d)){ continue; }
+
+			if( typeof a[d] == 'object' ){
+				if( ASTGUI.isArray(a[d]) ){
+					ar.push(  d + ' : [' + a[d].join(',') + ']' );
+				}else{
+					ar.push(  d + ' : ' + ASTGUI.getObjectPropertiesAsString(a[d]) );
+				}
+			}else{
+				ar.push(d + ' : '+ a[d]);
+			}
+		}
+		return '{' + ar.join(' ,') + '}' ;
+	},
+
+	getTrunkStatus : function (registry , trunkname, ttype){ // ASTGUI.getTrunkStatus (registry, trunkname);
+		/* registry should be == {
+			iax2 : ASTGUI.parseCLIResponse( ASTGUI.cliCommand('iax2 show registry') ) ,
+			sip : ASTGUI.parseCLIResponse( ASTGUI.cliCommand('sip show registry') )
+		} ;
+		*/
+		// trunkname == trunkname as trunk_x 
+		//var ttype = parent.astgui_managetrunks.misc.getTrunkType(trunkname) ;
+		try{
+		var this_IP = '';
+		if(!ttype || ( ttype != 'sip' && ttype != 'iax' && ttype != 'providers' ) ){ return '--'; }
+		if( ttype == 'providers' ){
+			var uname = parent.sessionData.pbxinfo.trunks[ttype][trunkname]['username'];
+			var host = parent.sessionData.pbxinfo.trunks[ttype][trunkname]['host'];
+			ttype = parent.astgui_managetrunks.misc.getProviderTrunkType(trunkname); // find 'sip' or 'iax'
+			if ( ttype != 'sip' && ttype != 'iax'){
+				return '--';
+			}
+		}else{
+			var uname = parent.sessionData.pbxinfo.trunks[ttype][trunkname]['username'];
+			var host = parent.sessionData.pbxinfo.trunks[ttype][trunkname]['host'];
+		}
+		if( !uname) {return '';}
+
+		(function(){
+			if(ttype=='iax'){var a ='iax2';}
+			if(ttype=='sip'){var a ='sip';}
+			var t = ASTGUI.cliCommand(a + ' show peer ' + trunkname) ;
+			t = ASTGUI.parseCLIResponse( t );
+			var IP = '';
+			var s = t.split('\n');
+			for(var i=0; i < s.length; i++ ){
+				var line = s[i];
+				if(line.contains('Addr->IP') ){ // if line is  'Addr->IP     : 68.62.219.197 Port 5060'
+					var tmp = line.afterChar(':'); // tmp = '68.62.219.197 Port 5060' ;
+					var tmp2 = tmp.split(' Port ');
+					IP = tmp2.join(':');
+					IP = IP.trim();
+					this_IP = IP;
+					return;
+				}
+			}
+		})();
+
+		if(ttype=='iax'){
+			var lines = registry.iax2.split('\n');
+		}else if(ttype=='sip'){
+			var lines = registry.sip.split('\n');
+		}
+
+		//var uname_lc = uname.toLowerCase();
+		// TODO: come up with a better alternative than this
+		// cli output of 'sip show registry' shows only a part of long usernames
+		// We should use action: status like we do for active channel monitoring.
+		
+		var uname_lc = uname.toLowerCase().substr(0,10);
+
+		for(var i = 0; i < lines.length; i++) {
+			var line = lines[i].trim().toLowerCase();

[... 1970 lines stripped ...]



More information about the asterisk-gui-commits mailing list