UNPKG

8.88 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
3import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
4import _inherits from 'babel-runtime/helpers/inherits';
5
6var _class, _temp, _initialiseProps;
7
8/* istanbul ignore file */
9import React from 'react';
10import PropTypes from 'prop-types';
11import ReactDOM from 'react-dom';
12import { log, func, obj } from '../../util';
13import { uid } from '../util';
14
15var INPUT_STYLE = {
16 position: 'absolute',
17 top: 0,
18 right: 0,
19 fontSize: 9999,
20 zIndex: 9999,
21 opacity: 0,
22 outline: 'none',
23 cursor: 'pointer'
24};
25
26var IframeUploader = (_temp = _class = function (_React$Component) {
27 _inherits(IframeUploader, _React$Component);
28
29 function IframeUploader(props) {
30 _classCallCheck(this, IframeUploader);
31
32 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
33
34 _initialiseProps.call(_this);
35
36 _this.domain = typeof document !== 'undefined' && document.domain ? document.domain : '';
37 _this.uid = uid();
38 return _this;
39 }
40
41 IframeUploader.prototype.componentDidMount = function componentDidMount() {
42 this.updateInputWH();
43 };
44
45 IframeUploader.prototype.componentDidUpdate = function componentDidUpdate() {
46 this.updateInputWH();
47 };
48
49 IframeUploader.prototype.startUpload = function startUpload() {
50 this.upload(this.file);
51 };
52
53 IframeUploader.prototype.upload = function upload(file) {
54 var _this2 = this;
55
56 if (!this.state.uploading) {
57 // eslint-disable-next-line
58 this.state.uploading = true;
59 this.setState({ uploading: true });
60 }
61
62 var _props = this.props,
63 beforeUpload = _props.beforeUpload,
64 action = _props.action,
65 name = _props.name,
66 data = _props.data;
67
68 if (!beforeUpload) {
69 return this.post(file);
70 }
71 var requestData = {
72 action: action,
73 name: name,
74 data: data
75 };
76 var before = beforeUpload(file, requestData);
77 if (before && before.then) {
78 before.then(function (data) {
79 _this2.post(file, data);
80 }, function () {
81 _this2.endUpload();
82 });
83 } else if (before !== false) {
84 this.post(file, obj.isPlainObject(before) ? before : undefined);
85 } else {
86 this.endUpload();
87 }
88 };
89
90 IframeUploader.prototype.endUpload = function endUpload() {
91 this.file = {};
92 if (this.state.uploading) {
93 // eslint-disable-next-line
94 this.state.uploading = false;
95 this.setState({ uploading: false });
96 }
97 };
98
99 IframeUploader.prototype.updateInputWH = function updateInputWH() {
100 var rootNode = ReactDOM.findDOMNode(this);
101 var inputNode = this.inputEl;
102 inputNode.style.height = rootNode.offsetHeight + 'px';
103 inputNode.style.width = rootNode.offsetWidth + 'px';
104 };
105
106 IframeUploader.prototype.abort = function abort(file) {
107 if (file) {
108 var _uid = file;
109 if (file && file.uid) {
110 _uid = file.uid;
111 }
112 if (_uid === this.file.uid) {
113 this.endUpload();
114 }
115 } else {
116 this.endUpload();
117 }
118 };
119
120 IframeUploader.prototype.post = function post(file) {
121 var requestOption = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
122
123 var formNode = this.formEl;
124 var dataSpan = this.dataEl;
125 var fileInput = this.inputEl;
126
127 var propsData = this.props.data;
128 if (typeof propsData === 'function') {
129 propsData = propsData(file);
130 }
131
132 var action = requestOption.action,
133 name = requestOption.name,
134 data = requestOption.data;
135
136 if (name) {
137 fileInput.setAttribute('name', name);
138 }
139
140 if (action) {
141 formNode.setAttribute('action', action);
142 }
143
144 if (data) {
145 propsData = data;
146 }
147
148 var inputs = document.createDocumentFragment();
149 for (var key in propsData) {
150 if (data.hasOwnProperty(key)) {
151 var input = document.createElement('input');
152 input.setAttribute('name', key);
153 input.value = propsData[key];
154 inputs.appendChild(input);
155 }
156 }
157 dataSpan.appendChild(inputs);
158 formNode.submit();
159 dataSpan.innerHTML = '';
160 this.props.onStart(file);
161 };
162
163 IframeUploader.prototype.render = function render() {
164 var _props2 = this.props,
165 disabled = _props2.disabled,
166 className = _props2.className,
167 children = _props2.children,
168 accept = _props2.accept,
169 name = _props2.name,
170 style = _props2.style;
171 var uid = this.uid;
172
173 var iframeName = name + '-' + uid + '-iframe';
174
175 return React.createElement(
176 'span',
177 {
178 className: className,
179 style: _extends({
180 position: 'relative',
181 zIndex: 0,
182 display: 'inline-block'
183 }, style)
184 },
185 !disabled ? React.createElement('iframe', {
186 ref: this.saveIFrameRef,
187 name: iframeName,
188 onLoad: this.onLoad,
189 style: { display: 'none' }
190 }) : null,
191 React.createElement(
192 'form',
193 {
194 ref: this.saveFormRef,
195 method: 'post',
196 action: this.props.action,
197 encType: 'multipart/form-data',
198 target: iframeName
199 },
200 React.createElement('input', { name: '_documentDomain', value: this.domain, type: 'hidden' }),
201 React.createElement('span', { ref: this.saveDataRef }),
202 React.createElement('input', {
203 ref: this.saveInputRef,
204 type: 'file',
205 accept: accept,
206 name: name,
207 onChange: this.onSelect,
208 style: INPUT_STYLE
209 })
210 ),
211 children
212 );
213 };
214
215 return IframeUploader;
216}(React.Component), _class.propTypes = {
217 style: PropTypes.object,
218 action: PropTypes.string.isRequired,
219 name: PropTypes.string.isRequired,
220 data: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
221 disabled: PropTypes.bool,
222 className: PropTypes.string,
223 children: PropTypes.node,
224 headers: PropTypes.object,
225 autoUpload: PropTypes.bool,
226 onSelect: PropTypes.func,
227 beforeUpload: PropTypes.func,
228 onStart: PropTypes.func,
229 onSuccess: PropTypes.func,
230 onError: PropTypes.func,
231 accept: PropTypes.string
232}, _class.defaultProps = {
233 name: 'file',
234 onSelect: func.noop,
235 beforeUpload: func.noop,
236 onStart: func.noop,
237 onSuccess: func.noop,
238 onError: func.noop,
239 onAbort: func.noop
240}, _initialiseProps = function _initialiseProps() {
241 var _this3 = this;
242
243 this.state = {
244 uploading: false
245 };
246 this.file = {};
247 this.uid = '';
248
249 this.onLoad = function () {
250 if (!_this3.state.uploading) {
251 return;
252 }
253 var props = _this3.props,
254 file = _this3.file;
255
256 var response = void 0;
257 try {
258 var doc = _this3.iFrameEl.contentDocument;
259 var script = doc.getElementsByTagName('script')[0];
260 if (script && script.parentNode === doc.body) {
261 doc.body.removeChild(script);
262 }
263 response = doc.body.innerHTML;
264 props.onSuccess(response, file);
265 } catch (err) {
266 log.warning('cross domain error for Upload. Maybe server should return document.domain script.');
267 response = 'cross-domain';
268 props.onError(err, null, file);
269 }
270 _this3.endUpload();
271 };
272
273 this.onSelect = function (e) {
274 _this3.file = {
275 uid: uid(),
276 name: e.target.value
277 };
278 _this3.props.onSelect([_this3.file]);
279 };
280
281 this.saveIFrameRef = function (ref) {
282 _this3.iFrameEl = ref;
283 };
284
285 this.saveFormRef = function (ref) {
286 _this3.formEl = ref;
287 };
288
289 this.saveDataRef = function (ref) {
290 _this3.dataEl = ref;
291 };
292
293 this.saveInputRef = function (ref) {
294 _this3.inputEl = ref;
295 };
296}, _temp);
297IframeUploader.displayName = 'IframeUploader';
298
299
300export default IframeUploader;
\No newline at end of file