1
0
mirror of https://github.com/lrsjng/h5ai.git synced 2025-08-30 01:00:07 +02:00

Compare commits

..

224 Commits

Author SHA1 Message Date
Lars Jung
aa94de4945 Update. 2021-01-24 16:10:29 +01:00
Lars Jung
d99a14eaa9 Update. 2021-01-24 16:05:44 +01:00
Lars Jung
7d914d45fb Update. 2021-01-24 16:04:10 +01:00
Lars Jung
2243f2e6a5 Merge pull request #739 from carlos22/patch-1
Add EXIF based image rotate for firefox
2021-01-24 15:59:55 +01:00
Lars Jung
4b6c8d796a Merge pull request #748 from fuchse-ohren/patch-1
Update class-setup.php
2021-01-24 15:59:06 +01:00
Lars Jung
d257b79067 Merge pull request #762 from myl7/l10n
Fix #760
2021-01-24 15:54:25 +01:00
Lars Jung
6b147c7bfb Merge pull request #761 from myl7/master
Fix #758
2021-01-24 15:54:11 +01:00
myl7
0f2c9d095d Fix class static variable usage. 2020-11-08 12:30:17 +08:00
myl7
184e01c0a6 Fix #760.
Limit l10n iso code available values.
2020-11-08 12:05:34 +08:00
myl7
136c654432 Fix #758.
Normalize paths before dirname/basename operations.
2020-11-07 22:58:22 +08:00
Fox Ears
c122d5e44a Update class-setup.php
Windows用にwhereコマンドに対応
2020-08-18 12:07:09 +09:00
Lars Jung
d81d8a9298 Update. 2020-07-26 22:45:36 +02:00
Lars Jung
a556a2be50 Update. 2020-07-25 23:06:16 +02:00
Lars Jung
6ef253e44a Update. 2020-07-24 10:03:34 +02:00
Lars Jung
252ffc5cb9 Update. 2020-07-24 09:57:30 +02:00
Lars Jung
70e112a43a Update. 2020-07-09 09:47:07 +02:00
Lars Jung
e8434f5d89 Update. 2020-07-09 09:46:32 +02:00
Karl G
984aca0093 Add EXIF based image rotate for firefox
Chrome 81 / Safari 13.1 does this automatically. Firefox still requires this CSS. According to spec (css4) it is now deprecated but implementation is optional.
2020-04-20 15:31:00 +02:00
Lars Jung
673ee7ccc7 Update. 2020-03-07 13:57:56 +01:00
Lars Jung
059b2e16ed Update. 2020-03-07 13:53:53 +01:00
Lars Jung
84d84e163b Merge pull request #732 from Woet/patch-1
Close the session for writing when sending a file
2020-03-07 13:18:29 +01:00
Woet
6da08269d8 Close the session for writing when sending a file
Right now, if you download an archive, you won't be able to browse within h5ai until the download is finished. This is because the session data is locked to prevent concurrent writes, which also prevents concurrent requests.

By adding session_write_close() in the on_download function, the session lock is released and concurrent requests will work.
2020-02-27 11:41:56 +08:00
Lars Jung
ce939c3115 Update. 2020-02-19 18:56:23 +01:00
Lars Jung
8889ac4e2e Update. 2020-02-19 18:36:12 +01:00
Lars Jung
2a3f860473 Update. 2020-02-16 17:08:31 +01:00
Lars Jung
5e72d0f6a3 Update. 2020-02-16 02:38:06 +01:00
Lars Jung
bc4f964b24 Update. 2020-02-16 02:37:00 +01:00
Lars Jung
3930e8c204 Merge pull request #726 from thomo/patch-1
Fix cache path in thumbnail comment
2020-02-16 02:25:01 +01:00
Thomas Mohaupt
b1960a0d15 Fix cache path in thumbnail comment
The mentioned cache path does not exists.
2019-12-15 10:48:08 +01:00
Lars Jung
a1bb7552dc Update changelog. 2019-08-12 22:00:22 +02:00
Lars Jung
324242a584 Update deps. 2019-08-12 21:54:07 +02:00
Lars Jung
78d6bf6c27 Update. 2019-05-05 23:03:07 +02:00
Lars Jung
745985bf18 Update. 2019-04-24 02:12:12 +02:00
Lars Jung
50167d3382 Update. 2019-04-24 02:09:57 +02:00
Lars Jung
24d8359a2e Clean up. 2019-04-16 20:59:05 +02:00
Lars Jung
869f1f5cda Merge pull request #694 from Daniel15/header-footer-basedir
Stop searching for header/footer files at web root
2019-04-16 14:19:56 +02:00
Lars Jung
5ffc5cf6fd Clean up. 2019-04-16 14:17:41 +02:00
Lars Jung
8966a517c6 Merge pull request #619 from djtm/patch-1
Fix Invalid argument supplied for foreach() in class-archive.php:138
2019-04-16 14:08:23 +02:00
Lars Jung
a92c44ef0a Merge pull request #687 from Retrobottega/master
Update Italian Translation
2019-04-16 14:06:55 +02:00
Lars Jung
59a41665b0 Merge pull request #683 from Azhe403/patch-1
add Indonesian as id.json
2019-04-16 14:06:39 +02:00
Lars Jung
f7333eb51c Merge pull request #586 from thadius856/master
Update options.json
2019-04-16 14:06:04 +02:00
Lars Jung
02bf7079dd Merge pull request #584 from carloshbcabral/master
Update pt-pt.json and added pt-br.json
2019-04-16 14:05:49 +02:00
Lars Jung
8a15390694 Update deps. 2019-04-16 14:03:51 +02:00
Lars Jung
6f61a12772 Update. 2019-04-05 23:02:49 +02:00
Lars Jung
566338020a Update. 2019-04-05 23:02:26 +02:00
Lars Jung
52ff7462a9 Clean code. 2019-03-22 23:01:35 +01:00
Lars Jung
427ca82722 Maintenance. 2019-03-22 02:33:58 +01:00
Lars Jung
c521ecd055 Update deps. 2019-02-20 22:06:03 +01:00
Daniel Lo Nigro
946c862dc4 Add option to stop searching for header/footer files once the root is reached
References https://github.com/lrsjng/h5ai/issues/669
2019-02-19 00:47:06 -08:00
SalGnt
2d371d112d Update it.json 2018-10-02 15:24:33 +02:00
Azhe-kun
77d6f4af7f add Indonesian as id.json 2018-09-03 18:59:06 +07:00
djtm
e2a743bca5 Fix Invalid argument supplied for foreach() in class-archive.php:139
Before this change, when trying to download a folder oder single file via the download (nginx/php7.1-fpm) option I get below error.

```
[error] 22294#22294: *1376 FastCGI sent in stderr: "PHP message: PHP Warning:  Invalid argument supplied for foreach() in ..._h5ai/private/php/ext/class-archive.php on line 138
PHP message: PHP Stack trace:
PHP message: PHP   1. {main}() ..._h5ai/public/index.php:0
PHP message: PHP   2. Bootstrap::run() /..._h5ai/public/index.php:17
PHP message: PHP   3. Api->apply() /..._h5ai/private/php/class-bootstrap.php:19
PHP message: PHP   4. Api->on_download() /..._h5ai/private/php/core/class-api.php:20
PHP message: PHP   5. Archive->output() /..._h5ai/private/php/core/class-api.php:37
PHP message: PHP   6. Archive->add_hrefs() /..._h5ai/private/php/ext/class-archive.php:28" while reading response header from upstream, 
client: 10.0.2.2, server: localhost.dev, request: "POST /downloads/? HTTP/1.1",
upstream: "fastcgi://127.0.0.1:9000", host: "localhost.dev:28888", referrer: "http://localhost.dev:28888/downloads/"
```
2017-04-24 03:09:21 +02:00
thadius856
ab4fa886c3 Update options.json
Fixed comment to indicate correct path.
2016-09-23 22:02:22 -07:00
Carlos Cabral
4b08092c18 Update pt-br.json 2016-09-09 03:38:40 -03:00
Carlos Cabral
0fd57cad51 Update and rename pt.json to pt-pt.json 2016-09-09 03:38:36 -03:00
Carlos Cabral
db764b6780 Create pt-br.json 2016-09-09 03:35:55 -03:00
Lars Jung
44e53ab213 Dev options. 2016-08-13 20:24:54 +02:00
Lars Jung
5af71185ff Release v0.29.0. 2016-08-12 14:57:36 +02:00
Lars Jung
d714ea90fb Prepare release. 2016-08-12 14:49:20 +02:00
Lars Jung
1e12faa756 Clean PHP. 2016-08-12 14:35:34 +02:00
Lars Jung
85ddff9c2d Turn onReady/Load into promised code. 2016-08-12 12:28:56 +02:00
Lars Jung
00232389ad Update changelog. 2016-08-11 19:51:55 +02:00
Lars Jung
e10fe49cc0 Add chunksize to thumbnail requests. 2016-08-11 19:50:28 +02:00
Lars Jung
6c52ae659f Update deps. 2016-08-11 17:31:42 +02:00
Lars Jung
3c54c1d66c Add space. 2016-08-11 16:43:06 +02:00
Lars Jung
940608d02a Fix selector field. 2016-08-11 00:53:43 +02:00
Lars Jung
b6b8d9f144 Clean some PHP code. 2016-08-11 00:33:06 +02:00
Lars Jung
c559edc208 Update changelog. 2016-08-10 23:59:27 +02:00
Lars Jung
4a41994556 Update changelog. 2016-08-10 23:49:41 +02:00
Lars Jung
d763d6b20a Fix safari language selection. 2016-08-10 16:35:57 +02:00
Lars Jung
dc2a74d251 Fix xhr check for safari. 2016-08-10 15:58:05 +02:00
Lars Jung
fe5ce111af Clean fallback mode topbar style. 2016-08-10 15:54:03 +02:00
Lars Jung
a930f4ce1b Clean info page styles. 2016-08-10 00:43:18 +02:00
Lars Jung
dae89ba5d8 Fix emtpy selection issues. 2016-08-10 00:20:40 +02:00
Lars Jung
78df81266c Another fix for download-all. 2016-08-09 23:26:16 +02:00
Lars Jung
b261c7e937 Docs. 2016-08-09 23:06:12 +02:00
Lars Jung
f9a7a217f8 Dereference sym links when using du. 2016-08-09 22:46:28 +02:00
Lars Jung
4d96cb47ad Fix drag-select on scrollable content. 2016-08-09 22:28:01 +02:00
Lars Jung
0f4fe15195 Fix always visible download button. 2016-08-09 19:27:43 +02:00
Lars Jung
d20d1e8b2c Lighter sidebars. 2016-08-09 03:06:50 +02:00
Lars Jung
4130f7a6fd Center icon labels. 2016-08-09 02:49:51 +02:00
Lars Jung
4ccd4bb030 Back to a cleaner GUI. 2016-08-07 18:15:22 +02:00
Lars Jung
16926f821d Update deps. 2016-08-03 11:52:45 +02:00
Lars Jung
7b5599e9d1 Merge pull request #561 from edmundlaugasson/master
added Estonian translation
2016-08-03 11:42:54 +02:00
Lars Jung
834f3b5425 Clean some tests. 2016-08-03 11:40:53 +02:00
Lars Jung
f0bee58869 Update piwik-analytics code. 2016-08-03 10:28:17 +02:00
edmundlaugasson
03e89dab5e added Estonian translation 2016-08-03 09:38:24 +03:00
Lars Jung
b7f25c45f2 Add unload funcs to audio and video previews. 2016-08-01 14:34:52 +02:00
Lars Jung
e5966bc610 Merge pull request #557 from Sirgue/patch-1
Update fr.json
2016-08-01 13:42:30 +02:00
Sirgue
78bc1e2a1e Update fr.json
Some translates for french language
2016-07-28 05:01:53 +02:00
Lars Jung
0315e29b44 Update deps. 2016-07-26 00:10:00 +02:00
Lars Jung
152dcb9b46 Revert. 2016-07-25 21:38:44 +02:00
Lars Jung
3a87b594a6 Update deps. 2016-07-25 20:15:35 +02:00
Lars Jung
631a0f7aa3 Merge pull request #556 from unix4you2/patch-2
Update es.json
2016-07-25 02:46:51 +02:00
Lars Jung
5564559b7c Merge pull request #555 from unix4you2/patch-1
Update es.json
2016-07-25 02:46:19 +02:00
Lars Jung
0e0f06d634 Add some tests. 2016-07-24 01:23:10 +02:00
Lars Jung
e52b3dd440 Width hack. 2016-07-23 22:30:26 +02:00
Lars Jung
c486962ff8 Minor. 2016-07-23 11:18:18 +02:00
Lars Jung
3fe1b2d6f8 Add tests. 2016-07-23 03:03:35 +02:00
Lars Jung
691cbce10f Replace regularCmp with cmp. 2016-07-23 02:36:16 +02:00
Lars Jung
4ccab28253 Update preview code. 2016-07-23 02:15:59 +02:00
Lars Jung
a6994150ca Add jsdom for headless testing. 2016-07-22 21:19:10 +02:00
Lars Jung
1d4b4b8a02 Update dom. 2016-07-22 20:15:14 +02:00
Lars Jung
20e080751d Update preview code. 2016-07-22 19:43:44 +02:00
Lars Jung
8a4ccd098c Clean preview code. 2016-07-22 03:59:50 +02:00
Lars Jung
9e0b1698fc Replace prism with lolight. 2016-07-21 16:31:14 +02:00
Lars Jung
18dfa1e09f Move some deps to package.json. 2016-07-21 14:26:48 +02:00
Lars Jung
83aad78ab0 Fix preview. 2016-07-21 13:48:54 +02:00
Lars Jung
9b88cdeb9b Update deps. 2016-07-21 13:44:31 +02:00
John Arroyave
11030a17af Update es.json 2016-07-11 08:02:25 -05:00
John Arroyave
aa7df50402 Update es.json 2016-07-11 07:44:35 -05:00
Lars Jung
2008d0755c Clean code. 2016-07-06 16:15:13 +02:00
Lars Jung
c7fdfc27a1 Update normalize to 4.2.0. 2016-07-02 15:11:11 +02:00
Lars Jung
717e046bb9 Update deps. 2016-07-02 13:41:01 +02:00
Lars Jung
5bbc88b8e2 Update tests. 2016-07-02 02:40:34 +02:00
Lars Jung
babb952485 Remove peer5 options. 2016-07-02 01:39:27 +02:00
Lars Jung
22b2db8daf Clean some code. 2016-07-02 00:38:52 +02:00
Lars Jung
8485905901 Clean sort code. 2016-07-01 19:26:17 +02:00
Lars Jung
73e74bb887 Update eslintrc. 2016-07-01 15:00:39 +02:00
Lars Jung
a893cb7534 Update readme. 2016-07-01 14:48:41 +02:00
Lars Jung
87e5472d42 Minor. 2016-07-01 14:44:51 +02:00
Lars Jung
05194167e1 Update prism. 2016-07-01 14:38:23 +02:00
Lars Jung
6dbffb8be1 Minor. 2016-07-01 03:55:27 +02:00
Lars Jung
24945faded Remove last jQuery refs and jQuery itself. 2016-07-01 03:27:38 +02:00
Lars Jung
3761a40e50 Clean code. 2016-06-30 02:19:49 +02:00
Lars Jung
f547d95f30 Minor. 2016-06-29 22:06:43 +02:00
Lars Jung
4a3e8c6734 Minor. 2016-06-29 19:03:54 +02:00
Lars Jung
07ccdbd734 Remove peer5. 2016-06-29 17:42:01 +02:00
Lars Jung
47b46813db Clean select code. 2016-06-29 16:59:39 +02:00
Lars Jung
82c0ae88f8 Clean select code. 2016-06-29 16:57:32 +02:00
Lars Jung
749c8b29c9 Clean select code. 2016-06-29 01:55:28 +02:00
Lars Jung
d0b6197aec Clean custom code. 2016-06-28 21:34:55 +02:00
Lars Jung
3b8edf9ad8 Clean tree code. 2016-06-28 19:44:52 +02:00
Lars Jung
9c4f3111ba Remove jq from tree. 2016-06-28 03:01:07 +02:00
Lars Jung
901d8c407d Bundle utils. 2016-06-26 17:57:25 +02:00
Lars Jung
6b3ba18da1 Update dom. 2016-06-26 17:07:43 +02:00
Lars Jung
cfbae4c5d5 Update. 2016-06-26 14:08:18 +02:00
Lars Jung
7320592dc2 Start to replace jQuery with dom. 2016-06-26 01:03:24 +02:00
Lars Jung
9234e3f287 Clean code. 2016-06-25 00:39:57 +02:00
Lars Jung
95c473a7c7 Clean code. 2016-06-24 23:06:00 +02:00
Lars Jung
3e14d7bed4 Clean code. 2016-06-24 21:26:59 +02:00
Lars Jung
aebfdeb1cd Remove all lodash deps. 2016-06-24 20:31:40 +02:00
Lars Jung
131d153cf5 More changes from jq.data to pure props. 2016-06-24 19:37:57 +02:00
Lars Jung
a3c9bc9db0 Initial switch from jq.data to pure props. 2016-06-24 18:59:16 +02:00
Lars Jung
06b4d81a61 Clean code. 2016-06-24 18:18:44 +02:00
Lars Jung
d8d7b997b5 Remove some more lodash refs. 2016-06-24 16:59:31 +02:00
Lars Jung
26c4d569aa Merge pull request #544 from PeterDaveHelloKitchen/image-optimize
optimize png images losslessly using zopflipng
2016-06-24 13:19:04 +02:00
Lars Jung
67d9e9794b Merge pull request #542 from kuoruan/translate
Update Chinese Translate
2016-06-24 13:15:23 +02:00
Lars Jung
0b8d7e5343 Minor. 2016-06-24 01:11:26 +02:00
Lars Jung
c3cd171785 Refactor. 2016-06-23 13:15:12 +02:00
Lars Jung
171f1c12eb Overlay sidebar. 2016-06-23 00:27:24 +02:00
Lars Jung
50644c84dc Overlay sidebar on small screens. 2016-06-23 00:19:23 +02:00
Lars Jung
92e8e34a66 Improve 64-bit hint. 2016-06-22 23:14:25 +02:00
Lars Jung
804df4c0fb Refactor PHP. 2016-06-22 22:07:57 +02:00
Lars Jung
41bb7d76b5 Refactor PHP. 2016-06-22 22:04:35 +02:00
Lars Jung
35df02984b Clean code. 2016-06-22 21:15:50 +02:00
Lars Jung
e0fc7043b5 Add PHP arch check. 2016-06-22 18:15:55 +02:00
Lars Jung
628836a201 PHP filesize. 2016-06-22 16:54:32 +02:00
Lars Jung
00f9ee09d3 Minor. 2016-06-22 11:36:36 +02:00
Lars Jung
029d4ed5af Minor. 2016-06-22 11:36:16 +02:00
Lars Jung
cd7c3c3dd4 Update editorconfig. 2016-06-21 03:25:20 +02:00
Lars Jung
d5c9668013 Update eslint. 2016-06-21 03:20:04 +02:00
Lars Jung
2fb7f9129e Add source check. 2016-06-21 03:16:35 +02:00
Lars Jung
f6150c58f4 Clean code. 2016-06-20 01:37:18 +02:00
Lars Jung
3246525d78 Remove some lodash deps. 2016-06-20 00:13:52 +02:00
Lars Jung
fe9cdbc46b Clean code. 2016-06-19 23:05:31 +02:00
Lars Jung
324fceb5c3 Move server to root dir. 2016-06-19 19:21:32 +02:00
Lars Jung
8656bdd74e Update styles. 2016-06-19 16:50:23 +02:00
Lars Jung
8ef9575e51 Replace jQuery.qrcode with kjua 0.1.1. 2016-06-19 14:47:39 +02:00
Lars Jung
1fc72d8473 Update ghu.js. 2016-06-19 14:08:26 +02:00
Lars Jung
2153056266 Rename global.js to pre.js. 2016-06-19 13:57:10 +02:00
Lars Jung
2240bd3ca1 Update deps. 2016-06-18 12:22:29 +02:00
Peter Dave Hello
127eaf9aac optimize png images losslessly using zopflipng 2016-06-11 10:21:37 +08:00
Lars Jung
7d5945d45b Minor changes. 2016-06-04 16:26:08 +02:00
Lars Jung
1d2c45dc68 Refactor view files. Add option to disable sidebar. 2016-06-04 16:09:35 +02:00
Lars Jung
2ee4a18e1c Clean build file. 2016-06-04 14:36:08 +02:00
Lars Jung
f0a9937dc6 Switch file names from jade to pug. 2016-06-04 02:43:48 +02:00
Lars Jung
3a2e61b163 Clean up tests. 2016-06-04 01:06:25 +02:00
Lars Jung
c4fa90a747 Add scar tests. 2016-06-03 23:08:30 +02:00
Lars Jung
1cba9290b6 Refactor win.js into globals.js. 2016-06-03 22:40:05 +02:00
Lars Jung
58cbad2bfd Disable filter. 2016-06-03 17:56:50 +02:00
Lars Jung
da9d027fed Remove custom modernizr. 2016-06-03 17:46:01 +02:00
Lars Jung
70d6528190 Test some module designs. 2016-06-03 17:38:00 +02:00
Lars Jung
f7187fb14b Stricter browser checks. Drop IE support. 2016-06-03 17:36:42 +02:00
Lars Jung
7ec2bdf16a Begin to move all src javascript to es6. Add search/filter ignore case option. 2016-06-02 23:16:23 +02:00
Hsing-Wang Liao
c7433b0d14 Update Traditional Chinese translation
Signed-off-by: Hsing-Wang Liao <kuoruan@gmail.com>
2016-06-01 14:20:47 +08:00
Hsing-Wang Liao
0179a5044b Update Simplified Chinese translation
Signed-off-by: Hsing-Wang Liao <kuoruan@gmail.com>
2016-06-01 14:08:08 +08:00
Lars Jung
f37e8e7b89 Update sinon to 1.17.3. 2016-05-31 02:00:19 +02:00
Lars Jung
ba670be7d8 Update ghu. Switch from jade to pug. 2016-05-31 01:21:44 +02:00
Lars Jung
93487de085 Remove sharpen arg from pdf convert. 2016-05-29 20:47:17 +02:00
Lars Jung
a2fb3d952d Replace getenv with SERVER lookups. 2016-05-29 19:05:50 +02:00
Lars Jung
fada3c1e36 Release custom head tags. 2016-05-29 18:21:32 +02:00
Lars Jung
aa87ec15b0 Add fallback mode. 2016-05-29 17:35:15 +02:00
Lars Jung
a0db0e0ac3 Update htaccess. 2016-05-29 14:52:39 +02:00
Lars Jung
a790c34a24 Readd some apache config. 2016-05-28 22:23:27 +02:00
Lars Jung
38daa4aa1f Update readme. 2016-05-28 21:34:23 +02:00
Lars Jung
c92822ba7d Update readme. 2016-05-28 19:58:17 +02:00
Lars Jung
18f2c72fd1 Change svg from text to image format. 2016-05-28 19:57:11 +02:00
Lars Jung
d03dc990fa Update readme and changelog. 2016-05-28 16:21:09 +02:00
Lars Jung
882abd1972 Merge pull request #510 from SushiDude/htaccess
Use mod_authz_core when available. Otherwise, fallback to mod_authz_host or mod_access_compat.
2016-05-28 00:04:37 +02:00
Lars Jung
2dd594ba13 Clean code. 2016-05-27 23:49:27 +02:00
Lars Jung
8d5473903e Merge pull request #534 from thezbyg/master
Fix incorrect tree item display.
2016-05-27 23:47:22 +02:00
Lars Jung
69c1ffd92f Fix and clean code from broken pull request. 2016-05-27 23:06:50 +02:00
Lars Jung
808e37d034 Merge pull request #526 from cygmris/master
Add commands support for Windows
2016-05-27 23:00:26 +02:00
Lars Jung
60ef5ff983 Merge pull request #492 from Joery/master
h5ai: fix typo & nl translation
2016-05-27 22:47:54 +02:00
Lars Jung
171539643e Merge pull request #537 from Monter/master
Update pl.json
2016-05-27 22:43:15 +02:00
Lars Jung
793bfce202 Minor change. 2016-05-27 22:42:11 +02:00
Lars Jung
10d6d2c3c1 Remove babel for now. 2016-05-27 20:35:43 +02:00
Lars Jung
51a161eede Minor tweaks. 2016-05-27 18:23:29 +02:00
Lars Jung
57b3ee6c2f Update deps: jquery, lodash, qrcode, modulejs. Minor fixes. 2016-05-27 17:56:32 +02:00
Lars Jung
641d9b3cfa Update deps. Fix lint issues. 2016-05-27 16:31:27 +02:00
Mark eM
5c2d84aaa9 Update pl.json 2016-05-22 20:25:50 +02:00
Albertas Vyšniauskas
8157ada8fc Fix incorrect tree item display.
Issues #533 and #499.
2016-05-17 17:04:24 +03:00
Lars Jung
8e143a4607 Update deps. 2016-05-16 16:10:37 +02:00
Lars Jung
e021862acf Minor tweaks. 2016-05-05 23:51:47 +02:00
Chr1sh3ng
ed9f04a372 Add commands support for Windows 2016-04-15 19:17:43 +08:00
Wyatt J. Brown
ca86993091 Use mod_authz_core when available. Otherwise, fallback to mod_authz_host or mod_access_compat.
https://github.com/lrsjng/h5ai/pull/489
https://github.com/lrsjng/h5ai/issues/504
2016-02-27 03:12:37 -05:00
Joery
85bd0abd8d Merge pull request #1 from lrsjng/master
h5ai: downstream 20160121
2016-01-21 10:09:53 +01:00
Lars Jung
ed1ab4053c Update apk icon. Add rust type and icon. 2016-01-19 01:18:08 +01:00
Lars Jung
6aed4455d3 Update deps. 2016-01-14 00:44:10 +01:00
Lars Jung
5f265672ae Remove blank lines from PHP sources. 2016-01-14 00:36:25 +01:00
Joery
1653306440 h5ai: update dutch translation 2015-12-25 22:03:03 +01:00
Joery
d0fe566f8f h5ai: fix typo 2015-12-25 22:02:30 +01:00
Lars Jung
11bab8d0a1 Fix mobile view. 2015-12-19 19:58:25 +01:00
202 changed files with 12138 additions and 27169 deletions

