diff --git a/README.md b/README.md index bdbd44d..a41c062 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ ``` -![preview_dark](/screenshots/after_dark.png) -![preview_401](/screenshots/401_dark.png) - +![preview_auto-index-ondesktop](/screenshots/auto-index-desktop-light-dark.png) +![preview_auto-index-on-mobile](/screenshots/auto-index-mobile-dark-light.png) +![preview_error-401](/screenshots/401_dark.png) ## Features - Responsive design @@ -25,6 +25,8 @@ ## Requirements - Apache >= 2.4 +## Limitations +- On mobile, column headers are hidden so sorting is implicitly disabled ## Install diff --git a/assets/FOOTER.html b/assets/FOOTER.html index 45b93f6..fb2880e 100644 --- a/assets/FOOTER.html +++ b/assets/FOOTER.html @@ -3,7 +3,7 @@ diff --git a/assets/HEADER.html b/assets/HEADER.html index 77b8fb1..ed05763 100644 --- a/assets/HEADER.html +++ b/assets/HEADER.html @@ -7,15 +7,23 @@ - +

+
+
- +
+ + + +
diff --git a/assets/css/style.css b/assets/css/style.css index 83e369d..998c8d1 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -6,13 +6,11 @@ * |__/ |___/ * * This file is part of kristuff/apache-fancy-pages. - * v0.1.9 - Copyright (c) 2021-2022 Kristuff + * v0.2.1 - Copyright (c) 2021-2022 Kristuff * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - - :root { --color-bg: #ffffff; --color-highlight: #000000; @@ -22,41 +20,40 @@ --color-table-bg: whitesmoke; --color-table-bg--head: #161720; --color-table-bg--even: #e3e2e2; - --color-table-border :rgba(0,0,0,0.05); + --color-table-border: rgba(0, 0, 0, 0.05); --color-table-text: #222222; --color-table-header-text: #dadada; --color-link-text: #115293; --color-link-text--visited: #115293; + --color-button-hover: rgba(29, 155, 240, 0.1); } - @media (prefers-color-scheme: dark) { :root { - --color-bg:#1f242b; + --color-bg: #1f242b; --color-highlight: #ffffff; --color-text: #bbb; --color-text-light: #8a8a8a; --color-text-xlight: #5e5f6c; --color-table-bg: #282e37; - --color-table-bg--head:#171b20; - --color-table-bg--even: rgba(255,255,255,0.03); - --color-table-border :rgba(255,255,255,0.1); + --color-table-bg--head: #171b20; + --color-table-bg--even: rgba(255, 255, 255, 0.03); + --color-table-border: rgba(255, 255, 255, 0.1); --color-table-text: #bbbbbb; - --color-table-header-text:#eaeaea; + --color-table-header-text: #eaeaea; --color-link-text: #3499dd; --color-link-text--visited: #3499dd; } * { - scrollbar-color:#313137 #171b20; - + scrollbar-color: #313137 #171b20; } } -*, -*::after, +*, +*::after, *::before { - box-sizing: border-box; + box-sizing: border-box; } html { @@ -70,14 +67,12 @@ body { font-weight: 400; color: var(--color-text); background-color: var(--color-bg); - } img { border-style: none; } - button, input, optgroup, @@ -96,27 +91,29 @@ a { a:visited { color: var(--color-link-text--visited); } - + a:hover { text-decoration: underline; } - .row { - box-sizing:border-box; - margin:0 auto; - width:94%; + box-sizing: border-box; + margin: 0 auto; + width: 94%; } h1 { font-weight: 300; +} +tr.hidden, +.hidden { + display: none !important; } /* ------------------- */ /* -- SECTION TITLE -- */ /* ------------------- */ - section#section-title { margin: 12px 0; min-height: 60px; @@ -128,54 +125,129 @@ section#section-title h1 { color: var(--color-highlight); min-height: 28px; } + section#section-title div#breadcrumb { color: var(--color-text-xlight); - font-size: 0.77rem; - display: block; -} -section#section-title div#breadcrumb .separator { - margin: 0 6px; + font-size: 0.8rem; + display: flex; + align-items: center; + flex-wrap: wrap; + max-width: 100%; } + section#section-title div#breadcrumb a, section#section-title div#breadcrumb a:visited { color: var(--color-text-light); + padding: 6px; } + section#section-title div#breadcrumb a.active, section#section-title div#breadcrumb a.active:visited { color: var(--color-text-xlight); } +.search-wrapper { + display: flex; + align-items: center; + flex-direction: row; + width: 100%; + height: 36px; + position: relative; +} + +.search-wrapper .close-icon, +.search-wrapper .search-icon { + display: flex; + height: 100%; + position: absolute; +} + +.search-wrapper .close-icon::before, +.search-wrapper .search-icon::before { + content: ""; + display: inline-flex; + align-items: center; + width: 20px; + height: 100%; + background-color: var(--color-text-light); + mask-position: center; + mask-size: contain; + mask-repeat: no-repeat; +} + +.search-wrapper .search-icon::before { + margin-left: 12px; + mask-image: url('data:image/svg+xml,'); +} + +.search-wrapper .close-icon::before { + background-color: var(--color-link-text); + mask-image: url('data:image/svg+xml,'); +} + +.search-wrapper input, +.search-wrapper input[type=text] { + width: 100%; + padding-left: 36px; + height: 100%; + border-radius: 100em; +} + +.search-wrapper button.close-search { + position: absolute; + right: 6px; + border-radius: 50%; + width: 28px; + height: 28px; + display: flex; + border: none; + background: none; + outline: none; + cursor: pointer; +} + +.search-wrapper button.close-search:focus { + outline: 2px solid var(--color-link-text); +} + +.search-wrapper button.close-search:not(.active) { + display: none; +} +.search-wrapper button.close-search:hover { + background: var(--color-button-hover); +} input#filter { - border:1px solid var(--color-table-border) ; + border: 1px solid var(--color-table-border); background-color: var(--color-table-bg--even); outline: 0; display: block; width: 100%; - margin:10px 0 6px 0; - color:var(--color-text); - padding: 5px; -} + color: var(--color-text); +} input#filter:focus, input#filter:focus-visible { - border-color:var(--color-link-text); + border-color: var(--color-link-text); box-shadow: inset 0 1px 1px rgba(var(--color-link-text), 0.075), 0 0 8px rgba(var(--color-link-text), 0.6); } +input#filter:focus+.search-icon::before, +input#filter:focus-visible+.search-icon::before { + background-color: var(--color-link-text); +} /* --------------------- */ /* -- SECTION CONTENT -- */ /* --------------------- */ - /** table index */ table#indexlist { width: 100%; - background: var(--color-table-bg); border: 0; table-layout: auto; border-collapse: collapse; + border-radius: 12px; } /** tableIndex: hide break row */ @@ -188,13 +260,14 @@ table#indexlist tr th.indexcolicon, table#indexlist tr td.indexcolicon { max-width: 45px; width: 45px; - padding-left: 0!important; - padding-right: 0!important; + padding-left: 0 !important; + padding-right: 0 !important; text-align: center; } + table#indexlist tr th.indexcolname, table#indexlist tr td.indexcolname { - padding-left: 0!important; + padding-left: 0 !important; } /** tableIndex: content */ @@ -205,7 +278,7 @@ table#indexlist tr td { color: var(--color-table-text); text-align: left; line-height: 1.125rem; - word-break:break-all; + word-break: break-all; } /** tableIndex: header */ @@ -213,38 +286,44 @@ table#indexlist tr.indexhead th { padding: 0.5rem 0.625rem 0.625rem; font-weight: bold; position: sticky; - top:0; + top: 0; background-color: var(--color-table-bg--head); } + table#indexlist tr.indexhead th a, table#indexlist tr.indexhead th a:visited { color: var(--color-table-header-text); } + table#indexlist tr td.indexcolname a, table#indexlist tr td.indexcolname a:visited { color: var(--color-highlight); } -table#indexlist tr[class*="dir"] td.indexcolname a { + +table#indexlist tr[class*=dir] td.indexcolname a { font-weight: 600; } table#indexlist .sorticon { margin-left: 6px; - color:var(--color-table-header-text); + color: var(--color-table-header-text); } -/** -table#indexlist tr { - background: var(--color-table-bg--even); - border-bottom: 1px solid var(--color-table-border); +table#indexlist tr.no-items td { + padding: 15px; + color: var(--color-text-light); } -*/ -/** tableIndex: alternative row style */ -table#indexlist tr:not(.indexhead):nth-child(even) { - background: var(--color-table-bg--even); +table#indexlist tr.no-items td { + text-align: center; } +/** + table#indexlist tr { + background: var(--color-table-bg--even); + border-bottom: 1px solid var(--color-table-border); + } + */ /* Adjust padding according to footer height (~50px) */ section#section-content { padding-bottom: 50px; @@ -253,8 +332,6 @@ section#section-content { /* -------------------- */ /* -- SECTION FOOTER -- */ /* -------------------- */ - - /* Fixed footer */ footer#section-footer { position: fixed; @@ -262,10 +339,11 @@ footer#section-footer { left: 0; right: 0; padding: 15px 0 10px 0; - color: var(--color-text-xlight); + color: var(--color-text-xlight); background-color: var(--color-bg); font-size: 0.75rem; } + footer#section-footer p { margin: 0; margin-top: 6px; @@ -273,46 +351,102 @@ footer#section-footer p { footer#section-footer a, footer#section-footer a:visited { - color: var(--color-text-xlight) ; + color: var(--color-text-xlight); text-decoration: underline; } + footer#section-footer a:hover { - color: var(--color-text) ; + color: var(--color-text); } footer#section-footer .row { border-top: 1px solid var(--color-text-xlight); } +@media (max-width: 400px) { + h1 { + font-size: 1.375em; + } +} + +@media (max-width: 767px) { + /** tableIndex: alternative row style */ + table#indexlist tr:not(.even-parentdir):not(.no-items):not(:first-of-type) { + border-bottom: 1px solid var(--color-table-border); + } + section#section-title div#breadcrumb { + padding-bottom: 6px; + } -@media only screen and (min-width:768px) { - .row{ - width:96%; + /* reduce icon width */ + table#indexlist tr th.indexcolicon, + table#indexlist tr td.indexcolicon { + max-width: 35px; + width: 35px; } + table#indexlist tr.indexhead th.indexcolicon, + table#indexlist tr.indexhead th.indexcolname, + table#indexlist tr.indexhead th.indexcollastmod, + table#indexlist tr.indexhead th.indexcoldesc, + table#indexlist tr.indexhead th.indexcolsize, + table#indexlist tr.even-parentdir td.indexcollastmod, + table#indexlist tr.even-parentdir td.indexcoldesc, + table#indexlist tr.even-parentdir td.indexcolsize { + display: none !important; + } - section#section-title div#breadcrumb { - display: inline-block; - max-width: calc(100% - 250px); + table#indexlist tr.even-parentdir td { + background-color: var(--color-table-bg--head); + color: var(--color-table-header-text); } - input#filter { - float: right; - width: 200px; - margin:0; - margin-top: -10px; - padding: 6px; + + table#indexlist tr.even-parentdir td.indexcolname a, + table#indexlist tr.even-parentdir td.indexcolname a:visited { + color: var(--color-table-header-text); + } + + table#indexlist th.indexcolname, + table#indexlist td.indexcolname { + border-top-right-radius: 9px; + border-bottom-right-radius: 9px; } -} + table#indexlist th.indexcolicon, + table#indexlist td.indexcolicon { + border-top-left-radius: 9px; + border-bottom-left-radius: 9px; + } -@media (max-width: 700px) { - /* Hide extra columns so they don't squash file names */ - .indexcollastmod, - .indexcoldesc, - .indexcolsize { - display: none; + table#indexlist tr.even-parentdir td.indexcolname { + padding-top: 15px; + padding-bottom: 15px; + } + + table#indexlist tr th.indexcolname, + table#indexlist tr td.indexcolname { + padding-left: 0 !important; + } + + table#indexlist tr:not(.even-parentdir) td.indexcolname { + display: block; + padding-bottom: 0; + font-weight: 600; + } + + table#indexlist tr td.indexcollastmod, + table#indexlist tr td.indexcoldesc, + table#indexlist tr td.indexcolsize { + display: inline-flex; + color: var(--color-text-light) !important; + font-size: 13px !important; + padding-left: 0 !important; + line-height: 1.1; + padding: 0; + padding-right: 6px !important; + padding-bottom: 8px !important; } h1 { @@ -321,12 +455,43 @@ footer#section-footer .row { footer#section-footer { text-align: center; + padding: 6px 0 10px 0; } - } -@media (max-width: 400px) { - h1 { - font-size: 1.375em; +@media only screen and (min-width: 768px) { + .row { + width: 96%; } -} + + .row.flex { + display: flex; + align-items: center; + } + + table#indexlist tr th.indexcolicon, + table#indexlist tr td.indexcolicon { + border-bottom-left-radius: 9px; + border-top-left-radius: 9px; + } + + table#indexlist tr th.indexcoldesc, + table#indexlist tr td.indexcoldesc { + border-top-right-radius: 9px; + border-bottom-right-radius: 9px; + } + + section#section-title div#breadcrumb { + width: calc(100% - 250px); + } + + .search-wrapper { + width: 230px; + margin-left: auto; + } + + /** tableIndex: alternative row style */ + table#indexlist tr:not(.indexhead):not(.hidden):nth-child(even) td { + background: var(--color-table-bg--even); + } +} \ No newline at end of file diff --git a/assets/js/script.js b/assets/js/script.js index 12ec626..2dec086 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -6,7 +6,7 @@ * |__/ |___/ * * This file is part of kristuff/apache-fancy-pages. - * v0.1.9 - Copyright (c) 2021-2022 Kristuff + * v0.2.1 - Copyright (c) 2021-2022 Kristuff * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -15,7 +15,9 @@ (function(document) { 'use strict'; - // support for document ready + /** + * Support for document ready + */ function documentReady(fn) { if (document.readyState != 'loading') { fn(); @@ -24,14 +26,23 @@ } } - // Underscore string's titleize. + /** + * Underscore string's titleize. + */ function titleize(str) { return decodeURI(str).toLowerCase().replace(/(?:^|\s|-)\S/g, c => c.toUpperCase()); } - + + /** + * Set the title and build breadcrumb according to + * current location. + */ function setTitle() { - let cleanPath = window.location.pathname.replace(/\/$/g, ''); - let titleText, breadcrumbHtml = '', index = 0, origin = window.location.origin + '/'; + let cleanPath = window.location.pathname.replace(/\/$/g, ''), + titleText, + breadcrumbHtml = '', + index = 0, + origin = window.location.origin + '/'; if (cleanPath) { let parts = cleanPath.split('/'); @@ -65,9 +76,11 @@ document.title = titleText; } - // Add sort icon according to query search - // use ▴ for ascending and ▾ for descending - // https://ux.stackexchange.com/questions/37564/use-up-or-down-arrow-to-represent-sort-ascending-at-table-header + /** + * Add sort icon according to query search. + * Use ▴ for ascending and ▾ for descending + * @see https://ux.stackexchange.com/questions/37564/use-up-or-down-arrow-to-represent-sort-ascending-at-table-header + */ function setSortIcon(){ let args = window.location.search; let sortIcon = '▴'; @@ -82,40 +95,74 @@ } } - // table filtering - var tableFilter = (function(Arr) { + /** + * Handle search input change. + */ + function onSearchInputChange(e) { + + let input = e.target, + closeButton = document.querySelector('.close-search'), + hidden = 0, + matchs = 0, + val = input.value.toLowerCase(), + rowNoItem = document.querySelector('table#indexlist tBody tr.no-items'); + + if (!rowNoItem){ + let row = document.createElement('tr'); + row.classList.add('no-items'); + row.innerHTML = 'No matching items'; + document.querySelector('table#indexlist tBody').appendChild(row); + rowNoItem = row; + } + if (val.length == 0){ + cleanSearch(); + return; + } - var _input; + document.querySelectorAll('table#indexlist tBody tr').forEach(row => { + if (row.classList.contains('indexbreakrow') || row.classList.contains('indexhead')) { + return; + } - function _onInputEvent(e) { - _input = e.target; - var tableBody = document.querySelector('table#indexlist tBody'); - Arr.forEach.call(tableBody.rows, _filter); - } + let text = row.textContent.toLowerCase(); + if (text.indexOf(val) === -1 || row.classList.contains('even-parentdir')) { + row.classList.add('hidden'); + hidden++; + } else { + row.classList.remove('hidden'); + matchs++; + } + }); - function _filter(row) { - var text = row.textContent.toLowerCase(), val = _input.value.toLowerCase(); - if (row.classList.contains('indexbreakrow') || row.classList.contains('indexhead')) return; - row.style.display = text.indexOf(val) === -1 ? 'none' : 'table-row'; - } + closeButton.classList.toggle('active', val.length > 0) + rowNoItem.classList.toggle('hidden', matchs > 0) - return { - init: function() { - var input = document.querySelector('input#filter'); - if (input) { - input.oninput = _onInputEvent; - } - } - }; - })(Array.prototype); + } + /** + * Clean search and restore filtered elements. + */ + function cleanSearch() { + document.querySelectorAll('table#indexlist tBody tr').forEach(element => { + if (element.classList.contains('no-items')){ + element.classList.add('hidden'); + } else { + element.classList.remove('hidden'); + } + }); + document.querySelector('.close-search').classList.remove('active'); + document.querySelector('input#filter').value = ''; + document.querySelector('input#filter').focus(); + } - // Go + /** + * Start + */ documentReady(function(){ setTitle(); setSortIcon(); - tableFilter.init(); + document.querySelector('input#filter').addEventListener('input', onSearchInputChange); + document.querySelector('.close-search').addEventListener('click', cleanSearch); }); })(document); - diff --git a/conf/fancy-error.conf b/conf/fancy-error.conf index 2b08648..986f1e0 100644 --- a/conf/fancy-error.conf +++ b/conf/fancy-error.conf @@ -5,7 +5,7 @@ # |__/ |___/ # # This file is part of kristuff/apache-fancy-pages. -# Version 0.1.9 +# Version 0.2.1 # Copyright (c) 2021-2022 Kristuff # # For the full copyright and license information, please view the LICENSE diff --git a/conf/fancy-index-tests.conf b/conf/fancy-index-tests.conf index b6ac1d7..c2e5a10 100644 --- a/conf/fancy-index-tests.conf +++ b/conf/fancy-index-tests.conf @@ -5,7 +5,7 @@ # |__/ |___/ # # This file is part of kristuff/apache-fancy-pages. -# Version 0.1.9 +# Version 0.2.1 # Copyright (c) 2021-2022 Kristuff # # For the full copyright and license information, please view the LICENSE diff --git a/conf/fancy-index.conf b/conf/fancy-index.conf index a51114b..0d589b9 100644 --- a/conf/fancy-index.conf +++ b/conf/fancy-index.conf @@ -5,7 +5,7 @@ # |__/ |___/ # # This file is part of kristuff/apache-fancy-pages. -# Version 0.1.9 +# Version 0.2.1 # Copyright (c) 2021-2022 Kristuff # # For the full copyright and license information, please view the LICENSE diff --git a/create_package.sh b/create_package.sh index a073f3a..c8a6183 100644 --- a/create_package.sh +++ b/create_package.sh @@ -7,7 +7,7 @@ # |__/ |___/ # # This file is part of kristuff/apache-fancy-pages. -# v0.1.9 - Copyright (c) 2021-2022 Kristuff +# v0.2.1 - Copyright (c) 2021-2022 Kristuff # # For the full copyright and license information, please view the LICENSE # file that was distributed with this source code. diff --git a/deb/changelog b/deb/changelog index 9377eda..1840b48 100644 --- a/deb/changelog +++ b/deb/changelog @@ -1,3 +1,17 @@ +apache-fancy-pages (0.2.1) unstable; urgency=medium + + * Fixed: close search button never display + + -- kristuff Sun, 25 Sep 2022 20:00:00 +0200 + +apache-fancy-pages (0.2) unstable; urgency=medium + + * Fixed: update style with some border radius, improve + display on mobile + * Added: search icon and dymanic close search button + + -- kristuff Sun, 25 Sep 2022 19:00:00 +0200 + apache-fancy-pages (0.1.10) unstable; urgency=medium * Fixed: reverse inverted sort icon diff --git a/deb/control b/deb/control index b475433..da0d262 100644 --- a/deb/control +++ b/deb/control @@ -1,5 +1,5 @@ Package: apache-fancy-pages -Version: 0.1.10 +Version: 0.2.1 Maintainer: kristuff Architecture: all Depends: apache2 diff --git a/screenshots/Apache-Fancy-pages_auto-index-filter.mp4 b/screenshots/Apache-Fancy-pages_auto-index-filter.mp4 new file mode 100644 index 0000000..b812d61 Binary files /dev/null and b/screenshots/Apache-Fancy-pages_auto-index-filter.mp4 differ diff --git a/screenshots/auto-index-desktop-dark.png b/screenshots/auto-index-desktop-dark.png new file mode 100644 index 0000000..c03c4c9 Binary files /dev/null and b/screenshots/auto-index-desktop-dark.png differ diff --git a/screenshots/auto-index-desktop-light-dark.png b/screenshots/auto-index-desktop-light-dark.png new file mode 100644 index 0000000..b45a381 Binary files /dev/null and b/screenshots/auto-index-desktop-light-dark.png differ diff --git a/screenshots/auto-index-desktop-light.png b/screenshots/auto-index-desktop-light.png new file mode 100644 index 0000000..14f6712 Binary files /dev/null and b/screenshots/auto-index-desktop-light.png differ diff --git a/screenshots/auto-index-mobile-dark-light.png b/screenshots/auto-index-mobile-dark-light.png new file mode 100644 index 0000000..4e60910 Binary files /dev/null and b/screenshots/auto-index-mobile-dark-light.png differ diff --git a/screenshots/auto-index-mobile-dark.png b/screenshots/auto-index-mobile-dark.png new file mode 100644 index 0000000..698b74a Binary files /dev/null and b/screenshots/auto-index-mobile-dark.png differ diff --git a/screenshots/auto-index-mobile-light.png b/screenshots/auto-index-mobile-light.png new file mode 100644 index 0000000..2fece66 Binary files /dev/null and b/screenshots/auto-index-mobile-light.png differ diff --git a/tests/folder_C-H/composer.json b/tests/folder_C-H/composer.json new file mode 100644 index 0000000..e69de29