UNPKG

14.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _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; };
8
9var _react = require('react');
10
11var _react2 = _interopRequireDefault(_react);
12
13var _reactDom = require('react-dom');
14
15var _reactDom2 = _interopRequireDefault(_reactDom);
16
17var _classnames = require('classnames');
18
19var _classnames2 = _interopRequireDefault(_classnames);
20
21var _uid = require('./uid');
22
23var _uid2 = _interopRequireDefault(_uid);
24
25var _warning = require('warning');
26
27var _warning2 = _interopRequireDefault(_warning);
28
29var _propTypes = require('prop-types');
30
31var _propTypes2 = _interopRequireDefault(_propTypes);
32
33function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
34
35function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
36
37function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
38
39function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
40
41function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
42
43function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
44
45function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } /**
46 * This source code is quoted from rc-upload.
47 * homepage: https://github.com/react-component/upload
48 */
49
50
51var IFRAME_STYLE = {
52 position: 'absolute',
53 top: 0,
54 opacity: 0,
55 filter: 'alpha(opacity=0)',
56 left: 0,
57 zIndex: 9999
58};
59
60var propTypes = {
61 component: _propTypes2["default"].string,
62 style: _propTypes2["default"].object,
63 disabled: _propTypes2["default"].bool,
64 clsPrefix: _propTypes2["default"].string,
65 className: _propTypes2["default"].string,
66 accept: _propTypes2["default"].string,
67 onStart: _propTypes2["default"].func,
68 multiple: _propTypes2["default"].bool,
69 children: _propTypes2["default"].any,
70 data: _propTypes2["default"].oneOfType([_propTypes2["default"].object, _propTypes2["default"].func]),
71 action: _propTypes2["default"].string,
72 name: _propTypes2["default"].string
73};
74// diferent from AjaxUpload, can only upload on at one time, serial seriously
75
76var IframeUploader = function (_Component) {
77 _inherits(IframeUploader, _Component);
78
79 function IframeUploader(props) {
80 _classCallCheck(this, IframeUploader);
81
82 var _this = _possibleConstructorReturn(this, _Component.call(this, props));
83
84 _this.file = {};
85 _this.state = {
86 uploading: false
87 };
88
89 _this.onLoad = _this.onLoad.bind(_this);
90 _this.onChange = _this.onChange.bind(_this);
91 _this.getIframeNode = _this.getIframeNode.bind(_this);
92 _this.getIframeDocument = _this.getIframeDocument.bind(_this);
93 _this.getFormNode = _this.getFormNode.bind(_this);
94 _this.getFormInputNode = _this.getFormInputNode.bind(_this);
95 _this.getFormDataNode = _this.getFormDataNode.bind(_this);
96 _this.getFileForMultiple = _this.getFileForMultiple.bind(_this);
97 _this.getIframeHTML = _this.getIframeHTML.bind(_this);
98 _this.initIframeSrc = _this.initIframeSrc.bind(_this);
99 _this.initIframe = _this.initIframe.bind(_this);
100 _this.endUpload = _this.endUpload.bind(_this);
101 _this.startUpload = _this.startUpload.bind(_this);
102 _this.updateIframeWH = _this.updateIframeWH.bind(_this);
103 _this.abort = _this.abort.bind(_this);
104 _this.post = _this.post.bind(_this);
105 return _this;
106 }
107
108 IframeUploader.prototype.componentDidMount = function componentDidMount() {
109 this.updateIframeWH();
110 this.initIframe();
111 };
112
113 IframeUploader.prototype.componentDidUpdate = function componentDidUpdate() {
114 this.updateIframeWH();
115 };
116
117 IframeUploader.prototype.onLoad = function onLoad() {
118 if (!this.state.uploading) {
119 return;
120 }
121 var props = this.props,
122 file = this.file;
123
124 var response = void 0;
125 try {
126 var doc = this.getIframeDocument();
127 var script = doc.getElementsByTagName('script')[0];
128 if (script && script.parentNode === doc.body) {
129 doc.body.removeChild(script);
130 }
131 response = doc.body.innerHTML;
132 props.onSuccess(response, file);
133 } catch (err) {
134 (0, _warning2["default"])(false, 'cross domain error for Upload. Maybe server should return document.domain script. see Note from https://github.com/react-component/upload');
135 response = 'cross-domain';
136 props.onError(err, null, file);
137 }
138 this.endUpload();
139 };
140
141 IframeUploader.prototype.onChange = function onChange() {
142 var _this2 = this;
143
144 var target = this.getFormInputNode();
145 // ie8/9 don't support FileList Object
146 // http://stackoverflow.com/questions/12830058/ie8-input-type-file-get-files
147 var file = this.file = {
148 uid: (0, _uid2["default"])(),
149 name: target.value
150 };
151 this.startUpload();
152 var props = this.props;
153
154 if (!props.beforeUpload) {
155 return this.post(file);
156 }
157 var before = props.beforeUpload(file);
158 if (before && before.then) {
159 before.then(function () {
160 _this2.post(file);
161 }, function () {
162 _this2.endUpload();
163 });
164 } else if (before !== false) {
165 this.post(file);
166 } else {
167 this.endUpload();
168 }
169 };
170
171 IframeUploader.prototype.getIframeNode = function getIframeNode() {
172 return this.refs.iframe;
173 };
174
175 IframeUploader.prototype.getIframeDocument = function getIframeDocument() {
176 return this.getIframeNode().contentDocument;
177 };
178
179 IframeUploader.prototype.getFormNode = function getFormNode() {
180 return this.getIframeDocument().getElementById('form');
181 };
182
183 IframeUploader.prototype.getFormInputNode = function getFormInputNode() {
184 return this.getIframeDocument().getElementById('input');
185 };
186
187 IframeUploader.prototype.getFormDataNode = function getFormDataNode() {
188 return this.getIframeDocument().getElementById('data');
189 };
190
191 IframeUploader.prototype.getFileForMultiple = function getFileForMultiple(file) {
192 return this.props.multiple ? [file] : file;
193 };
194
195 IframeUploader.prototype.getIframeHTML = function getIframeHTML(domain) {
196 var domainScript = '';
197 var domainInput = '';
198 if (domain) {
199 domainScript = '<script>document.domain="' + domain + '";</script>';
200 domainInput = '<input name="_documentDomain" value="' + domain + '" />';
201 }
202 return '\n <!DOCTYPE html>\n <html>\n <head>\n <meta http-equiv="X-UA-Compatible" content="IE=edge" />\n <style>\n body,html {padding:0;margin:0;border:0;overflow:hidden;}\n </style>\n ' + domainScript + '\n </head>\n <body>\n <form method="post"\n encType="multipart/form-data"\n action="' + this.props.action + '" id="form"\n style="display:block;height:9999px;position:relative;overflow:hidden;">\n <input id="input" type="file"\n name="' + this.props.name + '"\n style="position:absolute;top:0;right:0;height:9999px;font-size:9999px;cursor:pointer;"/>\n ' + domainInput + '\n <span id="data"></span>\n </form>\n </body>\n </html>\n ';
203 };
204
205 IframeUploader.prototype.initIframeSrc = function initIframeSrc() {
206 if (this.domain) {
207 this.getIframeNode().src = 'javascript:void((function(){\n var d = document;\n d.open();\n d.domain=\'' + this.domain + '\';\n d.write(\'\');\n d.close();\n })())';
208 }
209 };
210
211 IframeUploader.prototype.initIframe = function initIframe() {
212 var iframeNode = this.getIframeNode();
213 var win = iframeNode.contentWindow;
214 var doc = void 0;
215 this.domain = this.domain || '';
216 this.initIframeSrc();
217 try {
218 doc = win.document;
219 } catch (e) {
220 this.domain = document.domain;
221 this.initIframeSrc();
222 win = iframeNode.contentWindow;
223 doc = win.document;
224 }
225 doc.open('text/html', 'replace');
226 doc.write(this.getIframeHTML(this.domain));
227 doc.close();
228 this.getFormInputNode().onchange = this.onChange;
229 };
230
231 IframeUploader.prototype.endUpload = function endUpload() {
232 if (this.state.uploading) {
233 this.file = {};
234 // hack avoid batch
235 this.state.uploading = false;
236 this.setState({
237 uploading: false
238 });
239 this.initIframe();
240 }
241 };
242
243 IframeUploader.prototype.startUpload = function startUpload() {
244 if (!this.state.uploading) {
245 this.state.uploading = true;
246 this.setState({
247 uploading: true
248 });
249 }
250 };
251
252 IframeUploader.prototype.updateIframeWH = function updateIframeWH() {
253 var rootNode = _reactDom2["default"].findDOMNode(this);
254 var iframeNode = this.getIframeNode();
255 iframeNode.style.height = rootNode.offsetHeight + 'px';
256 iframeNode.style.width = rootNode.offsetWidth + 'px';
257 };
258
259 IframeUploader.prototype.abort = function abort(file) {
260 if (file) {
261 var uid = file;
262 if (file && file.uid) {
263 uid = file.uid;
264 }
265 if (uid === this.file.uid) {
266 this.endUpload();
267 }
268 } else {
269 this.endUpload();
270 }
271 };
272
273 IframeUploader.prototype.post = function post(file) {
274 var formNode = this.getFormNode();
275 var dataSpan = this.getFormDataNode();
276 var data = this.props.data;
277 var onStart = this.props.onStart;
278
279 if (typeof data === 'function') {
280 data = data(file);
281 }
282 var inputs = [];
283 for (var key in data) {
284 if (data.hasOwnProperty(key)) {
285 inputs.push('<input name="' + key + '" value="' + data[key] + '"/>');
286 }
287 }
288 dataSpan.innerHTML = inputs.join('');
289 formNode.submit();
290 dataSpan.innerHTML = '';
291 onStart(file);
292 };
293
294 IframeUploader.prototype.render = function render() {
295 var _classNames;
296
297 var _props = this.props,
298 Tag = _props.component,
299 disabled = _props.disabled,
300 className = _props.className,
301 clsPrefix = _props.clsPrefix,
302 children = _props.children,
303 style = _props.style,
304 name = _props.name,
305 action = _props.action,
306 headers = _props.headers,
307 data = _props.data,
308 type = _props.type,
309 listType = _props.listType,
310 fileList = _props.fileList,
311 defaultFileList = _props.defaultFileList,
312 size = _props.size,
313 beforeUpload = _props.beforeUpload,
314 showUploadList = _props.showUploadList,
315 supportServerRender = _props.supportServerRender,
316 onStart = _props.onStart,
317 onSuccess = _props.onSuccess,
318 multipart = _props.multipart,
319 onReady = _props.onReady,
320 customRequest = _props.customRequest,
321 withCredentials = _props.withCredentials,
322 onChange = _props.onChange,
323 others = _objectWithoutProperties(_props, ['component', 'disabled', 'className', 'clsPrefix', 'children', 'style', 'name', 'action', 'headers', 'data', 'type', 'listType', 'fileList', 'defaultFileList', 'size', 'beforeUpload', 'showUploadList', 'supportServerRender', 'onStart', 'onSuccess', 'multipart', 'onReady', 'customRequest', 'withCredentials', 'onChange']);
324
325 var iframeStyle = _extends({}, IFRAME_STYLE, {
326 display: this.state.uploading || disabled ? 'none' : ''
327 });
328 var cls = (0, _classnames2["default"])((_classNames = {}, _defineProperty(_classNames, clsPrefix, true), _defineProperty(_classNames, clsPrefix + '-disabled', disabled), _defineProperty(_classNames, className, className), _classNames));
329 return _react2["default"].createElement(
330 Tag,
331 _extends({
332 className: cls,
333 style: _extends({ position: 'relative', zIndex: 0 }, style)
334 }, others),
335 _react2["default"].createElement('iframe', {
336 ref: 'iframe',
337 onLoad: this.onLoad,
338 style: iframeStyle
339 }),
340 children
341 );
342 };
343
344 return IframeUploader;
345}(_react.Component);
346
347;
348IframeUploader.propTypes = propTypes;
349exports["default"] = IframeUploader;
350module.exports = exports['default'];
\No newline at end of file