1(function () { 2 const isPostbag = window.location.pathname.indexOf("/opinion/postbag") !== -1; 3 4 5 function getCookie(name) { 6 const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); 7 if (match) return match[2]; 8 try { 9 const rawLocal = localStorage.getItem(name); 10 if (rawLocal) { 11 // 1. Check if item has JSON expiration wrapper 12 if (rawLocal.charAt(0) === '{' && rawLocal.charAt(rawLocal.length - 1) === '}') { 13 try { 14 const parsed = JSON.parse(rawLocal); 15 if (parsed && typeof parsed.expires === 'number') { 16 if (Date.now() > parsed.expires) { 17 localStorage.removeItem(name); 18 return null; 19 } 20 return parsed.value; 21 } 22 } catch (jsonErr) { } 23 } 24 // 2. Check if item is a JWT token with an internal exp claim 25 const parts = rawLocal.split('.'); 26 if (parts.length === 3) { 27 try { 28 let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); 29 while (b64.length % 4) b64 += '='; 30 const payload = JSON.parse(atob(b64)); 31 if (payload && payload.exp && (payload.exp * 1000) < Date.now()) { 32 localStorage.removeItem(name); 33 return null; 34 } 35 } catch (jwtErr) { } 36 } 37 return rawLocal; 38 } 39 40 const rawSession = sessionStorage.getItem(name); 41 if (rawSession) return rawSession; 42 } catch (e) { 43 return null; 44 } 45 return null; 46 } 47 48 function setCookie(name, value, ms) { 49 const d = new Date(); 50 const ttl = ms || (1 * 60 * 60 * 1000); 51 const expiresTime = d.getTime() + ttl; 52 d.setTime(expiresTime); 53 document.cookie = name + "=" + value + ";path=/;SameSite=Lax;expires=" + d.toUTCString(); 54 try { 55 const itemObj = { 56 value: value, 57 expires: expiresTime 58 }; 59 localStorage.setItem(name, JSON.stringify(itemObj)); 60 sessionStorage.setItem(name, value); 61 } catch (e) { } 62 } 63 64 function isLoggedIn() { 65 const hasCookie = !!getCookie(window._m_c || "__bwp"); 66 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 67 const hasActiveSub = dgsMetaUser && dgsMetaUser.content === 'enable'; 68 return hasCookie || hasActiveSub; 69 } 70 71 function logPaywallView(type, action, variant, variantName, customParams) { 72 if (!action) { 73 action = 'paywall_impression'; 74 } 75 customParams = customParams || {}; 76 77 const isPostbag = window.location.pathname.indexOf("/opinion/postbag") !== -1; 78 const current_section = (typeof customParams.section_name !== 'undefined' && customParams.section_name !== null) 79 ? customParams.section_name 80 : ((typeof g_section_name !== 'undefined' && g_section_name) ? g_section_name : ""); 81 82 const isSubLanding = current_section === 'subscription' || current_section === 'digital-subscription' || current_section === 'subscriptions' || current_section === 'digital-subscriptions'; 83 84 let log_variant = variant; 85 if (isSubLanding) { 86 log_variant = ""; 87 } else if (typeof log_variant === 'undefined' || log_variant === null || log_variant === '') { 88 log_variant = window.DGS_PAYWALL_VARIANT || ''; 89 } 90 91 let log_variant_name = variantName; 92 if (isSubLanding) { 93 log_variant_name = ""; 94 } else if (typeof log_variant_name === 'undefined' || log_variant_name === null || log_variant_name === '') { 95 log_variant_name = window.DGS_PAYWALL_VARIANT_NAME || ''; 96 } 97 if (!isSubLanding && log_variant && !log_variant_name && window.DGS_PAYWALL_WORDINGS_ALL && window.DGS_PAYWALL_WORDINGS_ALL[log_variant]) { 98 const vObj = window.DGS_PAYWALL_WORDINGS_ALL[log_variant]; 99 log_variant_name = vObj['variant_name'] || ''; 100 } 101 102 let dgsBase = "/v3/"; 103 let log_type = isPostbag ? 'postbag' : type; 104 let log_content_id = isPostbag ? "" : ((typeof customParams.content_id !== 'undefined' && customParams.content_id !== null) 105 ? customParams.content_id 106 : ((typeof g_content_id !== 'undefined' && g_content_id) ? g_content_id : "")); 107 108 if (current_section === 'topic_main') { 109 log_type = 'topic_main'; 110 } else if (current_section === 'topic_content') { 111 log_type = 'topic_content'; 112 } 113 114 let log_topic_id = (typeof customParams.topic_id !== 'undefined' && customParams.topic_id !== null) 115 ? customParams.topic_id 116 : ((typeof g_topic_id !== 'undefined' && g_topic_id) ? g_topic_id : ""); 117 118 if (current_section === 'topic_content' && log_topic_id) { 119 log_content_id = log_topic_id; 120 } 121 122 let log_category_id = (typeof customParams.category_id !== 'undefined' && customParams.category_id !== null) 123 ? customParams.category_id 124 : ((typeof g_category_id !== 'undefined' && g_category_id) ? g_category_id : ""); 125 126 const logUrl = dgsBase + "api/log-action-paywall"; 127 const data = { 128 type: log_type, 129 action: action, 130 content_id: log_content_id, 131 section_name: current_section, 132 category_id: log_category_id, 133 variant: log_variant || "", 134 variant_name: log_variant_name || "" 135 }; 136 137 const params = new URLSearchParams(data); 138 139 // 1. ลà¸à¸à¹à¸à¹ navigator.sendBeacon สำหรัà¸à¸à¸²à¸£à¸à¸ CTA หรืà¸à¹à¸à¸¥à¸µà¹à¸¢à¸à¸«à¸à¹à¸² à¹à¸à¸·à¹à¸à¸à¹à¸à¸à¸à¸±à¸ Request à¹à¸à¸ Abort à¹à¸¡à¸·à¹à¸à¹à¸à¸£à¸²à¸§à¹à¹à¸à¸à¸£à¹ Unload/Redirect 140 if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') { 141 try { 142 const blob = new Blob([params.toString()], { type: 'application/x-www-form-urlencoded' }); 143 const sent = navigator.sendBeacon(logUrl, blob); 144 if (sent) { 145 console.log("Paywall action logged via sendBeacon:", action, data); 146 return; 147 } 148 } catch (beaconErr) { 149 console.warn("sendBeacon error, falling back to fetch/ajax:", beaconErr); 150 } 151 } 152 153 // 2. à¹à¸à¹ fetch à¸à¸£à¹à¸à¸¡ keepalive: true (à¸à¸³à¸à¸²à¸à¹à¸à¹à¸à¹à¸à¹à¸à¸·à¹à¸à¸à¹à¸¡à¹à¹à¸à¸à¸à¸³à¸¥à¸±à¸à¸à¸¹à¸ Unload/Redirect) 154 if (typeof fetch === 'function') { 155 fetch(logUrl, { 156 method: "POST", 157 headers: { 158 "Content-Type": "application/x-www-form-urlencoded" 159 }, 160 body: params, 161 keepalive: true 162 }) 163 .then(function (res) { return res.json(); }) 164 .then(function (res) { 165 console.log("Paywall action logged successfully via fetch:", res); 166 }) 167 .catch(function (err) { 168 console.error("Failed to log paywall view via fetch:", err); 169 }); 170 return; 171 } 172 173 // 3. Fallback สำหรัà¸à¹à¸à¸£à¸²à¸§à¹à¹à¸à¸à¸£à¹à¹à¸à¹à¸²à¸¡à¸²à¸à¸à¸µà¹à¹à¸¡à¹à¸¡à¸µ fetch/sendBeacon 174 if (typeof $ !== 'undefined' && $.ajax) { 175 $.ajax({ 176 url: logUrl, 177 method: "POST", 178 data: data, 179 dataType: "json", 180 success: function (res) { 181 console.log("Paywall view logged successfully via jQuery:", res); 182 }, 183 error: function (err) { 184 console.error("Failed to log paywall view via jQuery:", err); 185 } 186 }); 187 } 188 } 189 window.logPaywallView = logPaywallView; 190 191 function logPaywallLockDiagnostic(triggerSource) { 192 try { 193 const pageKey = 'dgs_diag_logged_' + window.location.pathname; 194 if (sessionStorage.getItem(pageKey)) { 195 return; 196 } 197 sessionStorage.setItem(pageKey, '1'); 198 199 const cookieName = window._p_c || "__bwp_pw"; 200 const loginCookieName = window._m_c || "__bwp"; 201
202 // 1. à¸à¸£à¸§à¸à¸ªà¸à¸à¸à¸¸à¸à¸à¸µà¹ Login (__bwp) 203 const matchLogin = document.cookie.match(new RegExp('(^| )' + loginCookieName + '=([^;]+)')); 204 const hasLoginCookie = !!matchLogin; 205 let loggedInUserId = null; 206 if (hasLoginCookie) { 207 try { 208 const loginRaw = decodeURIComponent(matchLogin[2]); 209 const uidMatch = loginRaw.match(/userID["\s:;]+([0-9]+)/i) || loginRaw.match(/"id"[:\s]+([0-9]+)/i); 210 if (uidMatch) loggedInUserId = uidMatch[1]; 211 } catch (e) { } 212 } 213 214 // 2. à¸à¸£à¸§à¸à¸ªà¸à¸à¸à¸¸à¸à¸à¸µà¹à¸ªà¸à¸²à¸à¸°à¸ªà¸¡à¸²à¸à¸´à¸ (_bp_pdgs หรืภ__bwp_pw) 215 const subCookie = getCookie(window._s_c || "_bp_pdgs"); 216 const hasSubCookie = (subCookie === "1"); 217 const matchPw = document.cookie.match(new RegExp('(^| )' + cookieName + '=([^;]+)')); 218 const hasPwCookie = !!matchPw; 219 let pwPayload = null; 220 let isPwExpired = false; 221 if (hasPwCookie) { 222 try { 223 const parts = matchPw[2].split('.'); 224 if (parts.length === 3) { 225 let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); 226 while (b64.length % 4) b64 += '='; 227 pwPayload = JSON.parse(atob(b64)); 228 if (pwPayload && pwPayload.exp) { 229 isPwExpired = (pwPayload.exp * 1000) < Date.now(); 230 } 231 } 232 } catch (e) { } 233 } 234 235 // 3. à¸à¸£à¸§à¸à¸ªà¸à¸ LocalStorage Backup (à¸à¹à¸²à¸¡à¸µà¸à¹à¸²à¸à¸à¸¢à¸¹à¹) 236 let lsPayload = null; 237 let hasLs = false; 238 let isLsExpired = false; 239 try { 240 const lsToken = localStorage.getItem(cookieName); 241 if (lsToken) { 242 hasLs = true; 243 const parts = lsToken.split('.'); 244 if (parts.length === 3) { 245 let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); 246 while (b64.length % 4) b64 += '='; 247 lsPayload = JSON.parse(atob(b64)); 248 if (lsPayload && lsPayload.exp) { 249 isLsExpired = (lsPayload.exp * 1000) < Date.now(); 250 } 251 } 252 } 253 } catch (e) { } 254 255 // à¸à¹à¸à¸ (1) Login à¸à¸¢à¸¹à¹ à¹à¸¥à¸° (2) มี Cookie สิà¸à¸à¸´à¹ (__bwp_sub หรืภ__bwp_pw) 256 if (!hasLoginCookie || (!hasSubCookie && !hasPwCookie)) { 257 return; 258 } 259 260 // 4. à¸à¸£à¸§à¸à¸ªà¸à¸ Meta Tags à¸à¸²à¸ Server / CDN 261 const dgsMetaContent = document.querySelector('meta[name="dgs-content"]'); 262 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 263 const metaContent = dgsMetaContent ? dgsMetaContent.content : null; 264 const metaUser = dgsMetaUser ? dgsMetaUser.content : null; 265 266 // 5. วิà¹à¸à¸£à¸²à¸°à¸«à¹à¹à¸«à¸à¸¸à¸à¸¥à¸§à¹à¸²à¸à¸³à¹à¸¡à¸¡à¸µà¸ªà¸´à¸à¸à¸´à¹à¹à¸¥à¹à¸§à¸¢à¸±à¸à¸à¸´à¸à¸¥à¹à¸à¸ 267 let lockReason = 'UNKNOWN_LOCK'; 268 if (isPwExpired || isLsExpired) { 269 lockReason = 'EXPIRED_TOKEN (Token à¹à¸ Cookie หรืภLocalStorage หมà¸à¸à¸²à¸¢à¸¸à¹à¸¥à¹à¸§)'; 270 } else if (pwPayload && pwPayload.pw === 0 && pwPayload.sub === 0) { 271 lockReason = 'TOKEN_PW_ZERO (มี Token à¹à¸à¹à¸ªà¸à¸²à¸à¸° pw=0 à¹à¸¥à¸° sub=0 à¹à¸¡à¹à¹à¸à¹ Subscriber)'; 272 } else if (loggedInUserId && pwPayload && pwPayload.uid && String(loggedInUserId) !== String(pwPayload.uid)) { 273 lockReason = 'UID_MISMATCH (User ID à¸à¸µà¹ Login à¹à¸¡à¹à¸à¸£à¸à¸à¸±à¸ UID à¹à¸ Token)'; 274 } else if (metaUser === 'disable') { 275 lockReason = 'CDN_CACHE_MISMATCH (มี Login, มี Cookie สมาà¸à¸´à¸à¸à¸£à¸ à¹à¸à¹ CDN สà¹à¸à¸«à¸à¹à¸²à¹à¸à¸ disable มา)'; 276 } else { 277 lockReason = 'ALL_TOKENS_VALID_BUT_PAYWALL_TRIGGERED (à¸à¹à¸à¸¡à¸¹à¸¥à¸à¸£à¸à¸à¹à¸§à¸à¹à¸à¹à¸à¸´à¸à¸¥à¹à¸à¸)'; 278 } 279 280 const diagPayload = { 281 trigger_source: triggerSource || 'unknown', 282 lock_reason: lockReason, 283 user_id: loggedInUserId || (pwPayload ? pwPayload.uid : null) || (lsPayload ? lsPayload.uid : null) || 'GUEST', 284 has_login_cookie: hasLoginCookie, 285 has_pw_cookie: hasPwCookie,
286 has_sub_cookie: hasSubCookie, 287 cookie_pw: pwPayload, 288 is_pw_cookie_expired: isPwExpired, 289 has_localstorage_pw: hasLs, 290 localstorage_pw: lsPayload, 291 is_ls_expired: isLsExpired, 292 meta_dgs_content: metaContent, 293 meta_dgs_user: metaUser, 294 page_url: window.location.href, 295 referrer: document.referrer || '', 296 timestamp: new Date().toISOString() 297 }; 298 299 const logEndpoint = "/v3/api/log-paywall-diagnostic"; 300 const bodyStr = JSON.stringify(diagPayload); 301 302 if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') { 303 const blob = new Blob([bodyStr], { type: 'application/json' }); 304 navigator.sendBeacon(logEndpoint, blob); 305 } else if (typeof fetch === 'function') { 306 fetch(logEndpoint, { 307 method: 'POST', 308 headers: { 'Content-Type': 'application/json' }, 309 body: bodyStr, 310 keepalive: true 311 }).catch(function () { }); 312 } 313 } catch (err) { 314 console.warn("[Paywall] logPaywallLockDiagnostic error:", err); 315 } 316 } 317 318 function initPaywallScrollObserver() { 319 // à¸à¹à¸à¸«à¸² Element à¸à¸à¸à¹à¸à¸ Paywall หรืà¸à¸à¸·à¹à¸à¸à¸µà¹à¸à¸µà¹à¹à¸à¸à¹à¸à¸¥à¸ (.sticky-blurred-paywall สำหรัภLife, .force_login--popup สำหรัภNews) 320 const paywallEl = document.querySelector('.sticky-blurred-paywall, .force_login--popup, .paywall-locked-body'); 321 if (!paywallEl) { 322 return; 323 } 324 325 // à¹à¸à¹ Intersection Observer API สำหรัà¸à¸à¸±à¸à¸à¸§à¸²à¸¡à¹à¸à¸¥à¸·à¹à¸à¸à¹à¸«à¸§à¹à¸¡à¸·à¹à¸à¹à¸¥à¸·à¹à¸à¸à¸à¸à¸¡à¸²à¹à¸à¸ Element 326 if (typeof IntersectionObserver !== 'undefined') { 327 const observer = new IntersectionObserver((entries, obs) => { 328 entries.forEach(entry => { 329 if (entry.isIntersecting) { 330 console.log("Paywall popup encountered: User scrolled down and saw the paywall."); 331 logPaywallView("article"); 332 logPaywallLockDiagnostic("scroll_blurred_article"); 333 obs.disconnect(); // สัà¹à¸à¸«à¸¢à¸¸à¸à¸à¸±à¸à¸à¸§à¸²à¸¡à¹à¸à¸¥à¸·à¹à¸à¸à¹à¸«à¸§à¸«à¸¥à¸±à¸à¸à¸²à¸à¸à¸±à¸à¸à¸¶à¸ Log สำà¹à¸£à¹à¸à¸à¸£à¸±à¹à¸à¹à¸£à¸ 334 } 335 }); 336 }, { 337 threshold: 0.1 // à¸à¸³à¸à¸²à¸à¹à¸¡à¸·à¹à¸ Element à¹à¸à¸¥à¹à¸à¸¶à¹à¸à¸¡à¸²à¹à¸à¸à¸à¸à¸¢à¹à¸²à¸à¸à¹à¸à¸¢ 10% 338 }); 339 observer.observe(paywallEl); 340 } else { 341 // ระà¸à¸à¸ªà¸³à¸£à¸à¸à¸ªà¸³à¸«à¸£à¸±à¸à¸à¸£à¸²à¸§à¹à¸à¸à¸£à¹à¸£à¸¸à¹à¸à¹à¸à¹à¸² (à¸à¸¹à¸ Event Scroll) 342 const onScroll = function () { 343 const rect = paywallEl.getBoundingClientRect(); 344 const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight); 345 if (rect.top >= 0 && rect.top <= viewHeight) { 346 console.log("Paywall popup encountered (fallback): User scrolled down and saw the paywall."); 347 logPaywallView("article"); 348 logPaywallLockDiagnostic("scroll_blurred_article_fallback"); 349 window.removeEventListener('scroll', onScroll); 350 } 351 }; 352 window.addEventListener('scroll', onScroll); 353 } 354 } 355 356 function initPopupTrigger() { 357 // Do not run paywall popup trigger on digital subscription pages 358 if (window.location.pathname.indexOf("/digital-subscription") !== -1) { 359 return; 360 } 361 362 if (window.location.pathname.indexOf("/subscriptions") !== -1) { 363 return; 364 } 365 366 // Do not run paywall popup trigger on premium publications (ebook) pages 367 if (window.location.pathname.indexOf("/premium-publications") !== -1) { 368 return; 369 } 370 371 // หà¸à¹à¸² Postbag: à¹à¸à¹à¹à¸à¸à¸²à¸° Lock Bar Paywall à¹à¸à¸«à¸à¹à¸²à¹à¸à¸·à¹à¸à¸«à¸² (à¹à¸¡à¹à¹à¸ªà¸à¸ Popup Modal) 372 if (isPostbag) { 373 initPaywallScrollObserver(); 374 return; 375 } 376 377 // à¸à¹à¸²à¸à¸à¹à¸²à¸ªà¸à¸²à¸à¸° Paywall à¹à¸¥à¸°à¸ªà¸´à¸à¸à¸´à¹à¸à¸²à¸£à¹à¸à¹à¸à¸²à¸à¸à¸£à¸à¸à¸²à¸ Meta Tags à¸à¸µà¹à¸ªà¹à¸à¸¡à¸²à¸à¸²à¸ Server 378 const dgsMetaArticle = document.querySelector('meta[name="dgs-content"]'); 379 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 380 381 const isContentLocked = dgsMetaArticle && dgsMetaArticle.content === 'enable'; 382 const isUserDisabled = dgsMetaUser && dgsMetaUser.content === 'disable'; 383 384 // à¸à¸±à¸à¸à¸²à¸£à¹à¸ªà¸à¸à¸à¸¥à¸à¸²à¸¡à¹à¸à¸·à¹à¸à¸à¹à¸à¸à¸à¸à¸à¸£à¸°à¹à¸ à¸à¸«à¸à¹à¸²à¸à¸ (ยà¸à¹à¸¥à¸´à¸ Section Popup à¹à¸¥à¸° Popup à¸à¹à¸²à¸§ < 3 à¹à¸à¸·à¸à¸) 385 if (isUserDisabled) { 386 logPaywallLockDiagnostic("page_load_user_disabled"); 387 if (isContentLocked) { 388 if (typeof g_content_id !== 'undefined' && g_content_id) { 389 // หà¸à¹à¸²à¸à¹à¸²à¸§à¹à¸à¸µà¹à¸¢à¸§à¸à¸µà¹à¹à¸à¸à¸¥à¹à¸à¸ (Print / Online > 3 à¹à¸à¸·à¸à¸): รัà¸à¸à¸±à¸§à¸à¸£à¸§à¸à¸à¸±à¸à¸à¸²à¸£à¹à¸¥à¸·à¹à¸à¸à¸«à¸à¹à¸²à¸à¸ (Scroll Observer) 390 initPaywallScrollObserver(); 391 } 392 } 393 } 394 } 395 396 // à¸à¸´à¸à¸à¸²à¸£à¸à¸±à¸à¸à¸¶à¸ Log Action à¹à¸¥à¸°à¸à¸²à¸£ Save ลภCache (sessionStorage / localStorage) à¹à¸¡à¸·à¹à¸à¸à¸à¸à¸¸à¹à¸¡ Subscribe 397 398 document.addEventListener("click", function (e) { 399 const btnDefault = e.target.closest('.btn--default'); 400 const btnBuy = e.target.closest('.btn-buynow, #subscribe_btn, .welcome-btn a, a[href*="/digital-subscription/payment/"], a[href*="Digital_subscription_c/payment/"]'); 401 const btnModalLogin = e.target.closest('#signinModal .btnsignin, #signinModal .planlogin-desc a'); 402 403 const path = window.location.pathname; 404 const isDigitalSubPage = path.indexOf("/digital-subscription") !== -1; 405 const isSubPage = path.indexOf("/subscriptions") !== -1 || path.indexOf("/subscription") !== -1; 406 407 if (btnDefault || (btnBuy && (isDigitalSubPage || isSubPage)) || (btnModalLogin && (isDigitalSubPage || isSubPage)) || btnBuy) { 408 const isArticlePopup = btnDefault && btnDefault.closest('.force_login--popup'); 409 const isPopupLogin = btnDefault && btnDefault.closest('#popup-login'); 410 const isEbookPopup = (btnDefault && btnDefault.closest('#popupdgs')) || path.indexOf("/premium-publications") !== -1; 411 const isPostbagPage = isPostbag || path.indexOf("/opinion/postbag") !== -1; 412 413 let pageType = 'section'; 414 let clickContentId = (typeof g_content_id !== 'undefined' && g_content_id) ? g_content_id : ""; 415 let currentSection = (typeof g_section_name !== 'undefined' && g_section_name) ? g_section_name : ""; 416 417 let clickVariant = window.DGS_PAYWALL_VARIANT || ''; 418 419 if (isEbookPopup) { 420 pageType = 'ebook'; 421 currentSection = 'ebook'; 422 clickVariant = window.DGS_PAYWALL_VARIANT || ''; 423 logPaywallView("ebook", "paywall_cta_click", clickVariant); 424 } else if (isPostbagPage) { 425 pageType = 'postbag'; 426 currentSection = 'opinion'; 427 clickVariant = window.DGS_PAYWALL_VARIANT || ''; 428 logPaywallView("postbag", "paywall_cta_click", clickVariant); 429 } else if (isArticlePopup) { 430 pageType = 'article'; 431 clickVariant = window.DGS_PAYWALL_VARIANT || ''; 432 logPaywallView("article", "paywall_cta_click", clickVariant); 433 } else if (isPopupLogin) { 434 pageType = 'article'; 435 clickVariant = window.DGS_PAYWALL_VARIANT || ''; 436 logPaywallView("article", "paywall_cta_click", clickVariant); 437 } else if (isDigitalSubPage || isSubPage) { 438 pageType = 'section'; 439 currentSection = isDigitalSubPage ? 'digital-subscription' : 'subscription'; 440 clickVariant = ''; 441 logPaywallView("section", "paywall_cta_click", "", "", { section_name: currentSection }); 442 } else { 443 // Fallback check based on globally available variables 444 pageType = (typeof g_content_id !== 'undefined' && g_content_id) ? 'article' : 'section'; 445 clickVariant = window.DGS_PAYWALL_VARIANT || ''; 446 if (!currentSection) { 447 currentSection = (pageType === 'section') ? 'digital-subscription' : ''; 448 }
449 logPaywallView(pageType, "paywall_cta_click", clickVariant); 450 } 451 452 if (currentSection === 'topic_main') { 453 pageType = 'topic_main'; 454 } else if (currentSection === 'topic_content') { 455 pageType = 'topic_content'; 456 if (typeof g_topic_id !== 'undefined' && g_topic_id) { 457 clickContentId = g_topic_id; 458 } 459 } 460 461 if (pageType) { 462 const isSubLandingSection = currentSection === 'subscription' || currentSection === 'digital-subscription' || currentSection === 'subscriptions' || currentSection === 'digital-subscriptions'; 463 const finalVariant = isSubLandingSection ? '' : clickVariant; 464 465 let clickVariantName = ''; 466 if (!isSubLandingSection) { 467 clickVariantName = window.DGS_PAYWALL_VARIANT_NAME || ''; 468 if (!clickVariantName && window.DGS_PAYWALL_WORDINGS_ALL && window.DGS_PAYWALL_WORDINGS_ALL[clickVariant]) { 469 const vObj = window.DGS_PAYWALL_WORDINGS_ALL[clickVariant]; 470 clickVariantName = vObj['variant_name'] || ''; 471 } 472 } 473 474 sessionStorage.setItem('clicked_subscribe_paywall', 'true'); 475 sessionStorage.setItem('subscribe_9_9_type', pageType); 476 sessionStorage.setItem('subscribe_9_9_content_id', clickContentId); 477 sessionStorage.setItem('subscribe_9_9_section_name', currentSection); 478 sessionStorage.setItem('subscribe_9_9_category_id', (typeof g_category_id !== 'undefined' && g_category_id) ? g_category_id : ""); 479 sessionStorage.setItem('subscribe_9_9_variant', finalVariant); 480 sessionStorage.setItem('subscribe_9_9_variant_name', clickVariantName); 481 482 // Backup to localStorage in case of bank redirect opening in a new tab/session 483 localStorage.setItem('subscribe_9_9_type_backup', pageType); 484 localStorage.setItem('subscribe_9_9_content_id_backup', clickContentId); 485 localStorage.setItem('subscribe_9_9_section_name_backup', currentSection); 486 localStorage.setItem('subscribe_9_9_category_id_backup', (typeof g_category_id !== 'undefined' && g_category_id) ? g_category_id : ""); 487 localStorage.setItem('subscribe_9_9_variant_backup', finalVariant); 488 localStorage.setItem('subscribe_9_9_variant_name_backup', clickVariantName); 489 } 490 } 491 }); 492 493 494 function checkCheckoutStart() { 495 if (window.location.pathname.indexOf("/digital-subscription/payment/") !== -1) { 496 if (sessionStorage.getItem('clicked_subscribe_paywall') === 'true') { 497 sessionStorage.removeItem('clicked_subscribe_paywall'); 498 499 const pageType = sessionStorage.getItem('subscribe_9_9_type') || localStorage.getItem('subscribe_9_9_type_backup') || 'section'; 500 const contentId = sessionStorage.getItem('subscribe_9_9_content_id') || localStorage.getItem('subscribe_9_9_content_id_backup'); 501 const sectionName = sessionStorage.getItem('subscribe_9_9_section_name') || localStorage.getItem('subscribe_9_9_section_name_backup') || 'digital-subscription'; 502 const categoryId = sessionStorage.getItem('subscribe_9_9_category_id') || localStorage.getItem('subscribe_9_9_category_id_backup'); 503 504 const isSubLandingSection = sectionName === 'subscription' || sectionName === 'digital-subscription' || sectionName === 'subscriptions' || sectionName === 'digital-subscriptions'; 505 const variant = isSubLandingSection ? '' : (sessionStorage.getItem('subscribe_9_9_variant') || localStorage.getItem('subscribe_9_9_variant_backup') || ''); 506 const variantName = isSubLandingSection ? '' : (sessionStorage.getItem('subscribe_9_9_variant_name') || localStorage.getItem('subscribe_9_9_variant_name_backup') || ''); 507 508 logPaywallView(pageType, 'checkout_start', variant, variantName, { 509 content_id: contentId, 510 section_name: sectionName, 511 category_id: categoryId, 512 topic_id: pageType === 'topic_content' ? contentId : null 513 }); 514 console.log("Logged checkout_start action for section: " + sectionName); 515 } 516 } 517 } 518 519 function checkPurchaseComplete() { 520 if (window.location.pathname.indexOf("/digital-subscription/payment/success/") !== -1) {
521 const urlParams = new URLSearchParams(window.location.search); 522 const ref = urlParams.get('Ref'); 523 if (ref) { 524 const sessionKey = 'purchase_complete_logged_' + ref; 525 if (sessionStorage.getItem(sessionKey) !== 'true' && localStorage.getItem(sessionKey) !== 'true') { 526 // Set immediately to prevent duplicate async trigger 527 sessionStorage.setItem(sessionKey, 'true'); 528 localStorage.setItem(sessionKey, 'true'); 529 530 const pageType = sessionStorage.getItem('subscribe_9_9_type') || localStorage.getItem('subscribe_9_9_type_backup') || 'section'; 531 const contentId = sessionStorage.getItem('subscribe_9_9_content_id') || localStorage.getItem('subscribe_9_9_content_id_backup'); 532 const sectionName = sessionStorage.getItem('subscribe_9_9_section_name') || localStorage.getItem('subscribe_9_9_section_name_backup') || 'digital-subscription'; 533 const categoryId = sessionStorage.getItem('subscribe_9_9_category_id') || localStorage.getItem('subscribe_9_9_category_id_backup'); 534 535 const isSubLandingSection = sectionName === 'subscription' || sectionName === 'digital-subscription' || sectionName === 'subscriptions' || sectionName === 'digital-subscriptions'; 536 const variant = isSubLandingSection ? '' : (sessionStorage.getItem('subscribe_9_9_variant') || localStorage.getItem('subscribe_9_9_variant_backup') || ''); 537 const variantName = isSubLandingSection ? '' : (sessionStorage.getItem('subscribe_9_9_variant_name') || localStorage.getItem('subscribe_9_9_variant_name_backup') || ''); 538 539 logPaywallView(pageType, 'purchase_complete', variant, variantName, { 540 content_id: contentId, 541 section_name: sectionName, 542 category_id: categoryId, 543 topic_id: pageType === 'topic_content' ? contentId : null 544 }); 545 console.log("Logged purchase_complete action with Ref: " + ref + " for section: " + sectionName); 546 547 // Clear subscription flow context from sessionStorage 548 sessionStorage.removeItem('subscribe_9_9_type'); 549 sessionStorage.removeItem('subscribe_9_9_content_id'); 550 sessionStorage.removeItem('subscribe_9_9_section_name'); 551 sessionStorage.removeItem('subscribe_9_9_category_id'); 552 sessionStorage.removeItem('pw_free_checked'); 553 sessionStorage.removeItem('subscribe_9_9_variant'); 554 sessionStorage.removeItem('subscribe_9_9_variant_name'); 555 556 // Clear backup from localStorage 557 localStorage.removeItem('subscribe_9_9_type_backup'); 558 localStorage.removeItem('subscribe_9_9_content_id_backup'); 559 localStorage.removeItem('subscribe_9_9_section_name_backup'); 560 localStorage.removeItem('subscribe_9_9_category_id_backup'); 561 localStorage.removeItem('subscribe_9_9_variant_backup'); 562 localStorage.removeItem('subscribe_9_9_variant_name_backup'); 563 } 564 } 565 } 566 } 567 568 function initSubscriptionModalLog() { 569 const isDigitalSub = window.location.pathname.indexOf("/digital-subscription") !== -1; 570 const isSub = window.location.pathname.indexOf("/subscriptions") !== -1 || window.location.pathname.indexOf("/subscription") !== -1; 571 572 if (!isDigitalSub && !isSub) { 573 return; 574 } 575 576 const sectionName = isDigitalSub ? "digital-subscription" : "subscription"; 577 const actionShow = isDigitalSub ? "digital-subscriptions_popup_signin" : "subscriptions_popup_signin"; 578 const actionLogin = isDigitalSub ? "digital-subscriptions_login" : "subscriptions_login_click"; 579 const actionClose = isDigitalSub ? "digital-subscriptions_popup_close" : "subscriptions_popup_close"; 580 581 let logged = false;
582 const handleModalShow = function () { 583 if (logged) return; 584 logged = true; 585 setTimeout(function () { logged = false; }, 1000); 586 587 logPaywallView("section", actionShow, null, null, { 588 content_id: "", 589 section_name: sectionName, 590 category_id: "null" 591 }); 592 }; 593 594 if (typeof $ !== 'undefined') { 595 $('#signinModal').on('show.bs.modal', handleModalShow); 596 } else { 597 const modalEl = document.getElementById('signinModal'); 598 if (modalEl) { 599 modalEl.addEventListener('show.bs.modal', handleModalShow); 600 } 601 } 602 603 const modalEl = document.getElementById('signinModal'); 604 if (modalEl) { 605 modalEl.addEventListener('click', function (e) { 606 const isSignIn = e.target.closest('.btnsignin'); 607 const isRegister = e.target.closest('.planlogin-desc a'); 608 const isClose = e.target.closest('.closex'); 609 610 if (isSignIn || isRegister) { 611 logPaywallView("section", actionLogin, null, null, { 612 content_id: "", 613 section_name: sectionName, 614 category_id: "null" 615 }); 616 } else if (isClose) { 617 logPaywallView("section", actionClose, null, null, { 618 content_id: "", 619 section_name: sectionName, 620 category_id: "null" 621 }); 622 } 623 }); 624 } 625 } 626 627 628 629 function initPaywallCopyProtection() { 630 // If developer cookie bpdgs_dev = 1 is set, bypass copy protection for testing 631 if (getCookie('bpdgs_dev') === '1') { 632 console.log("Paywall Copy Protection bypassed (bpdgs_dev = 1)"); 633 return; 634 } 635 636 const dgsMetaArticle = document.querySelector('meta[name="dgs-content"]'); 637 const isContentLocked = dgsMetaArticle && dgsMetaArticle.getAttribute('content') === 'enable'; 638 639 if (!isContentLocked) { 640 return; 641 } 642 643 // 1. Inject CSS to disable text selection on article content elements 644 const style = document.createElement('style'); 645 style.innerHTML = ` 646 .article-content, #article-content, .box-postbag--user { 647 -webkit-user-select: none !important; 648 -moz-user-select: none !important; 649 -ms-user-select: none !important; 650 user-select: none !important; 651 } 652 `; 653 document.head.appendChild(style); 654 655 // 2. Attach event listeners to prevent copy, cut, right-click context menu, and dragging 656 const targetElements = document.querySelectorAll('#article-content, .article-content, .box-postbag--user'); 657 targetElements.forEach(function (el) { 658 el.addEventListener('copy', function (e) { 659 e.preventDefault(); 660 return false; 661 }); 662 el.addEventListener('cut', function (e) { 663 e.preventDefault(); 664 return false; 665 }); 666 el.addEventListener('contextmenu', function (e) { 667 e.preventDefault(); 668 return false; 669 }); 670 el.addEventListener('dragstart', function (e) { 671 e.preventDefault(); 672 return false; 673 }); 674 }); 675 676 // 3. Prevent keyboard copy/select shortcuts (Ctrl+C, Cmd+C, Ctrl+A, Cmd+A) when focused/selected inside article 677 document.addEventListener('keydown', function (e) { 678 if ((e.ctrlKey || e.metaKey) && (e.key === 'c' || e.key === 'C' || e.key === 'a' || e.key === 'A')) { 679 const selection = window.getSelection(); 680 if (selection && selection.rangeCount > 0) { 681 let container = selection.getRangeAt(0).commonAncestorContainer; 682 if (container.nodeType === 3) container = container.parentNode; 683 if (container && container.closest && container.closest('#article-content, .article-content, .box-postbag--user')) { 684 e.preventDefault(); 685 return false;
686 } 687 } 688 } 689 }); 690 } 691 692 function hasActiveSubscriptionFromPaywallCookie() { 693 try { 694 // 1. à¸à¸£à¸§à¸à¸ªà¸à¸à¸à¸²à¸à¸à¸¸à¸à¸à¸µà¹à¸ªà¸à¸²à¸à¸°à¸«à¸à¹à¸²à¸à¹à¸²à¸ _bp_pdgs (à¸à¸¥à¸à¸à¸ ัย 100% à¸à¸²à¸¡à¸¡à¸²à¸à¸£à¸à¸²à¸ Dual-Cookie) 695 const subCookie = getCookie(window._s_c || "_bp_pdgs"); 696 if (subCookie === "1") { 697 return true; 698 } 699 700 // Fallback à¹à¸à¸·à¹à¸à¸ªà¸ าà¸à¹à¸§à¸à¸¥à¹à¸à¸¡ dev à¸à¸µà¹à¸à¸¸à¸à¸à¸µà¹ __bwp_pw ยัà¸à¸à¹à¸²à¸à¹à¸à¹à¸à¸²à¸ JS 701 const rawCookie = getCookie(window._p_c || "__bwp_pw"); 702 if (rawCookie) { 703 const parts = rawCookie.split('.'); 704 if (parts.length === 3) { 705 let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); 706 while (b64.length % 4) b64 += '='; 707 const payload = JSON.parse(atob(b64)); 708 if (payload && (payload.pw === 1 || payload.sub === 1)) { 709 if (!payload.exp || (payload.exp * 1000) > Date.now()) { 710 return true; 711 } 712 } 713 } 714 } 715 716 // 2. à¸à¸£à¸§à¸à¸ªà¸à¸à¸à¸²à¸ meta tag dgs-user 717 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 718 if (dgsMetaUser && dgsMetaUser.content === 'enable') { 719 return true; 720 } 721 722 return false; 723 } catch (e) { 724 return false; 725 } 726 } 727 728 function checkCdnSubscriberCacheMismatch() { 729 const isSubscriber = hasActiveSubscriptionFromPaywallCookie(); 730 const dgsMetaArticle = document.querySelector('meta[name="dgs-content"]'); 731 const isContentLocked = dgsMetaArticle && dgsMetaArticle.content === 'enable'; 732 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 733 const isUserDisabled = dgsMetaUser && dgsMetaUser.content === 'disable'; 734 const pageKey = 'cdn_bypass_' + window.location.pathname; 735 736 // à¸à¹à¸²à¸à¸¹à¹à¹à¸à¹à¹à¸à¹à¸à¸ªà¸¡à¸²à¸à¸´à¸à¸à¸²à¸ cookie _bp_pdgs หรืภ__bwp_pw à¹à¸à¹à¸«à¸à¹à¸²à¹à¸§à¹à¸à¸à¸µà¹à¹à¸à¹à¸à¸²à¸ CDN à¹à¸à¹à¸à¸«à¸à¹à¸²à¸à¸´à¸à¸¥à¹à¸à¸à¸à¸à¸à¸à¸¹à¹à¹à¸à¹à¸à¸±à¹à¸§à¹à¸ 737 if (isSubscriber && isContentLocked && isUserDisabled) { 738 if (!sessionStorage.getItem(pageKey)) { 739 sessionStorage.setItem(pageKey, '1'); 740 console.warn("CDN Subscriber Cache Mismatch detected Reloading to fetch live content from origin..."); 741 742 window.location.reload(); 743 return true; 744 } 745 } else if (dgsMetaUser && dgsMetaUser.content === 'enable') { 746 sessionStorage.removeItem(pageKey); 747 } 748 return false; 749 } 750 751 /** 752 * à¸à¸¹à¹à¸à¸·à¸à¸ªà¸´à¸à¸à¸´à¹à¸ªà¸¡à¸²à¸à¸´à¸à¸à¹à¸²à¸ Single Source of Truth (/member/get_member_login) 753 * à¹à¸¡à¹à¸¢à¸´à¸ /api/refresh-paywall-cookie à¸à¹à¸³à¸à¹à¸à¸ à¹à¸à¹à¸à¸±à¸à¸à¸±à¸à¸à¸¥à¸à¸²à¸ g_member à¹à¸ Header 754 * หาà¸à¸à¸à¸§à¹à¸²à¹à¸à¹à¸à¸ªà¸¡à¸²à¸à¸´à¸ (is_subscriber: true) à¹à¸à¹à¸«à¸à¹à¸²à¹à¸§à¹à¸à¸à¸±à¸à¸à¸¸à¸à¸±à¸à¸à¸´à¸à¹à¸à¸ Inox CDN หà¸à¹à¸²à¸¥à¹à¸à¸ -> สัà¹à¸ Reload à¹à¸à¸·à¹à¸ Bypass CDN 755 */ 756 function checkAndRecoverPaywallCookie() { 757 const loginCookieName = window.BKP_COOKIE_MEMBER || "__bwp"; 758 const hasLoginCookie = document.cookie.indexOf(loginCookieName + '=') !== -1; 759 const subCookie = getCookie(window._s_c || "_bp_pdgs"); 760 const hasSubCookie = (subCookie === "1"); 761 const pwCookieName = window._p_c || "__bwp_pw"; 762 const hasPwCookie = document.cookie.indexOf(pwCookieName + '=') !== -1; 763 764 // à¸à¹à¸²à¸¡à¸µà¸à¸¸à¸à¸à¸µà¹à¸ªà¸´à¸à¸à¸´à¹à¸à¸¢à¸¹à¹à¹à¸¥à¹à¸§ à¹à¸¡à¹à¸à¹à¸à¸à¸à¸³à¸à¸°à¹à¸£ 765 if (hasSubCookie || hasPwCookie) { 766 return false;
767 } 768 769 // à¸à¸£à¸§à¸à¸ªà¸à¸à¹à¸à¸à¸²à¸°à¹à¸¡à¸·à¹à¸à¸à¸¹à¹à¹à¸à¹à¹à¸à¹à¸²à¸ªà¸¹à¹à¸£à¸°à¸à¸à¸à¸¢à¸¹à¹ (มีà¸à¸¸à¸à¸à¸µà¹ Login) à¹à¸¥à¸°à¸«à¸à¹à¸²à¸à¸µà¹à¸à¸´à¸à¸¥à¹à¸à¸ 770 const dgsMetaArticle = document.querySelector('meta[name="dgs-content"]'); 771 const isContentLocked = dgsMetaArticle && dgsMetaArticle.content === 'enable'; 772 const dgsMetaUser = document.querySelector('meta[name="dgs-user"]'); 773 const isUserDisabled = !dgsMetaUser || dgsMetaUser.content === 'disable'; 774 775 if (hasLoginCookie && (isContentLocked || isUserDisabled)) { 776 const pageRecoveryKey = 'pw_recovery_' + window.location.pathname; 777 if (sessionStorage.getItem(pageRecoveryKey)) { 778 return false; 779 } 780 781 const triggerReloadIfSubscriber = function () { 782 const isSub = (window.g_member && window.g_member.is_subscriber) || hasActiveSubscriptionFromPaywallCookie(); 783 if (isSub) { 784 console.log("Paywall subscriber confirmed via get_member_login. Reloading to bypass CDN cache..."); 785 sessionStorage.setItem(pageRecoveryKey, '1'); 786 window.location.reload(); 787 } 788 }; 789 790 // à¸à¸¹à¸à¸à¸±à¸ g_member.get_member_login à¹à¸ Header (Single Source of Truth) à¹à¸à¸·à¹à¸à¹à¸¡à¹à¹à¸«à¹à¸¢à¸´à¸à¸à¹à¸³ 791 if (window.g_member && typeof window.g_member.get_member_login === 'function') { 792 window.g_member.get_member_login(function () { 793 triggerReloadIfSubscriber(); 794 }); 795 return true; 796 } 797 } 798 return false; 799 } 800 801 /** 802 * ลà¹à¸²à¸ Token à¸à¸à¸à¸à¸²à¸ localStorage à¹à¸à¸·à¹à¸à¸à¸§à¸²à¸¡à¸à¸¥à¸à¸à¸ ัยà¸à¸²à¸¡à¸¡à¸²à¸à¸£à¸à¸²à¸à¸ªà¸²à¸à¸¥ (Token à¸à¹à¸à¸à¸à¸¢à¸¹à¹à¹à¸ HttpOnly Cookie à¹à¸à¹à¸²à¸à¸±à¹à¸) 803 */ 804 function cleanupPaywallLocalStorage() { 805 try { 806 const cookieName = window._p_c || "__bwp_pw"; 807 if (localStorage.getItem(cookieName)) { 808 localStorage.removeItem(cookieName); 809 } 810 } catch (e) { 811 // silent fail 812 } 813 } 814 815 // Initialize trigger immediately on DOM ready without delay to prevent Flash of Content 816 function initDgsPaywall() { 817 // Clean up legacy _t parameter from URL bar if present to keep URL clean 818 if (window.location.search && window.location.search.indexOf('_t=') !== -1 && window.history && window.history.replaceState) { 819 const cleanSearch = window.location.search.replace(/([?&])_t=\d+(&|$)/, '$1').replace(/[?&]$/, ''); 820 const cleanUrl = window.location.pathname + cleanSearch + window.location.hash; 821 window.history.replaceState(null, document.title, cleanUrl); 822 } 823 824 cleanupPaywallLocalStorage(); 825 if (checkCdnSubscriberCacheMismatch()) { 826 return; 827 } 828 checkAndRecoverPaywallCookie(); 829 initPopupTrigger(); 830 initSubscriptionModalLog(); 831 checkCheckoutStart(); 832 checkPurchaseComplete(); 833 initPaywallCopyProtection(); 834 } 835 836 if (document.readyState === "complete" || document.readyState === "interactive") { 837 initDgsPaywall(); 838 } else { 839 document.addEventListener("DOMContentLoaded", initDgsPaywall); 840 } 841})();
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.