View File

@@ -1,5 +0,0 @@
{
"presets": [
"es2015"
]
}

View File

@@ -12,11 +12,11 @@ insert_final_newline = true
trim_trailing_whitespace = true
[{package.json,.travis.yml,.eslintrc,.babelrc}]
[{*.json,*.yml}]
indent_size = 2
[{*.md,*.jade}]
[{*.md,*.pug}]
trim_trailing_whitespace = false

View File

@@ -1,3 +1,3 @@
**/build/**
**/node_modules/**
**/vendor/**
/build/
/local/
/node_modules/

View File

@@ -1,35 +1,12 @@
---
root: true
parser: babel-eslint
env:
es6: true
node: true
ecmaFeatures:
arrowFunctions: true
binaryLiterals: true
blockBindings: true
classes: false
defaultParams: true
destructuring: true
forOf: true
generators: true
globalReturn: true
jsx: false
modules: true
objectLiteralComputedProperties: true
objectLiteralDuplicateProperties: true
objectLiteralShorthandMethods: true
objectLiteralShorthandProperties: true
octalLiterals: true
regexUFlag: true
regexYFlag: true
spread: true
superInFunctions: false
templateStrings: true
unicodeCodePointEscapes: true
parserOptions:
ecmaVersion: 2020
rules:
array-bracket-spacing: [2, never]
@@ -41,7 +18,7 @@
comma-dangle: [2, never]
comma-spacing: [2, {before: false, after: true}]
comma-style: [2, last]
complexity: [1, 25] ###
complexity: [1, 10] ###
computed-property-spacing: [2, never]
consistent-return: 2
consistent-this: [2, self]
@@ -59,12 +36,13 @@
handle-callback-err: 2
indent: [2, 4]
key-spacing: [2, {beforeColon: false, afterColon: true}]
keyword-spacing: [2, {before: true, after: true}]
linebreak-style: [2, unix]
max-depth: [1, 4]
max-len: [0, 80, 4]
max-nested-callbacks: [1, 3]
max-params: [1, 5] ###
max-statements: [1, 80] ###
max-params: [1, 4] ###
max-statements: [1, 30] ###
new-cap: 0
new-parens: 2
newline-after-var: 0
@@ -90,7 +68,6 @@
no-else-return: 1
no-empty: 2
no-empty-character-class: 2
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
@@ -181,7 +158,7 @@
prefer-const: 1
prefer-reflect: 1
prefer-spread: 2
prefer-template: 0 ###
prefer-template: 0
quote-props: [2, as-needed]
quotes: [2, single, avoid-escape]
radix: 2
@@ -189,12 +166,10 @@
semi: 2
semi-spacing: [2, {before: false, after: true}]
sort-vars: 0
space-after-keywords: [2, always]
space-before-blocks: [2, always]
space-before-function-paren: [2, {anonymous: always, named: never}]
space-in-parens: [2, never]
space-infix-ops: 2
space-return-throw-case: 2
space-unary-ops: [2, {words: true, nonwords: false}]
spaced-comment: [2, always]
strict: [2, never]

10
.gitignore vendored
View File

@@ -1,4 +1,6 @@
build
local
node_modules
npm-debug.log
/.nyc_output/
/build/
/coverage/
/local/
/node_modules/
/npm-debug.log

View File

@@ -1,141 +1,219 @@
# Changelog
* now require PHP 7.0.0+
* fix archive-single-item problem
* add header/footer search stop condition
* update languages (`id`, `it`, `pt-br`, `pt-pt`)
* add EXIF-based image rotation
* add `where` to command detection command list
* fix #758
* fix #760
* add `@babel/core` 7.12.10
* add `@babel/preset-env` 7.12.11
* remove `babel-loader`
* update `eslint` to 7.18.0
* update `ghu` to 0.26.0
* update `jsdom` to 16.4.0
* update `kjua` to 0.9.0
* update `lolight` to 1.4.0
* update `marked` to 1.2.7
* update `null-loader` to 4.0.1
* update `scar` to 2.3.0
## v0.29.2 - *2019-03-22*
* update `babel-loader` to 7.1.1
* update `eslint` to 5.15.3
* update `ghu` to 0.13.0
* update `jsdom` to 14.0.0
* update `kjua` to 0.2.0
* update `lolight` to 1.0.0
* update `scar` to 1.2.0
## v0.29.1 - *2019-01-20*
* replace `babel-preset-es2015` with `babel-preset-env`
* update `eslint` to 5.14.1
* update `ghu` to 0.12.0
* update `jsdom` to 9.2.0
* update `kjua` to 0.1.2
* update `lolight` to 0.6.0
* update `marked` to 0.6.1
* update `normalize.css` to 8.0.1
* update `scar` to 1.0.0
## v0.29.0 - *2016-08-12*
* back to cleaner visual experience
* add option to disable sidebar
* add options to filter/search ignore case
* replace PHP `getenv` calls with `$_SERVER` lookups
* add `view.fallbackMode` option to generally serve only fallback mode
* serve fallback mode for text browsers (`curl`, `links`, `lynx`, `w3m`)
* change type `txt-svg` to `img-svg`, no thumbs but preview
* fix a tree indentation glitch
* fix shell command detection on Windows
* fix Piwik anayltics
* fix `.htaccess` auth issues
* fix drag-select on scrollable content
* fix download-all function
* fix audio and video preview loading
* fix thumbnail request issues
* add `rust` type and icon
* add `autoplay` option to audio and video preview
* add `--dereference` to `shell-du` to follow sym links
* remove *Install* section from `README.md`, causes too much trouble
* remove peer5 support
* update build process to use `node 6.0+`, no need for babel now
* replace `jquery-qrcode` with [`kjua`](https://larsjung.de/kjua/)
* replace `prism` with [`lolight`](https://larsjung.de/lolight/)
* move deps to `package.json` (`normalize.css`, `kjua`, `lolight` and `marked`)
* remove `jQuery`
* remove `lodash`
* remove [`modulejs`](https://larsjung.de/modulejs/) for now
* reduce JS code by 60% (~250kb -> ~100kb)
* update languages (`et`, `nl`, `pl`)
## v0.28.0 - *2015-12-19*
* now requires PHP 5.5.0+
* changes index path to `/_h5ai/public/index.php`
* now only `/_h5ai/public/` needs to be accessable from web
* adds support for custom script and style additions
* adds options to set font families
* adds search
* adds ignorecase sorting option to tree
* adds wide links in tree view
* adds IE edge mode
* adds frontend tests
* fixes some styles in IE10
* fixes preview bottom bar for small screen widths
* now require PHP 5.5.0+
* change index path to `/_h5ai/public/index.php`
* now only `/_h5ai/public/` needs to be web-accessible
* add support for custom script and style additions
* add options to set font families
* add search
* add ignorecase sorting option to tree
* add wide links in tree view
* add IE edge mode
* add frontend tests
* fix some styles in IE10
* fix preview bottom bar for small screen widths
* lots of code cleanup and refactorings
* changes API
* updates build process, now uses [ghu](https://larsjung.de/ghu/)
* switches from jshint and jscs to [eslint](http://eslint.org/)
* updates `jQuery` to 2.1.4
* updates `lodash` to 3.9.3 (adds debounce and trim)
* updates `marked` to 0.3.5
* updates `modulejs` to 1.13.0
* updates `prism` to 2015-12-19
* updates h5bp styles to 5.2.0
* updates `normalize.css` to 3.0.3
* removes `Moment.js`
* change API
* update build process, now uses [`ghu`](https://larsjung.de/ghu/)
* switch from jshint and jscs to [`eslint`](http://eslint.org/)
* update `jQuery` to 2.1.4
* update `lodash` to 3.9.3 (add debounce and trim)
* update `marked` to 0.3.5
* update `modulejs` to 1.13.0
* update `prism` to 2015-12-19
* update h5bp styles to 5.2.0
* update `normalize.css` to 3.0.3
* remove `Moment.js`
## v0.27.0 - *2015-04-06*
* new layout
* adds editorconfig
* drops support for IE9 (gets fallback)
* updates sidebar settings
* adds info sidebar
* adds opt-out for click'n'drag selection
* adds package name option for single selections
* adds initial support for Peer5
* adds option to down-sample images for preview
* adds option for natural sorting in tree sidebar
* fixes problems with files/folders named `0`
* changes font from `Ubuntu` to `Roboto` (smaller footprint, clearer for small sizes)
* switches back to Google Fonts
* improves PDF thumbnail quality
* improves drag-select
* improves image preview
* prevents listing `_h5ai` folder and subfolders
* updates build process, now uses [mkr](https://larsjung.de/mkr/) and [fQuery](https://larsjung.de/fquery/)
* updates `jQuery` to 2.1.3
* updates `jQuery.qrcode` to 0.11.0
* updates `Lo-Dash` to 3.6.0
* updates `Modernizr` to 2.8.3
* updates `modulejs` to 1.4.0
* updates `Moment.js` to 2.9.0
* updates `Prism` to 2015-04-05
* removes deprecated Google Analytics code
* removes `jQuery.fracs`
* removes `jQuery.scrollpanel`
* removes `jQuery.mousewheel`
* language updates and additions (`af`, `es`, `ja`, `ko`, `ru`, `zh-cn`)
* add editorconfig
* drop support for IE9 (gets fallback)
* update sidebar settings
* add info sidebar
* add opt-out for click'n'drag selection
* add package name option for single selections
* add initial support for Peer5
* add option to down-sample images for preview
* add option for natural sorting in tree sidebar
* fix problems with files/folders named `0`
* change font from `Ubuntu` to `Roboto` (smaller footprint, clearer for small sizes)
* switch back to Google Fonts
* improve PDF thumbnail quality
* improve drag-select
* improve image preview
* prevent listing `_h5ai` folder and subfolders
* update build process, now uses [`mkr`](https://larsjung.de/mkr/) and [`fQuery`](https://larsjung.de/fquery/)
* update `jQuery` to 2.1.3
* update `jQuery.qrcode` to 0.11.0
* update `Lo-Dash` to 3.6.0
* update `Modernizr` to 2.8.3
* update `modulejs` to 1.4.0
* update `Moment.js` to 2.9.0
* update `Prism` to 2015-04-05
* remove deprecated Google Analytics code
* remove `jQuery.fracs`
* remove `jQuery.scrollpanel`
* remove `jQuery.mousewheel`
* update languages (`af`, `es`, `ja`, `ko`, `ru`, `zh-cn`)
## v0.26.1 - *2014-08-17*
* fixes links
* fix links
## v0.26.0 - *2014-08-16*
* removes True Type fonts
* outsources themes to [h5ai-themes](https://github.com/lrsjng/h5ai-themes)
* adds filesize fallback for large files and 32bit PHP
* fixes server detection
* adds config file tests to info page
* removes JSON shim
* adds caching of command checks
* updates `jQuery.mousewheel` to 3.1.12
* updates `jQuery.qrcode` to 0.8.0
* replaces `markdown` with [`marked`](https://github.com/chjj/marked) 0.3.2
* updates `modulejs` to 0.4.5
* updates `Moment.js` to 2.8.1
* replaces `underscore` with [`Lo-Dash`](https://github.com/lodash/lodash) 2.4.1
* replaces `SyntaxHighlighter` with [`Prism`](http://prismjs.com) 2014-08-04
* remove True Type fonts
* outsource themes to [h5ai-themes](https://github.com/lrsjng/h5ai-themes)
* add filesize fallback for large files and 32bit PHP
* fix server detection
* add config file tests to info page
* remove JSON shim
* add caching of command checks
* update `jQuery.mousewheel` to 3.1.12
* update `jQuery.qrcode` to 0.8.0
* replace `markdown` with [`marked`](https://github.com/chjj/marked) 0.3.2
* update `modulejs` to 0.4.5
* update `Moment.js` to 2.8.1
* replace `underscore` with [`Lo-Dash`](https://github.com/lodash/lodash) 2.4.1
* replace `SyntaxHighlighter` with [`Prism`](http://prismjs.com) 2014-08-04
## v0.25.2 - *2014-07-01*
* adds optional info page protection
* fixes `short_open_tag` issues for PHP < 5.4.0
* fixes default folder download (`alwaysVisible` option)
* add optional info page protection
* fix `short_open_tag` issues for PHP < 5.4.0
* fix default folder download (`alwaysVisible` option)
* minor fixes
## v0.25.1 - *2014-06-25*
* fixes broken paths for filenames containing '+' characters
* fixes Google Universal Analytics
* fixes file type check
* fix broken paths for filenames containing '+' characters
* fix Google Universal Analytics
* fix file type check
## v0.25.0 - *2014-06-22*
* adds sidebar
* adds initial theme support
* adds icons from [Evolvere Icon Theme](http://franksouza183.deviantart.com/art/Evolvere-Icon-theme-440718295)
* adds PHP variant to calc folder sizes
* adds scroll position reset on location change (issue [#279](https://github.com/lrsjng/h5ai/issues/279))
* adds option to hide unreadable files
* adds option where to place folders (top, inplace, bottom)
* adds markdown support for custom header and footer files
* adds video and audio preview via HTML5 elements (no fallback, works best in Chrome)
* adds filter reset on location change
* adds option to make download button always visible
* adds Google UA support
* extends selectable icon sizes (adds 128px, 192px, 256px, 384px)
* improves preview GUI
* add sidebar
* add initial theme support
* add icons from [Evolvere Icon Theme](http://franksouza183.deviantart.com/art/Evolvere-Icon-theme-440718295)
* add PHP variant to calc folder sizes
* add scroll position reset on location change (issue [#279](https://github.com/lrsjng/h5ai/issues/279))
* add option to hide unreadable files
* add option where to place folders (top, inplace, bottom)
* add markdown support for custom header and footer files
* add video and audio preview via HTML5 elements (no fallback, works best in Chrome)
* add filter reset on location change
* add option to make download button always visible
* add Google UA support
* extend selectable icon sizes (add 128px, 192px, 256px, 384px)
* improve preview GUI
* disable thumbs in `cache` folder
* fixes QR code URI origin (issue [#287](https://github.com/lrsjng/h5ai/issues/287))
* replaces PHP backtick operator with `exec`
* removes server side file manipulation extensions `dropbox`, `delete` and `rename`
* updates `H5BP` to 4.3.0
* updates `jQuery` to 2.1.1
* updates `json2.js` to 2014-02-04
* updates `markdown-js` to 0.5.0
* updates `Modernizr` to 2.8.2
* updates `Moment.js` to 2.6.0
* updates `Underscore.js` to 1.6.0
* language updates (`bg`, `ko`, `pt`, `sl`, `sv`, `zh-cn`)
* fix QR code URI origin (issue [#287](https://github.com/lrsjng/h5ai/issues/287))
* replace PHP backtick operator with `exec`
* remove server side file manipulation extensions `dropbox`, `delete` and `rename`
* update `H5BP` to 4.3.0
* update `jQuery` to 2.1.1
* update `json2.js` to 2014-02-04
* update `markdown-js` to 0.5.0
* update `Modernizr` to 2.8.2
* update `Moment.js` to 2.6.0
* update `Underscore.js` to 1.6.0
* update languages (`bg`, `ko`, `pt`, `sl`, `sv`, `zh-cn`)
## v0.24.1 - *2014-04-09*
* security fixes! (issues [#268](https://github.com/lrsjng/h5ai/issues/268), [#269](https://github.com/lrsjng/h5ai/issues/269))
* language updates (`fi`, `fr`, `hi`, `it`, `zh-tw`)
* fixes WinOS command detection
* fix WinOS command detection
* update languages (`fi`, `fr`, `hi`, `it`, `zh-tw`)
## v0.24.0 - *2013-09-04*

View File

@@ -2,23 +2,16 @@
[![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github]
A modern HTTP web server index for Apache httpd, lighttpd, nginx and Cherokee.
For bug reports and feature requests please use [issues][github-issues].
A modern HTTP web server index for Apache httpd, lighttpd, and nginx.
There was a [security flaw][cve] in versions 0.22.0 - 0.24.1 that was fixed in
0.25.0. If you are still using one of these versions you are advised to
upgrade.
## Install
## Important
Do **not** install any files from the `src` folder, they need to be
preprocessed to work correctly! Find a preprocessed package and detailed
install instructions on the [project page][web].
In short you have to take the following two steps:
* place folder `_h5ai` in the document root folder of the web server
* append `/_h5ai/public/index.php` to the end of the default index-file list
* Do **not** install any files from the `src` folder, they need to be
preprocessed to work correctly!
* Find a preprocessed package and detailed install instructions on the
[project page][web].
* For bug reports and feature requests please use [issues][github-issues].
## Build
@@ -27,7 +20,8 @@ There are installation ready packages for the latest [releases][release] and
[dev builds][develop]. But to build **h5ai** yourself either `git clone` or
download the repository. From within the root folder run the following
commands to find a fresh zipball in folder `build` (tested on linux only,
requires [`node 4.0+`][node] to be installed).
requires [`node 10.0+`][node] to be installed, might work on other
configurations).
~~~sh
> npm install
@@ -39,7 +33,7 @@ requires [`node 4.0+`][node] to be installed).
The MIT License (MIT)
Copyright (c) 2015 Lars Jung (https://larsjung.de)
Copyright (c) 2020 Lars Jung (https://larsjung.de)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -77,5 +71,3 @@ too. Exceptions are some [Material Design icons][material-design-icons] (CC BY 4
[license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square
[web-img]: https://img.shields.io/badge/web-larsjung.de/h5ai-a0a060.svg?style=flat-square
[github-img]: https://img.shields.io/badge/github-lrsjng/h5ai-a0a060.svg?style=flat-square
[cve]: https://larsjung.de/h5ai/cve-2015-3203.txt

2
ghu
View File

@@ -1,2 +0,0 @@
#!/usr/bin/env sh
node -r babel-core/register ghu.js "$@"

102
ghu.js
View File

@@ -1,8 +1,7 @@
const {resolve, join} = require('path');
const {
ghu,
autoprefixer, cssmin, each, ife, includeit, jade, jszip,
less, mapfn, newerThan, read, remove, run, uglify, watch, wrap, write
ghu, autoprefixer, cssmin, each, ife, includeit, jszip, less, mapfn,
pug, read, remove, run, uglify, watch, webpack, wrap, write
} = require('ghu');
const ROOT = resolve(__dirname);
@@ -10,7 +9,27 @@ const SRC = join(ROOT, 'src');
const TEST = join(ROOT, 'test');
const BUILD = join(ROOT, 'build');
const mapper = mapfn.p(SRC, BUILD).s('.less', '.css').s('.jade', '');
const mapper = mapfn.p(SRC, BUILD).s('.less', '.css').s('.pug', '');
const WEBPACK_CFG = {
mode: 'none',
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /jsdom/,
use: 'null-loader'
}
]
}
};
ghu.defaults('release');
@@ -28,9 +47,8 @@ ghu.before(runtime => {
}
runtime.comment = `${runtime.pkg.name} v${runtime.pkg.version} - ${runtime.pkg.homepage}`;
runtime.commentJs = `/* ${runtime.comment} */\n`;
runtime.commentHtml = `<!-- ${runtime.comment} -->`;
runtime.comment_js = `/* ${runtime.comment} */\n`;
runtime.comment_html = `<!-- ${runtime.comment} -->`;
console.log(runtime.comment);
});
@@ -45,88 +63,67 @@ ghu.task('clean', 'delete build folder', () => {
return remove(BUILD);
});
ghu.task('lint', 'lint all JavaScript files with eslint', () => {
return run('eslint .', {stdio: 'inherit'});
});
ghu.task('build:scripts', runtime => {
return read(`${SRC}/_h5ai/public/js/*.js`)
.then(newerThan(mapper, `${SRC}/_h5ai/public/js/**`))
return read(`${SRC}/_h5ai/public/js/scripts.js`)
.then(webpack(WEBPACK_CFG))
.then(wrap('\n\n// @include "pre.js"\n\n'))
.then(includeit())
.then(ife(() => runtime.args.production, uglify()))
.then(wrap(runtime.commentJs))
.then(wrap(runtime.comment_js))
.then(write(mapper, {overwrite: true}));
});
ghu.task('build:styles', runtime => {
return read(`${SRC}/_h5ai/public/css/*.less`)
.then(newerThan(mapper, `${SRC}/_h5ai/public/css/**`))
.then(includeit())
.then(less())
.then(autoprefixer())
.then(ife(() => runtime.args.production, cssmin()))
.then(wrap(runtime.commentJs))
.then(wrap(runtime.comment_js))
.then(write(mapper, {overwrite: true}));
});
ghu.task('build:pages', runtime => {
return read(`${SRC}: **/*.jade, ! **/*.tpl.jade`)
.then(newerThan(mapper, `${SRC}/**/*.tpl.jade`))
.then(jade({pkg: runtime.pkg}))
.then(wrap('', runtime.commentHtml))
return read(`${SRC}: **/*.pug, ! **/*.tpl.pug`)
.then(pug({pkg: runtime.pkg}))
.then(wrap('', runtime.comment_html))
.then(write(mapper, {overwrite: true}));
});
ghu.task('build:copy', runtime => {
const mapperRoot = mapfn.p(ROOT, join(BUILD, '_h5ai'));
const mapper_root = mapfn.p(ROOT, join(BUILD, '_h5ai'));
return Promise.all([
read(`${SRC}/**/conf/*.json`)
.then(newerThan(mapper))
.then(wrap(runtime.commentJs))
.then(wrap(runtime.comment_js))
.then(write(mapper, {overwrite: true, cluster: true})),
read(`${SRC}: **, ! **/*.js, ! **/*.less, ! **/*.jade, ! **/conf/*.json`)
.then(newerThan(mapper))
read(`${SRC}: **, ! **/*.js, ! **/*.less, ! **/*.pug, ! **/conf/*.json`)
.then(each(obj => {
if (/index\.php$/.test(obj.source)) {
if ((/index\.php$/).test(obj.source)) {
obj.content = obj.content.replace('{{VERSION}}', runtime.pkg.version);
}
}))
.then(write(mapper, {overwrite: true, cluster: true})),
read(`${ROOT}/*.md`)
.then(newerThan(mapperRoot))
.then(write(mapperRoot, {overwrite: true, cluster: true}))
.then(write(mapper_root, {overwrite: true, cluster: true}))
]);
});
ghu.task('build:tests', ['build:scripts', 'build:styles'], 'build the test suite', runtime => {
ghu.task('build:tests', ['build:styles'], 'build the test suite', () => {
return Promise.all([
read(`${TEST}/scripts.js`)
.then(newerThan(`${BUILD}/test/scripts.js`))
.then(includeit())
.then(write(`${BUILD}/test/scripts.js`, {overwrite: true})),
read(`${BUILD}/_h5ai/public/css/styles.css`)
.then(write(`${BUILD}/test/h5ai-styles.css`, {overwrite: true})),
read(`${TEST}/styles.less`)
.then(newerThan(`${BUILD}/test/styles.css`))
.then(includeit())
.then(less())
.then(autoprefixer())
.then(write(`${BUILD}/test/styles.css`, {overwrite: true})),
read(`${TEST}/index.html.jade`)
.then(newerThan(`${BUILD}/test/index.html`))
.then(jade({pkg: runtime.pkg}))
read(`${TEST}/index.html`)
.then(write(`${BUILD}/test/index.html`, {overwrite: true})),
read(`${BUILD}/_h5ai/public/js/scripts.js`)
.then(newerThan(`${BUILD}/test/h5ai-scripts.js`))
.then(write(`${BUILD}/test/h5ai-scripts.js`, {overwrite: true})),
read(`${BUILD}/_h5ai/public/css/styles.css`)
.then(newerThan(`${BUILD}/test/h5ai-styles.css`))
.then(write(`${BUILD}/test/h5ai-styles.css`, {overwrite: true}))
read(`${TEST}: index.js`)
.then(webpack(WEBPACK_CFG))
.then(wrap(`\n\n// @include "${SRC}/**/js/pre.js"\n\n`))
.then(includeit())
.then(write(mapfn.p(TEST, `${BUILD}/test`), {overwrite: true}))
]).then(() => {
console.log(`browse to file://${BUILD}/test/index.html to run the test suite`);
});
@@ -141,11 +138,10 @@ ghu.task('deploy', ['build'], 'deploy to a specified path with :dest=/some/path'
}
console.log(`deploy to ${runtime.args.dest}`);
const mapperDeploy = mapfn.p(BUILD, resolve(runtime.args.dest));
const mapper_deploy = mapfn.p(BUILD, resolve(runtime.args.dest));
return read(`${BUILD}/_h5ai/**`)
.then(newerThan(mapperDeploy))
.then(write(mapperDeploy, {overwrite: true, cluster: true}));
.then(write(mapper_deploy, {overwrite: true, cluster: true}));
});
ghu.task('watch', runtime => {

7428
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,8 @@
{
"name": "h5ai",
"version": "0.28.0",
"version": "0.30.0",
"description": "Modern HTTP web server index.",
"homepage": "https://larsjung.de/h5ai/",
"bugs": "https://github.com/lrsjng/h5ai/issues",
"author": "Lars Jung <lrsjng@gmail.com> (https://larsjung.de)",
"license": "MIT",
"repository": {
@@ -12,17 +11,21 @@
},
"scripts": {
"lint": "eslint .",
"ghu": "node -r babel-core/register ghu.js",
"build": "npm run -s ghu release"
"test": "node test",
"build": "node ghu release",
"precommit": "npm run -s lint && npm run -s test"
},
"devDependencies": {
"babel-core": "6.3.21",
"babel-eslint": "5.0.0-beta6",
"babel-preset-es2015": "6.3.13",
"eslint": "1.10.3",
"ghu": "0.4.0"
},
"engines": {
"node": ">=4.0.0"
"@babel/core": "7.12.10",
"@babel/preset-env": "7.12.11",
"eslint": "7.18.0",
"ghu": "0.26.0",
"jsdom": "16.4.0",
"kjua": "0.9.0",
"lolight": "1.4.0",
"marked": "1.2.7",
"normalize.css": "8.0.1",
"null-loader": "4.0.1",
"scar": "2.3.0"
}
}

View File

@@ -1,43 +1,4 @@
---
env:
es6: false
node: false
browser: true
mocha: false
globals:
modulejs: false
ecmaFeatures:
arrowFunctions: false
binaryLiterals: false
blockBindings: false
classes: false
defaultParams: false
destructuring: false
forOf: false
generators: false
globalReturn: false
jsx: false
modules: false
objectLiteralComputedProperties: false
objectLiteralDuplicateProperties: false
objectLiteralShorthandMethods: false
objectLiteralShorthandProperties: false
octalLiterals: false
regexUFlag: false
regexYFlag: false
spread: false
superInFunctions: false
templateStrings: false
unicodeCodePointEscapes: false
rules:
consistent-this: 0
func-names: 0
max-params: [1, 10]
no-invalid-this: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
no-console: 1
prefer-reflect: 0

View File

@@ -1,3 +1,165 @@
Satisfy all
Order deny,allow
Deny from all
## details here: https://github.com/h5bp/server-configs-apache
## SECURITY ###################################################################
DirectoryIndex disabled
FileETag None
ServerSignature Off
# Apache < 2.3
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
Satisfy All
</IfModule>
# Apache ≥ 2.3
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header unset ETag
Header unset X-Powered-By
</IfModule>
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
## COMPAT #####################################################################
AddDefaultCharset utf-8
<IfModule mod_mime.c>
AddCharset utf-8 .css .html .js .json .php .svg
AddType application/font-woff woff
AddType application/font-woff2 woff2
AddType application/json json
AddType application/javascript js
AddType application/vnd.ms-fontobject eot
AddType application/x-font-ttf ttc ttf
AddType image/jpeg jpeg jpg
AddType image/png png
AddType image/svg+xml svg svgz
AddType image/x-icon ico
AddType font/opentype otf
AddType text/css css
AddType text/html html
</IfModule>
## SPEED ######################################################################
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType text/html "access plus 1 minute"
ExpiresByType image/x-icon "access plus 1 week"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
</IfModule>
<IfModule mod_deflate.c>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
# Apache ≥ 2.3
<IfModule mod_authz_core.c>
# mod_filter as module only available for Apache ≥ 2.3.7
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE "application/atom+xml" \
"application/javascript" \
"application/json" \
"application/ld+json" \
"application/manifest+json" \
"application/rdf+xml" \
"application/rss+xml" \
"application/schema+json" \
"application/vnd.geo+json" \
"application/vnd.ms-fontobject" \
"application/x-font-ttf" \
"application/x-javascript" \
"application/x-web-app-manifest+json" \
"application/xhtml+xml" \
"application/xml" \
"font/eot" \
"font/opentype" \
"image/bmp" \
"image/svg+xml" \
"image/vnd.microsoft.icon" \
"image/x-icon" \
"text/cache-manifest" \
"text/css" \
"text/html" \
"text/javascript" \
"text/plain" \
"text/vcard" \
"text/vnd.rim.location.xloc" \
"text/vtt" \
"text/x-component" \
"text/x-cross-domain-policy" \
"text/xml"
</IfModule>
</IfModule>
# Apache < 2.3
<IfModule !mod_authz_core.c>
AddOutputFilterByType DEFLATE "application/atom+xml" \
"application/javascript" \
"application/json" \
"application/ld+json" \
"application/manifest+json" \
"application/rdf+xml" \
"application/rss+xml" \
"application/schema+json" \
"application/vnd.geo+json" \
"application/vnd.ms-fontobject" \
"application/x-font-ttf" \
"application/x-javascript" \
"application/x-web-app-manifest+json" \
"application/xhtml+xml" \
"application/xml" \
"font/eot" \
"font/opentype" \
"image/bmp" \
"image/svg+xml" \
"image/vnd.microsoft.icon" \
"image/x-icon" \
"text/cache-manifest" \
"text/css" \
"text/html" \
"text/javascript" \
"text/plain" \
"text/vcard" \
"text/vnd.rim.location.xloc" \
"text/vtt" \
"text/x-component" \
"text/x-cross-domain-policy" \
"text/xml"
</IfModule>
<IfModule mod_mime.c>
AddEncoding gzip gz
AddEncoding gzip svgz
</IfModule>
</IfModule>

View File

@@ -1,3 +0,0 @@
Satisfy all
Order deny,allow
Deny from all

View File

@@ -6,13 +6,17 @@
"download": "Descargar",
"empty": "vacío",
"files": "Archivos",
"filter": "Filtar",
"filter": "Filtrar",
"folders": "Directorios",
"grid": "Cuadrícula",
"icons": "Íconos",
"language": "Idioma",
"lastModified": "Última modificación",
"name": "Nombre",
"noMatch": "Sin coincidencias",
"parentDirectory": "Directorio superior",
"size": "Tamaño"
"search": "buscar",
"size": "Tamaño",
"tree": "Arbol",
"view": "Vista"
}

View File

@@ -0,0 +1,22 @@
{
"lang": "estonian",
"dateFormat": "DD-MM-YYYY HH.mm",
"details": "täpsem info",
"download": "laadi alla",
"empty": "tühi",
"files": "failid",
"filter": "filter",
"folders": "kataloogid",
"grid": "võre",
"icons": "ikoonid",
"language": "Keel",
"lastModified": "Viimati muudetud",
"name": "Nimi",
"noMatch": "ei leitud sobivat",
"parentDirectory": "Emakataloog",
"search": "otsi",
"size": "Suurus",
"tree": "Puu",
"view": "Vaade"
}

View File

@@ -6,13 +6,17 @@
"download": "télécharger",
"empty": "vide",
"files": "Fichiers",
"filter": "filtre",
"filter": "filtrer",
"folders": "Répertoires",
"grid": "grille",
"icons": "icônes",
"language": "Langue",
"lastModified": "Dernière modification",
"name": "Nom",
"noMatch": "rien trouvé",
"parentDirectory": "Dossier parent",
"size": "Taille"
"search": "rechercher",
"size": "Taille",
"tree": "Arborescence",
"view": "Disposition"
}

