js/base/component/rendered_dom.js
// NPM IMPORTS
import assert from 'assert'
import _ from 'lodash'
// COMMON IMPORTS
import T from 'devapt-core-common/dist/js/utils/types'
// BROWSER IMPORTS
import Dom from './dom'
const context = 'browser/base/component/rendered_dom'
/**
* @file UI rendered dom class.
*
* @author Luc BORIES
* @license Apache-2.0
*
* @example:
* API
* ->render():Promise - Render component DOM element.
* ->process_rendering_vnode(arg_rendering_result, arg_credentials):nothing - Process rendering VNode: create or update DOM element.
* ->save_rendering():nothing - Save rendering virtul node. Update component VNode with current component HTML.
*
* ->get_assets_promise():Promise - Get assets promises.
* ->get_assets_dependancies():array - Get assets dependancies.
* ->add_assets_dependancy(arg_asset_id):nothing - Add assets dependancy.
* ->init_assets():nothing - Init assets promises.
*/
export default class RenderedDDom extends Dom
{
/**
* Creates an instance of RenderedDom.
*
* @param {RuntimeBase} arg_runtime - client runtime.
* @param {Immutable.Map} arg_state - component initial state.
* @param {string} arg_log_context - context of traces of this instance (optional).
*
* @returns {nothing}
*/
constructor(arg_runtime, arg_state, arg_log_context)
{
const log_context = arg_log_context ? arg_log_context : context
super(arg_runtime, arg_state, log_context)
this.is_rendered_dom = true
this.is_menubar = false
this.is_breadcrumbs = false
this._ready_promise = Promise.resolve()
this._assets_dependancies = []
this._assets_promise = undefined
// DEBUG
// console.info(context + ':constructor:creating component ' + this.get_name())
// this.enable_trace()
}
/**
* Render component DOM element.
*
* @param {boolean} arg_force - should force creation of a new VNode if a previous rendering exists.
*
* @returns {Promise} - Promise of this to chain promises.
*/
render(arg_force)
{
this.enter_group('render')
this._ready_promise = this._ready_promise.then(
()=>{
const promise = this._render(arg_force)
return promise.then(
()=>{
this.update_size()
}
)
}
)
this.leave_group('render:async')
return this._ready_promise
}
_render(arg_force)
{
// const is_rendered = this.get_state_value('is_rendered', false)
// if (! arg_force && this._is_rendered)
// {
// this.leave_group('render:already rendered')
// return Promise.resolve()
// }
let promise = Promise.resolve()
if (arg_force)
{
this.debug('render:force rendering')
promise = this._rendering.render()
}
promise = promise.then(
()=>{
// SHOULD RENDER VNODE
if ( ! this.has_dom_vnode())
{
this.debug('render:should create vnode')
const p = this._rendering.render()
this.leave_group('render:vnode is created')
return p
}
// DISPLAY VNODE
if ( this.has_dom_vnode())
{
const vnode = this.get_dom_vnode()
const p = this.process_rendering_vnode(vnode)
this.leave_group('render:vnode is rendered')
return p
}
// RENDERING FAILED
this.error('render:render:no vnode to render')
this.leave_group('render:no vnode to render')
return Promise.reject(context + ':render:no dom vnode to render for ' + this.get_name())
}
)
return promise
}
/**
* PROCESS RENDERING VNODE: CREATE OR UPDATE DOM ELEMENT.
*/
process_rendering_vnode(arg_rendering_result, arg_credentials)
{
this._rendering.process_rendering_vnode(arg_rendering_result, arg_credentials)
this._is_visible = true
// PROCESS CHILDREN
// ...
}
/**
* Destroy component DOM element.
*
* @returns {Promise}
*/
destroy()
{
this.enter_group('destroy')
if (this._dom_element)
{
this._dom_element.parentNode.removeChild(this._dom_element)
}
this.leave_group('destroy')
}
/**
* Save rendering virtul node. Update component VNode with current component HTML.
*
* @returns {nothing}
*/
save_rendering()
{
this._rendering.save_rendering()
}
/**
* Update component size with its content.
*
* @returns {nothing}
*/
update_size()
{
// NOTHING TO DO
}
/**
* Get assets promises.
*
* @returns {Promise}
*/
get_assets_promise()
{
return this._assets_promise
}
/**
* Get assets dependancies.
*
* @returns {array}
*/
get_assets_dependancies()
{
return this._assets_dependancies
}
/**
* Add assets dependancy.
*
* @param {string} arg_asset_id - asset element id.
*
* @returns {nothing}
*/
add_assets_dependancy(arg_asset_id)
{
return this._assets_dependancies.push(arg_asset_id)
}
/**
* Init assets promises.
*
* @returns {nothing}
*/
init_assets()
{
this.enter_group('init_assets')
const assets_promises = []
this._assets_dependancies.forEach(
(asset_id)=>{
assets_promises.push( window.devapt().asset_promise(asset_id) )
}
)
// console.log(context + ':init:%s:assets:', this.get_name(), this._assets_dependancies)
this._assets_promise = Promise.all(assets_promises)
this.leave_group('init_assets')
}
}