A small blog where Matthias posted thoughts on things happening around Khan Academy. (Archived) About Me
I’m just going to open this by saying this technique was discovered by Ethan, and while I researched and described how it works here, I don’t deserve credit for the clever idea.
Josh recently posed a question on UKADS, where he asked how to avoid the Error Buddy errors created by attempting to use Vue.js inside of Khan Academy’s webpage environment.
I had a couple of ideas, but none of them worked as well as the solution posted by Ethan. He linked to a comment he had made (on one of Luke’s programs), explaining the following trick.
Okay, just a little more before we get to the interesting part. I want to mention that the parser used by KA (live-editor source link) for webpage projects (as Josh identified), is Slowparse, by Mozilla. It’s meant as an HTML validator, and so it throw errors for the custom attributes that Vue requires but that are not allowed by the HTML standard. Unfortunately, there’s no official way to turn off its errors like there is with JSHint.
One interesting thing to note, is that no run time errors in the webpage environment are passed to Oh Noes. This is in contrast to the try...catch
step in the PJS error flow. Instead, webpages go through these steps:
In order to get Slowparse to not parse our HTML code, Ethan put it inside a script
tag with a type
attribute. Of course, the HTML doesn’t run here, but we can get it easily with Javascript and insert into the page. This is more or less equivalent to putting the HTML code inside a Javascript string or loading it from a different program, but this has the advantage that you can edit it in a more normal fashion. Slowparse is smart enough to not run Javascript parsing on it, because of the type="text/html"
tag. The MDN specifies that if type
is anything other an a Javascript type, it is ignored by the browser, and treated as a data block, and Slowparse complies with this.
Here’s a quick inline example, or you can checkout a demo KA program;
<html>
<body>
<script type="text/html" id="htmlDataBlock">
<div fake:attr="hello">Test</div>
</script>
<script>
el = document.getElementById("htmlDataBlock");
el.outerHTML = el.innerHTML; //Replaces the tag and nested HTML with the inner HTML.
</script>
</body>
</html>