091.menus.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. /** This file is part of KCFinder project
  2. *
  3. * @desc Context menus
  4. * @package KCFinder
  5. * @version 3.12
  6. * @author Pavel Tzonkov <sunhater@sunhater.com>
  7. * @copyright 2010-2014 KCFinder Project
  8. * @license http://opensource.org/licenses/GPL-3.0 GPLv3
  9. * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3
  10. * @link http://kcfinder.sunhater.com
  11. */
  12. _.menu = {
  13. init: function() {
  14. $('#menu').html("<ul></ul>").css('display', 'none');
  15. },
  16. addItem: function(href, label, callback, denied) {
  17. if (typeof denied == "undefined")
  18. denied = false;
  19. $('#menu ul').append('<li><a href="' + href + '"' + (denied ? ' class="denied"' : "") + '><span>' + label + '</span></a></li>');
  20. if (!denied && $.isFunction(callback))
  21. $('#menu a[href="' + href + '"]').click(function() {
  22. _.menu.hide();
  23. return callback();
  24. });
  25. },
  26. addDivider: function() {
  27. if ($('#menu ul').html().length)
  28. $('#menu ul').append("<li>-</li>");
  29. },
  30. show: function(e) {
  31. var dlg = $('#menu'),
  32. ul = $('#menu ul');
  33. if (ul.html().length) {
  34. dlg.find('ul').first().menu();
  35. if (typeof e != "undefined") {
  36. var left = e.pageX,
  37. top = e.pageY,
  38. win = $(window);
  39. if ((dlg.outerWidth() + left) > win.width())
  40. left = win.width() - dlg.outerWidth();
  41. if ((dlg.outerHeight() + top) > win.height())
  42. top = win.height() - dlg.outerHeight();
  43. dlg.hide().css({
  44. left: left,
  45. top: top,
  46. width: ""
  47. }).fadeIn('fast');
  48. } else
  49. dlg.fadeIn('fast');
  50. } else
  51. ul.detach();
  52. },
  53. hide: function() {
  54. $('#clipboard').removeClass('selected');
  55. $('div.folder > a > span.folder').removeClass('context');
  56. $('#menu').hide().css('width', "").html("").data('title', null).unbind().click(function() {
  57. return false;
  58. });
  59. $(document).unbind('keydown').keydown(function(e) {
  60. return !_.selectAll(e);
  61. });
  62. }
  63. };
  64. // FILE CONTEXT MENU
  65. _.menuFile = function(file, e) {
  66. _.menu.init();
  67. var data = file.data(),
  68. files = $('.file.selected').get();
  69. // MULTIPLE FILES MENU
  70. if (file.hasClass('selected') && files.length && (files.length > 1)) {
  71. var thumb = false,
  72. notWritable = 0,
  73. cdata;
  74. $.each(files, function(i, cfile) {
  75. cdata = $(cfile).data();
  76. if (cdata.thumb) thumb = true;
  77. if (!data.writable) notWritable++;
  78. });
  79. if (_.opener.callBackMultiple) {
  80. // SELECT FILES
  81. _.menu.addItem("kcact:pick", _.label("Select"), function() {
  82. _.returnFiles(files);
  83. return false;
  84. });
  85. // SELECT THUMBNAILS
  86. if (thumb)
  87. _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnails"), function() {
  88. _.returnThumbnails(files);
  89. return false;
  90. });
  91. }
  92. if (data.thumb || data.smallThumb || _.support.zip) {
  93. _.menu.addDivider();
  94. // VIEW IMAGE
  95. if (data.thumb || data.smallThumb)
  96. _.menu.addItem("kcact:view", _.label("View"), function() {
  97. _.viewImage(data);
  98. });
  99. // DOWNLOAD
  100. if (_.support.zip)
  101. _.menu.addItem("kcact:download", _.label("Download"), function() {
  102. var pfiles = [];
  103. $.each(files, function(i, cfile) {
  104. pfiles[i] = $(cfile).data('name');
  105. });
  106. _.post(_.getURL('downloadSelected'), {dir:_.dir, files:pfiles});
  107. return false;
  108. });
  109. }
  110. // ADD TO CLIPBOARD
  111. if (_.access.files.copy || _.access.files.move) {
  112. _.menu.addDivider();
  113. _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() {
  114. var msg = '';
  115. $.each(files, function(i, cfile) {
  116. var cdata = $(cfile).data(),
  117. failed = false;
  118. for (i = 0; i < _.clipboard.length; i++)
  119. if ((_.clipboard[i].name == cdata.name) &&
  120. (_.clipboard[i].dir == _.dir)
  121. ) {
  122. failed = true;
  123. msg += cdata.name + ": " + _.label("This file is already added to the Clipboard.") + "\n";
  124. break;
  125. }
  126. if (!failed) {
  127. cdata.dir = _.dir;
  128. _.clipboard[_.clipboard.length] = cdata;
  129. }
  130. });
  131. _.initClipboard();
  132. if (msg.length) _.alert(msg.substr(0, msg.length - 1));
  133. return false;
  134. });
  135. }
  136. // DELETE
  137. if (_.access.files['delete']) {
  138. _.menu.addDivider();
  139. _.menu.addItem("kcact:rm", _.label("Delete"), function() {
  140. if ($(this).hasClass('denied')) return false;
  141. var failed = 0,
  142. dfiles = [];
  143. $.each(files, function(i, cfile) {
  144. var cdata = $(cfile).data();
  145. if (!cdata.writable)
  146. failed++;
  147. else
  148. dfiles[dfiles.length] = _.dir + "/" + cdata.name;
  149. });
  150. if (failed == files.length) {
  151. _.alert(_.label("The selected files are not removable."));
  152. return false;
  153. }
  154. var go = function(callBack) {
  155. _.fadeFiles();
  156. $.ajax({
  157. type: "post",
  158. dataType: "json",
  159. url: _.getURL("rm_cbd"),
  160. data: {files:dfiles},
  161. async: false,
  162. success: function(data) {
  163. if (callBack) callBack();
  164. _.check4errors(data);
  165. _.refresh();
  166. },
  167. error: function() {
  168. if (callBack) callBack();
  169. $('#files > div').css({
  170. opacity: "",
  171. filter: ""
  172. });
  173. _.alert(_.label("Unknown error."));
  174. }
  175. });
  176. };
  177. if (failed)
  178. _.confirm(
  179. _.label("{count} selected files are not removable. Do you want to delete the rest?", {count:failed}),
  180. go
  181. );
  182. else
  183. _.confirm(
  184. _.label("Are you sure you want to delete all selected files?"),
  185. go
  186. );
  187. return false;
  188. }, (notWritable == files.length));
  189. }
  190. _.menu.show(e);
  191. // SINGLE FILE MENU
  192. } else {
  193. $('.file').removeClass('selected');
  194. file.addClass('selected');
  195. $('#fileinfo').html($.$.htmlData(data.name) + " (" + _.humanSize(data.size) + ", " + data.date + ")");
  196. if (_.opener.callBack || _.opener.callBackMultiple) {
  197. // SELECT FILE
  198. _.menu.addItem("kcact:pick", _.label("Select"), function() {
  199. _.returnFile(file);
  200. return false;
  201. });
  202. // SELECT THUMBNAIL
  203. if (data.thumb)
  204. _.menu.addItem("kcact:pick_thumb", _.label("Select Thumbnail"), function() {
  205. _.returnFile(_.thumbsURL + "/" + _.dir + "/" + data.name);
  206. return false;
  207. });
  208. _.menu.addDivider();
  209. }
  210. // VIEW IMAGE
  211. if (data.thumb || data.smallThumb)
  212. _.menu.addItem("kcact:view", _.label("View"), function() {
  213. _.viewImage(data);
  214. });
  215. // DOWNLOAD
  216. _.menu.addItem("kcact:download", _.label("Download"), function() {
  217. $('#menu').html('<form id="downloadForm" method="post" action="' + _.getURL('download') + '"><input type="hidden" name="dir" /><input type="hidden" name="file" /></form>');
  218. $('#downloadForm input').get(0).value = _.dir;
  219. $('#downloadForm input').get(1).value = data.name;
  220. $('#downloadForm').submit();
  221. return false;
  222. });
  223. // ADD TO CLIPBOARD
  224. if (_.access.files.copy || _.access.files.move) {
  225. _.menu.addDivider();
  226. _.menu.addItem("kcact:clpbrdadd", _.label("Add to Clipboard"), function() {
  227. for (i = 0; i < _.clipboard.length; i++)
  228. if ((_.clipboard[i].name == data.name) &&
  229. (_.clipboard[i].dir == _.dir)
  230. ) {
  231. _.alert(_.label("This file is already added to the Clipboard."));
  232. return false;
  233. }
  234. var cdata = data;
  235. cdata.dir = _.dir;
  236. _.clipboard[_.clipboard.length] = cdata;
  237. _.initClipboard();
  238. return false;
  239. });
  240. }
  241. if (_.access.files.rename || _.access.files['delete'])
  242. _.menu.addDivider();
  243. // RENAME
  244. if (_.access.files.rename)
  245. _.menu.addItem("kcact:mv", _.label("Rename..."), function() {
  246. if (!data.writable) return false;
  247. _.fileNameDialog(
  248. {dir: _.dir, file: data.name},
  249. 'newName', data.name, _.getURL("rename"), {
  250. title: "New file name:",
  251. errEmpty: "Please enter new file name.",
  252. errSlash: "Unallowable characters in file name.",
  253. errDot: "File name shouldn't begins with '.'"
  254. },
  255. _.refresh
  256. );
  257. return false;
  258. }, !data.writable);
  259. // DELETE
  260. if (_.access.files['delete'])
  261. _.menu.addItem("kcact:rm", _.label("Delete"), function() {
  262. if (!data.writable) return false;
  263. _.confirm(_.label("Are you sure you want to delete this file?"),
  264. function(callBack) {
  265. $.ajax({
  266. type: "post",
  267. dataType: "json",
  268. url: _.getURL("delete"),
  269. data: {dir: _.dir, file: data.name},
  270. async: false,
  271. success: function(data) {
  272. if (callBack) callBack();
  273. _.clearClipboard();
  274. if (_.check4errors(data))
  275. return;
  276. _.refresh();
  277. },
  278. error: function() {
  279. if (callBack) callBack();
  280. _.alert(_.label("Unknown error."));
  281. }
  282. });
  283. }
  284. );
  285. return false;
  286. }, !data.writable);
  287. _.menu.show(e);
  288. }
  289. };
  290. // FOLDER CONTEXT MENU
  291. _.menuDir = function(dir, e) {
  292. _.menu.init();
  293. var data = dir.data(),
  294. html = '<ul>';
  295. if (_.clipboard && _.clipboard.length) {
  296. // COPY CLIPBOARD
  297. if (_.access.files.copy)
  298. _.menu.addItem("kcact:cpcbd", _.label("Copy {count} files", {count: _.clipboard.length}), function() {
  299. _.copyClipboard(data.path);
  300. return false;
  301. }, !data.writable);
  302. // MOVE CLIPBOARD
  303. if (_.access.files.move)
  304. _.menu.addItem("kcact:mvcbd", _.label("Move {count} files", {count: _.clipboard.length}), function() {
  305. _.moveClipboard(data.path);
  306. return false;
  307. }, !data.writable);
  308. if (_.access.files.copy || _.access.files.move)
  309. _.menu.addDivider();
  310. }
  311. // REFRESH
  312. _.menu.addItem("kcact:refresh", _.label("Refresh"), function() {
  313. _.refreshDir(dir);
  314. return false;
  315. });
  316. // DOWNLOAD
  317. if (_.support.zip) {
  318. _.menu.addDivider();
  319. _.menu.addItem("kcact:download", _.label("Download"), function() {
  320. _.post(_.getURL("downloadDir"), {dir:data.path});
  321. return false;
  322. });
  323. }
  324. if (_.access.dirs.create || _.access.dirs.rename || _.access.dirs['delete'])
  325. _.menu.addDivider();
  326. // NEW SUBFOLDER
  327. if (_.access.dirs.create)
  328. _.menu.addItem("kcact:mkdir", _.label("New Subfolder..."), function(e) {
  329. if (!data.writable) return false;
  330. _.fileNameDialog(
  331. {dir: data.path},
  332. "newDir", "", _.getURL("newDir"), {
  333. title: "New folder name:",
  334. errEmpty: "Please enter new folder name.",
  335. errSlash: "Unallowable characters in folder name.",
  336. errDot: "Folder name shouldn't begins with '.'"
  337. }, function() {
  338. _.refreshDir(dir);
  339. _.initDropUpload();
  340. if (!data.hasDirs) {
  341. dir.data('hasDirs', true);
  342. dir.children('span.brace').addClass('closed');
  343. }
  344. }
  345. );
  346. return false;
  347. }, !data.writable);
  348. // RENAME
  349. if (_.access.dirs.rename)
  350. _.menu.addItem("kcact:mvdir", _.label("Rename..."), function(e) {
  351. if (!data.removable) return false;
  352. _.fileNameDialog(
  353. {dir: data.path},
  354. "newName", data.name, _.getURL("renameDir"), {
  355. title: "New folder name:",
  356. errEmpty: "Please enter new folder name.",
  357. errSlash: "Unallowable characters in folder name.",
  358. errDot: "Folder name shouldn't begins with '.'"
  359. }, function(dt) {
  360. if (!dt.name) {
  361. _.alert(_.label("Unknown error."));
  362. return;
  363. }
  364. var currentDir = (data.path == _.dir);
  365. dir.children('span.folder').html($.$.htmlData(dt.name));
  366. dir.data('name', dt.name);
  367. dir.data('path', $.$.dirname(data.path) + '/' + dt.name);
  368. if (currentDir)
  369. _.dir = dir.data('path');
  370. _.initDropUpload();
  371. },
  372. true
  373. );
  374. return false;
  375. }, !data.removable);
  376. // DELETE
  377. if (_.access.dirs['delete'])
  378. _.menu.addItem("kcact:rmdir", _.label("Delete"), function() {
  379. if (!data.removable) return false;
  380. _.confirm(
  381. _.label("Are you sure you want to delete this folder and all its content?"),
  382. function(callBack) {
  383. $.ajax({
  384. type: "post",
  385. dataType: "json",
  386. url: _.getURL("deleteDir"),
  387. data: {dir: data.path},
  388. async: false,
  389. success: function(data) {
  390. if (callBack) callBack();
  391. if (_.check4errors(data))
  392. return;
  393. dir.parent().hide(500, function() {
  394. var folders = dir.parent().parent();
  395. var pDir = folders.parent().children('a').first();
  396. dir.parent().detach();
  397. if (!folders.children('div.folder').get(0)) {
  398. pDir.children('span.brace').first().removeClass('opened closed');
  399. pDir.parent().children('.folders').detach();
  400. pDir.data('hasDirs', false);
  401. }
  402. if (pDir.data('path') == _.dir.substr(0, pDir.data('path').length))
  403. _.changeDir(pDir);
  404. _.initDropUpload();
  405. });
  406. },
  407. error: function() {
  408. if (callBack) callBack();
  409. _.alert(_.label("Unknown error."));
  410. }
  411. });
  412. }
  413. );
  414. return false;
  415. }, !data.removable);
  416. _.menu.show(e);
  417. $('div.folder > a > span.folder').removeClass('context');
  418. if (dir.children('span.folder').hasClass('regular'))
  419. dir.children('span.folder').addClass('context');
  420. };
  421. // CLIPBOARD MENU
  422. _.openClipboard = function() {
  423. if (!_.clipboard || !_.clipboard.length) return;
  424. // CLOSE MENU
  425. if ($('#menu a[href="kcact:clrcbd"]').html()) {
  426. $('#clipboard').removeClass('selected');
  427. _.menu.hide();
  428. return;
  429. }
  430. setTimeout(function() {
  431. _.menu.init();
  432. var dlg = $('#menu'),
  433. jStatus = $('#status'),
  434. html = '<li class="list"><div>';
  435. // CLIPBOARD FILES
  436. $.each(_.clipboard, function(i, val) {
  437. var icon = $.$.getFileExtension(val.name);
  438. if (val.thumb)
  439. icon = ".image";
  440. else if (!val.smallIcon || !icon.length)
  441. icon = ".";
  442. icon = "themes/" + _.theme + "/img/files/small/" + icon + ".png";
  443. html += '<a title="' + _.label("Click to remove from the Clipboard") + '" onclick="_.removeFromClipboard(' + i + ')"' + ((i == 0) ? ' class="first"' : "") + '><span style="background-image:url(' + $.$.escapeDirs(icon) + ')">' + $.$.htmlData($.$.basename(val.name)) + '</span></a>';
  444. });
  445. html += '</div></li><li class="div-files">-</li>';
  446. $('#menu ul').append(html);
  447. // DOWNLOAD
  448. if (_.support.zip)
  449. _.menu.addItem("kcact:download", _.label("Download files"), function() {
  450. _.downloadClipboard();
  451. return false;
  452. });
  453. if (_.access.files.copy || _.access.files.move || _.access.files['delete'])
  454. _.menu.addDivider();
  455. // COPY
  456. if (_.access.files.copy)
  457. _.menu.addItem("kcact:cpcbd", _.label("Copy files here"), function() {
  458. if (!_.dirWritable) return false;
  459. _.copyClipboard(_.dir);
  460. return false;
  461. }, !_.dirWritable);
  462. // MOVE
  463. if (_.access.files.move)
  464. _.menu.addItem("kcact:mvcbd", _.label("Move files here"), function() {
  465. if (!_.dirWritable) return false;
  466. _.moveClipboard(_.dir);
  467. return false;
  468. }, !_.dirWritable);
  469. // DELETE
  470. if (_.access.files['delete'])
  471. _.menu.addItem("kcact:rmcbd", _.label("Delete files"), function() {
  472. _.confirm(
  473. _.label("Are you sure you want to delete all files in the Clipboard?"),
  474. function(callBack) {
  475. if (callBack) callBack();
  476. _.deleteClipboard();
  477. }
  478. );
  479. return false;
  480. });
  481. _.menu.addDivider();
  482. // CLEAR CLIPBOARD
  483. _.menu.addItem("kcact:clrcbd", _.label("Clear the Clipboard"), function() {
  484. _.clearClipboard();
  485. return false;
  486. });
  487. $('#clipboard').addClass('selected');
  488. _.menu.show();
  489. var left = $(window).width() - dlg.css({width: ""}).outerWidth(),
  490. top = $(window).height() - dlg.outerHeight() - jStatus.outerHeight(),
  491. lheight = top + dlg.outerTopSpace();
  492. dlg.find('.list').css({
  493. 'max-height': lheight,
  494. 'overflow-y': "auto",
  495. 'overflow-x': "hidden",
  496. width: ""
  497. });
  498. top = $(window).height() - dlg.outerHeight(true) - jStatus.outerHeight(true);
  499. dlg.css({
  500. left: left - 5,
  501. top: top
  502. }).fadeIn("fast");
  503. var a = dlg.find('.list').outerHeight(),
  504. b = dlg.find('.list div').outerHeight();
  505. if (b - a > 10) {
  506. dlg.css({
  507. left: parseInt(dlg.css('left')) - _.scrollbarWidth,
  508. }).width(dlg.width() + _.scrollbarWidth);
  509. }
  510. }, 1);
  511. };