1/** 2 * Javascript (including jQuery and Vue) needed for the PortAl theme. 3 * 4 * @package WordPress 5 * @subpackage asiportal 6 * @since PortAl 1.0.0-beta 7 */ 8 9// do not execute this js in /wp-admin 10if (document.body.classList.contains('wp-admin')) 11 exit; 12 13 14/** 15 * Table of Contents: 16 * - Global variables 17 * - Plain JS functions 18 * - Event listener on DOMContentLoaded 19 * - Event listener on window resize 20 * - Event listener on scroll 21 * - Newsfeed functions 22 * - Button blinking function 23 * - Search prediction function (site header) 24 * - Stick function (sidebar) 25 * - jQuery functions 26 * - Event listener on scroll 27 * - Initiating slick slider jQuery plugin 28 * - Workaround for legacy codes from Web 2.0 29 */ 30 31/** 32 * Global variables 33 */ 34 35var root = document.documentElement; 36var body = document.body; 37var header = document.querySelector('#asi-header'); 38var topbar = document.querySelector('.asi-top-bar'); 39var nav = document.querySelector('.asi-main-nav'); 40var navLv1 = document.querySelectorAll('.asi-main-nav-lv1 > li'); 41var mobileToggle = document.querySelector('.asi-mobile-toggle'); 42var mainNav = document.querySelector('.asi-full-nav'); 43var main = document.querySelector('main'); 44var shadow = document.querySelector('#asi-header span.after'); 45var stickySidebar = document.querySelector('.asi-sticky'); 46var nonSticky = document.querySelector('.asi-non-sticky'); 47var endSidebar = document.querySelector('.asi-sticky-end'); 48var navTimer; 49var simpleBar = null; // for storing the sticky sidebar 50 51 52/** 53 * Plain JS functions 54 */ 55 56/** 57 * Tidy all href in a tags to: 58 * - change http:// to https:// 59 * - append target="_blank" for external links AND files 60 * @since PortAl 1.0.0-beta 61 */ 62 63var links = document.querySelectorAll('a'); 64for (var i in links){ 65 if (typeof(links[i]) !== 'object') 66 continue; 67 if (links[i].getAttribute('href') !== null) 68 links[i].setAttribute('href', links[i].getAttribute('href').replace(/^http:\/\//i, 'https://')); 69 var href = (links[i].getAttribute('href')); 70 if (href === null) 71 continue; 72 if (href.includes(window.location.hostname)){ 73 if (!(href.match(/\.\w{2,}($|\?)/))) 74 continue; 75 if (href.match(/(\.com|\.org)(\/)?($|\?.*)/)) 76 continue; 77 } 78 else { 79 if (href === 'javascript:;') 80 continue; 81 if ((href.substring(0,6) === 'mailto')) 82 continue; 83 if ((href.substring(0,4) !== 'http') && (!(href.match(/\.\w{2,}((\/?)$|\?)/)))) 84 continue; 85 } 86 links[i].setAttribute('target', '_blank'); 87} 88 89/** 90 * Remove all href on lv1 links 91 * @since PortAl 1.0.0-beta 92 */ 93 94var lv1 = document.querySelectorAll('.asi-main-nav-lv1 li a'); 95for (var i=0; i < lv1.length; i++){ 96 lv1[i].setAttribute('href', 'javascript:;'); 97 lv1[i].addEventListener('click', function(){ 98 if (window.innerWidth >= 992){ 99 navTimer = setTimeout(function(){ 100 mainNav.classList.add('asi-showNavSlideDown'); 101 header.classList.add('asi-showNavFull'); 102 }, 550); 103 } 104 }); 105} 106 107/** 108 * Handle the display of dropdown menu on desktop (width > 992px) 109 * @since PortAl 1.0.0-beta 110 */ 111 112navLv1.forEach(function(n){ 113 n.addEventListener('mouseenter', function(){ 114 if (window.innerWidth >= 992){ 115 navTimer = setTimeout(function(){ 116 mainNav.classList.add('asi-showNavSlideDown'); 117 header.classList.add('asi-showNavFull'); 118 }, 550); 119 } 120 }); 121}); 122mainNav.addEventListener('mouseleave', function(){ 123 clearTimeout(navTimer); 124 if (window.innerWidth >= 992){ 125 header.classList.remove('asi-showNavFull'); 126 mainNav.classList.remove('asi-showNavSlideDown'); 127 } 128}); 129topbar.addEventListener('mouseenter', function(){ 130 clearTimeout(navTimer); 131 if (window.innerWidth >= 992){ 132 header.classList.remove('asi-showNavFull'); 133 mainNav.classList.remove('asi-showNavSlideDown'); 134 } 135}); 136header.addEventListener('mouseenter', function(){ 137 clearTimeout(navTimer); 138 if (window.innerWidth >= 992){ 139 header.classList.remove('asi-showNavFull'); 140 mainNav.classList.remove('asi-showNavSlideDown'); 141 } 142}); 143main.addEventListener('mouseenter', function(){ 144 clearTimeout(navTimer); 145 if (window.innerWidth >= 992){ 146 header.classList.remove('asi-showNavFull'); 147 mainNav.classList.remove('asi-showNavSlideDown'); 148 } 149}); 150shadow.addEventListener('mouseenter', function(){ 151 clearTimeout(navTimer); 152 if (window.innerWidth >= 992){ 153 header.classList.remove('asi-showNavFull'); 154 mainNav.classList.remove('asi-showNavSlideDown'); 155 } 156}); 157shadow.addEventListener('click', function(){ 158 clearTimeout(navTimer); 159 if (window.innerWidth >= 992){ 160 header.classList.remove('asi-showNavFull'); 161 mainNav.classList.remove('asi-showNavSlideDown'); 162 } 163}); 164 165/** 166 * Handle the mobile menu 167 * @since PortAl 1.0.0-beta 168 */ 169 170// hamgurger menu button 171mobileToggle.addEventListener('click', function(){ 172 root.classList.toggle('scrollLock'); 173 body.classList.toggle('scrollLock'); 174 header.classList.toggle('asi-showNavFull'); 175 mobileToggle.classList.toggle('close'); 176 mainNav.classList.toggle('asi-showNavSlideDown'); 177}); 178 179// mobile nav lv1 toggle 180document.querySelectorAll('.asi-main-nav-full > li.menu-item-has-children > a').forEach(function(a){ 181 a.addEventListener('click', function(e){ 182 e.preventDefault(); 183 this.classList.toggle('asi-showNav2nd'); 184 return false; 185 }); 186}); 187 188/** 189 * Redirect clicks on the newsletter subscription button (both main menu and footer) 190 * to the full form, with `email` query string appended with email filled
190in the input 191 * @since PortAl 1.0.0-beta 192 */ 193 194var email = document.querySelectorAll('.asi-form-sub'); 195email.forEach(function(e){ 196 e.addEventListener('click', function(){ 197 location.href = 'https://'+window.location.hostname+'/mailing-list?email='+document.querySelector(e.getAttribute('email')).value 198 }) 199}) 200 201 202/** 203 * Plain JS functions - Event listener on window resize 204 * @since PortAl 1.0.0-beta 205 */ 206 207window.addEventListener('resize', function() { 208 209/** 210 * Restore all navigations to the default state 211 * @since PortAl 1.0.0-beta 212 */ 213 if (window.innerWidth >= 768){ 214 root.classList.remove('scrollLock'); 215 body.classList.remove('scrollLock'); 216 header.classList.remove('asi-showNavFull'); 217 mainNav.classList.remove('asi-showNavSlideDown'); 218 mobileToggle.classList.remove('close'); 219 mainNav.classList.remove('asi-showNavSlideDown'); 220 document.querySelectorAll('.asi-main-nav-full > li.menu-item-has-children > a').forEach(function(a){ 221 a.classList.remove('asi-showNav2nd'); 222 }); 223 } 224 225 /** 226 * Stick the sticky filter 227 * @since PortAl 2.0.0 228 */ 229 230 asiStickTheBar(); 231 232}, true); // end of window resize 233 234 235/** 236 * Plain JS functions - Event listener on window resize 237 * @since PortAl 1.0.0-beta 238 */ 239 240window.addEventListener('scroll', function() { 241 242/** 243 * Stick the sticky filter 244 * @since PortAl 2.0.0 245 */ 246 247 asiStickTheBar(); 248 249}); 250 251 252/** 253 * Newsfeed functions 254 * @since PortAl 1.0.0-beta 255 */ 256 257// form the query string based on selected filters, and redirect to the result 258function asiNewsfeedFilter(){ 259 var cat = document.getElementById('asi-news-category').value; 260 var year = document.getElementById('asi-news-year').value; 261 var q = '?'; 262 263 if (cat !== '') 264 q += 'category='+cat; 265 if (year !== '') 266 q += '&time='+year; 267 268 location.search = q; 269} 270// clear the query string and redirect to the full newsfeed 271function asiNewsFeedClear(){ 272 location.href = location.toString().replace(location.search, ''); 273} 274// disable clicking on current page on the pagination 275if (!!document.querySelector('.asi-news-page-current')){ 276 document.querySelector('.asi-news-page-current').addEventListener('click', function(e){ 277 e.preventDefault(); 278 }); 279} 280 281/** 282 * Button blinking function 283 * @since PortAl 1.1.0 284 */ 285 286function asiBtnBlink(selector){ 287 var btn = document.querySelector(selector); 288 btn.classList.add('asi-btn-blink'); 289 setTimeout(function(){ 290 btn.classList.remove('asi-btn-blink'); 291 }, 1500); // 1500 is the total time of CSS aniation; refer to asiBtnBlinkKeyframes 292} 293 294/** 295 * Search prediction function (site header) 296 * @since PortAl 1.2.0 297 */ 298var searchBtn = document.querySelectorAll('.asi-search-btn'); 299searchBtn.forEach(function(e){ 300 e.addEventListener('click', function(){ 301 document.getElementById('asi-search-prediction').classList.remove('d-none'); 302 document.getElementById('asi-search-prediction-input').focus(); 303 }); 304}); 305var searchPrediction = new Vue({ 306 el: '#asi-search-prediction', 307 data: { 308 search: '', 309 ui: { 310 show: false, 311 loading: false, 312 }, 313 response: { 314 result:{page:[],file:[],rs:[],member:[],auditor:[],auditfirm:[]},didyoumean: '' 315 }, 316 timer: null 317 }, 318 watch: { 319 search: function(){ 320 if (this.timer){ 321 clearTimeout(this.timer) 322 } 323 if (this.search.length >= 0){ 324 this.timer = setTimeout(function(){ 325 searchPrediction.ui.loading = true; 326 searchPrediction.predict(); 327 clearTimeout(this.timer); 328 }, 1000); 329 } 330 } 331 }, 332 methods: { 333 _init: function(){ 334 this.search = ''; 335 this.response = {result:{page:[],file:[],rs:[],member:[],auditor:[],auditfirm:[]},didyoumean:''}; 336 }, 337 predict: function(){ 338 if (this.search !== ''){ 339 var ajax = new XMLHttpRequest(); 340 ajax.onreadystatechange = function(){ 341 if (ajax.readyState === XMLHttpRequest.DONE){ 342 searchPrediction.response = JSON.parse(ajax.responseText); 343 searchPrediction.ui.loading = false; 344 ajax.abort(); 345 } 346 } 347 ajax.open('POST', 'https://'+window.location.hostname+'/?s='+this.search+'&mode=quick'); 348 ajax.send(); 349 } 350 }, 351 close: function(){ 352 this._init(); 353 document.getElementById('asi-search-prediction').classList.add('d-none'); 354 }, 355 submit: function(){ 356 if (this.search.length > 0) 357 location.href = 'https://'+window.location.hostname+'/?s='+this.search; 358 } 359 } 360}); 361 362/** 363 * Stick function (sidebar) 364 * @since PortAl 2.0.0 365 */ 366 367function asiStickTheBar(){ 368 var stickySidebar = document.querySelector('.asi-sticky'); 369 var stickySticky = document.querySelector('.asi-sticky-sticky'); 370 // var stickyStickySib = document.querySelector('.asi-sticky-sticky + div'); 371 var nonSticky = document.querySelector('.asi-non-sticky'); 372 var endSidebar = document.querySelector('.asi-sticky-end'); 373 374 if (!stickySidebar) 375 return; 376 377 // reset the style first 378 stickySidebar.removeAttribute('style'); 379 nonSticky.removeAttribute('style'); 380 stickySticky.removeAttribute('style'); 381 // stickyStickySib.removeAttribute('style'); 382 383 var headerHeight = topbar.offsetHeight + nav.offsetHeight, 384 stickySidebarTop = stickySidebar.getBoundingClientRect().top - headerHeight, 385 stickySidebarWidth = stickySidebar.offsetWidth - 2, 386 stickySidebarPadtop = stickySticky.offsetHeight, 387 isNonstickyTallerThanScreen = ((nonSticky.offsetHeight - window.innerHeight + headerHeight) > 0), 388 stickyEndDistance = document.documentElement.clientHeight - endSidebar.getBoundingClientRect().top; 389 390 var stickySidebarCss = 'width: '+stickySidebarWidth+'px;', 391 nonStickyCss = ''; 392 393 // stickySidebarCss += 'height: '+(window.innerHeight - headerHeight)+'px;'; 394 395 if (stickySidebarTop < 0){ 396 var offset = (stickyEndDistance < 0)?0 : stickyEndDistance; 397 if (window.innerWidth >= 992){ 398 nonStickyCss += 'margin-left: '+stickySidebarWidth+'px;'; 399 stickySidebarCss += 'height: '+(window.innerHeight - headerHeight)+'px;'; 400 } 401 else 402 nonStickyCss += 'padding-top: 138px;'; 403 stickySidebarCss += 'position: fixed;' + 404 'top: '+(headerHeight - offset)+'px;'+ 405 'padding-top: '+(stickySidebarPadtop - 16)+'px;'; 406 stickySticky.style.cssText = 'background:white;'+ 407 'z-index:2;'+ 408 'position:fixed;'+ 409 // 'width: '+(stickySidebarWidth - 16)+'px;'+ 410 'width: '+(stickySidebarWidth)+'px;'+ 411 'margin-top: -'+(stickySidebarPadtop - 16)+'px;'; 412 if (window.innerWidth >= 992) 413 stickySticky.style.cssText += 'width: '+(stickySidebarWidth - 16)+'px;' + 414 'padding-right: 16px'; 415 // stickyStickySib.style.cssText = 'padding-top:16px;'; 416 417 } 418 419 if (!isNonstickyTallerThanScreen){ 420 // nonStickyCss += 'height: '+(stickySidebar.offsetHeight)+'px;'; 421 stickySidebarCss += 'max-height: '+(window.innerHeight - headerHeight)+'px;'; 422 } 423 424 stickySidebar.style.cssText = stickySidebarCss; 425 nonSticky.style.cssText = nonStickyCss; 426 427 if (simpleBar === null){ 428 simpleBar = new SimpleBar(stickySidebar, {autoHide: true, timeout: 2000}); 429 } 430 document.querySelectorAll('.asi-scrollbar').forEach(function(e){ 431 new SimpleBar(e, {autoHide: false}); 432 }); 433 // the following code is to trigger the captcha to render for member list page 434 var event = new Event("renderCaptcha", { bubbles: true, cancelable: false }); 435 console.log("renderCaptcha event fired"); 436 document.getElementById("asi-member").dispatchEvent(event); 437} 438asiStickTheBar(); // trigger it once anyway 439 440 441/** 442 * jQuery functions 443 * @since PortAl 1.0.0-beta 444 */ 445 446jQuery(function($){ 447 448/** 449 * Event listener on scroll (tablets) 450 * @since PortAl 1.0.0-beta 451 */ 452 453 $(document).on('touchmove', function(e){ 454 455/**
456 * Restore the menu to the default state on desktop (width > 992px) 457 * @since PortAl 1.0.0-beta 458 */ 459 460 if (window.innerWidth >= 992){ 461 header.classList.remove('asi-showNavFull'); 462 mainNav.classList.remove('asi-showNavSlideDown'); 463 } 464 465/** 466 * Stick the sticky filter 467 * @since PortAl 2.0.0 468 */ 469 470 asiStickTheBar(); 471 472 }); 473 474/** 475 * Initating slick sliders 476 * @since PortAl 1.0.0-beta 477 * @link https://kenwheeler.github.io/slick/ 478 */ 479 480 $('.asi-slick').each(function(){ 481 $(this).slick({ 482 accessibility: false, 483 adaptiveHeight: true, 484 autoplay: $(this).data('autoplay'), 485 autoplaySpeed: ($(this).data('autoplayspeed'))?$(this).data('autoplayspeed'):5000, 486 arrows: false, 487 dots: true, 488 infinite: $(this).data('autoplay'), 489 mobileFirst: true, 490 slidesToShow: 1, 491 slidesToScroll: $(this).data('scroll'), 492 responsive: Array.from($(this).data('responsive')) 493 }); 494 }); 495 496}); // end of jQuery 497 498 499/** 500 * Workaround for legacy codes from Web 2.0 501 * @since PortAl 1.0.0-beta 502 */ 503 504// show counter value instead of rolling up 505jQuery('.count_el').each(function(){ 506 jQuery(this).css({'font-weight': 600, 'text-align':'center', 'font-size': '32px'}) 507 .children('span') 508 .html(jQuery(this).children('span').data('to')); 509});
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.