Skip to content

Commit

Permalink
v2.3.0-beta.5
Browse files Browse the repository at this point in the history
Include commented source for riot.compiler
  • Loading branch information
aMarCruz committed Oct 28, 2015
1 parent 1be9f97 commit dae7653
Showing 1 changed file with 136 additions and 0 deletions.
136 changes: 136 additions & 0 deletions lib/riot_compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@

/*
Compilation for the browser
*/
riot.compile = (function () {

var
doc = window.document,
promise,
ready

// Gets a .tag file via asynchronous http. Once received, runs the callback on it.
function GET(url, fn, opts) {
var req = new XMLHttpRequest()

req.onreadystatechange = function() {
if (req.readyState === 4 &&
(req.status === 200 || !req.status && req.responseText.length))
fn(req.responseText, opts, url)
}
req.open('GET', url, true)
req.send('')
}

// Removes additional indentation of the source
function unindent(src, dbg) {
var indent = src.match(/^([ \t]*)</m) // only before first tag
if (indent && indent[1]) src = src.replace(new RegExp('^' + indent[1], 'gm'), '')
return src
}

// Runs the call to `riot.tag2` generated by the compiler
function globalEval(js, opts, comp) {
var
node = doc.createElement('script'),
root = doc.documentElement

node.text = js // writes the code into our new `script` element
root.appendChild(node) // injects it to page, execution is immediate
root.removeChild(node) // tmpl created, the script is no longer required
}

// Compile all tags defined with `<script type="riot/tag">`` to JavaScript.
// These can be inlined script definitions or external resources that load scripts
// defined with src attribute.
// After all scripts are compiled the given callback method is called.
function compileScripts(fn) {
var
scripts = doc.querySelectorAll('script[type="riot/tag"]'),
scriptsAmount = scripts.length

function done() {
promise.trigger('ready') // signal we are done
ready = true
if (fn) fn()
}

function compileTag(src, opts, url) {
globalEval(compile(src, opts, url))
if (!--scriptsAmount) done()
}

if (!scriptsAmount) done()
else {
for (var i = 0; i < scripts.length; ++i) { // Array.prototype.map is heavy
var
script = scripts[i],
opts = {template: script.getAttribute('template')},
url = script.getAttribute('src')

url ? GET(url, compileTag, opts) : compileTag(unindent(script.innerHTML), opts)
}
}
}

//// Entry point -----

return function (arg, fn) {

if (typeof arg === 'string') {
// fix in both, compile was called here and in globalEval

if (/^\s*</.test(arg)) { // this is a bit faster than trim()
// `riot.compile(tag [, true])`
// returns the tag as a string, if `true` is given, do not execute.
var js = compile(unindent(arg)) // fix: pass unindented src to compile, don't fake test
if (!fn) globalEval(js)
return js
}

// `riot.compile(url [, callback])`
// Loads the url and compiles all tags after which the callback is called.
GET(arg, function (str) {
var js = compile(str, {}, arg) // .tag do not need unindent
globalEval(js)
if (fn) fn(js, str)
})

}
else {

// `riot.compile([callback])`
// Compile all tags defined with `<script type="riot/tag">`` to JavaScript.

// must be a function
fn = typeof arg !== 'function' ? undefined : arg

// all compiled
if (ready)
return fn && fn()

// add to queue
if (promise) {
if (fn) promise.on('ready', fn)

// grab riot/tag elements + load & execute them
} else {
promise = riot.observable()
compileScripts(fn)
}
}
}

})()

// reassign mount methods
var mount = riot.mount

riot.mount = function(a, b, c) {
var ret
riot.compile(function() { ret = mount(a, b, c) })
return ret
}

// @deprecated
riot.mountTo = riot.mount

0 comments on commit dae7653

Please sign in to comment.