您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Make file:/// directory ("Index of...") pages actually useful. Adds navigation links, file preview pane, user-defined shortcuts, filtering, keyboard navigation, more.
当前为
// ==UserScript== // @name Supercharged Local Directory File Browser (Chrome browsers only) // @version 1.2 // @description Make file:/// directory ("Index of...") pages actually useful. Adds navigation links, file preview pane, user-defined shortcuts, filtering, keyboard navigation, more. // @author Gaspar Schott // @license GPL-3.0 // @match file:///* // @require http://code.jquery.com/jquery-latest.min.js // 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. // It does not work in Safari because Safari does not allow local directories to be browsed. // 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. // 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. // For Greasemonkey, open about:config and change greasemonkey.fileIsGreaseable to true. // For Tampermonkey, go to Chrome extension page, and tick the 'Allow access to file URLs' checkbox at the Tampermonkey extension section. // CHANGELOG: // v. 1.2 // Click to show bookmark menus instead of hover. // Added Cmd/Crl+Shift+O keybinding to open selected item in new window // Arrow navigation bugfixes // @namespace https://greatest.deepsurf.us/users/16170 // ==/UserScript== (function() { 'use strict'; var $ = jQuery; function platformIsMac() { return navigator.platform.indexOf('Mac') > -1; } function platformIsWin() { return navigator.platform.indexOf('Win') > -1; } // Don't run script in iframes or files (only directories) // if ( window.top != window.self ) { if ( window.frameElement !== null ) { return; } else if ( window.location.pathname.slice(-1) != '/') { return; } // ***** USER SETTINGS ***** // var $settings = { user_name: // Your user name '', // Shortcuts: add directories and files here; you may also use your browser's bookmarks, of course root_shortcuts: // Root directories: add or remove as you please (but at leave empty brackets). These defaults are applicable to Mac OS. ['Applications','Library','Users','Volumes'], // ['C:/Users','C:/Program Files','C:/Windows'], user_shortcuts: // User directories; you must enter your user_name above. ['Documents','Downloads','Library'], file_shortcuts: // Add specific file paths, e.g.: 'Users/MyUserName/Documents/MyDocument.html' // These files will be selected automatically when their containing directory is loaded // Limitations: only works for one file per directory; if more than one file per directory is listed, the last item will be selected. [], hide_invisibles: // Mac OS only: Files beginning with a "." will be ignored. true, ignore_files: // If true, ignored file types (see below) will not be loaded in the content pane; // If false, they will be treated as normal files, so if they are selected, the browser will attempt to download file types it can't handle. true, show_ignored_files: // If true, ignored files will be shown in the list grayed out; // if false, they will not appear at all. true, ignore_file_types: // ignore files with these extensions ['exe','.doc','.docx','ppt','pptx','xls','xlsx','odt','odp','msi','dll','rtf','indd','idml','.pages','.tif','tiff','.eps','.psd','.ai','.zip','pkg','.swf','.pls','.ics','.ds_store','alias','.dmg','.gz','.qxp','icon.jpg','thumbs.db'], // lowercase apps_as_dirs: // Mac OS only: if true, treat apps as directories; allows app contents to be browsed. This is the default behavior for Chrome. // If false, treat apps as ignored files. true }; // ***** END USER SETTINGS ***** // // ***** BUILD MENUS ***** // // PATHS var $location = window.location.pathname; var $current_dir_path = $location.replace(/%20/g,' ').replace(/\//g,'/<wbr>').replace(/_/g,'_<wbr>').replace(/—/g,'—<wbr>').replace(/\\/g,'/'); var $current_dir_name = $location.replace(/%20/g,' ').slice(0,-1); $current_dir_name = $current_dir_name.slice($current_dir_name.lastIndexOf('/') + 1); var $location_arr = $location.split('/'); var $parent_dir_link = $location_arr.slice(0,-2).join('/') + '/'; // Parents Link Menu Items var $parent_links_arr = function() { var $paths_arr = []; for ( var i = 1; i < $location_arr.length - 1; i++ ) { $paths_arr[0] = ''; // root $paths_arr[i] = $paths_arr[i - 1] + $location_arr[i] + '/'; } return $paths_arr; }; // function to build menu list items function menu_items(x,y,i) { 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>'; return $menu_item; } // Parents Directory Menu Items var $parents_dir_menu_arr = function() { var $parents_dir_menu_items = []; for ( var i = 1; i < $parent_links_arr().length; i++ ) { $parents_dir_menu_items[0] = menu_items('/','/',0); // root $parents_dir_menu_items[i] = menu_items($parent_links_arr(),$parent_links_arr(),i); } $parents_dir_menu_items.pop(); // remove current directory $parents_dir_menu_items = $parents_dir_menu_items.reverse().join('').replace(/%20/g,' '); return $parents_dir_menu_items; }; // Root Shortcuts Menu Items $settings.root_shortcuts = $settings.root_shortcuts.map(i => i + '/'); // add '/' var $root_shortcuts_menu_arr = function() { if ( $settings.root_shortcuts.length ) { var $root_shortcut_items = []; for ( var i = 0; i < $settings.root_shortcuts.length; i++ ) { $root_shortcut_items[i] = menu_items($settings.root_shortcuts,$settings.root_shortcuts,i); } $root_shortcut_items = $root_shortcut_items.join(''); return $root_shortcut_items; } }; // User Shortcuts Menu Items var $user_shortcuts_display_name = $settings.user_shortcuts.map(i => $settings.user_name + '/' + i + '/' ); // build display names $settings.user_shortcuts = $settings.user_shortcuts.map(i => 'users/' + $settings.user_name + '/' + i + '/'); // build link fragments var $user_shortcuts_menu_arr = function() { if ( $settings.user_name && $settings.user_shortcuts.length ) { var $user_shortcut_items = []; for ( var i = 0; i < $settings.user_shortcuts.length; i++ ) { $user_shortcut_items[i] = menu_items($settings.user_shortcuts,$user_shortcuts_display_name,i); } $user_shortcut_items = $user_shortcut_items.join(''); return $user_shortcut_items; } }; // File Shortcuts Menu Items var $file_shortcuts_display_name = $settings.file_shortcuts.map(i => i.split('/').pop()); // get file names from paths var $file_shortcuts_menu_arr = function() { if ( $settings.file_shortcuts.length ) { var $file_shortcut_items = []; for ( var i = 0; i < $settings.file_shortcuts.length; i++ ) { $file_shortcut_items[i] = menu_items($settings.file_shortcuts,$file_shortcuts_display_name,i); } $file_shortcut_items = $file_shortcut_items.join('').replace(/\/<\/a>/g,'<\/a>').replace(/<a /g,'<a class="file_shortcut" ').replace(/%20/g,' '); return $file_shortcut_items; } }; // ***** END BUILD MENUS ***** // // ***** BUILD UI ELEMENTS ***** // // ***** SIDEBAR ELEMENTS ***** // // 1. Parent Directory Menu var $parent_dir_menu = $( '<nav id="parent_dir_menu" style="margin:0;padding:0;display:table;width:100%;">' + '<a href="" style="width:100%;padding:0;display:table-cell;text-align:center;vertical-align:middle;text-decoration:none;">∧</a>' + '</nav>' ); $parent_dir_menu.find('a').attr('href',$parent_dir_link); // 2. Current Directory Name and Parents Directory Menu var $parents_dir_menu = $( '<nav id="parents_dir_menu" style="margin:0;padding:0;text-align:center;">' + '<div style="padding:4px 6px;display:inline-block;text-align:center;vertical-align:middle;overflow:hidden;cursor:pointer;hyphens:none;"></div>' + '<ul class="menu" style="display:none;margin:0;padding:0;position:absolute;top:;right:0;left:0;z-index:100;text-indent:0;text-align:left;background:lightgray;border-top:solid 1px gray;border-bottom:solid 1px gray;list-style-type:none;box-shadow: 0px 2px 3px -2px #888;"></ul>' + '</nav>' ); $parents_dir_menu.find('div').append( $current_dir_path ); $parents_dir_menu.find('ul').append( $parents_dir_menu_arr() ); // 3. Shortcuts Menu var $divider = $( '<li><hr style="margin:0;border-bottom:0;"></li>' ); var $shortcuts_menu = $( '<nav id="shortcuts_menu" style="margin:0;padding:0;">' + '<div style="width:6em;display:table-cell;text-align:center;vertical-align:middle;font-size:18px;cursor:pointer;">' + '≡' + '</div>' + '<ul class="menu" style="display:none;margin:0;padding:0;position:absolute;right:0;left:0;z-index:100;text-indent:0;text-align:left;background:lightgray;border-top:solid 1px gray;border-bottom:solid 1px gray;list-style-type:none;box-shadow: 0px 2px 3px -2px #888;"></ul>' + '</nav>' ); $shortcuts_menu.find('ul').append( $root_shortcuts_menu_arr(), $divider, $user_shortcuts_menu_arr(), $divider.clone(), $file_shortcuts_menu_arr(), $divider.clone() ); // 4. Details Button var $details_btn = $( '<button id="details_btn" style="margin:1em 0.5em 0.5em;clear:both" tabindex="-1">' + '<span id="show">Show details</span><span id="hide" style="display:none">' + 'Hide details' + '</span>' + '</button>' ); // 5. Invisibles Checkbox var $inv_checkbox = $( '<label id="inv_checkbox" for="inv_checkbox">' + '<input type="checkbox" name="inv_checkbox" tabindex="-1" />' + 'Hide Invisibles' + '</label>' ); // 6. Image Grid Button var $content_grid_btn = $( '<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">' + '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-right:2px;margin-bottom:2px;"></span>' + '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-bottom:2px;"></span>' + '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;margin-right:2px;"></span>' + '<span style="width:7px;height:7px;display:inline-block;box-sizing:border-box;border:solid 2px #666;"></span>' + '</div>' ); // ASSEMBLE SIDEBAR HEADER var $sidebar_header = $( '<table id="sidebar_header" style="width:100%;position:relative;border:0;user-select:none;">' + '<thead>' + '<tr style="border-bottom:solid 1px grey;background-color:#BBB;">' + '<th colspan="3" style="padding:4px;font-weight:normal;font-size:0.875em;letter-spacing:0.5em;cursor:default;">' + 'INDEX OF' + '</th>' + '</tr>' + '</thead>' + '<tbody>' + '<tr style="border-bottom:solid 1px grey;background-color:#BBB;">' + '<td style="width:24px;max-width:24px;min-width:24px;padding:0;"></td>' + '<td style="padding:0;border-left:solid 1px grey;border-right:solid 1px grey;"></td>' + '<td style="width:24px;max-width:24px;min-width:24px;padding:0;"></td>' + '</tr>' + '<tr>' + '<td colspan="3" style="position:relative;"></td>' + '</tr>' + '</tbody>' + '</table>' ); $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(1)').append( $parent_dir_menu ); $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(2)').append( $parents_dir_menu ); $sidebar_header.find('tbody tr:nth-child(1)').find('td:nth-child(3)').append( $shortcuts_menu ); $sidebar_header.find('tbody tr:last-child td').append( $details_btn, $inv_checkbox, $content_grid_btn ); if ( platformIsWin() ) { $inv_checkbox.hide(); } // 7. Sidebar var $sidebar = $( '<div id="sidebar" style="background-color:lightgray;height:100%;min-height:100%;overflow-wrap:break-word;box-sizing:border-box;border-right:solid 1px gray;font-size:0.875em;color:#333;"></div>' ); $sidebar.append($sidebar_header); // 8. Resize Handle var $handle = $( '<div id="handle" style="width:8px;position:absolute;top:0;right:-4px;bottom:0;z-index:1000;cursor:col-resize"></div>' ); // Assemble Sidebar Elements var $sidebar_wrapper = $( '<td id="sidebar_wrapper" class="focused" style="width:25%;will-change:width;padding:0;position:relative;border:0;background:lightgray"></td>' ); $sidebar_wrapper.append( $sidebar, $handle ); // ***** END SIDEBAR ELEMENTS ***** // // ***** BUILD CONTENT PANE ELEMENTS ***** // // 1. Edit Button Element var $content_edit_btn = $( '<td style="width:4em;padding:4px 6px 3px;vertical-align:middle;">' + '<button id="edit_btn" style="display:none;" tabindex="-1">Edit</button>' + '</td>' ); // 2. Title Element var $content_title = $( '<td id="content_title" style="padding:4px 1em 3px;vertical-align:middle;word-break:break-word;"></td>' ); // 3. Close Button Element var $content_close_btn = $( '<td style="width:4em;padding:4px 6px 3px;vertical-align:middle;">' + '<button id="close_btn" tabindex="-1">Close</button>' + '</td>' ); // 4. Content Header Element var $content_header = $( '<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;">' + '<table style="width:100%;padding:7px 12px 5px;"><tbody><tr></tr></tbody></table>' + '</header>' ); $content_header.find('tr').append($content_edit_btn, $content_title, $content_close_btn); // 5. Content Mask Element var $content_mask = $( '<div id="content_mask" style="position:absolute;top:0;right:0;bottom:0;left:0;display:none;z-index:2000;"></div>' ); $content_mask.css({'height':window.innerHeight + 'px'}); // 6. Image Grid Element var $content_grid = $( '<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>' ); // 7. Image Element var $image = $( '<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%);" />' ); var $content_image = $( '<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>' ); $content_image.append($image); // 8. Pdf (embed) Element var $content_embed = $( '<embed id="content_embed" style="width:100%;height:100%;position:absolute;0;right:0;bottom:0;left:0;display:none;" name="plugin" id="plugin" type="application/pdf" tabindex="0"></embed>' ); // 9. Iframe Element var $content_iframe = $( '<iframe id="content_iframe" style="width:100%;height:100%;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;display:none;border:0;" sandbox="allow-scripts allow-same-origin allow-modals" tabindex="0"></iframe>' ); // 10. Object Element // var $content_object = $( // '<object id="content_object" style="width:100%;height:100%;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;display:none;border:0;" tabindex="0"></object>' // ); // 9. Next/Prev Elements 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>'); 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>'); var $svg_arrow = 'url("data:image/svg+xml;utf8,<svg version=\'1.1\' id=\'Layer_1\' xmlns=\'http://www.w3.org/2000/svg\' x=\'0px\' y=\'0px\' width=\'11px\' height=\'16px\' viewBox=\'234.5 248 11 16\' enable-background=\'new 234.5 248 11 16\' xml:space=\'preserve\'><path d=\'M245.5,261l-3,3l-8-8l8-8l3,3l-5,5L245.5,261z\'/></svg>")'; $prev_btn.css({'filter':'invert(50%)','background':$svg_arrow + ' no-repeat center'}); $next_btn.css({'filter':'invert(50%)','background':$svg_arrow + ' no-repeat center','transform':'rotate(180deg)'}); // 10. Content container var $content_container = $('<section id="content_container" style="width:100%;height:100%;position:relative;top:0;overflow:visible;"></section>'); $content_container.append( $content_header, $content_mask, $content_grid, $content_image, $content_embed, $content_iframe ); // Assemble Content Pane Elements var $content_pane = $('<td id="content_pane" class="unfocused" style="width:75%;will-change:width;padding:0;border:0;background:white;position:relative;"></td>'); $content_pane.append( $content_container, $prev_btn, $next_btn ); // Set content height function setContentHeight() { var $content_headerHeight = $content_header.outerHeight(); $content_image.css({'top':$content_headerHeight }); $content_grid.add($content_embed).add($content_iframe).css({'height':window.innerHeight - $content_headerHeight,'top':$content_headerHeight }); } setContentHeight(); // resize head and content header $('window').on('resize', function() { headerHeight(); setContentHeight(); }); // ***** END BUILD CONTENT PANE ELEMENTS ***** // // ASSEMBLE MAIN CONTENT = SIDEBAR + CONTENT PANE var $main_content = $('<table id="main_content" style="width:100%;height:100%;border:0;"><tbody><tr></tr></tbody></table>'); $main_content.find('tr').append( $sidebar_wrapper, $content_pane ); // END BUILD UI ELEMENTS // DEFAULT HTML, BODY STYLES var $body = $('body'); var $dir_table = $body.find('> table'); $body.find('> h1:contains("Index of"),> #parentDirLinkBox,> #UI_goUp').remove(); $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'}); $body.prepend($main_content); // ***** SIDEBAR ***** // // Sidebar Variables var $dir_table_head = $dir_table.find('thead'); var $dir_table_head_cell = $dir_table_head.find('th'); var $dir_table_head_name = $dir_table_head_cell.filter(':first-of-type'); var $dir_table_head_details = $dir_table_head_name.nextAll(); var $dir_table_body = $dir_table.find('tbody'); var $dir_table_row = $dir_table_body.find('tr'); var $dir_table_cell = $dir_table_row.find('td'); var $dir_table_item_name = $dir_table_cell.filter(':nth-of-type(1)'); var $dir_table_details = $dir_table_item_name.nextAll(); var $dir_table_link = $dir_table_item_name.find('a'); // ***** Sidebar Header ***** // // Sidebar header menus heights function headerHeight() { $sidebar_header.find('nav').find('*').addBack().css({'height': 'auto' }); $shortcuts_menu.find('div').add($parent_dir_menu).find('a').addBack().css({'height': ($shortcuts_menu.closest('tr').height() ) +'px' }); } headerHeight(); // MENUS // Show menus on click function showMenu(x) { if ( $(x).parents('td').siblings('td').find('.clicked').length ) { hideMenu(); } $(x).toggleClass('clicked').find('.menu').toggle(); } function hideMenu() { $('.clicked').removeClass('clicked').find('.menu').hide(); } $parents_dir_menu.add($shortcuts_menu).on('click',function(e) { e.stopPropagation(); showMenu(this); }); $(document).on('click',function() { hideMenu(); }); // Menu hover effects $parents_dir_menu.add($shortcuts_menu).find('li').hover(function() { $(this).css({'background-color':'#BBB'}); }, function() { $(this).css({'background-color':'lightgrey'}); }); // Sidebar header invisibles button if ( $settings.hide_invisibles === true ) { $inv_checkbox.find('input').prop('checked',true); } $inv_checkbox.on('click', function(){ if ( $(this).find('input').is(':checked') ) { $(this).find('input').prop('checked',false); } else { $(this).find('input').prop('checked',true); } $('.invisible').toggle().filter('.selected').removeClass('selected'); }); // Sidebar header details button $details_btn.on('click',function() { $dir_table_details.add($dir_table_head_details).toggle(); $dir_table_body.css({'top':$dir_table_head.height() + 1 + 'px'}); $(this).find('span').toggle(); }); // ***** Dir_table setup ***** // $dir_table.detach().attr('id','dir_table'); // Dir_table styles $dir_table.css({'width':'100%','min-width':'100px','height':'calc(100% - ' + $sidebar_header.height() + 'px)','border':'0','position':'relative','overflow':'hidden','table-layout':'fixed'}); $dir_table_head.css({'text-align':'left'}); $dir_table_head_name.css({'padding-left':'2em'}); $dir_table_head_cell.css({'padding':'0 24px 4px;'}); $dir_table_body.css({'width':'100%','position':'absolute','top':'18px','right':'0','bottom':'0','left':'0','overflow-y':'auto','outline':'0'});//.attr('tabindex','0'); $dir_table_row.css({'display':'block'}); $dir_table_cell.css({'padding':'0px'}); $dir_table_link.css({'margin':'0px','display':'block','background-size':'auto 13px','-webkit-padding-start':'2em','padding':'4px 6px 4px 24px','color':'#333','text-decoration':'none','overflow':'hidden','background-position':'6px 4px'}); $dir_table_item_name.css({'display':'block'}); $dir_table_details.add($dir_table_head_details).css({'font-size':'0.875em','text-align':'left','height':'1.5em','vertical-align':'top'}).hide(); $dir_table_details.not('th').css({'padding':'0 24px 4px'}); // Directory Table Hover $dir_table_row.hover(function() { $(this).not('.selected').css({'background-color':'#BBB'}); // Highlight corresponding grid item if ( $content_grid.hasClass('visible') ) { var $this_href = $(this).find('a').attr('href'); $content_grid.find('a[href="' + $this_href + '"]').parent('div').css({'background':'#555'}).siblings('div:not(".selected")').css({'background':'transparent'}); } }, function() { $(this).not('.selected').css({'background-color':'transparent'}); if ( $content_grid.is(':visible') ) { $content_grid.find('div:not(".selected")').css({'background':'transparent'}); } }); // Dir_table link arrays var $dir_table_dir_link_arr = []; var $dir_table_file_link_arr = []; var $dir_table_file_ext_arr = []; $dir_table_row.not('.ignore,.invisible').find('a').each(function() { var $this_link = $(this).attr('href').toLowerCase(); if ( $this_link.endsWith('/') ) { $dir_table_dir_link_arr.push($this_link); return $dir_table_dir_link_arr; } else { var $this_link_ext = $this_link.slice($this_link.lastIndexOf('.')); $dir_table_file_link_arr.push($this_link); if ( $dir_table_file_ext_arr.indexOf($this_link_ext) < 0 ) { $dir_table_file_ext_arr.push($this_link_ext); } return $dir_table_file_link_arr, $dir_table_file_ext_arr; } }); // array of all dir_table links var $dir_table_link_arr = []; $dir_table_link_arr = $dir_table_dir_link_arr.concat($dir_table_file_link_arr); // array of image types var $image_ext_arr = ['.jpg','.jpeg','.png','apng','.gif','.bmp','webp']; // Classify dir_table items $dir_table_row.each(function() { var $this_href = $(this).find('a').text().toLowerCase(); // Directories or files if ( $this_href.endsWith('/') ) { $(this).addClass('dir'); } else { $(this).addClass('file'); } // pdf if ( $this_href.endsWith('.pdf') ) { $(this).addClass('pdf'); } else // images if ( $.inArray( $this_href.slice($this_href.lastIndexOf('.') ), $image_ext_arr ) != -1 ) { $(this).addClass('img'); } // invisibles if ( $this_href.startsWith('.') ) { $(this).addClass('invisible'); if ( $settings.hide_invisibles === true ) { $(this).hide(); } } // ignored if ( $settings.ignore_files === true ) { for ( var i = 0; i < $settings.ignore_file_types.length; i++ ) { if ( $this_href.endsWith( $settings.ignore_file_types[i] ) ) { $(this).addClass('ignore').find('a').css({'color':'#888'}); if ( $settings.show_ignored_files === false ) { $(this).hide(); } } } } // directories as Files and hide ignored files if ( $settings.apps_as_dirs === false ) { if ( $this_href.endsWith('.app/') ) { $(this).addClass('ignore app').find('a').css({'color':'#888'}); var $app_name = $(this).find('a').text().slice(0,-1); $(this).find('a').text($app_name); } } }); // end classify dir_table items $dir_table.appendTo('#sidebar'); // ***** End dir_table setup ***** // // ***************************** // // ***** SHOW/HIDE CONTENT ***** // function setContentTitle(el) { if ( el == $content_grid ) { $content_title.empty().prepend('Images from: /' + $current_dir_name); } else { $content_title.empty().prepend( $('.selected').find('a').text() ); } if ( $('.selected').hasClass('ignore') ) { $content_title.append(' (Ignored content)' ); } } function getDimensions(link, callback) { var img = new Image(); img.src = link; img.onload = function() { callback( this.width, this.height ); }; } function showThis(el,link) { if ( el == $content_image ) { el.find('img').attr('src',link); getDimensions( link, function( width, height ) { $content_title.append(' <span style="text-transform:lowercase;">(' + width + 'px × ' + height + 'px</span>)' ); }); } else if ( el == $content_embed ) { el.attr('type','application/pdf').attr('src',link + '?#zoom=100&scrollbar=1&toolbar=1&navpanes=1'); } else { el.attr('src',link); } unhideThis(el); } function showContentHeader() { $content_header.css({'display':'table'}); } function showPrevNextBtns() { if ( $dir_table.find('.img').length > 1 ) { $prev_btn.add($next_btn).css({'display':'block'}); } } function hidePrevNextBtns() { $prev_btn.add($next_btn).css({'display':'none'}); } function hideThis(el) { el.removeClass('visible').addClass('hidden').css({'z-index':'-1'}).hide(); } function unhideThis(el) { el.removeClass('hidden').addClass('visible').css({'z-index':'auto'}); if ( el == $content_grid ) { el.css({'display':'grid'}); showPrevNextBtns(); } else if ( el == $content_image) { el.show(); showPrevNextBtns(); } else { el.show(); } setContentTitle(el); showContentHeader(); } function closeThis(el) { if ( el == $content_grid ) { $content_grid.hide().empty(); } else if ( el == $content_image ) { $content_image.hide().find('img').removeAttr('src'); } else { el.removeClass('visible').hide().removeAttr('src'); hidePrevNextBtns(); $content_header.hide(); } } function emptyContentPane() { closeThis($content_image); closeThis($content_embed); closeThis($content_iframe); } $content_close_btn.on('click',function() { var $visible = $content_container.find('.visible'); var $hidden = $content_container.find('.hidden'); hideMenu(); if ( $visible == $content_grid && ( $hidden == $content_iframe || $hidden == $content_embed ) ) { var $this_content_src = $hidden.attr('src');//.replace(/%20/g,' '); $dir_table.find('a[href*="' + $this_content_src + '"]').each(function() { $(this).click(); }); } else if ( $visible == $content_image && $hidden == $content_grid ) { $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'}); } closeThis( $visible ); if ( $hidden.length ) { unhideThis($hidden); } scrollSidebar(); }); // ***** MAIN CLICK FUNCTION FOR SHOWING CONTENT ***** // $dir_table_row.on('click','a',function(e) { var $this_row = $(this).closest('tr'); var $this_link = 'file://' + $(this).attr('href'); $this_link = $this_link.slice($this_link.lastIndexOf('/') + 1 ); if ( $sidebar_wrapper.hasClass('unfocused') ) { sidebarFocus(); } hideMenu(); // if app, ignore or treat as directory if ( $this_row.hasClass('app') && $settings.apps_as_dirs === false ) { e.preventDefault(); } else if ( $this_row.hasClass('dir') ) { return; } else { e.preventDefault(); selectItem($this_row); if ( $content_grid.hasClass('visible') ) { hideThis($content_grid); } if ( $this_row.hasClass('ignore') ) { emptyContentPane(); showContentHeader(); } else if ( $this_row.hasClass('img') ) { closeThis($content_embed); closeThis($content_iframe); showThis($content_image,$this_link); showPrevNextBtns(); } else if ( $this_row.hasClass('pdf') ) { emptyContentPane(); showThis($content_embed,$this_link); } else { // iframe emptyContentPane(); showThis($content_iframe,$this_link); } } setContentTitle(); setContentHeight(); }); // File shortcuts: load directory then auto-select file $('.file_shortcut').on('click',function(e) { e.preventDefault(); var $this_link = $(this).attr('href'); var $this_dir = $this_link.slice(0,$this_link.lastIndexOf('/') ); window.location = $this_dir; }); // END MAIN CLICK FUNCTIONS // Auto-select file from file shortcut list; // Limitations: only loads last file from list found in directory, doesn't know anything about which actual file shortcut was selected function autoSelectFile() { if ( $settings.file_shortcuts.length ) { for ( var i = 0; i < $settings.file_shortcuts.length; i++ ) { if ( $.inArray($settings.file_shortcuts[i], $dir_table_link_arr ) ) { $dir_table.find( 'a[href*="/' + $settings.file_shortcuts[i] + '"]').click(); } } } } autoSelectFile(); function selectItem(el) { $(el).addClass('selected').css({'background-color':'lightsteelblue'}).find('a').css({'font-weight':'bold','color':'#333'}); $(el).siblings().removeClass('selected').css({'background-color':'transparent'}).find('a').css({'font-weight':'normal'}); $(el).siblings('.ignore').find('a').css({'color':'#888'}); // select grid item var $selected_link = $(el).find('a').attr('href'); $content_grid.find('a[href="' + $selected_link + '"]').parent('div').addClass('selected').css({'background':'#666'}).siblings().removeClass('selected').css({'background':'transparent'}); scrollSidebar(); scrollGrid(); } function selectBlur(el) { $(el).css({'background-color':'#BBB'}).find('a').css({'font-weight':'normal','color':'#444'}); } function sidebarFocus() { $sidebar_wrapper.removeClass('unfocused').addClass('focused'); $content_pane.removeClass('focused').addClass('unfocused'); selectItem('.selected'); } function contentFocus() { $sidebar_wrapper.removeClass('focused').addClass('unfocused'); $content_pane.removeClass('unfocused').addClass('focused'); if ( $content_image.find('img').attr('src') !== undefined ) { $content_image.focus(); } selectBlur('.selected'); } function scrollGrid() { if ( $content_grid.hasClass('visible') && $content_grid.find('.selected').length ) { $content_grid.find('.selected')[0].scrollIntoView({ behavior:'smooth',block:'nearest',inline:'nearest' }); } } function scrollSidebar() { if ( $sidebar.find('.selected').length ) { $sidebar.find('.selected')[0].scrollIntoView({ behavior:'smooth',block:'nearest',inline:'nearest' }); } } // Zoom Images $content_image.find('img').on('click',function() { if ( $(this).hasClass('default') ) { $(this).removeClass('default').css({'max-width':'','max-height':'','cursor':'zoom-out','top':'0','transform':'translateY(0%)'}); } else { $(this).addClass('default').css({'max-width':'100%','max-height':'calc(100% - 3px)','cursor':'zoom-in','top':'50%','transform':'translateY(-50%)'}); } }); // Focus content pane on click // $content_image.add($content_iframe).add($content_embed).on('click', contentFocus() ); // ***** KEYBOARD EVENTS ***** // $body.on('keydown',$dir_table,function(e) { $dir_table_row = $dir_table_row.filter(':visible'); var $selected = $dir_table_row.filter('.selected'); var $selected_href = $selected.find('a').attr('href'); var $first_item = $dir_table_row.first(); var $last_item = $dir_table_row.last(); var $prev_item = $selected.prevAll('tr:visible').first(); var $next_item = $selected.nextAll('tr:visible').first(); var $prev_image = $selected.prevAll('tr.img:visible').first(); var $next_image = $selected.nextAll('tr.img:visible').first(); switch ( e.key ) { case 'ArrowUp': // Go to parent folder if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { window.location = $parent_dir_link; break; } // Default action when content pane is focused if ( $sidebar_wrapper.hasClass('unfocused') ) { return; } if ( $first_item.hasClass('selected') ) { break; } else if ( $selected.length < 1 && $last_item.hasClass('dir') ) { emptyContentPane(); selectItem($last_item); } else if ( $prev_item.length && $prev_item.hasClass('dir') ) { emptyContentPane(); selectItem($prev_item); } else if ( $selected.length < 1 ) { $last_item.find('a').click(); } else { e.preventDefault(); $prev_item.find('a').click(); } break; case 'ArrowDown': if ( (e.ctrl || e.metaKey) && $selected.hasClass('app') && $settings.apps_as_dirs === false ) { return; } else if ( $sidebar_wrapper.hasClass('unfocused') ) { return; } else if ( (e.ctrl || e.metaKey) && $selected.hasClass('dir') ) { window.location = $selected_href; break; } if ( $last_item.hasClass('selected') ) { e.preventDefault(); } else if ( $selected.length < 1 && $first_item.hasClass('dir') ) { selectItem($first_item); } else if ( $selected.length < 1 ) { $first_item.find('a').click(); } else if ( $next_item.length > 0 && $next_item.hasClass('dir') ) { e.preventDefault(); emptyContentPane(); selectItem($next_item); } else { e.preventDefault(); $next_item.find('a').click(); } break; case 'ArrowLeft': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $sidebar_wrapper.hasClass('unfocused') ) { return; } // Navigate Grid or Images if ( $content_grid.hasClass('visible') ) { if ( $selected.length !== 1 ) { selectItem($dir_table_row.filter('.img').last() ); } else { selectItem($prev_image); } } else if ( $content_image.hasClass('visible') ) { $prev_image.find('a').click(); } else { $dir_table_row.filter('.img').last().find('a').click(); } break; case 'ArrowRight': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $sidebar_wrapper.hasClass('unfocused') || $selected.hasClass('ignore') ) { return; } // Navigate Grid or Images if ( $selected.hasClass('dir') ) { window.location = $selected_href; // Open directory } else if ( $content_grid.hasClass('visible') ) { if ( $selected.length == 0 ) { selectItem($dir_table_row.filter('.img').first() ); } else { selectItem($next_image); } } else if ( $content_image.hasClass('visible') ) { $next_image.find('a').click(); } else { $dir_table_row.filter('.img').first().find('a').click(); } break; case 'Enter': // Open directories (or ignore) if ( $selected.hasClass('app') && $settings.apps_as_dirs === false ) { break; } else if ( $selected.hasClass('dir') ) { window.location = $selected_href; } else if ( $selected.hasClass('file') ) { $selected.find('a').click(); } else { return; } break; case 'i': // Toggle Invisibles with Command-i if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $inv_checkbox.click(); } break; case 'w': // Close content pane if Close button visible with Command-w if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && $content_close_btn.is(':visible') ) { e.preventDefault(); e.stopPropagation(); $content_close_btn.click(); } break; case 'Tab': // Tab cannot blur focussed iframe $(':focus').blur(); if ( $sidebar_wrapper.hasClass('focused') ) { contentFocus(); } else if ( $sidebar_wrapper.hasClass('unfocused') ) { $('.selected').click(); sidebarFocus(); } break; } // end switch // Cmd/Ctrl + g: Show image Grid, with override for default browser binding if ( e.key == "g" && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { $content_grid_btn.click(); e.preventDefault(); e.stopPropagation(); } // Cmd/Ctrl + Shift + O: Open selected item in new window if ( e.key == "o" && (navigator.platform.match("Mac") ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey ) ) { window.open($selected_href); } }); // ***** END KEYBOARD EVENTS ***** // // ***** IMAGE NAVIGATION ***** // $prev_btn.on('mouseenter',function() { $(this).css({'opacity':'1'}); }).on('mouseleave',function() { $(this).css({'opacity':'0.6'}); }); $next_btn.on('mouseenter',function() { $(this).css({'opacity':'1'}); }).on('mouseleave',function() { $(this).css({'opacity':'0.6'}); }); $prev_btn.on( 'click', function(event) { var e = $.Event("keydown"); e.key = 'ArrowLeft'; $dir_table.trigger(e); }); $next_btn.on( 'click', function(event) { var e = $.Event("keydown"); e.key = 'ArrowRight'; $dir_table.trigger(e); }); // Edit Button -- not implemented // $content_edit_btn.on('click',function() { // var $selected_url = $('.selected').find('a').attr('href'); // window.open($selected_url); // }); // GRID BUTTON & IMAGE GRID // Show grid button only if images are found in directory function show_grid_btn() { for (var i = 0; i < $image_ext_arr.length; i++ ) { if ( $dir_table_file_ext_arr.indexOf($image_ext_arr[i]) != -1 ) { $content_grid_btn.show(); } } } show_grid_btn(); // Grid Button Hover $content_grid_btn.hover(function() { $(this).css({'opacity':1}); }, function() { $(this).css({'opacity':0.7}); }); // create grid items var $grid_item_el = $( '<div class="grid_item" style="display:inline-block;width:150px;height:150px;float:left;text-align:center;vertical-align:middle;">' + '<a href="">' + '<img src="" style="width:auto;height:auto;max-width:128px;max-height:128px;position:relative;top:50%;transform:translateY(-50%);opacity:0.8;" />' + '</a>' + '</div>' ); var $grid_items_arr; function gridItems() { $grid_items_arr = []; $dir_table_link.each(function() { var $this_link = $(this).attr('href'); var $this_ext = $this_link.toLowerCase().slice($this_link.lastIndexOf('.')); if ( $.inArray($this_ext,$image_ext_arr) != -1 ) { $grid_item_el.find('a').attr('href',$this_link).find('img').attr('src',$this_link); $grid_items_arr.push($grid_item_el.clone()); } return $grid_items_arr; }); } // Grid Button Click $content_grid_btn.on('click',function() { gridItems(); $content_grid.empty().append( $grid_items_arr ); selectItem( $dir_table.find('.selected') ); hideThis($('.visible') ); unhideThis($content_grid); setContentHeight(); }); // GRID ITEMS // Grid Item Hover $content_grid.on('mouseenter','> div:not(".selected")',function() { var $this_link = $(this).find('a').attr('href'); $(this).css({'background':'#555'}); $dir_table.find('a[href="' + $this_link + '"]').css({'background':'#BBB'}); }).on('mouseleave','> div:not(".selected")',function() { var $this_link = $(this).find('a').attr('href'); $(this).css({'background':'transparent'}); $dir_table.find('a[href="' + $this_link + '"]').css({'background':'transparent'}); }); // Grid Item Click $content_grid.on('click','> div',function(e) { e.preventDefault(); var $this_link = $(this).find('a').attr('href'); $dir_table.find('a[href="' + $this_link + '"]').click(); }); // ***** END IMAGE GRID ***** // // Resize Sidebar/Content Pane $handle.on('mousedown',function(f) { f.stopPropagation(); var $startX = f.pageX; var $sidebar_width = $sidebar_wrapper.width(); var $window_width = window.innerWidth; $content_mask.show(); // needed to prevent interactions with iframe $sidebar_wrapper.css({'-webkit-user-select':'none','-moz-user-select':'none','user-select':'none'}); $(document).on('mousemove',function(e) { e.stopPropagation(); var $deltaX = e.pageX - $startX; if ( e.pageX > 200 && e.pageX < $window_width - 200 ) { $sidebar_wrapper.css({'width':$sidebar_width + $deltaX + 'px'}); $content_pane.css({'width':($window_width - $sidebar_width) - $deltaX + 'px'}); } headerHeight(); setContentHeight(); }); $(document).on('mouseup',function() { $content_mask.hide(); $sidebar_wrapper.css({'-webkit-user-select':'auto','-moz-user-select':'auto','user-select':'auto'}); $(document).off('mousemove'); }); }); })();