1 /** 2 * drag file support for html5 file&dd 3 * @author yiminghe@gmail.com 4 * @refer: http://www.html5rocks.com/tutorials/file/filesystem/ 5 * http://yiminghe.iteye.com/blog/848613 6 */ 7 KISSY.add("editor/plugin/dragUpload/index", function (S, Editor) { 8 var Node = S.Node, 9 Event = S.Event, 10 Utils = Editor.Utils, 11 DOM = S.DOM; 12 13 function dragUpload(config) { 14 this.config=config||{}; 15 } 16 17 S.augment(dragUpload, { 18 renderUI:function (editor) { 19 var cfg = this.config, 20 fileInput = cfg['fileInput'] || "Filedata", 21 sizeLimit = cfg['sizeLimit'] || Number.MAX_VALUE, 22 serverParams = cfg['serverParams'] || {}, 23 serverUrl = cfg['serverUrl'] || "", 24 suffix = cfg['suffix'] || "png,jpg,jpeg,gif", 25 suffix_reg = new RegExp(suffix.split(/,/).join("|") + "$", "i"), 26 27 inserted = {}, startMonitor = false; 28 29 function nodeInsert(ev) { 30 var oe = ev['originalEvent'], 31 t = oe.target; 32 if (DOM.nodeName(t) == "img" && t.src.match(/^file:\/\//)) { 33 inserted[t.src] = t; 34 } 35 } 36 37 editor.docReady(function () { 38 var document = editor.get("document")[0]; 39 Event.on(document, "dragenter", function () { 40 //firefox 会插入伪数据 41 if (!startMonitor) { 42 Event.on(document, "DOMNodeInserted", nodeInsert); 43 startMonitor = true; 44 } 45 }); 46 47 Event.on(document, "drop", function (ev) { 48 Event.remove(document, "DOMNodeInserted", nodeInsert); 49 startMonitor = false; 50 ev.halt(); 51 ev = ev['originalEvent']; 52 53 var archor, ap; 54 /** 55 * firefox 会自动添加节点 56 */ 57 if (!S.isEmptyObject(inserted)) { 58 S.each(inserted, function (el) { 59 if (DOM.nodeName(el) == "img") { 60 archor = el.nextSibling; 61 ap = el.parentNode; 62 DOM.remove(el); 63 } 64 }); 65 inserted = {}; 66 } else { 67 // 空行里拖放肯定没问题,其他在文字中间可能不准确 68 ap = document.elementFromPoint(ev.clientX, ev.clientY); 69 archor = ap.lastChild; 70 } 71 72 var dt = ev['dataTransfer']; 73 dt.dropEffect = "copy"; 74 var files = dt['files']; 75 if (!files) { 76 return; 77 } 78 for (var i = 0; i < files.length; i++) { 79 var file = files[i], name = file.name, size = file.size; 80 if (!name.match(suffix_reg)) { 81 continue; 82 } 83 if (size / 1000 > sizeLimit) { 84 continue; 85 } 86 var img = new Node("<img " + "src='" + 87 Utils.debugUrl("theme/tao-loading.gif") 88 + "'" + "/>"); 89 var nakeImg = img[0]; 90 ap.insertBefore(nakeImg, archor); 91 var np = nakeImg.parentNode, np_name = DOM.nodeName(np); 92 // 防止拖放导致插入到 body 以外 93 if (np_name == "head" 94 || np_name == "html") { 95 DOM.insertBefore(nakeImg, document.body.firstChild); 96 } 97 98 fileUpload(file, img); 99 } 100 }); 101 }); 102 103 104 if (window['XMLHttpRequest'] && !XMLHttpRequest.prototype.sendAsBinary) { 105 XMLHttpRequest.prototype.sendAsBinary = function (dataStr, contentType) { 106 // chrome12 引入 WebKitBlobBuilder 107 var bb = new (window['BlobBuilder'] || window['WebKitBlobBuilder'])(); 108 var len = dataStr.length; 109 var data = new window['Uint8Array'](len); 110 for (var i = 0; i < len; i++) { 111 data[i] = dataStr['charCodeAt'](i); 112 } 113 bb.append(data.buffer); 114 this.send(bb['getBlob'](contentType)); 115 } 116 } 117 118 /** 119 * 120 * @param img loading 占位图片 121 * @param file 真实数据 122 */ 123 function fileUpload(file, img) { 124 125 var reader = new window['FileReader'](); 126 //chrome 不支持 addEventListener("load") 127 reader.onload = function (ev) { 128 // Please report improvements to: marco.buratto at tiscali.it 129 var fileName = file.name, 130 fileData = ev.target['result'], 131 boundary = "----kissy-editor-yiminghe", 132 xhr = new XMLHttpRequest(); 133 134 xhr.open("POST", serverUrl, true); 135 xhr.onreadystatechange = function () { 136 if (xhr.readyState == 4) { 137 if (xhr.status == 200 || xhr.status == 304) { 138 if (xhr.responseText != "") { 139 var info = window['JSON'].parse(xhr.responseText); 140 img[0].src = info['imgUrl']; 141 } 142 } else { 143 alert("服务器端出错!"); 144 img.remove(); 145 S.log(xhr); 146 } 147 xhr.onreadystatechange = null; 148 } 149 }; 150 151 var body = "\r\n--" + boundary + "\r\n"; 152 body += "Content-Disposition: form-data; name=\"" + 153 fileInput + "\"; filename=\"" + encodeURIComponent(fileName) + "\"\r\n"; 154 body += "Content-Type: " + (file.type || "application/octet-stream") + "\r\n\r\n"; 155 body += fileData + "\r\n"; 156 serverParams = Editor.Utils.normParams(serverParams); 157 for (var p in serverParams) { 158 if (serverParams.hasOwnProperty(p)) { 159 body += "--" + boundary + "\r\n"; 160 body += "Content-Disposition: form-data; name=\"" + 161 p + "\"\r\n\r\n"; 162 body += serverParams[p] + "\r\n"; 163 } 164 } 165 body += "--" + boundary + "--"; 166 167 xhr.setRequestHeader("Content-Type", 168 "multipart/form-data, boundary=" + boundary); 169 // simulate a file MIME POST request. 170 171 xhr.sendAsBinary("Content-Type: multipart/form-data; boundary=" + 172 boundary + "\r\nContent-Length: " + body.length 173 + "\r\n" + body + "\r\n"); 174 reader.onload = null; 175 }; 176 reader['readAsBinaryString'](file); 177 } 178 } 179 }); 180 181 return dragUpload; 182 }, { 183 requires:['editor'] 184 });