1// javascript file for adding pop-up decision trees to your web page 2 3// add a modal to the page 4 5var temp = '<div id="zt-modal" >'+ 6' <div id="zt-modal-content">'+ 7' <a onclick="close_popup();"><span class="close" id="zt-popup-close">×</span></a>'+ 8' <iframe id="zt-popup" seamless frameborder="0" width="100%" height="1" scrolling="no"></iframe>'+ 9' </div>'+ 10'</div>' 11 ; 12 13jQuery("body").append(temp); 14 15 16// set the sindow width, deending upon screen size 17// full size for mobile, 40% for desktop, 66% other 18 19if (window.innerWidth <= 640) 20 width = '95%' ; 21else if (window.innerWidth <= 1024) 22 width = '66%' ; 23else 24 width="40%" ; 25 26 27// make CSS for the modal 28 29document.getElementById('zt-modal-content').style.cssText = 'background-color: #fefefe; margin: 3% auto; padding: 20px ;border: 1px solid #888; width: '+width+';' ; 30 31document.getElementById('zt-modal').style.cssText = 'display: none; position: fixed; z-index: 1; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; overflow: auto; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.4); overflow-y: scroll; outline: 0; -webkit-overflow-scrolling: touch;'; 32 33document.getElementById('zt-popup-close').style.cssText = 'color:red; float:right; font-size:28px; font-weight: bold;'; 34 35 36// Get the modal 37var modal = document.getElementById('zt-modal'); 38 39 40// display the pop-up 41 42function show_popup(tree_id, parameters) 43{ 44 45// set the iFrame source to the tree URL 46 iframe = document.getElementById("zt-popup"); 47 var url = "https://zingtree.com/deploy/tree.php?z=popup&popup=1&disable_scroll=1&tree_id="+tree_id ; 48 url += parameters ;
49 iframe.src = url; 50 51// display the tree/modal 52 modal.style.display = "block"; 53 54} 55 56 57// same as above, except for gallery trees 58function show_gallery_popup(gallery_id, parameters) 59{ 60 61// set the iFrame source to the tree URL 62 iframe = document.getElementById("zt-popup"); 63 var url = "https://zingtree.com/deploy/tree.php?z=popup&popup=1&disable_scroll=1&gallery_id="+gallery_id ; 64 url += parameters ; 65 iframe.src = url; 66 67// display the tree/modal 68 modal.style.display = "block"; 69 70} 71 72// close the pop-up by hiding the modal 73 74function close_popup() 75{ 76 modal.style.display = "none"; 77 iframe = document.getElementById("zt-popup"); 78 iframe.src = ""; 79 80} 81 82 83// When the user clicks anywhere outside of the modal, close it 84window.onclick = function(event) { 85 if (event.target == modal) 86 close_popup() ; 87} 88 89// **************** resizer code for modal 90 91// call iframe full height 92;(function(undefined) { 93 'use strict'; 94 if(typeof window === 'undefined') return; // don't run for server side render 95 var 96 count = 0, 97 logEnabled = false, 98 hiddenCheckEnabled = false, 99 msgHeader = 'message', 100 msgHeaderLen = msgHeader.length, 101 msgId = '[iFrameSizer]', //Must match iframe msg ID 102 msgIdLen = msgId.length, 103 pagePosition = null, 104 requestAnimationFrame = window.requestAnimationFrame, 105 resetRequiredMethods = {max:1,scroll:1,bodyScroll:1,documentElementScroll:1}, 106 settings = {}, 107 timer = null, 108 logId = 'Host Page', 109 defaults = { 110 autoResize : true, 111 bodyBackground : null, 112 bodyMargin : null, 113 bodyMarginV1 : 8, 114 bodyPadding : null, 115 checkOrigin : false, 116 inPageLinks : false, 117 enablePublicMethods : true, 118 heightCalculationMethod : 'bodyOffset', 119 id : 'iFrameResizer', 120 interval : 32, 121 log : false, 122 maxHeight : Infinity, 123 maxWidth : Infinity, 124 minHeight : 0, 125 minWidth : 0, 126 resizeFrom : 'parent', 127 scrolling : false, 128 sizeHeight : true, 129 sizeWidth : false, 130 warningTimeout : 5000, 131 tolerance : 0, 132 widthCalculationMethod : 'scroll', 133 closedCallback : function(){}, 134 initCallback : function(){}, 135 messageCallback : function(){warn('MessageCallback function not defined');}, 136 resizedCallback : function(){}, 137 scrollCallback : function(){return true;} 138 }; 139 function addEventListener(obj,evt,func){ 140 /* istanbul ignore else */ // Not testable in PhantonJS 141 if ('addEventListener' in window){ 142 obj.addEventListener(evt,func, false); 143 } else if ('attachEvent' in window){//IE 144 obj.attachEvent('on'+evt,func); 145 } 146 } 147 function removeEventListener(el,evt,func){ 148 /* istanbul ignore else */ // Not testable in phantonJS 149 if ('removeEventListener' in window){ 150 el.removeEventListener(evt,func, false); 151 } else if ('detachEvent' in window){ //IE 152 el.detachEvent('on'+evt,func); 153 } 154 } 155 function setupRequestAnimationFrame(){ 156 var 157 vendors = ['moz', 'webkit', 'o', 'ms'], 158 x; 159 // Remove vendor prefixing if prefixed and break early if not 160 for (x = 0; x < vendors.length && !requestAnimationFrame; x += 1) { 161 requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 162 } 163 if (!(requestAnimationFrame)){ 164 log('setup','RequestAnimationFrame not supported'); 165 } 166 } 167 function getMyID(iframeId){ 168 var retStr = 'Host page: '+iframeId; 169 if (window.top !== window.self){ 170 if (window.parentIFrame && window.parentIFrame.getId){ 171 retStr = window.parentIFrame.getId()+': '+iframeId; 172 } else { 173 retStr = 'Nested host page: '+iframeId; 174 } 175 } 176 return retStr; 177 } 178 function formatLogHeader(iframeId){ 179 return msgId + '[' + getMyID(iframeId) + ']'; 180 } 181 function isLogEnabled(iframeId){ 182 return settings[iframeId] ? settings[iframeId].log : logEnabled; 183 } 184 function log(iframeId,msg){ 185 output('log',iframeId,msg,isLogEnabled(iframeId)); 186 } 187 function info(iframeId,msg){ 188 output('info',iframeId,msg,isLogEnabled(iframeId)); 189 } 190 function warn(iframeId,msg){ 191 output('warn',iframeId,msg,true); 192 } 193 function output(type,iframeId,msg,enabled){ 194 if (true === enabled && 'object' === typeof window.console){ 195 console[type](formatLogHeader(iframeId),msg); 196 } 197 } 198 function iFrameListener(event){ 199 function resizeIFrame(){ 200 function resize(){ 201 setSize(messageData); 202 setPagePosition(iframeId); 203 callback('resizedCallback',messageData); 204 } 205 ensureInRange('Height'); 206 ensureInRange('Width'); 207 syncResize(resize,messageData,'init'); 208 } 209 function processMsg(){ 210 var data = msg.substr(msgIdLen).split(':'); 211 return { 212 iframe: settings[data[0]].iframe, 213 id: data[0], 214 height: data[1], 215 width: data[2], 216 type: data[3] 217 }; 218 } 219 function ensureInRange(Dimension){ 220 var 221 max = Number(settings[iframeId]['max' + Dimension]), 222 min = Number(settings[iframeId]['min' + Dimension]), 223 dimension = Dimension.toLowerCase(), 224 size = Number(messageData[dimension]); 225 log(iframeId,'Checking ' + dimension + ' is in range ' + min + '-' + max); 226 if (size<min) { 227 size=min; 228 log(iframeId,'Set ' + dimension + ' to min value'); 229 } 230 if (size>max) { 231 size=max; 232 log(iframeId,'Set ' + dimension + ' to max value'); 233 } 234 messageData[dimension] = '' + size; 235 } 236 function isMessageFromIFrame(){ 237 function checkAllowedOrigin(){ 238 function checkList(){ 239 var 240 i = 0, 241 retCode = false; 242 log(iframeId,'Checking connection is from allowed list of origins: ' + checkOrigin); 243 for (; i < checkOrigin.length; i++) { 244 if (checkOrigin[i] === origin) { 245 retCode = true; 246 break; 247 } 248 } 249 return retCode; 250 } 251 function checkSingle(){ 252 var remoteHost = settings[iframeId].remoteHost; 253 log(iframeId,'Checking connection is from: '+remoteHost); 254 return origin === remoteHost; 255 } 256 return checkOrigin.constructor === Array ? checkList() : checkSingle(); 257 } 258 var 259 origin = event.origin, 260 checkOrigin = settings[iframeId].checkOrigin;
261 if (checkOrigin && (''+origin !== 'null') && !checkAllowedOrigin()) { 262 throw new Error( 263 'Unexpected message received from: ' + origin + 264 ' for ' + messageData.iframe.id + 265 '. Message was: ' + event.data + 266 '. This error can be disabled by setting the checkOrigin: false option or by providing of array of trusted domains.' 267 ); 268 } 269 return true; 270 } 271 function isMessageForUs(){ 272 return msgId === (('' + msg).substr(0,msgIdLen)) && (msg.substr(msgIdLen).split(':')[0] in settings); //''+Protects against non-string msg 273 } 274 function isMessageFromMetaParent(){ 275 //Test if this message is from a parent above us. This is an ugly test, however, updating 276 //the message format would break backwards compatibity. 277 var retCode = messageData.type in {'true':1,'false':1,'undefined':1}; 278 if (retCode){ 279 log(iframeId,'Ignoring init message from meta parent page'); 280 } 281 return retCode; 282 } 283 function getMsgBody(offset){ 284 return msg.substr(msg.indexOf(':')+msgHeaderLen+offset); 285 } 286 function forwardMsgFromIFrame(msgBody){ 287 log(iframeId,'MessageCallback passed: {iframe: '+ messageData.iframe.id + ', message: ' + msgBody + '}'); 288 callback('messageCallback',{ 289 iframe: messageData.iframe, 290 message: JSON.parse(msgBody) 291 }); 292 log(iframeId,'--'); 293 } 294 function getPageInfo(){ 295 var 296 bodyPosition = document.body.getBoundingClientRect(), 297 iFramePosition = messageData.iframe.getBoundingClientRect(); 298 return JSON.stringify({ 299 iframeHeight: iFramePosition.height, 300 iframeWidth: iFramePosition.width, 301 clientHeight: Math.max(document.documentElement.clientHeight, window.innerHeight || 0), 302 clientWidth: Math.max(document.documentElement.clientWidth, window.innerWidth || 0), 303 offsetTop: parseInt(iFramePosition.top - bodyPosition.top, 10), 304 offsetLeft: parseInt(iFramePosition.left - bodyPosition.left, 10), 305 scrollTop: window.pageYOffset, 306 scrollLeft: window.pageXOffset 307 }); 308 } 309 function sendPageInfoToIframe(iframe,iframeId){ 310 function debouncedTrigger(){ 311 trigger( 312 'Send Page Info', 313 'pageInfo:' + getPageInfo(), 314 iframe, 315 iframeId 316 ); 317 } 318 debouce(debouncedTrigger,32); 319 } 320 function startPageInfoMonitor(){ 321 function setListener(type,func){ 322 function sendPageInfo(){ 323 if (settings[id]){ 324 sendPageInfoToIframe(settings[id].iframe,id); 325 } else { 326 stop(); 327 } 328 } 329 ['scroll','resize'].forEach(function(evt){ 330 log(id, type + evt + ' listener for sendPageInfo'); 331 func(window,evt,sendPageInfo); 332 }); 333 } 334 function stop(){ 335 setListener('Remove ', removeEventListener); 336 } 337 function start(){ 338 setListener('Add ', addEventListener); 339 } 340 var id = iframeId; //Create locally scoped copy of iFrame ID 341 start(); 342 settings[id].stopPageInfo = stop; 343 } 344 function stopPageInfoMonitor(){ 345 if (settings[iframeId] && settings[iframeId].stopPageInfo){ 346 settings[iframeId].stopPageInfo(); 347 delete settings[iframeId].stopPageInfo; 348 } 349 } 350 function checkIFrameExists(){ 351 var retBool = true; 352 if (null === messageData.iframe) { 353 warn(iframeId,'IFrame ('+messageData.id+') not found'); 354 retBool = false; 355 } 356 return retBool; 357 } 358 function getElementPosition(target){ 359 var iFramePosition = target.getBoundingClientRect(); 360 getPagePosition(iframeId); 361 return { 362 x: Math.floor( Number(iFramePosition.left) + Number(pagePosition.x) ), 363 y: Math.floor( Number(iFramePosition.top) + Number(pagePosition.y) ) 364 }; 365 } 366 function scrollRequestFromChild(addOffset){ 367 /* istanbul ignore next */ //Not testable in Karma 368 function reposition(){ 369 pagePosition = newPosition; 370 scrollTo(); 371 log(iframeId,'--'); 372 } 373 function calcOffset(){ 374 return { 375 x: Number(messageData.width) + offset.x, 376 y: Number(messageData.height) + offset.y 377 }; 378 } 379 function scrollParent(){ 380 if (window.parentIFrame){ 381 window.parentIFrame['scrollTo'+(addOffset?'Offset':'')](newPosition.x,newPosition.y); 382 } else { 383 warn(iframeId,'Unable to scroll to requested position, window.parentIFrame not found'); 384 } 385 } 386 var 387 offset = addOffset ? getElementPosition(messageData.iframe) : {x:0,y:0}, 388 newPosition = calcOffset(); 389 log(iframeId,'Reposition requested from iFrame (offset x:'+offset.x+' y:'+offset.y+')'); 390 if(window.top !== window.self){ 391 scrollParent(); 392 } else { 393 reposition(); 394 } 395 } 396 function scrollTo(){ 397 if (false !== callback('scrollCallback',pagePosition)){ 398 setPagePosition(iframeId); 399 } else { 400 unsetPagePosition(); 401 } 402 } 403 function findTarget(location){ 404 function jumpToTarget(){ 405 var jumpPosition = getElementPosition(target); 406 log(iframeId,'Moving to in page link (#'+hash+') at x: '+jumpPosition.x+' y: '+jumpPosition.y); 407 pagePosition = { 408 x: jumpPosition.x, 409 y: jumpPosition.y 410 }; 411 scrollTo();
412 log(iframeId,'--'); 413 } 414 function jumpToParent(){ 415 if (window.parentIFrame){ 416 window.parentIFrame.moveToAnchor(hash); 417 } else { 418 log(iframeId,'In page link #'+hash+' not found and window.parentIFrame not found'); 419 } 420 } 421 var 422 hash = location.split('#')[1] || '', 423 hashData = decodeURIComponent(hash), 424 target = document.getElementById(hashData) || document.getElementsByName(hashData)[0]; 425 if (target){ 426 jumpToTarget(); 427 } else if(window.top!==window.self){ 428 jumpToParent(); 429 } else { 430 log(iframeId,'In page link #'+hash+' not found'); 431 } 432 } 433 function callback(funcName,val){ 434 return chkCallback(iframeId,funcName,val); 435 } 436 function actionMsg(){ 437 if(settings[iframeId].firstRun) firstRun(); 438 switch(messageData.type){ 439 case 'close': 440 closeIFrame(messageData.iframe); 441 break; 442 case 'message': 443 forwardMsgFromIFrame(getMsgBody(6)); 444 break; 445 case 'scrollTo': 446 scrollRequestFromChild(false); 447 break; 448 case 'scrollToOffset': 449 scrollRequestFromChild(true); 450 break; 451 case 'pageInfo': 452 sendPageInfoToIframe(settings[iframeId].iframe,iframeId); 453 startPageInfoMonitor(); 454 break; 455 case 'pageInfoStop': 456 stopPageInfoMonitor(); 457 break; 458 case 'inPageLink': 459 findTarget(getMsgBody(9)); 460 break; 461 case 'reset': 462 resetIFrame(messageData); 463 break; 464 case 'init': 465 resizeIFrame(); 466 callback('initCallback',messageData.iframe); 467 break; 468 default: 469 resizeIFrame(); 470 } 471 } 472 function hasSettings(iframeId){ 473 var retBool = true; 474 if (!settings[iframeId]){ 475 retBool = false; 476 warn(messageData.type + ' No settings for ' + iframeId + '. Message was: ' + msg); 477 } 478 return retBool; 479 } 480 function iFrameReadyMsgReceived(){ 481 for (var iframeId in settings){ 482 trigger('iFrame requested init',createOutgoingMsg(iframeId),document.getElementById(iframeId),iframeId); 483 } 484 } 485 function firstRun() { 486 settings[iframeId].firstRun = false; 487 } 488 function clearWarningTimeout() { 489 clearTimeout(settings[iframeId].msgTimeout); 490 settings[iframeId].warningTimeout = 0; 491 } 492 var 493 msg = event.data, 494 messageData = {}, 495 iframeId = null; 496 if('[iFrameResizerChild]Ready' === msg){ 497 iFrameReadyMsgReceived(); 498 } else if (isMessageForUs()){ 499 messageData = processMsg(); 500 iframeId = logId = messageData.id; 501 settings[iframeId].loaded = true; 502 if (!isMessageFromMetaParent() && hasSettings(iframeId)){ 503 log(iframeId,'Received: '+msg); 504 if ( checkIFrameExists() && isMessageFromIFrame() ){ 505 actionMsg(); 506 } 507 } 508 } else { 509 info(iframeId,'Ignored: '+msg); 510 } 511 } 512 function chkCallback(iframeId,funcName,val){ 513 var 514 func = null, 515 retVal = null; 516 if(settings[iframeId]){ 517 func = settings[iframeId][funcName]; 518 if( 'function' === typeof func){ 519 retVal = func(val); 520 } else { 521 throw new TypeError(funcName+' on iFrame['+iframeId+'] is not a function'); 522 } 523 } 524 return retVal; 525 } 526 function closeIFrame(iframe){ 527 var iframeId = iframe.id; 528 log(iframeId,'Removing iFrame: '+iframeId); 529 if (iframe.parentNode) { iframe.parentNode.removeChild(iframe); } 530 chkCallback(iframeId,'closedCallback',iframeId); 531 log(iframeId,'--'); 532 delete settings[iframeId]; 533 } 534 function getPagePosition(iframeId){ 535 if(null === pagePosition){ 536 pagePosition = { 537 x: (window.pageXOffset !== undefined) ? window.pageXOffset : document.documentElement.scrollLeft, 538 y: (window.pageYOffset !== undefined) ? window.pageYOffset : document.documentElement.scrollTop 539 }; 540 log(iframeId,'Get page position: '+pagePosition.x+','+pagePosition.y); 541 } 542 } 543 function setPagePosition(iframeId){ 544 if(null !== pagePosition){ 545 window.scrollTo(pagePosition.x,pagePosition.y); 546 log(iframeId,'Set page position: '+pagePosition.x+','+pagePosition.y); 547 unsetPagePosition(); 548 } 549 } 550 function unsetPagePosition(){ 551 pagePosition = null; 552 } 553 function resetIFrame(messageData){ 554 function reset(){ 555 setSize(messageData); 556 trigger('reset','reset',messageData.iframe,messageData.id); 557 } 558 log(messageData.id,'Size reset requested by '+('init'===messageData.type?'host page':'iFrame')); 559 getPagePosition(messageData.id); 560 syncResize(reset,messageData,'reset'); 561 } 562 function setSize(messageData){ 563 function setDimension(dimension){ 564 messageData.iframe.style[dimension] = messageData[dimension] + 'px'; 565 log( 566 messageData.id, 567 'IFrame (' + iframeId + 568 ') ' + dimension + 569 ' set to ' + messageData[dimension] + 'px' 570 ); 571 } 572 function chkZero(dimension){ 573 //FireFox sets dimension of hidden iFrames to zero. 574 //So if we detect that set up an event to check for 575 //when iFrame becomes visible. 576 /* istanbul ignore next */ //Not testable in PhantomJS 577 if (!hiddenCheckEnabled && '0' === messageData[dimension]){ 578 hiddenCheckEnabled = true; 579 log(iframeId,'Hidden iFrame detected, creating visibility listener'); 580 fixHiddenIFrames(); 581 } 582 } 583 function processDimension(dimension){ 584 setDimension(dimension); 585 chkZero(dimension); 586 } 587 var iframeId = messageData.iframe.id; 588 if(settings[iframeId]){ 589 if( settings[iframeId].sizeHeight) { processDimension('height'); } 590 if( settings[iframeId].sizeWidth ) { processDimension('width'); } 591 } 592 } 593 function syncResize(func,messageData,doNotSync){ 594 /* istanbul ignore if */ //Not testable in PhantomJS 595 if(doNotSync!==messageData.type && requestAnimationFrame){ 596 log(messageData.id,'Requesting animation frame'); 597 requestAnimationFrame(func); 598 } else { 599 func(); 600 } 601 } 602 function trigger(calleeMsg, msg, iframe, id, noResponseWarning) { 603 function postMessageToIFrame(){ 604 var target = settings[id].targetOrigin; 605 log(id,'[' + calleeMsg + '] Sending msg to iframe['+id+'] ('+msg+') targetOrigin: '+target); 606 iframe.contentWindow.postMessage( msgId + msg, target ); 607 } 608 function iFrameNotFound(){ 609 warn(id,'[' + calleeMsg + '] IFrame('+id+') not found'); 610 } 611 function chkAndSend(){ 612 if(iframe && 'contentWindow' in iframe && (null !== iframe.contentWindow)){ //Null test for PhantomJS 613 postMessageToIFrame(); 614 } else { 615 iFrameNotFound(); 616 } 617 } 618 function warnOnNoResponse() { 619 function warning() {
620 if (settings[id] && !settings[id].loaded && !errorShown) { 621 errorShown = true; 622 warn(id, 'IFrame has not responded within '+ settings[id].warningTimeout/1000 +' seconds. Check iFrameResizer.contentWindow.js has been loaded in iFrame. This message can be ingored if everything is working, or you can set the warningTimeout option to a higher value or zero to suppress this warning.'); 623 } 624 } 625 if (!!noResponseWarning && !!settings[id].warningTimeout) { 626 settings[id].msgTimeout = setTimeout(warning, settings[id].warningTimeout); 627 } 628 } 629 var errorShown = false; 630 id = id || iframe.id; 631 if(settings[id]) { 632 chkAndSend(); 633 warnOnNoResponse(); 634 } 635 } 636 function createOutgoingMsg(iframeId){ 637 return iframeId + 638 ':' + settings[iframeId].bodyMarginV1 + 639 ':' + settings[iframeId].sizeWidth + 640 ':' + settings[iframeId].log + 641 ':' + settings[iframeId].interval + 642 ':' + settings[iframeId].enablePublicMethods + 643 ':' + settings[iframeId].autoResize + 644 ':' + settings[iframeId].bodyMargin + 645 ':' + settings[iframeId].heightCalculationMethod + 646 ':' + settings[iframeId].bodyBackground + 647 ':' + settings[iframeId].bodyPadding + 648 ':' + settings[iframeId].tolerance + 649 ':' + settings[iframeId].inPageLinks + 650 ':' + settings[iframeId].resizeFrom + 651 ':' + settings[iframeId].widthCalculationMethod; 652 } 653 function setupIFrame(iframe,options){ 654 function setLimits(){ 655 function addStyle(style){ 656 if ((Infinity !== settings[iframeId][style]) && (0 !== settings[iframeId][style])){ 657 iframe.style[style] = settings[iframeId][style] + 'px'; 658 log(iframeId,'Set '+style+' = '+settings[iframeId][style]+'px'); 659 } 660 } 661 function chkMinMax(dimension){ 662 if (settings[iframeId]['min'+dimension]>settings[iframeId]['max'+dimension]){ 663 throw new Error('Value for min'+dimension+' can not be greater than max'+dimension); 664 } 665 } 666 chkMinMax('Height'); 667 chkMinMax('Width'); 668 addStyle('maxHeight'); 669 addStyle('minHeight'); 670 addStyle('maxWidth'); 671 addStyle('minWidth'); 672 } 673 function newId(){ 674 var id = ((options && options.id) || defaults.id + count++); 675 if (null !== document.getElementById(id)){ 676 id = id + count++; 677 } 678 return id; 679 } 680 function ensureHasId(iframeId){ 681 logId=iframeId; 682 if (''===iframeId){ 683 iframe.id = iframeId = newId(); 684 logEnabled = (options || {}).log; 685 logId=iframeId; 686 log(iframeId,'Added missing iframe ID: '+ iframeId +' (' + iframe.src + ')'); 687 } 688 return iframeId; 689 } 690 function setScrolling(){ 691 log(iframeId,'IFrame scrolling ' + (settings[iframeId].scrolling ? 'enabled' : 'disabled') + ' for ' + iframeId); 692 iframe.style.overflow = false === settings[iframeId].scrolling ? 'hidden' : 'auto'; 693 switch(settings[iframeId].scrolling) { 694 case true: 695 iframe.scrolling = 'yes'; 696 break; 697 case false: 698 iframe.scrolling = 'no'; 699 break; 700 default: 701 iframe.scrolling = settings[iframeId].scrolling; 702 } 703 } 704 //The V1 iFrame script expects an int, where as in V2 expects a CSS 705 //string value such as '1px 3em', so if we have an int for V2, set V1=V2 706 //and then convert V2 to a string PX value. 707 function setupBodyMarginValues(){ 708 if (('number'===typeof(settings[iframeId].bodyMargin)) || ('0'===settings[iframeId].bodyMargin)){ 709 settings[iframeId].bodyMarginV1 = settings[iframeId].bodyMargin; 710 settings[iframeId].bodyMargin = '' + settings[iframeId].bodyMargin + 'px'; 711 } 712 } 713 function checkReset(){ 714 // Reduce scope of firstRun to function, because IE8's JS execution 715 // context stack is borked and this value gets externally 716 // changed midway through running this function!!! 717 var 718 firstRun = settings[iframeId].firstRun, 719 resetRequertMethod = settings[iframeId].heightCalculationMethod in resetRequiredMethods; 720 if (!firstRun && resetRequertMethod){ 721 resetIFrame({iframe:iframe, height:0, width:0, type:'init'}); 722 } 723 } 724 function setupIFrameObject(){ 725 if(Function.prototype.bind){ //Ignore unpolyfilled IE8. 726 settings[iframeId].iframe.iFrameResizer = { 727 close : closeIFrame.bind(null,settings[iframeId].iframe), 728 resize : trigger.bind(null,'Window resize', 'resize', settings[iframeId].iframe), 729 moveToAnchor : function(anchor){ 730 trigger('Move to anchor','moveToAnchor:'+anchor, settings[iframeId].iframe,iframeId); 731 }, 732 sendMessage : function(message){ 733 message = JSON.stringify(message); 734 trigger('Send Message','message:'+message, settings[iframeId].iframe, iframeId); 735 } 736 }; 737 } 738 } 739 //We have to call trigger twice, as we can not be sure if all 740 //iframes have completed loading when this code runs. The 741 //event listener also catches the page changing in the iFrame. 742 function init(msg){ 743 function iFrameLoaded(){ 744 trigger('iFrame.onload', msg, iframe, undefined , true); 745 checkReset(); 746 } 747 addEventListener(iframe,'load',iFrameLoaded); 748 trigger('init', msg, iframe, undefined, true); 749 } 750 function checkOptions(options){ 751 if ('object' !== typeof options){ 752 throw new TypeError('Options is not an object'); 753 } 754 } 755 function copyOptions(options){ 756 for (var option in defaults) { 757 if (defaults.hasOwnProperty(option)){ 758 settings[iframeId][option] = options.hasOwnProperty(option) ? options[option] : defaults[option]; 759 } 760 } 761 } 762 function getTargetOrigin (remoteHost){ 763 return ('' === remoteHost || 'file://' === remoteHost) ? '*' : remoteHost; 764 } 765 function processOptions(options){ 766 options = options || {}; 767 settings[iframeId] = { 768 firstRun : true, 769 iframe : iframe,
770 remoteHost : iframe.src.split('/').slice(0,3).join('/') 771 }; 772 checkOptions(options); 773 copyOptions(options); 774 settings[iframeId].targetOrigin = true === settings[iframeId].checkOrigin ? getTargetOrigin(settings[iframeId].remoteHost) : '*'; 775 } 776 function beenHere(){ 777 return (iframeId in settings && 'iFrameResizer' in iframe); 778 } 779 var iframeId = ensureHasId(iframe.id); 780 if (!beenHere()){ 781 processOptions(options); 782 setScrolling(); 783 setLimits(); 784 setupBodyMarginValues(); 785 init(createOutgoingMsg(iframeId)); 786 setupIFrameObject(); 787 } else { 788 warn(iframeId,'Ignored iFrame, already setup.'); 789 } 790 } 791 function debouce(fn,time){ 792 if (null === timer){ 793 timer = setTimeout(function(){ 794 timer = null; 795 fn(); 796 }, time); 797 } 798 } 799 /* istanbul ignore next */ //Not testable in PhantomJS 800 function fixHiddenIFrames(){ 801 function checkIFrames(){ 802 function checkIFrame(settingId){ 803 function chkDimension(dimension){ 804 return '0px' === settings[settingId].iframe.style[dimension]; 805 } 806 function isVisible(el) { 807 return (null !== el.offsetParent); 808 } 809 if (isVisible(settings[settingId].iframe) && (chkDimension('height') || chkDimension('width'))){ 810 trigger('Visibility change', 'resize', settings[settingId].iframe, settingId); 811 } 812 } 813 for (var settingId in settings){ 814 checkIFrame(settingId); 815 } 816 } 817 function mutationObserved(mutations){ 818 log('window','Mutation observed: ' + mutations[0].target + ' ' + mutations[0].type); 819 debouce(checkIFrames,16); 820 } 821 function createMutationObserver(){ 822 var 823 target = document.querySelector('body'), 824 config = { 825 attributes : true, 826 attributeOldValue : false, 827 characterData : true, 828 characterDataOldValue : false, 829 childList : true, 830 subtree : true 831 }, 832 observer = new MutationObserver(mutationObserved); 833 observer.observe(target, config); 834 } 835 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; 836 if (MutationObserver) createMutationObserver(); 837 } 838 function resizeIFrames(event){ 839 function resize(){ 840 sendTriggerMsg('Window '+event,'resize'); 841 } 842 log('window','Trigger event: '+event); 843 debouce(resize,16); 844 } 845 /* istanbul ignore next */ //Not testable in PhantomJS 846 function tabVisible() { 847 function resize(){ 848 sendTriggerMsg('Tab Visable','resize'); 849 } 850 if('hidden' !== document.visibilityState) { 851 log('document','Trigger event: Visiblity change'); 852 debouce(resize,16); 853 } 854 } 855 function sendTriggerMsg(eventName,event){ 856 function isIFrameResizeEnabled(iframeId) { 857 return 'parent' === settings[iframeId].resizeFrom && 858 settings[iframeId].autoResize && 859 !settings[iframeId].firstRun; 860 } 861 for (var iframeId in settings){ 862 if(isIFrameResizeEnabled(iframeId)){ 863 trigger(eventName, event, document.getElementById(iframeId), iframeId); 864 } 865 } 866 } 867 function setupEventListeners(){ 868 addEventListener(window,'message',iFrameListener); 869 addEventListener(window,'resize', function(){resizeIFrames('resize');}); 870 addEventListener(document,'visibilitychange',tabVisible); 871 addEventListener(document,'-webkit-visibilitychange',tabVisible); //Andriod 4.4 872 addEventListener(window,'focusin',function(){resizeIFrames('focus');}); //IE8-9 873 addEventListener(window,'focus',function(){resizeIFrames('focus');}); 874 } 875 function factory(){ 876 function init(options,element){ 877 function chkType(){ 878 if(!element.tagName) { 879 throw new TypeError('Object is not a valid DOM element'); 880 } else if ('IFRAME' !== element.tagName.toUpperCase()) { 881 throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>'); 882 } 883 } 884 if(element) { 885 chkType(); 886 setupIFrame(element, options); 887 iFrames.push(element); 888 } 889 } 890 function warnDeprecatedOptions(options) { 891 if (options && options.enablePublicMethods) { 892 warn('enablePublicMethods option has been removed, public methods are now always available in the iFrame'); 893 } 894 } 895 var iFrames; 896 setupRequestAnimationFrame(); 897 setupEventListeners(); 898 return function iFrameResizeF(options,target){ 899 iFrames = []; //Only return iFrames past in on this call 900 warnDeprecatedOptions(options); 901 switch (typeof(target)){ 902 case 'undefined': 903 case 'string': 904 Array.prototype.forEach.call( 905 document.querySelectorAll( target || 'iframe' ), 906 init.bind(undefined, options) 907 ); 908 break; 909 case 'object': 910 init(options,target); 911 break; 912 default: 913 throw new TypeError('Unexpected data type ('+typeof(target)+')'); 914 } 915 return iFrames; 916 }; 917 } 918 function createJQueryPublicMethod($){ 919 if (!$.fn) { 920 info('','Unable to bind to jQuery, it is not fully loaded.'); 921 } else if (!$.fn.iFrameResize){ 922 $.fn.iFrameResize = function $iFrameResizeF(options) { 923 function init(index, element) { 924 setupIFrame(element, options); 925 } 926 return this.filter('iframe').each(init).end(); 927 }; 928 } 929 } 930 if (window.jQuery) { createJQueryPublicMethod(window.jQuery); } 931 if (typeof define === 'function' && define.amd) { 932 define([],factory); 933 } else if (typeof module === 'object' && typeof module.exports === 'object') { //Node for browserfy 934 module.exports = factory(); 935 } else { 936 window.iFrameResize = window.iFrameResize || factory(); 937 } 938 })();
939 940 iFrameResize({ 941 log : false, 942 inPageLinks : true, 943 944 }); 945
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.