Javascript Event Oriented Programming example on SPSocialFeed

SPSocialFeed is the sharepoint microblog, where you can post your thoughts and reply on yourself and other.

We wanted to add some functionalities for every reply and post added, so i used the new "MutationObserver" and "CustomEvent" new API's in ES6 to create an event-full way to implement solution
// batman is the man in-charge catching the bad guys in the night.
// so now he catches the good events in the feed
let batman = (function(){
    let config = { childList : true };

    let batman = class batman{
        constructor(){
            this.v = "2.0.0";
            //register call to batCave fn. to _spBodyOnLoadFunctionNames, the SP onready
            _spBodyOnLoadFunctionNames.push('batman.batCave');
        }

        batCave(){
            let feed = document.getElementById('ms-feedthreadsdiv');
            //childNodes can be any type of nodes, like text node. children is only HTMLElements childNodes.
            let posts = feed.children;
            let evt = new CustomEvent('feedReady', { detail : { feed : feed, posts : posts } });
            console.log('batman fire feedReady event');
            window.dispatchEvent(evt);

            //create observer on the feed to catch added threads
            let fireThreadsChange= (ml => { //ml is MutationList
                //the changes fires much more times than just added posts, the logs here are just for tutorial, you should comment them
                console.log('fireThreadsChange'); 
                console.log(ml); 
                for (let i = 0; i < ml.length; i++) {
                    //the feed does it in 2 stages, and only in the 2nd there is only 1, and only added
                    let mr = ml[i]; //mr is MutationRecord
                    if (mr.addedNodes.length === 1 && mr.addedNodes[0].className === 'ms-microfeed-thread') {
                        //this is a new thread
                        let evt = new CustomEvent('postAdded', { detail : mr.addedNodes[0]});
                        window.dispatchEvent(evt);
                    }
                }
                //no implementation yet to "show more records/posts", TBD
            });

            let feed_observer = new MutationObserver(fireThreadsChange);
            feed_observer.observe(feed, config);

            //create observer on every post's replies
            let fireRepliesChange = (ml => {
                //the changes fires much more times than just added reply, the logs here are just for tutorial, you should comment them
                console.log('fireRepliesChange'); 
                console.log(ml); 

                let firePostGotRepliesAdded = false;

                for (let i = 0; i < ml.length; i++) {
                    const mr = ml[i];
                    if (mr.addedNodes.length === 1 && mr.addedNodes[0].id.startsWith('ms-post_')) {
                        //its a new reply, or user expanded "see all replies"
                        let evt = new CustomEvent('replyAdded', { detail : mr.addedNodes[0]});
                        window.dispatchEvent(evt); 
                        firePostGotRepliesAdded = true;
                    }
                }

                if (firePostGotRepliesAdded) {
                    let post = $(mr[0].target).closest('.ms-microfeed-thread');
                    //notify there was a change in the post
                    let evt = new CustomEvent('postGotRepliesAdded', { detail : post[0]});
                    window.dispatchEvent(evt); 
                }
            });

            //added threads after 1st init
            window.addEventListener('threadAdded', e => {
                let thread = e.detail;
                //a thread might be added with some replies like with "show more"
                let _relpies = thread.querySelectorAll('.ms-microfeed-replyArea.ms-microfeed-repliesDiv > div');
                if (_relpies.length > 0) {
                    _relpies.forEach(_reply => {
                        let evt = new CustomEvent('replyAdded', { detail : _reply});
                        window.dispatchEvent(evt); 
                    });
                }
            });

            let _repliesArea_observer = new MutationObserver(fireRepliesChange);
            
            let allRepliesArea = feed.querySelectorAll('.ms-microfeed-replyArea.ms-microfeed-repliesDiv'); //i got this one wrong, TBD check for the right class
            allRepliesArea.forEach( _repliesArea => {
                _repliesArea_observer.observe(_repliesArea, config);
            });
        }
    }
    return new batman();
})();

//listen to events
window.addEventListener('postAdded', e => {
    console.log('postAdded');
    console.log(e.detail); //the post
    //code...
})

Comments

Popular posts from this blog

c# Service Play Sound with NAudio example by Moshe

Asp.Net Ending Response options, Response.End() vs CompleteRequest()

JS/JQ simulate Enter event