UNPKG

braintree-web

Version:

A suite of tools for integrating Braintree in the browser

121 lines (100 loc) 3.35 kB
"use strict"; var iFramer = require("@braintree/iframer"); var assign = require("../../../assign").assign; var browserDetection = require("../../shared/browser-detection"); var ELEMENT_STYLES = { position: "fixed", top: 0, left: 0, bottom: 0, padding: 0, margin: 0, border: 0, outline: "none", zIndex: 20001, background: "#FFFFFF", }; function noop() {} /** * * We should not ever really use the Modal. Modals are _like_ popups, but the key difference is that the customer can't actually verify it's app domain and thus secure/valid. Old PP sdk (./src/paypal) uses this * to get info from webviews (e.g. facebook). */ function Modal(options) { this._closed = null; this._frame = null; this._options = options || {}; this._container = this._options.container || document.body; } Modal.prototype.initialize = noop; Modal.prototype.open = function () { var iframerConfig = { src: this._options.openFrameUrl, name: this._options.name, scrolling: "yes", height: "100%", width: "100%", style: assign({}, ELEMENT_STYLES), title: "Lightbox Frame", }; if (browserDetection.isIos()) { // WKWebView has buggy behavior when scrolling a fixed position modal. The workaround is to lock scrolling in // the background. When modal is closed, we restore scrolling and return to the previous scroll position. if (browserDetection.isIosWKWebview()) { this._lockScrolling(); // Allows WKWebView to scroll all the way down to bottom iframerConfig.style = {}; } this._el = document.createElement("div"); assign(this._el.style, ELEMENT_STYLES, { height: "100%", width: "100%", overflow: "auto", "-webkit-overflow-scrolling": "touch", }); this._frame = iFramer(iframerConfig); this._el.appendChild(this._frame); } else { this._el = this._frame = iFramer(iframerConfig); } this._closed = false; this._container.appendChild(this._el); }; Modal.prototype.focus = noop; Modal.prototype.close = function () { this._container.removeChild(this._el); this._frame = null; this._closed = true; if (browserDetection.isIosWKWebview()) { this._unlockScrolling(); } }; Modal.prototype.isClosed = function () { return Boolean(this._closed); }; Modal.prototype.redirect = function (redirectUrl) { this._frame.src = redirectUrl; }; Modal.prototype._unlockScrolling = function () { document.body.style.overflow = this._savedBodyProperties.overflowStyle; document.body.style.position = this._savedBodyProperties.positionStyle; window.scrollTo( this._savedBodyProperties.left, this._savedBodyProperties.top ); delete this._savedBodyProperties; }; Modal.prototype._lockScrolling = function () { var doc = document.documentElement; // From https://stackoverflow.com/questions/9538868/prevent-body-from-scrolling-when-a-modal-is-opened#comment65626743_24727206 this._savedBodyProperties = { left: (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0), top: (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0), overflowStyle: document.body.style.overflow, positionStyle: document.body.style.position, }; document.body.style.overflow = "hidden"; document.body.style.position = "fixed"; window.scrollTo(0, 0); }; module.exports = Modal;