feeles-ide
Version:
The hackable and serializable IDE to make learning material
174 lines (150 loc) • 5.56 kB
JavaScript
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { SrcDocEnabled } from './setSrcDoc';
import ErrorMessage from './ErrorMessage';
import SvgButton from './SvgButton';
var Padding = 1;
var ScaleChangeMin = 0.02;
var Screen = function (_PureComponent) {
_inherits(Screen, _PureComponent);
function Screen() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, Screen);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Screen.__proto__ || _Object$getPrototypeOf(Screen)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
loading: false
}, _this._scale = 0, _this.handleUpdate = function () {
var _this$props = _this.props,
width = _this$props.width,
height = _this$props.height;
if (_this.iframe && _this.iframe.parentNode && _this.iframe.parentNode.parentNode) {
var rect = _this.iframe.parentNode.getBoundingClientRect();
var containerWidth = Math.max(0, rect.width - Padding);
var containerHeight = Math.max(0, rect.height - Padding);
var scale = containerHeight / containerWidth > height / width ? containerWidth / width : containerHeight / height;
if (Math.abs(_this._scale - scale) >= ScaleChangeMin) {
_this.iframe.style.transform = 'scale(' + scale + ')';
_this._scale = scale;
}
}
if (_this.iframe) {
requestAnimationFrame(_this.handleUpdate);
}
}, _this.handleFrame = function (ref) {
_this.iframe = ref;
_this.props.frameRef(ref);
_this._scale = 0;
if (_this.iframe) {
requestAnimationFrame(_this.handleUpdate);
}
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(Screen, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var _this2 = this;
if (this.props.reboot !== nextProps.reboot) {
if (!nextProps.reboot) {
this.setState({ loading: true }, function () {
setTimeout(function () {
_this2.setState({ loading: false });
}, 250);
});
}
}
if (this.iframe) {
this.iframe.width = nextProps.width + 'px';
this.iframe.height = nextProps.height + 'px';
}
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
display = _props.display,
isFullScreen = _props.isFullScreen;
var loading = this.state.loading;
var style = {
position: 'absolute',
width: '100%',
height: '100%',
left: 0,
top: 0,
background: 'linear-gradient(rgba(0,0,0,0.8), rgba(128,128,128,0.8))',
display: display ? 'block' : 'none',
paddingTop: isFullScreen ? 64 : 0, // フルスクリーン中、余白がなくならないように
boxSizing: 'border-box',
overflow: 'hidden',
zIndex: 10
};
var parentStyle = {
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
};
var frameStyle = {
border: '0 none',
flex: '0 0 auto',
opacity: loading ? 0 : 1,
transition: loading ? 'none' : 'opacity 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms'
};
var buttonStyle = {
position: 'absolute',
left: 0,
top: 0,
zIndex: 1
};
var sandbox = SrcDocEnabled ? 'allow-scripts allow-modals allow-popups' : 'allow-scripts allow-modals allow-popups allow-same-origin';
return React.createElement(
'div',
{ style: style },
React.createElement(ErrorMessage, { error: this.props.error }),
this.props.handleReload ? React.createElement(
SvgButton,
{ style: buttonStyle, onClick: this.props.handleReload },
'M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'
) : null,
React.createElement(
'div',
{ style: parentStyle },
this.props.reboot ? null : React.createElement('iframe', {
sandbox: sandbox,
style: frameStyle,
ref: this.handleFrame,
width: this.props.width,
height: this.props.height
})
)
);
}
}]);
return Screen;
}(PureComponent);
Screen.propTypes = {
reboot: PropTypes.bool.isRequired,
animation: PropTypes.bool.isRequired,
display: PropTypes.bool.isRequired,
frameRef: PropTypes.func.isRequired,
handleReload: PropTypes.func,
error: PropTypes.object,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
isFullScreen: PropTypes.bool.isRequired
};
Screen.defaultProps = {
animation: false,
display: false,
error: null,
isFullScreen: false
};
export default Screen;