import customEvent from './customEvent';
/**
* The dynamicElement util allows elements to be dynamically added to a common container element,
* defined in themes\shaw-globalnews\footer.php as <div class="l-dynamicElement"></div>.
* When a dynamic element is added or removed from the container, an "added" or "removed" event
* is fired respectively, allowing certain actions to be carried out to the dynaically element
* through delegation of the 'added' / 'removed' event.
*
* Exapmle: In "SocialShare", there's a delegation of the 'added' event, which triggers the setup
* of the social share button click listeners for dynamically added social share markup.
*
* @module dynamicElement
*/
const dynamicElement = {
selector: '.l-dynamicElement',
$container: false,
/*
* Add an HTML element to the dynamic container, dispatch an 'added' event when element is added.
*
* @param {HTMLElement} $elem - element to be added
* @param {String} childSelector = optional selector for the element's child element
*
* @method add
*/
add( $elem, childSelector = '' ) {
this.$container = document.querySelector( this.selector );
if ( this.$container ) {
this.$container.appendChild( $elem );
// When a child selector is provided, watch for the addition
// of the element identified by childSelector
if ( childSelector ) {
const observer = new MutationObserver( ( mutationsList ) => {
[].forEach.call( mutationsList, ( mutation ) => {
if ( 'childList' === mutation.type && $elem.querySelector( `${childSelector}:not([data-added])` ) ) {
$elem.querySelector( `${childSelector}` ).dataset.added = true; // eslint-disable-line no-param-reassign
observer.disconnect();
customEvent.fire( this.$container, 'added' );
}
});
});
// Start observing the target node for configured mutations
observer.observe( $elem, {
attributes: false,
childList: true,
subtree: true,
});
} else {
customEvent.fire( this.$container, 'added' );
}
}
},
/*
* Remove an HTML element to the dynamic container,
* dispatch an 'removed' event when element is removed.
*
* @param {HTMLElement} $elem - element to be removed
*
* @method remove
*/
remove( $elem ) {
if ( this.$container ) {
$elem.parentNode.removeChild( $elem ); // IE11 doesn't support remove()
customEvent.fire( this.$container, 'removed' );
}
},
};
export default dynamicElement;