I created a new programming language in JavaScript and I want users to be able to include it in their web pages just like any other script using the script
tag:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>My Prog Lang</title>
<script src="scripts/myProgLang.js"></script>
<script type="text/my-prog-lang" src="scripts/index.mypl"></script>
</head>
</html>
The idea is that myProgLang.js
will get the contents of all the scripts and execute them:
window.addEventListener("DOMContentLoaded", function () {
var scripts = document.querySelector('script[type="text/my-prog-lang"]');
var length = scripts.length;
for (var i = 0; i < length; i++) {
var script = scripts[i];
var src = script.getAttribute("src");
var content = AJAX.getSync(src);
myProgLang.eval(content);
}
}, false);
The obvious problem with this approach (beside making a synchronous AJAX call) is that scripts on different domains violate the same origin policy.
The obvious solution is to make use of a script loader such as RequireJS to load the script as plain text using the text plugin.
However I didn't want to include the entire RequireJS framework just for this task. So I did some digging around and found this answer: https://stackoverflow.com/a/4927418/783743
According to the above answer:
The innerHTML property of the script element should give you the scripts content as a string provided the script element is:
- an inline script, or
- that the script has loaded (if using the src attribute)
Unfortunately this doesn't work (at least on Opera). The script loaded using the src
attribute cannot be accessed using the innerHTML
property.
What other options do I have to tackle this problem?
If you attempt to include your custom script directly via a tag then it will fail to parse, and you won't be able to get the 's innerHTML.
I would suggest using a JSONP-style approach. Start by defining a global handler function, e.g.
// myproglang.js
window.registerSource = function(source) {
myProgLang.eval(source);
}
And then in your source file, wrap your code in a call to that function:
// source.mypl
registerSource("\
Dim foo as Integer;\
")
It's a bit ugly as it requires the text file to escape newline characters in order to maintain the string literal, but other than using XHR, that's the only viable solution I can think of.
You could always write a compile step for this "language" that replaces "\n"
with "\\\n"
and wraps the source in a registerSource() call. As long as it's transparent it's a viable option.