I've tried to develop an UI in JavaScript to parse specific code described in my ANTLR4 grammar. I use a visitor to parse all parts of code and generate a questionnaire. Afterwards, depending on users' input in a JavaScript form, I parse the last part of my code to generate results (it's close to the calculator mechanism drafted into ANTLR book). So far so good. Nonetheless, I would like to modify inputs in the JavaScript form and parse a second time to regenerate and recalculate some results. At this moment, the AST tree becomes empty. I've tried to reinitialise the lexer the parser, the visitor as such as to create a new instance of the parser. It seems that previous parser and lexer are still active and it is impossible to "move the cursor up" to parse again a specific block of my source code.
Thanks for your precious help.
Chris
Below summarised file and script.
grammar.G4
pre
: title ('\n')+
author ('\n')+
;
peri
: (statement ('\n')+)*
(answer ('\n')+)*
;
post
: (feedback ('\n')+)*
;
exercise
: pre peri post
;
//End of Grammar
javascript main class :
class MyExercise {
constructor(){
this.chars = antlr4.CharStreams.fromBuffer(input,'utf-8');
this.lexer = new MyLexer(this.chars);
this.tokens = new antlr4.CommonTokenStream(this.lexer);
this.parser = new MyParser(this.tokens);
this.visitor = new LabeledVisitor(this.exercise,this.parser);
this.parser.buildParseTrees = true;
tree = this.parser.pre();
this.visitor.visitPre(tree);
tree = this.parser.peri();
this.visitor.visitPeri(tree);
this.generateAnswersHTML() // generate HTML results and also inputfields to collect values from user.
this.generateSubmitButton(); // generate submit HTML button
}
generateSubmitButton(){
var button = document.createElement('input');
button.setAttribute('type','submit');
button.setAttribute('value','Check answer');
button.addEventListener("click",this.checkAnswers.bind(this));
document.getElementById("answer").appendChild(button);
}
checkAnswers(object){
var tree = this.parser.post();
this.visitor.visitPost(tree);
this.generateFeeback(); //Generate HTML feedbacks (function of inputed values by user)
}
}
It works well the first time but when I click again on the button checkanswer which calls checkAnswer() method, the tree becomes empty.
There are 2 ways to reparse your input:
Recreate your input stream, token source + parser every time.
Reset your input stream and token source, by
Recreate your input stream or load the new text into your existing one.
Call parser.reset().
Set your input stream again in the token source (to reset it, just calling .reset() won't cut it). lexer.setInputStream(input);
Set your token source in the token stream again, for the same reason. tokens.setTokenSource(lexer);
Related
so i have this block of sql query code here for sending user description to db in node js.
const sqlAddDescription = (desc, id) => {return `UPDATE \`Memcon\`.\`users_list\` SET \`description\` = '${desc}' WHERE (\`id\` = '${id}')`}
it's working completely fine, in the client user inputs a text and the db process goes on with no problem.
BUT if the user sends an input with backticks or quotes or even brackets, the process gonna fail because their text head on goes to ${desc} and it replaces it, so it creates an error.
How can i tell js to fully stringify the text, no matter the inputs.
(i also tried JSON.stringify but that serves a different purpose )
Ok... so a user enters info into the journal field and hits submit, and a function gets called on the information they have submitted, which I call changeTextComment(). That function calls another function and so on as the info is formatted and placed in the cue, as in a Facebook commentary.
I need this information saved so it can be recalled later, in local storage, making the app not refresh every time I restart it. So...
<script>
function appCache() {
// Check browser support
// this is experimental for local storage...
more here: http://www.w3schools.com/html/html5_webstorage.asp
if (typeof(Storage) != "undefined") {
localStorage.setItem(para);
// Retrieve
document.getElementById("journal").innerHTML = localStorage.getItem(para);
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Storage...";
};
</script>
So looking at the appCache function it seems like it might work except I need to identify what the key variable is that will be stored and then retrieved.
I think this is the variable userInput, as any time the user hits the 'add to journal' button this variable is used to store the user input and then put into the changeTextComment() function.
I am wondering if this is the simplest way to deal with this whole thing... I do not yet understand databases, but wondering if that would be easier to learn.
In this case, I would add the function Appcache() to the function changeText() such that it caches the variable and then how would I set it up to then feed the value of the variable's cached info into changeText() upon launch of the app?
Every submission to the journal will have a unique value.
Heres the ChangeTextComment() Function... still sorting out how to use classes in css to simplify these functions:
function changeTextComment(){
// to be modified from the above to change the location of the dump
var userInput = document.getElementById('userInput').value;
// get the input from the user
var panel = document.createElement("div"); // create a parent divider for everything
// assignment of attributes
panel.setAttribute("class","panel panel-default panel-body");
panel.setAttribute("id","panelBody");
var para = document.createElement("P");
var t = document.createTextNode(userInput);
para.appendChild(t);
// add comment area
var c = document.createElement("INPUT");
c.setAttribute("type", "text");
c.setAttribute("id", "comment");
c.setAttribute("placeholder", "comment here");
c.setAttribute("class", "form-control input-lg");
// add comment button attempt -- success <> now try to put it in the textarea
var d = document.createElement("INPUT");
d.setAttribute("type","button");
d.setAttribute("class","btn btn-info active pull-right");
d.setAttribute("onclick","commentThis()");
d.setAttribute("value","Add Comment");
panel.appendChild(para); // this is where a comments piece would go
// place the item
var destination = document.getElementById("journal")
//destination.insertBefore(Commentaryarea, destination.firstChild);
//destination.insertBefore(panel, destination.firstChild);
destination.insertBefore(panel, destination.firstChild);
panel.appendChild(c);
panel.appendChild(d);
document.getElementById("userInput").value = "";
document.getElementById("userInput").focus();}
</script>
<script>
function setText(a){
document.getElementById("userInput").value = a
document.getElementById("userInput").focus();
}
</script>
When you say "stored locally", do you mean stored in the visitors browser, i.e. with only themselves being able to see it and retrieve it? Or do you want other users to be able to see the data, and/or the commenter to be able to see it if they log in later from another location?
If it's the latter then you need to store it on the server side, and you're going to need a database for that. If all you need is to store journal entries then mongoDB is easy to set up with javascript, but if you have a lot of relations (journal entries being associated with users, comments on entries being associated with users and entries, ect) then perhaps an SQL database would suit you better.
How do i save entered/ inputted text using JavaScript/ html.
What do I want:
Name or code etc to be entered in a box (prompt box eksample) and then I want it to be displayed/ printed on the page and I want it to remain there so other people that visit can see it.
What I have:
I have code that shows a prompt box where you can enter text then displays it in green. However what i want is for the entered text to remain on the website for others to see...
function mobCode() {
mobCode = prompt("Insert Code", "Code here");
document.getElementById("mC").innerHTML = mobCode;
document.getElementById("mC").style.color="green";
}
<p id="mC"> Mob Code </p>
<button type="button" onclick="mobCode()"> Click to Add </button>
What you will probably have to do is write a script that will send the entered input to a database you build which can store that information,and then have your js access the database to display it in a certain area of your page.
Check out this Q & A one of the answers is a nice article to help explain the idea behind it: Send data from javascript to a mysql database
If you want to deal easier with persistence of the data, instead of setting up database and using server side script you can look at Facebook's Parse. The free plan is quite usefull for small projects. There is a JavaScript SDK that can be used directly from your javascript code.
Also you can view statistics from the Parse dashboard.
Here is some saple code for example:
// Create a new Parse object
var Post = new ParseObject("Post");
var post = new Post();
// Save it to Parse
post.save({"title": "Hello World"}).then(function(object) {
alert("Yay! It worked!");
});
I'm using a textarea to get input from the user and display it on the screen. How can I make sure that if they put in something like
<h1>YAY, I hacked in</h1>
I only display it as it is, and it doesn't display as an <h1>. There must be a function for this. Help? :D
As I commented, if you're about to send that data to a server, you should use one of the various XML Parsers available and strip + validate the input.
If you however, need to purely validate on the client, I suggest you use document.implementation.createHTMLDocument, which creates an fully fledged DOM Object on the stack. You can then operate in there and return your validated data.
Example:
function validate( input ) {
var doc = document.implementation.createHTMLDocument( "validate" );
doc.body.innerHTML = input;
return [].map.call( doc.body.querySelectorAll( '*' ), function( node ) {
return node.textContent;
}).join('') || doc.body.textContent;
}
call it like
validate( "<script>EVIL!</script>" );
You need to address this on the server side. If you filter with JavaScript at form submission time, the user can subvert your filter by creating their own page, using telnet, by disabling JavaScript, using the Chrome/FF/IE console, etc. And if you filter at display time, you haven't mitigated anything, you've only moved the breakin-point around on the page.
In PHP, for instance, if you wish to just dump the raw characters out with none of the user's formatting, you can use:
print htmlentities($user_submitted_data, ENT_NOQUOTES, 'utf-8');
In .NET:
someControl.innerHTML = Server.HtmlEncode(userSubmittedData);
If you're trying to sanitize the content client-side for immediate/preview display, this should be sufficient:
out.innerHTML = user_data.replace(/</g, "<").replace(/>/g, ">");
I have an html site with a form in it and I want the user to be able to create a text/xml file depending on the input. But I wan't to avoid setting up a webserver only for this task.
Is there a good way, to do that, e.g. with Javascript? I think you can't create files with Javascript, but maybe create a data url and pass the text, so the user can save it to file?
Or is there another way to achieve this simple task without a webserver?
Solved it, somehow. I create a data url data:text/xml;charset=utf-8, followed by the XML.
function createXML() {
var XML = 'data:text/xml;charset=utf-8,<MainNode>';
var elements = document.getElementsByTagName('input'),i;
for (i in elements) {
if (elements[i].checked == true) {
XML += elements[i].value;
}
}
XML += '</MainNode>';
window.open(XML);
}
So the url looks like data:text/xml;charset=utf-8,<MainNode><SubNode>...</SubNode>...</MainNode>
Unfortunately this doesn't work for me on Chromium(Chrome) and on Firefox. It just displays the XML instead of showing a save dialog. But I think that's because of my settings and at least you can save it as a XML-file manually.
I haven't tried this but it should work.
After getting form data, system will call page A.
page A will have javascript that gets query strings and builds the page accordingly.
After finishing page build, user can save current page with following statement in javascript
document.execCommand('SaveAs',true,'file.html');