Compare commits

...

223 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
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 trim_trailing_whitespace = true
[{package.json,.travis.yml,.eslintrc,.babelrc}] [{*.json,*.yml}]
indent_size = 2 indent_size = 2
[{*.md,*.jade}] [{*.md,*.pug}]
trim_trailing_whitespace = false trim_trailing_whitespace = false

View File

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

View File

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

10
.gitignore vendored
View File

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

View File

@@ -1,141 +1,219 @@
# Changelog # 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* ## v0.28.0 - *2015-12-19*
* now requires PHP 5.5.0+ * now require PHP 5.5.0+
* changes index path to `/_h5ai/public/index.php` * change index path to `/_h5ai/public/index.php`
* now only `/_h5ai/public/` needs to be accessable from web * now only `/_h5ai/public/` needs to be web-accessible
* adds support for custom script and style additions * add support for custom script and style additions
* adds options to set font families * add options to set font families
* adds search * add search
* adds ignorecase sorting option to tree * add ignorecase sorting option to tree
* adds wide links in tree view * add wide links in tree view
* adds IE edge mode * add IE edge mode
* adds frontend tests * add frontend tests
* fixes some styles in IE10 * fix some styles in IE10
* fixes preview bottom bar for small screen widths * fix preview bottom bar for small screen widths
* lots of code cleanup and refactorings * lots of code cleanup and refactorings
* changes API * change API
* updates build process, now uses [ghu](https://larsjung.de/ghu/) * update build process, now uses [`ghu`](https://larsjung.de/ghu/)
* switches from jshint and jscs to [eslint](http://eslint.org/) * switch from jshint and jscs to [`eslint`](http://eslint.org/)
* updates `jQuery` to 2.1.4 * update `jQuery` to 2.1.4
* updates `lodash` to 3.9.3 (adds debounce and trim) * update `lodash` to 3.9.3 (add debounce and trim)
* updates `marked` to 0.3.5 * update `marked` to 0.3.5
* updates `modulejs` to 1.13.0 * update `modulejs` to 1.13.0
* updates `prism` to 2015-12-19 * update `prism` to 2015-12-19
* updates h5bp styles to 5.2.0 * update h5bp styles to 5.2.0
* updates `normalize.css` to 3.0.3 * update `normalize.css` to 3.0.3
* removes `Moment.js` * remove `Moment.js`
## v0.27.0 - *2015-04-06* ## v0.27.0 - *2015-04-06*
* new layout * new layout
* adds editorconfig * add editorconfig
* drops support for IE9 (gets fallback) * drop support for IE9 (gets fallback)
* updates sidebar settings * update sidebar settings
* adds info sidebar * add info sidebar
* adds opt-out for click'n'drag selection * add opt-out for click'n'drag selection
* adds package name option for single selections * add package name option for single selections
* adds initial support for Peer5 * add initial support for Peer5
* adds option to down-sample images for preview * add option to down-sample images for preview
* adds option for natural sorting in tree sidebar * add option for natural sorting in tree sidebar
* fixes problems with files/folders named `0` * fix problems with files/folders named `0`
* changes font from `Ubuntu` to `Roboto` (smaller footprint, clearer for small sizes) * change font from `Ubuntu` to `Roboto` (smaller footprint, clearer for small sizes)
* switches back to Google Fonts * switch back to Google Fonts
* improves PDF thumbnail quality * improve PDF thumbnail quality
* improves drag-select * improve drag-select
* improves image preview * improve image preview
* prevents listing `_h5ai` folder and subfolders * prevent listing `_h5ai` folder and subfolders
* updates build process, now uses [mkr](https://larsjung.de/mkr/) and [fQuery](https://larsjung.de/fquery/) * update build process, now uses [`mkr`](https://larsjung.de/mkr/) and [`fQuery`](https://larsjung.de/fquery/)
* updates `jQuery` to 2.1.3 * update `jQuery` to 2.1.3
* updates `jQuery.qrcode` to 0.11.0 * update `jQuery.qrcode` to 0.11.0
* updates `Lo-Dash` to 3.6.0 * update `Lo-Dash` to 3.6.0
* updates `Modernizr` to 2.8.3 * update `Modernizr` to 2.8.3
* updates `modulejs` to 1.4.0 * update `modulejs` to 1.4.0
* updates `Moment.js` to 2.9.0 * update `Moment.js` to 2.9.0
* updates `Prism` to 2015-04-05 * update `Prism` to 2015-04-05
* removes deprecated Google Analytics code * remove deprecated Google Analytics code
* removes `jQuery.fracs` * remove `jQuery.fracs`
* removes `jQuery.scrollpanel` * remove `jQuery.scrollpanel`
* removes `jQuery.mousewheel` * remove `jQuery.mousewheel`
* language updates and additions (`af`, `es`, `ja`, `ko`, `ru`, `zh-cn`) * update languages (`af`, `es`, `ja`, `ko`, `ru`, `zh-cn`)
## v0.26.1 - *2014-08-17* ## v0.26.1 - *2014-08-17*
* fixes links * fix links
## v0.26.0 - *2014-08-16* ## v0.26.0 - *2014-08-16*
* removes True Type fonts * remove True Type fonts
* outsources themes to [h5ai-themes](https://github.com/lrsjng/h5ai-themes) * outsource themes to [h5ai-themes](https://github.com/lrsjng/h5ai-themes)
* adds filesize fallback for large files and 32bit PHP * add filesize fallback for large files and 32bit PHP
* fixes server detection * fix server detection
* adds config file tests to info page * add config file tests to info page
* removes JSON shim * remove JSON shim
* adds caching of command checks * add caching of command checks
* updates `jQuery.mousewheel` to 3.1.12 * update `jQuery.mousewheel` to 3.1.12
* updates `jQuery.qrcode` to 0.8.0 * update `jQuery.qrcode` to 0.8.0
* replaces `markdown` with [`marked`](https://github.com/chjj/marked) 0.3.2 * replace `markdown` with [`marked`](https://github.com/chjj/marked) 0.3.2
* updates `modulejs` to 0.4.5 * update `modulejs` to 0.4.5
* updates `Moment.js` to 2.8.1 * update `Moment.js` to 2.8.1
* replaces `underscore` with [`Lo-Dash`](https://github.com/lodash/lodash) 2.4.1 * replace `underscore` with [`Lo-Dash`](https://github.com/lodash/lodash) 2.4.1
* replaces `SyntaxHighlighter` with [`Prism`](http://prismjs.com) 2014-08-04 * replace `SyntaxHighlighter` with [`Prism`](http://prismjs.com) 2014-08-04
## v0.25.2 - *2014-07-01* ## v0.25.2 - *2014-07-01*
* adds optional info page protection * add optional info page protection
* fixes `short_open_tag` issues for PHP < 5.4.0 * fix `short_open_tag` issues for PHP < 5.4.0
* fixes default folder download (`alwaysVisible` option) * fix default folder download (`alwaysVisible` option)
* minor fixes * minor fixes
## v0.25.1 - *2014-06-25* ## v0.25.1 - *2014-06-25*
* fixes broken paths for filenames containing '+' characters * fix broken paths for filenames containing '+' characters
* fixes Google Universal Analytics * fix Google Universal Analytics
* fixes file type check * fix file type check
## v0.25.0 - *2014-06-22* ## v0.25.0 - *2014-06-22*
* adds sidebar * add sidebar
* adds initial theme support * add initial theme support
* adds icons from [Evolvere Icon Theme](http://franksouza183.deviantart.com/art/Evolvere-Icon-theme-440718295) * add icons from [Evolvere Icon Theme](http://franksouza183.deviantart.com/art/Evolvere-Icon-theme-440718295)
* adds PHP variant to calc folder sizes * add PHP variant to calc folder sizes
* adds scroll position reset on location change (issue [#279](https://github.com/lrsjng/h5ai/issues/279)) * add scroll position reset on location change (issue [#279](https://github.com/lrsjng/h5ai/issues/279))
* adds option to hide unreadable files * add option to hide unreadable files
* adds option where to place folders (top, inplace, bottom) * add option where to place folders (top, inplace, bottom)
* adds markdown support for custom header and footer files * add markdown support for custom header and footer files
* adds video and audio preview via HTML5 elements (no fallback, works best in Chrome) * add video and audio preview via HTML5 elements (no fallback, works best in Chrome)
* adds filter reset on location change * add filter reset on location change
* adds option to make download button always visible * add option to make download button always visible
* adds Google UA support * add Google UA support
* extends selectable icon sizes (adds 128px, 192px, 256px, 384px) * extend selectable icon sizes (add 128px, 192px, 256px, 384px)
* improves preview GUI * improve preview GUI
* disable thumbs in `cache` folder * disable thumbs in `cache` folder
* fixes QR code URI origin (issue [#287](https://github.com/lrsjng/h5ai/issues/287)) * fix QR code URI origin (issue [#287](https://github.com/lrsjng/h5ai/issues/287))
* replaces PHP backtick operator with `exec` * replace PHP backtick operator with `exec`
* removes server side file manipulation extensions `dropbox`, `delete` and `rename` * remove server side file manipulation extensions `dropbox`, `delete` and `rename`
* updates `H5BP` to 4.3.0 * update `H5BP` to 4.3.0
* updates `jQuery` to 2.1.1 * update `jQuery` to 2.1.1
* updates `json2.js` to 2014-02-04 * update `json2.js` to 2014-02-04
* updates `markdown-js` to 0.5.0 * update `markdown-js` to 0.5.0
* updates `Modernizr` to 2.8.2 * update `Modernizr` to 2.8.2
* updates `Moment.js` to 2.6.0 * update `Moment.js` to 2.6.0
* updates `Underscore.js` to 1.6.0 * update `Underscore.js` to 1.6.0
* language updates (`bg`, `ko`, `pt`, `sl`, `sv`, `zh-cn`) * update languages (`bg`, `ko`, `pt`, `sl`, `sv`, `zh-cn`)
## v0.24.1 - *2014-04-09* ## 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)) * 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`) * fix WinOS command detection
* fixes WinOS command detection * update languages (`fi`, `fr`, `hi`, `it`, `zh-tw`)
## v0.24.0 - *2013-09-04* ## v0.24.0 - *2013-09-04*

View File

@@ -2,23 +2,16 @@
[![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github] [![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. A modern HTTP web server index for Apache httpd, lighttpd, and nginx.
For bug reports and feature requests please use [issues][github-issues].
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 * Do **not** install any files from the `src` folder, they need to be
preprocessed to work correctly! Find a preprocessed package and detailed preprocessed to work correctly!
install instructions on the [project page][web]. * Find a preprocessed package and detailed install instructions on the
[project page][web].
In short you have to take the following two steps: * For bug reports and feature requests please use [issues][github-issues].
* 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
## Build ## 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 [dev builds][develop]. But to build **h5ai** yourself either `git clone` or
download the repository. From within the root folder run the following download the repository. From within the root folder run the following
commands to find a fresh zipball in folder `build` (tested on linux only, 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 ~~~sh
> npm install > npm install
@@ -39,7 +33,7 @@ requires [`node 4.0+`][node] to be installed).
The MIT License (MIT) 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal 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 [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 [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 [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 {resolve, join} = require('path');
const { const {
ghu, ghu, autoprefixer, cssmin, each, ife, includeit, jszip, less, mapfn,
autoprefixer, cssmin, each, ife, includeit, jade, jszip, pug, read, remove, run, uglify, watch, webpack, wrap, write
less, mapfn, newerThan, read, remove, run, uglify, watch, wrap, write
} = require('ghu'); } = require('ghu');
const ROOT = resolve(__dirname); const ROOT = resolve(__dirname);
@@ -10,7 +9,27 @@ const SRC = join(ROOT, 'src');
const TEST = join(ROOT, 'test'); const TEST = join(ROOT, 'test');
const BUILD = join(ROOT, 'build'); 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'); ghu.defaults('release');
@@ -28,9 +47,8 @@ ghu.before(runtime => {
} }
runtime.comment = `${runtime.pkg.name} v${runtime.pkg.version} - ${runtime.pkg.homepage}`; runtime.comment = `${runtime.pkg.name} v${runtime.pkg.version} - ${runtime.pkg.homepage}`;
runtime.commentJs = `/* ${runtime.comment} */\n`; runtime.comment_js = `/* ${runtime.comment} */\n`;
runtime.commentHtml = `<!-- ${runtime.comment} -->`; runtime.comment_html = `<!-- ${runtime.comment} -->`;
console.log(runtime.comment); console.log(runtime.comment);
}); });
@@ -45,88 +63,67 @@ ghu.task('clean', 'delete build folder', () => {
return remove(BUILD); return remove(BUILD);
}); });
ghu.task('lint', 'lint all JavaScript files with eslint', () => {
return run('eslint .', {stdio: 'inherit'});
});
ghu.task('build:scripts', runtime => { ghu.task('build:scripts', runtime => {
return read(`${SRC}/_h5ai/public/js/*.js`) return read(`${SRC}/_h5ai/public/js/scripts.js`)
.then(newerThan(mapper, `${SRC}/_h5ai/public/js/**`)) .then(webpack(WEBPACK_CFG))
.then(wrap('\n\n// @include "pre.js"\n\n'))
.then(includeit()) .then(includeit())
.then(ife(() => runtime.args.production, uglify())) .then(ife(() => runtime.args.production, uglify()))
.then(wrap(runtime.commentJs)) .then(wrap(runtime.comment_js))
.then(write(mapper, {overwrite: true})); .then(write(mapper, {overwrite: true}));
}); });
ghu.task('build:styles', runtime => { ghu.task('build:styles', runtime => {
return read(`${SRC}/_h5ai/public/css/*.less`) return read(`${SRC}/_h5ai/public/css/*.less`)
.then(newerThan(mapper, `${SRC}/_h5ai/public/css/**`))
.then(includeit()) .then(includeit())
.then(less()) .then(less())
.then(autoprefixer()) .then(autoprefixer())
.then(ife(() => runtime.args.production, cssmin())) .then(ife(() => runtime.args.production, cssmin()))
.then(wrap(runtime.commentJs)) .then(wrap(runtime.comment_js))
.then(write(mapper, {overwrite: true})); .then(write(mapper, {overwrite: true}));
}); });
ghu.task('build:pages', runtime => { ghu.task('build:pages', runtime => {
return read(`${SRC}: **/*.jade, ! **/*.tpl.jade`) return read(`${SRC}: **/*.pug, ! **/*.tpl.pug`)
.then(newerThan(mapper, `${SRC}/**/*.tpl.jade`)) .then(pug({pkg: runtime.pkg}))
.then(jade({pkg: runtime.pkg})) .then(wrap('', runtime.comment_html))
.then(wrap('', runtime.commentHtml))
.then(write(mapper, {overwrite: true})); .then(write(mapper, {overwrite: true}));
}); });
ghu.task('build:copy', runtime => { 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([ return Promise.all([
read(`${SRC}/**/conf/*.json`) read(`${SRC}/**/conf/*.json`)
.then(newerThan(mapper)) .then(wrap(runtime.comment_js))
.then(wrap(runtime.commentJs))
.then(write(mapper, {overwrite: true, cluster: true})), .then(write(mapper, {overwrite: true, cluster: true})),
read(`${SRC}: **, ! **/*.js, ! **/*.less, ! **/*.jade, ! **/conf/*.json`) read(`${SRC}: **, ! **/*.js, ! **/*.less, ! **/*.pug, ! **/conf/*.json`)
.then(newerThan(mapper))
.then(each(obj => { .then(each(obj => {
if (/index\.php$/.test(obj.source)) { if ((/index\.php$/).test(obj.source)) {
obj.content = obj.content.replace('{{VERSION}}', runtime.pkg.version); obj.content = obj.content.replace('{{VERSION}}', runtime.pkg.version);
} }
})) }))
.then(write(mapper, {overwrite: true, cluster: true})), .then(write(mapper, {overwrite: true, cluster: true})),
read(`${ROOT}/*.md`) read(`${ROOT}/*.md`)
.then(newerThan(mapperRoot)) .then(write(mapper_root, {overwrite: true, cluster: true}))
.then(write(mapperRoot, {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([ return Promise.all([
read(`${TEST}/scripts.js`) read(`${BUILD}/_h5ai/public/css/styles.css`)
.then(newerThan(`${BUILD}/test/scripts.js`)) .then(write(`${BUILD}/test/h5ai-styles.css`, {overwrite: true})),
.then(includeit())
.then(write(`${BUILD}/test/scripts.js`, {overwrite: true})),
read(`${TEST}/styles.less`) read(`${TEST}/index.html`)
.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}))
.then(write(`${BUILD}/test/index.html`, {overwrite: true})), .then(write(`${BUILD}/test/index.html`, {overwrite: true})),
read(`${BUILD}/_h5ai/public/js/scripts.js`) read(`${TEST}: index.js`)
.then(newerThan(`${BUILD}/test/h5ai-scripts.js`)) .then(webpack(WEBPACK_CFG))
.then(write(`${BUILD}/test/h5ai-scripts.js`, {overwrite: true})), .then(wrap(`\n\n// @include "${SRC}/**/js/pre.js"\n\n`))
.then(includeit())
read(`${BUILD}/_h5ai/public/css/styles.css`) .then(write(mapfn.p(TEST, `${BUILD}/test`), {overwrite: true}))
.then(newerThan(`${BUILD}/test/h5ai-styles.css`))
.then(write(`${BUILD}/test/h5ai-styles.css`, {overwrite: true}))
]).then(() => { ]).then(() => {
console.log(`browse to file://${BUILD}/test/index.html to run the test suite`); 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}`); 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/**`) return read(`${BUILD}/_h5ai/**`)
.then(newerThan(mapperDeploy)) .then(write(mapper_deploy, {overwrite: true, cluster: true}));
.then(write(mapperDeploy, {overwrite: true, cluster: true}));
}); });
ghu.task('watch', runtime => { 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", "name": "h5ai",
"version": "0.28.1", "version": "0.30.0",
"description": "Modern HTTP web server index.", "description": "Modern HTTP web server index.",
"homepage": "https://larsjung.de/h5ai/", "homepage": "https://larsjung.de/h5ai/",
"bugs": "https://github.com/lrsjng/h5ai/issues",
"author": "Lars Jung <lrsjng@gmail.com> (https://larsjung.de)", "author": "Lars Jung <lrsjng@gmail.com> (https://larsjung.de)",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@@ -12,17 +11,21 @@
}, },
"scripts": { "scripts": {
"lint": "eslint .", "lint": "eslint .",
"ghu": "node -r babel-core/register ghu.js", "test": "node test",
"build": "npm run -s ghu release" "build": "node ghu release",
"precommit": "npm run -s lint && npm run -s test"
}, },
"devDependencies": { "devDependencies": {
"babel-core": "6.3.21", "@babel/core": "7.12.10",
"babel-eslint": "5.0.0-beta6", "@babel/preset-env": "7.12.11",
"babel-preset-es2015": "6.3.13", "eslint": "7.18.0",
"eslint": "1.10.3", "ghu": "0.26.0",
"ghu": "0.4.0" "jsdom": "16.4.0",
}, "kjua": "0.9.0",
"engines": { "lolight": "1.4.0",
"node": ">=4.0.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: rules:
consistent-this: 0 no-console: 1
func-names: 0
max-params: [1, 10]
no-invalid-this: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-reflect: 0 prefer-reflect: 0

View File

@@ -1,3 +1,165 @@
Satisfy all ## details here: https://github.com/h5bp/server-configs-apache
Order deny,allow
Deny from all
## 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", "download": "Descargar",
"empty": "vacío", "empty": "vacío",
"files": "Archivos", "files": "Archivos",
"filter": "Filtar", "filter": "Filtrar",
"folders": "Directorios", "folders": "Directorios",
"grid": "Cuadrícula", "grid": "Cuadrícula",
"icons": "Íconos", "icons": "Íconos",
"language": "Idioma",
"lastModified": "Última modificación", "lastModified": "Última modificación",
"name": "Nombre", "name": "Nombre",
"noMatch": "Sin coincidencias", "noMatch": "Sin coincidencias",
"parentDirectory": "Directorio superior", "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", "download": "télécharger",
"empty": "vide", "empty": "vide",
"files": "Fichiers", "files": "Fichiers",
"filter": "filtre", "filter": "filtrer",
"folders": "Répertoires", "folders": "Répertoires",
"grid": "grille", "grid": "grille",
"icons": "icônes", "icons": "icônes",
"language": "Langue",
"lastModified": "Dernière modification", "lastModified": "Dernière modification",
"name": "Nom", "name": "Nom",
"noMatch": "rien trouvé", "noMatch": "rien trouvé",
"parentDirectory": "Dossier parent", "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", "folders": "cartelle",
"grid": "griglia", "grid": "griglia",
"icons": "icone", "icons": "icone",
"language": "Linugua",
"lastModified": "Ultima modifica", "lastModified": "Ultima modifica",
"name": "Nome", "name": "Nome",
"noMatch": "nessun risultato", "noMatch": "nessun risultato",
"parentDirectory": "Cartella Superiore", "parentDirectory": "Cartella Superiore",
"size": "Dimensione" "search": "cerca",
"size": "Dimensione",
"tree": "Albero",
"view": "Vista"
} }

View File

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

View File

@@ -10,9 +10,13 @@
"folders": "folderów", "folders": "folderów",
"grid": "kafelki", "grid": "kafelki",
"icons": "ikony", "icons": "ikony",
"language": "Język",
"lastModified": "Ostatnia modyfikacja", "lastModified": "Ostatnia modyfikacja",
"name": "Nazwa", "name": "Nazwa",
"noMatch": "nie znaleziono", "noMatch": "nie znaleziono",
"parentDirectory": "Katalog nadrzędny", "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", "dateFormat": "DD-MM-YYYY HH:mm",
"details": "detalhes", "details": "detalhes",
@@ -10,9 +10,13 @@
"folders": "pastas", "folders": "pastas",
"grid": "grelha", "grid": "grelha",
"icons": "ícones", "icons": "ícones",
"language": "Idioma",
"lastModified": "última modificação", "lastModified": "última modificação",
"name": "Nome", "name": "Nome",
"noMatch": "sem resultados", "noMatch": "sem resultados",
"parentDirectory": "diretório acima", "parentDirectory": "Diretório acima",
"size": "Tamanho" "search": "pesquisa",
"size": "Tamanho",
"tree": "Árvore",
"view": "Visualização"
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,14 @@
<?php <?php
class Context { class Context {
private static $DEFAULT_PASSHASH = 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'; private static $DEFAULT_PASSHASH = 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
private static $AS_ADMIN_SESSION_KEY = 'AS_ADMIN'; 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 $session;
private $request; private $request;
@@ -12,7 +17,6 @@ class Context {
private $passhash; private $passhash;
public function __construct($session, $request, $setup) { public function __construct($session, $request, $setup) {
$this->session = $session; $this->session = $session;
$this->request = $request; $this->request = $request;
$this->setup = $setup; $this->setup = $setup;
@@ -25,64 +29,60 @@ class Context {
} }
public function get_session() { public function get_session() {
return $this->session; return $this->session;
} }
public function get_request() { public function get_request() {
return $this->request; return $this->request;
} }
public function get_setup() { public function get_setup() {
return $this->setup; return $this->setup;
} }
public function get_options() { public function get_options() {
return $this->options; return $this->options;
} }
public function query_option($keypath = '', $default = null) { public function query_option($keypath = '', $default = null) {
return Util::array_query($this->options, $keypath, $default); return Util::array_query($this->options, $keypath, $default);
} }
public function get_types() { public function get_types() {
return Json::load($this->setup->get('CONF_PATH') . '/types.json'); return Json::load($this->setup->get('CONF_PATH') . '/types.json');
} }
public function login_admin($pass) { public function login_admin($pass) {
$this->session->set(Context::$AS_ADMIN_SESSION_KEY, strcasecmp(hash('sha512', $pass), $this->passhash) === 0); $this->session->set(Context::$AS_ADMIN_SESSION_KEY, strcasecmp(hash('sha512', $pass), $this->passhash) === 0);
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
} }
public function logout_admin() { public function logout_admin() {
$this->session->set(Context::$AS_ADMIN_SESSION_KEY, false); $this->session->set(Context::$AS_ADMIN_SESSION_KEY, false);
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
} }
public function is_admin() { public function is_admin() {
return $this->session->get(Context::$AS_ADMIN_SESSION_KEY); return $this->session->get(Context::$AS_ADMIN_SESSION_KEY);
} }
public function is_api_request() { public function is_api_request() {
return strtolower($this->setup->get('REQUEST_METHOD')) === 'post'; return strtolower($this->setup->get('REQUEST_METHOD')) === 'post';
} }
public function is_info_request() { public function is_info_request() {
return Util::starts_with($this->setup->get('REQUEST_HREF') . '/', $this->setup->get('PUBLIC_HREF')); 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'))); $rel_path = substr($path, strlen($this->setup->get('ROOT_PATH')));
$parts = explode('/', $rel_path); $parts = explode('/', $rel_path);
$encoded_parts = []; $encoded_parts = [];
@@ -96,13 +96,11 @@ class Context {
} }
public function to_path($href) { public function to_path($href) {
$rel_href = substr($href, strlen($this->setup->get('ROOT_HREF'))); $rel_href = substr($href, strlen($this->setup->get('ROOT_HREF')));
return Util::normalize_path($this->setup->get('ROOT_PATH') . '/' . rawurldecode($rel_href)); return Util::normalize_path($this->setup->get('ROOT_PATH') . '/' . rawurldecode($rel_href));
} }
public function is_hidden($name) { public function is_hidden($name) {
// always hide // always hide
if ($name === '.' || $name === '..') { if ($name === '.' || $name === '..') {
return true; return true;
@@ -119,7 +117,6 @@ class Context {
} }
public function read_dir($path) { public function read_dir($path) {
$names = []; $names = [];
if (is_dir($path)) { if (is_dir($path)) {
foreach (scandir($path) as $name) { foreach (scandir($path) as $name) {
@@ -137,12 +134,10 @@ class Context {
} }
public function is_managed_href($href) { public function is_managed_href($href) {
return $this->is_managed_path($this->to_path($href)); return $this->is_managed_path($this->to_path($href));
} }
public function is_managed_path($path) { public function is_managed_path($path) {
if (!is_dir($path) || strpos($path, '../') !== false || strpos($path, '/..') !== false || $path === '..') { if (!is_dir($path) || strpos($path, '../') !== false || strpos($path, '/..') !== false || $path === '..') {
return false; return false;
} }
@@ -175,7 +170,6 @@ class Context {
} }
public function get_current_path() { public function get_current_path() {
$current_href = Util::normalize_path($this->setup->get('REQUEST_HREF'), true); $current_href = Util::normalize_path($this->setup->get('REQUEST_HREF'), true);
$current_path = $this->to_path($current_href); $current_path = $this->to_path($current_href);
@@ -187,7 +181,6 @@ class Context {
} }
public function get_items($href, $what) { public function get_items($href, $what) {
if (!$this->is_managed_href($href)) { if (!$this->is_managed_href($href)) {
return []; return [];
} }
@@ -219,7 +212,6 @@ class Context {
} }
public function get_langs() { public function get_langs() {
$langs = []; $langs = [];
$l10n_path = $this->setup->get('CONF_PATH') . '/l10n'; $l10n_path = $this->setup->get('CONF_PATH') . '/l10n';
if (is_dir($l10n_path)) { if (is_dir($l10n_path)) {
@@ -238,10 +230,13 @@ class Context {
} }
public function get_l10n($iso_codes) { public function get_l10n($iso_codes) {
$results = []; $results = [];
foreach ($iso_codes as $iso_code) { 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'; $file = $this->setup->get('CONF_PATH') . '/l10n/' . $iso_code . '.json';
$results[$iso_code] = Json::load($file); $results[$iso_code] = Json::load($file);
$results[$iso_code]['isoCode'] = $iso_code; $results[$iso_code]['isoCode'] = $iso_code;
@@ -251,7 +246,6 @@ class Context {
} }
public function get_thumbs($requests) { public function get_thumbs($requests) {
$hrefs = []; $hrefs = [];
foreach ($requests as $req) { foreach ($requests as $req) {
@@ -263,7 +257,6 @@ class Context {
} }
private function prefix_x_head_href($href) { private function prefix_x_head_href($href) {
if (preg_match('@^(https?://|/)@i', $href)) { if (preg_match('@^(https?://|/)@i', $href)) {
return $href; return $href;
} }
@@ -272,7 +265,6 @@ class Context {
} }
private function get_fonts_html() { private function get_fonts_html() {
$fonts = $this->query_option('view.fonts', []); $fonts = $this->query_option('view.fonts', []);
$fonts_mono = $this->query_option('view.fontsMono', []); $fonts_mono = $this->query_option('view.fontsMono', []);
@@ -292,7 +284,6 @@ class Context {
} }
public function get_x_head_html() { public function get_x_head_html() {
$scripts = $this->query_option('resources.scripts', []); $scripts = $this->query_option('resources.scripts', []);
$styles = $this->query_option('resources.styles', []); $styles = $this->query_option('resources.styles', []);

View File

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

View File

@@ -1,47 +1,28 @@
<?php <?php
class Filesize { class Filesize {
private static $cache = [];
private $cache = []; public static function getSize($path, $withFoldersize, $withDu) {
$fs = new Filesize();
public function __construct() { return $fs->size($path, $withFoldersize, $withDu);
} }
public function fseek($path) { public static function getCachedSize($path, $withFoldersize, $withDu) {
if (array_key_exists($path, Filesize::$cache)) {
$size = 0; return Filesize::$cache[$path];
$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);
}
} }
while (fgetc($handle) !== false) { $size = Filesize::getSize($path, $withFoldersize, $withDu);
$size += 1;
}
fclose($handle);
Filesize::$cache[$path] = $size;
return $size; return $size;
} }
public function filesize($path) {
return @filesize($path); private function __construct() {}
}
private function read_dir($path) { private function read_dir($path) {
$paths = []; $paths = [];
if (is_dir($path)) { if (is_dir($path)) {
foreach (scandir($path) as $name) { foreach (scandir($path) as $name) {
@@ -53,8 +34,23 @@ class Filesize {
return $paths; 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)); $cmd = implode(' ', array_map('escapeshellarg', $cmdv));
$lines = []; $lines = [];
$rc = null; $rc = null;
@@ -62,38 +58,39 @@ class Filesize {
return $lines; return $lines;
} }
public function du_paths($paths) { private function exec_du_all($paths) {
$cmdv = array_merge(['du', '-sbL'], $paths);
$cmdv = array_merge(['du', '-sk'], $paths);
$lines = $this->exec($cmdv); $lines = $this->exec($cmdv);
$sizes = []; $sizes = [];
foreach ($lines as $line) { foreach ($lines as $line) {
$parts = preg_split('/[\s]+/', $line, 2); $parts = preg_split('/[\s]+/', $line, 2);
$size = intval($parts[0], 10) * 1024; $size = intval($parts[0], 10);
$path = $parts[1]; $path = $parts[1];
$sizes[$path] = $size; $sizes[$path] = $size;
} }
return $sizes; return $sizes;
} }
public function du_dir($path) { private function exec_du($path) {
$sizes = $this->exec_du_all([$path]);
return $this->du_paths($this->read_dir($path));
}
public function du_path($path) {
$sizes = $this->du_paths([$path]);
return $sizes[$path]; return $sizes[$path];
} }
public function add($path) {
$size = 0; private function size($path, $withFoldersize = false, $withDu = false) {
foreach ($this->read_dir($path) as $p) { if (is_file($path)) {
$size += $this->filesize($p); 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 <?php
class Item { class Item {
public static function cmp($item1, $item2) { public static function cmp($item1, $item2) {
if ($item1->is_folder && !$item2->is_folder) { if ($item1->is_folder && !$item2->is_folder) {
return -1; return -1;
} }
@@ -15,7 +13,6 @@ class Item {
} }
public static function get($context, $path, &$cache) { public static function get($context, $path, &$cache) {
if (!Util::starts_with($path, $context->get_setup()->get('ROOT_PATH'))) { if (!Util::starts_with($path, $context->get_setup()->get('ROOT_PATH'))) {
return null; return null;
} }
@@ -41,7 +38,6 @@ class Item {
public $is_content_fetched; public $is_content_fetched;
private function __construct($context, $path) { private function __construct($context, $path) {
$this->context = $context; $this->context = $context;
$this->path = Util::normalize_path($path, false); $this->path = Util::normalize_path($path, false);
@@ -53,7 +49,6 @@ class Item {
} }
public function to_json_object() { public function to_json_object() {
$obj = [ $obj = [
'href' => $this->href, 'href' => $this->href,
'time' => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript) 'time' => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript)
@@ -69,7 +64,6 @@ class Item {
} }
public function get_parent(&$cache) { public function get_parent(&$cache) {
$parent_path = Util::normalize_path(dirname($this->path), false); $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'))) { 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); return Item::get($this->context, $parent_path, $cache);
@@ -78,7 +72,6 @@ class Item {
} }
public function get_content(&$cache) { public function get_content(&$cache) {
$items = []; $items = [];
if (!$this->context->is_managed_href($this->href)) { if (!$this->context->is_managed_href($this->href)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +1,10 @@
<?php <?php
class Thumb { class Thumb {
private static $FFMPEG_CMDV = ['ffmpeg', '-ss', '0:00:10', '-i', '[SRC]', '-an', '-vframes', '1', '[DEST]']; 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 $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 $CONVERT_CMDV = ['convert', '-density', '200', '-quality', '100', '-strip', '[SRC][0]', '[DEST]'];
private static $GM_CONVERT_CMDV = ['gm', 'convert', '-density', '200', '-quality', '100', '-sharpen', '0x1.0', '[SRC][0]', '[DEST]']; private static $GM_CONVERT_CMDV = ['gm', 'convert', '-density', '200', '-quality', '100', '[SRC][0]', '[DEST]'];
private static $THUMB_CACHE = 'thumbs'; private static $THUMB_CACHE = 'thumbs';
private $context; private $context;
@@ -14,7 +13,6 @@ class Thumb {
private $thumbs_href; private $thumbs_href;
public function __construct($context) { public function __construct($context) {
$this->context = $context; $this->context = $context;
$this->setup = $context->get_setup(); $this->setup = $context->get_setup();
$this->thumbs_path = $this->setup->get('CACHE_PUB_PATH') . '/' . Thumb::$THUMB_CACHE; $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) { public function thumb($type, $source_href, $width, $height) {
$source_path = $this->context->to_path($source_href); $source_path = $this->context->to_path($source_href);
if (!file_exists($source_path) || Util::starts_with($source_path, $this->setup->get('CACHE_PUB_PATH'))) { if (!file_exists($source_path) || Util::starts_with($source_path, $this->setup->get('CACHE_PUB_PATH'))) {
return null; return null;
@@ -35,16 +32,16 @@ class Thumb {
$capture_path = $source_path; $capture_path = $source_path;
if ($type === 'img') { if ($type === 'img') {
$capture_path = $source_path; $capture_path = $source_path;
} else if ($type === 'mov') { } elseif ($type === 'mov') {
if ($this->setup->get('HAS_CMD_AVCONV')) { if ($this->setup->get('HAS_CMD_AVCONV')) {
$capture_path = $this->capture(Thumb::$AVCONV_CMDV, $source_path); $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); $capture_path = $this->capture(Thumb::$FFMPEG_CMDV, $source_path);
} }
} else if ($type === 'doc') { } elseif ($type === 'doc') {
if ($this->setup->get('HAS_CMD_CONVERT')) { if ($this->setup->get('HAS_CMD_CONVERT')) {
$capture_path = $this->capture(Thumb::$CONVERT_CMDV, $source_path); $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); $capture_path = $this->capture(Thumb::$GM_CONVERT_CMDV, $source_path);
} }
} }
@@ -53,7 +50,6 @@ class Thumb {
} }
private function thumb_href($source_path, $width, $height) { private function thumb_href($source_path, $width, $height) {
if (!file_exists($source_path)) { if (!file_exists($source_path)) {
return null; return null;
} }
@@ -63,7 +59,6 @@ class Thumb {
$thumb_href = $this->thumbs_href . '/' . $name; $thumb_href = $this->thumbs_href . '/' . $name;
if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) { if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) {
$image = new Image(); $image = new Image();
$et = false; $et = false;
@@ -86,7 +81,6 @@ class Thumb {
} }
private function capture($cmdv, $source_path) { private function capture($cmdv, $source_path) {
if (!file_exists($source_path)) { if (!file_exists($source_path)) {
return null; return null;
} }
@@ -94,7 +88,6 @@ class Thumb {
$capture_path = $this->thumbs_path . '/capture-' . sha1($source_path) . '.jpg'; $capture_path = $this->thumbs_path . '/capture-' . sha1($source_path) . '.jpg';
if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) { if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) {
foreach ($cmdv as &$arg) { foreach ($cmdv as &$arg) {
$arg = str_replace('[SRC]', $source_path, $arg); $arg = str_replace('[SRC]', $source_path, $arg);
$arg = str_replace('[DEST]', $capture_path, $arg); $arg = str_replace('[DEST]', $capture_path, $arg);
@@ -108,7 +101,6 @@ class Thumb {
} }
class Image { class Image {
private $source_file; private $source_file;
private $source; private $source;
private $width; private $width;
@@ -117,7 +109,6 @@ class Image {
private $dest; private $dest;
public function __construct($filename = null) { public function __construct($filename = null) {
$this->source_file = null; $this->source_file = null;
$this->source = null; $this->source = null;
$this->width = null; $this->width = null;
@@ -130,13 +121,11 @@ class Image {
} }
public function __destruct() { public function __destruct() {
$this->release_source(); $this->release_source();
$this->release_dest(); $this->release_dest();
} }
public function set_source($filename) { public function set_source($filename) {
$this->release_source(); $this->release_source();
$this->release_dest(); $this->release_dest();
@@ -160,7 +149,6 @@ class Image {
} }
public function save_dest_jpeg($filename, $quality = 80) { public function save_dest_jpeg($filename, $quality = 80) {
if (!is_null($this->dest)) { if (!is_null($this->dest)) {
@imagejpeg($this->dest, $filename, $quality); @imagejpeg($this->dest, $filename, $quality);
@chmod($filename, 0775); @chmod($filename, 0775);
@@ -168,7 +156,6 @@ class Image {
} }
public function release_dest() { public function release_dest() {
if (!is_null($this->dest)) { if (!is_null($this->dest)) {
@imagedestroy($this->dest); @imagedestroy($this->dest);
$this->dest = null; $this->dest = null;
@@ -176,7 +163,6 @@ class Image {
} }
public function release_source() { public function release_source() {
if (!is_null($this->source)) { if (!is_null($this->source)) {
@imagedestroy($this->source); @imagedestroy($this->source);
$this->source_file = null; $this->source_file = null;
@@ -188,7 +174,6 @@ class Image {
} }
public function thumb($width, $height) { public function thumb($width, $height) {
if (is_null($this->source)) { if (is_null($this->source)) {
return; return;
} }
@@ -233,7 +218,6 @@ class Image {
} }
public function rotate($angle) { public function rotate($angle) {
if (is_null($this->source) || ($angle !== 90 && $angle !== 180 && $angle !== 270)) { if (is_null($this->source) || ($angle !== 90 && $angle !== 180 && $angle !== 270)) {
return; return;
} }
@@ -245,7 +229,6 @@ class Image {
} }
public function normalize_exif_orientation($exif_source_file = null) { public function normalize_exif_orientation($exif_source_file = null) {
if (is_null($this->source) || !function_exists('exif_read_data')) { if (is_null($this->source) || !function_exists('exif_read_data')) {
return; return;
} }
@@ -255,7 +238,7 @@ class Image {
} }
$exif = exif_read_data($exif_source_file); $exif = exif_read_data($exif_source_file);
switch(@$exif['Orientation']) { switch (@$exif['Orientation']) {
case 3: case 3:
$this->rotate(180); $this->rotate(180);
break; 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') html(class='no-js', lang='en')
head head
<!--[if lt IE 10]><meta id='no-browser'><![endif]-->
meta(charset='utf-8') meta(charset='utf-8')
meta(http-equiv='x-ua-compatible', content='ie=edge') meta(http-equiv='x-ua-compatible', content='ie=edge')
title #{title} title #{title}
meta(name='description', content='#{title}') meta(name='description', content=title)
meta(name='viewport', content='width=device-width, initial-scale=1') 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='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='apple-touch-icon-precomposed', type='image/png', href!='<?= $public_href; ?>images/favicon/favicon-152.png')
link(rel='stylesheet', href!='<?= $public_href; ?>css/styles.css') 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; ?> <?= $x_head_tags; ?>
body#root(class='#{module}') body#root(class=module)
div#fallback-hints div#fallback-hints
<?php if (!$fallback_mode) { ?>
span.noJsMsg Works best with JavaScript enabled! span.noJsMsg Works best with JavaScript enabled!
span.noBrowserMsg Works best in #[a(href='http://browsehappy.com') modern browsers]! 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 block body

View File

@@ -1,27 +1,13 @@
Satisfy all ## make this folder accessible
Order allow,deny
Allow from all
DirectoryIndex disabled # Apache < 2.3
<IfModule !mod_authz_core.c>
<IfModule mod_autoindex.c> Order allow,deny
Options -Indexes Allow from all
Satisfy All
</IfModule> </IfModule>
AddDefaultCharset utf-8 # Apache ≥ 2.3
<IfModule mod_authz_core.c>
<IfModule mod_mime.c> Require all granted
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"
</IfModule> </IfModule>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#pv-txt-text { #pv-content-txt {
.raised; .raised;
box-sizing: border-box;
max-width: 960px; max-width: 960px;
text-align: left; text-align: left;
background: @col-back-paper; background: @col-back-paper;
@@ -8,103 +9,28 @@
padding: 8px; padding: 8px;
overflow: auto; overflow: auto;
&.highlighted { a, a:active, a:visited {
color: #2080FF;
text-decoration: none;
cursor: pointer;
code { &:hover {
line-height: 1.2em; color: #68A9FF;
}
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;
} }
} }
} }
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; .raised;
position: absolute; position: absolute;
@@ -7,7 +7,7 @@
max-height: 100%; max-height: 100%;
} }
#pv-vid-video:-webkit-full-screen { #pv-content-vid:-webkit-full-screen {
top: auto !important; top: auto !important;
left: auto !important; left: auto !important;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,12 +8,12 @@
} }
} }
#view.view-details { #view.view-details {
.header .label, .item .label { // .header .label, .item .label {
margin-right: 80px !important; // margin-right: 80px !important;
} // }
.header .date, .item .date { // .header .date, .item .date {
display: none; // display: none;
} // }
} }
#tree, #info { #tree, #info {
display: none !important; display: none !important;
@@ -21,8 +21,15 @@
} }
@media print { @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 { #toolbar, #sidebar, #tree, #info {
display: none !important; display: none !important;

View File

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

View File

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

View File

@@ -7,6 +7,7 @@
bottom: 0; bottom: 0;
overflow: hidden; overflow: hidden;
background: @col-back; background: @col-back;
line-height: 1.4;
} }
#root, input, select { #root, input, select {
@@ -15,10 +16,3 @@
font-weight: @font-weight; font-weight: @font-weight;
color: @col-text; 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 { #sidebar {
display: none;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
flex: 0 0 auto; flex: 0 0 auto;
order: 0; order: 0;
background: @col-back-panel; background: @col-back-panel;
border-right: 1px solid rgba(0,0,0,0.08); border-right: 1px solid @col-border;
padding: 16px; padding: 16px;
position: absolute;
top: 48px;
min-height: 100%;
z-index: 1;
.block { .block {
display: block; display: block;
margin: 0 0 24px 0; margin: 0 0 24px 0;

View File

@@ -5,7 +5,7 @@
order: 1; order: 1;
background: @col-back-panel; 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; z-index: 1;
} }

View File

@@ -23,24 +23,19 @@
} }
} }
margin: 16px; margin: 32px;
#items {
.rounded;
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2);
}
.header { .header {
position: relative; position: relative;
white-space: nowrap; white-space: nowrap;
display: list-item; display: list-item;
background: @col-back-panel;
border-bottom: 1px solid rgba(0,0,0,0.07); border-bottom: 1px solid rgba(0,0,0,0.07);
border-radius: 2px 2px 0 0; border-radius: 2px 2px 0 0;
.label, .date, .size { .label, .date, .size {
.eased-transition; .eased-transition;
line-height: 46px; line-height: 24px;
padding: 0px 8px 16px 8px;
opacity: 0.4; opacity: 0.4;
outline: 0; outline: 0;
@@ -115,3 +110,26 @@
.view-details-sized(16px) .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 { .item {
.card;
.rounded; .rounded;
overflow: hidden; overflow: hidden;
float: left; float: left;
@@ -34,7 +33,6 @@
.square { .square {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
background: @col-back-panel;
} }
.label { .label {

View File

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

View File

@@ -1,7 +1,6 @@
@charset "utf-8"; @charset "utf-8";
// @include "vendor/normalize.less" // @include "../../../../node_modules/normalize.css/normalize.css"
// @include "vendor/h5bp-pre.less"
// @include "lib/colors.less" // @include "lib/colors.less"
// @include "lib/fonts.less" // @include "lib/fonts.less"
@@ -11,5 +10,3 @@
// @include "lib/*/*.less" // @include "lib/*/*.less"
// @include "lib/responsive.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"> <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> </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"> <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="M20 4H4l6 9v5l4 2v-7z" fill="#555"/>
<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"/> </svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 172 B

View File

@@ -1,12 +1,16 @@
<?php <?php
define('H5AI_VERSION', '{{VERSION}}'); 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, '<')) { if (!function_exists('version_compare') || version_compare(PHP_VERSION, MIN_PHP_VERSION, '<')) {
header('Content-type: text/plain;charset=utf-8'); header('Content-type: text/plain;charset=utf-8');
echo '[err] h5ai requires PHP ' . MIN_PHP_VERSION . ' or later, but found PHP ' . PHP_VERSION; exit('[ERR] h5ai requires PHP ' . MIN_PHP_VERSION . ' or later, but found PHP ' . PHP_VERSION);
exit; }
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'; 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 (_) { const {isStr, isFn, dom} = require('../util');
var slice = Array.prototype.slice;
var subscriptions = {};
function sub(topic, callback) { const subscriptions = {};
if (_.isString(topic) && _.isFunction(callback)) {
if (!subscriptions[topic]) { const sub = (topic, listener) => {
subscriptions[topic] = []; if (isStr(topic) && isFn(listener)) {
} if (!subscriptions[topic]) {
subscriptions[topic].push(callback); subscriptions[topic] = [];
} }
subscriptions[topic].push(listener);
} }
};
function unsub(topic, callback) { const pub = (topic, ...args) => {
if (_.isString(topic) && _.isFunction(callback) && subscriptions[topic]) { // console.log(topic, args);
subscriptions[topic] = _.without(subscriptions[topic], callback); if (isStr(topic) && subscriptions[topic]) {
} subscriptions[topic].forEach(listener => {
listener.apply(topic, args);
});
} }
};
function pub(topic) { dom(global.window).on('resize', () => pub('resize'));
var args = slice.call(arguments, 1);
if (_.isString(topic) && subscriptions[topic]) { module.exports = {
_.each(subscriptions[topic], function (callback) { sub,
callback.apply(topic, args); pub
}); };
}
}
return {
sub: sub,
unsub: unsub,
pub: pub
};
});

View File

@@ -1,95 +1,96 @@
modulejs.define('core/format', ['_'], function (_) { const {isNum} = require('../util');
var decimalMetric = {
t: 1000.0, const decimalMetric = {
k: 1000.0, t: 1000.0,
u: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 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, datePatterns.forEach(pattern => {
k: 1024.0, format = format.replace(pattern[0], formatNumber(d[pattern[1]], pattern[2]));
u: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] });
};
var defaultMetric = decimalMetric; return format;
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';
function setDefaultMetric(useBinaryMetric) { module.exports = {
defaultMetric = useBinaryMetric ? binaryMetric : decimalMetric; setDefaultMetric,
} formatSize,
setDefaultDateFormat,
function formatSize(size, metric) { formatDate
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
};
});

View File

@@ -1,3 +1,2 @@
modulejs.define('core/langs', ['_', 'config'], function (_, config) { const {langs} = require('../config');
return _.extend({}, config.langs); 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) { const {each, values, difference} = require('../util');
var settings = _.extend({ const {request} = require('../server');
fastBrowsing: true, const allsettings = require('./settings');
unmanagedInNewWindow: true const event = require('./event');
}, allsettings.view); const notification = require('../view/notification');
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']
];
function forceEncoding(href) { const win = global.window;
return reForceEncoding.reduce(function (nuHref, data) { const doc = win.document;
return nuHref.replace(data[0], data[1]); const settings = Object.assign({
}, href); 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 forceEncoding(location);
return uri.replace(reUriToPathname, ''); };
}
var hrefsAreDecoded = (function () { const getDomain = () => doc.domain;
var testpathname = '/a b'; const getAbsHref = () => absHref;
var a = doc.createElement('a'); const getItem = () => require('../model/item').get(absHref);
a.href = testpathname; const load = () => {
return uriToPathname(a.href) === testpathname; return request({action: 'get', items: {href: absHref, what: 1}}).then(json => {
}()); const Item = require('../model/item');
const item = Item.get(absHref);
function encodedHref(href) { if (json) {
var a = doc.createElement('a'); const found = {};
var location;
a.href = href; each(json.items, jsonItem => {
location = uriToPathname(a.href); const e = Item.get(jsonItem);
found[e.absHref] = true;
});
if (hrefsAreDecoded) { each(item.content, e => {
location = encodeURIComponent(location).replace(/%2F/ig, '/'); if (!found[e.absHref]) {
} Item.remove(e.absHref);
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);
} }
});
}
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(); const item = getItem();
if (item.isLoaded) { 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); event.pub('location.changed', item);
refresh(); });
} else { }
notification.set('loading...'); };
load(function () {
item.isLoaded = true; const setLink = ($el, item) => {
notification.set(); $el.attr('href', item.absHref);
event.pub('location.changed', item);
}); if (history && item.isFolder() && item.isManaged) {
} $el.on('click', ev => {
setLocation(item.absHref);
ev.preventDefault();
return false;
});
} }
function setLink($el, item) { if (settings.unmanagedInNewWindow && !item.isManaged) {
$el.attr('href', item.absHref); $el.attr('target', '_blank');
if (history && item.isFolder() && item.isManaged) {
$el.on('click', function () {
setLocation(item.absHref);
return false;
});
}
if (settings.unmanagedInNewWindow && !item.isManaged) {
$el.attr('target', '_blank');
}
} }
};
function onPopState(ev) { const onPopState = ev => {
if (ev.state && ev.state.absHref) { if (ev.state && ev.state.absHref) {
setLocation(ev.state.absHref, true); setLocation(ev.state.absHref, true);
}
} }
};
window.onpopstate = history ? onPopState : null; win.onpopstate = history ? onPopState : null;
return { module.exports = {
forceEncoding: forceEncoding, forceEncoding,
getDomain: getDomain, getDomain,
getAbsHref: getAbsHref, getAbsHref,
getItem: getItem, getItem,
setLocation: setLocation, setLocation,
refresh: refresh, refresh,
setLink: setLink 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) { const {includes} = require('../util');
var imagesHref = settings.publicHref + 'images/'; const config = require('../config');
var uiHref = imagesHref + 'ui/'; const settings = require('./settings');
var themesHref = imagesHref + 'themes/';
var defaultThemeHref = themesHref + 'default/'; const imagesHref = settings.publicHref + 'images/';
var defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x']; 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) { const image = id => uiHref + id + '.svg';
return 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) { if (includes(defaultIcons, id)) {
var baseId = (id || '').split('-')[0]; return defaultThemeHref + id + '.svg';
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, baseId)) {
return defaultThemeHref + baseId + '.svg';
}
return { return defaultThemeHref + 'file.svg';
image: image, };
icon: icon
};
}); 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) { const config = require('../config');
return _.extend({}, config.options, {
publicHref: config.setup.PUBLIC_HREF, module.exports = Object.assign({}, config.options, {
rootHref: config.setup.ROOT_HREF publicHref: config.setup.PUBLIC_HREF,
}); rootHref: config.setup.ROOT_HREF
}); });

View File

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

View File

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

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