View File

@@ -0,0 +1,22 @@
{
"lang": "Bahasa Indonesia",
"dateFormat": "DD-MM-YYYY HH:mm",
"details": "rincian",
"download": "unduh",
"empty": "kosong",
"files": "berkas",
"filter": "saring",
"folders": "pelipat",
"grid": "jaring",
"icons": "ikon",
"language": "Bahasa",
"lastModified": "Di modifikasi",
"name": "Nama",
"noMatch": "tidak cocok",
"parentDirectory": "Direktori induk",
"search": "cari",
"size": "Ukuran",
"tree": "Pohon",
"view": "Tampil"
}

View File

@@ -10,9 +10,13 @@
"folders": "cartelle",
"grid": "griglia",
"icons": "icone",
"language": "Linugua",
"lastModified": "Ultima modifica",
"name": "Nome",
"noMatch": "nessun risultato",
"parentDirectory": "Cartella Superiore",
"size": "Dimensione"
"search": "cerca",
"size": "Dimensione",
"tree": "Albero",
"view": "Vista"
}

View File

@@ -1,11 +1,22 @@
{
"lang": "nederlands",
"dateFormat": "YYYY-MM-DD HH:mm",
"details": "details",
"empty": "lege",
"download": "download",
"empty": "leeg",
"files": "bestanden",
"filter": "filter",
"folders": "mappen",
"grid": "grid",
"icons": "iconen",
"language": "Taal",
"lastModified": "Laatste wijziging",
"name": "Naam",
"noMatch": "geen overeenkomst",
"parentDirectory": "Bovenliggende map",
"size": "Grootte"
"search": "zoeken",
"size": "Grootte",
"tree": "Boom",
"view": "Bekijk"
}

View File

@@ -10,9 +10,13 @@
"folders": "folderów",
"grid": "kafelki",
"icons": "ikony",
"language": "Język",
"lastModified": "Ostatnia modyfikacja",
"name": "Nazwa",
"noMatch": "nie znaleziono",
"parentDirectory": "Katalog nadrzędny",
"size": "Rozmiar"
"search": "szukaj",
"size": "Rozmiar",
"tree": "Drzewo",
"view": "Układ"
}

View File

@@ -0,0 +1,22 @@
{
"lang": "português do Brasil",
"dateFormat": "DD-MM-YYYY HH:mm",
"details": "detalhes",
"download": "download",
"empty": "vazio",
"files": "arquivos",
"filter": "filtro",
"folders": "pastas",
"grid": "grade",
"icons": "ícones",
"language": "Idioma",
"lastModified": "Última modificação",
"name": "Nome",
"noMatch": "sem resultados",
"parentDirectory": "Diretório acima",
"search": "pesquisa",
"size": "Tamanho",
"tree": "Árvore",
"view": "Visualização"
}

View File

@@ -1,5 +1,5 @@
{
"lang": "português",
"lang": "português de Portugal",
"dateFormat": "DD-MM-YYYY HH:mm",
"details": "detalhes",
@@ -10,9 +10,13 @@
"folders": "pastas",
"grid": "grelha",
"icons": "ícones",
"language": "Idioma",
"lastModified": "última modificação",
"name": "Nome",
"noMatch": "sem resultados",
"parentDirectory": "diretório acima",
"size": "Tamanho"
"parentDirectory": "Diretório acima",
"search": "pesquisa",
"size": "Tamanho",
"tree": "Árvore",
"view": "Visualização"
}

