Spaces:
Building
Building
/** | |
* @fileoverview Tree manager. | |
*/ | |
/** | |
* Load the inner html of a node. | |
* @param {string} id_ HTML id of the node | |
*/ | |
async function load_content(id_) { | |
const root = document.getElementById(id_); | |
// Guard to only load the content once | |
if (!root.classList.contains('etils-loaded')) { | |
root.classList.add('etils-loaded'); | |
// Compute the HTML content in Python | |
const html_content = await call_python('get_html_content', [root.id]); | |
// Insert at the end, without destroying the one-line content | |
root.insertAdjacentHTML('beforeend', html_content); | |
// Register listeners for all newly added children | |
registerChildrenEvent(root); | |
} | |
} | |
/** | |
* Function which execute the callback. | |
* @typedef {function():void} EventCallback | |
*/ | |
/** | |
* Register listerner for all element matching the class name. | |
* | |
* @param {!HTMLElement} elem Root element to which add the listener | |
* @param {string} class_name Class for which add the listener | |
* @param {!EventCallback} callback Function to call. | |
*/ | |
function registerClickListenerOnAll(elem, class_name, callback) { | |
const children = elem.querySelectorAll(`.${class_name}`); | |
for (const child of children) { | |
child.classList.remove(class_name); | |
child.addEventListener('click', function(event) { | |
// Only one click processed if multiple (nested) listener | |
event.stopPropagation(); | |
// Do not process the click if text is selected | |
const selection = document.getSelection(); | |
if (selection.type === 'Range') { | |
return; | |
} | |
callback.bind(this)(); | |
}); | |
} | |
} | |
/** | |
* Register all listerners for all children. | |
* @param {!HTMLElement} elem Root element to which add the listener | |
*/ | |
function registerChildrenEvent(elem) { | |
registerClickListenerOnAll( | |
elem, 'etils-register-onclick-expand', async function() { | |
// TODO(epot): As optimization, it's not required to query the id | |
// each time, but instead use closure. | |
// TODO(epot): Is there a way to only call this once ? | |
await load_content(this.parentElement.id); | |
// Toogle the collapsible section | |
this.parentElement.querySelector('.etils-collapsible') | |
.classList.toggle('etils-collapsible-active'); | |
this.classList.toggle('etils-caret-down'); | |
}); | |
registerClickListenerOnAll(elem, 'etils-register-onclick-switch', function() { | |
this.closest('.etils-content-switch') | |
.classList.toggle('etils-switch-active'); | |
}); | |
} | |