mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-05-25 20:44:53 -04:00
Refactored and lots of modification. See README.md.
This commit is contained in:
parent
859a680e19
commit
71ed41fa69
85 changed files with 3191 additions and 2969 deletions
20
README.md
20
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).
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
|
||||||
* [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)
|
* [Moment.js](http://momentjs.com) (MIT)
|
||||||
|
@ -30,20 +31,29 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
|
||||||
### v0.19 - *2012-??-??*
|
### v0.19 - *2012-04-??*
|
||||||
|
|
||||||
|
* adds lots of config options
|
||||||
|
* changes in `config.js` and `h5ai.htaccess`
|
||||||
* fixes js problems in IE 7+8
|
* fixes js problems in IE 7+8
|
||||||
* hides broken tree view in IE < 9 and adds a message to the footer
|
* hides broken tree view in IE < 9, adds a message to the footer
|
||||||
* disables hash changes since they break logical browser history
|
* removes hash changes since they break logical browser history
|
||||||
* fixes thumbnail size for portrait images in icon view
|
* fixes thumbnail size for portrait images in icon view
|
||||||
|
* adds an info page at `/_h5ai`
|
||||||
|
* sort order is preserved while browsing
|
||||||
|
* removes PHP error messages on thumbnail generation
|
||||||
|
* fixes PHP problems with zipped download
|
||||||
|
* 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)
|
* switches from [Datejs](http://www.datejs.com) to [Moment.js](http://momentjs.com)
|
||||||
* adds [underscore.js](http://underscorejs.org)
|
* adds [underscore.js](http://underscorejs.org)
|
||||||
* adds a info page to `/_ha5i`
|
* fixes mousewheel problems, updates [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) to 3.0.6
|
||||||
* updates lv translation
|
* updates lv translation
|
||||||
* adds ro translation by [Jakob Cosoroabă](http://github.com/midday)
|
* adds ro translation by [Jakob Cosoroabă](http://github.com/midday)
|
||||||
* adds ja translation by [metasta](http://github.com/metasta)
|
* adds ja translation by [metasta](http://github.com/metasta)
|
||||||
* adds nb translation by [Sindre Sorhus](http://github.com/sindresorhus)
|
* adds nb translation by [Sindre Sorhus](http://github.com/sindresorhus)
|
||||||
* adds sr translation by [Goran](http://github.com/vBm)
|
* 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*
|
||||||
|
|
|
@ -3,7 +3,7 @@ custom = true
|
||||||
|
|
||||||
# project
|
# project
|
||||||
project.name = h5ai
|
project.name = h5ai
|
||||||
project.version = pre0.19
|
project.version = 0.19-pre
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
|
15
build.xml
15
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="" />
|
||||||
|
@ -112,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>
|
||||||
|
|
|
@ -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,102 @@ 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": true,
|
||||||
|
"header": "_h5ai.header.html",
|
||||||
|
"footer": "_h5ai.footer.html"
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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": true,
|
||||||
|
"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.
|
||||||
|
*
|
||||||
|
* Date format in detailed view, for example: "YYYY-MM-DD HH:mm:ss"
|
||||||
|
* Syntax as specified by Moment.js (http://momentjs.com)
|
||||||
|
* This might be overidden by "dateFormat" in a lang specification.
|
||||||
|
*/
|
||||||
|
"l10n": {
|
||||||
|
"enabled": true,
|
||||||
|
"lang": "en",
|
||||||
|
"useBrowserLang": true,
|
||||||
|
"defaultDateFormat": "YYYY-MM-DD HH:mm"
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Link the hover effects between crumb, main view and tree.
|
||||||
|
*/
|
||||||
|
"link-hover-states": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show QRCodes on hovering files.
|
||||||
|
*/
|
||||||
|
"qrcode": {
|
||||||
|
"enabled": true,
|
||||||
|
"size": 150
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make entries selectable. At the moment only needed for zipped 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,96 +139,66 @@ 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.
|
||||||
* Note that this tree might have side effects as it sends HEAD requests
|
|
||||||
* to the folders, and therefore will invoke index.php scripts. Use
|
|
||||||
* folderStatus below to avoid such requests.
|
|
||||||
* It might also affect performance significantly.
|
|
||||||
*/
|
*/
|
||||||
"showTree": true,
|
"statusbar": {
|
||||||
|
"enabled": 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 Moment.js (http://momentjs.com)
|
|
||||||
*/
|
|
||||||
"dateFormat": "YYYY-MM-DD HH:mm",
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requires PHP on the server.
|
* Requires PHP on the server.
|
||||||
* Show thumbnails for image files.
|
* Show thumbnails for image files. Needs the "/_h5ai/cache" folder to be
|
||||||
|
* writable for the Apache Server.
|
||||||
*/
|
*/
|
||||||
"showThumbs": true,
|
"thumbnails": {
|
||||||
"thumbTypes": ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
"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
|
||||||
|
* to the folders, and therefore will invoke index.php scripts. Use
|
||||||
|
* "folderstatus" above to avoid such requests.
|
||||||
|
* It might also affect performance significantly.
|
||||||
|
*
|
||||||
|
* Slide tree bar into viewport if there is enough space.
|
||||||
|
*/
|
||||||
|
"tree": {
|
||||||
|
"enabled": true,
|
||||||
|
"slide": true
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requires PHP on the server.
|
* Requires PHP on the server.
|
||||||
* Enable zipped download of selected entries.
|
* Enable zipped download of selected entries.
|
||||||
*/
|
*/
|
||||||
"zippedDownload": true,
|
"zipped-download": {
|
||||||
|
"enabled": true
|
||||||
/*
|
}
|
||||||
* 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": 150,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allow filtering the displayed files and folders.
|
|
||||||
* Filters are ment to be JavaScript regular expressions.
|
|
||||||
*/
|
|
||||||
"showFilter": true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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": [],
|
||||||
|
@ -149,7 +214,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": [],
|
||||||
|
@ -171,7 +236,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"],
|
||||||
|
@ -187,18 +252,18 @@ 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.
|
||||||
*/
|
*/
|
||||||
"langs": {
|
"langs": {
|
||||||
|
|
||||||
|
@ -259,7 +324,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": {
|
||||||
|
@ -292,6 +358,21 @@ var H5AI_CONFIG = {
|
||||||
"noMatch": "no match"
|
"noMatch": "no match"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"gr": {
|
||||||
|
"lang": "ελληνικά",
|
||||||
|
"details": "Λεπτομέρειες",
|
||||||
|
"icons": "Εικονίδια",
|
||||||
|
"name": "Όνομα",
|
||||||
|
"lastModified": "Τελευταία Τροποποίηση",
|
||||||
|
"size": "Μέγεθος",
|
||||||
|
"parentDirectory": "Προηγούμενος Κατάλογος",
|
||||||
|
"empty": "κενό",
|
||||||
|
"folders": "Φάκελοι",
|
||||||
|
"files": "Αρχεία",
|
||||||
|
"download": "Μεταμόρφωση",
|
||||||
|
"noMatch": "Κανένα Ταίριασμα"
|
||||||
|
},
|
||||||
|
|
||||||
"it": {
|
"it": {
|
||||||
"lang": "italiano",
|
"lang": "italiano",
|
||||||
"details": "dettagli",
|
"details": "dettagli",
|
||||||
|
|
|
@ -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,19 @@
|
||||||
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;
|
||||||
|
|
||||||
|
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 +55,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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
68
src/_h5ai/css/inc/bottombar.less
Normal file
68
src/_h5ai/css/inc/bottombar.less
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
#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;
|
||||||
|
font-size: @smaller-font;
|
||||||
|
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,30 @@
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
margin: 0 auto;
|
margin: 50px auto;
|
||||||
|
}
|
||||||
|
|
||||||
> 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;
|
||||||
> footer {
|
cursor: pointer;
|
||||||
display: none;
|
|
||||||
padding-top: 10px;
|
&:hover {
|
||||||
margin-top: 80px;
|
color: #68A9FF;
|
||||||
border-top: 2px dashed #ddd;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#content-header {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content-footer {
|
||||||
|
padding-top: 12px;
|
||||||
|
margin-top: 32px;
|
||||||
|
}
|
||||||
|
|
|
@ -54,10 +54,10 @@
|
||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
color: #e80;
|
color: #e80;
|
||||||
}
|
}
|
||||||
&.selected:not(.selecting), &.selecting:not(.selected) {
|
}
|
||||||
border-color: rgba(240,100,0,0.2);
|
&.selected:not(.selecting) a, &.selecting:not(.selected) a {
|
||||||
background-color: rgba(240,100,0,0.2);
|
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 {
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
&.thumb {
|
&.thumb {
|
||||||
border: 1px solid #eee;
|
// border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,18 +132,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,10 +194,6 @@
|
||||||
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;
|
||||||
|
|
||||||
|
@ -218,7 +202,7 @@
|
||||||
height: 48px;
|
height: 48px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
&.thumb {
|
&.thumb {
|
||||||
border: 1px solid #eee;
|
// border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,6 +217,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 +241,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 {
|
||||||
|
|
|
@ -1,120 +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;
|
|
||||||
}
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
59
src/_h5ai/css/inc/h5ai-info.less
Normal file
59
src/_h5ai/css/inc/h5ai-info.less
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/_h5ai/css/inc/l10n.less
Normal file
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,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,7 +29,7 @@ body > nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body > footer {
|
#bottombar {
|
||||||
.center {
|
.center {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -39,14 +40,14 @@ body > footer {
|
||||||
a[href]:after {
|
a[href]:after {
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
body > nav {
|
#topbar {
|
||||||
position: static;
|
position: static;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
.view, #download {
|
.view, #download {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body > footer {
|
#bottombar {
|
||||||
position: static;
|
position: static;
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
|
|
||||||
html.h5ai-splash {
|
|
||||||
body {
|
|
||||||
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;
|
|
||||||
|
|
||||||
&.test-passed {
|
|
||||||
color: #5a5;
|
|
||||||
}
|
|
||||||
&.test-failed {
|
|
||||||
color: #a55;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,16 @@
|
||||||
|
|
||||||
|
#topbar {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
font-size: @smaller-font;
|
||||||
|
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
||||||
|
border-bottom: 1px solid rgb(210,210,210);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.nav-highlight {
|
.nav-highlight {
|
||||||
background-color: rgba(255,255,255,0.5);
|
background-color: rgba(255,255,255,0.5);
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
|
@ -21,23 +33,13 @@
|
||||||
border-left: @nav-sep-border;
|
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 {
|
#navbar {
|
||||||
display: block;
|
list-style: none;
|
||||||
height: 30px;
|
list-style-image: none;
|
||||||
line-height: 30px;
|
margin: 0;
|
||||||
padding: 0 10px;
|
padding: 0;
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
a, a:active, a:visited, span.element {
|
a, a:active, a:visited, span.element {
|
||||||
color: #555;
|
color: #555;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -76,50 +78,54 @@ body > nav {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
img.hint {
|
img.hint {
|
||||||
width: 10px;
|
width: 14px;
|
||||||
height: 10px;
|
height: 14px;
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.view {
|
.view {
|
||||||
.nav-right;
|
.nav-right;
|
||||||
}
|
}
|
||||||
#download {
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#filter {
|
||||||
|
.nav-right;
|
||||||
|
|
||||||
|
input {
|
||||||
display: none;
|
display: none;
|
||||||
.nav-right;
|
border: none;
|
||||||
.transition(all 0.2s ease-in-out);
|
font-family: Ubuntu, sans-serif;
|
||||||
|
color: #555;
|
||||||
&.failed {
|
background-color: rgba(0,0,0,0);
|
||||||
background-color: rgba(255,0,0,0.5);
|
width: 100px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#filter {
|
|
||||||
.nav-right;
|
|
||||||
|
|
||||||
|
&.current {
|
||||||
input {
|
input {
|
||||||
display: none;
|
display: inline;
|
||||||
border: none;
|
|
||||||
font-family: Ubuntu, sans-serif;
|
|
||||||
color: #555;
|
|
||||||
background-color: rgba(0,0,0,0);
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
input {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#download {
|
||||||
|
display: none;
|
||||||
|
.nav-right;
|
||||||
|
.transition(all 0.2s ease-in-out);
|
||||||
|
|
||||||
|
&.failed {
|
||||||
|
background-color: rgba(255,0,0,0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#download-auth {
|
#download-auth {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
font-size: 0.85em;
|
font-size: @smaller-font;
|
||||||
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
|
||||||
border: 1px solid rgb(210,210,210);
|
border: 1px solid rgb(210,210,210);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 0.85em;
|
font-size: @smaller-font;
|
||||||
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 +28,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 +44,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 +94,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);
|
||||||
|
|
|
@ -2,63 +2,37 @@
|
||||||
@import "inc/h5bp-norm";
|
@import "inc/h5bp-norm";
|
||||||
@import "inc/mixins";
|
@import "inc/mixins";
|
||||||
|
|
||||||
|
::-moz-selection { background: #68A9FF; color: #fff; text-shadow: none; }
|
||||||
|
::selection { background: #68A9FF; color: #fff; text-shadow: none; }
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: Ubuntu, sans-serif;
|
font-family: Ubuntu, sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #555;
|
color: #555;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
margin: 80px 30px;
|
margin: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@import "inc/nav";
|
@smaller-font: 15px;
|
||||||
|
|
||||||
|
@import "inc/topbar";
|
||||||
@import "inc/content";
|
@import "inc/content";
|
||||||
@import "inc/table";
|
|
||||||
@import "inc/extended";
|
@import "inc/extended";
|
||||||
|
@import "inc/bottombar";
|
||||||
|
@import "inc/l10n";
|
||||||
@import "inc/tree";
|
@import "inc/tree";
|
||||||
@import "inc/context";
|
@import "inc/context";
|
||||||
@import "inc/footer";
|
@import "inc/apache-autoindex-table";
|
||||||
@import "inc/responsive";
|
@import "inc/responsive";
|
||||||
|
|
||||||
|
|
||||||
html.js {
|
html.js .hideOnJs, html.no-js .hideOnNoJs {
|
||||||
.hideOnJs {
|
display: none;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.no-js {
|
|
||||||
#extended.details-view, #extended.icons-view {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
html.oldie {
|
html.oldie {
|
||||||
.oldBrowser {
|
.oldBrowser {
|
||||||
display: inline;
|
display: inline !important;
|
||||||
}
|
}
|
||||||
#tree {
|
#tree {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
@ -66,5 +40,4 @@ html.oldie {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@import "inc/splash";
|
@import "inc/h5ai-info";
|
||||||
|
|
||||||
|
|
|
@ -1,32 +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 class="oldBrowser"> ⚡ Some features disabled! Works best in <a href="http://browsehappy.com" target="_blank">modern browsers</a>. ⚡ </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/scripts.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
11
src/_h5ai/footer.php
Normal file
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>
|
|
@ -1,34 +1,41 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!--[if lt IE 7]> <html class="h5ai-js 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="h5ai-js no-js ie7 oldie" lang="en"> <![endif]-->
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||||
<!--[if IE 8]> <html class="h5ai-js 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="//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/styles.css">
|
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
||||||
<script src="/_h5ai/js/modernizr.min.js"></script>
|
<script src="/_h5ai/js/modernizr-2.5.3.min.js"></script>
|
||||||
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
|
||||||
</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>
|
||||||
The following code was generated by Apache's autoindex module. It is not valid HTML5, but this
|
<span class="oldBrowser"> ⚡ Some features disabled! Works best in <a href="http://browsehappy.com">modern browsers</a>. ⚡ </span>
|
||||||
section gets removed from the DOM tree as soon as its information is parsed. The actual page
|
</span>
|
||||||
should render as valid HTML5, even if the produced source is not valid HTML5.
|
<span class="right"></span>
|
||||||
-->
|
<span class="center"></span>
|
||||||
|
</div>
|
||||||
|
<script src="/_h5ai/config.js"></script>
|
||||||
|
<script src="/_h5ai/js/scripts.js"></script>
|
||||||
|
<div id="data-apache-autoindex" class="hideOnJs">
|
||||||
|
<!--
|
||||||
|
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
|
||||||
|
should render as valid HTML5, even if the produced source is not valid HTML5.
|
||||||
|
-->
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<!--[if lt IE 7]> <html class="h5ai-php no-js ie6 oldie" lang="en"> <![endif]-->
|
|
||||||
<!--[if IE 7]> <html class="h5ai-php no-js ie7 oldie" lang="en"> <![endif]-->
|
|
||||||
<!--[if IE 8]> <html class="h5ai-php 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="//fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
|
||||||
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
|
||||||
<script src="/_h5ai/js/modernizr.min.js"></script>
|
|
||||||
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
|
||||||
</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. -->
|
|
Binary file not shown.
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 564 B |
|
@ -1,32 +1,41 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!--[if lt IE 7]> <html class="h5ai-splash 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="h5ai-splash no-js ie7 oldie" lang="en"> <![endif]-->
|
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
|
||||||
<!--[if IE 8]> <html class="h5ai-splash 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-splash 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>h5ai %BUILD_VERSION%</title>
|
<title>h5ai %BUILD_VERSION% info page</title>
|
||||||
<meta name="description" content="h5ai · a beautified Apache index">
|
<meta name="description" content="h5ai · a beautified Apache index">
|
||||||
<meta name="author" content="Lars Jung">
|
|
||||||
<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="//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="//fonts.googleapis.com/css?family=Miltonian+Tattoo:regular">
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Miltonian+Tattoo:regular">
|
||||||
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
||||||
<script src="/_h5ai/js/modernizr.min.js"></script>
|
<script src="/_h5ai/js/modernizr-2.5.3.min.js"></script>
|
||||||
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="h5ai-info">
|
||||||
<h1><span class="h5ai">h5ai</span></h1>
|
<h1><span class="h5ai">h5ai</span></h1>
|
||||||
version %BUILD_VERSION%
|
version %BUILD_VERSION%
|
||||||
<h2>server supports</h2>
|
<h2>server supports</h2>
|
||||||
<ul id="tests">
|
<ul id="tests">
|
||||||
<li id="test-php"><span class="test-label">php version</span><span class="test-result"></span></li>
|
<li id="test-php"><span class="test-label">php version</span><span class="test-result">?</span></li>
|
||||||
<li id="test-zips"><span class="test-label">zipped downloads</span><span class="test-result"></span></li>
|
<li id="test-cache"><span class="test-label">cache</span><span class="test-result">?</span></li>
|
||||||
<li id="test-thumbs"><span class="test-label">thumbnails</span><span class="test-result"></span></li>
|
<li id="test-thumbs"><span class="test-label">thumbnails</span><span class="test-result">?</span></li>
|
||||||
|
<li id="test-temp"><span class="test-label">temp directory</span><span class="test-result">?</span></li>
|
||||||
|
<li id="test-zips"><span class="test-label">zipped downloads</span><span class="test-result">?</span></li>
|
||||||
</ul>
|
</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>
|
||||||
<script src="/_h5ai/config.js"></script>
|
<script src="/_h5ai/config.js"></script>
|
||||||
<script src="/_h5ai/js/scripts.js"></script>
|
<script src="/_h5ai/js/scripts.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,373 +0,0 @@
|
||||||
|
|
||||||
Module.define('conhtml', [jQuery, 'settings', 'path', 'util', 'core', 'localize'], function ($, settings, pathFactory, util, core, localize) {
|
|
||||||
|
|
||||||
var cache = {},
|
|
||||||
pathnameStatusCache = {},
|
|
||||||
contentTypeRegEx = /^text\/html;h5ai=/,
|
|
||||||
getPath = function (folder, tableRow) {
|
|
||||||
|
|
||||||
var absHref = util.getAbsHref(folder, tableRow),
|
|
||||||
path = cache[absHref];
|
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
path = pathFactory.create(folder, tableRow);
|
|
||||||
if (!path.isParentFolder) {
|
|
||||||
cache[path.absHref] = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
},
|
|
||||||
fetchStatus = function (pathname, callback) {
|
|
||||||
|
|
||||||
if (settings.folderStatus[pathname]) {
|
|
||||||
callback(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;
|
|
||||||
}
|
|
||||||
updateHtml(path);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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", core.image("crumb")).end()
|
|
||||||
.find("span").text(path.label).end();
|
|
||||||
|
|
||||||
if (path.isDomain) {
|
|
||||||
$html.addClass("domain");
|
|
||||||
$a.find("img").attr("src", core.image("home"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.isCurrentFolder) {
|
|
||||||
$html.addClass("current");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNaN(path.status)) {
|
|
||||||
if (path.status === 200) {
|
|
||||||
$a.append($("<img class='hint' src='" + 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,
|
|
||||||
imgClass = "",
|
|
||||||
icon16 = core.icon(path.type),
|
|
||||||
icon48 = 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 (settings.showThumbs === true && $.inArray(path.type, settings.thumbTypes) >= 0) {
|
|
||||||
imgClass = "class='thumb'";
|
|
||||||
var escapedHref = path.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
|
|
||||||
icon16 = core.api() + "?action=thumb&href=" + escapedHref + "&width=16&height=16&mode=square";
|
|
||||||
icon48 = 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 (!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", core.icon("folder-page"));
|
|
||||||
$a.find(".icon.big img").attr("src", 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);
|
|
||||||
localize.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='" + 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='" + core.image("tree") + "' /></span>")
|
|
||||||
.click(function (event) {
|
|
||||||
|
|
||||||
var $entry = $indicator.closest(".entry"); // $html
|
|
||||||
|
|
||||||
if ($indicator.hasClass("unknown")) {
|
|
||||||
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", core.icon("folder-home"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// is path the current folder?
|
|
||||||
if (path.isCurrentFolder) {
|
|
||||||
$html.addClass("current");
|
|
||||||
$a.find(".icon img").attr("src", 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", core.icon("folder-page"));
|
|
||||||
$a.append($("<span class='hint'><img src='" + 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 {
|
|
||||||
getPath: getPath,
|
|
||||||
updatePaths: updatePaths,
|
|
||||||
fetchStatusAndContent: fetchStatusAndContent,
|
|
||||||
|
|
||||||
updateCrumbHtml: updateCrumbHtml,
|
|
||||||
updateExtendedHtml: updateExtendedHtml,
|
|
||||||
updateTreeHtml: updateTreeHtml,
|
|
||||||
updateHtml: updateHtml
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,50 +0,0 @@
|
||||||
|
|
||||||
Module.define('context', [jQuery, 'settings'], function ($, settings) {
|
|
||||||
|
|
||||||
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 = 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
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,311 +0,0 @@
|
||||||
|
|
||||||
Module.define('core', [jQuery, 'settings', 'types', 'util'], function ($, settings, types, util) {
|
|
||||||
|
|
||||||
var $window = $(window),
|
|
||||||
extToFileType = (function (types) {
|
|
||||||
var map = {};
|
|
||||||
$.each(types, function (type, exts) {
|
|
||||||
$.each(exts, function (idx, ext) {
|
|
||||||
map[ext] = type;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return map;
|
|
||||||
}(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];
|
|
||||||
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"); }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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 ? 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();
|
|
||||||
formatSizes();
|
|
||||||
setTotals();
|
|
||||||
initIndicators();
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init,
|
|
||||||
hash: hash,
|
|
||||||
api: api,
|
|
||||||
image: image,
|
|
||||||
icon: icon,
|
|
||||||
shiftTree: shiftTree,
|
|
||||||
linkHoverStates: linkHoverStates,
|
|
||||||
initIndicators: initIndicators,
|
|
||||||
getFileType: getFileType
|
|
||||||
};
|
|
||||||
});
|
|
16
src/_h5ai/js/inc/core/entry.js
Normal file
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
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
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
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
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
|
||||||
|
};
|
||||||
|
});
|
32
src/_h5ai/js/inc/core/settings.js
Normal file
32
src/_h5ai/js/inc/core/settings.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
module.define('core/config', [H5AI_CONFIG], function (config) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
rootAbsHref: '/',
|
||||||
|
h5aiAbsHref: '/_h5ai/',
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
settings: _.extend({}, defaults, config.options),
|
||||||
|
types: _.extend({}, config.types),
|
||||||
|
langs: _.extend({}, config.langs)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.define('core/settings', ['core/config'], function (config) {
|
||||||
|
|
||||||
|
return config.settings;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.define('core/types', ['core/config'], function (config) {
|
||||||
|
|
||||||
|
return config.types;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.define('core/langs', ['core/config'], function (config) {
|
||||||
|
|
||||||
|
return config.langs;
|
||||||
|
});
|
18
src/_h5ai/js/inc/core/store.js
Normal file
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
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
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();
|
||||||
|
});
|
123
src/_h5ai/js/inc/ext/filter.js
Normal file
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
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;
|
||||||
|
});
|
|
@ -1,26 +1,29 @@
|
||||||
|
|
||||||
Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, settings, langs, core) {
|
module.define('ext/l10n', [jQuery, 'core/settings', 'core/langs', 'core/format', 'core/store'], function ($, allsettings, langs, format, store) {
|
||||||
|
|
||||||
var currentDateFormat = settings.dateFormat,
|
var defaults = {
|
||||||
formatDates = function (dateFormat) {
|
enabled: true,
|
||||||
|
lang: "en",
|
||||||
if (dateFormat) {
|
useBrowserLang: true,
|
||||||
currentDateFormat = dateFormat;
|
defaultDateFormat: 'YYYY-MM-DD HH:mm'
|
||||||
}
|
|
||||||
|
|
||||||
$('#extended .entry .date').each(function () {
|
|
||||||
|
|
||||||
var $this = $(this),
|
|
||||||
time = $this.data('time'),
|
|
||||||
formattedDate = time ? moment(time).format(currentDateFormat) : '';
|
|
||||||
|
|
||||||
$this.text(formattedDate);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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) {
|
localize = function (langs, lang, useBrowserLang) {
|
||||||
|
|
||||||
var storedLang = amplify.store(settings.store.lang),
|
var storedLang = store.get(storekey),
|
||||||
browserLang, selected, key;
|
browserLang, key;
|
||||||
|
|
||||||
if (langs[storedLang]) {
|
if (langs[storedLang]) {
|
||||||
lang = storedLang;
|
lang = storedLang;
|
||||||
|
@ -39,38 +42,45 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
||||||
lang = 'en';
|
lang = 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
selected = langs[lang];
|
currentLang = langs[lang];
|
||||||
if (selected) {
|
if (currentLang) {
|
||||||
$.each(selected, function (key, value) {
|
$.each(currentLang, function (key, value) {
|
||||||
$('.l10n-' + key).text(value);
|
$('.l10n-' + key).text(value);
|
||||||
});
|
});
|
||||||
$('.lang').text(lang);
|
$('.lang').text(lang);
|
||||||
$('.langOption').removeClass('current');
|
$('.langOption').removeClass('current');
|
||||||
$('.langOption.' + lang).addClass('current');
|
$('.langOption.' + lang).addClass('current');
|
||||||
core.hash({lang: lang});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
formatDates(selected.dateFormat || settings.dateFormat);
|
format.setDefaultDateFormat(currentLang.dateFormat || settings.defaultDateFormat);
|
||||||
|
|
||||||
|
$('#extended .entry .date').each(function () {
|
||||||
|
|
||||||
|
var $this = $(this);
|
||||||
|
|
||||||
|
$this.text(format.formatDate($this.data('time')));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
initLangSelector = function (langs) {
|
initLangSelector = function (langs) {
|
||||||
|
|
||||||
var $langOptions = $('#langSelector .langOptions'),
|
var $langSelector = $(template).appendTo('#bottombar .right'),
|
||||||
sortedLangsKeys = [],
|
$langOptions = $langSelector.find('.langOptions'),
|
||||||
$ul;
|
$ul = $langOptions.find('ul'),
|
||||||
|
sortedLangsKeys = [];
|
||||||
|
|
||||||
$.each(langs, function (lang) {
|
$.each(langs, function (lang) {
|
||||||
sortedLangsKeys.push(lang);
|
sortedLangsKeys.push(lang);
|
||||||
});
|
});
|
||||||
sortedLangsKeys.sort();
|
sortedLangsKeys.sort();
|
||||||
|
|
||||||
$ul = $('<ul />');
|
|
||||||
$.each(sortedLangsKeys, function (idx, lang) {
|
$.each(sortedLangsKeys, function (idx, lang) {
|
||||||
$('<li class="langOption" />')
|
$(langOptionTemplate)
|
||||||
.addClass(lang)
|
.addClass(lang)
|
||||||
.text(lang + ' - ' + langs[lang].lang)
|
.text(lang + ' - ' + langs[lang].lang)
|
||||||
.appendTo($ul)
|
.appendTo($ul)
|
||||||
.click(function () {
|
.click(function () {
|
||||||
amplify.store(settings.store.lang, lang);
|
store.put(storekey, lang);
|
||||||
localize(langs, lang, false);
|
localize(langs, lang, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -78,7 +88,7 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
||||||
.append($ul)
|
.append($ul)
|
||||||
.scrollpanel();
|
.scrollpanel();
|
||||||
|
|
||||||
$('#langSelector').hover(
|
$langSelector.hover(
|
||||||
function () {
|
function () {
|
||||||
$langOptions
|
$langOptions
|
||||||
.css('top', '-' + $langOptions.outerHeight() + 'px')
|
.css('top', '-' + $langOptions.outerHeight() + 'px')
|
||||||
|
@ -93,15 +103,16 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
init = function () {
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initLangSelector(langs);
|
initLangSelector(langs);
|
||||||
localize(langs, settings.lang, settings.useBrowserLang);
|
localize(langs, settings.lang, settings.useBrowserLang);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
init();
|
||||||
init: init,
|
|
||||||
formatDates: formatDates
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
});
|
44
src/_h5ai/js/inc/ext/link-hover-states.js
Normal file
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
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();
|
||||||
|
});
|
114
src/_h5ai/js/inc/ext/select.js
Normal file
114
src/_h5ai/js/inc/ext/select.js
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
|
||||||
|
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,
|
||||||
|
$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) {
|
||||||
|
|
||||||
|
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 .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);
|
||||||
|
$selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
|
||||||
|
$('#extended .entry.selecting.selected').removeClass('selecting').removeClass('selected');
|
||||||
|
$('#extended .entry.selecting').removeClass('selecting').addClass('selected');
|
||||||
|
publish();
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionStart = function (event) {
|
||||||
|
|
||||||
|
var view = $(document).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 .entry').removeClass('selected');
|
||||||
|
publish();
|
||||||
|
}
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectionRect.hide().appendTo($('body'));
|
||||||
|
|
||||||
|
// $('#topbar,#bottombar,#tree,input').on('mousedown', noSelection);
|
||||||
|
// $('#content').on('mousedown', 'a', noSelectionUnlessCtrl);
|
||||||
|
// $document.on('mousedown', selectionStart);
|
||||||
|
|
||||||
|
$document
|
||||||
|
.on('mousedown', '.noSelection', noSelection)
|
||||||
|
.on('mousedown', '.noSelectionUnlessCtrl,input,a', noSelectionUnlessCtrl)
|
||||||
|
.on('mousedown', selectionStart);
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
|
@ -1,7 +1,16 @@
|
||||||
|
|
||||||
Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core) {
|
module.define('ext/sort', [jQuery, 'core/settings', 'core/resource', 'core/store'], function ($, allsettings, resource, store) {
|
||||||
|
|
||||||
var type = function (entry) {
|
var defaults = {
|
||||||
|
enabled: false,
|
||||||
|
order: 'na'
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings.sort),
|
||||||
|
|
||||||
|
storekey = 'h5ai.sortorder',
|
||||||
|
|
||||||
|
type = function (entry) {
|
||||||
|
|
||||||
var $entry = $(entry);
|
var $entry = $(entry);
|
||||||
|
|
||||||
|
@ -54,17 +63,21 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
||||||
|
|
||||||
var order = orders[id];
|
var order = orders[id];
|
||||||
|
|
||||||
|
store.put(storekey, id);
|
||||||
|
|
||||||
$all.removeClass('ascending').removeClass('descending');
|
$all.removeClass('ascending').removeClass('descending');
|
||||||
order.head.addClass(order.clas);
|
order.head.addClass(order.clas);
|
||||||
$('#extended .entry').detach().sort(order.fn).appendTo($('#extended > ul'));
|
$('#extended .entry').detach().sort(order.fn).appendTo($('#extended > ul'));
|
||||||
core.hash({sort: id});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
init = function () {
|
init = function () {
|
||||||
|
|
||||||
var $ascending = $('<img src="' + core.image('ascending') + '" class="sort ascending" alt="ascending" />'),
|
if (!settings.enabled) {
|
||||||
$descending = $('<img src="' + core.image('descending') + '" class="sort descending" alt="descending" />'),
|
return;
|
||||||
initialOrder = core.hash('sort'),
|
}
|
||||||
|
|
||||||
|
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'),
|
$header = $('#extended li.header'),
|
||||||
$label = $header.find('a.label'),
|
$label = $header.find('a.label'),
|
||||||
$date = $header.find('a.date'),
|
$date = $header.find('a.date'),
|
||||||
|
@ -104,7 +117,7 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sortBy(initialOrder || settings.sortorder);
|
sortBy(store.get(storekey) || settings.order);
|
||||||
|
|
||||||
$label
|
$label
|
||||||
.append($ascending.clone()).append($descending.clone())
|
.append($ascending.clone()).append($descending.clone())
|
||||||
|
@ -128,7 +141,5 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
init();
|
||||||
init: init
|
|
||||||
};
|
|
||||||
});
|
});
|
76
src/_h5ai/js/inc/ext/statusbar.js
Normal file
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
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: 'thumbsrc',
|
||||||
|
href: entry.absHref,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
mode: 'square'
|
||||||
|
});
|
||||||
|
requestThumb($imgBig, {
|
||||||
|
action: 'thumbsrc',
|
||||||
|
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
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
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);
|
||||||
|
});
|
133
src/_h5ai/js/inc/ext/zipped-download.js
Normal file
133
src/_h5ai/js/inc/ext/zipped-download.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
|
||||||
|
module.define('ext/zipped-download', [jQuery, 'core/settings', 'core/resource', 'core/event'], function ($, allsettings, resource, event) {
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = _.extend({}, defaults, allsettings['zipped-download']),
|
||||||
|
|
||||||
|
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.status === 'ok') {
|
||||||
|
setTimeout(function () { // wait here so the img above can be updated in time
|
||||||
|
|
||||||
|
window.location = resource.api() + '?action=getzip&id=' + response.id;
|
||||||
|
}, 200);
|
||||||
|
} 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', resource.image('loading.gif', true));
|
||||||
|
$.ajax({
|
||||||
|
url: resource.api(),
|
||||||
|
data: {
|
||||||
|
action: 'zip',
|
||||||
|
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) {
|
||||||
|
|
||||||
|
var $downloadBtn = $('#download');
|
||||||
|
|
||||||
|
selectedHrefsStr = '';
|
||||||
|
if (entries.length) {
|
||||||
|
selectedHrefsStr = _.map(entries, function (entry) {
|
||||||
|
|
||||||
|
return entry.absHref;
|
||||||
|
}).join(':');
|
||||||
|
$downloadBtn.show();
|
||||||
|
} else {
|
||||||
|
$downloadBtn.hide();
|
||||||
|
$downloadAuth.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
init = function () {
|
||||||
|
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$download = $(downloadBtnTemplate)
|
||||||
|
.appendTo($('#navbar'))
|
||||||
|
.find('a').on('click', function (event) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
$downloadAuth.hide();
|
||||||
|
requestZipping(selectedHrefsStr);
|
||||||
|
});
|
||||||
|
$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();
|
||||||
|
});
|
|
@ -1,130 +0,0 @@
|
||||||
|
|
||||||
Module.define('extended', [jQuery, 'settings', 'conhtml', 'util', 'core'], function ($, settings, conhtml, util, core) {
|
|
||||||
|
|
||||||
var initBreadcrumb = function () {
|
|
||||||
|
|
||||||
var $ul = $("body > nav ul"),
|
|
||||||
pathname = "/",
|
|
||||||
path = conhtml.getPath(pathname),
|
|
||||||
pathnameParts = document.location.pathname.split("/"),
|
|
||||||
lastPart = "",
|
|
||||||
title = document.domain;
|
|
||||||
|
|
||||||
$ul.append(conhtml.updateCrumbHtml(path));
|
|
||||||
|
|
||||||
$.each(pathnameParts, function (idx, part) {
|
|
||||||
if (part !== "") {
|
|
||||||
pathname += part + "/";
|
|
||||||
$ul.append(conhtml.updateCrumbHtml(conhtml.getPath(pathname)));
|
|
||||||
lastPart = part + " - ";
|
|
||||||
title += " > " + part;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.title = 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 = conhtml.getPath(document.location.pathname, this);
|
|
||||||
$ul.append(conhtml.updateExtendedHtml(path));
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#extended").append($ul);
|
|
||||||
|
|
||||||
// empty
|
|
||||||
if ($ul.children(".entry:not(.folder-parent)").size() === 0) {
|
|
||||||
$("#extended").append($("<div class='empty l10n-empty'>empty</div>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// no match
|
|
||||||
$("#extended").append($("<div class='no-match l10n-noMatch'>no match</div>"));
|
|
||||||
},
|
|
||||||
customize = function () {
|
|
||||||
|
|
||||||
if (settings.customHeader) {
|
|
||||||
$.ajax({
|
|
||||||
url: settings.customHeader,
|
|
||||||
dataType: "html",
|
|
||||||
success: function (data) {
|
|
||||||
$("#content > header").append($(data)).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.customFooter) {
|
|
||||||
$.ajax({
|
|
||||||
url: settings.customFooter,
|
|
||||||
dataType: "html",
|
|
||||||
success: function (data) {
|
|
||||||
$("#content > footer").prepend($(data)).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fetchPath = function (pathname, callback) {
|
|
||||||
|
|
||||||
conhtml.fetchStatusAndContent(pathname, false, function (status, content) {
|
|
||||||
|
|
||||||
var path = conhtml.getPath(pathname);
|
|
||||||
|
|
||||||
path.status = status;
|
|
||||||
path.content = content;
|
|
||||||
callback(path);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fetchTree = function (pathname, callback, childPath) {
|
|
||||||
|
|
||||||
fetchPath(pathname, function (path) {
|
|
||||||
|
|
||||||
var parent = 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(conhtml.updateTreeHtml(path))
|
|
||||||
.scrollpanel()
|
|
||||||
.show();
|
|
||||||
core.shiftTree(false, true);
|
|
||||||
core.linkHoverStates();
|
|
||||||
setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
initBreadcrumb();
|
|
||||||
initExtendedView();
|
|
||||||
customize();
|
|
||||||
conhtml.updatePaths();
|
|
||||||
if (settings.showTree) {
|
|
||||||
populateTree();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,106 +0,0 @@
|
||||||
|
|
||||||
Module.define('finder', [jQuery, 'settings', 'util', 'core'], function ($, settings, util, core) {
|
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
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 util.reEscape(part);
|
|
||||||
}).join('|');
|
|
||||||
return new RegExp(sequence);
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
if (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', 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 = core.hash('filter');
|
|
||||||
if (initialFilter) {
|
|
||||||
$('#filter input').val(initialFilter);
|
|
||||||
checkState(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: init,
|
|
||||||
filter: filter
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Module.define('splash', [jQuery, 'core'], function ($, core) {
|
module.define('h5ai-info', [jQuery, 'core/resource'], function ($, resource) {
|
||||||
|
|
||||||
var setCheckResult = function (id, result) {
|
var setCheckResult = function (id, result) {
|
||||||
|
|
||||||
|
@ -11,16 +11,19 @@ Module.define('splash', [jQuery, 'core'], function ($, core) {
|
||||||
$ele.addClass('test-failed').text('no');
|
$ele.addClass('test-failed').text('no');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChecksResponse = function (response) {
|
handleChecksResponse = function (response) {
|
||||||
|
|
||||||
setCheckResult('#test-php', response && response.php);
|
_.each(['php', 'cache', 'thumbs', 'temp', 'zips'], function (test) {
|
||||||
setCheckResult('#test-zips', response && response.zips);
|
|
||||||
setCheckResult('#test-thumbs', response && response.thumbs);
|
setCheckResult('#test-' + test, response && response[test]);
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
checks = function () {
|
checks = function () {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: core.api(),
|
url: resource.api(),
|
||||||
data: {
|
data: {
|
||||||
action: 'checks'
|
action: 'checks'
|
||||||
},
|
},
|
||||||
|
@ -36,12 +39,11 @@ Module.define('splash', [jQuery, 'core'], function ($, core) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
init = function () {
|
init = function () {
|
||||||
|
|
||||||
checks();
|
checks();
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
init();
|
||||||
init: init
|
|
||||||
};
|
|
||||||
});
|
});
|
21
src/_h5ai/js/inc/h5ai-main.js
Normal file
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');
|
||||||
|
});
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
Module.define('h5ai', [jQuery, 'core', 'extended', 'localize', 'sort', 'finder', 'zip', 'context', 'splash'], function ($, core, extended, localize, sort, finder, zip, context, splash) {
|
|
||||||
|
|
||||||
var h5ai = {};
|
|
||||||
|
|
||||||
h5ai.init = function () {
|
|
||||||
|
|
||||||
var $html = $('html');
|
|
||||||
|
|
||||||
h5ai.isJs = $html.hasClass('h5ai-js');
|
|
||||||
h5ai.isPhp = $html.hasClass('h5ai-php');
|
|
||||||
h5ai.isSplash = $html.hasClass('h5ai-splash');
|
|
||||||
|
|
||||||
if (h5ai.isJs || h5ai.isPhp) {
|
|
||||||
if (h5ai.isJs) {
|
|
||||||
extended.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
core.init();
|
|
||||||
localize.init();
|
|
||||||
sort.init();
|
|
||||||
finder.init();
|
|
||||||
zip.init();
|
|
||||||
context.init();
|
|
||||||
|
|
||||||
if (h5ai.isPhp) {
|
|
||||||
$('#tree').scrollpanel();
|
|
||||||
core.shiftTree(false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h5ai.isSplash) {
|
|
||||||
splash.init();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return h5ai;
|
|
||||||
});
|
|
84
src/_h5ai/js/inc/lib/jquery.mousewheel-3.0.6.js
Normal file
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);
|
|
196
src/_h5ai/js/inc/lib/module.js
Normal file
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 (depId, id) {
|
||||||
|
|
||||||
|
if (_.inArray(def.id, depId) >= 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'));
|
|
@ -1,36 +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, Base64, H5AI_CONFIG */
|
/*global _, amplify, Base64, H5AI_CONFIG, jQuery, Modernizr, module, moment */
|
||||||
|
|
||||||
// @include "module.js"
|
// @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 "settings.js"
|
// @include "model/entry.js"
|
||||||
|
|
||||||
// @include "util.js"
|
// @include "parser/apache-autoindex.js"
|
||||||
// @include "core.js"
|
// @include "parser/generic-json.js"
|
||||||
// @include "localize.js"
|
|
||||||
// @include "sort.js"
|
|
||||||
// @include "zip.js"
|
|
||||||
// @include "finder.js"
|
|
||||||
// @include "context.js"
|
|
||||||
|
|
||||||
// @include "path.js"
|
// @include "view/extended.js"
|
||||||
// @include "connector.js"
|
// @include "view/spacing.js"
|
||||||
// @include "html.js"
|
// @include "view/viewmode.js"
|
||||||
// @include "extended.js"
|
|
||||||
|
|
||||||
// @include "splash.js"
|
// @include "ext/crumb.js"
|
||||||
|
// @include "ext/custom.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 "ext/zipped-download.js"
|
||||||
|
|
||||||
// @include "h5ai.js"
|
// @include "h5ai-info.js"
|
||||||
|
// @include "h5ai-main.js"
|
||||||
|
|
||||||
|
|
||||||
jQuery(function () {
|
$(function () {
|
||||||
|
|
||||||
var h5ai = Module.require('h5ai');
|
module.require($('body').attr('id'));
|
||||||
|
|
||||||
h5ai.init();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}());
|
}(jQuery));
|
||||||
|
|
282
src/_h5ai/js/inc/model/entry.js
Normal file
282
src/_h5ai/js/inc/model/entry.js
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
|
||||||
|
module.define('model/entry', [jQuery, 'core/types'], function ($, types) {
|
||||||
|
|
||||||
|
var domain = document.domain,
|
||||||
|
location = document.location.pathname,
|
||||||
|
|
||||||
|
|
||||||
|
// utils
|
||||||
|
|
||||||
|
reEndsWithSlash = /\/$/,
|
||||||
|
|
||||||
|
pathEndsWithSlash = function (sequence) {
|
||||||
|
|
||||||
|
return reEndsWithSlash.test(sequence);
|
||||||
|
},
|
||||||
|
|
||||||
|
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]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
extToFileType = (function (types) {
|
||||||
|
var map = {};
|
||||||
|
$.each(types, function (type, exts) {
|
||||||
|
$.each(exts, function (idx, ext) {
|
||||||
|
map[ext] = type;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}(types)),
|
||||||
|
|
||||||
|
getFileType = function (sequence) {
|
||||||
|
|
||||||
|
if (pathEndsWithSlash(sequence)) {
|
||||||
|
return 'folder';
|
||||||
|
}
|
||||||
|
|
||||||
|
var dotidx = sequence.lastIndexOf('.'),
|
||||||
|
ext = dotidx >= 0 ? sequence.substr(dotidx) : sequence;
|
||||||
|
|
||||||
|
return extToFileType[ext.toLowerCase()] || 'unknown';
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
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 = getFileType(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 pathEndsWithSlash(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
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,174 +0,0 @@
|
||||||
|
|
||||||
var Module = window.Module = (function ($) {
|
|
||||||
|
|
||||||
var definitions = {},
|
|
||||||
modules = {},
|
|
||||||
|
|
||||||
err = function (message) {
|
|
||||||
|
|
||||||
$.error('module: ' + message);
|
|
||||||
},
|
|
||||||
|
|
||||||
uniq = function (array) {
|
|
||||||
|
|
||||||
var set = {},
|
|
||||||
uniq = [];
|
|
||||||
|
|
||||||
$.each(array, function (idx, element) {
|
|
||||||
|
|
||||||
if (!set[element]) {
|
|
||||||
set[element] = true;
|
|
||||||
uniq.push(element);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return uniq;
|
|
||||||
},
|
|
||||||
|
|
||||||
depsIntern = function (ids) {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var deps = [];
|
|
||||||
|
|
||||||
if (typeof ids === 'string') {
|
|
||||||
|
|
||||||
var def = definitions[ids];
|
|
||||||
if (def) {
|
|
||||||
$.each(def.deps, function (idx, id) {
|
|
||||||
|
|
||||||
deps = deps.concat(depsIntern(id));
|
|
||||||
});
|
|
||||||
deps.push(def.id);
|
|
||||||
} else {
|
|
||||||
deps.push(ids);
|
|
||||||
}
|
|
||||||
} else if ($.isArray(ids)) {
|
|
||||||
|
|
||||||
$.each(ids, function (idx, id) {
|
|
||||||
|
|
||||||
deps = deps.concat(depsIntern(id));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return uniq(deps);
|
|
||||||
},
|
|
||||||
|
|
||||||
deps = function (ids) {
|
|
||||||
|
|
||||||
if (ids) {
|
|
||||||
try {
|
|
||||||
return depsIntern(ids);
|
|
||||||
} catch (e) {
|
|
||||||
err('cyclic dependencies for ids "' + ids + '"');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var res = {};
|
|
||||||
$.each(definitions, function (id, def) {
|
|
||||||
|
|
||||||
res[id] = deps(id);
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
log = function () {
|
|
||||||
|
|
||||||
var allDeps = deps(),
|
|
||||||
allInvDeps = {};
|
|
||||||
|
|
||||||
$.each(definitions, function (id, def) {
|
|
||||||
|
|
||||||
var invDeps = [];
|
|
||||||
$.each(allDeps, function (i, depId) {
|
|
||||||
|
|
||||||
if ($.inArray(id, depId) >= 0) {
|
|
||||||
invDeps.push(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
allInvDeps[id] = invDeps;
|
|
||||||
});
|
|
||||||
|
|
||||||
$.each(allDeps, function (id, deps) {
|
|
||||||
|
|
||||||
deps.pop();
|
|
||||||
console.log(id + ' -> [ ' + deps.join(', ') + ' ]');
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('\n');
|
|
||||||
$.each(allInvDeps, function (id, invDeps) {
|
|
||||||
|
|
||||||
invDeps.shift();
|
|
||||||
console.log(id + ' <- [ ' + invDeps.join(', ') + ' ]');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
defs = function () {
|
|
||||||
|
|
||||||
return $.extend({}, definitions);
|
|
||||||
},
|
|
||||||
|
|
||||||
mods = function () {
|
|
||||||
|
|
||||||
return $.extend({}, modules);
|
|
||||||
},
|
|
||||||
|
|
||||||
define = function (id, deps, fn) {
|
|
||||||
|
|
||||||
if ($.isFunction(deps)) {
|
|
||||||
fn = deps;
|
|
||||||
deps = [];
|
|
||||||
}
|
|
||||||
if (typeof id !== 'string') {
|
|
||||||
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
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
require = function (id) {
|
|
||||||
|
|
||||||
if (typeof id !== 'string') {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (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;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
deps: deps,
|
|
||||||
log: log,
|
|
||||||
defs: defs,
|
|
||||||
mods: mods,
|
|
||||||
define: define,
|
|
||||||
require: require
|
|
||||||
};
|
|
||||||
|
|
||||||
}(jQuery));
|
|
42
src/_h5ai/js/inc/parser/apache-autoindex.js
Normal file
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
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) {
|
||||||
|
|
||||||
|
_.each(json.entries, function (jsonEntry) {
|
||||||
|
|
||||||
|
Entry.get(jsonEntry.absHref, jsonEntry.time, jsonEntry.size, jsonEntry.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (json.hasOwnProperty('customHeader')) {
|
||||||
|
settings.custom.header = json.customHeader;
|
||||||
|
}
|
||||||
|
if (json.hasOwnProperty('customFooter')) {
|
||||||
|
settings.custom.footer = json.customFooter;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,98 +0,0 @@
|
||||||
|
|
||||||
Module.define('path', [jQuery, 'settings', 'util', 'core'], function ($, settings, util, core) {
|
|
||||||
|
|
||||||
var create = function (folder, tableRow) {
|
|
||||||
|
|
||||||
var path = {},
|
|
||||||
$tds, $a, time, 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 (!util.pathEndsWithSlash(folder)) {
|
|
||||||
folder += '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableRow) {
|
|
||||||
$tds = $(tableRow).find('td');
|
|
||||||
$a = $tds.eq(1).find('a');
|
|
||||||
time = Date.parse($tds.eq(2).text()) || 0;
|
|
||||||
size = util.parseSize($tds.eq(3).text());
|
|
||||||
|
|
||||||
path.parentFolder = folder;
|
|
||||||
path.label = $a.text();
|
|
||||||
path.type = util.pathEndsWithSlash(path.label) ? 'folder' : core.getFileType(path.label);
|
|
||||||
path.href = $a.attr('href');
|
|
||||||
path.time = time;
|
|
||||||
path.size = size;
|
|
||||||
} else {
|
|
||||||
splits = util.splitPath(folder);
|
|
||||||
|
|
||||||
path.parentFolder = splits.parent || '';
|
|
||||||
path.label = util.checkedDecodeUri(splits.name);
|
|
||||||
if (path.label === '/') {
|
|
||||||
path.label = util.checkedDecodeUri(document.domain);
|
|
||||||
}
|
|
||||||
path.type = 'folder';
|
|
||||||
path.href = splits.name;
|
|
||||||
path.time = 0;
|
|
||||||
path.size = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (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 && settings.setParentFolderLabels) {
|
|
||||||
if (path.isDomain) {
|
|
||||||
path.label = util.checkedDecodeUri(document.domain);
|
|
||||||
} else {
|
|
||||||
splits = util.splitPath(path.parentFolder);
|
|
||||||
path.label = util.checkedDecodeUri(splits.parentname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path.isEmpty = function () {
|
|
||||||
|
|
||||||
return !path.content || $.isEmptyObject(path.content);
|
|
||||||
};
|
|
||||||
path.onClick = function (context) {
|
|
||||||
|
|
||||||
core.triggerPathClick(path, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
create: create
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,57 +0,0 @@
|
||||||
|
|
||||||
Module.define('config', [jQuery, H5AI_CONFIG], function ($, config) {
|
|
||||||
|
|
||||||
var 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
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
settings: $.extend({}, defaults, config.options),
|
|
||||||
types: $.extend({}, config.types),
|
|
||||||
langs: $.extend({}, config.langs)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Module.define('settings', ['config'], function (config) {
|
|
||||||
|
|
||||||
return config.settings;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Module.define('types', ['config'], function (config) {
|
|
||||||
|
|
||||||
return config.types;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Module.define('langs', ['config'], function (config) {
|
|
||||||
|
|
||||||
return config.langs;
|
|
||||||
});
|
|
|
@ -1,117 +0,0 @@
|
||||||
|
|
||||||
Module.define('util', [jQuery], function ($) {
|
|
||||||
|
|
||||||
var reSplitPath = /^\/([^\/]+\/?)$/,
|
|
||||||
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
|
|
||||||
rePathEndsWithSlash = /\/$/,
|
|
||||||
reParseSize = /^\s*([\.\d]+)\s*([kmg]?)b?\s*$/i,
|
|
||||||
kilo = 1000.0,
|
|
||||||
sizeUnits = ['B', 'KB', 'MB', 'GB', 'TB'],
|
|
||||||
|
|
||||||
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]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
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
|
|
||||||
};
|
|
||||||
});
|
|
135
src/_h5ai/js/inc/view/extended.js
Normal file
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
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
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,187 +0,0 @@
|
||||||
|
|
||||||
Module.define('zip', [jQuery, 'settings', 'core'], function ($, settings, core) {
|
|
||||||
|
|
||||||
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 = $(document).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', core.image("download"));
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
if (response.status === 'ok') {
|
|
||||||
window.location = 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', core.image("loading.gif", true));
|
|
||||||
$.ajax({
|
|
||||||
url: 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);
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
|
|
||||||
handleResponse();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
init = function () {
|
|
||||||
|
|
||||||
if (settings.zippedDownload) {
|
|
||||||
$('<li id="download"><a href="#"><img alt="download" /><span class="l10n-download">download</span></a></li>')
|
|
||||||
.find('img').attr('src', 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
|
|
||||||
};
|
|
||||||
});
|
|
4
src/_h5ai/js/modernizr-2.5.3.min.js
vendored
Normal file
4
src/_h5ai/js/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);
|
4
src/_h5ai/js/modernizr.min.js
vendored
4
src/_h5ai/js/modernizr.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@
|
||||||
// ------------------
|
// ------------------
|
||||||
// @include "inc/lib/jquery-1.7.1.min.js"
|
// @include "inc/lib/jquery-1.7.1.min.js"
|
||||||
// @include "inc/lib/jquery.fracs-0.11.min.js"
|
// @include "inc/lib/jquery.fracs-0.11.min.js"
|
||||||
// @include "inc/lib/jquery.mousewheel.js"
|
// @include "inc/lib/jquery.mousewheel-3.0.6.js"
|
||||||
// @include "inc/lib/jquery.qrcode.js"
|
// @include "inc/lib/jquery.qrcode.js"
|
||||||
// @include "inc/lib/jquery.scrollpanel.js"
|
// @include "inc/lib/jquery.scrollpanel.js"
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
// @include "inc/lib/json2.js"
|
// @include "inc/lib/json2.js"
|
||||||
// @include "inc/lib/moment-1.5.0.min.js"
|
// @include "inc/lib/moment-1.5.0.min.js"
|
||||||
// @include "inc/lib/underscore-1.3.1.min.js"
|
// @include "inc/lib/underscore-1.3.1.min.js"
|
||||||
|
// @include "inc/lib/module.js"
|
||||||
|
|
||||||
// h5ai
|
// h5ai
|
||||||
// ----
|
// ----
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
<?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 ? "/" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
define("H5AI_ABS_PATH", safe_dirname(safe_dirname(__FILE__)));
|
$h5ai = new H5ai();
|
||||||
|
$options = $h5ai->getOptions();
|
||||||
function require_h5ai($lib) {
|
|
||||||
|
|
||||||
require_once(H5AI_ABS_PATH . $lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function fail($code, $msg, $cond = true) {
|
function fail($code, $msg, $cond = true) {
|
||||||
|
@ -31,11 +24,6 @@ function checkKeys($keys) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/H5ai.php");
|
|
||||||
$h5ai = new H5ai();
|
|
||||||
$options = $h5ai->getOptions();
|
|
||||||
|
|
||||||
|
|
||||||
list($action) = checkKeys(array("action"));
|
list($action) = checkKeys(array("action"));
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,11 +52,11 @@ if ($action === "httpcodes") {
|
||||||
|
|
||||||
else if ($action === "thumb") {
|
else if ($action === "thumb") {
|
||||||
|
|
||||||
fail(0, "thumbs are disabled", !$options["showThumbs"]);
|
fail(0, "thumbs are disabled", !$options["thumbnails"]["enabled"]);
|
||||||
list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode"));
|
list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode"));
|
||||||
|
|
||||||
require_h5ai("/php/inc/Thumbnail.php");
|
H5ai::req_once("/php/inc/Thumbnail.php");
|
||||||
require_h5ai("/php/inc/Image.php");
|
H5ai::req_once("/php/inc/Image.php");
|
||||||
|
|
||||||
$srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
|
$srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
|
||||||
|
|
||||||
|
@ -90,28 +78,42 @@ else if ($action === "thumb") {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "tree") {
|
else if ($action === "thumbsrc") {
|
||||||
|
|
||||||
list($href) = checkKeys(array("href"));
|
if (!$options["thumbnails"]["enabled"]) {
|
||||||
|
echo json_encode(array("code" => 1, "absHref" => null));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
require_h5ai("/php/inc/Tree.php");
|
list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode"));
|
||||||
|
|
||||||
$absHref = trim($href);
|
H5ai::req_once("/php/inc/Thumbnail.php");
|
||||||
$absPath = $h5ai->getAbsPath($absHref);
|
H5ai::req_once("/php/inc/Image.php");
|
||||||
|
|
||||||
$tree = new TreeEntry($h5ai, $absPath, $absHref);
|
$srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
|
||||||
$tree->loadContent();
|
|
||||||
|
|
||||||
echo $tree->contentToHtml();
|
if (!Thumbnail::isUsable()) {
|
||||||
|
echo json_encode(array("code" => 2, "absHref" => null));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$thumbnail = new Thumbnail($h5ai, $srcAbsHref, $mode, $width, $height);
|
||||||
|
$thumbnail->create(1);
|
||||||
|
if (!file_exists($thumbnail->getPath())) {
|
||||||
|
echo json_encode(array("code" => 3, "absHref" => null));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(array("code" => 0, "absHref" => $thumbnail->getHref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if ($action === "zip") {
|
else if ($action === "zip") {
|
||||||
|
|
||||||
fail(0, "zipped download is disabled", !$options["zippedDownload"]);
|
fail(0, "zipped download is disabled", !$options["zipped-download"]["enabled"]);
|
||||||
list($hrefs) = checkKeys(array("hrefs"));
|
list($hrefs) = checkKeys(array("hrefs"));
|
||||||
|
|
||||||
require_h5ai("/php/inc/ZipIt.php");
|
H5ai::req_once("/php/inc/ZipIt.php");
|
||||||
|
|
||||||
$zipit = new ZipIt($h5ai);
|
$zipit = new ZipIt($h5ai);
|
||||||
|
|
||||||
|
@ -147,8 +149,10 @@ else if ($action === "checks") {
|
||||||
|
|
||||||
$response = array(
|
$response = array(
|
||||||
'php' => $h5ai->checks["php"],
|
'php' => $h5ai->checks["php"],
|
||||||
'zips' => $h5ai->checks["php"] && $h5ai->checks["zip"],
|
'cache' => $h5ai->checks["php"] && $h5ai->checks["cache"],
|
||||||
'thumbs' => $h5ai->checks["php"] && $h5ai->checks["gd"]
|
'thumbs' => $h5ai->checks["php"] && $h5ai->checks["cache"] && $h5ai->checks["gd"],
|
||||||
|
'temp' => $h5ai->checks["php"] && $h5ai->checks["temp"],
|
||||||
|
'zips' => $h5ai->checks["php"] && $h5ai->checks["temp"] && $h5ai->checks["zip"]
|
||||||
);
|
);
|
||||||
echo json_encode($response);
|
echo json_encode($response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
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,58 +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->checks = array(
|
|
||||||
"php" => version_compare(PHP_VERSION, "5.2.0") >= 0,
|
|
||||||
"zip" => class_exists("ZipArchive"),
|
|
||||||
"gd" => GD_VERSION != "GD_VERSION"
|
|
||||||
);
|
|
||||||
|
|
||||||
$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) : "";
|
||||||
|
|
||||||
|
@ -66,9 +51,43 @@ class H5ai {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getH5aiAbsPath() {
|
|
||||||
|
|
||||||
return $this->h5aiAbsPath;
|
|
||||||
|
private $h5aiAbsPath,
|
||||||
|
$rootAbsPath, $ignore, $ignoreRE,
|
||||||
|
$config, $options,
|
||||||
|
$cache,
|
||||||
|
$rootAbsHref, $h5aiAbsHref,
|
||||||
|
$absHref, $absPath;
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
"zip" => class_exists("ZipArchive"),
|
||||||
|
"gd" => GD_VERSION != "GD_VERSION",
|
||||||
|
"cache" => is_writable($this->h5aiAbsPath . "/cache"),
|
||||||
|
"temp" => is_writable(sys_get_temp_dir())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +97,12 @@ class H5ai {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getH5aiAbsPath() {
|
||||||
|
|
||||||
|
return $this->h5aiAbsPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getRootAbsHref() {
|
public function getRootAbsHref() {
|
||||||
|
|
||||||
return $this->rootAbsHref;
|
return $this->rootAbsHref;
|
||||||
|
@ -90,54 +115,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) {
|
||||||
|
@ -152,7 +141,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,51 +153,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,24 +194,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);
|
||||||
|
@ -271,12 +205,7 @@ class H5ai {
|
||||||
|
|
||||||
$cached = $this->cache->get($absHref);
|
$cached = $this->cache->get($absHref);
|
||||||
if ($cached === false) {
|
if ($cached === false) {
|
||||||
$folderStatus = $this->options["folderStatus"];
|
$code = $this->fetchHttpCode($absHref);
|
||||||
if (array_key_exists($absHref, $folderStatus)) {
|
|
||||||
$code = $folderStatus[$absHref];
|
|
||||||
} else {
|
|
||||||
$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);
|
||||||
}
|
}
|
||||||
|
@ -286,6 +215,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");
|
||||||
|
@ -307,16 +247,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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
|
@ -28,7 +28,7 @@ class ZipIt {
|
||||||
|
|
||||||
$zip->addEmptyDir("/");
|
$zip->addEmptyDir("/");
|
||||||
foreach ($hrefs as $href) {
|
foreach ($hrefs as $href) {
|
||||||
$d = safe_dirname($href, true);
|
$d = H5ai::normalize_path(dirname($href, true));
|
||||||
$n = basename($href);
|
$n = basename($href);
|
||||||
$code = $this->h5ai->getHttpCode($d);
|
$code = $this->h5ai->getHttpCode($d);
|
||||||
if ($code == 401) {
|
if ($code == 401) {
|
||||||
|
@ -82,7 +82,7 @@ class ZipIt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code;
|
return $code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
function safe_dirname($path, $endWithSlash = false) {
|
|
||||||
|
|
||||||
$path = str_replace("\\", "/", dirname($path));
|
|
||||||
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
define("H5AI_ABS_PATH", safe_dirname(safe_dirname(__FILE__)));
|
|
||||||
|
|
||||||
function require_h5ai($lib) {
|
|
||||||
|
|
||||||
require_once(H5AI_ABS_PATH . $lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_h5ai("/php/inc/H5ai.php");
|
|
||||||
require_h5ai("/php/inc/Crumb.php");
|
|
||||||
require_h5ai("/php/inc/Customize.php");
|
|
||||||
require_h5ai("/php/inc/Extended.php");
|
|
||||||
require_h5ai("/php/inc/Tree.php");
|
|
||||||
|
|
||||||
$h5ai = new H5ai();
|
|
||||||
$crumb = new Crumb($h5ai);
|
|
||||||
$customize = new Customize($h5ai);
|
|
||||||
$extended = new Extended($h5ai);
|
|
||||||
$tree = new Tree($h5ai);
|
|
||||||
|
|
||||||
?>
|
|
|
@ -6,21 +6,25 @@
|
||||||
# Options +Indexes
|
# Options +Indexes
|
||||||
# Options +FollowSymLinks
|
# Options +FollowSymLinks
|
||||||
|
|
||||||
# pure JavaScript version
|
|
||||||
HeaderName /_h5ai/header.html
|
HeaderName /_h5ai/header.html
|
||||||
|
|
||||||
# PHP version
|
# pure JavaScript version
|
||||||
# HeaderName /_h5ai/header.php
|
|
||||||
|
|
||||||
ReadmeName /_h5ai/footer.html
|
ReadmeName /_h5ai/footer.html
|
||||||
|
|
||||||
|
# PHP version
|
||||||
|
# ReadmeName /_h5ai/footer.php
|
||||||
|
|
||||||
|
|
||||||
IndexIgnore _h5ai*
|
IndexIgnore _h5ai*
|
||||||
|
|
||||||
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
|
||||||
IndexOptions Charset=UTF-8
|
IndexOptions Charset=UTF-8
|
||||||
|
IndexOptions FancyIndexing
|
||||||
|
IndexOptions FoldersFirst
|
||||||
|
IndexOptions HTMLTable
|
||||||
|
IndexOptions NameWidth=*
|
||||||
|
IndexOptions SuppressDescription
|
||||||
IndexOptions SuppressHTMLPreamble
|
IndexOptions SuppressHTMLPreamble
|
||||||
IndexOptions SuppressRules
|
IndexOptions SuppressRules
|
||||||
IndexOptions SuppressDescription
|
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
||||||
IndexOptions NameWidth=*
|
|
||||||
IndexOptions HTMLTable
|
|
||||||
IndexOptions XHTML
|
IndexOptions XHTML
|
||||||
|
|
59
src/index.php
Normal file
59
src/index.php
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?php header("Content-type: text/html;h5ai=%BUILD_VERSION%"); ?>
|
||||||
|
<!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>Directory index · styled with h5ai</title>
|
||||||
|
<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="//fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
||||||
|
<link rel="stylesheet" href="/_h5ai/css/styles.css">
|
||||||
|
<script src="/_h5ai/js/modernizr-2.5.3.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body id="h5ai-main">
|
||||||
|
<div id="topbar" class="clearfix">
|
||||||
|
<ul id="navbar"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<div id="extended" class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
|
<script src="/_h5ai/config.js"></script>
|
||||||
|
<script src="/_h5ai/js/scripts.js"></script>
|
||||||
|
<div id="data-generic-json" class="hidden">
|
||||||
|
<?php if (stripos($_SERVER["REQUEST_METHOD"], "HEAD") === false) {
|
||||||
|
|
||||||
|
function find_h5ai($path, $h5ai) {
|
||||||
|
|
||||||
|
if (file_exists($path . $h5ai)) {
|
||||||
|
return $path . $h5ai;
|
||||||
|
} else {
|
||||||
|
$parent = str_replace("\\", "/", dirname($path));
|
||||||
|
if ($parent !== $path) {
|
||||||
|
return find_h5ai($parent, $h5ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error_log("h5ai not found from " . __DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once(find_h5ai(str_replace("\\", "/", __DIR__), "/_h5ai/php/inc/H5ai.php"));
|
||||||
|
$h5ai = new H5ai();
|
||||||
|
echo $h5ai->getGenericJson();
|
||||||
|
} ?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue