Artifact
6064f0dbb1cf2b4693aa9c578348f0edebbc42b5f56790ea47cdf9918c0fb199:
// allow to require('riot')
const
path = require('path'),
fs = require('fs'),
hasRiotPath = !!process.env.RIOT,
riotPath = path.normalize(process.env.RIOT || path.join('..', '..', 'riot')),
riot = require(riotPath),
// simple-dom helper
sdom = require('./sdom'),
Module = require('module'),
compiler = require('riot-compiler')
// fix #2225
// rollup considers the riot.default key as default export value instead of what we export here
delete riot.default
// time riot should wait before throwing during an async rendering
riot.settings.asyncRenderTimeout = 1000
/**
* Function that will be used by riot.require and by require('some.tag')
* @param { String } filename - path to the file to load and compile
* @param { Object } opts - compiler options
* @param { Object } context - context where the tag will be mounted (Module)
*/
function loadAndCompile(filename, opts, context) {
const src = compiler.compile(fs.readFileSync(filename, 'utf8'), opts)
const preTag = src.substring(0, src.indexOf('riot.tag'))
const tagDefinition = src.substring(src.indexOf('riot.tag'))
// here we will use template strings in riot@3.0.0
context._compile(`
var riot = require('${ hasRiotPath ? riotPath : 'riot' }')
${ preTag }
module.exports = ${ tagDefinition }
`, filename)
}
/**
* Enable the loading of riot tags with options riot.require('some.tag', { template: 'pug' })
* @param { String } filename - path to the file to load and compile
* @param { Object } opts - compiler options
* @returns { String } tag name
*/
function riotRequire(filename, opts) {
var module = new Module()
module.id = module.filename = filename
loadAndCompile(filename, opts, module)
return module.exports
}
// allow to require('some.tag')
if (require.extensions) {
require.extensions['.tag'] = function(module, filename) {
loadAndCompile(filename, {}, module)
}
}
/**
* Get the html as string form any riot tag instance
* @param { Tag } tag - riot tag instance
* @returns { String } tag template
*/
function getTagHtml(tag) {
return sdom.serialize(tag.root)
}
/**
* Render riot tags returning a strings
* @param { String } tagName - tag identifier
* @param { Object } opts - options to pass to the tag
* @returns { String } tag resulting template
*/
function render(tagName, opts) {
var tag = render.tag(tagName, opts),
html = getTagHtml(tag)
// unmount the tag avoiding memory leaks
tag.unmount()
return html
}
/**
* Render riot tags asynchronously
* @param { String } tagName - tag identifier
* @param { Object } opts - options to pass to the tag
* @returns { Promise } a promise resolved with the tag template string
*/
function renderAsync(tagName, opts) {
return Promise.race([
new Promise((resolve, reject) => {
setTimeout(function() {
reject(new Error(`Timeout error:: the tag "${ tagName }" didn't trigger the "ready" event during the rendering process`))
}, riot.settings.asyncRenderTimeout)
}),
new Promise(resolve => {
var tag = render.tag(tagName, opts)
tag.on('ready', function() {
var html = getTagHtml(tag)
tag.unmount()
resolve(html)
})
})
])
}
// extend the render function with some static methods
render.dom = function(tagName, opts) {
return riot.render.tag(tagName, opts).root
}
render.tag = function(tagName, opts) {
var root = document.createElement(tagName),
tag = riot.mount(root, opts)[0]
return tag
}
// extend the riot api adding some useful serverside methods
module.exports = exports.default = Object.assign(riot, {
// allow to require('riot').compile
compile: compiler.compile,
parsers: compiler.parsers,
require: riotRequire,
render,
renderAsync
})