clearwing

changeset 165:c3ab5bef2a7e 1.3.3-stv-gwt

Adding documentation, small fixes to send tap resource from js client
author Stelios <stv@roe.ac.uk>
date Thu May 05 18:12:03 2016 +0300 (2016-05-05)
parents 6d8910cb48cc
children abaf9fa8f130
files src/GENIUS-gwt-app/public/Genius.html src/GENIUS-gwt-app/public/adql_syntax/tap-autocomplete.js src/GENIUS-gwt-app/public/adql_syntax/tap-hint.js src/GENIUS-gwt-app/src/com/genius/uk/server/AutocompleteServiceImplAsync.java src/GENIUS-gwt-app/war/Genius.html src/GENIUS-gwt-app/war/genius/adql_syntax/tap-autocomplete.js src/GENIUS-gwt-app/war/genius/adql_syntax/tap-hint.js
line diff
     1.1 --- a/src/GENIUS-gwt-app/public/Genius.html	Thu Apr 28 14:59:14 2016 +0300
     1.2 +++ b/src/GENIUS-gwt-app/public/Genius.html	Thu May 05 18:12:03 2016 +0300
     1.3 @@ -11,7 +11,7 @@
     1.4      <!--                                                               -->
     1.5      <!-- Consider inlining CSS to reduce the number of requested files -->
     1.6      <!--                                                               -->
     1.7 -    <link type="text/css" rel="stylesheet" href="MyWebApp.css">
     1.8 +    <link type="text/css" rel="stylesheet" href="Genius.css">
     1.9  
    1.10      <!--                                           -->
    1.11      <!-- Any title is fine                         -->
    1.12 @@ -23,29 +23,29 @@
    1.13      <!-- If you add any GWT meta tags, they must   -->
    1.14      <!-- be added before this line.                -->
    1.15      <!--                                           -->
    1.16 -    <script type="text/javascript" language="javascript" src="mywebapp/mywebapp.nocache.js"></script>
    1.17 -    <script  type="text/javascript" language="javascript" src="mywebapp/adql_syntax/jquery-1.7.2.min.js"></script>
    1.18 -    <link rel="stylesheet" href="mywebapp/adql_syntax/codemirror.css">
    1.19 -    <link rel="stylesheet" href="mywebapp/adql_syntax/adql.css">
    1.20 -    <link rel="stylesheet" href="mywebapp/adql_syntax/simple-hint.css">
    1.21 -    <script src="mywebapp/adql_syntax/codemirror.js"></script>
    1.22 -    <script src="mywebapp/adql_syntax/adql.js"></script>
    1.23 -    <script src="mywebapp/adql_syntax/tap-hint.js"></script>
    1.24 -    <script src="mywebapp/adql_syntax/tap-autocomplete.js"></script>
    1.25 -    <script type="text/javascript" language="javascript">
    1.26 +    <script  type="text/javascript" src="genius/adql_syntax/jquery-1.7.2.min.js"></script>
    1.27 +    <link rel="stylesheet" href="genius/adql_syntax/codemirror.css">
    1.28 +    <link rel="stylesheet" href="genius/adql_syntax/adql.css">
    1.29 +    <link rel="stylesheet" href="genius/adql_syntax/simple-hint.css">
    1.30 +    <script src="genius/adql_syntax/codemirror.js"></script>
    1.31 +    <script src="genius/adql_syntax/adql.js"></script>
    1.32 +    <script src="genius/adql_syntax/tap-hint.js"></script>
    1.33 +    <script src="genius/adql_syntax/tap-autocomplete.js"></script>
    1.34 +    <script type="text/javascript"  src="genius/genius.nocache.js"></script>
    1.35 +    <script type="text/javascript">
    1.36      $( document ).ready(function() {
    1.37  	  var params = {
    1.38  	    textfieldid: "textfield",
    1.39 -	    web_service_path: 'mywebapp/autocomplete',
    1.40 +	    web_service_path: 'genius/autocompleteAsync',
    1.41  	    html_resource: jQuery("#content_dbaccess_SQL_form #tap_endpoint").val(),
    1.42 -	    tap_resource: "",
    1.43 -	    autocomplete_info_id: "autocomplete_info",
    1.44 -	    autocomplete_loader_id: "autocomplete_loader",
    1.45 +	    tap_resource: 'http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/tap/',
    1.46 +	    autocomplete_info_id: "",
    1.47 +	    autocomplete_loader_id: "",
    1.48  	    servicemode: "TAP",
    1.49 -	    initial_catalogues: ["GACS"]
    1.50 +	    initial_catalogues: ["caom2"]
    1.51  	  }
    1.52  
    1.53 -	  var autocomplete = new TapAutocomplete(params);
    1.54 +	  var autocompleteInstance = new TapAutocomplete(params);
    1.55  
    1.56      });
    1.57  
    1.58 @@ -67,7 +67,7 @@
    1.59        </div>
    1.60      </noscript>
    1.61  
    1.62 -    <h1>Web Application Starter Project</h1>
    1.63 +    <h1>Genius Autocomplete Demo</h1>
    1.64  
    1.65      <table align="center">
    1.66        <tr>
     2.1 --- a/src/GENIUS-gwt-app/public/adql_syntax/tap-autocomplete.js	Thu Apr 28 14:59:14 2016 +0300
     2.2 +++ b/src/GENIUS-gwt-app/public/adql_syntax/tap-autocomplete.js	Thu May 05 18:12:03 2016 +0300
     2.3 @@ -1,4 +1,4 @@
     2.4 -/*
     2.5 +/**
     2.6   *  Autocomplete for CodeMirror 2.
     2.7   *  Uses adql.js by Gregory Mantelet
     2.8   *  Extended to allow dynamic metadata keyword loading from webservice
     2.9 @@ -6,114 +6,123 @@
    2.10   *  @version 11/Feb/2015
    2.11   */
    2.12  
    2.13 -
    2.14  var TapAutocomplete = function(params) {
    2.15  
    2.16 -  this.istap = false;
    2.17 -  this.servicemode ="TAP";
    2.18 +	this.istap = false;
    2.19 +	this.servicemode = "TAP";
    2.20  
    2.21 -  if (params.textfieldid) this.textfieldid = params.textfieldid
    2.22 -  if (params.web_service_path) this.web_service_path = params.web_service_path;
    2.23 -  if (params.html_resource) this.html_resource = params.html_resource;
    2.24 -  if (params.tap_resource) this.tap_resource = params.tap_resource;
    2.25 -  if (params.autocomplete_info_id) this.autocomplete_info = params.autocomplete_info_id;
    2.26 -  if (params.autocomplete_loader_id) this.autocomplete_loader = params.autocomplete_loader_id;
    2.27 -  if (params.servicemode) this.servicemode = params.servicemode;
    2.28 -  if (params.initial_catalogues) {
    2.29 -     this.initial_catalogues = params.initial_catalogues;
    2.30 -  } else {
    2.31 -     this.initial_catalogues = [];
    2.32 -  }
    2.33 +	if (params.textfieldid)
    2.34 +		this.textfieldid = params.textfieldid
    2.35 +	if (params.web_service_path)
    2.36 +		this.web_service_path = params.web_service_path;
    2.37 +	if (params.html_resource)
    2.38 +		this.html_resource = params.html_resource;
    2.39 +	if (params.tap_resource)
    2.40 +		this.tap_resource = params.tap_resource;
    2.41 +	if (params.autocomplete_info_id)
    2.42 +		this.autocomplete_info = params.autocomplete_info_id;
    2.43 +	if (params.autocomplete_loader_id)
    2.44 +		this.autocomplete_loader = params.autocomplete_loader_id;
    2.45 +	if (params.servicemode)
    2.46 +		this.servicemode = params.servicemode;
    2.47 +	if (params.initial_catalogues) {
    2.48 +		this.initial_catalogues = params.initial_catalogues;
    2.49 +	} else {
    2.50 +		this.initial_catalogues = [];
    2.51 +	}
    2.52  
    2.53 -  if (this.servicemode.toLowerCase() == "tap") {
    2.54 -    this.istap = true;
    2.55 -  }
    2.56 +	if (this.servicemode.toLowerCase() == "tap") {
    2.57 +		this.istap = true;
    2.58 +	}
    2.59  
    2.60 +	if (this.editor == null && !jQuery('.CodeMirror').length > 0) {
    2.61 +		CodeMirror.commands.autocomplete = function(cm) {
    2.62 +			CodeMirror.tapHint(cm, CodeMirror.adqlHint,
    2.63 +					{
    2.64 +						webServicePath : params.web_service_path,
    2.65 +						tapResource : params.tap_resource,
    2.66 +						useAutocompleteService : (params.servicemode.toLowerCase() == "tap"),
    2.67 +						autocompleteLoader : params.autocomplete_loader_id,
    2.68 +						autocompleteInfo : params.autocomplete_info_id,
    2.69 +					});
    2.70 +		}
    2.71  
    2.72 -  if (this.editor == null && !jQuery('.CodeMirror').length > 0) {
    2.73 -    CodeMirror.commands.autocomplete = function(cm) {
    2.74 -      CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
    2.75 -        webServicePath: params.web_service_path,
    2.76 -        tapResource: params.tap_resource,
    2.77 -        useAutocompleteService: (params.servicemode.toLowerCase() == "tap"),
    2.78 -	    autocompleteLoader: params.autocomplete_loader_id,
    2.79 -        autocompleteInfo: params.autocomplete_info_id,
    2.80 -      });
    2.81 -    }
    2.82 +		this.editor = CodeMirror.fromTextArea(document.getElementById(params.textfieldid), {
    2.83 +			mode : "text/x-adql",
    2.84 +			tabMode : "indent",
    2.85 +			lineNumbers : true,
    2.86 +			matchBrackets : true,
    2.87 +			lineWrapping : true,
    2.88 +			textWrapping : true,
    2.89 +			extraKeys : {
    2.90 +				"Ctrl-Space" : "autocomplete",
    2.91 +			},
    2.92  
    2.93 -   this.editor = CodeMirror.fromTextArea(document.getElementById(params.textfieldid), {
    2.94 -      mode: "text/x-adql",
    2.95 -      tabMode: "indent",
    2.96 -      lineNumbers: true,
    2.97 -      matchBrackets: true,
    2.98 -      lineWrapping: true,
    2.99 -      textWrapping: true,
   2.100 -      extraKeys: {
   2.101 -        "Ctrl-Space": "autocomplete",
   2.102 -      },
   2.103 +		});
   2.104 +	}
   2.105  
   2.106 -    });
   2.107 -  }
   2.108 +	if (typeof this.editor.availableTags == 'undefined') {
   2.109 +		this.editor.availableTags = [ "SELECT", "FROM", "ORDER BY", "WHERE",
   2.110 +				"TOP", "IN", "AND", "OR", "WITH", "DESC", "ASC", "JOIN", "AS",
   2.111 +				"HAVING", "ABS", "GROUP", "BY", "INNER", "OUTER", "CROSS",
   2.112 +				"LEFT", "RIGHT", "FULL", "ON", "USING", "MIN", "MAX", "COUNT",
   2.113 +				"DISTINCT", "ALL", "LIKE", "ACOS", "ASIN", "ATAN", "ATAN2",
   2.114 +				"COS", "SIN", "TAN", "COT", "IS", "NOT", "NULL", "NATURAL",
   2.115 +				"EXISTS", "BETWEEN", "AREA", "BOX", "CENTROID", "CIRCLE",
   2.116 +				"CONTAINS", "COORD1", "COORD2", "COORDSYS", "DISTANCE",
   2.117 +				"INTERSECTS", "POINT", "POLYGON", "REGION" ];
   2.118 +	}
   2.119  
   2.120 -  if (typeof this.editor.availableTags == 'undefined') {
   2.121 -	  this.editor.availableTags = [
   2.122 -     		"SELECT", "FROM", "ORDER BY","WHERE", "TOP","IN", "AND", "OR", "WITH", "DESC", "ASC", "JOIN", "AS", "HAVING", "ABS",
   2.123 - 			"GROUP","BY", "INNER","OUTER","CROSS","LEFT","RIGHT","FULL","ON","USING","MIN","MAX","COUNT","DISTINCT","ALL","LIKE","ACOS","ASIN","ATAN","ATAN2","COS","SIN","TAN","COT","IS","NOT","NULL","NATURAL","EXISTS","BETWEEN","AREA","BOX","CENTROID","CIRCLE","CONTAINS","COORD1","COORD2","COORDSYS","DISTANCE","INTERSECTS","POINT","POLYGON","REGION"
   2.124 - 		];
   2.125 -  }
   2.126 -
   2.127 -  if (params.servicemode.toLowerCase() == "tap") {
   2.128 -    this.load_metadata_for_autocomplete(this.initial_catalogues);
   2.129 -  } else {
   2.130 -    this.load_metadata_from_html();
   2.131 -  }
   2.132 +	if (params.servicemode.toLowerCase() == "tap") {
   2.133 +		this.load_metadata_for_autocomplete(this.initial_catalogues);
   2.134 +	} else {
   2.135 +		this.load_metadata_from_html();
   2.136 +	}
   2.137  }
   2.138  
   2.139  /**
   2.140 - * Get the medata content from the HTML data to be used by the
   2.141 - * auto-completion functions Store the content in the
   2.142 - * keywords list
   2.143 - *
   2.144 + * Get the medata content from the HTML data to be used by the auto-completion
   2.145 + * functions Store the content in the keywords list
   2.146 + * 
   2.147   */
   2.148  TapAutocomplete.prototype.push_metadata_content_html = function(data) {
   2.149  
   2.150 -  var content = document.createElement('div');
   2.151 -  content.innerHTML = data;
   2.152 -  var tr = content.getElementsByClassName('heading');
   2.153 -  var tr2 = content.getElementsByClassName('expand');
   2.154 -  for (var i = 0; i < tr.length; i++) {
   2.155 -    var str = jQuery.trim(jQuery(tr[i]).justtext());
   2.156 -    var arr = str.split(".");
   2.157 -    for (var y = 0; y < arr.length; y++) {
   2.158 -    	this.editor.availableTags.push(arr[y]);
   2.159 -    }
   2.160 -  }
   2.161 -  for (var i = 0; i < tr2.length; i++) {
   2.162 -    if (!contains(this.editor.availableTags, tr2[i].innerHTML)) {
   2.163 -    	this.editor.availableTags.push(tr2[i].innerHTML);
   2.164 -    }
   2.165 -  }
   2.166 +	var content = document.createElement('div');
   2.167 +	content.innerHTML = data;
   2.168 +	var tr = content.getElementsByClassName('heading');
   2.169 +	var tr2 = content.getElementsByClassName('expand');
   2.170 +	for (var i = 0; i < tr.length; i++) {
   2.171 +		var str = jQuery.trim(jQuery(tr[i]).justtext());
   2.172 +		var arr = str.split(".");
   2.173 +		for (var y = 0; y < arr.length; y++) {
   2.174 +			this.editor.availableTags.push(arr[y]);
   2.175 +		}
   2.176 +	}
   2.177 +	for (var i = 0; i < tr2.length; i++) {
   2.178 +		if (!contains(this.editor.availableTags, tr2[i].innerHTML)) {
   2.179 +			this.editor.availableTags.push(tr2[i].innerHTML);
   2.180 +		}
   2.181 +	}
   2.182  
   2.183  };
   2.184  
   2.185  /**
   2.186 - * Get the medata content from the Json data to be used by the
   2.187 - * auto-completion functions Store the content in the
   2.188 - * keywords list
   2.189 - *
   2.190 + * Get the medata content from the Json data to be used by the auto-completion
   2.191 + * functions Store the content in the keywords list
   2.192 + * 
   2.193   */
   2.194  
   2.195  TapAutocomplete.prototype.push_metadata_json = function(data) {
   2.196 -  
   2.197 -  if (data.length > 0) {
   2.198 -    for (var i = 0; i < data.length; i++) {
   2.199 -      var str = jQuery.trim(data[i]);
   2.200 -      var arr = str.split(".");
   2.201 -      for (var y = 0; y < arr.length; y++) {
   2.202 -    	  this.editor.availableTags.push(arr[y]);
   2.203 -      }
   2.204 -    }
   2.205 -  }
   2.206 +
   2.207 +	if (data.length > 0) {
   2.208 +		for (var i = 0; i < data.length; i++) {
   2.209 +			var str = jQuery.trim(data[i]);
   2.210 +			var arr = str.split(".");
   2.211 +			for (var y = 0; y < arr.length; y++) {
   2.212 +				this.editor.availableTags.push(arr[y]);
   2.213 +			}
   2.214 +		}
   2.215 +	}
   2.216  
   2.217  };
   2.218  
   2.219 @@ -121,180 +130,192 @@
   2.220   * Run Autocomplete class
   2.221   */
   2.222  TapAutocomplete.prototype.run = function() {
   2.223 -  if (this.servicemode.toLowerCase() == "tap") {
   2.224 -    this.load_metadata_for_autocomplete();
   2.225 -  } else {
   2.226 -    this.load_metadata_from_html();
   2.227 -  }
   2.228 +	if (this.servicemode.toLowerCase() == "tap") {
   2.229 +		this.load_metadata_for_autocomplete();
   2.230 +	} else {
   2.231 +		this.load_metadata_from_html();
   2.232 +	}
   2.233  };
   2.234  
   2.235 -
   2.236  /**
   2.237   * Refresh autocomplete
   2.238   */
   2.239  TapAutocomplete.prototype.refresh = function() {
   2.240 -  CodeMirror.commands.autocomplete = function(cm) {
   2.241 -    CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
   2.242 -      webServicePath: this.web_service_path,
   2.243 -      tapResource: this.tap_resource,
   2.244 -      useAutocompleteService: this.istap,
   2.245 -      autocompleteInfo: this.autocomplete_info,
   2.246 -      autocompleteLoader: this.autocomplete_loader
   2.247 -    });
   2.248 -  }
   2.249 +	CodeMirror.commands.autocomplete = function(cm) {
   2.250 +		CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
   2.251 +			webServicePath : this.web_service_path,
   2.252 +			tapResource : this.tap_resource,
   2.253 +			useAutocompleteService : this.istap,
   2.254 +			autocompleteInfo : this.autocomplete_info,
   2.255 +			autocompleteLoader : this.autocomplete_loader
   2.256 +		});
   2.257 +	}
   2.258  
   2.259 -  if (this.servicemode.toLowerCase() == "tap") {
   2.260 -    this.load_metadata_for_autocomplete();
   2.261 -  } else {
   2.262 -    this.load_metadata_from_html();
   2.263 -  }
   2.264 +	if (this.servicemode.toLowerCase() == "tap") {
   2.265 +		this.load_metadata_for_autocomplete();
   2.266 +	} else {
   2.267 +		this.load_metadata_from_html();
   2.268 +	}
   2.269  };
   2.270  
   2.271  /**
   2.272 - * Refresh autocomplete
   2.273 + * Load catalogue tables
   2.274 + * 
   2.275   */
   2.276  TapAutocomplete.prototype.load_catalogue_tables = function(catalogue_list) {
   2.277  
   2.278 -  if (this.servicemode.toLowerCase() == "tap") {
   2.279 -    this.load_metadata_for_autocomplete(catalogue_list);
   2.280 -  } else {
   2.281 -    this.load_metadata_from_html();
   2.282 -  }
   2.283 +	if (this.servicemode.toLowerCase() == "tap") {
   2.284 +		this.load_metadata_for_autocomplete(catalogue_list);
   2.285 +	} else {
   2.286 +		this.load_metadata_from_html();
   2.287 +	}
   2.288  };
   2.289  
   2.290 +/**
   2.291 + * Load metadata for autocomplete from HTML resource. Talks with a Web service
   2.292 + * that fetches the initial list of keywords
   2.293 + * 
   2.294 + */
   2.295 +TapAutocomplete.prototype.load_metadata_from_html = function() {
   2.296 +	_this = this;
   2.297  
   2.298 +	if (_this.autocomplete_info)
   2.299 +		jQuery("#" + _this.autocomplete_info).html(
   2.300 +				"Loading catalogue metadata keywords for auto-complete");
   2.301 +	if (_this.autocomplete_loader)
   2.302 +		jQuery("#" + _this.autocomplete_loader).show();
   2.303  
   2.304 +	/**
   2.305 +	 * Check whether an object (obj) is contained in a list (a)
   2.306 +	 * 
   2.307 +	 */
   2.308 +	function contains(a, obj) {
   2.309 +		var i = a.length;
   2.310 +		while (i--) {
   2.311 +			if (a[i] === obj) {
   2.312 +				return true;
   2.313 +			}
   2.314 +		}
   2.315 +		return false;
   2.316 +	}
   2.317 +
   2.318 +	function push_metadata_content_html(data) {
   2.319 +		if (!_this.editor.availableTags) {
   2.320 +			_this.editor.availableTags = [];
   2.321 +		}
   2.322 +
   2.323 +		var content = document.createElement('div');
   2.324 +		content.innerHTML = data;
   2.325 +		var tr = content.getElementsByClassName('heading');
   2.326 +		var tr2 = content.getElementsByClassName('expand');
   2.327 +		for (var i = 0; i < tr.length; i++) {
   2.328 +			var str = jQuery.trim(jQuery(tr[i]).text());
   2.329 +			var arr = str.split(".");
   2.330 +			for (var y = 0; y < arr.length; y++) {
   2.331 +				_this.editor.availableTags.push(arr[y]);
   2.332 +			}
   2.333 +		}
   2.334 +
   2.335 +		for (var i = 0; i < tr2.length; i++) {
   2.336 +			if (!contains(_this.editor.availableTags, tr2[i].innerHTML)) {
   2.337 +				_this.editor.availableTags.push(tr2[i].innerHTML);
   2.338 +			}
   2.339 +		}
   2.340 +
   2.341 +	}
   2.342 +
   2.343 +	jQuery.ajax({
   2.344 +		type : "POST",
   2.345 +		async : false,
   2.346 +		data : {
   2.347 +			resource : _this.html_resource,
   2.348 +			mode : "vosi"
   2.349 +		},
   2.350 +		url : _this.web_service_path,
   2.351 +		timeout : 1000000,
   2.352 +		error : function() {
   2.353 +			if (_this.autocomplete_info)
   2.354 +				jQuery("#" + _this.autocomplete_info).html(
   2.355 +						"CTRL + Space to activate auto-complete");
   2.356 +			if (_this.autocomplete_loader)
   2.357 +				jQuery("#" + _this.autocomplete_loader).hide();
   2.358 +
   2.359 +		},
   2.360 +		success : function(data) {
   2.361 +
   2.362 +			if (data != "") {
   2.363 +				push_metadata_content_html(data);
   2.364 +			}
   2.365 +			if (_this.autocomplete_info)
   2.366 +				jQuery("#" + _this.autocomplete_info).html(
   2.367 +						"CTRL + Space to activate auto-complete");
   2.368 +			if (_this.autocomplete_loader)
   2.369 +				jQuery("#" + _this.autocomplete_loader).hide();
   2.370 +
   2.371 +		}
   2.372 +	});
   2.373 +};
   2.374  
   2.375  /**
   2.376 - * Load metadata for autocomplete from HTML resource. Talks with a Web service that fetches the initial list of keywords
   2.377 - *
   2.378 + * Load metadata for autocomplete. Talks with a Web service that fetches the
   2.379 + * initial list of keywords
   2.380 + * 
   2.381   */
   2.382 -TapAutocomplete.prototype.load_metadata_from_html = function() {
   2.383 -  _this = this; 
   2.384 +TapAutocomplete.prototype.load_metadata_for_autocomplete = function(
   2.385 +		optional_catalogues) {
   2.386 +	_this = this;
   2.387  
   2.388 -  if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("Loading catalogue metadata keywords for auto-complete");
   2.389 -  if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).show();
   2.390 +	optional_catalogues = (typeof optional_catalogues === 'undefined') ? []
   2.391 +			: optional_catalogues;
   2.392  
   2.393 -  /**
   2.394 -   * Check whether an object (obj) is contained in a list (a)
   2.395 -   * 
   2.396 -   */
   2.397 -  function contains(a, obj) {
   2.398 -    var i = a.length;
   2.399 -    while (i--) {
   2.400 -      if (a[i] === obj) {
   2.401 -        return true;
   2.402 -      }
   2.403 -    }
   2.404 -    return false;
   2.405 -  }
   2.406 +	if (_this.autocomplete_info)
   2.407 +		jQuery("#" + _this.autocomplete_info).html(
   2.408 +				"Loading catalogue metadata keywords for auto-complete");
   2.409 +	if (_this.autocomplete_loader)
   2.410 +		jQuery("#" + _this.autocomplete_loader).show();
   2.411  
   2.412 -  function push_metadata_content_html(data) {
   2.413 -	if (!_this.editor.availableTags) {
   2.414 -		_this.editor.availableTags = [];
   2.415 -    }
   2.416 +	function push_metadata_json(data) {
   2.417 +		if (data.length > 0) {
   2.418 +			for (var i = 0; i < data.length; i++) {
   2.419 +				var str = jQuery.trim(data[i]);
   2.420 +				var arr = str.split(".");
   2.421 +				for (var y = 0; y < arr.length; y++) {
   2.422 +					_this.editor.availableTags.push(arr[y]);
   2.423 +				}
   2.424 +			}
   2.425 +		}
   2.426  
   2.427 -    var content = document.createElement('div');
   2.428 -    content.innerHTML = data;
   2.429 -    var tr = content.getElementsByClassName('heading');
   2.430 -    var tr2 = content.getElementsByClassName('expand');
   2.431 -    for (var i = 0; i < tr.length; i++) {
   2.432 -      var str = jQuery.trim(jQuery(tr[i]).text());
   2.433 -      var arr = str.split(".");
   2.434 -      for (var y = 0; y < arr.length; y++) {
   2.435 -    	  _this.editor.availableTags.push(arr[y]);
   2.436 -      }
   2.437 -    }
   2.438 +	}
   2.439  
   2.440 -    for (var i = 0; i < tr2.length; i++) {
   2.441 -      if (!contains(_this.editor.availableTags, tr2[i].innerHTML)) {
   2.442 -    	  _this.editor.availableTags.push(tr2[i].innerHTML);
   2.443 -      }
   2.444 -    }
   2.445 +	optional_catalogues = JSON.stringify(optional_catalogues);
   2.446 +	jQuery.ajax({
   2.447 +		type : "POST",
   2.448 +		async : false,
   2.449 +		data : {
   2.450 +			resource : _this.tap_resource,
   2.451 +			optional_catalogues : optional_catalogues,
   2.452 +			mode : "tap",
   2.453 +		},
   2.454 +		url : _this.web_service_path,
   2.455 +		timeout : 1000000,
   2.456 +		error : function(e) {
   2.457 +			if (_this.autocomplete_info)
   2.458 +				jQuery("#" + _this.autocomplete_info).html(
   2.459 +						"CTRL + Space to activate auto-complete");
   2.460 +			if (_this.autocomplete_loader)
   2.461 +				jQuery("#" + _this.autocomplete_loader).hide();
   2.462 +		},
   2.463 +		success : function(data) {
   2.464  
   2.465 -  }
   2.466 -
   2.467 -
   2.468 -  jQuery.ajax({
   2.469 -    type: "POST",
   2.470 -    async: false,
   2.471 -    data: {
   2.472 -      resource: _this.html_resource,
   2.473 -      mode: "vosi"
   2.474 -    },
   2.475 -    url: _this.web_service_path,
   2.476 -    timeout: 1000000,
   2.477 -    error: function() {
   2.478 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   2.479 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   2.480 -
   2.481 -    },
   2.482 -    success: function(data) {
   2.483 -
   2.484 -      if (data != "") {
   2.485 -       push_metadata_content_html(data);
   2.486 -      }
   2.487 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   2.488 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   2.489 -
   2.490 -    }
   2.491 -  });
   2.492 -};
   2.493 -
   2.494 -
   2.495 -
   2.496 -/**
   2.497 - *  Load metadata for autocomplete. Talks with a Web service that fetches the initial list of keywords
   2.498 - *
   2.499 - */
   2.500 -TapAutocomplete.prototype.load_metadata_for_autocomplete = function(optional_catalogues) {
   2.501 -  _this = this; 
   2.502 -
   2.503 -  optional_catalogues = (typeof optional_catalogues === 'undefined') ? [] : optional_catalogues;
   2.504 -
   2.505 -  if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("Loading catalogue metadata keywords for auto-complete");
   2.506 -  if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).show();
   2.507 -
   2.508 -
   2.509 -  function push_metadata_json(data) {
   2.510 -    if (data.length > 0) {
   2.511 -      for (var i = 0; i < data.length; i++) {
   2.512 -        var str = jQuery.trim(data[i]);
   2.513 -        var arr = str.split(".");
   2.514 -        for (var y = 0; y < arr.length; y++) {
   2.515 -        	_this.editor.availableTags.push(arr[y]);
   2.516 -        }
   2.517 -      }
   2.518 -    }
   2.519 -
   2.520 -
   2.521 -  }
   2.522 -
   2.523 -  optional_catalogues=JSON.stringify(optional_catalogues);
   2.524 -
   2.525 -  jQuery.ajax({
   2.526 -    type: "POST",
   2.527 -    async: false,
   2.528 -    data: {
   2.529 -      resource: _this.tap_resource,
   2.530 -      optional_catalogues: optional_catalogues,
   2.531 -      mode: "tap"
   2.532 -    },
   2.533 -    url: _this.web_service_path,
   2.534 -    timeout: 1000000,
   2.535 -    error: function(e) {
   2.536 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   2.537 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   2.538 -    },
   2.539 -    success: function(data) {
   2.540 -
   2.541 -
   2.542 -      if (data != "") {
   2.543 -        push_metadata_json(data);
   2.544 -      }
   2.545 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   2.546 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   2.547 -    }
   2.548 -  });
   2.549 +			if (data != "") {
   2.550 +				push_metadata_json(data);
   2.551 +			}
   2.552 +			if (_this.autocomplete_info)
   2.553 +				jQuery("#" + _this.autocomplete_info).html(
   2.554 +						"CTRL + Space to activate auto-complete");
   2.555 +			if (_this.autocomplete_loader)
   2.556 +				jQuery("#" + _this.autocomplete_loader).hide();
   2.557 +		}
   2.558 +	});
   2.559  
   2.560  };
     3.1 --- a/src/GENIUS-gwt-app/public/adql_syntax/tap-hint.js	Thu Apr 28 14:59:14 2016 +0300
     3.2 +++ b/src/GENIUS-gwt-app/public/adql_syntax/tap-hint.js	Thu May 05 18:12:03 2016 +0300
     3.3 @@ -1,4 +1,4 @@
     3.4 -/*
     3.5 +/**
     3.6   *  Autocomplete for CodeMirror 2.
     3.7   *  Uses adql.js by Gregory Mantelet
     3.8   *  Extended to allow dynamic metadata keyword loading from webservice
     3.9 @@ -71,7 +71,6 @@
    3.10          return;
    3.11        }
    3.12        var result = getHints(editor, givenOptions);
    3.13 -      console.log(result);
    3.14        if (!result || !result.list.length) return;
    3.15        var completions = result.list;
    3.16  
    3.17 @@ -251,6 +250,7 @@
    3.18  
    3.19    /**
    3.20     *  Load metadata for autocomplete
    3.21 +   *  Sends Ajax request to autocomplete service with keyword & optional keyword
    3.22     *
    3.23     */
    3.24    function loadMetadataForAutocomplete(keyword, parentText, tags, editor, optional_keyword) {
    3.25 @@ -267,7 +267,8 @@
    3.26        data: {
    3.27          keyword: keyword,
    3.28          optional_keyword: optional_keyword,
    3.29 -        mode: "tap"
    3.30 +        mode: "tap",
    3.31 +        resource: editor.tapResource
    3.32  
    3.33        },
    3.34        url: editor.webServicePath,
    3.35 @@ -291,7 +292,9 @@
    3.36    }
    3.37  
    3.38  
    3.39 -
    3.40 +  /**
    3.41 +   * Get autocomplete keywords for given token
    3.42 +   */
    3.43    function getCompletions(token, context, keywords, options) {
    3.44      var found = [],
    3.45        start = token.string;
     4.1 --- a/src/GENIUS-gwt-app/src/com/genius/uk/server/AutocompleteServiceImplAsync.java	Thu Apr 28 14:59:14 2016 +0300
     4.2 +++ b/src/GENIUS-gwt-app/src/com/genius/uk/server/AutocompleteServiceImplAsync.java	Thu May 05 18:12:03 2016 +0300
     4.3 @@ -1,35 +1,17 @@
     4.4  package com.genius.uk.server;
     4.5  
     4.6  import javax.servlet.annotation.WebServlet;
     4.7 -
     4.8 -import com.genius.uk.client.AutocompleteServiceAsync;
     4.9 -import com.genius.uk.shared.FieldVerifier;
    4.10 -import com.google.gwt.user.client.rpc.AsyncCallback;
    4.11 -
    4.12  import java.io.IOException;
    4.13  import java.io.PrintWriter;
    4.14  import java.net.URL;
    4.15  import java.net.URLEncoder;
    4.16  import java.util.ArrayList;
    4.17 -import java.util.Enumeration;
    4.18 -import java.util.Random;
    4.19 -
    4.20  import javax.servlet.ServletException;
    4.21  import javax.servlet.http.HttpServlet;
    4.22  import javax.servlet.http.HttpServletRequest;
    4.23  import javax.servlet.http.HttpServletResponse;
    4.24 -
    4.25  import org.json.JSONArray;
    4.26  import org.json.JSONException;
    4.27 -import org.json.JSONObject;
    4.28 -
    4.29 -import java.io.IOException;
    4.30 -import java.net.MalformedURLException;
    4.31 -import java.net.URI;
    4.32 -import java.net.URL;
    4.33 -import java.sql.SQLException;
    4.34 -import java.util.Iterator;
    4.35 -
    4.36  import uk.ac.starlink.table.RowSequence;
    4.37  import uk.ac.starlink.table.StarTable;
    4.38  import uk.ac.starlink.table.StoragePolicy;
    4.39 @@ -38,7 +20,7 @@
    4.40  import uk.ac.starlink.votable.VOTableBuilder;
    4.41  
    4.42  /**
    4.43 - * The server-side implementation of the RPC service.
    4.44 + * The server-side implementation of the  Autocomplete service.
    4.45   */
    4.46  @SuppressWarnings("serial")
    4.47  @WebServlet(name = "AutocompleteImplAsync", urlPatterns = { "/autocompleteAsync" })
    4.48 @@ -56,7 +38,8 @@
    4.49  	}
    4.50  
    4.51  	/**
    4.52 -	 * Handle a request
    4.53 +	 * Handle a request for the Autocomplete Service
    4.54 +	 * Run a TAP synchronous query to the TAP_SCHEMA to fetch all keywords according to the input
    4.55  	 * 
    4.56  	 * @param req
    4.57  	 * @param res
    4.58 @@ -69,10 +52,10 @@
    4.59  
    4.60  		PrintWriter out = res.getWriter();
    4.61  
    4.62 -		String lang = "ADQL";
    4.63 -		String tapformat = "VOTABLE";
    4.64 -		String request = "doQuery";
    4.65 +		// Gather parameters
    4.66 +		
    4.67  		String keyword = (req.getParameter("keyword") == null) ? "" : req.getParameter("keyword");
    4.68 +		@SuppressWarnings("unused")
    4.69  		String mode = (req.getParameter("mode") == null) ? "" : req.getParameter("mode");
    4.70  		String keyword_type = (req.getParameter("keyword_type") == null) ? "" : req.getParameter("keyword_type");
    4.71  		String optional_keyword = (req.getParameter("optional_keyword") == null) ? ""
    4.72 @@ -80,69 +63,84 @@
    4.73  		String optional_catalogues = (req.getParameter("optional_catalogues") == null) ? ""
    4.74  				: req.getParameter("optional_catalogues");
    4.75  		String query = "";
    4.76 -		String tapService = "http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/tap/";
    4.77 +		String resource = (req.getParameter("resource") == null) ? ""
    4.78 +				: req.getParameter("resource");
    4.79 +		String tapService = resource;
    4.80 +		String getRequestString = "/sync?REQUEST=doQuery&FORMAT=VOTable/TD&VERSION=1.0&LANG=ADQL&QUERY=";
    4.81  
    4.82  		JSONArray array = new JSONArray();
    4.83 +		
    4.84 +		//Number of dots
    4.85  		int count_dots = keyword.length() - keyword.replace(".", "").length();
    4.86  
    4.87 +		
    4.88 +		// If the keyword_type schema is passed, check tables from TAP_SCHEMA for keyword or optional_keyword 
    4.89  		if (keyword_type.toLowerCase() == "schema") {
    4.90  			query = "SELECT table_name FROM TAP_SCHEMA.tables WHERE schema_name='" + keyword + "'";
    4.91  			if (optional_keyword != null && optional_keyword != "") {
    4.92 -				query += " AND (table_name LIKE '" + optional_keyword + "%' OR table_name LIKE '"
    4.93 -						+ keyword + "." + optional_keyword + "%')";
    4.94 +				query += " AND (table_name LIKE '" + optional_keyword + "%' OR table_name LIKE '" + keyword + "."
    4.95 +						+ optional_keyword + "%')";
    4.96  			}
    4.97 -			String queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
    4.98 +			String queryURLStr = tapService + getRequestString
    4.99  					+ URLEncoder.encode(query, "UTF-8");
   4.100  			queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.101  			array = starTableToJSONArray(urlToStartable(queryURLStr));
   4.102  			if (optional_keyword != null && optional_keyword != "") {
   4.103  				array = filter_name(array, optional_keyword);
   4.104  			}
   4.105 +	
   4.106 +		// If the keyword_type table is passed, check columns from TAP_SCHEMA for keyword or optional_keyword 
   4.107  		} else if (keyword_type.toLowerCase() == "table" || (count_dots >= 2)) {
   4.108  
   4.109  			query = "SELECT column_name FROM TAP_SCHEMA.columns WHERE table_name LIKE '%." + keyword
   4.110  					+ "' OR  table_name='" + keyword + "'";
   4.111  			if (optional_keyword != null && optional_keyword != "") {
   4.112 -				query += " AND (column_name LIKE '" + optional_keyword + "%' OR column_name LIKE '"
   4.113 -						+ keyword + "." + optional_keyword + "%')";
   4.114 +				query += " AND (column_name LIKE '" + optional_keyword + "%' OR column_name LIKE '" + keyword + "."
   4.115 +						+ optional_keyword + "%')";
   4.116  			}
   4.117 -			String queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
   4.118 +			String queryURLStr = tapService + getRequestString
   4.119  					+ URLEncoder.encode(query, "UTF-8");
   4.120  			queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.121  			array = starTableToJSONArray(urlToStartable(queryURLStr));
   4.122  
   4.123 +		// If no keyword is not empty, Check tables, and then columns if no tables found with keyword
   4.124 +		// (A table name in TAP_SCHEMA may look like schema.tablename or tablename, need to find either)
   4.125  		} else if (keyword != "") {
   4.126  
   4.127  			query = "SELECT table_name FROM TAP_SCHEMA.tables WHERE schema_name='" + keyword + "'";
   4.128  			if (optional_keyword != null && optional_keyword != "") {
   4.129 -				query += " AND (table_name LIKE '" + optional_keyword + "%' OR table_name LIKE '"
   4.130 -						+ keyword + "." + optional_keyword + "%')";
   4.131 +				query += " AND (table_name LIKE '" + optional_keyword + "%' OR table_name LIKE '" + keyword + "."
   4.132 +						+ optional_keyword + "%')";
   4.133  			}
   4.134 -			String queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
   4.135 +			
   4.136 +			String queryURLStr = tapService + getRequestString
   4.137  					+ URLEncoder.encode(query, "UTF-8");
   4.138  			queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.139  			array = starTableToJSONArray(urlToStartable(queryURLStr));
   4.140 +			
   4.141 +			// No tables foundm check columns for keyword
   4.142  			if (array.length() <= 0) {
   4.143  
   4.144  				query = "SELECT column_name FROM TAP_SCHEMA.columns WHERE table_name LIKE '%." + keyword
   4.145  						+ "' OR  table_name='" + keyword + "'";
   4.146  				if (optional_keyword != null && optional_keyword != "") {
   4.147 -					query += " AND (column_name LIKE '" + optional_keyword + "%' OR column_name LIKE '"
   4.148 -							+ keyword + "." + optional_keyword + "%')";
   4.149 +					query += " AND (column_name LIKE '" + optional_keyword + "%' OR column_name LIKE '" + keyword + "."
   4.150 +							+ optional_keyword + "%')";
   4.151  
   4.152  				}
   4.153 -				queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
   4.154 +				queryURLStr = tapService + getRequestString
   4.155  						+ URLEncoder.encode(query, "UTF-8");
   4.156  				queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.157  				array = starTableToJSONArray(urlToStartable(queryURLStr));
   4.158  
   4.159  			}
   4.160 -		
   4.161 +
   4.162  			if (optional_keyword != null && optional_keyword != "") {
   4.163  				array = filter_name(array, optional_keyword);
   4.164  			}
   4.165 -			
   4.166 +
   4.167  		} else {
   4.168 +			// No keyword found, get initial list of schemas or tables
   4.169  			try {
   4.170  				if (optional_catalogues != "" && optional_catalogues != null) {
   4.171  
   4.172 @@ -152,7 +150,7 @@
   4.173  
   4.174  						query = "SELECT table_name FROM TAP_SCHEMA.tables WHERE schema_name='" + json_array.get(i)
   4.175  								+ "'";
   4.176 -						String queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
   4.177 +						String queryURLStr = tapService + getRequestString
   4.178  								+ URLEncoder.encode(query, "UTF-8");
   4.179  						queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.180  						JSONArray newArray = starTableToJSONArray(urlToStartable(queryURLStr));
   4.181 @@ -163,7 +161,7 @@
   4.182  
   4.183  				} else {
   4.184  					query = "SELECT schema_name FROM TAP_SCHEMA.schemas";
   4.185 -					String queryURLStr = tapService + "/sync?REQUEST=doQuery&VERSION=1.0&LANG=ADQL&QUERY="
   4.186 +					String queryURLStr = tapService + getRequestString
   4.187  							+ URLEncoder.encode(query, "UTF-8");
   4.188  					queryURLStr = queryURLStr.replaceAll(" ", "%20");
   4.189  					array = starTableToJSONArray(urlToStartable(queryURLStr));
   4.190 @@ -180,11 +178,12 @@
   4.191  		out.flush();
   4.192  	}
   4.193  
   4.194 +	
   4.195  	/**
   4.196  	 * Given a query URL (tap/sync?...), generate a StarTable
   4.197  	 * 
   4.198  	 * @param queryURLStr
   4.199 -	 * @return
   4.200 +	 * @return StarTable star
   4.201  	 * @throws TableFormatException
   4.202  	 * @throws IOException
   4.203  	 */
   4.204 @@ -196,11 +195,12 @@
   4.205  		return star;
   4.206  	}
   4.207  
   4.208 +	
   4.209  	/**
   4.210  	 * Get a JSONArray from a Startable
   4.211  	 * 
   4.212  	 * @param star
   4.213 -	 * @return
   4.214 +	 * @return JSONArray array
   4.215  	 */
   4.216  	public JSONArray starTableToJSONArray(StarTable star) {
   4.217  
   4.218 @@ -224,9 +224,17 @@
   4.219  			// TODO Auto-generated catch block
   4.220  			e.printStackTrace();
   4.221  		}
   4.222 +		
   4.223  		return array;
   4.224  	}
   4.225  
   4.226 +	
   4.227 +	/**
   4.228 +	 * Filter a JSONArray for a keyword, return list where elements (split by '.' in case of 'schema.tablename') match keyword
   4.229 +	 * @param original_list
   4.230 +	 * @param keyword
   4.231 +	 * @return
   4.232 +	 */
   4.233  	public JSONArray filter_name(JSONArray original_list, String keyword) {
   4.234  
   4.235  		JSONArray filtered_list = new JSONArray();
   4.236 @@ -235,8 +243,8 @@
   4.237  
   4.238  			String string_value = "";
   4.239  			try {
   4.240 -			
   4.241 -				String[] item_arr =  (String[]) original_list.get(i);
   4.242 +
   4.243 +				String[] item_arr = (String[]) original_list.get(i);
   4.244  				String item = item_arr[0];
   4.245  
   4.246  				// Grab the last segment
   4.247 @@ -251,8 +259,8 @@
   4.248  					filtered_list.put(string_value);
   4.249  				}
   4.250  			} else {
   4.251 -				if (string_value!=""){
   4.252 -				    filtered_list.put(string_value);
   4.253 +				if (string_value != "") {
   4.254 +					filtered_list.put(string_value);
   4.255  				}
   4.256  			}
   4.257  		}
     5.1 --- a/src/GENIUS-gwt-app/war/Genius.html	Thu Apr 28 14:59:14 2016 +0300
     5.2 +++ b/src/GENIUS-gwt-app/war/Genius.html	Thu May 05 18:12:03 2016 +0300
     5.3 @@ -38,7 +38,7 @@
     5.4  	    textfieldid: "textfield",
     5.5  	    web_service_path: 'genius/autocompleteAsync',
     5.6  	    html_resource: jQuery("#content_dbaccess_SQL_form #tap_endpoint").val(),
     5.7 -	    tap_resource: "",
     5.8 +	    tap_resource: 'http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/tap/',
     5.9  	    autocomplete_info_id: "",
    5.10  	    autocomplete_loader_id: "",
    5.11  	    servicemode: "TAP",
     6.1 --- a/src/GENIUS-gwt-app/war/genius/adql_syntax/tap-autocomplete.js	Thu Apr 28 14:59:14 2016 +0300
     6.2 +++ b/src/GENIUS-gwt-app/war/genius/adql_syntax/tap-autocomplete.js	Thu May 05 18:12:03 2016 +0300
     6.3 @@ -1,4 +1,4 @@
     6.4 -/*
     6.5 +/**
     6.6   *  Autocomplete for CodeMirror 2.
     6.7   *  Uses adql.js by Gregory Mantelet
     6.8   *  Extended to allow dynamic metadata keyword loading from webservice
     6.9 @@ -6,114 +6,123 @@
    6.10   *  @version 11/Feb/2015
    6.11   */
    6.12  
    6.13 -
    6.14  var TapAutocomplete = function(params) {
    6.15  
    6.16 -  this.istap = false;
    6.17 -  this.servicemode ="TAP";
    6.18 +	this.istap = false;
    6.19 +	this.servicemode = "TAP";
    6.20  
    6.21 -  if (params.textfieldid) this.textfieldid = params.textfieldid
    6.22 -  if (params.web_service_path) this.web_service_path = params.web_service_path;
    6.23 -  if (params.html_resource) this.html_resource = params.html_resource;
    6.24 -  if (params.tap_resource) this.tap_resource = params.tap_resource;
    6.25 -  if (params.autocomplete_info_id) this.autocomplete_info = params.autocomplete_info_id;
    6.26 -  if (params.autocomplete_loader_id) this.autocomplete_loader = params.autocomplete_loader_id;
    6.27 -  if (params.servicemode) this.servicemode = params.servicemode;
    6.28 -  if (params.initial_catalogues) {
    6.29 -     this.initial_catalogues = params.initial_catalogues;
    6.30 -  } else {
    6.31 -     this.initial_catalogues = [];
    6.32 -  }
    6.33 +	if (params.textfieldid)
    6.34 +		this.textfieldid = params.textfieldid
    6.35 +	if (params.web_service_path)
    6.36 +		this.web_service_path = params.web_service_path;
    6.37 +	if (params.html_resource)
    6.38 +		this.html_resource = params.html_resource;
    6.39 +	if (params.tap_resource)
    6.40 +		this.tap_resource = params.tap_resource;
    6.41 +	if (params.autocomplete_info_id)
    6.42 +		this.autocomplete_info = params.autocomplete_info_id;
    6.43 +	if (params.autocomplete_loader_id)
    6.44 +		this.autocomplete_loader = params.autocomplete_loader_id;
    6.45 +	if (params.servicemode)
    6.46 +		this.servicemode = params.servicemode;
    6.47 +	if (params.initial_catalogues) {
    6.48 +		this.initial_catalogues = params.initial_catalogues;
    6.49 +	} else {
    6.50 +		this.initial_catalogues = [];
    6.51 +	}
    6.52  
    6.53 -  if (this.servicemode.toLowerCase() == "tap") {
    6.54 -    this.istap = true;
    6.55 -  }
    6.56 +	if (this.servicemode.toLowerCase() == "tap") {
    6.57 +		this.istap = true;
    6.58 +	}
    6.59  
    6.60 +	if (this.editor == null && !jQuery('.CodeMirror').length > 0) {
    6.61 +		CodeMirror.commands.autocomplete = function(cm) {
    6.62 +			CodeMirror.tapHint(cm, CodeMirror.adqlHint,
    6.63 +					{
    6.64 +						webServicePath : params.web_service_path,
    6.65 +						tapResource : params.tap_resource,
    6.66 +						useAutocompleteService : (params.servicemode.toLowerCase() == "tap"),
    6.67 +						autocompleteLoader : params.autocomplete_loader_id,
    6.68 +						autocompleteInfo : params.autocomplete_info_id,
    6.69 +					});
    6.70 +		}
    6.71  
    6.72 -  if (this.editor == null && !jQuery('.CodeMirror').length > 0) {
    6.73 -    CodeMirror.commands.autocomplete = function(cm) {
    6.74 -      CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
    6.75 -        webServicePath: params.web_service_path,
    6.76 -        tapResource: params.tap_resource,
    6.77 -        useAutocompleteService: (params.servicemode.toLowerCase() == "tap"),
    6.78 -	    autocompleteLoader: params.autocomplete_loader_id,
    6.79 -        autocompleteInfo: params.autocomplete_info_id,
    6.80 -      });
    6.81 -    }
    6.82 +		this.editor = CodeMirror.fromTextArea(document.getElementById(params.textfieldid), {
    6.83 +			mode : "text/x-adql",
    6.84 +			tabMode : "indent",
    6.85 +			lineNumbers : true,
    6.86 +			matchBrackets : true,
    6.87 +			lineWrapping : true,
    6.88 +			textWrapping : true,
    6.89 +			extraKeys : {
    6.90 +				"Ctrl-Space" : "autocomplete",
    6.91 +			},
    6.92  
    6.93 -   this.editor = CodeMirror.fromTextArea(document.getElementById(params.textfieldid), {
    6.94 -      mode: "text/x-adql",
    6.95 -      tabMode: "indent",
    6.96 -      lineNumbers: true,
    6.97 -      matchBrackets: true,
    6.98 -      lineWrapping: true,
    6.99 -      textWrapping: true,
   6.100 -      extraKeys: {
   6.101 -        "Ctrl-Space": "autocomplete",
   6.102 -      },
   6.103 +		});
   6.104 +	}
   6.105  
   6.106 -    });
   6.107 -  }
   6.108 +	if (typeof this.editor.availableTags == 'undefined') {
   6.109 +		this.editor.availableTags = [ "SELECT", "FROM", "ORDER BY", "WHERE",
   6.110 +				"TOP", "IN", "AND", "OR", "WITH", "DESC", "ASC", "JOIN", "AS",
   6.111 +				"HAVING", "ABS", "GROUP", "BY", "INNER", "OUTER", "CROSS",
   6.112 +				"LEFT", "RIGHT", "FULL", "ON", "USING", "MIN", "MAX", "COUNT",
   6.113 +				"DISTINCT", "ALL", "LIKE", "ACOS", "ASIN", "ATAN", "ATAN2",
   6.114 +				"COS", "SIN", "TAN", "COT", "IS", "NOT", "NULL", "NATURAL",
   6.115 +				"EXISTS", "BETWEEN", "AREA", "BOX", "CENTROID", "CIRCLE",
   6.116 +				"CONTAINS", "COORD1", "COORD2", "COORDSYS", "DISTANCE",
   6.117 +				"INTERSECTS", "POINT", "POLYGON", "REGION" ];
   6.118 +	}
   6.119  
   6.120 -  if (typeof this.editor.availableTags == 'undefined') {
   6.121 -	  this.editor.availableTags = [
   6.122 -     		"SELECT", "FROM", "ORDER BY","WHERE", "TOP","IN", "AND", "OR", "WITH", "DESC", "ASC", "JOIN", "AS", "HAVING", "ABS",
   6.123 - 			"GROUP","BY", "INNER","OUTER","CROSS","LEFT","RIGHT","FULL","ON","USING","MIN","MAX","COUNT","DISTINCT","ALL","LIKE","ACOS","ASIN","ATAN","ATAN2","COS","SIN","TAN","COT","IS","NOT","NULL","NATURAL","EXISTS","BETWEEN","AREA","BOX","CENTROID","CIRCLE","CONTAINS","COORD1","COORD2","COORDSYS","DISTANCE","INTERSECTS","POINT","POLYGON","REGION"
   6.124 - 		];
   6.125 -  }
   6.126 -
   6.127 -  if (params.servicemode.toLowerCase() == "tap") {
   6.128 -    this.load_metadata_for_autocomplete(this.initial_catalogues);
   6.129 -  } else {
   6.130 -    this.load_metadata_from_html();
   6.131 -  }
   6.132 +	if (params.servicemode.toLowerCase() == "tap") {
   6.133 +		this.load_metadata_for_autocomplete(this.initial_catalogues);
   6.134 +	} else {
   6.135 +		this.load_metadata_from_html();
   6.136 +	}
   6.137  }
   6.138  
   6.139  /**
   6.140 - * Get the medata content from the HTML data to be used by the
   6.141 - * auto-completion functions Store the content in the
   6.142 - * keywords list
   6.143 - *
   6.144 + * Get the medata content from the HTML data to be used by the auto-completion
   6.145 + * functions Store the content in the keywords list
   6.146 + * 
   6.147   */
   6.148  TapAutocomplete.prototype.push_metadata_content_html = function(data) {
   6.149  
   6.150 -  var content = document.createElement('div');
   6.151 -  content.innerHTML = data;
   6.152 -  var tr = content.getElementsByClassName('heading');
   6.153 -  var tr2 = content.getElementsByClassName('expand');
   6.154 -  for (var i = 0; i < tr.length; i++) {
   6.155 -    var str = jQuery.trim(jQuery(tr[i]).justtext());
   6.156 -    var arr = str.split(".");
   6.157 -    for (var y = 0; y < arr.length; y++) {
   6.158 -    	this.editor.availableTags.push(arr[y]);
   6.159 -    }
   6.160 -  }
   6.161 -  for (var i = 0; i < tr2.length; i++) {
   6.162 -    if (!contains(this.editor.availableTags, tr2[i].innerHTML)) {
   6.163 -    	this.editor.availableTags.push(tr2[i].innerHTML);
   6.164 -    }
   6.165 -  }
   6.166 +	var content = document.createElement('div');
   6.167 +	content.innerHTML = data;
   6.168 +	var tr = content.getElementsByClassName('heading');
   6.169 +	var tr2 = content.getElementsByClassName('expand');
   6.170 +	for (var i = 0; i < tr.length; i++) {
   6.171 +		var str = jQuery.trim(jQuery(tr[i]).justtext());
   6.172 +		var arr = str.split(".");
   6.173 +		for (var y = 0; y < arr.length; y++) {
   6.174 +			this.editor.availableTags.push(arr[y]);
   6.175 +		}
   6.176 +	}
   6.177 +	for (var i = 0; i < tr2.length; i++) {
   6.178 +		if (!contains(this.editor.availableTags, tr2[i].innerHTML)) {
   6.179 +			this.editor.availableTags.push(tr2[i].innerHTML);
   6.180 +		}
   6.181 +	}
   6.182  
   6.183  };
   6.184  
   6.185  /**
   6.186 - * Get the medata content from the Json data to be used by the
   6.187 - * auto-completion functions Store the content in the
   6.188 - * keywords list
   6.189 - *
   6.190 + * Get the medata content from the Json data to be used by the auto-completion
   6.191 + * functions Store the content in the keywords list
   6.192 + * 
   6.193   */
   6.194  
   6.195  TapAutocomplete.prototype.push_metadata_json = function(data) {
   6.196 -  
   6.197 -  if (data.length > 0) {
   6.198 -    for (var i = 0; i < data.length; i++) {
   6.199 -      var str = jQuery.trim(data[i]);
   6.200 -      var arr = str.split(".");
   6.201 -      for (var y = 0; y < arr.length; y++) {
   6.202 -    	  this.editor.availableTags.push(arr[y]);
   6.203 -      }
   6.204 -    }
   6.205 -  }
   6.206 +
   6.207 +	if (data.length > 0) {
   6.208 +		for (var i = 0; i < data.length; i++) {
   6.209 +			var str = jQuery.trim(data[i]);
   6.210 +			var arr = str.split(".");
   6.211 +			for (var y = 0; y < arr.length; y++) {
   6.212 +				this.editor.availableTags.push(arr[y]);
   6.213 +			}
   6.214 +		}
   6.215 +	}
   6.216  
   6.217  };
   6.218  
   6.219 @@ -121,180 +130,192 @@
   6.220   * Run Autocomplete class
   6.221   */
   6.222  TapAutocomplete.prototype.run = function() {
   6.223 -  if (this.servicemode.toLowerCase() == "tap") {
   6.224 -    this.load_metadata_for_autocomplete();
   6.225 -  } else {
   6.226 -    this.load_metadata_from_html();
   6.227 -  }
   6.228 +	if (this.servicemode.toLowerCase() == "tap") {
   6.229 +		this.load_metadata_for_autocomplete();
   6.230 +	} else {
   6.231 +		this.load_metadata_from_html();
   6.232 +	}
   6.233  };
   6.234  
   6.235 -
   6.236  /**
   6.237   * Refresh autocomplete
   6.238   */
   6.239  TapAutocomplete.prototype.refresh = function() {
   6.240 -  CodeMirror.commands.autocomplete = function(cm) {
   6.241 -    CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
   6.242 -      webServicePath: this.web_service_path,
   6.243 -      tapResource: this.tap_resource,
   6.244 -      useAutocompleteService: this.istap,
   6.245 -      autocompleteInfo: this.autocomplete_info,
   6.246 -      autocompleteLoader: this.autocomplete_loader
   6.247 -    });
   6.248 -  }
   6.249 +	CodeMirror.commands.autocomplete = function(cm) {
   6.250 +		CodeMirror.tapHint(cm, CodeMirror.adqlHint, {
   6.251 +			webServicePath : this.web_service_path,
   6.252 +			tapResource : this.tap_resource,
   6.253 +			useAutocompleteService : this.istap,
   6.254 +			autocompleteInfo : this.autocomplete_info,
   6.255 +			autocompleteLoader : this.autocomplete_loader
   6.256 +		});
   6.257 +	}
   6.258  
   6.259 -  if (this.servicemode.toLowerCase() == "tap") {
   6.260 -    this.load_metadata_for_autocomplete();
   6.261 -  } else {
   6.262 -    this.load_metadata_from_html();
   6.263 -  }
   6.264 +	if (this.servicemode.toLowerCase() == "tap") {
   6.265 +		this.load_metadata_for_autocomplete();
   6.266 +	} else {
   6.267 +		this.load_metadata_from_html();
   6.268 +	}
   6.269  };
   6.270  
   6.271  /**
   6.272 - * Refresh autocomplete
   6.273 + * Load catalogue tables
   6.274 + * 
   6.275   */
   6.276  TapAutocomplete.prototype.load_catalogue_tables = function(catalogue_list) {
   6.277  
   6.278 -  if (this.servicemode.toLowerCase() == "tap") {
   6.279 -    this.load_metadata_for_autocomplete(catalogue_list);
   6.280 -  } else {
   6.281 -    this.load_metadata_from_html();
   6.282 -  }
   6.283 +	if (this.servicemode.toLowerCase() == "tap") {
   6.284 +		this.load_metadata_for_autocomplete(catalogue_list);
   6.285 +	} else {
   6.286 +		this.load_metadata_from_html();
   6.287 +	}
   6.288  };
   6.289  
   6.290 +/**
   6.291 + * Load metadata for autocomplete from HTML resource. Talks with a Web service
   6.292 + * that fetches the initial list of keywords
   6.293 + * 
   6.294 + */
   6.295 +TapAutocomplete.prototype.load_metadata_from_html = function() {
   6.296 +	_this = this;
   6.297  
   6.298 +	if (_this.autocomplete_info)
   6.299 +		jQuery("#" + _this.autocomplete_info).html(
   6.300 +				"Loading catalogue metadata keywords for auto-complete");
   6.301 +	if (_this.autocomplete_loader)
   6.302 +		jQuery("#" + _this.autocomplete_loader).show();
   6.303  
   6.304 +	/**
   6.305 +	 * Check whether an object (obj) is contained in a list (a)
   6.306 +	 * 
   6.307 +	 */
   6.308 +	function contains(a, obj) {
   6.309 +		var i = a.length;
   6.310 +		while (i--) {
   6.311 +			if (a[i] === obj) {
   6.312 +				return true;
   6.313 +			}
   6.314 +		}
   6.315 +		return false;
   6.316 +	}
   6.317 +
   6.318 +	function push_metadata_content_html(data) {
   6.319 +		if (!_this.editor.availableTags) {
   6.320 +			_this.editor.availableTags = [];
   6.321 +		}
   6.322 +
   6.323 +		var content = document.createElement('div');
   6.324 +		content.innerHTML = data;
   6.325 +		var tr = content.getElementsByClassName('heading');
   6.326 +		var tr2 = content.getElementsByClassName('expand');
   6.327 +		for (var i = 0; i < tr.length; i++) {
   6.328 +			var str = jQuery.trim(jQuery(tr[i]).text());
   6.329 +			var arr = str.split(".");
   6.330 +			for (var y = 0; y < arr.length; y++) {
   6.331 +				_this.editor.availableTags.push(arr[y]);
   6.332 +			}
   6.333 +		}
   6.334 +
   6.335 +		for (var i = 0; i < tr2.length; i++) {
   6.336 +			if (!contains(_this.editor.availableTags, tr2[i].innerHTML)) {
   6.337 +				_this.editor.availableTags.push(tr2[i].innerHTML);
   6.338 +			}
   6.339 +		}
   6.340 +
   6.341 +	}
   6.342 +
   6.343 +	jQuery.ajax({
   6.344 +		type : "POST",
   6.345 +		async : false,
   6.346 +		data : {
   6.347 +			resource : _this.html_resource,
   6.348 +			mode : "vosi"
   6.349 +		},
   6.350 +		url : _this.web_service_path,
   6.351 +		timeout : 1000000,
   6.352 +		error : function() {
   6.353 +			if (_this.autocomplete_info)
   6.354 +				jQuery("#" + _this.autocomplete_info).html(
   6.355 +						"CTRL + Space to activate auto-complete");
   6.356 +			if (_this.autocomplete_loader)
   6.357 +				jQuery("#" + _this.autocomplete_loader).hide();
   6.358 +
   6.359 +		},
   6.360 +		success : function(data) {
   6.361 +
   6.362 +			if (data != "") {
   6.363 +				push_metadata_content_html(data);
   6.364 +			}
   6.365 +			if (_this.autocomplete_info)
   6.366 +				jQuery("#" + _this.autocomplete_info).html(
   6.367 +						"CTRL + Space to activate auto-complete");
   6.368 +			if (_this.autocomplete_loader)
   6.369 +				jQuery("#" + _this.autocomplete_loader).hide();
   6.370 +
   6.371 +		}
   6.372 +	});
   6.373 +};
   6.374  
   6.375  /**
   6.376 - * Load metadata for autocomplete from HTML resource. Talks with a Web service that fetches the initial list of keywords
   6.377 - *
   6.378 + * Load metadata for autocomplete. Talks with a Web service that fetches the
   6.379 + * initial list of keywords
   6.380 + * 
   6.381   */
   6.382 -TapAutocomplete.prototype.load_metadata_from_html = function() {
   6.383 -  _this = this; 
   6.384 +TapAutocomplete.prototype.load_metadata_for_autocomplete = function(
   6.385 +		optional_catalogues) {
   6.386 +	_this = this;
   6.387  
   6.388 -  if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("Loading catalogue metadata keywords for auto-complete");
   6.389 -  if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).show();
   6.390 +	optional_catalogues = (typeof optional_catalogues === 'undefined') ? []
   6.391 +			: optional_catalogues;
   6.392  
   6.393 -  /**
   6.394 -   * Check whether an object (obj) is contained in a list (a)
   6.395 -   * 
   6.396 -   */
   6.397 -  function contains(a, obj) {
   6.398 -    var i = a.length;
   6.399 -    while (i--) {
   6.400 -      if (a[i] === obj) {
   6.401 -        return true;
   6.402 -      }
   6.403 -    }
   6.404 -    return false;
   6.405 -  }
   6.406 +	if (_this.autocomplete_info)
   6.407 +		jQuery("#" + _this.autocomplete_info).html(
   6.408 +				"Loading catalogue metadata keywords for auto-complete");
   6.409 +	if (_this.autocomplete_loader)
   6.410 +		jQuery("#" + _this.autocomplete_loader).show();
   6.411  
   6.412 -  function push_metadata_content_html(data) {
   6.413 -	if (!_this.editor.availableTags) {
   6.414 -		_this.editor.availableTags = [];
   6.415 -    }
   6.416 +	function push_metadata_json(data) {
   6.417 +		if (data.length > 0) {
   6.418 +			for (var i = 0; i < data.length; i++) {
   6.419 +				var str = jQuery.trim(data[i]);
   6.420 +				var arr = str.split(".");
   6.421 +				for (var y = 0; y < arr.length; y++) {
   6.422 +					_this.editor.availableTags.push(arr[y]);
   6.423 +				}
   6.424 +			}
   6.425 +		}
   6.426  
   6.427 -    var content = document.createElement('div');
   6.428 -    content.innerHTML = data;
   6.429 -    var tr = content.getElementsByClassName('heading');
   6.430 -    var tr2 = content.getElementsByClassName('expand');
   6.431 -    for (var i = 0; i < tr.length; i++) {
   6.432 -      var str = jQuery.trim(jQuery(tr[i]).text());
   6.433 -      var arr = str.split(".");
   6.434 -      for (var y = 0; y < arr.length; y++) {
   6.435 -    	  _this.editor.availableTags.push(arr[y]);
   6.436 -      }
   6.437 -    }
   6.438 +	}
   6.439  
   6.440 -    for (var i = 0; i < tr2.length; i++) {
   6.441 -      if (!contains(_this.editor.availableTags, tr2[i].innerHTML)) {
   6.442 -    	  _this.editor.availableTags.push(tr2[i].innerHTML);
   6.443 -      }
   6.444 -    }
   6.445 +	optional_catalogues = JSON.stringify(optional_catalogues);
   6.446 +	jQuery.ajax({
   6.447 +		type : "POST",
   6.448 +		async : false,
   6.449 +		data : {
   6.450 +			resource : _this.tap_resource,
   6.451 +			optional_catalogues : optional_catalogues,
   6.452 +			mode : "tap",
   6.453 +		},
   6.454 +		url : _this.web_service_path,
   6.455 +		timeout : 1000000,
   6.456 +		error : function(e) {
   6.457 +			if (_this.autocomplete_info)
   6.458 +				jQuery("#" + _this.autocomplete_info).html(
   6.459 +						"CTRL + Space to activate auto-complete");
   6.460 +			if (_this.autocomplete_loader)
   6.461 +				jQuery("#" + _this.autocomplete_loader).hide();
   6.462 +		},
   6.463 +		success : function(data) {
   6.464  
   6.465 -  }
   6.466 -
   6.467 -
   6.468 -  jQuery.ajax({
   6.469 -    type: "POST",
   6.470 -    async: false,
   6.471 -    data: {
   6.472 -      resource: _this.html_resource,
   6.473 -      mode: "vosi"
   6.474 -    },
   6.475 -    url: _this.web_service_path,
   6.476 -    timeout: 1000000,
   6.477 -    error: function() {
   6.478 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   6.479 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   6.480 -
   6.481 -    },
   6.482 -    success: function(data) {
   6.483 -
   6.484 -      if (data != "") {
   6.485 -       push_metadata_content_html(data);
   6.486 -      }
   6.487 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   6.488 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   6.489 -
   6.490 -    }
   6.491 -  });
   6.492 -};
   6.493 -
   6.494 -
   6.495 -
   6.496 -/**
   6.497 - *  Load metadata for autocomplete. Talks with a Web service that fetches the initial list of keywords
   6.498 - *
   6.499 - */
   6.500 -TapAutocomplete.prototype.load_metadata_for_autocomplete = function(optional_catalogues) {
   6.501 -  _this = this; 
   6.502 -
   6.503 -  optional_catalogues = (typeof optional_catalogues === 'undefined') ? [] : optional_catalogues;
   6.504 -
   6.505 -  if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("Loading catalogue metadata keywords for auto-complete");
   6.506 -  if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).show();
   6.507 -
   6.508 -
   6.509 -  function push_metadata_json(data) {
   6.510 -    if (data.length > 0) {
   6.511 -      for (var i = 0; i < data.length; i++) {
   6.512 -        var str = jQuery.trim(data[i]);
   6.513 -        var arr = str.split(".");
   6.514 -        for (var y = 0; y < arr.length; y++) {
   6.515 -        	_this.editor.availableTags.push(arr[y]);
   6.516 -        }
   6.517 -      }
   6.518 -    }
   6.519 -
   6.520 -
   6.521 -  }
   6.522 -
   6.523 -  optional_catalogues=JSON.stringify(optional_catalogues);
   6.524 -
   6.525 -  jQuery.ajax({
   6.526 -    type: "POST",
   6.527 -    async: false,
   6.528 -    data: {
   6.529 -      resource: _this.tap_resource,
   6.530 -      optional_catalogues: optional_catalogues,
   6.531 -      mode: "tap"
   6.532 -    },
   6.533 -    url: _this.web_service_path,
   6.534 -    timeout: 1000000,
   6.535 -    error: function(e) {
   6.536 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   6.537 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   6.538 -    },
   6.539 -    success: function(data) {
   6.540 -
   6.541 -
   6.542 -      if (data != "") {
   6.543 -        push_metadata_json(data);
   6.544 -      }
   6.545 -      if (_this.autocomplete_info) jQuery("#" + _this.autocomplete_info).html("CTRL + Space to activate auto-complete");
   6.546 -      if (_this.autocomplete_loader) jQuery("#" + _this.autocomplete_loader).hide();
   6.547 -    }
   6.548 -  });
   6.549 +			if (data != "") {
   6.550 +				push_metadata_json(data);
   6.551 +			}
   6.552 +			if (_this.autocomplete_info)
   6.553 +				jQuery("#" + _this.autocomplete_info).html(
   6.554 +						"CTRL + Space to activate auto-complete");
   6.555 +			if (_this.autocomplete_loader)
   6.556 +				jQuery("#" + _this.autocomplete_loader).hide();
   6.557 +		}
   6.558 +	});
   6.559  
   6.560  };
     7.1 --- a/src/GENIUS-gwt-app/war/genius/adql_syntax/tap-hint.js	Thu Apr 28 14:59:14 2016 +0300
     7.2 +++ b/src/GENIUS-gwt-app/war/genius/adql_syntax/tap-hint.js	Thu May 05 18:12:03 2016 +0300
     7.3 @@ -1,4 +1,4 @@
     7.4 -/*
     7.5 +/**
     7.6   *  Autocomplete for CodeMirror 2.
     7.7   *  Uses adql.js by Gregory Mantelet
     7.8   *  Extended to allow dynamic metadata keyword loading from webservice
     7.9 @@ -71,7 +71,6 @@
    7.10          return;
    7.11        }
    7.12        var result = getHints(editor, givenOptions);
    7.13 -      console.log(result);
    7.14        if (!result || !result.list.length) return;
    7.15        var completions = result.list;
    7.16  
    7.17 @@ -251,6 +250,7 @@
    7.18  
    7.19    /**
    7.20     *  Load metadata for autocomplete
    7.21 +   *  Sends Ajax request to autocomplete service with keyword & optional keyword
    7.22     *
    7.23     */
    7.24    function loadMetadataForAutocomplete(keyword, parentText, tags, editor, optional_keyword) {
    7.25 @@ -267,7 +267,8 @@
    7.26        data: {
    7.27          keyword: keyword,
    7.28          optional_keyword: optional_keyword,
    7.29 -        mode: "tap"
    7.30 +        mode: "tap",
    7.31 +        resource: editor.tapResource
    7.32  
    7.33        },
    7.34        url: editor.webServicePath,
    7.35 @@ -291,7 +292,9 @@
    7.36    }
    7.37  
    7.38  
    7.39 -
    7.40 +  /**
    7.41 +   * Get autocomplete keywords for given token
    7.42 +   */
    7.43    function getCompletions(token, context, keywords, options) {
    7.44      var found = [],
    7.45        start = token.string;