PageSourceSearch

https://astrology.dailyom.com/media/js/dailyom-guide-parent.js?v=2026-06-11

js dailyom.com collected 2026-09-24 09:37:13 UTC 23,546 bytes, 675 lines download raw bytes

1/**
2 * DailyOM Guide — Ocean parent pages (landing + chat HTML). Hosted on livepel only.
3 * Edit cfg URLs below for staging/production.
4 */
5(function (global) {
6    'use strict';
7
8    var cfg = {
9        iframeOrigin: 'https://astrology.dailyom.com',
10        landingIframeUrl: 'https://astrology.dailyom.com/dailyom-guide',
11        chatIframeUrl: 'https://astrology.dailyom.com/dailyom-guide/chat-new',
12        landingPageUrl: 'https://www.dailyom.com',
13        chatPageUrl: 'https://www.dailyom.com/ai-course-search',
14        guideCssUrl: 'https://astrology.dailyom.com/media/css/dailyom-guide.css',
15        heightPadding: 20
16    };
17
18    var DISCLOSURE_COOKIE_NAME = 'dailyom_guide_disclosure_accepted';
19    var DISCLOSURE_COOKIE_MAX_AGE_DAYS = 365;
20    var SESSION_STORAGE_KEY = 'dailyom_guide_session_id';
21
22    function originFromUrl(url) {
23        try {
24            return new URL(url).origin;
25        } catch (e) {
26            return '';
27        }
28    }
29
30    function dirnameOfPage() {
31        try {
32            var path = global.location.pathname || '/';
33            var i = path.lastIndexOf('/');
34            if (i <= 0) {
35                return global.location.origin;
36            }
37            return global.location.origin + path.slice(0, i + 1);
38        } catch (e) {
39            return '';
40        }
41    }
42
43    function resolvePageUrl(explicit, filename) {
44        if (explicit) {
45            return explicit;
46        }
47        var base = dirnameOfPage();
48        return base ? base + filename : filename;
49    }
50
51    function getLandingPageUrl() {
52        return resolvePageUrl(cfg.landingPageUrl, 'dailyom-guide-landing.html');
53    }
54
55    function getChatPageUrl() {
56        return resolvePageUrl(cfg.chatPageUrl, 'dailyom-guide-chat-new.html');
57    }
58
59    function getIframeOrigin() {
60        return cfg.iframeOrigin || originFromUrl(cfg.landingIframeUrl) || originFromUrl(cfg.chatIframeUrl);
61    }
62
63    /** True when iframe has navigated to the child app (not about:blank / parent origin). */
64    function isIframeMessagingReady(iframe) {
65        if (!iframe || !iframe.contentWindow) {
66            return false;
67        }
68        var expectedOrigin = getIframeOrigin();
69        if (!expectedOrigin) {
70            return false;
71        }
72        var src = String(iframe.getAttribute('src') || iframe.src || '').trim();
73        if (!src || src === 'about:blank' || originFromUrl(src) !== expectedOrigin) {
74            return false;
75        }
76        try {
77            var href = iframe.contentWindow.location.href;
78            if (!href || href === 'about:blank') {
79                return false;
80            }
81            return originFromUrl(href) === expectedOrigin;
82        } catch (e) {
83            // Cross-origin: child has left about:blank; trust configured src origin.
84            return true;
85        }
86    }
87
88    function captureParentAttribution() {
89        if (global.DailyomGuideAttribution && typeof global.DailyomGuideAttribution.captureFromLocation === 'function') {
90            global.DailyomGuideAttribution.captureFromLocation();
91        }
92    }
93
94    function appendAttributionToUrl(urlString) {
95        if (global.DailyomGuideAttribution && typeof global.DailyomGuideAttribution.appendToUrl === 'function') {
96            return global.DailyomGuideAttribution.appendToUrl(urlString, global.location.href);
97        }
98        return urlString;
99    }
100
101    function appendAttributionToUrlObject(url) {
102        if (global.DailyomGuideAttribution && typeof global.DailyomGuideAttribution.appendToUrlObject === 'function') {
103            global.DailyomGuideAttribution.appendToUrlObject(url);
104        }
105        return url;
106    }
107
108    function postMarketingParamsToIframe(iframe) {
109        if (!iframe || !iframe.contentWindow || !global.DailyomGuideAttribution) {
110            return;
111        }
112        if (!isIframeMessagingReady(iframe)) {
113            return;
114        }
115        var origin = getIframeOrigin();
116        if (!origin) {
117            return;
118        }
119        try {
120            iframe.contentWindow.postMessage({
121                type: 'mo_guide_marketing_params',
122                params: global.DailyomGuideAttribution.getStored()
123            }, origin);
124        } catch (e) {}
125    }
126
127    function bindIframeMarketingSync(iframe) {
128        if (!iframe) {
129            return;
130        }
131        iframe.addEventListener('load', function () {
132            postMarketingParamsToIframe(iframe);
133        });
134        // Child iframe may ask for params after it boots (quizzes / tools).
135        var allowedOrigin = getIframeOrigin();
136        if (!global.__dailyomParentMarketingRequestBound) {
137            global.__dailyomParentMarketingRequestBound = true;
138            global.addEventListener('message', function (event) {
139                if (allowedOrigin && event.origin !== allowedOrigin) {
140                    return;
141                }
142                var data = event.data || {};
143                if (data.type !== 'request_mo_guide_marketing_params') {
144                    return;
145                }
146                var frames = global.document.querySelectorAll('iframe');
147                for (var i = 0; i < frames.length; i++) {
148                    postMarketingParamsToIframe(frames[i]);
149                }
150            });
151        }
152    }
153
154    function buildChatPageUrl(query) {
155        var url = new URL(getChatPageUrl(), global.location.href);
156        var q = String(query || '').trim();
157        if (q) {
158            url.searchParams.set('q', q);
159        } else {
160            url.searchParams.delete('q');
161        }
162        appendAttributionToUrlObject(url);
163        return url.toString();
164    }
165
166    function appendParentParams(iframeUrl, parentLandingUrl, parentChatUrl) {
167        var url = new URL(iframeUrl, global.location.href);
168        url.searchParams.set('parent_landing_page', parentLandingUrl || getLandingPageUrl());
169        url.searchParams.set('parent_chat_page', parentChatUrl || getChatPageUrl());
170        return url.toString();
171    }
172
173    function buildLandingIframeSrc() {
174        return appendAttributionToUrl(
175            appendParentParams(cfg.landingIframeUrl, getLandingPageUrl(), getChatPageUrl())
176        );
177    }
178
179    function buildChatIframeSrc(query) {
180        var url = new URL(cfg.chatIframeUrl, global.location.href);
181        url.searchParams.set('embed', '1');
182        var q = String(query || '').trim();
183        if (q) {
184            url.searchParams.set('q', q);
185        }
186        url.searchParams.set('parent_landing_page', getLandingPageUrl());
187        url.searchParams.set('parent_chat_page', getChatPageUrl());
188        appendAttributionToUrlObject(url);
189        return url.toString();
190    }
191
192    function navigateTop(url) {
193        try {
194            if (global.top && global.top !== global.self) {
195                global.top.location.href = url;
196                return;
197            }
198        } catch (e) {}
199        global.location.href = url;
200    }
201
202    function goToChatPage(query) {
203        navigateTop(buildChatPageUrl(query));
204    }
205
206    function goToLandingPage() {
207        navigateTop(getLandingPageUrl());
208    }
209
210    function applyNavLinks(root) {
211        root = root || global.document;
212        if (!root || !root.querySelectorAll) {
213            return;
214        }
215        root.querySelectorAll('[data-mo-guide-nav]').forEach(function (el) {
216            var kind = (el.getAttribute('data-mo-guide-nav') || '').toLowerCase();
217            if (kind === 'landing') {
218                el.setAttribute('href', getLandingPageUrl());
219            } else if (kind === 'chat') {
220                var prefill = el.getAttribute('data-mo-guide-prefill') || '';
221                el.setAttribute('href', buildChatPageUrl(prefill));
222            }
223        });
224    }
225
226    function scrollOceanParentToBottom(behavior) {
227        if (!global.document.documentElement.classList.contains('mo-guide-ocean-chat')) {
228            return;
229        }
230        var b = behavior === 'smooth' ? 'smooth' : 'auto';
231        function run() {
232            var docEl = global.document.documentElement;
233            var body = global.document.body;
234            var maxScroll = Math.max(body.scrollHeight, docEl.scrollHeight) - global.innerHeight;
235            try {
236                global.window.scrollTo({ top: Math.max(0, maxScroll), left: 0, behavior: b });
237            } catch (e) {
238                global.window.scrollTo(0, Math.max(0, maxScroll));
239            }
240        }
241        run();
242        global.requestAnimationFrame(run);
243        global.setTimeout(run, 120);
244        global.setTimeout(run, 350);
245    }
246
247    /** Scroll parent so the user's last message sits just below the fixed utility bar. */
248    function scrollOceanParentToUserAnchor(data) {
249        if (!global.document.documentElement.classList.contains('mo-guide-ocean-chat')) {
250            return;
251        }
252        var iframe = global.document.getElementById('dailyom-guide-chat-frame');
253        if (!iframe) {
254            return;
255        }
256        var msgTopInIframe = parseInt(data && data.messageTopInIframe, 10);
257        var offsetTop = parseInt(data && data.offsetTop, 10);
258        if (isNaN(offsetTop) || offsetTop < 0) {
259            offsetTop = 0;
260        }
261        var gap = parseInt(data && data.gap, 10);
262        if (isNaN(gap)) {
263            gap = 8;
264        }
265        var utility = global.document.querySelector('.mo-guide-ocean-utility');
266        if (!utility) {
267            utility = global.document.querySelector('.utility-bar');
268        }
269        var anchorY = utility ? utility.getBoundingClientRect().bottom + gap : 140;
270        var b = (data && data.behavior) === 'smooth' ? 'smooth' : 'auto';
271        function run() {
272            var iframeRect = iframe.getBoundingClientRect();
273            var target;
274            if (!isNaN(msgTopInIframe)) {
275                target = global.window.pageYOffset + iframeRect.top + msgTopInIframe - anchorY;
276            } else {
277                target = global.window.pageYOffset + iframeRect.top + offsetTop - anchorY;
278            }
279            target = Math.max(0, Math.round(target));
280            try {
281                global.window.scrollTo({ top: target, left: 0, behavior: b });
282            } catch (e) {
283                global.window.scrollTo(0, target);
284            }
285        }
286        run();
287        global.requestAnimationFrame(run);
288        global.setTimeout(run, 120);
289        global.setTimeout(run, 350);
290    }
291
292    function bindHeightListener(iframe, onMessage) {
293        var allowedOrigin = getIframeOrigin();
294        var isOceanChat = global.document.documentElement.classList.contains('mo-guide-ocean-chat');
295        global.addEventListener('message', function (event) {
296            if (event.origin !== allowedOrigin) {
297                return;
298            }
299            var data = event.data || {};
300            if (data.type === 'iframe_height_update' && data.height && iframe) {
301                var h = parseInt(data.height, 10);
302                if (!isNaN(h) && h > 0) {
303                    iframe.style.height = (h + (cfg.heightPadding || 20)) + 'px';
304                }
305            }
306            if (typeof onMessage === 'function') {
307                onMessage(event, data);
308            }
309        });
310    }
311
312    function syncSiteHeaderOffset(headerEl) {
313        if (!headerEl) {
314            return;
315        }
316        function sync() {
317            global.document.documentElement.style.setProperty(
318                '--site-header-height',
319                headerEl.offsetHeight + 'px'
320            );
321        }
322        sync();
323        global.addEventListener('resize', sync);
324    }
325
326    function applyParentCss() {
327        var cssEl = global.document.getElementById('mo-guide-parent-css');
328        if (cssEl && cfg.guideCssUrl) {
329            cssEl.href = cfg.guideCssUrl;
330        }
331    }
332
333    /** Webflow cannot set classes on <html>; also apply to body + #mo-guide-root wrapper. */
334    function applyParentScopeClasses(mode) {
335        var classes = ['mo-guide-ocean-parent'];
336        if (mode === 'chat') {
337            classes.push('mo-guide-ocean-chat');
338        } else if (mode === 'landing') {
339            classes.push('mo-guide-ocean-landing');
340        }
341        var docEl = global.document.documentElement;
342        var body = global.document.body;
343        var i;
344        var c;
345        for (i = 0; i < classes.length; i++) {
346            c = classes[i];
347            docEl.classList.add(c);
348            if (body) {
349                body.classList.add(c);
350            }
351        }
352        var root = global.document.getElementById('mo-guide-root');
353        if (!root) {
354            root = global.document.querySelector('.mo-guide-ocean-parent');
355        }
356        if (root) {
357            for (i = 0; i < classes.length; i++) {
358                root.classList.add(classes[i]);
359            }
360        }
361    }
362
363    function readDisclosureCookie() {
364        try {
365            var escaped = DISCLOSURE_COOKIE_NAME.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
366            var match = global.document.cookie.match(new RegExp('(?:^|; )' + escaped + '=([^;]*)'));
367            return match ? decodeURIComponent(match[1]) : '';
368        } catch (e) {
369            return '';
370        }
371    }
372
373    function persistDisclosureAccepted() {
374        try {
375            var maxAge = DISCLOSURE_COOKIE_MAX_AGE_DAYS * 24 * 60 * 60;
376            if (global.location.protocol === 'https:') {
377                global.document.cookie = DISCLOSURE_COOKIE_NAME + '=1; Max-Age=' + maxAge + '; Path=/; SameSite=None; Secure';
378            } else {
379                global.document.cookie = DISCLOSURE_COOKIE_NAME + '=1; Max-Age=' + maxAge + '; Path=/; SameSite=Lax';
380            }
381        } catch (e) {}
382    }
383
384    function initLandingParent() {
385        captureParentAttribution();
386        global.document.documentElement.classList.add('mo-guide-ocean-parent', 'mo-guide-ocean-landing');
387
388        syncSiteHeaderOffset(global.document.getElementById('site-header'));
389
390        var wrapper = global.document.getElementById('dailyom-guide-iframe');
391        var iframe = wrapper ? wrapper.querySelector('iframe') : null;
392        if (iframe) {
393            iframe.src = buildLandingIframeSrc();
394            bindHeightListener(iframe);
395            bindIframeMarketingSync(iframe);
396        }
397
398        applyNavLinks(global.document);
399
400        global.addEventListener('message', function (event) {
401            if (event.origin !== getIframeOrigin()) {
402                return;
403            }
404            var data = event.data || {};
405            if (data.type === 'mo_guide_go_chat' && data.query) {
406                goToChatPage(data.query);
407            }
408        });
409    }
410
411    function syncOceanComposerOffset() {
412        if (!global.document.documentElement.classList.contains('mo-guide-ocean-chat')) {
413            return;
414        }
415        var wrap = global.document.querySelector('.chat-page-input__wrapper');
416        if (!wrap) {
417            return;
418        }
419        var h = Math.ceil(wrap.getBoundingClientRect().height) + 12;
420        global.document.documentElement.style.setProperty('--mo-guide-composer-offset', h + 'px');
421        return h;
422    }
423
424    function initChatParent() {
425        captureParentAttribution();
426        applyParentScopeClasses('chat');
427
428        var iframe = global.document.getElementById('dailyom-guide-chat-frame');
429        var composer = global.document.getElementById('chat-composer');
430        var submitBtn = global.document.getElementById('chat-send-submit');
431        var chatForm = global.document.getElementById('chat-input-form');
432        var composerDisabled = false;
433
434        applyNavLinks(global.document);
435
436        function clearGuideSession() {
437            try {
438                global.sessionStorage.removeItem('dailyom_guide_initial_query');
439                global.sessionStorage.removeItem('dailyom_guide_chat_bootstrap');
440                global.sessionStorage.removeItem(SESSION_STORAGE_KEY);
441            } catch (e) {}
442        }
443
444        function bindOceanStartOverClear() {
445            var btn = global.document.getElementById('course-finder-start-over');
446            if (!btn) {
447                return;
448            }
449            btn.addEventListener('click', function () {
450                clearGuideSession();
451            });
452        }
453        bindOceanStartOverClear();
454
455        function onViewportChange() {
456            syncOceanComposerOffset();
457        }
458        onViewportChange();
459        global.addEventListener('resize', onViewportChange);
460        if (global.visualViewport) {
461            global.visualViewport.addEventListener('resize', onViewportChange);
462        }
463        if (iframe) {
464            iframe.addEventListener('load', onViewportChange);
465        }
466
467        function getQueryParam() {
468            return (new URLSearchParams(global.location.search || '').get('q') || '').trim();
469        }
470
471        function postToIframe(payload) {
472            if (!iframe || !iframe.contentWindow || !isIframeMessagingReady(iframe)) {
473                return false;
474            }
475            try {
476                iframe.contentWindow.postMessage(payload, getIframeOrigin());
477                return true;
478            } catch (e) {
479                return false;
480            }
481        }
482
483        function setComposerDisabled(disabled) {
484            composerDisabled = !!disabled;
485            if (submitBtn) {
486                submitBtn.disabled = composerDisabled;
487            }
488            if (composer) {
489                composer.setAttribute('aria-disabled', composerDisabled ? 'true' : 'false');
490                composer.setAttribute('contenteditable', composerDisabled ? 'false' : 'true');
491            }
492        }
493
494        function composerText() {
495            return composer ? (composer.textContent || '').trim() : '';
496        }
497
498        function clearComposer() {
499            if (composer) {
500                composer.innerHTML = '';
501            }
502        }
503
504        function focusComposer() {
505            if (!composer || composerDisabled) {
506                return;
507            }
508            try {
509                composer.focus({ preventScroll: true });
510            } catch (e) {
511                composer.focus();
512            }
513        }
514
515        function loadChatIframe(q) {
516            if (!iframe) {
517                return;
518            }
519            iframe.src = buildChatIframeSrc(q);
520            bindIframeMarketingSync(iframe);
521        }
522
523        function showDisclosureModal() {
524            var modal = global.document.getElementById('mo-guide-disclosure');
525            if (!modal) {
526                return;
527            }
528            modal.hidden = false;
529            global.document.documentElement.classList.add('mo-guide-disclosure-open');
530            if (global.document.body) {
531                global.document.body.classList.add('mo-guide-disclosure-open');
532            }
533            var rootOpen = global.document.getElementById('mo-guide-root');
534            if (rootOpen) {
535                rootOpen.classList.add('mo-guide-disclosure-open');
536            }
537        }
538
539        function hideDisclosureModal() {
540            var modal = global.document.getElementById('mo-guide-disclosure');
541            if (!modal) {
542                return;
543            }
544            modal.hidden = true;
545            global.document.documentElement.classList.remove('mo-guide-disclosure-open');
546            if (global.document.body) {
547                global.document.body.classList.remove('mo-guide-disclosure-open');
548            }
549            var rootClose = global.document.getElementById('mo-guide-root');
550            if (rootClose) {
551                rootClose.classList.remove('mo-guide-disclosure-open');
552            }
553        }
554
555        function initDisclosureGate(onAccepted) {
556            if (readDisclosureCookie() === '1') {
557                if (typeof onAccepted === 'function') {
558                    onAccepted();
559                }
560                return;
561            }
562            showDisclosureModal();
563            var agreeBtn = global.document.getElementById('mo-guide-disclosure-agree');
564            if (agreeBtn) {
565                agreeBtn.addEventListener('click', function () {
566                    persistDisclosureAccepted();
567                    hideDisclosureModal();
568                    postToIframe({ type: 'mo_guide_disclosure_result', accepted: true });
569                    if (typeof onAccepted === 'function') {
570                        onAccepted();
571                    }
572                }, { once: true });
573            }
574        }
575
576        function sendComposerMessage() {
577            if (composerDisabled) {
578                return;
579            }
580            var text = composerText();
581            if (!text) {
582                return;
583            }
584            if (postToIframe({ type: 'mo_guide_send_message', text: text })) {
585                clearComposer();
586            }
587        }
588
589        if (chatForm) {
590            chatForm.addEventListener('submit', function (e) {
591                e.preventDefault();
592                sendComposerMessage();
593            });
594        }
595
596        if (composer) {
597            composer.addEventListener('keydown', function (e) {
598                if (e.key === 'Enter' && !e.shiftKey) {
599                    e.preventDefault();
600                    sendComposerMessage();
601                }
602            });
603        }
604
605        bindHeightListener(iframe, function (event, data) {
606            if (data.type === 'mo_guide_scroll_bottom') {
607                scrollOceanParentToBottom(data.behavior);
608                return;
609            }
610            if (data.type === 'mo_guide_scroll_user_anchor') {
611                scrollOceanParentToUserAnchor(data);
612                return;
613            }
614            if (data.type === 'mo_guide_chat_state') {
615                setComposerDisabled(!!data.composerDisabled || !!data.loading);
616                return;
617            }
618            if (data.type === 'mo_guide_focus_composer') {
619                focusComposer();
620                return;
621            }
622            if (data.type === 'mo_guide_disclosure_request') {
623                if (readDisclosureCookie() === '1') {
624                    postToIframe({ type: 'mo_guide_disclosure_result', accepted: true });
625                }
626            }
627        });
628
629        var q = getQueryParam();
630        if (!q) {
631            goToLandingPage();
632            return;
633        }
634
635        initDisclosureGate(function () {
636            loadChatIframe(q);
637            onViewportChange();
638        });
639    }
640
641    function init() {
642        applyParentCss();
643
644        if (global.document.getElementById('dailyom-guide-chat-frame')) {
645            initChatParent();
646            return;
647        }
648        if (global.document.getElementById('dailyom-guide-landing-frame')) {
649            initLandingParent();
650        }
651    }
652
653    global.MoGuideParentConfig = cfg;
654    global.MoGuideParent = {
655        config: cfg,
656        getLandingPageUrl: getLandingPageUrl,
657        getChatPageUrl: getChatPageUrl,
658        getIframeOrigin: getIframeOrigin,
659        buildChatPageUrl: buildChatPageUrl,
660        buildLandingIframeSrc: buildLandingIframeSrc,
661        buildChatIframeSrc: buildChatIframeSrc,
662        goToChatPage: goToChatPage,
663        goToLandingPage: goToLandingPage,
664        navigateTop: navigateTop,
665        applyNavLinks: applyNavLinks,
666        bindHeightListener: bindHeightListener,
667        syncSiteHeaderOffset: syncSiteHeaderOffset
668    };
669
670    if (global.document.readyState === 'loading') {
671        global.document.addEventListener('DOMContentLoaded', init);
672    } else {
673        init();
674    }
675})(typeof window !== 'undefined' ? window : this);

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.