1document.addEventListener('DOMContentLoaded', function () { 2 /* log paywall settings for debugging */ 3 //console.log('Paywall Settings:', paywallSettings); 4 //console.log('Paywall Enabled (raw):', paywallSettings.enablePaywall); 5 //console.log('Paywall Enabled (type):', typeof paywallSettings.enablePaywall); 6 7 /* convert enablePaywall to number for comparison */ 8 const enablePaywall = parseInt(paywallSettings.enablePaywall, 10); 9 10 /* check for enablePaywall */ 11 if (enablePaywall !== 1) { 12 //console.log('Paywall not enabled for this page. Exiting.', { enablePaywall }); 13 return; 14 } 15 16 17 /* set subscriber cookie based on login status */ 18 function setSubscriberCookie(isLoggedIn) { 19 const value = isLoggedIn ? '1' : '0'; 20 /* create domain (e.g., .lakeplacidnews.com for subdomains) to include subdomains */ 21 const hostname = window.location.hostname; 22 const domainParts = hostname.split('.'); 23 const domain = domainParts.length > 2 ? `.${domainParts.slice(-2).join('.')}` : hostname; 24 document.cookie = `subscriber=${value}; path=/; domain=${domain}; max-age=86400; SameSite=Lax`; 25 } 26 27 //console.log('Paywall logic proceeding (enablePaywall is 1).'); 28 29 /* session management */ 30 const isAuthenticated = () => { 31 const session = localStorage.getItem('paywallSession'); 32 if (!session) { 33 setSubscriberCookie(false); 34 return false; 35 } 36 try { 37 const { timestamp } = JSON.parse(session); 38 const now = new Date().getTime(); 39 //console.log('now: ' + now); 40 const sessionValid = now <= timestamp + (30 * 24 * 60 * 60 * 1000); 41 //console.log('Session check:', { timestamp, sessionValid }); 42 if ( !sessionValid ) { 43 setSubscriberCookie(false); 44 localStorage.removeItem('paywallSession'); 45 } 46 setSubscriberCookie(true); 47 return sessionValid; 48 } catch (error) { 49 console.error('Invalid session data:', error); 50 return false; 51 } 52 }; 53 54 /* article counter */ 55 const getArticleCount = () => { 56 return parseInt(localStorage.getItem('articleCount') || '0', 10); 57 }; 58 59 const incrementArticleCount = () => { 60 const count = getArticleCount() + 1; 61 localStorage.setItem('articleCount', count); 62 return count; 63 }; 64 65 /* check if paywall should be triggered */ 66 const shouldShowPaywall = () => { 67 if (isAuthenticated()) { 68 //console.log('User is authenticated. Paywall not shown.'); 69 return false; 70 } 71 const count = incrementArticleCount(); 72 //console.log('Article Count:', count); 73 return count > parseInt(paywallSettings.freeArticleLimit, 10); 74 }; 75 76 /* create paywall overlay */ 77 const showPaywall = ( default_view = 'subscribe' ) => { 78 //console.log('Showing paywall overlay.'); 79 /* dsable scrolling */ 80 document.body.style.overflow = 'hidden'; 81 document.body.classList.add('login_no_scroll'); 82 83 /* if this paywall is still being used with ONECount - redirect to the /subscribe page instead of showing the subscription offers on the overlay */ 84 if ( paywallSettings.authenticator == 'onecount' ) { 85 window.location.href = '/subscribe'; 86 } 87 88 function printObject(o) { 89 var out = ''; 90 for (var p in o) { 91 out += p + ': ' + o[p] + '\n'; 92 } 93 console.log("%c" + out , "color:green"); 94 } 95 96 97 /* create overlay */ 98 const overlay = document.createElement('div'); 99 overlay.id = 'paywall-overlay'; 100 overlay.style.position = 'fixed'; 101 overlay.style.top = '0'; 102 overlay.style.left = '0'; 103 overlay.style.width = '100%'; 104 overlay.style.height = '100%'; 105 overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; 106 overlay.style.zIndex = '9999'; 107 overlay.style.padding = '20px'; 108 overlay.style.boxSizing = 'border-box'; 109 110 /* create the modal content */ 111 overlay.innerHTML = ` 112 <style> 113 .products {text-align:center; margin:0 auto; padding:0 20px 40px 20px; display:grid; grid-auto-columns:25%; grid-gap:20px; justify-content:center; grid-auto-flow:column;} 114 .products li {margin-top:20px; box-sizing:border-box; padding:20px; background:#fff; border-radius:6px; -webkit-box-shadow:0 0 7px 0 rgba(0, 0, 0, 0.25); 115 -moz-box-shadow:0 0 7px 0 rgba(0, 0, 0, 0.25); box-shadow:0 0 7px 0 rgba(0, 0, 0, 0.25);} 116 .products h2 {text-align:center; padding:10px 0; border-bottom:solid 1px #dbdbdb; margin:0 0 10px 0;} 117 .products img {width:100%; height:auto; border-radius:5px} 118 .woocommerce-product-gallery img {border-radius:5px;} 119 .woocommerce ul.product_list_widget li img {border-radius:3px;} 120 .add_to_cart_button {padding:10px 20px; margin:0 auto 10px auto; width:100%; background:#000; color:#fff; border-radius:5px;} 121 .products span.price {color:#1c7554; font-size:27px; font-weight:600; text-align:center;} 122 span.woocommerce-Price-amount {display:none} 123 .weekly_price {font-size:36px; font-weight:bold;} 124 .weekly_price:before {content:'$'; font-size:.6em; vertical-align:top; line-height:1.8em;} 125 .weekly_price:after {content:'. '; opacity:0;} 126 .per_week {color:#999; font-size:13px; font-weight:normal; line-height:13px} 127 .products h2 {font-size:20px} 128 .product-type-simple, .product-type-variable {position:relative;} 129 .best_deal {position:absolute; top:10px; background:#ea0800; color:#fff; width:100px; border-radius:3px; padding:4px 0; text-align:center; margin-left:-50px; left:50%; z-index:9999999999} 130 .add_to_cart_button {background:#ff6619; color:#fff; padding:8px 10px 8px 10px; border-radius:18px; width:140px; display:block} 131 .single_add_to_cart_button {background:#ff6619; color:#fff; padding:12px 15px 11px 15px; border-radius:18px; width:160px; margin:0 auto; display:block; border:unset; text-transform:uppercase; font-size:14px !important; font-weight:bold} 132 .products span.price {display:none !important;} 133 #ecommerce_content .screen-reader-text {display:none !important;} 134 .variations th.label {display:none} 135 .variations {display:grid; grid-template-columns:20px 1fr; grid-column-gap:7px; grid-row-gap:10px; margin-bottom:30px; width:100%;} 136 .variations tbody {grid-column:1/-1; width:100%; display:block} 137 .variations input {width:15px !important; padding:0 !important; margin:0 0 0 5px !important;} 138 .variations label {text-transform:unset !important;
138 color:#222 !important; font-size:14px !important; font-weight:normal !important; margin-right:unset !important; text-align:left} 139 .reset_variations {display:none} 140 .products img {width:100% !important; height:auto !important;} 141 .woocommerce-LoopProduct-link {pointer-events:none; cursor:default;} 142 .single_add_to_cart_button {cursor:pointer} 143 .as_low_as {color:#999; font-size:13px; font-weight:normal; margin-top:10px; line-height:13px; font-style:italic} 144 .variations {display:block; margin:20px 0} 145 .variations .value {width:100%;} 146 .variations select {width:220px; display:block; padding:6px 5px; } 147 .variations tr {width:100%; display:block} 148 .products h2 {height:80px} 149 .reset_variations {display:none !important;} 150 .variations_form {width:100%;} 151 .variations td {display:block} 152 .variations #subscription {border:solid 1px #dbdbdb; border-radius:3px; border-color:#dbdbdb; background:#fff !important;} 153 @media screen and (max-width:1300px) { 154 .variations select {width:100% !important;} 155 } 156 @media screen and (max-width:1050px) { 157 #overlay_subscribe_iframe { min-height:100% !important; height:100vh !important; overflow-y:visible;} 158 #paywall-overlay {overflow-y:auto;} 159 #subscriptions_wrap {height:unset; } 160 .products {grid-auto-columns:unset; grid-auto-flow:unset; grid-template-columns:1fr; justify-content:center} 161 .products li {width:100%; max-width:500px; justify-content:center; margin:0 auto;} 162 #overlay_subscribe_iframe {border:unset !important;} 163 } 164 @media screen and (max-width:1050px) { 165 #overlay_login_prompt {width:100% !important;} 166 } 167 @media screen and (max-width:500px) { 168 #paywall-overlay {right:10px} 169 #subscriptions_wrap { padding:35px 17px 10px 17px !important; position:fixed; overflow-y:hidden; height:calc(100vh - 20px); top:10px; bottom:10px; left:0; right:0; width:calc(100% - 20px) !important;} 170 #subscription_site_logo {width:100% !important; height:auto !important;} 171 #overlay_subscribe_iframe {height:630px !important; max-height:630px !important; min-height:unset !important; overflow-y:scroll; -moz-box-shadow:inset 0 -10px 10px -10px #888; -webkit-box-shadow:inset 0 -10px 10px -10px #888; box-shadow:inset 0 -10px 10px -10px #888; border-bottom:solid 1px #888; border-bottom-left-radius:6px; border-bottom-right-radius:6px} 172 #account_login {font-size:17px !important;} 173 #account_subscribe {font-size:17px !important;} 174 #inner_subscriptions_wrap {max-height:none; height:100%; overflow:scroll; } 175 176 } 177 </style> 178 <section id="subscriptions_wrap" style="max-width:1200px; width:calc(100% - 80px); margin:0 auto; background:#f2f2f2; box-sizing:border-box; padding:40px 30px 10px 30px; border-radius:8px; -webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.35); -moz-box-shadow: 0 0 9px 0 rgba(0,0,0,0.65); box-shadow: 0 0 9px 0 rgba(0, 0, 0, 0.65);"> 179 <a href="/"><img id="subscription_site_logo" style="width:330px; display:block; height:auto; margin:0 auto;" src="${paywallSettings.newspaperLogo}" border="0" alt="homepage logo"></a> 180 181 <!-- login prompt --> 182 <div id="inner_subscriptions_wrap" style="padding:30px 0; max-width:1080px; width:100%; margin:0 auto; justify-content:center"> 183 <p id="account_login" style="font-size:18px; text-align:center; padding-bottom:20px">Already have an account? <a id="overlay_login_link" style="font-weight:bold; color:#106ba2; font-size:18px; cursor:pointer;">Log in</a></p> 184 <p id="account_subscribe" style="font-size:18px; text-align:center; padding-bottom:20px">Don't have an account? <a id="overlay_subscribe_link" style="font-weight:bold; color:#106ba2; font-size:18px; cursor:pointer;">Subscribe now</a></p> 185 <p style="color:#222; font-size:15px; text-align:center; padding-bottom:15px">Get award winning reporting from a source you trust</p> 186 187 <div id="overlay_login_prompt" style="background:#fff; display:none; padding:35px 30px; border-radius:8px; width:50%; margin-left:auto; margin-right:auto; box-sizing: border-box; border:1px solid #ddd;-webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 7px 0 rgba(0,0,0,0.15); box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.15);"> 188 <h2 style="text-align:center; text-transform:uppercase; font-size:18px; letter-spacing:1px; color:#333;padding-bottom:30px; border-bottom:dotted 1px #d6d6d6">Customer Login</h2> 189 190 <p style="text-align:center; margin:30px 0; font-size:16px; color:#9f000c;">You've reached your limit of ${paywallSettings.freeArticleLimit} free articles.</p> 191 192 <div id="paywall-error" style="color: red; display: none;"></div> 193 194 <input type="email" id="paywall-email" placeholder="Email" style="width:100%; margin-bottom:10px; padding:8px; box-sizing:border-box; border-radius:4px; border:solid 1px #d8d8d8;"> 195 <div style="position: relative; margin-bottom: 10px;"> 196 <input type="password" id="paywall-password" placeholder="Password" style="width: 100%; padding: 8px; padding-right: 80px; box-sizing: border-box; border-radius:4px; border:solid 1px #d8d8d8;"> 197 <button id="toggle-password" style="position: absolute; right: 8px; top: 50%; transform: translateY(-50%); padding: 4px 8px; font-size: 12px; background: #ddd; border: none; border-radius: 4px; cursor: pointer;"><i class="fas fa-eye"></i></button> 198 </div> 199 <button id="paywall-login" style="padding: 10px 20px; background: #007BFF; color: white; border: none; border-radius: 4px; width: 100%; box-sizing: border-box; cursor:pointer;">
200 <span class="btn-text">Log In</span> 201 <i class="fa-solid fa-spinner fa-spin" style="display: none;"></i> 202 </button> 203 204 205 <p style="text-align:center; margin:30px 0; font-size:16px; color:#9f000c;"><a href="${paywallSettings.forgotPasswordUrl}" target="_top">Forgot Password?</a></p> 206 207 </div> 208 209 <!-- display subscriptions --> 210 <iframe id="overlay_subscribe_iframe" style="display:none; border:none; max-height:none" src="${paywallSettings.iframeUrl}" width="100%" height="570px"></iframe> 211 </div> 212 </section> 213 `; 214 document.body.appendChild(overlay); 215 216 if ( default_view === 'subscribe' ) { 217 document.getElementById('overlay_login_prompt').style.display = 'none'; 218 document.getElementById('overlay_subscribe_iframe').style.display = ''; 219 220 document.getElementById('account_login').style.display = ''; 221 document.getElementById('account_subscribe').style.display = 'none'; 222 223 224 } else { 225 document.getElementById('overlay_login_prompt').style.display = ''; 226 document.getElementById('overlay_subscribe_iframe').style.display = 'none'; 227 228 document.getElementById('account_login').style.display = 'none'; 229 document.getElementById('account_subscribe').style.display = ''; 230 } 231 232 233 /* handle switching between LOGIN and SUBCRIBE on the overlay */ 234 document.getElementById('overlay_login_link').addEventListener('click', async () => { 235 document.getElementById('overlay_login_prompt').style.display = ''; 236 document.getElementById('overlay_subscribe_iframe').style.display = 'none'; 237 238 document.getElementById('account_login').style.display = 'none'; 239 document.getElementById('account_subscribe').style.display = ''; 240 }); 241 242 /* handle login */ 243 document.getElementById('overlay_subscribe_link').addEventListener('click', async () => { 244 if ( paywallSettings.authenticator == 'onecount' ) { 245 246 window.location.href = '/subscribe'; 247 248 } else { 249 250 251 document.getElementById('overlay_login_prompt').style.display = 'none'; 252 document.getElementById('overlay_subscribe_iframe').style.display = ''; 253 254 document.getElementById('account_login').style.display = ''; 255 document.getElementById('account_subscribe').style.display = 'none'; 256 257 } 258 }); 259 260 261 262 /* handle login */ 263 document.getElementById('paywall-login').addEventListener('click', async () => { 264 const email = document.getElementById('paywall-email').value; 265 const password = document.getElementById('paywall-password').value; 266 const errorDiv = document.getElementById('paywall-error'); 267 268 if (!email || !password) { 269 errorDiv.style.display = 'block'; 270 errorDiv.textContent = 'Please enter both email and password.'; 271 return; 272 } 273 274 const spinner = document.getElementById('paywall-login').querySelector('i'); 275 const btnText = document.getElementById('paywall-login').querySelector('.btn-text'); 276 spinner.style.display = 'inline-block'; 277 btnText.style.display = 'none'; 278 document.getElementById('paywall-login').disabled = true; 279 280 try { 281 const response = await fetch(paywallSettings.pluginPath + 'api-auth.php', { 282 method: 'POST', 283 headers: { 284 'Content-Type': 'application/json', 285 }, 286 body: JSON.stringify({ 287 email, 288 password, 289 domain: window.location.hostname //'www.altoonamirror.com' 290 }) 291 }); 292 const data = await response.json(); 293 294 295 if (data.user && data.user.success) { 296 /* store the session */ 297 localStorage.setItem('paywallSession', JSON.stringify({ timestamp: new Date().getTime(), name:data.user.userAttributes.given_name })); 298 localStorage.removeItem('articleCount'); 299 //console.log('Session Created:', localStorage.getItem('paywallSession')); 300 document.body.removeChild(overlay); 301 document.body.style.overflow = 'auto'; 302 window.location.reload(); 303 } else { 304 errorDiv.style.display = 'block'; 305 errorDiv.textContent = data.message || 'Invalid credentials.'; 306 spinner.style.display = 'none'; 307 btnText.style.display = ''; 308 document.getElementById('paywall-login').disabled = false; 309 } 310 } catch (error) { 311 //console.log(error); 312 errorDiv.style.display = 'block'; 313 errorDiv.textContent = error; 314 } 315 }); 316 317 318 const passwordInput = document.getElementById('paywall-password'); 319 const toggleButton = document.getElementById('toggle-password'); 320 const toggleIcon = toggleButton.querySelector('i'); 321 toggleButton.addEventListener('click', () => { 322 const isPasswordVisible = passwordInput.type === 'text'; 323 passwordInput.type = isPasswordVisible ? 'password' : 'text'; 324 toggleIcon.className = isPasswordVisible ? 'fas fa-eye' : 'fas fa-eye-slash'; 325 }); 326 }; 327 328 /* trigger paywall if needed */ 329 if (shouldShowPaywall()) { 330 //console.log('Paywall triggered.'); 331 /* if this paywall is still being used with ONECount - make the default VIEW on the overlay the LOGIN box */ 332 if ( paywallSettings.authenticator == 'onecount' ) { 333 showPaywall('login'); 334 } else { 335 showPaywall(); 336 } 337 } 338});
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.