Vue - Directive to insert and execute html containing script tags

inset html containing script tags. And execute the scripts.

by Ben Clayton

HTML

<script src="https://unpkg.com/vue"></script>

<div id="app"></div>

<hr>


<script id="tmpl-app" type="text/x-template">
  <div>
    <h4>{{ global.title }}</h4>
    <hr>
    <div v-html="widgetcode"></div>
    <hr>
    <div v-dynamic="widgetcode"></div>
	</div>
</script>

CSS

body {
	    font-size: 20px;
}

.text {
	font-size: 24px;
}
.box {
  border: 1px solid red;
}

JavaScript

//---------------------------------------------------------
Vue.directive('dynamic', {
  bind: function(el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML = binding.value;

    function insertAndExecute(domelement) {
      var scripts = [];
			debugger;
      var ret = domelement.childNodes;
      for (var i = 0; ret[i]; i++) {
        if (scripts && nodeName(ret[i], "script") && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript")) {
          scripts.push(ret[i].parentNode ? ret[i].parentNode.removeChild(ret[i]) : ret[i]);
        }
        if (ret[i]){
        	insertAndExecute(ret[i]);
        }
        
      }

      for (script in scripts) {
        evalScript(scripts[script]);
      }
    }

    function nodeName(elem, name) {
      return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
    }

    function evalScript(elem) {
      data = (elem.text || elem.textContent || elem.innerHTML || "");
      var head = document.getElementsByTagName("head")[0] || document.documentElement,
        script = document.createElement("script");
      script.type = "text/javascript";
      script.appendChild(document.createTextNode(data));
      head.insertBefore(script, head.firstChild);
      head.removeChild(script);

      if (elem.parentNode) {
        elem.parentNode.removeChild(elem);
      }
    }
    insertAndExecute(el);
  }
})


var vm = new Vue({ // create a root Vue instance
  el: '#app', // this div gets replaced when View is rendered
  template: '#tmpl-app',
  data: function() {
    return {
      global: {
        title: "Test Injected html with script tag execution"
      }
    }
  },

  created: function() {
    // this.$data.global.name = 'BERTTY';

  },
  computed: {
    widgetcode: function() {
      return "hello from widget" + "<scr" + "ipt>alert('Hi 1')</scr" + "ipt><div><scr" + "ipt>alert('Hi 2')</scr" + "ipt></div>";
    }

  }
});