marko/runtime/renderable.js
Michael Rawlings 769c572e35 merge + fixes
2016-12-02 14:13:25 -08:00

107 lines
3.5 KiB
JavaScript

var marko = require('./index');
var extend = require('raptor-util/extend');
module.exports = function(target, renderer) {
var renderFunc = renderer && (renderer.renderer || renderer.render || renderer);
var createOut = target.createOut || renderer.createOut || marko.createOut;
return extend(target, {
createOut: createOut,
renderToString: function(data, callback) {
var localData = data || {};
var render = renderFunc || this._;
var out = createOut(localData.$global);
if (callback) {
out.on('finish', function() {
callback(null, out.toString(), out);
})
.once('error', callback);
render(localData, out);
return out.end();
} else {
out.sync();
render(localData, out);
return out.toString();
}
},
renderSync: function(data) {
var localData = data || {};
var render = renderFunc || this._;
var out = createOut(localData.$global);
out.sync();
render(localData, out);
return out.getResult();
},
/**
* Renders a template to either a stream (if the last
* argument is a Stream instance) or
* provides the output to a callback function (if the last
* argument is a Function).
*
* Supported signatures:
*
* render(data)
* render(data, out)
* render(data, stream)
* render(data, callback)
*
* @param {Object} data The view model data for the template
* @param {AsyncStream/AsyncVDOMBuilder} out A Stream, an AsyncStream/AsyncVDOMBuilder instance, or a callback function
* @return {AsyncStream/AsyncVDOMBuilder} Returns the AsyncStream/AsyncVDOMBuilder instance that the template is rendered to
*/
render: function(data, out) {
var callback;
var finalOut;
var finalData;
var globalData;
var render = renderFunc || this._;
var shouldBuffer = this._shouldBuffer;
var shouldEnd = true;
if (data) {
finalData = data;
if ((globalData = data.$global)) {
finalData.$global = null;
}
} else {
finalData = {};
}
if (out && out.isAsyncOut){
finalOut = out;
shouldEnd = false;
extend(out.global, globalData);
} else if (typeof out === 'function') {
finalOut = createOut(globalData);
callback = out;
} else {
finalOut = createOut(
globalData, // global
out, // writer(AsyncStream) or parentNode(AsyncVDOMBuilder)
null, // state
shouldBuffer // ignored by AsyncVDOMBuilder
);
}
if (callback) {
finalOut
.on('finish', function() {
callback(null, finalOut.getResult());
})
.once('error', callback);
}
finalOut.global.template = finalOut.global.template || this;
render(finalData, finalOut);
return shouldEnd ? finalOut.end() : finalOut;
}
});
};