ima-ui-atoms
Version:
IMA.js UI React atoms
166 lines (142 loc) • 6.03 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = _interopRequireDefault(require("react"));
var _Sizer = _interopRequireDefault(require("../sizer/Sizer"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const MIN_EXTENDED_PADDING = 500;
/**
* Html classic iframe
*
* @namespace ima.ui.atom.iframe
* @module ima.ui.atom
*/
class HtmlIframe extends _react.default.PureComponent {
static get contextTypes() {
return {
$Utils: _propTypes.default.object
};
}
static getDerivedStateFromProps(nextProps, prevState) {
return {
visibleInViewport: nextProps.noloading || prevState.visibleInViewport || false
};
}
constructor(props, context) {
super(props, context);
this.state = {};
this._registeredVisibilityId = null;
this._onVisibilityWriter = this.onVisibilityWriter.bind(this);
this._rootElement = _react.default.createRef();
this._helper = this.utils.$UIComponentHelper;
this._settings = this.utils.$Settings;
}
get utils() {
return this.context.$Utils || this.props.$Utils;
}
get useIntersectionObserver() {
return this.props.useIntersectionObserver !== undefined ? this.props.useIntersectionObserver : this._settings.plugin.uiAtoms.useIntersectionObserver.iframes;
}
get disableNoScript() {
return this.props.disableNoScript !== undefined ? this.props.disableNoScript : this._settings.plugin.uiAtoms.disableNoScript.iframes;
}
componentDidMount() {
if (this.state.visibleInViewport === false) {
this._registerToCheckingVisibility();
}
}
componentWillUnmount() {
this._unregisterToCheckingVisibility();
}
render() {
return _react.default.createElement("div", _extends({
ref: this._rootElement,
className: this._helper.cssClasses({
'atm-iframe': true,
'atm-overflow': true,
'atm-placeholder': !this.state.visibleInViewport,
'atm-responsive': this.props.layout === 'responsive',
'atm-fill': this.props.layout === 'fill'
}, this.props.className),
style: this.props.layout === 'responsive' ? {} : {
width: this.props.width || 'auto',
height: this.props.height || 'auto'
}
}, this._helper.getDataProps(this.props)), this.props.layout === 'responsive' ? _react.default.createElement(_Sizer.default, {
width: this.props.width,
height: this.props.height,
placeholder: true
}) : null, this.state.visibleInViewport ? _react.default.createElement("iframe", _extends({
src: this.props.src,
name: this.props.src,
srcDoc: this.props.srcDoc,
width: this.props.width,
height: this.props.height,
scrolling: this.props.scrolling,
sandbox: this.props.sandbox,
frameBorder: this.props.frameBorder,
allow: this.props.allow,
allowFullScreen: this.props.allowFullScreen,
onLoad: this.props.onLoad,
marginWidth: this.props.marginWidth,
marginHeight: this.props.marginHeight,
className: this._helper.cssClasses({
'atm-fill': true
})
}, this._helper.getAriaProps(this.props))) : null, !this.disableNoScript && _react.default.createElement("noscript", {
className: this._helper.cssClasses('atm-fill'),
style: {
display: 'block',
width: this.props.width || 'auto',
height: this.props.height || 'auto'
},
dangerouslySetInnerHTML: {
__html: `<iframe
src="${this.props.src}"
${this.props.srcDoc !== null ? `srcdoc="${this.props.srcDoc}"` : ''}
width="${this.props.width || 'auto'}"
height="${this.props.height || 'auto'}"
${this.props.sandbox ? `sandbox="${this.props.sandbox}"` : ''}
scrolling="${this.props.scrolling || 'no'}"
frameborder="${this.props.frameBorder || '0'}"
${this.props.allow ? `allow="${this.props.allow}"` : ''}
allowfullscreen="${this.props.allowFullScreen || '0'}"
${Number.isInteger(this.props.marginWidth) ? `marginwidth="${this.props.marginWidth}"` : ''}
${Number.isInteger(this.props.marginHeight) ? `marginheight="${this.props.marginHeight}"` : ''}
class="${this._helper.cssClasses('atm-fill atm-loaded')}"
${this._helper.serializeObjectToNoScript(this._helper.getAriaProps(this.props))}></iframe>`
}
}));
}
onVisibilityWriter(visibility, observer) {
if (visibility > 0) {
observer && observer.disconnect();
this._unregisterToCheckingVisibility();
if (this.state.visibleInViewport === false) {
this.setState({
visibleInViewport: true
});
}
}
}
_unregisterToCheckingVisibility() {
if (this._registeredVisibilityId) {
this._helper.visibility.unregister(this._registeredVisibilityId);
this._registeredVisibilityId = null;
}
}
_registerToCheckingVisibility() {
let extendedPadding = Math.max(this._helper.componentPositions.getWindowViewportRect().height / 2, MIN_EXTENDED_PADDING);
this._registeredVisibilityId = this._helper.visibility.register(this._helper.getVisibilityReader(this._rootElement.current, {
useIntersectionObserver: this.useIntersectionObserver,
extendedPadding,
width: this.props.width,
height: this.props.height
}), this._helper.wrapVisibilityWriter(this._onVisibilityWriter));
}
}
exports.default = HtmlIframe;