inplace editing/parsing in the syntax editor

This commit is contained in:
krasimir
2010-01-07 10:38:43 +00:00
parent 5be5ee1ccd
commit 712d079e7c
3 changed files with 140 additions and 81 deletions

View File

@@ -10,7 +10,7 @@
<script type="text/javascript" src="gfjseditor.js"></script>
<title>Web-based Syntax Editor</title>
</head>
<body onload="mkEditor('editor', Food)" onkeydown="hotKeys(event)">
<body onload="mkEditor('editor', Food)" onkeydown="return hotKeys(event)">
<div id="editor">
</div>
</body>

View File

@@ -99,19 +99,28 @@ function hotKeys(event) {
event = (event) ? event : ((window.event) ? event : null);
if (event) {
var charCode = (event.charCode) ? event.charCode : ((event.which) ? event.which : event.keyCode);
if (document.getElementById("actParse").className == "selected" && charCode != 27)
return true;
if (keys[String.fromCharCode(charCode).toUpperCase()] &&
!event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
keys[String.fromCharCode(charCode).toUpperCase()]();
return false;
}
else if (keys["" + charCode] &&
!event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
keys["" + charCode]();
return false;
}
else if (charCode >= "96" && charCode <= "105" &&
!event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
keys["" + (charCode - 96)]();
return false;
}
}
return true;
}
// Clears "numeric" hotkeys
@@ -152,7 +161,7 @@ function getNode(nodeName, node) {
// Action to be performed when the left arrow key is pressed
function leftArrowKey() {
var node = getNode(selectedNode, myTree);
var node = getNode(selectedNode, myTree);
if (!node.collapsed && node.hasChildren()) {
signClick(node.name, node.caption);
}
@@ -180,7 +189,7 @@ function getParent(nodeName, node) {
// Action to be performed when the right arrow key is pressed
function rightArrowKey() {
var node = getNode(selectedNode, myTree);
var node = getNode(selectedNode, myTree);
if (node.collapsed) {
signClick(node.name, node.caption);
}
@@ -269,6 +278,107 @@ function getLinearizedFrame() {
return linearizedFrame.join("");
}
// Linearizes and displays the abstract tree
function drawEditFrame() {
var frame = document.getElementById("conFrame");
frame.innerHTML = getEditFrame();
}
// Linearizes the abstract tree and returns it in HTML form
function getEditFrame() {
var editFrame = new Array();
for (var i in grammar.concretes) {
editFrame.push("<h4>", i, "</h4>");
editFrame.push("<p id='line", i, "'>");
if (abstractTree.isMeta()) {
editFrame.push("<span class='edit' contenteditable=true onkeydown='return editFrameKeyDown(this,\"",i,"\",event)'>&nbsp;");
isLastSelected = true;
} else {
var tokens = grammar.concretes[i].tagAndLinearize(abstractTree);
var isLastSelected = false;
for (var j = 0, k = tokens.length; j < k; j++) {
var token = tokens[j];
var node = getNode(token.tag, myTree);
if (node.name.substr(0, selectedNode.length) == selectedNode) {
if (!isLastSelected) {
editFrame.push("<span class='edit' contenteditable=true onkeydown='return editFrameKeyDown(this,\"",i,"\",event)'>");
isLastSelected = true;
}
if (token == "&-")
editFrame.push("<br/>");
else
editFrame.push(token+" ");
} else {
if (isLastSelected) {
editFrame.push("</span>");
isLastSelected = false;
}
if (token == "&-")
editFrame.push("<br/>");
else
editFrame.push("<span id='", token.tag, "' class='normal'>", token, "</span>");
}
}
}
if (isLastSelected) {
editFrame.push("</span>");
isLastSelected = false;
}
editFrame.push("</p>");
}
editFrame.push("<h4>Abstract</h4>");
editFrame.push("<p id='lineAbstract'>", createLinearizedFromAbstract(myTree, "0"), "</p>");
return editFrame.join("");
}
function editFrameKeyDown(me,lang,event) {
event = (event) ? event : ((window.event) ? event : null);
if (event) {
var charCode = (event.charCode) ? event.charCode : ((event.which) ? event.which : event.keyCode);
if (charCode == 13) {
refPageCounter = 0;
parseTrees = undefined;
var string = me.innerText;
if (string || string == "") {
var node = getNode(selectedNode, myTree);
switch (node.cat) {
case "String": parseTrees = [new Fun('"'+string+'"')]; break;
case "Int": if (isNaN(string) || (string && string.indexOf(".") != -1))
parseTrees = new Array();
else
parseTrees = [new Fun(string)];
break;
case "Float": if (isNaN(string))
parseTrees = new Array();
else
parseTrees = [new Fun(string)];
break;
default: parseTrees = grammar.concretes[lang].parser.parseString(string, node.cat); break;
}
if (parseTrees.length == 1) {
pushUndoClearRedo();
abstractTree = insertNode(abstractTree, selectedNode, "0", grammar.abstract.copyTree(grammar.abstract.handleLiterals(parseTrees[0], node.cat)));
document.getElementById("actFrame").innerHTML = showActions();
document.getElementById("refFrame").innerHTML = "";
clearHotKeys();
concludeAction();
} else if (parseTrees.length > 1) {
document.getElementById("refFrame").innerHTML = showTrees();
}
}
return false;
}
}
return true;
}
// Creates an HTML representation of a linearization of an abstract tree
function createLinearized(token) {
var node = getNode(token.tag, myTree);
@@ -281,7 +391,7 @@ function createLinearized(token) {
linearized.push("'normal'");
}
if (token == "&-") { linearized.push("<br />"); }
else { linearized.push(" onclick='nodeClick(\"", node.name, "\");'>&nbsp;", token, " </span>"); }
else { linearized.push(" onclick='nodeClick(\"", node.name, "\");'>", token, "</span>"); }
return linearized.join("");
}
@@ -486,12 +596,6 @@ function showActions(caption) {
actions.push(createAction("Refine", "action", "SingleWordCommand Refine", "R"));
actions.push(createAction("Replace", "unavailable", "SingleWordCommand Replace", "E"));
actions.push(createAction("Wrap", "unavailable", "SingleWordCommand Wrap", "W"));
for (var i in grammar.concretes) {
if (grammar.concretes[i].parser) {
actions.push(createAction("Parse", "action", "Command Parse IndefSgDet String_N", "P"));
} else { actions.push(createAction("Parse", "unavailable", "Command Parse IndefSgDet String_N", "P")); }
break;
}
}
else if (node.caption) {
actions.push(createAction("Cut", "action", "SingleWordCommand Cut", "X"));
@@ -501,8 +605,15 @@ function showActions(caption) {
actions.push(createAction("Refine", "unavailable", "SingleWordCommand Refine", "R"));
actions.push(createAction("Replace", "action", "SingleWordCommand Replace", "E"));
actions.push(createAction("Wrap", "action", "SingleWordCommand Wrap", "W"));
actions.push(createAction("Parse", "unavailable", "Command Parse IndefSgDet String_N", "P"));
}
for (var i in grammar.concretes) {
if (grammar.concretes[i].parser) {
actions.push(createAction("Parse", "action", "Command Parse IndefSgDet String_N", "P"));
} else { actions.push(createAction("Parse", "unavailable", "Command Parse IndefSgDet String_N", "P")); }
break;
}
if (node && !abstractNode.isComplete()) {
actions.push(createAction("RandomNode", "action", "RandomlyCommand Refine DefSgDet Node", "N"));
}
@@ -530,55 +641,14 @@ function createAction(actionName, className, caption, hotKey) {
// When the "Refine" action is selected, gets the appropriate refinements for a node
function clickRefine(actName) {
if (document.getElementById(actName).className == "action") {
highlightSelectedAction(actName);
pushUndoClearRedo();
if (selectedNode) {
refPageCounter = 0;
var node = getNodeFromAbstract(abstractTree, selectedNode, "0");
if (node.type == "String" || node.type == "Int" || node.type == "Float") {
var newType = undefined;
var newTypeCat = node.type + "_Literal_";
switch(node.type)
{
case "String":
var msg = editorGrammar.concretes[selectedLanguage].linearize(editorGrammar.abstract.parseTree("Command Enter IndefSgDet String_N", editorGrammar.abstract.startcat));
newType = prompt(msg.substring(0,1).toUpperCase().concat(msg.substring(1)),'String');
if (!newType) { newType = "AutoString"; }
break;
case "Int":
while (isNaN(newType) || (newType && newType.indexOf(".") != -1)) {
var msg = editorGrammar.concretes[selectedLanguage].linearize(editorGrammar.abstract.parseTree("Command Enter IndefSgDet Integer_N", editorGrammar.abstract.startcat));
newType = prompt(msg.substring(0,1).toUpperCase().concat(msg.substring(1)),'Int');
}
if (!newType) { newType = "8"; }
break;
case "Float":
while (isNaN(newType)) {
var msg = editorGrammar.concretes[selectedLanguage].linearize(editorGrammar.abstract.parseTree("Command Enter IndefSgDet Float_N", editorGrammar.abstract.startcat));
newType = prompt(msg.substring(0,1).toUpperCase().concat(msg.substring(1)),'Float');
}
if (!newType) { newType = "8.0"; }
if (newType.indexOf(".") == -1) { newType += ".0"; }
break;
}
if (node.type == "String") {
newTypeCat += "\"" + newType + "\"";
} else {
newTypeCat += newType;
}
if (!grammar.abstract.types[newTypeCat]) {
grammar.abstract.addType(newTypeCat, [], node.type);
for (var i in grammar.concretes) {
grammar.concretes[i].addRule(newTypeCat, function(cs){ return new Arr(new Str(newType));});
}
}
node.name = newTypeCat;
abstractTree = insertNode(abstractTree, selectedNode, "0", node);
document.getElementById("actFrame").innerHTML = showActions();
document.getElementById("refFrame").innerHTML = "";
clearHotKeys();
concludeAction();
clickParse("actParse");
} else {
highlightSelectedAction(actName);
pushUndoClearRedo();
document.getElementById("refFrame").innerHTML = showRefinements(selectedNode);
}
}
@@ -892,31 +962,9 @@ function clickParse(actName) {
highlightSelectedAction(actName);
var node = getNode(selectedNode, myTree);
if (selectedNode) {
refPageCounter = 0;
parseTrees = undefined;
var msg = editorGrammar.concretes[selectedLanguage].linearize(editorGrammar.abstract.parseTree("Command Enter IndefSgDet String_N", editorGrammar.abstract.startcat));
var string = prompt(msg.substring(0,1).toUpperCase().concat(msg.substring(1)),'String');
if (string || string == "") {
for (var i in grammar.concretes) {
parseTrees = grammar.concretes[i].parser.parseString(string, node.cat);
if (parseTrees.length == 1) {
pushUndoClearRedo();
abstractTree = insertNode(abstractTree, selectedNode, "0", grammar.abstract.copyTree(grammar.abstract.handleLiterals(parseTrees[0], node.cat)));
document.getElementById("actFrame").innerHTML = showActions();
document.getElementById("refFrame").innerHTML = "";
clearHotKeys();
concludeAction();
return false;
} else if (parseTrees.length > 1) {
document.getElementById("refFrame").innerHTML = showTrees();
return false;
}
}
} else { nodeClick(selectedNode); return false; }
var lin = editorGrammar.concretes[selectedLanguage].linearize(editorGrammar.abstract.parseTree("ErrorMessage Available Tree", editorGrammar.abstract.startcat));
alert(lin.substring(0,1).toUpperCase().concat(lin.substring(1)));
pushUndoClearRedo();
drawEditFrame();
}
nodeClick(selectedNode);
}
}

View File

@@ -78,8 +78,6 @@ body {
#tree {
left: -10px;
top: -10px;
width: 250px;
height: 250px;
margin: 0px;
padding: 10px;
overflow: auto;
@@ -232,10 +230,23 @@ span.normal {
color: black;
background-color: white;
text-decoration: none;
padding-left: 2px;
padding-right: 2px;
}
span.edit {
color: black;
background-color: white;
text-decoration: none;
border:2px inset;
padding-left: 2px;
padding-right: 2px;
}
span.selected {
color: white;
background-color: #3366CC;
text-decoration: none;
padding-left: 2px;
padding-right: 2px;
}