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-02-19 提交的版本,查看 最新版本

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