How to load XML in ACE? - javascript

UPDATE 1
Here is how I am currently loading text into my WT project.
wApp->require("ace.js");
//orignal XML, reads in incorrectly on one line
//std::string data = ReadFile("Q:\\settings.xml");
//XML after being formatted in notepad to look like xml, reads in correctly
//std::string data = ReadFile("Q:\\settings.txt");
//changed extension back to XML, edited in notepad++ to XML format, reads in correctly
std::string data = ReadFile("Q:\\settings_from_text.xml");
//test xml tag, reads in correctly
//std::string data = "<tag_1>some tag content</tag_1>";
//test xml tag with newline, reads in incorrectly on one line, doesnt read newline
//std::string data = "<tag_1>some tag content</tag_1>\n<tag_1>some tag content</tag_1>";
_ace_editor = new WText(data, Wt::PlainText);
//_ace_editor->setText(data);
_ace_editor->setInline(false);
// A WContainerWidget is rendered as a div
_ace_editor->resize(1000, 500);
std::string editor_ref = _ace_editor->jsRef(); // is a text string that will be the element when executed in JS
std::string command =
editor_ref + "._ace_editor = ace.edit(" + editor_ref + ");" +
editor_ref + "._ace_editor.setTheme(\"ace/theme/chrome\");" +
editor_ref + "._ace_editor.getSession().setMode(\"ace/mode/xml\");";// +
//editor_ref + "._ace_editor.setValue(\"" + data + "\");";
_ace_editor->doJavaScript(command);
Also, here is the ReadFile function
std::ifstream in(path, std::ios::in | std::ios::binary);
if(in)
{
std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
return(contents);
}
throw(errno);
ORIGINAL POST
I am trying to load some XML files into an Ace (http://ajaxorg.github.io/ace/#nav=about) editor that I embedded in a WT (http://www.webtoolkit.eu/wt?wtd=rqBfShGlNupXgK3M1sWOxUk1Loz3BsW0) page. The problem is that XML files for whatever reason have all their tags omitted from the load. Example: An XML file with the following content
<?xml version="1.0"?>
<settings>
<tag_1>some tag content</tag_1>
<tag_2/>
</settings>
will be loaded as
some tag content
I need the entire XML file as is, not just the contents of the tags.
After doing a bit of research, I have found quite a few other people on different forums asking the same thing but everything I have tried so far has not been working, which brings me here.
This includes setting the Ace mode to XML, trying to load the text in a different container before setting it to the ace window, changing the color schemes, and parsing a file in a different manner.
I am using visual studio 2010, and from debugging I can see that the file does get read in fully into a string with all the tags, but after it is set to the Ace window they are omitted.

Regardless of whether you are putting it on a WT page or not, bottom line this is a javascript question as that is what the ACE editor is, a javascript tool. Since you have not shown anything at all about how you are loading the xml content, I can only speculate that you must be writing the contents of the xml file into the pages output source?? I'll bet if you view-source do you see the tags? Well if so you are going about it wrong. The xml file needs to be loaded via javascript/ajax as I will demonstrate with a fully working example below (edit the 'url' in the $.ajax call to location of an xml file on your server), which shows tags and all contents of the xml file. Added the jQuery library just for simplicity of the ajax request code. Enjoy!
<!DOCTYPE html>
<html lang="en">
<head>
<title>ACE in Action</title>
<style type="text/css" media="screen">
#editor {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>
</head>
<body>
<div id="editor"></div>
<script src="http://rawgithub.com/ajaxorg/ace-builds/master/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
var callback = function (data, status, xhr) {
//data will be the xml returned from the server
if (status == 'success') {
var editor = ace.edit("editor");
//apparently, only modes supported are 'html', 'javascript' & 'text'
editor.getSession().setMode("ace/mode/html");
editor.setValue(data);
}
};
//using jQuery to fire off an ajax request to load the xml,
//using our callback as the success function
$.ajax(
{
url : '/testing/cd_catalog.xml',
dataType : 'text', //explicitly requesting the xml as text, rather than an xml document
success : callback
}
);
</script>
</body>
</html>
Actually, I take back some of what I said about the "must load via javascript/ajax", as I now realize you were just following ACE's example of putting the contents into the editor div beforehand. If you want to do that with html or xml content, the tags will be evaluated by the browser and not show up, unless you copy the editor div's innerHTML then instantiate the editor and then set it's value to the previously saved innerHTML. For example:
<div id="editor"><?xml version="1.0" encoding="ISO-8859-1">
<books>
<text>some text content</text>
<book/>
</books></div>
<script src="http://rawgithub.com/ajaxorg/ace-builds/master/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var txt = document.getElementById('editor').innerHTML;
var editor = ace.edit("editor");
//editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");
editor.setValue(txt);
</script>

XML fragments in XML... you can somehow expect that your browser will interpret them, unless properly escaped. Try this:
txt = new WText("<bla>something</bla>", Wt::PlainText);
which will escape all XML-ish characters in your text.
Wt's default (XHTMLText) will try to parse your input as XML, and if it succeeds filter possible XSS vectors from the XML before sending it as XML to the browser. If it can't parse the text as XML, it will escape XML-ish characters to avoid that a browser with a liberal parser would unintentionally execute attack vectors.
The third option (XHTMLUnsafeText) bypasses XSS filtering - dangerous, so only use it when you know that your text is safe and can not be influenced directly or indirectly by the user.

Related

Firebase could storage corrupts special characters in uploaded file

I have uploaded a js file to firebase cloud storage and made it public.
Also after uploading via google cloud console edited the metadata and set the content-language to unset , content-type to text/javascript and content-encoding to UTF-8. But still, the special characters such as äöå are shown corrupted
The usage of the JS file is like below ;
On a website, I have a script tag on <head/>
<head>
<script src="https://storage.googleapis.com/myapp.appspot.com/MyElement.js"
charset="UTF-8" or "iso-8859-1" <-- have tried both
type="text/javascript" />
</head>
...
<body>
...
<div id="locationForMyCustomEl"></div>
...
</body>
the content of the javascript file is something like
function setup(){
let element = document.querySelector("#locationForMyCustomEl");
element.innerHTML = "<h1> Köp för item </h1>"
/*
Have Also tried:
K\u00F6p f\u00F6r item
Köp för item
*/
}
setup();
But I always receive messed up characters like Köp för item in the resulting <h1/> tag.
If I open the javascript file in a browser (inserting the URL https://storage....lement.js)
the represented code also contains messed-up characters.
like
function setup(){
let element = document.querySelector("#locationForMyCustomEl");
element.innerHTML = "<h1> Köp för item </h1>"
}
It seems the uploaded file gets corrupted, and there is no way to restore it via charset.
How should I use special characters in an external javascript file?

Does end of script tag take priority than backtick?

I am developing page builder widget. I have to save entire html of edited page to local storage and database. PHP script will load saved html from database, and javascript would save it to local storage, and page builder widget script will parse html saved in local storage.
The problem is that when the html includes <script></script> tag, it won't load successfully. For example, the following script will show error, if html includes script tag.
<script>
<?php $html = $db->getPageHtml();?>
window.localStorage.setItem('pb_html', `<?php echo $html?>`);
</script>
For example, if $html is set as </script> the following script will show error:
<script>
window.localStorage.setItem('test', `</script>`);
</script>
The other html tags are successfully rendered. I think </script> take priority than ` (backtick) when javascript is parsed by browser.
PHP function htmlspecialchar won't solve this problem because it converts < and > to < and >. And page builder javascript don't understand it. Do you have any suggestion?
Browsers generally don't parse the script when looking for the </script> tag. First they extract everything between <script> and </script>, then this is parsed as JavaScript. It doesn't matter what type of quotes are used around the tag, since it isn't parsed at that point.
The usual way to avoid problems when you have a literal string containing </script> is to split it up.
window.localStorage.setItem('test', `</sc` + `ript>`);
See Why split the <script> tag when writing it with document.write()?

document.write - replace "</script>" tags with "<\/script>"

I've already tested this code manually adding the backslash to all the </script> tags, and
if all the tags become <\/script> the code works.
var iframe = document.createElement('iframe');
var html = '<html><head><script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"><\/script><script type="text/javascript">$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});<\/script></head><body><div class="eccolo"></div></body></html>';
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
iframe.contentWindow.document.close();
DEMO
But I need to dynamically auto-replace all the </script> tags with <\/script> using something like
XXX.replace(/<\/script>/ig, "<\\\/script>");
according to this post
but seems that this type of replace is actually not working...
var iframe = document.createElement('iframe');
var XXX = '<html><head><script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"><\/script><script type="text/javascript">$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});<\/script></head><body><div class="eccolo"></div></body></html>';
var YYY = XXX.replace(/<\/script>/ig, "<\\\/script>");
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(YYY);
iframe.contentWindow.document.close();
DEMO
Unfortunately I can't use .js files, so I hope that there is a way to properly do the tags replace
But what if I want to dynamically replace all the </script> tags with <\/script>...
In a comment below, you've said:
I'm getting the var XXX from an input that always changes.. I just added a defined value (var XXX='<html><head>...) in my question just for example
That's a very different thing than what's in your question. If you're saying that you'll receive input in the XXX string whose content (in memory, not a string literal) looks like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(window).load(function() {
function popo1() {
alert("ciaoooo!");
}
popo1();
$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");
});
</script>
</head>
<body>
<div class="eccolo"></div>
</body>
</html>
...then than input is perfectly fine and can be used as-is to set the content of the iframe. You don't have to do the replacement on it. The post you linked to doesn't relate to what you're doing.
But if you're saying you'll get input like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(window).load(function() {
var str = "The problem is here: </script>"; // <======
});
</script>
</head>
<body>
<div class="eccolo"></div>
</body>
</html>
...then you're in the same unfortunate position as the HTML parser: You don't know when the substring </script> actually ends a script element, or is text within a JavaScript string literal (or a comment). If you had a web page with that content, the HTML parser would conclude the script element ended immediately after The problem is here:. And indeed, if you output that content to an iframe via document.write, the parser will choke on it. The line:
var str = "The problem is here: </script>";
needs to be
var str = "The problem is here: <\/script>";
// or
var str = "The problem is here: </sc" + "ript>";
// or similar
...in order to avoid tripping up the HTML parser. (It would be fine in a .js file, but that's not your use case.)
Fundamentally, if you're receiving input with something like that in it, the person giving it to you is giving you invalid input. The substring </script> cannot appear in JavaScript code within <script>/</script> tags — not in a string literal, not in a comment, nowhere.
The answer defined by the spec is: Don't try to figure it out, require that it be correct. But if you know the scripts are JavaScript, and you really really want to allow invalid input and correct it, you'll need a JavaScript parser. That sounds outrageous, but Esprima is exactly that, there's jsparser in the Meteor stuff, and there may be others. You'd scan the string you're given to find <script>, then let the JavaScript parser take over and parse the code (you'll probably need to modify it so it knows to stop in </script> outside of a string literal / comment). Then take the text consumed by the parser, use your replace to convert any </script> in the code's text to <\/script>, and continue on.
It's non-trivial, which is why the spec doesn't require HTML parsers to do it.
But again, if the input is like your example in your question (without the backslashes you used to avoid this problem with your string literal), you don't have to do a replace at all. Just output it to the iframe, and it will work fine.
You can create script tag programatically and append in the head tag after page is loaded.
Following is the code and DEMO
var iframe = document.createElement('iframe');
var html = '<html><head></head><body><div class="eccolo"></div></body></html>';
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
var script1 = iframe.contentWindow.document.createElement('script');
var script2 = iframe.contentWindow.document.createElement('script');
script2.textContent = '$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});'
var head = iframe.contentWindow.document.querySelector('head');
head.appendChild(script1);
script1.onload = function() {
head.appendChild(script2);
}
script1.src = 'http://code.jquery.com/jquery-1.11.0.js';
iframe.contentWindow.document.close();
Hope it helps...

How to embed an XML file in HTML?

I am creating a simple web application for a comic using HTML and JavaScript. Because people that are not very technical should be able to add new comics, I thought about using an XML file as a configuration file.
I thought about using JSON and decided against it, mainly because the way comma's are used(no comma between two items breaks it, but a comma at the end of the list also breaks it.).
However, my question is now: How can I embed this XML file? Do I use the <link rel= /> tag, or something else like the <embed src= /> tag? And how can I then read information from the XML nodes in JavaScript?
I would recommend loading a JavaScript library that makes this easy. jQuery is one. If you include jQuery in your page then you use it to load the document and get access to the browser's XML parsing capabilities fairly easily.
http://api.jquery.com/jQuery.parseXML/ shows a simple example of finding values in an xml document once it's loaded.
This site http://think2loud.com/224-reading-xml-with-jquery/ gives a good example of how to load XML from a remote site. The basic idea is to use AJAX: here's a tiny snippet for posterity that will load foo.xml after the html document has loaded (relies on jQuery):
$( function() {
$.ajax({
type: "GET",
url: "foo.xml",
dataType: "xml",
success: myHandler(xml) {
}
});
});
Use xml tag. Example :
<html>
<xml Id = msg>
<message>
<to> Visitors </to>
<from> Author </from>
<Subject> XML Code Islands </Subject>
</message>
</xml>
</html>

Embedding XML in HTML

How would one go about embedding XML in a HTML page?
I was thinking using CDDATA would be the best approach but I get errors in the HTML document when the page loads.
<script><![CDATA[ ... ]]></script>
I'm needing to embed a XML document for fetching later with JavaScript. I need to do this since when the user opens it, they might not have internet access.
As long as the XML doesn't contain </script> anywhere, you can put it inside the script tags with a custom type attribute (and no CDATA section). Give the script tag an id attribute so you can fetch the content.
<script id="myxml" type="text/xmldata">
<x>
<y z="foo">
</y>
</x>
</script>​
...
<script> alert(document.getElementById('myxml').innerHTML);​ </script>
http://jsfiddle.net/hJuPs/
How about:
<script>
var xml = '<element> \
<childElement attr="value" /> \
</element>';
</script>
That would enable you to easily embed the XML for later retrieval in javascript.
According to the tutorial here, you can use the 'xml' tag to embed XML data within an HTML document. However, this implicitly displays the XML data in the browser.
http://www.expertrating.com/courseware/XMLCourse/XML-Embedding-HTML-8.asp

Categories

Resources