Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
faf1ce0bcf | ||
|
ce3ef3a195 | ||
|
ade6cf8e0b | ||
|
de92767e5a | ||
|
e67c854cb5 | ||
|
cc06b07d52 | ||
|
71ed41fa69 | ||
|
859a680e19 | ||
|
240adb79eb | ||
|
4a530f5ec0 | ||
|
eb7f3878b1 | ||
|
972be7677c | ||
|
0d22407a2d | ||
|
c173d74d06 | ||
|
eda1a3b6ac | ||
|
e4b6bace43 | ||
|
908848bfc7 | ||
|
764bc0034c | ||
|
c2e76dee24 | ||
|
81cce9e07c | ||
|
cdb9157cd1 | ||
|
f34de37913 | ||
|
3f0327ff1d | ||
|
998d3f30c6 | ||
|
0eda3f3701 | ||
|
db4bfec2dd | ||
|
a796bd606f | ||
|
1152c00018 | ||
|
194a202a0b | ||
|
fbff8686bf | ||
|
b1f6bd0d67 | ||
|
89a85c0dd2 | ||
|
18181edad9 | ||
|
db946f2812 | ||
|
833a8ed13f | ||
|
51c5eb53e7 | ||
|
3e318e43e8 | ||
|
d4c80612dc | ||
|
13693a4f3b | ||
|
1f1a6938ba | ||
|
a45725052b | ||
|
d90f7f33f7 | ||
|
f917f3b570 | ||
|
4be6e0f4c3 | ||
|
ad82ecad6f | ||
|
14db2a2db7 | ||
|
e1c7e3da59 | ||
|
6bbf0604b8 | ||
|
16d4aa3aa9 |
33
README.md
@@ -1,6 +1,6 @@
|
|||||||
# h5ai
|
# h5ai
|
||||||
|
|
||||||
Don't use files from this repository (`src` folder) for installation.
|
Please don't use files from this repository (`src` folder) for installation.
|
||||||
They need to be preprocessed/compiled to work correctly. You'll find a
|
They need to be preprocessed/compiled to work correctly. You'll find a
|
||||||
precompiled package on the [project page](http://larsjung.de/h5ai).
|
precompiled package on the [project page](http://larsjung.de/h5ai).
|
||||||
|
|
||||||
@@ -17,18 +17,47 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
|
|||||||
## h5ai profits from these great projects
|
## h5ai profits from these great projects
|
||||||
|
|
||||||
* [AmplifyJS](http://amplifyjs.com) (MIT/GPL)
|
* [AmplifyJS](http://amplifyjs.com) (MIT/GPL)
|
||||||
* [Datejs](http://www.datejs.com) (MIT)
|
|
||||||
* [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-173323228) (GPL)
|
* [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-173323228) (GPL)
|
||||||
* [HTML5 ★ Boilerplate](http://html5boilerplate.com)
|
* [HTML5 ★ Boilerplate](http://html5boilerplate.com)
|
||||||
* [jQuery](http://jquery.com) (MIT/GPL)
|
* [jQuery](http://jquery.com) (MIT/GPL)
|
||||||
|
* [jQuery.fracs](http://larsjung.de/fracs) (MIT)
|
||||||
* [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) (MIT)
|
* [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) (MIT)
|
||||||
* [modernizr](http://www.modernizr.com) (MIT/BSD)
|
* [modernizr](http://www.modernizr.com) (MIT/BSD)
|
||||||
|
* [Moment.js](http://momentjs.com) (MIT)
|
||||||
* [qrcode](http://www.d-project.com/qrcode/index.html) (MIT)
|
* [qrcode](http://www.d-project.com/qrcode/index.html) (MIT)
|
||||||
|
* [underscore.js](http://underscorejs.org) (MIT)
|
||||||
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
|
||||||
|
### v0.19 - *2012-04-??*
|
||||||
|
|
||||||
|
* adds lots of config options
|
||||||
|
* changes in `config.js` and `h5ai.htaccess`
|
||||||
|
* fixes js problems in IE 7+8
|
||||||
|
* hides broken tree view in IE < 9, adds a message to the footer
|
||||||
|
* removes hash changes since they break logical browser history
|
||||||
|
* fixes thumbnail size for portrait images in icon view
|
||||||
|
* fixes problems with file type recognition
|
||||||
|
* adds an info page at `/_h5ai`
|
||||||
|
* sort order is preserved while browsing
|
||||||
|
* removes PHP error messages on thumbnail generation
|
||||||
|
* fixes PHP some problems with packed download
|
||||||
|
* adds support for tarred downloads
|
||||||
|
* changes crumb image for folders with an index file
|
||||||
|
* adds `index.php` to use h5ai in non-Apache environments
|
||||||
|
* switches from [Datejs](http://www.datejs.com) to [Moment.js](http://momentjs.com)
|
||||||
|
* adds [underscore.js](http://underscorejs.org)
|
||||||
|
* fixes mousewheel problems, updates [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) to 3.0.6
|
||||||
|
* updates lv translation
|
||||||
|
* adds ro translation by [Jakob Cosoroabă](http://github.com/midday)
|
||||||
|
* adds ja translation by [metasta](http://github.com/metasta)
|
||||||
|
* adds nb translation by [Sindre Sorhus](http://github.com/sindresorhus)
|
||||||
|
* adds sr translation by [Goran](http://github.com/vBm)
|
||||||
|
* adds gr translation by [xhmikosr](http://github.com/xhmikosr)
|
||||||
|
|
||||||
|
|
||||||
### v0.18 - *2012-02-24*
|
### v0.18 - *2012-02-24*
|
||||||
|
|
||||||
* adds optional QRCode display
|
* adds optional QRCode display
|
||||||
|
@@ -3,7 +3,7 @@ custom = true
|
|||||||
|
|
||||||
# project
|
# project
|
||||||
project.name = h5ai
|
project.name = h5ai
|
||||||
project.version = 0.18
|
project.version = 0.19
|
||||||
|
|
||||||
|
|
||||||
# src
|
# src
|
||||||
@@ -18,4 +18,5 @@ release.dir = release
|
|||||||
# tools
|
# tools
|
||||||
tool.wepp = wepp
|
tool.wepp = wepp
|
||||||
tool.jslint = jslint
|
tool.jslint = jslint
|
||||||
|
tool.jshint = jshint
|
||||||
|
|
||||||
|
16
build.xml
@@ -54,6 +54,11 @@
|
|||||||
<jslint files="${build.dir}/_h5ai/js/inc/main.js" />
|
<jslint files="${build.dir}/_h5ai/js/inc/main.js" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="hint" depends="build-prepare">
|
||||||
|
<wepp file="${build.dir}/_h5ai/js/inc/main.js" tofile="${build.dir}/_h5ai/js/inc/main.js" />
|
||||||
|
<jshint files="${build.dir}/_h5ai/js/inc/main.js" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
|
||||||
<macrodef name="wepp-args">
|
<macrodef name="wepp-args">
|
||||||
<attribute name="args" default="" />
|
<attribute name="args" default="" />
|
||||||
@@ -77,7 +82,6 @@
|
|||||||
<attribute name="tofile" />
|
<attribute name="tofile" />
|
||||||
<sequential>
|
<sequential>
|
||||||
<wepp-args args="--inFile '@{file}' --outFile '@{toFile}'" />
|
<wepp-args args="--inFile '@{file}' --outFile '@{toFile}'" />
|
||||||
<bytes file="@{file}" toFile="@{toFile}" />
|
|
||||||
</sequential>
|
</sequential>
|
||||||
</macrodef>
|
</macrodef>
|
||||||
|
|
||||||
@@ -113,4 +117,14 @@
|
|||||||
</sequential>
|
</sequential>
|
||||||
</macrodef>
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="jshint">
|
||||||
|
<attribute name="files" />
|
||||||
|
<sequential>
|
||||||
|
<echo>JSHint @{files}</echo>
|
||||||
|
<exec executable="${tool.jshint}" failonerror="false">
|
||||||
|
<arg line="@{files}" />
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
Options -Indexes
|
Options -Indexes
|
||||||
|
|
||||||
AddType text/html .php
|
AddType text/html .php
|
||||||
@@ -9,6 +8,7 @@ AddType text/html .php
|
|||||||
# if php doesn't get interpreted try to
|
# if php doesn't get interpreted try to
|
||||||
# uncomment one of the following lines
|
# uncomment one of the following lines
|
||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
#AddHandler application/x-httpd-php .php
|
#AddHandler application/x-httpd-php .php
|
||||||
#AddHandler application/x-httpd-php5 .php
|
#AddHandler application/x-httpd-php5 .php
|
||||||
#AddHandler application/x-httpd-php52 .php
|
#AddHandler application/x-httpd-php52 .php
|
||||||
@@ -19,19 +19,19 @@ AddType text/html .php
|
|||||||
#AddHandler php53-script .php
|
#AddHandler php53-script .php
|
||||||
|
|
||||||
|
|
||||||
# cache images, css and js for 52 weeks
|
# cache images, css and js for 7 days
|
||||||
<IfModule headers_module>
|
<IfModule headers_module>
|
||||||
<FilesMatch "\.png$">
|
<FilesMatch "\.png$">
|
||||||
Header set Cache-Control "max-age=31449600, public"
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
<FilesMatch "\.css$">
|
<FilesMatch "\.css$">
|
||||||
Header set Cache-Control "max-age=31449600, public"
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
<FilesMatch "\.js$">
|
<FilesMatch "\.js$">
|
||||||
Header set Cache-Control "max-age=31449600, public"
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
<FilesMatch "thumb-.*\.jpg$">
|
<FilesMatch "thumb-.*\.jpg$">
|
||||||
Header set Cache-Control "max-age=31449600, public"
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
|
@@ -17,16 +17,17 @@ var H5AI_CONFIG = {
|
|||||||
"h5aiAbsHref": "/_h5ai/",
|
"h5aiAbsHref": "/_h5ai/",
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Filenames of customized header and footer files to look for
|
* Spacing of the main content.
|
||||||
* in each folder. For Example:
|
* Left and right will be added to a minimum of 30px. Top and bottom
|
||||||
*
|
* are calculated relative to the top and bottom bar heights.
|
||||||
* "customHeader": "_h5ai.header.html",
|
|
||||||
* "customFooter": "_h5ai.footer.html",
|
|
||||||
*
|
|
||||||
* This is disabled by default.
|
|
||||||
*/
|
*/
|
||||||
"customHeader": null,
|
"spacing": {
|
||||||
"customFooter": null,
|
"maxWidth": 960,
|
||||||
|
"top": 50,
|
||||||
|
"right": "auto",
|
||||||
|
"bottom": 50,
|
||||||
|
"left": "auto"
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An array of view modes the user may choose from. Currently there
|
* An array of view modes the user may choose from. Currently there
|
||||||
@@ -35,8 +36,111 @@ var H5AI_CONFIG = {
|
|||||||
* view mode is fixed and the selector buttons are hidden.
|
* view mode is fixed and the selector buttons are hidden.
|
||||||
* The user selected view mode is also stored local in modern browsers
|
* The user selected view mode is also stored local in modern browsers
|
||||||
* so that it will be persistent.
|
* so that it will be persistent.
|
||||||
|
*
|
||||||
|
* Set parent folder labels to real folder names.
|
||||||
*/
|
*/
|
||||||
"viewmodes": ["details", "icons"],
|
"view": {
|
||||||
|
"modes": ["details", "icons"],
|
||||||
|
"setParentFolderLabels": true
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extensions in alphabetical order.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show a clickable breadcrumb.
|
||||||
|
*/
|
||||||
|
"crumb": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Filenames of customized header and footer files to look for
|
||||||
|
* in each folder.
|
||||||
|
*/
|
||||||
|
"custom": {
|
||||||
|
"enabled": false,
|
||||||
|
"header": "_h5ai.header.html",
|
||||||
|
"footer": "_h5ai.footer.html"
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXPLICITLY: USE "shell" ON YOUR OWN RISK.
|
||||||
|
*
|
||||||
|
* Requires PHP on the server.
|
||||||
|
* Enable packaged download of selected entries.
|
||||||
|
* Execution: "php", "shell".
|
||||||
|
* Supported formats: "tar", "zip".
|
||||||
|
*/
|
||||||
|
"download": {
|
||||||
|
"enabled": false,
|
||||||
|
"execution": "shell",
|
||||||
|
"format": "zip"
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow filtering the displayed files and folders.
|
||||||
|
* Note: filters will be treated as JavaScript regular expressions
|
||||||
|
* if you prefix them with "re:".
|
||||||
|
*/
|
||||||
|
"filter": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Associative array of folders and their HTTP status codes to
|
||||||
|
* avoid HEAD requests to that folders. The key (folder) must start
|
||||||
|
* and end with a slash (/).
|
||||||
|
* For example
|
||||||
|
* "/some/folder/": 200
|
||||||
|
* will always return HTTP status 200 (OK), which will be interpreted
|
||||||
|
* as a non auto indexed folder, that means a folder containing an
|
||||||
|
* appropriate default index file.
|
||||||
|
*/
|
||||||
|
"folderstatus": {
|
||||||
|
"enabled": false,
|
||||||
|
"folders": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Localization, for example "en", "de" etc. - see "langs" below for
|
||||||
|
* possible values. Adjust it to your needs. If lang is not found in
|
||||||
|
* "langs" it defaults to "en".
|
||||||
|
*
|
||||||
|
* Optionally try to use browser language, falls back to previous
|
||||||
|
* specified language.
|
||||||
|
*/
|
||||||
|
"l10n": {
|
||||||
|
"enabled": true,
|
||||||
|
"lang": "en",
|
||||||
|
"useBrowserLang": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Link the hover effects between crumb, main view and tree.
|
||||||
|
*/
|
||||||
|
"link-hover-states": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show QRCodes on hovering files.
|
||||||
|
*/
|
||||||
|
"qrcode": {
|
||||||
|
"enabled": false,
|
||||||
|
"size": 150
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make entries selectable. At the moment only needed for packaged download.
|
||||||
|
*/
|
||||||
|
"select": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default sort order is a two letter code. The first letter specifies
|
* Default sort order is a two letter code. The first letter specifies
|
||||||
@@ -44,97 +148,58 @@ var H5AI_CONFIG = {
|
|||||||
* second letter specifies the sort order: "a" for "ascending" or "d"
|
* second letter specifies the sort order: "a" for "ascending" or "d"
|
||||||
* for "descending".
|
* for "descending".
|
||||||
*/
|
*/
|
||||||
"sortorder": "na",
|
"sort": {
|
||||||
|
"enabled": true,
|
||||||
|
"order": "na"
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show a folder tree, boolean.
|
* Show additional info in a statusbar.
|
||||||
|
*/
|
||||||
|
"statusbar": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Requires PHP on the server.
|
||||||
|
* Show thumbnails for image files. Needs the "/_h5ai/cache" folder to be
|
||||||
|
* writable for the Apache Server.
|
||||||
|
*/
|
||||||
|
"thumbnails": {
|
||||||
|
"enabled": true,
|
||||||
|
"types": ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
||||||
|
"delay": 1000
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace window title with current breadcrumb.
|
||||||
|
*/
|
||||||
|
"title": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show a folder tree.
|
||||||
* Note that this tree might have side effects as it sends HEAD requests
|
* Note that this tree might have side effects as it sends HEAD requests
|
||||||
* to the folders, and therefore will invoke index.php scripts. Use
|
* to the folders, and therefore will invoke index.php scripts. Use
|
||||||
* folderStatus below to avoid such requests.
|
* "folderstatus" above to avoid such requests.
|
||||||
* It might also affect performance significantly.
|
* It might also affect performance significantly.
|
||||||
|
*
|
||||||
|
* Slide tree bar into viewport if there is enough space.
|
||||||
*/
|
*/
|
||||||
"showTree": true,
|
"tree": {
|
||||||
|
"enabled": true,
|
||||||
/*
|
"slide": true
|
||||||
* Slide tree bar into viewport if there is enough space, boolean.
|
}
|
||||||
*/
|
|
||||||
"slideTree": true,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Associative array of folders and their HTTP status codes to
|
|
||||||
* avoid HEAD requests to that folders. The key (folder) must start
|
|
||||||
* and end with a slash (/).
|
|
||||||
* For example:
|
|
||||||
* "/some/folder/": 200
|
|
||||||
* will always return HTTP status 200 (OK), which will be interpreted
|
|
||||||
* as a non auto indexed folder, that means a folder containing an
|
|
||||||
* appropriate default index file.
|
|
||||||
*/
|
|
||||||
"folderStatus": {},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Localization, for example "en", "de" etc. - see h5aiLangs below for
|
|
||||||
* possible values. Adjust it to your needs. If lang is not found in
|
|
||||||
* h5aiLangs it defaults to "en".
|
|
||||||
*/
|
|
||||||
"lang": "en",
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to use browser language, falls back to previous specified lang.
|
|
||||||
*/
|
|
||||||
"useBrowserLang": true,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set parent folder labels to real folder names.
|
|
||||||
*/
|
|
||||||
"setParentFolderLabels": true,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Link the hover effects between crumb, extended view and tree.
|
|
||||||
*/
|
|
||||||
"linkHoverStates": true,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Date format in detailed view, for example: "yyyy-MM-dd HH:mm:ss"
|
|
||||||
* Syntax as specified by date.js
|
|
||||||
* http://code.google.com/p/datejs/wiki/FormatSpecifiers
|
|
||||||
*/
|
|
||||||
"dateFormat": "yyyy-MM-dd HH:mm",
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Requires PHP on the server.
|
|
||||||
* Show thumbnails for image files.
|
|
||||||
*/
|
|
||||||
"showThumbs": true,
|
|
||||||
"thumbTypes": ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Requires PHP on the server.
|
|
||||||
* Enable zipped download of selected entries.
|
|
||||||
*/
|
|
||||||
"zippedDownload": false,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show QRCodes on hovering files.
|
|
||||||
* Set this to the desired size in pixel or null to not display QRCodes.
|
|
||||||
* A good size to start with might be 150.
|
|
||||||
*/
|
|
||||||
"qrCodesSize": null,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allow filtering the displayed files and folders.
|
|
||||||
* Filters are ment to be JavaScript regular expressions.
|
|
||||||
*/
|
|
||||||
"showFilter": false
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File types mapped to file extensions.
|
* File types mapped to file extensions. In alphabetical order.
|
||||||
*/
|
*/
|
||||||
"types": {
|
"types": {
|
||||||
"archive": [".tar.bz2", ".tar.gz", ".tgz"],
|
"archive": [".tar.bz2", ".tar.gz", ".tgz"],
|
||||||
"audio": [".aif", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
|
"audio": [".aif", ".flac", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
|
||||||
"authors": ["authors"],
|
"authors": ["authors"],
|
||||||
"bin": [".class", ".o", ".so"],
|
"bin": [".class", ".o", ".so"],
|
||||||
"blank": [],
|
"blank": [],
|
||||||
@@ -150,7 +215,7 @@ var H5AI_CONFIG = {
|
|||||||
"doc": [".doc", ".docx", ".odm", ".odt", ".ott"],
|
"doc": [".doc", ".docx", ".odm", ".odt", ".ott"],
|
||||||
"draw": [".drw"],
|
"draw": [".drw"],
|
||||||
"eps": [".eps"],
|
"eps": [".eps"],
|
||||||
"exe": [".exe"],
|
"exe": [".bat", ".cmd", ".exe"],
|
||||||
"folder": [],
|
"folder": [],
|
||||||
"folder-home": [],
|
"folder-home": [],
|
||||||
"folder-open": [],
|
"folder-open": [],
|
||||||
@@ -172,7 +237,7 @@ var H5AI_CONFIG = {
|
|||||||
"package": [],
|
"package": [],
|
||||||
"pdf": [".pdf"],
|
"pdf": [".pdf"],
|
||||||
"php": [".php"],
|
"php": [".php"],
|
||||||
"playlist": [".m3u"],
|
"playlist": [".m3u", ".m3u8", ".pls"],
|
||||||
"png": [".png"],
|
"png": [".png"],
|
||||||
"pres": [".odp", ".otp", ".pps", ".ppt", ".pptx"],
|
"pres": [".odp", ".otp", ".pps", ".ppt", ".pptx"],
|
||||||
"psd": [".psd"],
|
"psd": [".psd"],
|
||||||
@@ -188,18 +253,21 @@ var H5AI_CONFIG = {
|
|||||||
"sql": [],
|
"sql": [],
|
||||||
"tar": [".tar"],
|
"tar": [".tar"],
|
||||||
"tex": [".tex"],
|
"tex": [".tex"],
|
||||||
"text": [".markdown", ".md", ".text", ".txt"],
|
"text": [".diff", ".markdown", ".md", ".patch", ".text", ".txt"],
|
||||||
"tiff": [".tiff"],
|
"tiff": [".tiff"],
|
||||||
"unknown": [],
|
"unknown": [],
|
||||||
"vcal": [".vcal"],
|
"vcal": [".vcal"],
|
||||||
"video": [".avi", ".flv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"],
|
"video": [".avi", ".flv", ".mkv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"],
|
||||||
"xml": [".xml"],
|
"xml": [".xml"],
|
||||||
"zip": [".bz2", ".jar", ".war", ".z", ".Z", ".zip"]
|
"zip": [".7z", ".bz2", ".jar", ".lzma", ".war", ".z", ".Z", ".zip"]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Available translations.
|
* Available translations. "en" in first place as a reference, otherwise in alphabetical order.
|
||||||
|
*
|
||||||
|
* Date format is used in detailed view, for example: "YYYY-MM-DD HH:mm:ss"
|
||||||
|
* Syntax as specified by Moment.js (http://momentjs.com)
|
||||||
*/
|
*/
|
||||||
"langs": {
|
"langs": {
|
||||||
|
|
||||||
@@ -215,7 +283,8 @@ var H5AI_CONFIG = {
|
|||||||
"folders": "folders",
|
"folders": "folders",
|
||||||
"files": "files",
|
"files": "files",
|
||||||
"download": "download",
|
"download": "download",
|
||||||
"noMatch": "no match"
|
"noMatch": "no match",
|
||||||
|
"dateFormat": "YYYY-MM-DD HH:mm"
|
||||||
},
|
},
|
||||||
|
|
||||||
"bg": {
|
"bg": {
|
||||||
@@ -228,9 +297,7 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Предходна директория",
|
"parentDirectory": "Предходна директория",
|
||||||
"empty": "празно",
|
"empty": "празно",
|
||||||
"folders": "папки",
|
"folders": "папки",
|
||||||
"files": "файлове",
|
"files": "файлове"
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"cs": {
|
"cs": {
|
||||||
@@ -243,9 +310,7 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Nadřazený adresář",
|
"parentDirectory": "Nadřazený adresář",
|
||||||
"empty": "prázdný",
|
"empty": "prázdný",
|
||||||
"folders": "složek",
|
"folders": "složek",
|
||||||
"files": "souborů",
|
"files": "souborů"
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"de": {
|
"de": {
|
||||||
@@ -260,7 +325,8 @@ var H5AI_CONFIG = {
|
|||||||
"folders": "Ordner",
|
"folders": "Ordner",
|
||||||
"files": "Dateien",
|
"files": "Dateien",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"noMatch": "keine Treffer"
|
"noMatch": "keine Treffer",
|
||||||
|
"dateFormat": "DD.MM.YYYY HH:mm"
|
||||||
},
|
},
|
||||||
|
|
||||||
"es": {
|
"es": {
|
||||||
@@ -274,8 +340,7 @@ var H5AI_CONFIG = {
|
|||||||
"empty": "vacío",
|
"empty": "vacío",
|
||||||
"folders": "Directorios",
|
"folders": "Directorios",
|
||||||
"files": "Archivos",
|
"files": "Archivos",
|
||||||
"download": "Descargar",
|
"download": "Descargar"
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"fr": {
|
"fr": {
|
||||||
@@ -290,7 +355,22 @@ var H5AI_CONFIG = {
|
|||||||
"folders": "Répertoires",
|
"folders": "Répertoires",
|
||||||
"files": "Fichiers",
|
"files": "Fichiers",
|
||||||
"download": "télécharger",
|
"download": "télécharger",
|
||||||
"noMatch": "no match"
|
"noMatch": "rien trouvé"
|
||||||
|
},
|
||||||
|
|
||||||
|
"gr": {
|
||||||
|
"lang": "ελληνικά",
|
||||||
|
"details": "Λεπτομέρειες",
|
||||||
|
"icons": "Εικονίδια",
|
||||||
|
"name": "Όνομα",
|
||||||
|
"lastModified": "Τελευταία Τροποποίηση",
|
||||||
|
"size": "Μέγεθος",
|
||||||
|
"parentDirectory": "Προηγούμενος Κατάλογος",
|
||||||
|
"empty": "κενό",
|
||||||
|
"folders": "Φάκελοι",
|
||||||
|
"files": "Αρχεία",
|
||||||
|
"download": "Μεταμόρφωση",
|
||||||
|
"noMatch": "Κανένα Ταίριασμα"
|
||||||
},
|
},
|
||||||
|
|
||||||
"it": {
|
"it": {
|
||||||
@@ -303,9 +383,22 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Cartella Superiore",
|
"parentDirectory": "Cartella Superiore",
|
||||||
"empty": "vuota",
|
"empty": "vuota",
|
||||||
"folders": "cartelle",
|
"folders": "cartelle",
|
||||||
"files": "file",
|
"files": "file"
|
||||||
"download": "download",
|
},
|
||||||
"noMatch": "no match"
|
|
||||||
|
"ja": {
|
||||||
|
"lang": "日本語",
|
||||||
|
"details": "詳細",
|
||||||
|
"icons": "アイコン",
|
||||||
|
"name": "名前",
|
||||||
|
"lastModified": "変更日",
|
||||||
|
"size": "サイズ",
|
||||||
|
"parentDirectory": "親フォルダ",
|
||||||
|
"empty": "項目なし",
|
||||||
|
"folders": "フォルダ",
|
||||||
|
"files": "ファイル",
|
||||||
|
"download": "ダウンロード",
|
||||||
|
"noMatch": "一致なし"
|
||||||
},
|
},
|
||||||
|
|
||||||
"lv": {
|
"lv": {
|
||||||
@@ -320,7 +413,22 @@ var H5AI_CONFIG = {
|
|||||||
"folders": "mapes",
|
"folders": "mapes",
|
||||||
"files": "faili",
|
"files": "faili",
|
||||||
"download": "lejupielādēt",
|
"download": "lejupielādēt",
|
||||||
"noMatch": "no match"
|
"noMatch": "nav sakritības"
|
||||||
|
},
|
||||||
|
|
||||||
|
"nb": {
|
||||||
|
"lang": "norwegian",
|
||||||
|
"details": "detaljer",
|
||||||
|
"icons": "ikoner",
|
||||||
|
"name": "Navn",
|
||||||
|
"lastModified": "Sist endret",
|
||||||
|
"size": "Størrelse",
|
||||||
|
"parentDirectory": "Overordnet mappe",
|
||||||
|
"empty": "tom",
|
||||||
|
"folders": "mapper",
|
||||||
|
"files": "filer",
|
||||||
|
"download": "last ned",
|
||||||
|
"noMatch": "ingen treff"
|
||||||
},
|
},
|
||||||
|
|
||||||
"nl": {
|
"nl": {
|
||||||
@@ -331,11 +439,7 @@ var H5AI_CONFIG = {
|
|||||||
"lastModified": "Laatste wijziging",
|
"lastModified": "Laatste wijziging",
|
||||||
"size": "Grootte",
|
"size": "Grootte",
|
||||||
"parentDirectory": "Bovenliggende map",
|
"parentDirectory": "Bovenliggende map",
|
||||||
"empty": "lege",
|
"empty": "lege"
|
||||||
"folders": "folders",
|
|
||||||
"files": "files",
|
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"pl": {
|
"pl": {
|
||||||
@@ -348,9 +452,7 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Katalog nadrzędny",
|
"parentDirectory": "Katalog nadrzędny",
|
||||||
"empty": "pusty",
|
"empty": "pusty",
|
||||||
"folders": "foldery",
|
"folders": "foldery",
|
||||||
"files": "pliki",
|
"files": "pliki"
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"pt": {
|
"pt": {
|
||||||
@@ -363,9 +465,22 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Diretório superior",
|
"parentDirectory": "Diretório superior",
|
||||||
"empty": "vazio",
|
"empty": "vazio",
|
||||||
"folders": "pastas",
|
"folders": "pastas",
|
||||||
"files": "arquivos",
|
"files": "arquivos"
|
||||||
"download": "download",
|
},
|
||||||
"noMatch": "no match"
|
|
||||||
|
"ro": {
|
||||||
|
"lang": "română",
|
||||||
|
"details": "detalii",
|
||||||
|
"icons": "pictograme",
|
||||||
|
"name": "nume",
|
||||||
|
"lastModified": "ultima modificare",
|
||||||
|
"size": "mărime",
|
||||||
|
"parentDirectory": "dosar părinte",
|
||||||
|
"empty": "gol",
|
||||||
|
"folders": "dosar",
|
||||||
|
"files": "fişiere",
|
||||||
|
"download": "descarcă",
|
||||||
|
"noMatch": "0 rezultate"
|
||||||
},
|
},
|
||||||
|
|
||||||
"ru": {
|
"ru": {
|
||||||
@@ -378,9 +493,7 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Главная директория",
|
"parentDirectory": "Главная директория",
|
||||||
"empty": "пусто",
|
"empty": "пусто",
|
||||||
"folders": "папки",
|
"folders": "папки",
|
||||||
"files": "файлы",
|
"files": "файлы"
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"sk": {
|
"sk": {
|
||||||
@@ -393,9 +506,22 @@ var H5AI_CONFIG = {
|
|||||||
"parentDirectory": "Nadriadený priečinok",
|
"parentDirectory": "Nadriadený priečinok",
|
||||||
"empty": "prázdny",
|
"empty": "prázdny",
|
||||||
"folders": "priečinkov",
|
"folders": "priečinkov",
|
||||||
"files": "súborov",
|
"files": "súborov"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sr": {
|
||||||
|
"lang": "srpski",
|
||||||
|
"details": "detalji",
|
||||||
|
"icons": "ikone",
|
||||||
|
"name": "Ime",
|
||||||
|
"lastModified": "Poslednja modifikacija",
|
||||||
|
"size": "Veličina",
|
||||||
|
"parentDirectory": "Roditeljski direktorijum",
|
||||||
|
"empty": "prazno",
|
||||||
|
"folders": "direktorijum",
|
||||||
|
"files": "fajlovi",
|
||||||
"download": "download",
|
"download": "download",
|
||||||
"noMatch": "no match"
|
"noMatch": "bez poklapanja"
|
||||||
},
|
},
|
||||||
|
|
||||||
"sv": {
|
"sv": {
|
||||||
@@ -406,11 +532,7 @@ var H5AI_CONFIG = {
|
|||||||
"lastModified": "Senast ändrad",
|
"lastModified": "Senast ändrad",
|
||||||
"size": "Filstorlek",
|
"size": "Filstorlek",
|
||||||
"parentDirectory": "Till överordnad mapp",
|
"parentDirectory": "Till överordnad mapp",
|
||||||
"empty": "tom",
|
"empty": "tom"
|
||||||
"folders": "folders",
|
|
||||||
"files": "files",
|
|
||||||
"download": "download",
|
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"tr": {
|
"tr": {
|
||||||
@@ -424,8 +546,7 @@ var H5AI_CONFIG = {
|
|||||||
"empty": "boş",
|
"empty": "boş",
|
||||||
"folders": "klasörler",
|
"folders": "klasörler",
|
||||||
"files": "dosyalar",
|
"files": "dosyalar",
|
||||||
"download": "indir",
|
"download": "indir"
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"zh-cn": {
|
"zh-cn": {
|
||||||
@@ -439,8 +560,7 @@ var H5AI_CONFIG = {
|
|||||||
"empty": "空文件夹",
|
"empty": "空文件夹",
|
||||||
"folders": "文件夹",
|
"folders": "文件夹",
|
||||||
"files": "文件",
|
"files": "文件",
|
||||||
"download": "下载",
|
"download": "下载"
|
||||||
"noMatch": "no match"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"zh-tw": {
|
"zh-tw": {
|
||||||
@@ -454,8 +574,7 @@ var H5AI_CONFIG = {
|
|||||||
"empty": "空資料夾",
|
"empty": "空資料夾",
|
||||||
"folders": "資料夾",
|
"folders": "資料夾",
|
||||||
"files": "檔案",
|
"files": "檔案",
|
||||||
"download": "下載",
|
"download": "下載"
|
||||||
"noMatch": "no match"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -14,7 +14,7 @@ $H5AI_CONFIG = array(
|
|||||||
* This configuration assumes that h5ai is installed
|
* This configuration assumes that h5ai is installed
|
||||||
* in the webroot directory of the Apache server.
|
* in the webroot directory of the Apache server.
|
||||||
*/
|
*/
|
||||||
"ROOT_ABS_PATH" => safe_dirname(safe_dirname(__FILE__)),
|
"ROOT_ABS_PATH" => dirname(dirname(__FILE__)),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Files/folders that should not be listed. Specified
|
* Files/folders that should not be listed. Specified
|
||||||
|
@@ -1,33 +1,32 @@
|
|||||||
|
|
||||||
#table {
|
#data-apache-autoindex {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
table {
|
table {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
|
||||||
th, td {
|
th, td {
|
||||||
padding: 3px 6px;
|
padding: 6px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
padding-bottom: 18px;
|
padding-bottom: 18px;
|
||||||
opacity: 0.4;
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
|
|
||||||
&:hover, &:hover a {
|
|
||||||
color: #555;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
a, a:visited {
|
a, a:visited {
|
||||||
color: #555;
|
color: #555;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.4;
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
|
||||||
img {
|
&:hover {
|
||||||
width: 12px;
|
color: #555;
|
||||||
height: 12px;
|
opacity: 0.9;
|
||||||
padding: 0 8px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +34,20 @@
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
a, a:active, a:visited {
|
||||||
|
display: block;
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e80;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
td:nth-child(1), th:nth-child(1) {
|
td:nth-child(1), th:nth-child(1) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -43,26 +56,23 @@
|
|||||||
img {
|
img {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
padding-top: 2px;
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
td:nth-child(2), th:nth-child(2) {
|
td:nth-child(2), th:nth-child(2) {
|
||||||
width: 682px;
|
width: 682px;
|
||||||
max-width: 682px;
|
max-width: 682px;
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
td:nth-child(3), th:nth-child(3) {
|
td:nth-child(3), th:nth-child(3) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 160px;
|
width: 160px;
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
td:nth-child(4), th:nth-child(4) {
|
td:nth-child(4), th:nth-child(4) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 70px;
|
width: 70px;
|
||||||
min-width: 70px;
|
min-width: 70px;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
67
src/_h5ai/css/inc/bottombar.less
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
#bottombar {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 6px 0 8px 0;
|
||||||
|
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
||||||
|
border-top: 1px solid rgb(210,210,210);
|
||||||
|
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
a, a:active, a:visited {
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e80;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
display: block;
|
||||||
|
padding: 0 8px;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin: 0 100px;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
display: block;
|
||||||
|
padding: 0 8px;
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
.noJsMsg {
|
||||||
|
color: #c33;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
.oldBrowser {
|
||||||
|
display: none;
|
||||||
|
color: #c33;
|
||||||
|
margin-left: 16px;
|
||||||
|
a, a:active, a:visited {
|
||||||
|
color: #c33;
|
||||||
|
text-decoration: underline;
|
||||||
|
&:hover {
|
||||||
|
color: #e80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
.sep {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
&.default {
|
||||||
|
}
|
||||||
|
&.dynamic {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,18 +1,31 @@
|
|||||||
|
|
||||||
#content {
|
#content {
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
margin: 0 auto;
|
margin: 50px auto;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
> header {
|
|
||||||
display: none;
|
#content-header, #content-footer {
|
||||||
padding-bottom: 10px;
|
|
||||||
margin-bottom: 80px;
|
a, a:active, a:visited {
|
||||||
border-bottom: 2px dashed #ddd;
|
color: #2080FF;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #68A9FF;
|
||||||
}
|
}
|
||||||
> footer {
|
|
||||||
display: none;
|
|
||||||
padding-top: 10px;
|
|
||||||
margin-top: 80px;
|
|
||||||
border-top: 2px dashed #ddd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#content-header {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content-footer {
|
||||||
|
padding-top: 12px;
|
||||||
|
margin-top: 32px;
|
||||||
|
}
|
||||||
|
30
src/_h5ai/css/inc/download.less
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
#download {
|
||||||
|
display: none;
|
||||||
|
.topbar-right;
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
|
||||||
|
&.failed {
|
||||||
|
background-color: rgba(255,0,0,0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-auth {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
||||||
|
border: 1px solid rgb(210,210,210);
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
margin: 4px 6px;
|
||||||
|
border: 1px solid rgb(210,210,210);
|
||||||
|
font-family: Ubuntu, sans-serif;
|
||||||
|
color: #555;
|
||||||
|
background-color: rgba(255,255,255,1);
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
}
|
@@ -13,6 +13,8 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
|
|
||||||
&.header {
|
&.header {
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
a, a:active, a:visited {
|
a, a:active, a:visited {
|
||||||
padding-bottom: 18px;
|
padding-bottom: 18px;
|
||||||
color: #555;
|
color: #555;
|
||||||
@@ -42,7 +44,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.entry {
|
&.entry {
|
||||||
|
|
||||||
a, a:active, a:visited {
|
a, a:active, a:visited {
|
||||||
display: block;
|
display: block;
|
||||||
color: #555;
|
color: #555;
|
||||||
@@ -54,11 +55,11 @@
|
|||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
color: #e80;
|
color: #e80;
|
||||||
}
|
}
|
||||||
&.selected:not(.selecting), &.selecting:not(.selected) {
|
}
|
||||||
|
&.selected:not(.selecting) a, &.selecting:not(.selected) a {
|
||||||
border-color: rgba(240,100,0,0.2);
|
border-color: rgba(240,100,0,0.2);
|
||||||
background-color: rgba(240,100,0,0.2);
|
background-color: rgba(240,100,0,0.2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
&.error {
|
&.error {
|
||||||
a, a:active, a:visited {
|
a, a:active, a:visited {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
@@ -102,7 +103,7 @@
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
&.thumb {
|
&.thumb {
|
||||||
border: 1px solid #eee;
|
// border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,18 +133,6 @@
|
|||||||
width: 80px;
|
width: 80px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
&.entry.thumb .icon.small {
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 5px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
background-color: #eee;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.empty, .no-match {
|
.empty, .no-match {
|
||||||
@@ -206,19 +195,15 @@
|
|||||||
border-color: #eee;
|
border-color: #eee;
|
||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
}
|
}
|
||||||
&.selected:not(.selecting), &.selecting:not(.selected) {
|
|
||||||
border-color: rgba(240,100,0,0.2);
|
|
||||||
background-color: rgba(240,100,0,0.2);
|
|
||||||
}
|
|
||||||
.icon {
|
.icon {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
min-width: 48px;
|
max-width: 100px;
|
||||||
min-height: 48px;
|
height: 48px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
&.thumb {
|
&.thumb {
|
||||||
border: 1px solid #eee;
|
// border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,6 +218,10 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.selected:not(.selecting) a, &.selecting:not(.selected) a {
|
||||||
|
border-color: rgba(240,100,0,0.2);
|
||||||
|
background-color: rgba(240,100,0,0.2);
|
||||||
|
}
|
||||||
&.error {
|
&.error {
|
||||||
a, a:active, a:visited {
|
a, a:active, a:visited {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
@@ -253,21 +242,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.entry.thumb .icon.big {
|
|
||||||
width: 100px;
|
|
||||||
height: 58px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
img {
|
|
||||||
background-color: #eee;
|
|
||||||
min-width: 46px;
|
|
||||||
min-height: 46px;
|
|
||||||
min-width: 12px;
|
|
||||||
min-height: 12px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.empty, .no-match {
|
.empty, .no-match {
|
||||||
|
19
src/_h5ai/css/inc/filter.less
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#filter {
|
||||||
|
.topbar-right;
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
border: none;
|
||||||
|
font-family: Ubuntu, sans-serif;
|
||||||
|
color: #555;
|
||||||
|
background-color: rgba(0,0,0,0);
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
input {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,108 +0,0 @@
|
|||||||
|
|
||||||
body > footer {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 5;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
padding: 6px 0 8px 0;
|
|
||||||
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
|
||||||
border-top: 1px solid rgb(210,210,210);
|
|
||||||
|
|
||||||
color: #999;
|
|
||||||
font-size: 0.85em;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
a, a:active, a:visited {
|
|
||||||
color: #555;
|
|
||||||
text-decoration: none;
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
opacity: 0.7;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #e80;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.left {
|
|
||||||
display: block;
|
|
||||||
padding: 0 8px;
|
|
||||||
float: left
|
|
||||||
}
|
|
||||||
.center {
|
|
||||||
display: block;
|
|
||||||
margin: 0 100px;
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
display: block;
|
|
||||||
padding: 0 8px;
|
|
||||||
float: right
|
|
||||||
}
|
|
||||||
.noJsMsg {
|
|
||||||
color: #c33;
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
|
||||||
.status {
|
|
||||||
.sep {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 6px;
|
|
||||||
}
|
|
||||||
&.default {
|
|
||||||
}
|
|
||||||
&.dynamic {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#langSelector {
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.langOptions {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
overflow: auto;
|
|
||||||
display: none;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
max-height: 200px;
|
|
||||||
background-color: rgb(241,241,241);
|
|
||||||
border: 1px solid rgb(210,210,210);
|
|
||||||
|
|
||||||
> .scrollbar {
|
|
||||||
margin: 0;
|
|
||||||
width: 6px;
|
|
||||||
background-color: rgb(210,210,210);
|
|
||||||
|
|
||||||
.drag {
|
|
||||||
background-color: rgb(180,180,180);
|
|
||||||
}
|
|
||||||
&.dragOn .drag {
|
|
||||||
background-color: rgb(150,150,150);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
li {
|
|
||||||
padding: 8px 24px 10px 24px;
|
|
||||||
white-space: nowrap;
|
|
||||||
border-top: 1px solid rgb(231,231,231);
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
color: #333;
|
|
||||||
background-color: rgba(255,255,255,0.8);
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
color: #e80;
|
|
||||||
background-color: rgba(255,255,255,0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
63
src/_h5ai/css/inc/h5ai-info.less
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
body#h5ai-info {
|
||||||
|
font-family: Ubuntu, Arial, sans;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #555;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.h5ai {
|
||||||
|
font-family: 'Miltonian Tattoo';
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3.6em;
|
||||||
|
margin: 0.9em 0 0 0;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 1.15em;
|
||||||
|
margin: 2.6em 0 0 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
p + p {
|
||||||
|
margin-top: 1.2em;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin-top: 0.6em;
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tests {
|
||||||
|
display: inline-block;
|
||||||
|
list-style-type: none;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.test-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
.test-result {
|
||||||
|
display: inline-block;
|
||||||
|
width: 70px;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #aaa;
|
||||||
|
|
||||||
|
&.test-passed {
|
||||||
|
color: #5a5;
|
||||||
|
}
|
||||||
|
&.test-failed {
|
||||||
|
color: #a55;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#bottombar {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
53
src/_h5ai/css/inc/l10n.less
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
#langSelector {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.langOptions {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
overflow: auto;
|
||||||
|
display: none;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
max-height: 200px;
|
||||||
|
background-color: rgb(241,241,241);
|
||||||
|
border: 1px solid rgb(210,210,210);
|
||||||
|
|
||||||
|
> .scrollbar {
|
||||||
|
margin: 0;
|
||||||
|
width: 6px;
|
||||||
|
background-color: rgb(210,210,210);
|
||||||
|
|
||||||
|
.drag {
|
||||||
|
background-color: rgb(180,180,180);
|
||||||
|
}
|
||||||
|
&.dragOn .drag {
|
||||||
|
background-color: rgb(150,150,150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 8px 24px 10px 24px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-top: 1px solid rgb(231,231,231);
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
color: #333;
|
||||||
|
background-color: rgba(255,255,255,0.8);
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
color: #e80;
|
||||||
|
background-color: rgba(255,255,255,0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
.border-radius (@radius) {
|
.border-radius (@radius) {
|
||||||
-webkit-border-radius: @radius; /* Saf3-4, iOS 1-3.2, Android <1.6 */
|
-webkit-border-radius: @radius; /* Saf3-4, iOS 1-3.2, Android <1.6 */
|
||||||
-moz-border-radius: @radius; /* FF1-3.6 */
|
-moz-border-radius: @radius; /* FF1-3.6 */
|
||||||
@@ -56,4 +55,3 @@
|
|||||||
-moz-background-size: @size; /* FF3.6 */
|
-moz-background-size: @size; /* FF3.6 */
|
||||||
background-size: @size; /* Opera, IE9, Saf5, Chrome, FF4 */
|
background-size: @size; /* Opera, IE9, Saf5, Chrome, FF4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,135 +0,0 @@
|
|||||||
|
|
||||||
.nav-highlight {
|
|
||||||
background-color: rgba(255,255,255,0.5);
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-hover {
|
|
||||||
.nav-highlight;
|
|
||||||
color: #e80;
|
|
||||||
}
|
|
||||||
|
|
||||||
@nav-sep-border: 1px solid rgba(0,0,0,0.05);
|
|
||||||
|
|
||||||
.nav-left {
|
|
||||||
float: left;
|
|
||||||
border-right: @nav-sep-border;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-right {
|
|
||||||
float: right;
|
|
||||||
border-left: @nav-sep-border;
|
|
||||||
}
|
|
||||||
|
|
||||||
body > nav {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 5;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
font-size: 0.85em;
|
|
||||||
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
|
||||||
border-bottom: 1px solid rgb(210,210,210);
|
|
||||||
|
|
||||||
span.jsDisabledFallback {
|
|
||||||
display: block;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
padding: 0 10px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
a, a:active, a:visited, span.element {
|
|
||||||
color: #555;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
opacity: 0.7;
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
padding: 0 10px;
|
|
||||||
|
|
||||||
&:hover, &.hover {
|
|
||||||
.nav-hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.current {
|
|
||||||
a, span.element {
|
|
||||||
.nav-highlight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
position: relative;
|
|
||||||
top: -2px;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
img + span, img + input {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
.crumb {
|
|
||||||
.nav-left;
|
|
||||||
.hint {
|
|
||||||
margin-left: 8px;
|
|
||||||
font-style: italic;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
img.hint {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.view {
|
|
||||||
.nav-right;
|
|
||||||
}
|
|
||||||
#download {
|
|
||||||
display: none;
|
|
||||||
.nav-right;
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
|
|
||||||
&.failed {
|
|
||||||
background-color: rgba(255,0,0,0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#filter {
|
|
||||||
.nav-right;
|
|
||||||
|
|
||||||
input {
|
|
||||||
display: none;
|
|
||||||
border: none;
|
|
||||||
font-family: Ubuntu, sans-serif;
|
|
||||||
color: #555;
|
|
||||||
background-color: rgba(0,0,0,0);
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
input {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#download-auth {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 5;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
font-size: 0.85em;
|
|
||||||
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
|
||||||
border: 1px solid rgb(210,210,210);
|
|
||||||
|
|
||||||
input {
|
|
||||||
display: block;
|
|
||||||
margin: 4px 6px;
|
|
||||||
border: 1px solid rgb(210,210,210);
|
|
||||||
font-family: Ubuntu, sans-serif;
|
|
||||||
color: #555;
|
|
||||||
background-color: rgba(255,255,255,1);
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
@media only screen and (max-width: 500px) {
|
||||||
body > nav {
|
#topbar {
|
||||||
.view span {
|
.view span {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -12,7 +13,7 @@ body > nav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 350px) {
|
@media only screen and (max-width: 350px) {
|
||||||
body > nav {
|
#topbar {
|
||||||
.crumb {
|
.crumb {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -28,9 +29,29 @@ body > nav {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body > footer {
|
#bottombar {
|
||||||
.center {
|
.center {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
a[href]:after {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
#topbar {
|
||||||
|
position: static;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
.view, #download {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#bottombar {
|
||||||
|
position: static;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
#tree {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
88
src/_h5ai/css/inc/topbar.less
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
#topbar {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
||||||
|
border-bottom: 1px solid rgb(210,210,210);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.topbar-highlight {
|
||||||
|
background-color: rgba(255,255,255,0.5);
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-hover {
|
||||||
|
.topbar-highlight;
|
||||||
|
color: #e80;
|
||||||
|
}
|
||||||
|
|
||||||
|
@topbar-sep-border: 1px solid rgba(0,0,0,0.05);
|
||||||
|
|
||||||
|
.topbar-left {
|
||||||
|
float: left;
|
||||||
|
border-right: @topbar-sep-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-right {
|
||||||
|
float: right;
|
||||||
|
border-left: @topbar-sep-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#navbar {
|
||||||
|
list-style: none;
|
||||||
|
list-style-image: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
a, a:active, a:visited, span.element {
|
||||||
|
color: #555;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
opacity: 0.7;
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
&:hover, &.hover {
|
||||||
|
.topbar-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.current {
|
||||||
|
a, span.element {
|
||||||
|
.topbar-highlight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
img + span, img + input {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.crumb {
|
||||||
|
.topbar-left;
|
||||||
|
.hint {
|
||||||
|
margin-left: 8px;
|
||||||
|
font-style: italic;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
img.hint {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.view {
|
||||||
|
.topbar-right;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 0.85em;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background-color: rgb(241,241,241);
|
background-color: rgb(241,241,241);
|
||||||
border-right: 2px solid rgb(221,221,221);
|
border-right: 2px solid rgb(221,221,221);
|
||||||
@@ -28,20 +27,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
.blank, .indicator {
|
.indicator {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
|
||||||
.indicator {
|
|
||||||
opacity: 0.7;
|
|
||||||
.transition(all 0.2s ease-in-out);
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
img {
|
img {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -52,13 +43,23 @@
|
|||||||
.transition(all 0.2s ease-in-out);
|
.transition(all 0.2s ease-in-out);
|
||||||
}
|
}
|
||||||
&.open {
|
&.open {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.7;
|
||||||
img {
|
img {
|
||||||
.transform(rotate(90deg));
|
.transform(rotate(90deg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.close {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
&.unknown {
|
&.unknown {
|
||||||
|
cursor: pointer;
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
|
&.none {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
> a, > a:active, > a.visited {
|
> a, > a:active, > a.visited {
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
@@ -92,16 +93,8 @@
|
|||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
img {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
&.file {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.current {
|
&.current {
|
||||||
> a, > a:active, > a:visited {
|
> a, > a:active, > a:visited {
|
||||||
border: 1px solid rgb(221,221,221);
|
border: 1px solid rgb(221,221,221);
|
||||||
|
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
@import "inc/h5bp-norm";
|
|
||||||
@import "inc/mixins";
|
|
||||||
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: Ubuntu, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #555;
|
|
||||||
background-color: #fff;
|
|
||||||
margin: 80px 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@import "inc/nav";
|
|
||||||
@import "inc/content";
|
|
||||||
@import "inc/table";
|
|
||||||
@import "inc/extended";
|
|
||||||
@import "inc/tree";
|
|
||||||
@import "inc/context";
|
|
||||||
@import "inc/footer";
|
|
||||||
@import "inc/responsive";
|
|
||||||
|
|
||||||
|
|
||||||
html.js {
|
|
||||||
.hideOnJs {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html.no-js {
|
|
||||||
.hideOnNoJs {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html.h5ai-js {
|
|
||||||
#h5ai-reference:after {
|
|
||||||
content: " (js)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html.h5ai-php {
|
|
||||||
#h5ai-reference:after {
|
|
||||||
content: " (php)";
|
|
||||||
}
|
|
||||||
|
|
||||||
#table {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tree, #content > header, #content > footer {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.no-js {
|
|
||||||
#extended.details-view, #extended.icons-view {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
47
src/_h5ai/css/styles.less
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
@import "inc/h5bp-norm";
|
||||||
|
@import "inc/mixins";
|
||||||
|
|
||||||
|
::-moz-selection { background: #68A9FF; color: #fff; text-shadow: none; }
|
||||||
|
::selection { background: #68A9FF; color: #fff; text-shadow: none; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Ubuntu, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #555;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@import "inc/topbar";
|
||||||
|
@import "inc/download";
|
||||||
|
@import "inc/filter";
|
||||||
|
|
||||||
|
@import "inc/content";
|
||||||
|
@import "inc/extended";
|
||||||
|
|
||||||
|
@import "inc/bottombar";
|
||||||
|
@import "inc/l10n";
|
||||||
|
|
||||||
|
@import "inc/tree";
|
||||||
|
@import "inc/context";
|
||||||
|
@import "inc/apache-autoindex-table";
|
||||||
|
|
||||||
|
@import "inc/responsive";
|
||||||
|
|
||||||
|
@import "inc/h5ai-info";
|
||||||
|
|
||||||
|
|
||||||
|
html.js .hideOnJs, html.no-js .hideOnNoJs {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
html.oldie {
|
||||||
|
.oldBrowser {
|
||||||
|
display: inline !important;
|
||||||
|
}
|
||||||
|
#tree {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,31 +1,4 @@
|
|||||||
<!-- generated code ends here -->
|
<!-- generated code ends here -->
|
||||||
</section>
|
</div>
|
||||||
</section>
|
|
||||||
<div id="selection-rect"></div>
|
|
||||||
<footer class="clearfix">
|
|
||||||
<span class="left">
|
|
||||||
<a id="h5ai-reference" href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
|
||||||
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
|
|
||||||
</span>
|
|
||||||
<span class="right">
|
|
||||||
<span id="langSelector">
|
|
||||||
<span class="lang">en</span> - <span class="l10n-lang">english</span>
|
|
||||||
<span class="langOptions"></span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span class="center">
|
|
||||||
<span class="hideOnNoJs">
|
|
||||||
<span class="status default">
|
|
||||||
<span class="folderTotal"></span> <span class="l10n-folders">folders</span>
|
|
||||||
<span class='sep'>·</span>
|
|
||||||
<span class="fileTotal"></span> <span class="l10n-files">files</span>
|
|
||||||
</span>
|
|
||||||
<span class="status dynamic">
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</footer>
|
|
||||||
<script src="/_h5ai/config.js"></script>
|
|
||||||
<script src="/_h5ai/js/libs.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
11
src/_h5ai/footer.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!-- generated code ends here -->
|
||||||
|
</div>
|
||||||
|
<div id="data-generic-json" class="hidden">
|
||||||
|
<?php if (stripos($_SERVER["REQUEST_METHOD"], "HEAD") === false) {
|
||||||
|
require_once(str_replace("\\", "/", __DIR__) . "/php/inc/H5ai.php");
|
||||||
|
$h5ai = new H5ai();
|
||||||
|
echo $h5ai->getGenericJson();
|
||||||
|
} ?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -2,30 +2,37 @@
|
|||||||
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
||||||
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||||
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
|
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
|
||||||
<!--[if gt IE 8]><!--> <html class="h5ai-js no-js" lang="en"> <!--<![endif]-->
|
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
<title>Directory index · styled with h5ai</title>
|
<title>Directory index · styled with h5ai</title>
|
||||||
<meta name="h5ai-version" content="h5ai %BUILD_VERSION% (js)">
|
|
||||||
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
|
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
|
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
|
||||||
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
|
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
|
||||||
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
||||||
<link rel="stylesheet" href="/_h5ai/css/main.css">
|
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
||||||
<script src="/_h5ai/js/modernizr.min.js"></script>
|
<script src="/_h5ai/config.js"></script>
|
||||||
|
<script src="/_h5ai/js/scripts.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="h5ai-main">
|
||||||
<nav class="clearfix hideOnNoJs">
|
<div id="topbar" class="clearfix">
|
||||||
<ul id="navbar"></ul>
|
<ul id="navbar"></ul>
|
||||||
</nav>
|
</div>
|
||||||
<section id="tree"></section>
|
<div id="content">
|
||||||
<section id="content">
|
<div id="extended" class="clearfix"></div>
|
||||||
<header></header>
|
</div>
|
||||||
<section id="extended" class="clearfix"></section>
|
<div id="bottombar" class="clearfix">
|
||||||
<footer></footer>
|
<span class="left">
|
||||||
<section id="table" class="hideOnJs">
|
<a id="h5ai-reference" href="http://larsjung.de/h5ai" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
||||||
|
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
|
||||||
|
<span class="oldBrowser"> ⚡ Some features disabled! Works best in <a href="http://browsehappy.com">modern browsers</a>. ⚡ </span>
|
||||||
|
</span>
|
||||||
|
<span class="right"></span>
|
||||||
|
<span class="center"></span>
|
||||||
|
</div>
|
||||||
|
<div id="data-apache-autoindex" class="hideOnJs">
|
||||||
<!--
|
<!--
|
||||||
The following code was generated by Apache's autoindex module. It is not valid HTML5, but this
|
The following code was generated by Apache's autoindex module. It is not valid HTML5, but this
|
||||||
section gets removed from the DOM tree as soon as its information is parsed. The actual page
|
section gets removed from the DOM tree as soon as its information is parsed. The actual page
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
|
||||||
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
|
||||||
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
|
|
||||||
<!--[if gt IE 8]><!--> <html class="h5ai-php no-js" lang="en"> <!--<![endif]-->
|
|
||||||
<?php include "php/main.php"; ?>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
||||||
<title><?php echo $h5ai->getTitle(); ?></title>
|
|
||||||
<meta name="h5ai-version" content="h5ai %BUILD_VERSION% (php)">
|
|
||||||
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
|
|
||||||
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
|
|
||||||
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
|
||||||
<link rel="stylesheet" href="/_h5ai/css/main.css">
|
|
||||||
<script src="/_h5ai/js/modernizr.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav class="clearfix">
|
|
||||||
<ul id="navbar">
|
|
||||||
<?php echo $crumb->toHtml(); ?>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<?php echo $tree->toHtml(); ?>
|
|
||||||
<section id="content">
|
|
||||||
<?php echo $customize->getHeader(); ?>
|
|
||||||
<?php echo $extended->toHtml(); ?>
|
|
||||||
<?php echo $customize->getFooter(); ?>
|
|
||||||
<section id="table" class="hideOnJs">
|
|
||||||
<!-- The following code was generated by Apache's autoindex module and gets ignored and removed from the DOM tree. -->
|
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
src/_h5ai/images/html5.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 564 B |
43
src/_h5ai/index.html
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
|
||||||
|
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<title>h5ai %BUILD_VERSION% info page</title>
|
||||||
|
<meta name="description" content="h5ai · a beautified Apache index">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
|
||||||
|
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
|
||||||
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
||||||
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Miltonian+Tattoo:regular">
|
||||||
|
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
||||||
|
<script src="/_h5ai/config.js"></script>
|
||||||
|
<script src="/_h5ai/js/scripts.js"></script>
|
||||||
|
</head>
|
||||||
|
<body id="h5ai-info">
|
||||||
|
<h1><span class="h5ai">h5ai</span></h1>
|
||||||
|
version %BUILD_VERSION%
|
||||||
|
<h2>server supports</h2>
|
||||||
|
<ul id="tests">
|
||||||
|
<li class="test" data-id="php"><span class="test-label">php version</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="cache"><span class="test-label">cache</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="thumbs"><span class="test-label">thumbnails</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="temp"><span class="test-label">temp directory</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="archive"><span class="test-label">php tar and zip</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="tar"><span class="test-label">shell tar</span><span class="test-result">?</span></li>
|
||||||
|
<li class="test" data-id="zip"><span class="test-label">shell zip</span><span class="test-result">?</span></li>
|
||||||
|
</ul>
|
||||||
|
<div id="bottombar" class="clearfix">
|
||||||
|
<span class="left">
|
||||||
|
<a id="h5ai-reference" href="http://larsjung.de/h5ai" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
||||||
|
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
|
||||||
|
<span class="oldBrowser"> ⚡ Some features disabled! Works best in <a href="http://browsehappy.com">modern browsers</a>. ⚡ </span>
|
||||||
|
</span>
|
||||||
|
<span class="right"></span>
|
||||||
|
<span class="center"></span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -1,115 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.connector = (function () {
|
|
||||||
|
|
||||||
var cache = {},
|
|
||||||
pathnameStatusCache = {},
|
|
||||||
contentTypeRegEx = /^text\/html;h5ai=/,
|
|
||||||
getPath = function (folder, tableRow) {
|
|
||||||
|
|
||||||
var absHref = H5AI.util.getAbsHref(folder, tableRow),
|
|
||||||
path = cache[absHref];
|
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
path = H5AI.Path(folder, tableRow);
|
|
||||||
if (!path.isParentFolder) {
|
|
||||||
cache[path.absHref] = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
},
|
|
||||||
fetchStatus = function (pathname, callback) {
|
|
||||||
|
|
||||||
if (H5AI.core.settings.folderStatus[pathname]) {
|
|
||||||
callback(H5AI.core.settings.folderStatus[pathname]);
|
|
||||||
return;
|
|
||||||
} else if (pathnameStatusCache[pathname]) {
|
|
||||||
callback(pathnameStatusCache[pathname]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: pathname,
|
|
||||||
type: "HEAD",
|
|
||||||
complete: function (xhr) {
|
|
||||||
|
|
||||||
var status = xhr.status;
|
|
||||||
|
|
||||||
if (status === 200 && contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
|
|
||||||
status = "h5ai";
|
|
||||||
}
|
|
||||||
pathnameStatusCache[pathname] = status;
|
|
||||||
callback(status);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updatePath = function (path) {
|
|
||||||
|
|
||||||
if (path.isFolder && !path.isParentFolder && path.status === undefined) {
|
|
||||||
fetchStatus(path.absHref, function (status) {
|
|
||||||
|
|
||||||
if (status !== "h5ai") {
|
|
||||||
path.status = status;
|
|
||||||
}
|
|
||||||
H5AI.html.updateHtml(path);
|
|
||||||
H5AI.core.linkHoverStates();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updatePaths = function () {
|
|
||||||
|
|
||||||
$.each(cache, function (ref, cached) {
|
|
||||||
updatePath(cached);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fetchStatusAndContent = function (pathname, includeParent, callback) {
|
|
||||||
|
|
||||||
fetchStatus(pathname, function (status) {
|
|
||||||
|
|
||||||
if (status !== "h5ai") {
|
|
||||||
callback(status, {});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: pathname,
|
|
||||||
type: "GET",
|
|
||||||
dataType: "html",
|
|
||||||
error: function (xhr) {
|
|
||||||
|
|
||||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
|
||||||
},
|
|
||||||
success: function (html, status, xhr) {
|
|
||||||
|
|
||||||
var content = {};
|
|
||||||
|
|
||||||
if (!contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
|
|
||||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(html).find("#table td").closest("tr").each(function () {
|
|
||||||
|
|
||||||
var path = getPath(pathname, this);
|
|
||||||
|
|
||||||
if (path.isFolder && (!path.isParentFolder || includeParent)) {
|
|
||||||
content[path.absHref] = path;
|
|
||||||
updatePath(path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
callback("h5ai", content);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
getPath: getPath,
|
|
||||||
updatePaths: updatePaths,
|
|
||||||
fetchStatusAndContent: fetchStatusAndContent
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.context = (function () {
|
|
||||||
|
|
||||||
var $context,
|
|
||||||
qrCodesSize,
|
|
||||||
showQrCode = function ($a) {
|
|
||||||
|
|
||||||
var absHref = $a.attr('href'),
|
|
||||||
url = 'http://' + document.domain + absHref;
|
|
||||||
|
|
||||||
$context.find('.qrcode').empty().qrcode({
|
|
||||||
render: Modernizr.canvas ? 'canvas' : 'div',
|
|
||||||
width: qrCodesSize,
|
|
||||||
height: qrCodesSize,
|
|
||||||
color: '#333',
|
|
||||||
text: url
|
|
||||||
});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
qrCodesSize = H5AI.core.settings.qrCodesSize;
|
|
||||||
if (!qrCodesSize) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hideTimeoutId = null;
|
|
||||||
|
|
||||||
$context = $('<div id="context"><div class="qrcode"/></div>');
|
|
||||||
$context.appendTo('body');
|
|
||||||
|
|
||||||
$('#extended')
|
|
||||||
.on('mouseenter', '.entry.file a', function () {
|
|
||||||
|
|
||||||
showQrCode($(this));
|
|
||||||
clearTimeout(hideTimeoutId);
|
|
||||||
$context.stop(true, true).fadeIn(400);
|
|
||||||
})
|
|
||||||
.on('mouseleave', '.entry.file a', function () {
|
|
||||||
|
|
||||||
hideTimeoutId = setTimeout(function () {
|
|
||||||
|
|
||||||
$context.stop(true, true).fadeOut(400);
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,439 +0,0 @@
|
|||||||
|
|
||||||
(function (window, $, H5AI, config) {
|
|
||||||
|
|
||||||
H5AI.core = (function () {
|
|
||||||
|
|
||||||
var $window = $(window),
|
|
||||||
defaults = {
|
|
||||||
store: {
|
|
||||||
viewmode: "h5ai.pref.viewmode",
|
|
||||||
lang: "h5ai.pref.lang"
|
|
||||||
},
|
|
||||||
callbacks: {
|
|
||||||
pathClick: []
|
|
||||||
},
|
|
||||||
|
|
||||||
rootAbsHref: "/",
|
|
||||||
h5aiAbsHref: "/_h5ai/",
|
|
||||||
customHeader: null,
|
|
||||||
customFooter: null,
|
|
||||||
viewmodes: ["details", "icons"],
|
|
||||||
sortorder: "na",
|
|
||||||
showTree: true,
|
|
||||||
slideTree: true,
|
|
||||||
folderStatus: {},
|
|
||||||
lang: "en",
|
|
||||||
useBrowserLang: true,
|
|
||||||
setParentFolderLabels: true,
|
|
||||||
linkHoverStates: true,
|
|
||||||
dateFormat: "yyyy-MM-dd HH:mm",
|
|
||||||
showThumbs: false,
|
|
||||||
thumbTypes: ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
|
||||||
zippedDownload: false,
|
|
||||||
qrCodesSize: null,
|
|
||||||
showFilter: false
|
|
||||||
},
|
|
||||||
settings = $.extend({}, defaults, config.options),
|
|
||||||
currentDateFormat = settings.dateFormat,
|
|
||||||
extToFileType = (function (types) {
|
|
||||||
var map = {};
|
|
||||||
$.each(types, function (type, exts) {
|
|
||||||
$.each(exts, function (idx, ext) {
|
|
||||||
map[ext] = type;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return map;
|
|
||||||
}(config.types)),
|
|
||||||
hash = function (obj) {
|
|
||||||
|
|
||||||
if ($.isPlainObject(obj)) {
|
|
||||||
var hashStr = '';
|
|
||||||
$.each($.extend({}, hash(), obj), function (key, value) {
|
|
||||||
if (value) {
|
|
||||||
hashStr += '/' + encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hashStr = '#!' + hashStr;
|
|
||||||
window.location.hash = hashStr;
|
|
||||||
return hashStr;
|
|
||||||
} else {
|
|
||||||
var result = {},
|
|
||||||
parts = document.location.hash.split('/');
|
|
||||||
|
|
||||||
if (parts.length >= 2 || parts[0] === '#!') {
|
|
||||||
parts.shift();
|
|
||||||
$.each(parts, function (idx, part) {
|
|
||||||
|
|
||||||
var match = /^([^=]*)=(.*?)$/.exec(part);
|
|
||||||
if (match) {
|
|
||||||
result[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return typeof obj === 'string' ? result[obj] : result;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
api = function () {
|
|
||||||
|
|
||||||
return settings.h5aiAbsHref + "php/api.php";
|
|
||||||
},
|
|
||||||
image = function (id, noPngExt) {
|
|
||||||
|
|
||||||
return settings.h5aiAbsHref + "images/" + id + (noPngExt ? "" : ".png");
|
|
||||||
},
|
|
||||||
icon = function (id, big) {
|
|
||||||
|
|
||||||
return settings.h5aiAbsHref + "icons/" + (big ? "48x48" : "16x16") + "/" + id + ".png";
|
|
||||||
},
|
|
||||||
viewmode = function (viewmode) {
|
|
||||||
|
|
||||||
var $viewDetails = $("#viewdetails"),
|
|
||||||
$viewIcons = $("#viewicons"),
|
|
||||||
$extended = $("#extended");
|
|
||||||
|
|
||||||
if (viewmode) {
|
|
||||||
amplify.store(settings.store.viewmode, viewmode);
|
|
||||||
} else {
|
|
||||||
viewmode = amplify.store(settings.store.viewmode);
|
|
||||||
}
|
|
||||||
viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
|
|
||||||
H5AI.core.hash({view: viewmode});
|
|
||||||
|
|
||||||
$viewDetails.add($viewIcons).removeClass("current");
|
|
||||||
if (viewmode === "details") {
|
|
||||||
$viewDetails.addClass("current");
|
|
||||||
$extended.addClass("details-view").removeClass("icons-view").show();
|
|
||||||
} else if (viewmode === "icons") {
|
|
||||||
$viewIcons.addClass("current");
|
|
||||||
$extended.removeClass("details-view").addClass("icons-view").show();
|
|
||||||
} else {
|
|
||||||
$extended.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initTopSpace = function () {
|
|
||||||
|
|
||||||
var $body = $("body"),
|
|
||||||
$tree = $("#tree"),
|
|
||||||
adjustTopSpace = function () {
|
|
||||||
|
|
||||||
var winHeight = $window.height(),
|
|
||||||
navHeight = $("body > nav").outerHeight(),
|
|
||||||
footerHeight = $("body > footer").outerHeight(),
|
|
||||||
contentSpacing = 50,
|
|
||||||
treeSpacing = 0;
|
|
||||||
|
|
||||||
$body.css({
|
|
||||||
"margin-top": navHeight + contentSpacing,
|
|
||||||
"margin-bottom": footerHeight + contentSpacing
|
|
||||||
});
|
|
||||||
|
|
||||||
$tree.css({
|
|
||||||
top: navHeight + treeSpacing,
|
|
||||||
height: winHeight - navHeight - footerHeight - 16 - 2 * treeSpacing
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
$tree.get(0).updateScrollbar();
|
|
||||||
} catch (err) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
$window.resize(function () {
|
|
||||||
adjustTopSpace();
|
|
||||||
});
|
|
||||||
adjustTopSpace();
|
|
||||||
},
|
|
||||||
initViews = function () {
|
|
||||||
|
|
||||||
var $navbar = $("#navbar"),
|
|
||||||
$extended = $("#extended");
|
|
||||||
|
|
||||||
$("#table").remove();
|
|
||||||
|
|
||||||
if (settings.viewmodes.length > 1) {
|
|
||||||
if ($.inArray("icons", settings.viewmodes) >= 0) {
|
|
||||||
$("<li id='viewicons' class='view'><a href='#'><img alt='view-icons' /><span class='l10n-icons'>icons</span></a></li>")
|
|
||||||
.find("img").attr("src", image("view-icons")).end()
|
|
||||||
.find("a").click(function (event) {
|
|
||||||
viewmode("icons");
|
|
||||||
event.preventDefault();
|
|
||||||
}).end()
|
|
||||||
.appendTo($navbar);
|
|
||||||
}
|
|
||||||
if ($.inArray("details", settings.viewmodes) >= 0) {
|
|
||||||
$("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>")
|
|
||||||
.find("img").attr("src", image("view-details")).end()
|
|
||||||
.find("a").click(function (event) {
|
|
||||||
viewmode("details");
|
|
||||||
event.preventDefault();
|
|
||||||
}).end()
|
|
||||||
.appendTo($navbar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// status update
|
|
||||||
$extended.find(".entry a").hover(
|
|
||||||
function () {
|
|
||||||
if ($extended.hasClass("icons-view")) {
|
|
||||||
var $this = $(this);
|
|
||||||
$(".status.default").hide();
|
|
||||||
$(".status.dynamic")
|
|
||||||
.empty()
|
|
||||||
.append($this.find(".label").clone())
|
|
||||||
.append($("<span class='sep'>·</span>"))
|
|
||||||
.append($this.find(".date").clone())
|
|
||||||
.show();
|
|
||||||
|
|
||||||
if (!$this.closest(".entry").hasClass("folder")) {
|
|
||||||
$(".status.dynamic")
|
|
||||||
.append($("<span class='sep'>·</span>"))
|
|
||||||
.append($this.find(".size").clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$(".status.default").show();
|
|
||||||
$(".status.dynamic").empty().hide();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
shiftTree = function (forceVisible, dontAnimate) {
|
|
||||||
|
|
||||||
var $tree = $("#tree"),
|
|
||||||
$extended = $("#extended");
|
|
||||||
|
|
||||||
if ((settings.slideTree && $tree.outerWidth() < $extended.offset().left) || forceVisible) {
|
|
||||||
if (dontAnimate) {
|
|
||||||
$tree.stop().css({ left: 0 });
|
|
||||||
} else {
|
|
||||||
$tree.stop().animate({ left: 0 });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dontAnimate) {
|
|
||||||
$tree.stop().css({ left: 18 - $tree.outerWidth() });
|
|
||||||
} else {
|
|
||||||
$tree.stop().animate({ left: 18 - $tree.outerWidth() });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initTree = function () {
|
|
||||||
|
|
||||||
$("#tree").hover(
|
|
||||||
function () { shiftTree(true); },
|
|
||||||
function () { shiftTree(); }
|
|
||||||
);
|
|
||||||
$window.resize(function () { shiftTree(); });
|
|
||||||
shiftTree(false, true);
|
|
||||||
},
|
|
||||||
selectLinks = function (href) {
|
|
||||||
|
|
||||||
var elements = [];
|
|
||||||
$("a[href^='/']").each(function () {
|
|
||||||
|
|
||||||
if ($(this).attr("href") === href) {
|
|
||||||
elements.push(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $(elements);
|
|
||||||
},
|
|
||||||
linkHoverStates = function () {
|
|
||||||
|
|
||||||
if (settings.linkHoverStates) {
|
|
||||||
$("a[href^='/']:not(.linkedHoverStates)").each(function () {
|
|
||||||
|
|
||||||
var $a = $(this).addClass("linkedHoverStates"),
|
|
||||||
href = $a.attr("href");
|
|
||||||
|
|
||||||
$a.hover(
|
|
||||||
function () { selectLinks(href).addClass("hover"); },
|
|
||||||
function () { selectLinks(href).removeClass("hover"); }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
formatDates = function (dateFormat) {
|
|
||||||
|
|
||||||
if (dateFormat) {
|
|
||||||
currentDateFormat = dateFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#extended .entry .date").each(function () {
|
|
||||||
|
|
||||||
var $this = $(this),
|
|
||||||
time = $this.data("time"),
|
|
||||||
formattedDate = time ? new Date(time).toString(currentDateFormat) : "";
|
|
||||||
|
|
||||||
$this.text(formattedDate);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
localize = function (langs, lang, useBrowserLang) {
|
|
||||||
|
|
||||||
var storedLang = amplify.store(settings.store.lang),
|
|
||||||
browserLang, selected, key;
|
|
||||||
|
|
||||||
if (langs[storedLang]) {
|
|
||||||
lang = storedLang;
|
|
||||||
} else if (useBrowserLang) {
|
|
||||||
browserLang = navigator.language;
|
|
||||||
if (langs[browserLang]) {
|
|
||||||
lang = browserLang;
|
|
||||||
} else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
|
|
||||||
lang = browserLang.substr(0, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!langs[lang]) {
|
|
||||||
lang = "en";
|
|
||||||
}
|
|
||||||
|
|
||||||
selected = langs[lang];
|
|
||||||
if (selected) {
|
|
||||||
$.each(selected, function (key, value) {
|
|
||||||
$(".l10n-" + key).text(value);
|
|
||||||
});
|
|
||||||
$(".lang").text(lang);
|
|
||||||
$(".langOption").removeClass("current");
|
|
||||||
$(".langOption." + lang).addClass("current");
|
|
||||||
H5AI.core.hash({lang: lang});
|
|
||||||
}
|
|
||||||
|
|
||||||
formatDates(selected.dateFormat || settings.dateFormat);
|
|
||||||
},
|
|
||||||
initLangSelector = function (langs) {
|
|
||||||
|
|
||||||
var $langOptions = $("#langSelector .langOptions"),
|
|
||||||
sortedLangsKeys = [],
|
|
||||||
$ul;
|
|
||||||
|
|
||||||
$.each(langs, function (lang) {
|
|
||||||
sortedLangsKeys.push(lang);
|
|
||||||
});
|
|
||||||
sortedLangsKeys.sort();
|
|
||||||
|
|
||||||
$ul = $("<ul />");
|
|
||||||
$.each(sortedLangsKeys, function (idx, lang) {
|
|
||||||
$("<li class='langOption' />")
|
|
||||||
.addClass(lang)
|
|
||||||
.text(lang + " - " + langs[lang].lang)
|
|
||||||
.appendTo($ul)
|
|
||||||
.click(function () {
|
|
||||||
amplify.store(settings.store.lang, lang);
|
|
||||||
localize(langs, lang, false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$langOptions
|
|
||||||
.append($ul)
|
|
||||||
.scrollpanel();
|
|
||||||
|
|
||||||
$("#langSelector").hover(
|
|
||||||
function () {
|
|
||||||
$langOptions
|
|
||||||
.css("top", "-" + $langOptions.outerHeight() + "px")
|
|
||||||
.stop(true, true)
|
|
||||||
.fadeIn();
|
|
||||||
$langOptions.get(0).updateScrollbar();
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$langOptions
|
|
||||||
.stop(true, true)
|
|
||||||
.fadeOut();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onIndicatorClick = function (event) {
|
|
||||||
|
|
||||||
var $indicator = $(this),
|
|
||||||
$entry = $indicator.closest(".entry"),
|
|
||||||
updateTreeScrollbar = $("#tree").get(0).updateScrollbar;
|
|
||||||
|
|
||||||
if ($indicator.hasClass("unknown")) {
|
|
||||||
$.get(api(), { "action": "tree", "href": $entry.find("> a").attr("href") }, function (html) {
|
|
||||||
|
|
||||||
var $content = $(html);
|
|
||||||
|
|
||||||
$indicator.removeClass("unknown");
|
|
||||||
if ($content.find("> li").size() === 0) {
|
|
||||||
$indicator.replaceWith($("<span class='blank' />"));
|
|
||||||
} else {
|
|
||||||
$indicator.addClass("open");
|
|
||||||
$entry.find("> .content").replaceWith($content);
|
|
||||||
updateTreeScrollbar();
|
|
||||||
$content.find(".indicator:not(.initiated)")
|
|
||||||
.click(onIndicatorClick)
|
|
||||||
.addClass("initiated");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if ($indicator.hasClass("open")) {
|
|
||||||
$indicator.removeClass("open");
|
|
||||||
updateTreeScrollbar(true);
|
|
||||||
$entry.find("> .content").slideUp(function () {
|
|
||||||
updateTreeScrollbar();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$indicator.addClass("open");
|
|
||||||
updateTreeScrollbar(true);
|
|
||||||
$entry.find("> .content").slideDown(function () {
|
|
||||||
updateTreeScrollbar();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initIndicators = function () {
|
|
||||||
|
|
||||||
$("#tree .entry.folder .indicator:not(.initiated)")
|
|
||||||
.click(onIndicatorClick)
|
|
||||||
.addClass("initiated");
|
|
||||||
},
|
|
||||||
getFileType = function (filename) {
|
|
||||||
|
|
||||||
var dotidx = filename.lastIndexOf('.'),
|
|
||||||
ext = dotidx >= 0 ? filename.substr(dotidx) : filename;
|
|
||||||
|
|
||||||
return extToFileType[ext.toLowerCase()] || "unknown";
|
|
||||||
},
|
|
||||||
formatSizes = function () {
|
|
||||||
|
|
||||||
$("#extended .entry .size").each(function () {
|
|
||||||
|
|
||||||
var $this = $(this),
|
|
||||||
bytes = $this.data("bytes"),
|
|
||||||
formattedSize = bytes >= 0 ? H5AI.util.formatSize(bytes) : "";
|
|
||||||
|
|
||||||
$this.text(formattedSize);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setTotals = function () {
|
|
||||||
|
|
||||||
var $extended = $("#extended");
|
|
||||||
|
|
||||||
$(".folderTotal").text($extended.find(".entry.folder:not(.folder-parent)").length);
|
|
||||||
$(".fileTotal").text($extended.find(".entry.file").length);
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
initViews();
|
|
||||||
viewmode();
|
|
||||||
initTopSpace();
|
|
||||||
initTree();
|
|
||||||
linkHoverStates();
|
|
||||||
initLangSelector(config.langs);
|
|
||||||
localize(config.langs, settings.lang, settings.useBrowserLang);
|
|
||||||
formatSizes();
|
|
||||||
setTotals();
|
|
||||||
initIndicators();
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
settings: settings,
|
|
||||||
hash: hash,
|
|
||||||
api: api,
|
|
||||||
image: image,
|
|
||||||
icon: icon,
|
|
||||||
shiftTree: shiftTree,
|
|
||||||
linkHoverStates: linkHoverStates,
|
|
||||||
initIndicators: initIndicators,
|
|
||||||
formatDates: formatDates,
|
|
||||||
getFileType: getFileType,
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(window, jQuery, H5AI, H5AI_CONFIG));
|
|
@@ -1,132 +0,0 @@
|
|||||||
|
|
||||||
(function (document, $, H5AI) {
|
|
||||||
|
|
||||||
H5AI.extended = (function () {
|
|
||||||
|
|
||||||
var initBreadcrumb = function () {
|
|
||||||
|
|
||||||
var $ul = $("body > nav ul"),
|
|
||||||
pathname = "/",
|
|
||||||
path = H5AI.connector.getPath(pathname),
|
|
||||||
pathnameParts = document.location.pathname.split("/"),
|
|
||||||
lastPart = "",
|
|
||||||
title = document.domain;
|
|
||||||
|
|
||||||
$ul.append(H5AI.html.updateCrumbHtml(path));
|
|
||||||
|
|
||||||
$.each(pathnameParts, function (idx, part) {
|
|
||||||
if (part !== "") {
|
|
||||||
pathname += part + "/";
|
|
||||||
$ul.append(H5AI.html.updateCrumbHtml(H5AI.connector.getPath(pathname)));
|
|
||||||
lastPart = part + " - ";
|
|
||||||
title += " > " + part;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.title = H5AI.util.checkedDecodeUri(lastPart + title);
|
|
||||||
},
|
|
||||||
initExtendedView = function () {
|
|
||||||
|
|
||||||
var $ul, $li;
|
|
||||||
|
|
||||||
$ul = $("<ul/>");
|
|
||||||
$li = $("<li class='header' />")
|
|
||||||
.appendTo($ul)
|
|
||||||
.append($("<a class='icon'></a>"))
|
|
||||||
.append($("<a class='label' href='#'><span class='l10n-name'></span></a>"))
|
|
||||||
.append($("<a class='date' href='#'><span class='l10n-lastModified'></span></a>"))
|
|
||||||
.append($("<a class='size' href='#'><span class='l10n-size'></span></a>"));
|
|
||||||
|
|
||||||
// entries
|
|
||||||
$("#table td").closest("tr").each(function () {
|
|
||||||
var path = H5AI.connector.getPath(document.location.pathname, this);
|
|
||||||
$ul.append(H5AI.html.updateExtendedHtml(path));
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#extended").append($ul);
|
|
||||||
|
|
||||||
// empty
|
|
||||||
if ($ul.children(".entry:not(.folder-parent)").size() === 0) {
|
|
||||||
$("#extended").append($("<div class='empty l10n-empty'>empty</div>"));
|
|
||||||
}
|
|
||||||
$("#extended").append($("<div class='no-match l10n-noMatch'>no match</div>"));
|
|
||||||
},
|
|
||||||
customize = function () {
|
|
||||||
|
|
||||||
if (H5AI.core.settings.customHeader) {
|
|
||||||
$.ajax({
|
|
||||||
url: H5AI.core.settings.customHeader,
|
|
||||||
dataType: "html",
|
|
||||||
success: function (data) {
|
|
||||||
$("#content > header").append($(data)).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (H5AI.core.settings.customFooter) {
|
|
||||||
$.ajax({
|
|
||||||
url: H5AI.core.settings.customFooter,
|
|
||||||
dataType: "html",
|
|
||||||
success: function (data) {
|
|
||||||
$("#content > footer").prepend($(data)).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fetchPath = function (pathname, callback) {
|
|
||||||
|
|
||||||
H5AI.connector.fetchStatusAndContent(pathname, false, function (status, content) {
|
|
||||||
|
|
||||||
var path = H5AI.connector.getPath(pathname);
|
|
||||||
|
|
||||||
path.status = status;
|
|
||||||
path.content = content;
|
|
||||||
callback(path);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fetchTree = function (pathname, callback, childPath) {
|
|
||||||
|
|
||||||
fetchPath(pathname, function (path) {
|
|
||||||
|
|
||||||
var parent = H5AI.util.splitPath(pathname).parent;
|
|
||||||
|
|
||||||
path.treeOpen = true;
|
|
||||||
if (childPath) {
|
|
||||||
path.content[childPath.absHref] = childPath;
|
|
||||||
}
|
|
||||||
if (parent === null) {
|
|
||||||
callback(path);
|
|
||||||
} else {
|
|
||||||
fetchTree(parent, callback, path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
populateTree = function () {
|
|
||||||
|
|
||||||
fetchTree(document.location.pathname, function (path) {
|
|
||||||
$("#tree")
|
|
||||||
.append(H5AI.html.updateTreeHtml(path))
|
|
||||||
.scrollpanel()
|
|
||||||
.show();
|
|
||||||
H5AI.core.shiftTree(false, true);
|
|
||||||
H5AI.core.linkHoverStates();
|
|
||||||
setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
initBreadcrumb();
|
|
||||||
initExtendedView();
|
|
||||||
customize();
|
|
||||||
H5AI.connector.updatePaths();
|
|
||||||
if (H5AI.core.settings.showTree) {
|
|
||||||
populateTree();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(document, jQuery, H5AI));
|
|
@@ -1,111 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.finder = (function () {
|
|
||||||
|
|
||||||
var filter = function (re) {
|
|
||||||
|
|
||||||
var match = [],
|
|
||||||
noMatch = [];
|
|
||||||
|
|
||||||
if (re) {
|
|
||||||
$('#extended .entry').each(function () {
|
|
||||||
|
|
||||||
var label = $(this).find('.label').text();
|
|
||||||
|
|
||||||
if (label.match(re)) {
|
|
||||||
match.push(this);
|
|
||||||
} else {
|
|
||||||
noMatch.push(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
match = $('#extended .entry');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(match).length) {
|
|
||||||
$('#extended .no-match').hide();
|
|
||||||
} else {
|
|
||||||
setTimeout(function () {
|
|
||||||
|
|
||||||
$('#extended .no-match').show();
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
$(match).fadeIn(200);
|
|
||||||
$(noMatch).fadeOut(200);
|
|
||||||
},
|
|
||||||
checkState = function (focus) {
|
|
||||||
|
|
||||||
var $filter = $('#filter'),
|
|
||||||
$input = $filter.find('input'),
|
|
||||||
val = $input.val();
|
|
||||||
|
|
||||||
if (val || focus) {
|
|
||||||
$filter.addClass('current');
|
|
||||||
} else {
|
|
||||||
$filter.removeClass('current');
|
|
||||||
}
|
|
||||||
H5AI.core.hash({filter: val});
|
|
||||||
},
|
|
||||||
parseFilterSequence = function (sequence) {
|
|
||||||
|
|
||||||
if (sequence.substr(0,3) === 're:') {
|
|
||||||
return new RegExp(sequence.substr(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
sequence = $.map($.trim(sequence).split(/\s+/), function (part) {
|
|
||||||
|
|
||||||
return H5AI.util.reEscape(part);
|
|
||||||
}).join('|');
|
|
||||||
return new RegExp(sequence);
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
if (H5AI.core.settings.showFilter) {
|
|
||||||
$("<li id='filter'><span class='element'><img alt='filter' /><input type='text' value='' placeholder='filter' /></span></li>")
|
|
||||||
.on('click', function () {
|
|
||||||
|
|
||||||
var $input = $(this).find('input');
|
|
||||||
$input.focus();
|
|
||||||
})
|
|
||||||
.find("img").attr("src", H5AI.core.image("filter")).end()
|
|
||||||
.find("input")
|
|
||||||
.on('focus', function () {
|
|
||||||
|
|
||||||
checkState(true);
|
|
||||||
})
|
|
||||||
.on('blur', function () {
|
|
||||||
|
|
||||||
checkState(false);
|
|
||||||
})
|
|
||||||
.on('keyup', function () {
|
|
||||||
|
|
||||||
var $input = $(this),
|
|
||||||
val = $input.val();
|
|
||||||
|
|
||||||
if (val) {
|
|
||||||
filter(parseFilterSequence(val));
|
|
||||||
} else {
|
|
||||||
filter();
|
|
||||||
}
|
|
||||||
checkState($input.is(':focus'));
|
|
||||||
})
|
|
||||||
.end()
|
|
||||||
.appendTo($("#navbar"));
|
|
||||||
|
|
||||||
var initialFilter = H5AI.core.hash('filter');
|
|
||||||
if (initialFilter) {
|
|
||||||
$('#filter input').val(initialFilter);
|
|
||||||
checkState(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init,
|
|
||||||
filter: filter
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,264 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.html = (function () {
|
|
||||||
|
|
||||||
var onClick = function (path, context) {
|
|
||||||
|
|
||||||
},
|
|
||||||
updateCrumbHtml = function (path) {
|
|
||||||
|
|
||||||
var $html, $a;
|
|
||||||
|
|
||||||
if (path.html.$crumb && path.html.$crumb.data("status") === path.status) {
|
|
||||||
return path.html.$crumb;
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = $("<li class='crumb'><a><img alt='>' /><span></span></a></li>")
|
|
||||||
.addClass(path.isFolder ? "folder" : "file");
|
|
||||||
|
|
||||||
if (path.status) {
|
|
||||||
$html.data("status", path.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
$a = $html.find("a")
|
|
||||||
.attr("href", path.absHref)
|
|
||||||
.click(function() { onClick(path, "crumb"); })
|
|
||||||
.find("img").attr("src", H5AI.core.image("crumb")).end()
|
|
||||||
.find("span").text(path.label).end();
|
|
||||||
|
|
||||||
if (path.isDomain) {
|
|
||||||
$html.addClass("domain");
|
|
||||||
$a.find("img").attr("src", H5AI.core.image("home"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.isCurrentFolder) {
|
|
||||||
$html.addClass("current");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNaN(path.status)) {
|
|
||||||
if (path.status === 200) {
|
|
||||||
$a.append($("<img class='hint' src='" + H5AI.core.image("page") + "' alt='not listable' />"));
|
|
||||||
} else {
|
|
||||||
$a.append($("<span class='hint'>(" + path.status + ")</span>"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.html.$crumb) {
|
|
||||||
path.html.$crumb.replaceWith($html);
|
|
||||||
}
|
|
||||||
path.html.$crumb = $html;
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
},
|
|
||||||
updateExtendedHtml = function (path) {
|
|
||||||
|
|
||||||
var $html, $a, $label,
|
|
||||||
formattedDate = path.date ? path.date.toString(H5AI.core.settings.dateFormat) : "",
|
|
||||||
imgClass = "",
|
|
||||||
icon16 = H5AI.core.icon(path.type),
|
|
||||||
icon48 = H5AI.core.icon(path.type, true);
|
|
||||||
|
|
||||||
if (path.html.$extended && path.html.$extended.data("status") === path.status) {
|
|
||||||
return path.html.$extended;
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = $("<li class='entry' />")
|
|
||||||
.data("path", path)
|
|
||||||
.addClass(path.isFolder ? "folder" : "file");
|
|
||||||
|
|
||||||
if (path.status) {
|
|
||||||
$html.data("status", path.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (H5AI.core.settings.showThumbs === true && $.inArray(path.type, H5AI.core.settings.thumbTypes) >= 0) {
|
|
||||||
imgClass = "class='thumb'";
|
|
||||||
var escapedHref = path.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
|
|
||||||
icon16 = H5AI.core.api() + "?action=thumb&href=" + escapedHref + "&width=16&height=16&mode=square";
|
|
||||||
icon48 = H5AI.core.api() + "?action=thumb&href=" + escapedHref + "&width=96&height=46&mode=rational";
|
|
||||||
}
|
|
||||||
|
|
||||||
$label = $("<span class='label'>" + path.label + "</span>");
|
|
||||||
$a = $("<a />")
|
|
||||||
.attr("href", path.absHref)
|
|
||||||
.click(function() { onClick(path, "extended"); })
|
|
||||||
.appendTo($html)
|
|
||||||
.append($("<span class='icon small'><img " + imgClass + " src='" + icon16 + "' alt='" + path.type + "' /></span>"))
|
|
||||||
.append($("<span class='icon big'><img " + imgClass + " src='" + icon48 + "' alt='" + path.type + "' /></span>"))
|
|
||||||
.append($label)
|
|
||||||
.append($("<span class='date' data-time='" + path.time + "'></span>"))
|
|
||||||
.append($("<span class='size' data-bytes='" + path.size + "'></span>"));
|
|
||||||
|
|
||||||
$a.hover(
|
|
||||||
function () {
|
|
||||||
if ($("#extended").hasClass("icons-view")) {
|
|
||||||
var $this = $(this);
|
|
||||||
$(".status.default").hide();
|
|
||||||
$(".status.dynamic")
|
|
||||||
.empty()
|
|
||||||
.append($this.find(".label").clone())
|
|
||||||
.append($("<span class='sep'>·</span>"))
|
|
||||||
.append($this.find(".date").clone())
|
|
||||||
.show();
|
|
||||||
|
|
||||||
if (!$this.closest(".entry").hasClass("folder")) {
|
|
||||||
$(".status.dynamic")
|
|
||||||
.append($("<span class='sep'>·</span>"))
|
|
||||||
.append($this.find(".size").clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$(".status.default").show();
|
|
||||||
$(".status.dynamic").empty().hide();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (path.isParentFolder) {
|
|
||||||
if (!H5AI.core.settings.setParentFolderLabels) {
|
|
||||||
$label.addClass("l10n-parentDirectory");
|
|
||||||
}
|
|
||||||
$html.addClass("folder-parent");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNaN(path.status)) {
|
|
||||||
if (path.status === 200) {
|
|
||||||
$html.addClass("page");
|
|
||||||
$a.find(".icon.small img").attr("src", H5AI.core.icon("folder-page"));
|
|
||||||
$a.find(".icon.big img").attr("src", H5AI.core.icon("folder-page", true));
|
|
||||||
} else {
|
|
||||||
$html.addClass("error");
|
|
||||||
$label.append($("<span class='hint'> " + path.status + " </span>"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.html.$extended) {
|
|
||||||
path.html.$extended.replaceWith($html);
|
|
||||||
H5AI.core.formatDates();
|
|
||||||
}
|
|
||||||
path.html.$extended = $html;
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
},
|
|
||||||
updateTreeHtml = function (path) {
|
|
||||||
|
|
||||||
var $html, $blank, $a, $indicator, $ul, idx;
|
|
||||||
|
|
||||||
$html = $("<div class='entry' />")
|
|
||||||
.data("path", path)
|
|
||||||
.addClass(path.isFolder ? "folder" : "file");
|
|
||||||
|
|
||||||
$blank = $("<span class='blank' />").appendTo($html);
|
|
||||||
|
|
||||||
$a = $("<a />")
|
|
||||||
.attr("href", path.absHref)
|
|
||||||
.click(function() { onClick(path, "tree"); })
|
|
||||||
.appendTo($html)
|
|
||||||
.append($("<span class='icon'><img src='" + H5AI.core.icon(path.type) + "' /></span>"))
|
|
||||||
.append($("<span class='label'>" + path.label + "</span>"));
|
|
||||||
|
|
||||||
if (path.isFolder) {
|
|
||||||
// indicator
|
|
||||||
if (path.status === undefined || !path.isEmpty()) {
|
|
||||||
$indicator = $("<span class='indicator initiated'><img src='" + H5AI.core.image("tree") + "' /></span>")
|
|
||||||
.click(function (event) {
|
|
||||||
|
|
||||||
var $entry = $indicator.closest(".entry"); // $html
|
|
||||||
|
|
||||||
if ($indicator.hasClass("unknown")) {
|
|
||||||
H5AI.connector.fetchStatusAndContent(path.absHref, false, function (status, content) {
|
|
||||||
|
|
||||||
path.status = status;
|
|
||||||
path.content = content;
|
|
||||||
path.treeOpen = true;
|
|
||||||
$("#tree").get(0).updateScrollbar(true);
|
|
||||||
updateTreeHtml(path);
|
|
||||||
$("#tree").get(0).updateScrollbar();
|
|
||||||
});
|
|
||||||
} else if ($indicator.hasClass("open")) {
|
|
||||||
path.treeOpen = false;
|
|
||||||
$indicator.removeClass("open");
|
|
||||||
$("#tree").get(0).updateScrollbar(true);
|
|
||||||
$entry.find("> ul.content").slideUp(function() {
|
|
||||||
|
|
||||||
$("#tree").get(0).updateScrollbar();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
path.treeOpen = true;
|
|
||||||
$indicator.addClass("open");
|
|
||||||
$("#tree").get(0).updateScrollbar(true);
|
|
||||||
$entry.find("> ul.content").slideDown(function() {
|
|
||||||
|
|
||||||
$("#tree").get(0).updateScrollbar();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (path.status === undefined) {
|
|
||||||
$indicator.addClass("unknown");
|
|
||||||
} else if (path.treeOpen) {
|
|
||||||
$indicator.addClass("open");
|
|
||||||
}
|
|
||||||
|
|
||||||
$blank.replaceWith($indicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// is path the domain?
|
|
||||||
if (path.isDomain) {
|
|
||||||
$html.addClass("domain");
|
|
||||||
$a.find(".icon img").attr("src", H5AI.core.icon("folder-home"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// is path the current folder?
|
|
||||||
if (path.isCurrentFolder) {
|
|
||||||
$html.addClass("current");
|
|
||||||
$a.find(".icon img").attr("src", H5AI.core.icon("folder-open"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// does it have subfolders?
|
|
||||||
if (!path.isEmpty()) {
|
|
||||||
$ul = $("<ul class='content' />").appendTo($html);
|
|
||||||
$.each(path.content, function (idx, entry) {
|
|
||||||
$("<li />").append(updateTreeHtml(entry)).appendTo($ul);
|
|
||||||
});
|
|
||||||
if (path.status === undefined || !path.treeOpen) {
|
|
||||||
$ul.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reflect folder status
|
|
||||||
if (!isNaN(path.status)) {
|
|
||||||
if (path.status === 200) {
|
|
||||||
$a.find(".icon img").attr("src", H5AI.core.icon("folder-page"));
|
|
||||||
$a.append($("<span class='hint'><img src='" + H5AI.core.image("page") + "' /></span>"));
|
|
||||||
} else {
|
|
||||||
$html.addClass("error");
|
|
||||||
$a.append($("<span class='hint'>" + path.status + "</span>"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.html.$tree) {
|
|
||||||
path.html.$tree.replaceWith($html);
|
|
||||||
}
|
|
||||||
path.html.$tree = $html;
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
},
|
|
||||||
updateHtml = function (path) {
|
|
||||||
|
|
||||||
updateCrumbHtml(path);
|
|
||||||
updateExtendedHtml(path);
|
|
||||||
updateTreeHtml(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
updateCrumbHtml: updateCrumbHtml,
|
|
||||||
updateExtendedHtml: updateExtendedHtml,
|
|
||||||
updateTreeHtml: updateTreeHtml,
|
|
||||||
updateHtml: updateHtml
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,95 +0,0 @@
|
|||||||
|
|
||||||
(function (document, $, H5AI) {
|
|
||||||
|
|
||||||
H5AI.Path = function (folder, tableRow) {
|
|
||||||
|
|
||||||
var path = {},
|
|
||||||
$tds, $a, date, size, splits;
|
|
||||||
|
|
||||||
// path.parentFolder: undefined
|
|
||||||
// path.label: undefined
|
|
||||||
// path.type: undefined
|
|
||||||
// path.href: undefined
|
|
||||||
// path.time: undefined
|
|
||||||
// path.size: undefined
|
|
||||||
// path.absHref: undefined
|
|
||||||
// path.isFolder: undefined
|
|
||||||
// path.isParentFolder: undefined
|
|
||||||
// path.isCurrentFolder: undefined
|
|
||||||
// path.isDomain: undefined
|
|
||||||
|
|
||||||
path.status = undefined; // undefined, "h5ai" or HTTP response code
|
|
||||||
path.content = undefined; // associative array path.absHref -> path
|
|
||||||
path.html = {
|
|
||||||
$crumb: undefined,
|
|
||||||
$extended: undefined,
|
|
||||||
$tree: undefined
|
|
||||||
};
|
|
||||||
path.treeOpen = false;
|
|
||||||
|
|
||||||
if (!H5AI.util.pathEndsWithSlash(folder)) {
|
|
||||||
folder += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableRow) {
|
|
||||||
$tds = $(tableRow).find("td");
|
|
||||||
$a = $tds.eq(1).find("a");
|
|
||||||
date = Date.parse($tds.eq(2).text());
|
|
||||||
size = H5AI.util.parseSize($tds.eq(3).text());
|
|
||||||
|
|
||||||
path.parentFolder = folder;
|
|
||||||
path.label = $a.text();
|
|
||||||
path.type = H5AI.util.pathEndsWithSlash(path.label) ? "folder" : H5AI.core.getFileType(path.label);
|
|
||||||
path.href = $a.attr("href");
|
|
||||||
path.time = date ? date.getTime() : 0;
|
|
||||||
path.size = size;
|
|
||||||
} else {
|
|
||||||
splits = H5AI.util.splitPath(folder);
|
|
||||||
|
|
||||||
path.parentFolder = splits.parent || "";
|
|
||||||
path.label = H5AI.util.checkedDecodeUri(splits.name);
|
|
||||||
if (path.label === "/") {
|
|
||||||
path.label = H5AI.util.checkedDecodeUri(document.domain);
|
|
||||||
}
|
|
||||||
path.type = "folder";
|
|
||||||
path.href = splits.name;
|
|
||||||
path.time = 0;
|
|
||||||
path.size = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (H5AI.util.pathEndsWithSlash(path.label)) {
|
|
||||||
path.label = path.label.slice(0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
path.isFolder = (path.type === "folder");
|
|
||||||
path.isParentFolder = (path.label === "Parent Directory");
|
|
||||||
if (path.isParentFolder) {
|
|
||||||
path.isFolder = true;
|
|
||||||
path.type = "folder-parent";
|
|
||||||
}
|
|
||||||
path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href;
|
|
||||||
path.isCurrentFolder = (path.absHref === document.location.pathname);
|
|
||||||
path.isDomain = (path.absHref === "/");
|
|
||||||
|
|
||||||
if (path.isParentFolder && H5AI.core.settings.setParentFolderLabels) {
|
|
||||||
if (path.isDomain) {
|
|
||||||
path.label = H5AI.util.checkedDecodeUri(document.domain);
|
|
||||||
} else {
|
|
||||||
splits = H5AI.util.splitPath(path.parentFolder);
|
|
||||||
path.label = H5AI.util.checkedDecodeUri(splits.parentname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path.isEmpty = function () {
|
|
||||||
|
|
||||||
return !path.content || $.isEmptyObject(path.content);
|
|
||||||
};
|
|
||||||
path.onClick = function (context) {
|
|
||||||
|
|
||||||
H5AI.core.triggerPathClick(path, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
}(document, jQuery, H5AI));
|
|
@@ -1,158 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.sort = (function () {
|
|
||||||
|
|
||||||
var type = function (entry) {
|
|
||||||
|
|
||||||
var $entry = $(entry);
|
|
||||||
|
|
||||||
if ($entry.hasClass("folder-parent")) {
|
|
||||||
return 0;
|
|
||||||
} else if ($entry.hasClass("folder")) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
},
|
|
||||||
cmp = function (entry1, entry2, rev, getVal) {
|
|
||||||
|
|
||||||
var res, val1, val2;
|
|
||||||
|
|
||||||
res = type(entry1) - type(entry2);
|
|
||||||
if (res !== 0) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
val1 = getVal(entry1);
|
|
||||||
val2 = getVal(entry2);
|
|
||||||
if (val1 < val2) {
|
|
||||||
return rev ? 1 : -1;
|
|
||||||
} else if (val1 > val2) {
|
|
||||||
return rev ? -1 : 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
cmpName = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, false, function (entry) {
|
|
||||||
return $(entry).find(".label").text().toLowerCase();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cmpTime = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, false, function (entry) {
|
|
||||||
return $(entry).find(".date").data("time");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cmpSize = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, false, function (entry) {
|
|
||||||
return $(entry).find(".size").data("bytes");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cmpNameRev = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, true, function (entry) {
|
|
||||||
return $(entry).find(".label").text().toLowerCase();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cmpTimeRev = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, true, function (entry) {
|
|
||||||
return $(entry).find(".date").data("time");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cmpSizeRev = function (entry1, entry2) {
|
|
||||||
|
|
||||||
return cmp(entry1, entry2, true, function (entry) {
|
|
||||||
return $(entry).find(".size").data("bytes");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
sort = function (fn) {
|
|
||||||
|
|
||||||
$("#extended .entry").detach().sort(fn).appendTo($("#extended > ul"));
|
|
||||||
},
|
|
||||||
$all, orders,
|
|
||||||
sortBy = function (id) {
|
|
||||||
|
|
||||||
var order = orders[id];
|
|
||||||
|
|
||||||
$all.removeClass("ascending").removeClass("descending");
|
|
||||||
order.head.addClass(order.clas);
|
|
||||||
sort(order.fn);
|
|
||||||
H5AI.core.hash({sort: id});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
var $ascending = $("<img src='" + H5AI.core.image("ascending") + "' class='sort ascending' alt='ascending' />"),
|
|
||||||
$descending = $("<img src='" + H5AI.core.image("descending") + "' class='sort descending' alt='descending' />"),
|
|
||||||
initialOrder = H5AI.core.hash('sort'),
|
|
||||||
$header = $("#extended li.header"),
|
|
||||||
$label = $header.find("a.label"),
|
|
||||||
$date = $header.find("a.date"),
|
|
||||||
$size = $header.find("a.size");
|
|
||||||
|
|
||||||
$all = $header.find("a.label,a.date,a.size");
|
|
||||||
orders = {
|
|
||||||
na: {
|
|
||||||
head: $label,
|
|
||||||
clas: "ascending",
|
|
||||||
fn: cmpName
|
|
||||||
},
|
|
||||||
nd: {
|
|
||||||
head: $label,
|
|
||||||
clas: "descending",
|
|
||||||
fn: cmpNameRev
|
|
||||||
},
|
|
||||||
da: {
|
|
||||||
head: $date,
|
|
||||||
clas: "ascending",
|
|
||||||
fn: cmpTime
|
|
||||||
},
|
|
||||||
dd: {
|
|
||||||
head: $date,
|
|
||||||
clas: "descending",
|
|
||||||
fn: cmpTimeRev
|
|
||||||
},
|
|
||||||
sa: {
|
|
||||||
head: $size,
|
|
||||||
clas: "ascending",
|
|
||||||
fn: cmpSize
|
|
||||||
},
|
|
||||||
sd: {
|
|
||||||
head: $size,
|
|
||||||
clas: "descending",
|
|
||||||
fn: cmpSizeRev
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sortBy(initialOrder ? initialOrder : H5AI.core.settings.sortorder);
|
|
||||||
|
|
||||||
$label
|
|
||||||
.append($ascending.clone()).append($descending.clone())
|
|
||||||
.click(function (event) {
|
|
||||||
sortBy("n" + ($label.hasClass("ascending") ? "d" : "a"));
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$date
|
|
||||||
.prepend($ascending.clone()).prepend($descending.clone())
|
|
||||||
.click(function (event) {
|
|
||||||
sortBy("d" + ($date.hasClass("ascending") ? "d" : "a"));
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$size
|
|
||||||
.prepend($ascending.clone()).prepend($descending.clone())
|
|
||||||
.click(function (event) {
|
|
||||||
sortBy("s" + ($size.hasClass("ascending") ? "d" : "a"));
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,120 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.util = (function () {
|
|
||||||
|
|
||||||
var reSplitPath = /^\/([^\/]+\/?)$/,
|
|
||||||
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
|
|
||||||
splitPath = function (pathname) {
|
|
||||||
|
|
||||||
var match;
|
|
||||||
|
|
||||||
if (pathname === "/") {
|
|
||||||
return {
|
|
||||||
parent: null,
|
|
||||||
parentname: null,
|
|
||||||
name: "/"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
match = reSplitPath2.exec(pathname);
|
|
||||||
if (match) {
|
|
||||||
return {
|
|
||||||
parent: match[1],
|
|
||||||
parentname: match[2],
|
|
||||||
name: match[3]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
match = reSplitPath.exec(pathname);
|
|
||||||
if (match) {
|
|
||||||
return {
|
|
||||||
parent: "/",
|
|
||||||
parentname: "/",
|
|
||||||
name: match[1]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rePathEndsWithSlash = /\/$/,
|
|
||||||
pathEndsWithSlash = function (pathname) {
|
|
||||||
|
|
||||||
return rePathEndsWithSlash.test(pathname);
|
|
||||||
},
|
|
||||||
getAbsHref = function (folder, tableRow) {
|
|
||||||
|
|
||||||
var $a, isParentFolder, href;
|
|
||||||
|
|
||||||
if (!pathEndsWithSlash(folder)) {
|
|
||||||
folder += "/";
|
|
||||||
}
|
|
||||||
if (!tableRow) {
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
$a = $(tableRow).find("td").eq(1).find("a");
|
|
||||||
isParentFolder = ($a.text() === "Parent Directory");
|
|
||||||
href = $a.attr("href");
|
|
||||||
return isParentFolder ? undefined : folder + href;
|
|
||||||
},
|
|
||||||
kilo = 1000.0,
|
|
||||||
reParseSize = /^\s*([\.\d]+)\s*([kmg]?)b?\s*$/i,
|
|
||||||
parseSize = function (str) {
|
|
||||||
|
|
||||||
var match = reParseSize.exec(str),
|
|
||||||
val, unit;
|
|
||||||
|
|
||||||
if (!match) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = parseFloat(match[1]);
|
|
||||||
unit = match[2].toLowerCase();
|
|
||||||
if (unit === "k") {
|
|
||||||
val *= kilo;
|
|
||||||
} else if (unit === "m") {
|
|
||||||
val *= kilo * kilo;
|
|
||||||
} else if (unit === "g") {
|
|
||||||
val *= kilo * kilo * kilo;
|
|
||||||
} else if (unit === "t") {
|
|
||||||
val *= kilo * kilo * kilo * kilo;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
},
|
|
||||||
sizeUnits = ["B", "KB", "MB", "GB", "TB"],
|
|
||||||
formatSize = function (size) {
|
|
||||||
|
|
||||||
var th = 1000.0,
|
|
||||||
i = 0,
|
|
||||||
maxI = sizeUnits.length - 1;
|
|
||||||
|
|
||||||
if (isNaN(size)) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (size >= th && i < maxI) {
|
|
||||||
size /= kilo;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + " " + sizeUnits[i];
|
|
||||||
},
|
|
||||||
checkedDecodeUri = function (uri) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
return decodeURI(uri);
|
|
||||||
} catch (err) {}
|
|
||||||
return uri;
|
|
||||||
},
|
|
||||||
reEscape = function (sequence) {
|
|
||||||
|
|
||||||
return sequence.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
splitPath: splitPath,
|
|
||||||
pathEndsWithSlash: pathEndsWithSlash,
|
|
||||||
getAbsHref: getAbsHref,
|
|
||||||
parseSize: parseSize,
|
|
||||||
formatSize: formatSize,
|
|
||||||
checkedDecodeUri: checkedDecodeUri,
|
|
||||||
reEscape: reEscape
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
(function ($, H5AI) {
|
|
||||||
|
|
||||||
H5AI.zippedDownload = (function () {
|
|
||||||
|
|
||||||
var x = 0,
|
|
||||||
y = 0,
|
|
||||||
$document = $(document),
|
|
||||||
$selectionRect = $("#selection-rect"),
|
|
||||||
selectedHrefsStr = "",
|
|
||||||
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
|
|
||||||
|
|
||||||
updateDownloadBtn = function () {
|
|
||||||
|
|
||||||
var $selected = $("#extended a.selected"),
|
|
||||||
$downloadBtn = $("#download");
|
|
||||||
|
|
||||||
selectedHrefsStr = "";
|
|
||||||
if ($selected.length) {
|
|
||||||
$selected.each(function () {
|
|
||||||
|
|
||||||
var href = $(this).attr("href");
|
|
||||||
selectedHrefsStr = selectedHrefsStr ? selectedHrefsStr + ":" + href : href;
|
|
||||||
});
|
|
||||||
$downloadBtn.show();
|
|
||||||
} else {
|
|
||||||
$downloadBtn.hide();
|
|
||||||
$downloadAuth.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectionUpdate = function (event) {
|
|
||||||
|
|
||||||
var l = Math.min(x, event.pageX),
|
|
||||||
t = Math.min(y, event.pageY),
|
|
||||||
w = Math.abs(x - event.pageX),
|
|
||||||
h = Math.abs(y - event.pageY),
|
|
||||||
selRect;
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
$selectionRect.css({left: l, top: t, width: w, height: h});
|
|
||||||
|
|
||||||
selRect = $selectionRect.fracs("rect");
|
|
||||||
$("#extended a").removeClass("selecting").each(function () {
|
|
||||||
|
|
||||||
var $a = $(this),
|
|
||||||
rect = $a.fracs("rect"),
|
|
||||||
inter = selRect.intersection(rect);
|
|
||||||
if (inter && !$a.closest(".entry").hasClass("folder-parent")) {
|
|
||||||
$a.addClass("selecting");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
selectionEnd = function (event) {
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
$document.off("mousemove", selectionUpdate);
|
|
||||||
$selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
|
|
||||||
$("#extended a.selecting.selected").removeClass("selecting").removeClass("selected");
|
|
||||||
$("#extended a.selecting").removeClass("selecting").addClass("selected");
|
|
||||||
updateDownloadBtn();
|
|
||||||
},
|
|
||||||
selectionStart = function (event) {
|
|
||||||
|
|
||||||
var view = $.fracs.viewport();
|
|
||||||
|
|
||||||
x = event.pageX;
|
|
||||||
y = event.pageY;
|
|
||||||
// only on left button and don't block the scrollbars
|
|
||||||
if (event.button !== 0 || x >= view.right || y >= view.bottom) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
$(':focus').blur();
|
|
||||||
if (!event.ctrlKey) {
|
|
||||||
$("#extended a").removeClass("selected");
|
|
||||||
updateDownloadBtn();
|
|
||||||
}
|
|
||||||
$selectionRect.show().css({left: x, top: y, width: 0, height: 0});
|
|
||||||
|
|
||||||
$document
|
|
||||||
.on("mousemove", selectionUpdate)
|
|
||||||
.one("mouseup", selectionEnd);
|
|
||||||
},
|
|
||||||
noSelection = function (event) {
|
|
||||||
|
|
||||||
event.stopImmediatePropagation();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
noSelectionUnlessCtrl = function (event) {
|
|
||||||
|
|
||||||
if (!event.ctrlKey) {
|
|
||||||
noSelection(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
failed = function () {
|
|
||||||
|
|
||||||
$download.addClass('failed');
|
|
||||||
setTimeout(function () {
|
|
||||||
$download.removeClass('failed');
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
handleResponse = function (response) {
|
|
||||||
|
|
||||||
|
|
||||||
$download.removeClass('current');
|
|
||||||
$img.attr('src', H5AI.core.image("download"));
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
if (response.status === 'ok') {
|
|
||||||
window.location = H5AI.core.api() + '?action=getzip&id=' + response.id;
|
|
||||||
} else {
|
|
||||||
if (response.code === 401) {
|
|
||||||
$downloadAuth
|
|
||||||
.css({
|
|
||||||
left: $download.offset().left,
|
|
||||||
top: $download.offset().top + $download.outerHeight()
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
$downloadUser.focus();
|
|
||||||
}
|
|
||||||
failed();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
failed();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
requestZipping = function (hrefsStr) {
|
|
||||||
|
|
||||||
$download.addClass('current');
|
|
||||||
$img.attr('src', H5AI.core.image("loading.gif", true));
|
|
||||||
$.ajax({
|
|
||||||
url: H5AI.core.api(),
|
|
||||||
data: {
|
|
||||||
action: 'zip',
|
|
||||||
hrefs: selectedHrefsStr
|
|
||||||
},
|
|
||||||
type: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
beforeSend: function (xhr) {
|
|
||||||
|
|
||||||
var user = $downloadUser.val(),
|
|
||||||
password = $downloadPassword.val();
|
|
||||||
|
|
||||||
if (user) {
|
|
||||||
xhr.setRequestHeader ('Authorization', 'Basic ' + Base64.encode(user + ':' + password));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
success: function (response) {
|
|
||||||
|
|
||||||
handleResponse(response);
|
|
||||||
},
|
|
||||||
failed: function () {
|
|
||||||
|
|
||||||
handleResponse();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
if (H5AI.core.settings.zippedDownload) {
|
|
||||||
$("<li id='download'><a href='#'><img alt='download' /><span class='l10n-download'>download</span></a></li>")
|
|
||||||
.find("img").attr("src", H5AI.core.image("download")).end()
|
|
||||||
.find("a").click(function (event) {
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
$downloadAuth.hide();
|
|
||||||
requestZipping(selectedHrefsStr);
|
|
||||||
}).end()
|
|
||||||
.appendTo($("#navbar"));
|
|
||||||
$("<div id='download-auth'><input id='download-auth-user' type='text' value='' placeholder='user' /><input id='download-auth-password' type='text' value='' placeholder='password' /></div>")
|
|
||||||
.appendTo($("body"));
|
|
||||||
|
|
||||||
$download = $('#download');
|
|
||||||
$downloadAuth = $('#download-auth');
|
|
||||||
$downloadUser = $('#download-auth-user');
|
|
||||||
$downloadPassword = $('#download-auth-password');
|
|
||||||
$img = $download.find('img');
|
|
||||||
|
|
||||||
$("body>nav,body>footer,#tree,input").on("mousedown", noSelection);
|
|
||||||
$("#content").on("mousedown", "a", noSelectionUnlessCtrl);
|
|
||||||
$document.on("mousedown", selectionStart);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
}(jQuery, H5AI));
|
|
16
src/_h5ai/js/inc/core/entry.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
module.define('core/entry', [jQuery, 'core/parser', 'model/entry'], function ($, parser, Entry) {
|
||||||
|
|
||||||
|
var absHref = document.location.pathname;
|
||||||
|
|
||||||
|
parser.parse(absHref, $('body'));
|
||||||
|
$('#data-apache-autoindex').remove();
|
||||||
|
|
||||||
|
var entry = Entry.get(absHref);
|
||||||
|
entry.status = 'h5ai';
|
||||||
|
if (entry.parent) {
|
||||||
|
entry.parent.isParentFolder = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
});
|
25
src/_h5ai/js/inc/core/event.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
module.define('core/event', [amplify], function (amplify) {
|
||||||
|
|
||||||
|
var sub = function (topic, callback) {
|
||||||
|
|
||||||
|
amplify.subscribe(topic, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
unsub = function (topic, callback) {
|
||||||
|
|
||||||
|
amplify.unsubscribe(topic, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
pub = function (topic, data) {
|
||||||
|
|
||||||
|
// console.log('EVENT PUB', topic, data);
|
||||||
|
amplify.publish(topic, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
sub: sub,
|
||||||
|
unsub: unsub,
|
||||||
|
pub: pub
|
||||||
|
};
|
||||||
|
});
|
80
src/_h5ai/js/inc/core/format.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
module.define('core/format', [moment], function (moment) {
|
||||||
|
|
||||||
|
var reParseSize = /^\s*([\.\d]+)\s*([kmgt]?)b?\s*$/i,
|
||||||
|
treshhold = 1000.0,
|
||||||
|
kilo = 1000.0,
|
||||||
|
sizeUnits = ['B', 'KB', 'MB', 'GB', 'TB'],
|
||||||
|
|
||||||
|
parseSize = function (str) {
|
||||||
|
|
||||||
|
var match = reParseSize.exec(str),
|
||||||
|
val, unit;
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = parseFloat(match[1]);
|
||||||
|
unit = match[2].toLowerCase();
|
||||||
|
if (unit === 'k') {
|
||||||
|
val *= kilo;
|
||||||
|
} else if (unit === 'm') {
|
||||||
|
val *= kilo * kilo;
|
||||||
|
} else if (unit === 'g') {
|
||||||
|
val *= kilo * kilo * kilo;
|
||||||
|
} else if (unit === 't') {
|
||||||
|
val *= kilo * kilo * kilo * kilo;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatSize = function (size) {
|
||||||
|
|
||||||
|
if (!_.isNumber(size) || size < 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0,
|
||||||
|
maxI = sizeUnits.length - 1;
|
||||||
|
|
||||||
|
while (size >= treshhold && i < maxI) {
|
||||||
|
size /= kilo;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + sizeUnits[i];
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultDateFormat = 'YYYY-MM-DD HH:mm',
|
||||||
|
|
||||||
|
setDefaultDateFormat = function (dateFormat) {
|
||||||
|
|
||||||
|
defaultDateFormat = dateFormat;
|
||||||
|
},
|
||||||
|
|
||||||
|
parseDate = function (str, dateFormat) {
|
||||||
|
|
||||||
|
try { // problems with ie < 9 :(
|
||||||
|
return moment(str, dateFormat || defaultDateFormat).valueOf() || null;
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
return Date.parse(str).valueOf() || null;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatDate = function (millis, dateFormat) {
|
||||||
|
|
||||||
|
if (!_.isNumber(millis) || !millis) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return moment(millis).format(dateFormat || defaultDateFormat);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
parseSize: parseSize,
|
||||||
|
formatSize: formatSize,
|
||||||
|
setDefaultDateFormat: setDefaultDateFormat,
|
||||||
|
parseDate: parseDate,
|
||||||
|
formatDate: formatDate
|
||||||
|
};
|
||||||
|
});
|
9
src/_h5ai/js/inc/core/parser.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
module.define('core/parser', [jQuery], function ($) {
|
||||||
|
|
||||||
|
if ($('#data-generic-json').length) {
|
||||||
|
return module.require('parser/generic-json');
|
||||||
|
}
|
||||||
|
|
||||||
|
return module.require('parser/apache-autoindex');
|
||||||
|
});
|
22
src/_h5ai/js/inc/core/resource.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
module.define('core/resource', ['core/settings'], function (settings) {
|
||||||
|
|
||||||
|
var api = function () {
|
||||||
|
|
||||||
|
return settings.h5aiAbsHref + 'php/api.php';
|
||||||
|
},
|
||||||
|
image = function (id, noPngExt) {
|
||||||
|
|
||||||
|
return settings.h5aiAbsHref + 'images/' + id + (noPngExt ? '' : '.png');
|
||||||
|
},
|
||||||
|
icon = function (id, big) {
|
||||||
|
|
||||||
|
return settings.h5aiAbsHref + 'icons/' + (big ? '48x48' : '16x16') + '/' + id + '.png';
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
api: api,
|
||||||
|
image: image,
|
||||||
|
icon: icon
|
||||||
|
};
|
||||||
|
});
|
93
src/_h5ai/js/inc/core/settings.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
module.define('core/settings', [H5AI_CONFIG], function (config) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
rootAbsHref: '/',
|
||||||
|
h5aiAbsHref: '/_h5ai/'
|
||||||
|
};
|
||||||
|
|
||||||
|
return _.extend({}, defaults, config.options);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.define('core/types', [H5AI_CONFIG], function (config) {
|
||||||
|
|
||||||
|
var reEndsWithSlash = /\/$/,
|
||||||
|
reStartsWithDot = /^\./,
|
||||||
|
|
||||||
|
fileExts = {},
|
||||||
|
fileNames = {},
|
||||||
|
|
||||||
|
parse = function (types) {
|
||||||
|
|
||||||
|
_.each(types, function (matches, type) {
|
||||||
|
|
||||||
|
_.each(matches, function (match) {
|
||||||
|
|
||||||
|
match = match.toLowerCase();
|
||||||
|
|
||||||
|
if (reStartsWithDot.test(match)) {
|
||||||
|
fileExts[match] = type;
|
||||||
|
} else {
|
||||||
|
fileNames[match] = type;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getType = function (sequence) {
|
||||||
|
|
||||||
|
if (reEndsWithSlash.test(sequence)) {
|
||||||
|
return 'folder';
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence = sequence.toLowerCase();
|
||||||
|
|
||||||
|
var slashidx = sequence.lastIndexOf('/'),
|
||||||
|
name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence,
|
||||||
|
dotidx = sequence.lastIndexOf('.'),
|
||||||
|
ext = dotidx >= 0 ? sequence.substr(dotidx) : sequence;
|
||||||
|
|
||||||
|
return fileNames[name] || fileExts[ext] || 'unknown';
|
||||||
|
};
|
||||||
|
|
||||||
|
parse(_.extend({}, config.types));
|
||||||
|
|
||||||
|
return {
|
||||||
|
getType: getType
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.define('core/langs', [H5AI_CONFIG], function (config) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
lang: 'unknown',
|
||||||
|
details: 'details',
|
||||||
|
icons: 'icons',
|
||||||
|
name: 'Name',
|
||||||
|
lastModified: 'Last modified',
|
||||||
|
size: 'Size',
|
||||||
|
parentDirectory: 'Parent Directory',
|
||||||
|
empty: 'empty',
|
||||||
|
folders: 'folders',
|
||||||
|
files: 'files',
|
||||||
|
download: 'download',
|
||||||
|
noMatch: 'no match',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm'
|
||||||
|
},
|
||||||
|
|
||||||
|
translations = {},
|
||||||
|
|
||||||
|
parse = function (langs) {
|
||||||
|
|
||||||
|
_.each(langs, function (trans, lang) {
|
||||||
|
|
||||||
|
translations[lang] = _.extend({}, defaults, trans);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
parse(_.extend({}, config.langs));
|
||||||
|
|
||||||
|
return translations;
|
||||||
|
});
|
18
src/_h5ai/js/inc/core/store.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
module.define('core/store', [amplify], function (amplify) {
|
||||||
|
|
||||||
|
var put = function (key, value) {
|
||||||
|
|
||||||
|
amplify.store(key, value);
|
||||||
|
},
|
||||||
|
|
||||||
|
get = function (key) {
|
||||||
|
|
||||||
|
return amplify.store(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
put: put,
|
||||||
|
get: get
|
||||||
|
};
|
||||||
|
});
|
84
src/_h5ai/js/inc/ext/crumb.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
module.define('ext/crumb', [jQuery, 'core/settings', 'core/resource', 'core/entry'], function ($, allsettings, resource, entry) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.crumb),
|
||||||
|
|
||||||
|
template = '<li class="crumb">' +
|
||||||
|
'<a>' +
|
||||||
|
'<img src="' + resource.image('crumb') + '" alt=">" />' +
|
||||||
|
'<span />' +
|
||||||
|
'</a>' +
|
||||||
|
'</li>',
|
||||||
|
pageHintTemplate = '<img class="hint" src="' + resource.image('page') + '" alt="has index page" />',
|
||||||
|
statusHintTemplate = '<span class="hint"></span>',
|
||||||
|
|
||||||
|
// updates the crumb for this single entry
|
||||||
|
update = function (entry) {
|
||||||
|
|
||||||
|
if (entry.$crumb && entry.$crumb.data('status') === entry.status) {
|
||||||
|
return entry.$crumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $html = $(template),
|
||||||
|
$a = $html.find('a');
|
||||||
|
|
||||||
|
$html
|
||||||
|
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||||
|
.data('status', entry.status);
|
||||||
|
|
||||||
|
$a
|
||||||
|
.attr('href', entry.absHref)
|
||||||
|
.find('span').text(entry.label).end();
|
||||||
|
|
||||||
|
if (entry.isDomain()) {
|
||||||
|
$html.addClass('domain');
|
||||||
|
$a.find('img').attr('src', resource.image('home'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.isCurrentFolder()) {
|
||||||
|
$html.addClass('current');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isNumber(entry.status)) {
|
||||||
|
if (entry.status === 200) {
|
||||||
|
$a.append($(pageHintTemplate));
|
||||||
|
} else {
|
||||||
|
$a.append($(statusHintTemplate).text('(' + entry.status + ')'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.$crumb) {
|
||||||
|
entry.$crumb.replaceWith($html);
|
||||||
|
}
|
||||||
|
entry.$crumb = $html;
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
},
|
||||||
|
|
||||||
|
// creates the complete crumb from entry down to the root
|
||||||
|
init = function (entry) {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var crumb = entry.getCrumb(),
|
||||||
|
$ul = $('#navbar');
|
||||||
|
|
||||||
|
_.each(crumb, function (e) {
|
||||||
|
|
||||||
|
$ul.append(update(e));
|
||||||
|
|
||||||
|
e.fetchStatus(function (e) {
|
||||||
|
|
||||||
|
update(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry);
|
||||||
|
});
|
42
src/_h5ai/js/inc/ext/custom.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
module.define('ext/custom', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
header: '_h5ai.header.html',
|
||||||
|
footer: '_h5ai.footer.html'
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.custom),
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isString(settings.header)) {
|
||||||
|
$.ajax({
|
||||||
|
url: settings.header,
|
||||||
|
dataType: 'html',
|
||||||
|
success: function (data) {
|
||||||
|
|
||||||
|
$('<div id="content-header">' + data + '</div>').prependTo('#content');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isString(settings.footer)) {
|
||||||
|
$.ajax({
|
||||||
|
url: settings.footer,
|
||||||
|
dataType: 'html',
|
||||||
|
success: function (data) {
|
||||||
|
|
||||||
|
$('<div id="content-footer">' + data + '</div>').appendTo('#content');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
137
src/_h5ai/js/inc/ext/download.js
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
module.define('ext/download', [jQuery, 'core/settings', 'core/resource', 'core/event'], function ($, allsettings, resource, event) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
execution: 'php',
|
||||||
|
format: 'zip'
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.download),
|
||||||
|
|
||||||
|
formats = ['tar', 'zip'],
|
||||||
|
|
||||||
|
downloadBtnTemplate = '<li id="download">' +
|
||||||
|
'<a href="#">' +
|
||||||
|
'<img src="' + resource.image('download') + '" alt="download" />' +
|
||||||
|
'<span class="l10n-download">download</span>' +
|
||||||
|
'</a>' +
|
||||||
|
'</li>',
|
||||||
|
authTemplate = '<div id="download-auth">' +
|
||||||
|
'<input id="download-auth-user" type="text" value="" placeholder="user" />' +
|
||||||
|
'<input id="download-auth-password" type="text" value="" placeholder="password" />' +
|
||||||
|
'</div>',
|
||||||
|
|
||||||
|
selectedHrefsStr = '',
|
||||||
|
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
|
||||||
|
|
||||||
|
failed = function () {
|
||||||
|
|
||||||
|
$download.addClass('failed');
|
||||||
|
setTimeout(function () {
|
||||||
|
$download.removeClass('failed');
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleResponse = function (response) {
|
||||||
|
|
||||||
|
$download.removeClass('current');
|
||||||
|
$img.attr('src', resource.image('download'));
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
if (response.code === 0) {
|
||||||
|
setTimeout(function () { // wait here so the img above can be updated in time
|
||||||
|
|
||||||
|
window.location = resource.api() + '?action=getarchive&id=' + response.id + '&as=h5ai-selection.' + settings.format;
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
if (response.code === 401) {
|
||||||
|
$downloadAuth
|
||||||
|
.css({
|
||||||
|
left: $download.offset().left,
|
||||||
|
top: $download.offset().top + $download.outerHeight()
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
$downloadUser.focus();
|
||||||
|
}
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
requestArchive = function (hrefsStr) {
|
||||||
|
|
||||||
|
$download.addClass('current');
|
||||||
|
$img.attr('src', resource.image('loading.gif', true));
|
||||||
|
$.ajax({
|
||||||
|
url: resource.api(),
|
||||||
|
data: {
|
||||||
|
action: 'archive',
|
||||||
|
execution: settings.execution,
|
||||||
|
format: settings.format,
|
||||||
|
hrefs: hrefsStr
|
||||||
|
},
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
|
||||||
|
var user = $downloadUser.val(),
|
||||||
|
password = $downloadPassword.val();
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
xhr.setRequestHeader('Authorization', 'Basic ' + Base64.encode(user + ':' + password));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: function (response) {
|
||||||
|
|
||||||
|
handleResponse(response);
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
|
||||||
|
handleResponse();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelection = function (entries) {
|
||||||
|
|
||||||
|
selectedHrefsStr = '';
|
||||||
|
if (entries.length) {
|
||||||
|
selectedHrefsStr = _.map(entries, function (entry) {
|
||||||
|
|
||||||
|
return entry.absHref;
|
||||||
|
}).join(':');
|
||||||
|
$download.appendTo('#navbar').show();
|
||||||
|
} else {
|
||||||
|
$download.hide();
|
||||||
|
$downloadAuth.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$download = $(downloadBtnTemplate)
|
||||||
|
.find('a').on('click', function (event) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
$downloadAuth.hide();
|
||||||
|
requestArchive(selectedHrefsStr);
|
||||||
|
}).end()
|
||||||
|
.appendTo('#navbar');
|
||||||
|
$img = $download.find('img');
|
||||||
|
|
||||||
|
$downloadAuth = $(authTemplate).appendTo('body');
|
||||||
|
$downloadUser = $downloadAuth.find('#download-auth-user');
|
||||||
|
$downloadPassword = $downloadAuth.find('#download-auth-password');
|
||||||
|
|
||||||
|
event.sub('selection', onSelection);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
123
src/_h5ai/js/inc/ext/filter.js
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
module.define('ext/filter', [jQuery, 'core/settings', 'core/resource'], function ($, allsettings, resource) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.filter),
|
||||||
|
|
||||||
|
template = '<li id="filter">' +
|
||||||
|
'<span class="element">' +
|
||||||
|
'<img src="' + resource.image('filter') + '" alt="filter" />' +
|
||||||
|
'<input type="text" value="" placeholder="filter" />' +
|
||||||
|
'</span>' +
|
||||||
|
'</li>',
|
||||||
|
noMatchTemplate = '<div class="no-match l10n-noMatch">no match</div>',
|
||||||
|
|
||||||
|
$filter, $input, $noMatch,
|
||||||
|
|
||||||
|
filter = function (re) {
|
||||||
|
|
||||||
|
var match = [],
|
||||||
|
noMatch = [],
|
||||||
|
duration = 200;
|
||||||
|
|
||||||
|
if (re) {
|
||||||
|
$('#extended .entry').each(function () {
|
||||||
|
|
||||||
|
var label = $(this).find('.label').text();
|
||||||
|
|
||||||
|
if (label.match(re)) {
|
||||||
|
match.push(this);
|
||||||
|
} else {
|
||||||
|
noMatch.push(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
match = $('#extended .entry');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($(match).length) {
|
||||||
|
$noMatch.hide();
|
||||||
|
} else {
|
||||||
|
setTimeout(function () { $noMatch.show(); }, duration);
|
||||||
|
}
|
||||||
|
$(match).fadeIn(duration);
|
||||||
|
$(noMatch).fadeOut(duration);
|
||||||
|
},
|
||||||
|
|
||||||
|
checkState = function (focus) {
|
||||||
|
|
||||||
|
var val = $input.val();
|
||||||
|
|
||||||
|
if (val || focus) {
|
||||||
|
$filter.addClass('current');
|
||||||
|
} else {
|
||||||
|
$filter.removeClass('current');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
escapeRegExp = function (sequence) {
|
||||||
|
|
||||||
|
return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&');
|
||||||
|
// return sequence.replace(/[|()\[{.+*?^$\\]/g,"\\$0");
|
||||||
|
},
|
||||||
|
|
||||||
|
parseFilterSequence = function (sequence) {
|
||||||
|
|
||||||
|
if (sequence.substr(0, 3) === 're:') {
|
||||||
|
return new RegExp(sequence.substr(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence = $.map($.trim(sequence).split(/\s+/), function (part) {
|
||||||
|
|
||||||
|
return escapeRegExp(part);
|
||||||
|
}).join('|');
|
||||||
|
|
||||||
|
return new RegExp(sequence);
|
||||||
|
},
|
||||||
|
|
||||||
|
update = function () {
|
||||||
|
|
||||||
|
var val = $input.val();
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
filter(parseFilterSequence(val));
|
||||||
|
} else {
|
||||||
|
filter();
|
||||||
|
}
|
||||||
|
checkState($input.is(':focus'));
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter = $(template);
|
||||||
|
$input = $filter.find('input');
|
||||||
|
$noMatch = $(noMatchTemplate).appendTo('#extended');
|
||||||
|
|
||||||
|
$filter
|
||||||
|
.on('click', function () {
|
||||||
|
|
||||||
|
$input.focus();
|
||||||
|
})
|
||||||
|
.appendTo('#navbar');
|
||||||
|
|
||||||
|
$input
|
||||||
|
.on('focus', function () {
|
||||||
|
|
||||||
|
checkState(true);
|
||||||
|
})
|
||||||
|
.on('blur', function () {
|
||||||
|
|
||||||
|
checkState(false);
|
||||||
|
})
|
||||||
|
.on('keyup', update);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
14
src/_h5ai/js/inc/ext/folderstatus.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
module.define('ext/folderstatus', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: true,
|
||||||
|
folders: {}
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.folderstatus),
|
||||||
|
|
||||||
|
folders = settings.enabled ? settings.folders : defaults.folders;
|
||||||
|
|
||||||
|
return folders;
|
||||||
|
});
|
117
src/_h5ai/js/inc/ext/l10n.js
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
module.define('ext/l10n', [jQuery, 'core/settings', 'core/langs', 'core/format', 'core/store'], function ($, allsettings, langs, format, store) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: true,
|
||||||
|
lang: 'en',
|
||||||
|
useBrowserLang: true
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.l10n),
|
||||||
|
|
||||||
|
template = '<span id="langSelector">' +
|
||||||
|
'<span class="lang">en</span> - <span class="l10n-lang">english</span>' +
|
||||||
|
'<span class="langOptions"> <ul /> </span>' +
|
||||||
|
'</span>',
|
||||||
|
langOptionTemplate = '<li class="langOption" />',
|
||||||
|
|
||||||
|
storekey = 'h5ai.language',
|
||||||
|
|
||||||
|
currentLang = null,
|
||||||
|
|
||||||
|
localize = function (langs, lang, useBrowserLang) {
|
||||||
|
|
||||||
|
var storedLang = store.get(storekey),
|
||||||
|
browserLang, key;
|
||||||
|
|
||||||
|
if (langs[storedLang]) {
|
||||||
|
lang = storedLang;
|
||||||
|
} else if (useBrowserLang) {
|
||||||
|
browserLang = navigator.language || navigator.browserLanguage;
|
||||||
|
if (browserLang) {
|
||||||
|
if (langs[browserLang]) {
|
||||||
|
lang = browserLang;
|
||||||
|
} else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
|
||||||
|
lang = browserLang.substr(0, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!langs[lang]) {
|
||||||
|
lang = 'en';
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLang = langs[lang];
|
||||||
|
if (currentLang) {
|
||||||
|
$.each(currentLang, function (key, value) {
|
||||||
|
$('.l10n-' + key).text(value);
|
||||||
|
});
|
||||||
|
$('.lang').text(lang);
|
||||||
|
$('.langOption').removeClass('current');
|
||||||
|
$('.langOption.' + lang).addClass('current');
|
||||||
|
}
|
||||||
|
|
||||||
|
format.setDefaultDateFormat(currentLang.dateFormat);
|
||||||
|
|
||||||
|
$('#extended .entry .date').each(function () {
|
||||||
|
|
||||||
|
var $this = $(this);
|
||||||
|
|
||||||
|
$this.text(format.formatDate($this.data('time')));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
initLangSelector = function (langs) {
|
||||||
|
|
||||||
|
var $langSelector = $(template).appendTo('#bottombar .right'),
|
||||||
|
$langOptions = $langSelector.find('.langOptions'),
|
||||||
|
$ul = $langOptions.find('ul'),
|
||||||
|
sortedLangsKeys = [];
|
||||||
|
|
||||||
|
$.each(langs, function (lang) {
|
||||||
|
sortedLangsKeys.push(lang);
|
||||||
|
});
|
||||||
|
sortedLangsKeys.sort();
|
||||||
|
|
||||||
|
$.each(sortedLangsKeys, function (idx, lang) {
|
||||||
|
$(langOptionTemplate)
|
||||||
|
.addClass(lang)
|
||||||
|
.text(lang + ' - ' + langs[lang].lang)
|
||||||
|
.appendTo($ul)
|
||||||
|
.click(function () {
|
||||||
|
store.put(storekey, lang);
|
||||||
|
localize(langs, lang, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$langOptions
|
||||||
|
.append($ul)
|
||||||
|
.scrollpanel();
|
||||||
|
|
||||||
|
$langSelector.hover(
|
||||||
|
function () {
|
||||||
|
$langOptions
|
||||||
|
.css('top', '-' + $langOptions.outerHeight() + 'px')
|
||||||
|
.stop(true, true)
|
||||||
|
.fadeIn();
|
||||||
|
$langOptions.get(0).updateScrollbar();
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$langOptions
|
||||||
|
.stop(true, true)
|
||||||
|
.fadeOut();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
initLangSelector(langs);
|
||||||
|
localize(langs, settings.lang, settings.useBrowserLang);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
44
src/_h5ai/js/inc/ext/link-hover-states.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
module.define('ext/link-hover-states', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings['link-hover-states']),
|
||||||
|
|
||||||
|
selector = "a[href^='/']",
|
||||||
|
|
||||||
|
selectLinks = function (href) {
|
||||||
|
|
||||||
|
return $(_.filter($(selector), function (el) {
|
||||||
|
|
||||||
|
return $(el).attr('href') === href;
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseEnter = function () {
|
||||||
|
|
||||||
|
var href = $(this).attr('href');
|
||||||
|
|
||||||
|
selectLinks(href).addClass('hover');
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseLeave = function () {
|
||||||
|
|
||||||
|
var href = $(this).attr('href');
|
||||||
|
|
||||||
|
selectLinks(href).removeClass('hover');
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (settings.enabled) {
|
||||||
|
$('body')
|
||||||
|
.on('mouseenter', selector, onMouseEnter)
|
||||||
|
.on('mouseleave', selector, onMouseLeave);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
56
src/_h5ai/js/inc/ext/qrcode.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
module.define('ext/qrcode', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
size: 150
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.qrcode),
|
||||||
|
|
||||||
|
template = '<div id="context"><div class="qrcode" /></div>',
|
||||||
|
|
||||||
|
$context, hideTimeoutId,
|
||||||
|
|
||||||
|
update = function (entry) {
|
||||||
|
|
||||||
|
$context.find('.qrcode').empty().qrcode({
|
||||||
|
render: Modernizr.canvas ? 'canvas' : 'div',
|
||||||
|
width: settings.size,
|
||||||
|
height: settings.size,
|
||||||
|
color: '#333',
|
||||||
|
text: 'http://' + document.domain + entry.absHref
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseenter = function (entry) {
|
||||||
|
|
||||||
|
if (!entry.isFolder()) {
|
||||||
|
update(entry);
|
||||||
|
clearTimeout(hideTimeoutId);
|
||||||
|
$context.stop(true, true).fadeIn(400);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseleave = function (entry) {
|
||||||
|
|
||||||
|
hideTimeoutId = setTimeout(function () {
|
||||||
|
|
||||||
|
$context.stop(true, true).fadeOut(400);
|
||||||
|
}, 200);
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$context = $(template).appendTo('body');
|
||||||
|
|
||||||
|
event.sub('entry.mouseenter', onMouseenter);
|
||||||
|
event.sub('entry.mouseleave', onMouseleave);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
123
src/_h5ai/js/inc/ext/select.js
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
module.define('ext/select', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.select),
|
||||||
|
|
||||||
|
x = 0, y = 0,
|
||||||
|
l = 0, t = 0, w = 0, h = 0,
|
||||||
|
shrink = 1/3,
|
||||||
|
$document = $(document),
|
||||||
|
$selectionRect = $('<div id="selection-rect"></div>'),
|
||||||
|
|
||||||
|
publish = function () {
|
||||||
|
|
||||||
|
var entries = _.map($('#extended .entry.selected'), function (entryElement) {
|
||||||
|
|
||||||
|
return $(entryElement).data('entry');
|
||||||
|
});
|
||||||
|
|
||||||
|
event.pub('selection', entries);
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionUpdate = function (event) {
|
||||||
|
|
||||||
|
l = Math.min(x, event.pageX);
|
||||||
|
t = Math.min(y, event.pageY);
|
||||||
|
w = Math.abs(x - event.pageX);
|
||||||
|
h = Math.abs(y - event.pageY);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
$selectionRect
|
||||||
|
.stop(true, true)
|
||||||
|
.css({left: l, top: t, width: w, height: h});
|
||||||
|
|
||||||
|
var selRect = $selectionRect.fracs('rect');
|
||||||
|
$('#extended .entry').removeClass('selecting').each(function () {
|
||||||
|
|
||||||
|
var $entry = $(this),
|
||||||
|
rect = $entry.find('a').fracs('rect'),
|
||||||
|
inter = selRect.intersection(rect);
|
||||||
|
if (inter && !$entry.hasClass('folder-parent')) {
|
||||||
|
$entry.addClass('selecting');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionEnd = function (event) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
$document.off('mousemove', selectionUpdate);
|
||||||
|
$('#extended .entry.selecting.selected').removeClass('selecting').removeClass('selected');
|
||||||
|
$('#extended .entry.selecting').removeClass('selecting').addClass('selected');
|
||||||
|
publish();
|
||||||
|
|
||||||
|
$selectionRect
|
||||||
|
.stop(true, true)
|
||||||
|
.animate({left: l + w * 0.5 * shrink, top: t + h * 0.5 * shrink, width: w * (1 - shrink), height: h * (1 - shrink), opacity: 0}, 300);
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionStart = function (event) {
|
||||||
|
|
||||||
|
var view = $(document).fracs('viewport');
|
||||||
|
|
||||||
|
x = event.pageX;
|
||||||
|
y = event.pageY;
|
||||||
|
l = x;
|
||||||
|
t = y;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
|
||||||
|
// only on left button and don't block the scrollbars
|
||||||
|
if (event.button !== 0 || l >= view.right || t >= view.bottom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
$(':focus').blur();
|
||||||
|
if (!event.ctrlKey) {
|
||||||
|
$('#extended .entry').removeClass('selected');
|
||||||
|
publish();
|
||||||
|
}
|
||||||
|
$selectionRect
|
||||||
|
.stop(true, true)
|
||||||
|
.css({left: l, top: t, width: w, height: h, opacity: 1})
|
||||||
|
.show();
|
||||||
|
|
||||||
|
$document
|
||||||
|
.on('mousemove', selectionUpdate)
|
||||||
|
.one('mouseup', selectionEnd);
|
||||||
|
},
|
||||||
|
|
||||||
|
noSelection = function (event) {
|
||||||
|
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
noSelectionUnlessCtrl = function (event) {
|
||||||
|
|
||||||
|
if (!event.ctrlKey) {
|
||||||
|
noSelection(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectionRect.hide().appendTo('body');
|
||||||
|
|
||||||
|
$document
|
||||||
|
.on('mousedown', '.noSelection', noSelection)
|
||||||
|
.on('mousedown', '.noSelectionUnlessCtrl,input,a', noSelectionUnlessCtrl)
|
||||||
|
.on('mousedown', selectionStart);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
145
src/_h5ai/js/inc/ext/sort.js
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
module.define('ext/sort', [jQuery, 'core/settings', 'core/resource', 'core/store'], function ($, allsettings, resource, store) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
order: 'na'
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.sort),
|
||||||
|
|
||||||
|
storekey = 'h5ai.sortorder',
|
||||||
|
|
||||||
|
type = function (entry) {
|
||||||
|
|
||||||
|
var $entry = $(entry);
|
||||||
|
|
||||||
|
if ($entry.hasClass('folder-parent')) {
|
||||||
|
return 0;
|
||||||
|
} else if ($entry.hasClass('folder')) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
cmpFn = function (rev, getVal) {
|
||||||
|
|
||||||
|
return function (entry1, entry2) {
|
||||||
|
|
||||||
|
var res, val1, val2;
|
||||||
|
|
||||||
|
res = type(entry1) - type(entry2);
|
||||||
|
if (res !== 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
val1 = getVal(entry1);
|
||||||
|
val2 = getVal(entry2);
|
||||||
|
if (val1 < val2) {
|
||||||
|
return rev ? 1 : -1;
|
||||||
|
} else if (val1 > val2) {
|
||||||
|
return rev ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getName = function (entry) {
|
||||||
|
|
||||||
|
return $(entry).find('.label').text().toLowerCase();
|
||||||
|
},
|
||||||
|
getTime = function (entry) {
|
||||||
|
|
||||||
|
return $(entry).find('.date').data('time');
|
||||||
|
},
|
||||||
|
getSize = function (entry) {
|
||||||
|
|
||||||
|
return $(entry).find('.size').data('bytes');
|
||||||
|
},
|
||||||
|
|
||||||
|
$all, orders,
|
||||||
|
|
||||||
|
sortBy = function (id) {
|
||||||
|
|
||||||
|
var order = orders[id];
|
||||||
|
|
||||||
|
store.put(storekey, id);
|
||||||
|
|
||||||
|
$all.removeClass('ascending').removeClass('descending');
|
||||||
|
order.head.addClass(order.clas);
|
||||||
|
$('#extended .entry').detach().sort(order.fn).appendTo('#extended > ul');
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $ascending = $('<img src="' + resource.image('ascending') + '" class="sort ascending" alt="ascending" />'),
|
||||||
|
$descending = $('<img src="' + resource.image('descending') + '" class="sort descending" alt="descending" />'),
|
||||||
|
$header = $('#extended li.header'),
|
||||||
|
$label = $header.find('a.label'),
|
||||||
|
$date = $header.find('a.date'),
|
||||||
|
$size = $header.find('a.size');
|
||||||
|
|
||||||
|
$all = $header.find('a.label,a.date,a.size');
|
||||||
|
orders = {
|
||||||
|
na: {
|
||||||
|
head: $label,
|
||||||
|
clas: 'ascending',
|
||||||
|
fn: cmpFn(false, getName)
|
||||||
|
},
|
||||||
|
nd: {
|
||||||
|
head: $label,
|
||||||
|
clas: 'descending',
|
||||||
|
fn: cmpFn(true, getName)
|
||||||
|
},
|
||||||
|
da: {
|
||||||
|
head: $date,
|
||||||
|
clas: 'ascending',
|
||||||
|
fn: cmpFn(false, getTime)
|
||||||
|
},
|
||||||
|
dd: {
|
||||||
|
head: $date,
|
||||||
|
clas: 'descending',
|
||||||
|
fn: cmpFn(true, getTime)
|
||||||
|
},
|
||||||
|
sa: {
|
||||||
|
head: $size,
|
||||||
|
clas: 'ascending',
|
||||||
|
fn: cmpFn(false, getSize)
|
||||||
|
},
|
||||||
|
sd: {
|
||||||
|
head: $size,
|
||||||
|
clas: 'descending',
|
||||||
|
fn: cmpFn(true, getSize)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sortBy(store.get(storekey) || settings.order);
|
||||||
|
|
||||||
|
$label
|
||||||
|
.append($ascending.clone()).append($descending.clone())
|
||||||
|
.click(function (event) {
|
||||||
|
sortBy('n' + ($label.hasClass('ascending') ? 'd' : 'a'));
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
$date
|
||||||
|
.prepend($ascending.clone()).prepend($descending.clone())
|
||||||
|
.click(function (event) {
|
||||||
|
sortBy('d' + ($date.hasClass('ascending') ? 'd' : 'a'));
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
$size
|
||||||
|
.prepend($ascending.clone()).prepend($descending.clone())
|
||||||
|
.click(function (event) {
|
||||||
|
sortBy('s' + ($size.hasClass('ascending') ? 'd' : 'a'));
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
76
src/_h5ai/js/inc/ext/statusbar.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
module.define('ext/statusbar', [jQuery, 'core/settings', 'core/format', 'core/event', 'core/entry'], function ($, allsettings, format, event, entry) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.statusbar),
|
||||||
|
|
||||||
|
template = '<span class="statusbar">' +
|
||||||
|
'<span class="status default">' +
|
||||||
|
'<span class="folderTotal"></span> <span class="l10n-folders">folders</span>' +
|
||||||
|
'<span class="sep">·</span>' +
|
||||||
|
'<span class="fileTotal"></span> <span class="l10n-files">files</span>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span class="status dynamic"></span>' +
|
||||||
|
'</span>',
|
||||||
|
sepTemplate = '<span class="sep">·</span>',
|
||||||
|
|
||||||
|
$statusDynamic,
|
||||||
|
$statusDefault,
|
||||||
|
|
||||||
|
update = function (html) {
|
||||||
|
|
||||||
|
if (html) {
|
||||||
|
$statusDefault.hide();
|
||||||
|
$statusDynamic.empty().append(html).show();
|
||||||
|
} else {
|
||||||
|
$statusDynamic.empty().hide();
|
||||||
|
$statusDefault.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function (entry) {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $statusbar = $(template),
|
||||||
|
$folderTotal = $statusbar.find('.folderTotal'),
|
||||||
|
$fileTotal = $statusbar.find('.fileTotal');
|
||||||
|
|
||||||
|
$statusDefault = $statusbar.find('.status.default');
|
||||||
|
$statusDynamic = $statusbar.find('.status.dynamic');
|
||||||
|
|
||||||
|
var stats = entry.getStats();
|
||||||
|
$folderTotal.text(stats.folders);
|
||||||
|
$fileTotal.text(stats.files);
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
event.sub('statusbar', update);
|
||||||
|
$('#bottombar > .center').append($statusbar);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
event.sub('entry.mouseenter', function (entry) {
|
||||||
|
|
||||||
|
var $span = $('<span/>').append(entry.label).append(sepTemplate).append(format.formatDate(entry.time));
|
||||||
|
|
||||||
|
if (!entry.isFolder()) {
|
||||||
|
$span.append(sepTemplate).append(format.formatSize(entry.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
update($span);
|
||||||
|
});
|
||||||
|
|
||||||
|
event.sub('entry.mouseleave', function (entry) {
|
||||||
|
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry);
|
||||||
|
});
|
59
src/_h5ai/js/inc/ext/thumbnails.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
module.define('ext/thumbnails', [jQuery, 'core/settings', 'core/resource', 'core/entry'], function ($, allsettings, resource, entry) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
types: ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
||||||
|
delay: 1000
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.thumbnails),
|
||||||
|
|
||||||
|
requestThumb = function ($img, data) {
|
||||||
|
|
||||||
|
$.getJSON(resource.api(), data, function (json) {
|
||||||
|
|
||||||
|
if (json.code === 0) {
|
||||||
|
$img.addClass('thumb').attr('src', json.absHref);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
checkEntry = function (entry) {
|
||||||
|
|
||||||
|
if (entry.$extended && $.inArray(entry.type, settings.types) >= 0) {
|
||||||
|
|
||||||
|
var $imgSmall = entry.$extended.find('.icon.small img');
|
||||||
|
var $imgBig = entry.$extended.find('.icon.big img');
|
||||||
|
|
||||||
|
requestThumb($imgSmall, {
|
||||||
|
action: 'getthumbsrc',
|
||||||
|
href: entry.absHref,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
mode: 'square'
|
||||||
|
});
|
||||||
|
requestThumb($imgBig, {
|
||||||
|
action: 'getthumbsrc',
|
||||||
|
href: entry.absHref,
|
||||||
|
width: 100,
|
||||||
|
height: 48,
|
||||||
|
mode: 'rational'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function (entry) {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
|
||||||
|
_.each(entry.content, checkEntry);
|
||||||
|
}, settings.delay);
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry);
|
||||||
|
});
|
27
src/_h5ai/js/inc/ext/title.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
module.define('ext/title', [jQuery, 'core/settings', 'core/entry'], function ($, allsettings, entry) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.title),
|
||||||
|
|
||||||
|
init = function (entry) {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var labels = _.pluck(entry.getCrumb(), 'label'),
|
||||||
|
title = labels.join(' > ');
|
||||||
|
|
||||||
|
if (labels.length > 1) {
|
||||||
|
title = labels[labels.length - 1] + ' - ' + title;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.title = title;
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry);
|
||||||
|
});
|
227
src/_h5ai/js/inc/ext/tree.js
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
|
||||||
|
module.define('ext/tree', [jQuery, 'core/settings', 'core/resource', 'core/event', 'core/entry', 'core/parser'], function ($, allsettings, resource, event, entry, parser) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
slide: true
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.tree),
|
||||||
|
|
||||||
|
template = '<div class="entry">' +
|
||||||
|
'<span class="indicator none">' +
|
||||||
|
'<img src="' + resource.image('tree') + '" />' +
|
||||||
|
'</span>' +
|
||||||
|
'<a>' +
|
||||||
|
'<span class="icon"><img /></span>' +
|
||||||
|
'<span class="label"></span>' +
|
||||||
|
'</a>' +
|
||||||
|
'</span>',
|
||||||
|
statusHintTemplate = '<span class="hint"></span>',
|
||||||
|
|
||||||
|
// updates the tree for this single entry
|
||||||
|
update = function (entry) {
|
||||||
|
|
||||||
|
var $html = $(template),
|
||||||
|
$indicator = $html.find('.indicator'),
|
||||||
|
$a = $html.find('a'),
|
||||||
|
$img = $html.find('.icon img'),
|
||||||
|
$label = $html.find('.label');
|
||||||
|
|
||||||
|
$html
|
||||||
|
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||||
|
.data('entry', entry)
|
||||||
|
.data('status', entry.status);
|
||||||
|
|
||||||
|
$a.attr('href', entry.absHref);
|
||||||
|
$img.attr('src', resource.icon(entry.type));
|
||||||
|
$label.text(entry.label);
|
||||||
|
|
||||||
|
if (entry.isFolder()) {
|
||||||
|
|
||||||
|
var subfolders = entry.getSubfolders();
|
||||||
|
|
||||||
|
// indicator
|
||||||
|
if (!entry.status || (entry.status === 'h5ai' && !entry.isContentFetched) || subfolders.length) {
|
||||||
|
|
||||||
|
$indicator.removeClass('none');
|
||||||
|
|
||||||
|
if (!entry.status || (entry.status === 'h5ai' && !entry.isContentFetched)) {
|
||||||
|
$indicator.addClass('unknown');
|
||||||
|
} else if (entry.isContentVisible) {
|
||||||
|
$indicator.addClass('open');
|
||||||
|
} else {
|
||||||
|
$indicator.addClass('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// is it the domain?
|
||||||
|
if (entry.isDomain()) {
|
||||||
|
$html.addClass('domain');
|
||||||
|
$img.attr('src', resource.icon('folder-home'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// is it the current folder?
|
||||||
|
if (entry.isCurrentFolder()) {
|
||||||
|
$html.addClass('current');
|
||||||
|
$img.attr('src', resource.icon('folder-open'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// does it have subfolders?
|
||||||
|
if (subfolders.length) {
|
||||||
|
var $ul = $('<ul class="content" />').appendTo($html);
|
||||||
|
_.each(subfolders, function (e) {
|
||||||
|
$('<li />').append(update(e)).appendTo($ul);
|
||||||
|
});
|
||||||
|
if (!entry.isContentVisible) {
|
||||||
|
$ul.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reflect folder status
|
||||||
|
if (_.isNumber(entry.status)) {
|
||||||
|
if (entry.status === 200) {
|
||||||
|
$img.attr('src', resource.icon('folder-page'));
|
||||||
|
} else {
|
||||||
|
$html.addClass('error');
|
||||||
|
$a.append($(statusHintTemplate).text(entry.status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (entry.$tree) {
|
||||||
|
entry.$tree.replaceWith($html);
|
||||||
|
}
|
||||||
|
entry.$tree = $html;
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
},
|
||||||
|
|
||||||
|
createOnIndicatorClick = function (parser) {
|
||||||
|
|
||||||
|
var $tree = $('#tree'),
|
||||||
|
tree = $tree.get(0),
|
||||||
|
slide = function (entry, $indicator, $content, down) {
|
||||||
|
|
||||||
|
entry.isContentVisible = down;
|
||||||
|
$indicator.removeClass('open close').addClass(down ? 'open' : 'close');
|
||||||
|
tree.updateScrollbar(true);
|
||||||
|
$content[down ? 'slideDown' : 'slideUp'](function () {
|
||||||
|
|
||||||
|
tree.updateScrollbar();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
var $indicator = $(this),
|
||||||
|
$entry = $indicator.closest('.entry'),
|
||||||
|
entry = $entry.data('entry'),
|
||||||
|
$content = $entry.find('> ul.content');
|
||||||
|
|
||||||
|
if ($indicator.hasClass('unknown')) {
|
||||||
|
|
||||||
|
entry.fetchContent(parser, function (entry) {
|
||||||
|
|
||||||
|
entry.isContentVisible = false;
|
||||||
|
|
||||||
|
var $entry = update(entry),
|
||||||
|
$indicator = $entry.find('> .indicator'),
|
||||||
|
$content = $entry.find('> ul.content');
|
||||||
|
|
||||||
|
if (!$indicator.hasClass('none')) {
|
||||||
|
slide(entry, $indicator, $content, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if ($indicator.hasClass('open')) {
|
||||||
|
|
||||||
|
slide(entry, $indicator, $content, false);
|
||||||
|
|
||||||
|
} else if ($indicator.hasClass('close')) {
|
||||||
|
|
||||||
|
slide(entry, $indicator, $content, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
shiftTree = function (forceVisible, dontAnimate) {
|
||||||
|
|
||||||
|
var $tree = $("#tree"),
|
||||||
|
$extended = $("#extended"),
|
||||||
|
left = ((settings.slide && $tree.outerWidth() < $extended.offset().left) || forceVisible || !$extended.is(':visible')) ? 0 : 18 - $tree.outerWidth();
|
||||||
|
|
||||||
|
if (dontAnimate) {
|
||||||
|
$tree.stop().css({ left: left });
|
||||||
|
} else {
|
||||||
|
$tree.stop().animate({ left: left });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchTree = function (entry, parser, callback) {
|
||||||
|
|
||||||
|
entry.isContentVisible = true;
|
||||||
|
entry.fetchContent(parser, function (entry) {
|
||||||
|
|
||||||
|
if (entry.parent) {
|
||||||
|
fetchTree(entry.parent, parser, callback);
|
||||||
|
} else {
|
||||||
|
callback(entry);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustSpacing = function () {
|
||||||
|
|
||||||
|
var $tree = $('#tree'),
|
||||||
|
tree = $tree[0],
|
||||||
|
winHeight = $(window).height(),
|
||||||
|
navHeight = $('#topbar').outerHeight(),
|
||||||
|
footerHeight = $('#bottombar').outerHeight();
|
||||||
|
|
||||||
|
$tree.css({
|
||||||
|
top: navHeight,
|
||||||
|
height: winHeight - navHeight - footerHeight - 16
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tree.updateScrollbar) {
|
||||||
|
tree.updateScrollbar();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// creates the complete tree from entry down to the root
|
||||||
|
init = function (entry, parser) {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $tree = $('<div id="tree" />').appendTo('body');
|
||||||
|
|
||||||
|
fetchTree(entry, parser, function (root) {
|
||||||
|
|
||||||
|
$tree
|
||||||
|
.append(update(root))
|
||||||
|
.scrollpanel()
|
||||||
|
.show();
|
||||||
|
|
||||||
|
adjustSpacing();
|
||||||
|
shiftTree(false, true);
|
||||||
|
setTimeout(function () { $tree.get(0).updateScrollbar(); }, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
$tree
|
||||||
|
.on('click', '.indicator', createOnIndicatorClick(parser))
|
||||||
|
.on('mouseenter', function () { shiftTree(true); })
|
||||||
|
.on('mouseleave', function () { shiftTree(); });
|
||||||
|
|
||||||
|
event.sub('ready', adjustSpacing);
|
||||||
|
$(window).on('resize', function () {
|
||||||
|
adjustSpacing();
|
||||||
|
shiftTree();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry, parser);
|
||||||
|
});
|
49
src/_h5ai/js/inc/h5ai-info.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
module.define('h5ai-info', [jQuery, 'core/resource'], function ($, resource) {
|
||||||
|
|
||||||
|
var setCheckResult = function (id, result) {
|
||||||
|
|
||||||
|
var $ele = $(id).find('.test-result');
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
$ele.addClass('test-passed').text('yes');
|
||||||
|
} else {
|
||||||
|
$ele.addClass('test-failed').text('no');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChecksResponse = function (response) {
|
||||||
|
|
||||||
|
$('.test').each(function () {
|
||||||
|
|
||||||
|
setCheckResult(this, response && response[$(this).data('id')]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
checks = function () {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: resource.api(),
|
||||||
|
data: {
|
||||||
|
action: 'getchecks'
|
||||||
|
},
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (response) {
|
||||||
|
|
||||||
|
handleChecksResponse(response);
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
|
||||||
|
handleChecksResponse();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
checks();
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
21
src/_h5ai/js/inc/h5ai-main.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
module.define('h5ai-main', [jQuery, 'core/event'], function ($, event) {
|
||||||
|
|
||||||
|
|
||||||
|
event.pub('beforeView');
|
||||||
|
|
||||||
|
module.require('view/extended');
|
||||||
|
module.require('view/viewmode');
|
||||||
|
module.require('view/spacing');
|
||||||
|
|
||||||
|
$('#h5ai-reference').append(module.require('core/parser').id === 'apache-autoindex' ? ' (js)' : ' (php)');
|
||||||
|
|
||||||
|
event.pub('beforeExt');
|
||||||
|
|
||||||
|
_.each(module.getIds(/^ext\/.+/), function (id) {
|
||||||
|
|
||||||
|
module.require(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
event.pub('ready');
|
||||||
|
});
|
10
src/_h5ai/js/inc/lib/amplify-1.1.0.min.js
vendored
Normal file
10
src/_h5ai/js/inc/lib/amplify.min.js
vendored
@@ -1,104 +0,0 @@
|
|||||||
/**
|
|
||||||
* Version: 1.0 Alpha-1
|
|
||||||
* Build Date: 13-Nov-2007
|
|
||||||
* Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
|
|
||||||
* License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
|
|
||||||
* Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
|
|
||||||
*/
|
|
||||||
Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
|
|
||||||
Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
|
||||||
return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
|
||||||
return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
|
|
||||||
return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
|
|
||||||
if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
|
|
||||||
var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
|
|
||||||
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
|
|
||||||
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
|
|
||||||
if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
|
|
||||||
if(x.month||x.months){this.addMonths(x.month||x.months);}
|
|
||||||
if(x.year||x.years){this.addYears(x.year||x.years);}
|
|
||||||
if(x.day||x.days){this.addDays(x.day||x.days);}
|
|
||||||
return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
|
|
||||||
return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
|
|
||||||
if(!x.second&&x.second!==0){x.second=-1;}
|
|
||||||
if(!x.minute&&x.minute!==0){x.minute=-1;}
|
|
||||||
if(!x.hour&&x.hour!==0){x.hour=-1;}
|
|
||||||
if(!x.day&&x.day!==0){x.day=-1;}
|
|
||||||
if(!x.month&&x.month!==0){x.month=-1;}
|
|
||||||
if(!x.year&&x.year!==0){x.year=-1;}
|
|
||||||
if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
|
|
||||||
if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
|
|
||||||
if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
|
|
||||||
if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
|
|
||||||
if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
|
|
||||||
if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
|
|
||||||
if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
|
|
||||||
if(x.timezone){this.setTimezone(x.timezone);}
|
|
||||||
if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
|
|
||||||
return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
|
|
||||||
var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
|
|
||||||
return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
|
|
||||||
Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
|
|
||||||
return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
|
|
||||||
var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
|
|
||||||
return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
|
|
||||||
var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
|
|
||||||
return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
|
|
||||||
(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
|
|
||||||
break;}
|
|
||||||
return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
|
|
||||||
rx.push(r[0]);s=r[1];}
|
|
||||||
return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
|
|
||||||
return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
|
|
||||||
throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
|
|
||||||
return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
|
|
||||||
if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
|
||||||
try{r=(px[i].call(this,s));}catch(e){r=null;}
|
|
||||||
if(r){return r;}}
|
|
||||||
throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
|
||||||
try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
|
|
||||||
rx.push(r[0]);s=r[1];}
|
|
||||||
return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
|
|
||||||
return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
|
|
||||||
rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
|
|
||||||
s=q[1];}
|
|
||||||
if(!r){throw new $P.Exception(s);}
|
|
||||||
if(q){throw new $P.Exception(q[1]);}
|
|
||||||
if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
|
|
||||||
return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
|
|
||||||
rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
|
|
||||||
if(!last&&q[1].length===0){last=true;}
|
|
||||||
if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
|
|
||||||
p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
|
|
||||||
if(rx[1].length<best[1].length){best=rx;}
|
|
||||||
if(best[1].length===0){break;}}
|
|
||||||
if(best[0].length===0){return best;}
|
|
||||||
if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
|
|
||||||
best[1]=q[1];}
|
|
||||||
return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
|
|
||||||
return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
|
|
||||||
if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
|
|
||||||
var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
|
|
||||||
return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
|
|
||||||
this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
|
|
||||||
var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
|
|
||||||
return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
|
|
||||||
for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
|
|
||||||
if(this.now){return new Date();}
|
|
||||||
var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
|
|
||||||
if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
|
|
||||||
if(!this.unit){this.unit="day";}
|
|
||||||
if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
|
|
||||||
if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
|
|
||||||
this[this.unit+"s"]=this.value*orient;}
|
|
||||||
return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
|
|
||||||
if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
|
|
||||||
if(this.month&&!this.day){this.day=1;}
|
|
||||||
return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
|
|
||||||
fn=_C[keys]=_.any.apply(null,px);}
|
|
||||||
return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
|
|
||||||
return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
|
|
||||||
return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
|
|
||||||
try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
|
|
||||||
return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
|
|
||||||
return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
|
|
4
src/_h5ai/js/inc/lib/jquery-1.7.1.min.js
vendored
Normal file
2
src/_h5ai/js/inc/lib/jquery.fracs-0.11.min.js
vendored
Normal file
4
src/_h5ai/js/inc/lib/jquery.min.js
vendored
84
src/_h5ai/js/inc/lib/jquery.mousewheel-3.0.6.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||||
|
* Licensed under the MIT License (LICENSE.txt).
|
||||||
|
*
|
||||||
|
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||||
|
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||||
|
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||||
|
*
|
||||||
|
* Version: 3.0.6
|
||||||
|
*
|
||||||
|
* Requires: 1.2.2+
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
var types = ['DOMMouseScroll', 'mousewheel'];
|
||||||
|
|
||||||
|
if ($.event.fixHooks) {
|
||||||
|
for ( var i=types.length; i; ) {
|
||||||
|
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.event.special.mousewheel = {
|
||||||
|
setup: function() {
|
||||||
|
if ( this.addEventListener ) {
|
||||||
|
for ( var i=types.length; i; ) {
|
||||||
|
this.addEventListener( types[--i], handler, false );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onmousewheel = handler;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
teardown: function() {
|
||||||
|
if ( this.removeEventListener ) {
|
||||||
|
for ( var i=types.length; i; ) {
|
||||||
|
this.removeEventListener( types[--i], handler, false );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onmousewheel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.extend({
|
||||||
|
mousewheel: function(fn) {
|
||||||
|
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
||||||
|
},
|
||||||
|
|
||||||
|
unmousewheel: function(fn) {
|
||||||
|
return this.unbind("mousewheel", fn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function handler(event) {
|
||||||
|
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
||||||
|
event = $.event.fix(orgEvent);
|
||||||
|
event.type = "mousewheel";
|
||||||
|
|
||||||
|
// Old school scrollwheel delta
|
||||||
|
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
|
||||||
|
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
|
||||||
|
|
||||||
|
// New school multidimensional scroll (touchpads) deltas
|
||||||
|
deltaY = delta;
|
||||||
|
|
||||||
|
// Gecko
|
||||||
|
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||||
|
deltaY = 0;
|
||||||
|
deltaX = -1*delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webkit
|
||||||
|
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
|
||||||
|
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
|
||||||
|
|
||||||
|
// Add event and delta to the front of the arguments
|
||||||
|
args.unshift(event, delta, deltaX, deltaY);
|
||||||
|
|
||||||
|
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
})(jQuery);
|
@@ -1,84 +0,0 @@
|
|||||||
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
|
||||||
* Licensed under the MIT License (LICENSE.txt).
|
|
||||||
*
|
|
||||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
|
||||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
|
||||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
|
||||||
*
|
|
||||||
* Version: 3.0.5
|
|
||||||
*
|
|
||||||
* Requires: 1.2.2+
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
|
|
||||||
var types = ['DOMMouseScroll', 'mousewheel'];
|
|
||||||
|
|
||||||
if ($.event.fixHooks) {
|
|
||||||
for ( var i=types.length; i; ) {
|
|
||||||
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$.event.special.mousewheel = {
|
|
||||||
setup: function() {
|
|
||||||
if ( this.addEventListener ) {
|
|
||||||
for ( var i=types.length; i; ) {
|
|
||||||
this.addEventListener( types[--i], handler, false );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.onmousewheel = handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
teardown: function() {
|
|
||||||
if ( this.removeEventListener ) {
|
|
||||||
for ( var i=types.length; i; ) {
|
|
||||||
this.removeEventListener( types[--i], handler, false );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.onmousewheel = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.extend({
|
|
||||||
mousewheel: function(fn) {
|
|
||||||
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
|
||||||
},
|
|
||||||
|
|
||||||
unmousewheel: function(fn) {
|
|
||||||
return this.unbind("mousewheel", fn);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function handler(event) {
|
|
||||||
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
|
||||||
event = $.event.fix(orgEvent);
|
|
||||||
event.type = "mousewheel";
|
|
||||||
|
|
||||||
// Old school scrollwheel delta
|
|
||||||
if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
|
|
||||||
if ( event.detail ) { delta = -event.detail/3; }
|
|
||||||
|
|
||||||
// New school multidimensional scroll (touchpads) deltas
|
|
||||||
deltaY = delta;
|
|
||||||
|
|
||||||
// Gecko
|
|
||||||
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
|
||||||
deltaY = 0;
|
|
||||||
deltaX = -1*delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webkit
|
|
||||||
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
|
|
||||||
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
|
|
||||||
|
|
||||||
// Add event and delta to the front of the arguments
|
|
||||||
args.unshift(event, delta, deltaX, deltaY);
|
|
||||||
|
|
||||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
})(jQuery);
|
|
@@ -72,14 +72,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$element
|
$element
|
||||||
.mousewheel(function (event, delta) {
|
.on('mousewheel', function (event, delta, deltaX, deltaY) {
|
||||||
|
|
||||||
$wrapper.scrollTop($wrapper.scrollTop() - 50 * delta);
|
$wrapper.scrollTop($wrapper.scrollTop() - 50 * deltaY);
|
||||||
update();
|
update();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
})
|
})
|
||||||
.scroll(update);
|
.on('scroll', update);
|
||||||
$element.get(0).updateScrollbar = update;
|
$element.get(0).updateScrollbar = update;
|
||||||
$wrapper
|
$wrapper
|
||||||
.css({
|
.css({
|
||||||
|
487
src/_h5ai/js/inc/lib/json2.js
Normal file
@@ -0,0 +1,487 @@
|
|||||||
|
/*
|
||||||
|
http://www.JSON.org/json2.js
|
||||||
|
2011-10-19
|
||||||
|
|
||||||
|
Public Domain.
|
||||||
|
|
||||||
|
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||||
|
|
||||||
|
See http://www.JSON.org/js.html
|
||||||
|
|
||||||
|
|
||||||
|
This code should be minified before deployment.
|
||||||
|
See http://javascript.crockford.com/jsmin.html
|
||||||
|
|
||||||
|
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||||
|
NOT CONTROL.
|
||||||
|
|
||||||
|
|
||||||
|
This file creates a global JSON object containing two methods: stringify
|
||||||
|
and parse.
|
||||||
|
|
||||||
|
JSON.stringify(value, replacer, space)
|
||||||
|
value any JavaScript value, usually an object or array.
|
||||||
|
|
||||||
|
replacer an optional parameter that determines how object
|
||||||
|
values are stringified for objects. It can be a
|
||||||
|
function or an array of strings.
|
||||||
|
|
||||||
|
space an optional parameter that specifies the indentation
|
||||||
|
of nested structures. If it is omitted, the text will
|
||||||
|
be packed without extra whitespace. If it is a number,
|
||||||
|
it will specify the number of spaces to indent at each
|
||||||
|
level. If it is a string (such as '\t' or ' '),
|
||||||
|
it contains the characters used to indent at each level.
|
||||||
|
|
||||||
|
This method produces a JSON text from a JavaScript value.
|
||||||
|
|
||||||
|
When an object value is found, if the object contains a toJSON
|
||||||
|
method, its toJSON method will be called and the result will be
|
||||||
|
stringified. A toJSON method does not serialize: it returns the
|
||||||
|
value represented by the name/value pair that should be serialized,
|
||||||
|
or undefined if nothing should be serialized. The toJSON method
|
||||||
|
will be passed the key associated with the value, and this will be
|
||||||
|
bound to the value
|
||||||
|
|
||||||
|
For example, this would serialize Dates as ISO strings.
|
||||||
|
|
||||||
|
Date.prototype.toJSON = function (key) {
|
||||||
|
function f(n) {
|
||||||
|
// Format integers to have at least two digits.
|
||||||
|
return n < 10 ? '0' + n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getUTCFullYear() + '-' +
|
||||||
|
f(this.getUTCMonth() + 1) + '-' +
|
||||||
|
f(this.getUTCDate()) + 'T' +
|
||||||
|
f(this.getUTCHours()) + ':' +
|
||||||
|
f(this.getUTCMinutes()) + ':' +
|
||||||
|
f(this.getUTCSeconds()) + 'Z';
|
||||||
|
};
|
||||||
|
|
||||||
|
You can provide an optional replacer method. It will be passed the
|
||||||
|
key and value of each member, with this bound to the containing
|
||||||
|
object. The value that is returned from your method will be
|
||||||
|
serialized. If your method returns undefined, then the member will
|
||||||
|
be excluded from the serialization.
|
||||||
|
|
||||||
|
If the replacer parameter is an array of strings, then it will be
|
||||||
|
used to select the members to be serialized. It filters the results
|
||||||
|
such that only members with keys listed in the replacer array are
|
||||||
|
stringified.
|
||||||
|
|
||||||
|
Values that do not have JSON representations, such as undefined or
|
||||||
|
functions, will not be serialized. Such values in objects will be
|
||||||
|
dropped; in arrays they will be replaced with null. You can use
|
||||||
|
a replacer function to replace those with JSON values.
|
||||||
|
JSON.stringify(undefined) returns undefined.
|
||||||
|
|
||||||
|
The optional space parameter produces a stringification of the
|
||||||
|
value that is filled with line breaks and indentation to make it
|
||||||
|
easier to read.
|
||||||
|
|
||||||
|
If the space parameter is a non-empty string, then that string will
|
||||||
|
be used for indentation. If the space parameter is a number, then
|
||||||
|
the indentation will be that many spaces.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||||
|
// text is '["e",{"pluribus":"unum"}]'
|
||||||
|
|
||||||
|
|
||||||
|
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||||
|
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||||
|
|
||||||
|
text = JSON.stringify([new Date()], function (key, value) {
|
||||||
|
return this[key] instanceof Date ?
|
||||||
|
'Date(' + this[key] + ')' : value;
|
||||||
|
});
|
||||||
|
// text is '["Date(---current time---)"]'
|
||||||
|
|
||||||
|
|
||||||
|
JSON.parse(text, reviver)
|
||||||
|
This method parses a JSON text to produce an object or array.
|
||||||
|
It can throw a SyntaxError exception.
|
||||||
|
|
||||||
|
The optional reviver parameter is a function that can filter and
|
||||||
|
transform the results. It receives each of the keys and values,
|
||||||
|
and its return value is used instead of the original value.
|
||||||
|
If it returns what it received, then the structure is not modified.
|
||||||
|
If it returns undefined then the member is deleted.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
// Parse the text. Values that look like ISO date strings will
|
||||||
|
// be converted to Date objects.
|
||||||
|
|
||||||
|
myData = JSON.parse(text, function (key, value) {
|
||||||
|
var a;
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
a =
|
||||||
|
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||||
|
if (a) {
|
||||||
|
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||||
|
+a[5], +a[6]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||||
|
var d;
|
||||||
|
if (typeof value === 'string' &&
|
||||||
|
value.slice(0, 5) === 'Date(' &&
|
||||||
|
value.slice(-1) === ')') {
|
||||||
|
d = new Date(value.slice(5, -1));
|
||||||
|
if (d) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
This is a reference implementation. You are free to copy, modify, or
|
||||||
|
redistribute.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*jslint evil: true, regexp: true */
|
||||||
|
|
||||||
|
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||||
|
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||||
|
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||||
|
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||||
|
test, toJSON, toString, valueOf
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Create a JSON object only if one does not already exist. We create the
|
||||||
|
// methods in a closure to avoid creating global variables.
|
||||||
|
|
||||||
|
var JSON;
|
||||||
|
if (!JSON) {
|
||||||
|
JSON = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function f(n) {
|
||||||
|
// Format integers to have at least two digits.
|
||||||
|
return n < 10 ? '0' + n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof Date.prototype.toJSON !== 'function') {
|
||||||
|
|
||||||
|
Date.prototype.toJSON = function (key) {
|
||||||
|
|
||||||
|
return isFinite(this.valueOf())
|
||||||
|
? this.getUTCFullYear() + '-' +
|
||||||
|
f(this.getUTCMonth() + 1) + '-' +
|
||||||
|
f(this.getUTCDate()) + 'T' +
|
||||||
|
f(this.getUTCHours()) + ':' +
|
||||||
|
f(this.getUTCMinutes()) + ':' +
|
||||||
|
f(this.getUTCSeconds()) + 'Z'
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.toJSON =
|
||||||
|
Number.prototype.toJSON =
|
||||||
|
Boolean.prototype.toJSON = function (key) {
|
||||||
|
return this.valueOf();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||||
|
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||||
|
gap,
|
||||||
|
indent,
|
||||||
|
meta = { // table of character substitutions
|
||||||
|
'\b': '\\b',
|
||||||
|
'\t': '\\t',
|
||||||
|
'\n': '\\n',
|
||||||
|
'\f': '\\f',
|
||||||
|
'\r': '\\r',
|
||||||
|
'"' : '\\"',
|
||||||
|
'\\': '\\\\'
|
||||||
|
},
|
||||||
|
rep;
|
||||||
|
|
||||||
|
|
||||||
|
function quote(string) {
|
||||||
|
|
||||||
|
// If the string contains no control characters, no quote characters, and no
|
||||||
|
// backslash characters, then we can safely slap some quotes around it.
|
||||||
|
// Otherwise we must also replace the offending characters with safe escape
|
||||||
|
// sequences.
|
||||||
|
|
||||||
|
escapable.lastIndex = 0;
|
||||||
|
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
||||||
|
var c = meta[a];
|
||||||
|
return typeof c === 'string'
|
||||||
|
? c
|
||||||
|
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||||
|
}) + '"' : '"' + string + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function str(key, holder) {
|
||||||
|
|
||||||
|
// Produce a string from holder[key].
|
||||||
|
|
||||||
|
var i, // The loop counter.
|
||||||
|
k, // The member key.
|
||||||
|
v, // The member value.
|
||||||
|
length,
|
||||||
|
mind = gap,
|
||||||
|
partial,
|
||||||
|
value = holder[key];
|
||||||
|
|
||||||
|
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||||
|
|
||||||
|
if (value && typeof value === 'object' &&
|
||||||
|
typeof value.toJSON === 'function') {
|
||||||
|
value = value.toJSON(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we were called with a replacer function, then call the replacer to
|
||||||
|
// obtain a replacement value.
|
||||||
|
|
||||||
|
if (typeof rep === 'function') {
|
||||||
|
value = rep.call(holder, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// What happens next depends on the value's type.
|
||||||
|
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'string':
|
||||||
|
return quote(value);
|
||||||
|
|
||||||
|
case 'number':
|
||||||
|
|
||||||
|
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||||
|
|
||||||
|
return isFinite(value) ? String(value) : 'null';
|
||||||
|
|
||||||
|
case 'boolean':
|
||||||
|
case 'null':
|
||||||
|
|
||||||
|
// If the value is a boolean or null, convert it to a string. Note:
|
||||||
|
// typeof null does not produce 'null'. The case is included here in
|
||||||
|
// the remote chance that this gets fixed someday.
|
||||||
|
|
||||||
|
return String(value);
|
||||||
|
|
||||||
|
// If the type is 'object', we might be dealing with an object or an array or
|
||||||
|
// null.
|
||||||
|
|
||||||
|
case 'object':
|
||||||
|
|
||||||
|
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||||
|
// so watch out for that case.
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an array to hold the partial results of stringifying this object value.
|
||||||
|
|
||||||
|
gap += indent;
|
||||||
|
partial = [];
|
||||||
|
|
||||||
|
// Is the value an array?
|
||||||
|
|
||||||
|
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||||
|
|
||||||
|
// The value is an array. Stringify every element. Use null as a placeholder
|
||||||
|
// for non-JSON values.
|
||||||
|
|
||||||
|
length = value.length;
|
||||||
|
for (i = 0; i < length; i += 1) {
|
||||||
|
partial[i] = str(i, value) || 'null';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join all of the elements together, separated with commas, and wrap them in
|
||||||
|
// brackets.
|
||||||
|
|
||||||
|
v = partial.length === 0
|
||||||
|
? '[]'
|
||||||
|
: gap
|
||||||
|
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||||
|
: '[' + partial.join(',') + ']';
|
||||||
|
gap = mind;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the replacer is an array, use it to select the members to be stringified.
|
||||||
|
|
||||||
|
if (rep && typeof rep === 'object') {
|
||||||
|
length = rep.length;
|
||||||
|
for (i = 0; i < length; i += 1) {
|
||||||
|
if (typeof rep[i] === 'string') {
|
||||||
|
k = rep[i];
|
||||||
|
v = str(k, value);
|
||||||
|
if (v) {
|
||||||
|
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Otherwise, iterate through all of the keys in the object.
|
||||||
|
|
||||||
|
for (k in value) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||||
|
v = str(k, value);
|
||||||
|
if (v) {
|
||||||
|
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join all of the member texts together, separated with commas,
|
||||||
|
// and wrap them in braces.
|
||||||
|
|
||||||
|
v = partial.length === 0
|
||||||
|
? '{}'
|
||||||
|
: gap
|
||||||
|
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||||
|
: '{' + partial.join(',') + '}';
|
||||||
|
gap = mind;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the JSON object does not yet have a stringify method, give it one.
|
||||||
|
|
||||||
|
if (typeof JSON.stringify !== 'function') {
|
||||||
|
JSON.stringify = function (value, replacer, space) {
|
||||||
|
|
||||||
|
// The stringify method takes a value and an optional replacer, and an optional
|
||||||
|
// space parameter, and returns a JSON text. The replacer can be a function
|
||||||
|
// that can replace values, or an array of strings that will select the keys.
|
||||||
|
// A default replacer method can be provided. Use of the space parameter can
|
||||||
|
// produce text that is more easily readable.
|
||||||
|
|
||||||
|
var i;
|
||||||
|
gap = '';
|
||||||
|
indent = '';
|
||||||
|
|
||||||
|
// If the space parameter is a number, make an indent string containing that
|
||||||
|
// many spaces.
|
||||||
|
|
||||||
|
if (typeof space === 'number') {
|
||||||
|
for (i = 0; i < space; i += 1) {
|
||||||
|
indent += ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the space parameter is a string, it will be used as the indent string.
|
||||||
|
|
||||||
|
} else if (typeof space === 'string') {
|
||||||
|
indent = space;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a replacer, it must be a function or an array.
|
||||||
|
// Otherwise, throw an error.
|
||||||
|
|
||||||
|
rep = replacer;
|
||||||
|
if (replacer && typeof replacer !== 'function' &&
|
||||||
|
(typeof replacer !== 'object' ||
|
||||||
|
typeof replacer.length !== 'number')) {
|
||||||
|
throw new Error('JSON.stringify');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a fake root object containing our value under the key of ''.
|
||||||
|
// Return the result of stringifying the value.
|
||||||
|
|
||||||
|
return str('', {'': value});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If the JSON object does not yet have a parse method, give it one.
|
||||||
|
|
||||||
|
if (typeof JSON.parse !== 'function') {
|
||||||
|
JSON.parse = function (text, reviver) {
|
||||||
|
|
||||||
|
// The parse method takes a text and an optional reviver function, and returns
|
||||||
|
// a JavaScript value if the text is a valid JSON text.
|
||||||
|
|
||||||
|
var j;
|
||||||
|
|
||||||
|
function walk(holder, key) {
|
||||||
|
|
||||||
|
// The walk method is used to recursively walk the resulting structure so
|
||||||
|
// that modifications can be made.
|
||||||
|
|
||||||
|
var k, v, value = holder[key];
|
||||||
|
if (value && typeof value === 'object') {
|
||||||
|
for (k in value) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||||
|
v = walk(value, k);
|
||||||
|
if (v !== undefined) {
|
||||||
|
value[k] = v;
|
||||||
|
} else {
|
||||||
|
delete value[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reviver.call(holder, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parsing happens in four stages. In the first stage, we replace certain
|
||||||
|
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||||
|
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||||
|
|
||||||
|
text = String(text);
|
||||||
|
cx.lastIndex = 0;
|
||||||
|
if (cx.test(text)) {
|
||||||
|
text = text.replace(cx, function (a) {
|
||||||
|
return '\\u' +
|
||||||
|
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the second stage, we run the text against regular expressions that look
|
||||||
|
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||||
|
// because they can cause invocation, and '=' because it can cause mutation.
|
||||||
|
// But just to be safe, we want to reject all unexpected forms.
|
||||||
|
|
||||||
|
// We split the second stage into 4 regexp operations in order to work around
|
||||||
|
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||||
|
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||||
|
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||||
|
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||||
|
// we look to see that the remaining characters are only whitespace or ']' or
|
||||||
|
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||||
|
|
||||||
|
if (/^[\],:{}\s]*$/
|
||||||
|
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||||
|
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||||
|
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||||
|
|
||||||
|
// In the third stage we use the eval function to compile the text into a
|
||||||
|
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||||
|
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||||
|
// in parens to eliminate the ambiguity.
|
||||||
|
|
||||||
|
j = eval('(' + text + ')');
|
||||||
|
|
||||||
|
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||||
|
// each name/value pair to a reviver function for possible transformation.
|
||||||
|
|
||||||
|
return typeof reviver === 'function'
|
||||||
|
? walk({'': j}, '')
|
||||||
|
: j;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||||
|
|
||||||
|
throw new SyntaxError('JSON.parse');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}());
|
4
src/_h5ai/js/inc/lib/modernizr-2.5.3.min.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/* Modernizr 2.5.3 (Custom Build) | MIT & BSD
|
||||||
|
* Build: http://www.modernizr.com/download/#-opacity-rgba-canvas-history-audio-video-shiv-cssclasses-prefixes
|
||||||
|
*/
|
||||||
|
;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(m.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}var d="2.5.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={},o={},p={},q=[],r=q.slice,s,t={}.hasOwnProperty,u;!x(t,"undefined")&&!x(t.call,"undefined")?u=function(a,b){return t.call(a,b)}:u=function(a,b){return b in a&&x(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},n.history=function(){return!!a.history&&!!history.pushState},n.rgba=function(){return v("background-color:rgba(150,255,150,.5)"),y(j.backgroundColor,"rgba")},n.opacity=function(){return w("opacity:.55"),/^0.55$/.test(j.opacity)},n.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},n.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c};for(var A in n)u(n,A)&&(s=A.toLowerCase(),e[s]=n[A](),q.push((e[s]?"":"no-")+s));return v(""),i=k=null,function(a,b){function g(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="<xyz></xyz>",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,e._prefixes=m,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document);
|
196
src/_h5ai/js/inc/lib/module.js
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/*!
|
||||||
|
* module.js
|
||||||
|
* author: Lars Jung
|
||||||
|
* license: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (global, name) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var self = {},
|
||||||
|
previous = global[name],
|
||||||
|
|
||||||
|
noConflict = function () {
|
||||||
|
|
||||||
|
if (global[name] === self) {
|
||||||
|
global[name] = previous;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
|
||||||
|
err = function (message) {
|
||||||
|
|
||||||
|
throw name + ' exception: ' + message;
|
||||||
|
},
|
||||||
|
|
||||||
|
definitions = {},
|
||||||
|
modules = {},
|
||||||
|
|
||||||
|
findDepsUnsafe = function (ids) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var deps = [];
|
||||||
|
|
||||||
|
if (_.isString(ids)) {
|
||||||
|
|
||||||
|
var def = definitions[ids];
|
||||||
|
if (def) {
|
||||||
|
_.each(def.deps, function (id) {
|
||||||
|
|
||||||
|
deps = deps.concat(findDepsUnsafe(id));
|
||||||
|
});
|
||||||
|
deps.push(def.id);
|
||||||
|
} else {
|
||||||
|
deps.push(ids);
|
||||||
|
}
|
||||||
|
} else if (_.isArray(ids)) {
|
||||||
|
|
||||||
|
_.each(ids, function (id) {
|
||||||
|
|
||||||
|
deps = deps.concat(findDepsUnsafe(id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.uniq(deps);
|
||||||
|
},
|
||||||
|
|
||||||
|
findDeps = function (ids) {
|
||||||
|
|
||||||
|
if (ids) {
|
||||||
|
try {
|
||||||
|
return findDepsUnsafe(ids);
|
||||||
|
} catch (e) {
|
||||||
|
err('cyclic dependencies for ids "' + ids + '"');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var res = {};
|
||||||
|
_.each(definitions, function (def, id) {
|
||||||
|
|
||||||
|
res[id] = findDeps(id);
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
log = function (showInvDeps) {
|
||||||
|
|
||||||
|
var allDeps = findDeps(),
|
||||||
|
allInvDeps = {},
|
||||||
|
out = '';
|
||||||
|
|
||||||
|
if (!showInvDeps) {
|
||||||
|
_.each(allDeps, function (deps, id) {
|
||||||
|
|
||||||
|
deps.pop();
|
||||||
|
out += (_.has(modules, id) ? '* ' : ' ') + id + ' -> [ ' + deps.join(', ') + ' ]\n';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_.each(definitions, function (def) {
|
||||||
|
|
||||||
|
var invDeps = [];
|
||||||
|
_.each(allDeps, function (depIds, id) {
|
||||||
|
|
||||||
|
if (_.indexOf(depIds, def.id) >= 0) {
|
||||||
|
invDeps.push(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
allInvDeps[def.id] = invDeps;
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(allInvDeps, function (invDeps, id) {
|
||||||
|
|
||||||
|
invDeps.shift();
|
||||||
|
out += (_.has(modules, id) ? '* ' : ' ') + id + ' <- [ ' + invDeps.join(', ') + ' ]\n';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
},
|
||||||
|
|
||||||
|
define = function (id, deps, fn) {
|
||||||
|
|
||||||
|
if (_.isFunction(deps)) {
|
||||||
|
fn = deps;
|
||||||
|
deps = [];
|
||||||
|
}
|
||||||
|
if (!_.isString(id)) {
|
||||||
|
err('id must be a string "' + id + '"');
|
||||||
|
}
|
||||||
|
if (!_.isArray(deps)) {
|
||||||
|
err('dependencies must be an array "' + deps + '"');
|
||||||
|
}
|
||||||
|
if (!_.isFunction(fn)) {
|
||||||
|
err('constructor must be a function "' + fn + '"');
|
||||||
|
}
|
||||||
|
if (definitions[id]) {
|
||||||
|
err('id already defined "' + id + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
definitions[id] = {
|
||||||
|
id: id,
|
||||||
|
deps: deps,
|
||||||
|
fn: fn
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getIds = function (regexp) {
|
||||||
|
|
||||||
|
var ids = _.map(definitions, function (def) {
|
||||||
|
|
||||||
|
return def.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!_.isRegExp(regexp)) {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.filter(ids, function (id) {
|
||||||
|
|
||||||
|
return regexp.test(id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
isDefined = function (id) {
|
||||||
|
|
||||||
|
return _.isString(id) ? !!definitions[id] : !!id;
|
||||||
|
},
|
||||||
|
|
||||||
|
require = function (id) {
|
||||||
|
|
||||||
|
if (!_.isString(id)) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.has(modules, id)) {
|
||||||
|
return modules[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
var def = definitions[id];
|
||||||
|
if (!def) {
|
||||||
|
err('id not defined "' + id + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
var deps = _.map(def.deps, function (depId) {
|
||||||
|
|
||||||
|
return require(depId);
|
||||||
|
});
|
||||||
|
|
||||||
|
var obj = def.fn.apply(this, deps);
|
||||||
|
modules[id] = obj;
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!_) {
|
||||||
|
err(name + ' depends on underscore');
|
||||||
|
}
|
||||||
|
|
||||||
|
self.noConflict = noConflict;
|
||||||
|
self.log = log;
|
||||||
|
self.define = define;
|
||||||
|
self.require = require;
|
||||||
|
self.getIds = getIds;
|
||||||
|
self.isDefined = isDefined;
|
||||||
|
|
||||||
|
global[name] = self;
|
||||||
|
|
||||||
|
}(this, 'module'));
|
6
src/_h5ai/js/inc/lib/moment-1.5.0.min.js
vendored
Normal file
31
src/_h5ai/js/inc/lib/underscore-1.3.1.min.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Underscore.js 1.3.1
|
||||||
|
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
|
// Underscore is freely distributable under the MIT license.
|
||||||
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||||
|
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||||
|
// For all details and documentation:
|
||||||
|
// http://documentcloud.github.com/underscore
|
||||||
|
(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||||
|
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
|
||||||
|
h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
|
||||||
|
b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
|
||||||
|
null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
|
||||||
|
function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
|
||||||
|
e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
|
||||||
|
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
|
||||||
|
return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
|
||||||
|
c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
|
||||||
|
b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
|
||||||
|
return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
|
||||||
|
d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
|
||||||
|
var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
|
||||||
|
c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
|
||||||
|
a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
|
||||||
|
b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
|
||||||
|
1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
|
||||||
|
b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
|
||||||
|
b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
|
||||||
|
function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
|
||||||
|
u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
|
||||||
|
function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
|
||||||
|
true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
|
@@ -1,42 +1,48 @@
|
|||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
'use strict';
|
'use strict';
|
||||||
/*jslint browser: true, confusion: true, regexp: true, vars: true, white: true */
|
/*jshint browser: true */
|
||||||
/*global Modernizr, jQuery, amplify, H5AI_CONFIG */
|
/*global _, amplify, Base64, H5AI_CONFIG, jQuery, Modernizr, module, moment */
|
||||||
|
|
||||||
var H5AI = {};
|
// @include "core/entry.js"
|
||||||
|
// @include "core/event.js"
|
||||||
|
// @include "core/format.js"
|
||||||
|
// @include "core/parser.js"
|
||||||
|
// @include "core/resource.js"
|
||||||
|
// @include "core/settings.js"
|
||||||
|
// @include "core/store.js"
|
||||||
|
|
||||||
// @include "Util.js"
|
// @include "model/entry.js"
|
||||||
// @include "Core.js"
|
|
||||||
// @include "Sort.js"
|
// @include "parser/apache-autoindex.js"
|
||||||
// @include "ZippedDownload.js"
|
// @include "parser/generic-json.js"
|
||||||
// @include "Finder.js"
|
|
||||||
// @include "Context.js"
|
// @include "view/extended.js"
|
||||||
|
// @include "view/spacing.js"
|
||||||
|
// @include "view/viewmode.js"
|
||||||
|
|
||||||
|
// @include "ext/crumb.js"
|
||||||
|
// @include "ext/custom.js"
|
||||||
|
// @include "ext/download.js"
|
||||||
|
// @include "ext/filter.js"
|
||||||
|
// @include "ext/folderstatus.js"
|
||||||
|
// @include "ext/l10n.js"
|
||||||
|
// @include "ext/link-hover-states.js"
|
||||||
|
// @include "ext/qrcode.js"
|
||||||
|
// @include "ext/select.js"
|
||||||
|
// @include "ext/sort.js"
|
||||||
|
// @include "ext/statusbar.js"
|
||||||
|
// @include "ext/thumbnails.js"
|
||||||
|
// @include "ext/title.js"
|
||||||
|
// @include "ext/tree.js"
|
||||||
|
|
||||||
|
// @include "h5ai-info.js"
|
||||||
|
// @include "h5ai-main.js"
|
||||||
|
|
||||||
// @include "Path.js"
|
|
||||||
// @include "Connector.js"
|
|
||||||
// @include "Html.js"
|
|
||||||
// @include "Extended.js"
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
var isPhp = $('html.h5ai-php').length > 0;
|
module.require($('body').attr('id'));
|
||||||
|
|
||||||
if (!isPhp) {
|
|
||||||
H5AI.extended.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
H5AI.core.init();
|
|
||||||
H5AI.sort.init();
|
|
||||||
H5AI.finder.init();
|
|
||||||
H5AI.zippedDownload.init();
|
|
||||||
H5AI.context.init();
|
|
||||||
|
|
||||||
if (isPhp) {
|
|
||||||
$('#tree').scrollpanel();
|
|
||||||
H5AI.core.shiftTree(false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}(jQuery));
|
}(jQuery));
|
||||||
|
255
src/_h5ai/js/inc/model/entry.js
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
|
||||||
|
module.define('model/entry', [jQuery, 'core/types'], function ($, types) {
|
||||||
|
|
||||||
|
var domain = document.domain,
|
||||||
|
location = document.location.pathname,
|
||||||
|
|
||||||
|
|
||||||
|
// utils
|
||||||
|
|
||||||
|
reEndsWithSlash = /\/$/,
|
||||||
|
|
||||||
|
|
||||||
|
createLabel = function (sequence) {
|
||||||
|
|
||||||
|
if (sequence.length > 1 && reEndsWithSlash.test(sequence)) {
|
||||||
|
sequence = sequence.slice(0, -1);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sequence = decodeURI(sequence);
|
||||||
|
} catch (err) {}
|
||||||
|
return sequence;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
reSplitPath = /^\/([^\/]+\/?)$/,
|
||||||
|
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
|
||||||
|
|
||||||
|
splitPath = function (sequence) {
|
||||||
|
|
||||||
|
var match;
|
||||||
|
|
||||||
|
sequence = sequence.replace(/\/+/g, '/');
|
||||||
|
if (sequence === '/') {
|
||||||
|
return {
|
||||||
|
parent: null,
|
||||||
|
parentname: null,
|
||||||
|
name: '/'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
match = reSplitPath2.exec(sequence);
|
||||||
|
if (match) {
|
||||||
|
return {
|
||||||
|
parent: match[1],
|
||||||
|
parentname: match[2],
|
||||||
|
name: match[3]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
match = reSplitPath.exec(sequence);
|
||||||
|
if (match) {
|
||||||
|
return {
|
||||||
|
parent: '/',
|
||||||
|
parentname: '/',
|
||||||
|
name: match[1]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
reContentType = /^text\/html;h5ai=/,
|
||||||
|
|
||||||
|
ajaxRequest = function (self, parser, callback) {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: self.absHref,
|
||||||
|
type: parser ? 'GET' : 'HEAD',
|
||||||
|
complete: function (xhr) {
|
||||||
|
|
||||||
|
if (xhr.status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) {
|
||||||
|
self.status = 'h5ai';
|
||||||
|
if (parser) {
|
||||||
|
parser.parse(self.absHref, xhr.responseText);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.status = xhr.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(self);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Entry
|
||||||
|
|
||||||
|
cache = {},
|
||||||
|
|
||||||
|
Entry = function (absHref) {
|
||||||
|
|
||||||
|
var split = splitPath(absHref);
|
||||||
|
|
||||||
|
cache[absHref] = this;
|
||||||
|
|
||||||
|
this.absHref = absHref;
|
||||||
|
this.type = types.getType(absHref);
|
||||||
|
this.label = createLabel(absHref === '/' ? domain : split.name);
|
||||||
|
this.time = null;
|
||||||
|
this.size = null;
|
||||||
|
this.parent = null;
|
||||||
|
this.status = null;
|
||||||
|
this.content = {};
|
||||||
|
|
||||||
|
if (split.parent) {
|
||||||
|
this.parent = cache[split.parent] || new Entry(split.parent);
|
||||||
|
this.parent.content[this.absHref] = this;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get = function (absHref, time, size, status) {
|
||||||
|
|
||||||
|
absHref = absHref || location;
|
||||||
|
|
||||||
|
var self = cache[absHref] || new Entry(absHref);
|
||||||
|
|
||||||
|
if (_.isNumber(time)) {
|
||||||
|
self.time = time;
|
||||||
|
}
|
||||||
|
if (_.isNumber(size)) {
|
||||||
|
self.size = size;
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
self.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
|
||||||
|
folderstatus = module.isDefined('ext/folderstatus') ? module.require('ext/folderstatus') : {},
|
||||||
|
|
||||||
|
fetchStatus = function (absHref, callback) {
|
||||||
|
|
||||||
|
var self = cache[absHref] || new Entry(absHref);
|
||||||
|
|
||||||
|
if (self.status || !self.isFolder()) {
|
||||||
|
callback(self);
|
||||||
|
} else if (folderstatus[absHref]) {
|
||||||
|
self.status = folderstatus[absHref];
|
||||||
|
callback(self);
|
||||||
|
} else {
|
||||||
|
ajaxRequest(self, null, callback);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchContent = function (absHref, parser, callback) {
|
||||||
|
|
||||||
|
var self = cache[absHref] || new Entry(absHref);
|
||||||
|
|
||||||
|
if (self.isContentFetched || _.keys(self.content).length > 1) {
|
||||||
|
self.isContentFetched = true;
|
||||||
|
callback(self);
|
||||||
|
} else {
|
||||||
|
fetchStatus(absHref, function (self) {
|
||||||
|
|
||||||
|
self.isContentFetched = true;
|
||||||
|
if (self.status === 'h5ai') {
|
||||||
|
ajaxRequest(self, parser, callback);
|
||||||
|
} else {
|
||||||
|
callback(self);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_.extend(Entry.prototype, {
|
||||||
|
|
||||||
|
isFolder: function () {
|
||||||
|
|
||||||
|
return reEndsWithSlash.test(this.absHref);
|
||||||
|
},
|
||||||
|
|
||||||
|
isCurrentFolder: function () {
|
||||||
|
|
||||||
|
return this.absHref === location;
|
||||||
|
},
|
||||||
|
|
||||||
|
isDomain: function () {
|
||||||
|
|
||||||
|
return this.absHref === '/';
|
||||||
|
},
|
||||||
|
|
||||||
|
isEmpty: function () {
|
||||||
|
|
||||||
|
return _.keys(this.content).length === 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchStatus: function (callback) {
|
||||||
|
|
||||||
|
return fetchStatus(this.absHref, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchContent: function (parser, callback) {
|
||||||
|
|
||||||
|
return fetchContent(this.absHref, parser, callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
getCrumb: function () {
|
||||||
|
|
||||||
|
var entry = this,
|
||||||
|
crumb = [entry];
|
||||||
|
|
||||||
|
while (entry.parent) {
|
||||||
|
entry = entry.parent;
|
||||||
|
crumb.unshift(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return crumb;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSubfolders: function () {
|
||||||
|
|
||||||
|
return _.sortBy(_.filter(this.content, function (entry) {
|
||||||
|
|
||||||
|
return entry.isFolder();
|
||||||
|
}), function (entry) {
|
||||||
|
|
||||||
|
return entry.absHref;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getStats: function () {
|
||||||
|
|
||||||
|
var folders = 0,
|
||||||
|
files = 0;
|
||||||
|
|
||||||
|
_.each(this.content, function (entry) {
|
||||||
|
|
||||||
|
if (entry.isFolder()) {
|
||||||
|
folders += 1;
|
||||||
|
} else {
|
||||||
|
files += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var depth = 0,
|
||||||
|
entry = this;
|
||||||
|
|
||||||
|
while (entry.parent) {
|
||||||
|
depth += 1;
|
||||||
|
entry = entry.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
folders: folders,
|
||||||
|
files: files,
|
||||||
|
depth: depth
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
get: get
|
||||||
|
};
|
||||||
|
});
|
42
src/_h5ai/js/inc/parser/apache-autoindex.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
module.define('parser/apache-autoindex', [jQuery, 'core/format', 'model/entry'], function ($, format, Entry) {
|
||||||
|
|
||||||
|
var parseTableRow = function (absHref, tr) {
|
||||||
|
|
||||||
|
var $tds = $(tr).find('td'),
|
||||||
|
$a = $tds.eq(1).find('a'),
|
||||||
|
label = $a.text(),
|
||||||
|
time = format.parseDate($tds.eq(2).text(), 'DD-MMM-YYYY HH:mm'),
|
||||||
|
size = format.parseSize($tds.eq(3).text());
|
||||||
|
|
||||||
|
absHref = absHref + $a.attr('href');
|
||||||
|
|
||||||
|
return label === 'Parent Directory' ? null : Entry.get(absHref, time, size);
|
||||||
|
},
|
||||||
|
|
||||||
|
parseTable = function (absHref, table) {
|
||||||
|
|
||||||
|
return _.compact(_.map($(table).find('td').closest('tr'), function (tr) {
|
||||||
|
|
||||||
|
return parseTableRow(absHref, tr);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
parse = function (absHref, html) {
|
||||||
|
|
||||||
|
var id = '#data-apache-autoindex',
|
||||||
|
$html = $(html),
|
||||||
|
$id = $html.filter(id);
|
||||||
|
|
||||||
|
if (!$id.length) {
|
||||||
|
$id = $html.find(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseTable(absHref, $id.find('table'));
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'apache-autoindex',
|
||||||
|
parse: parse
|
||||||
|
};
|
||||||
|
});
|
48
src/_h5ai/js/inc/parser/generic-json.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
module.define('parser/generic-json', [jQuery, 'core/settings', 'model/entry'], function ($, settings, Entry) {
|
||||||
|
|
||||||
|
// expectes an hash of the form
|
||||||
|
// {
|
||||||
|
// entries: [
|
||||||
|
// {absHref: String, time: Number, size: Number, status: Number or "h5ai"}
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
|
var parseJson = function (absHref, json) {
|
||||||
|
|
||||||
|
if (json.hasOwnProperty('customHeader')) {
|
||||||
|
settings.custom.header = json.customHeader;
|
||||||
|
}
|
||||||
|
if (json.hasOwnProperty('customFooter')) {
|
||||||
|
settings.custom.footer = json.customFooter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.map(json.entries, function (jsonEntry) {
|
||||||
|
|
||||||
|
return Entry.get(jsonEntry.absHref, jsonEntry.time, jsonEntry.size, jsonEntry.status);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
parseJsonStr = function (absHref, jsonStr) {
|
||||||
|
|
||||||
|
return parseJson(absHref, JSON.parse($.trim(jsonStr) || '{}'));
|
||||||
|
},
|
||||||
|
|
||||||
|
parse = function (absHref, html) {
|
||||||
|
|
||||||
|
var id = '#data-generic-json',
|
||||||
|
$html = $(html),
|
||||||
|
$id = $html.filter(id);
|
||||||
|
|
||||||
|
if (!$id.length) {
|
||||||
|
$id = $html.find(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseJsonStr(absHref, $id.text());
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'generic-json',
|
||||||
|
parse: parse
|
||||||
|
};
|
||||||
|
});
|
135
src/_h5ai/js/inc/view/extended.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
module.define('view/extended', [jQuery, 'core/settings', 'core/resource', 'core/format', 'core/event', 'core/entry'], function ($, allsettings, resource, format, event, entry) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
modes: ['details', 'icons'],
|
||||||
|
setParentFolderLabels: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.view),
|
||||||
|
|
||||||
|
template = '<li class="entry">' +
|
||||||
|
'<a>' +
|
||||||
|
'<span class="icon small"><img /></span>' +
|
||||||
|
'<span class="icon big"><img /></span>' +
|
||||||
|
'<span class="label" />' +
|
||||||
|
'<span class="date" />' +
|
||||||
|
'<span class="size" />' +
|
||||||
|
'</a>' +
|
||||||
|
'</li>',
|
||||||
|
hintTemplate = '<span class="hint"></span>',
|
||||||
|
listTemplate = '<ul>' +
|
||||||
|
'<li class="header">' +
|
||||||
|
'<a class="icon"></a>' +
|
||||||
|
'<a class="label" href="#"><span class="l10n-name"></span></a>' +
|
||||||
|
'<a class="date" href="#"><span class="l10n-lastModified"></span></a>' +
|
||||||
|
'<a class="size" href="#"><span class="l10n-size"></span></a>' +
|
||||||
|
'</li>' +
|
||||||
|
'</ul>',
|
||||||
|
emptyTemplate = '<div class="empty l10n-empty">empty</div>',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// updates this single entry
|
||||||
|
update = function (entry) {
|
||||||
|
|
||||||
|
if (entry.$extended && entry.status && entry.$extended.data('status') === entry.status) {
|
||||||
|
return entry.$extended;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $html = $(template),
|
||||||
|
$a = $html.find('a'),
|
||||||
|
$imgSmall = $html.find('.icon.small img'),
|
||||||
|
$imgBig = $html.find('.icon.big img'),
|
||||||
|
$label = $html.find('.label'),
|
||||||
|
$date = $html.find('.date'),
|
||||||
|
$size = $html.find('.size'),
|
||||||
|
icon16 = resource.icon(entry.type),
|
||||||
|
icon48 = resource.icon(entry.type, true),
|
||||||
|
escapedHref = entry.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
|
||||||
|
|
||||||
|
$html
|
||||||
|
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||||
|
.data('entry', entry)
|
||||||
|
.data('status', entry.status);
|
||||||
|
|
||||||
|
if (entry.isParentFolder) {
|
||||||
|
icon16 = resource.icon('folder-parent');
|
||||||
|
icon48 = resource.icon('folder-parent', true);
|
||||||
|
if (!settings.setParentFolderLabels) {
|
||||||
|
$label.addClass('l10n-parentDirectory');
|
||||||
|
}
|
||||||
|
$html.addClass('folder-parent');
|
||||||
|
}
|
||||||
|
|
||||||
|
$a.attr('href', entry.absHref);
|
||||||
|
$imgSmall.attr('src', icon16).attr('alt', entry.type);
|
||||||
|
$imgBig.attr('src', icon48).attr('alt', entry.type);
|
||||||
|
$label.text(entry.label);
|
||||||
|
$date.data('time', entry.time).text(format.formatDate(entry.time));
|
||||||
|
$size.data('bytes', entry.size).text(format.formatSize(entry.size));
|
||||||
|
|
||||||
|
if (entry.isFolder() && _.isNumber(entry.status)) {
|
||||||
|
if (entry.status === 200) {
|
||||||
|
$html.addClass('page');
|
||||||
|
$imgSmall.attr('src', resource.icon('folder-page'));
|
||||||
|
$imgBig.attr('src', resource.icon('folder-page', true));
|
||||||
|
} else {
|
||||||
|
$html.addClass('error');
|
||||||
|
$label.append($(hintTemplate).text(' ' + entry.status + ' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.$extended) {
|
||||||
|
entry.$extended.replaceWith($html);
|
||||||
|
}
|
||||||
|
entry.$extended = $html;
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseenter = function () {
|
||||||
|
|
||||||
|
var entry = $(this).closest('.entry').data('entry');
|
||||||
|
event.pub('entry.mouseenter', entry);
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseleave = function () {
|
||||||
|
|
||||||
|
var entry = $(this).closest('.entry').data('entry');
|
||||||
|
event.pub('entry.mouseleave', entry);
|
||||||
|
},
|
||||||
|
|
||||||
|
// creates the view for entry content
|
||||||
|
init = function (entry) {
|
||||||
|
|
||||||
|
var $extended = $('#extended'),
|
||||||
|
$ul = $(listTemplate);
|
||||||
|
|
||||||
|
if (entry.parent) {
|
||||||
|
$ul.append(update(entry.parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(entry.content, function (e) {
|
||||||
|
|
||||||
|
$ul.append(update(e));
|
||||||
|
|
||||||
|
e.fetchStatus(function (e) {
|
||||||
|
|
||||||
|
update(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$extended.append($ul);
|
||||||
|
|
||||||
|
if (entry.isEmpty()) {
|
||||||
|
$extended.append($(emptyTemplate));
|
||||||
|
}
|
||||||
|
|
||||||
|
$extended
|
||||||
|
.on('mouseenter', '.entry a', onMouseenter)
|
||||||
|
.on('mouseleave', '.entry a', onMouseleave);
|
||||||
|
};
|
||||||
|
|
||||||
|
init(entry);
|
||||||
|
});
|
35
src/_h5ai/js/inc/view/spacing.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
module.define('view/spacing', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
maxWidth: 960,
|
||||||
|
top: 50,
|
||||||
|
right: "auto",
|
||||||
|
bottom: 50,
|
||||||
|
left: "auto"
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.spacing),
|
||||||
|
|
||||||
|
adjustSpacing = function () {
|
||||||
|
|
||||||
|
$('#content').css({
|
||||||
|
'margin-top': settings.top + $('#topbar').outerHeight(),
|
||||||
|
'margin-bottom': settings.bottom + $('#bottombar').outerHeight()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
$('#content').css({
|
||||||
|
'max-width': settings.maxWidth,
|
||||||
|
'margin-right': settings.right,
|
||||||
|
'margin-left': settings.left
|
||||||
|
});
|
||||||
|
|
||||||
|
event.sub('ready', adjustSpacing);
|
||||||
|
$(window).on('resize', adjustSpacing);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
77
src/_h5ai/js/inc/view/viewmode.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
module.define('view/viewmode', [jQuery, 'core/settings', 'core/resource', 'core/store'], function ($, allsettings, resource, store) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
modes: ['details', 'icons'],
|
||||||
|
setParentFolderLabels: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.view),
|
||||||
|
|
||||||
|
storekey = 'h5ai.viewmode',
|
||||||
|
|
||||||
|
templates = {
|
||||||
|
details: '<li id="viewdetails" class="view">' +
|
||||||
|
'<a href="#">' +
|
||||||
|
'<img src="' + resource.image('view-details') + '" alt="view-details" />' +
|
||||||
|
'<span class="l10n-details">details</span>' +
|
||||||
|
'</a>' +
|
||||||
|
'</li>',
|
||||||
|
icons: '<li id="viewicons" class="view">' +
|
||||||
|
'<a href="#">' +
|
||||||
|
'<img src="' + resource.image('view-icons') + '" alt="view-icons" />' +
|
||||||
|
'<span class="l10n-icons">icons</span>' +
|
||||||
|
'</a>' +
|
||||||
|
'</li>'
|
||||||
|
},
|
||||||
|
|
||||||
|
update = function (viewmode) {
|
||||||
|
|
||||||
|
var $viewDetails = $('#viewdetails'),
|
||||||
|
$viewIcons = $('#viewicons'),
|
||||||
|
$extended = $('#extended');
|
||||||
|
|
||||||
|
if (viewmode) {
|
||||||
|
store.put(storekey, viewmode);
|
||||||
|
} else {
|
||||||
|
viewmode = store.get(storekey);
|
||||||
|
}
|
||||||
|
viewmode = $.inArray(viewmode, settings.modes) >= 0 ? viewmode : settings.modes[0];
|
||||||
|
|
||||||
|
$viewDetails.add($viewIcons).removeClass('current');
|
||||||
|
if (viewmode === 'details') {
|
||||||
|
$viewDetails.addClass('current');
|
||||||
|
$extended.addClass('details-view').removeClass('icons-view').show();
|
||||||
|
} else if (viewmode === 'icons') {
|
||||||
|
$viewIcons.addClass('current');
|
||||||
|
$extended.removeClass('details-view').addClass('icons-view').show();
|
||||||
|
} else {
|
||||||
|
$extended.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
var $navbar = $('#navbar'),
|
||||||
|
$extended = $('#extended');
|
||||||
|
|
||||||
|
settings.modes = _.intersection(settings.modes, defaults.modes);
|
||||||
|
|
||||||
|
if (settings.modes.length > 1) {
|
||||||
|
_.each(['icons', 'details'], function (view) {
|
||||||
|
if ($.inArray(view, settings.modes) >= 0) {
|
||||||
|
$(templates[view])
|
||||||
|
.appendTo($navbar)
|
||||||
|
.on('click', 'a', function (event) {
|
||||||
|
update(view);
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
@@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
// @include "inc/lib/jquery.min.js"
|
|
||||||
// @include "inc/lib/jquery.mousewheel.js"
|
|
||||||
// @include "inc/lib/jquery.fracs-core.min.js"
|
|
||||||
// @include "inc/lib/jquery.scrollpanel.js"
|
|
||||||
// @include "inc/lib/jquery.qrcode.js"
|
|
||||||
|
|
||||||
// @include "inc/lib/amplify.min.js"
|
|
||||||
// @include "inc/lib/base64.js"
|
|
||||||
// @include "inc/lib/date.js"
|
|
||||||
|
|
||||||
// @include "inc/main.js"
|
|
4
src/_h5ai/js/modernizr.min.js
vendored
25
src/_h5ai/js/scripts.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
// libs
|
||||||
|
// ----
|
||||||
|
// @include "inc/lib/modernizr-2.5.3.min.js"
|
||||||
|
// @include "inc/lib/moment-1.5.0.min.js"
|
||||||
|
// @include "inc/lib/json2.js"
|
||||||
|
// @include "inc/lib/base64.js"
|
||||||
|
|
||||||
|
// underscore libs
|
||||||
|
// ---------------
|
||||||
|
// @include "inc/lib/underscore-1.3.1.min.js"
|
||||||
|
// @include "inc/lib/module.js"
|
||||||
|
|
||||||
|
// jQuery libs
|
||||||
|
// -----------
|
||||||
|
// @include "inc/lib/jquery-1.7.1.min.js"
|
||||||
|
// @include "inc/lib/jquery.fracs-0.11.min.js"
|
||||||
|
// @include "inc/lib/jquery.mousewheel-3.0.6.js"
|
||||||
|
// @include "inc/lib/jquery.qrcode.js"
|
||||||
|
// @include "inc/lib/jquery.scrollpanel.js"
|
||||||
|
// @include "inc/lib/amplify-1.1.0.min.js"
|
||||||
|
|
||||||
|
// h5ai
|
||||||
|
// ----
|
||||||
|
// @include "inc/main.js"
|
@@ -1,150 +1,125 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
function safe_dirname($path, $endWithSlash = false) {
|
require_once(str_replace("\\", "/", __DIR__) . "/inc/H5ai.php");
|
||||||
|
|
||||||
$path = str_replace("\\", "/", dirname($path));
|
|
||||||
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
|
$h5ai = new H5ai();
|
||||||
|
$options = $h5ai->getOptions();
|
||||||
|
|
||||||
|
|
||||||
|
function json_exit($obj) {
|
||||||
|
|
||||||
|
$obj["code"] = 0;
|
||||||
|
echo json_encode($obj);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
define("H5AI_ABS_PATH", safe_dirname(safe_dirname(__FILE__)));
|
function json_fail($code, $msg = "", $cond = true) {
|
||||||
|
|
||||||
function require_h5ai($lib) {
|
|
||||||
|
|
||||||
require_once(H5AI_ABS_PATH . $lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function fail($code, $msg, $cond = true) {
|
|
||||||
if ($cond) {
|
if ($cond) {
|
||||||
echo "$code: $msg";
|
echo json_encode(array("code" => $code, "msg" => $msg));
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkKeys($keys) {
|
function check_keys($keys) {
|
||||||
$values = array();
|
$values = array();
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
fail(1, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST));
|
json_fail(101, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST));
|
||||||
$values[] = $_REQUEST[$key];
|
$values[] = $_REQUEST[$key];
|
||||||
}
|
}
|
||||||
return $values;
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/H5ai.php");
|
list($action) = check_keys(array("action"));
|
||||||
$h5ai = new H5ai();
|
|
||||||
$options = $h5ai->getOptions();
|
|
||||||
|
|
||||||
|
|
||||||
list($action) = checkKeys(array("action"));
|
if ($action === "getthumbsrc") {
|
||||||
|
|
||||||
|
if (!$options["thumbnails"]["enabled"]) {
|
||||||
if ($action === "httpcodes") {
|
json_fail(1, "thumbnails disabled");
|
||||||
|
|
||||||
list($hrefs) = checkKeys(array("hrefs"));
|
|
||||||
|
|
||||||
function getHttpCodes($h5ai, $hrefs) {
|
|
||||||
|
|
||||||
$codes = array();
|
|
||||||
foreach ($hrefs as $href) {
|
|
||||||
$href = trim($href);
|
|
||||||
if (strlen($href) > 0) {
|
|
||||||
$codes[$href] = $h5ai->getHttpCode($href);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $codes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$hrefs = preg_split("/;/", $hrefs);
|
list($srcAbsHref, $width, $height, $mode) = check_keys(array("href", "width", "height", "mode"));
|
||||||
$codes = getHttpCodes($h5ai, $hrefs);
|
|
||||||
|
|
||||||
echo count($codes) === 0 ? "{}" : json_encode($codes);
|
H5ai::req_once("/php/inc/Thumbnail.php");
|
||||||
}
|
H5ai::req_once("/php/inc/Image.php");
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "thumb") {
|
|
||||||
|
|
||||||
fail(0, "thumbs are disabled", !$options["showThumbs"]);
|
|
||||||
list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode"));
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/Thumbnail.php");
|
|
||||||
require_h5ai("/php/inc/Image.php");
|
|
||||||
|
|
||||||
$srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
|
$srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
|
||||||
|
|
||||||
if (!Thumbnail::isUsable()) {
|
if (!Thumbnail::isUsable()) {
|
||||||
Image::showImage($srcAbsPath);
|
json_fail(2, "thumbnails not supported");
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$thumbnail = new Thumbnail($h5ai, $srcAbsHref, $mode, $width, $height);
|
$thumbnail = new Thumbnail($h5ai, $srcAbsHref, $mode, $width, $height);
|
||||||
$thumbnail->create(1);
|
$thumbnail->create(1);
|
||||||
if (file_exists($thumbnail->getPath())) {
|
if (!file_exists($thumbnail->getPath())) {
|
||||||
Image::showImage($thumbnail->getPath());
|
json_fail(3, "thumbnail creation failed");
|
||||||
} else {
|
|
||||||
$image = new Image();
|
|
||||||
$image->setSource($srcAbsPath);
|
|
||||||
$image->thumb($mode, $width, $height);
|
|
||||||
$image->showDest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_exit(array("absHref" => $thumbnail->getHref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "tree") {
|
else if ($action === "archive") {
|
||||||
|
|
||||||
list($href) = checkKeys(array("href"));
|
json_fail(1, "downloads disabled", !$options["download"]["enabled"]);
|
||||||
|
|
||||||
require_h5ai("/php/inc/Tree.php");
|
list($execution, $format, $hrefs) = check_keys(array("execution", "format", "hrefs"));
|
||||||
|
|
||||||
$absHref = trim($href);
|
H5ai::req_once("/php/inc/Archive.php");
|
||||||
$absPath = $h5ai->getAbsPath($absHref);
|
$archive = new Archive($h5ai);
|
||||||
|
|
||||||
$tree = new TreeEntry($h5ai, $absPath, $absHref);
|
|
||||||
$tree->loadContent();
|
|
||||||
|
|
||||||
echo $tree->contentToHtml();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "zip") {
|
|
||||||
|
|
||||||
fail(0, "zipped download is disabled", !$options["zippedDownload"]);
|
|
||||||
list($hrefs) = checkKeys(array("hrefs"));
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/ZipIt.php");
|
|
||||||
|
|
||||||
$zipit = new ZipIt($h5ai);
|
|
||||||
|
|
||||||
$hrefs = explode(":", trim($hrefs));
|
$hrefs = explode(":", trim($hrefs));
|
||||||
$zipFile = $zipit->zip($hrefs);
|
$target = $archive->create($execution, $format, $hrefs);
|
||||||
|
|
||||||
if (is_string($zipFile)) {
|
if (!is_string($target)) {
|
||||||
$response = array('status' => 'ok', 'id' => basename($zipFile), 'size' => filesize($zipFile));
|
json_fail($target, "package creation failed");
|
||||||
} else {
|
|
||||||
$response = array('status' => 'failed', 'code' => $zipFile);
|
|
||||||
}
|
}
|
||||||
echo json_encode($response);
|
|
||||||
|
json_exit(array("id" => basename($target), "size" => filesize($target)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "getzip") {
|
else if ($action === "getarchive") {
|
||||||
|
|
||||||
list($id) = checkKeys(array("id"));
|
json_fail(1, "downloads disabled", !$options["download"]["enabled"]);
|
||||||
fail(1, "zipped file not found: " . $id, !preg_match("/^h5ai-zip-/", $id));
|
|
||||||
|
|
||||||
$zipFile = str_replace("\\", "/", sys_get_temp_dir()) . "/" . $id;
|
list($id, $as) = check_keys(array("id", "as"));
|
||||||
fail(2, "zipped file not found: " . $id, !file_exists($zipFile));
|
json_fail(2, "file not found", !preg_match("/^h5ai-selection-/", $id));
|
||||||
|
|
||||||
|
$target = H5ai::normalize_path(sys_get_temp_dir(), true) . $id;
|
||||||
|
json_fail(3, "file not found", !file_exists($target));
|
||||||
|
|
||||||
header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\"");
|
|
||||||
header("Content-Type: application/octet-stream");
|
header("Content-Type: application/octet-stream");
|
||||||
header("Content-Length: " . filesize($zipFile));
|
header("Content-Length: " . filesize($target));
|
||||||
|
header("Content-Disposition: attachment; filename=\"$as\"");
|
||||||
header("Connection: close");
|
header("Connection: close");
|
||||||
readfile($zipFile);
|
readfile($target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else if ($action === "getchecks") {
|
||||||
|
|
||||||
|
$php = $h5ai->checks["php"];
|
||||||
|
$cache = $php && $h5ai->checks["cache"];
|
||||||
|
$temp = $php && $h5ai->checks["temp"];
|
||||||
|
|
||||||
|
json_exit(array(
|
||||||
|
"php" => $php,
|
||||||
|
"cache" => $cache,
|
||||||
|
"thumbs" => $cache && $h5ai->checks["gd"],
|
||||||
|
"temp" => $temp,
|
||||||
|
"archive" => $temp && $h5ai->checks["archive"],
|
||||||
|
"tar" => $temp && $h5ai->checks["tar"],
|
||||||
|
"zip" => $temp && $h5ai->checks["zip"]
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
fail(1, "unsupported 'action' specified");
|
json_fail(100, "unsupported action");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
131
src/_h5ai/php/inc/Archive.php
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Archive {
|
||||||
|
|
||||||
|
private static $TAR_CMD = "$(cd [ROOTDIR] && tar --no-recursion -cf [TARGET] [DIRS] [FILES])";
|
||||||
|
private static $ZIP_CMD = "$(cd [ROOTDIR] && zip [TARGET] [FILES])";
|
||||||
|
|
||||||
|
|
||||||
|
private $h5ai, $dirs, $files, $sc401;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct($h5ai) {
|
||||||
|
|
||||||
|
$this->h5ai = $h5ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function create($execution, $format, $hrefs) {
|
||||||
|
|
||||||
|
$this->dirs = array();
|
||||||
|
$this->files = array();
|
||||||
|
$this->sc401 = false;
|
||||||
|
|
||||||
|
$this->addHrefs($hrefs);
|
||||||
|
|
||||||
|
if ($this->sc401) {
|
||||||
|
return 401;
|
||||||
|
} else if (count($this->dirs) === 0 && count($this->files) === 0) {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
$target = H5ai::normalize_path(sys_get_temp_dir(), true) . "h5ai-selection-" . microtime(true) . rand() . "." . $format;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($execution === "shell") {
|
||||||
|
|
||||||
|
if ($format === "tar") {
|
||||||
|
$cmd = Archive::$TAR_CMD;
|
||||||
|
} else if ($format === "zip") {
|
||||||
|
$cmd = Archive::$ZIP_CMD;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$cmd = str_replace("[ROOTDIR]", "\"" . $this->h5ai->getRootAbsPath() . "\"", $cmd);
|
||||||
|
$cmd = str_replace("[TARGET]", "\"" . $target . "\"", $cmd);
|
||||||
|
$cmd = str_replace("[DIRS]", count($this->dirs) ? "\"" . implode("\" \"", array_values($this->dirs)) . "\"" : "", $cmd);
|
||||||
|
$cmd = str_replace("[FILES]", count($this->files) ? "\"" . implode("\" \"", array_values($this->files)) . "\"" : "", $cmd);
|
||||||
|
|
||||||
|
`$cmd`;
|
||||||
|
|
||||||
|
} else if ($execution === "php") {
|
||||||
|
|
||||||
|
$archive = new PharData($target);
|
||||||
|
foreach ($this->dirs as $archivedDir) {
|
||||||
|
$archive->addEmptyDir($archivedDir);
|
||||||
|
}
|
||||||
|
foreach ($this->files as $realFile => $archivedFile) {
|
||||||
|
$archive->addFile($realFile, $archivedFile); // very, very slow :/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exeption $err) {
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
return @filesize($target) ? $target : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function addHrefs($hrefs) {
|
||||||
|
|
||||||
|
foreach ($hrefs as $href) {
|
||||||
|
|
||||||
|
$d = H5ai::normalize_path(dirname($href), true);
|
||||||
|
$n = basename($href);
|
||||||
|
|
||||||
|
$code = $this->h5ai->getHttpCode($d);
|
||||||
|
if ($code == 401) {
|
||||||
|
$this->sc401 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code == "h5ai" && !$this->h5ai->ignoreThisFile($n)) {
|
||||||
|
|
||||||
|
$realFile = $this->h5ai->getAbsPath($href);
|
||||||
|
$archivedFile = preg_replace("!^" . H5ai::normalize_path($this->h5ai->getRootAbsPath(), true) . "!", "", $realFile);
|
||||||
|
|
||||||
|
if (is_dir($realFile)) {
|
||||||
|
$this->addDir($realFile, $archivedFile);
|
||||||
|
} else {
|
||||||
|
$this->addFile($realFile, $archivedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function addFile($realFile, $archivedFile) {
|
||||||
|
|
||||||
|
if (is_readable($realFile)) {
|
||||||
|
$this->files[$realFile] = $archivedFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function addDir($realDir, $archivedDir) {
|
||||||
|
|
||||||
|
$code = $this->h5ai->getHttpCode($this->h5ai->getAbsHref($realDir));
|
||||||
|
if ($code == 401) {
|
||||||
|
$this->sc401 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code == "h5ai") {
|
||||||
|
$this->dirs[] = $archivedDir;
|
||||||
|
|
||||||
|
$files = $this->h5ai->readDir($realDir);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
|
||||||
|
$realFile = $realDir . "/" . $file;
|
||||||
|
$archivedFile = $archivedDir . "/" . $file;
|
||||||
|
|
||||||
|
if (is_dir($realFile)) {
|
||||||
|
$this->addDir($realFile, $archivedFile);
|
||||||
|
} else {
|
||||||
|
$this->addFile($realFile, $archivedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Crumb {
|
|
||||||
|
|
||||||
private $h5ai, $parts;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai) {
|
|
||||||
|
|
||||||
$this->h5ai = $h5ai;
|
|
||||||
$this->parts = array();
|
|
||||||
|
|
||||||
$href = $h5ai->getAbsHref();
|
|
||||||
while ($href !== "/") {
|
|
||||||
$this->parts[] = $href;
|
|
||||||
$href = safe_dirname($href, true);
|
|
||||||
}
|
|
||||||
$this->parts[] = "/";
|
|
||||||
|
|
||||||
$this->parts = array_reverse($this->parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function toHtml() {
|
|
||||||
|
|
||||||
$html = "";
|
|
||||||
$idx = 0;
|
|
||||||
foreach($this->parts as $href) {
|
|
||||||
$idx++;
|
|
||||||
$classes = "crumb folder" . ($idx === 1 ? " domain" : "") . ($idx === count($this->parts) ? " current" : "");
|
|
||||||
$image = $this->h5ai->image($idx === 1 ? "home" : "crumb");
|
|
||||||
$label = $this->h5ai->getLabel($href);
|
|
||||||
$hint = "";
|
|
||||||
|
|
||||||
$code = $this->h5ai->getHttpCode($href);
|
|
||||||
$classes .= " checkedHttpCode";
|
|
||||||
if ($code !== "h5ai") {
|
|
||||||
if ($code === 200) {
|
|
||||||
$hint = "<img class='hint' src='" . $this->h5ai->image("page") . "' alt='page' />";
|
|
||||||
} else {
|
|
||||||
$hint = "<span class='hint'>(" . $code . ")</span>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$html .= "<li class='$classes'>\n";
|
|
||||||
$html .= "\t<a href='$href'>\n";
|
|
||||||
$html .= "\t\t<img src='$image' alt='>' /><span>" . $label . "</span>" . $hint . "\n";
|
|
||||||
$html .= "\t</a>\n";
|
|
||||||
$html .= "</li>\n";
|
|
||||||
}
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Customize {
|
|
||||||
|
|
||||||
private $customHeader, $customFooter;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai) {
|
|
||||||
|
|
||||||
$absPath = $h5ai->getAbsPath();
|
|
||||||
$options = $h5ai->getOptions();
|
|
||||||
$this->customHeader = $options["customHeader"] ? $absPath . "/" . $options["customHeader"] : false;
|
|
||||||
$this->customFooter = $options["customFooter"] ? $absPath . "/" . $options["customFooter"] : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getHeader() {
|
|
||||||
|
|
||||||
return $this->getContent($this->customHeader, "header");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getFooter() {
|
|
||||||
|
|
||||||
return $this->getContent($this->customFooter, "footer");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function getContent($file, $tag) {
|
|
||||||
|
|
||||||
return (is_string($file) && file_exists($file)) ? ("<$tag>" . file_get_contents($file) . "</$tag>") : "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
105
src/_h5ai/php/inc/Entry.php
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Entry {
|
||||||
|
|
||||||
|
|
||||||
|
private static $cache = array();
|
||||||
|
|
||||||
|
|
||||||
|
public static function getCache() {
|
||||||
|
|
||||||
|
return Entry::$cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function get($h5ai, $absPath, $absHref) {
|
||||||
|
|
||||||
|
if (array_key_exists($absHref, Entry::$cache)) {
|
||||||
|
return Entry::$cache[$absHref];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Entry($h5ai, $absPath, $absHref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function sort() {
|
||||||
|
|
||||||
|
uasort(Entry::$cache, function ($entry1, $entry2) {
|
||||||
|
|
||||||
|
return strcasecmp($entry1->absHref, $entry2->absHref);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public $h5ai, $absPath, $absHref, $date, $size, $isFolder, $parent;
|
||||||
|
|
||||||
|
|
||||||
|
private function __construct($h5ai, $absPath, $absHref) {
|
||||||
|
|
||||||
|
$this->h5ai = $h5ai;
|
||||||
|
|
||||||
|
$this->absPath = H5ai::normalize_path($absPath);
|
||||||
|
|
||||||
|
$this->isFolder = is_dir($this->absPath);
|
||||||
|
$this->absHref = H5ai::normalize_path($absHref, $this->isFolder);
|
||||||
|
|
||||||
|
$this->date = filemtime($this->absPath);
|
||||||
|
|
||||||
|
if ($this->isFolder) {
|
||||||
|
$this->size = null;
|
||||||
|
} else {
|
||||||
|
$this->size = filesize($this->absPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->parent = null;
|
||||||
|
if ($this->absHref !== "/") {
|
||||||
|
$this->parent = Entry::get($this->h5ai, H5ai::normalize_path(dirname($this->absPath)), H5ai::normalize_path(dirname($this->absHref), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry::$cache[$this->absHref] = $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function toJsonObject($withStatus) {
|
||||||
|
|
||||||
|
$obj = array(
|
||||||
|
"absHref" => $this->absHref,
|
||||||
|
"time" => ($this->date * 1000),
|
||||||
|
"size" => $this->size
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($withStatus && $this->isFolder) {
|
||||||
|
$obj["status"] = $this->h5ai->getHttpCode($this->absHref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getParent() {
|
||||||
|
|
||||||
|
return $this->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getContent() {
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
|
||||||
|
if ($this->h5ai->getHttpCode($this->absHref) !== "h5ai") {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = $this->h5ai->readDir($this->absPath);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$entry = Entry::get($this->h5ai, $this->absPath . "/" . $file, $this->absHref . rawurlencode($file));
|
||||||
|
$content[$entry->absPath] = $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@@ -1,152 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/Thumbnail.php");
|
|
||||||
|
|
||||||
|
|
||||||
class Entry {
|
|
||||||
|
|
||||||
private $h5ai, $label, $absPath, $absHref, $date, $isFolder, $type, $size;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai, $absPath, $absHref, $type = null, $label = null) {
|
|
||||||
|
|
||||||
$this->h5ai = $h5ai;
|
|
||||||
$this->label = $label !== null ? $label : $this->h5ai->getLabel($absHref);
|
|
||||||
$this->absPath = $this->h5ai->normalizePath($absPath, false);
|
|
||||||
$this->isFolder = is_dir($this->absPath);
|
|
||||||
$this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
|
|
||||||
|
|
||||||
$this->date = filemtime($this->absPath);
|
|
||||||
|
|
||||||
if ($this->isFolder) {
|
|
||||||
$this->type = $type !== null ? $type : "folder";
|
|
||||||
$this->size = "";
|
|
||||||
} else {
|
|
||||||
$this->type = $type !== null ? $type : $this->h5ai->getType($this->absPath);
|
|
||||||
$this->size = filesize($this->absPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function isFolder() {
|
|
||||||
|
|
||||||
return $this->isFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function toHtml() {
|
|
||||||
|
|
||||||
$classes = "entry " . ($this->isFolder ? "folder " : "file ") . $this->type;
|
|
||||||
$imgClass = "";
|
|
||||||
$img = $this->type;
|
|
||||||
$smallImg = $this->h5ai->icon($this->type);
|
|
||||||
$bigImg = $this->h5ai->icon($this->type, true);
|
|
||||||
$hint = "";
|
|
||||||
|
|
||||||
if ($this->isFolder && $this->type !== "folder-parent") {
|
|
||||||
$code = $this->h5ai->getHttpCode($this->absHref);
|
|
||||||
$classes .= " checkedHttpCode";
|
|
||||||
if ($code !== "h5ai") {
|
|
||||||
if ($code === 200) {
|
|
||||||
$img = "folder-page";
|
|
||||||
$smallImg = $this->h5ai->icon("folder-page");
|
|
||||||
$bigImg = $this->h5ai->icon("folder-page", true);
|
|
||||||
} else {
|
|
||||||
$classes .= " error";
|
|
||||||
$hint = "<span class='hint'> " . $code . " </span>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($this->h5ai->showThumbs() && in_array($this->type, $this->h5ai->getThumbTypes())) {
|
|
||||||
$imgClass = " class='thumb' ";
|
|
||||||
$thumbnail = new Thumbnail($this->h5ai, $this->absHref, "square", 16, 16);
|
|
||||||
$thumbnail->create();
|
|
||||||
$smallImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
|
|
||||||
$thumbnail = new Thumbnail($this->h5ai,$this->absHref, "rational", 96, 46);
|
|
||||||
$thumbnail->create();
|
|
||||||
$bigImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = "\t<li class='" . $classes . "'>\n";
|
|
||||||
$html .= "\t\t<a href='" . $this->absHref . "'>\n";
|
|
||||||
$html .= "\t\t\t<span class='icon small'><img " . $imgClass . " src='" . $smallImg . "' alt='" . $img . "' /></span>\n";
|
|
||||||
$html .= "\t\t\t<span class='icon big'><img " . $imgClass . " src='" . $bigImg . "' alt='" . $img . "' /></span>\n";
|
|
||||||
$html .= "\t\t\t<span class='label'>" . $this->label . $hint . "</span>\n";
|
|
||||||
$html .= "\t\t\t<span class='date' data-time='" . $this->date . "000'></span>\n";
|
|
||||||
$html .= "\t\t\t<span class='size' data-bytes='" . $this->size . "'>" . $this->size . "</span>\n";
|
|
||||||
$html .= "\t\t</a>\n";
|
|
||||||
$html .= "\t</li>\n";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Extended {
|
|
||||||
|
|
||||||
private $h5ai, $parent, $content;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai) {
|
|
||||||
|
|
||||||
$this->h5ai = $h5ai;
|
|
||||||
$this->parent = null;
|
|
||||||
$this->content = array();
|
|
||||||
$this->loadContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function loadContent() {
|
|
||||||
|
|
||||||
if ($this->h5ai->getAbsHref() !== "/") {
|
|
||||||
$options = $this->h5ai->getOptions();
|
|
||||||
$parentPath = safe_dirname($this->h5ai->getAbsPath());
|
|
||||||
$parentHref = safe_dirname($this->h5ai->getAbsHref(), true);
|
|
||||||
$label = $options["setParentFolderLabels"] === true ? $this->h5ai->getLabel($parentHref) : "<span class='l10n-parentDirectory'>Parent Directory</span>";
|
|
||||||
$this->parent = new Entry($this->h5ai, $parentPath, $parentHref, "folder-parent", $label);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->content = array();
|
|
||||||
|
|
||||||
$files = $this->h5ai->readDir($this->h5ai->getAbsPath());
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$absPath = $this->h5ai->getAbsPath() . "/" . $file;
|
|
||||||
$absHref = $this->h5ai->getAbsHref() . rawurlencode($file);
|
|
||||||
$this->content[$absPath] = new Entry($this->h5ai, $absPath, $absHref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function toHtml() {
|
|
||||||
|
|
||||||
$html = "<section id='extended' class='" . $this->h5ai->getView() . "-view clearfix'>\n";
|
|
||||||
$html .= "<ul>\n";
|
|
||||||
$html .= $this->generateHeaders();
|
|
||||||
if ($this->parent !== null) {
|
|
||||||
$html .= $this->parent->toHtml();
|
|
||||||
}
|
|
||||||
foreach($this->content as $entry) {
|
|
||||||
$html .= $entry->toHtml();
|
|
||||||
}
|
|
||||||
$html .= "</ul>\n";
|
|
||||||
if (count($this->content) === 0) {
|
|
||||||
$html .= "<div class='empty l10n-empty'>empty</div>";
|
|
||||||
}
|
|
||||||
$html .= "<div class='no-match l10n-noMatch'>no match</div>";
|
|
||||||
$html .="</section>";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function generateHeaders() {
|
|
||||||
|
|
||||||
$html = "\t<li class='header'>\n";
|
|
||||||
$html .= "\t\t<a class='icon'></a>\n";
|
|
||||||
$html .= "\t\t<a class='label' href='#'><span class='l10n-name'>Name</span></a>\n";
|
|
||||||
$html .= "\t\t<a class='date' href='#'><span class='l10n-lastModified'>Last modified</span></a>\n";
|
|
||||||
$html .= "\t\t<a class='size' href='#'><span class='l10n-size'>Size</span></a>\n";
|
|
||||||
$html .= "\t</li>\n";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
@@ -1,52 +1,43 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_h5ai("/config.php");
|
|
||||||
require_h5ai("/php/inc/Cache.php");
|
define("H5AI_ABS_PATH", H5ai::normalize_path(dirname(dirname(dirname(__FILE__)))));
|
||||||
|
|
||||||
|
|
||||||
|
H5ai::req_once("/config.php");
|
||||||
|
H5ai::req_once("/php/inc/Cache.php");
|
||||||
|
H5ai::req_once("/php/inc/Entry.php");
|
||||||
|
|
||||||
|
|
||||||
class H5ai {
|
class H5ai {
|
||||||
|
|
||||||
private static $VIEWMODES = array("details", "icons");
|
|
||||||
|
|
||||||
private $h5aiAbsPath,
|
public static final function normalize_path($path, $endWithSlash = false) {
|
||||||
$rootAbsPath, $ignore, $ignoreRE,
|
|
||||||
$config, $options, $types, $langs,
|
|
||||||
$cache,
|
|
||||||
$rootAbsHref, $h5aiAbsHref, $domain,
|
|
||||||
$absHref, $absPath,
|
|
||||||
$view;
|
|
||||||
|
|
||||||
|
$path = str_replace("\\", "/", $path);
|
||||||
public function __construct() {
|
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
|
||||||
|
|
||||||
$this->h5aiAbsPath = H5AI_ABS_PATH;
|
|
||||||
|
|
||||||
global $H5AI_CONFIG;
|
|
||||||
$this->rootAbsPath = $H5AI_CONFIG["ROOT_ABS_PATH"];
|
|
||||||
$this->ignore = $H5AI_CONFIG["IGNORE"];
|
|
||||||
$this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"];
|
|
||||||
|
|
||||||
$this->config = $this->loadConfig($this->h5aiAbsPath . "/config.js");
|
|
||||||
$this->options = $this->config["options"];
|
|
||||||
$this->types = $this->config["types"];
|
|
||||||
$this->langs = $this->config["langs"];
|
|
||||||
|
|
||||||
$this->cache = new Cache($this->h5aiAbsPath . "/cache");
|
|
||||||
|
|
||||||
$this->rootAbsHref = $this->options["rootAbsHref"];
|
|
||||||
$this->h5aiAbsHref = $this->options["h5aiAbsHref"];
|
|
||||||
$this->domain = getenv("HTTP_HOST");
|
|
||||||
|
|
||||||
$this->absHref = $this->normalizePath(preg_replace('/\\?.*/', '', getenv("REQUEST_URI")), true);
|
|
||||||
$this->absPath = $this->getAbsPath($this->absHref);
|
|
||||||
|
|
||||||
$this->view = $this->options["viewmodes"][0];
|
|
||||||
if (!in_array($this->view, H5ai::$VIEWMODES)) {
|
|
||||||
$this->view = H5ai::$VIEWMODES[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function loadConfig($file) {
|
public static final function req_once($lib) {
|
||||||
|
|
||||||
|
require_once(H5AI_ABS_PATH . $lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final function starts_with($sequence, $start) {
|
||||||
|
|
||||||
|
return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final function ends_with($sequence, $end) {
|
||||||
|
|
||||||
|
return strcasecmp(substr($sequence, -strlen($end)), $end) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final function load_config($file) {
|
||||||
|
|
||||||
$str = file_exists($file) ? file_get_contents($file) : "";
|
$str = file_exists($file) ? file_get_contents($file) : "";
|
||||||
|
|
||||||
@@ -60,9 +51,47 @@ class H5ai {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getH5aiAbsPath() {
|
|
||||||
|
|
||||||
return $this->h5aiAbsPath;
|
|
||||||
|
private $h5aiAbsPath,
|
||||||
|
$rootAbsPath, $ignore, $ignoreRE,
|
||||||
|
$config, $options,
|
||||||
|
$rootAbsHref, $h5aiAbsHref,
|
||||||
|
$absHref, $absPath,
|
||||||
|
$cache;
|
||||||
|
|
||||||
|
public $checks;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
|
||||||
|
$this->h5aiAbsPath = H5ai::normalize_path(H5AI_ABS_PATH);
|
||||||
|
|
||||||
|
global $H5AI_CONFIG;
|
||||||
|
$this->rootAbsPath = H5ai::normalize_path($H5AI_CONFIG["ROOT_ABS_PATH"]);
|
||||||
|
$this->ignore = $H5AI_CONFIG["IGNORE"];
|
||||||
|
$this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"];
|
||||||
|
|
||||||
|
$this->config = H5ai::load_config($this->h5aiAbsPath . "/config.js");
|
||||||
|
$this->options = $this->config["options"];
|
||||||
|
|
||||||
|
$this->rootAbsHref = H5ai::normalize_path($this->options["rootAbsHref"], true);
|
||||||
|
$this->h5aiAbsHref = H5ai::normalize_path($this->options["h5aiAbsHref"], true);
|
||||||
|
|
||||||
|
$this->absHref = H5ai::normalize_path(preg_replace('/\\?.*/', '', getenv("REQUEST_URI")), true);
|
||||||
|
$this->absPath = $this->getAbsPath($this->absHref);
|
||||||
|
|
||||||
|
$this->cache = new Cache($this->h5aiAbsPath . "/cache");
|
||||||
|
|
||||||
|
$this->checks = array(
|
||||||
|
"php" => version_compare(PHP_VERSION, "5.2.0") >= 0,
|
||||||
|
"archive" => class_exists("PharData"),
|
||||||
|
"gd" => GD_VERSION != "GD_VERSION",
|
||||||
|
"cache" => is_writable($this->h5aiAbsPath . "/cache"),
|
||||||
|
"temp" => is_writable(sys_get_temp_dir()),
|
||||||
|
"tar" => preg_match("/tar$/", `which tar`) > 0,
|
||||||
|
"zip" => preg_match("/zip$/", `which zip`) > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +101,12 @@ class H5ai {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getH5aiAbsPath() {
|
||||||
|
|
||||||
|
return $this->h5aiAbsPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getRootAbsHref() {
|
public function getRootAbsHref() {
|
||||||
|
|
||||||
return $this->rootAbsHref;
|
return $this->rootAbsHref;
|
||||||
@@ -84,54 +119,18 @@ class H5ai {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getDomain() {
|
|
||||||
|
|
||||||
return $this->domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getView() {
|
|
||||||
|
|
||||||
return $this->view;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function api() {
|
public function api() {
|
||||||
|
|
||||||
return $this->h5aiAbsHref . "php/api.php";
|
return $this->h5aiAbsHref . "php/api.php";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function image($id) {
|
|
||||||
|
|
||||||
return $this->h5aiAbsHref . "images/" . $id . ".png";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function icon($id, $big = false) {
|
|
||||||
|
|
||||||
return $this->h5aiAbsHref . "icons/" . ($big ? "48x48" : "16x16") . "/" . $id . ".png";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getOptions() {
|
public function getOptions() {
|
||||||
|
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getLangs() {
|
|
||||||
|
|
||||||
return $this->langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function normalizePath($path, $endWithSlash) {
|
|
||||||
|
|
||||||
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getAbsHref($absPath = null, $endWithSlash = true) {
|
public function getAbsHref($absPath = null, $endWithSlash = true) {
|
||||||
|
|
||||||
if ($absPath === null) {
|
if ($absPath === null) {
|
||||||
@@ -146,7 +145,7 @@ class H5ai {
|
|||||||
$encodedParts[] = rawurlencode($part);
|
$encodedParts[] = rawurlencode($part);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->normalizePath($this->rootAbsHref . implode("/", $encodedParts), $endWithSlash);
|
return H5ai::normalize_path($this->rootAbsHref . implode("/", $encodedParts), $endWithSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -158,51 +157,14 @@ class H5ai {
|
|||||||
|
|
||||||
$absHref = substr($absHref, strlen($this->rootAbsHref));
|
$absHref = substr($absHref, strlen($this->rootAbsHref));
|
||||||
|
|
||||||
return $this->normalizePath($this->rootAbsPath . "/" . rawurldecode($absHref), false);
|
return H5ai::normalize_path($this->rootAbsPath . "/" . rawurldecode($absHref));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function showThumbs() {
|
|
||||||
|
|
||||||
return $this->options["showThumbs"] === true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getThumbTypes() {
|
|
||||||
|
|
||||||
return $this->options["thumbTypes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getTitle() {
|
|
||||||
|
|
||||||
$title = $this->domain . rawurldecode($this->absHref);
|
|
||||||
$title = preg_replace("/\/$/", "", $title);
|
|
||||||
$title = preg_replace("/\//", " > ", $title);
|
|
||||||
if ($this->absHref !== "/") {
|
|
||||||
$title = basename($this->absPath) . " - " . $title;
|
|
||||||
}
|
|
||||||
return $title;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getType($absPath) {
|
|
||||||
|
|
||||||
foreach($this->types as $type => $exts) {
|
|
||||||
foreach($exts as $ext) {
|
|
||||||
if ($this->endsWith($absPath, $ext)) {
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function ignoreThisFile($file) {
|
public function ignoreThisFile($file) {
|
||||||
|
|
||||||
// always ignore
|
// always ignore
|
||||||
if ($file === "." || $file === ".." || $this->startsWith($file, '.ht')) {
|
if ($file === "." || $file === ".." || H5ai::starts_with($file, '.ht')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,24 +198,6 @@ class H5ai {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getLabel($absHref) {
|
|
||||||
|
|
||||||
return $absHref === "/" ? $this->domain : rawurldecode(basename($absHref));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function startsWith($sequence, $start) {
|
|
||||||
|
|
||||||
return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function endsWith($sequence, $end) {
|
|
||||||
|
|
||||||
return strcasecmp(substr($sequence, -strlen($end)), $end) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getHttpCode($absHref) {
|
public function getHttpCode($absHref) {
|
||||||
|
|
||||||
//return $this->cachedHttpCode($absHref);
|
//return $this->cachedHttpCode($absHref);
|
||||||
@@ -265,12 +209,7 @@ class H5ai {
|
|||||||
|
|
||||||
$cached = $this->cache->get($absHref);
|
$cached = $this->cache->get($absHref);
|
||||||
if ($cached === false) {
|
if ($cached === false) {
|
||||||
$folderStatus = $this->options["folderStatus"];
|
|
||||||
if (array_key_exists($absHref, $folderStatus)) {
|
|
||||||
$code = $folderStatus[$absHref];
|
|
||||||
} else {
|
|
||||||
$code = $this->fetchHttpCode($absHref);
|
$code = $this->fetchHttpCode($absHref);
|
||||||
}
|
|
||||||
$cached = array("href" => $absHref, "code" => $code);
|
$cached = array("href" => $absHref, "code" => $code);
|
||||||
$this->cache->set($absHref, $cached);
|
$this->cache->set($absHref, $cached);
|
||||||
}
|
}
|
||||||
@@ -280,6 +219,17 @@ class H5ai {
|
|||||||
|
|
||||||
public function fetchHttpCode($absHref) {
|
public function fetchHttpCode($absHref) {
|
||||||
|
|
||||||
|
if (!is_dir($this->getAbsPath($absHref))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->options["folderstatus"]["enabled"]) {
|
||||||
|
$folders = $this->options["folderstatus"]["folders"];
|
||||||
|
if (array_key_exists($absHref, $folders)) {
|
||||||
|
return $folders[$absHref];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$contentType = "Content-Type:";
|
$contentType = "Content-Type:";
|
||||||
$h5aiContentType = "Content-Type: text/html;h5ai=";
|
$h5aiContentType = "Content-Type: text/html;h5ai=";
|
||||||
$host = getenv("HTTP_HOST");
|
$host = getenv("HTTP_HOST");
|
||||||
@@ -301,16 +251,53 @@ class H5ai {
|
|||||||
$content = fgets($socket);
|
$content = fgets($socket);
|
||||||
$code = intval(trim(substr($content, 9, 4)));
|
$code = intval(trim(substr($content, 9, 4)));
|
||||||
if ($code === 200) {
|
if ($code === 200) {
|
||||||
while (! $this->startsWith($content, $contentType)) {
|
while (! H5ai::starts_with($content, $contentType)) {
|
||||||
$content = fgets($socket);
|
$content = fgets($socket);
|
||||||
}
|
}
|
||||||
if ($this->startsWith($content, $h5aiContentType)) {
|
if (H5ai::starts_with($content, $h5aiContentType)) {
|
||||||
$code = "h5ai";
|
$code = "h5ai";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose($socket);
|
fclose($socket);
|
||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function fileExists($file) {
|
||||||
|
|
||||||
|
return is_string($file) && file_exists($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getGenericJson() {
|
||||||
|
|
||||||
|
$header = $this->options["custom"]["header"];
|
||||||
|
$footer = $this->options["custom"]["footer"];
|
||||||
|
$header = $this->fileExists($header ? $this->absPath . "/" . $header : null) ? $header : null;
|
||||||
|
$footer = $this->fileExists($footer ? $this->absPath . "/" . $footer : null) ? $footer : null;
|
||||||
|
|
||||||
|
// collect and sort entries
|
||||||
|
$folder = Entry::get($this, $this->absPath, $this->absHref);
|
||||||
|
while ($folder !== null) {
|
||||||
|
$folder->getContent();
|
||||||
|
$folder = $folder->getParent();
|
||||||
|
}
|
||||||
|
Entry::sort();
|
||||||
|
|
||||||
|
$entries = array();
|
||||||
|
foreach(Entry::getCache() as $entry) {
|
||||||
|
$entries[] = $entry->toJsonObject(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = array(
|
||||||
|
"entries" => $entries,
|
||||||
|
"customHeader" => $header,
|
||||||
|
"customFooter" => $footer
|
||||||
|
);
|
||||||
|
|
||||||
|
return json_encode($json) . "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
@@ -51,7 +51,15 @@ class Image {
|
|||||||
|
|
||||||
$this->sourceFile = $filename;
|
$this->sourceFile = $filename;
|
||||||
|
|
||||||
list($this->width, $this->height, $this->type) = getimagesize($this->sourceFile);
|
list($this->width, $this->height, $this->type) = @getimagesize($this->sourceFile);
|
||||||
|
|
||||||
|
if (!$this->width || !$this->height) {
|
||||||
|
$this->sourceFile = null;
|
||||||
|
$this->width = null;
|
||||||
|
$this->height = null;
|
||||||
|
$this->type = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->source = imagecreatefromstring(file_get_contents($this->sourceFile));
|
$this->source = imagecreatefromstring(file_get_contents($this->sourceFile));
|
||||||
}
|
}
|
||||||
@@ -99,6 +107,10 @@ class Image {
|
|||||||
|
|
||||||
private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) {
|
private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) {
|
||||||
|
|
||||||
|
if (is_null($this->source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_null($canWidth) && !is_null($canHeight)) {
|
if (!is_null($canWidth) && !is_null($canHeight)) {
|
||||||
$this->dest = imagecreatetruecolor($canWidth, $canHeight);
|
$this->dest = imagecreatetruecolor($canWidth, $canHeight);
|
||||||
} else {
|
} else {
|
||||||
@@ -134,6 +146,10 @@ class Image {
|
|||||||
|
|
||||||
public function squareThumb($width) {
|
public function squareThumb($width) {
|
||||||
|
|
||||||
|
if (is_null($this->source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$a = min($this->width, $this->height);
|
$a = min($this->width, $this->height);
|
||||||
$x = intval(($this->width - $a) / 2);
|
$x = intval(($this->width - $a) / 2);
|
||||||
$y = intval(($this->height - $a) / 2);
|
$y = intval(($this->height - $a) / 2);
|
||||||
@@ -144,6 +160,10 @@ class Image {
|
|||||||
|
|
||||||
public function rationalThumb($width, $height) {
|
public function rationalThumb($width, $height) {
|
||||||
|
|
||||||
|
if (is_null($this->source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$r = 1.0 * $this->width / $this->height;
|
$r = 1.0 * $this->width / $this->height;
|
||||||
|
|
||||||
$h = $height;
|
$h = $height;
|
||||||
@@ -164,6 +184,10 @@ class Image {
|
|||||||
|
|
||||||
public function centerThumb($width, $height, $color = null) {
|
public function centerThumb($width, $height, $color = null) {
|
||||||
|
|
||||||
|
if (is_null($this->source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$r = 1.0 * $this->width / $this->height;
|
$r = 1.0 * $this->width / $this->height;
|
||||||
|
|
||||||
$h = $height;
|
$h = $height;
|
||||||
@@ -187,6 +211,10 @@ class Image {
|
|||||||
|
|
||||||
public function freeThumb($width, $height) {
|
public function freeThumb($width, $height) {
|
||||||
|
|
||||||
|
if (is_null($this->source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$w = intval($width);
|
$w = intval($width);
|
||||||
$h = intval($height);
|
$h = intval($height);
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_h5ai("/php/inc/Image.php");
|
H5ai::req_once("/php/inc/Image.php");
|
||||||
|
|
||||||
|
|
||||||
class Thumbnail {
|
class Thumbnail {
|
||||||
|
@@ -1,158 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class TreeEntry {
|
|
||||||
|
|
||||||
private $h5ai, $label, $absPath, $absHref, $isFolder, $type, $content;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai, $absPath, $absHref, $type = null) {
|
|
||||||
|
|
||||||
$this->h5ai = $h5ai;
|
|
||||||
|
|
||||||
$this->label = $this->h5ai->getLabel($absHref);
|
|
||||||
$this->absPath = $this->h5ai->normalizePath($absPath, false);
|
|
||||||
$this->isFolder = is_dir($this->absPath);
|
|
||||||
$this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
|
|
||||||
|
|
||||||
$this->type = $type !== null ? $type : ($this->isFolder ? "folder" : $this->h5ai->getType($this->absPath));
|
|
||||||
$this->content = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function loadContent() {
|
|
||||||
|
|
||||||
$this->content = array();
|
|
||||||
|
|
||||||
if ($this->h5ai->getHttpCode($this->absHref) !== "h5ai") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$files = $this->h5ai->readDir($this->absPath);
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$tree = new TreeEntry($this->h5ai, $this->absPath . "/" . $file, $this->absHref . rawurlencode($file));
|
|
||||||
|
|
||||||
if ($tree->isFolder) {
|
|
||||||
$this->content[$tree->absPath] = $tree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function cmpTrees($t1, $t2) {
|
|
||||||
|
|
||||||
if ($t1->isFolder && !$t2->isFolder) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!$t1->isFolder && $t2->isFolder) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return strcasecmp($t1->absPath, $t2->absPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function sort() {
|
|
||||||
|
|
||||||
if ($this->content !== null) {
|
|
||||||
uasort($this->content, array($this, "cmpTrees"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function toHtml() {
|
|
||||||
|
|
||||||
$classes = "entry " . $this->type . ($this->absHref === $this->h5ai->getAbsHref() ? " current" : "");
|
|
||||||
$icon = $this->type;
|
|
||||||
if ($this->absHref === "/") {
|
|
||||||
$icon = "folder-home";
|
|
||||||
}
|
|
||||||
$hint = "";
|
|
||||||
$code = "h5ai";
|
|
||||||
|
|
||||||
if ($this->isFolder) {
|
|
||||||
$code = $this->h5ai->getHttpCode($this->absHref);
|
|
||||||
$classes .= " checkedHttpCode";
|
|
||||||
if ($code !== "h5ai") {
|
|
||||||
if ($code === 200) {
|
|
||||||
$icon = "folder-page";
|
|
||||||
$hint = "<span class='hint'><img src='" . $this->h5ai->image("page") . "' alt='page' /></span>";
|
|
||||||
} else {
|
|
||||||
$classes .= " error";
|
|
||||||
$hint = "<span class='hint'> " . $code . " </span>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = "<div class='" . $classes ."'>\n";
|
|
||||||
if ($this->content !== null && count($this->content) === 0 || $code !== "h5ai") {
|
|
||||||
$html .= "<span class='blank'></span>\n";
|
|
||||||
} else {
|
|
||||||
$indicatorState = $this->content === null ? " unknown" : " open";
|
|
||||||
$html .= "<span class='indicator" . $indicatorState . "'><img src='" . $this->h5ai->image("tree") . "' alt='>' /></span>\n";
|
|
||||||
}
|
|
||||||
$html .= "<a href='" . $this->absHref . "'>\n";
|
|
||||||
$html .= "<span class='icon'><img src='" . $this->h5ai->icon($icon) . "' alt='" . $icon . "' /></span>";
|
|
||||||
$html .= "<span class='label'>" . $this->label . "</span>" . $hint . "\n";
|
|
||||||
$html .= "</a>\n";
|
|
||||||
$html .= $this->contentToHtml();
|
|
||||||
$html .= "</div>\n";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function contentToHtml() {
|
|
||||||
|
|
||||||
$html = "<ul class='content'>\n";
|
|
||||||
if ($this->content !== null) {
|
|
||||||
foreach($this->content as $tree) {
|
|
||||||
$html .= "<li>" . $tree->toHtml() . "</li>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$html .= "</ul>\n";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getRoot() {
|
|
||||||
|
|
||||||
if ($this->absHref === "/") {
|
|
||||||
return $this;
|
|
||||||
};
|
|
||||||
|
|
||||||
$tree = new TreeEntry($this->h5ai, safe_dirname($this->absPath), safe_dirname($this->absHref, true));
|
|
||||||
$tree->loadContent();
|
|
||||||
$tree->content[$this->absPath] = $this;
|
|
||||||
|
|
||||||
return $tree->getRoot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Tree {
|
|
||||||
|
|
||||||
private $h5ai;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($h5ai) {
|
|
||||||
|
|
||||||
$this->h5ai = $h5ai;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function toHtml() {
|
|
||||||
|
|
||||||
$options = $this->h5ai->getOptions();
|
|
||||||
if ($options["showTree"] === false) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$tree = new TreeEntry($this->h5ai, $this->h5ai->getAbsPath(), $this->h5ai->getAbsHref());
|
|
||||||
$tree->loadContent();
|
|
||||||
$root = $tree->getRoot();
|
|
||||||
return "<section id='tree'>\n" . $root->toHtml() . "</section>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|