// ==UserScript== // @name Supercharged Local Directory File Browser // @version 2.1.0 // @description Makes file:/// directory ("Index of...") pages (and many server-generated index pages) actually useful. Adds navigation links, file preview pane, keyboard navigation, user-defined shortcuts, filtering, 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 various Chrome and Gecko-based browsers. It has only been minimally tested on Windows, however. It should work, but please report any issues. // It does not work in Safari because Safari does not allow local directories to be browsed. // 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. 2.1.0 // Added: Toggle Default/Dark modes menu item while browsing current directory; mode reverts to saved setting on dir change. // Added: White background for images so that images with transparency are visible against the grey background // Removed trailing "/" from directory display names. // Fixed an issue where font and image grid display got confused about what content to display. // Fixed directory names display in dark mode in server pages that use lists instead of tables. // Better styling for Grid button. // v. 2.0.2 // Various fixes suggested by "Zorg": // Dark mode now ignores html files (and media files), but inverts all plain text files. This solution is not perfect: there is a flash of inverted content when navigating from an html or media file to a non-html or media file; will look for a fix. // Fixed display of non-Latin characters in sidebar header. // Add support for linux "home" directory for user profile shortcuts // Made entire up directory button clickable. // v. 2.0.1 // Fixed wonky font preview scaling. // v. 2.0 // NEW! Not just for local directories anymore! Added support for *many* server-generated directory index pages (It's impossible to check every server configuration, needless to say, so it might not work in every case; let me know if you encounter problems.// NEW! Preview font files (otf, ttf, woff, woff2). Great for designers: preview fonts without installing them. Hint: To install previewed fonts, just type Cmd/Ctrl + O or right-click the link and save it to your fonts folder. Font preview pane is content-editable. // NEW! Preview font files (otf, ttf, woff, woff2). Great for designers: preview fonts without installing them. Hint: To install previewed fonts, just type Cmd/Ctrl + Shift + O or right-click the link and save it to your fonts folder. Font preview pane is content-editable. // Added: Now use the Left and Right arrow keys to navigate through images and fonts in a folder, skipping other files. Use up and down arrow keys to navigate all files normally. // Added: Basic dark mode user setting. // Added: Wrap-around keyboard navigation. // Added: Cmd/Ctr-D to toggle details. // Added: Cmd/Ctr-Shift-. and Cmd/Ctr-Shift-, to scale font previews text size. // Changed: Moved dynamically-added in-line styles to appended stylesheet. // Changed: Extensive refactoring of code for better separation of concerns. (More needs to be done.... Sigh.) // Removed: ScrollIntoView for Grid views. Scrolling didn't work reliably when the sidebar was also being scrolled. Will restore when bug fixed. // Many small bug fixes. // v. 1.4 // Added: Initial support for Firefox. Tested in Firefox 59, Waterfox 56. // Changed: Use SVG for menu icons // Changed: Code cleanup, reorganization // Renamed script to "Supercharged Local Directory File Browser" // v. 1.3 // Fixed: Keyboard navigation of ignored or invisible items fails if "Hide Invisibles" is toggled off after loading a directory. // Added: Also hide ignored files if "Hide Invisibles" is checked. // Added: Content reload button. // Changed: Reorganized settings to reduce confusion about how ignored files are treated. // v. 1.2 // Click to show menus instead of hover. // Added Cmd/Crl+Shift+O keybinding to open selected item in new window // Arrow navigation bugfixes // TO-DO: // Reload button resets font preview size. // Select two items for split pane view? // @namespace https://greasyfork.org/users/16170 // @downloadURL none // ==/UserScript== (function() { 'use strict'; var $ = jQuery; // ***** USER SETTINGS ***** // var $settings = { user_name: // Your computer user name 'MacBookPro', // Shortcuts: add directories and files here. (You can 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','Movies','Music','Pictures'], file_shortcuts: // Add specific file paths, e.g.: 'Users/MyUserName/Documents/MyDocument.html' // These files will be selected (loaded) 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. ['path/to/file.ext','path/to/another/file.ext'], ignore_files: // If true, ignored files (see below) will be greyed-out (default) in the file list and will not be loaded in the content pane when selected; // If false, they will be treated as normal files, so if they are selected, the browser will attempt to download any file types it can't handle (which makes keyboard navigation inconvenient). true, ignore_file_types: // ignore files with these extensions: ['exe','.doc','.docx','ppt','pptx','xls','xlsx','odt','odp','.csv','msi','dll','rtf','indd','idml','.pages','.tif','tiff','.eps','.psd','.ai','.afm','.pfb','.pfm','.tfm','.zip','pkg','.swf','.pls','.ics','.ds_store','ds_store','alias','.dmg','.gz','.qxp','icon.jpg','thumbs.db'], // lowercase hide_ignored_files: // If true, ignored files will be hidden in the file list; // if false, they will appear greyed-out (default). false, hide_invisibles: // Mac OS only: If true, files or directories beginning with a "." will be hidden. true, 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. false, dark_mode: // If true, gives the UI and content pane a dark theme, and inverts plain text content. false }; // ***** END USER SETTINGS ***** // // ***** SETUP ***** // var $userAgent = navigator.userAgent; function platformIsMac() { return navigator.platform.indexOf('Mac') > -1; } function platformIsWin() { return navigator.platform.indexOf('Win') > -1; } function platformIsLinux() { return navigator.platform.indexOf('Linux') > -1; } // Don't run script in iframes or files (only directories) // if ( window.top != window.self ) { if ( window.frameElement !== null ) { return; } if ( window.location.pathname.slice(-1) != '/') { return; } var $body = $('body'); // add lang attr, remove some unneeded default elements $body.attr('lang','en').find('> h1:contains("Index of"),> #parentDirLinkBox,> #UI_goUp,#UI_showHidden').remove(); var $location = decodeURIComponent(window.location.pathname); var $current_dir_path = $location.replace(/%20/g,' ').replace(/\//g,'/').replace(/_/g,'_').replace(/—/g,'—').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('/') + '/'; var e, i, n; var $this_link; var $dir_table; var $dir_table_type; var $dir_table_head; var $dir_table_head_cell; var $dir_table_head_name; var $dir_table_head_details; var $dir_table_body; var $dir_table_row; var $dir_table_cell; var $dir_table_item_name; var $dir_table_details; var $dir_table_item_icon; var $dir_table_link; var $dir_table_rule; var $selected; if ( $body.find('> table').length > 0 ) { $dir_table = $body.find('> table'); $dir_table.addClass('table'); } else { $dir_table = $body.find('> ul'); $dir_table.add('body').addClass('list'); } // ***** BUILD UI ELEMENTS ***** // // ***** SIDEBAR ELEMENTS ***** // // 1. Parent Directory Menu var $parent_dir_menu = $(''); $parent_dir_menu.find('a').attr('href',$parent_dir_link); // 2. Current Directory Name and Parents Directory Menu var $parents_dir_menu = $(''); $parents_dir_menu.find('div').append( $current_dir_path ); // 3. Shortcuts Menu var $divider = $('

  • '); var $shortcuts_menu = $(''); // 3.B Other Menu Items var $toggle_dark_mode = $('
  • Dark ThemeDefault Theme
  • '); // var $export_settings = $('
  • Export Settings
  • '); // 4. Details Button var $details_btn = $(''); // 5. Invisibles Checkbox var $inv_checkbox = $(''); // 6. Image Grid Button var $grid_btn = $('
    '); // 7. Sidebar Header Element var $sidebar_header = $(''); $sidebar_header.find('tbody tr:nth-child(1)').find('td').first().append( $parent_dir_menu ).next().append( $parents_dir_menu ).next().append( $shortcuts_menu ); $sidebar_header.find('tbody tr:last-child td').append( $details_btn, $inv_checkbox, $grid_btn ); var $dir_table_wrapper = $('
    '); // 8. Sidebar var $sidebar = $(''); $sidebar.append($sidebar_header); // 9. Resize Handle var $handle = $('
    '); // 10. Assemble Sidebar Elements var $sidebar_wrapper = $(''); $sidebar_wrapper.append( $sidebar, $handle ); // ***** END SIDEBAR ELEMENTS ***** // // ***** CONTENT PANE ELEMENTS ***** // // 1. Reload Button Element var $content_reload_btn = $(''); // 2. Title Element var $content_title = $(''); // 3. Close Button Element var $content_close_btn = $(''); // 4. Content Header Element var $content_header = $('
    '); $content_header.find('tr').append($content_reload_btn, $content_title, $content_close_btn); // 5. Content Mask Element var $content_mask = $('
    '); // 6. Image Grid Element var $content_grid = $('
    '); // 7. Content grid items var $image_grid_item_el = $('
    '); var $font_grid_item_el = $('
    '); var $content_font_size = $('
    '); // 8. Image Element var $image = $(''); var $content_image = $('
    '); $content_image.append($image); // 9. Pdf (embed) Element var $content_embed = $(''); // 10. Iframe Element var $content_iframe = $(''); // 11. Font Element var $sample_string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ
    abcdefghijklmnopqrstuvwxyz
    0123456789 [(!@#$%^&*;:)]'; var $lorem_string = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; var $specimen; function specimen() { var $specimen_arr = []; for ( i = 0; i < 4; i+=1 ) { $specimen = '
    '+ $sample_string +'
    '+ $lorem_string +'
    '+ $lorem_string +'
    '+ $lorem_string +'
    '; $specimen_arr.push($specimen); } $specimen_arr = $specimen_arr.reverse().join().replace(/,/g,''); return $specimen_arr; } // Use specimen() in $content_font in place of $specimen for 5 different sizes of $sample_string. $specimen = '
    '+ $sample_string +'
    '+ $lorem_string +'
    '+ $lorem_string +'
    '+ $lorem_string +'
    '; var $lorem = $('.lorem'); var $content_font = $('
    '+ $specimen +'
    '); // 12. Next/Prev Elements var $prev_btn = $('
    '); var $next_btn = $('
    '); // 13. Content container var $content_container = $('
    '); $content_container.append( $content_header, $content_font_size, $content_mask, $content_grid, $content_image, $content_embed, $content_iframe, $content_font ); // 14. Assemble Content Pane Elements var $content_pane = $(''); $content_pane.append( $content_container, $prev_btn, $next_btn ); // ***** END BUILD UI ELEMENTS ***** // // ***** STYLES ***** // var $custom_font_styles = document.createElement('style'); $custom_font_styles.appendChild(document.createTextNode("")); document.head.append($custom_font_styles); var $font_styles = ''; $custom_font_styles.append( $font_styles ); var $custom_styles = document.createElement("style"); $custom_styles.appendChild(document.createTextNode("")); var $up_arrow = 'url("data:image/svg+xml;utf8,")'; var $svg_arrow = 'url("data:image/svg+xml;utf8,")'; var $menu_icon = 'url("data:image/svg+xml;utf8,")'; var $grid_icon = 'url("data:image/svg+xml;utf8,")'; var $plus_sign = 'url("data:image/svg+xml;utf8,")'; var $minus_sign = 'url("data:image/svg+xml;utf8, ")'; var $styles = ''; $styles += 'html, body, :root { margin:0; padding:0; max-width:100%; height:100%; font-family:lucidagrande,"fira sans",helvetica,sans-serif; font-size:13px !important; hyphens:auto; overflow:hidden; border-radius:0; box-sizing:border-box; }'; $styles += 'ul { -webkit-margin-before:0em !important; -webkit-margin-after:0em !important; -webkit-padding-start:0em; }'; $styles += 'hr { margin:0; border-bottom:0; }'; // SIDEBAR $styles += '#sidebar_wrapper { width:25%; min-width:220px; will-change:width; padding:0; position:relative; border:0; background:lightgray; overflow:hidden; }'; $styles += '#sidebar { background-color:lightgray; height:'+ window.innerHeight +'px; min-height:100%; overflow-wrap:break-word; box-sizing:border-box; border-right:solid 1px gray; font-size:0.875em; color:#333; overflow:hidden; }'; $styles += '#handle { width:8px; position:absolute; top:0; right:-4px; bottom:0; z-index:1000; cursor:col-resize; }'; // Sidebar Header $styles += '#sidebar_header { width:100%; height:auto; position:relative; border:0; user-select:none; border-collapse:collapse; font-size:0.875rem; }'; $styles += '#sidebar_header thead tr, #sidebar_header tbody tr:first-of-type { border-bottom:solid 1px grey; background-color:#BBB; }'; $styles += '#sidebar_header thead th { padding:4px; font-weight:normal; font-size:0.875em; letter-spacing:0.5em; cursor:default; }'; $styles += '#sidebar_header tbody tr { position:relative; }'; $styles += '#sidebar_header tbody tr:first-of-type td:hover { cursor:pointer; }'; $styles += '#sidebar_header tbody tr:first-of-type td:first-of-type { position:relative; }'; $styles += '#sidebar_header tbody tr:first-of-type td:nth-of-type(odd) { width:24px; max-width:24px; min-width:24px; padding:0; }'; $styles += '#sidebar_header tbody tr:first-of-type td:nth-of-type(even) { width:100%; padding:0; border-left:solid 1px grey; border-right:solid 1px grey; }'; $styles += '#sidebar_header tbody tr:last-of-type td { padding:1em 0; vertical-align:middle; position:relative; white-space:normal; }'; // Menus $styles += '#parent_dir_menu { margin:0; padding:0; display:block; position:absolute; top:0; right:0; bottom:0; left:0; }'; $styles += '#parent_dir_menu a { width:100%; height:100%; padding:0; display:block; text-align:center; vertical-align:middle; text-decoration:none; opacity:0.7; background:' + $up_arrow + 'center no-repeat; }'; $styles += '#parents_dir_menu { margin:0; padding:0; height:auto; text-align:center; }'; $styles += '#parents_dir_menu div { padding:4px 6px; height:auto; display:inline-block; text-align:center; vertical-align:middle; overflow:hidden; cursor:pointer; hyphens:none; white-space:normal; }'; $styles += '#parents_dir_menu + ul { 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; }'; $styles += '#parents_dir_menu + ul li:hover, #shortcuts_menu + ul li:hover { background:#BBB; }'; $styles += '#parents_dir_menu + ul li a, #shortcuts_menu + ul li a { margin:0; padding:4px 6px; display:block; text-indent:0; text-decoration:none; color:#333; white-space:normal; }'; $styles += '#shortcuts_menu { margin:0; padding:0; }'; $styles += '#shortcuts_menu div { width:6em; display:table-cell; text-align:center; vertical-align:middle; font-size:18px; cursor:pointer; opacity:0.7; background:'+ $menu_icon + 'center no-repeat; }'; $styles += '#shortcuts_menu + ul { margin:0; padding:0; -webkit-margin-before:0em !important; -webkit-margin-after:0em !important; -webkit-padding-start:0em; 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; display:none; }'; $styles += '#shortcuts_menu div, #parent_dir_menu, #prev_btn, #next_btn { opacity:0.7; }'; $styles += '#dark_theme { display:block; }'; $styles += '#default_theme { display:none; }'; // Details Button $styles += '#details_btn { margin:0 0.5em; }'; $styles += '#details_btn span:last-of-type { display:none; }'; $styles += 'body.list #details_btn { color:#999; background:#EEE; outline:none; }'; // Grid Button $styles += '#grid_btn { margin:0; width:28px; height:18px; display:none; float:right; cursor:pointer; outline:0; background:'+ $grid_icon +' no-repeat center 100%; }'; $styles += '#grid_btn .menu { padding-right:29px; position:absolute; top:-1px; right:0; border:solid grey; border-width: 1px 0 1px 1px; display:none; }'; $styles += '#grid_btn .menu li { width:100%; padding:4px 6px; background:#CCC; display:block; float:right; clear:both; text-align:right; list-style:none; border-right:solid 1px grey; box-sizing:border-box; }'; $styles += '#grid_btn .menu li:first-of-type { border-bottom:solid 1px grey; }'; $styles += '#grid_btn:hover, #shortcuts_menu div:hover, #parent_dir_menu:hover, #prev_btn:hover, #next_btn:hover { opacity:1; }'; $styles += '#grid_btn.has_images, #grid_btn.has_fonts { display:inline-block; }'; $styles += '#grid_btn.has_images.has_fonts:hover ul.menu { display:block !important; }'; $styles += '#grid_btn.has_images.has_fonts:hover ul.menu li:hover { background:#BBB; }'; // Sidebar dir_table $styles += '#dir_table.table { width:100%; min-wdth:100px; border:0; position:relative; overflow:hidden; table-layout:fixed; border-collapse:collapse; font-size:0.875rem; }'; $styles += '#dir_table.table thead { width:100%; position:absolute; left:0; right:0; text-align:left; }'; $styles += '#dir_table.table thead th { padding:0 24px 4px; }'; $styles += '#dir_table.table thead .name { padding-left:2em; display:block; }'; $styles += '#dir_table.table > tbody { width:100%; position:absolute; right:0; bottom:0; left:0; overflow-y:auto; outline:0; }'; $styles += '#dir_table.table tbody .name { display:block; clear:right; text-align:left; }'; $styles += '#dir_table.table tbody tr { display:block; margin-inline-start:0; clear:both; }'; $styles += '#dir_table.table tbody a { margin:0; display:block; background-size:auto 13px; -webkit-padding-start:2m; padding: 4px 6px 4px 24px; color:#333; text-decoration:none; outline:none; overflow:hidden; background-position:6px 4px; white-space:normal; }'; $styles += '#dir_table.table #thead .name a { padding:0; }'; $styles += '#dir_table.table .icon img { margin-left:1rem; height:16px; }'; $styles += '#dir_table.table .icon + td.name a { -webkit-padding-start:1em; padding-left:6px; }'; $styles += '#dir_table.table .details, #dir_table.table.firefox #tbody > tr > td:not(:first-of-type) { display:none; padding:0 0 4px 24px; font-size:0.875em; text-align:left; vertical-align:top; float:left; }'; $styles += '#dir_table.table .details a { padding:0; }'; $styles += '#dir_table.table .rule { display:none; }'; $styles += '#dir_table.table.show_details .details, #dir_table.table.firefox.show_details #tbody > tr > td:not(:first-of-type) { display:block; }'; $styles += '#dir_table.table.headless > tbody { top:0 !important; }'; $styles += '#dir_table.table.headless .icon { vertical-align:middle; float:left; }'; $styles += '#dir_table.table.firefox #tbody > tr > td:not(:first-of-type) { padding:0 24px 4px; }'; $styles += '#dir_table.table.firefox #tbody > tr > td:last-of-type { text-indent:6px; }'; // dir_table.list $styles += '#dir_table_wrapper { width:100%; min-width:100px; border:0; position:relative; overflow-y:auto; }'; $styles += '#dir_table.list #dir_table_wrapper { padding-top:6px; }'; $styles += '#dir_table.list { width:100%; position:absolute; overflow-y:auto; list-style:none; -webkit-margin-before:0; -webkit-margin-after:0; -webkit-padding-start:0; font-size:0.875rem; line-height:1.4; }'; $styles += '#dir_table.list li a { display:block; padding:3px 1rem; text-decoration:none; color:#333; }'; $styles += '#dir_table.list li.dir a { padding-left:24px; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNqMU79rFUEQ/vbuodFEEkzAImBpkUabFP4ldpaJhZXYm/RiZWsv/hkWFglBUyTIgyAIIfgIRjHv3r39MePM7N3LcbxAFvZ2b2bn22/mm3XMjF+HL3YW7q28YSIw8mBKoBihhhgCsoORot9d3/ywg3YowMXwNde/PzGnk2vn6PitrT+/PGeNaecg4+qNY3D43vy16A5wDDd4Aqg/ngmrjl/GoN0U5V1QquHQG3q+TPDVhVwyBffcmQGJmSVfyZk7R3SngI4JKfwDJ2+05zIg8gbiereTZRHhJ5KCMOwDFLjhoBTn2g0ghagfKeIYJDPFyibJVBtTREwq60SpYvh5++PpwatHsxSm9QRLSQpEVSd7/TYJUb49TX7gztpjjEffnoVw66+Ytovs14Yp7HaKmUXeX9rKUoMoLNW3srqI5fWn8JejrVkK0QcrkFLOgS39yoKUQe292WJ1guUHG8K2o8K00oO1BTvXoW4yasclUTgZYJY9aFNfAThX5CZRmczAV52oAPoupHhWRIUUAOoyUIlYVaAa/VbLbyiZUiyFbjQFNwiZQSGl4IDy9sO5Wrty0QLKhdZPxmgGcDo8ejn+c/6eiK9poz15Kw7Dr/vN/z6W7q++091/AQYA5mZ8GYJ9K0AAAAAASUVORK5CYII= ") 6px 4px no-repeat; background-size:auto 13px; }'; $styles += '#dir_table.list li.file a { padding-left:24px; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABHUlEQVR42o2RMW7DIBiF3498iHRJD5JKHurL+CRVBp+i2T16tTynF2gO0KSb5ZrBBl4HHDBuK/WXACH4eO9/CAAAbdvijzLGNE1TVZXfZuHg6XCAQESAZXbOKaXO57eiKG6ft9PrKQIkCQqFoIiQFBGlFIB5nvM8t9aOX2Nd18oDzjnPgCDpn/BH4zh2XZdlWVmWiUK4IgCBoFMUz9eP6zRN75cLgEQhcmTQIbl72O0f9865qLAAsURAAgKBJKEtgLXWvyjLuFsThCSstb8rBCaAQhDYWgIZ7myM+TUBjDHrHlZcbMYYk34cN0YSLcgS+wL0fe9TXDMbY33fR2AYBvyQ8L0Gk8MwREBrTfKe4TpTzwhArXWi8HI84h/1DfwI5mhxJamFAAAAAElFTkSuQmCC") 6px 4px no-repeat; background-size:auto 13px; }'; $styles += '#dir_table tr, #dir_table li { background:transparent; }'; $styles += '#dir_table tr:hover, #dir_table li:hover, #dir_table .hovered { background:#BBB; }'; $styles += '#dir_table tr.selected, #dir_table li.selected { background:lightsteelblue; }'; $styles += '#dir_table tr.selected a, #dir_table li.selected a { font-weight:bold; color:#333; }'; $styles += 'body.blur_sidebar tr.selected { background-color:#BBB; }'; $styles += 'body.blur_sidebar tr.selected a { font-weight:normal; color:#444; }'; $styles += '#dir_table tr.ignore a, #dir_table tr.ignore.app a { color:#888; }'; $styles += '#dir_table.hide_invisibles .invisible { display:none !important; }'; $styles += '#dir_table.hide_ignored tr.ignore { display:none !important; }'; // CONTENT PANE $styles += '#content_pane { width:75%; will-change:width; padding:0; border:0; background:#FFF; position:relative; }'; $styles += '#content_container { width:100%; height:100%; top:0; overflow:visible; }'; // Content pane header $styles += '#content_header { 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; }'; $styles += '#content_header table { width:100%; padding:7px 12px 5px; border-collapse:collapse; font-size:0.875rem; }'; $styles += '#content_header td:first-of-type, #content_header td:last-of-type { width:6em; padding:4px 6px 3px; vertical-align:middle; }'; $styles += '#content_header td:first-of-type { float:left; text-align:left; }'; $styles += '#content_header td:last-of-type { float:right; text-align:right; }'; $styles += '#content_header td button { word-break:none; hyphens:none; }'; $styles += '#content_title { padding:4px 1em 3px; vertical-align:middle; word-break:break-word; text-align:center; }'; $styles += '#content_pane[class*="content"] #content_header { display:block !important; }'; // Font size button $styles += '#font_size { background:rgba(128,128,128,0.3); position:absolute; right:1rem; opacity:0; transition:opacity 1s ease-in-out; display:block; z-index:10; }'; $styles += '#font_size span { width:2rem; height:2rem; font-size:2rem; display:block; text-align:center; cursor:pointer; }'; $styles += '#font_size span:first-of-type { opacity:0.3; background:'+ $plus_sign +' center no-repeat; }'; $styles += '#font_size span:last-of-type { opacity:0.3; background:'+ $minus_sign +' center no-repeat; }'; $styles += '#font_size span:hover { opacity:0.5; filter:invert(100%); background-color:#666; }'; $styles += '#content_pane.has_font_content:hover #font_size, #content_pane.has_grid_content:hover #font_size { display:block; opacity:1; }'; $styles += '#content_mask { height:'+ window.innerHeight + 'px; position:absolute; top:0; right:0; bottom:0; left:0; display:none; z-index:9998; }'; $styles += '#content_image {padding:2em; position:absolute; top:0; right:0; bottom:0;left:0; display:none; background:#333; overflow:auto; text-align:center;}'; $styles += '#content_image img {width:auto; height:auto; max-width:100%; max-height:100%; max-height:calc(100% - 3px); cursor:zoom-in; -webkit-user-select:none; position:relative; top:50%; transform:translateY(-50%); background:#FFF; };'; $styles += '#content_image img.zoom_img { max-width:none; max-height:none; cursor:zoom-out; top:0; transform:translateY(0); }'; $styles += '#content_embed, #content_iframe { width:100%; height:100%; padding:0; position:absolute; top:0; right:0; bottom:0; left:0; border:0; display:none; }'; $styles += '#content_grid { width:auto; padding:0; display:none; position:absolute; right:0; bottom:0; left:0; overflow:auto; font-size:1em; background:#333; grid-gap:0; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); grid-template-rows:repeat(auto, 150px); z-index:1; }'; $styles += '#content_grid .image_grid_item { display:inline-block; width:150px; height:150px; float:left; text-align:center; vertical-align:middle; }'; $styles += '#content_grid .image_grid_item.selected { background:#666; }'; $styles += '#content_grid .image_grid_item:hover, #content_grid div.image_grid_item.hovered { background:#555 !important; }'; $styles += '#content_grid .font_grid_item { width:calc(100% - 2rem); padding:1rem 0.75rem; display:block; font-size:3em; text-align:left; outline:none; clear:both; }'; $styles += '#content_grid .font_grid_item:hover, #content_grid div.font_grid_item.hovered { background:#EEE !important; }'; $styles += '#content_grid .font_grid_item.selected { background:#DDD; }'; $styles += '#content_grid div img { width:auto; height:auto; max-width:128px; max-height:128px; position:relative; top:50%; transform:translateY(-50%); opacity:0.8; } '; $styles += '#content_grid.has_image_grid { display:grid !important; }'; $styles += '#content_grid.has_font_grid, #content_grid.has_grid { background:#FFF; display:block !important; }'; $styles += '#content_grid.has_grid div.selected { background:#DDD; }'; $styles += '#content_grid.has_grid div:hover, #content_grid.has_grid div.hovered { background:#EEE !important; }'; $styles += '#content_font { padding:1rem; display:none; position:absolute; right:0; bottom:0; left:0; overflow:auto; font-size:1em; word-break:break-all; overflow-wrap:break-word; hyphens:none; outline:none; }'; $styles += '.specimen { margin-bottom:0.25em; padding-bottom:0.25em; white-space:normal; text-align:left; border-bottom:solid 1px black; }'; $styles += '.lorem { margin-bottom:1em; text-align:justify; word-break:normal; white-space:normal; overflow-wrap:normal; hyphens:auto; }'; $styles += '.specimen + .lorem:first-line { letter-spacing:1pt; font-variant:small-caps; }'; $styles += '.lorem + .lorem { columns:2; column-gap:1em;}'; $styles += '.lorem + .lorem + .lorem { margin-bottom:2em; columns:3; }'; $styles += '#prev_btn, #next_btn { padding:0 1em; display:none; position:absolute; top:0; bottom:0; z-index:100; opacity:0.6; filter:invert(50%); background: ' + $svg_arrow + ' no-repeat center; }'; $styles += '#prev_btn { left:0 !important; }'; $styles += '#next_btn { right:0; transform:rotate(180deg); }'; $styles += '#content_pane.has_image_content #prev_btn, #content_pane.has_image_content #next_btn { display:block !important; }'; $styles += '#content_pane.has_font_content #content_font { display:block; }'; $styles += '#content_pane[class*="hidden"] #content_grid { display:none !important; z-index:auto; }'; $styles += '#content_pane.has_image_content #content_image { display:block !important; }'; $styles += '#content_pane.has_file_content #content_iframe { display:block !important; }'; $styles += '#content_pane.has_pdf_content #content_embed { display:block !important; }'; $styles += 'body.dark_mode #sidebar, body.dark_mode #content_header { background:#555; }'; $styles += 'body.dark_mode #sidebar ul.menu { background:#444; box-shadow-color:#111; }'; $styles += 'body.dark_mode #sidebar ul.menu li:hover { background:#666; }'; $styles += 'body.dark_mode #sidebar { border-right-color:#111; }'; $styles += 'body.dark_mode #sidebar_header thead tr, body.dark_mode #sidebar_header tbody tr:first-of-type { border-bottom:solid 1px black; background-color:#444; }'; $styles += 'body.dark_mode #sidebar_header tbody tr:first-of-type td:nth-of-type(even) { border-left-color:#111; border-right-color:#111; }'; $styles += 'body.dark_mode #sidebar_header .menu { border-top-color:#111; }'; $styles += 'body.dark_mode #sidebar_header .menu, body.dark_mode #content_header { border-bottom-color:#111; }'; $styles += 'body.dark_mode #sidebar tr *, body.dark_mode #sidebar li, body.dark_mode #sidebar li a, body.dark_mode #content_header tr { color:#EEE !important; }'; $styles += 'body.dark_mode #details_btn span { color:#333 !important; }'; $styles += 'body.dark_mode #dark_theme { display:none; }'; $styles += 'body.dark_mode #default_theme { display:block; }'; $styles += 'body.dark_mode #sidebar #grid_btn, body.dark_mode #grid_btn .menu, body.dark_mode #parent_dir_menu, body.dark_mode #shortcuts_menu { filter:invert(100%); }'; $styles += 'body.dark_mode #sidebar #grid_btn ul.menu { background:transparent; border: solid #111; border-width: 1px 0 1px 1px; box-shadow:none !important; }'; $styles += 'body.dark_mode #sidebar #grid_btn .menu li { background:#555; border-right-color: #111; }'; $styles += 'body.dark_mode #sidebar #grid_btn .menu li:first-of-type { border-bottom-color: #111; }'; $styles += 'body.dark_mode #sidebar #grid_btn .menu li:hover { background:#777; }'; $styles += 'body.dark_mode #dir_table tr.selected,body.dark_mode #dir_table li.selected { background:slategray !important; }'; $styles += 'body.dark_mode #dir_table tr:hover,body.dark_mode #dir_table li:hover { background:#777 !important; }'; $styles += 'body.dark_mode #content_pane, body.dark_mode #content_grid { background:#333; }'; $styles += 'body.dark_mode #content_font, body.dark_mode .font_grid_item { color:#CCC; }'; $styles += 'body.dark_mode #content_grid .font_grid_item:hover, body.dark_mode #content_grid .image_grid_item:hover { background:#555 !important }'; $styles += 'body.dark_mode #content_pane.has_font_content .specimen { border-bottom-color:#CCC; }'; $styles += 'body.dark_mode #content_iframe { filter:invert(87.5%); }'; var $excluded = ['.htm','.xhtm','.mp3','.m4a','.m4v','.mp4','.ogg','.ogm','.oga','.webm','.wav','.mpeg','.flac']; for ( i = 0, n = $excluded.length; i < n; i += 1) { $styles += 'body.dark_mode #content_iframe[src*="'+ $excluded[i] +'" i] { background:white; filter:unset; }'; } $styles += '#main_content { width:100%; height:100%; border:0; border-collapse:collapse; overflow:hidden; }'; $custom_styles.append($styles); document.head.appendChild($custom_styles); // Conditional Styles: var $gecko_styles = document.createElement("style"); var $custom_gecko_styles = ''; $custom_gecko_styles += ''; $gecko_styles.append($custom_gecko_styles); // for scrollIntoView var $block = ''; if( $userAgent.indexOf('Firefox') > -1 ){ document.head.appendChild($gecko_styles); $block = 'start'; } else { $block = 'nearest'; } // if( $userAgent.indexOf('Chrome') > -1 ){ // Do something // } // Sidebar Header: Hide invisibles checkbox user setting if ( $settings.hide_invisibles === true ) { $inv_checkbox.find('input').prop('checked',true); $dir_table.addClass('hide_invisibles'); } // Sidebar Header: Toggle Invisibles checkbox $inv_checkbox.on('click','input', function(e){ $dir_table.toggleClass('hide_invisibles'); $('.selected').removeClass('selected'); }); // Hide Ignored Files if ( $settings.hide_ignored_files === true ) { $dir_table.addClass('hide_ignored'); } // Dark Mode if ( $settings.dark_mode === true ) { $body.addClass('dark_mode'); } $toggle_dark_mode.on('click',function(e) { e.preventDefault(); $body.toggleClass('dark_mode'); }); // Hide hide invisibles chceckbox if ( platformIsWin() || window.location.href.indexOf('file:') < 0 ) { $inv_checkbox.hide(); } // ***** END STYLES ***** // // ***** BUILD MENUS ***** // // MENUS: Parents Link Menu Items var parentLinksArr = function() { var $paths_arr = []; for ( i = 1, n = $location_arr.length; i < n - 1; i+=1 ) { $paths_arr[0] = ''; // root $paths_arr[i] = $paths_arr[i - 1] + $location_arr[i] + '/'; } return $paths_arr; }; // MENUS: function to build menu list items var menuItems = function(x,y,i) { // (link, name, count) var $menu_item = '
  • ' + y[i] + '
  • '; return $menu_item; }; // MENUS: Parents Directory Menu Items var parents_dir_menu_arr = function() { var $parents_dir_menu_items = []; for ( var i = 1, n = parentLinksArr().length; i < n; i+=1 ) { $parents_dir_menu_items[0] = menuItems('/','/',0); // root $parents_dir_menu_items[i] = menuItems( parentLinksArr(), parentLinksArr(), 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; }; $parents_dir_menu.siblings('ul').append( parents_dir_menu_arr() ); // MENUS: Root Shortcuts Menu Items $settings.root_shortcuts = $settings.root_shortcuts.map(i => i + '/'); // append '/' to directory name var root_shortcuts_menu_arr = function() { if ( $settings.root_shortcuts.length ) { var $root_shortcut_items = []; for ( i = 0, n = $settings.root_shortcuts.length; i < n; i+=1 ) { $root_shortcut_items[i] = menuItems($settings.root_shortcuts,$settings.root_shortcuts,i); } $root_shortcut_items = $root_shortcut_items.join(''); return $root_shortcut_items; } }; // MENUS: User Shortcuts Menu Items var $user_shortcuts_display_name = $settings.user_shortcuts.map(i => $settings.user_name + '/' + i + '/' ); // build display names var $home = ''; if ( platformIsLinux() ) { $home = 'home/'; } else { $home = 'users/'; } $settings.user_shortcuts = $settings.user_shortcuts.map(i => $home + $settings.user_name + '/' + i + '/'); // build link fragments var userShortcutsMenuArr = function() { if ( $settings.user_name && $settings.user_shortcuts.length ) { var $user_shortcut_items = []; for ( i = 0, n = $settings.user_shortcuts.length; i < n; i+=1 ) { $user_shortcut_items[i] = menuItems($settings.user_shortcuts,$user_shortcuts_display_name,i); } $user_shortcut_items = $user_shortcut_items.join(''); return $user_shortcut_items; } }; // MENUS: File Shortcuts Menu Items var $file_shortcuts_display_name = $settings.file_shortcuts.map(i => i.split('/').pop()); // get file names from paths var fileShortcutsMenuArr = function() { if ( $settings.file_shortcuts.length ) { var $file_shortcut_items = []; for ( i = 0, n = $settings.file_shortcuts.length; i < n; i+=1 ) { $file_shortcut_items[i] = menuItems($settings.file_shortcuts,$file_shortcuts_display_name,i); } $file_shortcut_items = $file_shortcut_items.join('').replace(/\/<\/a>/g,'<\/a>').replace(/ thead').length ? $dir_table.find('> thead') : $dir_table.addClass('headless').find('> tbody > tr:first-of-type') ; $dir_table_head.attr('id','thead'); $dir_table_head_cell = $dir_table_head.find('th'); $dir_table_head_name = $dir_table_head.find('th:contains("Name")'); $dir_table_head_name.addClass('name'); $dir_table_head_details = $dir_table_head_name.nextAll(); $dir_table_head_details.addClass('details'); $dir_table_body = $dir_table.find('> tbody'); $dir_table_body.attr('id','tbody'); $dir_table_rule = $dir_table_body.find('hr').closest('tr'); $dir_table_rule.addClass('rule'); $dir_table_row = $dir_table_body.find('> tr').not('#thead').not('.rule'); $dir_table_cell = $dir_table_row.find('td'); $dir_table_link = $dir_table_cell.find('a'); $dir_table_item_name = $dir_table_link.parent('td'); $dir_table_item_name.addClass('name'); $dir_table_item_icon = $dir_table_item_name.add($dir_table_head_name).prev(); $dir_table_item_icon.addClass('icon'); // for directory lists with separate td for icons $dir_table_details = $dir_table_item_name.nextAll(); $dir_table_details.addClass('details'); } if( $userAgent.indexOf('Firefox') > -1 ) { $dir_table.addClass('firefox'); } if ( $dir_table.hasClass('list') ) { // Apache server $dir_table_wrapper.addClass('headless'); $dir_table_head = ''; $dir_table_head_cell = ''; $dir_table_head_name = ''; $dir_table_head_details = ''; $dir_table_body = ''; $dir_table_row = $dir_table.find('li'); $dir_table_cell = ''; $dir_table_details = ''; $dir_table_link = $dir_table_row.find('a'); // $dir_table_link.addClass('name'); $dir_table_item_name = $dir_table_link.text(); $sidebar.append($dir_table_wrapper); } $dir_table.detach().attr('id','dir_table'); // ***** DIR_TABLE SETUP ***** // // Sidebar Header: Show details button click function function detailsButton() { $dir_table.toggleClass('show_details'); $dir_table_body.css({'top':$dir_table_head.height() + 1 +'px'}); $details_btn.find('span').toggle(); } $details_btn.on('click', detailsButton ); // Dir_table: Row hover effects $dir_table_row.hover(function() { // Highlight corresponding grid item if ( $content_grid.is(':visible') ) { $this_link = $(this).find('a').attr('href'); $content_grid.find('[href="' + $this_link + '"]').closest('div').addClass('hovered'); } }, function() { if ( $content_grid.is(':visible') ) { $content_grid.find('.hovered').removeClass('hovered'); } }); // Dir_table: create 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() { $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; } }); // Dir_table: 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); // Dir_table: array of supported image types var $image_ext_arr = ['.jpg','.jpeg','.png','apng','.gif','.bmp','webp']; var $font_ext_arr = ['.otf','.ttf','.woff','.woff2']; var $font_family_arr = []; // Dir_table: Classify items $dir_table_row.each(function() { $this_link = $(this).find('a').attr('href'); if ( $this_link != undefined ) { $this_link = $this_link.toString().toLowerCase(); // Directories or files if ( $this_link.endsWith('/') ) { $(this).addClass('dir'); $(this).find('a').text($(this).find('a').text().slice(0,-1)); } else { $(this).addClass('file'); } // pdf if ( $this_link.endsWith('.pdf') ) { $(this).addClass('pdf'); } else if ( $.inArray( $this_link.slice($this_link.lastIndexOf('.') ), $image_ext_arr ) != -1 ) { $(this).addClass('img'); } else if ( $.inArray( $this_link.slice($this_link.lastIndexOf('.') ), $font_ext_arr ) != -1 ) { $(this).addClass('font'); } // invisibles if ( $this_link.slice($this_link.lastIndexOf('/') + 1 ) === '.' || $this_link.startsWith('.') || $(this).find('a').text().startsWith('.') ) { $(this).addClass('invisible'); } // ignored if ( $settings.ignore_files === true ) { for ( i = 0, n = $settings.ignore_file_types.length; i < n; i+=1 ) { if ( $this_link.endsWith( $settings.ignore_file_types[i] ) ) { $(this).closest('#dir_table > tbody > tr').addClass('ignore'); } } } // directories as Files and hide ignored files if ( $settings.apps_as_dirs === false ) { if ( $this_link.endsWith('.app/') ) { $(this).addClass('ignore app'); var $app_name = $(this).find('a').text().slice(0,-1); $(this).find('a').text($app_name); } } } }); // end classify dir_table items if ( $dir_table.hasClass('table') ) { $dir_table.appendTo($sidebar); } else { $dir_table.appendTo($dir_table_wrapper); } // Show grid button if images or fonts are found if ( $dir_table.find('.img').length ) { $dir_table.add($grid_btn).addClass('has_images'); } if ( $dir_table.find('.font').length ) { $dir_table.add($grid_btn).addClass('has_fonts'); } // ***** End dir_table setup ***** // // ***** APPEND MAIN CONTENT ***** // var $main_content = $('
    '); $main_content.find('tr').append( $sidebar_wrapper, $content_pane ); $body.prepend($main_content); // ***************************** // // ***** SHOW/HIDE CONTENT ***** // // MENUS: Hide Menu function function hideMenu() { $('.menu').hide(); } $(document).on('click', hideMenu ); // Set content height function setContentHeight() { var $dir_table_head_height = $dir_table_head.length ? $dir_table_head.height() : 0; var $content_headerHeight = $content_header.outerHeight(); $dir_table.add($dir_table_wrapper).css({'height':window.innerHeight - $sidebar_header.outerHeight() }); $dir_table.find($dir_table_body).css({'top': $dir_table_head_height }); $content_image.css({'top':$content_headerHeight }); $content_grid.add($content_embed).add($content_iframe).add($content_font).css({'height':window.innerHeight - $content_headerHeight,'top':$content_headerHeight }); $content_font_size.css({'top':$content_headerHeight + 13 }); } setContentHeight(); $('window').on('resize', setContentHeight ); function setContentTitle() { if ( $content_pane.hasClass('has_grid_content') && $content_grid.hasClass('has_grid') ) { $content_title.empty().prepend('Images and Fonts from: ' + $current_dir_name); } else if ( $content_pane.hasClass('has_grid_content') && $content_grid.hasClass('has_image_grid') ) { $content_title.empty().prepend('Images from: ' + $current_dir_name); } else if ( $content_pane.hasClass('has_grid_content') && $content_grid.hasClass('has_font_grid') ) { $content_title.empty().prepend('Fonts from: ' + $current_dir_name); } else { $content_title.empty().prepend( $('.selected').find('a').text() ); } if ( $('.selected').hasClass('ignore') ) { $content_title.append(' (Ignored content)' ); } } // Get image dimensions function getDimensions(link, callback) { var img = new Image(); img.src = link; img.onload = function() { callback( this.width, this.height ); }; } function scrollSidebar(row) { row[0].scrollIntoView({ behavior:'smooth', block:$block, inline:'nearest' }); } function scrollGrid(item) { item[0].scrollIntoView({ behavior:'smooth', block:$block, inline:'nearest' }); } // Select row on click and set classes for $content_pane function selectThis(row) { row.addClass('selected').siblings().removeClass('selected'); $selected = $dir_table.find('.selected'); scrollSidebar($selected); if ( row.hasClass('dir') ) { closeThis(); // empty content pane setContentTitle(); $content_pane.removeClass().addClass('has_dir_content'); } var $grid_selected = $content_grid.find('div.font_grid_item[href="'+ row.find('a').attr('href') +'"]').add('div a[href="'+ row.find('a').attr('href') +'"]').parent('div').addBack(); if ( $content_pane.hasClass('has_grid_content') ) { $grid_selected.addClass('selected').siblings().removeClass('selected'); $grid_selected = $content_grid.find('.selected'); // scrollGrid($grid_selected); // grid scroll is not working reliably } } function showIgnored() { closeThis(); $content_pane.addClass('has_ignored_content'); $content_title.append(' (Ignored content)' ); } function showImage(row,link) { $content_pane.addClass('has_image_content'); $content_image.find('img').removeClass('zoom_img').attr('src',link); getDimensions( link, function( width, height ) { $content_title.append(' (' + width + 'px × ' + height + 'px)' ); }); $content_grid.find('a[href="' + row.find('a').attr('href') + '"]').parent('div').addClass('selected').siblings().removeClass('selected'); } function showPdf(link) { $content_pane.addClass('has_pdf_content'); $content_embed.attr('type','application/pdf').attr('src',link + '?#zoom=100&scrollbar=1&toolbar=1&navpanes=1'); } function showFile(link) { $content_pane.addClass('has_file_content'); $content_iframe.attr('src',link); } function showFont(row,link) { var $font_family = row.find('.name').text(); addCustomStyle($font_family,link); $content_pane.addClass('has_font_content'); $content_font.css({ 'font-family':'"'+ $font_family +'"' }); } function addCustomStyle(font_family,link) { if ( $font_family_arr.indexOf(font_family) == -1 ) { $font_family_arr.push(font_family); $custom_font_styles.append('@font-face { font-family: "'+ font_family +'"; src: url("'+ link +'"); }'); // only add style if it doesn't exist } } // Show selected content function showThis(row,link) { if ( $content_pane.hasClass('has_grid_content') ) { $content_pane.removeClass().addClass('has_hidden_grid'); // hide grid when showing new content } else if ( $content_pane.hasClass('has_hidden_grid') ) { $content_pane.removeClass().addClass('has_hidden_grid'); // keep grid hidden when showing new content } else { $content_pane.removeClass(); } if ( row.hasClass('ignore') ) { showIgnored(); return; } if ( row.hasClass('img') ) { showImage(row,link); return; } if ( row.hasClass('pdf') ) { showPdf(link); return; } if ( row.hasClass('font') ) { showFont(row,link); return; } if ( row.hasClass('file') ) { showFile(link); return; } } // ***** MAIN CLICK FUNCTION FOR SHOWING CONTENT ***** // function clickDirTableLink(link) { var $this_row = link.closest('#dir_table > tbody > tr, #dir_table > li'); $this_link = link.attr('href'); if ( $this_row.hasClass('dir') ) { window.location = $this_link; } hideMenu(); showThis($this_row,$this_link); selectThis($this_row); setContentTitle(); setContentHeight(); } $dir_table_row.on('click','a',function(e) { e.preventDefault(); closeContent(); clickDirTableLink($(this)); }); // 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 ( i = 0, n = $settings.file_shortcuts.length; i < n; i+=1 ) { if ( $.inArray($settings.file_shortcuts[i], $dir_table_link_arr ) ) { $dir_table.find( 'a[href*="/' + $settings.file_shortcuts[i] + '"]').click(); } } } } autoSelectFile(); // File shortcuts: load directory then auto-select file function showFileShortcut(item) { e.preventDefault(); $this_link = item.attr('href'); var $this_dir = $this_link.slice(0,$this_link.lastIndexOf('/') ); window.location = $this_dir; } $('.file_shortcut').on('click',showFileShortcut ); // Reload Button function reloadThis() { if ( $content_pane.hasClass('has_grid_content') ) { $grid_btn.click(); } else if ( $content_pane.is('[class*="content"]') ) { $('.selected').find('a').click(); } else { return; } } $content_reload_btn.on('click', reloadThis ); function closeContent() { $content_image.find('img').removeAttr('src'); $content_embed.removeAttr('src'); $content_iframe.removeAttr('src'); $content_font.css({'font-family':''}); } function closeThis() { hideMenu(); if ( $content_pane.hasClass('has_grid_content') ) { $content_pane.removeClass('has_grid_content'); $content_grid.removeClass().empty().css({'font-size':'1em'}); } else if ( $content_pane.hasClass('has_hidden_grid') ) { $content_pane.removeClass().addClass('has_grid_content'); closeContent(); } else { $content_pane.removeClass(); closeContent(); } setContentTitle(); } // Close content button $content_close_btn.on( 'click', closeThis ); // ***** KEYBOARD EVENTS ***** // function navigateToThis(row) { if ( $content_pane.hasClass('has_grid_content') ) { selectThis(row); } else { row.find('a').click(); } } $body.on('keydown',$dir_table,function(e) { var $selected = $dir_table_row.filter('.selected'); var $selected_href = $selected.find('a').attr('href'); var $first_item = $dir_table_row.filter(':visible').first(); var $last_item = $dir_table_row.filter(':visible').last(); var $prev_item = $selected.prevAll(':visible').first(); var $next_item = $selected.nextAll(':visible').first(); var $first_image = $dir_table_row.filter('.img:visible').first(); var $last_image = $dir_table_row.filter('.img:visible').last(); var $prev_image = $selected.prevAll('.img:visible').first(); var $next_image = $selected.nextAll('.img:visible').first(); var $first_font = $dir_table_row.filter('.font:visible').first(); var $last_font = $dir_table_row.filter('.font:visible').last(); var $prev_font = $selected.prevAll('.font:visible').first(); var $next_font = $selected.nextAll('.font: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; } // Allow arrow navigation within if ( $('*[contentEditable="true"').is(':focus') ) { return; } e.preventDefault(); if ( $first_item.hasClass('selected') || $selected.length < 1 ) { $last_item.hasClass('dir') ? selectThis($last_item) : $last_item.find('a').click(); } else { $prev_item.hasClass('dir') ? selectThis($prev_item) : $prev_item.find('a').click(); } break; case 'ArrowDown': if ( (e.ctrl || e.metaKey) && $selected.hasClass('app') && $settings.apps_as_dirs === false ) { return; } else if ( $('*[contentEditable="true"').is(':focus') ) { return; } else if ( (e.ctrl || e.metaKey) && $selected.hasClass('dir') ) { window.location = $selected_href; break; } e.preventDefault(); if ( $last_item.hasClass('selected') || $selected.length < 1 ) { $first_item.hasClass('dir') ? selectThis($first_item) : $first_item.find('a').click(); } else { $next_item.hasClass('dir') ? selectThis($next_item) : $next_item.find('a').click(); } break; case 'ArrowLeft': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $('*[contentEditable="true"').is(':focus') ) { return; } // Navigate Grid or Images if ( $selected.length < 1 ) { $last_image.length ? navigateToThis($last_image) : navigateToThis($last_font); } else if ( $first_image.hasClass('selected') || $selected.length < 1 ) { $last_font.length ? navigateToThis($last_font) : navigateToThis($last_image); } else if ( $first_font.hasClass('selected') || $selected.length < 1 ) { $last_image.length ? navigateToThis($last_image) : navigateToThis($last_font); } else if ( $selected.hasClass('img') && $prev_image.length ) { navigateToThis($prev_image); } else { navigateToThis($prev_font); } break; case 'ArrowRight': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $('*[contentEditable="true"').is(':focus') || $selected.hasClass('dir ignore') ) { return; } // Navigate Grid or Images if ( $selected.hasClass('dir') ) { window.location = $selected_href; // Open directory } if ( $selected.length < 1 ) { $first_image.length ? navigateToThis($first_image) : navigateToThis($first_font); } else if ( $last_image.hasClass('selected') || $selected.length < 1 ) { $first_font.length ? navigateToThis($first_font) : navigateToThis($first_image); } else if ( $last_font.hasClass('selected') || $selected.length < 1 ) { $first_image.length ? navigateToThis($first_image) : navigateToThis($first_font); } else if ( $selected.hasClass('img') && $next_image.length ) { navigateToThis($next_image); } else { navigateToThis($next_font); } break; case 'Enter': // Open directories (or ignore) if ( $selected.hasClass('app') && $settings.apps_as_dirs === false ) { break; } else { $selected.find('a').click(); } break; case 'd': // Toggle Invisibles with Command-i if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $details_btn.click(); } break; case 'g': // Show image Grid if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $grid_btn.click(); } 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 'o': // Cmd/Ctrl + Shift + O: Open selected item in new window if ( (navigator.platform.match("Mac") ? e.metaKey && e.shiftKey : e.ctrlKey && e.shiftKey ) ) { window.open($selected_href); } break; case 'r': // Cmd/Ctrl + Shift + O: Open selected item in new window if ( $content_pane.is('[class*="has_"]') ) { e.preventDefault(); $content_reload_btn.click(); } else { return; } break; case 'w': // Close content pane if Close button visible with Command-w // Doesn't work in Firefox: can't override default keybinding if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && ($content_pane.is('[class*="has_"]')) ) { e.preventDefault(); e.stopPropagation(); $content_close_btn.click(); } break; case '.': // Increase font preview size if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.shiftKey ) { $('#increase').click(); } break; case ',': // Dencrease font preview size if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.shiftKey ) { $('#decrease').click(); } break; case 'tab': break; } // end switch }); // ***** END KEYBOARD EVENTS ***** // // ***** IMAGE NAVIGATION ***** // $prev_btn.on( 'click', function(event) { e = $.Event("keydown"); e.key = 'ArrowLeft'; $dir_table.trigger(e); }); $next_btn.on( 'click', function(event) { e = $.Event("keydown"); e.key = 'ArrowRight'; $dir_table.trigger(e); }); // Zoom Images $content_image.find('img').on('click',function() { $(this).toggleClass('zoom_img'); }); // ***** GRIDS ***** // var $this_ext; var $font_family; var imageGridItems = function() { var $image_grid_items_arr = []; $dir_table_row.filter('.img').each(function() { $this_link = $(this).find('a').attr('href'); $this_ext = $this_link.toLowerCase().slice($this_link.lastIndexOf('.')); if ( $.inArray( $this_ext, $image_ext_arr ) != -1 ) { // if this row file ext is in the image extension array $image_grid_item_el.find('a').attr('href',$this_link).find('img').attr('src',$this_link); $image_grid_items_arr.push( $image_grid_item_el.clone() ); } }); return $image_grid_items_arr; }; var fontGridItems = function() { var $font_grid_items_arr = []; $dir_table_row.filter('.font').each(function() { $this_link = $(this).find('a').attr('href'); $font_family = $(this).find('.name').text(); addCustomStyle( $font_family, $this_link ); $font_grid_item_el.attr('href',$this_link).css({ 'font-family':'"'+ $font_family +'"' }).empty().append( $font_family.slice( 0,$font_family.lastIndexOf('.') ) ); $font_grid_items_arr.push($font_grid_item_el.clone()); }); return $font_grid_items_arr; }; // Grid Button Click function showGrid() { $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); if ( $dir_table.hasClass('has_images') && ( $dir_table.hasClass('has_fonts') ) ) { $content_grid.empty().append( imageGridItems() ).append( fontGridItems() ); $content_grid.removeClass().addClass('has_grid'); } else if ( $dir_table.hasClass('has_images') ) { $content_grid.empty().append( imageGridItems() ); $content_grid.removeClass().addClass('has_image_grid'); } else { $content_grid.empty().append( fontGridItems() ); $content_grid.removeClass().addClass('has_font_grid'); } setContentTitle(); setContentHeight(); } $grid_btn.on('click', showGrid ); $('#show_image_grid').on('click',function(e) { e.stopPropagation(); $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); $content_grid.empty().append( imageGridItems() ); $content_grid.removeClass().addClass('has_image_grid'); setContentTitle(); setContentHeight(); }); $('#show_font_grid').on('click',function(e) { e.stopPropagation(); $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); $content_grid.empty().append( fontGridItems() ); $content_grid.removeClass().addClass('has_font_grid'); setContentTitle(); setContentHeight(); }); // GRID ITEMS var thisGridItemLink = function(el) { $this_link = el.find('a').attr('href') ? el.find('a').attr('href') : el.attr('href'); return $this_link; }; // Grid Item Hover $content_grid.on('mouseenter','> div:not(".selected")',function() { $dir_table.find('a[href="' + thisGridItemLink($(this)) + '"]').addClass('hovered'); }).on('mouseleave','> div:not(".selected")',function() { $dir_table.find('a[href="' + thisGridItemLink($(this)) + '"]').removeClass('hovered'); }); // Grid Item Click $content_grid.on('click','> div[class*="item"]',function(e) { e.preventDefault(); $dir_table.find('a[href="' + thisGridItemLink($(this)) + '"]').click(); }); // ***** FONT PREVIEWS ***** // var $em = parseFloat(getComputedStyle(document.body).fontSize); // pts/em $('#font_size').on('click','span',function() { if ( $(this).attr('id') === 'increase' ) { if ( $content_pane.is('.has_grid_content.has_font_content') ) { $content_grid.css({'font-size':(parseFloat($content_grid.css('font-size'))/$em * 1.125) +'em'}); return; } if ( $content_pane.is('.has_hidden_grid.has_font_content') ) { $content_font.css({'font-size':(parseFloat($content_font.css('font-size'))/$em * 1.125) +'em'}); return; } if ( $('#content_pane.has_font_content').length ) { $content_font.css({'font-size':(parseFloat($content_font.css('font-size'))/$em * 1.125) +'em'}); return; } } if ( $(this).attr('id') === 'decrease' ) { if ( $content_pane.is('.has_grid_content.has_font_content') ) { $content_grid.css({'font-size':(parseFloat($content_grid.css('font-size'))/$em * 8)/9 +'em'}); return; } if ( $content_pane.is('.has_hidden_grid.has_font_content') ) { $content_font.css({'font-size':(parseFloat($content_font.css('font-size'))/$em * 8)/9 +'em'}); return; } if ( $('#content_pane.has_font_content #content_font').length ) { $content_font.css({'font-size':(parseFloat($content_font.css('font-size'))/$em * 8)/9 +'em'}); return; } } }); // ***** END FONT PREVIEWS ***** // // 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'}); } 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'); }); }); })();