PageSourceSearch

https://www.najaraya.com/wp-content/plugins/simply-schedule-appoin…/assets/js/iframe-outer.js?ver=3.6.7.10

js najaraya.com collected 2026-10-06 08:23:43 UTC 42,398 bytes, 1,603 lines download raw bytes

1/*
2 * File: iframeResizer.js
3 * Desc: Force iframes to size to content.
4 * Requires: iframeResizer.contentWindow.js to be loaded into the target frame.
5 * Doc: https://github.com/davidjbradshaw/iframe-resizer
6 * Author: David J. Bradshaw - [email protected]
7 * Contributor: Jure Mav - [email protected]
8 * Contributor: Reed Dadoune - [email protected]
9 */
10
11// eslint-disable-next-line sonarjs/cognitive-complexity, no-shadow-restricted-names
12;(function (undefined) {
13  if (typeof window === 'undefined') return // don't run for server side render
14
15  var count = 0,
16    logEnabled = false,
17    hiddenCheckEnabled = false,
18    msgHeader = 'message',
19    msgHeaderLen = msgHeader.length,
20    msgId = '[iFrameSizer]', // Must match iframe msg ID
21    msgIdLen = msgId.length,
22    pagePosition = null,
23    requestAnimationFrame = window.requestAnimationFrame,
24    resetRequiredMethods = {
25      max: 1,
26      scroll: 1,
27      bodyScroll: 1,
28      documentElementScroll: 1
29    },
30    settings = {},
31    timer = null,
32    defaults = {
33      autoResize: true,
34      bodyBackground: null,
35      bodyMargin: null,
36      bodyMarginV1: 8,
37      bodyPadding: null,
38      checkOrigin: true,
39      inPageLinks: false,
40      enablePublicMethods: true,
41      heightCalculationMethod: 'bodyOffset',
42      id: 'iFrameResizer',
43      interval: 32,
44      log: false,
45      maxHeight: Infinity,
46      maxWidth: Infinity,
47      minHeight: 0,
48      minWidth: 0,
49      mouseEvents: true,
50      resizeFrom: 'parent',
51      scrolling: false,
52      sizeHeight: true,
53      sizeWidth: false,
54      warningTimeout: 5000,
55      tolerance: 0,
56      widthCalculationMethod: 'scroll',
57      onClose: function () {
58        return true
59      },
60      onClosed: function () {},
61      onInit: function () {},
62      onMessage: function () {
63        warn('onMessage function not defined')
64      },
65      onMouseEnter: function () {},
66      onMouseLeave: function () {},
67      onResized: function () {},
68      onScroll: function () {
69        return true
70      }
71    }
72
73  function getMutationObserver() {
74    return (
75      window.MutationObserver ||
76      window.WebKitMutationObserver ||
77      window.MozMutationObserver
78    )
79  }
80
81  function addEventListener(el, evt, func) {
82    el.addEventListener(evt, func, false)
83  }
84
85  function removeEventListener(el, evt, func) {
86    el.removeEventListener(evt, func, false)
87  }
88
89  function setupRequestAnimationFrame() {
90    var vendors = ['moz', 'webkit', 'o', 'ms']
91    var x
92
93    // Remove vendor prefixing if prefixed and break early if not
94    for (x = 0; x < vendors.length && !requestAnimationFrame; x += 1) {
95      requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']
96    }
97
98    if (!requestAnimationFrame) {
99      log('setup', 'RequestAnimationFrame not supported')
100    } else {
101      // Firefox extension content-scripts have a globalThis object that is not the same as window.
102      // Binding `requestAnimationFrame` to window allows the function to work and prevents errors
103      // being thrown when run in that context, and should be a no-op in every other context.
104      requestAnimationFrame = requestAnimationFrame.bind(window)
105    }
106  }
107
108  function getMyID(iframeId) {
109    var retStr = 'Host page: ' + iframeId
110
111    if (window.top !== window.self) {
112      retStr =
113        window.parentIFrame && window.parentIFrame.getId
114          ? window.parentIFrame.getId() + ': ' + iframeId
115          : 'Nested host page: ' + iframeId
116    }
117
118    return retStr
119  }
120
121  function formatLogHeader(iframeId) {
122    return msgId + '[' + getMyID(iframeId) + ']'
123  }
124
125  function isLogEnabled(iframeId) {
126    return settings[iframeId] ? settings[iframeId].log : logEnabled
127  }
128
129  function log(iframeId, msg) {
130    output('log', iframeId, msg, isLogEnabled(iframeId))
131  }
132
133  function info(iframeId, msg) {
134    output('info', iframeId, msg, isLogEnabled(iframeId))
135  }
136
137  function warn(iframeId, msg) {
138    output('warn', iframeId, msg, true)
139  }
140
141  function output(type, iframeId, msg, enabled) {
142    if (true === enabled && 'object' === typeof window.console) {
143      // eslint-disable-next-line no-console
144      console[type](formatLogHeader(iframeId), msg)
145    }
146  }
147
148  function iFrameListener(event) {
149    function resizeIFrame() {
150      function resize() {
151        setSize(messageData)
152        setPagePosition(iframeId)
153        on('onResized', messageData)
154      }
155
156      ensureInRange('Height')
157      ensureInRange('Width')
158
159      syncResize(resize, messageData, 'init')
160    }
161
162    function processMsg() {
163      var data = msg.substr(msgIdLen).split(':')
164      var height = data[1] ? parseInt(data[1], 10) : 0
165      var iframe = settings[data[0]] && settings[data[0]].iframe
166      var compStyle = getComputedStyle(iframe)
167
168      return {
169        iframe: iframe,
170        id: data[0],
171        height: height + getPaddingEnds(compStyle) + getBorderEnds(compStyle),
172        width: data[2],
173        type: data[3]
174      }
175    }
176
177    function getPaddingEnds(compStyle) {
178      if (compStyle.boxSizing !== 'border-box') {
179        return 0
180      }
181      var top = compStyle.paddingTop ? parseInt(compStyle.paddingTop, 10) : 0
182      var bot = compStyle.paddingBottom
183        ? parseInt(compStyle.paddingBottom, 10)
184        : 0
185      return top + bot
186    }
187
188    function getBorderEnds(compStyle) {
189      if (compStyle.boxSizing !== 'border-box') {
190        return 0
191      }
192      var top = compStyle.borderTopWidth
193        ? parseInt(compStyle.borderTopWidth, 10)
194        : 0
195      var bot = compStyle.borderBottomWidth
196        ? parseInt(compStyle.borderBottomWidth, 10)
197        : 0
198      return top + bot
199    }
200
201    function ensureInRange(Dimension) {
202      var max = Number(settings[iframeId]['max' + Dimension]),
203        min = Number(settings[iframeId]['min' + Dimension]),
204        dimension = Dimension.toLowerCase(),
205        size = Number(messageData[dimension])
206
207      log(iframeId, 'Checking ' + dimension + ' is in range ' + min + '-' + max)
208
209      if (size < min) {
210        size = min
211        log(iframeId, 'Set ' + dimension + ' to min value')
212      }
213
214      if (size > max) {
215        size = max
216        log(iframeId, 'Set ' + dimension + ' to max value')
217      }
218
219      messageData[dimension] = '' + size
220    }
221
222    function isMessageFromIFrame() {
223      function checkAllowedOrigin() {
224        function checkList() {
225          var i = 0,
226            retCode = false
227
228          log(
229            iframeId,
230            'Checking connection is from allowed list of origins: ' +
231              checkOrigin
232          )
233
234          for (; i < checkOrigin.length; i++) {
235            if (checkOrigin[i] === origin) {
236              retCode = true
237              break
238            }
239          }
240          return retCode
241        }
242
243        function checkSingle() {
244          var remoteHost = settings[iframeId] && settings[iframeId].remoteHost
245          log(iframeId, 'Checking connection is from: ' + remoteHost)
246          return origin === remoteHost
247        }
248
249        return checkOrigin.constructor === Array ? checkList() : checkSingle()
250      }
251
252      var origin = event.origin,
253        checkOrigin = settings[iframeId] && settings[iframeId].checkOrigin
254
255      if (checkOrigin && '' + origin !== 'null' && !checkAllowedOrigin()) {
256        throw new Error(
257          'Unexpected message received from: ' +
258            origin +
259            ' for ' +
260            messageData.iframe.id +
261            '. Message was: ' +
262            event.data +
263            '. This error can be disabled by setting the checkOrigin: false option or by providing of array of trusted domains.'
264        )
265      }
266
267      return true
268    }
269
270    function isMessageForUs() {
271      return (
272        msgId === ('' + msg).substr(0, msgIdLen) &&
273        msg.substr(msgIdLen).split(':')[0] in settings
274      ) // ''+Protects against non-string msg
275    }
276
277    function isMessageFromMetaParent() {
278      // Test if this message is from a parent above us. This is an ugly test, however, updating
279      // the message format would break backwards compatibility.
280      var retCode = messageData.type in { true: 1, false: 1, undefined: 1 }
281
282      if (retCode) {
283        log(iframeId, 'Ignoring init message from meta parent page')
284      }
285
286      return retCode
287    }
288
289    function getMsgBody(offset) {
290      return msg.substr(msg.indexOf(':') + msgHeaderLen + offset)
291    }
292
293    function forwardMsgFromIFrame(msgBody) {
294      log(
295        iframeId,
296        'onMessage passed: {iframe: ' +
297          messageData.iframe.id +
298          ', message: ' +
299          msgBody +
300          '}'
301      )
302
303      on('onMessage', {
304        iframe: messageData.iframe,
305        message: JSON.parse(msgBody)
306      })
307
308      log(iframeId, '--')
309    }
310
311    function getPageInfo() {
312      var bodyPosition = document.body.getBoundingClientRect(),
313        iFramePosition = messageData.iframe.getBoundingClientRect()
314
315      return JSON.stringify({
316        iframeHeight: iFramePosition.height,
317        iframeWidth: iFramePosition.width,
318        clientHeight: Math.max(
319          document.documentElement.clientHeight,
320          window.innerHeight || 0
321        ),
322        clientWidth: Math.max(
323          document.documentElement.clientWidth,
324          window.innerWidth || 0
325        ),
326        offsetTop: parseInt(iFramePosition.top - bodyPosition.top, 10),
327        offsetLeft: parseInt(iFramePosition.left - bodyPosition.left, 10),
328        scrollTop: window.pageYOffset,
329        scrollLeft: window.pageXOffset,
330        documentHeight: document.documentElement.clientHeight,
331        documentWidth: document.documentElement.clientWidth,
332        windowHeight: window.innerHeight,
333        windowWidth: window.innerWidth
334      })
335    }
336
337    function sendPageInfoToIframe(iframe, iframeId) {
338      function debouncedTrigger() {
339        trigger('Send Page Info', 'pageInfo:' + getPageInfo(), iframe, iframeId)
340      }
341      debounceFrameEvents(debouncedTrigger, 32, iframeId)
342    }
343
344    function startPageInfoMonitor() {
345      function setListener(type, func) {
346        function sendPageInfo() {
347          if (settings[id]) {
348            sendPageInfoToIframe(settings[id].iframe, id)
349          } else {
350            stop()
351          }
352        }
353
354        ;['scroll', 'resize'].forEach(function (evt) {
355          log(id, type + evt + ' listener for sendPageInfo')
356          func(window, evt, sendPageInfo)
357        })
358      }
359
360      function stop() {
361        setListener('Remove ', removeEventListener)
362      }
363
364      function start() {
365        setListener('Add ', addEventListener)
366      }
367
368      var id = iframeId // Create locally scoped copy of iFrame ID
369
370      start()
371
372      if (settings[id]) {
373        settings[id].stopPageInfo = stop
374      }
375    }
376
377    function stopPageInfoMonitor() {
378      if (settings[iframeId] && settings[iframeId].stopPageInfo) {
379        settings[iframeId].stopPageInfo()
380        delete settings[iframeId].stopPageInfo
381      }
382    }
383
384    function checkIFrameExists() {
385      var retBool = true
386
387      if (null === messageData.iframe) {
388        warn(iframeId, 'IFrame (' + messageData.id + ') not found')
389        retBool = false
390      }
391      return retBool
392    }
393
394    function getElementPosition(target) {
395      var iFramePosition = target.getBoundingClientRect()
396
397      getPagePosition(iframeId)
398
399      return {
400        x: Math.floor(Number(iFramePosition.left) + Number(pagePosition.x)),
401        y: Math.floor(Number(iFramePosition.top) + Number(pagePosition.y))
402      }
403    }
404
405    function scrollRequestFromChild(addOffset) {
406      /* istanbul ignore next */ // Not testable in Karma
407      function reposition() {
408        pagePosition = newPosition
409        scrollTo()
410        log(iframeId, '--')
411      }
412
413      function calcOffset() {
414        return {
415          x: Number(messageData.width) + offset.x,
416          y: Number(messageData.height) + offset.y
417        }
418      }
419
420      function scrollParent() {
421        if (window.parentIFrame) {
422          window.parentIFrame['scrollTo' + (addOffset ? 'Offset' : '')](
423            newPosition.x,
424            newPosition.y
425          )
426        } else {
427          warn(
428            iframeId,
429            'Unable to scroll to requested position, window.parentIFrame not found'
430          )
431        }
432      }
433
434      var offset = addOffset
435          ? getElementPosition(messageData.iframe)
436          : { x: 0, y: 0 },
437        newPosition = calcOffset()
438
439      log(
440        iframeId,
441        'Reposition requested from iFrame (offset x:' +
442          offset.x +
443          ' y:' +
444          offset.y +
445          ')'
446      )
447
448      if (window.top !== window.self) {
449        scrollParent()
450      } else {
451        reposition()
452      }
453    }
454
455    function scrollTo() {
456      if (false !== on('onScroll', pagePosition)) {
457        setPagePosition(iframeId)
458      } else {
459        unsetPagePosition()
460      }
461    }
462
463    function findTarget(location) {
464      function jumpToTarget() {
465        var jumpPosition = getElementPosition(target)
466
467        log(
468          iframeId,
469          'Moving to in page link (#' +
470            hash +
471            ') at x: ' +
472            jumpPosition.x +
473            ' y: ' +
474            jumpPosition.y
475        )
476        pagePosition = {
477          x: jumpPosition.x,
478          y: jumpPosition.y
479        }
480
481        scrollTo()
482        log(iframeId, '--')
483      }
484
485      function jumpToParent() {
486        if (window.parentIFrame) {
487          window.parentIFrame.moveToAnchor(hash)
488        } else {
489          log(
490            iframeId,
491            'In page link #' +
492              hash +
493              ' not found and window.parentIFrame not found'
494          )
495        }
496      }
497
498      var hash = location.split('#')[1] || '',
499        hashData = decodeURIComponent(hash),
500        target =
501          document.getElementById(hashData) ||
502          document.getElementsByName(hashData)[0]
503
504      if (target) {
505        jumpToTarget()
506      } else if (window.top !== window.self) {
507        jumpToParent()
508      } else {
509        log(iframeId, 'In page link #' + hash + ' not found')
510      }
511    }
512
513    function onMouse(event) {
514      var mousePos = {}
515
516      if (Number(messageData.width) === 0 && Number(messageData.height) === 0) {
517        var data = getMsgBody(9).split(':')
518        mousePos = {
519          x: data[1],
520          y: data[0]
521        }
522      } else {
523        mousePos = {
524          x: messageData.width,
525          y: messageData.height
526        }
527      }
528
529      on(event, {
530        iframe: messageData.iframe,
531        screenX: Number(mousePos.x),
532        screenY: Number(mousePos.y),
533        type: messageData.type
534      })
535    }
536
537    function on(funcName, val) {
538      return chkEvent(iframeId, funcName, val)
539    }
540
541    function actionMsg() {
542      if (settings[iframeId] && settings[iframeId].firstRun) firstRun()
543
544      switch (messageData.type) {
545        case 'close':
546          closeIFrame(messageData.iframe)
547          break
548
549        case 'message':
550          forwardMsgFromIFrame(getMsgBody(6))
551          break
552
553        case 'mouseenter':
554          onMouse('onMouseEnter')
555          break
556
557        case 'mouseleave':
558          onMouse('onMouseLeave')
559          break
560
561        case 'autoResize':
562          settings[iframeId].autoResize = JSON.parse(getMsgBody(9))
563          break
564
565        case 'scrollTo':
566          scrollRequestFromChild(false)
567          break
568
569        case 'scrollToOffset':
570          scrollRequestFromChild(true)
571          break
572
573        case 'pageInfo':
574          sendPageInfoToIframe(
575            settings[iframeId] && settings[iframeId].iframe,
576            iframeId
577          )
578          startPageInfoMonitor()
579          break
580
581        case 'pageInfoStop':
582          stopPageInfoMonitor()
583          break
584
585        case 'inPageLink':
586          findTarget(getMsgBody(9))
587          break
588
589        case 'reset':
590          resetIFrame(messageData)
591          break
592
593        case 'init':
594          resizeIFrame()
595          on('onInit', messageData.iframe)
596          break
597
598        default:
599          if (
600            Number(messageData.width) === 0 &&
601            Number(messageData.height) === 0
602          ) {
603            warn(
604              'Unsupported message received (' +
605                messageData.type +
606                '), this is likely due to the iframe containing a later ' +
607                'version of iframe-resizer than the parent page'
608            )
609          } else {
610            resizeIFrame()
611          }
612      }
613    }
614
615    function hasSettings(iframeId) {
616      var retBool = true
617
618      if (!settings[iframeId]) {
619        retBool = false
620        warn(
621          messageData.type +
622            ' No settings for ' +
623            iframeId +
624            '. Message was: ' +
625            msg
626        )
627      }
628
629      return retBool
630    }
631
632    function iFrameReadyMsgReceived() {
633      // eslint-disable-next-line no-restricted-syntax, guard-for-in
634      for (var iframeId in settings) {
635        trigger(
636          'iFrame requested init',
637          createOutgoingMsg(iframeId),
638          settings[iframeId].iframe,
639          iframeId
640        )
641      }
642    }
643
644    function firstRun() {
645      if (settings[iframeId]) {
646        settings[iframeId].firstRun = false
647      }
648    }
649
650    var msg = event.data,
651      messageData = {},
652      iframeId = null
653
654    if ('[iFrameResizerChild]Ready' === msg) {
655      iFrameReadyMsgReceived()
656    } else if (isMessageForUs()) {
657      messageData = processMsg()
658      iframeId = messageData.id
659      if (settings[iframeId]) {
660        settings[iframeId].loaded = true
661      }
662
663      if (!isMessageFromMetaParent() && hasSettings(iframeId)) {
664        log(iframeId, 'Received: ' + msg)
665
666        if (checkIFrameExists() && isMessageFromIFrame()) {
667          actionMsg()
668        }
669      }
670    } else {
671      info(iframeId, 'Ignored: ' + msg)
672    }
673  }
674
675  function chkEvent(iframeId, funcName, val) {
676    var func = null,
677      retVal = null
678
679    if (settings[iframeId]) {
680      func = settings[iframeId][funcName]
681
682      if ('function' === typeof func) {
683        retVal = func(val)
684      } else {
685        throw new TypeError(
686          funcName + ' on iFrame[' + iframeId + '] is not a function'
687        )
688      }
689    }
690
691    return retVal
692  }
693
694  function removeIframeListeners(iframe) {
695    var iframeId = iframe.id
696    delete settings[iframeId]
697  }
698
699  function closeIFrame(iframe) {
700    var iframeId = iframe.id
701    if (chkEvent(iframeId, 'onClose', iframeId) === false) {
702      log(iframeId, 'Close iframe cancelled by onClose event')
703      return
704    }
705    log(iframeId, 'Removing iFrame: ' + iframeId)
706
707    try {
708      // Catch race condition error with React
709      if (iframe.parentNode) {
710        iframe.parentNode.removeChild(iframe)
711      }
712    } catch (error) {
713      warn(error)
714    }
715
716    chkEvent(iframeId, 'onClosed', iframeId)
717    log(iframeId, '--')
718    removeIframeListeners(iframe)
719  }
720
721  function getPagePosition(iframeId) {
722    if (null === pagePosition) {
723      pagePosition = {
724        x:
725          window.pageXOffset !== undefined
726            ? window.pageXOffset
727            : document.documentElement.scrollLeft,
728        y:
729          window.pageYOffset !== undefined
730            ? window.pageYOffset
731            : document.documentElement.scrollTop
732      }
733      log(
734        iframeId,
735        'Get page position: ' + pagePosition.x + ',' + pagePosition.y
736      )
737    }
738  }
739
740  function setPagePosition(iframeId) {
741    if (null !== pagePosition) {
742      window.scrollTo(pagePosition.x, pagePosition.y)
743      log(
744        iframeId,
745        'Set page position: ' + pagePosition.x + ',' + pagePosition.y
746      )
747      unsetPagePosition()
748    }
749  }
750
751  function unsetPagePosition() {
752    pagePosition = null
753  }
754
755  function resetIFrame(messageData) {
756    function reset() {
757      setSize(messageData)
758      trigger('reset', 'reset', messageData.iframe, messageData.id)
759    }
760
761    log(
762      messageData.id,
763      'Size reset requested by ' +
764        ('init' === messageData.type ? 'host page' : 'iFrame')
765    )
766    getPagePosition(messageData.id)
767    syncResize(reset, messageData, 'reset')
768  }
769
770  function setSize(messageData) {
771    function setDimension(dimension) {
772      if (!messageData.id) {
773        log('undefined', 'messageData id not set')
774        return
775      }
776      messageData.iframe.style[dimension] = messageData[dimension] + 'px'
777      log(
778        messageData.id,
779        'IFrame (' +
780          iframeId +
781          ') ' +
782          dimension +
783          ' set to ' +
784          messageData[dimension] +
785          'px'
786      )
787    }
788
789    function chkZero(dimension) {
790      // FireFox sets dimension of hidden iFrames to zero.
791      // So if we detect that set up an event to check for
792      // when iFrame becomes visible.
793
794      /* istanbul ignore next */ // Not testable in PhantomJS
795      if (!hiddenCheckEnabled && '0' === messageData[dimension]) {
796        hiddenCheckEnabled = true
797        log(iframeId, 'Hidden iFrame detected, creating visibility listener')
798        fixHiddenIFrames()
799      }
800    }
801
802    function processDimension(dimension) {
803      setDimension(dimension)
804      chkZero(dimension)
805    }
806
807    var iframeId = messageData.iframe.id
808
809    if (settings[iframeId]) {
810      if (settings[iframeId].sizeHeight) {
811        processDimension('height')
812      }
813      if (settings[iframeId].sizeWidth) {
814        processDimension('width')
815      }
816    }
817  }
818
819  function syncResize(func, messageData, doNotSync) {
820    /* istanbul ignore if */ // Not testable in PhantomJS
821    if (
822      doNotSync !== messageData.type &&
823      requestAnimationFrame &&
824      // including check for jasmine because had trouble getting spy to work in unit test using requestAnimationFrame
825      !window.jasmine
826    ) {
827      log(messageData.id, 'Requesting animation frame')
828      requestAnimationFrame(func)
829    } else {
830      func()
831    }
832  }
833
834  function trigger(calleeMsg, msg, iframe, id, noResponseWarning) {
835    function postMessageToIFrame() {
836      var target = settings[id] && settings[id].targetOrigin
837      log(
838        id,
839        '[' +
840          calleeMsg +
841          '] Sending msg to iframe[' +
842          id +
843          '] (' +
844          msg +
845          ') targetOrigin: ' +
846          target
847      )
848      iframe.contentWindow.postMessage(msgId + msg, target)
849    }
850
851    function iFrameNotFound() {
852      warn(id, '[' + calleeMsg + '] IFrame(' + id + ') not found')
853    }
854
855    function chkAndSend() {
856      if (
857        iframe &&
858        'contentWindow' in iframe &&
859        null !== iframe.contentWindow
860      ) {
861        // Null test for PhantomJS
862        postMessageToIFrame()
863      } else {
864        iFrameNotFound()
865      }
866    }
867
868    function warnOnNoResponse() {
869      function warning() {
870        if (settings[id] && !settings[id].loaded && !errorShown) {
871          errorShown = true
872          warn(
873            id,
874            'IFrame has not responded within ' +
875              settings[id].warningTimeout / 1000 +
876              ' seconds. Check iFrameResizer.contentWindow.js has been loaded in iFrame. This message can be ignored if everything is working, or you can set the warningTimeout option to a higher value or zero to suppress this warning.'
877          )
878        }
879      }
880
881      if (
882        !!noResponseWarning &&
883        settings[id] &&
884        !!settings[id].warningTimeout
885      ) {
886        settings[id].msgTimeout = setTimeout(
887          warning,
888          settings[id].warningTimeout
889        )
890      }
891    }
892
893    var errorShown = false
894
895    id = id || iframe.id
896
897    if (settings[id]) {
898      chkAndSend()
899      warnOnNoResponse()
900    }
901  }
902
903  function createOutgoingMsg(iframeId) {
904    return (
905      iframeId +
906      ':' +
907      settings[iframeId].bodyMarginV1 +
908      ':' +
909      settings[iframeId].sizeWidth +
910      ':' +
911      settings[iframeId].log +
912      ':' +
913      settings[iframeId].interval +
914      ':' +
915      settings[iframeId].enablePublicMethods +
916      ':' +
917      settings[iframeId].autoResize +
918      ':' +
919      settings[iframeId].bodyMargin +
920      ':' +
921      settings[iframeId].heightCalculationMethod +
922      ':' +
923      settings[iframeId].bodyBackground +
924      ':' +
925      settings[iframeId].bodyPadding +
926      ':' +
927      settings[iframeId].tolerance +
928      ':' +
929      settings[iframeId].inPageLinks +
930      ':' +
931      settings[iframeId].resizeFrom +
932      ':' +
933      settings[iframeId].widthCalculationMethod +
934      ':' +
935      settings[iframeId].mouseEvents
936    )
937  }
938
939  function isNumber(value) {
940    return typeof value === 'number'
941  }
942
943  function setupIFrame(iframe, options) {
944    function setLimits() {
945      function addStyle(style) {
946        var styleValue = settings[iframeId][style]
947        if (Infinity !== styleValue && 0 !== styleValue) {
948          iframe.style[style] = isNumber(styleValue)
949            ? styleValue + 'px'
950            : styleValue
951          log(iframeId, 'Set ' + style + ' = ' + iframe.style[style])
952        }
953      }
954
955      function chkMinMax(dimension) {
956        if (
957          settings[iframeId]['min' + dimension] >
958          settings[iframeId]['max' + dimension]
959        ) {
960          throw new Error(
961            'Value for min' +
962              dimension +
963              ' can not be greater than max' +
964              dimension
965          )
966        }
967      }
968
969      chkMinMax('Height')
970      chkMinMax('Width')
971
972      addStyle('maxHeight')
973      addStyle('minHeight')
974      addStyle('maxWidth')
975      addStyle('minWidth')
976    }
977
978    function newId() {
979      var id = (options && options.id) || defaults.id + count++
980      if (null !== document.getElementById(id)) {
981        id += count++
982      }
983      return id
984    }
985
986    function ensureHasId(iframeId) {
987      if ('' === iframeId) {
988        // eslint-disable-next-line no-multi-assign
989        iframe.id = iframeId = newId()
990        logEnabled = (options || {}).log
991        log(
992          iframeId,
993          'Added missing iframe ID: ' + iframeId + ' (' + iframe.src + ')'
994        )
995      }
996
997      return iframeId
998    }
999
1000    function setScrolling() {
1001      log(
1002        iframeId,
1003        'IFrame scrolling ' +
1004          (settings[iframeId] && settings[iframeId].scrolling
1005            ? 'enabled'
1006            : 'disabled') +
1007          ' for ' +
1008          iframeId
1009      )
1010      iframe.style.overflow =
1011        false === (settings[iframeId] && settings[iframeId].scrolling)
1012          ? 'hidden'
1013          : 'auto'
1014      switch (settings[iframeId] && settings[iframeId].scrolling) {
1015        case 'omit':
1016          break
1017
1018        case true:
1019          iframe.scrolling = 'yes'
1020          break
1021
1022        case false:
1023          iframe.scrolling = 'no'
1024          break
1025
1026        default:
1027          iframe.scrolling = settings[iframeId]
1028            ? settings[iframeId].scrolling
1029            : 'no'
1030      }
1031    }
1032
1033    // The V1 iFrame script expects an int, where as in V2 expects a CSS
1034    // string value such as '1px 3em', so if we have an int for V2, set V1=V2
1035    // and then convert V2 to a string PX value.
1036    function setupBodyMarginValues() {
1037      if (
1038        'number' ===
1039          typeof (settings[iframeId] && settings[iframeId].bodyMargin) ||
1040        '0' === (settings[iframeId] && settings[iframeId].bodyMargin)
1041      ) {
1042        settings[iframeId].bodyMarginV1 = settings[iframeId].bodyMargin
1043        settings[iframeId].bodyMargin =
1044          '' + settings[iframeId].bodyMargin + 'px'
1045      }
1046    }
1047
1048    function checkReset() {
1049      // Reduce scope of firstRun to function, because IE8's JS execution
1050      // context stack is borked and this value gets externally
1051      // changed midway through running this function!!!
1052      var firstRun = settings[iframeId] && settings[iframeId].firstRun,
1053        resetRequertMethod =
1054          settings[iframeId] &&
1055          settings[iframeId].heightCalculationMethod in resetRequiredMethods
1056
1057      if (!firstRun && resetRequertMethod) {
1058        resetIFrame({ iframe: iframe, height: 0, width: 0, type: 'init' })
1059      }
1060    }
1061
1062    function setupIFrameObject() {
1063      if (settings[iframeId]) {
1064        settings[iframeId].iframe.iFrameResizer = {
1065          close: closeIFrame.bind(null, settings[iframeId].iframe),
1066
1067          removeListeners: removeIframeListeners.bind(
1068            null,
1069            settings[iframeId].iframe
1070          ),
1071
1072          resize: trigger.bind(
1073            null,
1074            'Window resize',
1075            'resize',
1076            settings[iframeId].iframe
1077          ),
1078
1079          moveToAnchor: function (anchor) {
1080            trigger(
1081              'Move to anchor',
1082              'moveToAnchor:' + anchor,
1083              settings[iframeId].iframe,
1084              iframeId
1085            )
1086          },
1087
1088          sendMessage: function (message) {
1089            message = JSON.stringify(message)
1090            trigger(
1091              'Send Message',
1092              'message:' + message,
1093              settings[iframeId].iframe,
1094              iframeId
1095            )
1096          }
1097        }
1098      }
1099    }
1100
1101    // We have to call trigger twice, as we can not be sure if all
1102    // iframes have completed loading when this code runs. The
1103    // event listener also catches the page changing in the iFrame.
1104    function init(msg) {
1105      function iFrameLoaded() {
1106        trigger('iFrame.onload', msg, iframe, undefined, true)
1107        checkReset()
1108      }
1109
1110      function createDestroyObserver(MutationObserver) {
1111        if (!iframe.parentNode) {
1112          return
1113        }
1114
1115        var destroyObserver = new MutationObserver(function (mutations) {
1116          mutations.forEach(function (mutation) {
1117            var removedNodes = Array.prototype.slice.call(mutation.removedNodes) // Transform NodeList into an Array
1118            removedNodes.forEach(function (removedNode) {
1119              if (removedNode === iframe) {
1120                closeIFrame(iframe)
1121              }
1122            })
1123          })
1124        })
1125        destroyObserver.observe(iframe.parentNode, {
1126          childList: true
1127        })
1128      }
1129
1130      var MutationObserver = getMutationObserver()
1131      if (MutationObserver) {
1132        createDestroyObserver(MutationObserver)
1133      }
1134
1135      addEventListener(iframe, 'load', iFrameLoaded)
1136      trigger('init', msg, iframe, undefined, true)
1137    }
1138
1139    function checkOptions(options) {
1140      if ('object' !== typeof options) {
1141        throw new TypeError('Options is not an object')
1142      }
1143    }
1144
1145    function copyOptions(options) {
1146      // eslint-disable-next-line no-restricted-syntax
1147      for (var option in defaults) {
1148        if (Object.prototype.hasOwnProperty.call(defaults, option)) {
1149          settings[iframeId][option] = Object.prototype.hasOwnProperty.call(
1150            options,
1151            option
1152          )
1153            ? options[option]
1154            : defaults[option]
1155        }
1156      }
1157    }
1158
1159    function getTargetOrigin(remoteHost) {
1160      return '' === remoteHost ||
1161        null !== remoteHost.match(/^(about:blank|javascript:|file:\/\/)/)
1162        ? '*'
1163        : remoteHost
1164    }
1165
1166    function depricate(key) {
1167      var splitName = key.split('Callback')
1168
1169      if (splitName.length === 2) {
1170        var name =
1171          'on' + splitName[0].charAt(0).toUpperCase() + splitName[0].slice(1)
1172        this[name] = this[key]
1173        delete this[key]
1174        warn(
1175          iframeId,
1176          "Deprecated: '" +
1177            key +
1178            "' has been renamed '" +
1179            name +
1180            "'. The old method will be removed in the next major version."
1181        )
1182      }
1183    }
1184
1185    function processOptions(options) {
1186      options = options || {}
1187      settings[iframeId] = {
1188        firstRun: true,
1189        iframe: iframe,
1190        remoteHost: iframe.src && iframe.src.split('/').slice(0, 3).join('/')
1191      }
1192
1193      checkOptions(options)
1194      Object.keys(options).forEach(depricate, options)
1195      copyOptions(options)
1196
1197      if (settings[iframeId]) {
1198        settings[iframeId].targetOrigin =
1199          true === settings[iframeId].checkOrigin
1200            ? getTargetOrigin(settings[iframeId].remoteHost)
1201            : '*'
1202      }
1203    }
1204
1205    function beenHere() {
1206      return iframeId in settings && 'iFrameResizer' in iframe
1207    }
1208
1209    var iframeId = ensureHasId(iframe.id)
1210
1211    if (!beenHere()) {
1212      processOptions(options)
1213      setScrolling()
1214      setLimits()
1215      setupBodyMarginValues()
1216      init(createOutgoingMsg(iframeId))
1217      setupIFrameObject()
1218    } else {
1219      warn(iframeId, 'Ignored iFrame, already setup.')
1220    }
1221  }
1222
1223  function debouce(fn, time) {
1224    if (null === timer) {
1225      timer = setTimeout(function () {
1226        timer = null
1227        fn()
1228      }, time)
1229    }
1230  }
1231
1232  var frameTimer = {}
1233  function debounceFrameEvents(fn, time, frameId) {
1234    if (!frameTimer[frameId]) {
1235      frameTimer[frameId] = setTimeout(function () {
1236        frameTimer[frameId] = null
1237        fn()
1238      }, time)
1239    }
1240  }
1241
1242  // Not testable in PhantomJS
1243  /* istanbul ignore next */
1244
1245  function fixHiddenIFrames() {
1246    function checkIFrames() {
1247      function checkIFrame(settingId) {
1248        function chkDimension(dimension) {
1249          return (
1250            '0px' ===
1251            (settings[settingId] && settings[settingId].iframe.style[dimension])
1252          )
1253        }
1254
1255        function isVisible(el) {
1256          return null !== el.offsetParent
1257        }
1258
1259        if (
1260          settings[settingId] &&
1261          isVisible(settings[settingId].iframe) &&
1262          (chkDimension('height') || chkDimension('width'))
1263        ) {
1264          trigger(
1265            'Visibility change',
1266            'resize',
1267            settings[settingId].iframe,
1268            settingId
1269          )
1270        }
1271      }
1272
1273      Object.keys(settings).forEach(function (key) {
1274        checkIFrame(key)
1275      })
1276    }
1277
1278    function mutationObserved(mutations) {
1279		// watch for changes in the inputs corresponding to the iframes
1280		mutations.forEach(mut=>{
1281			// make sure this executes only on pages with a formidable form
1282			if ( window.frmrules && mut.target.classList?.contains('ssa_appointment_form_field_appointment_id') && !mut.target.value){
1283				// scoped function to sync the iframe
1284				let syncIframe = () => {
1285					let src = jQuery(`#${mut.target.id}`).closest('div').find('iframe').attr('src')
1286					jQuery(`#${mut.target.id}`).closest('div').find('iframe').attr( 'src', '' )
1287					debouce(()=>{
1288						jQuery(`#${mut.target.id}`).closest('div').find('iframe').attr( 'src', src )
1289					}, 100 )
1290				}
1291				// debounce to space out the syncs and avoid crashing
1292				debouce(syncIframe, 16)
1293			}
1294		})
1295      log(
1296        'window',
1297        'Mutation observed: ' + mutations[0].target + ' ' + mutations[0].type
1298      )
1299      debouce(checkIFrames, 16)
1300    }
1301
1302    function createMutationObserver() {
1303      var target = document.querySelector('body'),
1304        config = {
1305          attributes: true,
1306          attributeOldValue: false,
1307          characterData: true,
1308          characterDataOldValue: false,
1309          childList: true,
1310          subtree: true
1311        },
1312        observer = new MutationObserver(mutationObserved)
1313
1314      observer.observe(target, config)
1315    }
1316
1317    var MutationObserver = getMutationObserver()
1318    if (MutationObserver) {
1319      createMutationObserver()
1320    }
1321  }
1322
1323  function resizeIFrames(event) {
1324    function resize() {
1325      sendTriggerMsg('Window ' + event, 'resize')
1326    }
1327
1328    log('window', 'Trigger event: ' + event)
1329    debouce(resize, 16)
1330  }
1331
1332  // Not testable in PhantomJS
1333  /* istanbul ignore next */
1334  function tabVisible() {
1335    function resize() {
1336      sendTriggerMsg('Tab Visible', 'resize')
1337    }
1338
1339    if ('hidden' !== document.visibilityState) {
1340      log('document', 'Trigger event: Visibility change')
1341      debouce(resize, 16)
1342    }
1343  }
1344
1345  function sendTriggerMsg(eventName, event) {
1346    function isIFrameResizeEnabled(iframeId) {
1347      return (
1348        settings[iframeId] &&
1349        'parent' === settings[iframeId].resizeFrom &&
1350        settings[iframeId].autoResize &&
1351        !settings[iframeId].firstRun
1352      )
1353    }
1354
1355    Object.keys(settings).forEach(function (iframeId) {
1356      if (isIFrameResizeEnabled(iframeId)) {
1357        trigger(eventName, event, settings[iframeId].iframe, iframeId)
1358      }
1359    })
1360  }
1361
1362  function setupEventListeners() {
1363    addEventListener(window, 'message', iFrameListener)
1364
1365    addEventListener(window, 'resize', function () {
1366      resizeIFrames('resize')
1367    })
1368
1369  }
1370
1371  function factory() {
1372    function init(options, element) {
1373      function chkType() {
1374        if (!element.tagName) {
1375          throw new TypeError('Object is not a valid DOM element')
1376        } else if ('IFRAME' !== element.tagName.toUpperCase()) {
1377          throw new TypeError(
1378            'Expected <IFRAME> tag, found <' + element.tagName + '>'
1379          )
1380        }
1381      }
1382
1383      if (element) {
1384        chkType()
1385        setupIFrame(element, options)
1386        iFrames.push(element)
1387      }
1388    }
1389
1390    function warnDeprecatedOptions(options) {
1391      if (options && options.enablePublicMethods) {
1392        warn(
1393          'enablePublicMethods option has been removed, public methods are now always available in the iFrame'
1394        )
1395      }
1396    }
1397
1398    var iFrames
1399
1400    setupRequestAnimationFrame()
1401    setupEventListeners()
1402
1403    return function iFrameResizeF(options, target) {
1404      iFrames = [] // Only return iFrames past in on this call
1405
1406      warnDeprecatedOptions(options)
1407
1408      switch (typeof target) {
1409        case 'undefined':
1410        case 'string':
1411          Array.prototype.forEach.call(
1412            document.querySelectorAll(target || 'iframe'),
1413            init.bind(undefined, options)
1414          )
1415          break
1416
1417        case 'object':
1418          init(options, target)
1419          break
1420
1421        default:
1422          throw new TypeError('Unexpected data type (' + typeof target + ')')
1423      }
1424
1425      return iFrames
1426    }
1427  }
1428
1429  function createJQueryPublicMethod($) {
1430    if (!$.fn) {
1431      info('', 'Unable to bind to jQuery, it is not fully loaded.')
1432    } else if (!$.fn.iFrameResize) {
1433      $.fn.iFrameResize = function $iFrameResizeF(options) {
1434        function init(index, element) {
1435          setupIFrame(element, options)
1436        }
1437
1438        return this.filter('iframe').each(init).end()
1439      }
1440    }
1441  }
1442
1443  if (window.jQuery) {
1444    createJQueryPublicMethod(window.jQuery)
1445  }
1446
1447  if (typeof define === 'function' && define.amd) {
1448    define([], factory)
1449  } else if (typeof module === 'object' && typeof module.exports === 'object') {
1450    // Node for browserfy
1451    module.exports = factory()
1452  }
1453  window.iFrameResize = window.iFrameResize || factory()
1454})()
1455
1456/* ----- SSA Code --------- */
1457
1458var bookingIframes = document.querySelectorAll('.ssa_booking_iframe');
1459var iframeInteraction = false; // Track if the iframe has been activated
1460
1461var ssaDebouncedScroll = debounce(function(e){ // Debouncing scroll event listener to improve performance
1462	ssaHandleScroll(e);
1463}, 300);
1464
1465// Detect any interactivity with iframe - focus moved to any element inside
1466window.addEventListener('blur', function(){
1467	let activeEl = document.activeElement;
1468
1469	if (activeEl.tagName === 'IFRAME' && activeEl.classList.contains('ssa_booking_iframe')) {
1470		iframeInteraction = true;
1471	}
1472});
1473
1474// helper function to initialize the IframeResizer
1475var ssaInitIframeResizer = function() {
1476	var ssaIframeSettings = {
1477		heightCalculationMethod: 'bodyOffset',
1478		checkOrigin: false,
1479		warningTimeout: 20000,
1480		onResized: ssaDebouncedScroll,
1481		onScroll: false
1482	}
1483
1484	iFrameResize(ssaIframeSettings, '.ssa_booking_iframe')
1485}
1486
1487// call on page load if there are SSA iframes
1488if (bookingIframes) {
1489	ssaInitIframeResizer();
1490}
1491
1492// Only run Elementor and FF code if jQuery is on the page
1493if ( window.jQuery ) {
1494
1495	// Elementor integration
1496	jQuery( document ).on( 'elementor/popup/show', function(){
1497		ssaInitIframeResizer()
1498	});
1499
1500	jQuery( document ).ready(function($){
1501
1502		// Formidable Forms integration
1503		$(document).on( 'frmPageChanged', function( event, form, response ) {
1504			var $iframes = $( '.frm_forms .ssa_booking_iframe' );
1505
1506			// if form page has changed, and the current page contains an SSA iframe,
1507			// initialize IframeResizer
1508			if( $iframes.length ) {
1509				ssaInitIframeResizer();
1510			}
1511		});
1512
1513		// Gravity Forms integration
1514		$( document ).on( 'gform_page_loaded', function( event, form_id, current_page ) {
1515			var $iframes = $( '.gform_wrapper .ssa_booking_iframe' );
1516
1517			// if form page has changed, and the current page contains an SSA iframe,
1518			// initialize IframeResizer
1519			if( $iframes.length ) {
1520				ssaInitIframeResizer();
1521			}
1522		});
1523	});
1524
1525} // end jQuery check
1526
1527// Returns a function, that, as long as it continues to be invoked, will not
1528// be triggered. The function will be called after it stops being called for
1529// N milliseconds. If `immediate` is passed, trigger the function on the
1530// leading edge, instead of the trailing.
1531function debounce(func, wait, immediate) {
1532	var timeout;
1533	return function() {
1534		var context = this, args = arguments;
1535		var later = function() {
1536			timeout = null;
1537			if (!immediate) func.apply(context, args);
1538		};
1539		var callNow = immediate && !timeout;
1540		clearTimeout(timeout);
1541		timeout = setTimeout(later, wait);
1542		if (callNow) func.apply(context, args);
1543	};
1544};
1545
1546function ssaHandleScroll(e) {
1547	if (e.type !== 'mutationObserver' ) { // Only scroll if iframe DOM has mutated
1548		return;
1549	}
1550
1551	var rect = e.iframe.getBoundingClientRect();
1552	var windowHeight = window.innerHeight || document.documentElement.clientHeight;
1553
1554	// is in viewPort 
1555	var isInViewport = rect.bottom >= 0 && 
1556						rect.right >= 0 && 
1557						rect.top <= (window.innerHeight) && 
1558						rect.left <= (window.innerWidth);
1559
1560	// is top of the iframe visible
1561	var isTopVisible = rect.top >= 0 && rect.top <= windowHeight;
1562
1563	// is bottom of the iframe visible
1564	var isBottomVisible = rect.bottom >= 0 && rect.bottom <= windowHeight;
1565
1566	if ( !isInViewport ) {
1567		return;
1568	}
1569
1570	if ( !iframeInteraction ) {
1571		return;
1572	}
1573
1574	if (isBottomVisible && isTopVisible) {
1575		// whole iframe is visible, do nothing
1576		return
1577	}
1578
1579	if ( rect.height > windowHeight ) {
1580		// top of the iframe is visible, scroll to the top of the iframe, 
1581		if ( isTopVisible ) {
1582			e.iframe.scrollIntoView({
1583				behavior: 'smooth',
1584				block: 'start'
1585			});
1586
1587		// if the bottom of the iframe is visible, scroll to the bottom of the iframe
1588		} else if ( isBottomVisible ) {
1589			e.iframe.scrollIntoView({
1590				behavior: 'smooth',
1591				block: 'end'
1592			});
1593		}
1594	} else {
1595		// if the iframe is smaller than the viewport, scroll to the center of the iframe
1596		e.iframe.scrollIntoView({
1597			behavior: 'smooth',
1598			block: 'center'
1599		});
1600		return;
1601	}
1602}
1603

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.