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.

Fra 18.02.2018. Se den seneste versjonen.

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