Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

You'll need to make an Ajax request... if it's the same domain as the page, it will load fine, if the server sent caching headers, it should use the existing copy.

If it's on another domain, you'll need CORS headers (where supported) and/or a JSONP loader in place.

This question has already been asked here and here.

Basically the concensus is:

  • if the script is inline it can be accessed with script.innerHTML
  • if it's not inline, you can only access it if you make a another ajax request. (obviously you may encounter a cross-domain issue)

Notes

If your HTTP headers are configured correctly, you should be able fetch the script from the browser's cache, so it'd be fast.

The cross-domain issue can be fixed with a Access-Control-Allow-Origin: * header from the script's host.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top