Added PHP implementation. For a full list of changes see README.md.
44
README.md
|
@ -9,17 +9,31 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
#### v0.12.3 · *2011-07-30*
|
### v0.13 · *2011-08-06*
|
||||||
|
|
||||||
* added tr translation by [Batuhan Icoz](http://github.com/batuhanicoz/h5ai)
|
* added PHP implementation! (should work with PHP 5.2+)
|
||||||
|
* added new options
|
||||||
|
* changed layout of the bottom bar to display status information
|
||||||
|
* added language selector to the bottom bar
|
||||||
|
* quoted keys in `options.js` to make it valid json
|
||||||
|
* changed value of option `lang` from `undefined` to `null`
|
||||||
|
* added some new keys to `h5aiLangs`
|
||||||
|
* added browser caching rules for css and js
|
||||||
|
* added pt translation by [Jonnathan](http://github.com/jonnsl)
|
||||||
|
* added bg translation by George Andonov
|
||||||
|
|
||||||
|
|
||||||
#### v0.12.2 · *2011-07-30*
|
### v0.12.3 · *2011-07-30*
|
||||||
|
|
||||||
|
* added tr translation by [Batuhan Icoz](http://github.com/batuhanicoz)
|
||||||
|
|
||||||
|
|
||||||
|
### v0.12.2 · *2011-07-30*
|
||||||
|
|
||||||
* added es translation by Jose David Calderon Serrano
|
* added es translation by Jose David Calderon Serrano
|
||||||
|
|
||||||
|
|
||||||
#### v0.12.1 · *2011-07-29*
|
### v0.12.1 · *2011-07-29*
|
||||||
|
|
||||||
* fixed unchecked use of console.log
|
* fixed unchecked use of console.log
|
||||||
|
|
||||||
|
@ -34,12 +48,12 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
* changed license to MIT license, see `LICENSE.txt`
|
* changed license to MIT license, see `LICENSE.txt`
|
||||||
|
|
||||||
|
|
||||||
#### v0.10.2 · *2011-07-26*
|
### v0.10.2 · *2011-07-26*
|
||||||
|
|
||||||
* improved tree scrollbar
|
* improved tree scrollbar
|
||||||
|
|
||||||
|
|
||||||
#### v0.10.1 · *2011-07-24*
|
### v0.10.1 · *2011-07-24*
|
||||||
|
|
||||||
* fixed problems with ' in links
|
* fixed problems with ' in links
|
||||||
|
|
||||||
|
@ -85,7 +99,7 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
* added localization, see `options.js`
|
* added localization, see `options.js`
|
||||||
|
|
||||||
|
|
||||||
#### v0.5.3 · *2011-07-04*
|
### v0.5.3 · *2011-07-04*
|
||||||
|
|
||||||
* refactored js
|
* refactored js
|
||||||
* added basic options support via `options.js`
|
* added basic options support via `options.js`
|
||||||
|
@ -93,13 +107,13 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
* optional tree sidebar
|
* optional tree sidebar
|
||||||
|
|
||||||
|
|
||||||
#### v0.5.2 · *2011-07-02*
|
### v0.5.2 · *2011-07-02*
|
||||||
|
|
||||||
* details view adjusts to window width
|
* details view adjusts to window width
|
||||||
* linked icon for *.gz and *.bz2
|
* linked icon for *.gz and *.bz2
|
||||||
|
|
||||||
|
|
||||||
#### v0.5.1 · *2011-07-01*
|
### v0.5.1 · *2011-07-01*
|
||||||
|
|
||||||
* disabled tree sidebar for now, since it had unwanted side effects
|
* disabled tree sidebar for now, since it had unwanted side effects
|
||||||
|
|
||||||
|
@ -119,13 +133,13 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
* updated dot.access
|
* updated dot.access
|
||||||
|
|
||||||
|
|
||||||
#### v0.3.2 · *2011-06-24*
|
### v0.3.2 · *2011-06-24*
|
||||||
|
|
||||||
* removed lib versions from file names
|
* removed lib versions from file names
|
||||||
* added 'empty' indicator for icons view
|
* added 'empty' indicator for icons view
|
||||||
|
|
||||||
|
|
||||||
#### v0.3.1 · *2011-06-24*
|
### v0.3.1 · *2011-06-24*
|
||||||
|
|
||||||
* refactored js
|
* refactored js
|
||||||
* added `folderClick` and `fileClick` callback hooks
|
* added `folderClick` and `fileClick` callback hooks
|
||||||
|
@ -140,20 +154,20 @@ It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-1733
|
||||||
* updated jQuery to version 1.6.1
|
* updated jQuery to version 1.6.1
|
||||||
|
|
||||||
|
|
||||||
#### v0.2.3 · *2011-06-17*
|
### v0.2.3 · *2011-06-17*
|
||||||
|
|
||||||
* more refactoring in main.js
|
* more refactoring in main.js
|
||||||
* ~~added custom js support, and global includes~~ *removed, only custom top and bottom sections supported*
|
* ~~added custom js support, and global includes~~ *removed, only custom top and bottom sections supported*
|
||||||
|
|
||||||
|
|
||||||
#### v0.2.2 · *2011-06-16*
|
### v0.2.2 · *2011-06-16*
|
||||||
|
|
||||||
* refactored a lot, added some comments
|
* refactored a lot, added some comments
|
||||||
* included fixes from [NumEricR](http://github.com/NumEricR/h5ai)
|
* included fixes from [NumEricR](http://github.com/NumEricR)
|
||||||
* added top/bottom message support, only basicly styled
|
* added top/bottom message support, only basicly styled
|
||||||
|
|
||||||
|
|
||||||
#### v0.2.1 · *2011-06-16*
|
### v0.2.1 · *2011-06-16*
|
||||||
|
|
||||||
* fixed croped filenames
|
* fixed croped filenames
|
||||||
* fixed missing .png extension in header
|
* fixed missing .png extension in header
|
||||||
|
|
|
@ -3,7 +3,7 @@ custom = true
|
||||||
|
|
||||||
# project
|
# project
|
||||||
project.name = h5ai
|
project.name = h5ai
|
||||||
project.version = 0.12.3
|
project.version = 0.13
|
||||||
|
|
||||||
|
|
||||||
# src
|
# src
|
||||||
|
|
BIN
release/h5ai-0.13.tar.gz
Normal file
16
src/h5ai/.htaccess
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
AddType text/html .php
|
||||||
|
|
||||||
|
# cache images, css and js for 52 weeks
|
||||||
|
<IfModule headers_module>
|
||||||
|
<FilesMatch "\.png$">
|
||||||
|
Header set Cache-Control "max-age=31449600, public"
|
||||||
|
</FilesMatch>
|
||||||
|
<FilesMatch "\.css$">
|
||||||
|
Header set Cache-Control "max-age=31449600, public"
|
||||||
|
</FilesMatch>
|
||||||
|
<FilesMatch "\.js$">
|
||||||
|
Header set Cache-Control "max-age=31449600, public"
|
||||||
|
</FilesMatch>
|
||||||
|
</IfModule>
|
||||||
|
|
7
src/h5ai/cache/readme.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Cache
|
||||||
|
|
||||||
|
This directory is used for server side caching. To use caching make this
|
||||||
|
directory writable for Apache.
|
||||||
|
|
||||||
|
There is no critical data in here. You can savely remove any content. This
|
||||||
|
will clear the cache.
|
|
@ -64,6 +64,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.folder-parent {
|
||||||
|
.date, .size {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.folder {
|
||||||
|
.size {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.icon, .label, .date, .size {
|
.icon, .label, .date, .size {
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
|
||||||
@import "inc/html5reset";
|
@import "html5reset";
|
||||||
@import "inc/mixins";
|
@import "mixins";
|
||||||
|
|
||||||
|
|
||||||
html.js {
|
html.js {
|
||||||
.jsDisabledFallback {
|
.hideOnJs {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html.no-js {
|
html.no-js {
|
||||||
body > nav ul {
|
.hideOnNoJs {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,9 @@ body > nav {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@import "inc/table";
|
@import "table";
|
||||||
@import "inc/extended";
|
@import "extended";
|
||||||
@import "inc/tree";
|
@import "tree";
|
||||||
|
|
||||||
|
|
||||||
body > footer {
|
body > footer {
|
||||||
|
@ -120,7 +120,7 @@ body > footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
padding: 10px 0;
|
padding: 6px 0 8px 0;
|
||||||
background-color: rgb(241,241,241);
|
background-color: rgb(241,241,241);
|
||||||
border-top: 2px solid rgb(210,210,210);
|
border-top: 2px solid rgb(210,210,210);
|
||||||
|
|
||||||
|
@ -132,27 +132,63 @@ body > footer {
|
||||||
color: #555;
|
color: #555;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
.transition( all 0.2s ease-in-out );
|
.transition( all 0.2s ease-in-out );
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #e80;
|
color: #e80;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
display: block;
|
||||||
|
padding: 0 8px;
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin: 0 300px;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
display: block;
|
||||||
|
padding: 0 8px;
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
#langSelector {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.langOptions {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
display: none;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
background-color: rgb(241,241,241);
|
||||||
|
border: 1px solid rgb(210,210,210);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#html5 {
|
|
||||||
position: absolute;
|
|
||||||
left: 6px;
|
|
||||||
bottom: 6px;
|
|
||||||
opacity: 0.4;
|
|
||||||
.transition( all 0.2s ease-in-out );
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
|
||||||
#tree {
|
#tree {
|
||||||
position: fixed;
|
|
||||||
display: none;
|
display: none;
|
||||||
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 82px;
|
||||||
|
z-index: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
padding: 16px 16px 16px 16px;
|
padding: 16px 16px 16px 16px;
|
||||||
|
|
3
src/h5ai/css/main-js.less
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
@import "inc/main";
|
||||||
|
|
15
src/h5ai/css/main-php.less
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
@import "inc/main";
|
||||||
|
|
||||||
|
|
||||||
|
#table {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#tree, #content > header, #content > footer {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
html.no-js {
|
||||||
|
#extended.details-view, #extended.icons-view {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,20 +4,27 @@
|
||||||
<footer></footer>
|
<footer></footer>
|
||||||
</section>
|
</section>
|
||||||
<section id="tree"></section>
|
<section id="tree"></section>
|
||||||
<footer>
|
<footer class="clearfix">
|
||||||
<a id="html5" href="http://www.w3.org/html/logo/" target="_blank" title="HTML5 semantics, storage & CSS3">
|
<span class="left">
|
||||||
<img class="logo" src="/h5ai/images/html5.png" alt="html5" />
|
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (js)</a>
|
||||||
<img class="techclass" src="/h5ai/images/html5-semantics.png" alt="html5-semantics" />
|
</span>
|
||||||
<img class="techclass" src="/h5ai/images/html5-storage.png" alt="html5-storage" />
|
<span class="right">
|
||||||
<img class="techclass" src="/h5ai/images/html5-css3.png" alt="html5-css3" />
|
<span class="hideOnJs">JavaScript is disabled!</span>
|
||||||
</a>
|
<span id="langSelector">
|
||||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
<span class="lang">en</span> - <span class="l10n-lang">english</span>
|
||||||
<span class="l10n-footerUsing">using</span>
|
<span class="langOptions"></span>
|
||||||
<a href="http://tiheum.deviantart.com/art/Faenza-Icons-173323228" target="_blank" title="icon theme for Gnome">Faenza icons</a>
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="center">
|
||||||
|
<span class="hideOnNoJs">
|
||||||
|
<span class="folderCount"></span> <span class="l10n-folders">folders</span>
|
||||||
|
·
|
||||||
|
<span class="fileCount"></span> <span class="l10n-files">files</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
|
<script src="/h5ai/js/lib/jquery.min.js"></script>
|
||||||
<script>window.jQuery || document.write( '<script src="/h5ai/js/lib/jquery.min.js"><\/script>' )</script>
|
|
||||||
<script src="/h5ai/options.js"></script>
|
<script src="/h5ai/options.js"></script>
|
||||||
<script src="/h5ai/js/main.js"></script>
|
<script src="/h5ai/js/main-js.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
4
src/h5ai/footer.php
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<!-- generated code ends here -->
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,30 +3,29 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Directory index · styled with h5ai</title>
|
<title>Directory index · styled with h5ai</title>
|
||||||
<meta name="h5ai-version" content="h5ai %BUILD_VERSION%">
|
<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="keywords" content="directory, index, autoindex, h5ai">
|
<meta name="keywords" content="directory, index, autoindex, h5ai">
|
||||||
<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" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
||||||
<link rel="stylesheet" type="text/css" href="/h5ai/css/main.css">
|
<link rel="stylesheet" type="text/css" href="/h5ai/css/main-js.css">
|
||||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="clearfix">
|
<nav class="clearfix">
|
||||||
<span class="jsDisabledFallback">Directory index · JavaScript is disabled</span>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li id="viewicons" class="view">
|
<li id="viewicons" class="view hideOnNoJs">
|
||||||
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-viewIcons">icons</span></a>
|
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-icons">icons</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li id="viewdetails" class="view" >
|
<li id="viewdetails" class="view hideOnNoJs" >
|
||||||
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-viewDetails">details</span></a>
|
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-details">details</span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<section id="content">
|
<section id="content">
|
||||||
<header></header>
|
<header></header>
|
||||||
<section id="table" class="jsDisabledFallback">
|
<section id="table" class="hideOnJs">
|
||||||
<!--
|
<!--
|
||||||
The following code was generated by apache's autoindex module. It is not valid HTML 5 for the
|
The following code was generated by apache's autoindex module. It is not valid HTML 5 for the
|
||||||
reason, that 'align' and 'valign' attributes on the td element are obsolete. Both of them are
|
reason, that 'align' and 'valign' attributes on the td element are obsolete. Both of them are
|
||||||
|
|
55
src/h5ai/header.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="no-js">
|
||||||
|
<?php include "php/main.php"; ?>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<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="keywords" content="directory, index, autoindex, h5ai">
|
||||||
|
<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" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/h5ai/css/main-php.css">
|
||||||
|
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="clearfix">
|
||||||
|
<ul>
|
||||||
|
<?php echo $crumb->toHtml(); ?>
|
||||||
|
<li id="viewicons" class="view hideOnNoJs">
|
||||||
|
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-icons">icons</span></a>
|
||||||
|
</li>
|
||||||
|
<li id="viewdetails" class="view hideOnNoJs" >
|
||||||
|
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-details">details</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php echo $tree->toHtml(); ?>
|
||||||
|
<section id="content">
|
||||||
|
<?php echo $customize->getHeader(); ?>
|
||||||
|
<?php echo $extended->toHtml(); ?>
|
||||||
|
<?php echo $customize->getFooter(); ?>
|
||||||
|
</section>
|
||||||
|
<footer class="clearfix">
|
||||||
|
<span class="left">
|
||||||
|
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (php)</a>
|
||||||
|
</span>
|
||||||
|
<span class="right">
|
||||||
|
<span class="hideOnJs">JavaScript is disabled!</span>
|
||||||
|
<span id="langSelector">
|
||||||
|
<span class="lang">en</span> - <span class="l10n-lang">english</span>
|
||||||
|
<span class="langOptions"></span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="center">
|
||||||
|
<?php echo $extended->getFolderCount(); ?> <span class="l10n-folders">folders</span>
|
||||||
|
·
|
||||||
|
<?php echo $extended->getFileCount(); ?> <span class="l10n-files">files</span>
|
||||||
|
</span>
|
||||||
|
</footer>
|
||||||
|
<script src="/h5ai/js/lib/jquery.min.js"></script>
|
||||||
|
<script src="/h5ai/options.js"></script>
|
||||||
|
<script src="/h5ai/js/main-php.js"></script>
|
||||||
|
<section id="table">
|
||||||
|
<!-- the following code was generated by apache's autoindex module and gets ignored -->
|
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 494 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 424 B |
Before Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 811 B |
155
src/h5ai/js/inc/extended.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
|
||||||
|
var Extended = function ( pathCache ) {
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* config
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.config = {
|
||||||
|
defaultSortOrder: "C=N;O=A",
|
||||||
|
customHeader: "h5ai.header.html",
|
||||||
|
customFooter: "h5ai.footer.html"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* init
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.init = function () {
|
||||||
|
|
||||||
|
try {
|
||||||
|
document.title = decodeURI( document.domain + document.location.pathname );
|
||||||
|
} catch ( err ) {
|
||||||
|
document.title = document.domain + document.location.pathname;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.initBreadcrumb();
|
||||||
|
this.initExtendedView();
|
||||||
|
this.customize();
|
||||||
|
this.initCounts();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* breadcrumb
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.initBreadcrumb = function () {
|
||||||
|
|
||||||
|
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 !== "" ) {
|
||||||
|
pathname += part + "/";
|
||||||
|
var path = pathCache.getPathForFolder( pathname );
|
||||||
|
$ul.append( path.updateCrumbHtml() );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* extended view
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.initExtendedView = function () {
|
||||||
|
|
||||||
|
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 );
|
||||||
|
$( "<a class='label' href='" + $label.attr( "href" ) + "'><span class='l10n-name'>" + $label.text() + "</span></a>" ).appendTo( $li );
|
||||||
|
$( "<a class='date' href='" + $date.attr( "href" ) + "'><span class='l10n-lastModified'>" + $date.text() + "</span></a>" ).appendTo( $li );
|
||||||
|
$( "<a class='size' href='" + $size.attr( "href" ) + "'><span class='l10n-size'>" + $size.text() + "</span></a>" ).appendTo( $li );
|
||||||
|
|
||||||
|
// header sort icons
|
||||||
|
var order = document.location.search;
|
||||||
|
if ( order === "" ) {
|
||||||
|
order = this.config.defaultSortOrder;
|
||||||
|
};
|
||||||
|
var $icon;
|
||||||
|
if ( order.indexOf( "O=A" ) >= 0 ) {
|
||||||
|
$icon = $( "<img src='/h5ai/images/ascending.png' class='sort' alt='ascending' />" );
|
||||||
|
} else {
|
||||||
|
$icon = $( "<img src='/h5ai/images/descending.png' class='sort' alt='descending' />" );
|
||||||
|
};
|
||||||
|
if ( order.indexOf( "C=N" ) >= 0 ) {
|
||||||
|
$li.find( "a.label" ).append( $icon );
|
||||||
|
} else if ( order.indexOf( "C=M" ) >= 0 ) {
|
||||||
|
$li.find( "a.date" ).prepend( $icon );
|
||||||
|
} else if ( order.indexOf( "C=S" ) >= 0 ) {
|
||||||
|
$li.find( "a.size" ).prepend( $icon );
|
||||||
|
};
|
||||||
|
|
||||||
|
$.timer.log( "start entries" );
|
||||||
|
// entries
|
||||||
|
$( "#table td" ).closest( "tr" ).each( function () {
|
||||||
|
var path = pathCache.getPathForTableRow( document.location.pathname, this );
|
||||||
|
$ul.append( path.updateExtendedHtml() );
|
||||||
|
} );
|
||||||
|
$.timer.log( "end entries" );
|
||||||
|
|
||||||
|
$( "#extended" ).append( $ul );
|
||||||
|
$.log( document.location.pathname, "folders:", $( "#extended .folder" ).size() , "files:", $( "#extended .file" ).size() );
|
||||||
|
|
||||||
|
// empty
|
||||||
|
if ( $ul.children( ".entry:not(.parentfolder)" ).size() === 0 ) {
|
||||||
|
$( "#extended" ).append( $( "<div class='empty l10n-empty'>empty</div>" ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
// in case of floats
|
||||||
|
$( "#extended" ).addClass( "clearfix" );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* customize
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.customize = function () {
|
||||||
|
|
||||||
|
$.ajax( {
|
||||||
|
url: this.config.customHeader,
|
||||||
|
dataType: "html",
|
||||||
|
success: function ( data ) {
|
||||||
|
$( "#content > header" ).append( $( data ) ).show();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
$.ajax( {
|
||||||
|
url: this.config.customFooter,
|
||||||
|
dataType: "html",
|
||||||
|
success: function ( data ) {
|
||||||
|
$( "#content > footer" ).prepend( $( data ) ).show();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* init counts
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.initCounts = function () {
|
||||||
|
|
||||||
|
$( ".folderCount" ).text( $( "#extended .entry.folder:not(.parentfolder)" ).size() );
|
||||||
|
$( ".fileCount" ).text( $( "#extended .entry.file" ).size() );
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var H5ai = function ( options, langs, pathCache ) {
|
var H5ai = function ( options, langs ) {
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
|
@ -7,28 +7,27 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
defaultSortOrder: "C=N;O=A",
|
|
||||||
store: {
|
store: {
|
||||||
viewmode: "h5ai.viewmode"
|
viewmode: "h5ai.viewmode",
|
||||||
|
lang: "h5ai.lang"
|
||||||
},
|
},
|
||||||
customHeader: "h5ai.header.html",
|
|
||||||
customFooter: "h5ai.footer.html",
|
|
||||||
callbacks: {
|
callbacks: {
|
||||||
pathClick: []
|
pathClick: []
|
||||||
},
|
},
|
||||||
|
|
||||||
viewmodes: [ "details", "icons" ],
|
viewmodes: [ "details", "icons" ],
|
||||||
showTree: false,
|
showTree: true,
|
||||||
folderStatus: {
|
folderStatus: {
|
||||||
},
|
},
|
||||||
lang: undefined,
|
lang: null,
|
||||||
useBrowserLang: true,
|
useBrowserLang: true,
|
||||||
setParentFolderLabels: true,
|
setParentFolderLabels: true,
|
||||||
linkHoverStates: true
|
linkHoverStates: true
|
||||||
};
|
};
|
||||||
this.config = $.extend( {}, defaults, options );
|
this.config = $.extend( {}, defaults, options );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* public api
|
* public api
|
||||||
*******************************/
|
*******************************/
|
||||||
|
@ -49,14 +48,14 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
|
|
||||||
this.init = function () {
|
this.init = function () {
|
||||||
|
|
||||||
document.title = decodeURI( document.domain + document.location.pathname );
|
|
||||||
|
|
||||||
this.applyViewmode();
|
this.applyViewmode();
|
||||||
this.initBreadcrumb();
|
|
||||||
this.initTopSpace();
|
this.initTopSpace();
|
||||||
this.initViews();
|
this.initViews();
|
||||||
this.customize();
|
this.initTree();
|
||||||
|
this.linkHoverStates();
|
||||||
|
this.initLangSelector( langs );
|
||||||
this.localize( langs, this.config.lang, this.config.useBrowserLang );
|
this.localize( langs, this.config.lang, this.config.useBrowserLang );
|
||||||
|
this.initIndicators();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
viewmode = this.getViewmode();
|
viewmode = this.getViewmode();
|
||||||
|
|
||||||
$( "#viewdetails,#viewicons" ).hide().removeClass( "current" );
|
$( "#viewdetails,#viewicons" ).hide().removeClass( "current" );
|
||||||
|
|
||||||
if ( this.config.viewmodes.length > 1 ) {
|
if ( this.config.viewmodes.length > 1 ) {
|
||||||
if ( $.inArray( "details", this.config.viewmodes ) >= 0 ) {
|
if ( $.inArray( "details", this.config.viewmodes ) >= 0 ) {
|
||||||
$( "#viewdetails" ).show();
|
$( "#viewdetails" ).show();
|
||||||
|
@ -116,31 +115,6 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* breadcrumb
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
this.initBreadcrumb = function () {
|
|
||||||
|
|
||||||
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 !== "" ) {
|
|
||||||
pathname += part + "/";
|
|
||||||
var path = pathCache.getPathForFolder( pathname );
|
|
||||||
$ul.append( path.updateCrumbHtml() );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* top space, depending on nav height
|
* top space, depending on nav height
|
||||||
*******************************/
|
*******************************/
|
||||||
|
@ -175,74 +149,13 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* extended view
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
this.initExtendedView = function () {
|
|
||||||
|
|
||||||
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 );
|
|
||||||
$( "<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 );
|
|
||||||
|
|
||||||
// header sort icons
|
|
||||||
var order = document.location.search;
|
|
||||||
if ( order === "" ) {
|
|
||||||
order = this.config.defaultSortOrder;
|
|
||||||
};
|
|
||||||
var $icon;
|
|
||||||
if ( order.indexOf( "O=A" ) >= 0 ) {
|
|
||||||
$icon = $( "<img src='/h5ai/images/ascending.png' class='sort' alt='ascending' />" );
|
|
||||||
} else {
|
|
||||||
$icon = $( "<img src='/h5ai/images/descending.png' class='sort' alt='descending' />" );
|
|
||||||
};
|
|
||||||
if ( order.indexOf( "C=N" ) >= 0 ) {
|
|
||||||
$li.find( "a.label" ).append( $icon );
|
|
||||||
} else if ( order.indexOf( "C=M" ) >= 0 ) {
|
|
||||||
$li.find( "a.date" ).prepend( $icon );
|
|
||||||
} else if ( order.indexOf( "C=S" ) >= 0 ) {
|
|
||||||
$li.find( "a.size" ).prepend( $icon );
|
|
||||||
};
|
|
||||||
|
|
||||||
$.timer.log( "start entries" );
|
|
||||||
// entries
|
|
||||||
$( "#table td" ).closest( "tr" ).each( function () {
|
|
||||||
var path = pathCache.getPathForTableRow( document.location.pathname, this );
|
|
||||||
$ul.append( path.updateExtendedHtml() );
|
|
||||||
} );
|
|
||||||
$.timer.log( "end entries" );
|
|
||||||
$( "#table" ).remove();
|
|
||||||
|
|
||||||
$( "#extended" ).append( $ul );
|
|
||||||
$.log( document.location.pathname, "folders:", $( "#extended .folder" ).size() , "files:", $( "#extended .file" ).size() );
|
|
||||||
|
|
||||||
// empty
|
|
||||||
if ( $ul.children( ".entry:not(.parentfolder)" ).size() === 0 ) {
|
|
||||||
$( "#extended" ).append( $( "<div class='empty l10n-empty'>empty</div>" ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
// in case of floats
|
|
||||||
$( "#extended" ).addClass( "clearfix" );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* init views
|
* init views
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
this.initViews = function () {
|
this.initViews = function () {
|
||||||
|
|
||||||
this.initExtendedView();
|
$( "#table" ).remove();
|
||||||
|
|
||||||
$( "#viewdetails" ).closest( "li" )
|
$( "#viewdetails" ).closest( "li" )
|
||||||
.click( $.proxy( function () {
|
.click( $.proxy( function () {
|
||||||
|
@ -257,25 +170,61 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* customize
|
* init tree
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
this.customize = function () {
|
this.initTree = function () {
|
||||||
|
|
||||||
$.ajax( {
|
var $tree = $( "#tree" );
|
||||||
url: this.config.customHeader,
|
var $extended = $( "#extended" );
|
||||||
dataType: "html",
|
var shiftTree = function ( forceVisible, dontAnimate ) {
|
||||||
success: function ( data ) {
|
if ( $tree.outerWidth() < $extended.offset().left || forceVisible === true ) {
|
||||||
$( "#content > header" ).append( $( data ) ).show();
|
if ( dontAnimate === true ) {
|
||||||
}
|
$tree.stop().css( { left: 0 } );
|
||||||
|
} else {
|
||||||
|
$tree.stop().animate( { left: 0 } );
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if ( dontAnimate === true ) {
|
||||||
|
$tree.stop().css( { left: 18 - $tree.outerWidth() } );
|
||||||
|
} else {
|
||||||
|
$tree.stop().animate( { left: 18 - $tree.outerWidth() } );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$tree.hover( function () { shiftTree( true ); }, function () { shiftTree(); } );
|
||||||
|
$( window ).resize( function() {
|
||||||
|
shiftTree();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
$.ajax( {
|
shiftTree( false, true );
|
||||||
url: this.config.customFooter,
|
};
|
||||||
dataType: "html",
|
|
||||||
success: function ( data ) {
|
|
||||||
$( "#content > footer" ).prepend( $( data ) ).show();
|
|
||||||
}
|
/*******************************
|
||||||
|
* link hover states
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.linkHoverStates = function () {
|
||||||
|
|
||||||
|
if ( !this.config.linkHoverStates ) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
$( "a[href^='/']:not(.linkedHoverStates)" ).each( function () {
|
||||||
|
|
||||||
|
var $a = $( this ).addClass( "linkedHoverStates" );
|
||||||
|
var href = $a.attr( "href" );
|
||||||
|
$a.hover(
|
||||||
|
function () {
|
||||||
|
$( "a[href='" + href + "']" ).addClass( "hover" );
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$( "a[href='" + href + "']" ).removeClass( "hover" );
|
||||||
|
}
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,22 +234,111 @@ var H5ai = function ( options, langs, pathCache ) {
|
||||||
* localization
|
* localization
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
this.localize = function ( data, lang, useBrowserLang ) {
|
this.initLangSelector = function ( langs ) {
|
||||||
|
|
||||||
|
var sortedLangsKeys = [];
|
||||||
|
for ( lang in langs ) {
|
||||||
|
sortedLangsKeys.push( lang );
|
||||||
|
};
|
||||||
|
sortedLangsKeys.sort();
|
||||||
|
|
||||||
|
var THIS = this;
|
||||||
|
var $ul = $( "<ul />" );
|
||||||
|
for ( idx in sortedLangsKeys ) {
|
||||||
|
( function ( lang ) {
|
||||||
|
$( "<li class='langOption' />" )
|
||||||
|
.addClass( lang )
|
||||||
|
.text( lang + " - " + langs[lang]["lang"] )
|
||||||
|
.appendTo( $ul )
|
||||||
|
.click( function () {
|
||||||
|
localStorage.setItem( THIS.config.store.lang, lang );
|
||||||
|
THIS.localize( langs, lang, false );
|
||||||
|
} );
|
||||||
|
} )( sortedLangsKeys[idx] );
|
||||||
|
};
|
||||||
|
$( "#langSelector .langOptions" )
|
||||||
|
.append( $ul );
|
||||||
|
$( "#langSelector" ).hover(
|
||||||
|
function () {
|
||||||
|
var $ele = $( ".langOptions" );
|
||||||
|
$ele.css( "top", "-" + $ele.outerHeight() + "px" ).stop( true, true ).fadeIn();
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$( ".langOptions" ).stop( true, true ).fadeOut();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.localize = function ( langs, lang, useBrowserLang ) {
|
||||||
|
|
||||||
if ( useBrowserLang === true ) {
|
if ( useBrowserLang === true ) {
|
||||||
var browserLang = navigator.language;
|
var browserLang = navigator.language;
|
||||||
if ( data[ browserLang ] !== undefined ) {
|
if ( langs[ browserLang ] !== undefined ) {
|
||||||
lang = browserLang;
|
lang = browserLang;
|
||||||
} else if ( browserLang.length > 2 && data[ browserLang.substr( 0, 2 ) ] !== undefined ) {
|
} else if ( browserLang.length > 2 && langs[ browserLang.substr( 0, 2 ) ] !== undefined ) {
|
||||||
lang = browserLang.substr( 0, 2 );
|
lang = browserLang.substr( 0, 2 );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( lang !== "en" && data[ lang ] !== undefined ) {
|
if ( langs[ lang ] === undefined ) {
|
||||||
var selected = data[ lang ];
|
lang = "en";
|
||||||
for ( key in selected ) {
|
|
||||||
$( ".l10n-" + key ).text( selected[key] );
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var storedLang = localStorage.getItem( this.config.store.lang );
|
||||||
|
if ( langs[ storedLang ] !== undefined ) {
|
||||||
|
lang = storedLang;
|
||||||
|
};
|
||||||
|
|
||||||
|
var selected = langs[ lang ];
|
||||||
|
for ( key in selected ) {
|
||||||
|
$( ".l10n-" + key ).text( selected[key] );
|
||||||
|
};
|
||||||
|
$( ".lang" ).text( lang );
|
||||||
|
$( ".langOption" ).removeClass( "current" );
|
||||||
|
$( ".langOption." + lang ).addClass( "current" );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* initiate tree indicators
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
this.initIndicators = function () {
|
||||||
|
|
||||||
|
var THIS = this;
|
||||||
|
$( "#tree .entry.folder:not(.initiatedIndicator)" ).each( function () {
|
||||||
|
|
||||||
|
var $entry = $( this ).addClass( "initiatedIndicator" );
|
||||||
|
var $indicator = $entry.find( "> .indicator" );
|
||||||
|
$indicator.click( function( event ) {
|
||||||
|
if ( $indicator.hasClass( "unknown" ) ) {
|
||||||
|
$.get( "/h5ai/php/treecontent.php", { "href": $entry.find( "> a" ).attr( "href" ) }, function ( html ) {
|
||||||
|
$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 );
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||||
|
THIS.initIndicators();
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
} else if ( $indicator.hasClass( "open" ) ) {
|
||||||
|
$indicator.removeClass( "open" );
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||||
|
$entry.find( "> .content" ).slideUp( function() {
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
$indicator.addClass( "open" );
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||||
|
$entry.find( "> .content" ).slideDown( function() {
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
} );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
133
src/h5ai/js/inc/jquery.scrollpanel.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
( function ( $ ) {
|
||||||
|
|
||||||
|
var init = 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 updateId = undefined;
|
||||||
|
|
||||||
|
var update = function ( repeat ) {
|
||||||
|
if ( updateId !== undefined && !repeat ) {
|
||||||
|
clearInterval( updateId );
|
||||||
|
updateId = undefined;
|
||||||
|
} else if ( updateId === undefined && repeat ) {
|
||||||
|
updateId = setInterval( function() { update( true ); }, 50 );
|
||||||
|
};
|
||||||
|
|
||||||
|
$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 ) {
|
||||||
|
$scrollbar
|
||||||
|
.fadeIn( 50 )
|
||||||
|
.css( {
|
||||||
|
height: $element.innerHeight() + $scrollbar.height() - $scrollbar.outerHeight( true )
|
||||||
|
} );
|
||||||
|
$drag
|
||||||
|
.css( {
|
||||||
|
top: $scrollbar.height() * scrollTopFrac,
|
||||||
|
height: $scrollbar.height() * visVertFrac
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
$scrollbar.fadeOut( 50 );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
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( {
|
||||||
|
"padding-right": $scrollbar.outerWidth( true ),
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$.fn.scrollpanel = function () {
|
||||||
|
|
||||||
|
return this.each( function () {
|
||||||
|
|
||||||
|
init( this );
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
} )( jQuery );
|
24
src/h5ai/js/inc/jquery.utils.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
( function( $ ) {
|
||||||
|
|
||||||
|
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
|
||||||
|
// modified
|
||||||
|
$.log = function () {
|
||||||
|
$.log.history = $.log.history || [];
|
||||||
|
$.log.history.push( arguments );
|
||||||
|
if ( window.console ) {
|
||||||
|
window.console.log( Array.prototype.slice.call( arguments ) );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var Timer = function () {
|
||||||
|
this.start = new Date().getTime();;
|
||||||
|
this.last = this.start;
|
||||||
|
this.log = function ( label ) {
|
||||||
|
var now = new Date().getTime();
|
||||||
|
$.log( "timer", label, "+" + (now - this.last), "=" + (now - this.start) );
|
||||||
|
this.last = now;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$.timer = new Timer();
|
||||||
|
|
||||||
|
} )( jQuery );
|
|
@ -170,6 +170,14 @@ var PathCache = function () {
|
||||||
|
|
||||||
var Path = function ( pathCache, folder, tableRow ) {
|
var Path = function ( pathCache, folder, tableRow ) {
|
||||||
|
|
||||||
|
this.checkedDecodeUri = function ( uri ) {
|
||||||
|
try {
|
||||||
|
return decodeURI( uri );
|
||||||
|
} catch ( err ) {
|
||||||
|
};
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! pathEndsWithSlashRegEx.test( folder ) ) {
|
if ( ! pathEndsWithSlashRegEx.test( folder ) ) {
|
||||||
folder += "/";
|
folder += "/";
|
||||||
};
|
};
|
||||||
|
@ -191,13 +199,13 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
|
|
||||||
this.parentFolder = splits[0];
|
this.parentFolder = splits[0];
|
||||||
this.href = splits[1];
|
this.href = splits[1];
|
||||||
this.label = decodeURI( splits[1] );
|
this.label = this.checkedDecodeUri( splits[1] );
|
||||||
this.icon16 = "/h5ai/icons/16x16/folder.png";
|
this.icon16 = "/h5ai/icons/16x16/folder.png";
|
||||||
this.alt = "[DIR]";
|
this.alt = "[DIR]";
|
||||||
this.date = "";
|
this.date = "";
|
||||||
this.size = "";
|
this.size = "";
|
||||||
if ( this.label === "/" ) {
|
if ( this.label === "/" ) {
|
||||||
this.label = decodeURI( document.domain ) + "/";
|
this.label = this.checkedDecodeUri( document.domain ) + "/";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,9 +222,9 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
|
|
||||||
if ( this.isParentFolder && h5ai.config.setParentFolderLabels ) {
|
if ( this.isParentFolder && h5ai.config.setParentFolderLabels ) {
|
||||||
if ( this.isDomain ) {
|
if ( this.isDomain ) {
|
||||||
this.label = decodeURI( document.domain );
|
this.label = this.checkedDecodeUri( document.domain );
|
||||||
} else {
|
} else {
|
||||||
this.label = decodeURI( pathCache.splitPathname( pathCache.splitPathname( this.parentFolder )[0] )[1].slice( 0, -1 ) );
|
this.label = this.checkedDecodeUri( pathCache.splitPathname( pathCache.splitPathname( this.parentFolder )[0] )[1].slice( 0, -1 ) );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,37 +245,10 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
|
|
||||||
this.onClick = function ( context ) {
|
this.onClick = function ( context ) {
|
||||||
|
|
||||||
pathCache.storeCache();
|
|
||||||
h5ai.triggerPathClick( this, context );
|
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.updateHtml = function () {
|
||||||
|
|
||||||
this.updateCrumbHtml();
|
this.updateCrumbHtml();
|
||||||
|
@ -292,7 +273,6 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
var $a = $( "<a><img src='/h5ai/images/crumb.png' alt='>' />" + this.label + "</a>" );
|
var $a = $( "<a><img src='/h5ai/images/crumb.png' alt='>' />" + this.label + "</a>" );
|
||||||
$a.attr( "href", this.absHref );
|
$a.attr( "href", this.absHref );
|
||||||
$a.click( $.proxy( function() { this.onClick( "crumb" ); }, this ) );
|
$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 );
|
$html.append( $a );
|
||||||
|
|
||||||
if ( this.isDomain ) {
|
if ( this.isDomain ) {
|
||||||
|
@ -340,7 +320,6 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
var $a = $( "<a />" ).appendTo( $html );
|
var $a = $( "<a />" ).appendTo( $html );
|
||||||
$a.attr( "href", this.absHref );
|
$a.attr( "href", this.absHref );
|
||||||
$a.click( $.proxy( function() { this.onClick( "extended" ); }, this ) );
|
$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 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 );
|
$( "<span class='icon big'><img src='" + this.icon48 + "' alt='" + this.alt + "' /></span>" ).appendTo( $a );
|
||||||
|
@ -391,7 +370,6 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
.append( $( "<span class='label'>" + this.label + "</span>" ) );
|
.append( $( "<span class='label'>" + this.label + "</span>" ) );
|
||||||
$a.attr( "href", this.absHref );
|
$a.attr( "href", this.absHref );
|
||||||
$a.click( $.proxy( function() { this.onClick( "tree" ); }, this ) );
|
$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 ) {
|
if ( this.isFolder ) {
|
||||||
// indicator
|
// indicator
|
||||||
|
@ -409,6 +387,7 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.treeOpen = true;
|
this.treeOpen = true;
|
||||||
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
||||||
|
pathCache.storeCache();
|
||||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||||
this.updateTreeHtml( function() {
|
this.updateTreeHtml( function() {
|
||||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||||
|
@ -417,6 +396,7 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
} else if ( $indicator.hasClass( "open" ) ) {
|
} else if ( $indicator.hasClass( "open" ) ) {
|
||||||
this.treeOpen = false;
|
this.treeOpen = false;
|
||||||
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
||||||
|
pathCache.storeCache();
|
||||||
$indicator.removeClass( "open" );
|
$indicator.removeClass( "open" );
|
||||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||||
$html.find( "> ul.content" ).slideUp( function() {
|
$html.find( "> ul.content" ).slideUp( function() {
|
||||||
|
@ -425,6 +405,7 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
} else {
|
} else {
|
||||||
this.treeOpen = true;
|
this.treeOpen = true;
|
||||||
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
pathCache.objectCache[this.absHref] = pathCache.pathToObject( this );
|
||||||
|
pathCache.storeCache();
|
||||||
$indicator.addClass( "open" );
|
$indicator.addClass( "open" );
|
||||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||||
$html.find( "> ul.content" ).slideDown( function() {
|
$html.find( "> ul.content" ).slideDown( function() {
|
||||||
|
@ -432,6 +413,7 @@ var Path = function ( pathCache, folder, tableRow ) {
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
}, this ) );
|
}, this ) );
|
||||||
|
$html.addClass( "initiatedIndicator" );
|
||||||
$blank.replaceWith( $indicator );
|
$blank.replaceWith( $indicator );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
var Tree = function ( pathCache, h5ai ) {
|
var Tree = function ( pathCache, h5ai ) {
|
||||||
|
|
||||||
var THIS = this;
|
|
||||||
var contentTypeRegEx = /^text\/html;h5ai=/;
|
|
||||||
|
|
||||||
this.init = function () {
|
this.init = function () {
|
||||||
|
|
||||||
|
@ -21,6 +19,7 @@ var Tree = function ( pathCache, h5ai ) {
|
||||||
path.status = status;
|
path.status = status;
|
||||||
};
|
};
|
||||||
path.updateHtml();
|
path.updateHtml();
|
||||||
|
h5ai.linkHoverStates();
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -36,34 +35,16 @@ var Tree = function ( pathCache, h5ai ) {
|
||||||
|
|
||||||
this.populateTree = function () {
|
this.populateTree = function () {
|
||||||
|
|
||||||
var $tree = $( "#tree" );
|
|
||||||
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 {
|
|
||||||
$tree.stop().animate( { left: 0 } );
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if ( dontAnimate === true ) {
|
|
||||||
$tree.stop().css( { left: 18 - $tree.outerWidth() } );
|
|
||||||
} else {
|
|
||||||
$tree.stop().animate( { left: 18 - $tree.outerWidth() } );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$tree.hover( function () { shiftTree( true ); }, function () { shiftTree(); } );
|
|
||||||
$( window ).resize( function() {
|
|
||||||
shiftTree();
|
|
||||||
} );
|
|
||||||
|
|
||||||
this.fetchTree( document.location.pathname, function( path ) {
|
this.fetchTree( document.location.pathname, function( path ) {
|
||||||
$tree.append( path.updateTreeHtml() );
|
$( "#tree" )
|
||||||
$tree.show();
|
.append( path.updateTreeHtml() )
|
||||||
scrollpanel( $tree );
|
.scrollpanel()
|
||||||
shiftTree( false, true );
|
.show();
|
||||||
|
h5ai.linkHoverStates();
|
||||||
|
pathCache.storeCache();
|
||||||
|
setTimeout( function () {
|
||||||
|
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||||
|
}, 1 );
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,6 +80,11 @@ var Tree = function ( pathCache, h5ai ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var THIS = this;
|
||||||
|
var contentTypeRegEx = /^text\/html;h5ai=/;
|
||||||
|
var pathnameStatusCache = {};
|
||||||
|
|
||||||
this.fetchStatusAndContent = function ( pathname, includeParent, callback ) {
|
this.fetchStatusAndContent = function ( pathname, includeParent, callback ) {
|
||||||
|
|
||||||
this.fetchStatus( pathname, function ( status ) {
|
this.fetchStatus( pathname, function ( status ) {
|
||||||
|
@ -136,8 +122,6 @@ var Tree = function ( pathCache, h5ai ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var pathnameStatusCache = {};
|
|
||||||
|
|
||||||
this.fetchStatus = function ( pathname, callback ) {
|
this.fetchStatus = function ( pathname, callback ) {
|
||||||
|
|
||||||
if ( h5ai.config.folderStatus[ pathname ] !== undefined ) {
|
if ( h5ai.config.folderStatus[ pathname ] !== undefined ) {
|
||||||
|
@ -161,127 +145,4 @@ var Tree = function ( pathCache, h5ai ) {
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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 updateId = undefined;
|
|
||||||
|
|
||||||
var update = function ( repeat ) {
|
|
||||||
if ( updateId !== undefined && !repeat ) {
|
|
||||||
clearInterval( updateId );
|
|
||||||
updateId = undefined;
|
|
||||||
} else if ( updateId === undefined && repeat ) {
|
|
||||||
updateId = setInterval( function() { update( true ); }, 50 );
|
|
||||||
};
|
|
||||||
|
|
||||||
$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 ) {
|
|
||||||
$scrollbar
|
|
||||||
.fadeIn( 50 )
|
|
||||||
.css( {
|
|
||||||
height: $element.innerHeight() + $scrollbar.height() - $scrollbar.outerHeight( true )
|
|
||||||
} );
|
|
||||||
$drag
|
|
||||||
.css( {
|
|
||||||
top: $scrollbar.height() * scrollTopFrac,
|
|
||||||
height: $scrollbar.height() * visVertFrac
|
|
||||||
} );
|
|
||||||
} else {
|
|
||||||
$scrollbar.fadeOut( 50 );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
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( {
|
|
||||||
"padding-right": $scrollbar.outerWidth( true ),
|
|
||||||
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();
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
44
src/h5ai/js/main-js.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
( function( $ ) {
|
||||||
|
|
||||||
|
// @include "inc/jquery.json.min.js"
|
||||||
|
// @include "inc/jquery.mousewheel.min.js"
|
||||||
|
// @include "inc/jquery.scrollpanel.js"
|
||||||
|
// @include "inc/jquery.utils.js"
|
||||||
|
// @include "inc/path.js"
|
||||||
|
// @include "inc/extended.js"
|
||||||
|
// @include "inc/h5ai.js"
|
||||||
|
// @include "inc/tree.js"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* create
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
$.timer.log( "start pathcache" );
|
||||||
|
var pathCache = new PathCache();
|
||||||
|
$.timer.log( "end pathcache" );
|
||||||
|
var extended = new Extended( pathCache );
|
||||||
|
var h5ai = new H5ai( h5aiOptions, h5aiLangs );
|
||||||
|
var tree = new Tree( pathCache, h5ai );
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* register public api
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
$.h5ai = {
|
||||||
|
click: $.proxy( h5ai.pathClick, h5ai )
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* init after dom load
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
$( function() {
|
||||||
|
|
||||||
|
extended.init();
|
||||||
|
tree.init();
|
||||||
|
h5ai.init();
|
||||||
|
} );
|
||||||
|
|
||||||
|
} )( jQuery );
|
36
src/h5ai/js/main-php.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
( function( $ ) {
|
||||||
|
|
||||||
|
// @include "inc/jquery.json.min.js"
|
||||||
|
// @include "inc/jquery.mousewheel.min.js"
|
||||||
|
// @include "inc/jquery.scrollpanel.js"
|
||||||
|
// @include "inc/jquery.utils.js"
|
||||||
|
// @include "inc/h5ai.js"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* create
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
var h5ai = new H5ai( h5aiOptions, h5aiLangs );
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* register public api
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
$.h5ai = {
|
||||||
|
click: $.proxy( h5ai.pathClick, h5ai )
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* init after dom load
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
$( function() {
|
||||||
|
|
||||||
|
h5ai.init();
|
||||||
|
$( "#tree" ).scrollpanel();
|
||||||
|
} );
|
||||||
|
|
||||||
|
} )( jQuery );
|
|
@ -1,66 +0,0 @@
|
||||||
( function( $ ) {
|
|
||||||
|
|
||||||
// @include "inc/jquery.json.min.js"
|
|
||||||
// @include "inc/jquery.mousewheel.min.js"
|
|
||||||
// @include "inc/path.js"
|
|
||||||
// @include "inc/h5ai.js"
|
|
||||||
// @include "inc/tree.js"
|
|
||||||
|
|
||||||
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
|
|
||||||
$.log = function () {
|
|
||||||
$.log.history = $.log.history || [];
|
|
||||||
$.log.history.push( arguments );
|
|
||||||
if ( window.console ) {
|
|
||||||
window.console.log( Array.prototype.slice.call( arguments ) );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var Timer = function () {
|
|
||||||
this.start = new Date().getTime();;
|
|
||||||
this.last = this.start;
|
|
||||||
this.log = function ( label ) {
|
|
||||||
var now = new Date().getTime();
|
|
||||||
$.log( "timer", label, "+" + (now - this.last), "=" + (now - this.start) );
|
|
||||||
this.last = now;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
$.timer = new Timer();
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* create
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
$.timer.log( "start pathcache" );
|
|
||||||
var pathCache = new PathCache();
|
|
||||||
$.timer.log( "end pathcache" );
|
|
||||||
var h5ai = new H5ai( h5aiOptions, h5aiLangs, pathCache );
|
|
||||||
var tree = new Tree( pathCache, h5ai );
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* register public api
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
$.h5ai = {
|
|
||||||
click: $.proxy( h5ai.pathClick, h5ai )
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* init after dom load
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
$( function() {
|
|
||||||
h5ai.init();
|
|
||||||
tree.init();
|
|
||||||
|
|
||||||
// just for testing, resets the local cache /////////
|
|
||||||
$( ".l10n-footerUsing" ).click( function () {
|
|
||||||
pathCache.cache = {};
|
|
||||||
pathCache.objectCache = {};
|
|
||||||
pathCache.storeCache();
|
|
||||||
} );
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
} );
|
|
||||||
|
|
||||||
} )( jQuery );
|
|
|
@ -13,7 +13,7 @@ h5aiOptions = {
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
viewmodes: [ "details", "icons" ],
|
"viewmodes": [ "details", "icons" ],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show a folder tree, boolean.
|
* Show a folder tree, boolean.
|
||||||
|
@ -22,7 +22,7 @@ h5aiOptions = {
|
||||||
* folderStatus below to avoid such requests.
|
* folderStatus below to avoid such requests.
|
||||||
* It might also affect performance significantly.
|
* It might also affect performance significantly.
|
||||||
*/
|
*/
|
||||||
showTree: true,
|
"showTree": true,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Associative array of folders and their HTTP status codes to
|
* Associative array of folders and their HTTP status codes to
|
||||||
|
@ -34,7 +34,7 @@ h5aiOptions = {
|
||||||
* as a non auto indexed folder, that means a folder containing an
|
* as a non auto indexed folder, that means a folder containing an
|
||||||
* appropriate default index file.
|
* appropriate default index file.
|
||||||
*/
|
*/
|
||||||
folderStatus: {
|
"folderStatus": {
|
||||||
/*
|
/*
|
||||||
* for example:
|
* for example:
|
||||||
* "/some/folder/": 200
|
* "/some/folder/": 200
|
||||||
|
@ -44,132 +44,189 @@ h5aiOptions = {
|
||||||
/*
|
/*
|
||||||
* Localization, for example "en", "de" etc. - see h5aiLangs below for
|
* Localization, for example "en", "de" etc. - see h5aiLangs below for
|
||||||
* possible values. Adjust it to your needs. If lang is not found in
|
* possible values. Adjust it to your needs. If lang is not found in
|
||||||
* h5aiLangs the displayed labels stay unchanged.
|
* h5aiLangs it defaults to "en".
|
||||||
*/
|
*/
|
||||||
lang: undefined,
|
"lang": null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to use browser language, falls back to previous specified lang.
|
* Try to use browser language, falls back to previous specified lang.
|
||||||
*/
|
*/
|
||||||
useBrowserLang: true,
|
"useBrowserLang": true,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set parent folder labels to real folder names.
|
* Set parent folder labels to real folder names.
|
||||||
*/
|
*/
|
||||||
setParentFolderLabels: true,
|
"setParentFolderLabels": true,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link the hover effects between crumb, extended view and tree.
|
* Link the hover effects between crumb, extended view and tree.
|
||||||
*/
|
*/
|
||||||
linkHoverStates: true
|
"linkHoverStates": true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only used in PHP implementation.
|
||||||
|
* Date format in PHP syntax, for example: "Y-m-d H:i:s"
|
||||||
|
* http://www.php.net/manual/en/function.date.php
|
||||||
|
*/
|
||||||
|
"dateFormat": "Y-m-d H:i",
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only used in PHP implementation.
|
||||||
|
* Files/folders that should never be listed. Specified
|
||||||
|
* by the complete filename or by a regular expression.
|
||||||
|
* http://www.php.net/manual/en/function.preg-match.php
|
||||||
|
*/
|
||||||
|
"ignore": [ "h5ai", "h5ai.header.html", "h5ai.footer.html" ],
|
||||||
|
"ignoreRE": [ "/^\\./" ]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Available translations.
|
* Available translations.
|
||||||
* "en" is just an example - see it as a reference. Those values
|
*/
|
||||||
* are "hardcoded" and will be displayed if all labels stay unchanged.
|
|
||||||
*/
|
|
||||||
h5aiLangs = {
|
h5aiLangs = {
|
||||||
|
|
||||||
"en": {
|
"en": {
|
||||||
viewDetails: "details",
|
"lang": "english",
|
||||||
viewIcons: "icons",
|
"details": "details",
|
||||||
columnName: "Name",
|
"icons": "icons",
|
||||||
columnLastModified: "Last modified",
|
"name": "Name",
|
||||||
columnSize: "Size",
|
"lastModified": "Last modified",
|
||||||
footerUsing: "using",
|
"size": "Size",
|
||||||
parentDirectory: "Parent Directory",
|
"parentDirectory": "Parent Directory",
|
||||||
empty: "empty"
|
"empty": "empty",
|
||||||
|
"folders": "folders",
|
||||||
|
"files": "files"
|
||||||
},
|
},
|
||||||
|
|
||||||
"de": {
|
"de": {
|
||||||
viewDetails: "Details",
|
"lang": "deutsch",
|
||||||
viewIcons: "Icons",
|
"details": "Details",
|
||||||
columnName: "Name",
|
"icons": "Icons",
|
||||||
columnLastModified: "Geändert",
|
"name": "Name",
|
||||||
columnSize: "Größe",
|
"lastModified": "Geändert",
|
||||||
footerUsing: "nutzt",
|
"size": "Größe",
|
||||||
parentDirectory: "Übergeordnetes Verzeichnis",
|
"parentDirectory": "Übergeordnetes Verzeichnis",
|
||||||
empty: "leer"
|
"empty": "leer",
|
||||||
|
"folders": "Ordner",
|
||||||
|
"files": "Dateien"
|
||||||
},
|
},
|
||||||
|
|
||||||
"fr": {
|
"fr": {
|
||||||
viewDetails: "détails",
|
"lang": "française",
|
||||||
viewIcons: "icônes",
|
"details": "détails",
|
||||||
columnName: "Nom",
|
"icons": "icônes",
|
||||||
columnLastModified: "Dernière modification",
|
"name": "Nom",
|
||||||
columnSize: "Taille",
|
"lastModified": "Dernière modification",
|
||||||
footerUsing: "utilise",
|
"size": "Taille",
|
||||||
parentDirectory: "Dossier parent",
|
"parentDirectory": "Dossier parent",
|
||||||
empty: "vide"
|
"empty": "vide",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"nl": {
|
"nl": {
|
||||||
viewDetails: "details",
|
"lang": "nederlands",
|
||||||
viewIcons: "iconen",
|
"details": "details",
|
||||||
columnName: "Naam",
|
"icons": "iconen",
|
||||||
columnLastModified: "Laatste wijziging",
|
"name": "Naam",
|
||||||
columnSize: "Grootte",
|
"lastModified": "Laatste wijziging",
|
||||||
footerUsing: "gebruikt",
|
"size": "Grootte",
|
||||||
parentDirectory: "Bovenliggende map",
|
"parentDirectory": "Bovenliggende map",
|
||||||
empty: "lege"
|
"empty": "lege",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"sv": {
|
"sv": {
|
||||||
viewDetails: "detaljerad",
|
"lang": "svenska",
|
||||||
viewIcons: "ikoner",
|
"details": "detaljerad",
|
||||||
columnName: "Filnamn",
|
"icons": "ikoner",
|
||||||
columnLastModified: "Senast ändrad",
|
"name": "Filnamn",
|
||||||
columnSize: "Filstorlek",
|
"lastModified": "Senast ändrad",
|
||||||
footerUsing: "använder",
|
"size": "Filstorlek",
|
||||||
parentDirectory: "Till överordnad mapp",
|
"parentDirectory": "Till överordnad mapp",
|
||||||
empty: "tom"
|
"empty": "tom",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"cs": {
|
"cs": {
|
||||||
viewDetails: "podrobnosti",
|
"lang": "[?lang?]",
|
||||||
viewIcons: "ikony",
|
"details": "podrobnosti",
|
||||||
columnName: "Název",
|
"icons": "ikony",
|
||||||
columnLastModified: "Upraveno",
|
"name": "Název",
|
||||||
columnSize: "Velikost",
|
"lastModified": "Upraveno",
|
||||||
footerUsing: "používá",
|
"size": "Velikost",
|
||||||
parentDirectory: "Nadřazený adresář",
|
"parentDirectory": "Nadřazený adresář",
|
||||||
empty: "prázdný"
|
"empty": "prázdný",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"sk": {
|
"sk": {
|
||||||
viewDetails: "podrobnosti",
|
"lang": "[?lang?]",
|
||||||
viewIcons: "ikony",
|
"details": "podrobnosti",
|
||||||
columnName: "Názov",
|
"icons": "ikony",
|
||||||
columnLastModified: "Upravené",
|
"name": "Názov",
|
||||||
columnSize: "Velkosť",
|
"lastModified": "Upravené",
|
||||||
footerUsing: "používá",
|
"size": "Velkosť",
|
||||||
parentDirectory: "Nadriadený priečinok",
|
"parentDirectory": "Nadriadený priečinok",
|
||||||
empty: "prázdny"
|
"empty": "prázdny",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"es": {
|
"es": {
|
||||||
viewDetails: "Detalles",
|
"lang": "español",
|
||||||
viewIcons: "Íconos",
|
"details": "Detalles",
|
||||||
columnName: "Nombre",
|
"icons": "Íconos",
|
||||||
columnLastModified: "Última modificación",
|
"name": "Nombre",
|
||||||
columnSize: "Tamaño",
|
"lastModified": "Última modificación",
|
||||||
footerUsing: "usando",
|
"size": "Tamaño",
|
||||||
parentDirectory: "Directorio superior",
|
"parentDirectory": "Directorio superior",
|
||||||
empty: "vacío"
|
"empty": "vacío",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"tr": {
|
"tr": {
|
||||||
viewDetails: "detaylar",
|
"lang": "türkçe",
|
||||||
viewIcons: "ikonlar",
|
"details": "detaylar",
|
||||||
columnName: "İsim",
|
"icons": "ikonlar",
|
||||||
columnLastModified: "Son Düzenleme",
|
"name": "İsim",
|
||||||
columnSize: "Boyut",
|
"lastModified": "Son Düzenleme",
|
||||||
footerUsing: "kullanıyor",
|
"size": "Boyut",
|
||||||
parentDirectory: "Üst Dizin",
|
"parentDirectory": "Üst Dizin",
|
||||||
empty: "boş"
|
"empty": "boş",
|
||||||
}
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
|
},
|
||||||
|
|
||||||
|
"pt": {
|
||||||
|
"lang": "português",
|
||||||
|
"details": "detalhes",
|
||||||
|
"icons": "ícones",
|
||||||
|
"name": "Nome",
|
||||||
|
"lastModified": "Última modificação",
|
||||||
|
"size": "Tamanho",
|
||||||
|
"parentDirectory": "Diretório superior",
|
||||||
|
"empty": "vazio",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
|
},
|
||||||
|
|
||||||
|
"bg": {
|
||||||
|
"lang": "[?lang?]",
|
||||||
|
"details": "детайли",
|
||||||
|
"icons": "икони",
|
||||||
|
"name": "Име",
|
||||||
|
"lastModified": "Последна промяна",
|
||||||
|
"size": "Размер",
|
||||||
|
"parentDirectory": "Предходна директория",
|
||||||
|
"empty": "празно",
|
||||||
|
"folders": "[?folders?]",
|
||||||
|
"files": "[?files?]"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
93
src/h5ai/php/cache.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
##############################################
|
||||||
|
# taken from here:
|
||||||
|
# http://www.jongales.com/blog/2009/02/18/simple-file-based-php-cache-class/
|
||||||
|
# with minor modifications
|
||||||
|
##############################################
|
||||||
|
|
||||||
|
class Cache {
|
||||||
|
private $dir;
|
||||||
|
|
||||||
|
function __construct( $dir ) {
|
||||||
|
|
||||||
|
$this->dir = $dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _name( $key ) {
|
||||||
|
|
||||||
|
return $this->dir . "/" . sha1( $key );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get( $key, $expiration = 3600 ) {
|
||||||
|
|
||||||
|
if ( !is_dir( $this->dir ) || !is_writable( $this->dir ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache_path = $this->_name( $key );
|
||||||
|
|
||||||
|
if ( !@file_exists( $cache_path ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( filemtime( $cache_path ) < ( time() - $expiration ) ) {
|
||||||
|
$this->clear( $key );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !$fp = @fopen( $cache_path, "rb" ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
flock( $fp, LOCK_SH );
|
||||||
|
$cache = "";
|
||||||
|
|
||||||
|
if ( filesize( $cache_path ) > 0 ) {
|
||||||
|
$cache = unserialize( fread( $fp, filesize( $cache_path ) ) );
|
||||||
|
} else {
|
||||||
|
$cache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
flock( $fp, LOCK_UN );
|
||||||
|
fclose( $fp );
|
||||||
|
|
||||||
|
return $cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set( $key, $data ) {
|
||||||
|
|
||||||
|
if ( !is_dir( $this->dir ) || !is_writable( $this->dir ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache_path = $this->_name( $key );
|
||||||
|
|
||||||
|
if ( ! $fp = fopen( $cache_path, "wb" ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flock( $fp, LOCK_EX ) ) {
|
||||||
|
fwrite( $fp, serialize( $data ) );
|
||||||
|
flock( $fp, LOCK_UN );
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fclose( $fp );
|
||||||
|
@chmod( $cache_path, 0777 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear( $key ) {
|
||||||
|
|
||||||
|
$cache_path = $this->_name( $key );
|
||||||
|
|
||||||
|
if ( file_exists( $cache_path ) ) {
|
||||||
|
unlink( $cache_path );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
52
src/h5ai/php/crumb.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Crumb {
|
||||||
|
private $h5ai, $parts;
|
||||||
|
|
||||||
|
public function __construct( $h5ai ) {
|
||||||
|
|
||||||
|
$this->h5ai = $h5ai;
|
||||||
|
$this->parts = array();
|
||||||
|
|
||||||
|
$href = $h5ai->getAbsHref();
|
||||||
|
while ( $href !== "/" && $href !== "//" ) {
|
||||||
|
$this->parts[] = $href;
|
||||||
|
$href = dirname( $href ) . "/";
|
||||||
|
}
|
||||||
|
$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 = "/h5ai/images/" . ( $idx === 1 ? "home.png" : "crumb.png" );
|
||||||
|
$label = $this->h5ai->getLabel( $href );
|
||||||
|
$hint = "";
|
||||||
|
|
||||||
|
$code = $this->h5ai->getHttpCode( $href );
|
||||||
|
$classes .= " checkedHttpCode";
|
||||||
|
if ( $code !== "h5ai" ) {
|
||||||
|
if ( $code === 200 ) {
|
||||||
|
$hint = "<img class='hint' src='/h5ai/images/page.png' 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='>' />" . $label . $hint . "\n";
|
||||||
|
$html .= "\t</a>\n";
|
||||||
|
$html .= "</li>\n";
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
27
src/h5ai/php/customize.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Customize {
|
||||||
|
private $h5ai;
|
||||||
|
|
||||||
|
public function __construct( $h5ai ) {
|
||||||
|
|
||||||
|
$this->h5ai = $h5ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeader() {
|
||||||
|
|
||||||
|
return $this->getContent( $this->h5ai->getAbsPath() . "/" . "h5ai.header.html", "header" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFooter() {
|
||||||
|
|
||||||
|
return $this->getContent( $this->h5ai->getAbsPath() . "/" . "h5ai.footer.html", "footer" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContent( $file, $tag ) {
|
||||||
|
|
||||||
|
return file_exists( $file ) ? ( "<" . $tag . ">" . file_get_contents( $file ) . "</" . $tag . ">" ) : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
205
src/h5ai/php/extended.php
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare( $that, $sortOrder ) {
|
||||||
|
|
||||||
|
if ( $this->isFolder && !$that->isFolder ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( !$this->isFolder && $that->isFolder ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = 0;
|
||||||
|
if ( $sortOrder[ "column" ] === "name" ) {
|
||||||
|
$res = strcasecmp( $this->absPath, $that->absPath );
|
||||||
|
} else if ( $sortOrder[ "column" ] === "date" ) {
|
||||||
|
$res = $this->date - $that->date;
|
||||||
|
} else if ( $sortOrder[ "column" ] === "size" ) {
|
||||||
|
$res = $this->size - $that->size;
|
||||||
|
}
|
||||||
|
if ( ! $sortOrder[ "ascending" ] ) {
|
||||||
|
$res = -$res;
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toHtml( $dateFormat ) {
|
||||||
|
|
||||||
|
$classes = "entry " . $this->type;
|
||||||
|
$img = $this->type;
|
||||||
|
$hint = "";
|
||||||
|
$dateLabel = date( $dateFormat, $this->date );
|
||||||
|
|
||||||
|
if ( $this->isFolder && $this->type !== "folder-parent" ) {
|
||||||
|
$code = $this->h5ai->getHttpCode( $this->absHref );
|
||||||
|
$classes .= " checkedHttpCode";
|
||||||
|
if ( $code !== "h5ai" ) {
|
||||||
|
if ( $code === 200 ) {
|
||||||
|
$img = "folder-page";
|
||||||
|
} else {
|
||||||
|
$classes .= " error";
|
||||||
|
$hint = "<span class='hint'> " . $code . " </span>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = "\t<li class='" . $classes . "'>\n";
|
||||||
|
$html .= "\t\t<a href='" . $this->absHref . "'>\n";
|
||||||
|
$html .= "\t\t\t<span class='icon small'><img src='/h5ai/icons/16x16/" . $img . ".png' alt='" . $img . "' /></span>\n";
|
||||||
|
$html .= "\t\t\t<span class='icon big'><img src='/h5ai/icons/48x48/" . $img . ".png' alt='" . $img . "' /></span>\n";
|
||||||
|
$html .= "\t\t\t<span class='label'>" . $this->label . $hint . "</span>\n";
|
||||||
|
$html .= "\t\t\t<span class='date'>" . $dateLabel . "</span>\n";
|
||||||
|
$html .= "\t\t\t<span class='size'>" . $this->formatSize( $this->size ) . "</span>\n";
|
||||||
|
$html .= "\t\t</a>\n";
|
||||||
|
$html .= "\t</li>\n";
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function formatSize( $size ) {
|
||||||
|
|
||||||
|
$units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
|
||||||
|
for ( $i = 0; $size >= 1024 && $i < 4; $i++ ) {
|
||||||
|
$size /= 1024;
|
||||||
|
}
|
||||||
|
return round( $size, 0 ) . " " . $units[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 = dirname( $this->h5ai->getAbsPath() );
|
||||||
|
$parentHref = dirname( $this->h5ai->getAbsHref() );
|
||||||
|
$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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cmpEntries( $p1, $p2 ) {
|
||||||
|
|
||||||
|
return $p1->compare( $p2, $this->h5ai->getSortOrder() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sort() {
|
||||||
|
|
||||||
|
uasort( $this->content, array( $this, "cmpEntries" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFolderCount() {
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
foreach( $this->content as $entry ) {
|
||||||
|
if ( $entry->isFolder() ) {
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFileCount() {
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
foreach( $this->content as $entry ) {
|
||||||
|
if ( !$entry->isFolder() ) {
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
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( $this->h5ai->getDateFormat() );
|
||||||
|
}
|
||||||
|
foreach( $this->content as $entry ) {
|
||||||
|
$html .= $entry->toHtml( $this->h5ai->getDateFormat() );
|
||||||
|
}
|
||||||
|
$html .= "</ul>\n";
|
||||||
|
if ( count( $this->content ) === 0 ) {
|
||||||
|
$html .= "<div class='empty l10n-empty'>empty</div>";
|
||||||
|
}
|
||||||
|
$html .="</section>";
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateHeaders() {
|
||||||
|
|
||||||
|
$asc = "<img src='/h5ai/images/ascending.png' class='sort' alt='ascending' />";
|
||||||
|
$desc = "<img src='/h5ai/images/descending.png' class='sort' alt='descending' />";
|
||||||
|
|
||||||
|
$so = $this->h5ai->getSortOrder();
|
||||||
|
$order = $so["ascending"] ? $asc : $desc;
|
||||||
|
$nameHref = "?col=name" . ( $so["column"] === "name" && $so["ascending"] ? "&asc=false" : "&asc=true" );
|
||||||
|
$dateHref = "?col=date" . ( $so["column"] === "date" && $so["ascending"] ? "&asc=false" : "&asc=true" );
|
||||||
|
$sizeHref = "?col=size" . ( $so["column"] === "size" && $so["ascending"] ? "&asc=false" : "&asc=true" );
|
||||||
|
$nameSort = $so["column"] === "name" ? $order : "";
|
||||||
|
$dateSort = $so["column"] === "date" ? $order : "";
|
||||||
|
$sizeSort = $so["column"] === "size" ? $order : "";
|
||||||
|
|
||||||
|
$html = "\t<li class='header'>\n";
|
||||||
|
$html .= "\t\t<a class='icon'></a>\n";
|
||||||
|
$html .= "\t\t<a class='label' href='$nameHref'><span class='l10n-name'>Name</span>$nameSort</a>\n";
|
||||||
|
$html .= "\t\t<a class='date' href='$dateHref'>$dateSort<span class='l10n-lastModified'>Last modified</span></a>\n";
|
||||||
|
$html .= "\t\t<a class='size' href='$sizeHref'>$sizeSort<span class='l10n-size'>Size</span></a>\n";
|
||||||
|
$html .= "\t</li>\n";
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
263
src/h5ai/php/h5ai.php
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "cache.php";
|
||||||
|
|
||||||
|
class H5ai {
|
||||||
|
private static $SORT_ORDER = array( "column" => "name", "ascending" => true );
|
||||||
|
private static $VIEWMODES = array( "details", "icons" );
|
||||||
|
|
||||||
|
private $docRoot, $domain, $options, $types, $cache, $absHref, $absPath, $ignore, $ignoreRE, $sortOrder, $dateFormat, $view;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
|
||||||
|
$this->docRoot = getenv( "DOCUMENT_ROOT" );
|
||||||
|
$this->domain = getenv( "HTTP_HOST" );
|
||||||
|
|
||||||
|
$this->options = $this->loadOptions( $this->docRoot . "/h5ai/options.js" );
|
||||||
|
$this->types = $this->loadTypes( $this->docRoot . "/h5ai/types.txt" );
|
||||||
|
$this->cache = new Cache( $this->docRoot . "/h5ai/cache" );
|
||||||
|
|
||||||
|
$this->absHref = $this->normalizePath( preg_replace( '/\\?.*/', '', getenv( "REQUEST_URI" ) ), true );
|
||||||
|
$this->absPath = $this->normalizePath( $this->docRoot . rawurldecode( $this->absHref ), false );
|
||||||
|
|
||||||
|
$this->ignore = $this->options["options"]["ignore"];
|
||||||
|
$this->ignoreRE = $this->options["options"]["ignoreRE"];
|
||||||
|
$this->sortOrder = array(
|
||||||
|
"column" => array_key_exists( "col", $_REQUEST ) ? $_REQUEST["col"] : H5ai::$SORT_ORDER["column"],
|
||||||
|
"ascending" => array_key_exists( "asc", $_REQUEST ) ? $_REQUEST["asc"] !== "false" : H5ai::$SORT_ORDER["ascending"]
|
||||||
|
);
|
||||||
|
$this->dateFormat = $this->options["options"]["dateFormat"];
|
||||||
|
$this->view = array_key_exists( "view", $_REQUEST ) ? $_REQUEST["view"] : $this->options["options"]["viewmodes"][0];
|
||||||
|
if ( !in_array( $this->view, H5ai::$VIEWMODES ) ) {
|
||||||
|
$this->view = H5ai::$VIEWMODES[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function loadOptions( $file ) {
|
||||||
|
|
||||||
|
$str = file_exists( $file ) ? file_get_contents( $file ) : "";
|
||||||
|
$str = preg_replace( "/\/\*.*?\*\//s", "", $str );
|
||||||
|
|
||||||
|
$optstr = preg_replace( "/^.*h5aiOptions\s*=\s*/s", "", $str );
|
||||||
|
$optstr = preg_replace( "/;.*/s", "", $optstr );
|
||||||
|
$options = json_decode( $optstr, true );
|
||||||
|
|
||||||
|
$langstr = preg_replace( "/^.*h5aiLangs\s*=\s*/s", "", $str );
|
||||||
|
$langstr = preg_replace( "/;.*/s", "", $langstr );
|
||||||
|
$langs = json_decode( $langstr, true );
|
||||||
|
|
||||||
|
return array( "options" => $options, "langs" => $langs );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function loadTypes( $file ) {
|
||||||
|
|
||||||
|
$lines = file( $file );
|
||||||
|
$types = array();
|
||||||
|
foreach( $lines as $line ) {
|
||||||
|
if ( substr( $line, 0, 1 ) === '#' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$types[] = preg_split( "/\s+/", $line );
|
||||||
|
}
|
||||||
|
return $types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocRoot() {
|
||||||
|
|
||||||
|
return $this->docRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDomain() {
|
||||||
|
|
||||||
|
return $this->domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getView() {
|
||||||
|
|
||||||
|
return $this->view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions() {
|
||||||
|
|
||||||
|
return $this->options["options"] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLangs() {
|
||||||
|
|
||||||
|
return $this->options["langs"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAbsHref( $absPath = null, $endWithSlash = true ) {
|
||||||
|
|
||||||
|
if ( $absPath === null ) {
|
||||||
|
return $this->absHref;
|
||||||
|
}
|
||||||
|
return $this->normalizePath( rawurlencode( preg_replace( "!^" . $this->docRoot . "!", "", $absPath ) ), $endWithSlash );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAbsPath( $absHref = null ) {
|
||||||
|
|
||||||
|
if ( $absHref === null ) {
|
||||||
|
return $this->absPath;
|
||||||
|
}
|
||||||
|
return $this->normalizePath( $this->docRoot . rawurldecode( $absHref ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSortOrder() {
|
||||||
|
|
||||||
|
return $this->sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDateFormat() {
|
||||||
|
|
||||||
|
return $this->dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ) {
|
||||||
|
foreach( array_slice( $type, 1 ) as $pattern ) {
|
||||||
|
if ( $this->endsWith( $absPath, $pattern ) ) {
|
||||||
|
return $type[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ignoreThisFile( $file ) {
|
||||||
|
|
||||||
|
# always ignore
|
||||||
|
if ( $file === "." || $file === ".." || $this->startsWith( $file, '.ht' ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( in_array( $file, $this->ignore ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
foreach ( $this->ignoreRE as $re ) {
|
||||||
|
if ( preg_match( $re, $file ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readDir( $path ) {
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
if ( is_dir( $path ) ) {
|
||||||
|
if ( $dir = opendir( $path ) ) {
|
||||||
|
while ( ( $file = readdir( $dir ) ) !== false ) {
|
||||||
|
if ( ! $this->ignoreThisFile( $file ) ) {
|
||||||
|
$content[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir( $dir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel( $absHref ) {
|
||||||
|
|
||||||
|
return $absHref === "/" ? $this->domain : rawurldecode( basename( $absHref ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function normalizePath( $path, $endWithSlash ) {
|
||||||
|
|
||||||
|
return ( $path === "/" ) ? "/" : ( preg_replace( '#/$#', '', $path ) . ( $endWithSlash ? "/" : "" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function startsWith( $sequence, $start ) {
|
||||||
|
|
||||||
|
return substr( $sequence, 0, strlen( $start ) ) === $start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function endsWith( $sequence, $end ) {
|
||||||
|
|
||||||
|
return substr( $sequence, -strlen( $end ) ) === $end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHttpCode( $absHref ) {
|
||||||
|
|
||||||
|
return $this->cachedHttpCode( $absHref );
|
||||||
|
#return $this->fetchHttpCode( $absHref );
|
||||||
|
#return $this->guessHttpCode( $absHref );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cachedHttpCode( $absHref ) {
|
||||||
|
|
||||||
|
$cached = $this->cache->get( $absHref );
|
||||||
|
if ( $cached === false ) {
|
||||||
|
$folderStatus = $this->options["options"]["folderStatus"];
|
||||||
|
if ( array_key_exists( $absHref, $folderStatus ) ) {
|
||||||
|
$code = $folderStatus[$absHref];
|
||||||
|
} else {
|
||||||
|
$code = $this->fetchHttpCode( $absHref );
|
||||||
|
}
|
||||||
|
$cached = array( "href" => $absHref, "code" => $code );
|
||||||
|
$this->cache->set( $absHref, $cached );
|
||||||
|
}
|
||||||
|
return $cached["code"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetchHttpCode( $absHref ) {
|
||||||
|
|
||||||
|
$contentType = "Content-Type:";
|
||||||
|
$h5aiContentType = "Content-Type: text/html;h5ai=";
|
||||||
|
$host = getenv( "HTTP_HOST" );
|
||||||
|
$port = getenv( "SERVER_PORT" );
|
||||||
|
$msg = "HEAD $absHref HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n\r\n";
|
||||||
|
|
||||||
|
$errno = "";
|
||||||
|
$errstr = "";
|
||||||
|
$socket = fsockopen( $host, $port, $errno, $errstr, 30 );
|
||||||
|
if( $socket === 0 ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite( $socket, $msg );
|
||||||
|
$content = fgets( $socket );
|
||||||
|
$code = intval( trim( substr( $content, 9, 4 ) ) );
|
||||||
|
if ( $code === 200 ) {
|
||||||
|
while ( ! $this->startsWith( $content, $contentType ) ) {
|
||||||
|
$content = fgets( $socket );
|
||||||
|
}
|
||||||
|
if ( $this->startsWith( $content, $h5aiContentType ) ) {
|
||||||
|
$code = "h5ai";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose( $socket );
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function guessHttpCode( $absHref ) {
|
||||||
|
|
||||||
|
$indexFiles = array( "index.html", "index.cgi", "index.pl", "index.php", "index.xhtml", "index.htm" );
|
||||||
|
$absPath = $this->getAbsPath( $absHref );
|
||||||
|
$files = $this->readDir( $absPath );
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
if ( in_array( $file, $indexFiles ) ) {
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "h5ai";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
23
src/h5ai/php/httpcode.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "h5ai.php";
|
||||||
|
|
||||||
|
function getHttpCodes( $h5ai, $hrefs ) {
|
||||||
|
|
||||||
|
$codes = array();
|
||||||
|
foreach ( $hrefs as $href ) {
|
||||||
|
$href = trim( $href );
|
||||||
|
if ( strlen( $href ) > 0 ) {
|
||||||
|
$codes[$href] = $h5ai->getHttpCode( $href );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$h5ai = new H5ai();
|
||||||
|
$hrefs = preg_split( "/;/", array_key_exists( "hrefs", $_REQUEST ) ? $_REQUEST[ "hrefs" ] : "" );
|
||||||
|
$codes = getHttpCodes( $h5ai, $hrefs );
|
||||||
|
|
||||||
|
echo count( $codes ) === 0 ? "{}" : json_encode( $codes );
|
||||||
|
|
||||||
|
?>
|
15
src/h5ai/php/main.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once "h5ai.php";
|
||||||
|
require_once "crumb.php";
|
||||||
|
require_once "customize.php";
|
||||||
|
require_once "extended.php";
|
||||||
|
require_once "tree.php";
|
||||||
|
|
||||||
|
$h5ai = new H5ai();
|
||||||
|
$crumb = new Crumb( $h5ai );
|
||||||
|
$customize = new Customize( $h5ai );
|
||||||
|
$extended = new Extended( $h5ai );
|
||||||
|
$tree = new Tree( $h5ai );
|
||||||
|
|
||||||
|
?>
|
147
src/h5ai/php/tree.php
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<?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" : "" );
|
||||||
|
$img = $this->type;
|
||||||
|
if ( $this->absHref === "/" ) {
|
||||||
|
$img = "folder-home";
|
||||||
|
}
|
||||||
|
$hint = "";
|
||||||
|
$code = "h5ai";
|
||||||
|
|
||||||
|
if ( $this->isFolder ) {
|
||||||
|
$code = $this->h5ai->getHttpCode( $this->absHref );
|
||||||
|
$classes .= " checkedHttpCode";
|
||||||
|
if ( $code !== "h5ai" ) {
|
||||||
|
if ( $code === 200 ) {
|
||||||
|
$img = "folder-page";
|
||||||
|
$hint = "<span class='hint'><img src='/h5ai/images/page.png' 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='/h5ai/images/tree.png' alt='>' /></span>\n";
|
||||||
|
}
|
||||||
|
$html .= "<a href='" . $this->absHref . "'>\n";
|
||||||
|
$html .= "<span class='icon'><img src='/h5ai/icons/16x16/" . $img . ".png' alt='" . $img . "' /></span>\n";
|
||||||
|
$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, dirname( $this->absPath ), dirname( $this->absHref ) );
|
||||||
|
$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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
20
src/h5ai/php/treecontent.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ( ! array_key_exists( "href", $_REQUEST ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once "h5ai.php";
|
||||||
|
require_once "tree.php";
|
||||||
|
|
||||||
|
$h5ai = new H5ai();
|
||||||
|
|
||||||
|
$absHref = trim( $_REQUEST[ "href" ] );
|
||||||
|
$absPath = $h5ai->getAbsPath( $absHref );
|
||||||
|
|
||||||
|
$tree = new TreeEntry( $h5ai, $absPath, $absHref );
|
||||||
|
$tree->loadContent();
|
||||||
|
|
||||||
|
echo $tree->contentToHtml();
|
||||||
|
|
||||||
|
?>
|
63
src/h5ai/types.txt
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
archive .tar.gz .tgz .tar.bz2
|
||||||
|
audio .mp3 .wav .ogg
|
||||||
|
authors AUTHORS authors
|
||||||
|
bin .so .o .class
|
||||||
|
blank
|
||||||
|
bmp .bmp
|
||||||
|
c .c
|
||||||
|
calc
|
||||||
|
cd .iso .cue
|
||||||
|
copying COPYING copying LICENSE license
|
||||||
|
cpp .cpp
|
||||||
|
css .css .less
|
||||||
|
deb .deb
|
||||||
|
default
|
||||||
|
doc .doc
|
||||||
|
draw
|
||||||
|
eps
|
||||||
|
exe .exe
|
||||||
|
folder
|
||||||
|
folder-home
|
||||||
|
folder-open
|
||||||
|
folder-page
|
||||||
|
folder-parent
|
||||||
|
gif .gif
|
||||||
|
gzip .gz
|
||||||
|
h .h
|
||||||
|
hpp .hpp
|
||||||
|
html .html .htm .shtml
|
||||||
|
ico .ico
|
||||||
|
image .xpm
|
||||||
|
install INSTALL install
|
||||||
|
java .java
|
||||||
|
jpg .jpg .jpeg
|
||||||
|
js .js .json
|
||||||
|
log .log CHANGELOG changelog LOG log
|
||||||
|
makefile .pom pom.xml build.xml
|
||||||
|
package
|
||||||
|
pdf .pdf
|
||||||
|
php .php
|
||||||
|
playlist .m3u
|
||||||
|
png .png
|
||||||
|
pres
|
||||||
|
psd
|
||||||
|
py .py
|
||||||
|
rar .rar
|
||||||
|
rb .rb
|
||||||
|
readme README readme
|
||||||
|
rpm .rpm
|
||||||
|
rss .rss
|
||||||
|
rtf .rtf
|
||||||
|
script .conf .ini .sh .shar .csh .ksh .tcl
|
||||||
|
source
|
||||||
|
sql
|
||||||
|
tar .tar
|
||||||
|
tex .tex
|
||||||
|
text .txt .text .md .markdown
|
||||||
|
tiff .tiff
|
||||||
|
unknown
|
||||||
|
vcal .vcal
|
||||||
|
video
|
||||||
|
xml .xml
|
||||||
|
zip .zip .Z .z .jar .war .bz2
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################
|
################################
|
||||||
# %BUILD_NAME% %BUILD_VERSION%
|
# %BUILD_NAME% %BUILD_VERSION% (js)
|
||||||
# customized .htaccess
|
# customized .htaccess
|
||||||
################################
|
################################
|
||||||
|
|
||||||
|
@ -8,23 +8,6 @@
|
||||||
# Options +FollowSymLinks
|
# Options +FollowSymLinks
|
||||||
|
|
||||||
|
|
||||||
<IfModule headers_module>
|
|
||||||
|
|
||||||
################################
|
|
||||||
# cache images for 52 weeks
|
|
||||||
################################
|
|
||||||
|
|
||||||
<FilesMatch "\.png$">
|
|
||||||
Header set Cache-Control "max-age=31449600, public"
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
|
|
||||||
################################
|
|
||||||
# style auto index
|
|
||||||
################################
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# IMPORTANT FOR XAMPP
|
# IMPORTANT FOR XAMPP
|
||||||
# if you're running XAMPP you might need to replace the
|
# if you're running XAMPP you might need to replace the
|
||||||
|
@ -33,13 +16,6 @@
|
||||||
################################
|
################################
|
||||||
<IfModule autoindex_module>
|
<IfModule autoindex_module>
|
||||||
|
|
||||||
################################
|
|
||||||
# uncomment the following line to force directory listing
|
|
||||||
# even for directories with valid index files
|
|
||||||
################################
|
|
||||||
|
|
||||||
# DirectoryIndex IGNORE-DEFAULT-INDEX-FILES
|
|
||||||
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# h5ai header and footer
|
# h5ai header and footer
|
||||||
|
@ -81,7 +57,7 @@
|
||||||
# icon mapping
|
# icon mapping
|
||||||
################################
|
################################
|
||||||
|
|
||||||
AddIcon /h5ai/icons/16x16/parent.png ..
|
AddIcon /h5ai/icons/16x16/folder-parent.png ..
|
||||||
AddIcon /h5ai/icons/16x16/folder.png ^^DIRECTORY^^
|
AddIcon /h5ai/icons/16x16/folder.png ^^DIRECTORY^^
|
||||||
AddIcon /h5ai/icons/16x16/blank.png ^^BLANKICON^^
|
AddIcon /h5ai/icons/16x16/blank.png ^^BLANKICON^^
|
||||||
|
|
||||||
|
@ -144,3 +120,4 @@
|
||||||
|
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
|
|
29
src/php.htaccess
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
################################
|
||||||
|
# %BUILD_NAME% %BUILD_VERSION% (php)
|
||||||
|
# customized .htaccess
|
||||||
|
################################
|
||||||
|
|
||||||
|
|
||||||
|
# Options +Indexes
|
||||||
|
# Options +FollowSymLinks
|
||||||
|
|
||||||
|
|
||||||
|
################################
|
||||||
|
# IMPORTANT FOR XAMPP
|
||||||
|
# if you're running XAMPP you might need to replace the
|
||||||
|
# following line with
|
||||||
|
# <IfModule autoindex_color_module>
|
||||||
|
################################
|
||||||
|
<IfModule autoindex_module>
|
||||||
|
|
||||||
|
HeaderName /h5ai/header.php
|
||||||
|
ReadmeName /h5ai/footer.php
|
||||||
|
|
||||||
|
IndexIgnore *
|
||||||
|
|
||||||
|
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
||||||
|
IndexOptions Charset=UTF-8
|
||||||
|
IndexOptions SuppressHTMLPreamble
|
||||||
|
|
||||||
|
</IfModule>
|
||||||
|
|