// ==UserScript== // @name Supercharged Local Directory File Browser // @version 2.7.1 // @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 (Michael Schrauzer) mshroud@gmail.com // @license GPL-3.0-or-later // @homepageURL https://openuserjs.org/scripts/gaspar_schot/Supercharged_Local_Directory_File_Browser // @contributionURL https://paypal.me/mschrauzer // @include file://*/ // @include file://*/?* // @require http://code.jquery.com/jquery-latest.min.js // NOTE: 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 been minimally tested on Windows and not at all on other OSes. It should work, but please report any issues. // The script 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 Tampermonkey, go to Chrome extension page, and tick the 'Allow access to file URLs' checkbox at the Tampermonkey extension section. // For Greasemonkey, open about:config and change greasemonkey.fileIsGreaseable to true. // @namespace https://greasyfork.org/users/16170 // @downloadURL none // ==/UserScript== (function() { 'use strict'; var $ = jQuery; // ***** USER SETTINGS ***** // const $settings = { // Paste your exported settings between the two lines below: //--------------------------------------------------------// shortcuts: // N.B.: Directory links must end with "/", file links must not. // You may add as many menus and links as you like; just copy the example below and edit as needed. // Local directory shortcuts must begin with "file:///"; external shortcuts must begin with the correct protocol ("http://" or "ftp://", etc.). // Note that because of same-origin security concerns, the browser will not allow you to navigate from an external webpage to a local directory. // But see this page for possible workarounds: https://stackoverflow.com/questions/39007243/cannot-open-local-file-chrome-not-allowed-to-load-local-resource [ { "menu_title":"My Sample Menu", "links": [ { "link_name":"My Directory Link 1", "link":"file:///Path/To/My/Directory/" }, { "link_name":"My Directory Link 2", "link":"file:///Path/To/My/Directory_2/" }, { "link_name":"My External Link", "link":"https://www.mywebpage.com/" }, { "link_name":"My File Link", "link":"file:///Path/To/My/File.ext" }, ] }, ], UI_font: // Choose an installed font for the UI. 'lucidagrande', UI_font_size: // Choose a default UI font size; use any standard CSS units. '13px', alternate_background: // If true (default false), alternate sidebar row background color. false, ignore_files: // If true (default), 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, hide_ignored_files: // If true, ignored files will be completely hidden from the file list; // If false (default), ignored files will appear greyed-out. false, hide_invisibles: // Un*x/Mac OS only: If true (default), files or directories beginning with a "." will be hidden. true, hide_details: // If true (default), hide file and directory details; if false, show them. true, default_sort: // Choose from: 'name', 'size', 'date', 'kind', 'ext', 'default'. // default = Chrome sorting: dirs on top, files alphabetical. 'default', dirs_on_top: // If true, directories will always be listed firs except when sorting by "name" (since otherwise sorting by "name" would equal "default"). // If false (default), directories and files will be sorted together. (In practice, dirs will typically still be separated when sorting by size, kind, and extension.) false, apps_as_dirs: // Un*x/Mac OS only: if true, treat apps as directories; allows app contents to be browsed. This is the default behavior for Chrome. // If false (default), treat apps as ignored files. false, dark_theme: // If true (default: false), gives the content pane a dark background, and inverts html and text content. false, grid_image_size: // Default = 150 150, grid_font_size: // Default = 1 1, autoload_index_files: // If true (default: false), automatically select first "index.ext" file found in directory. false, autoload_audio: // If true, the first audio file found in a directory will be automatically selected and loaded for playback. // If true, use left/right arrows to select audio files, use up/down arrows to select non-audio files (including video) only. // If false (default), audio files will be treated like any other file for navigation purposes (i.e., up and down arrows will select them too). // Note: if false, using up/down arrows will automatically begin playback of selected audio files; left/right arrows will select audio files without playing them. false, use_custom_icons: // if true (default), use custom icons for dirs and files // if false, use browser/server default icons true //--------------------------------------------------------// // Paste your exported settings between the above two lines. }; // ***** END USER SETTINGS ***** // // KEYBINDINGS: // Arrow Up/Down: Navigate up and down directory items // Cmd/Ctrl + Arrow Up: Go to parent directory // Arrow Left/Right: Navigate to prev/next image, font, or audio file, skipping other files, when files of these types are selected. // Opt/Alt + Arrow Left/Right: Skip audio ±10s // Shift + Opt/Alt + Arrow Left/Right: Skip audio ±30s // Arrow Right: Open selected directory. // Space: Pause/Play audio // Return: Open selected directory. // Cmd/Ctrl + D: Toggle file details (size, date modified) in some index page types. // Cmd/Ctrl + G: Show or Reset Grids // Cmd/Ctrl + I: Toggle Invisibles // Cmd/Ctrl + Shift + O: Open selected item in new window/tab // Cmd/Ctrl + R: Reload previewed content, reset scaled images/fonts. // Cmd/Ctrl + W: Close previewed content (not available in Firefox), or close window if no content is being previewed. // Cmd/Ctrl + Shift + : Scale preview items and grids. // CHANGELOG HISTORY: //• 2.7.1 // Added: User settings to choose default UI font-family and UI font-size. // Added: User setting and menu item to alternate sidebar row background color. // Improved: Directory preview styling: alternating row background, font-family and font-size honor user UI settings. // Internal: Completely reorganized CSS by properties instead of selectors. There may be lingering glitches; let me know if you find any. //• 2.7.0: New features and user settings. Please export your user_settings before updating and note the changes mentioned below. //• NEW (and experimental): Display a standard index of the selected sidebar directory in the preview pane. // This is very handy for browsing directories from the sidebar. // Clicking files and directories directly in the preview pane works as you'd expect, but it can be a little weird, // since you can navigate up and down the directory structure in the preview pane independently from the sidebar. //• NEW: Added URL query strings to remember directory selection history and various temporary UI settings between directory changes: // sort order, show/hide details, default/dark mode, sidebar width, and previously selected directory. //• NEW: Select files and directories by typed string. //• Improved: Converted user shortcut settings to JSON for greater flexibility. // Now you can create and name your own shortcut menu categories. // IMPORTANT: You must re-enter your old shortcuts in the new settings format. //• Added: Menu item to reset/delete query strings and return to the default user_settings in the script. //• Added: New user setting to show/hide details by default. (Don't know why it took so long to add this.) //• Added: User customizable file kinds for sorting. // You may add or remove file kind categories and file extensions to suit your own files: // See "$row_types" in code below, at the beginning of "General Setup" and just after the Changelog, to add your own. //• Removed "ignore_file_types" from the user_settings, because the list of ignored file extensions has been moved: // See "$row_settings" in code below, at the beginning of "General Setup" and just after the Changelog, to add your own. //• Removed "user_name" from the user_settings, because it is no longer needed. //• Improved: File shortcuts work much more reliably now, and thanks to query strings, you can now bookmark more than one file in a directory. //• Improved: Various small UI changes. //• Fixed: Toggle sidebar wasn't working. //• Fixed: Ignored files weren't being sorted. //• Internals: Abstracted a bunch of functions, removed some unneeded variables and functions. More to be done. //• If you like this script, please consider making a donation. See the "Donate" menu item. Thanks! //• 2.6.5 //• Fixed: First and last audio files would repeat when ended instead of going to next track in some circumstances. //• Fixed: Various issues with file navigation. //• 2.6.4 //• Added: Nice custom icons for dirs and various file types. Other minor UI tweaks. //• Added: New user setting to use default file icons instead the new custom ones, in case you don't like them. //• Added: Separate close button for audio player, since there was no way to close it while leaving other previewed content open. //• Fixed: Really, really fixed reload button and reload shortcut not working (I hope). //• Fixed: Yet more issues with arrow navigation. //• Fixed: Various UI issues with Firefox. //• Improved: Sidebar resizing should be more reliable (drag event was interacting with sidebar). //• Other: Abstracted some styles and cleaned up code. //• Many other bug fixes. //• 2.6.3: Minor UI improvements and bugfixes. //• Changed: Open dirs on double-click. (You can still open them by selecting and pressing "Return" or the Right Arrow Key.) //• Changed: Removed autoplay_audio preference. //• Fixed: Reload button and reload shortcut weren't working correctly. //• Fixed: Clicking audio file name didn't pause/play file. //• Fixed: Sidebar height didn't reset when changing sort order. //• Fixed: Directories with a "." in the name were being sorted as if the trailing text was an extension. //• Fixed: Corrected some code that prevented the script from working in Safari; while Safari still doesn't allow local directories to be browsed, the script will work on server-generated pages. //• Other: Removed some unneeded styles and functions, simplified arrow navigation code. //• 2.6.2: Fixes for a few more pesky bugs. Just when you think you're safe.... Apologies. //• Fixed: Reload and Close buttons and keyboard combinations now work for audio files. //• Fixed: Preview pane titlebar wasn't showing in some circumstances. //• 2.6.1: Hopefully fixed a bug when navigating folders containing audio files. Sorry about that! //• 2.6.0: Sorting, new user settings, and much more! This is a pretty substantial update. //• Added: Donate link (paypal.me/mschrauzer) to the main shortcuts menu. If you like this script, please support its development. Thank you! //• Added: Support for additional common server-generated index types. The script should now work on index pages structured as unordered lists, "
" text, and html tables.
    //• Added: Sorting by name, size, date modified, kind, file extension, and default Chrome sorting (i.e., dirs on top, files alphabetical).
       //• Click the "Details" button (or Cmd/Ctrl + D) to show the available sort options.
       //• Note: Some server configurations don't provide size or date information; on such sites, these sorting options will not be available.
       //• Note: Sorting by kind is based on the file extension, so it is rather coarse (at least for now); many non-image/audio/pdf files will simply be categorized as generic "Files".
    //• Added: Added "Sort by..." menu item in the main shortcuts menu.
    //• Added: New User Settings (gives you control over some behavior added in the last update):
              //• default_sort: Choose default sort method: by name, size, date, kind, extension, or Chrome default (dirs on top, files alphabetical).
              //• dirs_on_top: Choose whether directories should be sorted separately from files.
              //• autoload_index_files: If true (default false), autoload first index.[ext] file found in directory.
              //• autoload_audio:
                 //• If false (default), treat audio files like other files for navigation purposes. Use up and down arrows as normal, only show audio controls when an audio file is selected.
                 //• (Note that when false, only one file in the directory at a time can be selected.)
                 //• If true, autoload first audio file in directory (and cover art, if any) and navigate audio with left and right arrows, other files with up and down arrows. This was the previous behavior of the script.
    //• Added: Alert reminder to add your computer user account name to the settings.
    //• Enhancement: UI: Added flyout submenus to main shortcuts menu.
    //• Enhancement: Added .aiff, .ape, .m4a to recognized audio format types.
    //• Enhancement: Added .svg to recognized image format types (they now are shown in an  element instead of an ');
    const $content_media =      $('');
    const $prev_track =         $('
'); const $next_track = $('
'); const $audio = $(''); const $loop = $(''); const $shuffle = $(''); const $close_audio = $('
'); const $checkbox_cont = $('
'); const $content_reload_btn = $(''); const $content_title = $(''); const $content_close_btn = $(''); const $content_header = $('
'); const $prev_btn = $('
'); const $next_btn = $('
'); const $content_container = $('
'); const $content_pane = $(''); // SVG UI ICONS const $svg_prefix = 'url("data:image/svg+xml;utf8,")'; const $up_arrow_inv = $svg_prefix + 'width=\'12.728px\' height=\'7.779px\' viewBox=\'0 0 12.728 7.779\' enable-background=\'new 0 0 12.728 7.779\' xml:space=\'preserve\'>")'; const $svg_arrow = $svg_prefix + 'width=\'11px\' height=\'16px\' viewBox=\'234.5 248 11 16\' enable-background=\'new 234.5 248 11 16\' xml:space=\'preserve\'>")'; const $toggle = $svg_prefix + 'width=\'13.779px\' height=\'12.729px\' viewBox=\'2.474 -2.475 13.779 12.729\' enable-background=\'new 2.474 -2.475 13.779 12.729\' xml:space=\'preserve\'> ")'; const $check_mark = $svg_prefix + 'width=\'17px\' height=\'14px\' viewBox=\'250.182 490.01 17 14\' enable-background=\'new 250.182 490.01 16.971 14.143\' xml:space=\'preserve\'>")'; const $check_mark_inv = $svg_prefix + 'width=\'17px\' height=\'14px\' viewBox=\'250.182 490.01 17 14\' enable-background=\'new 250.182 490.01 16.971 14.143\' xml:space=\'preserve\'>")'; const $menu_arrow = $svg_prefix + 'width=\'24px\' height=\'16px\' viewBox=\'0 0 24 16\' enable-background=\'new 0 0 24 16\' xml:space=\'preserve\'> ")'; const $menu_arrow_inv = $svg_prefix + 'width=\'24px\' height=\'16px\' viewBox=\'0 0 24 16\' enable-background=\'new 0 0 24 16\' xml:space=\'preserve\'> ")'; const $menu_icon = $svg_prefix + 'width=\'13px\' height=\'10px\' viewBox=\'0 0 13 10\' enable-background=\'new 0 0 13 10\' xml:space=\'preserve\'>")'; const $grid_icon = $svg_prefix + 'width=\'16px\' height=\'16px\' viewBox=\'0 0 16 16\' enable-background=\'new 0 0 16 16\' xml:space=\'preserve\'>")'; const $plus_sign = $svg_prefix + 'width=\'16px\' height=\'16px\' viewBox=\'0 0 16 16\' xml:space=\'preserve\'>")'; const $minus_sign = $svg_prefix + 'width=\'16px\' height=\'16px\' viewBox=\'0 0 16 16\' xml:space=\'preserve\'> ")'; const $next_track_arrow = $svg_prefix + 'width=\'12.8px\' height=\'14px\' viewBox=\'-2 0 12.8 14\' enable-background=\'new -2 0 12.8 14\' xml:space=\'preserve\'>")'; const $next_track_arrow_gecko = $svg_prefix + 'width=\'12.8px\' height=\'14px\' viewBox=\'-2 0 12.8 14\' enable-background=\'new -2 0 12.8 14\' xml:space=\'preserve\'>")'; const $next_track_arrow_gecko_hover = $svg_prefix + 'width=\'12.8px\' height=\'14px\' viewBox=\'-2 0 12.8 14\' enable-background=\'new -2 0 12.8 14\' xml:space=\'preserve\'>")'; const $music = $svg_prefix + 'width=\'143.717px\' height=\'199.404px\' viewBox=\'0 0 143.717 199.404\' enable-background=\'new 0 0 143.717 199.404\' xml:space=\'preserve\'> ")'; //SVG FILE ICONS // Chrome default icons const $file_icon_dir_default = '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= ")'; const $file_icon_file_default = 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABHUlEQVR42o2RMW7DIBiF3498iHRJD5JKHurL+CRVBp+i2T16tTynF2gO0KSb5ZrBBl4HHDBuK/WXACH4eO9/CAAAbdvijzLGNE1TVZXfZuHg6XCAQESAZXbOKaXO57eiKG6ft9PrKQIkCQqFoIiQFBGlFIB5nvM8t9aOX2Nd18oDzjnPgCDpn/BH4zh2XZdlWVmWiUK4IgCBoFMUz9eP6zRN75cLgEQhcmTQIbl72O0f9865qLAAsURAAgKBJKEtgLXWvyjLuFsThCSstb8rBCaAQhDYWgIZ7myM+TUBjDHrHlZcbMYYk34cN0YSLcgS+wL0fe9TXDMbY33fR2AYBvyQ8L0Gk8MwREBrTfKe4TpTzwhArXWi8HI84h/1DfwI5mhxJamFAAAAAElFTkSuQmCC ")'; // Custom file icons const $svg_icon_prefix = 'url("data:image/svg+xml;utf8, '; const $file_icon_dir = $svg_icon_prefix + ' ")'; const $file_icon_dir_invisible = $svg_icon_prefix + ' ")'; const $file_icon_app = $svg_icon_prefix + ' ")'; const $file_icon_file = $svg_icon_prefix + ' ")'; const $file_icon_text = $svg_icon_prefix + ' ")'; const $file_icon_image = $svg_icon_prefix + ' ")'; const $file_icon_pdf = $svg_icon_prefix + ' ")'; const $file_icon_font = $svg_icon_prefix + '")'; const $file_icon_code = $svg_icon_prefix + ' ")'; const $file_icon_html = $svg_icon_prefix + ' ")'; const $file_icon_ignored = $svg_icon_prefix + '")'; const $file_icon_invisible = $svg_icon_prefix + ' ")'; // const $file_icon_video = 'url("data:image/svg+xml;utf8,")'; // const $file_icon_audio = 'url("data:image/svg+xml;utf8,")'; // const $file_icon_archive = 'url("data:image/svg+xml;utf8,")'; function assembleUIElements() { // setParentLink(); $parents_dir_menu.find('div').append( $current_dir_path ); $sidebar_header.find('thead th').append($toggle_sidebar); $sidebar_header.find('tbody tr').first().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 ); $dir_list.append($dir_list_head, $dir_list_body); $sidebar.append($sidebar_header, $dir_list); $sidebar_wrapper.append( $sidebar, $sidebar_overlay, $handle ); $content_image.append( $image ); $checkbox_cont.append( $loop, $shuffle ); $content_media.append( $prev_track, $next_track, $audio, $checkbox_cont, $close_audio ); $content_font.append( $specimen ); $content_header.find('tr').first().append( $content_reload_btn, $content_title, $content_close_btn ); $content_header.find('tr').last().append( $content_media ); $content_container.append( $content_header, $content_scale, $content_overlay, $content_grid, $content_image, $content_embed, $content_iframe, $content_font ); $content_pane.append( $content_container, $prev_btn, $next_btn ); } assembleUIElements(); // ***** STYLES ***** // // DEFINE STYLES var $styles = ''; // margin $styles += 'html, body, :root, #sidebar ul, #parent_dir_menu, #parent_dir_menu, #parents_dir_menu, #parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span, #shortcuts_menu, #grid_btn, #dir_list tbody a' + '{ margin: 0; }'; // margin-top $styles += '#checkbox_div label input, #details_btn' + '{ margin-top: 0; }'; $styles += 'body.has_audio #dir_list input' + '{ margin-top: 1px; }'; $styles += '.lorem.first' + '{ margin-top: 0.5em; }'; // margin-right $styles += '#dir_list thead th.checked' + '{ margin-right: 0; }'; $styles += 'body.has_audio #dir_list input' + '{ margin-right: 8px; }'; $styles += '#details_btn' + '{ margin-right: 0.5em; }'; $styles += '#dir_list thead th:last-of-type' + '{ margin-right: 1em; }'; // margin-bottom $styles += '#details_btn' + '{ margin-bottom: 0; }'; $styles += 'body.has_audio #dir_list input' + '{ margin-bottom: 1px; }'; $styles += '.lorem' + '{ margin-bottom: 1em; }'; $styles += '.lorem + .lorem + .lorem' + '{ margin-bottom: 2em; }'; // margin-left $styles += '#dir_list thead th.checked' + '{ margin-left: 0; }'; $styles += 'body.has_hidden_sidebar #reload_btn' + '{ margin-left: 16pt; }'; $styles += '#details_btn' + '{ margin-left: 0.5em; }'; $styles += '#dir_list tbody tr' + '{ margin-inline-start:0; }'; // padding $styles += 'html, body, :root, #sidebar_wrapper, #sidebar ul, #parent_dir_menu, #sidebar_header tbody tr td, #parent_dir_menu, #parent_dir_menu a, #parents_dir_menu, #shortcuts_menu, #dir_list .details a, #content_pane, #content_embed, #content_iframe' + '{ padding: 0; }'; $styles += '#sidebar_header thead th' + '{ padding: 4px; }'; $styles += '#content_media' + '{ padding: 6px; }'; // padding-top $styles += '#dir_list thead th, #dir_list .details, #content_grid .font_grid_item, #prev_track, #next_track' + '{ padding-top: 0; }'; $styles += '#details_btn, #prev_btn, #next_btn' + '{ padding-top: 2px; }'; $styles += '#parents_dir_menu div, #grid_btn .menu li, #dir_list tbody a, #content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type, #content_title' + '{ padding-top: 4px; }'; $styles += '#sidebar_header tbody tr:last-of-type td, #parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span' + '{ padding-top: 6px; }'; $styles += '#content_header table' + '{ padding-top: 7px; }'; $styles += '#content_grid .font_grid_item:first-of-type, #content_image, #content_font' + '{ padding-top: 2rem; }'; // padding-bottom $styles += '#sidebar_header tbody tr:last-of-type td, #dir_list .details, #prev_track, #next_track' + '{ padding-right: 0; }'; $styles += '#parents_dir_menu div, #details_btn, #grid_btn .menu li, #dir_list tbody a, #content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type' + '{ padding-right: 6px; }'; $styles += '#parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span' + '{ padding-right: 8px; }'; $styles += '#dir_list tbody tr, #content_header table, #content_title, #prev_btn, #next_btn' + '{ padding-right: 12px; }'; $styles += '#grid_btn .menu, #dir_list thead th' + '{ padding-right: 29px; }'; $styles += '#content_grid .font_grid_item, #content_image, #content_font' + '{ padding-right: 2.5rem; }'; // padding-bottom $styles += '#prev_track, #next_track, #prev_btn, #next_btn' + '{ padding-bottom: 0px }'; $styles += '#details_btn, body.is_dirs_on_top #dir_list tbody tr.sorted:not(:last-of-type)' + '{ padding-bottom: 2px; }'; $styles += '#content_title' + '{ padding-bottom: 3px;}'; $styles += '#parents_dir_menu div, #grid_btn .menu li, #dir_list tbody a, #dir_list .details' + '{ padding-bottom: 4px; }'; $styles += '.specimen' + '{ padding-bottom: 0.25em; }'; $styles += '#content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type' + '{ padding-bottom: 3px; }'; $styles += '#content_header table' + '{ padding-bottom: 5px; }'; $styles += '#sidebar_header tbody tr:last-of-type td, #parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span, #dir_list thead th' + '{ padding-bottom: 6px; }'; $styles += '#dir_list thead th.details' + '{ padding-bottom: 9px; }'; $styles += '#content_grid .font_grid_item' + '{ padding-bottom: 0.5rem; }'; $styles += '#content_grid.has_image_grid' + '{ padding-bottom: 1rem; }'; $styles += '#content_grid .font_grid_item:last-of-type, #content_image, #content_font' + '{ padding-bottom: 2rem; }'; // padding-left $styles += '#grid_btn .menu, #sidebar_header tbody tr:last-of-type td' + '{ padding-left: 0; }'; $styles += '#dir_list .audio a, #dir_list .video a' + '{ padding-left: 4px; }'; $styles += '#dir_list td.icon, #dir_list .icon + td.name a, #checkbox_div #parents_dir_menu div, #details_btn, #grid_btn .menu li, #content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type' + '{ padding-left: 6px; }'; $styles += '#parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span' + '{ padding-left: 8px; }'; $styles += '#content_header table, #content_title, #prev_btn, #next_btn' + '{ padding-left: 12px; }'; $styles += '#dir_list thead th, #dir_list .details' + '{ padding-left: 24px; }'; $styles += '#dir_list tbody a' + '{ padding-left: 26px; -webkit-padding-start:2em; }'; $styles += '#sort_menu li span, #dir_list thead .name, #default' + '{ padding-left: 2em; }'; $styles += '#content_grid .font_grid_item, #content_image, #content_font' + '{ padding-left: 2.5rem; }'; // -webkit-margin & -webkit-padding $styles += '#sidebar ul' + '{ -webkit-margin-before:0em !important; -webkit-margin-after:0em !important; -webkit-padding-start:0em; }'; $styles += '#dir_list .icon + td.name a' + '{ -webkit-padding-start:1em; }'; // width $styles += 'html, body, :root, table, #sidebar_header tbody tr:first-of-type td:nth-of-type(even), #parent_dir_menu a, #dir_list thead, #dir_list tbody, #shortcuts_menu + ul > li > ul, #grid_btn .menu li, body.has_hidden_sidebar #content_pane, #content_container, #content_header, #content_embed, #content_iframe' + '{ width: 100%; }'; $styles += '#content_grid, #content_grid div img, #content_image img:not(.zoom_img)' + '{ width: auto; }'; $styles += '#handle' + '{ width: 8px; }'; $styles += '#close_audio' + '{ width: 14px; }'; $styles += '#toggle_sidebar' + '{ width: 16px; }'; $styles += 'body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ width: 20px; }'; $styles += '#sidebar_header tbody tr:first-of-type td:nth-of-type(odd)' + '{ width: 24px; }'; $styles += '#grid_btn' + '{ width: 28px; }'; $styles += '#dir_list thead th.checked:after, #prev_track, #next_track, #scale span' + '{ width: 2rem; }'; $styles += '#shortcuts_menu div, #content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type' + '{ width: 6em; }'; $styles += 'body.has_hidden_sidebar #sidebar_wrapper' + '{ width: 0; }'; $styles += '#sidebar_wrapper' + '{ width:'+ $UI_pref_width +'%; }'; $styles += '#content_pane' + '{ width:'+ (100 - $UI_pref_width).toString() +'%; }'; $styles += '#content_grid .image_grid_item' + '{ width:'+ $grid_image_size +'px; }'; $styles += '#content_grid .font_grid_item' + '{ width:calc(100% - 5rem); }'; // max-width $styles += 'html, body, :root, #content_image img:not(.zoom_img)' + '{ max-width: 100%; }'; $styles += '#content_image img.zoom_img' + '{ max-width: none; }'; $styles += '#sidebar_header tbody tr:first-of-type td:nth-of-type(odd)' + '{ max-width: 24px; }'; $styles += '#content_grid div img' + '{ max-width:'+ ($grid_image_size - $grid_image_size/8) +'px; }'; // min-width $styles += '#sidebar_header tbody tr:first-of-type td:nth-of-type(odd)' + '{ min-width: 24px; }'; $styles += '#dir_list' + '{ min-width: 100px; }'; $styles += '#sidebar_wrapper' + '{ min-width: 220px; }'; // height $styles += 'html, body, :root, #parent_dir_menu a, #content_container, #main_content, #content_embed, #content_iframe' + '{ height: 100%; }'; $styles += '#sidebar_header, #parents_dir_menu, #parents_dir_menu div, #content_grid div img, #content_image img:not(.zoom_img)' + '{ height: auto; }'; $styles += '#dir_list thead th.checked:after' + '{ height: 8px; }'; $styles += '#toggle_sidebar, #close_audio' + '{ height: 14px; }'; $styles += '#dir_list td.icon' + '{ height: 16px; }'; $styles += '#grid_btn, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ height: 18px; }'; $styles += 'body.dark_theme #dir_list thead th.checked:after' + '{ height: 1em; }'; $styles += '#prev_track, #next_track, #scale span' + '{ height: 2rem; }'; $styles += '#content_grid .image_grid_item' + '{ height:'+ $grid_image_size +'px; }'; $styles += '#sidebar' + '{ height:'+ window.innerHeight +'px; }'; $styles += '#sidebar_overlay, #content_overlay' + '{ height:'+ window.innerHeight + 'px; }'; // max-height $styles += '#content_image img.zoom_img' + '{ max-height: none; }'; $styles += '#content_grid div img' + '{ max-height:'+ ($grid_image_size - $grid_image_size/8) +'px; }'; $styles += '#content_image img:not(.zoom_img)' + '{ max-height:calc(100% - 3px); }'; // min-height $styles += '#sidebar' + '{ min-height: 100%; }'; // border $styles += '#sidebar_wrapper, #sidebar_header, #dir_list, #main_content, #content_pane, #content_embed, #content_iframe' + '{ border: 0; }'; $styles += '#close_audio, body.dark_theme ul' + '{ border: solid 1px #222; }'; $styles += '#details_btn' + '{ border: solid 1px #333; }'; $styles += 'body.default_theme #sidebar ul' + '{ border: solid 1px gray; }'; // border-top $styles += 'body.dark_theme #sidebar_header .menu, body.dark_theme #sidebar #grid_btn ul.menu' + '{ border-top:solid 1px #111; }'; $styles += 'body.dark_theme #dir_list #tbody' + '{ border-top:solid 1px #222; }'; $styles += 'body.dark_theme #content_header tr:last-of-type' + '{ border-top:solid 1px #333; }'; $styles += 'body.default_theme #dir_list tbody, #grid_btn .menu' + '{ border-top:solid 1px grey; }'; $styles += '#content_header tr:last-of-type' + '{ border-top:solid 1px #888; }'; $styles += '#sort_by, #donate' + // , tr.dir ~ tr:not(.dir,.invisible,.ignore) '{ border-top:solid 1px #999; }'; $styles += 'body.dark_theme.is_dirs_on_top #dir_list tbody tr.dir + tr.file' + '{ border-top:solid 1px #CCC; }'; // border-right $styles += '#parents_dir_menu + ul, #shortcuts_menu + ul, body.dark_theme #sidebar #grid_btn ul.menu' + '{ border-right:0 !important; }'; $styles += 'body.dark_theme #sidebar_header tbody tr:first-of-type td:nth-of-type(even), body.dark_theme #sidebar, body.dark_theme #sidebar #grid_btn .menu li' + '{ border-right:solid 1px #111; }'; $styles += '#sidebar, body.default_theme #sidebar_header tbody tr:first-of-type td:nth-of-type(even), #grid_btn .menu li' + '{ border-right:solid 1px grey; }'; // border-bottom $styles += 'body.dark_theme #sidebar_header thead tr, body.dark_theme #sidebar_header tbody tr:first-of-type' + '{ border-bottom:solid 1px black; }'; $styles += 'body.dark_theme #sidebar_header .menu, body.dark_theme #content_header, body.dark_theme #sidebar #grid_btn .menu li:first-of-type, body.dark_theme #sidebar #grid_btn ul.menu' + '{ border-bottom:solid 1px #111; }'; $styles += 'body.default_theme #sidebar_header thead tr, body.default_theme #sidebar_header tbody tr:first-of-type, #grid_btn .menu li:first-of-type, #grid_btn .menu, .specimen' + '{ border-bottom:solid 1px grey; }'; $styles += '#shortcuts_menu + ul > li.has_submenu.ruled, body.is_dirs_on_top #dir_list tbody tr.sorted:not(:last-of-type)' + '{ border-bottom:solid 1px #999; }'; $styles += 'body.default_theme #content_header' + '{ border-bottom:solid 1px #AAA; }'; $styles += 'body.dark_theme.is_dirs_on_top #dir_list tbody tr.sorted:not(:last-of-type), body.dark_theme #content_pane.has_font_content hr' + '{ border-bottom:solid 1px #CCC; }'; // border-left $styles += '#parents_dir_menu + ul, #shortcuts_menu + ul' + '{ border-left:0; }'; $styles += 'body.dark_theme #sidebar_header tbody tr:first-of-type td:nth-of-type(even), body.dark_theme #sidebar #grid_btn ul.menu' + '{ border-left:solid 1px #111; }'; $styles += 'body.default_theme #sidebar_header tbody tr:first-of-type td:nth-of-type(even), #grid_btn .menu' + '{ border-left:solid 1px grey; }'; // border-radius $styles += 'html, body, :root' + '{ border-radius: 0; }'; $styles += '#details_btn' + '{ border-radius: 3px; }'; $styles += '#close_audio' + '{ border-radius: 100%; }'; // outline $styles += '#grid_btn, #dir_list tbody, #dir_list tbody a, #content_grid .font_grid_item, #content_font' + '{ outline: none; }'; // background-color $styles += '#sidebar_wrapper, body.default_theme #sidebar, body.default_theme #sidebar ul, body.default_theme #content_header' + '{ background-color: lightgray }'; $styles += 'body.default_theme #dir_list .selected, body.default_theme #dir_list .selected.audio, body.default_theme #dir_list .playing' + '{ background-color: lightsteelblue; }'; $styles += 'body.dark_theme #dir_list .selected' + '{ background-color: slategray; }'; $styles += 'body.dark_theme #content_grid, #content_image, body.dark_theme #content_pane' + '{ background-color: #333; }'; $styles += 'body.dark_theme #sidebar ul, body.dark_theme #sidebar_header thead, body.dark_theme #sidebar_header tbody tr:first-of-type, body.dark_theme.alternate_background #dir_list tbody tr:nth-of-type(odd):not(.selected)' + '{ background-color: #444; }'; $styles += '#content_grid:not(.has_grid) .image_grid_item:hover, #content_grid:not(.has_grid) div.image_grid_item.hovered, body.dark_theme #sidebar, body.dark_theme #content_header, body.dark_theme #dir_list #tbody, body.dark_theme #grid_btn .menu li, body.dark_theme .font_grid_item:hover, body.dark_theme .font_grid_item.hovered, body.dark_theme .image_grid_item:hover, body.dark_theme .image_grid_item.hovered' + '{ background-color: #555; }'; $styles += '#content_grid:not(.has_grid) .image_grid_item.selected, body.dark_theme #sidebar ul li:hover, body.dark_theme #content_grid .font_grid_item.selected, body.dark_theme #content_grid .image_grid_item.selected' + '{ background-color: #666; }'; $styles += 'body.dark_theme #grid_btn .menu li:hover, body.dark_theme #dir_list tbody tr:hover, body.dark_theme #dir_list tbody li:hover, body.dark_theme.alternate_background #dir_list #tbody tr:hover, body.dark_theme #sidebar .hovered' + '{ background-color: #777; }'; $styles += 'body.default_theme #sidebar_header thead tr, body.default_theme #sidebar_header tbody tr:first-of-type, #parents_dir_menu + ul li:hover, #shortcuts_menu + ul li:not(.has_submenu):hover, #grid_btn.has_images.has_fonts:hover .menu li:hover, body.default_theme #dir_list tbody tr:hover, body.default_theme.alternate_background #dir_list #tbody tr:hover, body.default_theme #dir_list .hovered, body.default_theme.alternate_background #dir_list #tbody tr.hovered' + '{ background-color: #BBB; }'; $styles += 'body.default_theme #grid_btn .menu li, body.default_theme #content_grid div.selected, body.default_theme.alternate_background #dir_list tbody tr:nth-of-type(odd):not(.selected)' + '{ background-color: #CCC; }'; $styles += 'body.default_theme #content_grid div:hover, body.default_theme #content_grid div.hovered' + '{ background-color: #DDD; }'; $styles += 'body.default_theme #dir_list tbody' + '{ background-color: #DFDFDF; }'; $styles += 'body.default_theme #content_pane, #content_image img.zoom_img, #content_grid.has_font_grid, #content_grid.has_grid, #content_pane.has_file_content #content_iframe' + '{ background-color: #FFF; }'; $styles += '#scale' + '{ background-color: rgba(128,128,128,0.3); }'; $styles += 'body.is_chrome #audio' + '{ background-color: rgb(241, 243, 244); }'; $styles += 'body.dark_theme #dir_list .playing, body.dark_theme #dir_list .selected.audio' + '{ background-color: #4C7E80; }'; $styles += '#dir_list tbody tr, #dir_list .audio a, #dir_list .video a, body.has_audio #content_pane.has_ignored_content #content_image, body.dark_theme #grid_btn .menu, body #dir_list tr.file.audio a.icon, body #dir_list tr.file.video a.icon, body.use_custom_icons #dir_list tr.file.ignore a.icon' + '{ background-color: transparent; }'; // overflow $styles += '#content_container' + '{ overflow: visible; }'; $styles += 'html, body, :root, #parents_dir_menu div, #shortcuts_menu, #dir_list, #dir_list tbody a, #main_content' + '{ overflow: hidden; }'; $styles += '#content_font, #content_grid, #content_image' + '{ overflow: auto; }'; $styles += '#dir_list tbody' + '{ overflow-y: auto; }'; $styles += '#sidebar, #content_font' + '{ overflow-wrap: break-word; }'; $styles += '.lorem' + '{ overflow-wrap: normal; }'; // vertical-align $styles += '#dir_list .details' + '{ vertical-align: top }'; $styles += '#sidebar_header tbody tr:last-of-type td, #parent_dir_menu a, #parents_dir_menu div, #shortcuts_menu div, #content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type, #content_title, #content_grid .image_grid_item' + '{ vertical-align:middle; }'; // box-sizing $styles += 'html, body, :root, #sidebar, #grid_btn .menu li' + '{ box-sizing: border-box; }'; // box-shadow $styles += 'body.default_theme #sidebar ul' + '{ box-shadow: 0px 2px 3px -2px #888; }'; $styles += 'body.dark_theme #sidebar ul' + '{ box-shadow:0px 2px 3px -2px #111; }'; $styles += 'body.dark_theme #sidebar #grid_btn ul.menu' + '{ box-shadow:none; }'; // will-change $styles += '#sidebar_wrapper, #content_pane' + '{ will-change: width }'; // content $styles += '#dir_list thead th.checked:after, body.has_hidden_sidebar #handle, #dir_list thead th.checked:before, #dir_list thead td.icon, #dir_list tr:empty, #dir_list .audio td.icon, #dir_list .video td.icon, body.hide_invisibles .invisible, body.hide_ignored .ignore, #content_pane.has_ignored_content:before, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ content:"" }'; $styles += 'body.dark_theme #dir_list thead th.checked:after' + '{ content:" " }'; // DISPLAY & VISIBILITY // display $styles += '#sidebar tbody tr:first-of-type ul, #grid_btn ul.menu, #default_theme, #details_btn span:last-of-type, #grid_btn, #dir_list thead .name input, #dir_list .details, body.has_hidden_sidebar #handle, #dir_list thead th.checked:before, #dir_list thead td.icon, #dir_list tr:empty, #dir_list .audio td.icon, #dir_list .video td.icon, body.hide_invisibles .invisible, body.hide_ignored .ignore, #sidebar_overlay, #content_overlay, #content_header, #content_grid, #content_image, #content_image img[src="/"], #content_font, #content_embed, #content_iframe, #content_media, #next_btn, #prev_btn, #content_pane[class*="hidden"] #content_grid, body.dark_theme #dark_theme, body.use_custom_icons #dir_list img, #dir_list tr.file.audio a img, #dir_list tr.file.video a img' + '{ display: none; }'; $styles += '#sidebar li, #parent_dir_menu, #parent_dir_menu a, #parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span, #dark_theme, #dir_list thead .name, #default, #dir_list tbody .name, body.show_invisibles #dir_list tbody tr, body.hide_invisibles #dir_list tbody tr:not(.invisible), #dir_list tbody a, #shortcuts_menu + ul > li:hover > ul, #shortcuts_menu + ul > li > ul:hover, body.has_images.has_fonts #grid_btn:hover ul.menu, #content_pane[class*="content"] #content_header, body.is_playing #content_header, #content_grid .font_grid_item, #checkbox_div label, body.has_audio #content_pane:not(.has_image_content) #content_image, #content_pane.has_font_content:hover #scale, #content_pane.has_grid_content:hover #scale, #content_pane.has_image_content:hover #scale, #scale span, #content_pane.has_image_content #prev_btn, #content_pane.has_image_content #next_btn, #content_pane.has_font_content #prev_btn, #content_pane.has_font_content #next_btn, #content_pane.has_grid_content #prev_btn, #content_pane.has_grid_content #next_btn, #content_pane.has_font_content #content_font, #content_pane.has_image_content #content_image, #content_pane.has_pdf_content #content_embed, #content_pane.has_file_content #content_iframe, #content_grid.has_font_grid, #content_grid.has_grid, body.dark_theme #default_theme, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ display: block; }'; $styles += '#parents_dir_menu div, body.has_fonts #grid_btn, body.has_images #grid_btn, #dir_list thead th.checked:after, #dir_list.show_details .details:not(.ext), body.is_gecko #dir_list.show_details #tbody > tr > td:not(:first-of-type), body.has_audio #dir_list thead input, #content_grid .image_grid_item, #checkbox_div, #prev_track, #next_track, body.dark_theme #dir_list thead th.checked:after' + '{ display: inline-block; }'; $styles += '#shortcuts_menu div, body.has_audio.autoload_audio #content_media, body.is_playing #content_media, body.is_paused #content_media' + '{ display: table-cell; }'; $styles += '#content_grid.has_image_grid' + '{ display: grid; }'; $styles += '#content_grid { grid-gap:0; grid-template-columns:repeat(auto-fit, minmax('+ $grid_image_size +'px, 1fr)); grid-template-rows:repeat(auto, minmax('+ $grid_image_size +'px, 1fr)); }'; // opacity $styles += '#scale' + '{ opacity:0; }'; $styles += '#scale span:first-of-type, #scale span:last-of-type, #content_pane.has_ignored_content:before' + '{ opacity:0.3; }'; $styles += '#scale span:hover' + '{ opacity:0.5; }'; $styles += '#prev_btn, #next_btn' + '{ opacity:0.6; }'; $styles += '#sidebar_header tbody tr:first-of-type td:last-of-type:hover div, #shortcuts_menu div, #shortcuts_menu div, #parent_dir_menu, #prev_btn, #next_btn, #toggle_sidebar, #close_audio, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ opacity: 0.7; }'; $styles += '#content_grid div img' + '{ opacity:0.8; }'; $styles += '#grid_btn:hover, #parent_dir_menu:hover, #prev_btn:hover, #next_btn:hover, #toggle_sidebar:hover, #content_pane.has_font_content:hover #scale, #content_pane.has_grid_content:hover #scale, #content_pane.has_image_content:hover #scale' + '{ opacity:1; }'; // transform $styles += 'body.has_hidden_sidebar #toggle_sidebar, #dir_list thead th.checked:not(.up):after, #next_track, #next_btn' + '{ transform:rotate(180deg); }'; $styles += '#close_audio' + '{ transform:rotate(45deg); }'; $styles += '#content_grid div img, #content_image img:not(.zoom_img), .vert_center' + '{ transform:translateY(-50%); }'; $styles += '#content_image img.zoom_img' + '{ transform:translateY(0); }'; // transition $styles += '#scale' + '{ transition:opacity 1s ease-in-out; }'; // filter $styles += '#prev_btn, #next_btn' + '{ filter:invert(50%); }'; $styles += 'body.dark_theme #content_iframe, body.dark_theme #close_audio' + '{ filter:invert(87.5%); }'; $styles += '#scale span:hover, body.dark_theme #sidebar #grid_btn, body.dark_theme #grid_btn .menu, body.dark_theme #parent_dir_menu, body.dark_theme #shortcuts_menu, body.dark_theme #toggle_sidebar' + '{ filter:invert(100%); }'; // POSITION & LAYOUT // position $styles += '#sidebar_wrapper, #sidebar_header, #sidebar_header tbody tr, #sidebar_header tbody tr:first-of-type td:first-of-type, #sidebar_header tbody tr:last-of-type td, #dir_list, #dir_list thead, #dir_list thead th.checked ,#dir_list tr.ignore a, #dir_list tr.ignore.app a, #dir_list tr.ignore td.details, #shortcuts_menu + ul > li.has_submenu, #content_pane, #content_grid div img, #content_image img:not(.zoom_img)' + '{ position: relative; }'; $styles += '#sidebar ul, #handle, #parent_dir_menu, #toggle_sidebar, body.has_hidden_sidebar #sidebar_wrapper, #dir_list tbody, #dir_list thead th.checked:after, #sidebar_overlay, #content_overlay, #content_header, #content_grid, #content_image, #content_font, #content_embed, #content_iframe, #scale, #prev_btn, #next_btn, #content_pane.has_ignored_content:before, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ position: absolute; }'; // top $styles += '#handle, #parent_dir_menu, #content_container, #sidebar_overlay, #content_overlay, #content_header, #content_image, #content_image img.zoom_img, #content_embed, #content_iframe, #prev_btn, #next_btn, #content_pane.has_ignored_content:before, body.use_custom_icons #dir_list tr.file.ignore a.icon::before' + '{ top: 0; }'; $styles += '#shortcuts_menu + ul > li > ul, #grid_btn .menu' + '{ top: -1px; }'; $styles += '#toggle_sidebar' + '{ top: 1px; }'; $styles += 'body.has_hidden_sidebar #sidebar_wrapper, #dir_list thead th.checked:after' + '{ top: 2px; }'; $styles += '#content_grid div img, #content_image img:not(.zoom_img), .vert_center' + '{ top: 50%; }'; // right $styles += '#sidebar ul, #parent_dir_menu, #grid_btn .menu, #dir_list thead, #dir_list tbody, #sidebar_overlay, #content_overlay, #content_header, #content_image, #content_embed, #content_iframe, #content_grid, #content_font, #content_pane.has_ignored_content:before, #next_btn' + '{ right: 0; }'; $styles += '#toggle_sidebar' + '{ right: 2px; }'; $styles += '#handle' + '{ right: -4px; }'; $styles += '#scale' + '{ right: 1rem; }'; // bottom $styles += '#handle, #parent_dir_menu, #sidebar_overlay, #content_overlay, #content_image, #content_embed, #content_iframe, #content_grid, #content_font, #prev_btn, #next_btn, #content_pane.has_ignored_content:before, #dir_list tbody' + '{ bottom: 0; }'; // left $styles += '#sidebar ul, #parent_dir_menu, #grid_btn .menu, #dir_list thead, #dir_list tbody, #sidebar_overlay, #content_overlay, #content_header, #content_image, #content_embed, #content_iframe, #content_grid, #content_font, #content_pane.has_ignored_content:before, body.use_custom_icons #dir_list tr.file.ignore a.icon::before, body.has_hidden_sidebar #toggle_sidebar' + '{ left: 0; }'; $styles += 'body.has_hidden_sidebar #sidebar_wrapper' + '{ left: 3px; }'; $styles += '#shortcuts_menu + ul > li > ul' + '{ left: 100%; }'; // z-index $styles += '#content_grid' + '{ z-index: 1; }'; $styles += '#scale' + '{ z-index: 10; }'; $styles += '#parents_dir_menu + ul, #content_header, #prev_btn, #next_btn' + '{ z-index: 100; }'; $styles += '#handle' + '{ z-index: 1000; }'; $styles += '#sidebar_header' + '{ z-index: 2000; }'; $styles += '#shortcuts_menu + ul, #toggle_sidebar, #sidebar_overlay, #content_overlay' + '{ z-index: 9999; }'; $styles += 'body.has_hidden_sidebar #sidebar_header' + '{ z-index:unset; }'; $styles += '#content_pane[class*="hidden"] #content_grid' + '{ z-index: auto; }'; // float $styles += '#content_header tr:first-of-type td:first-of-type, #checkbox_div label' + '{ float: left; }'; $styles += '#close_audio, #grid_btn, #content_header tr:first-of-type td:last-of-type' + '{ float: right; }'; // clear $styles += '#dir_list tbody .name' + '{ clear:right; }'; $styles += '#checkbox_div label, #grid_btn .menu li, #dir_list tbody tr, #content_grid .font_grid_item' + '{ clear: both; }'; // cursor $styles += '#sidebar_header thead th, #sort_menu .disabled span, #dir_list .disabled' + '{ cursor: default; }'; $styles += '#sidebar_header tbody tr:first-of-type td:hover, #parents_dir_menu div, #shortcuts_menu div, #grid_btn, #dir_list thead th, #scale span' + '{ cursor: pointer; }'; $styles += '#handle' + '{ cursor: col-resize; }'; $styles += '#content_image img:not(.zoom_img)' + '{ cursor: zoom-in; }'; $styles += '#content_image img.zoom_img' + '{ cursor: zoom-out; }'; // TEXT // font-family $styles += 'html, body, :root' + '{ font-family:'+ $settings.UI_font +', arial, "fira sans", helvetica, sans-serif; }'; // font-size $styles += 'html' + '{ font-size: 100.001%; }'; $styles += 'body, :root' + '{ font-size:'+ $settings.UI_font_size +'; }'; //$styles += '#shortcuts_menu div' + // '{ font-size: 18px; }'; $styles += '#sidebar, #sidebar_header, #sidebar_header thead th, #dir_list, #dir_list .details, #content_header, #content_header table' + '{ font-size: 0.875rem; }'; $styles += '#content_grid' + '{ font-size: 1rem; }'; $styles += '#scale span' + '{ font-size: 2rem; }'; $styles += '#content_grid .font_grid_item' + '{ font-size:'+ $grid_font_size * 3 +'em; }'; $styles += '#content_font' + '{ font-size:'+ $grid_font_size +'em; }'; $styles += '.lorem.first:first-line' + '{ font-size:'+ $grid_font_size*1.33 +'em; }'; // font-weight $styles += '#sidebar_header thead th' + '{ font-weight: normal }'; $styles += '#dir_list .selected a, #dir_list .playing a' + '{ font-weight: bold }'; // font-variant $styles += '.lorem.first:first-line' + '{ font-variant: small-caps }'; // color $styles += 'body.dark_theme #shortcuts_menu + ul > li > ul, body.dark_theme #shortcuts_menu + ul > li.has_submenu + li:not(.has_submenu)' + '{ color: #111 }'; $styles += '#sidebar, #parents_dir_menu + ul li a, body.default_theme #shortcuts_menu + ul li a, body.default_theme #shortcuts_menu + ul li > span, #dir_list tbody a, #dir_list .selected a, #dir_list .playing a, #content_header, body.dark_theme #details_btn span' + '{ color: #333 }'; $styles += 'body.dark_theme #sidebar_header thead tr, body.dark_theme #sidebar_header tbody tr:first-of-type' + '{ color: #444 }'; $styles += '#scale span:hover' + '{ color: #666 }'; $styles += '#dir_list tr.ignore a, #dir_list tr.ignore.app a, #dir_list tr.ignore td.details' + '{ color: #777 }'; $styles += '#sort_menu .disabled span, #dir_list .disabled' + '{ color: #999 }'; $styles += 'body.dark_theme #dir_list tr.file.ignore a.icon, body.dark_theme #dir_list tr.ignore td.details' + '{ color: #BBB }'; $styles += 'body.dark_theme #content_font, body.dark_theme .font_grid_item' + '{ color: #CCC }'; $styles += 'body.dark_theme #sidebar th, body.dark_theme #sidebar td, body.dark_theme #sidebar a, body.dark_theme #content_header tr, body.dark_theme #sidebar tbody tr:first-of-type span' + '{ color: #EEE }'; // text-align $styles += '#sidebar ul, #dir_list thead, #dir_list tbody, #dir_list tbody .name, #dir_list .details, #content_header tr:first-of-type td:first-of-type, #content_grid .font_grid_item, .specimen' + '{ text-align: left; }'; $styles += '#parent_dir_menu a, #parents_dir_menu, #parents_dir_menu div, #shortcuts_menu div, #content_header, #content_title, #content_grid .image_grid_item, #content_image, #content_media, #scale span' + '{ text-align: center; }'; $styles += '#grid_btn .menu li, #content_header tr:first-of-type td:last-of-type' + '{ text-align: right; }'; $styles += '.lorem' + '{ text-align: justify; }'; // text-indent $styles += '#sort_menu li' + '{ text-indent: 1em; }'; // text-decoration $styles += 'a, a:hover' + '{ text-decoration: none !important; }'; // line-height $styles += '#dir_list tr a' + '{ line-height: 1.4 }'; $styles += '.lorem' + '{ line-height: 1.4 }'; // columns $styles += '.lorem + .lorem' + '{ columns:2; column-gap:1em; }'; $styles += '.lorem + .lorem + .lorem' + '{ columns:3; }'; // letter-spacing $styles += '.lorem.first:first-line' + '{ letter-spacing: 1pt }'; $styles += '#sidebar_header thead th' + '{ letter-spacing: 0.5em }'; // white-space $styles += '#sidebar_header tbody tr:last-of-type td, #parents_dir_menu div, #parents_dir_menu + ul li a, #shortcuts_menu + ul li a, #shortcuts_menu + ul li > span, #dir_list tbody a, .specimen, .lorem' + '{ white-space: normal; }'; $styles += '#grid_btn .menu li' + '{ white-space: pre; }'; $styles += '#dir_list thead' + '{ white-space: pre-wrap; }'; // list-style $styles += '#sidebar ul, #grid_btn .menu li' + '{ list-style-type: none; }'; // hyphens $styles += '#parents_dir_menu div, #content_header td button, #content_font' + '{ hyphens: none; }'; $styles += 'html, body, :root, .lorem' + '{ hyphens: auto; }'; // word-break $styles += '#content_header td button' + '{ word-break: none; }'; $styles += '#content_title' + '{ word-break: break-word; }'; $styles += '#content_font' + '{ word-break: break-all; }'; $styles += '.lorem' + '{ word-break: normal; }'; // user-select $styles += '#sidebar_header, #content_image img:not(.zoom_img)' + '{ user-select:none; -webkit-user-select:none; }'; // TABLES // border-collapse $styles += 'table' + '{ border-collapse: collapse; }'; // table-layout $styles += '#dir_list' + '{ table-layout: fixed; }'; // BACKGROUND IMAGES & ICONS $styles += '#parent_dir_menu a { background:' + $up_arrow + 'center no-repeat; }'; $styles += '#shortcuts_menu div { background:'+ $menu_icon + 'center no-repeat; }'; $styles += 'body.default_theme #shortcuts_menu + ul > li.has_submenu { background:'+ $menu_arrow +' right no-repeat; background-size: 12px; }'; $styles += 'body.default_theme #shortcuts_menu + ul > li.has_submenu:hover { background:#BBB '+ $menu_arrow +' right no-repeat; background-size: 12px; }'; $styles += 'body.default_theme #sort_menu li.checked span { background:'+ $check_mark +' 4px center no-repeat; background-size:12px; }'; $styles += '#grid_btn { background:'+ $grid_icon +' center no-repeat; }'; $styles += '#toggle_sidebar { background:'+ $toggle +' center no-repeat; background-size:12px; }'; $styles += '#dir_list thead th.checked { background:'+ $check_mark +' 10px 2px no-repeat; background-size:10px; }'; $styles += 'body.default_theme #dir_list thead th.checked:after { background:'+ $up_arrow +' center no-repeat; background-size:10px; }'; $styles += '#dir_list tbody a { background-size:auto 13px; background-position:6px 4px; }'; $styles += 'body.has_audio #content_pane:not(.has_image_content) #content_image { background:'+ $music +' center no-repeat; background-size:33.33%; }'; $styles += '#prev_track, #next_track { background: rgb(241, 243, 244) '+ $next_track_arrow +' center no-repeat; background-blend-mode:difference; }'; $styles += '#prev_track:hover, #next_track:hover { background-blend-mode:normal; }'; $styles += '#close_audio { background:#EEE '+ $plus_sign +' center no-repeat; background-size:10px; }'; $styles += '#scale span:first-of-type { background:'+ $plus_sign +' center no-repeat; }'; $styles += '#scale span:last-of-type { background:'+ $minus_sign +' center no-repeat; }'; $styles += '#prev_btn, #next_btn { background: ' + $svg_arrow + ' center no-repeat; }'; $styles += '#content_pane.has_ignored_content::before { background:'+ $file_icon_ignored +' center no-repeat; background-size:50%; }'; $styles += 'body.dark_theme #shortcuts_menu + ul > li.has_submenu { background:'+ $menu_arrow_inv +' right no-repeat; background-size: 12px; }'; $styles += 'body.dark_theme #shortcuts_menu + ul > li.has_submenu:hover { background:#666 '+ $menu_arrow_inv +' right no-repeat; background-size: 12px; }'; $styles += 'body.dark_theme #sort_menu li.checked a { background:'+ $check_mark_inv +' 4px center no-repeat; background-size:12px; }'; $styles += 'body.dark_theme #dir_list thead th.checked { background:'+ $check_mark_inv +' 10px 2px no-repeat; background-size:10px; }'; $styles += 'body.dark_theme #dir_list thead th.checked:after { background:'+ $up_arrow_inv +' center no-repeat; background-size:10px; }'; // EXCLUDED: Prevent previewed files with these extensions from being inverted in dark mode for ( let i = 0, n = $row_settings.exclude.length; i < n; i += 1) { $styles += 'body.dark_theme #content_iframe[src*="'+ $row_settings.exclude[i] +'" i], body.dark_theme #content_iframe[src$="/" i] { background:#FFF; filter: unset; }'; } $styles += 'body.use_default_icons #dir_list .dir a.icon { background:'+ $file_icon_dir_default + ' 6px 4px no-repeat; background-size:auto 13px; }'; $styles += 'body.use_default_icons #dir_list .file a.icon { background:'+ $file_icon_file_default + ' 6px 4px no-repeat; background-size:auto 13px; }'; $styles += 'body.use_custom_icons #dir_list tr.file:not(.dir) a.icon { background: '+ $file_icon_file +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.file.audio a.icon, body.use_custom_icons #dir_list tr.file.video a.icon { background: transparent; }'; $styles += 'body.use_custom_icons #dir_list tr.file.font a.icon { background: '+ $file_icon_font +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.file.image a.icon { background: '+ $file_icon_image +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.file.pdf a.icon { background: '+ $file_icon_pdf +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.file[class*="htm"] a.icon { background: '+ $file_icon_html +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.file.ignore a.icon { background: '+ $file_icon_ignored +' 6px 4px no-repeat; }'; $styles += 'body.use_custom_icons #dir_list tr.file.invisible a.icon { background: '+ $file_icon_invisible +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.dir.invisible a.icon { background: '+ $file_icon_dir_invisible +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.dir:not(.app) a.icon { background: '+ $file_icon_dir +' 6px 4px no-repeat; background-size:14px 14px; }'; $styles += 'body.use_custom_icons #dir_list tr.app a { background: '+ $file_icon_app +' 6px 4px no-repeat !important; background-size:14px 14px; }'; // Plain text icons for ( let i = 0, n = $row_types.text.length; i < n; i += 1) { $styles += 'body.use_custom_icons #dir_list tr.file.'+ $row_types.text[i] +' a.icon { background: '+ $file_icon_text +' 6px 4px no-repeat; background-size:14px 14px }'; }; // Code file icons for ( let i = 0, n = $row_types.code.length; i < n; i += 1) { $styles += 'body.use_custom_icons #dir_list tr.file.'+ $row_types.code[i] +' a.icon { background: '+ $file_icon_code +' 6px 4px no-repeat; background-size:14px 14px }'; }; // Gecko Styles: var $gecko_styles = ''; $gecko_styles += 'html, body { border: solid 1px gray !important; }'; $gecko_styles += 'button { padding:0; }'; $gecko_styles += 'body.is_gecko #grid_btn .menu { top:-7px; left:-120px; }'; $gecko_styles += 'thead {font-size:100%;}'; $gecko_styles += '#dir_list th, #dir_list td {width:auto;}'; $gecko_styles += '#dir_list .dir::before {position:absolute;}'; $gecko_styles += 'body.is_gecko.use_default_icons:not(.is_converted_list) #dir_list .file .name .icon { padding-left:4px; background:none; }'; $gecko_styles += 'body.is_gecko.use_default_icons #dir_list .file .name .icon img { margin-right:6px; height:14px; }'; $gecko_styles += 'body.is_gecko #dir_list #tbody > tr > td:not(:first-of-type) { padding:0 24px 4px; }'; $gecko_styles += 'body.is_gecko #dir_list #tbody > tr > td:last-of-type { text-indent:6px; }'; $gecko_styles += '#prev_track, #next_track { background: #3F3F3F '+ $next_track_arrow_gecko +' center no-repeat; padding-bottom:9px; }'; $gecko_styles += 'body.dark_theme #prev_track, body.dark_theme #next_track { background: #252525 '+ $next_track_arrow_gecko +' center no-repeat; }'; $gecko_styles += 'body #prev_track:hover, body #next_track:hover { background: #252525 '+ $next_track_arrow_gecko_hover +' center no-repeat; }'; $gecko_styles += '#prev_track:hover, #next_track:hover { background-blend-mode:difference; }'; $gecko_styles += '#content_header tr:first-of-type td:first-of-type, #content_header tr:first-of-type td:last-of-type { padding-top:8px; }'; const $font_preview_styles = document.createElement('style'); const $custom_styles = document.createElement("style"); const $custom_gecko_styles = document.createElement("style"); function addStyles() { // for font previews $font_preview_styles.appendChild(document.createTextNode("")); document.head.append($font_preview_styles); var $font_styles = ''; $font_preview_styles.append( $font_styles ); // basic UI styles $custom_styles.appendChild(document.createTextNode("")); $custom_styles.append($styles); document.head.appendChild($custom_styles); // Firefox styles if ( $userAgent.indexOf('Firefox') > -1 ) { $custom_gecko_styles.appendChild(document.createTextNode("")); $custom_gecko_styles.append($gecko_styles); document.head.appendChild($custom_gecko_styles); } } // ***** END STYLES ***** // // ***** BUILD MENUS ***** // const parentLinksArr = function() { var $paths_arr = []; var $path = window.location.pathname; while ( $path.lastIndexOf('/') > 0 ) { $path = $path.slice( 0,$path.lastIndexOf('/') ); $paths_arr.push($path); } if ( $userAgent.indexOf('Firefox') > -1 ) { $paths_arr.push('///'); } else { $paths_arr.push('//'); // root } return $paths_arr; }; // MENUS: Create menu list items var $menu_item; const menuItems = function(x,y,i,b) { // (link, name, count, boolean) let $qstr = '/?'; if ( b === true ) { $protocol = ''; $qstr = ''; $query_prefs = ''; } $menu_item = '
  • ' + y[i] + '/
  • '; return $menu_item; }; var $parent_dir_link; function setParentLink() { var $query_prefs = new URLSearchParams( window.location.search ); $query_prefs.delete('file'); $UI_pref_history_arr = $query_prefs.get('history') !== null ? $query_prefs.get('history').split(' ') : []; if ( $UI_pref_history_arr.length == 1 ) { $query_prefs.set('selected',$UI_pref_history_arr.shift(0)); $query_prefs.delete('history'); } else if ( $UI_pref_history_arr.length > 1 ) { $query_prefs.set('selected',$UI_pref_history_arr.shift(0)); $query_prefs.set('history',$UI_pref_history_arr.join('+')); } else { $query_prefs.delete('selected'); } let $qstr = $query_prefs.toString().length == 0 ? '' : '?'; $query_prefs.sort(); $parent_dir_link = $protocol + $location_arr.slice(0,-2).join('/') +'/'+ $qstr + decodeURIComponent($query_prefs); $parent_dir_menu.find('a').attr( 'href', $parent_dir_link ); } setParentLink(); $parent_dir_menu.on('click','a',function(e) { e.preventDefault(); setParentLink(); $('#parent_dir_menu').find('a').attr( 'href', $parent_dir_link ); window.location = $parent_dir_link; }); // MENUS: Directory Parents Links const parents_dir_menu_arr = function() { var $parents_dir_menu_items = []; for ( let i = 1, n = parentLinksArr().length + 1; i < n; i+=1 ) { $parents_dir_menu_items[i] = menuItems( parentLinksArr(), parentLinksArr(), i, false); } $parents_dir_menu_items.pop(); // remove current directory if ( $parents_dir_menu_items[1] !== undefined ) { let str = $parents_dir_menu_items[1].slice($parents_dir_menu_items[1].lastIndexOf('?'),$parents_dir_menu_items[1].lastIndexOf('">')); for ( let i = 1; i < $parents_dir_menu_items.length; i+=1 ) { // recursively update selected and history query str str = str.replace(/selected=\d+&*/,'').replace(/history=(\d+)$/,'selected=$1').replace(/history=(\d+)\+/,'selected=$1&history=').replace(/&$/,''); $parents_dir_menu_items[i] = $parents_dir_menu_items[i].replace(/\?.+?">/,str +'">'); } } $parents_dir_menu_items = $parents_dir_menu_items.join('') .replace(/%20/g,' ').replace(/file=.+?&/g,'&').replace(/file=.+?/g,'').replace(/>\/(?!\/)/g,'>').replace(/>\/\/\/\//<').replace(/>\/\/\//<'); return $parents_dir_menu_items; }; // MENUS: Shortcuts var $menu_items = []; var $shortcuts_links_arr = []; const shortcutMenus = function() { const $shortcuts = $settings.shortcuts; if ( $shortcuts.length > 0 ) { for ( let i = 0; i < $shortcuts.length; i+=1 ) { var $links_arr = []; var $links = $shortcuts[i].links; for ( let j = 0; j < $links.length; j+=1 ) { if ( !$links[j].link.endsWith('/') ) { $links[j].link = $links[j].link.slice(0,$links[j].link.lastIndexOf('/') + 1) + '?file=' + $links[j].link.slice($links[j].link.lastIndexOf('/') + 1) ; } $shortcuts_links_arr.push($links[j].link); $links_arr[j] = '
  • ' + $links[j].link_name + '
  • '; } var $links_arr_str = $links_arr.join(''); $menu_items[i] = '
  • '+ $shortcuts[i].menu_title +'
      '+ $links_arr_str +'
  • '; } $menu_items = $menu_items.join(''); } return ($shortcuts_links_arr,$menu_items); } shortcutMenus(); // MENUS: Other menu items var $sort_by = $('
  • Sort by…
    • Name
    • Size
    • Date
    • Kind
    • Extension
    • Default
    '); const $toggle_dark_theme = $('
  • Dark ThemeDefault Theme
  • '); const $toggle_alt_bckgrd = $('
  • Alternate Backgrounds
  • '); const $default_settings = $('
  • Default User Settings
  • '); const $export_settings = $('
  • Export User Settings
  • '); const $donate_link = $('
  • '); function assembleMenus() { // called by buildUI(); $parents_dir_menu.siblings('ul').append( parents_dir_menu_arr() ); $shortcuts_menu.siblings('ul').append( $menu_items, $sort_by, $toggle_dark_theme, $toggle_alt_bckgrd, $default_settings, $export_settings, $donate_link ); } // ***** END BUILD MENUS ***** // // ***** DIRECTORY LIST Set Up ***** // // CONVERT VARIOUS SERVER-GENERATED INDEX PAGES TO DEFAULT (Chrome) STRUCTURE var $list_items, $rows; var yr, mo, dd, pref; var factor = {k:1, kb:1, m:1000, mb:1000, g:1000000, gb:1000000, t:1000000000,tb:1000000000} var sizeCalc = function(x,y) { y === '' ? y = 'k' : y = y; return x == '-' ? 0 : x * factor[ y.toString().toLowerCase() ]; // convert size abbreviation to multiplaction factor } // Convert matched date and size strings to default size and date format, calculate data-values for sorting var sizeAndDate = function(match,p1,p2,p3,p4,p5,p6,offset,string) { p1.toString().length == 4 ? (yr = p1, dd = p3) : (yr = p3, dd = p1); p2.toString().length == 3 ? mo = "JanFebMarAprMayJunJulAugSepOctNovDec".indexOf(p2)/3 + 1 : mo = p2; // convert month into number, or use number p6 = undefined|'' ? p6 = 1 : p6 = p6; mo.toString().length == 1 ? pref = 0 : pref = null; // add a zero before single digit months (i.e., multiply year by 10) return '' + [p5,p6].join('') + ''+ [yr, mo, dd].join('-') +' '+ [p4].join(':') +'\n'; }; // AMPPS index pages if ( window.location.href.indexOf('localhost') > -1 && $body.find('> title:contains(AMPPS)').length ) { $dir_list = $body.find('> center > div > table'); $dir_list.remove(); $body.addClass('is_ampps').empty().append($dir_list); } // Pre type if ( window.location.href.indexOf('file:') == -1 && $body.find('> pre').length > 0 ) { $list_items = $body.find('> pre').html(); $body.addClass('is_converted_pre').find('> pre').remove(); $list_items = $list_items .replace(/^.+?\n/, '') // delete header row .replace(/^.+?Parent Directory.+?\n/gm, '\n') // delete parent directory link .replace(/^\s*\.\.\/<\/a>\s*$/gm, '') // delete parent directory link (list type) .replace(/^\s*\s*/gm, '') // delete all images (icons) .replace(/^\s*
    .+?<\/address>\s*/,'') // delete address element .replace(/^\s*(.+?)<\/a>\s*/gm, '$2') // create name cell .replace(/(\d{2}|\d{4})[\/-](\d{2}|\w{3})[\/-](\d{2}|\d{4})\s+?([\d:]+)\s*([\.\d]+)([A-z]{0,2})\s*$/gm, sizeAndDate); // dates (search dd-mmm-yyyy hh:mm) and sizes } // List type if ( window.location.href.indexOf('file:') == -1 && $body.find('> ul').length > 0 ) { $list_items = $body.find('> ul').html(); $body.addClass('is_converted_list').find('> ul').remove(); if ( $list_items.indexOf('') != -1 ) { $list_items = $list_items.replace(/
  • \s*/g,'').replace(/\s*<\/li>/g, '\n'); $list_items = $list_items.replace(/data-value="">\s+(.+?)<\/a>/g, 'data-value="$2">$2<\/a>'); $list_items = $list_items.replace(//,''); } } // Table type if ( window.location.href.indexOf('file:') == -1 && $body.find('> table').length > 0 ) { $list_items = $body.find('> table tbody').length > -1 ? $body.find('> table tbody').html() : $body.find('> table'); $body.addClass('is_converted_table').find('> table').remove(); $list_items = $list_items // .replace(//g, '') // delete all images (icons) .replace(/<\/tr>/g, '') // delete empty tr .replace(/<\/tr>/, '') // delete empty tr .replace(/(?:||)(?: |\s*)(?:<\/th>|<\/td>)/g, '') // delete empty th or td .replace(/\s*(.+?)<\/a>\s*<\/td>/g, '$2') .replace(/<\/td>(.+?)<\/a>/g, '$4') // move default image to .name td .replace(/(?:|)(\d{4}|\d{2})-(\d{2}|\w{3})-(\d{4}|\d{2})\s*([\d:-]*)\s*<\/td>(?:|)\s*([-\.\d]*)([A-z]*)\s*<\/td><\/tr>/g, sizeAndDate) .replace(/^\s*
    .+?<\/address>\s*$/,''); // delete address line } // Convert Gecko-style local index pages if ( window.location.href.indexOf('file:') > -1 && $userAgent.indexOf('Firefox') > -1 ) { $body.find('> table').find('> thead').find('th[colspan="2"]').attr('colspan',1); $list_items = $body.find('> table').find('> tbody').html(); $body.find('> table').remove(); $list_items = $list_items .replace(/') .replace(/ -1 && $body.find('> table').length > 0 && $userAgent.indexOf('Firefox') < 0) { $list_items = $body.find('> table tbody').html(); $body.addClass('is_default_table').find('> table').remove(); } // ***** END CONVERT INDEX PAGES ***** // $dir_list_body.append($list_items); var $dir_list_row = $dir_list_body.find('> tr'); var $dir_list_item_name = $dir_list_row.find('a').parent('td'); var $dir_list_details = $dir_list_item_name.nextAll(); $dir_list_details.addClass('details'); // ***** END CONVERT INDEX PAGES ***** // // ***** PREPARE DIR LIST ***** // var $this_link; var $this_text; var $this_ext; // Get dir_list item row var thisRow = function(x) { return $(x).closest('#dir_list > tbody > tr').length ? $(x).closest('#dir_list > tbody > tr') : $(x).closest('#dir_list > li'); }; // Get dir_list item link var thisLink = function(x) { return $(x).find('a').length ? $(x).find('a').attr('href') : $(x).attr('href'); }; // Get dir_list item name var thisText = function(x) { return $(x).find('a').length ? decodeURIComponent( $(x).find('a').text().toLowerCase() ) : decodeURIComponent( $(x).text().toLowerCase() ); }; var thisExt = function(x) { return thisLink(x).toLowerCase().endsWith('app/') ? 'app' : thisLink(x).toLowerCase().endsWith('/') ? '/' : $(x).find('a').attr('href').toLowerCase().slice( $(x).find('a').attr('href').lastIndexOf('.') + 1 ); } // Dir_List: Classify items function classifyDirListItems() { $dir_list_row.each(function() { let row = {}; $this_link = thisLink(this); $this_text = thisText(this); $this_ext = thisExt(this); // Add ID and lowercase .name data $(this).attr('id',$(this).index()).find('td').first().addClass('name').attr( 'data-value',$this_text.toLowerCase() ); // add ID if ( $this_ext === '/' ) { $(this).addClass('dir').attr('data-ext','dir'); } else { $(this).addClass('file').attr('data-ext',$this_ext); } if ( $this_text.indexOf('.') === 0 ) { $(this).addClass('invisible'); } $(this).append('') .append('');//attr('data-ext',$this_ext); // For listed supported file types for ( let key in $row_types ) { if ( $row_types[key].includes($this_ext) ) { let $display_key = key.charAt(0).toUpperCase() + key.slice(1); let kind = $display_key === undefined ? 'File' : $display_key; $(this).addClass(key).addClass($this_ext).attr('data-type',$display_key); if ( key === 'audio' || key === 'video' ) { $(this).find('a').prepend(''); } $(this).find('td.kind').attr('data-value',kind).text(kind); } }; // For ignored and excluded items for ( let key in $row_settings ) { if ( $row_settings[key].includes($this_ext) ) { $(this).addClass(key); } if ( $row_settings[key].includes($this_ext) && key == 'ignore' ) { } } }); // end classify dir_list items } // ***** END DIR_LIST SETUP ***** // // ***** UI SETUP ***** // // Add body classes depending on available content types function bodyClasses() { if ( $userAgent.indexOf('Chrome') > 0 ) { $body.addClass('is_chrome'); } if ( $userAgent.indexOf('Firefox') > 0 ) { $body.addClass('is_gecko'); } if ( $dir_list.find('.image').length ) { $body.addClass('has_images'); } if ( $dir_list.find('.font').length ) { $body.addClass('has_fonts'); } if ( $dir_list.find('.audio').length ) { $dir_list.add($body).addClass('has_audio'); } if ( $dir_list.find('.video').length ) { $dir_list.add($body).addClass('has_video'); } } function init() { addStyles(); if ( navigator.platform.indexOf('Win') > -1 || window.location.href.indexOf('file:') < 0 ) { $inv_checkbox.hide(); } if ( $settings.hide_invisibles === true ) { $inv_checkbox.find('input').prop('checked',true); $body.addClass('hide_invisibles').removeClass('show_invisibles'); } else { $inv_checkbox.find('input').prop('checked',false); $body.addClass('show_invisibles').removeClass('hide_invisibles'); } if ( $UI_pref_background === true ) { $body.addClass('alternate_background'); } else { $body.removeClass('alternate_background'); } if ( $settings.hide_ignored_files === true ) { $body.addClass('hide_ignored'); } if ( $UI_pref_details === false ) { $dir_list.addClass('show_details'); $dir_list_body.css({'top':$dir_list_head.height() + 1 +'px'}); $details_btn.find('span').first().hide().next().show(); } if ( $UI_pref_theme === true ) { $body.addClass('dark_theme'); } else { $body.addClass('default_theme'); } if ( $settings.use_custom_icons === true ) { $body.addClass('use_custom_icons'); } else { $body.addClass('use_default_icons'); } // Hide audio controls if $settings.autoload_audio = false (but show when audio file is selected) if ( $settings.autoload_audio === true ) { $body.addClass('autoload_audio'); } if ( $settings.autoload_index_files === true ) { autoSelectFile(); } } init(); function buildUI() { assembleMenus(); classifyDirListItems(); bodyClasses(); $dir_list.appendTo($sidebar); var $main_content = $('
    /g,'') .replace(/<\/a><\/td><\/tr><\/tbody><\/table>/g,'') .replace(/sortable-data="\d+?/g,'data-value="') .replace(/([\d-]+)<\/td>\s*(.+?)<\/td>/g,'$2, $3File 
    '); $main_content.find('tr').append( $sidebar_wrapper, $content_pane ); $body.empty().prepend($main_content); if ( $body.hasClass('is_converted_list') ) { $('#sort_by_size, #sort_by_date, #size, #date').addClass('disabled'); } if ( $body.hasClass('is_converted_table') || $body.hasClass('is_converted_pre') ) { if ( $dir_list.find('td.size').length < 1 ) { $('#sort_by_size,th#size').addClass('disabled'); }; if ( $dir_list.find('td.date').length < 1 ) { $('#sort_by_date,th#date').addClass('disabled'); }; } } buildUI(); // ***** BASIC UI FUNCTIONS ***** // function showMenus(el) { var $position = $(el).position(); $(el).find('> ul').css({'top':$position.top + $(el).innerHeight() + 'px'}).toggle().parent('td').siblings('td').find('.menu').hide(); } $parents_dir_menu.add($shortcuts_menu).parent('td').on('click',function(e) { e.stopPropagation(); showMenus(this); }); function hideMenus() { $('.menu').hide(); } $(document).on('click', hideMenus ); function toggleInvisibles() { $body.toggleClass('hide_invisibles').toggleClass('show_invisibles'); } $inv_checkbox.on('click','input', toggleInvisibles ); function toggleDarkMode(e) { e.preventDefault(); $body.toggleClass('dark_theme').toggleClass('default_theme'); toggleQuery('dark_theme'); } $toggle_dark_theme.on('click', toggleDarkMode ); function toggleAlternateBackground(e) { e.preventDefault(); $body.toggleClass('alternate_background'); toggleQuery('alternate_background'); } $toggle_alt_bckgrd.on('click', toggleAlternateBackground ); function toggleDetails() { $dir_list.toggleClass('show_details'); $dir_list_body.css({'top':$dir_list_head.height() + 1 +'px'}); $details_btn.find('span').toggle(); toggleQuery('hide_details'); } $details_btn.on('click', toggleDetails ); function toggleSidebar() { $body.toggleClass('has_hidden_sidebar'); setContentHeight(); } $toggle_sidebar.on('click', toggleSidebar); // Default settings: remove queries; function defaultSettings() { $location = window.location.href; $location = $location.slice(0,$location.lastIndexOf('?')); window.location.assign($location); } $default_settings.on('click', function() { if (window.confirm( "Are you sure you want to reset all your temporary UI settings to the defaults in your user_settings?" ) ) { defaultSettings(); } }); function setContentHeight() { var $dir_list_head_height = $dir_list_head.length ? $dir_list_head.height() : 0; var $content_headerHeight = $content_header.outerHeight(); $dir_list.add($dir_list_wrapper).css({'height':window.innerHeight - $sidebar_header.outerHeight() }); $dir_list.find($dir_list_body).css({'top': $dir_list_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_scale.css({'top':$content_headerHeight + 13 }); $content_media.find('> div:first-of-type').add('#content_media > div:nth-of-type(2)').css({'height':$audio.height() }); $('#checkbox_div').css({'margin-right': - $('#checkbox_div').outerWidth() }); } 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); return; } if ( $content_pane.hasClass('has_grid_content') && $content_grid.hasClass('has_image_grid') ) { $content_title.empty().prepend('Images from: ' + $current_dir_name); return; } if ( $content_pane.hasClass('has_grid_content') && $content_grid.hasClass('has_font_grid') ) { $content_title.empty().prepend('Fonts from: ' + $current_dir_name); return; } if ( $body.hasClass('has_audio') && $settings.autoload_audio === true ) { $content_title.empty().prepend( thisText($('.playing')) ); return; } $content_title.empty().prepend( $('.selected').find('a').text() ); if ( $('.selected').hasClass('ignore') ) { $content_title.prepend('Ignored content: ' ); } if ( $('.selected').hasClass('dir') ) { $content_title.prepend('Index of: ' ); } } function getDimensions(link, callback) { var img = new Image(); img.src = link; img.onload = function() { callback( this.width, this.height ); }; } function scrollSidebar(row) { var $block = $userAgent.indexOf('Firefox') > -1 ? $block = 'start' : $block = 'nearest'; if (row[0] !== undefined ) { row[0].scrollIntoView({ behavior:'smooth', block:$block, inline:'nearest' }); } } function scrollGrid(item) { var $block = $userAgent.indexOf('Firefox') > -1 ? $block = 'start' : $block = 'nearest'; if (item[0] !== undefined ) { item[0].scrollIntoView({ behavior:'smooth', block:$block, inline:'nearest' }); } } // ***** SORTING ***** // var $sort_all = $dir_list_body.find('tr'); var $sort_dirs = $dir_list_body.find('tr.dir').not('.app'); var $sort_files = $dir_list_body.find('tr').not('.dir').add('.app'); var currentIndex, prevIndex; var $default_index = $('#thead').find('#default').index(); var $sort_direction = 1; var dataName = function(x) { return $(x).find('td').eq(0).data('value').toString(); }; var dataData = function(x,index) { return $(x).find('td').eq(index).attr('data-value') === undefined ? '' : $(x).find('td').eq(index).attr('data-value').toString(); }; // comparison functions var sortByName = function(x,y,sortDirection) { return sortDirection === 1 ? dataName(x).localeCompare(dataName(y)) : dataName(y).localeCompare(dataName(x)); }; var sortByData = function(x,y,index,sortDirection) { // sort by data then by name if ( sortDirection === 1 ) { return dataData(x,index).localeCompare(dataData(y,index), undefined, { numeric:true }) === 0 ? dataName(x).localeCompare(dataName(y)) : dataData(x,index).localeCompare(dataData(y,index), undefined, { numeric:true }); } else { return dataData(y,index).localeCompare(dataData(x,index), undefined, { numeric:true }) === 0 ? dataName(y).localeCompare(dataName(x)) : dataData(y,index).localeCompare(dataData(x,index), undefined, { numeric:true }); } }; // sort elements: sort by name if index = 0, else sort by data-value. var sortEls = function(els,index,sortDirection) { els.detach().sort(function(a,b) { return index === 0 ? sortByName(a,b,sortDirection) : sortByData(a,b,index,sortDirection); }); }; function sortDirList(index, sortDirection) { $dir_list_row.removeClass('sorted'); if ( index == $default_index ) { if ( index == $default_index ) { index = 0; } sortEls( $sort_dirs, index, sortDirection ); sortEls( $sort_files, index, sortDirection ); if (sortDirection === 1 ) { $.each($sort_dirs, function() { $dir_list_body.append(this); }); $.each($sort_files, function() { $dir_list_body.append(this); }); } else { $.each($sort_files, function() { $dir_list_body.append(this); }); $.each($sort_dirs, function() { $dir_list_body.append(this); }); } } else if ( $settings.dirs_on_top === false || index == 0 && index !== $default_index ) { sortEls( $sort_all, index, sortDirection ); $.each($sort_all, function() { $dir_list_body.append(this); }); $body.removeClass('is_dirs_on_top'); } else if ( $settings.dirs_on_top === true || index !== 0 ) { sortEls( $sort_dirs, index, sortDirection ); sortEls( $sort_files, index, sortDirection ); if (sortDirection === 1 ) { $.each($sort_dirs, function() { $dir_list_body.append(this); }); $.each($sort_files, function() { $dir_list_body.append(this); }); } else { $.each($sort_files, function() { $dir_list_body.append(this); }); $.each($sort_dirs, function() { $dir_list_body.append(this); }); } } if ( index === $('#thead').find('#kind').index() || index === $('#thead').find('#ext').index() ) { $body.addClass('is_dirs_on_top'); addSortStyle( index, sortDirection ); } } function addSortStyle(index, sortDirection) { var $this_value, $next_value; $dir_list_row.removeClass('sorted'); $dir_list_row.filter(':visible').not('.dir').add('.app').each(function() { $this_value = $(this).find('td').eq(index).attr('data-value'); $next_value = $(this).next('tr:visible').find('td').eq(index).attr('data-value'); if ( $this_value !== $next_value ) { $(this).addClass('sorted'); } if ( $(this).attr('data-type') !== $(this).next('tr:visible').attr('data-type') ) { $(this).addClass('sorted'); } }); if ( sortDirection == 1 ) { $dir_list_row.filter('.dir').last().addClass('sorted'); } } // Sort on click function clickSort(x,y) { // x = clicked sort link, y = bool (false ? don't set query_prefs) currentIndex = x.index(); if ( currentIndex != prevIndex ) { // Only reverse sort order after clicking a sort column once. prevIndex = currentIndex; $sort_direction = 1; } sortDirList(currentIndex, $sort_direction); $sort_direction = -1 * $sort_direction; x.toggleClass('up').addClass('checked').siblings().removeClass('checked up'); $('#sort_menu').find('li').eq(currentIndex).addClass('checked').siblings().removeClass('checked'); setContentHeight(); if ( y === true ) { $query_prefs = getQueryPrefs(); $query_prefs.set('sort',$('#sort_menu').find('li').eq(currentIndex).text().toLowerCase() ); updateQuery(); } } // Sort on clicking dir_list sort header $('#thead').on('click','th:not(.disabled)',function(e) { e.preventDefault(); e.stopPropagation(); var i = $(this).index(); clickSort( $(this),true) }); // Sort Menu: click the list header that contains the selected menu text. $('#sort_menu').on('click','li:not(.disabled)',function(e) { e.preventDefault(); e.stopPropagation(); $(this).addClass('checked').siblings().removeClass('checked'); $('#theader th[id*="'+ thisText($(this)).slice(0,2) +'" i]').click(); setContentHeight(); }); // Initialize page // var $sort = $settings.default_sort.toLowerCase(); function initialSort() { switch ( $UI_pref_sort ) { case 'name': i = 0; break; case 'size': i = 1; break; case 'date': i = 2; break; case 'kind': i = 3; break; case 'ext': i = 4; break; default: i = 5; } $('#theader').find('th').eq(i).click(); } initialSort(); // ***** END SORTING ***** // // ***** END BASIC UI FUNCTIONS ***** // // ***** CONTENT PREVIEW ***** // var $selected = $dir_list_row.filter('.selected'); var $playing = $dir_list_row.filter('.playing'); // Select row on click and set classes for $content_pane function selectThis(row) { // If autoload_audio === true, navigate audio and other files separately; otherwise, treat audio files like any other if ( $settings.autoload_audio == true ) { if ( row.hasClass('audio') || row.hasClass('video') ) { row.addClass('playing').siblings().removeClass('playing hovered'); $content_pane.addClass('has_audio_content'); } else { row.addClass('selected').siblings().removeClass('selected hovered'); // previewThis( row, thisLink(row) ); } } if ( $settings.autoload_audio == false ) { row.addClass('selected').siblings().removeClass('selected playing hovered'); if ( row.hasClass('audio') || row.hasClass('video') ) { row.addClass('playing'); $content_pane.addClass('has_audio_content'); } else { $content_pane.removeClass('has_audio_content'); } } if ( row.hasClass('dir') ) { closeThis(); closeGrid(); $content_pane.removeClass().addClass('has_dir_content'); } // Select corresponding grid item var $grid_selected = $content_grid.find('div.font_grid_item[href="'+ thisLink(row) +'"]').add('div.image_grid_item a[href="'+ thisLink(row) +'"]').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 ); // not working reliably together with scroll sidebar } setContentTitle(); scrollSidebar(row); } function showIgnored() { closeThis(); $content_pane.addClass('has_ignored_content'); $content_title.append(' (Ignored content)' ); } function showMedia(row) { if ( $settings.autoload_audio == false ) { closeContent(); } $content_pane.addClass('has_audio_content'); $body.hasClass('is_playing') ? $task = 'stop' : $task = 'play'; $playing = row; playThis( $playing.index('.audio:not(.unchecked)'),$task ); } function showImage(row,link) { $content_pane.addClass('has_image_content'); $content_image.find('img').removeClass('zoom_img').attr('src',link).attr('style',''); getDimensions( link, function( width, height ) { if ( !$body.is('.has_audio') ) { $content_title.append(' (' + width + 'px × ' + height + 'px)' ); } }); $content_grid.find('a[href="' + thisLink(row) + '"]').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 = thisText(row); if ( $font_family_arr.indexOf($font_family) == -1 ) { $font_family_arr.push($font_family); $font_preview_styles.append('@font-face { font-family: "'+ $font_family +'"; src: url("'+ link +'"); }'); // only add style if it doesn't exist } $content_pane.addClass('has_font_content'); $content_font.css({ 'font-family':'"'+ $font_family +'"' }); } // Show selected content function previewThis(row,link) { if ( $content_pane.hasClass('has_grid_content') ) { hideGrid(); } if ( row.hasClass('unchecked') ) { // return; } if ( row.hasClass('ignore') ) { showIgnored(); return; } if ( row.hasClass('audio') ) { showMedia(row); return; } if ( row.hasClass('font') ) { showFont(row,link); return; } if ( row.hasClass('image') ) { showImage(row,link); return; } if ( row.hasClass('pdf') ) { showPdf(link); return; } if ( row.hasClass('file') || row.hasClass('dir')) { showFile(link); return; } } // ***** MAIN CLICK FUNCTIONS FOR PREVIEWING CONTENT ***** // // CLICK ROW & SET UI function clickDirListLink(row) { hideMenus(); closeContent(); selectThis( thisRow(row) ); previewThis( thisRow(row), thisLink(row) ); setContentTitle(); setContentHeight(); } // CLICK ROW function clickRow(row) { // toggle play/pause, or click list item if ( $body.hasClass('is_playing') && thisRow( row ).hasClass('playing') ) { playAudio('pause'); } else if ( $body.hasClass('is_paused') && thisRow( row ).hasClass('playing') ) { playAudio('play'); } else { clickDirListLink( row ); } } $dir_list_row.on('click','a', function(e) { e.preventDefault(); e.stopPropagation(); clickRow( $(this) ); }); // DOUBLE-CLICK DIRECTORY function doubleClickRow(row) { if ( row.hasClass('dir') ) { $query_prefs = getQueryPrefs(); var $history = $query_prefs.get('history') === null ? '' : '+'+ $query_prefs.get('history'); var $current_index = row.prevAll('.dir:visible:not(.ignore)').length; $history = $current_index + $history; // update history $query_prefs.delete('selected'); $query_prefs.set('history',$history); updateQuery(); window.location = row.find('a').attr('href') +'?'+ $query_prefs; } } $dir_list_row.filter('.dir').on('dblclick', function(e) { e.preventDefault(); e.stopPropagation(); doubleClickRow( $(this) ); }); // Prev and Next Buttons function prevNextItem(e) { e = $.Event("keydown"); if ( $(this).attr('id') === 'prev_btn' ) { $playing.length ? e.key = 'ArrowUp' : e.key = 'ArrowLeft'; } else { $playing.length ? e.key = 'ArrowDown' : e.key = 'ArrowRight'; } $dir_list.trigger(e); } $content_pane.on( 'click','#prev_btn, #next_btn', prevNextItem ); // AUTOLOAD index files or files from the file shortcut list; function autoSelectFile() { if ( $UI_pref_selected !== '' ) { let $selectThisRow = $dir_list.find('tbody tr:not(.invisible)').eq($UI_pref_selected); clickThis( $selectThisRow ); } else if ( $UI_pref_file !== '' ) { let $selectThisRow = $dir_list_row.find('a:contains('+ $UI_pref_file +')'); clickThis( $selectThisRow ); } else if ( $dir_list.find( 'a[href*="/index."]').length > -1 ) { $dir_list.find( 'a[href*="/index."]').click(); return; } } autoSelectFile(); // File shortcuts: load directory, then auto-select file function showFileShortcut(item) { $this_link = thisLink(item); window.location = $this_link.slice( 0, $this_link.lastIndexOf('/') ); } // RESET CONTENT function resetAudio() { var $this_src = $audio.find('source').attr('src'); $audio.find('source').attr('src',$this_src); $audio.trigger('load'); return; } function resetFont() { $content_font.css({'font-size':'1em'}); } function resetGrid() { $content_grid.attr('style',''); $content_grid.find('.image_grid_item, img').attr('style',''); setContentHeight(); } function resetImage() { $content_image.attr('data-image-scale-factor',1).find('img').attr('style',''); } function reloadThis() { if ( $content_pane.hasClass('has_dir_content') || $content_pane.attr('class') === '' || $('#content_pane[class]').length < 1 ) { window.location = window.location.href; } if ( $content_pane.hasClass('has_font_content') || $content_pane.hasClass('has_image_content') ) { // resetAudio(); resetFont(); resetImage(); } if ( $content_pane.hasClass('has_grid_content') ) { $grid_btn.click(); } if ( $content_pane.hasClass('has_file_content') ) { $('.selected').find('a').click(); } if ( $content_pane.hasClass('has_audio_content') ) { $audio.prop('currentTime', 0); playAudio('stop'); } setContentHeight(); } $content_reload_btn.on('click', reloadThis ); // CLOSE CONTENT (Close button or Cmd/Ctrl + W) function closeContent() { $content_embed.removeAttr('src'); $content_iframe.removeAttr('src'); $content_font.css({'font-family':''}); $content_image.find('img').removeAttr('src'); resetImage(); $content_pane.removeClass('has_image_content has_font_content has_file_content has_pdf_content has_ignored_content') if ( $settings.autoload_audio === true ) { //$audio.trigger('pause').find('source').attr('src',''); } else { $audio.trigger('pause').find('source').attr('src',''); $body.removeClass('is_playing').removeClass('is_paused'); $content_pane.removeClass('has_audio_content'); } } function closeThis() { hideMenus(); if ( $content_pane.hasClass('has_grid_content') ) { closeGrid(); } else if ( $content_pane.hasClass('has_hidden_grid') ) { closeContent(); $content_pane.removeClass().addClass('has_grid_content'); } else { $content_pane.removeClass(); closeContent(); } setContentTitle(); } $content_close_btn.on( 'click', closeThis ); $('#close_audio').on('click',function() { $audio.trigger('pause').find('source').attr('src',''); $body.removeClass('is_paused'); $content_pane.removeClass('has_audio_content'); setContentHeight(); }); // ***** KEYBOARD EVENTS AND NAVIGATION ***** // function clickThis(el) { el.find('a').length > 0 ? el.find('a').click() : el.click(); } function navigateToThis(row) { if ( $content_pane.hasClass('has_grid_content') ) { selectThis(row); // clickThis(row); } else { clickThis(row); } } // Select dir_list_row by typed string var str = '', timer; function timeoutID() { timer = window.setTimeout( function() { str = ''; }, 1500 ); }; function alphaNav(e) { if (typeof timer == 'number' ) { window.clearTimeout( timer ); timer = 0; // id } timeoutID(); str += e.key // Select row; todo: select next row by nearest letter $('#dir_list').find('td.name[data-value^="'+ str +'"]').first().find('a').click(); } // KEYBOARD EVENTS $body.on('keydown',$dir_list,function(e) { $dir_list_row = $dir_list.find('tbody tr:not(.unchecked)').filter(':visible'); $selected = $dir_list.find('tbody tr.selected'); var $selected_href = thisLink($selected); $playing = $dir_list_row.filter('.playing'); var $time; var firstRow = function(className) { return className == undefined ? $dir_list_row.first() : $dir_list_row.filter( className ).first(); } var lastRow = function(className) { return className == undefined ? $dir_list_row.last() : $dir_list_row.filter( className ).last(); } var nextRow = function(className) { return className == undefined ? $selected.nextAll(':visible:not(.unchecked)').first() : $selected.nextAll( className ).filter(':visible:not(.unchecked)').first(); } var prevRow = function(className) { return className == undefined ? $selected.prevAll(':visible:not(.unchecked)').first() : $selected.prevAll( className ).filter(':visible:not(.unchecked)').first(); } switch ( e.key ) { case 'ArrowUp': if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { $('#parent_dir_menu a').trigger('click'); break; } if ( $('*[contentEditable="true"]').is(':focus') ) { return; // Allow arrow navigation within content_editable elemnets } e.preventDefault(); if ( $settings.autoload_audio === true ) { prevRow(':not(.audio, .video)').length < 1 || $selected.length < 1 ? clickThis( lastRow(':not(.audio, .video)') ) : clickThis( prevRow(':not(.audio, .video)') ); } if ( $settings.autoload_audio === false ) { prevRow().length < 1 || $selected.length < 1 ? ( scrollSidebar( lastRow() ), clickThis( lastRow() ) ) : clickThis( prevRow() ); } ( prevRow().length < 1 || $selected.length < 1 ) && $settings.autoload_audio === false ? scrollSidebar( lastRow() ) : scrollSidebar( $('.selected') ); 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') ) { $selected.find('a').trigger('dblclick'); break; } e.preventDefault(); if ( $settings.autoload_audio === true ) { // select non-audio items nextRow(':not(.audio, .video)').length < 1 || $selected.length < 1 ? clickThis( firstRow(':not(.audio, .video)') ) : clickThis( nextRow(':not(.audio, .video)') ); } if ( $settings.autoload_audio === false ) { // select any item nextRow().length < 1 || $selected.length < 1 ? ( scrollSidebar( firstRow() ),clickThis( firstRow() ) ) : clickThis( nextRow() ); } nextRow().length < 1 || $selected.length < 1 ? scrollSidebar( firstRow() ) : scrollSidebar( $('.selected') ); break; case 'ArrowLeft': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $('*[contentEditable="true"]').is(':focus') ) { return; } // Skip audio -30s if ( e.altKey && e.shiftKey ) { $time = $audio.prop('currentTime'); $audio.prop('currentTime', $time - 30); return; } // Skip audio -10s if ( e.altKey ) { $time = $audio.prop('currentTime'); $audio.prop('currentTime', $time - 10); return; } // Navigate Grid or Images if ( $body.hasClass('has_audio') && !$content_grid.hasClass('has_grid') && $playing.length < 1 ) { playThis( $dir_list.find('.audio:not(.unchecked)').length - 1,'stop'); setContentHeight(); return; } else if ( $playing.length > 0 ) { prevTrack('stop'); setContentHeight(); return; } else if ( $selected.length < 1 || $selected.hasClass('dir') || firstRow().hasClass('selected') ) { if ( $body.hasClass('has_fonts') ) { navigateToThis( lastRow('.font') ); } else if ( $body.hasClass('has_images') ) { navigateToThis( lastRow('.image') ); } else { navigateToThis( lastRow() ); } } else if ( $selected.hasClass('image') ) { if ( prevRow('.image').length > 0 ) { navigateToThis( prevRow('.image') ); } else if ( lastRow('.font').length > 0 ) { navigateToThis( lastRow('.font') ); } else { navigateToThis( lastRow('.image') ) } } else if ( $selected.hasClass('font') ) { if ( prevRow('.font').length > 0 ) { navigateToThis( prevRow('.font') ); } else if ( lastRow('.image').length > 0 ) { navigateToThis( lastRow('.image') ); } else { navigateToThis( lastRow('.font') ) } } else { lastRow('.image').length ? navigateToThis( lastRow('.font') ) : navigateToThis( lastRow('.image') ); } scrollSidebar( $('tr.selected') ); if ( $content_pane.hasClass('has_grid_content') ) { scrollGrid( $('div.selected') ); } scrollSidebar( $('tr.selected') ); resetImage(); break; case 'ArrowRight': if ( (e.ctrl || e.metaKey) || ( e.ctrl && e.metaKey ) ) { return; } else if ( $('*[contentEditable="true"]').is(':focus') || $selected.hasClass('dir ignore') ) { return; } // Skip audio 30s if ( e.altKey && e.shiftKey ) { $time = $audio.prop('currentTime'); $audio.prop('currentTime', $time + 30); return; } // Skip audio 10s if ( e.altKey ) { $time = $audio.prop('currentTime'); $audio.prop('currentTime', $time + 10); return; } if ( $selected.hasClass('dir') && ( !$body.hasClass('has_audio') && !$content_pane.hasClass('has_grid_content') ) ) { $selected.find('a').trigger('dblclick'); return; } // Navigate Grid or Images if ( $body.hasClass('has_audio') && !$content_grid.hasClass('has_grid') && $playing.length < 1 ) { playThis(0,'stop'); return; } else if ( $playing.length > 0 ) { nextTrack('stop'); return; } else if ( $selected.length < 1 || $selected.hasClass('dir') || lastRow().hasClass('selected') ) { if ( $body.hasClass('has_images') ) { navigateToThis( firstRow('.image') ); } else if ( $body.hasClass('has_fonts') ) { navigateToThis( firstRow('.font') ); } else { navigateToThis( firstRow() ); } } else if ( $selected.hasClass('font') ) { if ( nextRow('.font').length > 0 ) { navigateToThis( nextRow('.font') ); } else if ( firstRow('.image').length > 0 ) { navigateToThis( firstRow('.image') ); } else { navigateToThis( firstRow('.font') ) } } else if ( $selected.hasClass('image') ) { if ( nextRow('.image').length > 0 ) { navigateToThis( nextRow('.image') ); } else if ( firstRow('.font').length > 0 ) { navigateToThis( firstRow('.font') ); } else { navigateToThis( firstRow('.image') ) } } else { firstRow('.image').length ? navigateToThis( firstRow('.image') ) : navigateToThis( firstRow('.font') ); } setContentHeight(); scrollSidebar( $('tr.selected') ); if ( $content_pane.hasClass('has_grid_content') ) { scrollGrid( $('div.selected') ); } resetImage(); break; case ' ': // space bar if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } // Play/pause audio if ( $body.hasClass('has_audio') && $body.hasClass('is_playing') ) { e.preventDefault(); playAudio('pause'); } else if ( $body.hasClass('has_audio') && $body.hasClass('is_paused') || $playing.length ) { e.preventDefault(); playAudio('play'); } break; case 'Enter': // Open directories (or ignore) if ( $selected.hasClass('app') && $settings.apps_as_dirs === false ) { break; } else { if ( $selected.hasClass('dir') ) { $selected.find('a').trigger('dblclick'); } else { $selected.find('a').click(); } } break; case 'A': case 'B': case 'C': case '': case 'E': case 'F': case '': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case '': case 'P': case 'Q': case '': case 'S': case 'T': case 'U': case 'V': case '': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case '': case 'e': case 'f': case '': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case '': case 'p': case 'q': case '': case 's': case 't': case 'u': case 'v': case '': case 'x': case 'y': case 'z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case 'd': // Toggle Invisibles with Command-i if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $details_btn.click(); } if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case 'g': // Show image Grid if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $grid_btn.click(); } if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case 'i': // Cmd/Ctrl + I: Toggle Invisibles if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); e.stopPropagation(); $inv_checkbox.find('input').click(); } if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case 'o': // Cmd/Ctrl + Shift + O: Open selected item in new window if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.shiftKey ) { window.open($selected_href); } break; case 'r': // Cmd/Ctrl + Shift + R: Refresh if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) ) { e.preventDefault(); $content_reload_btn.click(); } if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case 'w': // Close content pane if Close button visible with Cmd/Crtl + 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(); } if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } break; case '.': if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } // Increase font preview size if ( (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.shiftKey ) { $('#increase').click(); } break; case ',': if ( !e.metaKey && !e.ctrlKey && !e.altKey ) { alphaNav(e); } // Decrease 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 ***** // // ***** GRIDS ***** // const fontGridItems = function() { var $font_grid_items_arr = []; $dir_list_row.filter('.font').each(function() { let $this_link = $(this).find('a').attr('href'); let $font_family = thisText($(this)); if ( $font_family_arr.indexOf($font_family) == -1 ) { $font_family_arr.push($font_family); $font_preview_styles.append('@font-face { font-family: "'+ $font_family +'"; src: url("'+ $this_link +'"); }'); // only add style if it doesn't exist } $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; }; const imageGridItems = function() { var $image_grid_items_arr = []; $dir_list_row.filter('.image').each(function() { // $this_link = thisLink(this); let $this_link = thisLink(this); $this_ext = thisExt(this); let exts = $row_types.image.filter( ext => $.inArray(ext, $row_settings.ignore) == -1 ); if ( $.inArray( $this_ext, exts ) > -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; }; function showFontGrid() { $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); $content_grid.empty().append( fontGridItems() ); $content_grid.removeClass().addClass('has_font_grid'); } function showImageGrid() { $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); $content_grid.empty().append( imageGridItems() ); $content_grid.removeClass().addClass('has_image_grid'); } function showGrids() { $content_pane.removeClass('has_hidden_grid').addClass('has_grid_content'); $content_grid.empty().append( imageGridItems(), fontGridItems() ); $content_grid.removeClass().addClass('has_grid'); } $grid_btn.on('click', function(e) { e.stopPropagation(); resetGrid(); showGrids(); setContentTitle(); setContentHeight(); }); $('#show_image_grid').on('click', function(e) { e.stopPropagation(); resetGrid(); showImageGrid(); setContentTitle(); setContentHeight(); }); $('#show_font_grid').on('click', function(e) { e.stopPropagation(); resetGrid(); showFontGrid(); setContentTitle(); setContentHeight(); }); function hideGrid() { $content_pane.removeClass('has_grid_content').addClass('has_hidden_grid'); } function closeGrid() { $content_pane.removeClass('has_grid_content'); $content_grid.removeClass().empty().css({'font-size':'1em'}); } // GRID ITEMS // Grid Item Hover $content_grid.on('mouseenter','> div:not(.selected)',function() { thisRow($dir_list.find('a[href*="'+ thisLink(this) +'"]')).addClass('hovered'); }).on('mouseleave','> div:not(.selected)',function() { thisRow($dir_list.find('a[href*="'+ thisLink(this) +'"]')).removeClass('hovered'); }); // Dir_list_row hover and highlight corresponding grid item $dir_list_row.hover(function() { if ( $content_grid.is(':visible') ) { $content_grid.find('[href*="'+ thisLink(this) +'"]').closest('div').addClass('hovered'); } }, function() { if ( $content_grid.is(':visible') ) { $content_grid.find('.hovered').removeClass('hovered'); } }); // Show clicked grid item function gridItemClick(e) { e.preventDefault(); $dir_list.find('a[href*="'+ thisLink(this) +'"]').click(); } $content_grid.on('click','div[class*="item"],div[class*="item"] a', gridItemClick ); // ***** SCALE PREVIEW ITEMS ***** // var $em = parseInt(getComputedStyle(document.body).fontSize); // pts/em var $font_incr = 1.125; // scale factor for font size increase/decrease var $image_incr = 1.125; var $image_width; var $image_height; var $image_scale_factor; var $image_grid_item_size; var $grid_scale_factor; var fontSize = function(el) { return parseFloat(el.css('font-size')); }; function scaleFonts(incr, y) { if ( y === -1 ) { incr = 1/incr; } if ( $content_pane.hasClass('has_grid_content') && ( $content_grid.hasClass('has_font_grid') || $content_grid.hasClass('has_grid') ) ) { $content_grid.css({'font-size':( fontSize($content_grid)/$em * incr ) +'em'}); return; } if ( $content_pane.hasClass('has_font_content') ) { $content_font.css({'font-size':( fontSize($content_font)/$em * incr ) +'em'}); return; } } function scaleImages(incr, y) { if (y === -1 ) { incr = 1/incr; } if ( $content_pane.hasClass('has_image_content') && !$content_pane.hasClass('has_grid_content') ) { $image_width = parseFloat( $content_image.find('img').width() ) * incr; // increment image size $image_height = parseFloat( $content_image.find('img').height() ) * incr; // increment image size $image_scale_factor = parseFloat( $content_image.attr('data-image-scale-factor') ); // get scale factor $content_image.attr('data-image-scale-factor', parseFloat( $image_scale_factor ) * incr ).find('img').removeClass('zoom_img').css({'width':$image_width +'px', 'max-width':'none', 'max-height':'none','top':'0','transform':'translateY(0)'}); $content_image.scrollLeft( ( $image_width - $(window).width() )/2 ) ; if ( ( ( $image_height - $(window).height() )/2 ) > 0 ) { $content_image.scrollTop( ( $image_height - $(window).height() )/2 ); } return; } if ( $content_pane.hasClass('has_grid_content') && ( $content_grid.hasClass('has_image_grid') || $content_grid.hasClass('has_grid') ) ) { $image_grid_item_size = parseFloat( $('.image_grid_item').width() * incr); $grid_scale_factor = parseFloat( $content_grid.attr('data-grid-scale-factor') ); $content_grid.attr('data-grid-scale-factor', parseFloat( $grid_scale_factor ) * incr ).css({'grid-template-columns':'repeat(auto-fit, minmax('+ ($image_grid_item_size) +'px, 1fr))', 'grid-template-rows':'repeat(auto, minmax('+ ($image_grid_item_size) +'px))' }); $content_grid.find('.image_grid_item').css({'width':$image_grid_item_size +'px', 'height':$image_grid_item_size +'px'}); // grid items are square, so width = height $content_grid.find('img').css({'max-width':( $image_grid_item_size - $image_grid_item_size/8 ) +'px', 'max-height':( $image_grid_item_size - $image_grid_item_size/8) +'px'}); return; } } function scalePreviewItems(y) { // combine scaling into one function scaleImages( $image_incr, y ); scaleFonts( $font_incr, y ); } $('#scale').on('click','span',function() { if ( $(this).attr('id') === 'increase' ) { scalePreviewItems(1); } if ( $(this).attr('id') === 'decrease' ) { scalePreviewItems(-1); } }); function zoomImage(x,e) { $this_link = $(x).attr('src'); var $offset = $(x).offset(); var $this_width = $(x).width(); var $this_height = $(x).height(); $(x).toggleClass('zoom_img'); if ( $(x).attr('style') !== '' || $(x).attr('style') !== undefined ) { $(x).attr('style',''); } if ( $this_link !== undefined ) { getDimensions( $this_link, function( width, height ) { $content_image.scrollLeft( (e.pageX - $offset.left) * width/($this_width + 13) - ( e.pageX - $offset.left ) - 52 ) ; $content_image.scrollTop( (e.pageY - $offset.top) * height/($this_height + 13) - ( e.pageY - $offset.top ) - 52 ); }); } } $content_image.on('click', 'img', function(e) { zoomImage( this,e ) }); // ***** END SCALE PREVIEW ITEMS ***** // // ***** AUDIO CONTENT ***** // var $count = 0; var $playlist; var $shuffleList = []; var $next; var $task; function updatePlaylist() { $playlist = []; $dir_list_row.filter('.audio:not(.unchecked)').each(function() { $this_link = thisLink(this); $playlist.push($this_link); }); return $playlist; } function initShuffleList() { updatePlaylist(); $shuffleList = []; for ( let i = 0; i < $playlist.length; i += 1 ) { $shuffleList.push(i); } return $shuffleList; } function updateCount() { $count = $playing.index('.audio:not(.unchecked)'); } function toggleChecked(e) { e.stopPropagation(); $(this).blur(); thisRow(this).toggleClass('unchecked'); updateCount(); updatePlaylist(); initShuffleList(); } $dir_list_row.filter('.audio').on('click','input', toggleChecked ); function toggleAllChecked(e) { e.stopPropagation(); $dir_list_row.find('input').trigger('click'); updatePlaylist(); initShuffleList(); } $dir_list.find('#play_toggle').on('click', toggleAllChecked ); function loadAudio( count ) { var $this_track = $dir_list_row.filter('.audio:not(.unchecked)').eq(count); $audio.find('source').attr('src', thisLink($this_track) ); $audio.trigger('load'); selectThis( $this_track ); setContentTitle(); } function playAudio( task ) { // Trigger play or stop based on task if ( task === 'play' ) { $audio.trigger('play'); $body.removeClass('is_paused').addClass('is_playing'); } if ( task === 'pause' ) { $audio.trigger('pause'); $body.addClass('is_paused').removeClass('is_playing'); } if ( task === 'stop' ) { $audio.trigger('pause'); $audio.prop('currentTime',0); $body.addClass('is_paused').removeClass('is_playing'); } } function playThis( count, task ) { loadAudio( count ); playAudio( task ); // scrollSidebar( $('.playing')[0] ); scrollSidebar( document.getElementsByClassName('playing') ); } function playPause() { if ( $body.hasClass('is_playing') ) { playAudio('pause') }; if ( $body.hasClass('is_paused') ) { playAudio('play') }; // if ( $('.playing').hasClass('audio') ) { // for audio files only, for now // return $audio.get(0).paused ? $audio.get(0).play() : $audio.get(0).pause(); // } } function nextTrack(navTask) { $('.playing').length == 1 ? $playing = $('.playing') : $playing = $dir_list_row.filter('.audio:not(.unchecked)').first(); var $next_track = $playing.nextAll('.audio:not(.unchecked)').first(); var $next_track_index = $next_track.index('.audio:not(.unchecked)'); if ( $shuffle.find('input').prop('checked') ) { // shuffle shuffle(); } else if ( $playing.hasClass('unchecked') ) { // if playing is unchecked $next_track.length === 1 ? $count = $next_track_index : $count = 0; $task = 'play'; } else if ( $next_track.length !== 1 ) { // if no next track, loop to beginning $count = 0; $loop.find('input').prop('checked') === true ? $task = 'play' : $task = 'stop'; } else if ( $next_track.length === 1 ) { $count = $next_track_index; $task = 'play'; } if ( navTask == 'stop' ) { $task = 'stop'; } playThis($count, $task); navTask = ''; } function prevTrack(navTask) { $('.playing').length == 1 ? $playing = $('.playing') : $playing = $dir_list_row.filter('.audio:not(.unchecked)').first(); var $prev_track = $playing.prevAll('.audio:not(.unchecked)').first(); var $prev_track_index = $prev_track.index('.audio:not(.unchecked)'); if ( $shuffle.find('input').prop('checked') ) { // shuffle shuffle(); } else if ( $playing.hasClass('unchecked') ) { // if playing is unchecked $prev_track.length === 1 ? $count = $prev_track_index : $count = $playlist.length - 1; } else if ( $prev_track.length !== 1 ) { // loop to end and play $count = ($('.audio:not(.unchecked)').length - 1); $task = 'play'; } else if ( $prev_track.length != 1 ) { // loop to end and play $task = 'stop'; } else if ( $count > 0 ) { // play prev track $count = $prev_track_index; $task = 'play'; } if ( navTask == 'stop' ) { $task = 'stop'; } playThis( $count, $task ); navTask = ''; } // Prev/Next Track buttons $prev_track.on( 'click', prevTrack ); $next_track.on( 'click', nextTrack ); function toggleShuffle() { if ( $shuffle.find('input').prop('checked') ) { updatePlaylist(); initShuffleList(); $count = Math.floor( Math.random() * $shuffleList.length ); playThis($count,'stop'); } } $shuffle.on('click', toggleShuffle ); function shuffle() { if ( $shuffleList.length <= 1 && $loop.find('input').prop('checked') ) { // If loop is checked, and all songs have been shuffled... initShuffleList(); $next = Math.floor( Math.random() * $shuffleList.length ); // choose a random index number from the remaining unplayed songs, $count = $shuffleList[ $next ]; // set the playing $count to the index $task = 'play'; } else if ( $shuffleList.length === 0 ) { // else if all songs have been shuffled, select the first song and stop; $count = 0; $task = 'stop'; } else { $next = Math.floor( Math.random() * $shuffleList.length ); // else choose a random index number from the remaining unplayed songs, $count = $shuffleList[ $next ]; // set the playing $count to the index $shuffleList.splice( $next, 1 ); // remove the indexed value from the unplayed list, $task = 'play'; } } function initAudio() { if ( $body.hasClass('has_audio') ) { if ( $settings.autoload_audio === true ) { loadAudio(0); autoLoadCoverArt(); } $audio.on('ended', nextTrack ); } } initAudio(); function autoLoadCoverArt() { var $matched; var $image_titles = []; $dir_list_row.filter('.image').each(function() { $image_titles.push( thisText(this) ); }); // Find image file with name matching default cover art name for ( let i = 0; i < $image_titles.length; i++) { if ( $image_titles[i].match(/(cover\.|front\.)/) ) { $matched = $(document.getElementById('dir_list').getElementsByClassName('image').item(i)); $matched.addClass('selected'); showImage( $matched, thisLink( $matched ) ); return true; } } // If no default cover art found, select first image in dir, if any. if ( $('.selected').length < 1 && $dir_list_row.filter('.image').length > 0 ) { $matched = $(document.getElementById('dir_list').getElementsByClassName('image').item(0)); $matched.addClass('selected').siblings().removeClass('selected'); showImage( $matched, thisLink( $matched ) ); } } // ***** END AUDIO CONTENT ***** // // ***** OTHER FUNCTIONS ***** // // Resize Sidebar/Content Pane function resizeSidebar(f) { f.stopPropagation(); var $startX = f.pageX; var $sidebar_width = $sidebar_wrapper.width(); var $window_width = window.innerWidth; $sidebar_overlay.show(); // needed to prevent interactions with iframe $content_overlay.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() { $sidebar_overlay.hide(); // needed to prevent interactions with iframe $content_overlay.hide(); $sidebar_wrapper.css({'-webkit-user-select':'auto','-moz-user-select':'auto','user-select':'auto'}); $(document).off('mousemove'); // update URI query $sidebar_width = $sidebar_wrapper.width(); $query_prefs = getQueryPrefs(); $query_prefs.set('width',$sidebar_width); updateQuery(); }); } $handle.on('mousedown', resizeSidebar ); // EXPORT SETTINGS var $settings_string = unescape( $settings.toSource() ); $settings_string = $settings_string.replace('JSON.parse\(unescape\("\{','').replace('\}"))','').replace(/\/",/g,'",').replace(/\/"],/g,'"],').replace(/"(\w+?)":/g,'\n\n$1:\t'); var save = function(filename, data) { var blob = new Blob([data], {type: 'text/html'}); if ( window.navigator.msSaveOrOpenBlob ) { window.navigator.msSaveBlob( blob, filename ); } else { var elem = window.document.createElement('a'); elem.href = window.URL.createObjectURL(blob); elem.download = filename; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); URL.revokeObjectURL(blob); } }; $export_settings.on('click','a',function(e) { e.preventDefault(); save("settings.txt",$settings_string); }); })();