Supercharged Local Directory File Browser (Chrome browsers only)

Make file:/// directory ("Index of...") pages actually useful. Adds navigation links, file preview pane, user-defined shortcuts, filtering, keyboard navigation, more.

2018-03-11 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

  1. // ==UserScript==
  2. // @name Supercharged Local Directory File Browser (Chrome browsers only)
  3. // @version 1.2
  4. // @description Make file:/// directory ("Index of...") pages actually useful. Adds navigation links, file preview pane, user-defined shortcuts, filtering, keyboard navigation, more.
  5. // @author Gaspar Schott
  6. // @license GPL-3.0
  7. // @match file:///*
  8. // @require http://code.jquery.com/jquery-latest.min.js
  9.  
  10. // This script was developed in Vivaldi, running on Mac OS High Sierra. It has been tested in Chromium, Opera Next, Iridium, and in general it should work in all Chrome-based browsers.
  11. // It does not work in Safari because Safari does not allow local directories to be browsed.
  12. // In theory, it should work in Firefox, but because Firefox uses a different DOM for building the Index pages, the script would have to be rewritten.
  13.  
  14. // NOTE: By default, Greasemonkey and Tampermonkey will not run scripts on file:/// urls, so for this script to work, you will have to enable it first.
  15. // For Greasemonkey, open about:config and change greasemonkey.fileIsGreaseable to true.
  16. // For Tampermonkey, go to Chrome extension page, and tick the 'Allow access to file URLs' checkbox at the Tampermonkey extension section.
  17.  
  18. // CHANGELOG:
  19. // v. 1.2
  20. // Click to show bookmark menus instead of hover.
  21. // Added Cmd/Crl+Shift+O keybinding to open selected item in new window
  22. // Arrow navigation bugfixes
  23.  
  24. // @namespace https://greatest.deepsurf.us/users/16170
  25. // ==/UserScript==
  26.  
  27. (function() {
  28. 'use strict';
  29. var $ = jQuery;
  30.  
  31. function platformIsMac() {
  32. return navigator.platform.indexOf('Mac') > -1;
  33. }
  34. function platformIsWin() {
  35. return navigator.platform.indexOf('Win') > -1;
  36. }
  37. // Don't run script in iframes or files (only directories)
  38. // if ( window.top != window.self ) {
  39. if ( window.frameElement !== null ) {
  40. return;
  41. } else if ( window.location.pathname.slice(-1) != '/') {
  42. return;
  43. }
  44.  
  45. // ***** USER SETTINGS ***** //
  46. var $settings = {
  47. user_name: // Your user name
  48. '',
  49. // Shortcuts: add directories and files here; you may also use your browser's bookmarks, of course
  50. root_shortcuts: // Root directories: add or remove as you please (but at leave empty brackets). These defaults are applicable to Mac OS.
  51. ['Applications','Library','Users','Volumes'],
  52. // ['C:/Users','C:/Program Files','C:/Windows'],
  53. user_shortcuts: // User directories; you must enter your user_name above.
  54. ['Documents','Downloads','Library'],
  55. file_shortcuts: // Add specific file paths, e.g.: 'Users/MyUserName/Documents/MyDocument.html'
  56. // These files will be selected automatically when their containing directory is loaded
  57. // Limitations: only works for one file per directory; if more than one file per directory is listed, the last item will be selected.
  58. [],
  59. hide_invisibles: // Mac OS only: Files beginning with a "." will be ignored.
  60. true,
  61. ignore_files: // If true, ignored file types (see below) will not be loaded in the content pane;
  62. // If false, they will be treated as normal files, so if they are selected, the browser will attempt to download file types it can't handle.
  63. true,
  64. show_ignored_files: // If true, ignored files will be shown in the list grayed out;
  65. // if false, they will not appear at all.
  66. true,
  67. ignore_file_types: // ignore files with these extensions
  68. ['exe','.doc','.docx','ppt','pptx','xls','xlsx','odt','odp','msi','dll','rtf','indd','idml','.pages','.tif','tiff','.eps','.psd','.ai','.zip','pkg','.swf','.pls','.ics','.ds_store','alias','.dmg','.gz','.qxp','icon.jpg','thumbs.db'], // lowercase
  69. apps_as_dirs: // Mac OS only: if true, treat apps as directories; allows app contents to be browsed. This is the default behavior for Chrome.
  70. // If false, treat apps as ignored files.
  71. true
  72. };
  73. // ***** END USER SETTINGS ***** //
  74.  
  75. // ***** BUILD MENUS ***** //
  76.  
  77. // PATHS
  78. var $location = window.location.pathname;
  79. var $current_dir_path = $location.replace(/%20/g,' ').replace(/\//g,'/<wbr>').replace(/_/g,'_<wbr>').replace(/—/g,'—<wbr>').replace(/\\/g,'/');
  80. var $current_dir_name = $location.replace(/%20/g,' ').slice(0,-1);
  81. $current_dir_name = $current_dir_name.slice($current_dir_name.lastIndexOf('/') + 1);
  82. var $location_arr = $location.split('/');
  83. var $parent_dir_link = $location_arr.slice(0,-2).join('/') + '/';
  84.  
  85. // Parents Link Menu Items
  86. var $parent_links_arr = function() {
  87. var $paths_arr = [];
  88. for ( var i = 1; i < $location_arr.length - 1; i++ ) {
  89. $paths_arr[0] = ''; // root
  90. $paths_arr[i] = $paths_arr[i - 1] + $location_arr[i] + '/';
  91. }
  92. return $paths_arr;
  93. };
  94.  
  95. // function to build menu list items
  96. function menu_items(x,y,i) {
  97. var $menu_item = '<li><a href="file:///' + x[i] + '" style="margin:0;padding:4px 6px;display:block;text-indent:0;text-decoration:none;color:#333;">' + y[i] + '</a></li>';
  98. return $menu_item;
  99. }
  100.  
  101. // Parents Directory Menu Items
  102. var $parents_dir_menu_arr = function() {
  103. var $parents_dir_menu_items = [];
  104. for ( var i = 1; i < $parent_links_arr().length; i++ ) {
  105. $parents_dir_menu_items[0] = menu_items('/','/',0); // root
  106. $parents_dir_menu_items[i] = menu_items($parent_links_arr(),$parent_links_arr(),i);
  107. }
  108. $parents_dir_menu_items.pop(); // remove current directory
  109. $parents_dir_menu_items = $parents_dir_menu_items.reverse().join('').replace(/%20/g,' ');
  110. return $parents_dir_menu_items;
  111. };
  112.  
  113. // Root Shortcuts Menu Items
  114. $settings.root_shortcuts = $settings.root_shortcuts.map(i => i + '/'); // add '/'
  115.  
  116. var $root_shortcuts_menu_arr = function() {
  117. if ( $settings.root_shortcuts.length ) {
  118. var $root_shortcut_items = [];
  119. for ( var i = 0; i < $settings.root_shortcuts.length; i++ ) {
  120. $root_shortcut_items[i] = menu_items($settings.root_shortcuts,$settings.root_shortcuts,i);
  121. }
  122. $root_shortcut_items = $root_shortcut_items.join('');
  123. return $root_shortcut_items;
  124. }
  125. };
  126.  
  127. // User Shortcuts Menu Items
  128. var $user_shortcuts_display_name = $settings.user_shortcuts.map(i => $settings.user_name + '/' + i + '/' ); // build display names
  129. $settings.user_shortcuts = $settings.user_shortcuts.map(i => 'users/' + $settings.user_name + '/' + i + '/'); // build link fragments
  130.  
  131. var $user_shortcuts_menu_arr = function() {
  132. if ( $settings.user_name && $settings.user_shortcuts.length ) {
  133. var $user_shortcut_items = [];
  134. for ( var i = 0; i < $settings.user_shortcuts.length; i++ ) {
  135. $user_shortcut_items[i] = menu_items($settings.user_shortcuts,$user_shortcuts_display_name,i);
  136. }
  137. $user_shortcut_items = $user_shortcut_items.join('');
  138. return $user_shortcut_items;
  139. }
  140. };
  141.  
  142. // File Shortcuts Menu Items
  143. var $file_shortcuts_display_name = $settings.file_shortcuts.map(i => i.split('/').pop()); // get file names from paths
  144.  
  145. var $file_shortcuts_menu_arr = function() {
  146. if ( $settings.file_shortcuts.length ) {
  147. var $file_shortcut_items = [];
  148. for ( var i = 0; i < $settings.file_shortcuts.length; i++ ) {
  149. $file_shortcut_items[i] = menu_items($settings.file_shortcuts,$file_shortcuts_display_name,i);
  150. }
  151. $file_shortcut_items = $file_shortcut_items.join('').replace(/\/<\/a>/g,'<\/a>').replace(/<a /g,'<a class="file_shortcut" ').replace(/%20/g,' ');
  152. return $file_shortcut_items;
  153. }
  154. };
  155.  
  156. // ***** END BUILD MENUS ***** //
  157.  
  158.  
  159. // ***** BUILD UI ELEMENTS ***** //
  160.  
  161. // ***** SIDEBAR ELEMENTS ***** //
  162.  
  163. // 1. Parent Directory Menu
  164. var $parent_dir_menu = $(
  165. '<nav id="parent_dir_menu" style="margin:0;padding:0;display:table;width:100%;">' +
  166. '<a href="" style="width:100%;padding:0;display:table-cell;text-align:center;vertical-align:middle;text-decoration:none;">&and;</a>' +
  167. '</nav>'
  168. );
  169. $parent_dir_menu.find('a').attr('href',$parent_dir_link);
  170.  
  171. // 2. Current Directory Name and Parents Directory Menu
  172. var $parents_dir_menu = $(
  173. '<nav id="parents_dir_menu" style="margin:0;padding:0;text-align:center;">' +
  174. '<div style="padding:4px 6px;display:inline-block;text-align:center;vertical-align:middle;overflow:hidden;cursor:pointer;hyphens:none;"></div>' +
  175. '<ul class="menu" style="display:none;margin:0;padding:0;position:absolute;top:;right:0;left:0;z-index:100;text-indent:0;text-align:left;background:lightgray;border-top:solid 1px gray;border-bottom:solid 1px gray;list-style-type:none;box-shadow: 0px 2px 3px -2px #888;"></ul>' +
  176. '</nav>'
  177. );
  178. $parents_dir_menu.find('div').append( $current_dir_path );
  179. $parents_dir_menu.find('ul').append( $parents_dir_menu_arr() );
  180.  
  181. // 3. Shortcuts Menu
  182. var $divider = $(
  183. '<li><hr style="margin:0;border-bottom:0;"></li>'
  184. );
  185. var $shortcuts_menu = $(
  186. '<nav id="shortcuts_menu" style="margin:0;padding:0;">' +
  187. '<div style="width:6em;display:table-cell;text-align:center;vertical-align:middle;font-size:18px;cursor:pointer;">' +
  188. '&equiv;' +
  189. '</div>' +
  190. '<ul class="menu" style="display:none;margin:0;padding:0;position:absolute;right:0;left:0;z-index:100;text-indent:0;text-align:left;background:lightgray;border-top:solid 1px gray;border-bottom:solid 1px gray;list-style-type:none;box-shadow: 0px 2px 3px -2px #888;"></ul>' +
  191. '</nav>'
  192. );
  193. $shortcuts_menu.find('ul').append( $root_shortcuts_menu_arr(), $divider, $user_shortcuts_menu_arr(), $divider.clone(), $file_shortcuts_menu_arr(), $divider.clone() );
  194.  
  195. // 4. Details Button
  196. var $details_btn = $(
  197. '<button id="details_btn" style="margin:1em 0.5em 0.5em;clear:both" tabindex="-1">' +
  198. '<span id="show">Show details</span><span id="hide" style="display:none">' +
  199. 'Hide details' +
  200. '</span>' +
  201. '</button>'
  202. );
  203.  
  204. // 5. Invisibles Checkbox
  205. var $inv_checkbox = $(
  206. '<label id="inv_checkbox" for="inv_checkbox">' +
  207. '<input type="checkbox" name="inv_checkbox" tabindex="-1" />' +
  208. 'Hide Invisibles' +
  209. '</label>'
  210. );
  211.  
  212. // 6. Image Grid Button
  213. var $content_grid_btn = $(
  214. '<div id="grid_btn" style="margin:0 0 -0.5em 1em;width:16px;height:16px;display:none;position:absolute;top:1em;right:0.5em;line-height:0;cursor:pointer;outline:0;opacity:0.7;" tabindex="-1" title="Show Image Grid">' +
  215. '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-right:2px;margin-bottom:2px;"></span>' +
  216. '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-bottom:2px;"></span>' +
  217. '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-right:2px;"></span>' +
  218. '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;"></span>' +
  219. '</div>'
  220. );
  221.  
  222. // ASSEMBLE SIDEBAR HEADER
  223. var $sidebar_header = $(
  224. '<table id="sidebar_header" style="width:100%;position:relative;border:0;user-select:none;">' +
  225. '<thead>' +
  226. '<tr style="border-bottom:solid 1px grey;background-color:#BBB;">' +
  227. '<th colspan="3" style="padding:4px;font-weight:normal;font-size:0.875em;letter-spacing:0.5em;cursor:default;">' +
  228. 'INDEX OF' +
  229. '</th>' +
  230. '</tr>' +
  231. '</thead>' +
  232. '<tbody>' +
  233. '<tr style="border-bottom:solid 1px grey;background-color:#BBB;">' +
  234. '<td style="width:24px;max-width:24px;min-width:24px;padding:0;"></td>' +
  235. '<td style="padding:0;border-left:solid 1px grey;border-right:solid 1px grey;"></td>' +
  236. '<td style="width:24px;max-width:24px;min-width:24px;padding:0;"></td>' +
  237. '</tr>' +
  238. '<tr>' +
  239. '<td colspan="3" style="position:relative;"></td>' +
  240. '</tr>' +
  241. '</tbody>' +
  242. '</table>'
  243. );
  244. $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(1)').append( $parent_dir_menu );
  245. $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(2)').append( $parents_dir_menu );
  246. $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(3)').append( $shortcuts_menu );
  247. $sidebar_header.find('tbody tr:last-child td').append( $details_btn, $inv_checkbox, $content_grid_btn );
  248. if ( platformIsWin() ) { $inv_checkbox.hide(); }
  249.  
  250. // 7. Sidebar
  251. var $sidebar = $(
  252. '<div id="sidebar" style="background-color:lightgray;height:100%;min-height:100%;overflow-wrap:break-word;box-sizing:border-box;border-right:solid 1px gray;font-size:0.875em;color:#333;"></div>'
  253. );
  254. $sidebar.append($sidebar_header);
  255.  
  256. // 8. Resize Handle
  257. var $handle = $(
  258. '<div id="handle" style="width:8px;position:absolute;top:0;right:-4px;bottom:0;z-index:1000;cursor:col-resize"></div>'
  259. );
  260.  
  261. // Assemble Sidebar Elements
  262. var $sidebar_wrapper = $(
  263. '<td id="sidebar_wrapper" class="focused" style="width:25%;will-change:width;padding:0;position:relative;border:0;background:lightgray"></td>'
  264. );
  265. $sidebar_wrapper.append( $sidebar, $handle );
  266.  
  267. // ***** END SIDEBAR ELEMENTS ***** //
  268.  
  269. // ***** BUILD CONTENT PANE ELEMENTS ***** //
  270.  
  271. // 1. Edit Button Element
  272. var $content_edit_btn = $(
  273. '<td style="width:4em;padding:4px 6px 3px;vertical-align:middle;">' +
  274. '<button id="edit_btn" style="display:none;" tabindex="-1">Edit</button>' +
  275. '</td>'
  276. );
  277.  
  278. // 2. Title Element
  279. var $content_title = $(
  280. '<td id="content_title" style="padding:4px 1em 3px;vertical-align:middle;word-break:break-word;"></td>'
  281. );
  282.  
  283. // 3. Close Button Element
  284. var $content_close_btn = $(
  285. '<td style="width:4em;padding:4px 6px 3px;vertical-align:middle;">' +
  286. '<button id="close_btn" tabindex="-1">Close</button>' +
  287. '</td>'
  288. );
  289.  
  290. // 4. Content Header Element
  291. var $content_header = $(
  292. '<header id="content_header" style="width:100%;display:none;position:absolute;top:0;right:0;left:0;z-index:200;background:lightgray;border-bottom:solid 1px #AAA;font-size:0.875em;color:#333;text-align:center;text-transform:uppercase;">' +
  293. '<table style="width:100%;padding:7px 12px 5px;"><tbody><tr></tr></tbody></table>' +
  294. '</header>'
  295. );
  296. $content_header.find('tr').append($content_edit_btn, $content_title, $content_close_btn);
  297.  
  298. // 5. Content Mask Element
  299. var $content_mask = $(
  300. '<div id="content_mask" style="position:absolute;top:0;right:0;bottom:0;left:0;display:none;z-index:2000;"></div>'
  301. );
  302. $content_mask.css({'height':window.innerHeight + 'px'});
  303.  
  304. // 6. Image Grid Element
  305. var $content_grid = $(
  306. '<div id="content_grid" style="width:auto;padding:0;display:none;position:absolute;right:0;bottom:0;left:0;overflow:auto;background:#333;grid-gap:0;grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));grid-template-rows: repeat(auto, 150px);"></div>'
  307. );
  308.  
  309. // 7. Image Element
  310. var $image = $(
  311. '<img class="default" style="width:auto;height:auto;max-width:100%;max-height:calc(100% - 3px);cursor:zoom-in;-webkit-user-select:none;position:relative;top:50%;transform:translateY(-50%);" />'
  312. );
  313. var $content_image = $(
  314. '<div id="content_image" style="padding:2em;position:absolute;top:0;right:0;bottom:0;left:0;display:none;background:#333;overflow:auto;text-align:center;"></div>'
  315. );
  316. $content_image.append($image);
  317.  
  318. // 8. Pdf (embed) Element
  319. var $content_embed = $(
  320. '<embed id="content_embed" style="width:100%;height:100%;position:absolute;0;right:0;bottom:0;left:0;display:none;" name="plugin" id="plugin" type="application/pdf" tabindex="0"></embed>'
  321. );
  322.  
  323. // 9. Iframe Element
  324. var $content_iframe = $(
  325. '<iframe id="content_iframe" style="width:100%;height:100%;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;display:none;border:0;" sandbox="allow-scripts allow-same-origin allow-modals" tabindex="0"></iframe>'
  326. );
  327.  
  328. // 10. Object Element
  329. // var $content_object = $(
  330. // '<object id="content_object" style="width:100%;height:100%;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;display:none;border:0;" tabindex="0"></object>'
  331. // );
  332.  
  333. // 9. Next/Prev Elements
  334. var $prev_btn = $('<div id="prev_btn" style="padding:0 1em;display:none;position:absolute;top:0;bottom:0;left:0;z-index:100;opacity:0.6;"></div>');
  335. var $next_btn = $('<div id="next_btn" style="padding:0 1em;display:none;position:absolute;top:0;bottom:0;right:0;z-index:100;opacity:0.6;"></div>');
  336. var $svg_arrow = 'url("data:image/svg+xml;utf8,<svg version=\'1.1\' id=\'Layer_1\' xmlns=\'http://www.w3.org/2000/svg\' x=\'0px\' y=\'0px\' width=\'11px\' height=\'16px\' viewBox=\'234.5 248 11 16\' enable-background=\'new 234.5 248 11 16\' xml:space=\'preserve\'><path d=\'M245.5,261l-3,3l-8-8l8-8l3,3l-5,5L245.5,261z\'/></svg>")';
  337. $prev_btn.css({'filter':'invert(50%)','background':$svg_arrow + ' no-repeat center'});
  338. $next_btn.css({'filter':'invert(50%)','background':$svg_arrow + ' no-repeat center','transform':'rotate(180deg)'});
  339.  
  340. // 10. Content container
  341. var $content_container = $('<section id="content_container" style="width:100%;height:100%;position:relative;top:0;overflow:visible;"></section>');
  342. $content_container.append( $content_header, $content_mask, $content_grid, $content_image, $content_embed, $content_iframe );
  343.  
  344. // Assemble Content Pane Elements
  345. var $content_pane = $('<td id="content_pane" class="unfocused" style="width:75%;will-change:width;padding:0;border:0;background:white;position:relative;"></td>');
  346.  
  347. $content_pane.append( $content_container, $prev_btn, $next_btn );
  348.  
  349. // Set content height
  350. function setContentHeight() {
  351. var $content_headerHeight = $content_header.outerHeight();
  352. $content_image.css({'top':$content_headerHeight });
  353. $content_grid.add($content_embed).add($content_iframe).css({'height':window.innerHeight - $content_headerHeight,'top':$content_headerHeight });
  354. }
  355. setContentHeight();
  356.  
  357. // resize head and content header
  358. $('window').on('resize', function() {
  359. headerHeight();
  360. setContentHeight();
  361. });
  362.  
  363. // ***** END BUILD CONTENT PANE ELEMENTS ***** //
  364.  
  365.  
  366. // ASSEMBLE MAIN CONTENT = SIDEBAR + CONTENT PANE
  367. var $main_content = $('<table id="main_content" style="width:100%;height:100%;border:0;"><tbody><tr></tr></tbody></table>');
  368. $main_content.find('tr').append( $sidebar_wrapper, $content_pane );
  369.  
  370. // END BUILD UI ELEMENTS
  371.  
  372. // DEFAULT HTML, BODY STYLES
  373.  
  374. var $body = $('body');
  375. var $dir_table = $body.find('> table');
  376.  
  377. $body.find('> h1:contains("Index of"),> #parentDirLinkBox,> #UI_goUp').remove();
  378. $body.attr('lang','en').parents('html').addBack().css({'margin':'0','padding':'0','height':'100%','font-family':'lucidagrande,"fira sans",helvetica,sans-serif','font-size':'13px','hyphens':'auto','overflow':'hidden'});
  379. $body.prepend($main_content);
  380.  
  381.  
  382. // ***** SIDEBAR ***** //
  383.  
  384. // Sidebar Variables
  385. var $dir_table_head = $dir_table.find('thead');
  386. var $dir_table_head_cell = $dir_table_head.find('th');
  387. var $dir_table_head_name = $dir_table_head_cell.filter(':first-of-type');
  388. var $dir_table_head_details = $dir_table_head_name.nextAll();
  389. var $dir_table_body = $dir_table.find('tbody');
  390. var $dir_table_row = $dir_table_body.find('tr');
  391. var $dir_table_cell = $dir_table_row.find('td');
  392. var $dir_table_item_name = $dir_table_cell.filter(':nth-of-type(1)');
  393. var $dir_table_details = $dir_table_item_name.nextAll();
  394. var $dir_table_link = $dir_table_item_name.find('a');
  395.  
  396. // ***** Sidebar Header ***** //
  397.  
  398. // Sidebar header menus heights
  399. function headerHeight() {
  400. $sidebar_header.find('nav').find('*').addBack().css({'height': 'auto' });
  401. $shortcuts_menu.find('div').add($parent_dir_menu).find('a').addBack().css({'height': ($shortcuts_menu.closest('tr').height() ) +'px' });
  402. }
  403. headerHeight();
  404.  
  405. // MENUS
  406. // Show menus on click
  407. function showMenu(x) {
  408. if ( $(x).parents('td').siblings('td').find('.clicked').length ) {
  409. hideMenu();
  410. }
  411. $(x).toggleClass('clicked').find('.menu').toggle();
  412. }
  413. function hideMenu() {
  414. $('.clicked').removeClass('clicked').find('.menu').hide();
  415. }
  416. $parents_dir_menu.add($shortcuts_menu).on('click',function(e) {
  417. e.stopPropagation();
  418. showMenu(this);
  419. });
  420. $(document).on('click',function() {
  421. hideMenu();
  422. });
  423.  
  424. // Menu hover effects
  425. $parents_dir_menu.add($shortcuts_menu).find('li').hover(function() {
  426. $(this).css({'background-color':'#BBB'});
  427. }, function() {
  428. $(this).css({'background-color':'lightgrey'});
  429. });
  430.  
  431. // Sidebar header invisibles button
  432. if ( $settings.hide_invisibles === true ) {
  433. $inv_checkbox.find('input').prop('checked',true);
  434. }
  435.  
  436. $inv_checkbox.on('click', function(){
  437. if ( $(this).find('input').is(':checked') ) {
  438. $(this).find('input').prop('checked',false);
  439. } else {
  440. $(this).find('input').prop('checked',true);
  441. }
  442. $('.invisible').toggle().filter('.selected').removeClass('selected');
  443. });
  444.  
  445. // Sidebar header details button
  446. $details_btn.on('click',function() {
  447. $dir_table_details.add($dir_table_head_details).toggle();
  448. $dir_table_body.css({'top':$dir_table_head.height() + 1 + 'px'});
  449. $(this).find('span').toggle();
  450. });
  451.  
  452. // ***** Dir_table setup ***** //
  453.  
  454. $dir_table.detach().attr('id','dir_table');
  455.  
  456. // Dir_table styles
  457. $dir_table.css({'width':'100%','min-width':'100px','height':'calc(100% - ' + $sidebar_header.height() + 'px)','border':'0','position':'relative','overflow':'hidden','table-layout':'fixed'});
  458. $dir_table_head.css({'text-align':'left'});
  459. $dir_table_head_name.css({'padding-left':'2em'});
  460. $dir_table_head_cell.css({'padding':'0 24px 4px;'});
  461. $dir_table_body.css({'width':'100%','position':'absolute','top':'18px','right':'0','bottom':'0','left':'0','overflow-y':'auto','outline':'0'});//.attr('tabindex','0');
  462. $dir_table_row.css({'display':'block'});
  463. $dir_table_cell.css({'padding':'0px'});
  464. $dir_table_link.css({'margin':'0px','display':'block','background-size':'auto 13px','-webkit-padding-start':'2em','padding':'4px 6px 4px 24px','color':'#333','text-decoration':'none','overflow':'hidden','background-position':'6px 4px'});
  465. $dir_table_item_name.css({'display':'block'});
  466. $dir_table_details.add($dir_table_head_details).css({'font-size':'0.875em','text-align':'left','height':'1.5em','vertical-align':'top'}).hide();
  467. $dir_table_details.not('th').css({'padding':'0 24px 4px'});
  468.  
  469. // Directory Table Hover
  470. $dir_table_row.hover(function() {
  471. $(this).not('.selected').css({'background-color':'#BBB'});
  472. // Highlight corresponding grid item
  473. if ( $content_grid.hasClass('visible') ) {
  474. var $this_href = $(this).find('a').attr('href');
  475. $content_grid.find('a[href="' + $this_href + '"]').parent('div').css({'background':'#555'}).siblings('div:not(".selected")').css({'background':'transparent'});
  476. }
  477. }, function() {
  478. $(this).not('.selected').css({'background-color':'transparent'});
  479. if ( $content_grid.is(':visible') ) {
  480. $content_grid.find('div:not(".selected")').css({'background':'transparent'});
  481. }
  482. });
  483.  
  484. // Dir_table link arrays
  485. var $dir_table_dir_link_arr = [];
  486. var $dir_table_file_link_arr = [];
  487. var $dir_table_file_ext_arr = [];
  488. $dir_table_row.not('.ignore,.invisible').find('a').each(function() {
  489. var $this_link = $(this).attr('href').toLowerCase();
  490. if ( $this_link.endsWith('/') ) {
  491. $dir_table_dir_link_arr.push($this_link);
  492. return $dir_table_dir_link_arr;
  493. } else {
  494. var $this_link_ext = $this_link.slice($this_link.lastIndexOf('.'));
  495. $dir_table_file_link_arr.push($this_link);
  496. if ( $dir_table_file_ext_arr.indexOf($this_link_ext) < 0 ) {
  497. $dir_table_file_ext_arr.push($this_link_ext);
  498. }
  499. return $dir_table_file_link_arr, $dir_table_file_ext_arr;
  500. }
  501. });
  502. // array of all dir_table links
  503. var $dir_table_link_arr = [];
  504. $dir_table_link_arr = $dir_table_dir_link_arr.concat($dir_table_file_link_arr);
  505.  
  506. // array of image types
  507. var $image_ext_arr = ['.jpg','.jpeg','.png','apng','.gif','.bmp','webp'];
  508.  
  509. // Classify dir_table items
  510. $dir_table_row.each(function() {
  511.  
  512. var $this_href = $(this).find('a').text().toLowerCase();
  513.  
  514. // Directories or files
  515. if ( $this_href.endsWith('/') ) {
  516. $(this).addClass('dir');
  517. } else {
  518. $(this).addClass('file');
  519. }
  520. // pdf
  521. if ( $this_href.endsWith('.pdf') ) {
  522. $(this).addClass('pdf');
  523. } else
  524. // images
  525. if ( $.inArray( $this_href.slice($this_href.lastIndexOf('.') ), $image_ext_arr ) != -1 ) {
  526. $(this).addClass('img');
  527. }
  528.  
  529. // invisibles
  530. if ( $this_href.startsWith('.') ) {
  531. $(this).addClass('invisible');
  532. if ( $settings.hide_invisibles === true ) {
  533. $(this).hide();
  534. }
  535. }
  536.  
  537. // ignored
  538. if ( $settings.ignore_files === true ) {
  539. for ( var i = 0; i < $settings.ignore_file_types.length; i++ ) {
  540. if ( $this_href.endsWith( $settings.ignore_file_types[i] ) ) {
  541. $(this).addClass('ignore').find('a').css({'color':'#888'});
  542. if ( $settings.show_ignored_files === false ) {
  543. $(this).hide();
  544. }
  545. }
  546. }
  547. }
  548.  
  549. // directories as Files and hide ignored files
  550. if ( $settings.apps_as_dirs === false ) {
  551. if ( $this_href.endsWith('.app/') ) {
  552. $(this).addClass('ignore app').find('a').css({'color':'#888'});
  553. var $app_name = $(this).find('a').text().slice(0,-1);
  554. $(this).find('a').text($app_name);
  555. }
  556. }
  557. }); // end classify dir_table items
  558.  
  559. $dir_table.appendTo('#sidebar');
  560.  
  561. // ***** End dir_table setup ***** //
  562.  
  563. // ***************************** //
  564.  
  565. // ***** SHOW/HIDE CONTENT ***** //
  566.  
  567. function setContentTitle(el) {
  568. if ( el == $content_grid ) {
  569. $content_title.empty().prepend('Images from: /' + $current_dir_name);
  570. } else {
  571. $content_title.empty().prepend( $('.selected').find('a').text() );
  572. }
  573. if ( $('.selected').hasClass('ignore') ) {
  574. $content_title.append(' (Ignored content)' );
  575. }
  576. }
  577.  
  578. function getDimensions(link, callback) {
  579. var img = new Image();
  580. img.src = link;
  581. img.onload = function() { callback( this.width, this.height ); };
  582. }
  583.  
  584. function showThis(el,link) {
  585. if ( el == $content_image ) {
  586. el.find('img').attr('src',link);
  587. getDimensions( link, function( width, height ) {
  588. $content_title.append(' <span style="text-transform:lowercase;">(' + width + 'px &times; ' + height + 'px</span>)' );
  589. });
  590. } else if ( el == $content_embed ) {
  591. el.attr('type','application/pdf').attr('src',link + '?#zoom=100&scrollbar=1&toolbar=1&navpanes=1');
  592. } else {
  593. el.attr('src',link);
  594. }
  595. unhideThis(el);
  596. }
  597.  
  598. function showContentHeader() {
  599. $content_header.css({'display':'table'});
  600. }
  601.  
  602. function showPrevNextBtns() {
  603. if ( $dir_table.find('.img').length > 1 ) {
  604. $prev_btn.add($next_btn).css({'display':'block'});
  605. }
  606. }
  607.  
  608. function hidePrevNextBtns() {
  609. $prev_btn.add($next_btn).css({'display':'none'});
  610. }
  611.  
  612. function hideThis(el) {
  613. el.removeClass('visible').addClass('hidden').css({'z-index':'-1'}).hide();
  614. }
  615.  
  616. function unhideThis(el) {
  617. el.removeClass('hidden').addClass('visible').css({'z-index':'auto'});
  618. if ( el == $content_grid ) {
  619. el.css({'display':'grid'});
  620. showPrevNextBtns();
  621. } else if ( el == $content_image) {
  622. el.show();
  623. showPrevNextBtns();
  624. } else {
  625. el.show();
  626. }
  627. setContentTitle(el);
  628. showContentHeader();
  629. }
  630.  
  631. function closeThis(el) {
  632. if ( el == $content_grid ) {
  633. $content_grid.hide().empty();
  634. } else if ( el == $content_image ) {
  635. $content_image.hide().find('img').removeAttr('src');
  636. } else {
  637. el.removeClass('visible').hide().removeAttr('src');
  638. hidePrevNextBtns();
  639. $content_header.hide();
  640. }
  641. }
  642.  
  643. function emptyContentPane() {
  644. closeThis($content_image);
  645. closeThis($content_embed);
  646. closeThis($content_iframe);
  647. }
  648.  
  649. $content_close_btn.on('click',function() {
  650.  
  651. var $visible = $content_container.find('.visible');
  652. var $hidden = $content_container.find('.hidden');
  653. hideMenu();
  654.  
  655. if ( $visible == $content_grid && ( $hidden == $content_iframe || $hidden == $content_embed ) ) {
  656. var $this_content_src = $hidden.attr('src');//.replace(/%20/g,' ');
  657. $dir_table.find('a[href*="' + $this_content_src + '"]').each(function() {
  658. $(this).click();
  659. });
  660. } else if ( $visible == $content_image && $hidden == $content_grid ) {
  661. $content_grid.find('a[href="' + $dir_table.find('.selected').find('a').attr('href') + '"]').parent('div').addClass('selected').css({'background':'#666'}).siblings('div').removeClass('selected').css({'background':'transparent'});
  662. }
  663. closeThis( $visible );
  664. if ( $hidden.length ) {
  665. unhideThis($hidden);
  666. }
  667. scrollSidebar();
  668.  
  669. });
  670.  
  671. // ***** MAIN CLICK FUNCTION FOR SHOWING CONTENT ***** //
  672.  
  673. $dir_table_row.on('click','a',function(e) {
  674.  
  675. var $this_row = $(this).closest('tr');
  676. var $this_link = 'file://' + $(this).attr('href');
  677. $this_link = $this_link.slice($this_link.lastIndexOf('/') + 1 );
  678.  
  679. if ( $sidebar_wrapper.hasClass('unfocused') ) {
  680. sidebarFocus();
  681. }
  682. hideMenu();
  683.  
  684. // if app, ignore or treat as directory
  685. if ( $this_row.hasClass('app') && $settings.apps_as_dirs === false ) {
  686. e.preventDefault();
  687. } else if ( $this_row.hasClass('dir') ) {
  688. return;
  689. } else {
  690. e.preventDefault();
  691.  
  692. selectItem($this_row);
  693.  
  694. if ( $content_grid.hasClass('visible') ) {
  695. hideThis($content_grid);
  696. }
  697. if ( $this_row.hasClass('ignore') ) {
  698. emptyContentPane();
  699. showContentHeader();
  700. } else if ( $this_row.hasClass('img') ) {
  701. closeThis($content_embed);
  702. closeThis($content_iframe);
  703. showThis($content_image,$this_link);
  704. showPrevNextBtns();
  705. } else if ( $this_row.hasClass('pdf') ) {
  706. emptyContentPane();
  707. showThis($content_embed,$this_link);
  708. } else { // iframe
  709. emptyContentPane();
  710. showThis($content_iframe,$this_link);
  711. }
  712. }
  713. setContentTitle();
  714. setContentHeight();
  715. });
  716.  
  717. // File shortcuts: load directory then auto-select file
  718. $('.file_shortcut').on('click',function(e) {
  719. e.preventDefault();
  720. var $this_link = $(this).attr('href');
  721. var $this_dir = $this_link.slice(0,$this_link.lastIndexOf('/') );
  722. window.location = $this_dir;
  723. });
  724.  
  725. // END MAIN CLICK FUNCTIONS
  726.  
  727. // Auto-select file from file shortcut list;
  728. // Limitations: only loads last file from list found in directory, doesn't know anything about which actual file shortcut was selected
  729. function autoSelectFile() {
  730. if ( $settings.file_shortcuts.length ) {
  731. for ( var i = 0; i < $settings.file_shortcuts.length; i++ ) {
  732. if ( $.inArray($settings.file_shortcuts[i], $dir_table_link_arr ) ) {
  733. $dir_table.find( 'a[href*="/' + $settings.file_shortcuts[i] + '"]').click();
  734. }
  735. }
  736. }
  737. }
  738. autoSelectFile();
  739.  
  740. function selectItem(el) {
  741. $(el).addClass('selected').css({'background-color':'lightsteelblue'}).find('a').css({'font-weight':'bold','color':'#333'});
  742. $(el).siblings().removeClass('selected').css({'background-color':'transparent'}).find('a').css({'font-weight':'normal'});
  743. $(el).siblings('.ignore').find('a').css({'color':'#888'});
  744. // select grid item
  745. var $selected_link = $(el).find('a').attr('href');
  746. $content_grid.find('a[href="' + $selected_link + '"]').parent('div').addClass('selected').css({'background':'#666'}).siblings().removeClass('selected').css({'background':'transparent'});
  747. scrollSidebar();
  748. scrollGrid();
  749. }
  750.  
  751. function selectBlur(el) { $(el).css({'background-color':'#BBB'}).find('a').css({'font-weight':'normal','color':'#444'}); }
  752.  
  753. function sidebarFocus() {
  754. $sidebar_wrapper.removeClass('unfocused').addClass('focused');
  755. $content_pane.removeClass('focused').addClass('unfocused');
  756. selectItem('.selected');
  757. }
  758.  
  759. function contentFocus() {
  760. $sidebar_wrapper.removeClass('focused').addClass('unfocused');
  761. $content_pane.removeClass('unfocused').addClass('focused');
  762. if ( $content_image.find('img').attr('src') !== undefined ) {
  763. $content_image.focus();
  764. }
  765. selectBlur('.selected');
  766. }
  767.  
  768. function scrollGrid() {
  769. if ( $content_grid.hasClass('visible') && $content_grid.find('.selected').length ) {
  770. $content_grid.find('.selected')[0].scrollIntoView({ behavior:'smooth',block:'nearest',inline:'nearest' });
  771. }
  772. }
  773. function scrollSidebar() {
  774. if ( $sidebar.find('.selected').length ) {
  775. $sidebar.find('.selected')[0].scrollIntoView({ behavior:'smooth',block:'nearest',inline:'nearest' });
  776. }
  777. }
  778.  
  779. // Zoom Images
  780. $content_image.find('img').on('click',function() {
  781. if ( $(this).hasClass('default') ) {
  782. $(this).removeClass('default').css({'max-width':'','max-height':'','cursor':'zoom-out','top':'0','transform':'translateY(0%)'});
  783. } else {
  784. $(this).addClass('default').css({'max-width':'100%','max-height':'calc(100% - 3px)','cursor':'zoom-in','top':'50%','transform':'translateY(-50%)'});
  785. }
  786. });
  787.  
  788. // Focus content pane on click
  789. // $content_image.add($content_iframe).add($content_embed).on('click', contentFocus() );
  790.  
  791. // ***** KEYBOARD EVENTS ***** //
  792.  
  793. $body.on('keydown',$dir_table,function(e) {
  794.  
  795. $dir_table_row = $dir_table_row.filter(':visible');
  796. var $selected = $dir_table_row.filter('.selected');
  797. var $selected_href = $selected.find('a').attr('href');
  798. var $first_item = $dir_table_row.first();
  799. var $last_item = $dir_table_row.last();
  800. var $prev_item = $selected.prevAll('tr:visible').first();
  801. var $next_item = $selected.nextAll('tr:visible').first();
  802. var $prev_image = $selected.prevAll('tr.img:visible').first();
  803. var $next_image = $selected.nextAll('tr.img:visible').first();
  804.  
  805. switch ( e.key ) {
  806.  
  807. case 'ArrowUp':
  808.  
  809. // Go to parent folder
  810. if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) {
  811. window.location = $parent_dir_link;
  812. break;
  813. }
  814.  
  815. // Default action when content pane is focused
  816. if ( $sidebar_wrapper.hasClass('unfocused') ) {
  817. return;
  818. }
  819.  
  820. if ( $first_item.hasClass('selected') ) {
  821. break;
  822. } else if ( $selected.length < 1 && $last_item.hasClass('dir') ) {
  823. emptyContentPane();
  824. selectItem($last_item);
  825. } else if ( $prev_item.length && $prev_item.hasClass('dir') ) {
  826. emptyContentPane();
  827. selectItem($prev_item);
  828. } else if ( $selected.length < 1 ) {
  829. $last_item.find('a').click();
  830. } else {
  831. e.preventDefault();
  832. $prev_item.find('a').click();
  833. }
  834. break;
  835.  
  836. case 'ArrowDown':
  837.  
  838. if ( (e.ctrl || e.metaKey) && $selected.hasClass('app') && $settings.apps_as_dirs === false ) {
  839. return;
  840. } else if ( $sidebar_wrapper.hasClass('unfocused') ) {
  841. return;
  842. } else if ( (e.ctrl || e.metaKey) && $selected.hasClass('dir') ) {
  843. window.location = $selected_href;
  844. break;
  845. }
  846.  
  847. if ( $last_item.hasClass('selected') ) {
  848. e.preventDefault();
  849. } else if ( $selected.length < 1 && $first_item.hasClass('dir') ) {
  850. selectItem($first_item);
  851. } else if ( $selected.length < 1 ) {
  852. $first_item.find('a').click();
  853. } else if ( $next_item.length > 0 && $next_item.hasClass('dir') ) {
  854. e.preventDefault();
  855. emptyContentPane();
  856. selectItem($next_item);
  857. } else {
  858. e.preventDefault();
  859. $next_item.find('a').click();
  860. }
  861. break;
  862.  
  863. case 'ArrowLeft':
  864.  
  865. if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) {
  866. return;
  867. } else if ( $sidebar_wrapper.hasClass('unfocused') ) {
  868. return;
  869. }
  870. // Navigate Grid or Images
  871. if ( $content_grid.hasClass('visible') ) {
  872. if ( $selected.length !== 1 ) {
  873. selectItem($dir_table_row.filter('.img').last() );
  874. } else {
  875. selectItem($prev_image);
  876. }
  877. } else if ( $content_image.hasClass('visible') ) {
  878. $prev_image.find('a').click();
  879. } else {
  880. $dir_table_row.filter('.img').last().find('a').click();
  881. }
  882. break;
  883.  
  884. case 'ArrowRight':
  885.  
  886. if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) {
  887. return;
  888. } else if ( $sidebar_wrapper.hasClass('unfocused') || $selected.hasClass('ignore') ) {
  889. return;
  890. }
  891. // Navigate Grid or Images
  892. if ( $selected.hasClass('dir') ) {
  893. window.location = $selected_href; // Open directory
  894. } else if ( $content_grid.hasClass('visible') ) {
  895. if ( $selected.length == 0 ) {
  896. selectItem($dir_table_row.filter('.img').first() );
  897. } else {
  898. selectItem($next_image);
  899. }
  900. } else if ( $content_image.hasClass('visible') ) {
  901. $next_image.find('a').click();
  902. } else {
  903. $dir_table_row.filter('.img').first().find('a').click();
  904. }
  905. break;
  906.  
  907. case 'Enter':
  908. // Open directories (or ignore)
  909. if ( $selected.hasClass('app') && $settings.apps_as_dirs === false ) {
  910. break;
  911. } else if ( $selected.hasClass('dir') ) {
  912. window.location = $selected_href;
  913. } else if ( $selected.hasClass('file') ) {
  914. $selected.find('a').click();
  915. } else {
  916. return;
  917. }
  918. break;
  919.  
  920. case 'i':
  921. // Toggle Invisibles with Command-i
  922. if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) {
  923. e.preventDefault();
  924. e.stopPropagation();
  925. $inv_checkbox.click();
  926. }
  927. break;
  928.  
  929. case 'w':
  930. // Close content pane if Close button visible with Command-w
  931. if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && $content_close_btn.is(':visible') ) {
  932. e.preventDefault();
  933. e.stopPropagation();
  934. $content_close_btn.click();
  935. }
  936. break;
  937.  
  938. case 'Tab':
  939. // Tab cannot blur focussed iframe
  940. $(':focus').blur();
  941. if ( $sidebar_wrapper.hasClass('focused') ) {
  942. contentFocus();
  943. } else if ( $sidebar_wrapper.hasClass('unfocused') ) {
  944. $('.selected').click();
  945. sidebarFocus();
  946. }
  947. break;
  948.  
  949. } // end switch
  950.  
  951. // Cmd/Ctrl + g: Show image Grid, with override for default browser binding
  952. if ( e.key == "g" && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) {
  953. $content_grid_btn.click();
  954. e.preventDefault();
  955. e.stopPropagation();
  956. }
  957.  
  958. // Cmd/Ctrl + Shift + O: Open selected item in new window
  959. if ( e.key == "o" && (navigator.platform.match("Mac") ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey ) ) {
  960. window.open($selected_href);
  961. }
  962. });
  963.  
  964. // ***** END KEYBOARD EVENTS ***** //
  965.  
  966. // ***** IMAGE NAVIGATION ***** //
  967.  
  968. $prev_btn.on('mouseenter',function() {
  969. $(this).css({'opacity':'1'});
  970. }).on('mouseleave',function() {
  971. $(this).css({'opacity':'0.6'});
  972. });
  973.  
  974. $next_btn.on('mouseenter',function() {
  975. $(this).css({'opacity':'1'});
  976. }).on('mouseleave',function() {
  977. $(this).css({'opacity':'0.6'});
  978. });
  979.  
  980. $prev_btn.on( 'click', function(event) {
  981. var e = $.Event("keydown");
  982. e.key = 'ArrowLeft';
  983. $dir_table.trigger(e);
  984. });
  985.  
  986. $next_btn.on( 'click', function(event) {
  987. var e = $.Event("keydown");
  988. e.key = 'ArrowRight';
  989. $dir_table.trigger(e);
  990. });
  991.  
  992. // Edit Button -- not implemented
  993. // $content_edit_btn.on('click',function() {
  994. // var $selected_url = $('.selected').find('a').attr('href');
  995. // window.open($selected_url);
  996. // });
  997.  
  998. // GRID BUTTON & IMAGE GRID
  999. // Show grid button only if images are found in directory
  1000. function show_grid_btn() {
  1001. for (var i = 0; i < $image_ext_arr.length; i++ ) {
  1002. if ( $dir_table_file_ext_arr.indexOf($image_ext_arr[i]) != -1 ) {
  1003. $content_grid_btn.show();
  1004. }
  1005. }
  1006. }
  1007. show_grid_btn();
  1008.  
  1009. // Grid Button Hover
  1010. $content_grid_btn.hover(function() {
  1011. $(this).css({'opacity':1});
  1012. }, function() {
  1013. $(this).css({'opacity':0.7});
  1014. });
  1015.  
  1016. // create grid items
  1017. var $grid_item_el = $(
  1018. '<div class="grid_item" style="display:inline-block;width:150px;height:150px;float:left;text-align:center;vertical-align:middle;">' +
  1019. '<a href="">' +
  1020. '<img src="" style="width:auto;height:auto;max-width:128px;max-height:128px;position:relative;top:50%;transform:translateY(-50%);opacity:0.8;" />' +
  1021. '</a>' +
  1022. '</div>'
  1023. );
  1024. var $grid_items_arr;
  1025. function gridItems() {
  1026. $grid_items_arr = [];
  1027. $dir_table_link.each(function() {
  1028. var $this_link = $(this).attr('href');
  1029. var $this_ext = $this_link.toLowerCase().slice($this_link.lastIndexOf('.'));
  1030. if ( $.inArray($this_ext,$image_ext_arr) != -1 ) {
  1031. $grid_item_el.find('a').attr('href',$this_link).find('img').attr('src',$this_link);
  1032. $grid_items_arr.push($grid_item_el.clone());
  1033. }
  1034. return $grid_items_arr;
  1035. });
  1036. }
  1037.  
  1038. // Grid Button Click
  1039. $content_grid_btn.on('click',function() {
  1040. gridItems();
  1041. $content_grid.empty().append( $grid_items_arr );
  1042. selectItem( $dir_table.find('.selected') );
  1043. hideThis($('.visible') );
  1044. unhideThis($content_grid);
  1045. setContentHeight();
  1046. });
  1047.  
  1048. // GRID ITEMS
  1049. // Grid Item Hover
  1050. $content_grid.on('mouseenter','> div:not(".selected")',function() {
  1051. var $this_link = $(this).find('a').attr('href');
  1052. $(this).css({'background':'#555'});
  1053. $dir_table.find('a[href="' + $this_link + '"]').css({'background':'#BBB'});
  1054. }).on('mouseleave','> div:not(".selected")',function() {
  1055. var $this_link = $(this).find('a').attr('href');
  1056. $(this).css({'background':'transparent'});
  1057. $dir_table.find('a[href="' + $this_link + '"]').css({'background':'transparent'});
  1058. });
  1059.  
  1060. // Grid Item Click
  1061. $content_grid.on('click','> div',function(e) {
  1062. e.preventDefault();
  1063. var $this_link = $(this).find('a').attr('href');
  1064. $dir_table.find('a[href="' + $this_link + '"]').click();
  1065. });
  1066.  
  1067.  
  1068. // ***** END IMAGE GRID ***** //
  1069.  
  1070. // Resize Sidebar/Content Pane
  1071. $handle.on('mousedown',function(f) {
  1072. f.stopPropagation();
  1073. var $startX = f.pageX;
  1074. var $sidebar_width = $sidebar_wrapper.width();
  1075. var $window_width = window.innerWidth;
  1076. $content_mask.show(); // needed to prevent interactions with iframe
  1077. $sidebar_wrapper.css({'-webkit-user-select':'none','-moz-user-select':'none','user-select':'none'});
  1078.  
  1079. $(document).on('mousemove',function(e) {
  1080. e.stopPropagation();
  1081. var $deltaX = e.pageX - $startX;
  1082. if ( e.pageX > 200 && e.pageX < $window_width - 200 ) {
  1083. $sidebar_wrapper.css({'width':$sidebar_width + $deltaX + 'px'});
  1084. $content_pane.css({'width':($window_width - $sidebar_width) - $deltaX + 'px'});
  1085. }
  1086. headerHeight();
  1087. setContentHeight();
  1088. });
  1089. $(document).on('mouseup',function() {
  1090. $content_mask.hide();
  1091. $sidebar_wrapper.css({'-webkit-user-select':'auto','-moz-user-select':'auto','user-select':'auto'});
  1092. $(document).off('mousemove');
  1093. });
  1094. });
  1095.  
  1096.  
  1097. })();