1 | import _extends from 'babel-runtime/helpers/extends';
|
2 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
3 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
4 | import _inherits from 'babel-runtime/helpers/inherits';
|
5 |
|
6 | var _class, _temp, _initialiseProps;
|
7 |
|
8 |
|
9 | import React from 'react';
|
10 | import PropTypes from 'prop-types';
|
11 | import ReactDOM from 'react-dom';
|
12 | import { log, func, obj } from '../../util';
|
13 | import { uid } from '../util';
|
14 |
|
15 | var 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 |
|
26 | var 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 |
|
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 |
|
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);
|
297 | IframeUploader.displayName = 'IframeUploader';
|
298 |
|
299 |
|
300 | export default IframeUploader; |
\ | No newline at end of file |