imce_extras.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. //This pack implemets: keyboard shortcuts, file sorting, resize bars, and inline thumbnail preview.
  2. (function($) {
  3. // add scale calculator for resizing.
  4. imce.hooks.load.push(function () {
  5. $('#edit-width, #edit-height').focus(function () {
  6. var fid, r, w, isW, val;
  7. if (fid = imce.vars.prvfid) {
  8. isW = this.id == 'edit-width', val = imce.el(isW ? 'edit-height' : 'edit-width').value*1;
  9. if (val && (w = imce.isImage(fid)) && (r = imce.fids[fid].cells[3].innerHTML*1 / w))
  10. this.value = Math.round(isW ? val/r : val*r);
  11. }
  12. });
  13. });
  14. // Shortcuts
  15. var F = null;
  16. imce.initiateShortcuts = function () {
  17. $(imce.NW).attr('tabindex', '0').keydown(function (e) {
  18. if (F = imce.dirKeys['k'+ e.keyCode]) return F(e);
  19. });
  20. $(imce.FLW).attr('tabindex', '0').keydown(function (e) {
  21. if (F = imce.fileKeys['k'+ e.keyCode]) return F(e);
  22. }).focus();
  23. };
  24. //shortcut key-function pairs for directories
  25. imce.dirKeys = {
  26. k35: function (e) {//end-home. select first or last dir
  27. var L = imce.tree['.'].li;
  28. if (e.keyCode == 35) while (imce.hasC(L, 'expanded')) L = L.lastChild.lastChild;
  29. $(L.childNodes[1]).click().focus();
  30. },
  31. k37: function (e) {//left-right. collapse-expand directories.(right may also move focus on files)
  32. var L, B = imce.tree[imce.conf.dir], right = e.keyCode == 39;
  33. if (B.ul && (right ^ imce.hasC(L = B.li, 'expanded')) ) $(L.firstChild).click();
  34. else if (right) $(imce.FLW).focus();
  35. },
  36. k38: function (e) {//up. select the previous directory
  37. var B = imce.tree[imce.conf.dir];
  38. if (L = B.li.previousSibling) {
  39. while (imce.hasC(L, 'expanded')) L = L.lastChild.lastChild;
  40. $(L.childNodes[1]).click().focus();
  41. }
  42. else if ((L = B.li.parentNode.parentNode) && L.tagName == 'LI') $(L.childNodes[1]).click().focus();
  43. },
  44. k40: function (e) {//down. select the next directory
  45. var B = imce.tree[imce.conf.dir], L = B.li, U = B.ul;
  46. if (U && imce.hasC(L, 'expanded')) $(U.firstChild.childNodes[1]).click().focus();
  47. else do {if (L.nextSibling) return $(L.nextSibling.childNodes[1]).click().focus();
  48. }while ((L = L.parentNode.parentNode).tagName == 'LI');
  49. }
  50. };
  51. //add equal keys
  52. imce.dirKeys.k36 = imce.dirKeys.k35;
  53. imce.dirKeys.k39 = imce.dirKeys.k37;
  54. //shortcut key-function pairs for files
  55. imce.fileKeys = {
  56. k38: function (e) {//up-down. select previous-next row
  57. var fid = imce.lastFid(), i = fid ? imce.fids[fid].rowIndex+e.keyCode-39 : 0;
  58. imce.fileClick(imce.findex[i], e.ctrlKey, e.shiftKey);
  59. },
  60. k35: function (e) {//end-home. select first or last row
  61. imce.fileClick(imce.findex[e.keyCode == 35 ? imce.findex.length-1 : 0], e.ctrlKey, e.shiftKey);
  62. },
  63. k13: function (e) {//enter-insert. send file to external app.
  64. imce.send(imce.vars.prvfid);
  65. return false;
  66. },
  67. k37: function (e) {//left. focus on directories
  68. $(imce.tree[imce.conf.dir].a).focus();
  69. },
  70. k65: function (e) {//ctrl+A to select all
  71. if (e.ctrlKey && imce.findex.length) {
  72. var fid = imce.findex[0].id;
  73. imce.selected[fid] ? (imce.vars.lastfid = fid) : imce.fileClick(fid);//select first row
  74. imce.fileClick(imce.findex[imce.findex.length-1], false, true);//shift+click last row
  75. return false;
  76. }
  77. }
  78. };
  79. //add equal keys
  80. imce.fileKeys.k40 = imce.fileKeys.k38;
  81. imce.fileKeys.k36 = imce.fileKeys.k35;
  82. imce.fileKeys.k45 = imce.fileKeys.k13;
  83. //add default operation keys. delete, R(esize), T(humbnails), U(pload)
  84. $.each({k46: 'delete', k82: 'resize', k84: 'thumb', k85: 'upload'}, function (k, op) {
  85. imce.fileKeys[k] = function (e) {
  86. if (imce.ops[op] && !imce.ops[op].disabled) imce.opClick(op);
  87. };
  88. });
  89. //prepare column sorting
  90. imce.initiateSorting = function() {
  91. //add cache hook. cache the old directory's sort settings before the new one replaces it.
  92. imce.hooks.cache.push(function (cache, newdir) {
  93. cache.cid = imce.vars.cid, cache.dsc = imce.vars.dsc;
  94. });
  95. //add navigation hook. refresh sorting after the new directory content is loaded.
  96. imce.hooks.navigate.push(function (data, olddir, cached) {
  97. cached ? imce.updateSortState(data.cid, data.dsc) : imce.firstSort();
  98. });
  99. imce.vars.cid = imce.cookie('imcecid') * 1;
  100. imce.vars.dsc = imce.cookie('imcedsc') * 1;
  101. imce.cols = imce.el('file-header').rows[0].cells;
  102. $(imce.cols).click(function () {imce.columnSort(this.cellIndex, imce.hasC(this, 'asc'));});
  103. imce.firstSort();
  104. };
  105. //sort the list for the first time
  106. imce.firstSort = function() {
  107. imce.columnSort(imce.vars.cid, imce.vars.dsc);
  108. };
  109. //sort file list according to column index.
  110. imce.columnSort = function(cid, dsc) {
  111. if (imce.findex.length < 2) return;
  112. var func = 'sort'+ (cid == 0 ? 'Str' : 'Num') + (dsc ? 'Dsc' : 'Asc');
  113. var prop = cid == 2 || cid == 3 ? 'innerHTML' : 'id';
  114. //sort rows
  115. imce.findex.sort(cid ? function(r1, r2) {return imce[func](r1.cells[cid][prop], r2.cells[cid][prop])} : function(r1, r2) {return imce[func](r1.id, r2.id)});
  116. //insert sorted rows
  117. for (var row, i=0; row = imce.findex[i]; i++) {
  118. imce.tbody.appendChild(row);
  119. }
  120. imce.updateSortState(cid, dsc);
  121. };
  122. //update column states
  123. imce.updateSortState = function(cid, dsc) {
  124. $(imce.cols[imce.vars.cid]).removeClass(imce.vars.dsc ? 'desc' : 'asc');
  125. $(imce.cols[cid]).addClass(dsc ? 'desc' : 'asc');
  126. imce.vars.cid != cid && imce.cookie('imcecid', imce.vars.cid = cid);
  127. imce.vars.dsc != dsc && imce.cookie('imcedsc', (imce.vars.dsc = dsc) ? 1 : 0);
  128. };
  129. //sorters
  130. imce.sortStrAsc = function(a, b) {return a.toLowerCase() < b.toLowerCase() ? -1 : 1;};
  131. imce.sortStrDsc = function(a, b) {return imce.sortStrAsc(b, a);};
  132. imce.sortNumAsc = function(a, b) {return a-b;};
  133. imce.sortNumDsc = function(a, b) {return b-a};
  134. //set resizers for resizable areas and recall previous dimensions
  135. imce.initiateResizeBars = function () {
  136. imce.setResizer('#navigation-resizer', 'X', imce.NW, null, 1, function(p1, p2, m) {
  137. p1 != p2 && imce.cookie('imcenww', p2);
  138. });
  139. imce.setResizer('#browse-resizer', 'Y', imce.BW, imce.PW, 50, function(p1, p2, m) {
  140. p1 != p2 && imce.cookie('imcebwh', p2);
  141. });
  142. imce.recallDimensions();
  143. };
  144. //set a resize bar
  145. imce.setResizer = function (resizer, axis, area1, area2, Min, callback) {
  146. var opt = axis == 'X' ? {pos: 'pageX', func: 'width'} : {pos: 'pageY', func: 'height'};
  147. var Min = Min || 0;
  148. var $area1 = $(area1), $area2 = area2 ? $(area2) : null, $doc = $(document);
  149. $(resizer).mousedown(function(e) {
  150. var pos = e[opt.pos];
  151. var end = start = $area1[opt.func]();
  152. var Max = $area2 ? start + $area2[opt.func]() : 1200;
  153. var drag = function(e) {
  154. end = Math.min(Max - Min, Math.max(start + e[opt.pos] - pos, Min));
  155. $area1[opt.func](end);
  156. $area2 && $area2[opt.func](Max - end);
  157. return false;
  158. };
  159. var undrag = function(e) {
  160. $doc.unbind('mousemove', drag).unbind('mouseup', undrag);
  161. callback && callback(start, end, Max);
  162. };
  163. $doc.mousemove(drag).mouseup(undrag);
  164. return false;
  165. });
  166. };
  167. //get&set area dimensions of the last session from the cookie
  168. imce.recallDimensions = function() {
  169. var $body = $(document.body);
  170. if (!$body.hasClass('imce')) return;
  171. //row heights
  172. imce.recallHeights(imce.cookie('imcebwh') * 1);
  173. $(window).resize(function(){imce.recallHeights()});
  174. //navigation wrapper
  175. var nwOldWidth = imce.cookie('imcenww') * 1;
  176. nwOldWidth && $(imce.NW).width(Math.min(nwOldWidth, $body.width() - 10));
  177. };
  178. //set row heights with respect to window height
  179. imce.recallHeights = function(bwFixedHeight) {
  180. //window & body dimensions
  181. var winHeight = window.opera ? window.innerHeight : $(window).height();
  182. var bodyHeight = $(document.body).outerHeight(true);
  183. var diff = winHeight - bodyHeight;
  184. var bwHeight = $(imce.BW).height(), pwHeight = $(imce.PW).height();
  185. if (bwFixedHeight) {
  186. //row heights
  187. diff -= bwFixedHeight - bwHeight;
  188. bwHeight = bwFixedHeight;
  189. pwHeight += diff;
  190. }
  191. else {
  192. diff = parseInt(diff/2);
  193. bwHeight += diff;
  194. pwHeight += diff;
  195. }
  196. $(imce.BW).height(bwHeight);
  197. $(imce.PW).height(pwHeight);
  198. };
  199. //cookie get & set
  200. imce.cookie = function (name, value) {
  201. if (typeof(value) == 'undefined') {//get
  202. return document.cookie ? imce.decode((document.cookie.match(new RegExp('(?:^|;) *' + name + '=([^;]*)(?:;|$)')) || ['', ''])[1].replace(/\+/g, '%20')) : '';
  203. }
  204. document.cookie = name +'='+ encodeURIComponent(value) +'; expires='+ (new Date(new Date() * 1 + 15 * 86400000)).toUTCString() +'; path=' + Drupal.settings.basePath + 'imce';//set
  205. };
  206. //view thumbnails(smaller than tMaxW x tMaxH) inside the rows.
  207. //Large images can also be previewed by setting imce.vars.prvstyle to a valid image style(imagecache preset)
  208. imce.thumbRow = function (row) {
  209. var w = row.cells[2].innerHTML * 1;
  210. if (!w) return;
  211. var h = row.cells[3].innerHTML * 1;
  212. if (imce.vars.tMaxW < w || imce.vars.tMaxH < h) {
  213. if (!imce.vars.prvstyle || imce.conf.dir.indexOf('styles') == 0) return;
  214. var img = new Image();
  215. img.src = imce.imagestyleURL(imce.getURL(row.id), imce.vars.prvstyle);
  216. img.className = 'imagestyle-' + imce.vars.prvstyle;
  217. }
  218. else {
  219. var prvH = h, prvW = w;
  220. if (imce.vars.prvW < w || imce.vars.prvH < h) {
  221. if (h < w) {
  222. prvW = imce.vars.prvW;
  223. prvH = prvW*h/w;
  224. }
  225. else {
  226. prvH = imce.vars.prvH;
  227. prvW = prvH*w/h;
  228. }
  229. }
  230. var img = new Image(prvW, prvH);
  231. img.src = imce.getURL(row.id);
  232. }
  233. var cell = row.cells[0];
  234. cell.insertBefore(img, cell.firstChild);
  235. };
  236. //convert a file URL returned by imce.getURL() to an image style(imagecache preset) URL
  237. imce.imagestyleURL = function (url, stylename) {
  238. var len = imce.conf.furl.length - 1;
  239. return url.substr(0, len) + '/styles/' + stylename + '/' + imce.conf.scheme + url.substr(len);
  240. };
  241. // replace table view with box view for file list
  242. imce.boxView = function () {
  243. var w = imce.vars.boxW, h = imce.vars.boxH;
  244. if (!w || !h || imce.ie && imce.ie < 8) return;
  245. var $body = $(document.body);
  246. var toggle = function() {
  247. $body.toggleClass('box-view');
  248. // refresh dom. required by all except FF.
  249. $('#file-list').appendTo(imce.FW).appendTo(imce.FLW);
  250. };
  251. $body.append('<style type="text/css">.box-view #file-list td.name {width: ' + w + 'px;height: ' + h + 'px;} .box-view #file-list td.name span {width: ' + w + 'px;word-wrap: normal;text-overflow: ellipsis;}</style>');
  252. imce.hooks.load.push(function() {
  253. toggle();
  254. imce.SBW.scrollTop = 0;
  255. imce.opAdd({name: 'changeview', title: Drupal.t('Change view'), func: toggle});
  256. });
  257. imce.hooks.list.push(imce.boxViewRow);
  258. };
  259. // process a row for box view. include all data in box title.
  260. imce.boxViewRow = function (row) {
  261. var s = ' | ', w = row.cells[2].innerHTML * 1, dim = w ? s + w + 'x' + row.cells[3].innerHTML * 1 : '';
  262. row.cells[0].title = imce.decode(row.id) + s + row.cells[1].innerHTML + (dim) + s + row.cells[4].innerHTML;
  263. };
  264. })(jQuery);