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.pesonalizeMode) { 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 * delelte 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.pesonalizeMode = '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.pesonalizeMode = 'ask_login'; 135 } else if ('logged' === setting) { 136 this.pesonalizeMode = '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 179 success: function (response) { 180 181 response = JSON.parse(JSON.stringify(response)); 182 if ('save' === type) { 183 $('.bookmark-trigger[data-pid=' + pid + ']').css('opacity', 0).addClass('bookmarked').animate({opacity: 1}, 250); 184 self.setStorage(storageKey, '1'); 185 if (self.yesPopup) { 186 savedPopupTemplate = savedPopupTemplate.replace('{{classes}}', 'added'); 187 } 188 } else { 189 $('.bookmark-trigger[data-pid=' + pid + ']').css('opacity', 0).removeClass('bookmarked').animate({opacity: 1}, 250); 190 self.deleteStorage(storageKey); 191 if (self.yesPopup) { 192 savedPopupTemplate = savedPopupTemplate.replace('{{classes}}', 'removed'); 193 } 194 } 195 196 target.removeClass('in-progress'); 197 self.isProgress = false; 198 199 if (self.yesPopup) { 200 savedPopupTemplate = savedPopupTemplate 201 .replace('{{image}}', response.image) 202 .replace('{{title}}', response.title) 203 .replace('{{description}}', response.description); 204 205 clearTimeout(self.personalizeTimeout); 206 self.personalizePopup.empty(); 207 self.personalizePopup.append(savedPopupTemplate); 208 self.personalizePopup.fadeIn(300); 209 210 self.personalizeTimeout = setTimeout(function () { 211 self.personalizePopup.fadeOut(600); 212 }, 2000); 213 } 214 } 215 }); 216 }); 217 } 218 219 /** follow category */ 220 Module.followCategoryToggle = function () { 221 222 if ('no' === this.pesonalizeMode) { 223 return; 224 } 225 226 const self = this; 227 self._body.on('click', '.follow-trigger[data-cid]', function (e) { 228 229 e.preventDefault(); 230 e.stopPropagation(); 231 232 var target = $(this); 233 var cid = target.data('cid'); 234 235 if (!cid || self.isProgress) { 236 return false; 237 } 238 239 self.isProgress = true; 240 clearTimeout(self.personalizeTimeout); 241 target.addClass('in-progress'); 242 243 const storageKey = self.getCategoryFollowKey(cid); 244 let followPopupTemplate = self.followPopupTemplate; 245 const catName = target.data('name'); 246 247 let type = 'follow'; 248 if (target.hasClass('followed')) { 249 type = 'unfollow'; 250 } 251 252 $.ajax({
253 type: 'POST', 254 url: self.ajaxURL, 255 data: { 256 uuid: self.personalizeUID, 257 action: 'rb_follow_category', 258 cid: cid, 259 type: type, 260 }, 261 success: function (response) { 262 response = JSON.parse(JSON.stringify(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 }); 295 }); 296 } 297 298 /** follow writer */ 299 Module.followWriterToggle = function () { 300 301 if ('no' === this.pesonalizeMode) { 302 return; 303 } 304 305 const self = this; 306 self._body.on('click', '.follow-trigger[data-uid]', function (e) { 307 308 e.preventDefault(); 309 e.stopPropagation(); 310 311 var target = $(this); 312 var uid = target.data('uid'); 313 314 if (!uid || self.isProgress) { 315 return false; 316 } 317 318 self.isProgress = true; 319 clearTimeout(self.personalizeTimeout); 320 target.addClass('in-progress'); 321 322 const storageKey = self.getWriterFollowKey(uid); 323 let followPopupTemplate = self.followPopupTemplate; 324 const authName = target.data('name'); 325 326 let type = 'follow'; 327 if (target.hasClass('followed')) { 328 type = 'unfollow'; 329 } 330 331 $.ajax({
332 type: 'POST', 333 url: self.ajaxURL, 334 data: { 335 uuid: self.personalizeUID, 336 action: 'rb_follow_writer', 337 uid: uid, 338 type: type, 339 }, 340 success: function (response) { 341 342 response = JSON.parse(JSON.stringify(response)); 343 344 if ('follow' === type) { 345 $('.follow-trigger[data-uid=' + uid + ']').css('opacity', 0).addClass('followed').animate({opacity: 1}, 150); 346 self.setStorage(storageKey, '1'); 347 if (self.yesPopup) { 348 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'added'); 349 } 350 } else { 351 $('.follow-trigger[data-uid=' + uid + ']').css('opacity', 0).removeClass('followed').animate({opacity: 1}, 150); 352 self.deleteStorage(storageKey); 353 if (self.yesPopup) { 354 followPopupTemplate = followPopupTemplate.replace('{{classes}}', 'removed'); 355 } 356 } 357 358 target.removeClass('in-progress'); 359 self.isProgress = false; 360 361 if (self.yesPopup) { 362 followPopupTemplate = followPopupTemplate 363 .replace('{{description}}', response.description) 364 .replace('{{name}}', authName); 365 366 clearTimeout(self.personalizeTimeout); 367 self.personalizePopup.empty(); 368 self.personalizePopup.append(followPopupTemplate); 369 self.personalizePopup.fadeIn(300); 370 self.personalizeTimeout = setTimeout(function () { 371 self.personalizePopup.fadeOut(600); 372 }, 2000); 373 } 374 } 375 }); 376 }); 377 } 378 379 /** keep notification */ 380 Module.keepPersonalizePopup = function () { 381 382 const self = this; 383 if (self.personalizePopup.length > 0) { 384 self.personalizePopup.on({ 385 mouseenter: function () { 386 clearTimeout(self.personalizeTimeout); 387 }, 388 mouseleave: function () { 389 self.personalizeTimeout = setTimeout(function () { 390 self.personalizePopup.fadeOut(600); 391 }, 1200); 392 } 393 }); 394 } 395 } 396 397 /** sync layouts */ 398 Module.syncPersonalizeLayout = function () { 399 400 if ('no' === this.pesonalizeMode) { 401 return; 402 } 403 404 this.isProgress = true; 405 this.syncLayoutBookmarks(); 406 this.syncLayoutCategories(); 407 this.syncLayoutWitters(); 408 this.isProgress = false; 409 } 410 411 Module.syncLayoutBookmarks = function () { 412 413 const self = this; 414 const bookmarks = document.querySelectorAll('.rb-bookmark[data-pid]'); 415 416 bookmarks.forEach((bookmark) => { 417 if (bookmark.classList.contains('loaded')) { 418 return; 419 } 420 bookmark.insertAdjacentHTML('beforeend', self.bookmarkToggleTemplate); 421 if ('yes' === self.pesonalizeMode) { 422 const storageKey = self.getSavedKey(bookmark.getAttribute('data-pid')); 423 const bookmarked = self.getStorage(storageKey) == 1; 424 if (bookmarked) { 425 bookmark.classList.add('bookmarked'); 426 } else { 427 bookmark.classList.remove('bookmarked'); 428 } 429 } else { 430 bookmark.classList.remove('bookmark-trigger'); 431 } 432 bookmark.classList.add('loaded'); 433 }); 434 } 435 436 Module.syncLayoutCategories = function () { 437 438 const self = this; 439 const catFollows = document.querySelectorAll('.rb-follow[data-cid]'); 440 441 catFollows.forEach((cat) => { 442 if (cat.classList.contains('loaded')) { 443 return; 444 } 445 cat.insertAdjacentHTML('beforeend', self.followToggleTemplate); 446 if ('yes' === self.pesonalizeMode) { 447 const storageKey = self.getCategoryFollowKey(cat.getAttribute('data-cid')); 448 const bookmarked = self.getStorage(storageKey) == 1; 449 if (bookmarked) { 450 cat.classList.add('followed'); 451 } else { 452 cat.classList.remove('followed'); 453 } 454 } else { 455 cat.classList.remove('follow-trigger'); 456 } 457 cat.classList.add('loaded'); 458 }); 459 } 460 461 Module.syncLayoutWitters = function () { 462 463 const self = this; 464 const writerFollows = document.querySelectorAll('.rb-follow[data-uid]'); 465
466 writerFollows.forEach((writer) => { 467 if (writer.classList.contains('loaded')) { 468 return; 469 } 470 writer.insertAdjacentHTML('beforeend', self.followToggleTemplate); 471 if ('yes' === self.pesonalizeMode) { 472 const storageKey = self.getWriterFollowKey(writer.getAttribute('data-uid')); 473 const bookmarked = self.getStorage(storageKey) == 1; 474 if (bookmarked) { 475 writer.classList.add('followed'); 476 } else { 477 writer.classList.remove('followed'); 478 } 479 } else { 480 writer.classList.remove('follow-trigger'); 481 } 482 writer.classList.add('loaded'); 483 }); 484 } 485 486 Module.syncPersonalizeData = function () { 487 488 const self = this; 489 const blankSavedKey = self.getSavedKey(''); 490 const blankCatKey = self.getCategoryFollowKey(''); 491 const blankWriterKey = self.getWriterFollowKey(''); 492 let i, id; 493 494 FOXIZ_CORE_SCRIPT.setCookie('personalize_sync', ''); 495 FOXIZ_CORE_SCRIPT.setCookie('syncTimeout', '1', self.syncTimeout); 496 497 $.ajax({
498 type: 'POST', 499 url: self.ajaxURL, 500 data: { 501 action: 'rbpersonalizedata', 502 }, 503 success: function (response) { 504 response = JSON.parse(JSON.stringify(response)); 505 506 if (self.yesStorage) { 507 for (i = 0; i < localStorage.length; i++) { 508 var key = localStorage.key(i); 509 if (key.includes(blankSavedKey) || key.includes(blankCatKey) || key.includes(blankWriterKey)) { 510 self.deleteStorage(key); 511 } 512 } 513 514 if (response.bookmarks && response.bookmarks.length > 0) { 515 for (i = 0; i < response.bookmarks.length; i++) { 516 id = response.bookmarks[i]; 517 self.setStorage(self.getSavedKey(id), '1'); 518 } 519 } 520 521 if (response.categories && response.categories.length > 0) { 522 for (i = 0; i < response.categories.length; i++) { 523 id = response.categories[i]; 524 self.setStorage(self.getCategoryFollowKey(id), '1'); 525 } 526 } 527 528 if (response.writers && response.writers.length > 0) { 529 for (i = 0; i < response.writers.length; i++) { 530 id = response.writers[i]; 531 self.setStorage(self.getWriterFollowKey(id), '1'); 532 } 533 } 534 } 535 self.isProgress = false; 536 self.syncPersonalizeLayout(); 537 } 538 }); 539 } 540 541 /** for reading list template */ 542 Module.readingListTemplate = function () { 543 544 const self = this; 545 const mySaved = $('#my-saved'); 546 const myCategories = $('#my-categories'); 547 const myWriters = $('#my-writers'); 548 const myRecommended = $('#my-recommended'); 549 550 if (mySaved.length < 1) { 551 return false; 552 } 553 self.isProgress = true; 554 $.ajax({
555 type: 'POST', 556 url: self.ajaxURL, 557 data: { 558 action: 'rbreadinglist' 559 }, 560 success: function (response) { 561 562 response = JSON.parse(JSON.stringify(response)); 563 564 if ('no' === self.pesonalizeMode) { 565 mySaved.hide().html(response.saved).fadeIn(250); 566 $(".interest-section").remove(); 567 $("#my-recommended").remove(); 568 return false; 569 } else { 570 mySaved.hide().html(response.saved).fadeIn(250); 571 } 572 573 if (myCategories.length > 0) { 574 myCategories.hide().html(response.categories).fadeIn(250); 575 } 576 if (myWriters.length > 0) { 577 myWriters.html(response.writers).fadeIn(250); 578 } 579 580 if (myRecommended.length > 0) { 581 myRecommended.hide().html(response.recommended).fadeIn(250); 582 } 583 584 self.isProgress = false; 585 Waypoint.refreshAll(); 586 587 setTimeout(function () { 588 self.syncPersonalizeLayout(); 589 }, 1) 590 } 591 }); 592 } 593 594 return Module; 595 596 }(FOXIZ_PERSONALIZE || {}, jQuery) 597) 598 599/** init */ 600jQuery(document).ready(function ($) { 601 FOXIZ_PERSONALIZE.init(); 602});
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.