plupload.config.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. let thumbList = [];
  2. let thumbLength = 0;
  3. let uploaderFuncUrl = (top.BASE_URL + "");
  4. let $parent = (top || top.parent);
  5. let uploader = new plupload.Uploader({
  6. runtimes: "html5,html4,silverlight,flash",
  7. browse_button: "image-upload",
  8. container: "container",
  9. chunk_size: "10000kb",
  10. unique_names: false,
  11. selected_files: 8, // 한번에 선택한 파일 개수
  12. max_files: 30, // 전체 파일 개수 제한
  13. urlstream_upload: true,
  14. multi_selection: true,
  15. multipart_params: [],
  16. url: uploaderFuncUrl,
  17. flash_swf_url: $parent.tinyMCE.baseURL + '/plupload/js/Moxie.swf',
  18. silverlight_xap_url: $parent.tinyMCE.baseURL + '/plupload/js/Moxie.xap',
  19. resize: {
  20. // width: $parent.tinyMCE.activeEditor.getContainer().offsetWidth,
  21. // height: $parent.tinyMCE.activeEditor.getContainer().offsetHeight,
  22. crop: false,
  23. quality: 100
  24. },
  25. filters: {
  26. max_file_size: "10mb",
  27. mime_types: [{
  28. title: "Image files",
  29. extensions: "jpg,gif,png,bmp"
  30. }],
  31. prevent_duplicates: true
  32. },
  33. init:
  34. {
  35. // 초기 설정
  36. PostInit: function (up) {
  37. if (up.state !== 1) {
  38. $parent.message("잠시후 다시 시도해주세요.", "error");
  39. return false;
  40. }
  41. document.getElementsByClassName("picker-content")[0].innerHTML = "";
  42. $(".picker-content").sortable({
  43. start: function (event, ui) {
  44. ui.placeholder.css({visibility: 'visible', border: '1px solid #4D88FF'});
  45. },
  46. change: function (event, ui) {
  47. ui.placeholder.css({visibility: 'visible', border: '1px solid #4D88FF'});
  48. },
  49. stop: function (event, ui) {
  50. sortFiles();
  51. }
  52. }).disableSelection();
  53. },
  54. // 파일 필터 중
  55. FileFiltered: function (up, files) {
  56. if (up.files.length > 0) {
  57. up.files.forEach(function (n) {
  58. if (!(/(\.jpg|\.gif|\.png|\.bmp)$/i.test(n.name))) {
  59. alert("첨부하신 파일은 허용되지 않는 확장자입니다.");
  60. }
  61. });
  62. }
  63. if (!files) {
  64. up.removeFile(files);
  65. $parent.message("사진를 추가할 수 없습니다. 다시 시도 해주세요.", "error");
  66. return false;
  67. }
  68. },
  69. // 업로드 전 보낼 값 지정
  70. BeforeUpload: function (up, file) {
  71. up.settings.multipart_params = {fileID: file.id};
  72. },
  73. // 파일 가상추가
  74. // up.state (1: stoped, 2: started) plupload resize
  75. FilesAdded: function (up, files) {
  76. if (files.length > up.settings.selected_files) {
  77. $parent.message("사진는 한번에 " + up.settings.selected_files + "개까지 올릴 수 있습니다.", "error");
  78. return false;
  79. }
  80. // 최대 업로드 가능 개수
  81. plupload.each(files, function (file) {
  82. try {
  83. if (file.getSource().getSource().size <= 0) {
  84. throw new Error("파일 형식이 옳지 않습니다.");
  85. } else if (up.files.length > up.settings.max_files) {
  86. throw new Error("사진는 최대 " + up.settings.max_files + "개 까지 가능합니다.");
  87. }
  88. } catch (error) {
  89. $parent.popMessage(error.message, "error");
  90. up.removeFile(file);
  91. up.refresh();
  92. return false;
  93. }
  94. if (up.state !== plupload.STARTED) {
  95. let preView = new moxie.image.Image();
  96. let params = up.settings.resize;
  97. let blob = file.getSource();
  98. try { // mOxie 미리보기 생성
  99. preView.onload = function () // 이미지 썸네일 생성
  100. {
  101. /*
  102. console.log("params.width: " + params.width);
  103. console.log("params.width: " + params.height);
  104. console.log("this.width: " + this.width);
  105. console.log("this.width: " + this.height);
  106. console.log("params.preserve_headers: " + params.preserve_headers);
  107. console.log("params.crop: " + params.crop);
  108. */
  109. if ((params.width > this.width) && (params.preserve_headers && !params.crop)) {
  110. } else {
  111. preView.downsize(params.width, params.height, params.crop, params.preserve_headers); // 크기가 지정한 값보다 크다면 조절
  112. }
  113. paintImg(file, preView.getAsDataURL(blob.type, params.quality));
  114. };
  115. preView.onresize = function (e) {
  116. $parent.popMessage("`" + e.target.name + "` 이미지는 허용 가능한 크기를 초과해 재조정하였습니다.", "warning");
  117. };
  118. preView.onerror = function () {
  119. this.destroy();
  120. };
  121. preView.onloadend = function () {
  122. this.destroy();
  123. };
  124. preView.load(blob);
  125. // 미리보기 생성이 안된다면
  126. if (file.type === "image/gif" && preView.size <= 0) {
  127. var reader = new FileReader();
  128. reader.onloadend = function () {
  129. if (reader.result) {
  130. paintImg(file, reader.result);
  131. }
  132. };
  133. reader.readAsDataURL(file.getNative());
  134. }
  135. } catch (e) {
  136. $parent.popMessage("`" + e.target.name + "` 이미지는 첨부할 수 없습니다.", "error");
  137. return false;
  138. }
  139. }
  140. });
  141. up.refresh();
  142. },
  143. // 업로드 중..
  144. UploadProgress: function (up, files) {
  145. loading();
  146. },
  147. // 실제 사진 업로드
  148. FileUploaded: function (up, file, response) { // 사용안함
  149. let data = JSON.parse(response.response);
  150. try {
  151. if (typeof data != "undefined" && data != "") {
  152. if (file.id && up.state == plupload.STARTED) {
  153. let editorHTML = "<img src='" + data.imageUrl + "?" + Date.now() + "' alt='" + data.imageName + "'/><br /> \u200C";
  154. $parent.tinymce.activeEditor.execCommand('mceInsertContent', false, editorHTML);
  155. // 이미지 번호 저장
  156. /*
  157. if(typeof data.imageID != "undefined" || data.imageID == null){
  158. $parent.setImageID(data.imageID);
  159. }*/
  160. } else {
  161. throw new Error("사진 업로드 중 오류가 발생하였습니다. 다시 시도해주세요.");
  162. }
  163. } else {
  164. throw new Error("첨부한 사진은 사용할 수 없습니다. 다른 사진을 사용해주세요.");
  165. }
  166. } catch (error) {
  167. $parent.message(error.message, "error");
  168. up.removeFile(file);
  169. up.splice(file);
  170. return false;
  171. }
  172. },
  173. FilesRemoved: function(up, files) {
  174. console.log(up);
  175. console.log(files);
  176. },
  177. // 모든 사진 업로드 완료
  178. UploadComplete: function (up, files) {
  179. if (up.total.queued == 0 && up.files.length > 0) {
  180. $parent.message(up.files.length + "개의 사진이 추가 되었습니다.");
  181. }
  182. stopUploader();
  183. },
  184. // 오류 노출
  185. Error: function (up, error) {
  186. if (error.code == 9999) {
  187. $parent.message("\nError #" + error.code + ": " + error.message, "error");
  188. }
  189. return false;
  190. }
  191. }
  192. });
  193. uploader.init();
  194. /*
  195. * Tinymce 내부 호출
  196. */
  197. window.startUploader = function () {
  198. if (uploader.files.length > 0) {
  199. uploader.start();
  200. } else {
  201. stopUploader();
  202. }
  203. };
  204. window.stopUploader = function () {
  205. setTimeout(function () {
  206. uploader.refresh();
  207. uploader.stop();
  208. uploader.unbindAll();
  209. uploader.destroy();
  210. }, 1000);
  211. setTimeout(function () {
  212. $parent.selfAutoResize(15);
  213. }, 0);
  214. setTimeout(function () {
  215. $parent.tinymce.activeEditor.load();
  216. }, 500);
  217. // setTimeout(function(){$parent.tinymce.activeEditor.execCommand('mceAutoResize', true);}, 1000);
  218. loading();
  219. $parent.tinyMCE.activeEditor.windowManager.close();
  220. };
  221. window.insertContent = function () {
  222. if (thumbLength > 0) {
  223. loading();
  224. for (let index in thumbList) {
  225. $parent.tinymce.activeEditor.execCommand('mceInsertContent', false, thumbList[index]);
  226. }
  227. $parent.message(thumbLength + "개의 사진이 추가 되었습니다.");
  228. }
  229. stopUploader();
  230. };
  231. window.removeThumb = function (e) {
  232. if ($(".picker-list-box").length <= 0) {
  233. $parent.popMessage("삭제할 파일이 없습니다.", "warning");
  234. return false;
  235. } else {
  236. if (typeof e != "undefined") {
  237. if (confirm("지워진 사진은 복구할 수 없습니다.\n\n해당 사진을 삭제하겠습니까?")) {
  238. let removeTab = e.closest(".picker-list-box");
  239. let fileID = removeTab.attr("id");
  240. delete thumbList[fileID];
  241. removeTab.remove();
  242. uploader.removeFile(uploader.getFile(fileID));
  243. $parent.popMessage("해당 사진이 정상적으로 삭제 되었습니다.");
  244. thumbLength--;
  245. }
  246. } else {
  247. if (confirm("지워진 사진들은 복구할 수 없습니다.\n\n모든 사진을 삭제하겠습니까?")) {
  248. uploader.splice(); // 초기화
  249. uploader.refresh();
  250. $(".picker-content").empty();
  251. thumbLength = 0;
  252. thumbList = new Array(); // 삭제
  253. $parent.popMessage("모든 사진이 정상적으로 삭제 되었습니다.");
  254. }
  255. }
  256. return true;
  257. }
  258. };
  259. /*
  260. * Plupload 내부 호출
  261. */
  262. let sortFiles = function () {
  263. let fileListObj = $(".picker-list-box");
  264. let tmpFileList = [];
  265. let tmpThumbList = [];
  266. $.each(fileListObj, function (index) {
  267. if (typeof this.id != "undefined") {
  268. tmpFileList.push(uploader.getFile(this.id));
  269. tmpThumbList[this.id] = thumbList[this.id];
  270. }
  271. });
  272. $.each(uploader.files, function (index) {
  273. uploader.files[index] = tmpFileList[index];
  274. });
  275. thumbList = tmpThumbList;
  276. uploader.refresh();
  277. };
  278. let loading = function () {
  279. // 레이어 팝업 기능
  280. let temp = $('.wrap-loading');
  281. let bg = temp.prev(); // dimmed 레이어를 감지하기 위한 boolean 변수
  282. if (bg) {
  283. $('.layer').show(); // 'bg' 클래스가 존재하면 레이어가 나타나고 배경은 dimmed 된다.
  284. temp.show();
  285. } else {
  286. $('.layer').hide();
  287. temp.hide();
  288. }
  289. // 화면의 중앙에 레이어를 띄운다.
  290. if (temp.outerHeight() < $(document).height()) {
  291. temp.css('margin-top', '-' + (temp.outerHeight() / 2 - 26) + 'px');
  292. } else {
  293. temp.css('top', '0');
  294. }
  295. if (temp.outerWidth() < $(document).width()) {
  296. temp.css('margin-left', '-' + (temp.outerWidth() / 2 - 25) + 'px');
  297. } else {
  298. temp.css('left', '0');
  299. }
  300. };
  301. let paintImg = function (file, src) {
  302. let imgHTML = `<img src="${src}" width="100%" alt="${file.name}" aria-label="image" data-load-type="valign" data-target="thumb"/>`;
  303. let thumbHTML = `<div class="picker-list-box picker-sortable-item active" id="${file.id}">
  304. <div class="picker-list-item">
  305. <div class="picker-list-item-in">
  306. <div class="picker-image-box">
  307. <a href="#" class="picker-image" aria-label="Enlarge" onclick="return false;">${imgHTML}</a>
  308. </div>
  309. <a href="#" class="picker-image-title picker-image-draggable" aria-label="Name" onclick="return false;">${file.name}</a>
  310. <button type="button" class="picker-image-remove mce-close" aria-hidden="true" aria-label="Remove">
  311. <i class="mce-ico mce-i-remove"></i>
  312. </button>
  313. </div>
  314. </div>
  315. </div>`
  316. document.getElementsByClassName("picker-content")[0].innerHTML += thumbHTML;
  317. thumbList[file.id] = "<br/>" + imgHTML; // 썸네일 이미지 임시저장 (에디터에 뿌려줌)
  318. thumbLength++;
  319. };
  320. let resizeImage = function (blob, params, cb) {
  321. try {
  322. let img = new o.Image();
  323. img.onload = function () {
  324. // no manipulation required if...
  325. if (params.width > this.width &&
  326. params.height > this.height &&
  327. params.quality === undef &&
  328. params.preserve_headers &&
  329. !params.crop
  330. ) {
  331. this.destroy();
  332. return cb(blob);
  333. }
  334. // otherwise downsize
  335. img.downsize(params.width, params.height, params.crop, params.preserve_headers);
  336. console.log(img.getAsDataURL());
  337. paintImg(blob, img.getAsDataURL());
  338. };
  339. img.onresize = function () {
  340. cb(this.getAsBlob(blob.type, params.quality));
  341. this.destroy();
  342. };
  343. img.onerror = function () {
  344. cb(blob);
  345. };
  346. img.load(blob);
  347. } catch (ex) {
  348. cb(blob);
  349. }
  350. }