gf-3.4: src/www/syntax-editor/editor_menu.js
/* --- Editor Menu object --------------------------------------------------- */
function EditorMenu(editor,opts) {
var t = this;
/* --- Configuration ---------------------------------------------------- */
// default values for options:
this.options={
target: "editor",
show_grammar_menu: true,
show_startcat_menu: true,
show_to_menu: true,
show_random_button: true,
show_import: true,
show_export: true,
}
// Apply supplied options
if(opts) for(var o in opts) this.options[o]=opts[o];
/* --- Creating UI components ------------------------------------------- */
this.container = editor.ui.menubar;
this.ui = {
grammar_menu: empty_id("select","grammar_menu"),
startcat_menu: empty("select"),
to_toggle: button("Languages…", function(){
toggleHidden(t.ui.to_menu);
}),
to_menu: node("select",{
id: "to_menu",
multiple: "multiple",
class: "hidden"
}),
random_button: button("Random", function(){
t.editor.generate_random();
}),
import: {
toggle: button("Import…", function(){
toggleHidden(t.ui.import.panel);
}),
panel: node("div",{
id: "import",
class: "hidden"
}),
input: node("input",{type:"text"},[]),
button: button("Import", function(){
t.editor.import_ast(t.ui.import.input.value);
toggleHidden(t.ui.import.panel);
})
},
export_button: button("Export", function(){
alert(t.editor.ast.toString());
}),
debug_toggle: button("⚙", function(){
toggleHidden(element("debug"));
})
};
this.ui.to_toggle.title = "Select languages to linearise to (use Ctrl/Shift to select multiple)";
this.ui.random_button.title = "Insert a randomly generated tree at the current node";
this.ui.import.toggle.title = "Import an abstract syntax tree from a string (replaces current tree)";
this.ui.export_button.title = "Get the string representation of the abstract syntax tree";
this.ui.debug_toggle.title = "Toggle the debug console";
if (t.options.show_grammar_menu) {
appendChildren(t.container, [text(" Grammar: "), t.ui.grammar_menu]);
t.ui.grammar_menu.onchange = function(){
var grammar_url = t.ui.grammar_menu.value;
t.gm.change_grammar(grammar_url);
}
}
if (t.options.show_startcat_menu) {
appendChildren(t.container, [text(" Start Category: "), t.ui.startcat_menu]);
t.ui.startcat_menu.onchange = function(){
var startcat = t.ui.startcat_menu.value;
t.gm.change_startcat(startcat);
}
}
if (t.options.show_to_menu) {
appendChildren(t.container, [text(" To: "), t.ui.to_toggle, t.ui.to_menu]);
t.ui.to_menu.onchange = function(){
var languages = new Array();
for (i in t.ui.to_menu.options) {
var opt = t.ui.to_menu.options[i];
if (opt.selected)
languages.push(opt.value);
}
t.gm.change_languages(languages);
}
}
if (t.options.show_random_button) {
appendChildren(t.container, [t.ui.random_button]);
}
if (t.options.show_import) {
appendChildren(t.container, [
t.ui.import.toggle,
t.ui.import.panel
]);
appendChildren(t.ui.import.panel, [
text("Import AST: "),
t.ui.import.input,
t.ui.import.button
]);
}
if (t.options.show_export) {
appendChildren(t.container, [
t.ui.export_button,
]);
}
appendChildren(t.container, [t.ui.debug_toggle]);
/* --- Client state initialisation -------------------------------------- */
this.editor = editor;
this.gm = editor.gm;
this.server = editor.server;
/* --- Register Grammar Manager hooks ----------------------------------- */
this.gm.register_action("onload", bind(this.hook_onload, this));
this.gm.register_action("change_grammar", bind(this.hook_change_grammar, this));
this.gm.register_action("change_startcat", bind(this.hook_change_startcat, this));
}
/* --- Grammar menu --------------------------------------------------------- */
// show the grammar list
EditorMenu.prototype.hook_onload=function(dir,grammar_names,dir_count) {
debug("EditorMenu: onload");
var t=this;
var first_time=t.ui.grammar_menu.options.length == 0;
if(first_time) {
t.grammars=[];
t.grammar_dirs=[];
}
t.grammar_dirs.push(dir);
t.grammars=t.grammars.concat(grammar_names.map(function(g){return dir+g}))
function glabel(g) {
return hasPrefix(dir,"/tmp/gfse.") ? "gfse: "+g : g
}
function opt(g) { return option(glabel(g),dir+g); }
appendChildren(t.ui.grammar_menu, map(opt, grammar_names));
function pick_first_grammar() {
if(t.timeout) clearTimeout(t.timeout),t.timeout=null;
var grammar0=t.gm.options.initial.grammar;
if(!grammar0) grammar0=t.grammars[0];
t.ui.grammar_menu.value=grammar0;
// t.change_grammar();
}
// Wait at most 1.5s before showing the grammar menu.
if(first_time) t.timeout=setTimeout(pick_first_grammar,1500);
if(t.grammar_dirs.length>=dir_count) pick_first_grammar();
}
// Copied from minibar.js
EditorMenu.prototype.hook_change_grammar=function(grammar) {
debug("EditorMenu: change grammar");
var t=this;
t.update_startcat_menu(grammar);
t.update_language_menu(t.ui.to_menu, grammar);
}
/* --- Start category menu -------------------------------------------------- */
// Called from hook_change_grammar
EditorMenu.prototype.update_startcat_menu=function(grammar) {
var t=this;
var menu=this.ui.startcat_menu;
menu.innerHTML="";
var cats=grammar.categories;
for(var cat in cats) menu.appendChild(option(cats[cat],cats[cat]))
var startcat0 = t.gm.options.initial.startcat;
if (elem(startcat0, cats))
menu.value = startcat0;
else
menu.value = grammar.startcat;
}
// If startcat changed externally, update menu
EditorMenu.prototype.hook_change_startcat=function(startcat) {
debug("EditorMenu: change startcat");
var t=this;
var menu=this.ui.startcat_menu;
menu.value = startcat;
}
/* --- Langugage (to) menu -------------------------------------------------- */
// Called from hook_change_grammar
EditorMenu.prototype.update_language_menu=function(menu,grammar) {
var t = this;
function langpart(conc,abs) { // langpart("FoodsEng","Foods") == "Eng"
return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc;
}
// Replace the options in the menu with the languages in the grammar
var langs=grammar.languages;
menu.innerHTML="";
for(var i=0; i<langs.length; i++) {
var ln=langs[i].name;
if(!hasPrefix(ln,"Disamb")) {
var lp=langpart(ln,grammar.name);
var opt=option(lp,ln);
if (elem(lp, t.gm.options.initial.languages)) {
opt.selected=true;
}
menu.appendChild(opt);
}
}
}