PageSourceSearch

https://grassrootreporters.ng/wp-content/plugins/penci-text-to-speech/assets/js/text-to-speech.js?ver=1.4

js grassrootreporters.ng collected 2026-10-03 02:55:02 UTC 15,454 bytes, 365 lines download raw bytes

vendor: 3,983 bytes, lines 1-63
1/*!
2 * MediaElement.js
3 * http://www.mediaelementjs.com/
4 *
5 * Wrapper that mimics native HTML5 MediaElement (audio and video)
6 * using a variety of technologies (pure JavaScript, Flash, iframe)
7 *
8 * Copyright 2010-2017, John Dyer (http://j.hn/)
9 * License: MIT
10 *
11 */
12!function r(i, l, a) {
13    function d(t, e) {
14        if (!l[t]) {
15            if (!i[t]) {
16                var s = "function" == typeof require && require;
17                if (!e && s) return s(t, !0);
18                if (p) return p(t, !0);
19                var o = new Error("Cannot find module '" + t + "'");
20                throw o.code = "MODULE_NOT_FOUND", o
21            }
22            var n = l[t] = {exports: {}};
23            i[t][0].call(n.exports, function (e) {
24                return d(i[t][1][e] || e)
25            }, n, n.exports, r, i, l, a)
26        }
27        return l[t].exports
28    }
29
30    for (var p = "function" == typeof require && require, e = 0; e < a.length; e++) d(a[e]);
31    return d
32}({
33    1: [function (e, t, s) {
34        "use strict";
35        mejs.i18n.en["mejs.speed-rate"] = "Speed Rate", Object.assign(mejs.MepDefaults, {
36            speeds: ["2.00", "1.50", "1.25", "1.00", "0.75"],
37            defaultSpeed: "1.00",
38            speedChar: "x",
39            speedText: null
40        }), Object.assign(MediaElementPlayer.prototype, {
41            buildspeed: function (l, e, t, a) {
42                var d = this;
43                if (null !== d.media.rendererName && /(native|html5)/i.test(d.media.rendererName)) {
44                    for (var o = [], s = mejs.Utils.isString(d.options.speedText) ? d.options.speedText : mejs.i18n.t("mejs.speed-rate"), p = function (e) {
45                        for (var t = 0, s = o.length; t < s; t++) if (o[t].value === e) return o[t].name
46                    }, c = void 0, n = !1, r = 0, i = d.options.speeds.length; r < i; r++) {
47                        var u = d.options.speeds[r];
48                        "string" == typeof u ? (o.push({
49                            name: "" + u + d.options.speedChar,
50                            value: u
51                        }), u === d.options.defaultSpeed && (n = !0)) : (o.push(u), u.value === d.options.defaultSpeed && (n = !0))
52                    }
53                    n || o.push({
54                        name: d.options.defaultSpeed + d.options.speedChar,
55                        value: d.options.defaultSpeed
56                    }), o.sort(function (e, t) {
57                        return parseFloat(t.value) - parseFloat(e.value)
58                    }), d.cleanspeed(l), l.speedButton = document.createElement("div"), l.speedButton.className = d.options.classPrefix + "button " + d.options.classPrefix + "speed-button", l.speedButton.innerHTML = '<button type="button" aria-controls="' + d.id + '" title="' + s + '" aria-label="' + s + '" tabindex="0">' + p(d.options.defaultSpeed) + '</button><div class="' + d.options.classPrefix + "speed-selector " + d.options.classPrefix + 'offscreen"><ul class="' + d.options.classPrefix + 'speed-selector-list"></ul></div>', d.addControlElement(l.speedButton, "speed");
59                    for (var f = 0, v = o.length; f < v; f++) {
60                        var h = d.id + "-speed-" + o[f].value;
61                        l.speedButton.querySelector("ul").innerHTML += '<li class="' + d.options.classPrefix + 'speed-selector-list-item"><input class="' + d.options.classPrefix + 'speed-selector-input" type="radio" name="' + d.id + '_speed"disabled="disabled" value="' + o[f].value + '" id="' + h + '"  ' + (o[f].value === d.options.defaultSpeed ? ' checked="checked"' : "") + '/><label for="' + h + '" class="' + d.options.classPrefix + "speed-selector-label" + (o[f].value === d.options.defaultSpeed ? " " + d.options.classPrefix + "speed-selected" : "") + '">' + o[f].name + "</label></li>"
62                    }
63                    c = d.options.defaultSpeed, l.speedSelector = l.speedButton.querySelector("." + d.options.classPrefix + "speed-selector");
64                    for (var m = ["mouseenter", "focusin"], S = ["mouseleave", "focusout"], x = l.speedButton.querySelectorAll('input[type="radio"]'), b = l.speedButton.querySelectorAll("." + d.options.classPrefix + "speed-selector-label"), y = 0, g = m.length; y < g; y++) l.speedButton.addEventListener(m[y], function () {
65                        mejs.Utils.removeClass(l.speedSelector, d.options.classPrefix + "offscreen"), l.speedSelector.style.height = l.speedSelector.querySelector("ul").offsetHeight, l.speedSelector.style.top = -1 * parseFloat(l.speedSelector.offsetHeight) + "px"
66                    });
67                    for (var k = 0, P = S.length; k < P; k++) l.speedSelector.addEventListener(S[k], function () {
68                        mejs.Utils.addClass(this, d.options.classPrefix + "offscreen")
69                    });
70                    for (var j = 0, E = x.length; j < E; j++) {
71                        var B = x[j];
72                        B.disabled = !1, B.addEventListener("click", function () {
73                            var e = this.value;
74                            c = e, a.playbackRate = parseFloat(e), l.speedButton.querySelector("button").innerHTML = p(e);
75                            for (var t = l.speedButton.querySelectorAll("." + d.options.classPrefix + "speed-selected"), s = 0, o = t.length; s < o; s++) mejs.Utils.removeClass(t[s], d.options.classPrefix + "speed-selected");
76                            this.checked = !0;
77                            for (var n = mejs.Utils.siblings(this, function (e) {
78                                return mejs.Utils.hasClass(e, d.options.classPrefix + "speed-selector-label")
79                            }), r = 0, i = n.length; r < i; r++) mejs.Utils.addClass(n[r], d.options.classPrefix + "speed-selected")
80                        })
81                    }
82                    for (var U = 0, C = b.length; U < C; U++) b[U].addEventListener("click", function () {
83                        var e = mejs.Utils.siblings(this, function (e) {
84                            return "INPUT" === e.tagName
85                        })[0], t = mejs.Utils.createEvent("click", e);
86                        e.dispatchEvent(t)
87                    });
88                    d.options.keyActions.push({
89                        keys: [60, 188], action: function (e, t, s, o) {
90                            if ("<" == o.key) for (var n = 0; n < x.length - 1; n++) if (x[n].checked) {
91                                var r = x[n + 1];
92                                r.dispatchEvent(mejs.Utils.createEvent("click", r));
93                                break
94                            }
95                        }
96                    }, {
97                        keys: [62, 190], action: function (e, t, s, o) {
98                            if (">" == o.key) for (var n = 1; n < x.length; n++) if (x[n].checked) {
99                                var r = x[n - 1];
100                                r.dispatchEvent(mejs.Utils.createEvent("click", r));
101                                break
102                            }
103                        }
104                    }), l.speedSelector.addEventListener("keydown", function (e) {
105                        e.stopPropagation()
106                    }), a.addEventListener("loadedmetadata", function () {
107                        c && (a.playbackRate = parseFloat(c))
108                    })
109                }
110            }, cleanspeed: function (e) {
111                e && (e.speedButton && e.speedButton.parentNode.removeChild(e.speedButton), e.speedSelector && e.speedSelector.parentNode.removeChild(e.speedSelector))
112            }
113        })
114    }, {}]
115}, {}, [1]);
116// Remove download button for web-kit players
117window.addEventListener('DOMContentLoaded', (event) => {
118
119    for (let singleAudioTag of document.querySelectorAll('.penci-texttospeech-wrapper audio')) {
120
121        // Playback speed
122        const $speeds = singleAudioTag.parentElement.parentElement.parentElement.querySelector('.penci-texttospeech--speed');
123        if ($speeds !== null) {
124
125            /** Init saved speed */
126            const savedSpeed = getStorageSettings('speed');
127
128            /** Apply saved speed from the last visit */
129            if (savedSpeed) {
130
131                const $speedButtonSaved = document.querySelector(`button.penci-texttospeech--speed-button[data-speed='${savedSpeed}']`);
132
133                if ($speedButtonSaved) {
134
135                    speedClick({target: $speedButtonSaved});
136
137                }
138
139            }
140
141            /** Listen for clicks */
142            $speeds.addEventListener('click', speedClick);
143
144            /**
145             * Speed button click handler
146             * @param e
147             */
148            function speedClick(e) {
149
150                const $speedButton = e.target;
151
152                setSpeed($speedButton.getAttribute('data-speed'));
153                setSpeedButtonActive($speeds, $speedButton);
154
155            }
156
157            /**
158             * Set speed for Penci Text To Speech player
159             * @param speed
160             */
161            function setSpeed(speed) {
162
163                // WP Player
164                if (typeof window.MediaElementPlayer === 'function') {
165
166                    new MediaElementPlayer(singleAudioTag.id);
167
168                }
169
170                singleAudioTag.playbackRate = speed;
171
172                updateStorage('speed', speed);
173
174            }
175
176            /**
177             * Set active-speed class for active button
178             * @param $speeds
179             * @param $speedButton
180             */
181            function setSpeedButtonActive($speeds, $speedButton) {
182
183                $speeds.querySelectorAll('.active-speed').forEach(element => element.classList.remove('active-speed'));
184                $speedButton.classList.add('active-speed');
185
186            }
187
188        }
189
190        // Disallow downloading interface
191        if (singleAudioTag.parentElement.getAttribute('data-download') !== '1') {
192
193            singleAudioTag.controlsList = 'nodownload';
194
195        }
196
197        // Chrome style player
198        if (singleAudioTag.parentElement.parentElement.classList.contains('speaker-chrome')) {
199
200            const $playerWrapper = singleAudioTag.parentElement.parentElement;
201            let volumeShow = false;
202
203            /** Show volume slider */
204            $playerWrapper.addEventListener('mouseover', function (e) {
205
206                if (e.target.parentElement.classList.contains('mejs-volume-button') && !volumeShow) {
207
208                    $playerWrapper.classList.remove('mejs-volume-hide');
209                    $playerWrapper.classList.add('mejs-volume-show');
210                    volumeShow = true;
211
212                }
213
214            }, {passive: true});
215
216            /** Hide volume slider */
217            $playerWrapper.addEventListener('mouseout', function (e) {
218
219                if (e.target.className.length > 0 && !e.target.className.includes('mejs-horizontal-volume') && volumeShow) {
220
221                    $playerWrapper.classList.add('mejs-volume-hide');
222
223                    setTimeout(() => {
224
225                        $playerWrapper.classList.remove('mejs-volume-show');
226                        $playerWrapper.classList.remove('mejs-volume-hide');
227
228                    }, 100);
229
230                    volumeShow = false;
231
232                }
233
234            }, {passive: true});
235
236            /** Add the More menu button */
237            setTimeout(() => {
238
239                const $playerControls = $playerWrapper.querySelector('.mejs-controls');
240                const $downloadLink = $playerWrapper.parentElement.querySelector('.penci-texttospeech-download-box a');
241
242                // Dont add more menu if download link is not exist
243                if ($downloadLink === null) {
244                    return
245                }
246
247                // Add More menu button and menu
248                const $moreButton = document.createElement('div');
249                $moreButton.classList.add('mejs-button');
250                $moreButton.classList.add('mejs-more-button');
251                $moreButton.innerHTML = '<button type="button" title="More" aria-label="More" tabindex="0"></button>';
252                $moreButton.addEventListener('click', (e) => {
253
254                    // Remove old menu or create new menu
255                    if (document.querySelector('.mejs-more-menu') !== null) {
256
257                        document.querySelector('.mejs-more-menu').remove();
258
259                    } else {
260
261                        // Add more menu
262                        const $moreMenu = document.createElement('div');
263                        $moreMenu.classList.add('mejs-more-menu');
264                        $moreMenu.style.bottom = `${e.layerY}px`;
265                        $moreMenu.style.right = `${e.layerX}px`;
266                        $moreMenu.innerHTML = `<a href="${$downloadLink.href}" class="mejs-more-menu--download" target="_blank" rel="noopener">Download</a>`;
267
268                        $playerControls.appendChild($moreMenu);
269
270                    }
271
272                }, {passive: false})
273
274                // Remove More menu if click somewhere
275                document.addEventListener('click', (e) => {
276
277                    // Exit if no one menu founded on the page
278                    if (document.querySelector('.mejs-more-menu') === null) {
279                        return;
280                    }
281
282                    const elClassName = e.target.className;
283                    if (elClassName !== 'mejs-more-menu--download' && elClassName !== 'mejs-more-button' && elClassName !== '') {
284
285                        document.querySelector('.mejs-more-menu').remove();
286
287                    }
288
289                }, {passive: true});
290
291                $playerControls.appendChild($moreButton);
292
293            }, 1);
294
295        }
296
297        // Backend duration
298        const $dataHolder = singleAudioTag.closest('.penci-texttospeech-box > div');
299        if ($dataHolder.getAttribute('data-length-formatted')) {
300
301            const lengthFormatted = $dataHolder.getAttribute('data-length-formatted');
302
303            setTimeout(() => {
304
305                if ($dataHolder.querySelector('.mejs-duration')) {
306                    $dataHolder.querySelector('.mejs-duration').innerHTML = lengthFormatted;
307                }
308
309            }, 1);
310
311        }
312
313        /**
314         * Get settings from storage by key
315         * @param key
316         * @returns {boolean|*}
317         */
318        function getStorageSettings(key) {
319
320            let storedSettings = window.localStorage.getItem('PenciTextToSpeech');
321
322            if (storedSettings) {
323
324                let localStorage = JSON.parse(storedSettings);
325                return localStorage[key] ? localStorage[key] : false;
326
327            } else {
328
329                return false;
330
331            }
332
333        }
334
335        /**
336         * Update local storage
337         * @param key
338         * @param value
339         */
340        function updateStorage(key, value) {
341
342            const storage = window.localStorage.getItem('PenciTextToSpeech');
343
344            if (storage) {
345
346                let localStorage = JSON.parse(storage);
347                localStorage[key] = value;
348
349                window.localStorage.setItem('PenciTextToSpeech', JSON.stringify(localStorage));
350
351            } else {
352
353                let localStorage = {};
354                localStorage[key] = value;
355
356                window.localStorage.setItem('PenciTextToSpeech', JSON.stringify(localStorage));
357
358            }
359
360        }
361
362    }
363
364});
365

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.