Tuesday, April 2, 2013

Embedding Embedded Code in ICE

‹prev | My Chain | next›

Up today, I would like to explore embedding code in the embedded version of the ICE Code Editor. ICE is my fork of Mr.doob's code editor that is used throughout 3D Game Programming for Kids.

Currently, I can embed the editor, but the code that goes in there is the default project (there are a couple of sample projects ready-to-go in ICE).

My initial thought is to put the whole thing in a <script> tag with a type of text/template, although "template" is not quite right. Really, it is JavaScript that I don't want executed. I'll start with text/ice-code. There is probably something better, but...

I had been an empty element on which to hang embedded ICE code:
<div id="ice"></div>
Instead, I will:
<script type="text/ice-code"><![CDATA[
<body></body>
<script src="http://gamingJS.com/Three.js"></script>
<script src="http://gamingJS.com/Tween.js"></script>
<script src="http://gamingJS.com/ChromeFixes.js"></script>
<script>
  // This is where stuff in our game will happen:
  var scene = new THREE.Scene();

  // ...
  function animate() { /* ... */ }
  animate();
</script>
]]>
</script>
I try to extract and use with:
var scripts_nodelist = document.getElementsByTagName('script'),
    scripts = Array.prototype.slice.call(scripts_nodelist),
    ice_samples = scripts.filter(function(s) {
      return s.type == 'text/ice-code';
    });

var sourcecode;
if (ice_samples.length > 0) {
  var script = ice_samples[0];
  script.insertAdjacentHTML('beforebegin', '<div id=ice></div>
');
  sourcecode = script.innerText;
  embedded = true;
}
var ice_parent = document.getElementById('ice') || document.body,
    embedded = !!document.getElementById('ice');
But the problem is that, even inside CDATA, Chrome is seeing the first closing script tag as closing the template script tag. I believe that I no other choice but to invent a small templating language for this. The simplest thing that I can think of is to replace angle brackets with double square brackets:
<body></body>
[[script src="http://gamingJS.com/Three.js"]][[/script]]
[[script src="http://gamingJS.com/Tween.js"]][[/script]]
[[script src="http://gamingJS.com/ChromeFixes.js"]][[/script]]
[[script]]
  // Actual page code here
[[/script]]
I can then modify the source code on read with simple regular expressions:
// ...
  sourcecode = script.innerText.
    replace(/\[\[/g, '<').
    replace(/\]\]/g, '>');
  // ...
With that, I have code embedded from in-page content:



There is really no way to avoid the closing script tag issue, and this seems a fairly simple way to work around it. I will sleep on it to see if I can come up with something better.


Day #710

No comments:

Post a Comment