├── .eslintignore ├── src ├── _h5ai │ ├── public │ │ ├── js │ │ │ ├── scripts.js │ │ │ ├── lib │ │ │ │ ├── core │ │ │ │ │ ├── langs.js │ │ │ │ │ ├── settings.js │ │ │ │ │ ├── store.js │ │ │ │ │ ├── event.js │ │ │ │ │ ├── resource.js │ │ │ │ │ ├── types.js │ │ │ │ │ └── format.js │ │ │ │ ├── ext │ │ │ │ │ ├── preview │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── preview-aud.js │ │ │ │ │ │ ├── preview-vid.js │ │ │ │ │ │ ├── preview-img.js │ │ │ │ │ │ └── preview-txt.js │ │ │ │ │ ├── title.js │ │ │ │ │ ├── autorefresh.js │ │ │ │ │ ├── google-analytics.js │ │ │ │ │ ├── custom.js │ │ │ │ │ ├── piwik-analytics.js │ │ │ │ │ ├── crumb.js │ │ │ │ │ ├── download.js │ │ │ │ │ ├── filter.js │ │ │ │ │ ├── search.js │ │ │ │ │ ├── sort.js │ │ │ │ │ ├── thumbnails.js │ │ │ │ │ ├── l10n.js │ │ │ │ │ └── info.js │ │ │ │ ├── util │ │ │ │ │ ├── index.js │ │ │ │ │ ├── misc.js │ │ │ │ │ ├── lo.js │ │ │ │ │ └── naturalCmp.js │ │ │ │ ├── config.js │ │ │ │ ├── view │ │ │ │ │ ├── notification.js │ │ │ │ │ ├── base.js │ │ │ │ │ ├── sidebar.js │ │ │ │ │ └── viewmode.js │ │ │ │ ├── init.js │ │ │ │ ├── main │ │ │ │ │ └── index.js │ │ │ │ └── server.js │ │ │ └── pre.js │ │ ├── images │ │ │ ├── fallback │ │ │ │ ├── file.png │ │ │ │ ├── folder.png │ │ │ │ └── folder-parent.png │ │ │ ├── favicon │ │ │ │ ├── favicon-16.png │ │ │ │ ├── favicon-32.png │ │ │ │ ├── favicon-152.png │ │ │ │ ├── favicon-16-32.ico │ │ │ │ └── favicon.svg │ │ │ ├── themes │ │ │ │ ├── default │ │ │ │ │ ├── aud.svg │ │ │ │ │ ├── vid.svg │ │ │ │ │ ├── folder.svg │ │ │ │ │ ├── x.svg │ │ │ │ │ ├── file.svg │ │ │ │ │ ├── ar.svg │ │ │ │ │ ├── folder-page.svg │ │ │ │ │ ├── txt.svg │ │ │ │ │ ├── folder-parent.svg │ │ │ │ │ ├── img.svg │ │ │ │ │ └── bin.svg │ │ │ │ ├── comity │ │ │ │ │ ├── txt-md.svg │ │ │ │ │ ├── txt-rb.svg │ │ │ │ │ ├── ar-apk.svg │ │ │ │ │ ├── txt-script.svg │ │ │ │ │ ├── txt-php.svg │ │ │ │ │ ├── txt-html.svg │ │ │ │ │ ├── txt-css.svg │ │ │ │ │ ├── txt-py.svg │ │ │ │ │ ├── txt-js.svg │ │ │ │ │ ├── x-pdf.svg │ │ │ │ │ ├── txt-less.svg │ │ │ │ │ ├── txt-rust.svg │ │ │ │ │ ├── ar-rpm.svg │ │ │ │ │ └── ar-deb.svg │ │ │ │ └── README.md │ │ │ └── ui │ │ │ │ ├── crumb.svg │ │ │ │ ├── sort.svg │ │ │ │ ├── download.svg │ │ │ │ ├── preview-next.svg │ │ │ │ ├── preview-prev.svg │ │ │ │ ├── preview-raw.svg │ │ │ │ ├── selected.svg │ │ │ │ ├── sidebar.svg │ │ │ │ ├── tree-indicator.svg │ │ │ │ ├── view-details.svg │ │ │ │ ├── back.svg │ │ │ │ ├── view-icons.svg │ │ │ │ ├── preview-fullscreen.svg │ │ │ │ ├── preview-no-fullscreen.svg │ │ │ │ ├── preview-close.svg │ │ │ │ ├── view-grid.svg │ │ │ │ ├── tree-toggle.svg │ │ │ │ ├── info-toggle.svg │ │ │ │ ├── spinner.svg │ │ │ │ ├── filter.svg │ │ │ │ ├── search.svg │ │ │ │ └── paypal.svg │ │ ├── css │ │ │ ├── lib │ │ │ │ ├── view │ │ │ │ │ ├── content.less │ │ │ │ │ ├── mainrow.less │ │ │ │ │ ├── notification.less │ │ │ │ │ ├── root.less │ │ │ │ │ ├── view-grid.less │ │ │ │ │ ├── view-icons.less │ │ │ │ │ ├── topbar.less │ │ │ │ │ ├── view.less │ │ │ │ │ ├── fallback.less │ │ │ │ │ ├── view-details.less │ │ │ │ │ └── sidebar.less │ │ │ │ ├── ext │ │ │ │ │ ├── preview-aud.less │ │ │ │ │ ├── preview-vid.less │ │ │ │ │ ├── custom.less │ │ │ │ │ ├── filter.less │ │ │ │ │ ├── search.less │ │ │ │ │ ├── preview-txt.less │ │ │ │ │ ├── preview-img.less │ │ │ │ │ ├── info.less │ │ │ │ │ ├── crumb.less │ │ │ │ │ ├── contextmenu.less │ │ │ │ │ ├── select.less │ │ │ │ │ ├── tree.less │ │ │ │ │ └── preview.less │ │ │ │ ├── fonts.less │ │ │ │ ├── misc.less │ │ │ │ ├── responsive.less │ │ │ │ ├── colors.less │ │ │ │ ├── mixins.less │ │ │ │ └── main │ │ │ │ │ └── info.less │ │ │ └── styles.less │ │ ├── ext │ │ │ └── README.md │ │ ├── cache │ │ │ └── README.md │ │ ├── .htaccess │ │ └── index.php │ └── private │ │ ├── php │ │ ├── pages │ │ │ ├── index.php.pug │ │ │ ├── info.php.pug │ │ │ └── page.tpl.pug │ │ ├── core │ │ │ ├── class-session.php │ │ │ ├── class-logger.php │ │ │ ├── class-theme.php │ │ │ ├── class-request.php │ │ │ ├── class-fallback.php │ │ │ ├── class-json.php │ │ │ ├── class-filesize.php │ │ │ ├── class-item.php │ │ │ ├── class-util.php │ │ │ └── class-api.php │ │ ├── ext │ │ │ ├── class-search.php │ │ │ └── class-custom.php │ │ └── class-bootstrap.php │ │ ├── cache │ │ └── README.md │ │ └── conf │ │ ├── l10n │ │ ├── sk.json │ │ ├── tr.json │ │ ├── nb.json │ │ ├── ro.json │ │ ├── sr.json │ │ ├── hu.json │ │ ├── sv.json │ │ ├── he.json │ │ ├── da.json │ │ ├── hi.json │ │ ├── af.json │ │ ├── fi.json │ │ ├── hr.json │ │ ├── sl.json │ │ ├── bg.json │ │ ├── it.json │ │ ├── ja.json │ │ ├── pt.json │ │ ├── uk.json │ │ ├── cs.json │ │ ├── el.json │ │ ├── ko.json │ │ ├── ru.json │ │ ├── zh-cn.json │ │ ├── zh-tw.json │ │ ├── de.json │ │ ├── et.json │ │ ├── nl.json │ │ ├── pl.json │ │ ├── lv.json │ │ ├── es.json │ │ ├── fr.json │ │ └── en.json │ │ └── types.json └── .eslintrc ├── .gitignore ├── test ├── tests │ ├── premisses.js │ └── unit │ │ ├── core │ │ ├── event.js │ │ └── format.js │ │ └── util │ │ ├── naturalCmp.js │ │ └── parsePatten.js ├── index.html ├── index.js └── util │ └── pin.js ├── .editorconfig ├── package.json └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | **/vendor 4 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/scripts.js: -------------------------------------------------------------------------------- 1 | require('./lib/init'); 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | local 3 | node_modules 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: 1 4 | prefer-reflect: 0 5 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/langs.js: -------------------------------------------------------------------------------- 1 | const {langs} = require('../config'); 2 | module.exports = Object.assign({}, langs); 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/fallback/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/fallback/file.png -------------------------------------------------------------------------------- /src/_h5ai/public/images/fallback/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/fallback/folder.png -------------------------------------------------------------------------------- /src/_h5ai/public/images/favicon/favicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/favicon/favicon-16.png -------------------------------------------------------------------------------- /src/_h5ai/public/images/favicon/favicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/favicon/favicon-32.png -------------------------------------------------------------------------------- /src/_h5ai/public/images/favicon/favicon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/favicon/favicon-152.png -------------------------------------------------------------------------------- /src/_h5ai/public/images/favicon/favicon-16-32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/favicon/favicon-16-32.ico -------------------------------------------------------------------------------- /src/_h5ai/public/images/fallback/folder-parent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0oVicero0/h5ai/HEAD/src/_h5ai/public/images/fallback/folder-parent.png -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/view/content.less: -------------------------------------------------------------------------------- 1 | #content { 2 | overflow: auto; 3 | flex: 1 1 auto; 4 | order: 50; 5 | position: relative; 6 | } 7 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/view/mainrow.less: -------------------------------------------------------------------------------- 1 | #mainrow { 2 | .flex-row; 3 | flex: 1 1 auto; 4 | order: 50; 5 | 6 | height: 0; // non-webkit fix; 7 | } 8 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/preview-aud.less: -------------------------------------------------------------------------------- 1 | #pv-content-aud { 2 | .raised; 3 | 4 | position: absolute; 5 | 6 | max-width: 100%; 7 | max-height: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/aud.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/vid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/preview/index.js: -------------------------------------------------------------------------------- 1 | require('./preview'); 2 | require('./preview-aud'); 3 | require('./preview-img'); 4 | require('./preview-txt'); 5 | require('./preview-vid'); 6 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/util/index.js: -------------------------------------------------------------------------------- 1 | module.exports = Object.assign({}, 2 | require('./lo'), 3 | require('./dom'), 4 | require('./naturalCmp'), 5 | require('./misc') 6 | ); 7 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/favicon/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/ar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/config.js: -------------------------------------------------------------------------------- 1 | const {request} = require('./server'); 2 | 3 | const config = module.exports = { 4 | _update: query => request(query).then(resp => Object.assign(config, resp)) 5 | }; 6 | -------------------------------------------------------------------------------- /src/_h5ai/public/ext/README.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | This directory is used for additional script and style files. You have to add 4 | them manualy to the `resources` section in `_h5ai/private/conf/options.json`. 5 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/folder-page.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/txt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/folder-parent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/img.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/settings.js: -------------------------------------------------------------------------------- 1 | const config = require('../config'); 2 | 3 | module.exports = Object.assign({}, config.options, { 4 | publicHref: config.setup.PUBLIC_HREF, 5 | rootHref: config.setup.ROOT_HREF 6 | }); 7 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/crumb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/sort.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /test/tests/premisses.js: -------------------------------------------------------------------------------- 1 | const {test, assert} = require('scar'); 2 | 3 | test('window is global object', () => { 4 | assert.ok(global.window); 5 | assert.equal(global.window, global.window.window); 6 | assert.ok(global.window.document); 7 | }); 8 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/pages/index.php.pug: -------------------------------------------------------------------------------- 1 | extends ./page.tpl.pug 2 | 3 | block init 4 | - var title = `index - powered by h5ai v${pkg.version} (${pkg.homepage})` 5 | - var module = 'index' 6 | 7 | block body 8 | div#fallback 9 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-next.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-prev.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-raw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/selected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/tree-indicator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/fonts.less: -------------------------------------------------------------------------------- 1 | @font-family: "Ubuntu", "Roboto", "Helvetica", "Arial", "sans-serif"; 2 | @font-weight: normal; 3 | @font-size: 13px; 4 | @font-family-mono: "Ubuntu Mono", "Monaco", "Lucida Sans Typewriter", "monospace"; 5 | @font-size-mono: 15px; 6 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/view-details.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/view-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/pages/info.php.pug: -------------------------------------------------------------------------------- 1 | extends ./page.tpl.pug 2 | 3 | block init 4 | - var title = `h5ai info page - v${pkg.version}` 5 | - var module = 'info' 6 | 7 | block body 8 | div#content 9 | h1#header 10 | a(href=pkg.homepage) h5ai 11 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | h5ai test suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/preview-vid.less: -------------------------------------------------------------------------------- 1 | #pv-content-vid { 2 | .raised; 3 | 4 | position: absolute; 5 | 6 | max-width: 100%; 7 | max-height: 100%; 8 | } 9 | 10 | #pv-content-vid:-webkit-full-screen { 11 | top: auto !important; 12 | left: auto !important; 13 | } 14 | -------------------------------------------------------------------------------- /src/_h5ai/public/cache/README.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | Public cache. 4 | 5 | This directory is used for server side caching. To use caching make this 6 | directory writable for your webserver. 7 | 8 | There is no critical data in here. You can savely remove any content. This 9 | will clear the cache. 10 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-no-fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/private/cache/README.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | Private cache. 4 | 5 | This directory is used for server side caching. To use caching make this 6 | directory writable for your webserver. 7 | 8 | There is no critical data in here. You can savely remove any content. This 9 | will clear the cache. 10 | -------------------------------------------------------------------------------- /src/_h5ai/public/.htaccess: -------------------------------------------------------------------------------- 1 | ## make this folder accessible 2 | 3 | # Apache < 2.3 4 | 5 | Order allow,deny 6 | Allow from all 7 | Satisfy All 8 | 9 | 10 | # Apache ≥ 2.3 11 | 12 | Require all granted 13 | 14 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-md.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/preview-close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/view-grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/styles.less: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | // @include "../../../../node_modules/normalize.css/normalize.css" 4 | 5 | // @include "lib/colors.less" 6 | // @include "lib/fonts.less" 7 | // @include "lib/misc.less" 8 | // @include "lib/mixins.less" 9 | 10 | // @include "lib/*/*.less" 11 | 12 | // @include "lib/responsive.less" 13 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/tree-toggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/sk.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "slovenčina", 3 | 4 | "details": "podrobnosti", 5 | "empty": "prázdny", 6 | "files": "súborov", 7 | "folders": "priečinkov", 8 | "icons": "ikony", 9 | "lastModified": "Upravené", 10 | "name": "Názov", 11 | "parentDirectory": "Nadriadený priečinok", 12 | "size": "Velkosť" 13 | } 14 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/info-toggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "türkçe", 3 | 4 | "details": "detaylar", 5 | "download": "indir", 6 | "empty": "boş", 7 | "files": "dosyalar", 8 | "folders": "klasörler", 9 | "icons": "ikonlar", 10 | "lastModified": "Son Düzenleme", 11 | "name": "İsim", 12 | "parentDirectory": "Üst Dizin", 13 | "size": "Boyut" 14 | } 15 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/view/notification.less: -------------------------------------------------------------------------------- 1 | #notification { 2 | position: fixed; 3 | left: 50%; 4 | width: 200px; 5 | margin-left: -100px; 6 | z-index: 100; 7 | padding: 3px 6px 6px 6px; 8 | color: @col-text-primary-white; 9 | background: rgba(0,0,0,0.2); 10 | border-radius: 0 0 4px 4px; 11 | text-align: center; 12 | overflow: hidden; 13 | } 14 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/nb.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "norwegian", 3 | 4 | "details": "detaljer", 5 | "download": "last ned", 6 | "empty": "tom", 7 | "files": "filer", 8 | "folders": "mapper", 9 | "icons": "ikoner", 10 | "lastModified": "Sist endret", 11 | "name": "Navn", 12 | "noMatch": "ingen treff", 13 | "parentDirectory": "Overordnet mappe", 14 | "size": "Størrelse" 15 | } 16 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/ro.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "română", 3 | 4 | "details": "detalii", 5 | "download": "descarcă", 6 | "empty": "gol", 7 | "files": "fişiere", 8 | "folders": "dosar", 9 | "icons": "pictograme", 10 | "lastModified": "ultima modificare", 11 | "name": "nume", 12 | "noMatch": "0 rezultate", 13 | "parentDirectory": "dosar părinte", 14 | "size": "mărime" 15 | } 16 | -------------------------------------------------------------------------------- /test/tests/unit/core/event.js: -------------------------------------------------------------------------------- 1 | const {test, assert} = require('scar'); 2 | const event = require('../../../../src/_h5ai/public/js/lib/core/event'); 3 | 4 | test('core.event', () => { 5 | assert.equal(typeof event, 'object', 'is object'); 6 | assert.deepEqual(Object.keys(event).sort(), ['sub', 'pub'].sort()); 7 | assert.equal(typeof event.sub, 'function'); 8 | assert.equal(typeof event.pub, 'function'); 9 | }); 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | 6 | [*] 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 4 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | 15 | [{package.json,.travis.yml,.eslintrc}] 16 | indent_size = 2 17 | 18 | 19 | [{*.md,*.pug}] 20 | trim_trailing_whitespace = false 21 | 22 | 23 | [*.svg] 24 | insert_final_newline = false 25 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/view/root.less: -------------------------------------------------------------------------------- 1 | #root { 2 | .flex-column; 3 | position: absolute; 4 | left: 0; 5 | top: 0; 6 | right: 0; 7 | bottom: 0; 8 | overflow: hidden; 9 | background: @col-back; 10 | line-height: 1.4; 11 | } 12 | 13 | #root, input, select { 14 | font-family: @font-family; 15 | font-size: @font-size; 16 | font-weight: @font-weight; 17 | color: @col-text; 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/sr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "srpski", 3 | 4 | "details": "detalji", 5 | "download": "download", 6 | "empty": "prazno", 7 | "files": "fajlovi", 8 | "folders": "direktorijum", 9 | "icons": "ikone", 10 | "lastModified": "Poslednja modifikacija", 11 | "name": "Ime", 12 | "noMatch": "bez poklapanja", 13 | "parentDirectory": "Roditeljski direktorijum", 14 | "size": "Veličina" 15 | } 16 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/README.md: -------------------------------------------------------------------------------- 1 | # Themes 2 | 3 | This directory will contain any themes you add. At the moment there are only 4 | icon themes supported. The folder structure is: `/.`, 5 | with `` one of `svg`, `png` or `jpg`. 6 | 7 | To select a theme use the option `view > theme` in file `conf/options.json`. 8 | 9 | You will find the previously included icon themes [here](https://github.com/lrsjng/h5ai-themes). 10 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/custom.less: -------------------------------------------------------------------------------- 1 | #content-header, #content-footer { 2 | margin: 16px; 3 | padding: 8px; 4 | color: @col-text; 5 | 6 | a, a:active, a:visited { 7 | color: @col-link; 8 | text-decoration: none; 9 | cursor: pointer; 10 | 11 | &:hover { 12 | color: @col-link-hover; 13 | } 14 | } 15 | 16 | h1, h2, h3, h4, h5, h6, p { 17 | margin: 0.1em 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | if (!global.window) { 2 | global.window = require('jsdom').jsdom().defaultView; 3 | } 4 | 5 | const {test} = require('scar'); 6 | const {pinHtml} = require('./util/pin'); 7 | 8 | require('./tests/premisses'); 9 | require('./tests/unit/core/event'); 10 | require('./tests/unit/core/format'); 11 | require('./tests/unit/util/naturalCmp'); 12 | require('./tests/unit/util/parsePatten'); 13 | 14 | pinHtml(); 15 | 16 | test.cli({sync: true}); 17 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "magyar", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "részletek", 6 | "download": "letöltés", 7 | "empty": "üres", 8 | "files": "fájlok", 9 | "folders": "mappák", 10 | "icons": "ikonok", 11 | "lastModified": "Utoljára módosítva", 12 | "name": "Név", 13 | "noMatch": "nincs találat", 14 | "parentDirectory": "Szülő könyvtár", 15 | "size": "Méret" 16 | } 17 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "svenska", 3 | 4 | "details": "detaljerad", 5 | "download": "ladda ner", 6 | "empty": "tom", 7 | "files": "filer", 8 | "folders": "kataloger", 9 | "grid": "rutnät", 10 | "icons": "ikoner", 11 | "lastModified": "Senast ändrad", 12 | "name": "Filnamn", 13 | "noMatch": "ingen matchning", 14 | "parentDirectory": "Till överordnad mapp", 15 | "size": "Filstorlek" 16 | } 17 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/he.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "עברית", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "פרטים", 6 | "download": "הורדה", 7 | "empty": "ריק", 8 | "files": "קבצים", 9 | "filter": "סינון", 10 | "folders": "תיקיות", 11 | "icons": "צלמיות", 12 | "lastModified": "שינוי אחרון", 13 | "name": "שם", 14 | "noMatch": "אין תוצאות", 15 | "parentDirectory": "תיקיית הורה", 16 | "size": "גודל" 17 | } 18 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/ui/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/view/notification.js: -------------------------------------------------------------------------------- 1 | const {dom} = require('../util'); 2 | const base = require('./base'); 3 | 4 | const init = () => { 5 | const $el = dom('
').hide().appTo(base.$root); 6 | 7 | const set = content => { 8 | if (content) { 9 | $el.html(content).show(); 10 | } else { 11 | $el.hide(); 12 | } 13 | }; 14 | 15 | return { 16 | set 17 | }; 18 | }; 19 | 20 | module.exports = init(); 21 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/da.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "dansk", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "detaljer", 6 | "download": "download", 7 | "empty": "tom", 8 | "files": "filer", 9 | "filter": "filter", 10 | "folders": "mapper", 11 | "grid": "grid", 12 | "icons": "ikoner", 13 | "lastModified": "Sidst ændret", 14 | "name": "Navn", 15 | "noMatch": "ingen match", 16 | "parentDirectory": "Overordnet mappe", 17 | "size": "Størrelse" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/hi.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "हिंदी", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "विस्तार", 6 | "download": "डाउनलोड", 7 | "empty": "खाली", 8 | "files": "फ़ाइलें", 9 | "filter": "फ़िल्टर", 10 | "folders": "फोल्डर", 11 | "grid": "ग्रिड", 12 | "icons": "आइकॉन", 13 | "lastModified": "पिछला परिवर्तन", 14 | "name": "नाम", 15 | "noMatch": "कोई समानता नहीं", 16 | "parentDirectory": "मूल डायरेक्टरी", 17 | "size": "माप" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/af.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "afrikaans", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "besonderhede", 6 | "download": "aflaai", 7 | "empty": "leeg", 8 | "files": "lêers", 9 | "filter": "filter", 10 | "folders": "gidse", 11 | "grid": "rooster", 12 | "icons": "ikone", 13 | "lastModified": "Laas verander", 14 | "name": "Naam", 15 | "noMatch": "geen resultaat", 16 | "parentDirectory": "Hoër Vlak", 17 | "size": "Grootte" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "finnish", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "tiedot", 6 | "download": "lataa", 7 | "empty": "tyhjä", 8 | "files": "tiedostoa", 9 | "filter": "suodata", 10 | "folders": "hakemistoa", 11 | "grid": "ruudukko", 12 | "icons": "ikonit", 13 | "lastModified": "Viimeksi muokattu", 14 | "name": "Nimi", 15 | "noMatch": "ei osumia", 16 | "parentDirectory": "Ylähakemisto", 17 | "size": "Koko" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "hrvatski", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "detalji", 6 | "download": "preuzmi", 7 | "empty": "prazno", 8 | "files": "datoteka", 9 | "filter": "filter", 10 | "folders": "direktorij(a)", 11 | "grid": "mreža", 12 | "icons": "ikone", 13 | "lastModified": "Posljednja izmjena", 14 | "name": "Naziv", 15 | "noMatch": "nema rezultata", 16 | "parentDirectory": "Natrag", 17 | "size": "Veličina" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/sl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "slovenščina", 3 | 4 | "dateFormat": "DD. MM. YYYY HH:mm", 5 | "details": "podrobnosti", 6 | "download": "prenesi", 7 | "empty": "prazno", 8 | "files": "datoteke", 9 | "filter": "filter", 10 | "folders": "mape", 11 | "grid": "mreža", 12 | "icons": "ikone", 13 | "lastModified": "Zadnja sprememba", 14 | "name": "Ime", 15 | "noMatch": "ni zadetkov", 16 | "parentDirectory": "Nadrejena mapa", 17 | "size": "Velikost" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/bg.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "български", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "детайли", 6 | "download": "изтегляне", 7 | "empty": "празна", 8 | "files": "файлове", 9 | "filter": "филтър", 10 | "folders": "директории", 11 | "grid": "мрежа", 12 | "icons": "икони", 13 | "lastModified": "Последна промяна", 14 | "name": "Име", 15 | "noMatch": "няма съвпадение", 16 | "parentDirectory": "Предходна директория", 17 | "size": "Размер" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "italiano", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "dettagli", 6 | "download": "download", 7 | "empty": "vuota", 8 | "files": "file", 9 | "filter": "filtra", 10 | "folders": "cartelle", 11 | "grid": "griglia", 12 | "icons": "icone", 13 | "lastModified": "Ultima modifica", 14 | "name": "Nome", 15 | "noMatch": "nessun risultato", 16 | "parentDirectory": "Cartella Superiore", 17 | "size": "Dimensione" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "日本語", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "詳細", 6 | "download": "ダウンロード", 7 | "empty": "(空)", 8 | "files": "ファイル", 9 | "filter": "フィルター", 10 | "folders": "フォルダー", 11 | "grid": "グリッド", 12 | "icons": "アイコン", 13 | "language": "言語", 14 | "lastModified": "最終変更日時", 15 | "name": "名前", 16 | "noMatch": "一致する項目が見つかりません", 17 | "parentDirectory": "親ディレクトリへ", 18 | "size": "サイズ", 19 | "view": "ビュー" 20 | } 21 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "português", 3 | 4 | "dateFormat": "DD-MM-YYYY HH:mm", 5 | "details": "detalhes", 6 | "download": "descarregar", 7 | "empty": "vazio", 8 | "files": "arquivos", 9 | "filter": "filtro", 10 | "folders": "pastas", 11 | "grid": "grelha", 12 | "icons": "ícones", 13 | "lastModified": "última modificação", 14 | "name": "Nome", 15 | "noMatch": "sem resultados", 16 | "parentDirectory": "diretório acima", 17 | "size": "Tamanho" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "українська", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "Деталі", 6 | "download": "Завантажити", 7 | "empty": "Порожньо", 8 | "files": "Файли(ів)", 9 | "filter": "Фільтр", 10 | "folders": "Тек(и)", 11 | "grid": "Гратка", 12 | "icons": "Піктограми", 13 | "lastModified": "Останні зміни", 14 | "name": "Ім'я", 15 | "noMatch": "Немає співпадінь", 16 | "parentDirectory": "Головна тека", 17 | "size": "Розмір" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "čeština", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "Podrobnosti", 6 | "download": "Stáhnout", 7 | "empty": "Prázdná složka", 8 | "files": "souborů", 9 | "filter": "Filtr", 10 | "folders": "složek", 11 | "grid": "Seznam", 12 | "icons": "Velké ikony", 13 | "lastModified": "Datum změny", 14 | "name": "Název", 15 | "noMatch": "Žádná shoda", 16 | "parentDirectory": "Nadřazený adresář", 17 | "size": "Velikost" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/el.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "ελληνικά", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "λεπτομέρειες", 6 | "download": "μεταμόρφωση", 7 | "empty": "κενό", 8 | "files": "αρχεία", 9 | "filter": "φίλτρο", 10 | "folders": "φάκελοι", 11 | "grid": "πλέγμα", 12 | "icons": "εικονίδια", 13 | "lastModified": "Τελευταία τροποποίηση", 14 | "name": "Όνομα", 15 | "noMatch": "κανένα αποτέλεσμα", 16 | "parentDirectory": "Προηγούμενος Κατάλογος", 17 | "size": "Μέγεθος" 18 | } 19 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "한국어", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "자세히", 6 | "download": "다운로드", 7 | "empty": "빈 폴더", 8 | "files": "파일", 9 | "filter": "필터", 10 | "folders": "폴더", 11 | "grid": "그리드", 12 | "icons": "아이콘", 13 | "language": "언어", 14 | "lastModified": "최근 수정일", 15 | "name": "파일명", 16 | "noMatch": "해당파일이 없습니다.", 17 | "parentDirectory": "상위폴더", 18 | "search": "검색", 19 | "size": "크기", 20 | "tree": "트리", 21 | "view": "보기" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "русский", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "Детали", 6 | "download": "Скачать", 7 | "empty": "Пусто", 8 | "files": "Файлы", 9 | "filter": "Фильтр", 10 | "folders": "Папки", 11 | "grid": "Сетка", 12 | "icons": "Иконки", 13 | "language": "Язык", 14 | "lastModified": "Последние изменения", 15 | "name": "Имя", 16 | "noMatch": "Нет совпадений", 17 | "parentDirectory": "Главная директория", 18 | "size": "Размер", 19 | "view": "Вид" 20 | } 21 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "简体中文", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "详情", 6 | "download": "下载", 7 | "empty": "空文件夹", 8 | "files": "文件", 9 | "filter": "过滤", 10 | "folders": "文件夹", 11 | "grid": "网格", 12 | "icons": "图标", 13 | "language": "语言", 14 | "lastModified": "修改时间", 15 | "name": "文件名", 16 | "noMatch": "无匹配项", 17 | "parentDirectory": "父文件夹", 18 | "search": "搜索", 19 | "size": "大小", 20 | "tree": "树形目录", 21 | "view": "视图", 22 | "info": "信息" 23 | } 24 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/zh-tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "正體中文", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "詳細資料", 6 | "download": "下載", 7 | "empty": "空資料夾", 8 | "files": "檔案", 9 | "filter": "過濾", 10 | "folders": "資料夾", 11 | "grid": "網格", 12 | "icons": "圖示", 13 | "language": "語言", 14 | "lastModified": "上次修改", 15 | "name": "檔名", 16 | "noMatch": "沒有符合的檔案", 17 | "parentDirectory": "上層目錄", 18 | "search": "搜尋", 19 | "size": "大小", 20 | "tree": "樹形目錄", 21 | "view": "檢視", 22 | "info": "資訊" 23 | } 24 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/store.js: -------------------------------------------------------------------------------- 1 | const store = global.window.localStorage; 2 | const storekey = '_h5ai'; 3 | 4 | 5 | const load = () => { 6 | try { 7 | return JSON.parse(store[storekey]); 8 | } catch (e) {/* skip */} 9 | return {}; 10 | }; 11 | 12 | const save = obj => { 13 | store[storekey] = JSON.stringify(obj); 14 | }; 15 | 16 | const put = (key, value) => { 17 | const obj = load(); 18 | obj[key] = value; 19 | save(obj); 20 | }; 21 | 22 | const get = key => load()[key]; 23 | 24 | 25 | module.exports = { 26 | put, 27 | get 28 | }; 29 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/core/class-session.php: -------------------------------------------------------------------------------- 1 | store = &$store; 9 | } 10 | 11 | public function set($key, $value) { 12 | $key = Session::$KEY_PREFIX . $key; 13 | $this->store[$key] = $value; 14 | } 15 | 16 | public function get($key, $default = null) { 17 | $key = Session::$KEY_PREFIX . $key; 18 | return array_key_exists($key, $this->store) ? $this->store[$key] : $default; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/filter.less: -------------------------------------------------------------------------------- 1 | #filter { 2 | 3 | input { 4 | display: none; 5 | border: none; 6 | font-size: 16px; 7 | color: @col-text; 8 | background: transparent; 9 | outline: 0; 10 | width: 160px; 11 | padding: 0 12px 0 4px; 12 | line-height: 48px; 13 | vertical-align: top; 14 | } 15 | 16 | &.active { 17 | input { 18 | display: inline-block; 19 | } 20 | } 21 | 22 | &.pending { 23 | input { 24 | color: @col-text-disabled-black; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/search.less: -------------------------------------------------------------------------------- 1 | #search { 2 | 3 | input { 4 | display: none; 5 | border: none; 6 | font-size: 16px; 7 | color: @col-text; 8 | background: transparent; 9 | outline: 0; 10 | width: 160px; 11 | padding: 0 12px 0 4px; 12 | line-height: 48px; 13 | vertical-align: top; 14 | } 15 | 16 | &.active { 17 | input { 18 | display: inline-block; 19 | } 20 | } 21 | 22 | &.pending { 23 | input { 24 | color: @col-text-disabled-black; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/util/misc.js: -------------------------------------------------------------------------------- 1 | const escapePattern = sequence => { 2 | return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); 3 | }; 4 | 5 | const parsePattern = (sequence, advanced) => { 6 | if (!advanced) { 7 | return escapePattern(sequence); 8 | } 9 | 10 | if (sequence.substr(0, 3) === 're:') { 11 | return sequence.substr(3); 12 | } 13 | 14 | return sequence.trim().split(/\s+/).map(part => { 15 | return part.split('').map(char => escapePattern(char)).join('.*?'); 16 | }).join('|'); 17 | }; 18 | 19 | module.exports = { 20 | parsePattern 21 | }; 22 | -------------------------------------------------------------------------------- /test/tests/unit/core/format.js: -------------------------------------------------------------------------------- 1 | const {test, assert} = require('scar'); 2 | const format = require('../../../../src/_h5ai/public/js/lib/core/format'); 3 | 4 | test('core.format', () => { 5 | assert.equal(typeof format, 'object'); 6 | assert.deepEqual(Object.keys(format).sort(), ['setDefaultMetric', 'formatSize', 'setDefaultDateFormat', 'formatDate'].sort()); 7 | assert.equal(typeof format.setDefaultMetric, 'function'); 8 | assert.equal(typeof format.formatSize, 'function'); 9 | assert.equal(typeof format.setDefaultDateFormat, 'function'); 10 | assert.equal(typeof format.formatDate, 'function'); 11 | }); 12 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "deutsch", 3 | 4 | "dateFormat": "DD.MM.YYYY HH:mm", 5 | "details": "Details", 6 | "download": "Download", 7 | "empty": "leer", 8 | "files": "Dateien", 9 | "filter": "filtern", 10 | "folders": "Ordner", 11 | "grid": "Gitter", 12 | "icons": "Icons", 13 | "language": "Sprache", 14 | "lastModified": "Geändert", 15 | "name": "Name", 16 | "noMatch": "keine Treffer", 17 | "parentDirectory": "Übergeordnetes Verzeichnis", 18 | "search": "suchen", 19 | "size": "Größe", 20 | "tree": "Baum", 21 | "view": "Ansicht" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/et.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "estonian", 3 | 4 | "dateFormat": "DD-MM-YYYY HH.mm", 5 | "details": "täpsem info", 6 | "download": "laadi alla", 7 | "empty": "tühi", 8 | "files": "failid", 9 | "filter": "filter", 10 | "folders": "kataloogid", 11 | "grid": "võre", 12 | "icons": "ikoonid", 13 | "language": "Keel", 14 | "lastModified": "Viimati muudetud", 15 | "name": "Nimi", 16 | "noMatch": "ei leitud sobivat", 17 | "parentDirectory": "Emakataloog", 18 | "search": "otsi", 19 | "size": "Suurus", 20 | "tree": "Puu", 21 | "view": "Vaade" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "nederlands", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "details", 6 | "download": "download", 7 | "empty": "leeg", 8 | "files": "bestanden", 9 | "filter": "filter", 10 | "folders": "mappen", 11 | "grid": "grid", 12 | "icons": "iconen", 13 | "language": "Taal", 14 | "lastModified": "Laatste wijziging", 15 | "name": "Naam", 16 | "noMatch": "geen overeenkomst", 17 | "parentDirectory": "Bovenliggende map", 18 | "search": "zoeken", 19 | "size": "Grootte", 20 | "tree": "Boom", 21 | "view": "Bekijk" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "polski", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "szczegóły", 6 | "download": "pobierz", 7 | "empty": "pusty", 8 | "files": "plików", 9 | "filter": "filtr", 10 | "folders": "folderów", 11 | "grid": "kafelki", 12 | "icons": "ikony", 13 | "language": "Język", 14 | "lastModified": "Ostatnia modyfikacja", 15 | "name": "Nazwa", 16 | "noMatch": "nie znaleziono", 17 | "parentDirectory": "Katalog nadrzędny", 18 | "search": "szukaj", 19 | "size": "Rozmiar", 20 | "tree": "Drzewo", 21 | "view": "Układ" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/lv.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "latviešu", 3 | 4 | "dateFormat": "YYYY-MM-DD HH:mm", 5 | "details": "detaļas", 6 | "download": "lejupielādēt", 7 | "empty": "tukšs", 8 | "files": "faili", 9 | "filter": "filtrēt", 10 | "folders": "mapes", 11 | "grid": "režģis", 12 | "icons": "ikonas", 13 | "language": "Valoda", 14 | "lastModified": "Pēdējoreiz modificēts", 15 | "name": "Nosaukums", 16 | "noMatch": "nav sakritības", 17 | "parentDirectory": "Vecākdirektorijs", 18 | "search": "meklēt", 19 | "size": "Izmērs", 20 | "tree": "Koks", 21 | "view": "Skats" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/init.js: -------------------------------------------------------------------------------- 1 | const {dom, awaitReady} = require('./util'); 2 | const config = require('./config'); 3 | 4 | const name = dom('script[data-module]').attr('data-module'); 5 | const query = { 6 | action: 'get', 7 | setup: true, 8 | options: true, 9 | types: true 10 | }; 11 | 12 | if (name === 'index') { 13 | query.theme = true; 14 | query.langs = true; 15 | } else if (name === 'info') { 16 | query.refresh = true; 17 | } else { 18 | throw new Error(`no-main-module: '${name}'`); 19 | } 20 | 21 | config._update(query) 22 | .then(() => awaitReady()) 23 | .then(() => require(`./main/${name}`)); 24 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "español", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "Detalles", 6 | "download": "Descargar", 7 | "empty": "vacío", 8 | "files": "Archivos", 9 | "filter": "Filtrar", 10 | "folders": "Directorios", 11 | "grid": "Cuadrícula", 12 | "icons": "Íconos", 13 | "language": "Idioma", 14 | "lastModified": "Última modificación", 15 | "name": "Nombre", 16 | "noMatch": "Sin coincidencias", 17 | "parentDirectory": "Directorio superior", 18 | "search": "buscar", 19 | "size": "Tamaño", 20 | "tree": "Arbol", 21 | "view": "Vista" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "français", 3 | 4 | "dateFormat": "DD/MM/YYYY HH:mm", 5 | "details": "détails", 6 | "download": "télécharger", 7 | "empty": "vide", 8 | "files": "Fichiers", 9 | "filter": "filtrer", 10 | "folders": "Répertoires", 11 | "grid": "grille", 12 | "icons": "icônes", 13 | "language": "Langue", 14 | "lastModified": "Dernière modification", 15 | "name": "Nom", 16 | "noMatch": "rien trouvé", 17 | "parentDirectory": "Dossier parent", 18 | "search": "rechercher", 19 | "size": "Taille", 20 | "tree": "Arborescence", 21 | "view": "Disposition" 22 | } 23 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-rb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/private/conf/l10n/en.json: -------------------------------------------------------------------------------- 1 | /* only here as a reference, these values are the hardcoded defaults */ 2 | { 3 | "lang": "english", 4 | 5 | "dateFormat": "YYYY-MM-DD HH:mm", 6 | "details": "details", 7 | "download": "download", 8 | "empty": "empty", 9 | "files": "files", 10 | "filter": "filter", 11 | "folders": "folders", 12 | "grid": "grid", 13 | "icons": "icons", 14 | "language": "Language", 15 | "lastModified": "Last modified", 16 | "name": "Name", 17 | "noMatch": "no match", 18 | "parentDirectory": "Parent Directory", 19 | "search": "search", 20 | "size": "Size", 21 | "tree": "Tree", 22 | "view": "View" 23 | } 24 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/default/bin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/main/index.js: -------------------------------------------------------------------------------- 1 | require('../view/viewmode'); 2 | 3 | require('../ext/autorefresh'); 4 | require('../ext/contextmenu'); 5 | require('../ext/crumb'); 6 | require('../ext/custom'); 7 | require('../ext/download'); 8 | require('../ext/filter'); 9 | require('../ext/google-analytics'); 10 | require('../ext/info'); 11 | require('../ext/l10n'); 12 | require('../ext/piwik-analytics'); 13 | require('../ext/preview'); 14 | require('../ext/search'); 15 | require('../ext/select'); 16 | require('../ext/sort'); 17 | require('../ext/thumbnails'); 18 | require('../ext/title'); 19 | require('../ext/tree'); 20 | 21 | const href = global.window.document.location.href; 22 | require('../core/location').setLocation(href, true); 23 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-script.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/title.js: -------------------------------------------------------------------------------- 1 | const event = require('../core/event'); 2 | const allsettings = require('../core/settings'); 3 | 4 | const doc = global.window.document; 5 | const settings = Object.assign({ 6 | enabled: false 7 | }, allsettings.title); 8 | 9 | const onLocationChanged = item => { 10 | const labels = item.getCrumb().map(i => i.label); 11 | let title = labels.join(' > '); 12 | 13 | if (labels.length > 1) { 14 | title = labels[labels.length - 1] + ' - ' + title; 15 | } 16 | 17 | doc.title = title; 18 | }; 19 | 20 | const init = () => { 21 | if (!settings.enabled) { 22 | return; 23 | } 24 | 25 | event.sub('location.changed', onLocationChanged); 26 | }; 27 | 28 | init(); 29 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/preview-txt.less: -------------------------------------------------------------------------------- 1 | #pv-content-txt { 2 | .raised; 3 | 4 | box-sizing: border-box; 5 | max-width: 960px; 6 | text-align: left; 7 | background: @col-back-paper; 8 | margin: 0 auto; 9 | padding: 8px; 10 | overflow: auto; 11 | 12 | a, a:active, a:visited { 13 | color: #2080FF; 14 | text-decoration: none; 15 | cursor: pointer; 16 | 17 | &:hover { 18 | color: #68A9FF; 19 | } 20 | } 21 | } 22 | 23 | pre#pv-content-txt { 24 | code { 25 | line-height: 1.2em; 26 | } 27 | } 28 | 29 | div#pv-content-txt { 30 | font-size: 1.1em; 31 | padding: 8px 24px; 32 | 33 | code { 34 | color: #008200; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/event.js: -------------------------------------------------------------------------------- 1 | const {isStr, isFn, dom} = require('../util'); 2 | 3 | const subscriptions = {}; 4 | 5 | const sub = (topic, listener) => { 6 | if (isStr(topic) && isFn(listener)) { 7 | if (!subscriptions[topic]) { 8 | subscriptions[topic] = []; 9 | } 10 | subscriptions[topic].push(listener); 11 | } 12 | }; 13 | 14 | const pub = (topic, ...args) => { 15 | // console.log(topic, args); 16 | if (isStr(topic) && subscriptions[topic]) { 17 | subscriptions[topic].forEach(listener => { 18 | listener.apply(topic, args); 19 | }); 20 | } 21 | }; 22 | 23 | dom(global.window).on('resize', () => pub('resize')); 24 | 25 | module.exports = { 26 | sub, 27 | pub 28 | }; 29 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/preview-img.less: -------------------------------------------------------------------------------- 1 | #pv-content-img { 2 | .raised; 3 | 4 | @check-white: #f8f8f8; 5 | @check-black: #e8e8e8; 6 | 7 | position: absolute; 8 | 9 | max-width: 100%; 10 | max-height: 100%; 11 | 12 | background-color: @check-white; 13 | background-image: 14 | -webkit-linear-gradient(45deg, @check-black 25%, transparent 25%, transparent 75%, @check-black 75%, @check-black), 15 | -webkit-linear-gradient(45deg, @check-black 25%, transparent 25%, transparent 75%, @check-black 75%, @check-black); 16 | background-size: 60px 60px; 17 | background-position: 0 0, 30px 30px; 18 | 19 | &.loading { 20 | opacity: 0.5; 21 | margin-top: 32px; 22 | width: 240px; 23 | height: 240px; 24 | border-radius: 1000px; 25 | overflow: hidden; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h5ai", 3 | "version": "0.29.0", 4 | "description": "Modern HTTP web server index.", 5 | "homepage": "https://larsjung.de/h5ai/", 6 | "bugs": "https://github.com/lrsjng/h5ai/issues", 7 | "author": "Lars Jung (https://larsjung.de)", 8 | "license": "MIT", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/lrsjng/h5ai.git" 12 | }, 13 | "scripts": { 14 | "build": "node ghu release" 15 | }, 16 | "devDependencies": { 17 | "babel-loader": "6.2.4", 18 | "babel-preset-es2015": "6.13.2", 19 | "eslint": "3.2.2", 20 | "ghu": "0.11.0", 21 | "jsdom": "9.4.2", 22 | "kjua": "0.1.1", 23 | "lolight": "0.3.0", 24 | "marked": "0.3.6", 25 | "normalize.css": "4.2.0", 26 | "null-loader": "0.1.1", 27 | "scar": "0.17.0" 28 | }, 29 | "engines": { 30 | "node": ">=6.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/core/class-logger.php: -------------------------------------------------------------------------------- 1 | { 5 | assert.equal(typeof naturalCmp, 'function', 'is function'); 6 | 7 | [ 8 | '-1', 9 | '0', 10 | '00', 11 | '000', 12 | '001', 13 | '01', 14 | '02', 15 | '1', 16 | '3', 17 | 'a0', 18 | 'a00', 19 | 'a1', 20 | 'a2', 21 | 'a 0', 22 | 'a 00', 23 | 'a 000', 24 | 'a 01', 25 | 'a 1', 26 | 'a 2', 27 | 'a 3', 28 | 'a.1', 29 | 'a.1.0', 30 | 'a.1.1', 31 | 'a.1.1.0', 32 | 'a.1.10', 33 | 'z' 34 | ].forEach((b, idx, arr) => { 35 | if (idx === 0) { 36 | return; 37 | } 38 | const a = arr[idx - 1]; 39 | assert.equal(naturalCmp(a, b), -1, `fix#${idx} - ${insp(a)} < ${insp(b)}`); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/autorefresh.js: -------------------------------------------------------------------------------- 1 | const event = require('../core/event'); 2 | const location = require('../core/location'); 3 | const allsettings = require('../core/settings'); 4 | 5 | const win = global.window; 6 | const settings = Object.assign({ 7 | enabled: false, 8 | interval: 5000 9 | }, allsettings.autorefresh); 10 | let timeoutId = null; 11 | 12 | 13 | const heartbeat = () => { 14 | location.refresh(); 15 | }; 16 | 17 | const before = () => { 18 | win.clearTimeout(timeoutId); 19 | }; 20 | 21 | const after = () => { 22 | win.clearTimeout(timeoutId); 23 | timeoutId = win.setTimeout(heartbeat, settings.interval); 24 | }; 25 | 26 | const init = () => { 27 | if (!settings.enabled) { 28 | return; 29 | } 30 | 31 | settings.interval = Math.max(1000, settings.interval); 32 | 33 | event.sub('location.beforeChange', before); 34 | event.sub('location.beforeRefresh', before); 35 | event.sub('location.changed', after); 36 | event.sub('location.refreshed', after); 37 | }; 38 | 39 | 40 | init(); 41 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/view/view-icons.less: -------------------------------------------------------------------------------- 1 | #view.view-icons { 2 | 3 | .view-icons-sized(@size) { 4 | 5 | .item { 6 | width: @size * 4/3; 7 | } 8 | 9 | .landscape { 10 | width: @size * 4/3; 11 | height: @size; 12 | 13 | img { 14 | width: @size; 15 | height: @size; 16 | } 17 | 18 | .thumb { 19 | width: @size * 4/3; 20 | } 21 | } 22 | } 23 | 24 | margin: 28px; 25 | 26 | .item { 27 | .rounded; 28 | overflow: hidden; 29 | float: left; 30 | margin: 8px; 31 | 32 | &:hover { 33 | .raised; 34 | } 35 | } 36 | 37 | .landscape { 38 | display: block; 39 | background: @col-back-panel; 40 | } 41 | 42 | .label { 43 | padding: 0 6px; 44 | line-height: 24px; 45 | text-align: center; 46 | } 47 | 48 | .date, .size { 49 | display: none; 50 | } 51 | 52 | .view-icons-sized(96px); 53 | } 54 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/core/class-theme.php: -------------------------------------------------------------------------------- 1 | context = $context; 9 | } 10 | 11 | public function get_icons() { 12 | $public_path = $this->context->get_setup()->get('PUBLIC_PATH'); 13 | $theme = $this->context->query_option('view.theme', '-NONE-'); 14 | $theme_path = $public_path . '/images/themes/' . $theme; 15 | 16 | $icons = []; 17 | 18 | if (is_dir($theme_path)) { 19 | if ($dir = opendir($theme_path)) { 20 | while (($name = readdir($dir)) !== false) { 21 | $path_parts = pathinfo($name); 22 | if (in_array(@$path_parts['extension'], Theme::$EXTENSIONS)) { 23 | $icons[$path_parts['filename']] = $theme . '/' . $name; 24 | } 25 | } 26 | closedir($dir); 27 | } 28 | } 29 | 30 | return $icons; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/view/base.js: -------------------------------------------------------------------------------- 1 | const {dom} = require('../util'); 2 | 3 | const rootSelector = 'body'; 4 | const topbarTpl = 5 | ``; 13 | const mainrowTpl = 14 | `
15 |
16 |
`; 17 | 18 | const init = () => { 19 | const $root = dom(rootSelector) 20 | .attr('id', 'root') 21 | .clr() 22 | .app(topbarTpl) 23 | .app(mainrowTpl); 24 | 25 | return { 26 | $root, 27 | $topbar: $root.find('#topbar'), 28 | $toolbar: $root.find('#toolbar'), 29 | $flowbar: $root.find('#flowbar'), 30 | $mainrow: $root.find('#mainrow'), 31 | $content: $root.find('#content') 32 | }; 33 | }; 34 | 35 | module.exports = init(); 36 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/resource.js: -------------------------------------------------------------------------------- 1 | const {includes} = require('../util'); 2 | const config = require('../config'); 3 | const settings = require('./settings'); 4 | 5 | const imagesHref = settings.publicHref + 'images/'; 6 | const uiHref = imagesHref + 'ui/'; 7 | const themesHref = imagesHref + 'themes/'; 8 | const defaultThemeHref = themesHref + 'default/'; 9 | const defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x']; 10 | 11 | 12 | const image = id => uiHref + id + '.svg'; 13 | 14 | const icon = id => { 15 | const baseId = (id || '').split('-')[0]; 16 | const href = config.theme[id] || config.theme[baseId]; 17 | 18 | if (href) { 19 | return themesHref + href; 20 | } 21 | 22 | if (includes(defaultIcons, id)) { 23 | return defaultThemeHref + id + '.svg'; 24 | } 25 | 26 | if (includes(defaultIcons, baseId)) { 27 | return defaultThemeHref + baseId + '.svg'; 28 | } 29 | 30 | return defaultThemeHref + 'file.svg'; 31 | }; 32 | 33 | 34 | module.exports = { 35 | image, 36 | icon 37 | }; 38 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/info.less: -------------------------------------------------------------------------------- 1 | #info { 2 | overflow: auto; 3 | flex: 0 0 auto; 4 | order: 99; 5 | 6 | padding: 32px 32px 32px 48px; 7 | white-space: nowrap; 8 | overflow-x: hidden; 9 | width: 240px; 10 | 11 | .icon { 12 | width: 240px; 13 | height: 180px; 14 | 15 | img { 16 | .rounded; 17 | display: block; 18 | overflow: hidden; 19 | margin: 0 auto; 20 | width: 180px; 21 | height: 180px; 22 | } 23 | 24 | .thumb { 25 | width: 240px; 26 | } 27 | } 28 | 29 | .block { 30 | border-top: 1px solid @col-border; 31 | border-bottom: 1px solid @col-border; 32 | margin: 0 0 24px 0; 33 | padding: 24px 0; 34 | } 35 | 36 | .label { 37 | font-size: 16px; 38 | margin-bottom: 16px; 39 | } 40 | 41 | .time, .size, .content { 42 | line-height: 20px; 43 | height: 20px; 44 | } 45 | 46 | .qrcode { 47 | margin: 0 auto; 48 | width: 200px; 49 | 50 | img { 51 | display: block; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-php.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-html.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/core/types.js: -------------------------------------------------------------------------------- 1 | const {each, map} = require('../util'); 2 | const config = require('../config'); 3 | 4 | const reEndsWithSlash = /\/$/; 5 | const regexps = {}; 6 | 7 | 8 | const escapeRegExp = sequence => { 9 | return sequence.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$]/g, '\\$&'); 10 | // return sequence.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 11 | }; 12 | 13 | const parse = types => { 14 | each(types, (patterns, type) => { 15 | const pattern = '^(' + map(patterns, p => '(' + escapeRegExp(p).replace(/\*/g, '.*') + ')').join('|') + ')$'; 16 | regexps[type] = new RegExp(pattern, 'i'); 17 | }); 18 | }; 19 | 20 | const getType = sequence => { 21 | if (reEndsWithSlash.test(sequence)) { 22 | return 'folder'; 23 | } 24 | 25 | const slashidx = sequence.lastIndexOf('/'); 26 | const name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence; 27 | let result; 28 | 29 | each(regexps, (regexp, type) => { 30 | if (regexps[type].test(name)) { 31 | result = type; 32 | } 33 | }); 34 | 35 | return result ? result : 'file'; 36 | }; 37 | 38 | 39 | parse(Object.assign({}, config.types)); 40 | 41 | module.exports = { 42 | getType 43 | }; 44 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/google-analytics.js: -------------------------------------------------------------------------------- 1 | const {map} = require('../util'); 2 | const event = require('../core/event'); 3 | const allsettings = require('../core/settings'); 4 | 5 | const win = global.window; 6 | const settings = Object.assign({ 7 | enabled: false, 8 | id: 'UA-000000-0' 9 | }, allsettings['google-analytics-ua']); 10 | 11 | const snippet = () => { 12 | /* eslint-disable */ 13 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 14 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 15 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 16 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 17 | /* eslint-enable */ 18 | }; 19 | 20 | const init = () => { 21 | if (!settings.enabled) { 22 | return; 23 | } 24 | 25 | snippet(); 26 | 27 | win.ga('create', settings.id, 'auto'); 28 | 29 | event.sub('location.changed', item => { 30 | const loc = win.location; 31 | win.ga('send', 'pageview', { 32 | location: loc.protocol + '//' + loc.host + item.absHref, 33 | title: map(item.getCrumb(), i => i.label).join(' > ') 34 | }); 35 | }); 36 | }; 37 | 38 | init(); 39 | -------------------------------------------------------------------------------- /src/_h5ai/public/images/themes/comity/txt-css.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/server.js: -------------------------------------------------------------------------------- 1 | const {each, dom} = require('./util'); 2 | const XHR = global.window.XMLHttpRequest; 3 | 4 | const request = data => { 5 | return new Promise(resolve => { 6 | const xhr = new XHR(); 7 | const onReadyStateChange = () => { 8 | if (xhr.readyState === XHR.DONE) { 9 | try { 10 | resolve(JSON.parse(xhr.responseText)); 11 | } catch (err) { 12 | resolve({err, txt: xhr.responseText}); 13 | } 14 | } 15 | }; 16 | 17 | xhr.open('POST', '?', true); 18 | xhr.onreadystatechange = onReadyStateChange; 19 | xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); 20 | xhr.send(JSON.stringify(data)); 21 | }); 22 | }; 23 | 24 | const formRequest = data => { 25 | const $form = dom('
'); 26 | 27 | each(data, (val, key) => { 28 | dom('') 29 | .attr('name', key) 30 | .attr('value', val) 31 | .appTo($form); 32 | }); 33 | 34 | $form.appTo('body'); 35 | $form[0].submit(); 36 | $form.rm(); 37 | }; 38 | 39 | module.exports = { 40 | request, 41 | formRequest 42 | }; 43 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/custom.js: -------------------------------------------------------------------------------- 1 | const marked = require('marked'); 2 | const {each, dom} = require('../util'); 3 | const server = require('../server'); 4 | const event = require('../core/event'); 5 | const allsettings = require('../core/settings'); 6 | 7 | 8 | const settings = Object.assign({ 9 | enabled: false 10 | }, allsettings.custom); 11 | 12 | const update = (data, key) => { 13 | const $el = dom(`#content-${key}`); 14 | 15 | if (data && data[key].content) { 16 | let content = data[key].content; 17 | if (data[key].type === 'md') { 18 | content = marked(content); 19 | } 20 | $el.html(content).show(); 21 | } else { 22 | $el.hide(); 23 | } 24 | }; 25 | 26 | const onLocationChanged = item => { 27 | server.request({action: 'get', custom: item.absHref}).then(response => { 28 | const data = response && response.custom; 29 | each(['header', 'footer'], key => update(data, key)); 30 | }); 31 | }; 32 | 33 | const init = () => { 34 | if (!settings.enabled) { 35 | return; 36 | } 37 | 38 | dom('
').hide().preTo('#content'); 39 | dom('').hide().appTo('#content'); 40 | 41 | event.sub('location.changed', onLocationChanged); 42 | }; 43 | 44 | 45 | init(); 46 | -------------------------------------------------------------------------------- /src/_h5ai/public/css/lib/ext/crumb.less: -------------------------------------------------------------------------------- 1 | #crumbbar { 2 | overflow: hidden; 3 | height: 48px; 4 | font-size: 16px; 5 | padding: 0 8px; 6 | // border-left: 1px solid rgba(0,0,0,0.05); 7 | 8 | a, a:active, a:visited { 9 | color: @col-text; 10 | cursor: pointer; 11 | text-decoration: none; 12 | 13 | &.active { 14 | font-weight: bold; 15 | } 16 | &:hover { 17 | color: @col-text-hover; 18 | } 19 | &:focus { 20 | outline: 0; 21 | } 22 | } 23 | .crumb { 24 | .eased-transition; 25 | display: inline-block; 26 | } 27 | .sep { 28 | width: 24px; 29 | height: 24px; 30 | padding: 12px 0; 31 | line-height: 48px; 32 | display: inline-block; 33 | vertical-align: top; 34 | } 35 | .crumb:first-of-type .sep { 36 | width: 0; 37 | } 38 | .label { 39 | line-height: 48px; 40 | display: inline-block; 41 | vertical-align: top; 42 | padding: 0 8px; 43 | } 44 | .hint { 45 | width: 20px; 46 | height: 20px; 47 | padding: 16px 0 0 0; 48 | line-height: 48px; 49 | display: inline-block; 50 | vertical-align: top; 51 | position: relative; 52 | top: -2px; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/_h5ai/private/php/pages/page.tpl.pug: -------------------------------------------------------------------------------- 1 | block init 2 | 3 | 4 | doctype html 5 | html(class='no-js', lang='en') 6 | 7 | head 8 | meta(charset='utf-8') 9 | meta(http-equiv='x-ua-compatible', content='ie=edge') 10 | title #{title} 11 | meta(name='description', content=title) 12 | meta(name='viewport', content='width=device-width, initial-scale=1') 13 | link(rel='shortcut icon', href!='images/favicon/favicon-16-32.ico') 14 | link(rel='apple-touch-icon-precomposed', type='image/png', href!='images/favicon/favicon-152.png') 15 | link(rel='stylesheet', href!='css/styles.css') 16 | 17 | script(src!='js/scripts.js', data-module=module) 18 | 19 | 20 | 21 | body#root(class=module) 22 | 23 | div#fallback-hints 24 | 25 | span.noJsMsg Works best with JavaScript enabled! 26 | span.noBrowserMsg Works best in #[a(href='http://browsehappy.com') modern browsers]! 27 | 28 | span.backlink #[a(href=pkg.homepage, title=`h5ai v${pkg.version} - ${pkg.description}`) powered by h5ai] 29 | 30 | block body 31 | -------------------------------------------------------------------------------- /src/_h5ai/public/js/lib/ext/preview/preview-aud.js: -------------------------------------------------------------------------------- 1 | const {dom} = require('../../util'); 2 | const format = require('../../core/format'); 3 | const allsettings = require('../../core/settings'); 4 | const preview = require('./preview'); 5 | 6 | const settings = Object.assign({ 7 | enabled: false, 8 | autoplay: true, 9 | types: [] 10 | }, allsettings['preview-aud']); 11 | const tpl = '