1
0
forked from GitHub/gf-core

RGL Browse: version 2, including API search

Also using a jquery panel framework for layout stuff.
This commit is contained in:
john.j.camilleri
2013-07-23 14:16:42 +00:00
parent b6267b8296
commit 77b987103d
5 changed files with 351 additions and 250 deletions

View File

@@ -2,11 +2,44 @@
GF RGL Browser
John J. Camilleri, 2012
*/
$(document).ready(function() {
var thing = null;
$(document).ready(function(){
thing = new Thing();
// ===== URL history =====
$.history.on('load change push pushed', function(event, url, type) {
var stripExt = function(s) {
var i = s.lastIndexOf('.');
return (i>-1) ? s.substr(0, i) : s;
};
var s = url.split("/");
var lang = s[0];
var module = stripExt(s[1]);
var parseLineNo = s[1].match(/:(\d+)(-(\d+))?$/);
if (thing.state.current.equals(lang, module)) {
if (parseLineNo) {
scrollToCodeLine(parseInt(parseLineNo[1]));
}
// else there's nothing to do!
} else {
if (parseLineNo != null)
thing.loadFile(lang, module, parseInt(parseLineNo[1]));
else
thing.loadFile(lang, module);
}
}).listen('hash');
});
function Thing() {
var t = this;
// ===== State information =====
state = {
this.state = {
index: undefined,
lookup: {},
loadCount: 0,
@@ -15,14 +48,14 @@ $(document).ready(function() {
language: undefined,
module: undefined,
set: function(lang, module) {
state.current.language = lang;
state.current.module = module;
t.state.current.language = lang;
t.state.current.module = module;
},
equals: function(a, b) {
if (!b)
return (a == state.current.module);
return (a == t.state.current.module);
else
return (a == state.current.language) && (b == state.current.module);
return (a == t.state.current.language) && (b == t.state.current.module);
}
},
title: "RGL Source Browser",
@@ -31,33 +64,32 @@ $(document).ready(function() {
} ;
var lookupModuleLanguage = function(module) {
var l = state.lookup[module];
var l = t.state.lookup[module];
if (l==undefined || l.length==0)
return null;
else if (l.length==1)
return l[0];
else {
for (i in l) {
if ($.inArray(l[i], state.defaultLangs))
if ($.inArray(l[i], t.state.defaultLangs))
return l[i];
}
return l[0]; // no preferred default, just return first...
}
}
var lookupAllModuleLanguages = function(module) {
return state.lookup[module];
return t.state.lookup[module];
}
// ===== Utility/UI functions =====
var showLoading = function(){
state.loadCount++;
t.state.loadCount++;
$("#loading").show();
}
var hideLoading = function(){
state.loadCount = Math.max(state.loadCount-1, 0);
if (state.loadCount == 0)
t.state.loadCount = Math.max(t.state.loadCount-1, 0);
if (t.state.loadCount == 0)
$("#loading").hide();
}
@@ -82,14 +114,14 @@ $(document).ready(function() {
}
var clearScope = function(msg) {
$('#scope_list').empty();
$('#scope #results').empty();
updateScopeCount();
if (msg) {
$('#scope_list').html("<em>"+msg+"</em>");
$('#scope #results').html("<em>"+msg+"</em>");
}
}
var setScope = function(code) {
$('#scope_list').html(code);
$('#scope #results').html(code);
}
var clearCode = function(msg) {
$('#code pre').empty();
@@ -102,22 +134,24 @@ $(document).ready(function() {
prettyPrint();
}
var updateScopeCount = function(){
$('#scope_count').text( $("#scope_list tr:visible").length );
$('#scope #count').text( $("#scope #results tr:visible").length );
}
var updateAPICount = function(){
$('#api #count').text( $("#api #results tr:visible").length );
}
var setLanguage = function(lang){
state.language = lang;
t.state.language = lang;
$("#languages select").val(lang);
initModules(lang);
}
// obj can be just a plain selector or a jQuery object
var showPanel = function(obj, callback){
this.showPanel = function(obj, callback){
showLoading();
setTimeout(function(){
$(".panel:visible").hide();
$(obj).show(0, callback);
recalculateHeights();
updateScopeCount();
hideLoading();
}, 500); // this ensures the loading displays
@@ -128,28 +162,36 @@ $(document).ready(function() {
var setTitle = function(s){
$('#module_name').html(s);
$('title').html(state.title + ": " + s);
$('title').html(t.state.title + ": " + s);
}
// ===== Initialization =====
// Initialize the panels, tabs
$("a.tab").click(function(){
var panel = $(this).attr("href");
t.showPanel(panel);
return false;
});
t.showPanel(".panel:first");
// Load the index file and populate language & module lists
$.ajax({
url: "index.json",
dataType: "json",
type: "GET",
success: function(data) {
state.index = data;
if (data['urlprefix']) state.urlPrefix = data['urlprefix'];
t.state.index = data;
if (data['urlprefix']) t.state.urlPrefix = data['urlprefix'];
// Build language lookup index
for (var lang in data['languages']) {
for (var i in data['languages'][lang]) {
var module = data['languages'][lang][i];
if (!module) continue;
if (!state.lookup[module]) state.lookup[module] = [];
state.lookup[module].push(lang);
if (!t.state.lookup[module]) t.state.lookup[module] = [];
t.state.lookup[module].push(lang);
}
}
@@ -169,6 +211,11 @@ $(document).ready(function() {
.appendTo(lang_select);
}
setLanguage("english");
// Initialize API results
initAPI();
// Done
hideLoading();
},
error: function(){
@@ -177,50 +224,15 @@ $(document).ready(function() {
}
});
// Initialize the panels, tabs
$("a.tab").click(function(){
var panel = $(this).attr("href");
showPanel(panel);
return false;
});
showPanel(".panel:first");
// ===== URL history =====
$.History.bind(function(hash){
var s = hash.split("/");
var lang = s[0];
var module = stripExt(s[1]);
var parseLineNo = s[1].match(/:(\d+)(-(\d+))?$/);
if (state.current.equals(lang, module)) {
if (parseLineNo) {
scrollToCodeLine(parseInt(parseLineNo[1]));
}
// else there's nothing to do!
} else {
if (parseLineNo != undefined)
loadFile(lang, module, parseInt(parseLineNo[1]));
else
loadFile(lang, module);
}
});
var stripExt = function(s) {
var i = s.lastIndexOf('.');
return (i>-1) ? s.substr(0, i) : s;
};
// ===== Loading functionality =====
// Initialize the module list
var initModules = function(lang){
state.index['languages'][lang] = state.index['languages'][lang].sort();
t.state.index['languages'][lang] = t.state.index['languages'][lang].sort();
$("#modules").empty();
for (var i in state.index['languages'][lang]) {
var module = state.index['languages'][lang][i];
for (var i in t.state.index['languages'][lang]) {
var module = t.state.index['languages'][lang][i];
if (!module) continue;
$('<a>')
.html(module)
@@ -230,9 +242,9 @@ $(document).ready(function() {
};
// Load both scope & source for a file
var loadFile = function(lang, module, lineNo){
this.loadFile = function(lang, module, lineNo){
setTitle(lang+"/"+module);
state.current.set(lang, module);
t.state.current.set(lang, module);
loadTagsFile(module);
loadSourceFile(lang, module, lineNo);
}
@@ -279,7 +291,7 @@ $(document).ready(function() {
clearCode();
showLoading();
$.ajax({
url: state.urlPrefix + "lib/src/"+lang+"/"+module+".gf",
url: t.state.urlPrefix + "lib/src/"+lang+"/"+module+".gf",
type: "GET",
dataType: "text",
success: function(data, status, xhr){
@@ -296,6 +308,74 @@ $(document).ready(function() {
});
}
// Which modules do we include for API?
var apiModules = [
// api
"Constructors",
// abstract
"Adjective",
"Adverb",
"Backward",
"Cat",
"Common",
"Compatibility",
"Conjunction",
"Extra",
"Grammar",
"Idiom",
"Lang",
"Lexicon",
"Noun",
"Numeral",
"NumeralTransfer",
"Phrase",
"Question",
"Relative",
"Sentence",
"Structural",
"Symbol",
"Tense",
"Text",
"Transfer",
"Verb",
];
var initAPI = function() {
showLoading();
$('#api #results').empty();
for (var i in apiModules) {
var module = apiModules[i];
$.ajax({
url: "tags/"+module+".gf-tags",
type: "GET",
dataType: "text",
success: function(data){
data = data.replace(/^(\S+)\s(\S+)\s(.+)?$/gm, function(a,b,c,d){
var out = '';
var s = d.split("\t");
if (c != "indir") {
var type = s[1];
if (type) {
var bits = s[0].split("/"); // ["lib", "src", "english", "AdjectiveEng.gf:43-46"]
var name = bits[3]+"/"+bits[4];
var url = "#"+bits[3]+"/"+bits[4];
var anchor = '<a href="'+url+'">'+name+'</a>';
out += '<tr name="'+b+'"><th>'+b+'</th><td>'+c+'</td><td>'+anchor+'</td><td>'+s[1]+'</td></tr>'
}
}
return out;
});
$('#api #results').append($(data));
$("#api #results tr").removeClass('odd');
$("#api #results tr:odd").addClass('odd');
},
error: function(data){
console.log("Error loading tags file: " + module);
},
});
}
hideLoading();
}
// ===== Filtering of scope info =====
@@ -306,7 +386,7 @@ $(document).ready(function() {
var haystack = obj.attr('name');
if (haystack == undefined)
return false;
if ($("#case_sensitive").is(":checked"))
if ($("#scope #case_sensitive").is(":checked"))
return haystack.indexOf(needle)>=0;
else
return haystack.toLowerCase().indexOf(needle.toLowerCase())>=0;
@@ -314,97 +394,107 @@ $(document).ready(function() {
var runFilter = function() {
showLoading();
var s = $("#search").val();
$("#scope #results tr").removeClass('odd');
var s = $("#scope #search").val();
try {
if (s) {
$("#scope_list tr:match(\""+s+"\")").show();
$("#scope_list tr:not(:match(\""+s+"\"))").hide();
$("#scope #results tr").hide();
$("#scope #results tr:match(\""+s+"\")").show();
} else {
$("#scope_list tr").show();
$("#scope #results tr").show();
}
if ($("#show_local").is(":checked") ) {
$("#scope_list tr.indir").hide();
if ($("#scope #show_local").is(":checked") ) {
$("#scope #results tr.indir").hide();
}
} catch (error) {
alert(error.message);
}
updateScopeCount();
$("#scope #results tr:visible:odd").addClass('odd');
hideLoading();
}
// Instant results
var prevSearch = $("#search").val();
$("#search").keyup(function(){
var s = $("#search").val();
var prevSearch = $("#scope #search").val();
$("#scope #search").keyup(function(){
var s = $("#scope #search").val();
if (s!=prevSearch) {
runFilter();
prevSearch = s;
}
});
$("#submit").hide();
// Filter & clear buttons
// $("#submit").click(runFilter);
$("#search").keypress(function(e){
$("#scope #search").keypress(function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) { // Enter
runFilter();
}
});
$("#clear").click(function(){
$("#search")
$("#scope #clear").click(function(){
$("#scope #search")
.val('')
.focus()
runFilter();
});
$("#case_sensitive").change(runFilter);
$("#show_all").change(runFilter);
$("#show_local").change(runFilter);
$("#scope #case_sensitive").change(runFilter);
$("#scope #show_all").change(runFilter);
$("#scope #show_local").change(runFilter);
// ===== API search =====
// ===== Window resizing stuff =====
// Custom selector
$.expr[':'].matchAPI = function(a,b,c) {
var obj = $(a); // tr
var ident = $(obj.children().get(0)).text();
var type = $(obj.children().get(3)).text();
var needle = c[3];
var match_ident = ident.toLowerCase().indexOf(needle.toLowerCase())>=0;
var match_type = type.toLowerCase().indexOf(needle.toLowerCase())>=0;
// if ($("#scope #case_sensitive").is(":checked"))
// return haystack.indexOf(needle)>=0;
// else
return match_ident || match_type ;
};
// refer: http://paulirish.com/2009/throttled-smartresize-jquery-event-handler/
(function($,sr){
// debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) {
var timeout;
return function debounced () {
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
};
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
var runFilterAPI = function() {
showLoading();
$("#api #results tr").removeClass('odd');
var s = $("#api #search").val();
try {
if (s) {
$("#api #results tr").hide();
$("#api #results tr:matchAPI(\""+s+"\")").show();
} else {
$("#api #results tr").show();
}
} catch (error) {
alert(error.message);
}
// smartresize
jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
})(jQuery,'smartresize');
// usage:
$(window).smartresize(function() {
recalculateHeights();
});
var recalculateHeights = function() {
var x = 55; // just found empirically
$('body').height( $(window).height()-x);
$('.maxheight').each(function(){
var obj = $(this);
var parent = obj.parent();
obj.height(parent.height() - (obj.offset().top - parent.offset().top) - parseInt(parent.css('padding-bottom')));
});
updateAPICount();
$("#api #results tr:visible:odd").addClass('odd');
hideLoading();
}
recalculateHeights();
});
// Instant results
var prevAPISearch = $("#api #search").val();
$("#api #search").keyup(function(){
var s = $("#api #search").val();
if (s!=prevAPISearch) {
runFilterAPI();
prevAPISearch = s;
}
});
$("#api #search").keypress(function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) { // Enter
runFilterAPI();
}
});
$("#api #clear").click(function(){
$("#api #search")
.val('')
.focus()
runFilterAPI();
});
};