{"version":3,"file":"pollyhelper.min.js","sources":["../src/pollyhelper.js"],"sourcesContent":["/* jshint ignore:start */\ndefine(['jquery', 'core/log'], function ($, log) {\n\n    \"use strict\"; // jshint ;_;\n\n    log.debug('Polly Helper: initialising');\n\n    return {\n        sentenceURLs: [],\n        sentencetexts: [],\n        wordstarts: [],\n        wordcounts: [],\n        textblock: false,\n        textstring: false,\n        wordselector: '',\n        sentenceselector: '',\n        passagecssclass: 'filterpoodll_pollytextblock_cont',\n        cloudpoodlltoken: '',\n        cloudpoodllurl: '',\n        region: '',\n        voice: '',\n        highlightmode: '',\n        theplayer: false,\n        pendingurls: 0,\n\n        //for making multiple instances\n        clone: function () {\n            return $.extend(true, {}, this);\n        },\n\n        reset: function(){\n            this.unspanify_text_passage();\n            this.textblock = false;\n            this.textstring = false;\n            this.sentenceURLs= [];\n            this.sentencetexts= [];\n            this.wordstarts= [];\n            this.wordcounts= [];\n        },\n\n        set_textblock: function(textblock){\n            var that = this;\n\n            //if we are already set to this textblock, then do nothing\n            if(textblock===this.textblock){\n                log.debug('it was the same textblock');\n                return;\n            }\n            //remove the previous spans if we had them\n            if(this.textblock!==false) {\n                    this.reset();\n            }\n            //set our new textblock\n            this.textblock= textblock;\n            var usetext = textblock.text();\n\n            // Break text into sentences, and fetch data + TTS URL for each sentence.\n            this.spanify_text_passage();\n            this.sentencetexts = this.get_sentences_from_spanified_text();\n            this.pendingurls=this.sentencetexts.length;\n            var previousend = 0;\n\n            for (var currentsentence = 0; currentsentence < this.sentencetexts.length; currentsentence++){\n                this.wordstarts[currentsentence]= previousend;\n                this.wordcounts[currentsentence]= this.split_into_words(this.sentencetexts[currentsentence]).length;\n                previousend = previousend + this.wordcounts[currentsentence];\n\n                var speaktext = this.sentencetexts[currentsentence];\n                this.fetch_polly_url(speaktext,\n                    function(sentenceindex) {\n                        return function(pollyurl) {\n                            that.sentenceURLs[sentenceindex] = pollyurl;\n                            log.debug(sentenceindex + ' ' + pollyurl);\n                            that.pendingurls--;\n                        }\n                    }(currentsentence)\n                );\n            }\n        },\n\n        set_text: function(textstring){\n            var that = this;\n            //if we already have this one, return\n            if(textstring===this.textstring) {\n                log.debug('it was the same textstring');\n                return;\n            }\n            //remove the previous spans if we had them\n            if(this.textblock!==false) {\n                this.reset();\n            }\n\n            //remember this for next time\n            this.textstring= textstring;\n            this.sentencetexts[0]=textstring;\n            this.pendingurls=1;\n            this.fetch_polly_url(textstring,\n                function(pollyurl){\n                    that.sentenceURLs[0] = pollyurl;\n                    log.debug('0' + ' ' + pollyurl);\n                    that.pendingurls--;\n                }\n            );\n\n        },\n\n        init: function (theplayer,itemid,\n                        textblock, voice,sentenceselector,wordselector,\n                        passagecssclass,highlightmode, cloudpoodlltoken,\n                        region, cloudpoodllurl ) {\n            var that = this;\n            this.sentenceselector= sentenceselector;\n            this.wordselector= wordselector;\n            this.passagecssclass= passagecssclass;\n            this.cloudpoodlltoken = cloudpoodlltoken;\n            this.highlightmode=highlightmode;\n            this.voice = voice;\n            this.theplayer = theplayer;\n            this.region = region;\n            //The url will be html encoded so we decode it\n            this.cloudpoodllurl = new DOMParser().parseFromString(cloudpoodllurl, \"text/html\").body.textContent;\n            log.debug('Polly Helper: cloudpoodllurl=' + this.cloudpoodllurl);\n\n            this.set_textblock(textblock);\n\n        },\n\n        // FUNCTION: Split a text passage into sentences.\n        split_into_sentences: function(thetext){\n            thetext = thetext.replace(/\\s+/g,' ').trim();\n            if(thetext ===''){return[];}\n            return thetext.match(/([^\\.!\\?]+[\\.!\\?\"']+)|([^\\.!\\?\"']+$)/g);\n        },\n\n        // FUNCTION: Split a text passage into words.\n        split_into_words: function(thetext){\n            thetext = thetext.replace(/\\s+/g,' ').trim();\n            if(thetext===''){return[];}\n            return thetext.split(' ');\n        },\n\n        // FUNCTION: Fetch polly url.\n        fetch_polly_url: function (speaktext, callback) {\n\n            // The REST API we are calling.\n            var functionname = 'local_cpapi_fetch_polly_url';\n\n            // Fetch the Posturl. We need this.\n            // Set up our ajax request\n            var xhr = new XMLHttpRequest();\n            var that = this;\n\n            // Set up our handler for the response.\n            xhr.onreadystatechange = function (e) {\n                if (this.readyState === 4) {\n                    if (xhr.status === 200) {\n\n                        // Get a yes or forgetit or tryagain.\n                        var payload = xhr.responseText;\n                        var payloadobject = JSON.parse(payload);\n                        if (payloadobject) {\n                            // ReturnCode > 0  indicates an error.\n                            if (payloadobject.returnCode > 0) {\n                                console.log(payloadobject.returnMessage);\n                                return false;\n                                // If all good, then lets do the embed.\n                            } else if (payloadobject.returnCode === 0){\n                                var pollyurl = payloadobject.returnMessage;\n                                callback(pollyurl);\n                            } else {\n                                console.log('Polly Signed URL Request failed:');\n                                console.log(payloadobject);\n                            }\n                        } else {\n                            console.log('Polly Signed URL Request something bad happened');\n                        }\n                    } else {\n                        console.log('Polly Signed URL Request Not 200 response:' + xhr.status);\n                    }\n                }\n            };\n\n            // Make our request.\n            var xhrparams = \"wstoken=\" + this.cloudpoodlltoken\n                    + \"&wsfunction=\" + functionname\n                    + \"&moodlewsrestformat=\" + 'json'\n                    + \"&text=\" + encodeURIComponent(speaktext)\n                    + '&texttype=text'\n                    + '&voice=' + this.voice\n                    + '&appid=' + 'filter_poodll'\n                    + '&owner=poodll'\n                    + '&region=' + this.region;\n\n            var serverurl = this.cloudpoodllurl + \"/webservice/rest/server.php\";\n            xhr.open(\"POST\", serverurl, true);\n            xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            xhr.send(xhrparams);\n        },\n\n        // Is not used.\n        // FUNCTION: Determine if the string is text or HTML.\n        isHTML: function (testString) {\n            var htmlRegex = new RegExp(\"<([A-Za-z][A-Za-z0-9]*)\\\\b[^>]*>(.*?)</\\\\1>\");\n            return htmlRegex.test(testString);\n        },\n\n        unspanify_text_passage: function(){\n\n            //remove select to read class to container\n            this.textblock.removeClass(this.passagecssclass);\n\n           // remove previously set up spans\n            if(this.highlightmode==='word'){\n                this.textblock.find('.tbr_word').contents().unwrap();\n            } else {\n            // For sentences.\n                this.textblock.find('.tbr_sentence').contents().unwrap();\n            }// End of for loop.\n        },\n\n        // FUNCTION: Break a text passage into words/sentences, and surround the words with marker tags.\n        spanify_text_passage: function(){\n            var that = this;\n\n            // The itemcount er.\n            var itemcount = -1;\n\n            //add select to read class to container\n            this.textblock.addClass(this.passagecssclass);\n\n            // Get all the text nodes in the textblock.\n            var textnodes = this.textblock.find('*').contents().filter(function(){ return this.nodeType === 3; });\n            // Wrap sentence or words in text block with spans.\n            textnodes.each(function(){\n                var retpieces = '';\n                if(that.highlightmode==='word'){\n                    //for words\n                    var thewords = that.split_into_words($(this).text());\n                    for (var theword = 0; theword < thewords.length; theword++){\n                        itemcount++;\n                        retpieces =  retpieces + '<span class=\"tbr_word\" data-wordindex=\"'+ itemcount +'\">' + thewords[theword] + '</span> ';\n                    }// End of for loop.\n                } else {\n                    // For sentences.\n                    var thesentences = that.split_into_sentences($(this).text());\n                    for (var thesentence=0; thesentence < thesentences.length; thesentence++){\n                        itemcount++;\n                        retpieces =  retpieces + '<span class=\"tbr_sentence\" data-sentenceindex=\"'+ itemcount +'\">' + thesentences[thesentence] + '</span>&nbsp;';\n                    }// End of for loop.\n                }\n                $(this).replaceWith(retpieces);\n            });// End of textnodes each\n        },\n\n        get_sentences_from_spanified_text: function(){\n            var sentences = [];\n            var spans = this.textblock.find('span.tbr_sentence');\n            spans.each(function(){\n                sentences.push($(this).text());\n            });\n            return sentences\n        },\n\n        // FUNCTION: Unhighlight a sentence as active.\n        dehighlight_all: function(){\n            switch(this.highlightmode){\n                case 'word':\n                    $(this.wordselector,this.textblock).removeClass('activesentence');\n                    break;\n                case 'sentence':\n                    $(this.sentenceselector).removeClass('activesentence');\n                    break;\n                case 'none':\n                default:\n                // Do nothing.\n            }\n        },\n\n        // FUNCTION: Highlight a sentence as active.\n        highlight_sentence: function(thesentence_index){\n            switch(this.highlightmode){\n                case 'word':\n                    $(this.wordselector,this.textblock).removeClass('activesentence');\n                    $(this.wordselector,this.textblock).slice(this.wordstarts[thesentence_index],\n                            this.wordstarts[thesentence_index] +\n                            this.wordcounts[thesentence_index]).addClass('activesentence');\n                    break;\n                case 'sentence':\n                    $(this.sentenceselector).removeClass('activesentence');\n                    $(this.sentenceselector + '[data-sentenceindex=' + thesentence_index + ']').addClass('activesentence');\n                    break;\n                case 'none':\n                default:\n                // Do nothing.\n            }\n        },\n\n        // FUNCTION: Play a single sentence and mark it active for display purposes.\n        doplayaudio: function(thesentence) {\n            var that=this;\n            if(this.pendingurls>0){\n                setTimeout(function(){that.doplayaudio(thesentence);},100);\n                return;\n            }\n            if (typeof thesentence === 'number') {\n                // If thesentence is a number.\n                this.dehighlight_all();\n                this.highlight_sentence(thesentence);\n                this.theplayer.attr('src', this.sentenceURLs[thesentence]);\n            //    log.debug('sentenceurl:' + this.sentenceURLs[thesentence]);\n            //    log.debug('sentencenumber:' + thesentence);\n            //    log.debug('sentencetext:' + this.sentencetexts[thesentence]);\n            } else {\n                if(this.sentenceURLs.length > 0) {\n                    this.theplayer.attr('src', this.sentenceURLs[0]);\n                }\n            }\n            this.theplayer[0].load();\n            this.theplayer[0].play();\n        }\n    }\n});"],"names":["define","$","log","debug","sentenceURLs","sentencetexts","wordstarts","wordcounts","textblock","textstring","wordselector","sentenceselector","passagecssclass","cloudpoodlltoken","cloudpoodllurl","region","voice","highlightmode","theplayer","pendingurls","clone","extend","this","reset","unspanify_text_passage","set_textblock","that","text","spanify_text_passage","get_sentences_from_spanified_text","length","previousend","currentsentence","split_into_words","speaktext","fetch_polly_url","sentenceindex","pollyurl","set_text","init","itemid","DOMParser","parseFromString","body","textContent","split_into_sentences","thetext","replace","trim","match","split","callback","xhr","XMLHttpRequest","onreadystatechange","e","readyState","status","payload","responseText","payloadobject","JSON","parse","returnCode","console","returnMessage","xhrparams","encodeURIComponent","serverurl","open","setRequestHeader","send","isHTML","testString","RegExp","test","removeClass","find","contents","unwrap","itemcount","addClass","filter","nodeType","each","retpieces","thewords","theword","thesentences","thesentence","replaceWith","sentences","push","dehighlight_all","highlight_sentence","thesentence_index","slice","doplayaudio","setTimeout","attr","load","play"],"mappings":"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"}