Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
89fd74c4ab | ||
|
5708b2e38e | ||
|
2407cd50ce | ||
|
fbcb8cb5e8 | ||
|
d822eb63e2 | ||
|
5245b131b8 | ||
|
0293d54789 | ||
|
0d4edcb047 | ||
|
a339814582 | ||
|
8eac4ca133 |
88
README.md
@@ -1,36 +1,9 @@
|
||||
# h5ai v0.6   ·   a beautified Apache index
|
||||
# h5ai v0.10.1   ·   a beautified Apache index
|
||||
|
||||
|
||||
## Screenshots
|
||||
|
||||
<a href="http://larsjung.de/h5ai/sample/screenshots/h5ai-v0.5.2-details.png" target="_blank">
|
||||
<img src="http://larsjung.de/h5ai/sample/screenshots/h5ai-v0.5.2-details.png" width="400px" alt="screenshot" title="details view" style="display: inline" />
|
||||
</a>
|
||||
     
|
||||
<a href="http://larsjung.de/h5ai/sample/screenshots/h5ai-v0.5.2-icons.png" target="_blank">
|
||||
<img src="http://larsjung.de/h5ai/sample/screenshots/h5ai-v0.5.2-icons.png" width="400px" alt="screenshot" title="icons view" style="display: inline" />
|
||||
</a>
|
||||
|
||||
|
||||
## Live example
|
||||
|
||||
View a [sample folder](http://larsjung.de/h5ai/sample)
|
||||
*(the files are all empty to save webspace)*
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
Everything you need is located in folder `target`.
|
||||
|
||||
* Copy folder `h5ai` to the web-root directory of your server or alternativly set an alias `/h5ai/` to
|
||||
this folder.
|
||||
* Add the content of file `dot.htaccess` to the `.htaccess` file inside the directory you want to be
|
||||
styled (you might have to create this file). This directory and any subdirectories will be styled by h5ai.
|
||||
* Adjust `options.js` inside the `h5ai` folder to your needs. Defaults will be fine for a start.
|
||||
|
||||
Optionally add `h5ai.header.html` and/or `h5ai.footer.html` files to any of the styled folders to [display
|
||||
custom top or bottom sections](http://larsjung.de/h5ai/sample/customize). The content of those files
|
||||
will be wrapped by `<header>` and `<footer>` tags.
|
||||
h5ai aims to make browsing files on a Apache HTTP server more comfortable.
|
||||
See the [live demo](http://larsjung.de/h5ai/sample).
|
||||
For installation instructions and documentation have a look at
|
||||
[project page](http://larsjung.de/h5ai).
|
||||
|
||||
|
||||
## License and References
|
||||
@@ -47,19 +20,64 @@ please respect their rights.
|
||||
|
||||
## Changelog
|
||||
|
||||
### v0.10.1
|
||||
*2011-07-24*
|
||||
|
||||
* fixed problems with ' in links
|
||||
|
||||
|
||||
### v0.10
|
||||
*2011-07-24*
|
||||
|
||||
* fixed problems with XAMPP on Windows (see dot.htaccess comments for instructions)
|
||||
* fixed tree fade-in-fade-out effect for small displays ([issue #6](http://github.com/lrsjng/h5ai/issues/6))
|
||||
* added custom scrollbar to tree ([issue #6](http://github.com/lrsjng/h5ai/issues/6))
|
||||
* fixed broken links caused by URI encoding/decoding ([issue #9](http://github.com/lrsjng/h5ai/issues/9))
|
||||
* added "empty" to localization (hope Google Translate did a good job here)
|
||||
|
||||
|
||||
### v0.9
|
||||
*2011-07-18*
|
||||
|
||||
* linked hover states between crumb, extended view and tree
|
||||
* fixed size of tree view (now there's a ugly scrollbar, hopefully will be fixed)
|
||||
* refactored js to improve performance and cleaned code
|
||||
* added caching for folder status codes and content
|
||||
* added fr translation by [Nicolas](http://github.com/Nicosmos)
|
||||
* added nl translation by [Stefan de Konink](http://github.com/skinkie)
|
||||
* added sv translation by Oscar Carlsson
|
||||
|
||||
|
||||
### v0.8
|
||||
*2011-07-08*
|
||||
|
||||
* removed slashes from folder labels
|
||||
* optionally rename parent folder entries to real folder names, see `options.js`
|
||||
* long breadcrumbs (multiple rows) no longer hide content
|
||||
* error folder icons are opaque now
|
||||
* refactored js a lot (again...)
|
||||
|
||||
|
||||
### v0.7
|
||||
*2011-07-07*
|
||||
|
||||
* removed shadows
|
||||
* smarter tree side bar
|
||||
|
||||
|
||||
### v0.6
|
||||
*2011-07-05*
|
||||
|
||||
* refactored js
|
||||
* added localization, see options.js
|
||||
* added localization, see `options.js`
|
||||
|
||||
|
||||
### v0.5.3
|
||||
*2011-07-04*
|
||||
|
||||
* refactored js
|
||||
* added basic options support
|
||||
* commented options.js
|
||||
* added basic options support via `options.js`
|
||||
* commented `options.js`
|
||||
* optional tree sidebar
|
||||
|
||||
|
||||
|
@@ -3,7 +3,7 @@ custom = true
|
||||
|
||||
# project
|
||||
project.name = h5ai
|
||||
project.version = 0.6
|
||||
project.version = 0.10.1
|
||||
|
||||
|
||||
# src
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<project
|
||||
name="h5ai"
|
||||
basedir="."
|
||||
default="build"
|
||||
xmlns:scripp="antlib:de.larsjung.scripp.ant"
|
||||
>
|
||||
<target name="init">
|
||||
|
@@ -8,7 +8,7 @@
|
||||
# Options +FollowSymLinks
|
||||
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
<IfModule headers_module>
|
||||
|
||||
################################
|
||||
# cache images for 52 weeks
|
||||
@@ -25,7 +25,13 @@
|
||||
# style auto index
|
||||
################################
|
||||
|
||||
<IfModule mod_autoindex.c>
|
||||
################################
|
||||
# IMPORTANT FOR XAMPP
|
||||
# if you're running XAMPP you might need to replace the
|
||||
# following line with
|
||||
# <IfModule autoindex_color_module>
|
||||
################################
|
||||
<IfModule autoindex_module>
|
||||
|
||||
################################
|
||||
# uncomment the following line to force directory listing
|
||||
|
@@ -12,42 +12,56 @@
|
||||
white-space: nowrap;
|
||||
clear: both;
|
||||
|
||||
&.header a {
|
||||
padding-bottom: 18px;
|
||||
color: #555;
|
||||
opacity: 0.4;
|
||||
cursor: pointer;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&:visited {
|
||||
&.header {
|
||||
a, a:active, a:visited {
|
||||
padding-bottom: 18px;
|
||||
color: #555;
|
||||
}
|
||||
&:hover {
|
||||
color: #555;
|
||||
opacity: 0.9;
|
||||
}
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
text-decoration: none;
|
||||
opacity: 0.4;
|
||||
cursor: pointer;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&:hover {
|
||||
color: #555;
|
||||
opacity: 0.9;
|
||||
}
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.entry {
|
||||
border-bottom: 1px solid #ddd;
|
||||
|
||||
a {
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
|
||||
&:hover, &.hover {
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
&.notListable {
|
||||
> a, > a:visited {
|
||||
opacity: 0.7;
|
||||
color: #999;
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
margin-left: 12px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
opacity: 1;
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,11 +89,6 @@
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
.error {
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
.date {
|
||||
position: absolute;
|
||||
@@ -111,7 +120,7 @@
|
||||
|
||||
#extended.icons-view {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
padding: 3px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 15px;
|
||||
|
||||
@@ -127,7 +136,7 @@
|
||||
&.entry {
|
||||
float: left;
|
||||
|
||||
a {
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
margin: 8px;
|
||||
padding: 8px;
|
||||
@@ -135,16 +144,17 @@
|
||||
height: 120px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0,0,0,0);
|
||||
|
||||
&:hover {
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
//.box-shadow( 0, 0, 20px, #999 );
|
||||
}
|
||||
.icon {
|
||||
display: block;
|
||||
@@ -161,20 +171,28 @@
|
||||
.label {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
.error {
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
.date, .size {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.notListable {
|
||||
> a, > a:visited {
|
||||
opacity: 0.7;
|
||||
color: #999;
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
text-decoration: none;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
padding: 0 6px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +1,77 @@
|
||||
|
||||
#tree {
|
||||
display: none;
|
||||
position: fixed;
|
||||
display: none;
|
||||
left: 0;
|
||||
top: 80px;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
font-size: 0.85em;
|
||||
padding: 16px 32px 16px 16px;
|
||||
background-color: rgb(240,240,240);
|
||||
border: 1px solid rgb(225,225,225);
|
||||
background-color: rgb(241,241,241);
|
||||
border: 2px solid rgb(210,210,210);
|
||||
border-left: none;
|
||||
.border-radius ( 0 15px 15px 0 );
|
||||
.box-shadow( 0 0 30px #999 );
|
||||
|
||||
> .scrollbar {
|
||||
margin: 12px;
|
||||
width: 6px;
|
||||
background-color: rgb(210,210,210);
|
||||
.border-radius( 3px );
|
||||
|
||||
.drag {
|
||||
background-color: rgb(180,180,180);
|
||||
.border-radius( 3px );
|
||||
}
|
||||
&.dragOn .drag {
|
||||
background-color: rgb(150,150,150);
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
> a, > a.visited {
|
||||
.blank, .indicator {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 25px;
|
||||
float: left;
|
||||
}
|
||||
.indicator {
|
||||
opacity: 0.7;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
img {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 3px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
vertical-align: bottom;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
}
|
||||
&.open {
|
||||
img {
|
||||
.transform( rotate(90deg) );
|
||||
}
|
||||
}
|
||||
&.unknown {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
> a, > a:active, > a.visited {
|
||||
margin-left: 16px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid rgba(0,0,0,0);
|
||||
.border-radius( 5px );
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -39,7 +90,7 @@
|
||||
.hint {
|
||||
display: inline-block;
|
||||
margin-left: 12px;
|
||||
font-style: italic;
|
||||
font-size: 0.9em;
|
||||
color: #ccc;
|
||||
img {
|
||||
width: 10px;
|
||||
@@ -47,26 +98,29 @@
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
.error {
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&.file {
|
||||
display: none;
|
||||
}
|
||||
&.current {
|
||||
> a, > a:visited {
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
> a, > a:active, > a:visited {
|
||||
border: 1px solid rgb(221,221,221);
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.notListable {
|
||||
> a, > a:visited {
|
||||
&.error {
|
||||
> a, > a:active, > a:visited {
|
||||
color: #999;
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
.content {
|
||||
list-style: none;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ html.no-js {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: Ubuntu, sans-serif;
|
||||
font-size: 16px;
|
||||
@@ -22,16 +23,6 @@ body {
|
||||
}
|
||||
|
||||
|
||||
a, a:visited {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body > nav {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
@@ -39,9 +30,8 @@ body > nav {
|
||||
left: 0;
|
||||
top: 0;
|
||||
font-size: 0.85em;
|
||||
background-color: rgb(240,240,240);
|
||||
border-bottom: 1px solid rgb(225,225,225);
|
||||
.box-shadow( 0 0 30px #555 );
|
||||
background-color: rgb(241,241,241);
|
||||
border-bottom: 2px solid rgb(210,210,210);
|
||||
|
||||
span.jsDisabledFallback {
|
||||
display: block;
|
||||
@@ -50,45 +40,27 @@ body > nav {
|
||||
padding: 0 10px;
|
||||
color: #999;
|
||||
}
|
||||
li {
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&.crumb {
|
||||
float: left;
|
||||
border-right: 1px dotted rgb(225,225,225);
|
||||
.hint {
|
||||
margin-left: 8px;
|
||||
font-style: italic;
|
||||
color: #999;
|
||||
}
|
||||
img.hint {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
&.current {
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
&.view {
|
||||
float: right;
|
||||
border-left: 1px dotted rgb(225,225,225);
|
||||
}
|
||||
&:hover, &:hover a {
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
color: #e80;
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
.current a {
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
img {
|
||||
width: 16px;
|
||||
@@ -96,11 +68,30 @@ body > nav {
|
||||
vertical-align: bottom;
|
||||
padding: 0 6px 6px 0;
|
||||
}
|
||||
.crumb {
|
||||
float: left;
|
||||
border-right: 1px solid rgb(231,231,231);
|
||||
.hint {
|
||||
margin-left: 8px;
|
||||
font-style: italic;
|
||||
color: #999;
|
||||
}
|
||||
img.hint {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.view {
|
||||
float: right;
|
||||
border-left: 1px solid rgb(231,231,231);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#content {
|
||||
max-width: 980px;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
|
||||
> header {
|
||||
@@ -130,15 +121,16 @@ body > footer {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 10px 0;
|
||||
border-top: 1px solid rgb(225,225,225);
|
||||
background-color: rgb(240,240,240);
|
||||
background-color: rgb(241,241,241);
|
||||
border-top: 2px solid rgb(210,210,210);
|
||||
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
text-align: center;
|
||||
.box-shadow( 0 0 30px #555 );
|
||||
|
||||
a, a:visited {
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&:hover {
|
||||
@@ -152,15 +144,14 @@ body > footer {
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
bottom: 6px;
|
||||
float: left;
|
||||
opacity: 0.4;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.4;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
}
|
||||
&:hover img {
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<img class="techclass" src="/h5ai/images/html5-storage.png" alt="html5-storage" />
|
||||
<img class="techclass" src="/h5ai/images/html5-css3.png" alt="html5-css3" />
|
||||
</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai %BUILD_VERSION%">h5ai</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
||||
<span class="l10n-footerUsing">using</span>
|
||||
<a href="http://tiheum.deviantart.com/art/Faenza-Icons-173323228" target="_blank" title="icon theme for Gnome">Faenza icons</a>
|
||||
</footer>
|
||||
|
@@ -13,12 +13,9 @@
|
||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<nav class="clearfix">
|
||||
<span class="jsDisabledFallback">Directory index · JavaScript is disabled</span>
|
||||
<ul>
|
||||
<li id="domain" class="crumb">
|
||||
<a href="/"><img src="/h5ai/images/home.png" alt="domain" /><span>domain</span></a>
|
||||
</li>
|
||||
<li id="viewicons" class="view">
|
||||
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-viewIcons">icons</span></a>
|
||||
</li>
|
||||
@@ -26,7 +23,6 @@
|
||||
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-viewDetails">details</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</nav>
|
||||
<section id="content">
|
||||
<header></header>
|
||||
|
BIN
src/h5ai/icons/16x16/folder-home.png
Normal file
After Width: | Height: | Size: 637 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 236 B |
BIN
src/h5ai/icons/48x48/folder-home.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
src/h5ai/images/blank.png
Normal file
After Width: | Height: | Size: 227 B |
BIN
src/h5ai/images/tree.png
Normal file
After Width: | Height: | Size: 458 B |
@@ -1,99 +0,0 @@
|
||||
|
||||
var File = function ( utils, folder, tableRow ) {
|
||||
|
||||
if ( ! /\/$/.test( folder ) ) {
|
||||
folder += "/";
|
||||
};
|
||||
|
||||
if ( tableRow !== undefined ) {
|
||||
var $tds = $( tableRow ).find( "td" );
|
||||
var $img = $( $tds.get( 0 ) ).find( "img" );
|
||||
var $a= $( $tds.get( 1 ) ).find( "a" );
|
||||
|
||||
this.parentFolder = folder;
|
||||
this.icon16 = $img.attr( "src" );
|
||||
this.alt = $img.attr( "alt" );
|
||||
this.label = $a.text();
|
||||
this.href = $a.attr("href");
|
||||
this.date = $( $tds.get(2) ).text();
|
||||
this.size = $( $tds.get(3) ).text();
|
||||
} else {
|
||||
var splits = utils.splitPathname( folder );
|
||||
|
||||
this.parentFolder = splits[0];
|
||||
this.label = splits[1];
|
||||
this.icon16 = "/h5ai/icons/16x16/folder.png";
|
||||
this.alt = "[DIR]";
|
||||
this.href = this.label;
|
||||
this.date = "";
|
||||
this.size = "";
|
||||
if ( this.label === "/" ) {
|
||||
this.label = document.domain + "/";
|
||||
};
|
||||
};
|
||||
|
||||
this.icon48 = this.icon16.replace( "16x16", "48x48" );
|
||||
this.isFolder = ( this.alt === "[DIR]" );
|
||||
this.isParentFolder = ( this.isFolder && this.label === "Parent Directory" );
|
||||
this.absHref = this.isParentFolder ? this.href : this.parentFolder + this.href;
|
||||
this.content = undefined;
|
||||
|
||||
|
||||
this.isComplete = function () {
|
||||
|
||||
if ( this.isFolder ) {
|
||||
if ( this.content === undefined ) {
|
||||
return false;
|
||||
} else if ( this.content instanceof Array ) {
|
||||
for ( idx in this.content ) {
|
||||
if ( !this.content[idx].isComplete() ) {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
this.toHtml = function () {
|
||||
|
||||
var $entry = $( "<div class='entry' />" );
|
||||
|
||||
try {
|
||||
var $a = $( "<a href='" + this.absHref + "' />" )
|
||||
.appendTo( $entry )
|
||||
.append( $( "<span class='icon'><img src='" + this.icon16 + "' /></span>" ) )
|
||||
.append( $( "<span class='label'>" + this.label + "</span>" ) );
|
||||
|
||||
if ( this.isFolder ) {
|
||||
$entry.addClass( "folder" );
|
||||
if ( this.absHref === document.location.pathname ) {
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-open.png" );
|
||||
$entry.addClass( "current" );
|
||||
};
|
||||
if ( this.content instanceof Array ) {
|
||||
var $ul = $( "<ul class='content' />" ).appendTo( $entry );
|
||||
for ( idx in this.content ) {
|
||||
$( "<li />" ).append( this.content[idx].toHtml() ).appendTo( $ul );
|
||||
};
|
||||
} else if ( this.content === undefined ) {
|
||||
$a.append( $( "<span class='hint'><img src='/h5ai/images/loading.png' /></span>" ) );
|
||||
} else if ( this.content === 200 ) {
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.append( $( "<span class='hint'><img src='/h5ai/images/page.png' /></span>" ) );
|
||||
} else {
|
||||
$a.append( $( "<span class='hint error'>" + this.content + "</span>" ) );
|
||||
$entry.addClass( "notListable" );
|
||||
};
|
||||
} else {
|
||||
$entry.addClass( "file" );
|
||||
};
|
||||
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>fail</span>" ).appendTo( $entry );
|
||||
};
|
||||
|
||||
return $entry;
|
||||
};
|
||||
};
|
@@ -1,26 +1,20 @@
|
||||
|
||||
var H5ai = function ( options ) {
|
||||
var H5ai = function ( options, langs, pathCache ) {
|
||||
|
||||
|
||||
/*******************************
|
||||
* config
|
||||
*******************************/
|
||||
|
||||
var defaults = {
|
||||
columnClasses: [ "icon", "name", "date", "size" ],
|
||||
defaultSortOrder: "C=N;O=A",
|
||||
store: {
|
||||
viewmode: "h5ai.viewmode"
|
||||
},
|
||||
icons: {
|
||||
crumb: "/h5ai/images/crumb.png",
|
||||
ascending: "/h5ai/images/ascending.png",
|
||||
descending: "/h5ai/images/descending.png"
|
||||
},
|
||||
customHeader: "h5ai.header.html",
|
||||
customFooter: "h5ai.footer.html",
|
||||
callbacks: {
|
||||
folderClick: [],
|
||||
fileClick: []
|
||||
pathClick: []
|
||||
},
|
||||
|
||||
viewmodes: [ "details", "icons" ],
|
||||
@@ -28,7 +22,9 @@ var H5ai = function ( options ) {
|
||||
folderStatus: {
|
||||
},
|
||||
lang: undefined,
|
||||
useBrowserLang: true
|
||||
useBrowserLang: true,
|
||||
setParentFolderLabels: true,
|
||||
linkHoverStates: true
|
||||
};
|
||||
this.config = $.extend( {}, defaults, options );
|
||||
|
||||
@@ -37,20 +33,11 @@ var H5ai = function ( options ) {
|
||||
/*******************************
|
||||
* public api
|
||||
*******************************/
|
||||
|
||||
this.folderClick = function ( fn ) {
|
||||
|
||||
if ( typeof fn === "function" ) {
|
||||
this.config.callbacks.folderClick.push( fn );
|
||||
};
|
||||
return this;
|
||||
};
|
||||
this.pathClick = function ( fn ) {
|
||||
|
||||
|
||||
this.fileClick = function ( fn ) {
|
||||
|
||||
if ( typeof fn === "function" ) {
|
||||
this.config.callbacks.fileClick.push( fn );
|
||||
if ( $.isFunction( fn ) ) {
|
||||
this.config.callbacks.pathClick.push( fn );
|
||||
};
|
||||
return this;
|
||||
};
|
||||
@@ -63,11 +50,14 @@ var H5ai = function ( options ) {
|
||||
|
||||
this.init = function () {
|
||||
|
||||
document.title = decodeURI( document.domain + document.location.pathname );
|
||||
|
||||
this.applyViewmode();
|
||||
this.initBreadcrumb();
|
||||
this.initTopSpace();
|
||||
this.initViews();
|
||||
this.customize();
|
||||
this.localize( h5aiLangs, this.config.lang, this.config.useBrowserLang );
|
||||
this.localize( langs, this.config.lang, this.config.useBrowserLang );
|
||||
};
|
||||
|
||||
|
||||
@@ -76,18 +66,10 @@ var H5ai = function ( options ) {
|
||||
* callback triggers
|
||||
*******************************/
|
||||
|
||||
this.triggerFolderClick = function ( label ) {
|
||||
this.triggerPathClick = function ( path, context ) {
|
||||
|
||||
for ( idx in this.config.callbacks.folderClick ) {
|
||||
this.config.callbacks.folderClick[idx].call( window, label );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.triggerFileClick = function ( label ) {
|
||||
|
||||
for ( idx in this.config.callbacks.fileClick ) {
|
||||
this.config.callbacks.fileClick[idx].call( window, label );
|
||||
for ( idx in this.config.callbacks.pathClick ) {
|
||||
this.config.callbacks.pathClick[idx].call( window, path, context );
|
||||
};
|
||||
};
|
||||
|
||||
@@ -100,10 +82,7 @@ var H5ai = function ( options ) {
|
||||
this.getViewmode = function () {
|
||||
|
||||
var viewmode = localStorage.getItem( this.config.store.viewmode );
|
||||
if ( $.inArray( viewmode, this.config.viewmodes ) >= 0 ) {
|
||||
return viewmode;
|
||||
};
|
||||
return this.config.viewmodes[0];
|
||||
return $.inArray( viewmode, this.config.viewmodes ) >= 0 ? viewmode : this.config.viewmodes[0];
|
||||
};
|
||||
|
||||
|
||||
@@ -112,8 +91,10 @@ var H5ai = function ( options ) {
|
||||
if ( viewmode !== undefined ) {
|
||||
localStorage.setItem( this.config.store.viewmode, viewmode );
|
||||
};
|
||||
viewmode = this.getViewmode();
|
||||
|
||||
$( "body > nav li.view" ).hide();
|
||||
$( "body > nav li.view" ).hide().removeClass( "current" );
|
||||
|
||||
if ( this.config.viewmodes.length > 1 ) {
|
||||
if ( $.inArray( "details", this.config.viewmodes ) >= 0 ) {
|
||||
$( "#viewdetails" ).show();
|
||||
@@ -123,12 +104,11 @@ var H5ai = function ( options ) {
|
||||
};
|
||||
};
|
||||
|
||||
$( "body > nav li.view" ).removeClass( "current" );
|
||||
if ( this.getViewmode() === "details" ) {
|
||||
if ( viewmode === "details" ) {
|
||||
$( "#viewdetails" ).closest( "li" ).addClass( "current" );
|
||||
$( "#table" ).hide();
|
||||
$( "#extended" ).addClass( "details-view" ).removeClass( "icons-view" ).show();
|
||||
} else if ( this.getViewmode() === "icons" ) {
|
||||
} else if ( viewmode === "icons" ) {
|
||||
$( "#viewicons" ).closest( "li" ).addClass( "current" );
|
||||
$( "#table" ).hide();
|
||||
$( "#extended" ).removeClass( "details-view" ).addClass( "icons-view" ).show();
|
||||
@@ -138,29 +118,63 @@ var H5ai = function ( options ) {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* breadcrumb and doc title
|
||||
* breadcrumb
|
||||
*******************************/
|
||||
|
||||
this.initBreadcrumb = function () {
|
||||
|
||||
$( "#domain span" ).text( document.domain );
|
||||
var pathname = decodeURI( document.location.pathname );
|
||||
var parts = pathname.split( "/" );
|
||||
var path = "/";
|
||||
var $ul = $( "nav ul" );
|
||||
for ( idx in parts ) {
|
||||
var part = parts[idx];
|
||||
var $ul = $( "body > nav ul" );
|
||||
|
||||
var pathname = "/";
|
||||
var path = pathCache.getPathForFolder( pathname );
|
||||
$ul.append( path.updateCrumbHtml() );
|
||||
|
||||
var pathnameParts = document.location.pathname.split( "/" );
|
||||
for ( idx in pathnameParts ) {
|
||||
var part = pathnameParts[idx];
|
||||
if ( part !== "" ) {
|
||||
path += part + "/";
|
||||
$ul.append( $( "<li class='crumb'><a href='" + path + "'><img src='" + this.config.icons.crumb + "' alt='>' />" + part + "</a></li>" ) );
|
||||
pathname += part + "/";
|
||||
var path = pathCache.getPathForFolder( pathname );
|
||||
$ul.append( path.updateCrumbHtml() );
|
||||
};
|
||||
};
|
||||
$( "body > nav .crumb:last" ).addClass( "current" );
|
||||
};
|
||||
|
||||
document.title = document.domain + pathname;
|
||||
|
||||
|
||||
/*******************************
|
||||
* top space, depending on nav height
|
||||
*******************************/
|
||||
|
||||
this.initTopSpace = function () {
|
||||
|
||||
function adjustTopSpace() {
|
||||
|
||||
var winHeight = $( window ).height();
|
||||
var navHeight = $( "body > nav" ).outerHeight();
|
||||
var footerHeight = $( "body > footer" ).outerHeight();
|
||||
var contentSpacing = 50;
|
||||
var treeSpacing = 50;
|
||||
|
||||
$( "body" )
|
||||
.css( "margin-top", "" + ( navHeight + contentSpacing ) + "px" )
|
||||
.css( "margin-bottom", "" + ( footerHeight + contentSpacing ) + "px" );
|
||||
|
||||
$( "#tree" )
|
||||
.css( "top", "" + ( navHeight + treeSpacing ) + "px" )
|
||||
.css( "height", "" + ( winHeight - navHeight - footerHeight - 36 - 2 * treeSpacing ) + "px" );
|
||||
try {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} catch ( err ) {};
|
||||
};
|
||||
|
||||
$( window ).resize( function () {
|
||||
adjustTopSpace();
|
||||
} );
|
||||
adjustTopSpace();
|
||||
};
|
||||
|
||||
|
||||
@@ -171,22 +185,7 @@ var H5ai = function ( options ) {
|
||||
|
||||
this.initTableView = function () {
|
||||
|
||||
var ref = this;
|
||||
function getColumnClass( idx ) {
|
||||
|
||||
if ( idx >= 0 && idx < ref.config.columnClasses.length ) {
|
||||
return ref.config.columnClasses[idx];
|
||||
};
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
$( "#table td" ).removeAttr( "align" ).removeAttr( "valign" );
|
||||
$( "#table tr" ).each( function () {
|
||||
var colIdx = 0;
|
||||
$( this ).find( "th,td" ).each( function () {
|
||||
$( this ).addClass( getColumnClass( colIdx++ ) );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
@@ -200,11 +199,12 @@ var H5ai = function ( options ) {
|
||||
var $ul = $( "<ul/>" );
|
||||
|
||||
// headers
|
||||
var $ths = $( "#table th" );
|
||||
var $label = $ths.eq( 1 ).find( "a" );
|
||||
var $date = $ths.eq( 2 ).find( "a" );
|
||||
var $size = $ths.eq( 3 ).find( "a" );
|
||||
var $li = $( "<li class='header' />" ).appendTo( $ul );
|
||||
$( "<a class='icon'></a>" ).appendTo( $li );
|
||||
var $label = $( "th.name a" );
|
||||
var $date = $( "th.date a" );
|
||||
var $size = $( "th.size a" );
|
||||
$( "<a class='label' href='" + $label.attr( "href" ) + "'><span class='l10n-columnName'>" + $label.text() + "</span></a>" ).appendTo( $li );
|
||||
$( "<a class='date' href='" + $date.attr( "href" ) + "'><span class='l10n-columnLastModified'>" + $date.text() + "</span></a>" ).appendTo( $li );
|
||||
$( "<a class='size' href='" + $size.attr( "href" ) + "'><span class='l10n-columnSize'>" + $size.text() + "</span></a>" ).appendTo( $li );
|
||||
@@ -216,9 +216,9 @@ var H5ai = function ( options ) {
|
||||
};
|
||||
var $icon;
|
||||
if ( order.indexOf( "O=A" ) >= 0 ) {
|
||||
$icon = $( "<img src='" + this.config.icons.ascending + "' class='sort' alt='ascending' />" );
|
||||
$icon = $( "<img src='/h5ai/images/ascending.png' class='sort' alt='ascending' />" );
|
||||
} else {
|
||||
$icon = $( "<img src='" + this.config.icons.descending + "' class='sort' alt='descending' />" );
|
||||
$icon = $( "<img src='/h5ai/images/descending.png' class='sort' alt='descending' />" );
|
||||
};
|
||||
if ( order.indexOf( "C=N" ) >= 0 ) {
|
||||
$li.find( "a.label" ).append( $icon );
|
||||
@@ -227,68 +227,27 @@ var H5ai = function ( options ) {
|
||||
} else if ( order.indexOf( "C=S" ) >= 0 ) {
|
||||
$li.find( "a.size" ).prepend( $icon );
|
||||
};
|
||||
|
||||
// entries
|
||||
$( "#table td.name a" ).closest( "tr" ).each( function () {
|
||||
var $tr = $( this );
|
||||
var $img = $tr.find( "td.icon img" );
|
||||
var iconsmall = $img.attr( "src" );
|
||||
var iconbig = iconsmall.replace( "16x16", "48x48" );
|
||||
var alt = $img.attr( "alt" );
|
||||
var $link = $tr.find( "td.name a" );
|
||||
var label = $link.text();
|
||||
var href = $link.attr( "href" );
|
||||
var date = $tr.find( "td.date" ).text();
|
||||
var size = $tr.find( "td.size" ).text();
|
||||
|
||||
var $li = $( "<li class='entry' />" ).appendTo( $ul );
|
||||
if ( alt === "[DIR]" ) {
|
||||
$li.addClass( "folder" );
|
||||
} else {
|
||||
$li.addClass( "file" );
|
||||
}
|
||||
var $a = $( "<a href='" + href + "' />" ).appendTo( $li );
|
||||
$( "<span class='icon small'><img src='" + iconsmall + "' alt='" + alt + "' /></span>" ).appendTo( $a );
|
||||
$( "<span class='icon big'><img src='" + iconbig + "' alt='" + alt + "' /></span>" ).appendTo( $a );
|
||||
$( "<span class='label'>" + label + "</span>" ).appendTo( $a );
|
||||
$( "<span class='date'>" + date + "</span>" ).appendTo( $a );
|
||||
$( "<span class='size'>" + size + "</span>" ).appendTo( $a );
|
||||
// entries
|
||||
$( "#table td" ).closest( "tr" ).each( function () {
|
||||
var path = pathCache.getPathForTableRow( document.location.pathname, this );
|
||||
$ul.append( path.updateExtendedHtml() );
|
||||
} );
|
||||
$( "#table" ).remove();
|
||||
|
||||
$( "#extended" ).append( $ul );
|
||||
|
||||
$entries = $( "#extended .entry" );
|
||||
|
||||
// empty
|
||||
if ( $entries.size() === 0 || $entries.size() === 1 && $entries.find( ".label" ).text() === "Parent Directory" ) {
|
||||
$( "#extended" ).append( $( "<div class='empty'>empty</div>" ) );
|
||||
};
|
||||
|
||||
// parent folder
|
||||
if ( $entries.size() > 0 ) {
|
||||
$entry0 = $( $entries.get(0) );
|
||||
if ( $entry0.find( ".label" ).text() === "Parent Directory" ) {
|
||||
$entry0.find( ".label" ).addClass( "l10n-parentDirectory" );
|
||||
$entry0.addClass( "parentfolder" );
|
||||
};
|
||||
if ( $ul.children( ".entry:not(.parentfolder)" ).size() === 0 ) {
|
||||
$( "#extended" ).append( $( "<div class='empty l10n-empty'>empty</div>" ) );
|
||||
};
|
||||
|
||||
// in case of floats
|
||||
$( "#extended" ).append( $( "<div class='clearfix' />" ) );
|
||||
|
||||
// click callbacks
|
||||
var ref = this;
|
||||
$( "#extended .entry.folder" )
|
||||
.click( function() {
|
||||
ref.triggerFolderClick( $( this ).find( ".label" ).text() );
|
||||
} );
|
||||
$( "#extended .entry.file" )
|
||||
.click( function() {
|
||||
ref.triggerFileClick( $( this ).find( ".label" ).text() );
|
||||
} );
|
||||
$( "#extended" ).addClass( "clearfix" );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* init views
|
||||
*******************************/
|
||||
@@ -298,15 +257,14 @@ var H5ai = function ( options ) {
|
||||
this.initTableView();
|
||||
this.initExtendedView();
|
||||
|
||||
var ref = this;
|
||||
$( "#viewdetails" ).closest( "li" )
|
||||
.click( function () {
|
||||
ref.applyViewmode( "details" );
|
||||
} );
|
||||
.click( $.proxy( function () {
|
||||
this.applyViewmode( "details" );
|
||||
}, this ) );
|
||||
$( "#viewicons" ).closest( "li" )
|
||||
.click( function () {
|
||||
ref.applyViewmode( "icons" );
|
||||
} );
|
||||
.click( $.proxy( function () {
|
||||
this.applyViewmode( "icons" );
|
||||
}, this ) );
|
||||
};
|
||||
|
||||
|
||||
@@ -349,12 +307,9 @@ var H5ai = function ( options ) {
|
||||
} else if ( browserLang.length > 2 && data[ browserLang.substr( 0, 2 ) ] !== undefined ) {
|
||||
lang = browserLang.substr( 0, 2 );
|
||||
};
|
||||
if ( lang === "en" ) {
|
||||
lang = undefined;
|
||||
};
|
||||
};
|
||||
|
||||
if ( data[ lang ] !== undefined ) {
|
||||
if ( lang !== "en" && data[ lang ] !== undefined ) {
|
||||
var selected = data[ lang ];
|
||||
for ( key in selected ) {
|
||||
$( ".l10n-" + key ).text( selected[key] );
|
||||
|
11
src/h5ai/js/inc/jquery.mousewheel.min.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
|
||||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
||||
* 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.
|
||||
*
|
||||
* Version: 3.0.2
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
|
408
src/h5ai/js/inc/path.js
Normal file
@@ -0,0 +1,408 @@
|
||||
|
||||
|
||||
var PathCache = function () {
|
||||
|
||||
|
||||
var pathnameRegEx = /^(\/(.*\/)*)([^\/]+\/?)$/;
|
||||
|
||||
this.splitPathname = function ( pathname ) {
|
||||
|
||||
if ( pathname === "/" ) {
|
||||
return [ "", "/" ];
|
||||
};
|
||||
var match = pathnameRegEx.exec( pathname );
|
||||
return [ match[1], match[3] ];
|
||||
};
|
||||
|
||||
|
||||
this.cache = {};
|
||||
|
||||
|
||||
this.loadCache = function () {
|
||||
|
||||
var json = localStorage.getItem( "h5ai.cache" );
|
||||
var objs = $.evalJSON( json );
|
||||
var cache = {};
|
||||
for ( idx in objs ) {
|
||||
var obj = objs[idx];
|
||||
var path = this.objectToPath( obj );
|
||||
cache[path.absHref] = path;
|
||||
};
|
||||
return cache;
|
||||
};
|
||||
|
||||
|
||||
this.storeCache = function () {
|
||||
|
||||
var objs = [];
|
||||
for ( ref in this.cache ) {
|
||||
var path = this.cache[ref];
|
||||
if ( path.isFolder ) {
|
||||
objs.push( this.pathToObject( path ) );
|
||||
};
|
||||
};
|
||||
var json = $.toJSON( objs );
|
||||
localStorage.setItem( "h5ai.cache", json );
|
||||
};
|
||||
|
||||
|
||||
this.pathToObject = function ( path ) {
|
||||
|
||||
var object = {
|
||||
r: path.absHref,
|
||||
s: path.status,
|
||||
c: [],
|
||||
o: path.treeOpen
|
||||
};
|
||||
|
||||
if ( path.content !== undefined ) {
|
||||
for ( ref in path.content ) {
|
||||
object.c.push( ref );
|
||||
};
|
||||
};
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
|
||||
this.objectToPath = function ( obj ) {
|
||||
|
||||
var path = this.getPathForFolder( obj.r );
|
||||
path.status = obj.s;
|
||||
path.content = {};
|
||||
path.treeOpen = obj.o;
|
||||
for ( idx in obj.c ) {
|
||||
var href = obj.c[idx];
|
||||
path.content[href] = this.getPathForFolder( href );
|
||||
};
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
this.getPathForFolder = function ( folder ) {
|
||||
|
||||
return this.getCachedPath( new Path( this, folder ) );
|
||||
};
|
||||
|
||||
|
||||
this.getPathForTableRow = function ( parentFolder, tableRow ) {
|
||||
|
||||
return this.getCachedPath( new Path( this, parentFolder, tableRow ) );
|
||||
};
|
||||
|
||||
|
||||
this.getCachedPath = function ( path ) {
|
||||
|
||||
if ( path.isParentFolder ) {
|
||||
return path;
|
||||
};
|
||||
|
||||
var cachedPath = this.cache[path.absHref];
|
||||
if ( cachedPath !== undefined ) {
|
||||
return cachedPath;
|
||||
};
|
||||
|
||||
this.cache[path.absHref] = path;
|
||||
this.storeCache();
|
||||
return path;
|
||||
};
|
||||
|
||||
this.cache = this.loadCache();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
var Path = function ( pathCache, folder, tableRow ) {
|
||||
|
||||
if ( ! /\/$/.test( folder ) ) {
|
||||
folder += "/";
|
||||
};
|
||||
|
||||
if ( tableRow !== undefined ) {
|
||||
var $tds = $( tableRow ).find( "td" );
|
||||
var $img = $tds.eq( 0 ).find( "img" );
|
||||
var $a= $tds.eq( 1 ).find( "a" );
|
||||
|
||||
this.parentFolder = folder;
|
||||
this.icon16 = $img.attr( "src" );
|
||||
this.alt = $img.attr( "alt" );
|
||||
this.label = $a.text();
|
||||
this.href = $a.attr("href"); //decodeURI( $a.attr("href") );
|
||||
this.date = $tds.eq( 2 ).text();
|
||||
this.size = $tds.eq( 3 ).text();
|
||||
} else {
|
||||
var splits = pathCache.splitPathname( folder );
|
||||
|
||||
this.parentFolder = splits[0];
|
||||
this.href = splits[1];
|
||||
this.label = decodeURI( splits[1] );
|
||||
this.icon16 = "/h5ai/icons/16x16/folder.png";
|
||||
this.alt = "[DIR]";
|
||||
this.date = "";
|
||||
this.size = "";
|
||||
if ( this.label === "/" ) {
|
||||
this.label = decodeURI( document.domain ) + "/";
|
||||
};
|
||||
};
|
||||
|
||||
if ( /\/$/.test( this.label ) ) {
|
||||
this.label = this.label.slice( 0, -1 );
|
||||
};
|
||||
|
||||
this.icon48 = this.icon16.replace( "16x16", "48x48" );
|
||||
this.isFolder = ( this.alt === "[DIR]" );
|
||||
this.isParentFolder = ( this.isFolder && this.label === "Parent Directory" );
|
||||
this.absHref = this.isParentFolder ? this.href : this.parentFolder + this.href;
|
||||
this.isCurrentFolder = ( this.absHref === document.location.pathname );
|
||||
this.isDomain = ( this.absHref === "/" );
|
||||
|
||||
if ( this.isParentFolder && h5ai.config.setParentFolderLabels ) {
|
||||
if ( this.isDomain ) {
|
||||
this.label = decodeURI( document.domain );
|
||||
} else {
|
||||
this.label = decodeURI( pathCache.splitPathname( pathCache.splitPathname( this.parentFolder )[0] )[1].slice( 0, -1 ) );
|
||||
};
|
||||
};
|
||||
|
||||
this.status = undefined; // undefined, "h5ai" or HTTP response code
|
||||
this.content = undefined; // associative array path.absHref -> path
|
||||
this.html = {
|
||||
$crumb: undefined,
|
||||
$extended: undefined,
|
||||
$tree: undefined
|
||||
};
|
||||
this.treeOpen = false;
|
||||
|
||||
this.isEmpty = function() {
|
||||
|
||||
return this.content === undefined || $.isEmptyObject( this.content );
|
||||
};
|
||||
|
||||
|
||||
this.onClick = function ( context ) {
|
||||
|
||||
pathCache.storeCache();
|
||||
h5ai.triggerPathClick( this, context );
|
||||
};
|
||||
|
||||
|
||||
this.onHoverIn = function () {
|
||||
|
||||
if ( h5ai.config.linkHoverStates ) {
|
||||
for ( ref in this.html ) {
|
||||
$ref = this.html[ref];
|
||||
if ( $ref !== undefined ) {
|
||||
$ref.find( "> a" ).addClass( "hover" );
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.onHoverOut = function () {
|
||||
|
||||
if ( h5ai.config.linkHoverStates ) {
|
||||
for ( ref in this.html ) {
|
||||
$ref = this.html[ref];
|
||||
if ( $ref !== undefined ) {
|
||||
$ref.find( "> a" ).removeClass( "hover" );
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.updateHtml = function () {
|
||||
|
||||
this.updateCrumbHtml();
|
||||
this.updateExtendedHtml();
|
||||
this.updateTreeHtml();
|
||||
};
|
||||
|
||||
|
||||
this.updateCrumbHtml = function () {
|
||||
|
||||
var $html = $( "<li class='crumb' />" ).data( "path", this );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a><img src='/h5ai/images/crumb.png' alt='>' />" + this.label + "</a>" );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "crumb" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "crumb" ); }, this ), $.proxy( function() { this.onHoverOut( "crumb" ); }, this ) );
|
||||
$html.append( $a );
|
||||
|
||||
if ( this.isDomain ) {
|
||||
$html.addClass( "domain" );
|
||||
$a.find( "img" ).attr( "src", "/h5ai/images/home.png" );
|
||||
};
|
||||
|
||||
if ( this.isCurrentFolder ) {
|
||||
$html.addClass( "current" );
|
||||
};
|
||||
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$( "<img class='hint' src='/h5ai/images/page.png' alt='not listable' />" ).appendTo( $a );
|
||||
} else {
|
||||
$( "<span class='hint'>(" + this.status + ")</span>" ).appendTo( $a );
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$crumb !== undefined ) {
|
||||
this.html.$crumb.replaceWith( $html );
|
||||
};
|
||||
this.html.$crumb = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
|
||||
|
||||
this.updateExtendedHtml = function () {
|
||||
|
||||
var $html = $( "<li class='entry' />" ).data( "path", this );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a />" ).appendTo( $html );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "extended" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "extended" ); }, this ), $.proxy( function() { this.onHoverOut( "extended" ); }, this ) );
|
||||
|
||||
$( "<span class='icon small'><img src='" + this.icon16 + "' alt='" + this.alt + "' /></span>" ).appendTo( $a );
|
||||
$( "<span class='icon big'><img src='" + this.icon48 + "' alt='" + this.alt + "' /></span>" ).appendTo( $a );
|
||||
var $label = $( "<span class='label'>" + this.label + "</span>" ).appendTo( $a );
|
||||
$( "<span class='date'>" + this.date + "</span>" ).appendTo( $a );
|
||||
$( "<span class='size'>" + this.size + "</span>" ).appendTo( $a );
|
||||
|
||||
if ( this.isParentFolder ) {
|
||||
if ( !h5ai.config.setParentFolderLabels ) {
|
||||
$label.addClass( "l10n-parentDirectory" );
|
||||
};
|
||||
$html.addClass( "parentfolder" );
|
||||
};
|
||||
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$html.addClass( "page" );
|
||||
$a.find( ".icon.small img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.find( ".icon.big img" ).attr( "src", "/h5ai/icons/48x48/folder-page.png" );
|
||||
} else {
|
||||
$html.addClass( "error" );
|
||||
$label.append( $( "<span class='hint'> " + this.status + " </span>" ) );
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$extended !== undefined ) {
|
||||
this.html.$extended.replaceWith( $html );
|
||||
};
|
||||
this.html.$extended = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
|
||||
|
||||
this.updateTreeHtml = function () {
|
||||
|
||||
var $html = $( "<div class='entry' />" ).data( "path", this );
|
||||
var $blank = $( "<span class='blank' />" ).appendTo( $html );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a />" )
|
||||
.appendTo( $html )
|
||||
.append( $( "<span class='icon'><img src='" + this.icon16 + "' /></span>" ) )
|
||||
.append( $( "<span class='label'>" + this.label + "</span>" ) );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "tree" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "tree" ); }, this ), $.proxy( function() { this.onHoverOut( "tree" ); }, this ) );
|
||||
|
||||
if ( this.isFolder ) {
|
||||
// indicator
|
||||
if ( this.status === undefined || !this.isEmpty() ) {
|
||||
var $indicator = $( "<span class='indicator'><img src='/h5ai/images/tree.png' /></span>" );
|
||||
if ( this.status === undefined ) {
|
||||
$indicator.addClass( "unknown" );
|
||||
} else if ( this.treeOpen ) {
|
||||
$indicator.addClass( "open" );
|
||||
};
|
||||
$indicator.click( $.proxy( function( event ) {
|
||||
if ( $indicator.hasClass( "unknown" ) ) {
|
||||
tree.fetchStatusAndContent( this.absHref, false, $.proxy( function ( status, content ) {
|
||||
this.status = status;
|
||||
this.content = content;
|
||||
this.treeOpen = true;
|
||||
this.updateTreeHtml( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
}, this ) );
|
||||
} else if ( $indicator.hasClass( "open" ) ) {
|
||||
this.treeOpen = false;
|
||||
$indicator.removeClass( "open" );
|
||||
$html.find( "> ul.content" ).slideUp( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
} else {
|
||||
this.treeOpen = true;
|
||||
$indicator.addClass( "open" );
|
||||
$html.find( "> ul.content" ).slideDown( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
};
|
||||
}, this ) );
|
||||
$blank.replaceWith( $indicator );
|
||||
};
|
||||
|
||||
// is this the domain?
|
||||
if ( this.isDomain ) {
|
||||
$html.addClass( "domain" );
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-home.png" );
|
||||
};
|
||||
|
||||
// is this the current folder?
|
||||
if ( this.isCurrentFolder ) {
|
||||
$html.addClass( "current" );
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-open.png" );
|
||||
};
|
||||
|
||||
// does it have subfolders?
|
||||
if ( !this.isEmpty() ) {
|
||||
var $ul = $( "<ul class='content' />" ).appendTo( $html );
|
||||
for ( idx in this.content ) {
|
||||
$( "<li />" ).append( this.content[idx].updateTreeHtml() ).appendTo( $ul );
|
||||
};
|
||||
if ( this.status === undefined || !this.treeOpen ) {
|
||||
$ul.hide();
|
||||
};
|
||||
};
|
||||
|
||||
// reflect folder status
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.append( $( "<span class='hint'><img src='/h5ai/images/page.png' /></span>" ) );
|
||||
} else {
|
||||
$html.addClass( "error" );
|
||||
$a.append( $( "<span class='hint'>" + this.status + "</span>" ) );
|
||||
};
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$tree !== undefined ) {
|
||||
this.html.$tree.replaceWith( $html );
|
||||
};
|
||||
this.html.$tree = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
};
|
@@ -1,164 +1,110 @@
|
||||
|
||||
var Tree = function ( utils, h5ai ) {
|
||||
var Tree = function ( pathCache, h5ai ) {
|
||||
|
||||
var thistree = this;
|
||||
var THIS = this;
|
||||
var contentTypeRegEx = /^text\/html;h5ai=/;
|
||||
|
||||
this.init = function () {
|
||||
|
||||
if ( h5ai.config.showTree ) {
|
||||
this.checkCrumb();
|
||||
this.checkCurrentFolder();
|
||||
this.initShifting();
|
||||
this.updatePaths();
|
||||
this.populateTree();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.checkCrumb = function () {
|
||||
this.updatePath = function ( path ) {
|
||||
|
||||
$( "li.crumb a" ).each( function() {
|
||||
|
||||
var $a = $( this );
|
||||
var pathname = $a.attr( "href" );
|
||||
thistree.checkPathname( pathname, function ( status ) {
|
||||
if ( status !== 0 ) {
|
||||
$( "<img class='hint' src='/h5ai/images/page.png' alt='not listable' />" ).appendTo( $a );
|
||||
if ( status !== 200 ) {
|
||||
$( "<span class='hint'>(" + status + ")</span>" ).appendTo( $a );
|
||||
};
|
||||
if ( path.isFolder && !path.isParentFolder && path.status === undefined ) {
|
||||
this.fetchStatus( path.absHref, function ( status ) {
|
||||
if ( status !== "h5ai" ) {
|
||||
path.status = status;
|
||||
};
|
||||
path.updateHtml();
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.checkCurrentFolder = function () {
|
||||
|
||||
$( "#extended li.entry.folder" ).each( function() {
|
||||
|
||||
var $entry = $( this );
|
||||
if ( $entry.hasClass( "parentfolder" ) ) {
|
||||
return;
|
||||
};
|
||||
|
||||
var $a = $entry.find( "a" );
|
||||
var pathname = decodeURI( document.location.pathname ) + $a.attr( "href" );
|
||||
thistree.checkPathname( pathname, function ( status ) {
|
||||
if ( status === 200 ) {
|
||||
$a.find( ".icon.small img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.find( ".icon.big img" ).attr( "src", "/h5ai/icons/48x48/folder-page.png" );
|
||||
} else if ( status !== 0 ) {
|
||||
$entry.addClass( "notListable" );
|
||||
$a.find( ".label" )
|
||||
.append( " " )
|
||||
.append( $( "<span class='error'>" + status + "</span>" ) );
|
||||
};
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.shiftTree = function ( show ) {
|
||||
|
||||
var $tree = $( "#tree" );
|
||||
var $extended = $( "#extended" );
|
||||
var show = show || false;
|
||||
|
||||
if ( $tree.outerWidth() < $extended.offset().left || show ) {
|
||||
$tree.stop().animate( { left: 0 } );
|
||||
} else {
|
||||
$tree.stop().animate( { left: 24 - $tree.outerWidth() } );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.initShifting = function () {
|
||||
|
||||
$( "#tree" ).hover(
|
||||
function () {
|
||||
thistree.shiftTree( true );
|
||||
},
|
||||
function () {
|
||||
thistree.shiftTree();
|
||||
}
|
||||
);
|
||||
$( window ).resize( function() {
|
||||
thistree.shiftTree();
|
||||
} );
|
||||
|
||||
this.updatePaths = function () {
|
||||
|
||||
for ( var ref in pathCache.cache ) {
|
||||
this.updatePath( pathCache.cache[ref] );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.populateTree = function () {
|
||||
|
||||
var $tree = $( "#tree" );
|
||||
$tree.css( { left: -400 } ).show();
|
||||
|
||||
this.shiftTree();
|
||||
|
||||
this.fetchTree( decodeURI( document.location.pathname ), function( entry ) {
|
||||
$tree.empty().append( entry.toHtml() );
|
||||
thistree.shiftTree();
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.fetchTree = function ( pathname, callback ) {
|
||||
|
||||
this.walkBack( pathname, function( walkbackedPathname ) {
|
||||
var entry = new File( utils, walkbackedPathname );
|
||||
thistree.fetchEntriesRecursive( walkbackedPathname, function ( content ) {
|
||||
entry.content = content;
|
||||
callback( entry );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.walkBack = function ( pathname, callback ) {
|
||||
|
||||
var splits = utils.splitPathname( pathname );
|
||||
var parent = splits[0];
|
||||
if ( parent === "" ) {
|
||||
callback( pathname );
|
||||
} else {
|
||||
this.checkPathname( parent, function( state ) {
|
||||
if ( state === 0 ) {
|
||||
thistree.walkBack( parent, callback );
|
||||
var $extended = $( "#extended" );
|
||||
var shiftTree = function ( forceVisible, dontAnimate ) {
|
||||
if ( $tree.outerWidth() < $extended.offset().left || forceVisible === true ) {
|
||||
if ( dontAnimate === true ) {
|
||||
$tree.stop().css( { left: 0 } );
|
||||
} else {
|
||||
callback( pathname );
|
||||
$tree.stop().animate( { left: 0 } );
|
||||
};
|
||||
} );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.fetchEntriesRecursive = function ( pathname, callback ) {
|
||||
|
||||
this.fetchEntries( pathname, false, function ( entries ) {
|
||||
if ( entries instanceof Array ) {
|
||||
for ( idx in entries ) {
|
||||
( function ( entry ) {
|
||||
if ( entry.isFolder ) {
|
||||
thistree.fetchEntriesRecursive( entry.absHref, function( content ) {
|
||||
entry.content = content;
|
||||
callback( entries );
|
||||
} );
|
||||
};
|
||||
} ) ( entries[idx] );
|
||||
} else {
|
||||
if ( dontAnimate === true ) {
|
||||
$tree.stop().css( { left: 18 - $tree.outerWidth() } );
|
||||
} else {
|
||||
$tree.stop().animate( { left: 18 - $tree.outerWidth() } );
|
||||
};
|
||||
};
|
||||
callback( entries );
|
||||
};
|
||||
|
||||
$tree.hover( function () { shiftTree( true ); }, function () { shiftTree(); } );
|
||||
$( window ).resize( function() {
|
||||
shiftTree();
|
||||
} );
|
||||
|
||||
this.fetchTree( document.location.pathname, function( path ) {
|
||||
$tree.append( path.updateTreeHtml() );
|
||||
$tree.show();
|
||||
scrollpanel( $tree );
|
||||
shiftTree( false, true );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.fetchEntries = function ( pathname, includeParent, callback ) {
|
||||
this.fetchTree = function ( pathname, callback, childPath ) {
|
||||
|
||||
this.checkPathname( pathname, function ( status ) {
|
||||
console.log( "checkPathname", pathname, status );
|
||||
if ( status !== 0 ) {
|
||||
callback( status );
|
||||
this.fetchPath( pathname, $.proxy( function ( path ) {
|
||||
|
||||
path.treeOpen = true;
|
||||
|
||||
if ( childPath !== undefined ) {
|
||||
path.content[ childPath.absHref ] = childPath;
|
||||
};
|
||||
|
||||
var parent = pathCache.splitPathname( pathname )[0];
|
||||
if ( parent === "" ) {
|
||||
callback( path );
|
||||
} else {
|
||||
this.fetchTree( parent, callback, path );
|
||||
};
|
||||
}, this ) );
|
||||
};
|
||||
|
||||
|
||||
this.fetchPath = function ( pathname, callback ) {
|
||||
|
||||
this.fetchStatusAndContent( pathname, false, function ( status, content ) {
|
||||
var path = pathCache.getPathForFolder( pathname );
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
callback( path );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
this.fetchStatusAndContent = function ( pathname, includeParent, callback ) {
|
||||
|
||||
this.fetchStatus( pathname, function ( status ) {
|
||||
|
||||
if ( status !== "h5ai" ) {
|
||||
callback( status, {} );
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -167,53 +113,168 @@ var Tree = function ( utils, h5ai ) {
|
||||
type: "GET",
|
||||
dataType: "html",
|
||||
error: function ( xhr ) {
|
||||
callback( xhr.status ); // since it was checked before this should never happen
|
||||
callback( xhr.status, {} ); // since it was checked before this should never happen
|
||||
},
|
||||
success: function ( html, status, xhr ) {
|
||||
if ( !contentTypeRegEx.test( xhr.getResponseHeader( "Content-Type" ) ) ) {
|
||||
callback( xhr.status ); // since it was checked before this should never happen
|
||||
callback( xhr.status, {} ); // since it was checked before this should never happen
|
||||
return;
|
||||
};
|
||||
|
||||
var entries = [];
|
||||
$( html ).find( "#table table td" ).closest( "tr" ).each( function () {
|
||||
var entry = new File( utils, pathname, this );
|
||||
if ( !entry.isParentFolder || includeParent ) {
|
||||
entries.push( entry );
|
||||
var content = {};
|
||||
$( html ).find( "#table td" ).closest( "tr" ).each( function () {
|
||||
var path = pathCache.getPathForTableRow( pathname, this );
|
||||
if ( path.isFolder && ( !path.isParentFolder || includeParent ) ) {
|
||||
content[path.absHref] = path;
|
||||
THIS.updatePath( path );
|
||||
};
|
||||
} );
|
||||
callback( entries );
|
||||
callback( "h5ai", content );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
var pathnameCache = {};
|
||||
|
||||
this.checkPathname = function ( pathname, callback ) {
|
||||
var pathnameStatusCache = {};
|
||||
|
||||
this.fetchStatus = function ( pathname, callback ) {
|
||||
|
||||
if ( h5ai.config.folderStatus[ pathname ] !== undefined ) {
|
||||
callback( h5ai.config.folderStatus[ pathname ] );
|
||||
return;
|
||||
};
|
||||
|
||||
if ( pathnameCache[ pathname ] !== undefined ) {
|
||||
callback( pathnameCache[ pathname ] );
|
||||
} else if ( pathnameStatusCache[ pathname ] !== undefined ) {
|
||||
callback( pathnameStatusCache[ pathname ] );
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
$.ajax( {
|
||||
url: pathname,
|
||||
type: "HEAD",
|
||||
complete: function ( xhr ) {
|
||||
var status = xhr.status;
|
||||
if ( xhr.status === 200 && contentTypeRegEx.test( xhr.getResponseHeader( "Content-Type" ) ) ) {
|
||||
status = 0;
|
||||
if ( status === 200 && contentTypeRegEx.test( xhr.getResponseHeader( "Content-Type" ) ) ) {
|
||||
status = "h5ai";
|
||||
};
|
||||
pathnameCache[ pathname ] = status;
|
||||
pathnameStatusCache[ pathname ] = status;
|
||||
callback( status );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
var scrollpanel = function ( htmlElement ) {
|
||||
|
||||
var $element = $( htmlElement );
|
||||
|
||||
if ( $element.css( "position" ) === undefined || $element.css( "position" ) === "static" ) {
|
||||
$element.css( "position", "relative" );
|
||||
};
|
||||
|
||||
var $scrollbar = $( "<div class='scrollbar' />" );
|
||||
var $drag = $( "<div class='drag' />" ).appendTo( $scrollbar );
|
||||
$element
|
||||
.wrapInner( "<div class='wrapper'><div class='content' /></div>" )
|
||||
.append( $scrollbar );
|
||||
var $wrapper = $element.find( "> .wrapper" );
|
||||
var $content = $wrapper.find( "> .content" );
|
||||
var mouseOffsetY = 0;
|
||||
|
||||
var update = function () {
|
||||
$wrapper.css( "height", $element.height() );
|
||||
var visibleHeight = $element.height();
|
||||
var contentHeight = $content.outerHeight();
|
||||
var scrollTop = $wrapper.scrollTop();
|
||||
var scrollTopFrac = scrollTop / contentHeight;
|
||||
var visVertFrac = Math.min( visibleHeight / contentHeight, 1 );
|
||||
|
||||
if ( visVertFrac < 1 ) {
|
||||
$wrapper.css( "padding-right", $scrollbar.outerWidth( true ) );
|
||||
$scrollbar
|
||||
.show()
|
||||
.css( {
|
||||
height: $element.innerHeight() + $scrollbar.height() - $scrollbar.outerHeight( true )
|
||||
} );
|
||||
$drag
|
||||
.css( {
|
||||
top: $scrollbar.height() * scrollTopFrac,
|
||||
height: $scrollbar.height() * visVertFrac
|
||||
} );
|
||||
} else {
|
||||
$wrapper.css( "padding-right", 0 );
|
||||
$scrollbar.hide()
|
||||
};
|
||||
};
|
||||
var scroll = function ( event ) {
|
||||
var clickFrac = ( event.pageY - $scrollbar.offset().top - mouseOffsetY ) / $scrollbar.height();
|
||||
$wrapper.scrollTop( $content.outerHeight() * clickFrac );
|
||||
update();
|
||||
};
|
||||
|
||||
$element
|
||||
.mousewheel( function ( event, delta) {
|
||||
$wrapper.scrollTop( $wrapper.scrollTop() - 50 * delta );
|
||||
update();
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
} )
|
||||
.scroll( update );
|
||||
$element.get( 0 ).updateScrollbar = update;
|
||||
$wrapper
|
||||
.css( {
|
||||
height: $element.height(),
|
||||
overflow: "hidden"
|
||||
} );
|
||||
$scrollbar
|
||||
.css( {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
right: 0,
|
||||
overflow: "hidden"
|
||||
} )
|
||||
.mousedown( function ( event ) {
|
||||
mouseOffsetY = $drag.outerHeight() / 2;
|
||||
scroll( event );
|
||||
$scrollbar.addClass( "dragOn" );
|
||||
$( window )
|
||||
.bind( "mousemove", scroll )
|
||||
.one( "mouseup", function ( event ) {
|
||||
$scrollbar.removeClass( "dragOn" );
|
||||
$( window ).unbind( "mousemove", scroll );
|
||||
scroll( event );
|
||||
event.stopPropagation();
|
||||
} );
|
||||
event.stopPropagation();
|
||||
} )
|
||||
.attr( "unselectable", "on" )
|
||||
.css( "-moz-user-select", "none" )
|
||||
.each( function () {
|
||||
this.onselectstart = function () {
|
||||
return false;
|
||||
};
|
||||
} );
|
||||
$drag
|
||||
.css( {
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
width: "100%"
|
||||
} )
|
||||
.mousedown( function ( event ) {
|
||||
mouseOffsetY = event.pageY - $drag.offset().top;
|
||||
scroll( event );
|
||||
$scrollbar.addClass( "dragOn" );
|
||||
$( window )
|
||||
.bind( "mousemove", scroll )
|
||||
.one( "mouseup", function ( event ) {
|
||||
$scrollbar.removeClass( "dragOn" );
|
||||
$( window ).unbind( "mousemove", scroll );
|
||||
scroll( event );
|
||||
event.stopPropagation();
|
||||
} );
|
||||
event.stopPropagation();
|
||||
} );
|
||||
|
||||
update();
|
||||
};
|
||||
|
||||
};
|
||||
|
@@ -1,15 +0,0 @@
|
||||
|
||||
var Utils = function () {
|
||||
|
||||
var pathnameRegEx = /^(\/(.*\/)*)([^\/]+\/?)$/;
|
||||
|
||||
this.splitPathname = function ( pathname ) {
|
||||
|
||||
if ( pathname === "/" ) {
|
||||
return [ "", "/" ];
|
||||
};
|
||||
var match = pathnameRegEx.exec( pathname );
|
||||
return [ match[1], match[3] ];
|
||||
};
|
||||
|
||||
};
|
@@ -1,8 +1,9 @@
|
||||
( function( $ ) {
|
||||
|
||||
// @include "inc/utils.js"
|
||||
// @include "inc/jquery.json.min.js"
|
||||
// @include "inc/jquery.mousewheel.min.js"
|
||||
// @include "inc/path.js"
|
||||
// @include "inc/h5ai.js"
|
||||
// @include "inc/file.js"
|
||||
// @include "inc/tree.js"
|
||||
|
||||
|
||||
@@ -10,9 +11,9 @@
|
||||
* create
|
||||
*******************************/
|
||||
|
||||
var utils = new Utils();
|
||||
var h5ai = new H5ai( h5aiOptions );
|
||||
var tree = new Tree( utils, h5ai );
|
||||
var pathCache = new PathCache();
|
||||
var h5ai = new H5ai( h5aiOptions, h5aiLangs, pathCache );
|
||||
var tree = new Tree( pathCache, h5ai );
|
||||
|
||||
|
||||
/*******************************
|
||||
@@ -20,11 +21,9 @@
|
||||
*******************************/
|
||||
|
||||
$.h5ai = {
|
||||
folderClick: h5ai.folderClick,
|
||||
fileClick: h5ai.fileClick
|
||||
click: $.proxy( h5ai.pathClick, h5ai )
|
||||
};
|
||||
|
||||
|
||||
/*******************************
|
||||
* init after dom load
|
||||
*******************************/
|
||||
@@ -32,6 +31,13 @@
|
||||
$( function() {
|
||||
h5ai.init();
|
||||
tree.init();
|
||||
} );
|
||||
|
||||
// just for testing, resets the local cache /////////
|
||||
$( ".l10n-footerUsing" ).click( function () {
|
||||
pathCache.cache = {};
|
||||
pathCache.storeCache();
|
||||
} );
|
||||
/////////////////////////////////////////////////////
|
||||
} );
|
||||
|
||||
} )( jQuery );
|
@@ -1,3 +1,7 @@
|
||||
/*
|
||||
* h5ai %BUILD_VERSION%
|
||||
* Options and localization
|
||||
*/
|
||||
|
||||
h5aiOptions = {
|
||||
|
||||
@@ -18,7 +22,7 @@ h5aiOptions = {
|
||||
* folderStatus below to avoid such requests.
|
||||
* It might also affect performance significantly.
|
||||
*/
|
||||
showTree: false,
|
||||
showTree: true,
|
||||
|
||||
/*
|
||||
* Associative array of folders and their HTTP status codes to
|
||||
@@ -47,7 +51,17 @@ h5aiOptions = {
|
||||
/*
|
||||
* Try to use browser language, falls back to previous specified lang.
|
||||
*/
|
||||
useBrowserLang: true
|
||||
useBrowserLang: true,
|
||||
|
||||
/*
|
||||
* Set parent folder labels to real folder names.
|
||||
*/
|
||||
setParentFolderLabels: true,
|
||||
|
||||
/*
|
||||
* Link the hover effects between crumb, extended view and tree.
|
||||
*/
|
||||
linkHoverStates: true
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +80,8 @@ h5aiLangs = {
|
||||
columnLastModified: "Last modified",
|
||||
columnSize: "Size",
|
||||
footerUsing: "using",
|
||||
parentDirectory: "Parent Directory"
|
||||
parentDirectory: "Parent Directory",
|
||||
empty: "empty"
|
||||
},
|
||||
|
||||
"de": {
|
||||
@@ -76,7 +91,63 @@ h5aiLangs = {
|
||||
columnLastModified: "Geändert",
|
||||
columnSize: "Größe",
|
||||
footerUsing: "nutzt",
|
||||
parentDirectory: "Übergeordnetes Verzeichnis"
|
||||
}
|
||||
parentDirectory: "Übergeordnetes Verzeichnis",
|
||||
empty: "leer"
|
||||
},
|
||||
|
||||
"fr": {
|
||||
viewDetails: "détails",
|
||||
viewIcons: "icônes",
|
||||
columnName: "Nom",
|
||||
columnLastModified: "Dernière modification",
|
||||
columnSize: "Taille",
|
||||
footerUsing: "utilise",
|
||||
parentDirectory: "Dossier parent",
|
||||
empty: "vide"
|
||||
},
|
||||
|
||||
"nl": {
|
||||
viewDetails: "details",
|
||||
viewIcons: "iconen",
|
||||
columnName: "Naam",
|
||||
columnLastModified: "Laatste wijziging",
|
||||
columnSize: "Grootte",
|
||||
footerUsing: "gebruikt",
|
||||
parentDirectory: "Bovenliggende map",
|
||||
empty: "lege"
|
||||
},
|
||||
|
||||
"sv": {
|
||||
viewDetails: "detaljerad",
|
||||
viewIcons: "ikoner",
|
||||
columnName: "Filnamn",
|
||||
columnLastModified: "Senast ändrad",
|
||||
columnSize: "Filstorlek",
|
||||
footerUsing: "använder",
|
||||
parentDirectory: "Till överordnad mapp",
|
||||
empty: "tom"
|
||||
},
|
||||
|
||||
"cs": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Název",
|
||||
columnLastModified: "Upraveno",
|
||||
columnSize: "Velikost",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadřazený adresář",
|
||||
empty: "prázdný"
|
||||
},
|
||||
|
||||
"sk": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Názov",
|
||||
columnLastModified: "Upravené",
|
||||
columnSize: "Velkosť",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadriadený priečinok",
|
||||
empty: "prázdny"
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
################################
|
||||
# h5ai 0.6
|
||||
# h5ai 0.10.1
|
||||
# customized .htaccess
|
||||
################################
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# Options +FollowSymLinks
|
||||
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
<IfModule headers_module>
|
||||
|
||||
################################
|
||||
# cache images for 52 weeks
|
||||
@@ -25,7 +25,13 @@
|
||||
# style auto index
|
||||
################################
|
||||
|
||||
<IfModule mod_autoindex.c>
|
||||
################################
|
||||
# IMPORTANT FOR XAMPP
|
||||
# if you're running XAMPP you might need to replace the
|
||||
# following line with
|
||||
# <IfModule autoindex_color_module>
|
||||
################################
|
||||
<IfModule autoindex_module>
|
||||
|
||||
################################
|
||||
# uncomment the following line to force directory listing
|
||||
@@ -56,7 +62,7 @@
|
||||
|
||||
IndexOrderDefault Ascending Name
|
||||
|
||||
IndexOptions Type=text/html;h5ai=0.6
|
||||
IndexOptions Type=text/html;h5ai=0.10.1
|
||||
IndexOptions Charset=UTF-8
|
||||
IndexOptions FancyIndexing
|
||||
IndexOptions HTMLTable
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<img class="techclass" src="/h5ai/images/html5-storage.png" alt="html5-storage" />
|
||||
<img class="techclass" src="/h5ai/images/html5-css3.png" alt="html5-css3" />
|
||||
</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai 0.6">h5ai</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai 0.10.1</a>
|
||||
<span class="l10n-footerUsing">using</span>
|
||||
<a href="http://tiheum.deviantart.com/art/Faenza-Icons-173323228" target="_blank" title="icon theme for Gnome">Faenza icons</a>
|
||||
</footer>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Directory index · styled with h5ai</title>
|
||||
<meta name="h5ai-version" content="h5ai 0.6">
|
||||
<meta name="h5ai-version" content="h5ai 0.10.1">
|
||||
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
|
||||
<meta name="keywords" content="directory, index, autoindex, h5ai">
|
||||
<link rel="shortcut icon" type="image/png" href="/h5ai/images/h5ai-16x16.png">
|
||||
@@ -13,12 +13,9 @@
|
||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<nav class="clearfix">
|
||||
<span class="jsDisabledFallback">Directory index · JavaScript is disabled</span>
|
||||
<ul>
|
||||
<li id="domain" class="crumb">
|
||||
<a href="/"><img src="/h5ai/images/home.png" alt="domain" /><span>domain</span></a>
|
||||
</li>
|
||||
<li id="viewicons" class="view">
|
||||
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-viewIcons">icons</span></a>
|
||||
</li>
|
||||
@@ -26,7 +23,6 @@
|
||||
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-viewDetails">details</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</nav>
|
||||
<section id="content">
|
||||
<header></header>
|
||||
|
BIN
target/h5ai/icons/16x16/folder-home.png
Normal file
After Width: | Height: | Size: 637 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 236 B |
BIN
target/h5ai/icons/48x48/folder-home.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
target/h5ai/images/blank.png
Normal file
After Width: | Height: | Size: 227 B |
BIN
target/h5ai/images/tree.png
Normal file
After Width: | Height: | Size: 458 B |
@@ -1,3 +1,7 @@
|
||||
/*
|
||||
* h5ai 0.10.1
|
||||
* Options and localization
|
||||
*/
|
||||
|
||||
h5aiOptions = {
|
||||
|
||||
@@ -18,7 +22,7 @@ h5aiOptions = {
|
||||
* folderStatus below to avoid such requests.
|
||||
* It might also affect performance significantly.
|
||||
*/
|
||||
showTree: false,
|
||||
showTree: true,
|
||||
|
||||
/*
|
||||
* Associative array of folders and their HTTP status codes to
|
||||
@@ -47,7 +51,17 @@ h5aiOptions = {
|
||||
/*
|
||||
* Try to use browser language, falls back to previous specified lang.
|
||||
*/
|
||||
useBrowserLang: true
|
||||
useBrowserLang: true,
|
||||
|
||||
/*
|
||||
* Set parent folder labels to real folder names.
|
||||
*/
|
||||
setParentFolderLabels: true,
|
||||
|
||||
/*
|
||||
* Link the hover effects between crumb, extended view and tree.
|
||||
*/
|
||||
linkHoverStates: true
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +80,8 @@ h5aiLangs = {
|
||||
columnLastModified: "Last modified",
|
||||
columnSize: "Size",
|
||||
footerUsing: "using",
|
||||
parentDirectory: "Parent Directory"
|
||||
parentDirectory: "Parent Directory",
|
||||
empty: "empty"
|
||||
},
|
||||
|
||||
"de": {
|
||||
@@ -76,7 +91,63 @@ h5aiLangs = {
|
||||
columnLastModified: "Geändert",
|
||||
columnSize: "Größe",
|
||||
footerUsing: "nutzt",
|
||||
parentDirectory: "Übergeordnetes Verzeichnis"
|
||||
}
|
||||
parentDirectory: "Übergeordnetes Verzeichnis",
|
||||
empty: "leer"
|
||||
},
|
||||
|
||||
"fr": {
|
||||
viewDetails: "détails",
|
||||
viewIcons: "icônes",
|
||||
columnName: "Nom",
|
||||
columnLastModified: "Dernière modification",
|
||||
columnSize: "Taille",
|
||||
footerUsing: "utilise",
|
||||
parentDirectory: "Dossier parent",
|
||||
empty: "vide"
|
||||
},
|
||||
|
||||
"nl": {
|
||||
viewDetails: "details",
|
||||
viewIcons: "iconen",
|
||||
columnName: "Naam",
|
||||
columnLastModified: "Laatste wijziging",
|
||||
columnSize: "Grootte",
|
||||
footerUsing: "gebruikt",
|
||||
parentDirectory: "Bovenliggende map",
|
||||
empty: "lege"
|
||||
},
|
||||
|
||||
"sv": {
|
||||
viewDetails: "detaljerad",
|
||||
viewIcons: "ikoner",
|
||||
columnName: "Filnamn",
|
||||
columnLastModified: "Senast ändrad",
|
||||
columnSize: "Filstorlek",
|
||||
footerUsing: "använder",
|
||||
parentDirectory: "Till överordnad mapp",
|
||||
empty: "tom"
|
||||
},
|
||||
|
||||
"cs": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Název",
|
||||
columnLastModified: "Upraveno",
|
||||
columnSize: "Velikost",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadřazený adresář",
|
||||
empty: "prázdný"
|
||||
},
|
||||
|
||||
"sk": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Názov",
|
||||
columnLastModified: "Upravené",
|
||||
columnSize: "Velkosť",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadriadený priečinok",
|
||||
empty: "prázdny"
|
||||
}
|
||||
|
||||
};
|
||||
|