View File

@@ -6,7 +6,7 @@
"download": "下载",
"empty": "空文件夹",
"files": "文件",
"filter": "查找",
"filter": "过滤",
"folders": "文件夹",
"grid": "网格",
"icons": "图标",
@@ -15,6 +15,9 @@
"name": "文件名",
"noMatch": "无匹配项",
"parentDirectory": "父文件夹",
"search": "搜索",
"size": "大小",
"view": "视图"
"tree": "树形目录",
"view": "视图",
"info": "信息"
}

View File

@@ -10,9 +10,14 @@
"folders": "資料夾",
"grid": "網格",
"icons": "圖示",
"language": "語言",
"lastModified": "上次修改",
"name": "檔名",
"noMatch": "沒有符合的檔案",
"parentDirectory": "上層目錄",
"size": "大小"
"search": "搜尋",
"size": "大小",
"tree": "樹形目錄",
"view": "檢視",
"info": "資訊"
}

View File

@@ -32,6 +32,8 @@
General view options.
- binaryPrefix: boolean, set to true uses 1024B=1KiB when formatting file sizes (see http://en.wikipedia.org/wiki/Binary_prefix)
- disableSidebar: boolean, hides sidebar and toggle button
- fallbackMode: boolean, serve fallback mode
- fastBrowsing: boolean, use History API if available (no need to reload the whole page)
- fonts: array of strings, fonts to use in regular context
- fontsMono: array of strings, fonts to use in monopspaced context
@@ -52,12 +54,14 @@
is given the view size is fixed and the selector buttons are hidden.
The user selected view size is also stored local in modern browsers
so that it will be persistent.
- theme: string, name of one of the folders in "_h5ai/images/themes", defaults to "default"
- theme: string, name of one of the folders in "_h5ai/public/images/themes", defaults to "default"
- unmanaged: array of strings, don't manage folders containing one of those files
- unmanagedInNewWindow: boolean, open unmanaged links in new window/tab
*/
"view": {
"binaryPrefix": false,
"disableSidebar": false,
"fallbackMode": false,
"fastBrowsing": true,
"fonts": ["Ubuntu", "Roboto", "Helvetica", "Arial", "sans-serif"],
"fontsMono": ["Ubuntu Mono", "Monaco", "Lucida Sans Typewriter", "monospace"],
@@ -89,13 +93,6 @@
"interval": 5000
},
/*
Enable a context menu (right-click) on some elements.
*/
"contextmenu": {
"enabled": false
},
/*
Show a clickable breadcrumb.
*/
@@ -111,9 +108,14 @@
Note the different filenames: "header" (only current) - "headers" (current and sub directories)!
The file's content will be placed inside a <div/> tag above/below the main content.
If a file's extension is ".md" instead of ".html" its content will be interpreted as markdown.
- stopSearchingAtRoot: boolean, only search for header and footer files until the web root
directory. if `false`, will search for header/footer up the entire directory structure,
even above the web root
*/
"custom": {
"enabled": true
"enabled": true,
"stopSearchingAtRoot": true
},
/*
@@ -142,11 +144,13 @@
- advanced: boolean, use advanced pattern parsing
- debounceTime: number, debounce wait time in milliseconds
- ignorecase: boolean, ignore case
*/
"filter": {
"enabled": false,
"advanced": true,
"debounceTime": 100
"debounceTime": 100,
"ignorecase": true
},
/*
@@ -158,7 +162,7 @@
- type: string, "php" (sloooow) or "shell-du" (sloow)
*/
"foldersize": {
"enabled": false,
"enabled": true,
"type": "php"
},
@@ -184,7 +188,8 @@
"enabled": true,
"show": false,
"qrcode": true,
"qrColor": "#999"
"qrFill": "#999",
"qrBack": "#fff"
},
/*
@@ -201,16 +206,6 @@
"useBrowserLang": true
},
/*
Adds peer5 p2p downloader which is based on webrtc (see peer5.com).
- id: string, the API key
*/
"peer5": {
"enabled": false,
"id": "z142i5n5qypq4cxr"
},
/*
Adds Piwik tracker javascript code.
@@ -226,10 +221,12 @@
/*
Play a audio preview on click.
- autoplay: start playing as soon as ready
- types: array of strings
*/
"preview-aud": {
"enabled": true,
"autoplay": true,
"types": ["aud"]
},
@@ -242,59 +239,59 @@
"preview-img": {
"enabled": true,
"size": false,
"types": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png", "img-raw"]
"types": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png", "img-raw", "img-svg"]
},
/*
Show text file preview on click.
"types" maps file types to http://prismjs.com languages.
Additional type are:
- "markdown" to render Markdown text
- "none" for floating text
- "fixed" for fixed width text
Available styles are:
0: floating text
1: fixed width text
2: markdown
3: syntax highlighting
- types: dict string to string, maps types to languages
- styles: dict string to int, maps types to styles
*/
"preview-txt": {
"enabled": true,
"types": {
"txt": "fixed",
"txt-authors": "fixed",
"txt-c": "c",
"txt-cpp": "cpp",
"txt-css": "css",
"txt-diff": "fixed",
"txt-go": "go",
"txt-h": "c",
"txt-hpp": "cpp",
"txt-install": "fixed",
"txt-java": "java",
"txt-js": "javascript",
"txt-json": "javascript",
"txt-less": "css",
"txt-license": "fixed",
"txt-log": "fixed",
"txt-makefile": "fixed",
"txt-md": "markdown",
// "txt-php": "php",
"txt-py": "python",
"txt-rb": "ruby",
"txt-readme": "fixed",
"txt-rtf": "fixed",
"txt-scala": "scala",
"txt-script": "bash",
"txt-xml": "fixed"
"styles": {
"txt": 1,
"txt-authors": 1,
"txt-c": 3,
"txt-cpp": 3,
"txt-css": 3,
"txt-diff": 1,
"txt-go": 3,
"txt-h": 3,
"txt-hpp": 3,
"txt-install": 1,
"txt-js": 3,
"txt-json": 3,
"txt-less": 3,
"txt-license": 1,
"txt-log": 1,
"txt-makefile": 1,
"txt-md": 2,
"txt-py": 3,
"txt-rb": 3,
"txt-readme": 1,
"txt-rtf": 1,
"txt-rust": 3,
"txt-script": 3,
"txt-xml": 1
}
},
/*
Play a video preview on click.
- autoplay: start playing as soon as ready
- types: array of strings
*/
"preview-vid": {
"enabled": true,
"autoplay": true,
"types": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"]
},
@@ -309,11 +306,13 @@
- advanced: boolean, use advanced pattern parsing
- debounceTime: number, debounce wait time in milliseconds
- ignorecase: boolean, ignore case
*/
"search": {
"enabled": true,
"enabled": false,
"advanced": true,
"debounceTime": 300
"debounceTime": 300,
"ignorecase": true
},
/*
@@ -344,12 +343,12 @@
"column": 0,
"reverse": false,
"ignorecase": true,
"natural": false,
"natural": true,
"folders": 0
},
/*
Show thumbnails for image files. Needs the "/_h5ai/cache" folder to be
Show thumbnails for image files. Needs the "/_h5ai/public/cache" folder to be
writable for the web Server.
- img: array of strings
@@ -358,6 +357,7 @@
- delay: number, delay in milliseconds after "dom-ready" before thumb-requesting starts
- size: number, size in pixel of the generated thumbnails
- exif: boolean, use included EXIF thumbs if possible
- chunksize: int, number of thumbs per request
*/
"thumbnails": {
"enabled": true,
@@ -366,7 +366,8 @@
"doc": ["x-pdf", "x-ps"],
"delay": 1,
"size": 240,
"exif": false
"exif": false,
"chunksize": 20
},
/*
@@ -389,7 +390,7 @@
"enabled": true,
"show": true,
"maxSubfolders": 50,
"naturalSort": false,
"naturalSort": true,
"ignorecase": true
}
}

View File

@@ -18,6 +18,7 @@
"img-jpg": ["*.jpg", "*.jpeg"],
"img-png": ["*.png"],
"img-raw": ["*.cr2", "*.nef"],
"img-svg": ["*.svg"],
"img-tiff": ["*.tiff"],
"txt": ["*.text", "*.txt"],
"txt-build": ["*.pom", "build.xml", "pom.xml"],
@@ -41,9 +42,9 @@
"txt-rb": ["*.rb"],
"txt-rss": ["*.rss"],
"txt-rtf": ["*.rtf"],
"txt-rust": ["*.rs", "*.rlib"],
"txt-script": ["*.conf", "*.bsh", "*.csh", "*.ini", "*.ksh", "*.sh", "*.shar", "*.tcl", "*.zsh"],
"txt-source": [],
"txt-svg": ["*.svg"],
"txt-tex": ["*.tex"],
"txt-vcal": ["*.vcal"],
"txt-xml": ["*.xml"],

View File

@@ -1,11 +1,9 @@
<?php
class Bootstrap {
private static $autopaths = ['core', 'ext'];
public static function run() {
spl_autoload_register(['Bootstrap', 'autoload']);
putenv('LANG=en_US.UTF-8');
setlocale(LC_CTYPE, 'en_US.UTF-8');
@@ -13,26 +11,27 @@ class Bootstrap {
session_start();
$session = new Session($_SESSION);
$request = new Request($_REQUEST);
$request = new Request($_REQUEST, file_get_contents('php://input'));
$setup = new Setup($request->query_boolean('refresh', false));
$context = new Context($session, $request, $setup);
if ($context->is_api_request()) {
(new Api($context))->apply();
} else if ($context->is_info_request()) {
} elseif ($context->is_info_request()) {
$public_href = $setup->get('PUBLIC_HREF');
$x_head_tags = $context->get_x_head_html();
$fallback_mode = false;
require __DIR__ . '/pages/info.php';
} else {
$public_href = $setup->get('PUBLIC_HREF');
$x_head_tags = $context->get_x_head_html();
$fallback_mode = $context->is_fallback_mode();
$fallback_html = (new Fallback($context))->get_html();
require __DIR__ . '/pages/index.php';
}
}
public static function autoload($class_name) {
$filename = 'class-' . strtolower($class_name) . '.php';
foreach (Bootstrap::$autopaths as $path) {

View File

@@ -1,20 +1,17 @@
<?php
class Api {
private $context;
private $request;
private $setup;
public function __construct($context) {
$this->context = $context;
$this->request = $context->get_request();
$this->setup = $context->get_setup();
}
public function apply() {
$action = $this->request->query('action');
$supported = ['download', 'get', 'login', 'logout'];
Util::json_fail(Util::ERR_UNSUPPORTED, 'unsupported action', !in_array($action, $supported));
@@ -24,17 +21,17 @@ class Api {
}
private function on_download() {
Util::json_fail(Util::ERR_DISABLED, 'download disabled', !$this->context->query_option('download.enabled', false));
$as = $this->request->query('as');
$type = $this->request->query('type');
$base_href = $this->request->query('baseHref');
$hrefs = $this->request->query('hrefs');
$hrefs = $this->request->query('hrefs', '');
$archive = new Archive($this->context);
set_time_limit(0);
session_write_close();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $as . '"');
header('Connection: close');
@@ -45,70 +42,57 @@ class Api {
}
private function on_get() {
$response = [];
foreach (['langs', 'options', 'types'] as $name) {
if ($this->request->query_boolean($name, false)) {
$methodname = 'get_' . $name;
$response[$name] = $this->context->$methodname();
}
}
if ($this->request->query_boolean('setup', false)) {
$response['setup'] = $this->setup->to_jsono($this->context->is_admin());
}
if ($this->request->query_boolean('theme', false)) {
$theme = new Theme($this->context);
$response['theme'] = $theme->get_icons();
}
if ($this->request->query('items', false)) {
$href = $this->request->query('items.href');
$what = $this->request->query_numeric('items.what');
$response['items'] = $this->context->get_items($href, $what);
}
if ($this->request->query('custom', false)) {
Util::json_fail(Util::ERR_DISABLED, 'custom disabled', !$this->context->query_option('custom.enabled', false));
$href = $this->request->query('custom');
$custom = new Custom($this->context);
$response['custom'] = $custom->get_customizations($href);
}
if ($this->request->query('l10n', false)) {
Util::json_fail(Util::ERR_DISABLED, 'l10n disabled', !$this->context->query_option('l10n.enabled', false));
$iso_codes = $this->request->query_array('l10n');
$iso_codes = array_filter($iso_codes);
$response['l10n'] = $this->context->get_l10n($iso_codes);
}
if ($this->request->query('search', false)) {
Util::json_fail(Util::ERR_DISABLED, 'search disabled', !$this->context->query_option('search.enabled', false));
$href = $this->request->query('search.href');
$pattern = $this->request->query('search.pattern');
$ignorecase = $this->request->query_boolean('search.ignorecase', false);
$search = new Search($this->context);
$response['search'] = $search->get_items($href, $pattern);
$response['search'] = $search->get_items($href, $pattern, $ignorecase);
}
if ($this->request->query('thumbs', false)) {
Util::json_fail(Util::ERR_DISABLED, 'thumbnails disabled', !$this->context->query_option('thumbnails.enabled', false));
Util::json_fail(Util::ERR_UNSUPPORTED, 'thumbnails not supported', !$this->setup->get('HAS_PHP_JPEG'));
$thumbs = $this->request->query_array('thumbs');
$response['thumbs'] = $this->context->get_thumbs($thumbs);
}
@@ -116,13 +100,11 @@ class Api {
}
private function on_login() {
$pass = $this->request->query('pass');
Util::json_exit(['asAdmin' => $this->context->login_admin($pass)]);
}
private function on_logout() {
Util::json_exit(['asAdmin' => $this->context->logout_admin()]);
}
}

View File

@@ -1,9 +1,14 @@
<?php
class Context {
private static $DEFAULT_PASSHASH = 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
private static $AS_ADMIN_SESSION_KEY = 'AS_ADMIN';
private static $L10N_ISO_CODES = array(
'af', 'bg', 'cs', 'da', 'de', 'el', 'en', 'es', 'et', 'fi', 'fr', 'he',
'hi', 'hr', 'hu', 'id', 'it', 'ja','ko', 'lv', 'nb', 'nl', 'pl',
'pt-br', 'pt-pt', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv', 'tr', 'uk',
'zh-cn', 'zh-tw'
);
private $session;
private $request;
@@ -12,7 +17,6 @@ class Context {
private $passhash;
public function __construct($session, $request, $setup) {
$this->session = $session;
$this->request = $request;
$this->setup = $setup;
@@ -25,64 +29,60 @@ class Context {
}
public function get_session() {
return $this->session;
}
public function get_request() {
return $this->request;
}
public function get_setup() {
return $this->setup;
}
public function get_options() {
return $this->options;
}
public function query_option($keypath = '', $default = null) {
return Util::array_query($this->options, $keypath, $default);
}
public function get_types() {
return Json::load($this->setup->get('CONF_PATH') . '/types.json');
}
public function login_admin($pass) {
$this->session->set(Context::$AS_ADMIN_SESSION_KEY, strcasecmp(hash('sha512', $pass), $this->passhash) === 0);
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
}
public function logout_admin() {
$this->session->set(Context::$AS_ADMIN_SESSION_KEY, false);
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
}
public function is_admin() {
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
}
public function is_api_request() {
return strtolower($this->setup->get('REQUEST_METHOD')) === 'post';
}
public function is_info_request() {
return Util::starts_with($this->setup->get('REQUEST_HREF') . '/', $this->setup->get('PUBLIC_HREF'));
}
public function to_href($path, $trailing_slash = true) {
public function is_text_browser() {
return preg_match('/curl|links|lynx|w3m/i', $this->setup->get('HTTP_USER_AGENT')) === 1;
}
public function is_fallback_mode() {
return $this->query_option('view.fallbackMode', false) || $this->is_text_browser();
}
public function to_href($path, $trailing_slash = true) {
$rel_path = substr($path, strlen($this->setup->get('ROOT_PATH')));
$parts = explode('/', $rel_path);
$encoded_parts = [];
@@ -96,13 +96,11 @@ class Context {
}
public function to_path($href) {
$rel_href = substr($href, strlen($this->setup->get('ROOT_HREF')));
return Util::normalize_path($this->setup->get('ROOT_PATH') . '/' . rawurldecode($rel_href));
}
public function is_hidden($name) {
// always hide
if ($name === '.' || $name === '..') {
return true;
@@ -119,7 +117,6 @@ class Context {
}
public function read_dir($path) {
$names = [];
if (is_dir($path)) {
foreach (scandir($path) as $name) {
@@ -137,12 +134,10 @@ class Context {
}
public function is_managed_href($href) {
return $this->is_managed_path($this->to_path($href));
}
public function is_managed_path($path) {
if (!is_dir($path) || strpos($path, '../') !== false || strpos($path, '/..') !== false || $path === '..') {
return false;
}
@@ -175,7 +170,6 @@ class Context {
}
public function get_current_path() {
$current_href = Util::normalize_path($this->setup->get('REQUEST_HREF'), true);
$current_path = $this->to_path($current_href);
@@ -187,7 +181,6 @@ class Context {
}
public function get_items($href, $what) {
if (!$this->is_managed_href($href)) {
return [];
}
@@ -219,7 +212,6 @@ class Context {
}
public function get_langs() {
$langs = [];
$l10n_path = $this->setup->get('CONF_PATH') . '/l10n';
if (is_dir($l10n_path)) {
@@ -238,10 +230,13 @@ class Context {
}
public function get_l10n($iso_codes) {
$results = [];
foreach ($iso_codes as $iso_code) {
if (!in_array($iso_code, Context::$L10N_ISO_CODES)) {
continue;
}
$file = $this->setup->get('CONF_PATH') . '/l10n/' . $iso_code . '.json';
$results[$iso_code] = Json::load($file);
$results[$iso_code]['isoCode'] = $iso_code;
@@ -251,7 +246,6 @@ class Context {
}
public function get_thumbs($requests) {
$hrefs = [];
foreach ($requests as $req) {
@@ -263,7 +257,6 @@ class Context {
}
private function prefix_x_head_href($href) {
if (preg_match('@^(https?://|/)@i', $href)) {
return $href;
}
@@ -272,7 +265,6 @@ class Context {
}
private function get_fonts_html() {
$fonts = $this->query_option('view.fonts', []);
$fonts_mono = $this->query_option('view.fontsMono', []);
@@ -292,7 +284,6 @@ class Context {
}
public function get_x_head_html() {
$scripts = $this->query_option('resources.scripts', []);
$styles = $this->query_option('resources.styles', []);

View File

@@ -1,16 +1,13 @@
<?php
class Fallback {
private $context;
public function __construct($context) {
$this->context = $context;
}
public function get_html($path = null) {
if (!$path) {
$path = $this->context->get_current_path();
}

View File

@@ -1,47 +1,28 @@
<?php
class Filesize {
private static $cache = [];
private $cache = [];
public function __construct() {
public static function getSize($path, $withFoldersize, $withDu) {
$fs = new Filesize();
return $fs->size($path, $withFoldersize, $withDu);
}
public function fseek($path) {
$size = 0;
$step = 1073741824;
$handle = fopen($path, 'r');
fseek($handle, 0, SEEK_SET);
while ($step > 1) {
fseek($handle, $step, SEEK_CUR);
if (fgetc($handle) !== false) {
$size += $step + 1;
} else {
fseek($handle, -$step, SEEK_CUR);
$step = intval($step / 2, 10);
}
public static function getCachedSize($path, $withFoldersize, $withDu) {
if (array_key_exists($path, Filesize::$cache)) {
return Filesize::$cache[$path];
}
while (fgetc($handle) !== false) {
$size += 1;
}
fclose($handle);
$size = Filesize::getSize($path, $withFoldersize, $withDu);
Filesize::$cache[$path] = $size;
return $size;
}
public function filesize($path) {
return @filesize($path);
}
private function __construct() {}
private function read_dir($path) {
$paths = [];
if (is_dir($path)) {
foreach (scandir($path) as $name) {
@@ -53,8 +34,23 @@ class Filesize {
return $paths;
}
private function exec($cmdv) {
private function php_filesize($path, $recursive = false) {
// if (PHP_INT_SIZE < 8) {
// }
$size = @filesize($path);
if (!is_dir($path) || !$recursive) {
return $size;
}
foreach ($this->read_dir($path) as $p) {
$size += $this->php_filesize($p, true);
}
return $size;
}
private function exec($cmdv) {
$cmd = implode(' ', array_map('escapeshellarg', $cmdv));
$lines = [];
$rc = null;
@@ -62,38 +58,39 @@ class Filesize {
return $lines;
}
public function du_paths($paths) {
$cmdv = array_merge(['du', '-sk'], $paths);
private function exec_du_all($paths) {
$cmdv = array_merge(['du', '-sbL'], $paths);
$lines = $this->exec($cmdv);
$sizes = [];
foreach ($lines as $line) {
$parts = preg_split('/[\s]+/', $line, 2);
$size = intval($parts[0], 10) * 1024;
$size = intval($parts[0], 10);
$path = $parts[1];
$sizes[$path] = $size;
}
return $sizes;
}
public function du_dir($path) {
return $this->du_paths($this->read_dir($path));
}
public function du_path($path) {
$sizes = $this->du_paths([$path]);
private function exec_du($path) {
$sizes = $this->exec_du_all([$path]);
return $sizes[$path];
}
public function add($path) {
$size = 0;
foreach ($this->read_dir($path) as $p) {
$size += $this->filesize($p);
private function size($path, $withFoldersize = false, $withDu = false) {
if (is_file($path)) {
return $this->php_filesize($path);
}
return $size;
if (is_dir($path) && $withFoldersize) {
if ($withDu) {
return $this->exec_du($path);
}
return $this->php_filesize($path, true);
}
return null;
}
}

View File

@@ -1,9 +1,7 @@
<?php
class Item {
public static function cmp($item1, $item2) {
if ($item1->is_folder && !$item2->is_folder) {
return -1;
}
@@ -15,7 +13,6 @@ class Item {
}
public static function get($context, $path, &$cache) {
if (!Util::starts_with($path, $context->get_setup()->get('ROOT_PATH'))) {
return null;
}
@@ -41,7 +38,6 @@ class Item {
public $is_content_fetched;
private function __construct($context, $path) {
$this->context = $context;
$this->path = Util::normalize_path($path, false);
@@ -53,7 +49,6 @@ class Item {
}
public function to_json_object() {
$obj = [
'href' => $this->href,
'time' => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript)
@@ -69,7 +64,6 @@ class Item {
}
public function get_parent(&$cache) {
$parent_path = Util::normalize_path(dirname($this->path), false);
if ($parent_path !== $this->path && Util::starts_with($parent_path, $this->context->get_setup()->get('ROOT_PATH'))) {
return Item::get($this->context, $parent_path, $cache);
@@ -78,7 +72,6 @@ class Item {
}
public function get_content(&$cache) {
$items = [];
if (!$this->context->is_managed_href($this->href)) {

View File

@@ -1,12 +1,10 @@
<?php
class Json {
const SINGLE = 1;
const MULTI = 2;
public static function load($path) {
if (!is_readable($path)) {
return [];
}
@@ -16,25 +14,21 @@ class Json {
}
public static function save($path, $obj) {
$json = json_encode($obj);
return file_put_contents($path, $json) !== false;
}
public static function decode($json) {
private static function decode($json) {
$json = Json::strip($json);
return json_decode($json, true);
}
public static function strip($commented_json) {
private static function strip($commented_json) {
$insideString = false;
$insideComment = false;
$json = '';
for ($i = 0; $i < strlen($commented_json); $i += 1) {
for ($i = 0, $len = strlen($commented_json); $i < $len; $i += 1) {
$char = $commented_json[$i];
$charchar = $char . @$commented_json[$i + 1];
$prevChar = @$commented_json[$i - 1];
@@ -45,22 +39,22 @@ class Json {
if ($insideString) {
$json .= $char;
} else if (!$insideComment && $charchar === '//') {
} elseif (!$insideComment && $charchar === '//') {
$insideComment = Json::SINGLE;
$i += 1;
} else if (!$insideComment && $charchar === '/*') {
} elseif (!$insideComment && $charchar === '/*') {
$insideComment = Json::MULTI;
$i += 1;
} else if (!$insideComment) {
} elseif (!$insideComment) {
$json .= $char;
} else if ($insideComment === Json::SINGLE && $charchar === "\r\n") {
} elseif ($insideComment === Json::SINGLE && $charchar === "\r\n") {
$insideComment = false;
$json .= $charchar;
$i += 1;
} else if ($insideComment === Json::SINGLE && $char === "\n") {
} elseif ($insideComment === Json::SINGLE && $char === "\n") {
$insideComment = false;
$json .= $char;
} else if ($insideComment === Json::MULTI && $charchar === '*/') {
} elseif ($insideComment === Json::MULTI && $charchar === '*/') {
$insideComment = false;
$i += 1;
}

