1/** FOXIZ_PERSONALIZE */ 2var FOXIZ_PERSONALIZE = (function (Module, $) { 3 'use strict'; 4 5 Module.initParams = function () { 6 7 this.yesStorage = this.isStorageAvailable(); 8 this.ajaxURL = typeof foxizCoreParams !== 'undefined' ? foxizCoreParams.ajaxurl || '' : ''; 9 this.syncTimeout = 0.5; //12 hours 10 this.personalizeUID = 11 (typeof FOXIZ_CORE_SCRIPT !== "undefined" && FOXIZ_CORE_SCRIPT.personalizeUID !== undefined) 12 ? FOXIZ_CORE_SCRIPT.personalizeUID 13 : 'u0'; 14 this._body = $('body'); 15 this.isProgress = false; 16 this.checkPersonalize(); 17 18 this.personalizePopup = $('#bookmark-notification'); 19 this.yesPopup = this.personalizePopup.length || false; 20 21 this.followPopupTemplate = $('#follow-notification-template').html(); 22 this.savedPopupTemplate = $('#bookmark-notification-template').html(); 23 24 if ('ask_login' === this.personalizeMode) { 25 this.bookmarkToggleTemplate = $('#bookmark-ask-login-template').html(); 26 this.followToggleTemplate = $('#follow-ask-login-template').html(); 27 } else { 28 this.bookmarkToggleTemplate = $('#bookmark-toggle-template').html(); 29 this.followToggleTemplate = $('#follow-toggle-template').html(); 30 } 31 } 32 33 Module.init = function () { 34 35 this.initParams(); 36 37 if (FOXIZ_CORE_SCRIPT.getCookie('personalize_sync') || this.syncInterval()) { 38 this.syncPersonalizeData(); 39 } else { 40 this.syncPersonalizeLayout(); 41 } 42 this.keepPersonalizePopup(); 43 this.readingListTemplate(); 44 this.bookmarkToggle(); 45 this.followCategoryToggle(); 46 this.followWriterToggle(); 47 } 48 49 Module.getSavedKey = function (id) { 50 return this.personalizeUID + '-saved-' + id; 51 } 52 53 Module.getCategoryFollowKey = function (id) { 54 return this.personalizeUID + '-cat-' + id; 55 } 56 57 Module.getWriterFollowKey = function (id) { 58 return this.personalizeUID + '-writer-' + id; 59 } 60 61 /** 62 * 63 * @returns {boolean} 64 */ 65 Module.isStorageAvailable = function () { 66 let storage; 67 try { 68 storage = window['localStorage']; 69 storage.setItem('__rbStorageSet', 'x'); 70 storage.removeItem('__rbStorageSet'); 71 return true; 72 } catch (e) { 73 return false; 74 } 75 } 76 77 /** 78 * set localStorage 79 * @param key 80 * @param data 81 */ 82 Module.setStorage = function (key, data) { 83 this.yesStorage && localStorage.setItem(key, typeof data === 'string' ? data : JSON.stringify(data)); 84 } 85 86 /** 87 * get localStorage 88 * @param key 89 * @param defaultValue 90 * @returns {any} 91 */ 92 Module.getStorage = function (key, defaultValue) { 93 if (!this.yesStorage) return null; 94 const data = localStorage.getItem(key); 95 if (data === null) return defaultValue; 96 try { 97 return JSON.parse(data); 98 } catch (e) { 99 return data; 100 } 101 } 102 103 /** 104 * delete localStorage 105 * @param key 106 */ 107 Module.deleteStorage = function (key) { 108 this.yesStorage && localStorage.removeItem(key); 109 } 110 111 /** Sync bookmarks for logged-in user across devices. */ 112 Module.syncInterval = function () { 113 114 const isLogged = FOXIZ_CORE_SCRIPT.getCookie('u_logged'); 115 const syncTimeout = !FOXIZ_CORE_SCRIPT.getCookie('syncTimeout'); 116 117 return isLogged && syncTimeout; 118 } 119 120 /** 121 * check checkPersonalize 122 */ 123 Module.checkPersonalize = function () { 124 this.personalizeMode = 'yes'; 125 let setting = 'all'; 126 const isLogged = FOXIZ_CORE_SCRIPT.getCookie('u_logged'); 127 if (this._body.hasClass('personalized-logged-only')) { 128 setting = 'logged'; 129 } else if (this._body.hasClass('personalized-ask-login')) { 130 setting = 'login'; 131 } 132 if (!isLogged) { 133 if ('login' === setting) { 134 this.personalizeMode = 'ask_login'; 135 } else if ('logged' === setting) { 136 this.personalizeMode = 'no'; 137 } 138 } 139 }; 140 141 /** saved a post */ 142 Module.bookmarkToggle = function () { 143 144 const self = this; 145 self._body.on('click', '.bookmark-trigger', function (e) { 146 147 e.preventDefault(); 148 e.stopPropagation(); 149 150 const target = $(this); 151 const pid = target.data('pid'); 152 153 if (!pid || self.isProgress) { 154 return false;
155 } 156 157 self.isProgress = true; 158 clearTimeout(self.personalizeTimeout); 159 target.addClass('in-progress'); 160 161 const storageKey = self.getSavedKey(pid); 162 let savedPopupTemplate = self.savedPopupTemplate; 163 164 let type = 'save'; 165 if (target.hasClass('bookmarked')) { 166 type = 'remove'; 167 } 168 169 $.ajax({ 170 type: 'POST', 171 url: self.ajaxURL, 172 data: { 173 action: 'rbbookmark', 174 pid: pid, 175 type: type, 176 uuid: self.personalizeUID 177 }, 178 success: function (response) { 179 if ('save' === type) { 180 $('.bookmark-trigger[data-pid=' + pid + ']').css('opacity', 0).addClass('bookmarked').animate({opacity: 1}, 250); 181 self.setStorage(storageKey, '1'); 182 if (self.yesPopup) { 183 savedPopupTemplate = savedPopupTemplate.replace('{{classes}}', 'added'); 184 } 185 } else { 186 $('.bookmark-trigger[data-pid=' + pid + ']').css('opacity', 0).removeClass('bookmarked').animate({opacity: 1}, 250); 187 self.deleteStorage(storageKey); 188 if (self.yesPopup) { 189 savedPopupTemplate = savedPopupTemplate.replace('{{classes}}', 'removed'); 190 } 191 } 192 193 target.removeClass('in-progress'); 194 self.isProgress = false; 195 196 if (self.yesPopup) { 197 savedPopupTemplate = savedPopupTemplate 198 .replace('{{image}}', response.image) 199 .replace('{{title}}', response.title) 200 .replace('{{description}}', response.description); 201 202 clearTimeout(self.personalizeTimeout); 203 self.personalizePopup.empty(); 204 self.personalizePopup.append(savedPopupTemplate); 205 self.personalizePopup.fadeIn(300); 206 207 self.personalizeTimeout = setTimeout(function () { 208 self.personalizePopup.fadeOut(600); 209 }, 2000); 210 } 211 }, 212 error: function () { 213 target.removeClass('in-progress'); 214 self.isProgress = false; 215 } 216 }); 217 }); 218 } 219 220 /** follow category */ 221 Module.followCategoryToggle = function () { 222 223 if ('no' === this.personalizeMode) { 224 return; 225 } 226 227 const self = this; 228 self._body.on('click', '.follow-trigger[data-cid]', function (e) { 229 230 e.preventDefault(); 231 e.stopPropagation(); 232 233 const target = $(this); 234 const cid = target.data('cid'); 235 236 if (!cid || self.isProgress) { 237 return false; 238 } 239 240 self.isProgress = true; 241 clearTimeout(self.personalizeTimeout); 242 target.addClass('in-progress'); 243 244 const storageKey = self.getCategoryFollowKey(cid); 245 let followPopupTemplate = self.followPopupTemplate; 246 const catName = target.data('name'); 247 248 let type = 'follow'; 249 if (target.hasClass('followed')) { 250 type = 'unfollow'; 251 } 252 253 $.ajax({ 254 type: 'POST', 255 url: self.ajaxURL, 256 data: { 257 uuid: self.personalizeUID, 258 action: 'rb_follow_category', 259 cid: cid, 260 type: type, 261 }, 262 success: function (response) { 263 if ('follow' === type) { 264 $('.follow-trigger[data-cid=' + cid + ']').css('opacity', 0).addClass('followed').animate({opacity: 1}, 150); 265 self.setStorage(storageKey, '1'); 266 if (self.yesPopup) { 267 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'added'); 268 } 269 } else { 270 $('.follow-trigger[data-cid=' + cid + ']').css('opacity', 0).removeClass('followed').animate({opacity: 1}, 150); 271 self.deleteStorage(storageKey); 272 if (self.yesPopup) { 273 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'removed'); 274 } 275 } 276 277 target.removeClass('in-progress'); 278 self.isProgress = false;
279 280 if (self.yesPopup) { 281 followPopupTemplate = followPopupTemplate 282 .replace('{{description}}', response.description) 283 .replace('{{name}}', catName); 284 285 clearTimeout(self.personalizeTimeout); 286 self.personalizePopup.empty(); 287 self.personalizePopup.append(followPopupTemplate); 288 self.personalizePopup.fadeIn(300); 289 self.personalizeTimeout = setTimeout(function () { 290 self.personalizePopup.fadeOut(600); 291 }, 2000); 292 } 293 }, 294 error: function () { 295 target.removeClass('in-progress'); 296 self.isProgress = false; 297 } 298 }); 299 }); 300 } 301 302 /** follow writer */ 303 Module.followWriterToggle = function () { 304 305 if ('no' === this.personalizeMode) { 306 return; 307 } 308 309 const self = this; 310 self._body.on('click', '.follow-trigger[data-uid]', function (e) { 311 312 e.preventDefault(); 313 e.stopPropagation(); 314 315 const target = $(this); 316 const uid = target.data('uid'); 317 318 if (!uid || self.isProgress) { 319 return false; 320 } 321 322 self.isProgress = true; 323 clearTimeout(self.personalizeTimeout); 324 target.addClass('in-progress'); 325 326 const storageKey = self.getWriterFollowKey(uid); 327 let followPopupTemplate = self.followPopupTemplate; 328 const authName = target.data('name'); 329 330 let type = 'follow'; 331 if (target.hasClass('followed')) { 332 type = 'unfollow'; 333 } 334 335 $.ajax({ 336 type: 'POST', 337 url: self.ajaxURL, 338 data: { 339 uuid: self.personalizeUID, 340 action: 'rb_follow_writer', 341 uid: uid, 342 type: type, 343 }, 344 success: function (response) { 345 if ('follow' === type) { 346 $('.follow-trigger[data-uid=' + uid + ']').css('opacity', 0).addClass('followed').animate({opacity: 1}, 150); 347 self.setStorage(storageKey, '1'); 348 if (self.yesPopup) { 349 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'added'); 350 } 351 } else { 352 $('.follow-trigger[data-uid=' + uid + ']').css('opacity', 0).removeClass('followed').animate({opacity: 1}, 150); 353 self.deleteStorage(storageKey); 354 if (self.yesPopup) { 355 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'removed'); 356 } 357 } 358 359 target.removeClass('in-progress'); 360 self.isProgress = false; 361 362 if (self.yesPopup) { 363 followPopupTemplate = followPopupTemplate 364 .replace('{{description}}', response.description) 365 .replace('{{name}}', authName); 366 367 clearTimeout(self.personalizeTimeout); 368 self.personalizePopup.empty(); 369 self.personalizePopup.append(followPopupTemplate); 370 self.personalizePopup.fadeIn(300); 371 self.personalizeTimeout = setTimeout(function () { 372 self.personalizePopup.fadeOut(600); 373 }, 2000); 374 } 375 }, 376 error: function () { 377 target.removeClass('in-progress'); 378 self.isProgress = false;
379 } 380 }); 381 }); 382 } 383 384 /** keep notification */ 385 Module.keepPersonalizePopup = function () { 386 387 const self = this; 388 if (self.personalizePopup.length > 0) { 389 self.personalizePopup.on({ 390 mouseenter: function () { 391 clearTimeout(self.personalizeTimeout); 392 }, 393 mouseleave: function () { 394 self.personalizeTimeout = setTimeout(function () { 395 self.personalizePopup.fadeOut(600); 396 }, 1200); 397 } 398 }); 399 } 400 } 401 402 /** sync layouts */ 403 Module.syncPersonalizeLayout = function () { 404 405 if ('no' === this.personalizeMode) { 406 return; 407 } 408 409 this.isProgress = true; 410 this.syncLayoutBookmarks(); 411 this.syncLayoutCategories(); 412 this.syncLayoutWriters(); 413 this.isProgress = false; 414 } 415 416 Module.syncLayoutBookmarks = function () { 417 418 const self = this; 419 const bookmarks = document.querySelectorAll('.rb-bookmark[data-pid]'); 420 421 bookmarks.forEach((bookmark) => { 422 if (bookmark.classList.contains('loaded')) { 423 return; 424 } 425 bookmark.insertAdjacentHTML('beforeend', self.bookmarkToggleTemplate); 426 if ('yes' === self.personalizeMode) { 427 const storageKey = self.getSavedKey(bookmark.getAttribute('data-pid')); 428 const bookmarked = self.getStorage(storageKey) == 1; 429 if (bookmarked) { 430 bookmark.classList.add('bookmarked'); 431 } else { 432 bookmark.classList.remove('bookmarked'); 433 } 434 } else { 435 bookmark.classList.remove('bookmark-trigger'); 436 } 437 bookmark.classList.add('loaded'); 438 }); 439 } 440 441 Module.syncLayoutCategories = function () { 442 443 const self = this; 444 const catFollows = document.querySelectorAll('.rb-follow[data-cid]'); 445 446 catFollows.forEach((cat) => { 447 if (cat.classList.contains('loaded')) { 448 return; 449 } 450 cat.insertAdjacentHTML('beforeend', self.followToggleTemplate); 451 if ('yes' === self.personalizeMode) { 452 const storageKey = self.getCategoryFollowKey(cat.getAttribute('data-cid')); 453 const bookmarked = self.getStorage(storageKey) == 1; 454 if (bookmarked) { 455 cat.classList.add('followed'); 456 } else { 457 cat.classList.remove('followed'); 458 } 459 } else { 460 cat.classList.remove('follow-trigger'); 461 } 462 cat.classList.add('loaded'); 463 }); 464 } 465 466 Module.syncLayoutWriters = function () { 467 468 const self = this; 469 const writerFollows = document.querySelectorAll('.rb-follow[data-uid]'); 470 471 writerFollows.forEach((writer) => { 472 if (writer.classList.contains('loaded')) { 473 return; 474 } 475 writer.insertAdjacentHTML('beforeend', self.followToggleTemplate); 476 if ('yes' === self.personalizeMode) { 477 const storageKey = self.getWriterFollowKey(writer.getAttribute('data-uid')); 478 const bookmarked = self.getStorage(storageKey) == 1; 479 if (bookmarked) { 480 writer.classList.add('followed'); 481 } else { 482 writer.classList.remove('followed'); 483 } 484 } else { 485 writer.classList.remove('follow-trigger'); 486 } 487 writer.classList.add('loaded'); 488 }); 489 } 490 491 Module.syncPersonalizeData = function () { 492 493 const self = this; 494 const blankSavedKey = self.getSavedKey(''); 495 const blankCatKey = self.getCategoryFollowKey(''); 496 const blankWriterKey = self.getWriterFollowKey(''); 497 let i, id; 498 499 FOXIZ_CORE_SCRIPT.setCookie('personalize_sync', ''); 500 FOXIZ_CORE_SCRIPT.setCookie('syncTimeout', '1', self.syncTimeout); 501 502 $.ajax({ 503 type: 'POST', 504 url: self.ajaxURL, 505 data: { 506 action: 'rbpersonalizedata', 507 }, 508 success: function (response) { 509 if (self.yesStorage) {
510 const keysToDelete = []; 511 for (i = 0; i < localStorage.length; i++) { 512 const key = localStorage.key(i); 513 if (key && (key.includes(blankSavedKey) || key.includes(blankCatKey) || key.includes(blankWriterKey))) { 514 keysToDelete.push(key); 515 } 516 } 517 keysToDelete.forEach(function(key) { 518 self.deleteStorage(key); 519 }); 520 521 if (response.bookmarks && response.bookmarks.length > 0) { 522 for (i = 0; i < response.bookmarks.length; i++) { 523 id = response.bookmarks[i]; 524 self.setStorage(self.getSavedKey(id), '1'); 525 } 526 } 527 528 if (response.categories && response.categories.length > 0) { 529 for (i = 0; i < response.categories.length; i++) { 530 id = response.categories[i]; 531 self.setStorage(self.getCategoryFollowKey(id), '1'); 532 } 533 } 534 535 if (response.writers && response.writers.length > 0) { 536 for (i = 0; i < response.writers.length; i++) { 537 id = response.writers[i]; 538 self.setStorage(self.getWriterFollowKey(id), '1'); 539 } 540 } 541 } 542 self.isProgress = false; 543 self.syncPersonalizeLayout(); 544 }, 545 error: function () { 546 self.isProgress = false; 547 self.syncPersonalizeLayout(); 548 } 549 }); 550 } 551 552 /** for reading list template */ 553 Module.readingListTemplate = function () { 554 555 const self = this; 556 const mySaved = $('#my-saved'); 557 const myCategories = $('#my-categories'); 558 const myWriters = $('#my-writers'); 559 const myRecommended = $('#my-recommended'); 560 561 if (mySaved.length < 1) { 562 return false; 563 } 564 self.isProgress = true; 565 $.ajax({ 566 type: 'POST', 567 url: self.ajaxURL, 568 data: { 569 action: 'rbreadinglist' 570 }, 571 success: function (response) { 572 if ('no' === self.personalizeMode) { 573 mySaved.hide().html(response.saved).fadeIn(250); 574 $(".interest-section").remove(); 575 $("#my-recommended").remove(); 576 return; 577 } 578 579 mySaved.hide().html(response.saved).fadeIn(250); 580 581 if (myCategories.length > 0) { 582 myCategories.hide().html(response.categories).fadeIn(250); 583 } 584 if (myWriters.length > 0) { 585 myWriters.html(response.writers).fadeIn(250); 586 } 587 if (myRecommended.length > 0) { 588 myRecommended.hide().html(response.recommended).fadeIn(250); 589 } 590 591 self.isProgress = false; 592 if (typeof RB_VIEWPORT_OBSERVER !== 'undefined') { 593 RB_VIEWPORT_OBSERVER.refreshAll(); 594 } 595 596 setTimeout(function () { 597 self.syncPersonalizeLayout(); 598 }, 1); 599 }, 600 error: function () { 601 self.isProgress = false; 602 } 603 }); 604 } 605 606 return Module; 607 608 }(FOXIZ_PERSONALIZE || {}, jQuery) 609) 610 611/** init */ 612jQuery(document).ready(function ($) { 613 FOXIZ_PERSONALIZE.init(); 614});
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.