mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
GWT lib and translator: added support for multiple pgf files.
This commit is contained in:
@@ -12,6 +12,8 @@ public class CompletionOracle extends SuggestOracle {
|
||||
|
||||
private PGF pgf;
|
||||
|
||||
private String pgfName;
|
||||
|
||||
private ErrorHandler errorHandler;
|
||||
|
||||
private List<String> inputLangs = null;
|
||||
@@ -32,6 +34,14 @@ public class CompletionOracle extends SuggestOracle {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public String getGrammarName() {
|
||||
return pgfName;
|
||||
}
|
||||
|
||||
public void setGrammarName(String pgfName) {
|
||||
this.pgfName = pgfName;
|
||||
}
|
||||
|
||||
public void setInputLangs(List<String> inputLangs) {
|
||||
this.inputLangs = inputLangs;
|
||||
this.oldQuery = null;
|
||||
@@ -109,7 +119,7 @@ public class CompletionOracle extends SuggestOracle {
|
||||
// hack: first report no completions, to hide suggestions until we get the new completions
|
||||
callback.onSuggestionsReady(request, new SuggestOracle.Response(Collections.<CompletionSuggestion>emptyList()));
|
||||
|
||||
jsonRequest = pgf.complete(request.getQuery(), getInputLangs(), null, LIMIT_SCALE_FACTOR * request.getLimit(),
|
||||
jsonRequest = pgf.complete(getGrammarName(), request.getQuery(), getInputLangs(), null, LIMIT_SCALE_FACTOR * request.getLimit(),
|
||||
new PGF.CompleteCallback() {
|
||||
public void onResult(PGF.Completions completions) {
|
||||
List<CompletionSuggestion> suggestions = new ArrayList<CompletionSuggestion>();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package se.chalmers.cs.gf.gwt.client;
|
||||
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
|
||||
public class GrammarBox extends ListBox {
|
||||
|
||||
public GrammarBox() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setGrammarNames(PGF.GrammarNames grammarNames) {
|
||||
for (PGF.GrammarName grammarName : grammarNames.iterable()) {
|
||||
addItem(grammarName.getName());
|
||||
}
|
||||
if (!grammarNames.isEmpty()) {
|
||||
setSelectedIndex(0);
|
||||
setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public String getSelectedGrammar() {
|
||||
int i = getSelectedIndex();
|
||||
return i == -1 ? null : getValue(i);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,21 +2,23 @@ package se.chalmers.cs.gf.gwt.client;
|
||||
|
||||
public class InputLanguageBox extends MultiListBox {
|
||||
|
||||
public InputLanguageBox() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setGrammar(PGF.Grammar grammar) {
|
||||
for (PGF.Language l : grammar.getLanguages().iterable()) {
|
||||
String name = l.getName();
|
||||
if (l.canParse()) {
|
||||
addItem(name);
|
||||
if (name.equals(grammar.getUserLanguage())) {
|
||||
setSelectedIndex(getItemCount()-1);
|
||||
}
|
||||
}
|
||||
public InputLanguageBox() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setGrammar(PGF.Grammar grammar) {
|
||||
clear();
|
||||
addItem("Any language", "");
|
||||
for (PGF.Language l : grammar.getLanguages().iterable()) {
|
||||
String name = l.getName();
|
||||
if (l.canParse()) {
|
||||
addItem(name);
|
||||
if (name.equals(grammar.getUserLanguage())) {
|
||||
setSelectedIndex(getItemCount()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
setEnabled(true);
|
||||
}
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,15 +2,17 @@ package se.chalmers.cs.gf.gwt.client;
|
||||
|
||||
public class OutputLanguageBox extends MultiListBox {
|
||||
|
||||
public OutputLanguageBox() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setGrammar(PGF.Grammar grammar) {
|
||||
for (PGF.Language l : grammar.getLanguages().iterable()) {
|
||||
addItem(l.getName());
|
||||
public OutputLanguageBox() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setGrammar(PGF.Grammar grammar) {
|
||||
clear();
|
||||
addItem("All languages", "");
|
||||
for (PGF.Language l : grammar.getLanguages().iterable()) {
|
||||
addItem(l.getName());
|
||||
}
|
||||
setEnabled(true);
|
||||
}
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,17 +10,33 @@ import java.util.ArrayList;
|
||||
public class PGF {
|
||||
|
||||
private String baseURL;
|
||||
private String pgfName;
|
||||
|
||||
public PGF (String baseURL, String pgfName) {
|
||||
public PGF (String baseURL) {
|
||||
this.baseURL = baseURL;
|
||||
this.pgfName = pgfName;
|
||||
}
|
||||
|
||||
/* List grammars */
|
||||
|
||||
public JSONRequest listGrammars (final GrammarNamesCallback callback) {
|
||||
return JSONRequestBuilder.sendRequest(baseURL + "/", null, callback);
|
||||
}
|
||||
|
||||
public interface GrammarNamesCallback extends JSONCallback<GrammarNames> { }
|
||||
|
||||
public static class GrammarNames extends IterableJsArray<GrammarName> {
|
||||
protected GrammarNames() { }
|
||||
}
|
||||
|
||||
public static class GrammarName extends JavaScriptObject {
|
||||
protected GrammarName() { }
|
||||
|
||||
public final native String getName() /*-{ return this.name; }-*/;
|
||||
}
|
||||
|
||||
/* Grammar */
|
||||
|
||||
public JSONRequest grammar (final GrammarCallback callback) {
|
||||
return sendRequest("grammar", null, callback);
|
||||
public JSONRequest grammar (String pgfName, final GrammarCallback callback) {
|
||||
return sendGrammarRequest(pgfName, "grammar", null, callback);
|
||||
}
|
||||
|
||||
public interface GrammarCallback extends JSONCallback<Grammar> { }
|
||||
@@ -55,7 +71,7 @@ public class PGF {
|
||||
|
||||
/* Translation */
|
||||
|
||||
public JSONRequest translate (String input, List<String> fromLangs, String cat, List<String> toLangs,
|
||||
public JSONRequest translate (String pgfName, String input, List<String> fromLangs, String cat, List<String> toLangs,
|
||||
final TranslateCallback callback) {
|
||||
List<Arg> args = new ArrayList<Arg>();
|
||||
args.add(new Arg("input", input));
|
||||
@@ -70,7 +86,7 @@ public class PGF {
|
||||
args.add(new Arg("to", to));
|
||||
}
|
||||
}
|
||||
return sendRequest("translate", args, callback);
|
||||
return sendGrammarRequest(pgfName, "translate", args, callback);
|
||||
}
|
||||
|
||||
public interface TranslateCallback extends JSONCallback<Translations> { }
|
||||
@@ -89,7 +105,7 @@ public class PGF {
|
||||
|
||||
/* Completion */
|
||||
|
||||
public JSONRequest complete (String input, List<String> fromLangs, String cat, int limit, final CompleteCallback callback) {
|
||||
public JSONRequest complete (String pgfName, String input, List<String> fromLangs, String cat, int limit, final CompleteCallback callback) {
|
||||
List<Arg> args = new ArrayList<Arg>();
|
||||
args.add(new Arg("input", input));
|
||||
if (fromLangs != null) {
|
||||
@@ -99,7 +115,7 @@ public class PGF {
|
||||
}
|
||||
args.add(new Arg("cat", cat));
|
||||
args.add(new Arg("limit", limit));
|
||||
return sendRequest("complete", args, callback);
|
||||
return sendGrammarRequest(pgfName, "complete", args, callback);
|
||||
}
|
||||
|
||||
public interface CompleteCallback extends JSONCallback<Completions> { }
|
||||
@@ -117,7 +133,7 @@ public class PGF {
|
||||
|
||||
/* Parsing */
|
||||
|
||||
public JSONRequest parse (String input, List<String> fromLangs, String cat, final ParseCallback callback) {
|
||||
public JSONRequest parse (String pgfName, String input, List<String> fromLangs, String cat, final ParseCallback callback) {
|
||||
List<Arg> args = new ArrayList<Arg>();
|
||||
args.add(new Arg("input", input));
|
||||
if (fromLangs != null) {
|
||||
@@ -126,7 +142,7 @@ public class PGF {
|
||||
}
|
||||
}
|
||||
args.add(new Arg("cat", cat));
|
||||
return sendRequest("parse", args, callback);
|
||||
return sendGrammarRequest(pgfName, "parse", args, callback);
|
||||
}
|
||||
|
||||
public interface ParseCallback extends JSONCallback<ParseResults> { }
|
||||
@@ -144,7 +160,7 @@ public class PGF {
|
||||
|
||||
/* Common */
|
||||
|
||||
public <T extends JavaScriptObject> JSONRequest sendRequest(String resource, List<Arg> args, final JSONCallback<T> callback) {
|
||||
public <T extends JavaScriptObject> JSONRequest sendGrammarRequest(String pgfName, String resource, List<Arg> args, final JSONCallback<T> callback) {
|
||||
return JSONRequestBuilder.sendRequest(baseURL + "/" + pgfName + "/" + resource, args, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package se.chalmers.cs.gf.gwt.client;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
|
||||
public class StatusPopup extends PopupPanel {
|
||||
|
||||
private Label label = new Label();
|
||||
|
||||
public StatusPopup () {
|
||||
super(true, true);
|
||||
label = new Label();
|
||||
add(label);
|
||||
}
|
||||
|
||||
public void setStatus(String msg) {
|
||||
removeStyleDependentName("error");
|
||||
label.setText(msg);
|
||||
center();
|
||||
}
|
||||
|
||||
public void showError(String msg, Throwable e) {
|
||||
GWT.log(msg, e);
|
||||
addStyleDependentName("error");
|
||||
label.setText(msg);
|
||||
center();
|
||||
}
|
||||
|
||||
public void clearStatus() {
|
||||
removeStyleDependentName("error");
|
||||
label.setText("");
|
||||
hide();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,175 +5,212 @@ import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.ChangeListener;
|
||||
import com.google.gwt.user.client.ui.ClickListener;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
|
||||
|
||||
public class TranslateApp implements EntryPoint {
|
||||
|
||||
private static final String pgfBaseURL = "/pgf";
|
||||
private static final String pgfName = "grammar.pgf";
|
||||
private static final String pgfBaseURL = "/pgf";
|
||||
|
||||
private PGF pgf;
|
||||
private PGF pgf;
|
||||
|
||||
private CompletionOracle oracle;
|
||||
private SuggestBox suggest;
|
||||
private PGF.Grammar grammar;
|
||||
private InputLanguageBox fromLangBox;
|
||||
private OutputLanguageBox toLangBox;
|
||||
private Button translateButton;
|
||||
private VerticalPanel outputPanel;
|
||||
private PopupPanel statusPopup;
|
||||
private Label statusLabel;
|
||||
private CompletionOracle oracle;
|
||||
private SuggestBox suggest;
|
||||
private PGF.Grammar grammar;
|
||||
private GrammarBox grammarBox;
|
||||
private InputLanguageBox fromLangBox;
|
||||
private OutputLanguageBox toLangBox;
|
||||
private Button translateButton;
|
||||
private VerticalPanel outputPanel;
|
||||
private StatusPopup statusPopup;
|
||||
|
||||
private void addTranslation(String text, String toLang) {
|
||||
Label l = new Label(text);
|
||||
l.addStyleName("my-translation");
|
||||
PGF.Language lang = grammar.getLanguage(toLang);
|
||||
if (lang != null) {
|
||||
l.getElement().setLang(lang.getLanguageCode());
|
||||
//
|
||||
// Translation
|
||||
//
|
||||
|
||||
private void translate() {
|
||||
outputPanel.clear();
|
||||
setStatus("Translating...");
|
||||
pgf.translate(getGrammarName(), suggest.getText(), fromLangBox.getSelectedValues(), null,
|
||||
toLangBox.getSelectedValues(), new PGF.TranslateCallback() {
|
||||
public void onResult (PGF.Translations translations) {
|
||||
for (PGF.Translation t : translations.iterable()) {
|
||||
Label l = new Label(t.getText());
|
||||
l.addStyleName("my-translation");
|
||||
PGF.Language lang = grammar.getLanguage(t.getTo());
|
||||
if (lang != null) {
|
||||
l.getElement().setLang(lang.getLanguageCode());
|
||||
}
|
||||
outputPanel.add(l);
|
||||
}
|
||||
clearStatus();
|
||||
}
|
||||
public void onError (Throwable e) {
|
||||
showError("Translation failed", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
outputPanel.add(l);
|
||||
}
|
||||
|
||||
private void translate() {
|
||||
outputPanel.clear();
|
||||
setStatus("Translating...");
|
||||
pgf.translate(suggest.getText(), fromLangBox.getSelectedValues(), null,
|
||||
toLangBox.getSelectedValues(), new PGF.TranslateCallback() {
|
||||
public void onResult (PGF.Translations translations) {
|
||||
for (PGF.Translation t : translations.iterable()) {
|
||||
addTranslation(t.getText(), t.getTo());
|
||||
}
|
||||
clearStatus();
|
||||
}
|
||||
public void onError (Throwable e) {
|
||||
showError("Translation failed", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
// Status stuff
|
||||
//
|
||||
|
||||
private void updateLangs() {
|
||||
oracle.setInputLangs(fromLangBox.getSelectedValues());
|
||||
}
|
||||
private void setStatus(String msg) {
|
||||
statusPopup.setStatus(msg);
|
||||
}
|
||||
|
||||
private void setStatus(String msg) {
|
||||
statusLabel.setText(msg);
|
||||
statusPopup.center();
|
||||
}
|
||||
private void showError(String msg, Throwable e) {
|
||||
statusPopup.showError(msg, e);
|
||||
}
|
||||
|
||||
private void showError(String msg, Throwable e) {
|
||||
GWT.log(msg, e);
|
||||
setStatus(msg);
|
||||
}
|
||||
private void clearStatus() {
|
||||
statusPopup.clearStatus();
|
||||
}
|
||||
|
||||
private void clearStatus() {
|
||||
statusPopup.hide();
|
||||
}
|
||||
//
|
||||
// Grammars
|
||||
//
|
||||
|
||||
private void setGrammar(PGF.Grammar grammar) {
|
||||
this.grammar = grammar;
|
||||
private String getGrammarName() {
|
||||
return grammarBox.getSelectedGrammar();
|
||||
}
|
||||
|
||||
fromLangBox.setGrammar(grammar);
|
||||
toLangBox.setGrammar(grammar);
|
||||
private void updateAvailableGrammars() {
|
||||
pgf.listGrammars(new PGF.GrammarNamesCallback() {
|
||||
public void onResult(PGF.GrammarNames grammarNames) {
|
||||
grammarBox.setGrammarNames(grammarNames);
|
||||
// setGrammarNames() picks the first grammar automatically
|
||||
updateSelectedGrammar();
|
||||
}
|
||||
|
||||
updateLangs();
|
||||
clearStatus();
|
||||
translateButton.setEnabled(true);
|
||||
}
|
||||
public void onError (Throwable e) {
|
||||
showError("Error getting grammar list", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createTranslationUI() {
|
||||
private void updateSelectedGrammar() {
|
||||
oracle.setGrammarName(getGrammarName());
|
||||
updateAvailableLanguages();
|
||||
}
|
||||
|
||||
oracle = new CompletionOracle(pgf, new CompletionOracle.ErrorHandler() {
|
||||
public void onError(Throwable e) {
|
||||
showError("Completion failed", e);
|
||||
}
|
||||
});
|
||||
//
|
||||
// Languages
|
||||
//
|
||||
|
||||
suggest = new SuggestBox(oracle);
|
||||
suggest.addKeyboardListener(new KeyboardListenerAdapter() {
|
||||
public void onKeyUp (Widget sender, char keyCode, int modifiers) {
|
||||
if (keyCode == KEY_ENTER) {
|
||||
translate();
|
||||
}
|
||||
}
|
||||
});
|
||||
private void updateAvailableLanguages() {
|
||||
pgf.grammar(getGrammarName(), new PGF.GrammarCallback() {
|
||||
public void onResult(PGF.Grammar grammar) {
|
||||
TranslateApp.this.grammar = grammar;
|
||||
|
||||
fromLangBox = new InputLanguageBox();
|
||||
fromLangBox.addItem("Any language", "");
|
||||
fromLangBox.addChangeListener(new ChangeListener() {
|
||||
public void onChange(Widget sender) {
|
||||
updateLangs();
|
||||
translate();
|
||||
}
|
||||
});
|
||||
fromLangBox.setGrammar(grammar);
|
||||
toLangBox.setGrammar(grammar);
|
||||
|
||||
toLangBox = new OutputLanguageBox();
|
||||
toLangBox.addItem("All languages", "");
|
||||
toLangBox.addChangeListener(new ChangeListener() {
|
||||
public void onChange(Widget sender) {
|
||||
updateLangs();
|
||||
translate();
|
||||
}
|
||||
});
|
||||
updateSelectedLanguages();
|
||||
clearStatus();
|
||||
translateButton.setEnabled(true);
|
||||
}
|
||||
|
||||
translateButton = new Button("Translate");
|
||||
translateButton.setEnabled(false);
|
||||
translateButton.addClickListener(new ClickListener() {
|
||||
public void onClick(Widget sender) {
|
||||
translate();
|
||||
}
|
||||
});
|
||||
public void onError (Throwable e) {
|
||||
showError("Error getting language information", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
HorizontalPanel settingsPanel = new HorizontalPanel();
|
||||
settingsPanel.addStyleName("my-settingsPanel");
|
||||
settingsPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
|
||||
settingsPanel.add(new Label("From:"));
|
||||
settingsPanel.add(fromLangBox);
|
||||
settingsPanel.add(new Label("To:"));
|
||||
settingsPanel.add(toLangBox);
|
||||
settingsPanel.add(translateButton);
|
||||
private void updateSelectedLanguages() {
|
||||
oracle.setInputLangs(fromLangBox.getSelectedValues());
|
||||
translate();
|
||||
}
|
||||
|
||||
outputPanel = new VerticalPanel();
|
||||
outputPanel.addStyleName("my-translations");
|
||||
//
|
||||
// GUI
|
||||
//
|
||||
|
||||
VerticalPanel vPanel = new VerticalPanel();
|
||||
vPanel.setWidth("100%");
|
||||
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
||||
vPanel.add(suggest);
|
||||
vPanel.add(settingsPanel);
|
||||
vPanel.add(outputPanel);
|
||||
private void createTranslationUI() {
|
||||
|
||||
RootPanel.get().add(vPanel);
|
||||
statusPopup = new StatusPopup();
|
||||
setStatus("Loading...");
|
||||
|
||||
}
|
||||
oracle = new CompletionOracle(pgf, new CompletionOracle.ErrorHandler() {
|
||||
public void onError(Throwable e) {
|
||||
showError("Completion failed", e);
|
||||
}
|
||||
});
|
||||
|
||||
public void onModuleLoad() {
|
||||
statusLabel = new Label("Loading...");
|
||||
statusPopup = new PopupPanel(true, true);
|
||||
statusPopup.add(statusLabel);
|
||||
statusPopup.center();
|
||||
suggest = new SuggestBox(oracle);
|
||||
suggest.addKeyboardListener(new KeyboardListenerAdapter() {
|
||||
public void onKeyUp (Widget sender, char keyCode, int modifiers) {
|
||||
if (keyCode == KEY_ENTER) {
|
||||
translate();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pgf = new PGF(pgfBaseURL, pgfName);
|
||||
grammarBox = new GrammarBox();
|
||||
grammarBox.addChangeListener(new ChangeListener() {
|
||||
public void onChange(Widget sender) {
|
||||
updateSelectedGrammar();
|
||||
}
|
||||
});
|
||||
|
||||
createTranslationUI();
|
||||
ChangeListener languageChangeListener = new ChangeListener() {
|
||||
public void onChange(Widget sender) {
|
||||
updateSelectedLanguages();
|
||||
}
|
||||
};
|
||||
|
||||
pgf.grammar(new PGF.GrammarCallback() {
|
||||
public void onResult(PGF.Grammar grammar) {
|
||||
setGrammar(grammar);
|
||||
}
|
||||
fromLangBox = new InputLanguageBox();
|
||||
fromLangBox.addChangeListener(languageChangeListener);
|
||||
|
||||
public void onError (Throwable e) {
|
||||
showError("Error getting language information", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
toLangBox = new OutputLanguageBox();
|
||||
toLangBox.addChangeListener(languageChangeListener);
|
||||
|
||||
translateButton = new Button("Translate");
|
||||
translateButton.setEnabled(false);
|
||||
translateButton.addClickListener(new ClickListener() {
|
||||
public void onClick(Widget sender) {
|
||||
translate();
|
||||
}
|
||||
});
|
||||
|
||||
HorizontalPanel settingsPanel = new HorizontalPanel();
|
||||
settingsPanel.addStyleName("my-settingsPanel");
|
||||
settingsPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
|
||||
settingsPanel.add(new Label("Grammar:"));
|
||||
settingsPanel.add(grammarBox);
|
||||
settingsPanel.add(new Label("From:"));
|
||||
settingsPanel.add(fromLangBox);
|
||||
settingsPanel.add(new Label("To:"));
|
||||
settingsPanel.add(toLangBox);
|
||||
settingsPanel.add(translateButton);
|
||||
|
||||
outputPanel = new VerticalPanel();
|
||||
outputPanel.addStyleName("my-translations");
|
||||
|
||||
VerticalPanel vPanel = new VerticalPanel();
|
||||
vPanel.setWidth("100%");
|
||||
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
||||
vPanel.add(suggest);
|
||||
vPanel.add(settingsPanel);
|
||||
vPanel.add(outputPanel);
|
||||
|
||||
RootPanel.get().add(vPanel);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
|
||||
public void onModuleLoad() {
|
||||
pgf = new PGF(pgfBaseURL);
|
||||
createTranslationUI();
|
||||
updateAvailableGrammars();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user