1/** @namespace */ 2var wli = wli || {}; 3 4var scriptDataObj = jQuery("[data-wli-lib]").data(); 5 6wli.widgetUrl = scriptDataObj.secureDomain.toLowerCase(); 7wli.homeUrl = scriptDataObj.homeDomain.toLowerCase(); 8wli.compUrl = scriptDataObj.componentDomain.toLowerCase(); 9 10var stylesheetURL = wli.widgetUrl + "/External/WCControls/V12/WebDeps/Widgets/styles/wli-widget-styles.css"; 11 12if (scriptDataObj.defaultStyles != false) { 13 jQuery("head").prepend('<link rel="stylesheet" href="' + stylesheetURL + '" />'); 14} 15 16/** 17 * Represents the web menu for quicklinks, breadcrumbs, sitemap, etc. 18 * @constructor 19 * @param {String} domain - The home page URL or root domain URL of the website. 20 * @property {Object} Root - The home page or root domain page. 21 * @property {Object} L2 - The top level navigation items. 22 * @property {Object} CurrentPage - The current page the browser has loaded. 23 * @property {Object} Section - The L2 item that each L3 and lower page belongs to. 24 */ 25wli.WebMenu = function(domain) { 26 this.Root = { 27 URL : domain, 28 Target : "", 29 Name : "Home" 30 }; 31 this.L2 = {}; 32 this.CurrentPage = {}; 33 this.Section = {}; 34 35 /** 36 * Array of nodes in the web menu that will represent the L2 nodes. 37 * @type {Array} 38 */ 39 var nodeTree = []; 40 41 /** 42 * Iterator variable for use in loops. 43 * @type {Number} 44 */ 45 var i; 46 47 /** 48 * Iterator variable for use in loops. 49 * @type {Number} 50 */ 51 var x; 52 53 // Constructor processes 54 jQuery(".wsite-menu-default > li").each(function(index) { 55 jQuery(this).children("a").each(function() { 56 var linkName = jQuery(this).text(); 57 58 if (linkName.indexOf("&") !== -1) { 59 linkName = linkName.replace("&", "&"); 60 } 61 62 nodeTree.push({ 63 URL : this.href, 64 Target : jQuery(this).attr("target"), 65 Name : linkName 66 }); 67 }); 68 69 var L2node = nodeTree[nodeTree.length - 1]; 70 71 L2node["SubMenu"] = getChildMenuStructure(this); 72 73 for (i in L2node.SubMenu) { 74 L2node.SubMenu[i]["Parent"] = L2node; 75 } 76 }); 77 78 for (i in nodeTree) { 79 // Push the nodeTree array objects into the L2 object property 80 this.L2[i] = nodeTree[i]; 81 } 82 83 // Set the CurrentPage property 84 this.CurrentPage = this.findCurrentPage(this.L2, document.URL); 85 // Set the SectionName property 86 this.Section = this.findSectionName(this.CurrentPage); 87 88 /** 89 * Recursive function for building out children pages in the web menu. 90 * @param {HTMLElement} parentli - The parent page in the web menu that may have children nodes. 91 * @returns {Array} - Array of all children nodes for the page the function was called on. 92 */ 93 function getChildMenuStructure(parentli) { 94 /** @type {Array} */ 95 var subMenu = []; 96 97 jQuery("> div > ul > li > a, > ul > li > a", parentli).each(function() { 98 var linkName = jQuery(this).children(".wsite-menu-title").text(); 99 100 if (linkName.indexOf("&") !== -1) { 101 linkName = linkName.replace("&", "&"); 102 } 103 104 var subNode = { 105 URL : this.href, 106 Target : jQuery(this).attr("target"), 107 Name : linkName, 108 SubMenu : getChildMenuStructure(jQuery(this).closest("li")[0]), 109 Level : function(){ if (this.Parent && this.Parent.Level) { return this.Parent.Level() + 1;} else return 3;} 110 }; 111 112 for (i in subNode.SubMenu) { 113 subNode.SubMenu[i]["Parent"] = subNode; 114 } 115 116 subMenu.push(subNode); 117 }); 118 119 return subMenu; 120 } 121}; 122 123 /** 124 * Method for generating breadcrumb links that show the site hierarchy from the current page. 125 * @param {Object} [opts] - Optional object used to override default properties. 126 * @returns {String} - HTML String of all breadcrumb links wrapped in <ul>. 127 */ 128 wli.WebMenu.prototype.Breadcrumbs = function(opts) { 129 /** @type {number} */ 130 var x; 131 132 /** @type {number} */ 133 var i; 134 135 /** @type {Object} */ 136 var settings = {}; 137 138 /** @type {Object} */ 139 // The divider default property is the text character used to separate the breadcrumb links. 140 var defaults = { 141 divider : " | " 142 }; 143 144 // Merge default properties into settings 145 for (x in defaults) { 146 settings[x] = defaults[x]; 147 } 148 149 // Merge options provided into settings, overriding defaults 150 for (x in opts) { 151 settings[x] = opts[x]; 152 } 153 154 /** @type {Array} */ 155 var breadcrumbNodes = []; 156 157 /** @type {Array} */ 158 var nodes = []; 159 160 /** @type {Array} */ 161 var breadcrumbHTML = []; 162 163 // Add the current page to the breadcrumbs 164 if (this.CurrentPage) { 165 breadcrumbNodes.push(this.CurrentPage); 166 } 167 168 // Add the current page's parent and its parents to the breadcrumbs 169 if (this.CurrentPage.Parent) { 170 var returnedNodes = findBreadcrumbs(this.CurrentPage.Parent); 171 172 for (i in returnedNodes) { 173 breadcrumbNodes.push(returnedNodes[i]); 174 } 175 } 176 177 // Add the homepage to the breadcrumbs 178 breadcrumbNodes.push(this.Root); 179 180 // Parse the breadcrumbs array and build an HTML structure for outputting to the DOM 181 for (i in breadcrumbNodes) { 182 // Set the "target" attribute for the <a> tags to an empty string if the node has no Target property 183 if (!breadcrumbNodes[i].Target) { 184 breadcrumbNodes[i].Target = ""; 185 } 186 187 if (i == 0) { 188 breadcrumbHTML[i] = '<li><a href="' + breadcrumbNodes[i].URL + '" target="' 189 + breadcrumbNodes[i].Target + '">' + breadcrumbNodes[i].Name 190 + '</a></li>'; 191 192 continue; 193 } 194 195 breadcrumbHTML[i] = '<li><a href="' + breadcrumbNodes[i].URL + '" target="' 196 + breadcrumbNodes[i].Target + '">' + breadcrumbNodes[i].Name 197 + '</a>' + settings.divider + '</li>'; 198 } 199 200 breadcrumbHTML.reverse(); 201 202 return "<ul>" + breadcrumbHTML.join("") + "</ul>"; 203 204 /** 205 * Recursive function used for finding the breadcrumb nodes. 206 * @param {object} parent - The parent node object for the current page. 207 * @returns {Array} - Array of breadcrumb node objects. 208 */ 209 function findBreadcrumbs(parent) { 210 nodes.push(parent); 211 212 if (parent.Parent) { 213 findBreadcrumbs(parent.Parent); 214 } 215 216 return nodes; 217 } 218 }; 219 220 /** 221 * Method for generating quicklinks that show all of the sibling pages and children pages of the current page. 222 * @param {object} [opts] - Optional object used to override default properties. 223 * @returns {string} - HTML String of all quicklinks wrapped in <ul>. 224 */ 225 wli.WebMenu.prototype.Quicklinks = function(opts) { 226 var quicklinkNodes = []; 227 var quicklinkHTML = []; 228 var i; 229 var x; 230 231 if (this.CurrentPage) { 232 233 if (this.CurrentPage.Parent) { 234 var currentPage = this.CurrentPage; 235 var siblingNodes = this.CurrentPage.Parent.SubMenu; 236 var childrenNodes = this.CurrentPage.SubMenu; 237 238 if (this.CurrentPage.Parent.Parent) { 239 var parentNodes = this.CurrentPage.Parent.Parent.SubMenu; 240 241 if (parentNodes.length > 0) { 242 for (i in parentNodes) { 243 parentNodes[i]["Class"] = "wli-quicklink-parent"; 244 quicklinkNodes.push(parentNodes[i]); 245 } 246 } 247 } 248 249 for (i in siblingNodes) { 250 if (siblingNodes[i].URL == currentPage.URL) { 251 siblingNodes[i]["Class"] = "wli-quicklink-sibling wli-quicklink-current"; 252 quicklinkNodes.push(siblingNodes[i]); 253 254 if (siblingNodes[i].SubMenu.length > 0) { 255 for (x in childrenNodes) { 256 childrenNodes[x]["Class"] = "wli-quicklink-child"; 257 quicklinkNodes.push(childrenNodes[x]); 258 } 259 } 260 } 261 262 if (siblingNodes[i].URL !== currentPage.URL) { 263 siblingNodes[i]["Class"] = "wli-quicklink-sibling"; 264 quicklinkNodes.push(siblingNodes[i]); 265 } 266 } 267 } 268 269 if (!this.CurrentPage.Parent) { 270 var childrenNodes = this.CurrentPage.SubMenu; 271 272 for (i in childrenNodes) { 273 quicklinkNodes.push(childrenNodes[i]); 274 } 275 } 276 } 277 278 for (i in quicklinkNodes) { 279 if (!quicklinkNodes[i].Target) { 280 quicklinkNodes[i].Target = ""; 281 } 282 283 if (!quicklinkNodes[i].Class) { 284 quicklinkNodes[i].Class = ""; 285 } 286 287 quicklinkHTML[i] = '<li class="' + quicklinkNodes[i].Class + '"><a href="'
288 + quicklinkNodes[i].URL + '" target="' + quicklinkNodes[i].Target 289 + '">' + quicklinkNodes[i].Name + '</a></li>'; 290 } 291 292 if (quicklinkHTML.length > 0) { 293 return '<ul class="wli-quicklinks">' + quicklinkHTML.join("") + '</ul>'; 294 } else { 295 return ""; 296 } 297}; 298 299 /** 300 * Method for generating a sitemap that shows all of the pages in the web menu. 301 * @param {object} [opts] - Optional object used to override default properties. 302 * @returns {string} - HTML String of the sitemap wrapped in <ul>. 303 */ 304 wli.WebMenu.prototype.Sitemap = function(opts) { 305 /** @type {Array} */ 306 var sitemapNodes = []; 307 308 /** @type {Array} */ 309 var sitemapHTML = []; 310 311 /** @type {Array} */ 312 var i; 313 314 /** @type {Array} */ 315 var level = 2; 316 317 /** @type {Object} */ 318 var settings = {}; 319 320 /** @type {Object} */ 321 var defaults = { 322 showRoot : false 323 }; 324 325 for (x in defaults) { 326 settings[x] = defaults[x]; 327 } 328 329 for (x in opts) { 330 settings[x] = opts[x]; 331 } 332 333 // Method processes 334 for (i in this.L2) { 335 if (typeof this.L2[i] !== "function") { 336 sitemapNodes.push(this.L2[i]); 337 338 if (this.L2[i].SubMenu.length > 0) { 339 level = 3; 340 } 341 } 342 } 343 344 for (i in sitemapNodes) { 345 if (!sitemapNodes[i].Target) { 346 sitemapNodes[i].Target = ""; 347 } 348 349 sitemapHTML[i] = '<li><a href="' + sitemapNodes[i].URL + '" ' 350 + 'target="' + sitemapNodes[i].Target + '">' 351 + sitemapNodes[i].Name + '</a>' + buildSiteMap(sitemapNodes[i].SubMenu) 352 + '</li>'; 353 } 354 355 /** 356 * Recursive function used for building the sitemap. 357 * @param {Object} menuItem - The SubMenu of a given node in the web menu. 358 * @returns {String} - HTML string of children nodes wrapped in <ul>. 359 */ 360 function buildSiteMap(menuItem) { 361 if (menuItem && menuItem.length < 1) { 362 return ""; 363 } 364 365 /** @type {Number} */ 366 var x; 367 368 /** @type {HTMLElement} */ 369 var ul = document.createElement("ul"); 370 371 for (x in menuItem) { 372 if (typeof menuItem[x] !== "function") { 373 level = menuItem[x].Level(); 374 375 var li = document.createElement("li"); 376 var a = document.createElement("a"); 377 var linktext = document.createTextNode(menuItem[x].Name); 378 379 a.href = menuItem[x].URL; 380 a.target = menuItem[x].Target; 381 382 a.appendChild(linktext); 383 li.appendChild(a); 384 385 ul.appendChild(li); 386 387 if (menuItem[x].SubMenu.length > 0) { 388 li.appendChild(jQuery(buildSiteMap(menuItem[x].SubMenu))[0]); 389 } 390 } 391 } 392 393 return "<ul>" + ul.innerHTML + "</ul>"; 394 } 395 396 /** 397 * Recursive function not currently used, intended use is for finding how many levels deep in web menu the page is. 398 * @param {Object} parentItem - The parent node of the current page in the web menu. 399 */ 400 function findSiteMapParent(parentItem) { 401 if (parentItem.Parent) { 402 level++; 403 findSiteMapParent(parentItem.Parent); 404 } 405 } 406 407 if (settings.showRoot === true) { 408 return '<ul class="wli-sitemap-root"><li><a href="' + this.Root.URL + '">' 409 + this.Root.Name + '</a>' 410 + '<ul class="wli-sitemap">' + sitemapHTML.join("") + '</ul></li></ul>'; 411 } 412 else { 413 return '<ul class="wli-sitemap">' + sitemapHTML.join("") + '</ul>'; 414 } 415 }; 416 417 /** 418 * Method for finding the current page in the supplied node tree object. 419 * @param {Object} tree - An object of web menu nodes to search through. 420 * @param {String} searchURL - The URL of the current page to look for in the tree argument. 421 * @returns {Object|String} - The node of the current page in the web menu or an empty string. 422 */ 423 wli.WebMenu.prototype.findCurrentPage = function(tree, searchURL) { 424 /** @type {Number} */ 425 var i; 426 427 for (i in tree) { 428 if (tree[i].URL == searchURL) { 429 return tree[i]; 430 } 431 else { 432 var node = this.findCurrentPage(tree[i].SubMenu, searchURL); 433 434 if (node) { 435 return node; 436 } 437 } 438 } 439 440 return ""; 441 }; 442 443 /** 444 * Method for finding the L2 node in the web menu of the current page. 445 * @param {Object} currentPage - The node of the current page in the web menu. 446 * @returns {Object|String} - The L2 node of the current page or an empty string. 447 */ 448 wli.WebMenu.prototype.findSectionName = function(currentPage) { 449 /** @type {Number} */ 450 var i; 451 452 for (i in this.L2) { 453 if (this.L2[i].URL == currentPage.URL) { 454 return currentPage; 455 } 456 } 457 458 if (currentPage.Parent) { 459 return this.findSectionName(currentPage.Parent); 460 } 461 462 return ""; 463 }; 464 465 /** 466 * Method for setting up all dynamic page elements pulled from the web menu. 467 * @param {Object} [opts] - Optional object used to override default properties. 468 */ 469 wli.WebMenu.prototype.PageSetup = function(opts) { 470 /** @type {Object} */ 471 var settings = {}; 472 473 /** @type {Object} */ 474 var defaults = { 475 componentURL : "", 476 componentPageTitle : "", 477 pageTitle : "", 478 sectionTitle : "", 479 breadcrumbs : "", 480 quicklinks : {}, 481 sitemap : "", 482 oldQuicklinks : false, 483 onComplete : function() {}, // Callback function to execute when page setup is complete. 484 }; 485 486 for (x in defaults) { 487 settings[x] = defaults[x]; 488 } 489 490 for (x in opts) { 491 settings[x] = opts[x]; 492 } 493 494 // Function processes 495 if (settings.componentPageTitle) { 496 if (this.CurrentPage != "" && this.CurrentPage.URL.indexOf(settings.componentURL) > -1) { 497 jQuery(settings.componentPageTitle).html(this.CurrentPage.Name); 498 } 499 } 500 501 if (settings.pageTitle) { 502 jQuery(settings.pageTitle).html(this.CurrentPage.Name); 503 } 504 505 if (settings.sectionTitle) { 506 jQuery(settings.sectionTitle).html(this.Section.Name); 507 } 508 509 if (settings.breadcrumbs) { 510 jQuery(settings.breadcrumbs).html(this.Breadcrumbs()); 511 } 512 513 if (!settings.oldQuicklinks) { 514 if (settings.quicklinks.target) { 515 var targetNode = document.querySelector(settings.quicklinks.nodeList); 516 517 wli.buildQuicklinks(targetNode, settings.quicklinks, 0); 518 }; 519 } 520 521 if (settings.oldQuicklinks) { 522 jQuery(settings.quicklinks.target).addClass("wli-old-quicklinks").html(this.Quicklinks()); 523 } 524 525 if (settings.sitemap) { 526 jQuery(settings.sitemap).html(this.Sitemap()); 527 } 528
529 if (settings.onComplete && typeof(settings.onComplete) == "function") { 530 settings.onComplete(); 531 } 532 }; 533 534 // Factory method for creating new instances of WebMenu() 535 /** 536 * Method for creating new instances of WebMenu() with a factory pattern. 537 * @param {String} domain - The home page URL or root domain URL of the website. 538 * @returns {Object} - A new instance of WebMenu(). 539 */ 540 wli.WebMenu.Create = function(domain) { 541 return new wli.WebMenu(domain); 542 }; 543 544 545 546/** 547 * Represents the functionality of the UI widgets on web pages. 548 * @constructor 549 * @param {String} domain - The URL that will be used to pull data from for the widgets. 550 * @property {String} Root - The URL that will be used to pull data from for the widgets. 551 */ 552wli.Widget = function(domain) { 553 this.Root = domain; 554}; 555 556 /** 557 * Method for making cross-domain API calls to obtain data used by the widgets. 558 * @param {Object} [opts] - Optional object used to override default properties. 559 */ 560 wli.Widget.prototype.XSLT = function(opts) { 561 /** @type {Number} */ 562 var x; 563 564 /** @type {Object} */ 565 var settings = {}; 566 567 /** 568 * Default options object used for base configuration options. 569 * @type {Object} 570 * @property {String} xmlURL - The path for the XML file. 571 * @property {String} xslURL - The path for the XSL file. 572 * @property {String} domainURL - The URL that will be used to pull data from for this widget. 573 * @property {String} fullURL - A full custom URL for the API call. 574 * @property {String} jsLoad - The location for API file. 575 * @property {String} target - The CSS/jQuery selector of DOM element that will receive the widget output. 576 * @property {Boolean} scrolling - Determines if the widget should be scrolling its content on the page. 577 * @property {Number} scrollingItemsToShow - The number of items to show at once while scrolling. 578 * @property {Function} onComplete - The callback function to execute after the widget has been rendered in the DOM. 579 */ 580 var defaults = { 581 xmlURL : "", 582 xslURL : "", 583 domainURL : this.Root, 584 fullURL : "", 585 jsLoad : "/WCControls/V12/WebDeps/Widgets/api/xsltransform_js-load.aspx", 586 target : "", 587 scrolling : false, 588 scrollingItemsToShow : 3, 589 onComplete : function() {} 590 }; 591 592 for (x in defaults) { 593 settings[x] = defaults[x]; 594 } 595 596 for (x in opts) { 597 settings[x] = opts[x]; 598 } 599 600 // Set order for asynchronous Ajax calls to execute on jsonp return 601 var jsonpIndex = wli.xsltIndexer.length + 1; 602 603 wli.xsltIndexer.push({ 604 id : jsonpIndex, 605 target : settings.target, 606 domainURL : settings.domainURL, 607 scrolling : settings.scrolling, 608 scrollingItemsToShow : settings.scrollingItemsToShow, 609 onComplete : settings.onComplete 610 }); 611 612 // Function Processes 613 var jsonpURL = 614 settings.domainURL + 615 "/external/" + 616 settings.jsLoad + 617 "?xmlurl=" + 618 encodeURIComponent(settings.xmlURL) + 619 "&xslurl=" + 620 encodeURIComponent(settings.xslURL) + 621 "&jsonp=wli.transformhandler&jsonp_param=" + 622 encodeURIComponent(jsonpIndex); 623 624 // When a full URL is provided to the js-load file, override the other 625 // options setting the domain and js-load file location 626 if (settings.fullURL) { 627 jsonpURL = settings.fullURL; 628 } 629 630 // Make the API call and ensure cross-domain requests are acceptable 631 jQuery.ajax({ 632 cache : false, 633 async : true, 634 url : jsonpURL, 635 dataType : "jsonp" 636 }); 637 }; 638 639 /** 640 * Method for creating a new instance of Widget() with a factory pattern. 641 * @param {String} domain - The URL that will be used to pull data from for the widgets. 642 * @returns {Object} - A new instance of Widget(). 643 */ 644 wli.Widget.Create = function(domain) { 645 return new wli.Widget(domain); 646 }; 647 648 649 650/** 651 * The index order of asynchronous callbacks for widget API calls. 652 * @type {Array} 653 */ 654wli.xsltIndexer = []; 655 656/** 657 * The callback handler function for widget API calls. 658 * @param {String} data - The stringified HTML returned by the API. 659 * @param {String} index - The stringified number value of the API call index returned by the API. 660 */ 661wli.transformhandler = function(data, index) { 662 var x; 663 var i; 664 var opts = {}; 665 666 for (x in wli.xsltIndexer) { 667 if (wli.xsltIndexer[x].id == index) { 668 for (i in wli.xsltIndexer[x]) { 669 opts[i] = wli.xsltIndexer[x][i]; 670 } 671 } 672 } 673 674 // Default settings 675 var settings = {}; 676 677 var defaults = { 678 target : "", 679 domainURL : "", 680 onComplete : false 681 }; 682 683 for (x in defaults) { 684 settings[x] = defaults[x]; 685 } 686 687 for (x in opts) { 688 settings[x] = opts[x]; 689 } 690 691 jQuery(settings.target).html(data); 692 693 if (settings.scrolling == true) { 694 if (jQuery(settings.target).length > 0) { 695 if (jQuery.isFunction(jQuery.fn.carouFredSel)) { 696 jQuery("[data-wli-role='scrolling']", settings.target).carouFredSel({ 697 items : settings.scrollingItemsToShow, 698 direction : "up", 699 scroll : { 700 items : 1, 701 duration : 1000 702 } 703 }); 704 } else {
705 jQuery.getScript(wli.widgetUrl + "/External/WCControls/V12/WebDeps/Widgets/scripts/caroufredsel.js").done(function() { 706 jQuery("[data-wli-role='scrolling']", settings.target).carouFredSel({ 707 items : settings.scrollingItemsToShow, 708 direction : "up", 709 scroll : { 710 items : 1, 711 duration : 1000 712 } 713 }); 714 }).fail(function() { 715 console.log("Failed to load Caroufredsel"); 716 }); 717 } 718 } 719 } 720 721 if ((settings.onComplete) && (typeof(settings.onComplete) === "function")) { 722 settings.onComplete(settings.domainURL); 723 } 724 725 if (wli.compUrl) { 726 jQuery("a", settings.target).each(function() { 727 this.href = this.href.replace(wli.widgetUrl, wli.compUrl) 728 }); 729 } 730}; 731 732 733 734/** 735 * Helper function for getting the value of known GET variables in the query string. 736 * @param {String} param - The GET variable being looked for in the URL. 737 * @returns {String} - The value of the GET variable being looked for in the URL. 738 */ 739wli.urlGET = function(param) { 740 var query = window.location.search.substring(1); 741 var variables = query.split("&"); 742 var i; 743 744 for (i = 0; i < variables.length; i++) { 745 var get = variables[i].split("="); 746 747 if (get[0] == param) { 748 return get[1]; 749 } 750 } 751 752 console.log("Query variable " + param + " not found"); 753 return ""; 754}; 755 756/** 757 * Function for removing existing inline styles, classes, and ID from existing node tree. NOTE: This mutates the passed nodeList. Only pass in what you want changed. 758 * @param {nodeList} elem - The passed nodeList to be scrubbed of style/classes/ID. 759 */ 760var topLevel = true; 761var foundOnce = false; 762var currURL = window.location.href; 763 764wli.ScrubAll = function(elem) { 765 if (jQuery(elem).hasClass("wsite-nav-current") || elem.id == "active" || elem.href == currURL) { 766 var currPage = true; 767 } 768 else { 769 var currPage = false; 770 } 771 if (elem.id) {elem.removeAttribute("id");} 772 if (elem.className) {elem.removeAttribute("class");} 773 if (elem.style) {elem.removeAttribute("style");} 774 775 if (topLevel) { 776 topLevel = false; 777 778 elem.className = "wli-div-level-0"; 779 } 780 else { 781 var parentDiv = jQuery(elem).parents("div")[0].className; 782 783 if (elem.tagName == "DIV") { 784 var currNum = parentDiv.replace("wli-div-level-", ""); 785 currNum++; 786 elem.className = "wli-div-level-" + currNum; 787 }; 788 789 if (elem.tagName == "SPAN") { 790 if ( /^[<>]{1}$/.test( elem.innerText.trim() ) ) { 791 elem.innerHTML = ""; 792 }; 793 }; 794 795 if (elem.tagName == "UL") { 796 elem.className = parentDiv.replace("div", "ul"); 797 }; 798 799 if (elem.tagName == "LI") { 800 if (currPage) { 801 jQuery(elem).addClass("wli-current-list-item"); 802 jQuery(elem).closest("ul").addClass("wli-current-list"); 803 } 804 else { 805 elem.className = parentDiv.replace("div", "li"); 806 }; 807 }; 808 809 if (elem.tagName == "A") { 810 if ( jQuery(elem).parent(".wli-current-list-item").length > 0 || currPage ) { 811 if (!foundOnce) { 812 elem.className = "wli-current-page"; 813 jQuery(elem).parents("li").addClass("active"); 814 foundOnce = true; 815 }; 816 }; 817 }; 818 819 if (elem.tagName == "BUTTON") { 820 elem.style = "display: none"; 821 } 822 }; 823 824 if (elem.children) { 825 for ( var i = elem.children.length - 1, j = 0; i >= j; j++ ) { 826 wli.ScrubAll( elem.children[j] ); 827 }; 828 }; 829 }; 830 831 wli.buildQuicklinks = function(targetNode,quicklinksObj, retryTimes) { 832 if (targetNode != null) { 833 var copiedNode = targetNode.cloneNode(true); 834 wli.ScrubAll(copiedNode); 835 836 if (quicklinksObj.title) { 837 var quicklinksTitle = document.createElement("h2"); 838 var quicklinksTitleText = document.createTextNode(quicklinksObj.title); 839 840 quicklinksTitle.appendChild(quicklinksTitleText); 841 jQuery(copiedNode).prepend(quicklinksTitle); 842 }; 843 jQuery(quicklinksObj.target).html(copiedNode); 844 } 845 846 if (targetNode == null && retryTimes < 20) { 847 wli.wait(200).then(function() { 848 targetNode = document.querySelector(quicklinksObj.nodeList); 849 850 wli.buildQuicklinks(targetNode,quicklinksObj, retryTimes + 1); 851 }); 852 } 853 854 if (targetNode == null && retryTimes >= 20) { 855 console.log("Cannot find the node with selector " + quicklinksObj.nodeList + ", please make sure mobileNavContainer has been updated with the proper selector."); 856 } 857 }; 858 859/** 860 * Helper function for correcting relative path URLs on background-images scraped from cross-domain web pages. 861 * @param {Object} opts - Optional object used to override default properties. 862 */ 863wli.ImageCorrect = function(opts) { 864 /** 865 * Iterator variable for use in loops. 866 * @type {Number} 867 */ 868 var x; 869 870 /** 871 * Settings object used for storing configuration options. 872 * @type {Object} 873 */ 874 var settings = {}; 875 876 /** 877 * Default options object used for base configuration options. 878 * @type {Object} 879 * @property {String} target - The CSS/jQuery selector of DOM element that needs a background-image corrected. 880 * @property {String} wrongDomain - The URL of the erroneous domain caused by relative pathing in CSS on the scraped web page. 881 * @property {String} rightDomain - The URL of the correct domain where the background-image files are located. 882 */ 883 var defaults = { 884 target : "", 885 wrongDomain : "", 886 rightDomain : "" 887 }; 888 889 for (x in defaults) { 890 settings[x] = defaults[x]; 891 } 892 893 for (x in opts) { 894 settings[x] = opts[x]; 895 } 896 897 var wrongDomain = settings.wrongDomain.toLowerCase(); 898 var rightDomain = settings.rightDomain.toLowerCase(); 899 900 jQuery(settings.target).each(function() { 901 var relativeURL = jQuery(this).css("background-image"); 902 if (relativeURL.indexOf(wrongDomain) > -1 && relativeURL.indexOf("repeater.aspx") == -1) { 903 var fixedURL = relativeURL.replace(wrongDomain, rightDomain); 904 var currentInlineStyles = jQuery(this).attr("style"); 905 if (currentInlineStyles == null) { currentInlineStyles = ""; }; 906 var fixedInlineStyles = currentInlineStyles + "background-image: " + fixedURL + " !important;"; 907 jQuery(this).attr("style", fixedInlineStyles); 908 }; 909 }); 910}; 911 912 913/** 914 * Initiate a marquee style image rotator for client sponsor images on the web page. 915 * @param {Object} opts - Optional object used to override default properties. 916 */ 917wli.SponsorScroll = function(opts) { 918 /** 919 * Iterator variable for use in loops. 920 * @type {Number} 921 */ 922 var x; 923 924 /** 925 * Settings object used for storing configuration options. 926 * @type {Object} 927 */ 928 var settings = {}; 929 930 /** 931 * Default options object used for base configuration options. 932 * @type {Object} 933 * @property {String} target - The CSS/jQuery selector of DOM element that contains sponsor images to be scrolled. 934 */ 935 var defaults = { 936 target : "", 937 scrollSpeed : 1, 938 mouseScrollSpeed : 1, 939 }; 940 941 for (x in defaults) { 942 settings[x] = defaults[x]; 943 } 944 945 for (x in opts) { 946 settings[x] = opts[x]; 947 } 948 949 jQuery("img", settings.target).load(function() { 950 wli.wait(50).then(function() { 951 marqueeInit({ 952 uniqueid: "sponsor-crawler", 953 inc: settings.mouseScrollSpeed, //speed - pixel increment for each iteration of this marquee's movement
954 mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false) 955 moveatleast: settings.scrollSpeed, 956 neutral: 150, 957 persist: true, 958 savedirection: true 959 }); 960 }); 961 }); 962}; 963 964 965/** 966 * Helper function used for handling timeout requests with jQuery's promise/deferred pattern. 967 * @param {Number} ms - The number of milliseconds to wait until resolving the returned promise. 968 * @returns {Object} - A promise object that will be resolved after the supplied number of milliseconds have passed. 969 */ 970wli.wait = function(ms) { 971 /** 972 * The deferred object to resolve after the supplied number of milliseconds have passed. 973 * @type {Object} 974 */ 975 var deferred = new jQuery.Deferred(); 976 977 setTimeout(deferred.resolve, ms); 978 979 return deferred.promise(); 980}; 981 982wli.updateSlider = function(direction) { 983 var activeIndex = 0; 984 985 for (var i = wli.featuredSlidesArray.length - 1; i >= 0; i--) { 986 if (jQuery(wli.featuredSlidesArray[i]).hasClass("featured-active")) { 987 activeIndex = i; 988 } 989 } 990 991 if (!isNaN(direction)) { 992 oldIndex = activeIndex; 993 activeIndex = Number(direction) - 1; 994 995 if (oldIndex == activeIndex) { 996 return; 997 } 998 999 jQuery(wli.featuredSlidesArray).removeClass("featured-visible"); 1000 1001 if (oldIndex < activeIndex) { 1002 for (var i = oldIndex; i < activeIndex; i++) { 1003 jQuery(wli.featuredSlidesArray[i]).addClass("featured-left").removeClass("featured-right"); 1004 }; 1005 1006 jQuery(wli.featuredSlidesArray[oldIndex]).addClass("featured-visible").removeClass("featured-active"); 1007 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-active featured-visible").removeClass("featured-right"); 1008 } 1009 1010 if (oldIndex > activeIndex) { 1011 for (var i = oldIndex; i > activeIndex; i--) { 1012 jQuery(wli.featuredSlidesArray[i]).addClass("featured-right").removeClass("featured-left"); 1013 }; 1014 1015 jQuery(wli.featuredSlidesArray[oldIndex]).addClass("featured-visible").removeClass("featured-active"); 1016 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-active featured-visible").removeClass("featured-left"); 1017 } 1018 } 1019 1020 if (direction == "right") { 1021 if (activeIndex != 0) { 1022 jQuery(wli.featuredSlidesArray).removeClass("featured-visible"); 1023 1024 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-right featured-visible").removeClass("featured-active"); 1025 activeIndex -= 1; 1026 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-active featured-visible").removeClass("featured-left"); 1027 } 1028 }; 1029 1030 if (direction == "left") { 1031 if (activeIndex != wli.featuredSlidesArray.length - 1) { 1032 jQuery(wli.featuredSlidesArray).removeClass("featured-visible"); 1033 1034 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-left featured-visible").removeClass("featured-active"); 1035 activeIndex += 1;
1036 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-active featured-visible").removeClass("featured-right"); 1037 } 1038 }; 1039 1040 if (direction == "initialize") { 1041 jQuery(wli.featuredSlidesArray[activeIndex]).addClass("featured-active featured-visible").removeClass("featured-right"); 1042 } 1043 1044 if (activeIndex == 0) { 1045 jQuery(".featured-event-nav-left").addClass("featured-invisible"); 1046 } else { 1047 jQuery(".featured-event-nav-left").removeClass("featured-invisible"); 1048 } 1049 1050 if (activeIndex == wli.featuredSlidesArray.length - 1) { 1051 jQuery(".featured-event-nav-right").addClass("featured-invisible"); 1052 } else { 1053 jQuery(".featured-event-nav-right").removeClass("featured-invisible"); 1054 } 1055 1056 jQuery(".featured-event-nav-item").removeClass("active-item"); 1057 jQuery(".nav-item-" + (activeIndex + 1)).addClass("active-item"); 1058}; 1059 1060wli.getTallestHeight = function(elemArr) { 1061 var tallest = 0; 1062 1063 for (var i = elemArr.length - 1; i >= 0; i--) {; 1064 tallest = Math.max(tallest, jQuery(elemArr[i]).outerHeight()); 1065 }; 1066 1067 return tallest; 1068} 1069 1070wli.normalizeWidth = function(elemArr) { 1071 var widestWidth = 0; 1072 1073 jQuery(elemArr).each(function() { 1074 widestWidth = Math.max(this.getBoundingClientRect().width, widestWidth); 1075 }); 1076 1077 jQuery(elemArr).width(widestWidth + 1); 1078}; 1079 1080wli.widgetTypes = { 1081 "event-plain" : { 1082 EntityId : '0', 1083 maxResults : 5, 1084 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events.aspx", 1085 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events.xsl" 1086 }, 1087 "event-block" : { 1088 EntityId : '0', 1089 maxResults : 5, 1090 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events2.aspx", 1091 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events2.xsl" 1092 }, 1093 "event-block-type" : { 1094 EntityId : '0', 1095 maxResults : 5, 1096 eventType : "%", 1097 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events-type.aspx", 1098 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-events-type.xsl" 1099 }, 1100 "event-featured" : { 1101 EntityId : '0', 1102 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-featured-events.aspx", 1103 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-featured-events.xsl", 1104 onComplete : function() { 1105 wli.featuredSlidesArray = jQuery(".wli-featured-event-item").toArray(); 1106 1107 if (wli.featuredSlidesArray.length > 1) { 1108 jQuery(".featured-event-nav-right").click(function() { 1109 wli.updateSlider("left"); 1110 }); 1111 1112 jQuery(".featured-event-nav-left").click(function() { 1113 wli.updateSlider("right"); 1114 }); 1115 1116 jQuery(".featured-event-nav-item").click(function() { 1117 wli.updateSlider(this.dataset.wliNavItem); 1118 }); 1119 } else { 1120 jQuery(".featured-event-nav-left, .featured-event-nav-right").remove(); 1121 }; 1122 1123 wli.updateSlider("initialize"); 1124 1125 jQuery(".wli-featured-event-description").each(function() { 1126 jQuery(this).html(jQuery(this).text()); 1127 }); 1128 1129 var tallestHeight = wli.getTallestHeight(wli.featuredSlidesArray); 1130 1131 jQuery(".wli-featured-event-slide-container").height(tallestHeight); 1132 1133 jQuery(window).on("load resize", function() { 1134 if (jQuery(window).width() <= 1024) { 1135 jQuery(".wli-featured-event-image-container, .wli-dettailed-event-details-container").css("display", "table-row"); 1136 jQuery(".wli-featured-event-address-container, .wli-featured-event-datetime-container").addClass("centerFullWidth"); 1137 } else { 1138 jQuery(".wli-featured-event-image-container, .wli-dettailed-event-details-container").css("display", "table-cell"); 1139 jQuery(".wli-featured-event-address-container, .wli-featured-event-datetime-container").removeClass("centerFullWidth"); 1140 }; 1141 1142 var tallestHeight = wli.getTallestHeight(wli.featuredSlidesArray); 1143 1144 jQuery(".wli-featured-event-slide-container").height(tallestHeight); 1145 }); 1146 } 1147 }, 1148 "event-org-plain" : { 1149 EntityId : '0', 1150 maxResults : 5, 1151 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-org-events.aspx",
1152 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-org-events.xsl" 1153 }, 1154 "event-com-plain" : { 1155 EntityId : '0', 1156 maxResults : 5, 1157 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-community-events.aspx", 1158 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-community-events.xsl" 1159 }, 1160 "event-org-block" : { 1161 EntityId : '0', 1162 maxResults : 5, 1163 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-org-events2.aspx", 1164 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-org-events2.xsl" 1165 }, 1166 "event-com-block" : { 1167 EntityId : '0', 1168 maxResults : 5, 1169 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-community-events2.aspx", 1170 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-community-events2.xsl" 1171 }, 1172 "event-mo-block" : { 1173 EntityId : '0', 1174 maxResults : 5, 1175 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-member-events.aspx", 1176 xslURL : "/External/WCControls/V12/WebDeps/Widgets/events/wli-member-events.xsl" 1177 }, 1178 "jobs-plain" : { 1179 maxResults : 5, 1180 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/jobs/wli-job-openings.aspx", 1181 xslURL : "/External/WCControls/V12/WebDeps/Widgets/jobs/wli-job-openings.xsl" 1182 }, 1183 "members-plain" : { 1184 EntityId : '0', 1185 maxResults : 5, 1186 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/members/wli-new-members.aspx", 1187 xslURL : "/External/WCControls/V12/WebDeps/Widgets/members/wli-new-members.xsl" 1188 }, 1189 "members-block" : { 1190 EntityId : '0', 1191 maxResults : 3, 1192 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/members/wli-new-members2.aspx", 1193 xslURL : "/External/WCControls/V12/WebDeps/Widgets/members/wli-new-members2.xsl" 1194 }, 1195 "news-plain" : { 1196 articleType : '%', 1197 maxResults : 5, 1198 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/news/wli-news.aspx", 1199 xslURL : "/External/WCControls/V12/WebDeps/Widgets/news/wli-news.xsl" 1200 }, 1201 "news-block" : { 1202 articleType : '%', 1203 maxResults : 5, 1204 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/news/wli-news2.aspx", 1205 xslURL : "/External/WCControls/V12/WebDeps/Widgets/news/wli-news2.xsl" 1206 }, 1207 "sponsor-plain" : { 1208 contenttypeid : 11, 1209 xmlURL : "/External/WCControls/V12/WebDeps/Widgets/sponsor/wli-sponsors.aspx", 1210 xslURL : "/External/WCControls/V12/WebDeps/Widgets/sponsor/wli-sponsors.xsl", 1211 onComplete : function() { 1212 if (typeof marqueeInit !== "function") { 1213 var sponsorScript = document.createElement('script'); 1214 1215 sponsorScript.src = wli.widgetUrl + "/External/WCControls/V12/WebDeps/Widgets/scripts/crawler.js"; 1216 1217 sponsorScript.onload = function () { 1218 wli.SponsorScroll({ 1219 target : ".wli-sponsor-scroller", 1220 scrollSpeed : 1, 1221 mouseScrollSpeed : 5 1222 }); 1223 }; 1224 1225 document.head.appendChild(sponsorScript); 1226 } else { 1227 wli.SponsorScroll({ 1228 target : ".wli-sponsor-scroller", 1229 scrollSpeed : 1, 1230 mouseScrollSpeed : 5 1231 }); 1232 }; 1233 } 1234 } 1235} 1236 1237wli.queryStringBuilder = function(arr) { 1238 for (var i = 0, j = arr.length; i < j; i++) { 1239 arr[i] = encodeURI(arr[i]); 1240 } 1241 1242 return "?" + arr.join("&"); 1243} 1244 1245wli.widgetWrapper = function(obj) { 1246 var currObj = {}; 1247 for (setting in obj) { 1248 currObj[setting] = obj[setting]; 1249 } 1250 1251 if (currObj.widgetType) { 1252 for (setting in wli.widgetTypes[currObj.widgetType]) { 1253 currObj[setting] = wli.widgetTypes[currObj.widgetType][setting]; 1254 } 1255 }; 1256 1257 if (currObj.target) { 1258 if (jQuery(currObj.target).length > 0) { 1259 var elemData = jQuery(currObj.target).data(); 1260 } else { 1261 return 1262 } 1263 } else { 1264 console.log("Widget called without a target"); 1265 return 1266 }; 1267 1268 if (currObj.xmlURL) { 1269 var qsArr = []; 1270 1271 if (elemData.wliGet) { 1272 qsArr.push("maxresults=" + elemData.wliGet); 1273 } 1274 else if (currObj.maxResults) { 1275 qsArr.push("maxresults=" + currObj.maxResults); 1276 }; 1277 1278 if (elemData.wliEventType) { 1279 qsArr.push("eventtype=" + elemData.wliEventType); 1280 } 1281 else if (currObj.eventType) { 1282 qsArr.push("eventtype=" + currObj.eventType); 1283 }; 1284 1285 if (elemData.wliEntityId) { 1286 qsArr.push("entityid=" + elemData.wliEntityId); 1287 } 1288 else if (currObj.EntityId) { 1289 qsArr.push("entityid=" + currObj.EntityId); 1290 }; 1291 1292 if (elemData.wliArticleType) { 1293 qsArr.push("articletype=" + elemData.wliArticleType); 1294 } else if (currObj.articleType) { 1295 qsArr.push("articletype=" + currObj.articleType); 1296 }; 1297 1298 if (elemData.wliWidget == "sponsor-plain") { 1299 if (elemData.wliContentTypeId) { 1300 qsArr.push("contenttypeid=" + elemData.wliContentTypeId); 1301 } else { 1302 qsArr.push("contenttypeid=11"); 1303 } 1304 1305 if (elemData.wliElementName) { 1306 qsArr.push("element=" + elemData.wliElementName); 1307 } 1308 else { 1309 qsArr.push("element=sponsor"); 1310 } 1311 }; 1312 1313 if (elemData.wliWidget == "members-plain" || elemData.wliWidget == "members-block") { 1314 if (elemData.wliDaysNew) { 1315 qsArr.push("membersince=" + elemData.wliDaysNew); 1316 } else { 1317 qsArr.push("membersince=45"); 1318 } 1319 } 1320 1321 currObj.xmlURL = currObj.xmlURL + wli.queryStringBuilder(qsArr); 1322 } else { 1323 console.log("Widget called without xmlURL"); 1324 return 1325 } 1326 1327 if (currObj.xslURL) { 1328 1329 } else { 1330 console.log("Widget called without xslURL"); 1331 return 1332 } 1333 1334 if (elemData.wliScrolling) { 1335 currObj.scrolling = true; 1336 } 1337 1338 if (elemData.wliShow) { 1339 currObj.scrollingItemsToShow = Number(elemData.wliShow); 1340 } 1341 1342 wli.Widget.Create(wli.widgetUrl).XSLT(currObj); 1343} 1344 1345jQuery("[data-wli-widget]").each(function() { 1346 var currObj = { 1347 "target" : this, 1348 "widgetType" : this.dataset.wliWidget 1349 } 1350 1351 wli.widgetWrapper(currObj); 1352}); 1353 1354wli.WebMenu.Create(wli.homeUrl).PageSetup({ 1355 breadcrumbs : ".wli-breadcrumbs-container", 1356 sitemap : ".wli-sitemap-container" 1357});
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.