PageSourceSearch

https://www.motherearthnews.com/wp-content/plugins/opi-authentication/assets/js/auth/access/article.js

js motherearthnews.com collected 2026-09-24 08:38:53 UTC 13,277 bytes, 312 lines download raw bytes

1(function ($) {
2    'use strict';
3
4    $(function () {
5        var gatingData = window.OPI_AUTH_ACCESS_ARTICLE || {};
6        var isArticleGated = String(gatingData.is_article_gated) === 'true';
7        var modalData = gatingData.modal || {};
8
9        var $continueBtn = $('[data-continue-reading]').first();
10        if ($continueBtn.length) {
11            $('[id$="_Article_300x250"], [id*="_Article_300x250"]').each(function () {
12                var isBeforeContinue = !!(this.compareDocumentPosition($continueBtn[0]) & Node.DOCUMENT_POSITION_FOLLOWING);
13                if (isBeforeContinue) {
14                    $(this).css('display', 'none');
15                }
16            });
17        }
18
19        var lock = {
20            on: function () {
21                if (!document.body.classList.contains('opi-paywall-locked')) {
22                    document.body.classList.add('opi-paywall-locked');
23                }
24                document.body.style.overflow = 'hidden';
25            },
26            off: function () {
27                document.body.classList.remove('opi-paywall-locked');
28                if (!document.body.classList.contains('opi-auth-locked')) {
29                    document.body.style.overflow = '';
30                }
31            }
32        };
33
34        function one(selector) {
35            var $all = $(selector);
36            if ($all.length > 1) {
37                $all.slice(1).remove();
38                $all = $all.eq(0);
39            }
40            return $all;
41        }
42
43        function ensureScaffold() {
44            var $overlay = one('[data-opi-paywall-overlay]');
45            var $wrapper = one('[data-opi-paywall-wrapper]');
46
47            if (!$overlay.length) {
48                $overlay = $(
49                    '<div data-opi-paywall-overlay class="fixed inset-0 bg-black/50 backdrop-blur-sm opacity-0 transition-opacity duration-200 ease-out z-[9998] pointer-events-none" style="display:none;"></div>'
50                ).appendTo('body');
51            }
52            if (!$wrapper.length) {
53                $wrapper = $(
54                    '<div data-opi-paywall-wrapper class="fixed inset-0 z-[9999] hidden overflow-y-auto flex items-center justify-center p-6" style="visibility:hidden;"></div>'
55                ).appendTo('body');
56            }
57            return { $overlay: $overlay, $wrapper: $wrapper };
58        }
59
60        function showOverlay($overlay) {
61            $overlay.css('display', 'block');
62            if ($overlay[0]) {
63                $overlay[0].offsetHeight;
64            }
65            $overlay.removeClass('pointer-events-none opacity-0')
66                .addClass('opacity-100')
67                .css('pointer-events', 'auto');
68        }
69
70        function hideOverlay($overlay) {
71            $overlay.removeClass('opacity-100').addClass('opacity-0').css('pointer-events', 'none');
72            setTimeout(function () {
73                $overlay.css('display', 'none');
74            }, 200);
75        }
76
77        function hardHideWrapper($wrapper) {
78            $wrapper.addClass('hidden').removeClass('flex').css({ display: 'none', visibility: 'hidden' });
79        }
80
81        function safeOpiCall(methodName) {
82            try {
83                return !!(window.OPI && typeof window.OPI[methodName] === 'function' && window.OPI[methodName]());
84            } catch (err) {
85                return false;
86            }
87        }
88
89        function appendRedirectUrl(url) {
90            if (!url || !window.location || !window.location.href) {
91                return url;
92            }
93            return url + (url.indexOf('?') !== -1 ? '&' : '?') + 'redirectURL=' + encodeURIComponent(window.location.href);
94        }
95
96        function getEncryptedCustomerId() {
97            var id = '';
98
99            if (modalData.encrypted_customer_id) {
100                id = modalData.encrypted_customer_id;
101            }
102
103            if (!id) {
104                try {
105                    var access = window.OPI_AUTH_ACCESS || {};
106                    id = access.encrypted_customer_id || '';
107                } catch (err) {}
108            }
109
110            if (!id) {
111                try {
112                    var authData = window.OPI_AUTH_DATA || {};
113                    if (authData.user && authData.user.data) {
114                        id = authData.user.data.encrypted_customer_id || '';
115                    }
116                } catch (err) {}
117            }
118
119            if (!id) {
120                try {
121                    if (window.OPI && typeof window.OPI.getUserField === 'function') {
122                        id = window.OPI.getUserField('encrypted_customer_id') || '';
123                    }
124                } catch (err) {}
125            }
126
127            if (!id) {
128                try {
129                    var cookies = document.cookie.split(';');
130                    for (var i = 0; i < cookies.length; i++) {
131                        var item = cookies[i].trim();
132                        if (item.indexOf('opi_user=') === 0) {
133                            var raw = item.substring('opi_user='.length);
134                            var cookieData;
135                            try {
136                                cookieData = JSON.parse(decodeURIComponent(raw));
137                            } catch (parseErr) {
138                                cookieData = JSON.parse(raw);
139                            }
140                            if (cookieData && cookieData.encrypted_customer_id) {
141                                id = cookieData.encrypted_customer_id;
142                                break;
143                            }
144                        }
145                    }
146                } catch (err) {}
147            }
148
149            return id || '';
150        }
151
152        function applyEncryptedCustomerId(url) {
153            if (!url) {
154                return url;
155            }
156            var encryptedCustomerId = getEncryptedCustomerId();
157            if (!encryptedCustomerId) {
158                return url;
159            }
160            return String(url)
161                .replace(/\{encrypted_customer_id\}/g, encryptedCustomerId)
162                .replace(/%7Bencrypted_customer_id%7D/gi, encryptedCustomerId);
163        }
164
165        function buildRenewLink() {
166            var renewLink = modalData.renew_link || '';
167            if (!renewLink) {
168                return '';
169            }
170            return appendRedirectUrl(applyEncryptedCustomerId(renewLink));
171        }
172
173        function markup() {
174            var title = modalData.title || 'Unlock this content';
175            var description = modalData.description || 'Sign in or register to continue reading.';
176            var registerLink = appendRedirectUrl(modalData.register_link || '');
177            var loginLink = modalData.login_link || '/sso/login';
178            var isLoggedIn = safeOpiCall('isLoggedIn');
179            var hasAccess = safeOpiCall('isStaff') || safeOpiCall('canViewDigital');
180            var showRenewMembership = isLoggedIn && !hasAccess;
181            var primaryHref = showRenewMembership ? (buildRenewLink() || registerLink || loginLink) : registerLink;
182            var primaryLabel = showRenewMembership ? 'Renew Membership' : (modalData.register_button_text || 'Register Now');
183            var primaryCta = primaryHref ? '<a href="' + primaryHref + '" class="w-full inline-flex items-center justify-center rounded-md border border-transparent px-4 py-2.5 text-base font-semibold text-white bg-primary hover:bg-primary-75 mb-3">' + primaryLabel + '</a>' : '';
184            var loginPromptHtml = showRenewMembership ? '' : '<button type="button" data-opi-paywall-login class="text-sm text-gray-600 hover:text-primary hover:underline bg-transparent border-0 cursor-pointer p-0">Already a member/subscriber? Sign in</button>';
185
186            return '' +
187                '<div id="opi-paywall-modal" data-opi-paywall-modal class="relative w-full max-w-sm rounded-xl border border-[#
187E5E5E5] bg-white overflow-visible px-6 pt-5 pb-6 flex-shrink-0 my-auto" role="dialog" aria-modal="true" aria-labelledby="opi-paywall-title">' +
188                '<button type="button" data-opi-paywall-close class="absolute top-1.5 right-1.5 z-10 inline-flex items-center justify-center rounded-md p-1.5 text-black/50 hover:text-black/70 hover:bg-black/5 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 cursor-pointer" aria-label="Close paywall modal">' +
189                '<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 pointer-events-none" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">' +
190                '<path fill-rule="evenodd" d="M10 8.586l4.95-4.95a1 1 0 111.414 1.415L11.414 10l4.95 4.95a1 1 0 01-1.415 1.414L10 11.414l-4.95 4.95a1 1 0 01-1.414-1.415L8.586 10l-4.95-4.95A1 1 0 115.05 3.636L10 8.586z" clip-rule="evenodd"/>' +
191                '</svg>' +
192                '</button>' +
193                '<div class="flex flex-col items-center justify-center text-center">' +
194                '<h2 id="opi-paywall-title" class="text-xl lg:text-2xl font-bold text-primary mt-0 mb-2 pr-1">' + title + '</h2>' +
195                '<p class="text-black/70 text-sm lg:text-base mb-4">' + description + '</p>' +
196                primaryCta +
197                loginPromptHtml +
198                '</div>' +
199                '</div>';
200        }
201
202        function closePaywall() {
203            var $overlay = $('[data-opi-paywall-overlay]');
204            var $wrapper = $('[data-opi-paywall-wrapper]');
205
206            $('#opi-paywall-modal').remove();
207            hideOverlay($overlay);
208            hardHideWrapper($wrapper);
209            lock.off();
210        }
211
212        function unlockContent() {
213            lock.off();
214            $('#opi_gating_part_two_content').removeClass('hidden').css('display', '');
215            $('[data-continue-reading]').addClass('hidden').attr('aria-hidden', 'true');
216            closePaywall();
217        }
218
219        function openPaywall() {
220            var s = ensureScaffold();
221            var $overlay = s.$overlay;
222            var $wrapper = s.$wrapper;
223
224            $('#opi-paywall-modal').remove();
225
226            $wrapper.append(markup())
227                .removeClass('hidden').addClass('flex')
228                .css({ display: 'flex', visibility: 'visible' });
229
230            showOverlay($overlay);
231            lock.on();
232
233            $('#opi-paywall-modal [data-opi-paywall-close]').trigger('focus');
234        }
235
236        function continueReadingLogic() {
237            if (!isArticleGated) {
238                unlockContent();
239                return;
240            }
241
242            try {
243                if (!window.OPI) {
244                    openPaywall();
245                    return;
246                }
247
248                var isLoggedIn = safeOpiCall('isLoggedIn');
249                var canViewDigital = safeOpiCall('canViewDigital');
250
251                if (isLoggedIn && canViewDigital) {
252                    unlockContent();
253                    try {
254                        var live = document.querySelector('[aria-live]');
255                        if (live) {
256                            live.textContent = 'Full article unlocked.';
257                        }
258                    } catch (announceError) {
259                        console.log('Live region announcement failed:', announceError);
260                    }
261                } else {
262                    openPaywall();
263                }
264            } catch (err) {
265                console.log('Error during access check:', err);
266                openPaywall();
267            }
268        }
269
270        $(document)
271            .off('click.opiPaywall', '[data-continue-reading]')
272            .on('click.opiPaywall', '[data-continue-reading]', function (e) {
273                e.preventDefault();
274                continueReadingLogic();
275            });
276
277        $(document)
278            .off('click.opiPaywall', '#opi-paywall-modal [data-opi-paywall-close]')
279            .on('click.opiPaywall', '#opi-paywall-modal [data-opi-paywall-close]', function (e) {
280                e.preventDefault();
281                closePaywall();
282            });
283
284        $(document)
285            .off('mousedown.opiPaywall touchstart.opiPaywall', '[data-opi-paywall-wrapper]')
286            .on('mousedown.opiPaywall touchstart.opiPaywall', '[data-opi-paywall-wrapper]', function (e) {
287                if (e.target === this && $('#opi-paywall-modal').length) {
288                    closePaywall();
289                }
290            });
291
292        $(document)
293            .off('keydown.opiPaywall')
294            .on('keydown.opiPaywall', function (e) {
295                if ((e.key === 'Escape' || e.keyCode === 27) && $('#opi-paywall-modal').length) {
296                    e.preventDefault();
297                    closePaywall();
298                }
299            });
300
301        $(document)
302            .off('click.opiPaywall', '#opi-paywall-modal [data-opi-paywall-login]')
303            .on('click.opiPaywall', '#opi-paywall-modal [data-opi-paywall-login]', function (e) {
304                e.preventDefault();
305                closePaywall();
306                // Use direct API to open login modal without custserv mode
307                if (window.opiAuthModal && typeof window.opiAuthModal.open === 'function') {
308                    window.opiAuthModal.open();
309                }
310            });
311    });
312})(window.jQuery || jQuery);

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.