diff --git a/src/MessengerCustomerChat.js b/src/MessengerCustomerChat.js index e7d5737..0a8a776 100644 --- a/src/MessengerCustomerChat.js +++ b/src/MessengerCustomerChat.js @@ -10,6 +10,69 @@ const removeElementByIds = ids => { }); }; +/** + * Use MutationObserver or DOMNodeInserted event to check if the fb_dialog DOM is loaded. + * If it is loaded, call parameter function `callback`. + * @param {function} callback + */ +const addDOMNodeListenerOfFacebookPlugin = callback => { + // check compatibility of MutationObserver + const MutationObserver = + window.MutationObserver || + window.WebKitMutationObserver || + window.MozMutationObserver; + if (MutationObserver) { + // create an observer instance + const observer = new MutationObserver((mutations, observerSelf) => { + mutations.forEach(mutation => { + if ( + mutation.target.id === 'fb-root' && + mutation.addedNodes.length > 0 + ) { + const { addedNodes } = mutation; + addedNodes.forEach(element => { + if ( + element && + element.className && + typeof element.className === 'string' && + element.className.includes('fb_dialog') + ) { + callback(); + observerSelf.disconnect(); + } + }); + } + }); + }); + // select the target node + const target = document.querySelector('body'); + // configuration of the observer: + const config = { childList: true, subtree: true }; + + // pass in the target node, as well as the observer options + observer.observe(target, config); + } else if (document.body.addEventListener) { + document.addEventListener( + 'DOMNodeInserted', + event => { + const element = event.target; + if ( + element.className && + typeof element.className === 'string' && + element.className.includes('fb_dialog') + ) { + callback(); + } + }, + false + ); + } else { + console.warn( + 'MutationObserver and addEventListener are not supported! Callback function of addDOMNodeListenerOfFacebookPlugin would not work.' + ); + } +}; + export default class MessengerCustomerChat extends Component { static propTypes = { pageId: PropTypes.string.isRequired, @@ -204,20 +267,9 @@ export default class MessengerCustomerChat extends Component { const { fbLoaded, shouldShowDialog } = this.state; if (fbLoaded && shouldShowDialog !== this.props.shouldShowDialog) { - document.addEventListener( - 'DOMNodeInserted', - event => { - const element = event.target; - if ( - element.className && - typeof element.className === 'string' && - element.className.includes('fb_dialog') - ) { - this.controlPlugin(); - } - }, - false - ); + addDOMNodeListenerOfFacebookPlugin(() => { + this.controlPlugin(); + }); this.subscribeEvents(); } // Add a random key to rerender. Reference: