import { compile, render } from "./../_external/ejs/ejs.js";
import { Helper } from "../util/Helper.js";
/**
* View
* Provides management and rendering of ejs templates including DOM diffing.
*/
class View
{
/**
* Constructor
* @param {App} appInstance - App reference
*/
constructor( appInstance )
{
this.app = appInstance;
this.globalViewData = {};
}
/**
* Sets window title
* @param {string} title - Title to set
*/
setWindowTitle( title )
{
if ( window && window.document && window.document.title )
{
window.document.title = title;
}
}
/**
* Compiles template with given options
* @param {string} template - EJS based template
* @param {object} opts - EJS template options. @see {@link https://ejs.co/#docs}
* @returns {*} - Compiled template function
*/
compile( template, opts )
{
return compile( template, opts );
}
/**
* Generate HTML from given template string and data
* @param tmpl
* @param data
* @param tmplOptions
* @returns {string} - Generated HTML
*/
getHtml( tmpl, data = {}, tmplOptions = null )
{
return render( tmpl, this.createData( data ), tmplOptions );
}
/**
* Renders template with given data to html container.
*
* @param {HTMLElement|null} container - Container in which template should be rendered.
* @param {string} tmpl - EJS template string
* @param {object=} [data={}] - Template data.
* @param {boolean} [forceRepaint=false] - If false, DOM diffing is enabled.
* @param {object=} [tmplOptions=null] - EJS template options. @see {@link https://ejs.co/#docs}
*/
render( container, tmpl, data = {}, forceRepaint = false, tmplOptions = null )
{
const html = this.getHtml( tmpl, data, tmplOptions );
this.renderHtml( container, html );
}
/**
*
* @param {HTMLElement|null} container - Container in which template should be rendered.
* @param {string} html - HTML string to be rendered
*/
renderHtml( container, html )
{
if ( !container || false === ( container instanceof HTMLElement ) )
{
throw new Error( 'Invalid container. Given container must be an instance of an HTMLElement.' );
}
container.innerHTML = html;
}
createData( data = {} )
{
if ( data.hasOwnProperty( '_lcs' ) )
{
console.warn( '_lcs already exists in template data.' );
}
else
{
data[ '_lcs' ] = this.app.l18n.getLocale.bind( this.app.l18n );
}
if ( data.hasOwnProperty( '_lcn' ) )
{
console.warn( '_lcn already exists in template data.' );
}
else
{
data[ '_lcn' ] = this.app.l18n.getNumber.bind( this.app.l18n );;
}
if ( data.hasOwnProperty( '_lcd' ) )
{
console.warn( '_lcd already exists in template data.' );
}
else
{
data[ '_lcd' ] = this.app.l18n.getDateTime.bind( this.app.l18n );
}
const gvdKeys = Object.keys( this.globalViewData );
for ( let gi = 0; gi < gvdKeys.length; gi++ )
{
if ( data.hasOwnProperty( gvdKeys[ gi ] ) )
{
console.warn( `The globalViewData entry ${gvdKeys[ gi ]} already exists in template data.` );
}
else
{
data[ gvdKeys[ gi ] ] = this.globalViewData[ gvdKeys[ gi ] ];
}
}
return data;
}
}
export { View };