UNPKG

13.3 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
40
41function _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; }
42
43function _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); } /**
44 * This source code is quoted from rc-upload.
45 * homepage: https://github.com/react-component/upload
46 */
47
48
49var IFRAME_STYLE = {
50 position: 'absolute',
51 top: 0,
52 opacity: 0,
53 filter: 'alpha(opacity=0)',
54 left: 0,
55 zIndex: 9999
56};
57
58var propTypes = {
59 component: _propTypes2["default"].string,
60 style: _propTypes2["default"].object,
61 disabled: _propTypes2["default"].bool,
62 clsPrefix: _propTypes2["default"].string,
63 className: _propTypes2["default"].string,
64 accept: _propTypes2["default"].string,
65 onStart: _propTypes2["default"].func,
66 multiple: _propTypes2["default"].bool,
67 children: _propTypes2["default"].any,
68 data: _propTypes2["default"].oneOfType([_propTypes2["default"].object, _propTypes2["default"].func]),
69 action: _propTypes2["default"].string,
70 name: _propTypes2["default"].string
71};
72// diferent from AjaxUpload, can only upload on at one time, serial seriously
73
74var IframeUploader = function (_Component) {
75 _inherits(IframeUploader, _Component);
76
77 function IframeUploader(props) {
78 _classCallCheck(this, IframeUploader);
79
80 var _this = _possibleConstructorReturn(this, _Component.call(this, props));
81
82 _this.file = {};
83 _this.state = {
84 uploading: false
85 };
86
87 _this.onLoad = _this.onLoad.bind(_this);
88 _this.onChange = _this.onChange.bind(_this);
89 _this.getIframeNode = _this.getIframeNode.bind(_this);
90 _this.getIframeDocument = _this.getIframeDocument.bind(_this);
91 _this.getFormNode = _this.getFormNode.bind(_this);
92 _this.getFormInputNode = _this.getFormInputNode.bind(_this);
93 _this.getFormDataNode = _this.getFormDataNode.bind(_this);
94 _this.getFileForMultiple = _this.getFileForMultiple.bind(_this);
95 _this.getIframeHTML = _this.getIframeHTML.bind(_this);
96 _this.initIframeSrc = _this.initIframeSrc.bind(_this);
97 _this.initIframe = _this.initIframe.bind(_this);
98 _this.endUpload = _this.endUpload.bind(_this);
99 _this.startUpload = _this.startUpload.bind(_this);
100 _this.updateIframeWH = _this.updateIframeWH.bind(_this);
101 _this.abort = _this.abort.bind(_this);
102 _this.post = _this.post.bind(_this);
103 return _this;
104 }
105
106 IframeUploader.prototype.componentDidMount = function componentDidMount() {
107 this.updateIframeWH();
108 this.initIframe();
109 };
110
111 IframeUploader.prototype.componentDidUpdate = function componentDidUpdate() {
112 this.updateIframeWH();
113 };
114
115 IframeUploader.prototype.onLoad = function onLoad() {
116 if (!this.state.uploading) {
117 return;
118 }
119 var props = this.props,
120 file = this.file;
121
122 var response = void 0;
123 try {
124 var doc = this.getIframeDocument();
125 var script = doc.getElementsByTagName('script')[0];
126 if (script && script.parentNode === doc.body) {
127 doc.body.removeChild(script);
128 }
129 response = doc.body.innerHTML;
130 props.onSuccess(response, file);
131 } catch (err) {
132 (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');
133 response = 'cross-domain';
134 props.onError(err, null, file);
135 }
136 this.endUpload();
137 };
138
139 IframeUploader.prototype.onChange = function onChange() {
140 var _this2 = this;
141
142 var target = this.getFormInputNode();
143 // ie8/9 don't support FileList Object
144 // http://stackoverflow.com/questions/12830058/ie8-input-type-file-get-files
145 var file = this.file = {
146 uid: (0, _uid2["default"])(),
147 name: target.value
148 };
149 this.startUpload();
150 var props = this.props;
151
152 if (!props.beforeUpload) {
153 return this.post(file);
154 }
155 var before = props.beforeUpload(file);
156 if (before && before.then) {
157 before.then(function () {
158 _this2.post(file);
159 }, function () {
160 _this2.endUpload();
161 });
162 } else if (before !== false) {
163 this.post(file);
164 } else {
165 this.endUpload();
166 }
167 };
168
169 IframeUploader.prototype.getIframeNode = function getIframeNode() {
170 return this.refs.iframe;
171 };
172
173 IframeUploader.prototype.getIframeDocument = function getIframeDocument() {
174 return this.getIframeNode().contentDocument;
175 };
176
177 IframeUploader.prototype.getFormNode = function getFormNode() {
178 return this.getIframeDocument().getElementById('form');
179 };
180
181 IframeUploader.prototype.getFormInputNode = function getFormInputNode() {
182 return this.getIframeDocument().getElementById('input');
183 };
184
185 IframeUploader.prototype.getFormDataNode = function getFormDataNode() {
186 return this.getIframeDocument().getElementById('data');
187 };
188
189 IframeUploader.prototype.getFileForMultiple = function getFileForMultiple(file) {
190 return this.props.multiple ? [file] : file;
191 };
192
193 IframeUploader.prototype.getIframeHTML = function getIframeHTML(domain) {
194 var domainScript = '';
195 var domainInput = '';
196 if (domain) {
197 domainScript = '<script>document.domain="' + domain + '";</script>';
198 domainInput = '<input name="_documentDomain" value="' + domain + '" />';
199 }
200 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 ';
201 };
202
203 IframeUploader.prototype.initIframeSrc = function initIframeSrc() {
204 if (this.domain) {
205 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 })())';
206 }
207 };
208
209 IframeUploader.prototype.initIframe = function initIframe() {
210 var iframeNode = this.getIframeNode();
211 var win = iframeNode.contentWindow;
212 var doc = void 0;
213 this.domain = this.domain || '';
214 this.initIframeSrc();
215 try {
216 doc = win.document;
217 } catch (e) {
218 this.domain = document.domain;
219 this.initIframeSrc();
220 win = iframeNode.contentWindow;
221 doc = win.document;
222 }
223 doc.open('text/html', 'replace');
224 doc.write(this.getIframeHTML(this.domain));
225 doc.close();
226 this.getFormInputNode().onchange = this.onChange;
227 };
228
229 IframeUploader.prototype.endUpload = function endUpload() {
230 if (this.state.uploading) {
231 this.file = {};
232 // hack avoid batch
233 this.state.uploading = false;
234 this.setState({
235 uploading: false
236 });
237 this.initIframe();
238 }
239 };
240
241 IframeUploader.prototype.startUpload = function startUpload() {
242 if (!this.state.uploading) {
243 this.state.uploading = true;
244 this.setState({
245 uploading: true
246 });
247 }
248 };
249
250 IframeUploader.prototype.updateIframeWH = function updateIframeWH() {
251 var rootNode = _reactDom2["default"].findDOMNode(this);
252 var iframeNode = this.getIframeNode();
253 iframeNode.style.height = rootNode.offsetHeight + 'px';
254 iframeNode.style.width = rootNode.offsetWidth + 'px';
255 };
256
257 IframeUploader.prototype.abort = function abort(file) {
258 if (file) {
259 var uid = file;
260 if (file && file.uid) {
261 uid = file.uid;
262 }
263 if (uid === this.file.uid) {
264 this.endUpload();
265 }
266 } else {
267 this.endUpload();
268 }
269 };
270
271 IframeUploader.prototype.post = function post(file) {
272 var formNode = this.getFormNode();
273 var dataSpan = this.getFormDataNode();
274 var data = this.props.data;
275 var onStart = this.props.onStart;
276
277 if (typeof data === 'function') {
278 data = data(file);
279 }
280 var inputs = [];
281 for (var key in data) {
282 if (data.hasOwnProperty(key)) {
283 inputs.push('<input name="' + key + '" value="' + data[key] + '"/>');
284 }
285 }
286 dataSpan.innerHTML = inputs.join('');
287 formNode.submit();
288 dataSpan.innerHTML = '';
289 onStart(file);
290 };
291
292 IframeUploader.prototype.render = function render() {
293 var _classNames;
294
295 var _props = this.props,
296 Tag = _props.component,
297 disabled = _props.disabled,
298 className = _props.className,
299 clsPrefix = _props.clsPrefix,
300 children = _props.children,
301 style = _props.style;
302
303 var iframeStyle = _extends({}, IFRAME_STYLE, {
304 display: this.state.uploading || disabled ? 'none' : ''
305 });
306 var cls = (0, _classnames2["default"])((_classNames = {}, _defineProperty(_classNames, clsPrefix, true), _defineProperty(_classNames, clsPrefix + '-disabled', disabled), _defineProperty(_classNames, className, className), _classNames));
307 return _react2["default"].createElement(
308 Tag,
309 {
310 className: cls,
311 style: _extends({ position: 'relative', zIndex: 0 }, style)
312 },
313 _react2["default"].createElement('iframe', {
314 ref: 'iframe',
315 onLoad: this.onLoad,
316 style: iframeStyle
317 }),
318 children
319 );
320 };
321
322 return IframeUploader;
323}(_react.Component);
324
325;
326IframeUploader.propTypes = propTypes;
327exports["default"] = IframeUploader;
328module.exports = exports['default'];
\No newline at end of file