View File

@@ -1,25 +1,21 @@
<?php
class Logger {
private static $start;
private static $prev;
public static function init() {
private static function time() {
return microtime(true) * 1000; // sec * 1000 = ms
}
public static function init() {
self::$start = self::time();
self::$prev = self::$start;
register_shutdown_function(function () { Logger::log('shutdown'); });
Logger::log('--------------------------------');
}
private static function time() {
return microtime(true) * 1000; // sec * 1000 = ms
}
public static function log($message=null, $obj=null) {
$now = self::time();
$message = number_format($now - self::$start, 3) . ' ' . number_format($now - self::$prev, 3) . ' ' . $message;
@@ -28,4 +24,5 @@ class Logger {
self::$prev = $now;
}
}
Logger::init();

View File

@@ -1,16 +1,14 @@
<?php
class Request {
private $params;
public function __construct($params) {
$this->params = $params;
public function __construct($params, $body) {
$data = json_decode($body, true);
$this->params = $data !== null ? $data : $params;
}
public function query($keypath = '', $default = Util::NO_DEFAULT) {
$value = Util::array_query($this->params, $keypath, Util::NO_DEFAULT);
if ($value === Util::NO_DEFAULT) {
@@ -22,20 +20,17 @@ class Request {
}
public function query_boolean($keypath = '', $default = Util::NO_DEFAULT) {
$value = $this->query($keypath, $default);
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
public function query_numeric($keypath = '', $default = Util::NO_DEFAULT) {
$value = $this->query($keypath, $default);
Util::json_fail(Util::ERR_ILLIGAL_PARAM, 'parameter \'' . $keypath . '\' is not numeric', !is_numeric($value));
return intval($value, 10);
}
public function query_array($keypath = '', $default = Util::NO_DEFAULT) {
$value = $this->query($keypath, $default);
Util::json_fail(Util::ERR_ILLIGAL_PARAM, 'parameter \'' . $keypath . '\' is no array', !is_array($value));
return $value;

View File

@@ -1,24 +1,19 @@
<?php
class Session {
private static $KEY_PREFIX = '__H5AI__';
private $store;
public function __construct(&$store) {
$this->store = &$store;
}
public function set($key, $value) {
$key = Session::$KEY_PREFIX . $key;
$this->store[$key] = $value;
}
public function get($key, $default = null) {
$key = Session::$KEY_PREFIX . $key;
return array_key_exists($key, $this->store) ? $this->store[$key] : $default;
}

View File

@@ -1,12 +1,10 @@
<?php
class Setup {
private $store;
private $refresh;
public function __construct($refresh = false) {
$this->store = [];
$this->refresh = $refresh;
@@ -19,7 +17,6 @@ class Setup {
}
private function set($key, $value) {
if (array_key_exists($key, $this->store)) {
Logger::log('setup key already taken', [
'key' => $key,
@@ -40,7 +37,6 @@ class Setup {
}
public function get($key) {
if (!array_key_exists($key, $this->store)) {
Logger::log('setup key not found', ['key' => $key]);
exit;
@@ -50,18 +46,18 @@ class Setup {
}
private function add_globals_and_envs() {
$this->set('PHP_VERSION', PHP_VERSION);
$this->set('MIN_PHP_VERSION', MIN_PHP_VERSION);
$this->set('PHP_ARCH', (PHP_INT_SIZE * 8) . '-bit');
$this->set('REQUEST_METHOD', getenv('REQUEST_METHOD'));
$this->set('REQUEST_HREF', parse_url(getenv('REQUEST_URI'), PHP_URL_PATH));
$this->set('SCRIPT_NAME', getenv('SCRIPT_NAME'));
$this->set('SERVER_SOFTWARE', getenv('SERVER_SOFTWARE'));
$this->set('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']);
$this->set('REQUEST_HREF', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
$this->set('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
$this->set('SERVER_SOFTWARE', $_SERVER['SERVER_SOFTWARE']);
$this->set('HTTP_USER_AGENT', $_SERVER['HTTP_USER_AGENT']);
}
private function add_php_checks() {
$this->set('HAS_PHP_EXIF', function_exists('exif_thumbnail'));
$has_php_jpeg = false;
@@ -73,14 +69,12 @@ class Setup {
}
private function add_app_metadata() {
$this->set('NAME', 'h5ai');
$this->set('VERSION', H5AI_VERSION);
$this->set('FILE_PREFIX', '_h5ai');
}
private function add_server_metadata_and_check() {
$server_software = $this->get('SERVER_SOFTWARE');
$server_name = null;
$server_version = null;
@@ -96,7 +90,6 @@ class Setup {
}
private function add_paths() {
$script_name = $this->get('SCRIPT_NAME');
if ($this->get('SERVER_NAME') === 'lighttpd') {
$script_name = preg_replace('#^.*?//#', '/', $script_name);
@@ -123,23 +116,25 @@ class Setup {
}
private function add_sys_cmd_checks() {
$cmds_cache_path = Util::normalize_path($this->get('CACHE_PRV_PATH') . '/cmds.json', false);
$cmds = Json::load($cmds_cache_path);
if (sizeof($cmds) === 0 || $this->refresh) {
$cmds['command'] = Util::exec_0('command -v command');
$cmds['which'] = Util::exec_0('which which');
$cmds['which'] = Util::exec_0('which which') || Util::exec_0('which which.exe');
$cmds['where'] = Util::exec_0('where where.exe');
$cmd = false;
if ($cmds['command']) {
$cmd = 'command -v';
} else if ($cmds['which']) {
} elseif ($cmds['which']) {
$cmd = 'which';
} elseif ($cmds['where']) {
$cmd = 'where';
}
foreach (['avconv', 'convert', 'du', 'ffmpeg', 'gm', 'tar', 'zip'] as $c) {
$cmds[$c] = ($cmd !== false) && Util::exec_0($cmd . ' ' . $c);
$cmds[$c] = ($cmd !== false) && (Util::exec_0($cmd . ' ' . $c) || Util::exec_0($cmd . ' ' . $c . '.exe'));
}
Json::save($cmds_cache_path, $cmds);
@@ -150,7 +145,6 @@ class Setup {
}
public function to_jsono($as_admin = false) {
$keys = [
'PUBLIC_HREF',
'ROOT_HREF'
@@ -162,6 +156,7 @@ class Setup {
'PHP_VERSION',
'MIN_PHP_VERSION',
'PHP_ARCH',
'HAS_PHP_EXIF',
'HAS_PHP_JPEG',

View File

@@ -1,18 +1,14 @@
<?php
class Theme {
private static $EXTENSIONS = ['svg', 'png', 'jpg'];
private $context;
public function __construct($context) {
$this->context = $context;
}
public function get_icons() {
$public_path = $this->context->get_setup()->get('PUBLIC_PATH');
$theme = $this->context->query_option('view.theme', '-NONE-');
$theme_path = $public_path . '/images/themes/' . $theme;

View File

@@ -1,7 +1,6 @@
<?php
class Util {
const ERR_MISSING_PARAM = 'ERR_MISSING_PARAM';
const ERR_ILLIGAL_PARAM = 'ERR_ILLIGAL_PARAM';
const ERR_FAILED = 'ERR_FAILED';
@@ -11,27 +10,23 @@ class Util {
const RE_DELIMITER = '@';
public static function normalize_path($path, $trailing_slash = false) {
$path = preg_replace('#[\\\\/]+#', '/', $path);
return preg_match('#^(\w:)?/$#', $path) ? $path : (rtrim($path, '/') . ($trailing_slash ? '/' : ''));
}
public static function json_exit($obj = []) {
header('Content-type: application/json;charset=utf-8');
echo json_encode($obj);
exit;
}
public static function json_fail($err, $msg = '', $cond = true) {
if ($cond) {
Util::json_exit(['err' => $err, 'msg' => $msg]);
}
}
public static function array_query($array, $keypath = '', $default = Util::NO_DEFAULT) {
$value = $array;
$keys = array_filter(explode('.', $keypath));
@@ -46,30 +41,25 @@ class Util {
}
public static function starts_with($sequence, $head) {
return substr($sequence, 0, strlen($head)) === $head;
}
public static function ends_with($sequence, $tail) {
$len = strlen($tail);
return $len === 0 ? true : substr($sequence, -$len) === $tail;
}
public static function wrap_pattern($pattern) {
return Util::RE_DELIMITER . str_replace(Util::RE_DELIMITER, '\\' . Util::RE_DELIMITER, $pattern) . Util::RE_DELIMITER;
}
public static function passthru_cmd($cmd) {
$rc = null;
passthru($cmd, $rc);
return $rc;
}
public static function exec_cmdv($cmdv) {
if (!is_array($cmdv)) {
$cmdv = func_get_args();
}
@@ -82,7 +72,6 @@ class Util {
}
public static function exec_0($cmd) {
$lines = [];
$rc = null;
try {
@@ -92,32 +81,9 @@ class Util {
return false;
}
private static $size_cache = [];
public static function filesize($context, $path) {
if (array_key_exists($path, Util::$size_cache)) {
return Util::$size_cache[$path];
}
$fs = new Filesize();
$size = null;
if (is_file($path)) {
if (PHP_INT_SIZE < 8) {
$size = $fs->fseek($path);
} else {
$size = $fs->filesize($path);
}
} else if (is_dir($path) && $context->query_option('foldersize.enabled', false)) {
if ($context->get_setup()->get('HAS_CMD_DU') && $context->query_option('foldersize.type', null) === 'shell-du') {
$size = $fs->du_path($path);
} else {
$size = $fs->add($path);
}
}
Util::$size_cache[$path] = $size;
return $size;
$withFoldersize = $context->query_option('foldersize.enabled', false);
$withDu = $context->get_setup()->get('HAS_CMD_DU') && $context->query_option('foldersize.type', null) === 'shell-du';
return Filesize::getCachedSize($path, $withFoldersize, $withDu);
}
}

View File

@@ -1,7 +1,6 @@
<?php
class Archive {
const NULL_BYTE = "\0";
private static $SEGMENT_SIZE = 16777216; // 1024 * 1024 * 16 = 16MiB
@@ -14,12 +13,10 @@ class Archive {
private $files;
public function __construct($context) {
$this->context = $context;
}
public function output($type, $base_href, $hrefs) {
$this->base_path = $this->context->to_path($base_href);
if (!$this->context->is_managed_path($this->base_path)) {
return false;
@@ -39,22 +36,16 @@ class Archive {
}
if ($type === 'php-tar') {
return $this->php_tar($this->dirs, $this->files);
} else if ($type === 'shell-tar') {
} elseif ($type === 'shell-tar') {
return $this->shell_cmd(Archive::$TAR_PASSTHRU_CMD);
} else if ($type === 'shell-zip') {
} elseif ($type === 'shell-zip') {
return $this->shell_cmd(Archive::$ZIP_PASSTHRU_CMD);
}
return false;
}
private function shell_cmd($cmd) {
$cmd = str_replace('[ROOTDIR]', escapeshellarg($this->base_path), $cmd);
$cmd = str_replace('[DIRS]', count($this->dirs) ? implode(' ', array_map('escapeshellarg', $this->dirs)) : '', $cmd);
$cmd = str_replace('[FILES]', count($this->files) ? implode(' ', array_map('escapeshellarg', $this->files)) : '', $cmd);
@@ -67,11 +58,9 @@ class Archive {
}
private function php_tar($dirs, $files) {
$filesizes = [];
$total_size = 512 * count($dirs);
foreach (array_keys($files) as $real_file) {
$size = filesize($real_file);
$filesizes[$real_file] = $size;
@@ -84,11 +73,10 @@ class Archive {
header('Content-Length: ' . $total_size);
foreach ($dirs as $real_dir => $archived_dir) {
echo $this->php_tar_header($archived_dir, 0, @filemtime($real_dir . DIRECTORY_SEPARATOR . "."), 5);
echo $this->php_tar_header($archived_dir, 0, @filemtime($real_dir . DIRECTORY_SEPARATOR . '.'), 5);
}
foreach ($files as $real_file => $archived_file) {
foreach ($files as $real_file => $archived_file) {
$size = $filesizes[$real_file];
echo $this->php_tar_header($archived_file, $size, @filemtime($real_file), 0);
@@ -103,7 +91,6 @@ class Archive {
}
private function php_tar_header($filename, $size, $mtime, $type) {
$name = substr(basename($filename), -99);
$prefix = substr(Util::normalize_path(dirname($filename)), -154);
if ($prefix === '.') {
@@ -136,7 +123,6 @@ class Archive {
}
private function print_file($file) {
// Send file content in segments to not hit PHP's memory limit (default: 128M)
if ($fd = fopen($file, 'rb')) {
while (!feof($fd)) {
@@ -149,14 +135,17 @@ class Archive {
}
private function add_hrefs($hrefs) {
if (!is_array($hrefs)) {
$hrefs = array($hrefs);
}
foreach ($hrefs as $href) {
if (trim($href) === '') {
continue;
}
$d = Util::normalize_path(dirname($href), true);
$href = Util::normalize_path($href, false);
$d = dirname($href);
$n = basename($href);
if ($this->context->is_managed_href($d) && !$this->context->is_hidden($n)) {
@@ -174,20 +163,17 @@ class Archive {
}
private function add_file($real_file, $archived_file) {
if (is_readable($real_file)) {
$this->files[$real_file] = $archived_file;
}
}
private function add_dir($real_dir, $archived_dir) {
if ($this->context->is_managed_path($real_dir)) {
$this->dirs[$real_dir] = $archived_dir;
$files = $this->context->read_dir($real_dir);
foreach ($files as $file) {
$real_file = $real_dir . '/' . $file;
$archived_file = $archived_dir . '/' . $file;

View File

@@ -1,18 +1,14 @@
<?php
class Custom {
private static $EXTENSIONS = ['html', 'md'];
private $context;
public function __construct($context) {
$this->context = $context;
}
private function read_custom_file($path, $name, &$content, &$type) {
$file_prefix = $this->context->get_setup()->get('FILE_PREFIX');
foreach (Custom::$EXTENSIONS as $ext) {
@@ -26,7 +22,6 @@ class Custom {
}
public function get_customizations($href) {
if (!$this->context->query_option('custom.enabled', false)) {
return [
'header' => ['content' => null, 'type' => null],
@@ -46,14 +41,12 @@ class Custom {
$this->read_custom_file($path, 'footer', $footer, $footer_type);
while ($header === null || $footer === null) {
if ($header === null) {
$this->read_custom_file($path, 'headers', $header, $header_type);
}
if ($footer === null) {
$this->read_custom_file($path, 'footers', $footer, $footer_type);
}
if ($path === $root_path) {
break;
}
@@ -61,6 +54,14 @@ class Custom {
if ($parent_path === $path) {
break;
}
// Stop once we reach the root
if (
$this->context->query_option('custom.stopSearchingAtRoot', true) &&
$path === $this->context->get_setup()->get('ROOT_PATH')
) {
break;
}
$path = $parent_path;
}

View File

@@ -1,19 +1,19 @@
<?php
class Search {
private $context;
public function __construct($context) {
$this->context = $context;
}
public function get_paths($root, $pattern = null) {
public function get_paths($root, $pattern = null, $ignorecase = false) {
$paths = [];
if ($pattern && $this->context->is_managed_path($root)) {
$re = Util::wrap_pattern($pattern);
if ($ignorecase) {
$re .= 'i';
}
$names = $this->context->read_dir($root);
foreach ($names as $name) {
$path = $root . '/' . $name;
@@ -21,20 +21,18 @@ class Search {
$paths[] = $path;
}
if (@is_dir($path)) {
$paths = array_merge($paths, $this->get_paths($path, $pattern));
$paths = array_merge($paths, $this->get_paths($path, $pattern, $ignorecase));
}
}
}
return $paths;
}
public function get_items($href, $pattern = null) {
public function get_items($href, $pattern = null, $ignorecase = false) {
$cache = [];
$root = $this->context->to_path($href);
$paths = $this->get_paths($root, $pattern);
$paths = $this->get_paths($root, $pattern, $ignorecase);
$items = array_map(function ($path) {
return Item::get($this->context, $path, $cache)->to_json_object();
}, $paths);
return $items;

View File

@@ -1,11 +1,10 @@
<?php
class Thumb {
private static $FFMPEG_CMDV = ['ffmpeg', '-ss', '0:00:10', '-i', '[SRC]', '-an', '-vframes', '1', '[DEST]'];
private static $AVCONV_CMDV = ['avconv', '-ss', '0:00:10', '-i', '[SRC]', '-an', '-vframes', '1', '[DEST]'];
private static $CONVERT_CMDV = ['convert', '-density', '200', '-quality', '100', '-sharpen', '0x1.0', '-strip', '[SRC][0]', '[DEST]'];
private static $GM_CONVERT_CMDV = ['gm', 'convert', '-density', '200', '-quality', '100', '-sharpen', '0x1.0', '[SRC][0]', '[DEST]'];
private static $CONVERT_CMDV = ['convert', '-density', '200', '-quality', '100', '-strip', '[SRC][0]', '[DEST]'];
private static $GM_CONVERT_CMDV = ['gm', 'convert', '-density', '200', '-quality', '100', '[SRC][0]', '[DEST]'];
private static $THUMB_CACHE = 'thumbs';
private $context;
@@ -14,7 +13,6 @@ class Thumb {
private $thumbs_href;
public function __construct($context) {
$this->context = $context;
$this->setup = $context->get_setup();
$this->thumbs_path = $this->setup->get('CACHE_PUB_PATH') . '/' . Thumb::$THUMB_CACHE;
@@ -26,7 +24,6 @@ class Thumb {
}
public function thumb($type, $source_href, $width, $height) {
$source_path = $this->context->to_path($source_href);
if (!file_exists($source_path) || Util::starts_with($source_path, $this->setup->get('CACHE_PUB_PATH'))) {
return null;
@@ -35,16 +32,16 @@ class Thumb {
$capture_path = $source_path;
if ($type === 'img') {
$capture_path = $source_path;
} else if ($type === 'mov') {
} elseif ($type === 'mov') {
if ($this->setup->get('HAS_CMD_AVCONV')) {
$capture_path = $this->capture(Thumb::$AVCONV_CMDV, $source_path);
} else if ($this->setup->get('HAS_CMD_FFMPEG')) {
} elseif ($this->setup->get('HAS_CMD_FFMPEG')) {
$capture_path = $this->capture(Thumb::$FFMPEG_CMDV, $source_path);
}
} else if ($type === 'doc') {
} elseif ($type === 'doc') {
if ($this->setup->get('HAS_CMD_CONVERT')) {
$capture_path = $this->capture(Thumb::$CONVERT_CMDV, $source_path);
} else if ($this->setup->get('HAS_CMD_GM')) {
} elseif ($this->setup->get('HAS_CMD_GM')) {
$capture_path = $this->capture(Thumb::$GM_CONVERT_CMDV, $source_path);
}
}
@@ -53,7 +50,6 @@ class Thumb {
}
private function thumb_href($source_path, $width, $height) {
if (!file_exists($source_path)) {
return null;
}
@@ -63,7 +59,6 @@ class Thumb {
$thumb_href = $this->thumbs_href . '/' . $name;
if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) {
$image = new Image();
$et = false;
@@ -86,7 +81,6 @@ class Thumb {
}
private function capture($cmdv, $source_path) {
if (!file_exists($source_path)) {
return null;
}
@@ -94,7 +88,6 @@ class Thumb {
$capture_path = $this->thumbs_path . '/capture-' . sha1($source_path) . '.jpg';
if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) {
foreach ($cmdv as &$arg) {
$arg = str_replace('[SRC]', $source_path, $arg);
$arg = str_replace('[DEST]', $capture_path, $arg);
@@ -108,7 +101,6 @@ class Thumb {
}
class Image {
private $source_file;
private $source;
private $width;
@@ -117,7 +109,6 @@ class Image {
private $dest;
public function __construct($filename = null) {
$this->source_file = null;
$this->source = null;
$this->width = null;
@@ -130,13 +121,11 @@ class Image {
}
public function __destruct() {
$this->release_source();
$this->release_dest();
}
public function set_source($filename) {
$this->release_source();
$this->release_dest();
@@ -160,7 +149,6 @@ class Image {
}
public function save_dest_jpeg($filename, $quality = 80) {
if (!is_null($this->dest)) {
@imagejpeg($this->dest, $filename, $quality);
@chmod($filename, 0775);
@@ -168,7 +156,6 @@ class Image {
}
public function release_dest() {
if (!is_null($this->dest)) {
@imagedestroy($this->dest);
$this->dest = null;
@@ -176,7 +163,6 @@ class Image {
}
public function release_source() {
if (!is_null($this->source)) {
@imagedestroy($this->source);
$this->source_file = null;
@@ -188,7 +174,6 @@ class Image {
}
public function thumb($width, $height) {
if (is_null($this->source)) {
return;
}
@@ -233,7 +218,6 @@ class Image {
}
public function rotate($angle) {
if (is_null($this->source) || ($angle !== 90 && $angle !== 180 && $angle !== 270)) {
return;
}
@@ -245,7 +229,6 @@ class Image {
}
public function normalize_exif_orientation($exif_source_file = null) {
if (is_null($this->source) || !function_exists('exif_read_data')) {
return;
}
@@ -255,7 +238,7 @@ class Image {
}
$exif = exif_read_data($exif_source_file);
switch(@$exif['Orientation']) {
switch (@$exif['Orientation']) {
case 3:
$this->rotate(180);
break;

View File

@@ -1,8 +0,0 @@
extends ./page.tpl.jade
block init
- var title = 'index - powered by h5ai v' + pkg.version + ' (' + pkg.homepage + ')'
- var module = 'index'
block body
div#fallback <?= $fallback_html; ?>

View File

@@ -0,0 +1,8 @@
extends ./page.tpl.pug
block init
- var title = `index - powered by h5ai v${pkg.version} (${pkg.homepage})`
- var module = 'index'
block body
div#fallback <?= $fallback_html; ?>

View File

@@ -1,10 +0,0 @@
extends ./page.tpl.jade
block init
- var title = 'h5ai info page - v' + pkg.version
- var module = 'info'
block body
div#content
h1#header
a(href='#{pkg.homepage}') h5ai

View File

@@ -0,0 +1,10 @@
extends ./page.tpl.pug
block init
- var title = `h5ai info page - v${pkg.version}`
- var module = 'info'
block body
div#content
h1#header
a(href=pkg.homepage) h5ai

View File

@@ -5,23 +5,26 @@ doctype html
html(class='no-js', lang='en')
head
<!--[if lt IE 10]><meta id='no-browser'><![endif]-->
meta(charset='utf-8')
meta(http-equiv='x-ua-compatible', content='ie=edge')
title #{title}
meta(name='description', content='#{title}')
meta(name='description', content=title)
meta(name='viewport', content='width=device-width, initial-scale=1')
link(rel='shortcut icon', href!='<?= $public_href; ?>images/favicon/favicon-16-32.ico')
link(rel='apple-touch-icon-precomposed', type='image/png', href!='<?= $public_href; ?>images/favicon/favicon-152.png')
link(rel='stylesheet', href!='<?= $public_href; ?>css/styles.css')
script(src!='<?= $public_href; ?>js/scripts.js', data-module='#{module}')
<?php if (!$fallback_mode) { ?>
script(src!='<?= $public_href; ?>js/scripts.js', data-module=module)
<?php } ?>
<?= $x_head_tags; ?>
body#root(class='#{module}')
body#root(class=module)
div#fallback-hints
<?php if (!$fallback_mode) { ?>
span.noJsMsg Works best with JavaScript enabled!
span.noBrowserMsg Works best in #[a(href='http://browsehappy.com') modern browsers]!
span.backlink #[a(href='#{pkg.homepage}', title='h5ai v#{pkg.version} - #{pkg.description}') powered by h5ai]
<?php } ?>
span.backlink #[a(href=pkg.homepage, title=`h5ai v${pkg.version} - ${pkg.description}`) powered by h5ai]
block body

View File

@@ -1,27 +1,13 @@
Satisfy all
Order allow,deny
Allow from all
## make this folder accessible
DirectoryIndex disabled
<IfModule mod_autoindex.c>
Options -Indexes
# Apache < 2.3
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
Satisfy All
</IfModule>
AddDefaultCharset utf-8
<IfModule mod_mime.c>
AddCharset utf-8 .css .html .js .json .php .svg
</IfModule>
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType image/x-icon "access plus 1 week"
# Apache ≥ 2.3
<IfModule mod_authz_core.c>
Require all granted
</IfModule>

View File

@@ -27,7 +27,7 @@
@col-back-native-selection: @col-pink-a200;
@col-text: @col-text-primary-black;
@col-back: @col-grey-100;
@col-back: @col-white;
@col-back-paper: @col-white;
@col-back-panel: @col-grey-50;
@col-text-hover: @col-blue-400;

View File

@@ -1,5 +1,4 @@
#cm-overlay {
display: none;
position: fixed;
left: 0;
top: 0;

View File

@@ -3,7 +3,6 @@
input {
display: none;
border: none;
font-weight: lighter;
font-size: 16px;
color: @col-text;
background: transparent;

View File

@@ -1,12 +1,9 @@
#info {
display: none;
overflow: auto;
flex: 0 0 auto;
order: 99;
padding: 16px;
border-left: 1px solid @col-border;
padding: 32px 32px 32px 48px;
white-space: nowrap;
overflow-x: hidden;
width: 240px;
@@ -50,7 +47,7 @@
margin: 0 auto;
width: 200px;
canvas {
img {
display: block;
}
}

View File

@@ -1,4 +1,4 @@
#pv-aud-audio {
#pv-content-aud {
.raised;
position: absolute;

View File

@@ -1,4 +1,4 @@
#pv-img-image {
#pv-content-img {
.raised;
@check-white: #f8f8f8;
@@ -6,6 +6,8 @@
position: absolute;
image-orientation: from-image;
max-width: 100%;
max-height: 100%;

View File

@@ -1,6 +1,7 @@
#pv-txt-text {
#pv-content-txt {
.raised;
box-sizing: border-box;
max-width: 960px;
text-align: left;
background: @col-back-paper;
@@ -8,103 +9,28 @@
padding: 8px;
overflow: auto;
&.highlighted {
a, a:active, a:visited {
color: #2080FF;
text-decoration: none;
cursor: pointer;
code {
line-height: 1.2em;
}
a, a:active, a:visited {
color: #2080FF;
text-decoration: none;
cursor: pointer;
&:hover {
color: #68A9FF;
}
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #aaa;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.builtin {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string,
.token.variable {
color: #a67f59;
background: hsla(0,0%,100%,.5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important {
color: #e90;
}
.token.important {
font-weight: bold;
}
.token.entity {
cursor: help;
}
}
&.markdown {
font-size: 1.1em;
padding: 8px 24px;
a, a:active, a:visited {
color: #2080FF;
text-decoration: none;
cursor: pointer;
&:hover {
color: #68A9FF;
}
}
code {
color: #008200;
&:hover {
color: #68A9FF;
}
}
}
pre#pv-content-txt {
code {
line-height: 1.2em;
}
}
div#pv-content-txt {
font-size: 1.1em;
padding: 8px 24px;
code {
color: #008200;
}
}

View File

@@ -1,4 +1,4 @@
#pv-vid-video {
#pv-content-vid {
.raised;
position: absolute;
@@ -7,7 +7,7 @@
max-height: 100%;
}
#pv-vid-video:-webkit-full-screen {
#pv-content-vid:-webkit-full-screen {
top: auto !important;
left: auto !important;
}

View File

@@ -1,5 +1,4 @@
#pv-overlay {
display: none;
position: fixed;
left: 0;
top: 0;
@@ -17,7 +16,7 @@
background: @col-grey-900;
}
#pv-content {
#pv-container {
position: absolute;
}

View File

@@ -3,7 +3,6 @@
input {
display: none;
border: none;
font-weight: lighter;
font-size: 16px;
color: @col-text;
background: transparent;

View File

@@ -1,5 +1,4 @@
#selection-rect {
display: none;
position: absolute;
left: 0;
top: 0;

View File

@@ -1,16 +1,12 @@
#tree {
display: none;
overflow: auto;
flex: 0 0 auto;
order: 1;
padding: 16px 16px 16px 8px;
border-right: 1px solid @col-border;
padding: 32px 32px 32px 16px;
white-space: nowrap;
max-width: 250px;
overflow-x: hidden;
font-weight: lighter;
a, a:active, a.visited {
display: block;
@@ -37,23 +33,29 @@
cursor: pointer;
img {
.eased-transition;
// .eased-transition;
width: 20px;
height: 20px;
zoom: 1;
}
&.open {
img {
transform: rotate(90deg);
zoom: 1;
}
}
.item {
clear: left;
&.open > .indicator img {
transform: rotate(90deg);
}
&.unknown {
&.unknown > .indicator {
opacity: 0.3;
}
&.none {
&.none > .indicator {
opacity: 0;
cursor: inherit;
}
&.unknown > .content, &.none > .content, &.closed > .content {
display: none;
}
}
.icon {
@@ -71,8 +73,12 @@
}
.content {
list-style: none;
margin: 0;
padding: 0 0 0 20px;
}
.summary {
color: @col-text-disabled-black;
padding: 0 0 0 8px;
}
}

View File

@@ -5,7 +5,6 @@
order: 50;
color: @col-text;
text-align: center;
font-weight: lighter;
}
code {
@@ -67,7 +66,7 @@
#hint {
margin: 12px auto;
width: 300px;
width: 320px;
}
#tests {
@@ -78,11 +77,10 @@
padding: 0;
.test {
.card;
.rounded;
background: @col-back-paper;
margin: 12px 0 0 0;
padding: 8px 12px 12px 12px;
border-bottom: 1px solid @col-border;
}
.label {
display: inline-block;

View File

@@ -12,3 +12,18 @@
*:focus {
outline: none;
}
code, pre {
font-family: @font-family-mono;
font-size: @font-size-mono;
font-weight: @font-weight;
color: @col-text;
}
audio, canvas, iframe, img, svg, video {
vertical-align: middle;
}
textarea {
resize: vertical;
}

View File

@@ -1,5 +1,18 @@
.card {
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2);
.hidden {
display: none !important;
}
.invisible {
visibility: hidden;
}
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
.raised {
@@ -43,7 +56,6 @@
}
.el-button {
.card;
.rounded;
.eased-transition;
color: @col-text-primary-white;
@@ -57,10 +69,11 @@
}
.el-input {
.card;
.rounded;
.clear-appearance;
background: @col-back-paper;
border: none;
outline: none;
background: @col-back-panel;
border: 1px solid @col-border;
}

View File

@@ -8,12 +8,12 @@
}
}
#view.view-details {
.header .label, .item .label {
margin-right: 80px !important;
}
.header .date, .item .date {
display: none;
}
// .header .label, .item .label {
// margin-right: 80px !important;
// }
// .header .date, .item .date {
// display: none;
// }
}
#tree, #info {
display: none !important;
@@ -21,8 +21,15 @@
}
@media print {
a[href]:after {
content: "" !important;
*,
*:before,
*:after,
*:first-letter,
*:first-line {
background: transparent !important;
color: #000 !important;
box-shadow: none !important;
text-shadow: none !important;
}
#toolbar, #sidebar, #tree, #info {
display: none !important;

View File

@@ -2,4 +2,5 @@
overflow: auto;
flex: 1 1 auto;
order: 50;
position: relative;
}

View File

@@ -5,7 +5,6 @@
padding: 32px 16px;
table {
.card;
display: block;
width: 100%;
border-collapse: collapse;
@@ -15,13 +14,12 @@
padding: 6px;
text-align: left;
border: none;
border-bottom: 1px solid #eee;
border-bottom: 1px solid #f0f0f0;
}
th {
color: #aaa;
font-weight: lighter;
font-weight: normal;
line-height: 36px;
background: @col-back-panel;
}
td {
overflow: hidden;
@@ -70,7 +68,7 @@
overflow: hidden;
text-align: right;
background: @col-back-panel;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.2);
border-bottom: 1px solid @col-border;
a, a:active, a:visited {
.eased-transition;

View File

@@ -7,6 +7,7 @@
bottom: 0;
overflow: hidden;
background: @col-back;
line-height: 1.4;
}
#root, input, select {
@@ -15,10 +16,3 @@
font-weight: @font-weight;
color: @col-text;
}
pre, code {
font-family: @font-family-mono;
font-size: @font-size-mono;
font-weight: @font-weight;
color: @col-text;
}

View File

@@ -1,13 +1,17 @@
#sidebar {
display: none;
overflow-x: hidden;
overflow-y: auto;
flex: 0 0 auto;
order: 0;
background: @col-back-panel;
border-right: 1px solid rgba(0,0,0,0.08);
border-right: 1px solid @col-border;
padding: 16px;
position: absolute;
top: 48px;
min-height: 100%;
z-index: 1;
.block {
display: block;
margin: 0 0 24px 0;

View File

@@ -5,7 +5,7 @@
order: 1;
background: @col-back-panel;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.2);
border-bottom: 1px solid @col-border;
z-index: 1;
}

View File

@@ -23,24 +23,19 @@
}
}
margin: 16px;
#items {
.rounded;
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2);
}
margin: 32px;
.header {
position: relative;
white-space: nowrap;
display: list-item;
background: @col-back-panel;
border-bottom: 1px solid rgba(0,0,0,0.07);
border-radius: 2px 2px 0 0;
.label, .date, .size {
.eased-transition;
line-height: 46px;
line-height: 24px;
padding: 0px 8px 16px 8px;
opacity: 0.4;
outline: 0;
@@ -115,3 +110,26 @@
.view-details-sized(16px)
}
#view.view-details {
&.width-0 {
.label {
margin-right: 4px;
}
.date {
display: none;
}
.size {
display: none;
}
}
&.width-1 {
.label {
margin-right: 64px;
}
.date {
display: none;
}
}
}

View File

@@ -17,10 +17,9 @@
}
}
margin: 8px;
margin: 28px;
.item {
.card;
.rounded;
overflow: hidden;
float: left;
@@ -34,7 +33,6 @@
.square {
display: inline-block;
vertical-align: top;
background: @col-back-panel;
}
.label {

View File

@@ -21,10 +21,9 @@
}
}
margin: 8px;
margin: 28px;
.item {
.card;
.rounded;
overflow: hidden;
float: left;
@@ -43,6 +42,7 @@
.label {
padding: 0 6px;
line-height: 24px;
text-align: center;
}
.date, .size {

View File

@@ -1,7 +1,6 @@
@charset "utf-8";
// @include "vendor/normalize.less"
// @include "vendor/h5bp-pre.less"
// @include "../../../../node_modules/normalize.css/normalize.css"
// @include "lib/colors.less"
// @include "lib/fonts.less"
@@ -11,5 +10,3 @@
// @include "lib/*/*.less"
// @include "lib/responsive.less"
// @include "vendor/h5bp-post.less"

View File

@@ -1,169 +0,0 @@
/* ==========================================================================
Helper classes
========================================================================== */
/*
* Hide visually and from screen readers
*/
.hidden {
display: none !important;
}
/*
* Hide only visually, but have it available for screen readers:
* http://snook.ca/archives/html_and_css/hiding-content-for-accessibility
*/
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
/*
* Extends the .visuallyhidden class to allow the element
* to be focusable when navigated to via the keyboard:
* https://www.drupal.org/node/897638
*/
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}
/*
* Hide visually and from screen readers, but maintain layout
*/
.invisible {
visibility: hidden;
}
/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.clearfix:before,
.clearfix:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.clearfix:after {
clear: both;
}
/* ==========================================================================
EXAMPLE Media Queries for Responsive Design.
These examples override the primary ('mobile first') styles.
Modify as content requires.
========================================================================== */
// @media only screen and (min-width: 35em) {
// /* Style adjustments for viewports that meet the condition */
// }
// @media print,
// (-webkit-min-device-pixel-ratio: 1.25),
// (min-resolution: 1.25dppx),
// (min-resolution: 120dpi) {
// /* Style adjustments for high resolution devices */
// }
/* ==========================================================================
Print styles.
Inlined to avoid the additional HTTP request:
http://www.phpied.com/delay-loading-your-print-css/
========================================================================== */
@media print {
*,
*:before,
*:after,
*:first-letter,
*:first-line {
background: transparent !important;
color: #000 !important; /* Black prints faster:
http://www.sanbeiji.com/archives/953 */
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
/*
* Don't show links that are fragment identifiers,
* or use the `javascript:` pseudo protocol
*/
a[href^="#"]:after,
a[href^="javascript:"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
/*
* Printing Tables:
* http://css-discuss.incutio.com/wiki/Printing_Tables
*/
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
}

View File

@@ -1,96 +0,0 @@
/* HTML5 Boilerplate v5.2.0 | MIT License | https://html5boilerplate.com/ */
/*
* What follows is the result of much research on cross-browser styling.
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
* Kroc Camen, and the H5BP dev community and team.
*/
/* ==========================================================================
Base styles: opinionated defaults
========================================================================== */
html {
color: #222;
font-size: 1em;
line-height: 1.4;
}
/*
* Remove text-shadow in selection highlight:
* https://twitter.com/miketaylr/status/12228805301
*
* These selection rule sets have to be separate.
* Customize the background color to match your design.
*/
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
/*
* A better looking default horizontal rule
*/
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
/*
* Remove the gap between audio, canvas, iframes,
* images, videos and the bottom of their containers:
* https://github.com/h5bp/html5-boilerplate/issues/440
*/
audio,
canvas,
iframe,
img,
svg,
video {
vertical-align: middle;
}
/*
* Remove default fieldset styles.
*/
fieldset {
border: 0;
margin: 0;
padding: 0;
}
/*
* Allow only vertical resizing of textareas.
*/
textarea {
resize: vertical;
}
/* ==========================================================================
Browser Upgrade Prompt
========================================================================== */
// .browserupgrade {
// margin: 0.2em 0;
// background: #ccc;
// color: #000;
// padding: 0.2em 0;
// }
/* ==========================================================================
Author's custom styles
========================================================================== */

View File

@@ -1,424 +0,0 @@
/* normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS and IE text size adjust after device orientation change,
* without disabling user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove default margin.
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Correct `block` display not defined for any HTML5 element in IE 8/9.
* Correct `block` display not defined for `details` or `summary` in IE 10/11
* and Firefox.
* Correct `block` display not defined for `main` in IE 11.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
/**
* 1. Correct `inline-block` display not defined in IE 8/9.
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
*/
audio,
canvas,
progress,
video {
display: inline-block; /* 1 */
vertical-align: baseline; /* 2 */
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address `[hidden]` styling not present in IE 8/9/10.
* Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
*/
[hidden],
template {
display: none;
}
/* Links
========================================================================== */
/**
* Remove the gray background color from active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* Improve readability of focused elements when they are also in an
* active/hover state.
*/
a:active,
a:hover {
outline: 0;
}
/* Text-level semantics
========================================================================== */
/**
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/**
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/**
* Address styling not present in Safari and Chrome.
*/
dfn {
font-style: italic;
}
/**
* Address variable `h1` font-size and margin within `section` and `article`
* contexts in Firefox 4+, Safari, and Chrome.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Address styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/**
* Address inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* Embedded content
========================================================================== */
/**
* Remove border when inside `a` element in IE 8/9/10.
*/
img {
border: 0;
}
/**
* Correct overflow not hidden in IE 9/10/11.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* Address margin not present in IE 8/9 and Safari.
*/
figure {
margin: 1em 40px;
}
/**
* Address differences between Firefox and other browsers.
*/
hr {
box-sizing: content-box;
height: 0;
}
/**
* Contain overflow in all browsers.
*/
pre {
overflow: auto;
}
/**
* Address odd `em`-unit font size rendering in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
/* Forms
========================================================================== */
/**
* Known limitation: by default, Chrome and Safari on OS X allow very limited
* styling of `select`, unless a `border` property is set.
*/
/**
* 1. Correct color not being inherited.
* Known issue: affects color of disabled elements.
* 2. Correct font properties not being inherited.
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
*/
button,
input,
optgroup,
select,
textarea {
color: inherit; /* 1 */
font: inherit; /* 2 */
margin: 0; /* 3 */
}
/**
* Address `overflow` set to `hidden` in IE 8/9/10/11.
*/
button {
overflow: visible;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
* Correct `select` style inheritance in Firefox.
*/
button,
select {
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* Remove inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/**
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
input {
line-height: normal;
}
/**
* It's recommended that you don't attempt to style these elements.
* Firefox's implementation doesn't respect box-sizing, padding, or width.
*
* 1. Address box sizing set to `content-box` in IE 8/9/10.
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
* `font-size` values of the `input`, it causes the cursor style of the
* decrement button to change from `default` to `text`.
*/
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
box-sizing: content-box; /* 2 */
}
/**
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
* Safari (but not Chrome) clips the cancel button when the search input has
* padding (and `textfield` appearance).
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct `color` not being inherited in IE 8/9/10/11.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/**
* Remove default vertical scrollbar in IE 8/9/10/11.
*/
textarea {
overflow: auto;
}
/**
* Don't inherit the `font-weight` (applied by a rule above).
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
*/
optgroup {
font-weight: bold;
}
/* Tables
========================================================================== */
/**
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 B

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 B

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 120 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#a4c639" d="m 5.78125,2 c -0.00155,0.010339 -0.00155,0.020911 0,0.03125 -0.010339,-0.00155 -0.020911,-0.00155 -0.03125,0 -0.00155,0.010339 -0.00155,0.020911 0,0.03125 -0.00155,0.010339 -0.00155,0.020911 0,0.03125 -0.00155,0.010339 -0.00155,0.020911 0,0.03125 -0.00155,0.010339 -0.00155,0.020911 0,0.03125 L 6.625,3.625 C 5.9445396,4.3022596 5.5134919,5.1886446 5.5,6.15625 l 9,0 C 14.486508,5.1886446 14.05546,4.3022596 13.375,3.625 L 14.25,2.15625 c 0.0016,-0.010339 0.0016,-0.020911 0,-0.03125 0.0016,-0.010339 0.0016,-0.020911 0,-0.03125 0.0016,-0.010339 0.0016,-0.020911 0,-0.03125 -0.0081,-0.012465 -0.01878,-0.023194 -0.03125,-0.03125 C 14.210694,2.0187849 14.199965,2.0080563 14.1875,2 c -0.01034,-0.00155 -0.02091,-0.00155 -0.03125,0 -0.01034,-0.00155 -0.02091,-0.00155 -0.03125,0 -0.01034,-0.00155 -0.02091,-0.00155 -0.03125,0 -0.0016,0.010339 -0.0016,0.020911 0,0.03125 -0.01034,-0.00155 -0.02091,-0.00155 -0.03125,0 -0.0016,0.010339 -0.0016,0.020911 0,0.03125 L 13.21875,3.5 C 12.508811,2.8579404 11.574169,2.4161295 10.5,2.3125 l -1,0 C 8.4258309,2.4161295 7.4911892,2.8579404 6.78125,3.5 L 5.9375,2.0625 c 0.00155,-0.010339 0.00155,-0.020911 0,-0.03125 -0.010339,-0.00155 -0.020911,-0.00155 -0.03125,0 C 5.8981937,2.0187849 5.8874651,2.0080563 5.875,2 5.8646606,1.9984471 5.8540894,1.9984471 5.84375,2 5.8334106,1.9984471 5.8228394,1.9984471 5.8125,2 5.8021606,1.9984471 5.7915894,1.9984471 5.78125,2 z M 8,3.84375 c 0.020808,-0.00123 0.041692,-0.00123 0.0625,0 0.2933398,-0.043249 0.5943541,0.2102369 0.59375,0.5 C 8.6738727,4.6179758 8.4219324,4.8799872 8.140625,4.8799872 7.8593176,4.8799872 7.6073773,4.6179758 7.625,4.34375 7.6183882,4.1213788 7.7809375,3.9046463 8,3.84375 z m 3.84375,0 c 0.02081,-0.00123 0.04169,-0.00123 0.0625,0 0.29334,-0.043249 0.594354,0.2102369 0.59375,0.5 0.01762,0.2742258 -0.234318,0.5362372 -0.515625,0.5362372 -0.281307,0 -0.533248,-0.2620114 -0.515625,-0.5362372 -0.0066,-0.2223712 0.155938,-0.4391037 0.375,-0.5 z m -6.375,2.71875 c -2.995e-4,2.2008535 0,4.418486 0,6.625 0,0.698086 0.5327963,1.25 1.21875,1.25 l 0.0625,0 0,2.5625 c 0,0.553265 0.4467345,1 1,1 0.5532655,0 1,-0.446735 1,-1 l 0,-2.5625 2.5,0 0,2.5625 c 0,0.553265 0.446735,1 1,1 0.553265,0 1,-0.446735 1,-1 l 0,-2.5625 0.0625,0 c 0.68596,0 1.21875,-0.551914 1.21875,-1.25 10e-7,-2.205262 0,-4.4258583 0,-6.625 z m -1.625,0.59375 c -0.5532655,0 -1,0.4467345 -1,1 l 0,4.28125 c 0,0.553265 0.4467345,1 1,1 0.5532655,0 1,-0.446735 1,-1 l 0,-4.28125 c 0,-0.5532655 -0.4467345,-1 -1,-1 z m 12.3125,0 c -0.553265,0 -1,0.4467345 -1,1 l 0,4.28125 c 0,0.553265 0.446735,1 1,1 0.553265,0 1,-0.446735 1,-1 l 0,-4.28125 c 0,-0.5532655 -0.446735,-1 -1,-1 z"/>
<path fill="#a4c639" d="M14.5 3.2C14.4 3.2 14.2 3.3 14.1 3.5L13.3 5C12.3 4.4 11.2 4 10 4 8.8 4 7.7 4.3 6.8 4.9L5.9 3.5C5.8 3.3 5.6 3.2 5.5 3.3 5.4 3.3 5.4 3.2 5.3 3.3L5.2 3.3C5 3.5 4.9 3.8 5.1 4L6 5.6C4.8 6.7 4 8.2 4 10L16 10C16 8.3 15.3 6.7 14.1 5.6L15 4C15.1 3.8 15 3.5 14.8 3.3L14.7 3.3C14.7 3.2 14.6 3.2 14.5 3.2zM7.3 7C7.8 7 8.2 7.4 8.2 7.9 8.2 8.4 7.8 8.8 7.3 8.8 6.8 8.8 6.4 8.4 6.4 7.9 6.4 7.4 6.8 7 7.3 7zM12.7 7C13.2 7 13.6 7.4 13.6 7.9 13.6 8.4 13.2 8.8 12.7 8.8 12.2 8.8 11.8 8.4 11.8 7.9 11.8 7.4 12.2 7 12.7 7zM4 10.5L4 16 16 16 16 10.5 4 10.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 656 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#795548" d="M18 9.9 17.3 9.5c0 0 0-0.1 0-0.1L17.9 8.8C17.9 8.8 18 8.6 18 8.5 18 8.4 17.9 8.4 17.9 8.4L17.1 8.1c0 0 0-0.1 0-0.1l0.4-0.7c0 0 0-0.1 0-0.3 0-0.1-0.1-0.1-0.1-0.1L16.5 6.7c0 0 0-0.1-0.1-0.1l0.3-0.7c0-0.1 0-0.1 0-0.3 0 0-0.1-0.1-0.1-0.1l-0.8 0c0 0-0.1-0.1-0.1-0.1L15.7 4.6c0-0.1 0-0.1 0-0.3 0 0-0.1-0.1-0.3 0l-0.8 0.1c0 0-0.1-0.1-0.1-0.1l0-0.8c0-0.1 0-0.1-0.1-0.1 0 0-0.1 0-0.3 0l-0.7 0.3c0 0-0.1 0-0.1-0.1L13.1 2.7c0-0.1 0-0.1-0.1-0.1-0.1 0-0.1 0-0.3 0l-0.7 0.4c0 0-0.1 0-0.1 0L11.6 2.3c0-0.1-0.1-0.1-0.1-0.1-0.1 0-0.1 0-0.3 0.1l-0.5 0.5c0 0-0.1 0-0.1 0L10.1 2.1C10.1 2 10 2 10 2 9.9 2 9.9 2 9.9 2.1l-0.4 0.7c0 0-0.1 0-0.1 0L8.8 2.3c0 0-0.1-0.1-0.3-0.1-0.1 0-0.1 0.1-0.1 0.1L8.1 2.9c0 0-0.1 0-0.1 0L7.3 2.5c0 0-0.1 0-0.3 0-0.1 0-0.1 0.1-0.1 0.1L6.7 3.5c0 0-0.1 0-0.1 0.1L5.9 3.4c-0.1 0-0.1 0-0.3 0 0 0-0.1 0.1-0.1 0.1l0 0.8c0 0-0.1 0.1-0.1 0.1L4.6 4.3c-0.1 0-0.1 0-0.3 0 0 0-0.1 0.1 0 0.3l0.1 0.8c0 0-0.1 0.1-0.1 0.1l-0.8 0c-0.1 0-0.1 0-0.1 0.1 0 0 0 0.1 0 0.3l0.3 0.7c0 0 0 0.1-0.1 0.1L2.7 6.9c-0.1 0-0.1 0-0.1 0.1 0 0.1 0 0.1 0 0.3l0.4 0.7c0 0 0 0.1 0 0.1L2.3 8.4c-0.1 0-0.1 0.1-0.1 0.1 0 0.1 0 0.1 0.1 0.3l0.5 0.5c0 0 0 0.1 0 0.1L2.1 9.9C2 9.9 2 10 2 10c0 0.1 0 0.1 0.1 0.1l0.7 0.4c0 0 0 0.1 0 0.1l-0.5 0.5c0 0-0.1 0.1-0.1 0.3 0 0.1 0.1 0.1 0.1 0.1l0.7 0.3c0 0 0 0.1 0 0.1l-0.4 0.7c0 0 0 0.1 0 0.3 0 0.1 0.1 0.1 0.1 0.1l0.8 0.1c0 0 0 0.1 0.1 0.1l-0.3 0.7c0 0.1 0 0.1 0 0.3 0 0 0.1 0.1 0.1 0.1l0.8 0c0 0 0.1 0.1 0.1 0.1l-0.1 0.8c0 0.1 0 0.1 0 0.3 0 0 0.1 0.1 0.3 0l0.8-0.1c0 0 0.1 0.1 0.1 0.1l0 0.8c0 0.1 0 0.1 0.1 0.1 0 0 0.1 0 0.3 0l0.7-0.3c0 0 0.1 0 0.1 0.1l0.1 0.8c0 0.1 0 0.1 0.1 0.1 0.1 0 0.1 0 0.3 0l0.7-0.4c0 0 0.1 0 0.1 0l0.3 0.7c0 0.1 0.1 0.1 0.1 0.1 0.1 0 0.1 0 0.3-0.1l0.5-0.5c0 0 0.1 0 0.1 0l0.4 0.7C9.9 17.9 10 18 10 18c0.1 0 0.1 0 0.1-0.1l0.4-0.7c0 0 0.1 0 0.1 0l0.5 0.5c0 0 0.1 0.1 0.3 0.1 0.1 0 0.1-0.1 0.1-0.1l0.3-0.7c0 0 0.1 0 0.1 0l0.7 0.4c0 0 0.1 0 0.3 0 0.1 0 0.1-0.1 0.1-0.1l0.1-0.8c0 0 0.1 0 0.1-0.1l0.7 0.3c0.1 0 0.1 0 0.3 0 0 0 0.1-0.1 0.1-0.1l0-0.8c0 0 0.1-0.1 0.1-0.1l0.8 0.1c0.1 0 0.1 0 0.3 0 0 0 0.1-0.1 0-0.3l-0.1-0.8c0 0 0.1-0.1 0.1-0.1l0.8 0c0.1 0 0.1 0 0.1-0.1 0 0 0-0.1 0-0.3l-0.3-0.7c0 0 0-0.1 0.1-0.1l0.8-0.1c0.1 0 0.1 0 0.1-0.1 0-0.1 0-0.1 0-0.3l-0.4-0.7c0 0 0-0.1 0-0.1l0.7-0.3c0.1 0 0.1-0.1 0.1-0.1 0-0.1 0-0.1-0.1-0.3l-0.5-0.5c0 0 0-0.1 0-0.1l0.7-0.4C18 10.1 18 10 18 10 18 9.9 18 9.9 17.9 9.9zm-4.5 5.6c-0.3 0-0.4-0.3-0.4-0.5 0-0.3 0.3-0.4 0.5-0.4 0.3 0 0.4 0.3 0.4 0.5 0 0.3-0.3 0.4-0.5 0.4zm-0.3-1.5c-0.3 0-0.4 0.1-0.5 0.3l-0.3 1.1C11.8 15.6 10.9 15.8 10 15.8c-0.8 0-1.8-0.1-2.4-0.5L7.3 14.2c0-0.3-0.3-0.4-0.5-0.3L5.8 14.2C5.7 13.9 5.5 13.7 5.4 13.5l4.7 0c0 0 0.1 0 0.1 0l0-1.6c0 0 0 0-0.1 0l-1.4 0 0-1.1 1.5 0c0.1 0 0.7 0 0.9 0.8 0 0.3 0.1 0.9 0.3 1.2 0.1 0.3 0.4 0.8 0.8 0.8l2.4 0c0 0 0 0 0.1 0-0.1 0.3-0.4 0.4-0.5 0.7l-1.1-0.4zm-6.6 1.5c-0.3 0-0.5-0.1-0.5-0.4 0-0.3 0.1-0.5 0.4-0.5 0.3 0 0.5 0.1 0.5 0.4 0 0.3-0.1 0.5-0.4 0.5zM4.8 8.1c0.1 0.3 0 0.5-0.3 0.7-0.3 0.1-0.5 0-0.7-0.3-0.1-0.3 0-0.5 0.3-0.7 0.3-0.1 0.5 0 0.7 0.3zM4.3 9.5 5.4 9.1C5.7 8.9 5.7 8.6 5.7 8.5l-0.3-0.5 0.8 0 0 3.8-1.6 0C4.4 11.2 4.3 10.7 4.3 10.1c0-0.3 0-0.4 0-0.7zm4.5-0.4 0-1.1 2 0c0.1 0 0.7 0.1 0.7 0.5 0 0.4-0.4 0.5-0.8 0.5l-1.8 0zM16 10c0 0.1 0 0.3 0 0.4l-0.5 0c0 0-0.1 0-0.1 0.1l0 0.3c0 0.7-0.4 0.8-0.7 0.8-0.3 0-0.7-0.1-0.7-0.3-0.1-0.9-0.5-1.2-0.9-1.6 0.5-0.4 1.2-0.9 1.2-1.6 0-0.8-0.5-1.4-0.9-1.5C12.7 6.2 12.2 6.2 12 6.2l-6.2 0C6.6 5.3 7.8 4.6 9.1 4.3l0.7 0.8c0.1 0.1 0.4 0.1 0.7 0l0.8-0.8c1.8 0.3 3.1 1.4 3.9 2.8l-0.5 1.2c-0.1 0.3 0 0.4 0.3 0.5l1.1 0.5c0 0.1 0 0.4 0 0.5zM9.7 3.6c0.1-0.1 0.5-0.1 0.7 0 0.1 0.1 0.1 0.5 0 0.7-0.1 0.1-0.5 0.1-0.7 0-0.1-0.1-0.1-0.5 0-0.7zm5.6 4.5C15.4 7.8 15.7 7.7 16 7.8 16.2 8 16.4 8.2 16.2 8.5 16.1 8.8 15.8 8.9 15.6 8.8 15.3 8.6 15.2 8.4 15.3 8.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -1,5 +1,3 @@
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="24" height="24" version="1.1">
<g transform="translate(0,-8)">
<path d="m15.8 22.3h-0.8l-0.3-0.3c1-1.1 1.6-2.6 1.6-4.2 0-3.6-2.9-6.5-6.5-6.5-3.6 0-6.5 2.9-6.5 6.5 0 3.6 2.9 6.5 6.5 6.5 1.6 0 3.1-0.6 4.2-1.6l0.3 0.3v0.8l5 5 1.5-1.5-5-5zm-6 0c-2.5 0-4.5-2-4.5-4.5 0-2.5 2-4.5 4.5-4.5 2.5 0 4.5 2 4.5 4.5 0 2.5-2 4.5-4.5 4.5z" fill="#555"/>
</g>
</svg>
<path d="M20 4H4l6 9v5l4 2v-7z" fill="#555"/>
</svg>

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 172 B

View File

@@ -1,12 +1,16 @@
<?php
define('H5AI_VERSION', '{{VERSION}}');
define('MIN_PHP_VERSION', '5.5.0');
define('MIN_PHP_VERSION', '7.0.0');
if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<')) {
header('Content-type: text/plain;charset=utf-8');
echo '[err] h5ai requires PHP ' . MIN_PHP_VERSION . ' or later, but found PHP ' . PHP_VERSION;
exit;
exit('[ERR] h5ai requires PHP ' . MIN_PHP_VERSION . ' or later, but found PHP ' . PHP_VERSION);
}
if (substr(H5AI_VERSION, 0, 1) === '{') {
header('Content-type: text/plain;charset=utf-8');
exit('[ERR] h5ai sources must be preprocessed to work correctly');
}
require_once __DIR__ . '/../private/php/class-bootstrap.php';

View File

@@ -1,25 +0,0 @@
modulejs.define('boot', ['$', 'core/server'], function ($, server) {
var module = $('script[data-module]').data('module');
var data = {
action: 'get',
setup: true,
options: true,
types: true
};
if (module === 'index') {
data.theme = true;
data.langs = true;
} else if (module === 'info') {
data.refresh = true;
} else {
return;
}
server.request(data, function (config) {
modulejs.define('config', config);
$(function () {
modulejs.require('main/' + module);
});
});
});

View File

@@ -0,0 +1,5 @@
const {request} = require('./server');
const config = module.exports = {
_update: query => request(query).then(resp => Object.assign(config, resp))
};

View File

@@ -1,36 +1,28 @@
modulejs.define('core/event', ['_'], function (_) {
var slice = Array.prototype.slice;
var subscriptions = {};
const {isStr, isFn, dom} = require('../util');
function sub(topic, callback) {
if (_.isString(topic) && _.isFunction(callback)) {
if (!subscriptions[topic]) {
subscriptions[topic] = [];
}
subscriptions[topic].push(callback);
const subscriptions = {};
const sub = (topic, listener) => {
if (isStr(topic) && isFn(listener)) {
if (!subscriptions[topic]) {
subscriptions[topic] = [];
}
subscriptions[topic].push(listener);
}
};
function unsub(topic, callback) {
if (_.isString(topic) && _.isFunction(callback) && subscriptions[topic]) {
subscriptions[topic] = _.without(subscriptions[topic], callback);
}
const pub = (topic, ...args) => {
// console.log(topic, args);
if (isStr(topic) && subscriptions[topic]) {
subscriptions[topic].forEach(listener => {
listener.apply(topic, args);
});
}
};
function pub(topic) {
var args = slice.call(arguments, 1);
dom(global.window).on('resize', () => pub('resize'));
if (_.isString(topic) && subscriptions[topic]) {
_.each(subscriptions[topic], function (callback) {
callback.apply(topic, args);
});
}
}
return {
sub: sub,
unsub: unsub,
pub: pub
};
});
module.exports = {
sub,
pub
};

View File

@@ -1,95 +1,96 @@
modulejs.define('core/format', ['_'], function (_) {
var decimalMetric = {
t: 1000.0,
k: 1000.0,
u: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const {isNum} = require('../util');
const decimalMetric = {
t: 1000.0,
k: 1000.0,
u: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
};
const binaryMetric = {
t: 1024.0,
k: 1024.0,
u: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
};
let defaultMetric = decimalMetric;
const datePatterns = [
[/YYYY/, 'Y', 4],
[/YY/, 'Y', 2],
[/Y/, 'Y', 0],
[/MM/, 'M', 2],
[/M/, 'M', 0],
[/DD/, 'D', 2],
[/D/, 'D', 0],
[/HH/, 'H', 2],
[/H/, 'H', 0],
[/mm/, 'm', 2],
[/m/, 'm', 0],
[/ss/, 's', 2],
[/s/, 's', 0]
];
let defaultDateFormat = 'YYYY-MM-DD HH:mm';
const setDefaultMetric = useBinaryMetric => {
defaultMetric = useBinaryMetric ? binaryMetric : decimalMetric;
};
const formatSize = (size, metric) => {
metric = metric || defaultMetric;
if (!isNum(size) || size < 0) {
return '';
}
let i = 0;
const maxI = metric.u.length - 1;
while (size >= metric.t && i < maxI) {
size /= metric.k;
i += 1;
}
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + metric.u[i];
};
const setDefaultDateFormat = dateFormat => {
defaultDateFormat = dateFormat;
};
const formatNumber = (number, padding) => {
let str = String(number);
if (padding) {
str = ('000' + str).substr(-padding);
}
return str;
};
const formatDate = (millis, format) => {
if (!millis || !isNum(millis)) {
return '';
}
format = format || defaultDateFormat;
const date = new Date(millis);
const d = {
Y: date.getFullYear(),
M: date.getMonth() + 1,
D: date.getDate(),
H: date.getHours(),
m: date.getMinutes(),
s: date.getSeconds()
};
var binaryMetric = {
t: 1024.0,
k: 1024.0,
u: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
};
var defaultMetric = decimalMetric;
var datePatterns = [
[/YYYY/, 'Y', 4],
[/YY/, 'Y', 2],
[/Y/, 'Y', 0],
[/MM/, 'M', 2],
[/M/, 'M', 0],
[/DD/, 'D', 2],
[/D/, 'D', 0],
[/HH/, 'H', 2],
[/H/, 'H', 0],
[/mm/, 'm', 2],
[/m/, 'm', 0],
[/ss/, 's', 2],
[/s/, 's', 0]
];
var defaultDateFormat = 'YYYY-MM-DD HH:mm';
datePatterns.forEach(pattern => {
format = format.replace(pattern[0], formatNumber(d[pattern[1]], pattern[2]));
});
return format;
};
function setDefaultMetric(useBinaryMetric) {
defaultMetric = useBinaryMetric ? binaryMetric : decimalMetric;
}
function formatSize(size, metric) {
metric = metric || defaultMetric;
if (!_.isNumber(size) || size < 0) {
return '';
}
var i = 0;
var maxI = metric.u.length - 1;
while (size >= metric.t && i < maxI) {
size /= metric.k;
i += 1;
}
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + metric.u[i];
}
function setDefaultDateFormat(dateFormat) {
defaultDateFormat = dateFormat;
}
function formatNumber(number, padding) {
var str = String(number);
if (padding) {
str = ('000' + str).substr(-padding);
}
return str;
}
function formatDate(millis, format) {
if (!millis || !_.isNumber(millis)) {
return '';
}
format = format || defaultDateFormat;
var date = new Date(millis);
var d = {
Y: date.getFullYear(),
M: date.getMonth() + 1,
D: date.getDate(),
H: date.getHours(),
m: date.getMinutes(),
s: date.getSeconds()
};
datePatterns.forEach(function (pattern) {
format = format.replace(pattern[0], formatNumber(d[pattern[1]], pattern[2]));
});
return format;
}
return {
setDefaultMetric: setDefaultMetric,
formatSize: formatSize,
setDefaultDateFormat: setDefaultDateFormat,
formatDate: formatDate
};
});
module.exports = {
setDefaultMetric,
formatSize,
setDefaultDateFormat,
formatDate
};

View File

@@ -1,3 +1,2 @@
modulejs.define('core/langs', ['_', 'config'], function (_, config) {
return _.extend({}, config.langs);
});
const {langs} = require('../config');
module.exports = Object.assign({}, langs);

View File

@@ -1,181 +1,181 @@
modulejs.define('core/location', ['_', 'core/event', 'core/modernizr', 'core/settings', 'view/notification'], function (_, event, modernizr, allsettings, notification) {
var settings = _.extend({
fastBrowsing: true,
unmanagedInNewWindow: true
}, allsettings.view);
var doc = document;
var history = settings.fastBrowsing && modernizr.history ? window.history : null;
var reUriToPathname = /^.*:\/\/[^\/]*|[^\/]*$/g;
var absHref = null;
var reForceEncoding = [
[/\/+/g, '/'],
[/ /g, '%20'],
[/!/g, '%21'],
[/#/g, '%23'],
[/\$/g, '%24'],
[/&/g, '%26'],
[/'/g, '%27'],
[/\(/g, '%28'],
[/\)/g, '%29'],
[/\*/g, '%2A'],
[/\+/g, '%2B'],
[/\,/g, '%2C'],
[/:/g, '%3A'],
[/;/g, '%3B'],
[/\=/g, '%3D'],
[/\?/g, '%3F'],
[/@/g, '%40'],
[/\[/g, '%5B'],
[/\]/g, '%5D']
];
const {each, values, difference} = require('../util');
const {request} = require('../server');
const allsettings = require('./settings');
const event = require('./event');
const notification = require('../view/notification');
function forceEncoding(href) {
return reForceEncoding.reduce(function (nuHref, data) {
return nuHref.replace(data[0], data[1]);
}, href);
const win = global.window;
const doc = win.document;
const settings = Object.assign({
fastBrowsing: true,
unmanagedInNewWindow: true
}, allsettings.view);
const history = settings.fastBrowsing ? win.history : null;
const reUriToPathname = /^.*:\/\/[^\/]*|[^\/]*$/g;
const reForceEncoding = [
[/\/+/g, '/'],
[/ /g, '%20'],
[/!/g, '%21'],
[/#/g, '%23'],
[/\$/g, '%24'],
[/&/g, '%26'],
[/'/g, '%27'],
[/\(/g, '%28'],
[/\)/g, '%29'],
[/\*/g, '%2A'],
[/\+/g, '%2B'],
[/\,/g, '%2C'],
[/:/g, '%3A'],
[/;/g, '%3B'],
[/\=/g, '%3D'],
[/\?/g, '%3F'],
[/@/g, '%40'],
[/\[/g, '%5B'],
[/\]/g, '%5D']
];
let absHref = null;
const forceEncoding = href => {
return reForceEncoding.reduce((nuHref, data) => {
return nuHref.replace(data[0], data[1]);
}, href);
};
const uriToPathname = uri => {
return uri.replace(reUriToPathname, '');
};
const hrefsAreDecoded = (() => {
const testpathname = '/a b';
const a = doc.createElement('a');
a.href = testpathname;
return uriToPathname(a.href) === testpathname;
})();
const encodedHref = href => {
const a = doc.createElement('a');
let location;
a.href = href;
location = uriToPathname(a.href);
if (hrefsAreDecoded) {
location = encodeURIComponent(location).replace(/%2F/ig, '/');
}
function uriToPathname(uri) {
return uri.replace(reUriToPathname, '');
}
return forceEncoding(location);
};
var hrefsAreDecoded = (function () {
var testpathname = '/a b';
var a = doc.createElement('a');
const getDomain = () => doc.domain;
const getAbsHref = () => absHref;
const getItem = () => require('../model/item').get(absHref);
a.href = testpathname;
return uriToPathname(a.href) === testpathname;
}());
const load = () => {
return request({action: 'get', items: {href: absHref, what: 1}}).then(json => {
const Item = require('../model/item');
const item = Item.get(absHref);
function encodedHref(href) {
var a = doc.createElement('a');
var location;
if (json) {
const found = {};
a.href = href;
location = uriToPathname(a.href);
each(json.items, jsonItem => {
const e = Item.get(jsonItem);
found[e.absHref] = true;
});
if (hrefsAreDecoded) {
location = encodeURIComponent(location).replace(/%2F/ig, '/');
}
return forceEncoding(location);
}
function getDomain() {
return doc.domain;
}
function getAbsHref() {
return absHref;
}
function getItem() {
return modulejs.require('model/item').get(absHref);
}
function load(callback) {
modulejs.require('core/server').request({action: 'get', items: {href: absHref, what: 1}}, function (json) {
var Item = modulejs.require('model/item');
var item = Item.get(absHref);
if (json) {
var found = {};
_.each(json.items, function (jsonItem) {
var e = Item.get(jsonItem);
found[e.absHref] = true;
});
_.each(item.content, function (e) {
if (!found[e.absHref]) {
Item.remove(e.absHref);
}
});
}
if (_.isFunction(callback)) {
callback(item);
}
});
}
function refresh() {
var item = getItem();
var oldItems = _.values(item.content);
event.pub('location.beforeRefresh');
load(function () {
var newItems = _.values(item.content);
var added = _.difference(newItems, oldItems);
var removed = _.difference(oldItems, newItems);
event.pub('location.refreshed', item, added, removed);
});
}
function setLocation(newAbsHref, keepBrowserUrl) {
event.pub('location.beforeChange');
newAbsHref = encodedHref(newAbsHref);
if (absHref !== newAbsHref) {
absHref = newAbsHref;
if (history) {
if (keepBrowserUrl) {
history.replaceState({absHref: absHref}, '', absHref);
} else {
history.pushState({absHref: absHref}, '', absHref);
each(item.content, e => {
if (!found[e.absHref]) {
Item.remove(e.absHref);
}
});
}
return item;
});
};
const refresh = () => {
const item = getItem();
const oldItems = values(item.content);
event.pub('location.beforeRefresh');
load().then(() => {
const newItems = values(item.content);
const added = difference(newItems, oldItems);
const removed = difference(oldItems, newItems);
event.pub('location.refreshed', item, added, removed);
});
};
const setLocation = (newAbsHref, keepBrowserUrl) => {
event.pub('location.beforeChange');
newAbsHref = encodedHref(newAbsHref);
if (absHref !== newAbsHref) {
absHref = newAbsHref;
if (history) {
if (keepBrowserUrl) {
history.replaceState({absHref}, '', absHref);
} else {
history.pushState({absHref}, '', absHref);
}
}
}
var item = getItem();
if (item.isLoaded) {
const item = getItem();
if (item.isLoaded) {
event.pub('location.changed', item);
refresh();
} else {
notification.set('loading...');
load().then(() => {
item.isLoaded = true;
notification.set();
event.pub('location.changed', item);
refresh();
} else {
notification.set('loading...');
load(function () {
item.isLoaded = true;
notification.set();
event.pub('location.changed', item);
});
}
});
}
};
const setLink = ($el, item) => {
$el.attr('href', item.absHref);
if (history && item.isFolder() && item.isManaged) {
$el.on('click', ev => {
setLocation(item.absHref);
ev.preventDefault();
return false;
});
}
function setLink($el, item) {
$el.attr('href', item.absHref);
if (history && item.isFolder() && item.isManaged) {
$el.on('click', function () {
setLocation(item.absHref);
return false;
});
}
if (settings.unmanagedInNewWindow && !item.isManaged) {
$el.attr('target', '_blank');
}
if (settings.unmanagedInNewWindow && !item.isManaged) {
$el.attr('target', '_blank');
}
};
function onPopState(ev) {
if (ev.state && ev.state.absHref) {
setLocation(ev.state.absHref, true);
}
const onPopState = ev => {
if (ev.state && ev.state.absHref) {
setLocation(ev.state.absHref, true);
}
};
window.onpopstate = history ? onPopState : null;
win.onpopstate = history ? onPopState : null;
return {
forceEncoding: forceEncoding,
getDomain: getDomain,
getAbsHref: getAbsHref,
getItem: getItem,
setLocation: setLocation,
refresh: refresh,
setLink: setLink
};
});
module.exports = {
forceEncoding,
getDomain,
getAbsHref,
getItem,
setLocation,
refresh,
setLink
};

View File

@@ -1,25 +0,0 @@
modulejs.define('core/modernizr', function () {
var hasCanvas = (function () {
var elem = document.createElement('canvas');
return Boolean(elem.getContext && elem.getContext('2d'));
}());
var hasHistory = Boolean(window.history && history.pushState);
var hasLocalStorage = (function () {
var key = '#test#';
try {
localStorage.setItem(key, key);
localStorage.removeItem(key);
return true;
} catch (e) {
return false;
}
}());
return {
canvas: hasCanvas,
history: hasHistory,
localstorage: hasLocalStorage
};
});

View File

@@ -1,37 +1,37 @@
modulejs.define('core/resource', ['_', 'config', 'core/settings'], function (_, config, settings) {
var imagesHref = settings.publicHref + 'images/';
var uiHref = imagesHref + 'ui/';
var themesHref = imagesHref + 'themes/';
var defaultThemeHref = themesHref + 'default/';
var defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x'];
const {includes} = require('../util');
const config = require('../config');
const settings = require('./settings');
const imagesHref = settings.publicHref + 'images/';
const uiHref = imagesHref + 'ui/';
const themesHref = imagesHref + 'themes/';
const defaultThemeHref = themesHref + 'default/';
const defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x'];
function image(id) {
return uiHref + id + '.svg';
const image = id => uiHref + id + '.svg';
const icon = id => {
const baseId = (id || '').split('-')[0];
const href = config.theme[id] || config.theme[baseId];
if (href) {
return themesHref + href;
}
function icon(id) {
var baseId = (id || '').split('-')[0];
var href = config.theme[id] || config.theme[baseId];
if (href) {
return themesHref + href;
}
if (_.indexOf(defaultIcons, id) >= 0) {
return defaultThemeHref + id + '.svg';
}
if (_.indexOf(defaultIcons, baseId) >= 0) {
return defaultThemeHref + baseId + '.svg';
}
return defaultThemeHref + 'file.svg';
if (includes(defaultIcons, id)) {
return defaultThemeHref + id + '.svg';
}
if (includes(defaultIcons, baseId)) {
return defaultThemeHref + baseId + '.svg';
}
return {
image: image,
icon: icon
};
});
return defaultThemeHref + 'file.svg';
};
module.exports = {
image,
icon
};

View File

@@ -1,35 +0,0 @@
modulejs.define('core/server', ['_', '$'], function (_, $) {
function request(data, callback) {
$.ajax({
url: '?',
data: data,
type: 'post',
dataType: 'json'
})
.done(function (json) {
callback(json);
})
.fail(function () {
callback();
});
}
function formRequest(data) {
var $form = $('<form method="post" action="?" style="display:none;"/>');
_.each(data, function (val, key) {
$('<input type="hidden"/>')
.attr('name', key)
.attr('value', val)
.appendTo($form);
});
$form.appendTo('body').submit().remove();
}
return {
request: request,
formRequest: formRequest
};
});

View File

@@ -1,6 +1,6 @@
modulejs.define('core/settings', ['_', 'config'], function (_, config) {
return _.extend({}, config.options, {
publicHref: config.setup.PUBLIC_HREF,
rootHref: config.setup.ROOT_HREF
});
const config = require('../config');
module.exports = Object.assign({}, config.options, {
publicHref: config.setup.PUBLIC_HREF,
rootHref: config.setup.ROOT_HREF
});

View File

@@ -1,32 +1,28 @@
modulejs.define('core/store', ['core/modernizr'], function (modernizr) {
var store = modernizr.localstorage ? window.localStorage : {};
var storekey = '_h5ai';
const store = global.window.localStorage;
const storekey = '_h5ai';
function load() {
try {
return JSON.parse(store[storekey]);
} catch (e) {/* skip */}
return {};
}
const load = () => {
try {
return JSON.parse(store[storekey]);
} catch (e) {/* skip */}
return {};
};
function save(obj) {
store[storekey] = JSON.stringify(obj);
}
const save = obj => {
store[storekey] = JSON.stringify(obj);
};
function put(key, value) {
var obj = load();
obj[key] = value;
save(obj);
}
const put = (key, value) => {
const obj = load();
obj[key] = value;
save(obj);
};
function get(key) {
return load()[key];
}
const get = key => load()[key];
return {
put: put,
get: get
};
});
module.exports = {
put,
get
};

View File

@@ -1,43 +1,43 @@
modulejs.define('core/types', ['_', 'config'], function (_, config) {
var reEndsWithSlash = /\/$/;
var regexps = {};
const {each, map} = require('../util');
const config = require('../config');
const reEndsWithSlash = /\/$/;
const regexps = {};
function escapeRegExp(sequence) {
return sequence.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$]/g, '\\$&');
// return sequence.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
const escapeRegExp = sequence => {
return sequence.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$]/g, '\\$&');
// return sequence.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
};
const parse = types => {
each(types, (patterns, type) => {
const pattern = '^(' + map(patterns, p => '(' + escapeRegExp(p).replace(/\*/g, '.*') + ')').join('|') + ')$';
regexps[type] = new RegExp(pattern, 'i');
});
};
const getType = sequence => {
if (reEndsWithSlash.test(sequence)) {
return 'folder';
}
function parse(types) {
_.each(types, function (patterns, type) {
var pattern = '^(' + _.map(patterns, function (p) { return '(' + escapeRegExp(p).replace(/\*/g, '.*') + ')'; }).join('|') + ')$';
regexps[type] = new RegExp(pattern, 'i');
});
}
const slashidx = sequence.lastIndexOf('/');
const name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence;
let result;
function getType(sequence) {
if (reEndsWithSlash.test(sequence)) {
return 'folder';
each(regexps, (regexp, type) => {
if (regexps[type].test(name)) {
result = type;
}
});
var slashidx = sequence.lastIndexOf('/');
var name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence;
var result;
_.each(regexps, function (regexp, type) {
if (regexps[type].test(name)) {
result = type;
return false;
}
});
return result ? result : 'file';
}
return result ? result : 'file';
};
parse(_.extend({}, config.types));
parse(Object.assign({}, config.types));
return {
getType: getType
};
});
module.exports = {
getType
};

Some files were not shown because too many files have changed in this diff Show More