UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

214 lines (213 loc) 7.83 kB
import { __assign, __extends } from "tslib"; /* istanbul ignore file */ import React from 'react'; import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import { log, func, obj } from '../../util'; import { uid } from '../util'; var INPUT_STYLE = { position: 'absolute', top: 0, right: 0, fontSize: 9999, zIndex: 9999, opacity: 0, outline: 'none', cursor: 'pointer', }; var IframeUploader = /** @class */ (function (_super) { __extends(IframeUploader, _super); function IframeUploader(props) { var _this = _super.call(this, props) || this; _this.file = {}; _this.uid = ''; _this.state = { uploading: false, }; _this.onLoad = function () { if (!_this.state.uploading) { return; } var _a = _this, props = _a.props, file = _a.file; var response; try { var doc = _this.iFrameEl.contentDocument; var script = doc.getElementsByTagName('script')[0]; if (script && script.parentNode === doc.body) { doc.body.removeChild(script); } response = doc.body.innerHTML; props.onSuccess(response, file); } catch (err) { log.warning('cross domain error for Upload. Maybe server should return document.domain script.'); response = 'cross-domain'; props.onError(err, null, file); } _this.endUpload(); }; _this.onSelect = function (e) { _this.file = { uid: uid(), name: e.target.value, }; _this.props.onSelect([_this.file]); }; _this.saveIFrameRef = function (ref) { _this.iFrameEl = ref; }; _this.saveFormRef = function (ref) { _this.formEl = ref; }; _this.saveDataRef = function (ref) { _this.dataEl = ref; }; _this.saveInputRef = function (ref) { _this.inputEl = ref; }; _this.domain = typeof document !== 'undefined' && document.domain ? document.domain : ''; _this.uid = uid(); return _this; } IframeUploader.prototype.componentDidMount = function () { this.updateInputWH(); }; IframeUploader.prototype.componentDidUpdate = function () { this.updateInputWH(); }; IframeUploader.prototype.startUpload = function () { this.upload(this.file); }; IframeUploader.prototype.upload = function (file) { var _this = this; if (!this.state.uploading) { // eslint-disable-next-line this.state.uploading = true; this.setState({ uploading: true }); } var _a = this.props, beforeUpload = _a.beforeUpload, action = _a.action, name = _a.name, data = _a.data; if (!beforeUpload) { return this.post(file); } var requestData = { action: action, name: name, data: data, }; var before = beforeUpload(file, requestData); if (before && before.then) { before.then(function (data) { _this.post(file, data); }, function () { _this.endUpload(); }); } else if (before !== false) { this.post(file, obj.isPlainObject(before) ? before : undefined); } else { this.endUpload(); } }; IframeUploader.prototype.endUpload = function () { this.file = {}; if (this.state.uploading) { // eslint-disable-next-line this.state.uploading = false; this.setState({ uploading: false }); } }; IframeUploader.prototype.updateInputWH = function () { var rootNode = ReactDOM.findDOMNode(this); var inputNode = this.inputEl; inputNode.style.height = "".concat(rootNode.offsetHeight, "px"); inputNode.style.width = "".concat(rootNode.offsetWidth, "px"); }; IframeUploader.prototype.abort = function (file) { if (file) { var uid_1 = file; if (file && file.uid) { uid_1 = file.uid; } if (uid_1 === this.file.uid) { this.endUpload(); } } else { this.endUpload(); } }; IframeUploader.prototype.post = function (file, requestOption) { if (requestOption === void 0) { requestOption = {}; } var formNode = this.formEl; var dataSpan = this.dataEl; var fileInput = this.inputEl; var propsData = this.props.data; if (typeof propsData === 'function') { propsData = propsData(file); } var action = requestOption.action, name = requestOption.name, data = requestOption.data; if (name) { fileInput.setAttribute('name', name); } if (action) { formNode.setAttribute('action', action); } if (data) { propsData = data; } var inputs = document.createDocumentFragment(); for (var key in propsData) { if (data.hasOwnProperty(key)) { var input = document.createElement('input'); input.setAttribute('name', key); input.value = propsData[key]; inputs.appendChild(input); } } dataSpan.appendChild(inputs); formNode.submit(); dataSpan.innerHTML = ''; this.props.onStart(file); }; IframeUploader.prototype.render = function () { var _a = this.props, disabled = _a.disabled, className = _a.className, children = _a.children, accept = _a.accept, name = _a.name, style = _a.style; var uid = this.uid; var iframeName = "".concat(name, "-").concat(uid, "-iframe"); return (React.createElement("span", { className: className, style: __assign({ position: 'relative', zIndex: 0, display: 'inline-block' }, style) }, !disabled ? (React.createElement("iframe", { ref: this.saveIFrameRef, name: iframeName, onLoad: this.onLoad, style: { display: 'none' } })) : null, React.createElement("form", { ref: this.saveFormRef, method: "post", action: this.props.action, encType: "multipart/form-data", target: iframeName }, React.createElement("input", { name: "_documentDomain", value: this.domain, type: "hidden" }), React.createElement("span", { ref: this.saveDataRef }), React.createElement("input", { ref: this.saveInputRef, type: "file", accept: accept, name: name, onChange: this.onSelect, style: INPUT_STYLE })), children)); }; IframeUploader.propTypes = { style: PropTypes.object, action: PropTypes.string.isRequired, name: PropTypes.string.isRequired, data: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), disabled: PropTypes.bool, className: PropTypes.string, children: PropTypes.node, headers: PropTypes.object, autoUpload: PropTypes.bool, onSelect: PropTypes.func, beforeUpload: PropTypes.func, onStart: PropTypes.func, onSuccess: PropTypes.func, onError: PropTypes.func, accept: PropTypes.string, }; IframeUploader.defaultProps = { name: 'file', onSelect: func.noop, beforeUpload: func.noop, onStart: func.noop, onSuccess: func.noop, onError: func.noop, onAbort: func.noop, }; return IframeUploader; }(React.Component)); export default IframeUploader;