1var FIX = FIX || {}; 2 3FIX.addEventListener = function(el, type, callback) { 4 if (typeof el.addEventListener === 'function') { 5 el.addEventListener(type, callback, false); 6 } 7 else if (typeof el.attachEvent === 'object' && el.attachEvent !== null) { 8 el.attachEvent('on'+type, callback); 9 } 10}; 11 12 13FIX.removeEventListener = function(el, type, callback) { 14 if (typeof el.removeEventListener === 'function') { 15 el.removeEventListener(type, callback, false); 16 } 17 else if (typeof el.detachEvent === 'object' && el.detachEvent !== null) { 18 el.detachEvent('on' + type, callback); 19 } 20}; 21 22FIX.pageWrapperHeight = 0; 23FIX.designMode = FIX.designMode || ""; 24FIX.passwordProtection = "none"; 25FIX.headerHeight = 0; 26FIX.isFixedHeader = false; 27 28// gets a number value for a given property describing box model dimensions 29FIX.getBoxPropertyValue = function(el, property) { 30 var camelProperties = { 31 'padding-top' : 'paddingTop', 32 'padding-right' : 'paddingRight', 33 'padding-bottom' : 'paddingBottom', 34 'padding-left' : 'paddingLeft', 35 'border-top-width' : 'borderTopWidth', 36 'border-right-width' : 'borderRightWidth', 37 'border-bottom-width' : 'borderBottomWidth', 38 'border-left-width' : 'borderLeftWidth', 39 'margin-top' : 'marginTop', 40 'margin-right' : 'marginRight', 41 'margin-bottom' : 'marginBottom', 42 'margin-left' : 'marginLeft', 43 'width' : 'width' 44 }; 45 if (!camelProperties[property]) { 46 throw new Error('FIX unknown property "'+property+'".'); 47 } 48 49 var styleValue = ''; 50 51 if (typeof window.getComputedStyle === 'function') { 52 styleValue = parseInt(window.getComputedStyle(el, null).getPropertyValue(property), 10); 53 } 54 else if (typeof el.currentStyle === 'object' && el.currentStyle !== null) { 55 styleValue = parseInt(el.currentStyle[camelProperties[property]], 10); 56 } 57 58 // margins and borders should be numbers, 59 // however on IEs and Opera values as 'auto' or 'none' can't be converted to Number 60 if (isNaN(styleValue)) { 61 styleValue = 0; 62 } 63 64 return styleValue; 65}; 66 67// finds .Liner (section's inner wrapper) for a given section ID 68FIX.findLiner = function(parentId) { 69 var parent = document.getElementById(parentId); 70 if (!parent) { 71 return; 72 } 73 var el = parent.firstChild; 74 while (el) { 75 if (/(^|\s)Liner(\s|$)/.test(el.className)) { 76 return el; 77 } 78 el = el.nextSibling; 79 } 80}; 81 82FIX.computeHeightForLiner = function(el, height) { 83 var verticalPadding = FIX.getBoxPropertyValue(el, 'padding-top') + 84 FIX.getBoxPropertyValue(el, 'padding-bottom'); 85 var verticalBorder = FIX.getBoxPropertyValue(el, 'border-top-width') + 86 FIX.getBoxPropertyValue(el, 'border-bottom-width'); 87 var topMargin = FIX.getBoxPropertyValue(el, 'margin-top'); 88 89 return height - verticalPadding - verticalBorder - topMargin; 90}; 91 92FIX.computeAvailableWidth = function(el) { 93 var horizontalPadding = FIX.getBoxPropertyValue(el, 'padding-left') + 94 FIX.getBoxPropertyValue(el, 'padding-right'); 95 96 return el.clientWidth - horizontalPadding; 97}; 98 99// sets min-height (height for IE6) for columns' liners to make all columns equally long 100FIX.fixLiners = function() { 101 var pageWrapper = document.getElementById('PageWrapper'); 102 var ids = ['ContentColumn', 'NavColumn', 'ExtraColumn']; 103 var highestLinerHeight = 0; 104 var liners = []; 105 var id; 106 var liner; 107 var i, ilen; 108 var linerNewHeight; 109 110 // find the longest liner 111 for (i=0, ilen=ids.length; i<ilen; i++) { 112 id = ids[i]; 113 liner = FIX.findLiner(id); 114 if (liner) { 115 var linerTopMargin = FIX.getBoxPropertyValue(liner, 'margin-top'); 116 var linerHeight = liner.offsetHeight + linerTopMargin; 117 liners.push(liner); 118 if (linerHeight > highestLinerHeight) { 119 highestLinerHeight = linerHeight; 120 } 121 } 122 } 123 124 // make all liners equally long 125 for (i=0, ilen=liners.length; i<ilen; i++) { 126 liner = liners[i]; 127 if (liner) { 128 linerNewHeight = FIX.computeHeightForLiner(liner, highestLinerHeight); 129 if (linerNewHeight > 0) { 130 linerNewHeight = linerNewHeight + 'px'; 131 // check if the browser understands min-height 132 // by checking maxHeight property for body 133 // as checking minHeight will not detect not understanding max/min height by IE6 134 if (typeof document.body.style.maxHeight === "undefined") { 135 // IE 6 136 liner.style.height = linerNewHeight; 137 } 138 else { 139 liner.style.minHeight = linerNewHeight; 140 } 141 } 142 } 143 } 144 145 // set pageWrapper height to check later if it has changed (i.e. because of 3rd party scripts) 146 FIX.pageWrapperHeight = pageWrapper.offsetHeight; 147}; 148 149FIX.scrollIntoViewHash = function() { 150 var el = document.getElementById(window.location.hash.replace("#", "")); 151 if (el) { 152 var y = el.offsetTop; 153 while (el = el.offsetParent) { 154 y += el.offsetTop; 155 } 156 setTimeout(function() { 157 window.scrollTo(0, y - FIX.headerHeight); 158 }, 500); 159 } 160}; 161 162FIX.scrollIntoViewHashLinks = function () { 163 var links = document.getElementsByTagName("a"); 164 165 function scrollWithOffset(event, el, href) { 166 var url = window.location.href; 167 var baseAhref = href.substr(0, href.indexOf("#")); 168 var baseUrl = url.substr(0, url.indexOf("#")) || url; 169 if (baseAhref !== baseUrl) { 170 // return if not the same page anchor link 171 return true; 172 } 173 174 var y = el.offsetTop; 175 while (el = el.offsetParent) { 176 y += el.offsetTop; 177 } 178 179 window.scrollTo(0, y - FIX.headerHeight); 180 181 if (event.preventDefault) { 182 event.preventDefault(); 183 } else { 184 event.returnValue = false; // IE8 185 } 186 return false;
187 } 188 189 for (var i = 0, ilen = links.length; i < ilen; i++) { 190 var ahref = links[i].href; 191 192 if (ahref.indexOf("#") > 0) { 193 var anchorId = ahref.substr(ahref.indexOf("#") + 1, ahref.length); 194 var el = document.getElementById(anchorId); 195 if (el) { 196 (function (alink, element) { 197 FIX.addEventListener(alink, 'click', function (event) { 198 scrollWithOffset(event, element, alink.href); 199 }, false); 200 }(links[i], el)) 201 } 202 } 203 } 204}; 205 206FIX.doEndOfBody = function() { 207 var pageWrapper = document.getElementById('PageWrapper'); 208 if (!pageWrapper) { 209 return; // quit silently when page is not a standard SS template (just in case) 210 } 211 212 var startLoop = function() { 213 var counter = 0; 214 var max = 120; 215 var delay = 500; 216 var loop = function() { 217 counter++; 218 if (counter > max) { 219 return; 220 } 221 pageWrapper = document.getElementById('PageWrapper'); 222 // check if pageWrapper height has changed 223 if (pageWrapper.offsetHeight !== FIX.pageWrapperHeight) { 224 FIX.fixLiners(); 225 } 226 setTimeout(function() { 227 loop(); 228 }, delay); 229 }; 230 loop(); 231 }; 232 233 FIX.fixEzine2LabelWidth(); 234 FIX.responsiveVideo(); 235 236 window.addEventListener("resize", FIX.fixEzine2LabelWidth, true); 237 238 if ((typeof MOBILE === 'undefined' || MOBILE.viewMode !== 'mobile') && FIX.isFixedHeader) { 239 FIX.headerHeight = document.getElementById("Header").offsetHeight; 240 FIX.scrollIntoViewHashLinks(); 241 } 242 243 if (window.location.hash) { 244 FIX.addEventListener(window, 'load', FIX.scrollIntoViewHash); 245 } 246 247 // fix liners height only for legacy templates 248 if (FIX.designMode === "legacy") { 249 // fix liners height right away 250 if (typeof MOBILE === 'undefined' || MOBILE.viewMode !== 'mobile') { 251 FIX.fixLiners(); 252 // do fixLiners once again when all images are loaded as this may affect columns' height 253 // and also run it a few more times in a loop (against 3rd party scripts that may extend a page) 254 if (document.readyState === "complete") { 255 // if the page is already loaded (i.e. for protected content) 256 startLoop(); 257 } else { 258 FIX.addEventListener(window, 'load', startLoop); 259 } 260 } 261 } 262 263 FIX.horizontalNavbar(); 264}; 265 266FIX.track = function (anchorEl) { 267 if (/sbi[^.]+.?\.sitesell\.com/.test(window.location.href)) { 268 return true; // we don't want to track links in preview 269 } 270 else { 271 var anchorElHref = /href="(.*?)"/g.exec(anchorEl.outerHTML)[1]; 272 var path = anchorElHref.split("/").slice(3).join("/"); 273 var matches = anchorElHref.match(/^https?\:\/\/([^\/]+)/); 274 var thisDomain = window.location.hostname.replace(/^www\./, ""); 275 if (matches && 276 (thisDomain !== matches[1].substr(-thisDomain.length)) && // local link 277 (!/google/.test(matches[1])) && // don't include TLD ".com" because don't want to track "google.ca" either 278 (!/\.mp4|\.avi|\.css|\.doc|\.docx|\.dot|\.dotx|\.exe|\.flv|\.gif|\.jpeg|\.jpg|\.js|\.mov|\.mp3|\.mp4|\.mpeg|\.mpg|\.png|\.potx|\.pps|\.ppsx|\.ppt|\.pptx|\.qt|\.ra|\.ram|\.rm|\.swf|\.tex|\.txt|\.wav|\.wma|\.wmv|\.xls|\.xlsx|\.xlt|\.xltx|\.xml|\.zip/.test(path)) // media link 279 ) { 280 // The link is an external, non-media and non-google link. We want to track this click. 281 var url = '/cgi-bin/counter.pl?url=' + encodeURIComponent(anchorElHref) + '&referrer=' + encodeURIComponent(window.location); 282 if (anchorEl.target.toLowerCase() === '_blank') { 283 window.open(url); 284 } 285 else { 286 window.location.href = url; 287 } 288 return false; 289 } 290 else { 291 return true; 292 } 293 } 294}; 295 296// password protection 297var getMsg = (function() { 298 var original = getMsg; 299 return function(form) { 300 var result = original(form); 301 if (document.getElementById('ProtectedContent').style.display === 'block') { 302 FIX.passwordProtection = "off"; 303 FIX.doEndOfBody(); 304 } 305 return result; 306 }; 307}()); 308 309// IE fix for start index negative values in substr 310if ('ab'.substr(-1) != 'b') { 311 String.prototype.substr = function(substr) { 312 return function(start, length) { 313 // did we get a negative start, calculate how much it is from the beginning of the string 314 if (start < 0) start = this.length + start; 315 316 // call the original function 317 return substr.call(this, start, length); 318 } 319 } (String.prototype.substr); 320} 321 322FIX.getByClassName = function(cn){ 323 var arr = []; 324 var els = document.getElementsByTagName("*"); 325 var exp = new RegExp("^(.* )?"+cn+"( .*)?$", "g"); 326 for (var i = 0; i < els.length; i++ ){ 327 if (exp.test(els[i].className)){ 328 arr.push(els[i]); 329 } 330 } 331 return arr; 332}; 333 334FIX.horizontalNavBarWide = function() { 335 if (document.all && !document.querySelector) { 336 var wideHorizontalNavs = FIX.getByClassName("HorizontalNavBarWide"); 337 for(var i = 0, ilen = wideHorizontalNavs.length; i < ilen; i++) { 338 wideHorizontalNavs[i].className = wideHorizontalNavs[i].className.replace("HorizontalNavBarWide", "HorizontalNavBarCenter"); 339 } 340 } 341}; 342 343FIX.horizontalNavDropDownOn = {}; 344FIX.horizontalNavDropDownOff = {}; 345FIX.horizontalNavDropDownForceOn = {}; 346 347FIX.horizontalNavbar = function() { 348 var horizontalNavs = FIX.getByClassName("HorizontalNavBar"); 349 var horizontalNavEntered = [];
350 var delay = 350; 351 var mobile = /iPhone|iPod|iPad|BlackBerry|PlayBook|Touch|Android|Silk/.test(navigator.userAgent); 352 var ie6 = (typeof document.body.style.maxHeight === 'undefined'); 353 354 function showSubmenu(li) { 355 li.className += " hover"; 356 } 357 358 function hideSubmenu(li) { 359 li.className = li.className.replace(/(^|\s+)hover/, ''); 360 } 361 362 function hideTheSameLevelSubmenus(nav, level) { 363 var exp = new RegExp("li"+ level); 364 var lis = nav.getElementsByTagName("li"); 365 for (var i = 0, ilen = lis.length; i < ilen; i++) { 366 var liClassName = lis[i].className; 367 if (liClassName.match(/hover/) && liClassName.match(exp)) { 368 hideSubmenu(lis[i]); 369 } 370 } 371 } 372 373 // hide submenus on mobile (tap outside the navigation) 374 if (mobile) { 375 function hideSubmenuMobile() { 376 var hovers = document.querySelectorAll(".HorizontalNavBar .hover"); 377 for(var i = 0, ilen = hovers.length; i < ilen; i++) { 378 hovers[i].className = hovers[i].className.replace(/(^|\s+)hover/, ''); 379 } 380 } 381 function revertPointers() { 382 var pointers = document.querySelectorAll(".navheader b"); 383 for(var i = 0, ilen = pointers.length; i < ilen; i++) { 384 } 385 } 386 387 var pageWrapper = document.getElementById("PageWrapper"); 388 FIX.addEventListener(pageWrapper, 'click', function() { 389 hideSubmenuMobile(); 390 revertPointers(); 391 }); 392 } 393 394 for(var i = 0, ilen = horizontalNavs.length; i < ilen; i++) { 395 // remove CSS support of drop down 396 horizontalNavs[i].className = horizontalNavs[i].className.replace("HorizontalNavBarCSS", ""); 397 398 // stop propagating touchend outside navigation wrappers 399 if (mobile) { 400 (function(nav) { 401 nav.addEventListener("touchend", function(e) { 402 e.stopPropagation(); 403 }, false); 404 }(horizontalNavs[i])); 405 } 406 407 // a flag to control whether to use delay (navigation not entered yet) or show submenus instantly 408 horizontalNavEntered.push(false); 409 410 var horizontalNavDelayOn; 411 var horizontalNavDelayOff; 412 413 (function(nav, i) { 414 var timer = null; 415 horizontalNavDelayOn = function() { 416 clearTimeout(timer); 417 timer = setTimeout(function() { 418 horizontalNavEntered[i] = true; 419 }, delay); 420 }; 421 horizontalNavDelayOff = function() { 422 clearTimeout(timer); 423 timer = setTimeout(function() { 424 horizontalNavEntered[i] = false; 425 }, delay); 426 }; 427 428 FIX.addEventListener(nav, 'mouseover', horizontalNavDelayOn); 429 FIX.addEventListener(nav, 'mouseout', horizontalNavDelayOff); 430 431 }(horizontalNavs[i], i)); 432 433 // drop down support 434 var lis = horizontalNavs[i].getElementsByTagName("li"); 435 for(var j = 0, jlen = lis.length; j < jlen; j++) { 436 if (mobile) { 437 (function(li, i, j) { 438 FIX.addEventListener(li, 'click', function(e) { 439 // prevent propagation 440 e.stopPropagation(); 441 // toggle hover 442 if (!/hover/.test(li.className)) { 443 var navigationLevel = li.className.match(/li[0-9]/).input[2]; 444 hideTheSameLevelSubmenus(horizontalNavs[i], navigationLevel); 445 showSubmenu(li); 446 } else { 447 hideSubmenu(li); 448 } 449 }); 450 }(lis[j], i, j)); 451 } 452 else { // desktop 453 (function(li, i, j) { 454 var timer = null; 455 var localDelay = delay; 456 FIX.horizontalNavDropDownOn[j] = function() { 457 clearTimeout(timer); 458 if (!li.className.match(/hover/)) { 459 if (li.className.match(/submenu/)) { 460 var navigationLevel = li.className.match(/li[0-9]/).input[2]; 461 hideTheSameLevelSubmenus(horizontalNavs[i], navigationLevel); 462 } 463 if (horizontalNavEntered[i]) { 464 localDelay = 0; 465 } else { 466 localDelay = delay; 467 } 468 timer = setTimeout(function() { 469 showSubmenu(li); 470 }, localDelay); 471 } 472 }; 473 FIX.horizontalNavDropDownOff[j] = function() { 474 clearTimeout(timer); 475 if (li.className.match(/hover/)) { 476 timer = setTimeout(function() { 477 hideSubmenu(li); 478 }, delay); 479 } 480 }; 481 FIX.horizontalNavDropDownForceOn[j] = function() { 482 if (!li.className.match(/hover/)) { 483 clearTimeout(timer); 484 showSubmenu(li); 485 } 486 }; 487 FIX.addEventListener(li, 'mouseover', FIX.horizontalNavDropDownOn[j]); 488 FIX.addEventListener(li, 'mouseout', FIX.horizontalNavDropDownOff[j]); 489 FIX.addEventListener(li, 'click', FIX.horizontalNavDropDownForceOn[j]); 490 }(lis[j], i, j)); 491 } 492 } 493 494 // generate submenu pointers 495 var navheaders = horizontalNavs[i].getElementsByTagName("span"); 496 for(var l = 0, llen = navheaders.length; l < llen; l++) { 497 navheaders[l].innerHTML = '<ins></ins>' + navheaders[l].innerHTML; 498 } 499 } 500 FIX.horizontalNavBarWide(); 501}; 502 503FIX.horizontalNavbarOff = function() { 504 var horizontalNavs = FIX.getByClassName("HorizontalNavBar"); 505 var mobile = /iPhone|iPod|iPad|BlackBerry|PlayBook|Touch|Android|Silk/.test(navigator.userAgent);
506 // drop down support 507 for(var i = 0, ilen = horizontalNavs.length; i < ilen; i++) { 508 var lis = horizontalNavs[i].getElementsByTagName("li"); 509 for (var j = 0, jlen = lis.length; j < jlen; j++) { 510 if (!mobile) { 511 (function (li, i, j) { 512 FIX.removeEventListener(li, 'mouseover', FIX.horizontalNavDropDownOn[j]); 513 FIX.removeEventListener(li, 'mouseout', FIX.horizontalNavDropDownOff[j]); 514 FIX.removeEventListener(li, 'click', FIX.horizontalNavDropDownForceOn[j]); 515 }(lis[j], i, j)); 516 } 517 } 518 } 519}; 520 521FIX.fixEzine2LabelWidth = function() { 522 var ezines2 = document.querySelectorAll('.EzineHorizontal'), // Fix only the horizontal Ezine2 blocks. 523 ezine2, 524 i, 525 ilen, 526 labels, 527 label, 528 offsetTop = [], 529 j, 530 jlen, 531 width, 532 maxWidth; 533 534 if (!ezines2) { 535 return; 536 } 537 for (i = 0, ilen = ezines2.length; i < ilen; i += 1) { 538 ezine2 = ezines2[i]; 539 labels = ezine2.querySelectorAll('label'); 540 if (labels) { 541 jlen = labels.length; 542 maxWidth = 0; 543 for (j = 0; j < jlen; j += 1) { 544 label = labels[j]; 545 offsetTop[j] = label.offsetTop; 546 label.style.width = 'auto'; // Remove previously set width. 547 width = FIX.getBoxPropertyValue(label, 'width'); 548 maxWidth = (width > maxWidth) ? width : maxWidth; // Store the maximum width of a label. 549 } 550 551 // Check if labels are not on the same line. 552 if (offsetTop[0] !== offsetTop[offsetTop.length -1]) { 553 for (j = 0; j < jlen; j += 1) { 554 label = labels[j]; 555 label.style.width = maxWidth + 1 + "px"; // Set the max width with a 1px buffer. 556 } 557 } 558 } 559 } 560}; 561 562FIX.responsiveVideo = function() { 563 var iframes, 564 iframe, 565 iframeWidth, 566 i, 567 ilen, 568 wrapper, 569 parent, 570 sibling, 571 flowplayers = document.querySelectorAll('.flowplayer'), 572 flowplayer; 573 574 iframes = document.querySelectorAll('iframe'); 575 576 var isYoutube = function (iframe) { 577 return /youtube\.com/.test(iframe.src); 578 }; 579 580 var isSitesellYoutube = function (iframe) { 581 return /youtube\.sitesell\.com/.test(iframe.src); 582 }; 583 584 var isVimeo = function (iframe) { 585 return /vimeo\.com/.test(iframe.src); 586 }; 587 588 var isSbitube = function (iframe) { 589 return /sbitube\.com/.test(iframe.src); 590 }; 591 592 var isJWPlayer= function (iframe) { 593 return /jwplatform\.com/.test(iframe.src); 594 }; 595 596 var isWistia= function (iframe) { 597 return (/wistia\.net/.test(iframe.src) && !/videoFoam=true/.test(iframe.src)); 598 }; 599 600 for (i = 0, ilen = iframes.length; i < ilen; i += 1) { 601 iframe = iframes[i]; 602 if (isYoutube(iframe) || isSitesellYoutube(iframe) || isVimeo(iframe) || isSbitube(iframe) || isJWPlayer(iframe) || isWistia(iframe)) { 603 iframeWidth = iframe.width; 604 if (!iframeWidth) { 605 iframeWidth = iframe.offsetWidth + 10; 606 } 607 if (iframeWidth < FIX.computeAvailableWidth(iframe.parentNode)) { 608 continue; 609 } 610 iframe.style.width = 100 + '%'; 611 iframe.style.height = 100 + '%'; 612 iframe.name = 'responsiveVideoNo' + i; 613 wrapper = document.createElement('div'); 614 wrapper.className = 'video-container'; 615 sibling = iframe.nextSibling; 616 parent = iframe.parentNode; 617 wrapper.appendChild(iframe); 618 parent.insertBefore(wrapper, sibling); 619 } 620 } 621 for (i = 0, ilen = flowplayers.length; i < ilen; i += 1) { 622 flowplayer = flowplayers[i]; 623 if (flowplayer.offsetWidth < (FIX.computeAvailableWidth(flowplayer.parentNode) -10)) { 624 continue; 625 } 626 if (parseFloat(flowplayer.dataset.ratio) === 0.5625) { 627 flowplayer.className += ' video-container'; 628 } 629 } 630};
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.