PageSourceSearch

https://www.stereofox.com/js/player/init.js?v=1162?v=1162

js stereofox.com collected 2026-10-02 08:31:46 UTC 8,966 bytes, 336 lines download raw bytes

1
2var domain = window.location.origin;
3var sfPlayerRoot = sfPlayerRoot ? sfPlayerRoot : null;
4var spotifyClientId = 'dfcdf84f37514d2697a1446f820407fb';
5
6/**
7 * Prevent Double loading of actions and files.
8 */
9if (!sfPlayerRoot) {
10
11    console.log('Initializing player', ver);
12    var currentUser = null;
13    sfPlayerRoot = '/js/player/';
14
15    function getAssetURL(asset) {
16        const url = sfPlayerRoot + asset + '?ver=' + ver;
17        return url;
18    }
19
20    function loadScript(url, callback) {
21        var head = document.head;
22        var script = document.createElement('script');
23        script.type = 'text/javascript';
24        script.src = url;
25
26        script.onreadystatechange = callback;
27        script.onload = callback;
28
29        head.appendChild(script);
30    }
31
32    function loadStyle(url) {
33        var head = document.head;
34        var style = document.createElement('link');
35        style.rel = 'stylesheet';
36        style.href = url;
37
38        head.appendChild(style);
39    }
40
41    function funcExists(functionName) {
42        if (typeof window[functionName] === "function") {
43            return true;
44        }
45        return false;
46    }
47
48
49    /**
50     * After jquery is loaded we can load the rest of the scripts.
51     * 
52     * @returns {undefined}
53     */
54    function loadAfterJQuery() {
55        /**
56         * Load jQuery
57         */
58        jsf = jQuery;
59
60        loadScript(getAssetURL('api.js', function () {
61
62        }));
63
64        loadScript(getAssetURL('spotify.js'), function () {
65            //init should be done after the user is loaded.
66        });
67
68        loadScript(getAssetURL('apple.js'), function () {
69            /**
70             * The current-user request can finish before this file
71             * arrives. If the linked account is already in session,
72             * hand its token to the controller now.
73             */
74            if (typeof sessionController === 'undefined' || typeof sfApple === 'undefined') {
75                return;
76            }
77            var user = sessionController.getCurrentUser();
78            var account = user && user.hasAppleMusicAccount ? user.hasAppleMusicAccount() : null;
79            if (account) {
80                sfApple.init(account.getAccessToken(), account.getStorefront());
81            }
82        });
83
84        loadScript(getAssetURL('video.js'), function () {
85            //init should be done after the user is loaded.
86        });
87
88        const playerScriptName = playerHtml.replace(/\.html$/, '.js');
89        loadScript(getAssetURL(playerScriptName), function () {
90            sfPlayer.init(playerHtml);
91        });
92
93        loadScript(getAssetURL('account.js'), function () {
94            sfAccount.init();
95        });
96
97        /**
98         * Match the stylesheet to the requested player HTML so each
99         * skin (player.html / player-2026.html / ...) gets its own CSS.
100         */
101        var playerCss = playerHtml.replace(/\.html$/, '.css');
102        loadStyle(getAssetURL('styles/' + playerCss));
103
104    }
105
106    /**
107     * Load init scripts
108     */
109    loadScript('https://www.youtube.com/iframe_api');
110
111    /**
112     * If we do not have JQuery in the page then load it.
113     */
114    if (!('jQuery' in window)) {
115        loadScript(getAssetURL('scripts/jQuery.js'), loadAfterJQuery);
116    } else {
117        /**
118         * Else just load the dependencies
119         */
120        loadAfterJQuery();
121    }
122
123    /**
124     * Subscribe to the user change event of gatsby
125     */
126    if (funcExists('gatsbySubscribe')) {
127        window.gatsbySubscribe(window.gatsbyPubSub.M_USER_UPDATED, (args) => {
128            console.log(args);
129            currentUser = args;
130        });
131    }
132
133    /**
134     * Based on https://gist.github.com/benjamingr/0433b52559ad61f6746be786525e97e8
135     * 
136     * @param {type} ee
137     * @returns {unresolved}
138     */
139    function interceptNetworkRequests(ee) {
140        const open = XMLHttpRequest.prototype.open;
141        const send = XMLHttpRequest.prototype.send;
142
143        const isRegularXHR = open.toString().indexOf('native code') !== -1;
144
145        if (isRegularXHR) {
146            XMLHttpRequest.prototype.open = function () {
147                ee.onOpen && ee.onOpen(this, arguments);
148                if (ee.onLoad) {
149                    this.addEventListener('load', ee.onLoad.bind(ee));
150                }
151                if (ee.onError) {
152                    this.addEventListener('error', ee.onError.bind(ee));
153                }
154                return open.apply(this, arguments);
155            };
156            XMLHttpRequest.prototype.send = function () {
157                ee.onSend && ee.onSend(this, arguments);
158                return send.apply(this, arguments);
159            };
160        }
161
162        return ee;
163    }
164}
165
166/**
167 * 
168 * @param {type} key
169 * @returns {unresolved}
170 */
171function getURLParams(key, url) {
172
173    /**
174     * Make the URL param safe, meaning all
175     * params should be behind the & symbol.
176     * If this is not added, then the first param
177     * will not be read. 
178     */
179    var url = !url ? window.location.href : url;
180    url = url.replace('?', '?&');
181
182    /**
183     * Initialize the object and pass the url
184     * @type URLSearchParams
185     */
186    const sp = new URLSearchParams(url);
187    return sp.has(key) ? sp.get(key) : false;
188}
189
190/**
191 * Shows a message the frontend
192 * 
193 * @param {type} msg
194 * @returns {undefined}
195 */
196function showMessage(msg, isError = false) {
197    ajaxController.showMsg(msg, isError);
198}
199
200/**
201 * For debug, be able to clear our the modal sessions.
202 */
203function cleanUpModalClosing(){
204    sessionStorage.setItem('modalSkipAds', '');
205    sessionStorage.setItem('modalSkipPreview', '');
206    localStorage.setItem("currentPlayTime", 0);
207    alert('Modal sessions cleared');
208}
209
210var sfPlayerModalLoadingId = null;
211
212async function hidePlayerModal(which) {
213    if($('#player.player-2026').length <= 0){
214        /**
215         * Make sure we only show these modals on the new player.
216         */
217        return;
218    }
219
220    var id = '';
221    switch (which) {
222        case 'ads':
223            id = ('modalSkipAds');
224            break;
225        case 'preview':
226            id = ('modalSkipPreview');
227            break;
228        default:
229            id = which;
230            break;
231    }
232
233    $('#' + id).remove();
234}
235
236/**
237 * 
238 * @param {*} which 
239 * @param {*} force 
240 * @returns 
241 */
242async function showPlayerModal(which, force = false) {
243
244    if($('#player.player-2026').length <= 0){
245        /**
246         * Make sure we only show these modals on the new player.
247         */
248        return;
249    }
250
251    var id = '';
252    var daysBeforeReasking = 30;
253    switch (which) {
254        case 'ads':
255            id = ('modalSkipAds');
256            daysBeforeReasking = 14;
257            break;
258        case 'preview':
259            id = ('modalSkipPreview');
260            daysBeforeReasking = 7;
261            break;
262        default:
263            id = which;
264            break;
265    }
266
267    /**
268     * First check if it was dismissed before.
269     */
270    try {
271        const lastAsked = sessionStorage.getItem(id);
272        console.log('Last asked for ' + id + ': ' + lastAsked);
273        if (lastAsked && !isNaN(lastAsked) && !force) {
274            const lastAskedTime = new Date(parseInt(lastAsked));
275            const now = new Date();
276            const diffTime = Math.abs(now - lastAskedTime);
277            const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
278            if (diffDays < daysBeforeReasking) {
279                /*
280                 * Only this prompt is on cooldown. It used to clear every
281                 * player modal on the way out, so asking for one that had
282                 * been dismissed would take down whichever other one happened
283                 * to be on screen.
284                 */
285                $('#' + id).remove();
286                return;
287            }
288        }
289    } catch (e) {
290        console.error('Unable to access sessionStorage', e);
291    }
292
293    /** Check if its already shown */
294    if ($('#' + id).length > 0) {
295        return;
296    }
297
298    /** Avoid duplicate loads while the same modal is already being fetched. */
299    if (sfPlayerModalLoadingId) {
300        return;
301    }
302
303    /*
304     * One prompt at a time, and whichever got there first keeps its place
305     * until the reader dismisses it. Swapping one for another mid-listen was
306     * the other half of the flicker: these are asked once and then left
307     * alone, not re-decided on every track.
308     */
309    if ($('.sf-modal-player').length > 0) {
310        return;
311    }
312
313    sfPlayerModalLoadingId = id;
314    try {
315        //const modal = await sfLoadModal(id);
316        await sfAccount.loadModal(id);
317    } finally {
318        sfPlayerModalLoadingId = null;
319    }
320
321    if(isMobile()){
322        var modals = $('#' + id);
323        const mobile = $('#m-player-modals');
324        mobile.html(modals);
325    }
326
327}
328
329function isMobile() {
330    return $(window.document).width() < 1024;
331}
332
333function requestAppleMusicToken() {
334
335    const user = sfAccount.getUser();
336}

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.