Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8e21a3c038 | ||
|
df30c67ade | ||
|
2d3b0eed4f | ||
|
a371ee2afd | ||
|
480c4aab79 | ||
|
745bff09cb | ||
|
7d6ced78da | ||
|
b9835ebaad | ||
|
8da046d550 | ||
|
e5b7ee6125 | ||
|
e70d9029d2 | ||
|
b561082bca | ||
|
ae464169a6 | ||
|
0f681930b3 | ||
|
5db74d054f |
2
.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
# Build folders to ignore
|
||||
bin
|
||||
build
|
||||
#target
|
||||
target
|
||||
|
||||
build.local.*
|
||||
|
||||
|
155
README.md
@@ -1,42 +1,105 @@
|
||||
# h5ai v0.11   ·   a beautified Apache index
|
||||
# h5ai
|
||||
|
||||
h5ai tries to make browsing files on a Apache HTTP server more comfortable. It makes use of the
|
||||
built-in autoindex module of Apache and adds styles and functionality to the page generated by
|
||||
this module.
|
||||
For installation instructions and documentation have a look at the [project page](http://larsjung.de/h5ai).
|
||||
There is also a [sample folder](http://larsjung.de/h5ai/sample).
|
||||
* Website with download, docs and demo: <http://larsjung.de/h5ai>
|
||||
* Sources: <http://github.com/lrsjng/h5ai>
|
||||
|
||||
[h5ai](http://larsjung.de/h5ai) is provided under the terms of the MIT License.
|
||||
It uses
|
||||
[HTML5 Boilerplate](http://html5boilerplate.com),
|
||||
[jQuery](http://jquery.com),
|
||||
[Modernizr](http://www.modernizr.com) and
|
||||
[Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-173323228),
|
||||
please respect their rights.
|
||||
h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h5ai/blob/master/LICENSE.txt).
|
||||
It uses the [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-173323228) (GPL license).
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
### v0.11
|
||||
*2011-07-27*
|
||||
|
||||
### v0.15.1 · *2011-09-06*
|
||||
|
||||
* fixed security issues with the zipped download feature
|
||||
* made zipped download optional (but enabled by default)
|
||||
|
||||
|
||||
### v0.15 · *2011-09-04*
|
||||
|
||||
* added zipped download for selected files
|
||||
* cleaned and refactored
|
||||
|
||||
|
||||
### v0.14.1 · *2011-09-01*
|
||||
|
||||
* display meta information in bottom bar (icon view)
|
||||
* added zh-cn translation by [Dongsheng Cai](http://github.com/dongsheng)
|
||||
* added pl translation by Radosław Zając
|
||||
* added ru translation by Богдан Илюхин
|
||||
|
||||
|
||||
### v0.14 · *2011-08-16*
|
||||
|
||||
* added image thumbnails for PHP version
|
||||
* new option `slideTree` to turn off auto slide in
|
||||
|
||||
|
||||
### v0.13.2 · *2011-08-12*
|
||||
|
||||
* changes in `/h5ai/.htaccess` ... PHP configuration ...
|
||||
|
||||
|
||||
### v0.13.1 · *2011-08-12*
|
||||
|
||||
* ~~hopefully fixed that PHP doesn't get interpreted~~ :/
|
||||
* fixed initial tree display
|
||||
* added sort order option
|
||||
* added/fixed some translations
|
||||
* added lv translation by Sandis Veinbergs
|
||||
|
||||
|
||||
### v0.13 · *2011-08-06*
|
||||
|
||||
* 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.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
|
||||
|
||||
|
||||
### v0.12.1 · *2011-07-29*
|
||||
|
||||
* fixed unchecked use of console.log
|
||||
|
||||
|
||||
### v0.12 · *2011-07-28*
|
||||
|
||||
* improved performance
|
||||
|
||||
|
||||
### v0.11 · *2011-07-27*
|
||||
|
||||
* changed license to MIT license, see `LICENSE.txt`
|
||||
|
||||
|
||||
### v0.10.2
|
||||
*2011-07-26*
|
||||
### v0.10.2 · *2011-07-26*
|
||||
|
||||
* improved tree scrollbar
|
||||
|
||||
|
||||
### v0.10.1
|
||||
*2011-07-24*
|
||||
### v0.10.1 · *2011-07-24*
|
||||
|
||||
* fixed problems with ' in links
|
||||
|
||||
|
||||
### v0.10
|
||||
*2011-07-24*
|
||||
### v0.10 · *2011-07-24*
|
||||
|
||||
* fixed problems with XAMPP on Windows (see `dot.htaccess` comments for instructions)
|
||||
* fixed tree fade-in-fade-out effect for small displays ([issue #6](http://github.com/lrsjng/h5ai/issues/6))
|
||||
@@ -45,8 +108,7 @@ please respect their rights.
|
||||
* added "empty" to localization (hope Google Translate did a good job here)
|
||||
|
||||
|
||||
### v0.9
|
||||
*2011-07-18*
|
||||
### v0.9 · *2011-07-18*
|
||||
|
||||
* linked hover states between crumb, extended view and tree
|
||||
* fixed size of tree view (now there's a ugly scrollbar, hopefully will be fixed)
|
||||
@@ -57,8 +119,7 @@ please respect their rights.
|
||||
* added sv translation by Oscar Carlsson
|
||||
|
||||
|
||||
### v0.8
|
||||
*2011-07-08*
|
||||
### v0.8 · *2011-07-08*
|
||||
|
||||
* removed slashes from folder labels
|
||||
* optionally rename parent folder entries to real folder names, see `options.js`
|
||||
@@ -67,22 +128,19 @@ please respect their rights.
|
||||
* refactored js a lot (again...)
|
||||
|
||||
|
||||
### v0.7
|
||||
*2011-07-07*
|
||||
### v0.7 · *2011-07-07*
|
||||
|
||||
* removed shadows
|
||||
* smarter tree side bar
|
||||
|
||||
|
||||
### v0.6
|
||||
*2011-07-05*
|
||||
### v0.6 · *2011-07-05*
|
||||
|
||||
* refactored js
|
||||
* added localization, see `options.js`
|
||||
|
||||
|
||||
### v0.5.3
|
||||
*2011-07-04*
|
||||
### v0.5.3 · *2011-07-04*
|
||||
|
||||
* refactored js
|
||||
* added basic options support via `options.js`
|
||||
@@ -90,28 +148,24 @@ please respect their rights.
|
||||
* optional tree sidebar
|
||||
|
||||
|
||||
### v0.5.2
|
||||
*2011-07-02*
|
||||
### v0.5.2 · *2011-07-02*
|
||||
|
||||
* details view adjusts to window width
|
||||
* 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
|
||||
|
||||
|
||||
### v0.5
|
||||
*2011-07-01*
|
||||
### v0.5 · *2011-07-01*
|
||||
|
||||
* added tree sidebar
|
||||
* some refactorings
|
||||
|
||||
|
||||
### v0.4
|
||||
*2011-06-27*
|
||||
### v0.4 · *2011-06-27*
|
||||
|
||||
* added better fallback, in case JavaScript is disabled
|
||||
* rewrote js, fixed middle-button click etc. problems
|
||||
@@ -120,23 +174,20 @@ please respect their rights.
|
||||
* updated dot.access
|
||||
|
||||
|
||||
### v0.3.2
|
||||
*2011-06-24*
|
||||
### v0.3.2 · *2011-06-24*
|
||||
|
||||
* removed lib versions from file names
|
||||
* added 'empty' indicator for icons view
|
||||
|
||||
|
||||
### v0.3.1
|
||||
*2011-06-24*
|
||||
### v0.3.1 · *2011-06-24*
|
||||
|
||||
* refactored js
|
||||
* added `folderClick` and `fileClick` callback hooks
|
||||
* fixed .emtpy style
|
||||
|
||||
|
||||
### v0.3
|
||||
*2011-06-23*
|
||||
### v0.3 · *2011-06-23*
|
||||
|
||||
* included build stuff, files previously found in the base directory are now located in folder `target`
|
||||
* styles and scripts are now minified
|
||||
@@ -144,23 +195,20 @@ please respect their rights.
|
||||
* updated jQuery to version 1.6.1
|
||||
|
||||
|
||||
### v0.2.3
|
||||
*2011-06-17*
|
||||
### v0.2.3 · *2011-06-17*
|
||||
|
||||
* more refactoring in main.js
|
||||
* ~~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
|
||||
* 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
|
||||
|
||||
|
||||
### v0.2.1
|
||||
*2011-06-16*
|
||||
### v0.2.1 · *2011-06-16*
|
||||
|
||||
* fixed croped filenames
|
||||
* fixed missing .png extension in header
|
||||
@@ -168,8 +216,7 @@ please respect their rights.
|
||||
* added changelog
|
||||
|
||||
|
||||
### v0.2
|
||||
*2011-06-15*
|
||||
### v0.2 · *2011-06-15*
|
||||
|
||||
* added icon view
|
||||
|
||||
|
@@ -3,7 +3,7 @@ custom = true
|
||||
|
||||
# project
|
||||
project.name = h5ai
|
||||
project.version = 0.11
|
||||
project.version = 0.15.1
|
||||
|
||||
|
||||
# src
|
||||
@@ -11,7 +11,8 @@ src.dir = src
|
||||
|
||||
|
||||
# build
|
||||
build.dir = target
|
||||
build.dir = build
|
||||
release.dir = release
|
||||
|
||||
|
||||
# libs
|
||||
|
116
build.xml
@@ -1,59 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project
|
||||
name="h5ai"
|
||||
basedir="."
|
||||
default="build"
|
||||
xmlns:scripp="antlib:de.larsjung.scripp.ant"
|
||||
name="h5ai"
|
||||
basedir="."
|
||||
default="release"
|
||||
xmlns:scripp="antlib:de.larsjung.scripp.ant"
|
||||
>
|
||||
<target name="init">
|
||||
<property file="build.properties" />
|
||||
<tstamp>
|
||||
<format property="build.stamp" pattern="yyyy-MM-dd-HHmmss" />
|
||||
</tstamp>
|
||||
<property name="build.label" value="${project.name} ${project.version} b${build.stamp}" />
|
||||
<echo>Build: ${build.label}</echo>
|
||||
<target name="init">
|
||||
<property file="build.properties" />
|
||||
<tstamp>
|
||||
<format property="build.stamp" pattern="yyyy-MM-dd-HHmmss" />
|
||||
</tstamp>
|
||||
<property name="build.label" value="${project.name} ${project.version} b${build.stamp}" />
|
||||
<echo>Build: ${build.label}</echo>
|
||||
<taskdef
|
||||
resource="de/larsjung/scripp/ant/antlib.xml"
|
||||
uri="antlib:de.larsjung.scripp.ant"
|
||||
classpath="${lib.scripp.jar}"
|
||||
resource="de/larsjung/scripp/ant/antlib.xml"
|
||||
uri="antlib:de.larsjung.scripp.ant"
|
||||
classpath="${lib.scripp.jar}"
|
||||
/>
|
||||
</target>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="clean" depends="init">
|
||||
<delete dir="${build.dir}" />
|
||||
</target>
|
||||
<target name="clean" depends="init">
|
||||
<delete dir="${build.dir}" />
|
||||
<delete dir="${release.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="build" depends="clean">
|
||||
<mkdir dir="${build.dir}" />
|
||||
<copy todir="${build.dir}">
|
||||
<fileset dir="${src.dir}" />
|
||||
</copy>
|
||||
<replace dir="${build.dir}">
|
||||
<replacefilter token="%BUILD%" value="${build.label}" />
|
||||
<replacefilter token="%BUILD_NAME%" value="${project.name}" />
|
||||
<replacefilter token="%BUILD_VERSION%" value="${project.version}" />
|
||||
<replacefilter token="%BUILD_STAMP%" value="${build.stamp}" />
|
||||
</replace>
|
||||
|
||||
<scripp.dir dir="${build.dir}/h5ai/css" />
|
||||
<scripp.dir dir="${build.dir}/h5ai/js" />
|
||||
</target>
|
||||
<target name="build-prepare" depends="clean">
|
||||
<mkdir dir="${build.dir}" />
|
||||
<copy todir="${build.dir}">
|
||||
<fileset dir="${src.dir}" />
|
||||
<fileset file="LICENSE.txt" />
|
||||
<fileset file="README.md" />
|
||||
</copy>
|
||||
<replace dir="${build.dir}">
|
||||
<replacefilter token="%BUILD%" value="${build.label}" />
|
||||
<replacefilter token="%BUILD_NAME%" value="${project.name}" />
|
||||
<replacefilter token="%BUILD_VERSION%" value="${project.version}" />
|
||||
<replacefilter token="%BUILD_STAMP%" value="${build.stamp}" />
|
||||
</replace>
|
||||
</target>
|
||||
|
||||
|
||||
<macrodef name="scripp.dir">
|
||||
<attribute name="dir" />
|
||||
<sequential>
|
||||
<scripp:process>
|
||||
<fileset dir="@{dir}" includes="**/*.less,**/*.css,**/*.js" excludes="inc/**/*,**/*.min.css,**/*.min.js" />
|
||||
<globmapper from="*.less" to="*.css" />
|
||||
<globmapper from="*.css" to="*.css" />
|
||||
<globmapper from="*.js" to="*.js" />
|
||||
</scripp:process>
|
||||
<delete dir="@{dir}/inc">
|
||||
<fileset dir="@{dir}" includes="**/*.less" />
|
||||
</delete>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<target name="build" depends="build-prepare">
|
||||
<scripp.dir dir="${build.dir}/h5ai/css" />
|
||||
<scripp.dir dir="${build.dir}/h5ai/js" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="build-uncompressed" depends="build-prepare">
|
||||
<scripp.dir dir="${build.dir}/h5ai/css" compress="false" />
|
||||
<scripp.dir dir="${build.dir}/h5ai/js" compress="false" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="release" depends="build">
|
||||
<mkdir dir="${release.dir}" />
|
||||
<zip destfile="${release.dir}/${project.name}-${project.version}.zip" basedir="${build.dir}" />
|
||||
<tar destfile="${release.dir}/${project.name}-${project.version}.tar" basedir="${build.dir}"/>
|
||||
<gzip destfile="${release.dir}/${project.name}-${project.version}.tar.gz" src="${release.dir}/${project.name}-${project.version}.tar"/>
|
||||
<delete file="${release.dir}/${project.name}-${project.version}.tar" />
|
||||
</target>
|
||||
|
||||
|
||||
<macrodef name="scripp.dir">
|
||||
<attribute name="dir" />
|
||||
<attribute name="compress" default="true" />
|
||||
<sequential>
|
||||
<scripp:process compress="@{compress}">
|
||||
<fileset dir="@{dir}" includes="**/*.less,**/*.css,**/*.js" excludes="inc/**/*,**/*.min.css,**/*.min.js" />
|
||||
<globmapper from="*.less" to="*.css" />
|
||||
<globmapper from="*.css" to="*.css" />
|
||||
<globmapper from="*.js" to="*.js" />
|
||||
</scripp:process>
|
||||
<delete dir="@{dir}/inc">
|
||||
<fileset dir="@{dir}" includes="**/*.less" />
|
||||
</delete>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</project>
|
||||
|
BIN
release/h5ai-0.15.1.tar.gz
Normal file
BIN
release/h5ai-0.15.1.zip
Normal file
146
src/dot.htaccess
@@ -1,146 +0,0 @@
|
||||
################################
|
||||
# %BUILD_NAME% %BUILD_VERSION%
|
||||
# customized .htaccess
|
||||
################################
|
||||
|
||||
|
||||
# Options +Indexes
|
||||
# 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
|
||||
# if you're running XAMPP you might need to replace the
|
||||
# following line with
|
||||
# <IfModule autoindex_color_module>
|
||||
################################
|
||||
<IfModule autoindex_module>
|
||||
|
||||
################################
|
||||
# uncomment the following line to force directory listing
|
||||
# even for directories with valid index files
|
||||
################################
|
||||
|
||||
# DirectoryIndex IGNORE-DEFAULT-INDEX-FILES
|
||||
|
||||
|
||||
################################
|
||||
# h5ai header and footer
|
||||
################################
|
||||
|
||||
HeaderName /h5ai/header.html
|
||||
ReadmeName /h5ai/footer.html
|
||||
|
||||
|
||||
################################
|
||||
# hide h5ai folder and config files from index
|
||||
################################
|
||||
|
||||
IndexIgnore h5ai h5ai.header.html h5ai.footer.html
|
||||
|
||||
|
||||
################################
|
||||
# table options
|
||||
################################
|
||||
|
||||
IndexOrderDefault Ascending Name
|
||||
|
||||
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
||||
IndexOptions Charset=UTF-8
|
||||
IndexOptions FancyIndexing
|
||||
IndexOptions HTMLTable
|
||||
IndexOptions XHTML
|
||||
IndexOptions SuppressHTMLPreamble
|
||||
IndexOptions SuppressRules
|
||||
IndexOptions SuppressDescription
|
||||
IndexOptions FoldersFirst
|
||||
IndexOptions IgnoreCase
|
||||
IndexOptions IconsAreLinks
|
||||
IndexOptions VersionSort
|
||||
IndexOptions NameWidth=*
|
||||
|
||||
|
||||
################################
|
||||
# icon mapping
|
||||
################################
|
||||
|
||||
AddIcon /h5ai/icons/16x16/parent.png ..
|
||||
AddIcon /h5ai/icons/16x16/folder.png ^^DIRECTORY^^
|
||||
AddIcon /h5ai/icons/16x16/blank.png ^^BLANKICON^^
|
||||
|
||||
AddIcon /h5ai/icons/16x16/readme.png README
|
||||
AddIcon /h5ai/icons/16x16/copying.png COPYING LICENSE
|
||||
AddIcon /h5ai/icons/16x16/install.png INSTALL
|
||||
AddIcon /h5ai/icons/16x16/authors.png AUTHORS
|
||||
AddIcon /h5ai/icons/16x16/log.png LOG Log log
|
||||
|
||||
AddIcon /h5ai/icons/16x16/css.png .less
|
||||
AddIcon /h5ai/icons/16x16/script.png .conf .ini .sh .shar .csh .ksh .tcl
|
||||
AddIcon /h5ai/icons/16x16/makefile.png .pom pom.xml build.xml
|
||||
AddIcon /h5ai/icons/16x16/bin.png .so .o
|
||||
|
||||
AddIcon /h5ai/icons/16x16/archive.png .tar.gz .tgz .tar.bz2
|
||||
AddIcon /h5ai/icons/16x16/zip.png .zip .Z .z .jar .war .gz .bz2
|
||||
AddIcon /h5ai/icons/16x16/tar.png .tar
|
||||
AddIcon /h5ai/icons/16x16/pdf.png .pdf
|
||||
AddIcon /h5ai/icons/16x16/deb.png .deb
|
||||
AddIcon /h5ai/icons/16x16/rpm.png .rpm
|
||||
AddIcon /h5ai/icons/16x16/cd.png .iso .cue
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/png.png image/png
|
||||
AddIconByType /h5ai/icons/16x16/jpg.png image/jpeg
|
||||
AddIconByType /h5ai/icons/16x16/gif.png image/gif
|
||||
AddIconByType /h5ai/icons/16x16/ico.png image/x-icon
|
||||
AddIconByType /h5ai/icons/16x16/bmp.png image/x-ms-bmp
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/html.png text/html
|
||||
AddIconByType /h5ai/icons/16x16/css.png text/css
|
||||
AddIconByType /h5ai/icons/16x16/xml.png application/xml
|
||||
AddIconByType /h5ai/icons/16x16/js.png application/javascript application/json
|
||||
AddIconByType /h5ai/icons/16x16/php.png application/x-httpd-php
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/py.png text/x-python
|
||||
AddIconByType /h5ai/icons/16x16/rb.png application/x-ruby
|
||||
AddIconByType /h5ai/icons/16x16/java.png text/x-java
|
||||
AddIconByType /h5ai/icons/16x16/cpp.png text/x-c++src
|
||||
AddIconByType /h5ai/icons/16x16/hpp.png text/x-c++hdr
|
||||
AddIconByType /h5ai/icons/16x16/c.png text/x-csrc
|
||||
AddIconByType /h5ai/icons/16x16/h.png text/x-chdr
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/pdf.png application/pdf
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/rtf.png text/rtf application/rtf
|
||||
AddIconByType /h5ai/icons/16x16/tex.png text/x-tex
|
||||
AddIconByType /h5ai/icons/16x16/makefile.png text/x-makefile
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/bin.png application/java-vm
|
||||
AddIconByType /h5ai/icons/16x16/exe.png application/x-executable application/x-msdos-program
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/text.png text/*
|
||||
AddIconByType /h5ai/icons/16x16/image.png image/*
|
||||
AddIconByType /h5ai/icons/16x16/audio.png audio/*
|
||||
AddIconByType /h5ai/icons/16x16/video.png video/*
|
||||
|
||||
AddIconByEncoding /h5ai/icons/16x16/zip.png x-compress x-gzip x-bzip2
|
||||
|
||||
DefaultIcon /h5ai/icons/16x16/unknown.png
|
||||
|
||||
</IfModule>
|
||||
|
35
src/h5ai/.htaccess
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
AddType text/html .php
|
||||
|
||||
|
||||
###########################################
|
||||
# if php doesn't get interpreted try to
|
||||
# uncomment one of the following lines
|
||||
###########################################
|
||||
#AddHandler application/x-httpd-php .php
|
||||
#AddHandler application/x-httpd-php5 .php
|
||||
#AddHandler application/x-httpd-php52 .php
|
||||
#AddHandler application/x-httpd-php53 .php
|
||||
#AddHandler php-script .php
|
||||
#AddHandler php5-script .php
|
||||
#AddHandler php52-script .php
|
||||
#AddHandler php53-script .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>
|
||||
<FilesMatch "thumb-.*\.jpg$">
|
||||
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.
|
@@ -1,209 +1,265 @@
|
||||
|
||||
#extended.details-view {
|
||||
display: none;
|
||||
display: none;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
clear: both;
|
||||
li {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
clear: both;
|
||||
|
||||
&.header {
|
||||
a, a:active, a:visited {
|
||||
padding-bottom: 18px;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
opacity: 0.4;
|
||||
cursor: pointer;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&:hover {
|
||||
color: #555;
|
||||
opacity: 0.9;
|
||||
}
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.entry {
|
||||
border-bottom: 1px solid #ddd;
|
||||
&.header {
|
||||
a, a:active, a:visited {
|
||||
padding-bottom: 18px;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
opacity: 0.4;
|
||||
cursor: pointer;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover, &.hover {
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
margin-left: 12px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
opacity: 1;
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon, .label, .date, .size {
|
||||
padding: 6px;
|
||||
}
|
||||
.icon {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
width: 16px;
|
||||
&:hover {
|
||||
color: #555;
|
||||
opacity: 0.9;
|
||||
}
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.entry {
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.icon.big {
|
||||
display: none;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
margin: 0 270px 0 24px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
.date {
|
||||
position: absolute;
|
||||
right: 100px;
|
||||
top: 0;
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-align: right;
|
||||
width: 80px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
text-align: center;
|
||||
margin: 50px 0;
|
||||
color: #ddd;
|
||||
font-size: 5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #ddd;
|
||||
|
||||
&:hover, &.hover {
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
&.selected {
|
||||
border-color: rgba(240,100,0,0.2);
|
||||
background-color: rgba(240,100,0,0.2);
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
margin-left: 12px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
opacity: 1;
|
||||
background-color: #f6f6f6;
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.folder-parent {
|
||||
.date, .size {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.folder {
|
||||
.size {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon, .label, .date, .size {
|
||||
padding: 6px;
|
||||
}
|
||||
.icon {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
width: 16px;
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.icon.big {
|
||||
display: none;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
margin: 0 270px 0 24px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
.date {
|
||||
position: absolute;
|
||||
right: 100px;
|
||||
top: 0;
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-align: right;
|
||||
width: 80px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&.entry.thumb .icon.small {
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
|
||||
img {
|
||||
background-color: #eee;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #ddd;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
text-align: center;
|
||||
margin: 50px 0;
|
||||
color: #ddd;
|
||||
font-size: 5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#selection-rect {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
border: 1px dashed rgba(240,100,0,0.5);
|
||||
background-color: rgba(240,100,0,0.2);
|
||||
}
|
||||
|
||||
|
||||
#extended.icons-view {
|
||||
display: none;
|
||||
padding: 3px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 15px;
|
||||
display: none;
|
||||
padding: 3px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 15px;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
&.header {
|
||||
display: none;
|
||||
}
|
||||
&.entry {
|
||||
float: left;
|
||||
li {
|
||||
&.header {
|
||||
display: none;
|
||||
}
|
||||
&.entry {
|
||||
float: left;
|
||||
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
margin: 8px;
|
||||
padding: 8px;
|
||||
width: 100px;
|
||||
height: 120px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0,0,0,0);
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
.icon {
|
||||
display: block;
|
||||
a, a:active, a:visited {
|
||||
display: block;
|
||||
margin: 8px;
|
||||
padding: 8px;
|
||||
width: 100px;
|
||||
height: 120px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0,0,0,0);
|
||||
|
||||
img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
.icon.small {
|
||||
display: none;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.date, .size {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
text-decoration: none;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
padding: 0 6px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
padding: 16px;
|
||||
height: 120px;
|
||||
text-align: center;
|
||||
color: #ddd;
|
||||
font-size: 5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
&.selected {
|
||||
border-color: rgba(240,100,0,0.2);
|
||||
background-color: rgba(240,100,0,0.2);
|
||||
}
|
||||
.icon {
|
||||
display: block;
|
||||
|
||||
img {
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
.icon.small {
|
||||
display: none;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.date, .size {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
a, a:active, a:visited {
|
||||
color: #aaa;
|
||||
text-decoration: none;
|
||||
|
||||
.label {
|
||||
.hint {
|
||||
padding: 0 6px;
|
||||
font-size: 0.9em;
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
border-color: #eee;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.entry.thumb .icon.big {
|
||||
width: 100px;
|
||||
height: 58px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
background-color: #eee;
|
||||
min-width: 46px;
|
||||
min-height: 46px;
|
||||
min-width: 12px;
|
||||
min-height: 12px;
|
||||
border: 1px solid #ddd;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
padding: 16px;
|
||||
height: 120px;
|
||||
text-align: center;
|
||||
color: #ddd;
|
||||
font-size: 5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
@@ -53,8 +53,8 @@ sup { top: -0.5em; }
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 15px; }
|
||||
textarea { overflow: auto; }
|
||||
.ie6 legend, .ie7 legend { margin-left: -7px; }
|
||||
textarea { overflow: auto; }
|
||||
.ie6 legend, .ie7 legend { margin-left: -7px; }
|
||||
input[type="radio"] { vertical-align: text-bottom; }
|
||||
input[type="checkbox"] { vertical-align: bottom; }
|
||||
.ie7 input[type="checkbox"] { vertical-align: baseline; }
|
||||
@@ -81,7 +81,7 @@ a:hover { color: #036; }
|
||||
/**
|
||||
* Primary styles
|
||||
*
|
||||
* Author:
|
||||
* Author:
|
||||
*/
|
||||
|
||||
|
||||
@@ -117,20 +117,20 @@ a:hover { color: #036; }
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 480px) {
|
||||
|
||||
|
||||
/* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */
|
||||
}
|
||||
|
||||
|
||||
@media print {
|
||||
* { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important;
|
||||
-ms-filter: none !important; }
|
||||
-ms-filter: none !important; }
|
||||
a, a:visited { color: #444 !important; text-decoration: underline; }
|
||||
a[href]:after { content: " (" attr(href) ")"; }
|
||||
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
||||
thead { display: table-header-group; }
|
||||
thead { display: table-header-group; }
|
||||
tr, img { page-break-inside: avoid; }
|
||||
@page { margin: 0.5cm; }
|
||||
p, h2, h3 { orphans: 3; widows: 3; }
|
||||
|
210
src/h5ai/css/inc/main.less
Normal file
@@ -0,0 +1,210 @@
|
||||
|
||||
@import "html5reset";
|
||||
@import "mixins";
|
||||
|
||||
|
||||
html.js {
|
||||
.hideOnJs {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
html.no-js {
|
||||
.hideOnNoJs {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: Ubuntu, sans-serif;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
margin: 80px 30px;
|
||||
}
|
||||
|
||||
|
||||
body > nav {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
font-size: 0.85em;
|
||||
background-color: rgb(241,241,241);
|
||||
border-bottom: 2px solid rgb(210,210,210);
|
||||
|
||||
span.jsDisabledFallback {
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
color: #999;
|
||||
}
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
.current a {
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: bottom;
|
||||
padding: 0 6px 6px 0;
|
||||
}
|
||||
.crumb {
|
||||
float: left;
|
||||
border-right: 1px solid rgb(231,231,231);
|
||||
.hint {
|
||||
margin-left: 8px;
|
||||
font-style: italic;
|
||||
color: #999;
|
||||
}
|
||||
img.hint {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.view {
|
||||
float: right;
|
||||
border-left: 1px solid rgb(231,231,231);
|
||||
}
|
||||
#download {
|
||||
display: none;
|
||||
float: right;
|
||||
border-left: 1px solid rgb(231,231,231);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#content {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
|
||||
> header {
|
||||
display: none;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 80px;
|
||||
border-bottom: 2px dashed #ddd;
|
||||
}
|
||||
> footer {
|
||||
display: none;
|
||||
padding-top: 10px;
|
||||
margin-top: 80px;
|
||||
border-top: 2px dashed #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@import "table";
|
||||
@import "extended";
|
||||
@import "tree";
|
||||
|
||||
|
||||
body > footer {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 6px 0 8px 0;
|
||||
background-color: rgb(241,241,241);
|
||||
border-top: 2px solid rgb(210,210,210);
|
||||
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
text-align: center;
|
||||
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
color: #e80;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
display: block;
|
||||
padding: 0 8px;
|
||||
float: left
|
||||
}
|
||||
.center {
|
||||
display: block;
|
||||
margin: 0 300px;
|
||||
}
|
||||
.right {
|
||||
display: block;
|
||||
padding: 0 8px;
|
||||
float: right
|
||||
}
|
||||
.status {
|
||||
.sep {
|
||||
display: inline-block;
|
||||
padding: 0 6px;
|
||||
}
|
||||
&.default {
|
||||
}
|
||||
&.dynamic {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,38 +1,38 @@
|
||||
|
||||
.border-radius ( @radius ) {
|
||||
-moz-border-radius: @radius;
|
||||
-webkit-border-radius: @radius;
|
||||
border-radius: @radius;
|
||||
.border-radius (@radius) {
|
||||
-moz-border-radius: @radius;
|
||||
-webkit-border-radius: @radius;
|
||||
border-radius: @radius;
|
||||
}
|
||||
|
||||
|
||||
.box-shadow ( @shadow ) {
|
||||
-moz-box-shadow: @shadow;
|
||||
-webkit-box-shadow: @shadow;
|
||||
box-shadow: @shadow;
|
||||
.box-shadow (@shadow) {
|
||||
-moz-box-shadow: @shadow;
|
||||
-webkit-box-shadow: @shadow;
|
||||
box-shadow: @shadow;
|
||||
}
|
||||
|
||||
|
||||
.transition ( @transition ) {
|
||||
-moz-transition: @transition;
|
||||
-ms-transition: @transition;
|
||||
-o-transition: @transition;
|
||||
-webkit-transition: @transition;
|
||||
transition: @transition;
|
||||
.transition (@transition) {
|
||||
-moz-transition: @transition;
|
||||
-ms-transition: @transition;
|
||||
-o-transition: @transition;
|
||||
-webkit-transition: @transition;
|
||||
transition: @transition;
|
||||
}
|
||||
|
||||
|
||||
.transform ( @transform ) {
|
||||
-moz-transform: @transform;
|
||||
-o-transform: @transform;
|
||||
-webkit-transform: @transform;
|
||||
transform: @transform;
|
||||
.transform (@transform) {
|
||||
-moz-transform: @transform;
|
||||
-o-transform: @transform;
|
||||
-webkit-transform: @transform;
|
||||
transform: @transform;
|
||||
}
|
||||
|
||||
|
||||
.background-size ( @size ) {
|
||||
-moz-background-size: @size;
|
||||
-webkit-background-size: @size;
|
||||
background-size: @size;
|
||||
.background-size (@size) {
|
||||
-moz-background-size: @size;
|
||||
-webkit-background-size: @size;
|
||||
background-size: @size;
|
||||
}
|
||||
|
||||
|
@@ -1,68 +1,68 @@
|
||||
|
||||
#table {
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
th, td {
|
||||
padding: 3px 6px;
|
||||
text-align: left;
|
||||
border: none;
|
||||
}
|
||||
th {
|
||||
padding-bottom: 18px;
|
||||
opacity: 0.4;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
th, td {
|
||||
padding: 3px 6px;
|
||||
text-align: left;
|
||||
border: none;
|
||||
}
|
||||
th {
|
||||
padding-bottom: 18px;
|
||||
opacity: 0.4;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
|
||||
&:hover, &:hover a {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
opacity: 0.9;
|
||||
}
|
||||
a, a:visited {
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
&:hover, &:hover a {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
opacity: 0.9;
|
||||
}
|
||||
a, a:visited {
|
||||
color: #555;
|
||||
font-weight: normal;
|
||||
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
td {
|
||||
border: 1px solid #ddd;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
td:nth-child(1), th:nth-child(1) {
|
||||
text-align: center;
|
||||
width: 16px;
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
td {
|
||||
border: 1px solid #ddd;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
td:nth-child(1), th:nth-child(1) {
|
||||
text-align: center;
|
||||
width: 16px;
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
}
|
||||
td:nth-child(2), th:nth-child(2) {
|
||||
width: 682px;
|
||||
max-width: 682px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
td:nth-child(3), th:nth-child(3) {
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
min-width: 160px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
td:nth-child(4), th:nth-child(4) {
|
||||
text-align: right;
|
||||
width: 70px;
|
||||
min-width: 70px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
}
|
||||
td:nth-child(2), th:nth-child(2) {
|
||||
width: 682px;
|
||||
max-width: 682px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
td:nth-child(3), th:nth-child(3) {
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
min-width: 160px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
td:nth-child(4), th:nth-child(4) {
|
||||
text-align: right;
|
||||
width: 70px;
|
||||
min-width: 70px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,128 +1,129 @@
|
||||
|
||||
#tree {
|
||||
position: fixed;
|
||||
display: none;
|
||||
left: 0;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
font-size: 0.85em;
|
||||
padding: 16px 16px 16px 16px;
|
||||
background-color: rgb(241,241,241);
|
||||
border: 2px solid rgb(210,210,210);
|
||||
border-left: none;
|
||||
.border-radius ( 0 15px 15px 0 );
|
||||
display: none;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 82px;
|
||||
z-index: 1;
|
||||
overflow: auto;
|
||||
font-size: 0.85em;
|
||||
padding: 16px 16px 16px 16px;
|
||||
background-color: rgb(241,241,241);
|
||||
border: 2px solid rgb(210,210,210);
|
||||
border-left: none;
|
||||
.border-radius (0 15px 15px 0);
|
||||
|
||||
> .scrollbar {
|
||||
margin: 12px 12px 12px 0;
|
||||
width: 6px;
|
||||
background-color: rgb(210,210,210);
|
||||
.border-radius( 3px );
|
||||
|
||||
.drag {
|
||||
background-color: rgb(180,180,180);
|
||||
.border-radius( 3px );
|
||||
}
|
||||
&.dragOn .drag {
|
||||
background-color: rgb(150,150,150);
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
.blank, .indicator {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 25px;
|
||||
float: left;
|
||||
}
|
||||
.indicator {
|
||||
opacity: 0.7;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
img {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 3px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
vertical-align: bottom;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
}
|
||||
&.open {
|
||||
img {
|
||||
.transform( rotate(90deg) );
|
||||
}
|
||||
}
|
||||
&.unknown {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
> a, > a:active, > a.visited {
|
||||
margin-left: 16px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid rgba(0,0,0,0);
|
||||
.border-radius( 5px );
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
> .scrollbar {
|
||||
margin: 12px 12px 12px 0;
|
||||
width: 6px;
|
||||
background-color: rgb(210,210,210);
|
||||
.border-radius(3px);
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
.label {
|
||||
display: inline-block;
|
||||
}
|
||||
.icon {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
display: inline-block;
|
||||
margin-left: 12px;
|
||||
font-size: 0.9em;
|
||||
color: #ccc;
|
||||
img {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.file {
|
||||
display: none;
|
||||
}
|
||||
&.current {
|
||||
> a, > a:active, > a:visited {
|
||||
border: 1px solid rgb(221,221,221);
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
> a, > a:active, > a:visited {
|
||||
color: #999;
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
list-style: none;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
.drag {
|
||||
background-color: rgb(180,180,180);
|
||||
.border-radius(3px);
|
||||
}
|
||||
&.dragOn .drag {
|
||||
background-color: rgb(150,150,150);
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
.blank, .indicator {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 25px;
|
||||
float: left;
|
||||
}
|
||||
.indicator {
|
||||
opacity: 0.7;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
img {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 3px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
vertical-align: bottom;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
}
|
||||
&.open {
|
||||
img {
|
||||
.transform(rotate(90deg));
|
||||
}
|
||||
}
|
||||
&.unknown {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
> a, > a:active, > a.visited {
|
||||
margin-left: 16px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid rgba(0,0,0,0);
|
||||
.border-radius(5px);
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
.label {
|
||||
display: inline-block;
|
||||
}
|
||||
.icon {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
display: inline-block;
|
||||
margin-left: 12px;
|
||||
font-size: 0.9em;
|
||||
color: #ccc;
|
||||
img {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.file {
|
||||
display: none;
|
||||
}
|
||||
&.current {
|
||||
> a, > a:active, > a:visited {
|
||||
border: 1px solid rgb(221,221,221);
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.error {
|
||||
> a, > a:active, > a:visited {
|
||||
color: #999;
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
color: #c55;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
list-style: none;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
src/h5ai/css/main-js.less
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
@import "inc/main";
|
||||
|
17
src/h5ai/css/main-php.less
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
@import "inc/main";
|
||||
|
||||
|
||||
#table {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tree, #content > header, #content > footer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
html.no-js {
|
||||
#extended.details-view, #extended.icons-view {
|
||||
display: block;
|
||||
}
|
||||
}
|
@@ -1,158 +0,0 @@
|
||||
|
||||
@import "inc/html5reset";
|
||||
@import "inc/mixins";
|
||||
|
||||
|
||||
html.js {
|
||||
.jsDisabledFallback {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
html.no-js {
|
||||
body > nav ul {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: Ubuntu, sans-serif;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
margin: 80px 30px;
|
||||
}
|
||||
|
||||
|
||||
body > nav {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
font-size: 0.85em;
|
||||
background-color: rgb(241,241,241);
|
||||
border-bottom: 2px solid rgb(210,210,210);
|
||||
|
||||
span.jsDisabledFallback {
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
color: #999;
|
||||
}
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
opacity: 0.7;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
|
||||
&:hover, &.hover {
|
||||
color: #e80;
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
.current a {
|
||||
background-color: rgba(255,255,255,0.5);
|
||||
opacity: 1.0;
|
||||
}
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: bottom;
|
||||
padding: 0 6px 6px 0;
|
||||
}
|
||||
.crumb {
|
||||
float: left;
|
||||
border-right: 1px solid rgb(231,231,231);
|
||||
.hint {
|
||||
margin-left: 8px;
|
||||
font-style: italic;
|
||||
color: #999;
|
||||
}
|
||||
img.hint {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
vertical-align: baseline;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.view {
|
||||
float: right;
|
||||
border-left: 1px solid rgb(231,231,231);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#content {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
|
||||
> header {
|
||||
display: none;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 80px;
|
||||
border-bottom: 2px dashed #ddd;
|
||||
}
|
||||
> footer {
|
||||
display: none;
|
||||
padding-top: 10px;
|
||||
margin-top: 80px;
|
||||
border-top: 2px dashed #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@import "inc/table";
|
||||
@import "inc/extended";
|
||||
@import "inc/tree";
|
||||
|
||||
|
||||
body > footer {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 10px 0;
|
||||
background-color: rgb(241,241,241);
|
||||
border-top: 2px solid rgb(210,210,210);
|
||||
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
text-align: center;
|
||||
|
||||
a, a:active, a:visited {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
.transition( all 0.2s ease-in-out );
|
||||
|
||||
&:hover {
|
||||
color: #e80;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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,23 +1,34 @@
|
||||
<!-- generated code ends here -->
|
||||
</section>
|
||||
<section id="extended"></section>
|
||||
<footer></footer>
|
||||
</section>
|
||||
<section id="tree"></section>
|
||||
<footer>
|
||||
<a id="html5" href="http://www.w3.org/html/logo/" target="_blank" title="HTML5 semantics, storage & CSS3">
|
||||
<img class="logo" src="/h5ai/images/html5.png" alt="html5" />
|
||||
<img class="techclass" src="/h5ai/images/html5-semantics.png" alt="html5-semantics" />
|
||||
<img class="techclass" src="/h5ai/images/html5-storage.png" alt="html5-storage" />
|
||||
<img class="techclass" src="/h5ai/images/html5-css3.png" alt="html5-css3" />
|
||||
</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
|
||||
<span class="l10n-footerUsing">using</span>
|
||||
<a href="http://tiheum.deviantart.com/art/Faenza-Icons-173323228" target="_blank" title="icon theme for Gnome">Faenza icons</a>
|
||||
</footer>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/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/js/main.js"></script>
|
||||
<!-- generated code ends here -->
|
||||
</section>
|
||||
<section id="extended" class="clearfix"></section>
|
||||
<footer></footer>
|
||||
</section>
|
||||
<section id="tree"></section>
|
||||
<footer class="clearfix">
|
||||
<span class="left">
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (js)</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">
|
||||
<span class="hideOnNoJs">
|
||||
<span class="status default">
|
||||
<span class="folderCount"></span> <span class="l10n-folders">folders</span>
|
||||
<span class='sep'>·</span>
|
||||
<span class="fileCount"></span> <span class="l10n-files">files</span>
|
||||
</span>
|
||||
<span class="status dynamic">
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</footer>
|
||||
<script src="/h5ai/js/lib/jquery.min.js"></script>
|
||||
<script src="/h5ai/options.js"></script>
|
||||
<script src="/h5ai/js/main-js.js"></script>
|
||||
</body>
|
||||
</html>
|
4
src/h5ai/footer.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<!-- generated code ends here -->
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
@@ -1,35 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Directory index · styled with h5ai</title>
|
||||
<meta name="h5ai-version" content="h5ai %BUILD_VERSION%">
|
||||
<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.css">
|
||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||
<meta charset="utf-8">
|
||||
<title>Directory index · styled with h5ai</title>
|
||||
<meta name="h5ai-version" content="h5ai %BUILD_VERSION% (js)">
|
||||
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
|
||||
<meta name="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-js.css">
|
||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="clearfix">
|
||||
<span class="jsDisabledFallback">Directory index · JavaScript is disabled</span>
|
||||
<ul>
|
||||
<li id="viewicons" class="view">
|
||||
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-viewIcons">icons</span></a>
|
||||
</li>
|
||||
<li id="viewdetails" class="view" >
|
||||
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-viewDetails">details</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section id="content">
|
||||
<header></header>
|
||||
<section id="table" class="jsDisabledFallback">
|
||||
<!--
|
||||
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
|
||||
removed via javascript. The actual page should render as perfect HTML 5, even if the produced
|
||||
source is not valid HTML 5.
|
||||
-->
|
||||
<div id="selection-rect"></div>
|
||||
<nav class="clearfix">
|
||||
<ul>
|
||||
<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>
|
||||
<li id="download" class="hideOnNoJs">
|
||||
<a href="#"><img src="/h5ai/images/download.png" alt="download" /><span class="l10n-download">download</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section id="content">
|
||||
<header></header>
|
||||
<section id="table" class="hideOnJs">
|
||||
<!--
|
||||
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
|
||||
removed via javascript. The actual page should render as perfect HTML 5, even if the produced
|
||||
source is not valid HTML 5.
|
||||
-->
|
||||
|
63
src/h5ai/header.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<!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>
|
||||
<div id="selection-rect"></div>
|
||||
<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>
|
||||
<li id="download" class="hideOnNoJs">
|
||||
<a href="#"><img src="/h5ai/images/download.png" alt="download" /><span class="l10n-download">download</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">
|
||||
<span class="status default">
|
||||
<?php echo $extended->getFolderCount(); ?> <span class="l10n-folders">folders</span>
|
||||
<span class='sep'>·</span>
|
||||
<?php echo $extended->getFileCount(); ?> <span class="l10n-files">files</span>
|
||||
</span>
|
||||
<span class="status dynamic">
|
||||
</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 |
BIN
src/h5ai/images/download.png
Normal file
After Width: | Height: | Size: 528 B |
Before Width: | Height: | Size: 424 B |
Before Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 811 B |
119
src/h5ai/js/inc/extended.js
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
var Extended = function (pathCache, h5ai) {
|
||||
"use strict";
|
||||
/*global $*/
|
||||
|
||||
var settings = {
|
||||
customHeader: "h5ai.header.html",
|
||||
customFooter: "h5ai.footer.html"
|
||||
},
|
||||
initTitle = function () {
|
||||
|
||||
document.title = document.domain + document.location.pathname;
|
||||
try {
|
||||
document.title = decodeURI(document.title);
|
||||
} catch (err) {}
|
||||
},
|
||||
initBreadcrumb = function () {
|
||||
|
||||
var idx, part,
|
||||
$ul = $("body > nav ul"),
|
||||
pathname = "/",
|
||||
path = pathCache.getPath(pathname),
|
||||
pathnameParts = document.location.pathname.split("/");
|
||||
|
||||
$ul.append(path.updateCrumbHtml());
|
||||
|
||||
for (idx in pathnameParts) {
|
||||
part = pathnameParts[idx];
|
||||
if (part !== "") {
|
||||
pathname += part + "/";
|
||||
$ul.append(pathCache.getPath(pathname).updateCrumbHtml());
|
||||
}
|
||||
}
|
||||
},
|
||||
initExtendedView = function () {
|
||||
|
||||
var $ths = $("#table th"),
|
||||
$label = $ths.eq(1).find("a"),
|
||||
$date = $ths.eq(2).find("a"),
|
||||
$size = $ths.eq(3).find("a"),
|
||||
sortquery = document.location.search,
|
||||
order = {
|
||||
column: (sortquery.indexOf("C=N") >= 0) ? "name" : (sortquery.indexOf("C=M") >= 0) ? "date" : (sortquery.indexOf("C=S") >= 0) ? "size" : h5ai.settings.sortorder.column,
|
||||
ascending: (sortquery.indexOf("O=A") >= 0) ? true : (sortquery.indexOf("O=D") >= 0) ? false : h5ai.settings.sortorder.ascending
|
||||
},
|
||||
$icon, $ul, $li;
|
||||
|
||||
$ul = $("<ul/>");
|
||||
$li = $("<li class='header' />")
|
||||
.appendTo($ul)
|
||||
.append($("<a class='icon'></a>"))
|
||||
.append($("<a class='label' href='" + $label.attr("href") + "'><span class='l10n-name'>" + $label.text() + "</span></a>"))
|
||||
.append($("<a class='date' href='" + $date.attr("href") + "'><span class='l10n-lastModified'>" + $date.text() + "</span></a>"))
|
||||
.append($("<a class='size' href='" + $size.attr("href") + "'><span class='l10n-size'>" + $size.text() + "</span></a>"));
|
||||
|
||||
// header sort icons
|
||||
if (order.ascending) {
|
||||
$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.column === "date") {
|
||||
$li.find("a.date").prepend($icon);
|
||||
} else if (order.column === "size") {
|
||||
$li.find("a.size").prepend($icon);
|
||||
} else {
|
||||
$li.find("a.label").append($icon);
|
||||
}
|
||||
|
||||
// entries
|
||||
$("#table td").closest("tr").each(function () {
|
||||
var path = pathCache.getPath(document.location.pathname, this);
|
||||
$ul.append(path.updateExtendedHtml());
|
||||
});
|
||||
|
||||
$("#extended").append($ul);
|
||||
|
||||
// empty
|
||||
if ($ul.children(".entry:not(.parentfolder)").size() === 0) {
|
||||
$("#extended").append($("<div class='empty l10n-empty'>empty</div>"));
|
||||
}
|
||||
},
|
||||
customize = function () {
|
||||
|
||||
$.ajax({
|
||||
url: settings.customHeader,
|
||||
dataType: "html",
|
||||
success: function (data) {
|
||||
$("#content > header").append($(data)).show();
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: settings.customFooter,
|
||||
dataType: "html",
|
||||
success: function (data) {
|
||||
$("#content > footer").prepend($(data)).show();
|
||||
}
|
||||
});
|
||||
},
|
||||
initCounts = function () {
|
||||
|
||||
$(".folderCount").text($("#extended .entry.folder:not(.parentfolder)").size());
|
||||
$(".fileCount").text($("#extended .entry.file").size());
|
||||
},
|
||||
init = function () {
|
||||
|
||||
initTitle();
|
||||
initBreadcrumb();
|
||||
initExtendedView();
|
||||
customize();
|
||||
initCounts();
|
||||
},
|
||||
extended = {
|
||||
init: init
|
||||
};
|
||||
|
||||
return extended;
|
||||
};
|
@@ -1,319 +1,395 @@
|
||||
|
||||
var H5ai = function ( options, langs, pathCache ) {
|
||||
|
||||
|
||||
/*******************************
|
||||
* config
|
||||
*******************************/
|
||||
|
||||
var defaults = {
|
||||
defaultSortOrder: "C=N;O=A",
|
||||
store: {
|
||||
viewmode: "h5ai.viewmode"
|
||||
},
|
||||
customHeader: "h5ai.header.html",
|
||||
customFooter: "h5ai.footer.html",
|
||||
callbacks: {
|
||||
pathClick: []
|
||||
},
|
||||
|
||||
viewmodes: [ "details", "icons" ],
|
||||
showTree: false,
|
||||
folderStatus: {
|
||||
},
|
||||
lang: undefined,
|
||||
useBrowserLang: true,
|
||||
setParentFolderLabels: true,
|
||||
linkHoverStates: true
|
||||
};
|
||||
this.config = $.extend( {}, defaults, options );
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* public api
|
||||
*******************************/
|
||||
|
||||
this.pathClick = function ( fn ) {
|
||||
|
||||
if ( $.isFunction( fn ) ) {
|
||||
this.config.callbacks.pathClick.push( fn );
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* init
|
||||
*******************************/
|
||||
|
||||
this.init = function () {
|
||||
|
||||
document.title = decodeURI( document.domain + document.location.pathname );
|
||||
|
||||
this.applyViewmode();
|
||||
this.initBreadcrumb();
|
||||
this.initTopSpace();
|
||||
this.initViews();
|
||||
this.customize();
|
||||
this.localize( langs, this.config.lang, this.config.useBrowserLang );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* callback triggers
|
||||
*******************************/
|
||||
|
||||
this.triggerPathClick = function ( path, context ) {
|
||||
|
||||
for ( idx in this.config.callbacks.pathClick ) {
|
||||
this.config.callbacks.pathClick[idx].call( window, path, context );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* local stored viewmode
|
||||
*******************************/
|
||||
|
||||
this.getViewmode = function () {
|
||||
|
||||
var viewmode = localStorage.getItem( this.config.store.viewmode );
|
||||
return $.inArray( viewmode, this.config.viewmodes ) >= 0 ? viewmode : this.config.viewmodes[0];
|
||||
};
|
||||
|
||||
|
||||
this.applyViewmode = function ( viewmode ) {
|
||||
|
||||
if ( viewmode !== undefined ) {
|
||||
localStorage.setItem( this.config.store.viewmode, viewmode );
|
||||
};
|
||||
viewmode = this.getViewmode();
|
||||
|
||||
$( "body > nav li.view" ).hide().removeClass( "current" );
|
||||
|
||||
if ( this.config.viewmodes.length > 1 ) {
|
||||
if ( $.inArray( "details", this.config.viewmodes ) >= 0 ) {
|
||||
$( "#viewdetails" ).show();
|
||||
};
|
||||
if ( $.inArray( "icons", this.config.viewmodes ) >= 0 ) {
|
||||
$( "#viewicons" ).show();
|
||||
};
|
||||
};
|
||||
|
||||
if ( viewmode === "details" ) {
|
||||
$( "#viewdetails" ).closest( "li" ).addClass( "current" );
|
||||
$( "#table" ).hide();
|
||||
$( "#extended" ).addClass( "details-view" ).removeClass( "icons-view" ).show();
|
||||
} else if ( viewmode === "icons" ) {
|
||||
$( "#viewicons" ).closest( "li" ).addClass( "current" );
|
||||
$( "#table" ).hide();
|
||||
$( "#extended" ).removeClass( "details-view" ).addClass( "icons-view" ).show();
|
||||
} else {
|
||||
$( "#table" ).show();
|
||||
$( "#extended" ).hide();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* 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
|
||||
*******************************/
|
||||
|
||||
this.initTopSpace = function () {
|
||||
|
||||
function adjustTopSpace() {
|
||||
|
||||
var winHeight = $( window ).height();
|
||||
var navHeight = $( "body > nav" ).outerHeight();
|
||||
var footerHeight = $( "body > footer" ).outerHeight();
|
||||
var contentSpacing = 50;
|
||||
var treeSpacing = 50;
|
||||
|
||||
$( "body" )
|
||||
.css( "margin-top", "" + ( navHeight + contentSpacing ) + "px" )
|
||||
.css( "margin-bottom", "" + ( footerHeight + contentSpacing ) + "px" );
|
||||
|
||||
$( "#tree" )
|
||||
.css( "top", "" + ( navHeight + treeSpacing ) + "px" )
|
||||
.css( "height", "" + ( winHeight - navHeight - footerHeight - 36 - 2 * treeSpacing ) + "px" );
|
||||
try {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} catch ( err ) {};
|
||||
};
|
||||
|
||||
$( window ).resize( function () {
|
||||
adjustTopSpace();
|
||||
} );
|
||||
adjustTopSpace();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* table view
|
||||
*******************************/
|
||||
|
||||
this.initTableView = function () {
|
||||
|
||||
$( "#table td" ).removeAttr( "align" ).removeAttr( "valign" );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* 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 );
|
||||
};
|
||||
|
||||
// entries
|
||||
$( "#table td" ).closest( "tr" ).each( function () {
|
||||
var path = pathCache.getPathForTableRow( document.location.pathname, this );
|
||||
$ul.append( path.updateExtendedHtml() );
|
||||
} );
|
||||
$( "#table" ).remove();
|
||||
|
||||
$( "#extended" ).append( $ul );
|
||||
|
||||
// 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
|
||||
*******************************/
|
||||
|
||||
this.initViews = function () {
|
||||
|
||||
this.initTableView();
|
||||
this.initExtendedView();
|
||||
|
||||
$( "#viewdetails" ).closest( "li" )
|
||||
.click( $.proxy( function () {
|
||||
this.applyViewmode( "details" );
|
||||
}, this ) );
|
||||
$( "#viewicons" ).closest( "li" )
|
||||
.click( $.proxy( function () {
|
||||
this.applyViewmode( "icons" );
|
||||
}, this ) );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* 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();
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
* localization
|
||||
*******************************/
|
||||
|
||||
this.localize = function ( data, lang, useBrowserLang ) {
|
||||
|
||||
if ( useBrowserLang === true ) {
|
||||
var browserLang = navigator.language;
|
||||
if ( data[ browserLang ] !== undefined ) {
|
||||
lang = browserLang;
|
||||
} else if ( browserLang.length > 2 && data[ browserLang.substr( 0, 2 ) ] !== undefined ) {
|
||||
lang = browserLang.substr( 0, 2 );
|
||||
};
|
||||
};
|
||||
|
||||
if ( lang !== "en" && data[ lang ] !== undefined ) {
|
||||
var selected = data[ lang ];
|
||||
for ( key in selected ) {
|
||||
$( ".l10n-" + key ).text( selected[key] );
|
||||
};
|
||||
};
|
||||
};
|
||||
var H5ai = function (options, langs) {
|
||||
"use strict";
|
||||
/*global $, window, localStorage*/
|
||||
|
||||
var defaults = {
|
||||
store: {
|
||||
viewmode: "h5ai.viewmode",
|
||||
lang: "h5ai.lang"
|
||||
},
|
||||
callbacks: {
|
||||
pathClick: []
|
||||
},
|
||||
|
||||
viewmodes: ["details", "icons"],
|
||||
sortorder: {
|
||||
column: "name",
|
||||
ascending: true
|
||||
},
|
||||
showTree: true,
|
||||
slideTree: true,
|
||||
folderStatus: {},
|
||||
lang: null,
|
||||
useBrowserLang: true,
|
||||
setParentFolderLabels: true,
|
||||
linkHoverStates: true,
|
||||
|
||||
dateFormat: "Y-m-d H:i",
|
||||
ignore: ["h5ai", "h5ai.header.html", "h5ai.footer.html"],
|
||||
ignoreRE: ["/^\\./"],
|
||||
showThumbs: true,
|
||||
|
||||
zippedDownload: true
|
||||
},
|
||||
settings = $.extend({}, defaults, options),
|
||||
pathClick = function (fn) {
|
||||
|
||||
if ($.isFunction(fn)) {
|
||||
settings.callbacks.pathClick.push(fn);
|
||||
}
|
||||
},
|
||||
triggerPathClick = function (path, context) {
|
||||
|
||||
var i, l, a = settings.callbacks.pathClick;
|
||||
|
||||
for (i = 0, l = a.length; i < l; i++) {
|
||||
a[i].call(window, path, context);
|
||||
}
|
||||
},
|
||||
getViewmode = function () {
|
||||
|
||||
var viewmode = localStorage.getItem(settings.store.viewmode);
|
||||
|
||||
return $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
|
||||
},
|
||||
applyViewmode = function (viewmode) {
|
||||
|
||||
if (viewmode) {
|
||||
localStorage.setItem(settings.store.viewmode, viewmode);
|
||||
}
|
||||
viewmode = getViewmode();
|
||||
|
||||
$("#viewdetails,#viewicons").hide().removeClass("current");
|
||||
|
||||
if (settings.viewmodes.length > 1) {
|
||||
if ($.inArray("details", settings.viewmodes) >= 0) {
|
||||
$("#viewdetails").show();
|
||||
}
|
||||
if ($.inArray("icons", settings.viewmodes) >= 0) {
|
||||
$("#viewicons").show();
|
||||
}
|
||||
}
|
||||
|
||||
if (viewmode === "details") {
|
||||
$("#viewdetails").closest("li").addClass("current");
|
||||
$("#extended").addClass("details-view").removeClass("icons-view").show();
|
||||
} else if (viewmode === "icons") {
|
||||
$("#viewicons").closest("li").addClass("current");
|
||||
$("#extended").removeClass("details-view").addClass("icons-view").show();
|
||||
} else {
|
||||
$("#extended").hide();
|
||||
}
|
||||
},
|
||||
initTopSpace = function () {
|
||||
|
||||
var adjustTopSpace = function () {
|
||||
|
||||
var winHeight = $(window).height(),
|
||||
navHeight = $("body > nav").outerHeight(),
|
||||
footerHeight = $("body > footer").outerHeight(),
|
||||
contentSpacing = 50,
|
||||
treeSpacing = 50;
|
||||
|
||||
$("body").css({
|
||||
"margin-top": navHeight + contentSpacing,
|
||||
"margin-bottom": footerHeight + contentSpacing
|
||||
});
|
||||
|
||||
$("#tree").css({
|
||||
top: navHeight + treeSpacing,
|
||||
height: winHeight - navHeight - footerHeight - 36 - 2 * treeSpacing
|
||||
});
|
||||
|
||||
try {
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
$(window).resize(function () {
|
||||
adjustTopSpace();
|
||||
});
|
||||
adjustTopSpace();
|
||||
},
|
||||
initViews = function () {
|
||||
|
||||
$("#table").remove();
|
||||
|
||||
$("#viewdetails").closest("li")
|
||||
.click(function () { applyViewmode("details"); });
|
||||
$("#viewicons").closest("li")
|
||||
.click(function () { applyViewmode("icons"); });
|
||||
|
||||
// status update
|
||||
$("#extended .entry a").hover(
|
||||
function () {
|
||||
if ($("#extended").hasClass("icons-view")) {
|
||||
var $this = $(this);
|
||||
$(".status.default").hide();
|
||||
$(".status.dynamic")
|
||||
.empty()
|
||||
.append($this.find(".label").clone())
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".date").clone())
|
||||
.show();
|
||||
|
||||
if (!$this.closest(".entry").hasClass("folder")) {
|
||||
$(".status.dynamic")
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".size").clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
function () {
|
||||
$(".status.default").show();
|
||||
$(".status.dynamic").empty().hide();
|
||||
}
|
||||
);
|
||||
},
|
||||
shiftTree = function (forceVisible, dontAnimate) {
|
||||
|
||||
var $tree = $("#tree"),
|
||||
$extended = $("#extended");
|
||||
|
||||
if (settings.slideTree && $tree.outerWidth() < $extended.offset().left || forceVisible) {
|
||||
if (dontAnimate) {
|
||||
$tree.stop().css({ left: 0 });
|
||||
} else {
|
||||
$tree.stop().animate({ left: 0 });
|
||||
}
|
||||
} else {
|
||||
if (dontAnimate) {
|
||||
$tree.stop().css({ left: 18 - $tree.outerWidth() });
|
||||
} else {
|
||||
$tree.stop().animate({ left: 18 - $tree.outerWidth() });
|
||||
}
|
||||
}
|
||||
},
|
||||
initTree = function () {
|
||||
|
||||
$("#tree").hover(
|
||||
function () { shiftTree(true); },
|
||||
function () { shiftTree(); }
|
||||
);
|
||||
$(window).resize(function () { shiftTree(); });
|
||||
shiftTree(false, true);
|
||||
},
|
||||
linkHoverStates = function () {
|
||||
|
||||
if (settings.linkHoverStates) {
|
||||
$("a[href^='/']:not(.linkedHoverStates)").each(function () {
|
||||
|
||||
var $a = $(this).addClass("linkedHoverStates"),
|
||||
href = $a.attr("href");
|
||||
|
||||
$a.hover(
|
||||
function () { $("a[href='" + href + "']").addClass("hover"); },
|
||||
function () { $("a[href='" + href + "']").removeClass("hover"); }
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
localize = function (langs, lang, useBrowserLang) {
|
||||
|
||||
var storedLang = localStorage.getItem(settings.store.lang),
|
||||
browserLang, selected, key;
|
||||
|
||||
if (langs[storedLang]) {
|
||||
lang = storedLang;
|
||||
} else if (useBrowserLang) {
|
||||
browserLang = navigator.language;
|
||||
if (langs[browserLang]) {
|
||||
lang = browserLang;
|
||||
} else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
|
||||
lang = browserLang.substr(0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!langs[lang]) {
|
||||
lang = "en";
|
||||
}
|
||||
|
||||
selected = langs[lang];
|
||||
if (selected) {
|
||||
for (key in selected) {
|
||||
$(".l10n-" + key).text(selected[key]);
|
||||
}
|
||||
$(".lang").text(lang);
|
||||
$(".langOption").removeClass("current");
|
||||
$(".langOption." + lang).addClass("current");
|
||||
}
|
||||
},
|
||||
initLangSelector = function (langs) {
|
||||
|
||||
var idx, lang,
|
||||
sortedLangsKeys = [],
|
||||
$ul;
|
||||
|
||||
for (lang in langs) {
|
||||
sortedLangsKeys.push(lang);
|
||||
}
|
||||
sortedLangsKeys.sort();
|
||||
|
||||
$ul = $("<ul />");
|
||||
for (idx in sortedLangsKeys) {
|
||||
(function (lang) {
|
||||
$("<li class='langOption' />")
|
||||
.addClass(lang)
|
||||
.text(lang + " - " + langs[lang].lang)
|
||||
.appendTo($ul)
|
||||
.click(function () {
|
||||
localStorage.setItem(settings.store.lang, lang);
|
||||
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();
|
||||
}
|
||||
);
|
||||
},
|
||||
initIndicators = function () {
|
||||
|
||||
$("#tree .entry.folder:not(.initiatedIndicator)").each(function () {
|
||||
|
||||
var $entry = $(this).addClass("initiatedIndicator"),
|
||||
$indicator = $entry.find("> .indicator");
|
||||
|
||||
$indicator.click(function (event) {
|
||||
|
||||
var $content;
|
||||
|
||||
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();
|
||||
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();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
initZippedDownload = function () {
|
||||
|
||||
var x = 0,
|
||||
y = 0,
|
||||
$window = $(window),
|
||||
selected = function (hrefs) {
|
||||
|
||||
var query, idx;
|
||||
for (idx in hrefs) {
|
||||
query = query ? query + ":" + hrefs[idx] : hrefs[idx];
|
||||
}
|
||||
query = "/h5ai/php/zipcontent.php?hrefs=" + query;
|
||||
$("#download").show().find("a").attr("href", query);
|
||||
},
|
||||
selectionUpdate = function (event) {
|
||||
|
||||
var l = Math.min(x, event.pageX),
|
||||
t = Math.min(y, event.pageY),
|
||||
w = Math.abs(x - event.pageX),
|
||||
h = Math.abs(y - event.pageY),
|
||||
sel;
|
||||
|
||||
event.preventDefault();
|
||||
$("#selection-rect").css({left: l, top: t, width: w, height: h});
|
||||
|
||||
sel = $("#selection-rect").fracs("rect");
|
||||
$("#extended a").removeClass("selected").each(function () {
|
||||
|
||||
var $a = $(this),
|
||||
rect = $a.fracs("rect"),
|
||||
inter = sel.intersection(rect);
|
||||
if (inter && !$a.closest(".entry").hasClass("folder-parent")) {
|
||||
$a.addClass("selected");
|
||||
}
|
||||
});
|
||||
},
|
||||
selectionEnd = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$("#selection-rect").hide().css({left: 0, top: 0, width: 0, height: 0});
|
||||
|
||||
$window.unbind("mousemove", selectionUpdate);
|
||||
|
||||
var hrefs = [];
|
||||
$("#extended a.selected").each(function () {
|
||||
hrefs.push($(this).attr("href"));
|
||||
});
|
||||
if (hrefs.length > 0) {
|
||||
selected(hrefs);
|
||||
}
|
||||
},
|
||||
selectionStart = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
x = event.pageX;
|
||||
y = event.pageY;
|
||||
$("#download").hide().find("a").attr("href", "#");
|
||||
$("#extended a").removeClass("selected");
|
||||
$("#selection-rect").show().css({left: x, top: y, width: 0, height: 0});
|
||||
|
||||
$window
|
||||
.bind("mousemove", selectionUpdate)
|
||||
.one("mouseup", selectionEnd);
|
||||
},
|
||||
noSelection = function (event) {
|
||||
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
if (settings.zippedDownload) {
|
||||
$("body>nav,body>footer,#tree,#extended a").bind("mousedown", noSelection);
|
||||
$("#extended a").live("mousedown", noSelection);
|
||||
$window.bind("mousedown", selectionStart);
|
||||
}
|
||||
},
|
||||
init = function () {
|
||||
|
||||
applyViewmode();
|
||||
initTopSpace();
|
||||
initViews();
|
||||
initTree();
|
||||
linkHoverStates();
|
||||
initLangSelector(langs);
|
||||
localize(langs, settings.lang, settings.useBrowserLang);
|
||||
initIndicators();
|
||||
initZippedDownload();
|
||||
},
|
||||
h5ai = {
|
||||
settings: settings,
|
||||
shiftTree: shiftTree,
|
||||
linkHoverStates: linkHoverStates,
|
||||
pathClick: pathClick,
|
||||
triggerPathClick: triggerPathClick,
|
||||
init: init
|
||||
};
|
||||
|
||||
return h5ai;
|
||||
};
|
||||
|
871
src/h5ai/js/inc/jquery.fracs.js
Normal file
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
* jQuery.fracs 0.10
|
||||
* http://larsjung.de/fracs
|
||||
*
|
||||
* provided under the terms of the MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
* ModPlug 0.4
|
||||
* http://larsjung.de/modplug
|
||||
*
|
||||
* provided under the terms of the MIT License
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
/*globals jQuery */
|
||||
/*jslint confusion: true */
|
||||
|
||||
var reference = "_mp_api";
|
||||
|
||||
$.ModPlug = $.ModPlug || {
|
||||
plugin: function (namespace, options) {
|
||||
|
||||
if (!namespace || $[namespace] || $.fn[namespace]) {
|
||||
// $.error("No namespace specified, or a plugin already exists on 'jQuery." + namespace + "'");
|
||||
return !namespace ? 1 : ($[namespace] ? 2 : 3);
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
statics: {},
|
||||
methods: {},
|
||||
defaultStatic: undefined,
|
||||
defaultMethod: undefined
|
||||
},
|
||||
settings = $.extend({}, defaults, options),
|
||||
staticPlug = function () {
|
||||
|
||||
var args, defaultMethod;
|
||||
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
defaultMethod = settings.defaultStatic instanceof Function ? settings.defaultStatic.apply(this, args) : settings.defaultStatic;
|
||||
if (staticPlug[defaultMethod] instanceof Function) {
|
||||
return staticPlug[defaultMethod].apply(this, args);
|
||||
}
|
||||
$.error("Static method defaulted to '" + defaultMethod + "' does not exist on 'jQuery." + namespace + "'");
|
||||
},
|
||||
methods = {},
|
||||
methodPlug = function (method) {
|
||||
|
||||
var args, defaultMethod;
|
||||
|
||||
if (methods[method] instanceof Function) {
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
return methods[method].apply(this, args);
|
||||
}
|
||||
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
defaultMethod = settings.defaultMethod instanceof Function ? settings.defaultMethod.apply(this, args) : settings.defaultMethod;
|
||||
if (methods[defaultMethod] instanceof Function) {
|
||||
return methods[defaultMethod].apply(this, args);
|
||||
}
|
||||
$.error("Method '" + method + "' defaulted to '" + defaultMethod + "' does not exist on 'jQuery." + namespace + "'");
|
||||
},
|
||||
api = {
|
||||
addStatics: function (newStatics) {
|
||||
|
||||
$.extend(staticPlug, newStatics);
|
||||
staticPlug[reference] = api;
|
||||
return this;
|
||||
},
|
||||
addMethods: function (newMethods) {
|
||||
|
||||
$.extend(methods, newMethods);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
api.addStatics(settings.statics).addMethods(settings.methods);
|
||||
$[namespace] = staticPlug;
|
||||
$.fn[namespace] = methodPlug;
|
||||
return 0;
|
||||
},
|
||||
module: function (namespace, options) {
|
||||
|
||||
if (!$[namespace] || !$[namespace][reference]) {
|
||||
// $.error("No ModPlug plugin exists on 'jQuery." + namespace + "'");
|
||||
return !$[namespace] ? 1 : 2;
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
statics: {},
|
||||
methods: {}
|
||||
},
|
||||
settings = $.extend({}, defaults, options);
|
||||
|
||||
$[namespace][reference].addStatics(settings.statics).addMethods(settings.methods);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
|
||||
/*
|
||||
* jQuery.fracs - Core API
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
/*globals jQuery, HTMLElement */
|
||||
/*jslint browser: true, vars: true */
|
||||
|
||||
|
||||
var FracsData = function (htmlElementOrRect) {
|
||||
|
||||
var target = htmlElementOrRect,
|
||||
callbacks = [],
|
||||
prevFracs;
|
||||
|
||||
this.size = function () {
|
||||
|
||||
return callbacks.length;
|
||||
};
|
||||
|
||||
this.bind = function (callback) {
|
||||
|
||||
if (callback instanceof Function && $.inArray(callback, callbacks) === -1) {
|
||||
callbacks.push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
this.unbind = function (callback) {
|
||||
|
||||
if (callback instanceof Function) {
|
||||
var idx = $.inArray(callback, callbacks);
|
||||
if (idx >= 0) {
|
||||
callbacks.splice(idx, 1);
|
||||
}
|
||||
} else {
|
||||
callbacks = [];
|
||||
}
|
||||
};
|
||||
|
||||
this.check = function () {
|
||||
|
||||
var rect = target instanceof HTMLElement ? $.fracs.rect(target) : target,
|
||||
fracs = $.fracs.fracs(rect, $.fracs.viewport());
|
||||
|
||||
if (!prevFracs || !prevFracs.equals(fracs)) {
|
||||
$.each(callbacks, function (idx, callback) {
|
||||
callback.call(target, fracs, prevFracs);
|
||||
});
|
||||
prevFracs = fracs;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var Rect = function (left, top, width, height) {
|
||||
|
||||
var fracsData;
|
||||
|
||||
this.left = Math.round(left);
|
||||
this.top = Math.round(top);
|
||||
this.width = Math.round(width);
|
||||
this.height = Math.round(height);
|
||||
this.right = this.left + this.width;
|
||||
this.bottom = this.top + this.height;
|
||||
|
||||
this.equals = function (that) {
|
||||
|
||||
return this.left === that.left && this.top === that.top && this.width === that.width && this.height === that.height;
|
||||
};
|
||||
|
||||
this.area = function () {
|
||||
|
||||
return this.width * this.height;
|
||||
};
|
||||
|
||||
this.intersection = function (rect) {
|
||||
|
||||
var left = Math.max(this.left, rect.left),
|
||||
right = Math.min(this.right, rect.right),
|
||||
top = Math.max(this.top, rect.top),
|
||||
bottom = Math.min(this.bottom, rect.bottom),
|
||||
width = right - left,
|
||||
height = bottom - top;
|
||||
|
||||
return (width >= 0 && height >= 0) ? new Rect(left, top, width, height) : undefined;
|
||||
};
|
||||
|
||||
this.envelope = function (rect) {
|
||||
|
||||
var left = Math.min(this.left, rect.left),
|
||||
right = Math.max(this.right, rect.right),
|
||||
top = Math.min(this.top, rect.top),
|
||||
bottom = Math.max(this.bottom, rect.bottom),
|
||||
width = right - left,
|
||||
height = bottom - top;
|
||||
|
||||
return new Rect(left, top, width, height);
|
||||
};
|
||||
|
||||
this.bind = function (callback) {
|
||||
|
||||
if (!fracsData) {
|
||||
fracsData = new FracsData(this);
|
||||
$(window).bind("scroll resize", fracsData.check);
|
||||
}
|
||||
fracsData.bind(callback);
|
||||
};
|
||||
|
||||
this.unbind = function (callback) {
|
||||
|
||||
if (fracsData) {
|
||||
fracsData.unbind(callback);
|
||||
if (fracsData.size() === 0) {
|
||||
$(window).unbind("scroll resize", fracsData.check);
|
||||
fracsData = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.check = function () {
|
||||
|
||||
if (fracsData) {
|
||||
fracsData.check();
|
||||
}
|
||||
};
|
||||
|
||||
this.fracs = function () {
|
||||
|
||||
$.fracs.fracs(this);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var FracsResult = function (rectDocument, rectElement, rectViewport, visible, viewport, possible) {
|
||||
|
||||
/*jslint confusion: true */
|
||||
|
||||
if (!rectDocument || !rectElement || !rectViewport || !visible || !viewport || !possible) {
|
||||
this.rects = undefined;
|
||||
this.visible = 0;
|
||||
this.viewport = 0;
|
||||
this.possible = 0;
|
||||
} else {
|
||||
this.rects = {
|
||||
document: rectDocument,
|
||||
element: rectElement,
|
||||
viewport: rectViewport
|
||||
};
|
||||
this.visible = visible;
|
||||
this.viewport = viewport;
|
||||
this.possible = possible;
|
||||
}
|
||||
|
||||
this.equals = function (that) {
|
||||
|
||||
return this.fracsEqual(that) && this.rectsEqual(that);
|
||||
};
|
||||
|
||||
this.fracsEqual = function (that) {
|
||||
|
||||
return this.visible === that.visible && this.viewport === that.viewport && this.possible === that.possible;
|
||||
};
|
||||
|
||||
this.rectsEqual = function (that) {
|
||||
|
||||
if (!this.rects || !that.rects) {
|
||||
return this.rects === that.rects;
|
||||
}
|
||||
return this.rects.document.equals(that.rects.document)
|
||||
&& this.rects.element.equals(that.rects.element)
|
||||
&& this.rects.viewport.equals(that.rects.viewport);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var ScrollState = function () {
|
||||
|
||||
var document = $.fracs.document(),
|
||||
viewport = $.fracs.viewport(),
|
||||
width = document.width - viewport.width,
|
||||
height = document.height - viewport.height;
|
||||
|
||||
this.width = width <= 0 ? undefined : viewport.left / width;
|
||||
this.height = height <= 0 ? undefined : viewport.top / height;
|
||||
this.left = viewport.left;
|
||||
this.top = viewport.top;
|
||||
this.right = document.right - viewport.right;
|
||||
this.bottom = document.bottom - viewport.bottom;
|
||||
|
||||
this.equals = function (that) {
|
||||
|
||||
return this.width === that.width && this.height === that.height
|
||||
&& this.left === that.left && this.top === that.top
|
||||
&& this.right === that.right && this.bottom === that.bottom;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var ScrollStateTracker = function () {
|
||||
|
||||
var prevState,
|
||||
callbacks = [],
|
||||
check = function () {
|
||||
|
||||
var state = new ScrollState();
|
||||
if (!prevState || !prevState.equals(state)) {
|
||||
$.each(callbacks, function (idx, callback) {
|
||||
callback.call(window, state, prevState);
|
||||
});
|
||||
prevState = state;
|
||||
}
|
||||
};
|
||||
|
||||
$(window).bind("resize scroll load", check);
|
||||
|
||||
this.bind = function (callback) {
|
||||
|
||||
callbacks.push(callback);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// @beta
|
||||
var FracsElement = function (htmlElement, fracs) {
|
||||
|
||||
this.element = htmlElement;
|
||||
this.fracs = fracs;
|
||||
|
||||
this.update = function () {
|
||||
|
||||
var fracs = $.fracs.fracs(this.element),
|
||||
changed = !this.fracs || !this.fracs.equals(fracs);
|
||||
this.fracs = fracs;
|
||||
return changed;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// @beta
|
||||
var FracsGroup = function (htmlElements, property, callback) {
|
||||
|
||||
var THIS = this,
|
||||
targets = [],
|
||||
prevBest = null;
|
||||
|
||||
$.each(htmlElements, function (idx, element) {
|
||||
if (element instanceof HTMLElement) {
|
||||
targets.push(new FracsElement(element));
|
||||
}
|
||||
});
|
||||
|
||||
this.check = function () {
|
||||
|
||||
var best,
|
||||
viewport = $.fracs.viewport();
|
||||
|
||||
$.each(targets, function (idx, target) {
|
||||
target.update();
|
||||
if (!best || target.fracs[property] > best.fracs[property]) {
|
||||
best = target;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (best && best.fracs[property] === 0) {
|
||||
best = null;
|
||||
}
|
||||
|
||||
if (prevBest !== best) {
|
||||
callback.call(THIS, best, prevBest);
|
||||
prevBest = best;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var $document = $(document),
|
||||
$window = $(window),
|
||||
$htmlBody = $("html,body"),
|
||||
scrollStateTracker,
|
||||
dataNs = "fracs",
|
||||
statics = {
|
||||
document: function () {
|
||||
|
||||
/*jslint confusion: true */
|
||||
return new Rect(0, 0, $document.width(), $document.height());
|
||||
},
|
||||
viewport: function () {
|
||||
|
||||
/*jslint confusion: true */
|
||||
return new Rect($window.scrollLeft(), $window.scrollTop(), $window.width(), $window.height());
|
||||
},
|
||||
rect: function (htmlElement) {
|
||||
|
||||
var $target = $(htmlElement),
|
||||
offset = $target.offset();
|
||||
|
||||
if (!$target.is(":visible")) {
|
||||
return new Rect(0, 0, 0, 0);
|
||||
}
|
||||
return new Rect(offset.left, offset.top, $target.outerWidth(), $target.outerHeight());
|
||||
},
|
||||
fracs: function (rect, viewport) {
|
||||
|
||||
var intersection, intersectionElementSpace, intersectionViewportSpace, intersectionArea, possibleArea;
|
||||
|
||||
rect = rect instanceof HTMLElement ? statics.rect(rect) : rect;
|
||||
viewport = viewport || statics.viewport();
|
||||
intersection = rect.intersection(viewport);
|
||||
|
||||
if (!intersection) {
|
||||
return new FracsResult();
|
||||
}
|
||||
|
||||
intersectionElementSpace = new Rect(intersection.left - rect.left, intersection.top - rect.top, intersection.width, intersection.height);
|
||||
intersectionViewportSpace = new Rect(intersection.left - viewport.left, intersection.top - viewport.top, intersection.width, intersection.height);
|
||||
intersectionArea = intersection.area();
|
||||
possibleArea = Math.min(rect.width, viewport.width) * Math.min(rect.height, viewport.height);
|
||||
|
||||
return new FracsResult(
|
||||
intersection,
|
||||
intersectionElementSpace,
|
||||
intersectionViewportSpace,
|
||||
intersectionArea / rect.area(),
|
||||
intersectionArea / viewport.area(),
|
||||
intersectionArea / possibleArea
|
||||
);
|
||||
},
|
||||
round: function (value, decs) {
|
||||
|
||||
if (isNaN(decs) || decs <= 0) {
|
||||
return Math.round(value);
|
||||
}
|
||||
return Math.round(value * Math.pow(10, decs)) / Math.pow(10, decs);
|
||||
},
|
||||
scrollTo: function (left, top, duration) {
|
||||
|
||||
duration = isNaN(duration) ? 1000 : duration;
|
||||
$htmlBody.stop(true).animate({ scrollLeft: left, scrollTop: top }, duration);
|
||||
},
|
||||
scroll: function (left, top, duration) {
|
||||
|
||||
duration = isNaN(duration) ? 1000 : duration;
|
||||
$htmlBody.stop(true).animate({ scrollLeft: $window.scrollLeft() + left, scrollTop: $window.scrollTop() + top }, duration);
|
||||
},
|
||||
scrollState: function (callback) {
|
||||
|
||||
if (callback instanceof Function) {
|
||||
scrollStateTracker = scrollStateTracker || new ScrollStateTracker();
|
||||
scrollStateTracker.bind(callback);
|
||||
} else {
|
||||
return new ScrollState();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods = {
|
||||
bind: function (callback) {
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var $this = $(this),
|
||||
data = $this.data(dataNs);
|
||||
|
||||
if (!data) {
|
||||
data = new FracsData(this);
|
||||
$this.data(dataNs, data);
|
||||
$window.bind("scroll resize", data.check);
|
||||
}
|
||||
data.bind(callback);
|
||||
});
|
||||
},
|
||||
unbind: function (callback) {
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var $this = $(this),
|
||||
data = $this.data(dataNs);
|
||||
|
||||
if (data) {
|
||||
data.unbind(callback);
|
||||
if (data.size() === 0) {
|
||||
$this.removeData(dataNs);
|
||||
$window.unbind("scroll resize", data.check);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
check: function () {
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var data = $(this).data(dataNs);
|
||||
|
||||
if (data) {
|
||||
data.check();
|
||||
}
|
||||
});
|
||||
},
|
||||
fracs: function () {
|
||||
|
||||
return statics.fracs(statics.rect(this.get(0)), statics.viewport());
|
||||
},
|
||||
rect: function () {
|
||||
|
||||
return statics.rect(this.get(0));
|
||||
},
|
||||
max: function (property, callback) {
|
||||
|
||||
if (callback instanceof Function) {
|
||||
|
||||
var data = new FracsGroup(this, property, callback);
|
||||
|
||||
$window.bind("scroll resize", data.check);
|
||||
data.check();
|
||||
return this;
|
||||
} else {
|
||||
var obj, elements, maxValue;
|
||||
|
||||
if ($.inArray(property, [ "possible", "visible", "viewport" ]) >= 0) {
|
||||
obj = "fracs";
|
||||
} else if ($.inArray(property, [ "width", "height", "left", "right", "top", "bottom" ]) >= 0) {
|
||||
obj = "rect";
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.each(function () {
|
||||
|
||||
var fracs = statics[obj](this);
|
||||
|
||||
if (!maxValue || fracs[property] > maxValue) {
|
||||
elements = [ this ];
|
||||
maxValue = fracs[property];
|
||||
} else if (fracs[property] === maxValue) {
|
||||
elements.push(this);
|
||||
}
|
||||
});
|
||||
return $(elements);
|
||||
}
|
||||
},
|
||||
min: function (property) {
|
||||
|
||||
var obj, elements, minValue;
|
||||
|
||||
if ($.inArray(property, [ "possible", "visible", "viewport" ]) >= 0) {
|
||||
obj = "fracs";
|
||||
} else if ($.inArray(property, [ "width", "height", "left", "right", "top", "bottom" ]) >= 0) {
|
||||
obj = "rect";
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.each(function () {
|
||||
|
||||
var fracs = statics[obj](this);
|
||||
|
||||
if (!minValue || fracs[property] < minValue) {
|
||||
elements = [ this ];
|
||||
minValue = fracs[property];
|
||||
} else if (fracs[property] === minValue) {
|
||||
elements.push(this);
|
||||
}
|
||||
});
|
||||
return $(elements);
|
||||
},
|
||||
envelope: function () {
|
||||
|
||||
var envelope, rect;
|
||||
|
||||
this.each(function () {
|
||||
rect = statics.rect(this);
|
||||
envelope = !envelope ? rect : envelope.envelope(rect);
|
||||
});
|
||||
return envelope;
|
||||
},
|
||||
scrollTo: function (paddingLeft, paddingTop, duration) {
|
||||
|
||||
var rect;
|
||||
|
||||
paddingLeft = paddingLeft || 0;
|
||||
paddingTop = paddingTop || 0;
|
||||
rect = statics.rect(this.get(0));
|
||||
|
||||
statics.scrollTo(rect.left - paddingLeft, rect.top - paddingTop, duration);
|
||||
return this;
|
||||
},
|
||||
softLink: function (paddingLeft, paddingTop, duration) {
|
||||
|
||||
return this.filter("a[href^=#]").each(function () {
|
||||
var $a = $(this),
|
||||
href = $a.attr("href");
|
||||
$a.click(function () {
|
||||
$(href).fracs("scrollTo", paddingLeft, paddingTop, duration);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
defaultStatic = function () {
|
||||
|
||||
return "fracs";
|
||||
},
|
||||
defaultMethod = function () {
|
||||
|
||||
if (arguments.length === 0) {
|
||||
return "fracs";
|
||||
} else if (arguments[0] instanceof Function) {
|
||||
return "bind";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$.ModPlug.plugin("fracs", {
|
||||
statics: statics,
|
||||
methods: methods,
|
||||
defaultStatic: defaultStatic,
|
||||
defaultMethod: defaultMethod
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
|
||||
/*
|
||||
* jQuery.fracs - Outline API
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
/*globals jQuery */
|
||||
/*jslint browser: true, vars: true */
|
||||
|
||||
|
||||
var Outline = function (canvas, options) {
|
||||
|
||||
if (!(canvas instanceof HTMLElement && canvas.nodeName.toLowerCase() === "canvas")) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
var defaults = {
|
||||
crop: false,
|
||||
duration: 0,
|
||||
focusWidth: 0.5,
|
||||
focusHeight: 0.5,
|
||||
autoFocus: true,
|
||||
styles: [ {
|
||||
selector: "header,footer,section,article",
|
||||
fillStyle: "rgb(230,230,230)"
|
||||
}, {
|
||||
selector: "h1",
|
||||
fillStyle: "rgb(240,140,060)"
|
||||
}, {
|
||||
selector: "h2",
|
||||
fillStyle: "rgb(200,100,100)"
|
||||
}, {
|
||||
selector: "h3",
|
||||
fillStyle: "rgb(100,200,100)"
|
||||
}, {
|
||||
selector: "h4",
|
||||
fillStyle: "rgb(100,100,200)"
|
||||
} ],
|
||||
viewportStyle: {
|
||||
fillStyle: "rgba(228,77,38,0.3)"
|
||||
},
|
||||
viewportDragStyle: {
|
||||
fillStyle: "rgba(228,77,38,0.6)"
|
||||
},
|
||||
invertViewport: false
|
||||
},
|
||||
settings = $.extend({}, defaults, options),
|
||||
$window = $(window),
|
||||
$htmlBody = $("html,body"),
|
||||
$canvas = $(canvas),
|
||||
width = $canvas.attr("width"),
|
||||
height = $canvas.attr("height"),
|
||||
context = canvas.getContext("2d"),
|
||||
docRect,
|
||||
vpRect,
|
||||
scale,
|
||||
drag = false,
|
||||
focusWidth,
|
||||
focusHeight,
|
||||
scroll = function (event) {
|
||||
|
||||
var r, x, y;
|
||||
|
||||
r = $canvas.fracs("rect");
|
||||
x = event.pageX - r.left;
|
||||
y = event.pageY - r.top;
|
||||
$.fracs.scrollTo(x / scale - vpRect.width * focusWidth, y / scale - vpRect.height * focusHeight, settings.duration);
|
||||
},
|
||||
drawRect = function (context, rect, strokeWidth, strokeStyle, fillStyle, invert) {
|
||||
|
||||
if (strokeWidth !== undefined && scale) {
|
||||
strokeWidth = strokeWidth > 0.2 / scale ? strokeWidth : 0.2 / scale;
|
||||
}
|
||||
|
||||
if (strokeStyle || fillStyle) {
|
||||
if (invert !== true) {
|
||||
context.beginPath();
|
||||
context.rect(rect.left, rect.top, rect.width, rect.height);
|
||||
if (fillStyle) {
|
||||
context.fillStyle = fillStyle;
|
||||
context.fill();
|
||||
}
|
||||
if (strokeStyle) {
|
||||
context.lineWidth = strokeWidth;
|
||||
context.strokeStyle = strokeStyle;
|
||||
context.stroke();
|
||||
}
|
||||
} else {
|
||||
if (fillStyle) {
|
||||
context.beginPath();
|
||||
context.rect(0, 0, docRect.width, rect.top);
|
||||
context.rect(0, rect.top, rect.left, rect.height);
|
||||
context.rect(rect.right, rect.top, docRect.right - rect.right, rect.height);
|
||||
context.rect(0, rect.bottom, docRect.width, docRect.bottom - rect.bottom);
|
||||
context.fillStyle = fillStyle;
|
||||
context.fill();
|
||||
}
|
||||
if (strokeStyle) {
|
||||
context.beginPath();
|
||||
context.rect(rect.left, rect.top, rect.width, rect.height);
|
||||
context.lineWidth = strokeWidth;
|
||||
context.strokeStyle = strokeStyle;
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
drawElement = function (context, htmlElement, strokeWidth, strokeStyle, fillStyle) {
|
||||
|
||||
var $element = $(htmlElement),
|
||||
rect = $element.fracs("rect");
|
||||
|
||||
if ($element.css("visibility") === "hidden") {
|
||||
return;
|
||||
}
|
||||
|
||||
strokeWidth = strokeWidth === "auto" ? $element.css("border-top-width") : strokeWidth;
|
||||
strokeStyle = strokeStyle === "auto" ? $element.css("border-top-color") : strokeStyle;
|
||||
fillStyle = fillStyle === "auto" ? $element.css("background-color") : fillStyle;
|
||||
drawRect(context, rect, strokeWidth, strokeStyle, fillStyle);
|
||||
},
|
||||
drawViewport = function () {
|
||||
|
||||
var strokeWidth, strokeStyle, fillStyle;
|
||||
|
||||
if (drag && settings.viewportDragStyle) {
|
||||
strokeWidth = settings.viewportDragStyle.storkeWidth;
|
||||
strokeStyle = settings.viewportDragStyle.strokeStyle;
|
||||
fillStyle = settings.viewportDragStyle.fillStyle;
|
||||
} else {
|
||||
strokeWidth = settings.viewportStyle.storkeWidth;
|
||||
strokeStyle = settings.viewportStyle.strokeStyle;
|
||||
fillStyle = settings.viewportStyle.fillStyle;
|
||||
}
|
||||
drawRect(context, vpRect, strokeWidth, strokeStyle, fillStyle, settings.invertViewport);
|
||||
},
|
||||
applyStyles = function (context) {
|
||||
|
||||
$.each(settings.styles, function (idx, style) {
|
||||
$(style.selector).each(function () {
|
||||
drawElement(context, this, style.strokeWidth, style.strokeStyle, style.fillStyle);
|
||||
});
|
||||
});
|
||||
},
|
||||
draw = function () {
|
||||
|
||||
/*jslint confusion: true */
|
||||
|
||||
var scaleX, scaleY;
|
||||
|
||||
docRect = $.fracs.document();
|
||||
vpRect = $.fracs.viewport();
|
||||
scaleX = width / docRect.width;
|
||||
scaleY = height / docRect.height;
|
||||
scale = scaleX < scaleY ? scaleX : scaleY;
|
||||
|
||||
if (settings.crop) {
|
||||
$canvas.attr("width", docRect.width * scale).attr("height", docRect.height * scale);
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, $canvas.width(), $canvas.height());
|
||||
|
||||
context.scale(scale, scale);
|
||||
applyStyles(context);
|
||||
drawViewport();
|
||||
context.scale(1 / scale, 1 / scale);
|
||||
},
|
||||
init = function () {
|
||||
|
||||
$canvas
|
||||
.css("cursor", "pointer")
|
||||
.mousedown(function (event) {
|
||||
|
||||
var r;
|
||||
|
||||
event.preventDefault();
|
||||
drag = true;
|
||||
if (settings.autoFocus) {
|
||||
r = $canvas.fracs("rect");
|
||||
focusWidth = (((event.pageX - r.left) / scale) - vpRect.left) / vpRect.width;
|
||||
focusHeight = (((event.pageY - r.top) / scale) - vpRect.top) / vpRect.height;
|
||||
}
|
||||
if (!settings.autoFocus || focusWidth < 0 || focusWidth > 1 || focusHeight < 0 || focusHeight > 1) {
|
||||
focusWidth = settings.focusWidth;
|
||||
focusHeight = settings.focusHeight;
|
||||
}
|
||||
scroll(event);
|
||||
$canvas.css("cursor", "crosshair").addClass("dragOn");
|
||||
$htmlBody.css("cursor", "crosshair");
|
||||
$window
|
||||
.bind("mousemove", scroll)
|
||||
.one("mouseup", function (event) {
|
||||
event.preventDefault();
|
||||
$canvas.css("cursor", "pointer").removeClass("dragOn");
|
||||
$htmlBody.css("cursor", "auto");
|
||||
$window.unbind("mousemove", scroll);
|
||||
drag = false;
|
||||
draw();
|
||||
});
|
||||
});
|
||||
canvas.onselectstart = function () {
|
||||
return false;
|
||||
};
|
||||
$window.bind("load resize scroll", draw);
|
||||
draw();
|
||||
};
|
||||
|
||||
|
||||
init();
|
||||
|
||||
|
||||
this.draw = draw;
|
||||
};
|
||||
|
||||
|
||||
var dataNs = "outline",
|
||||
methods = {
|
||||
outline: function (options) {
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var outline;
|
||||
|
||||
if (options === "redraw") {
|
||||
outline = $(this).data(dataNs);
|
||||
if (outline) {
|
||||
outline.draw();
|
||||
}
|
||||
} else {
|
||||
outline = new Outline(this, options);
|
||||
if (outline) {
|
||||
$(this).data(dataNs, outline);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$.ModPlug.module("fracs", {
|
||||
methods: methods
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
|
31
src/h5ai/js/inc/jquery.json.min.js
vendored
@@ -1,31 +0,0 @@
|
||||
// v2.2
|
||||
(function($){$.toJSON=function(o)
|
||||
{if(typeof(JSON)=='object'&&JSON.stringify)
|
||||
return JSON.stringify(o);var type=typeof(o);if(o===null)
|
||||
return"null";if(type=="undefined")
|
||||
return undefined;if(type=="number"||type=="boolean")
|
||||
return o+"";if(type=="string")
|
||||
return $.quoteString(o);if(type=='object')
|
||||
{if(typeof o.toJSON=="function")
|
||||
return $.toJSON(o.toJSON());if(o.constructor===Date)
|
||||
{var month=o.getUTCMonth()+1;if(month<10)month='0'+month;var day=o.getUTCDate();if(day<10)day='0'+day;var year=o.getUTCFullYear();var hours=o.getUTCHours();if(hours<10)hours='0'+hours;var minutes=o.getUTCMinutes();if(minutes<10)minutes='0'+minutes;var seconds=o.getUTCSeconds();if(seconds<10)seconds='0'+seconds;var milli=o.getUTCMilliseconds();if(milli<100)milli='0'+milli;if(milli<10)milli='0'+milli;return'"'+year+'-'+month+'-'+day+'T'+
|
||||
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
|
||||
if(o.constructor===Array)
|
||||
{var ret=[];for(var i=0;i<o.length;i++)
|
||||
ret.push($.toJSON(o[i])||"null");return"["+ret.join(",")+"]";}
|
||||
var pairs=[];for(var k in o){var name;var type=typeof k;if(type=="number")
|
||||
name='"'+k+'"';else if(type=="string")
|
||||
name=$.quoteString(k);else
|
||||
continue;if(typeof o[k]=="function")
|
||||
continue;var val=$.toJSON(o[k]);pairs.push(name+":"+val);}
|
||||
return"{"+pairs.join(", ")+"}";}};$.evalJSON=function(src)
|
||||
{if(typeof(JSON)=='object'&&JSON.parse)
|
||||
return JSON.parse(src);return eval("("+src+")");};$.secureEvalJSON=function(src)
|
||||
{if(typeof(JSON)=='object'&&JSON.parse)
|
||||
return JSON.parse(src);var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
|
||||
return eval("("+src+")");else
|
||||
throw new SyntaxError("Error parsing JSON, source is not valid.");};$.quoteString=function(string)
|
||||
{if(string.match(_escapeable))
|
||||
{return'"'+string.replace(_escapeable,function(a)
|
||||
{var c=_meta[a];if(typeof c==='string')return c;c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
|
||||
return'"'+string+'"';};var _escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var _meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};})(jQuery);
|
147
src/h5ai/js/inc/jquery.scrollpanel.js
Normal file
@@ -0,0 +1,147 @@
|
||||
(function ($) {
|
||||
|
||||
var init = function (htmlElement) {
|
||||
|
||||
var $element = $(htmlElement),
|
||||
$scrollbar, $drag, $wrapper, $content, mouseOffsetY, updateId,
|
||||
update, scroll;
|
||||
|
||||
if (!$element.css("position") || $element.css("position") === "static") {
|
||||
$element.css("position", "relative");
|
||||
}
|
||||
|
||||
$scrollbar = $("<div class='scrollbar' />");
|
||||
$drag = $("<div class='drag' />").appendTo($scrollbar);
|
||||
$element
|
||||
.wrapInner("<div class='wrapper'><div class='content' /></div>")
|
||||
.append($scrollbar);
|
||||
$wrapper = $element.find("> .wrapper");
|
||||
$content = $wrapper.find("> .content");
|
||||
mouseOffsetY = 0;
|
||||
|
||||
update = function (repeat) {
|
||||
|
||||
var visibleHeight, contentHeight, scrollTop, scrollTopFrac, visVertFrac;
|
||||
|
||||
if (updateId && !repeat) {
|
||||
clearInterval(updateId);
|
||||
updateId = undefined;
|
||||
} else if (!updateId && repeat) {
|
||||
updateId = setInterval(function() { update(true); }, 50);
|
||||
}
|
||||
|
||||
$wrapper.css("height", $element.height());
|
||||
visibleHeight = $element.height();
|
||||
contentHeight = $content.outerHeight();
|
||||
scrollTop = $wrapper.scrollTop();
|
||||
scrollTopFrac = scrollTop / contentHeight;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
scroll = function (event) {
|
||||
|
||||
var clickFrac = (event.pageY - $scrollbar.offset().top - mouseOffsetY) / $scrollbar.height();
|
||||
|
||||
$wrapper.scrollTop($content.outerHeight() * clickFrac);
|
||||
update();
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
$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",
|
||||
cursor: "pointer"
|
||||
})
|
||||
.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.preventDefault();
|
||||
})
|
||||
.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);
|
29
src/h5ai/js/inc/jquery.utils.js
Normal file
@@ -0,0 +1,29 @@
|
||||
(function ($) {
|
||||
"use strict";
|
||||
/*global jQuery, window*/
|
||||
|
||||
// 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));
|
||||
}
|
||||
};
|
||||
|
||||
$.timer = (function () {
|
||||
var start = $.now(),
|
||||
last = start,
|
||||
timer = {
|
||||
log: function (label) {
|
||||
var now = $.now();
|
||||
$.log("timer", label, "+" + (now - last), "=" + (now - start));
|
||||
last = now;
|
||||
}
|
||||
};
|
||||
|
||||
return timer;
|
||||
}());
|
||||
|
||||
})(jQuery);
|
@@ -1,411 +1,404 @@
|
||||
|
||||
var Path = function (pathCache, folder, tableRow) {
|
||||
"use strict";
|
||||
/*global $, h5ai, tree*/
|
||||
|
||||
var path,
|
||||
checkedDecodeUri = function (uri) {
|
||||
|
||||
try { return decodeURI(uri); } catch (err) {}
|
||||
return uri;
|
||||
},
|
||||
isEmpty = function () {
|
||||
|
||||
return path.content === undefined || $.isEmptyObject(path.content);
|
||||
},
|
||||
onClick = function (context) {
|
||||
|
||||
h5ai.triggerPathClick(path, context);
|
||||
},
|
||||
updateHtml = function () {
|
||||
|
||||
path.updateCrumbHtml();
|
||||
path.updateExtendedHtml();
|
||||
path.updateTreeHtml();
|
||||
},
|
||||
updateCrumbHtml = function () {
|
||||
|
||||
var $html, $a;
|
||||
|
||||
if (path.html.$crumb && path.html.$crumb.data("status") === path.status) {
|
||||
return path.html.$crumb;
|
||||
}
|
||||
|
||||
$html = $("<li class='crumb' />")
|
||||
.data("path", path)
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
if (path.status) {
|
||||
$html.data("status", path.status);
|
||||
}
|
||||
|
||||
$a = $("<a><img src='/h5ai/images/crumb.png' alt='>' />" + path.label + "</a>")
|
||||
.appendTo($html)
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { onClick("crumb"); });
|
||||
|
||||
if (path.isDomain) {
|
||||
$html.addClass("domain");
|
||||
$a.find("img").attr("src", "/h5ai/images/home.png");
|
||||
}
|
||||
|
||||
if (path.isCurrentFolder) {
|
||||
$html.addClass("current");
|
||||
}
|
||||
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$("<img class='hint' src='/h5ai/images/page.png' alt='not listable' />").appendTo($a);
|
||||
} else {
|
||||
$("<span class='hint'>(" + path.status + ")</span>").appendTo($a);
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$crumb) {
|
||||
path.html.$cpathreplaceWith($html);
|
||||
}
|
||||
path.html.$crumb = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
updateExtendedHtml = function () {
|
||||
|
||||
var $html, $a, $label;
|
||||
|
||||
if (path.html.$extended && path.html.$extended.data("status") === path.status) {
|
||||
return path.html.$extended;
|
||||
}
|
||||
|
||||
$html = $("<li class='entry' />")
|
||||
.data("path", path)
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
if (path.status) {
|
||||
$html.data("status", path.status);
|
||||
}
|
||||
|
||||
$label = $("<span class='label'>" + path.label + "</span>");
|
||||
$a = $("<a />")
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { onClick("extended"); })
|
||||
.appendTo($html)
|
||||
.append($("<span class='icon small'><img src='" + path.icon16 + "' alt='" + path.alt + "' /></span>"))
|
||||
.append($("<span class='icon big'><img src='" + path.icon48 + "' alt='" + path.alt + "' /></span>"))
|
||||
.append($label)
|
||||
.append($("<span class='date'>" + path.date + "</span>"))
|
||||
.append($("<span class='size'>" + path.size + "</span>"));
|
||||
|
||||
$a.hover(
|
||||
function () {
|
||||
if ($("#extended").hasClass("icons-view")) {
|
||||
var $this = $(this);
|
||||
$(".status.default").hide();
|
||||
$(".status.dynamic")
|
||||
.empty()
|
||||
.append($this.find(".label").clone())
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".date").clone())
|
||||
.show();
|
||||
|
||||
if (!$this.closest(".entry").hasClass("folder")) {
|
||||
$(".status.dynamic")
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".size").clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
function () {
|
||||
$(".status.default").show();
|
||||
$(".status.dynamic").empty().hide();
|
||||
}
|
||||
);
|
||||
|
||||
if (path.isParentFolder) {
|
||||
if (!h5ai.settings.setParentFolderLabels) {
|
||||
$label.addClass("l10n-parentDirectory");
|
||||
}
|
||||
$html.addClass("parentfolder");
|
||||
}
|
||||
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$html.addClass("page");
|
||||
$a.find(".icon.small img").attr("src", "/h5ai/icons/16x16/folder-page.png");
|
||||
$a.find(".icon.big img").attr("src", "/h5ai/icons/48x48/folder-page.png");
|
||||
} else {
|
||||
$html.addClass("error");
|
||||
$label.append($("<span class='hint'> " + path.status + " </span>"));
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$extended) {
|
||||
path.html.$extended.replaceWith($html);
|
||||
}
|
||||
path.html.$extended = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
updateTreeHtml = function () {
|
||||
|
||||
var $html, $blank, $a, $indicator, $ul, idx;
|
||||
|
||||
$html = $("<div class='entry' />")
|
||||
.data("path", path)
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
$blank = $("<span class='blank' />").appendTo($html);
|
||||
|
||||
$a = $("<a />")
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { path.onClick("tree"); })
|
||||
.appendTo($html)
|
||||
.append($("<span class='icon'><img src='" + path.icon16 + "' /></span>"))
|
||||
.append($("<span class='label'>" + path.label + "</span>"));
|
||||
|
||||
if (path.isFolder) {
|
||||
// indicator
|
||||
if (path.status === undefined || !path.isEmpty()) {
|
||||
$indicator = $("<span class='indicator'><img src='/h5ai/images/tree.png' /></span>");
|
||||
if (path.status === undefined) {
|
||||
$indicator.addClass("unknown");
|
||||
} else if (path.treeOpen) {
|
||||
$indicator.addClass("open");
|
||||
}
|
||||
$indicator.click(function(event) {
|
||||
|
||||
if ($indicator.hasClass("unknown")) {
|
||||
tree.fetchStatusAndContent(path.absHref, false, function (status, content) {
|
||||
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
path.treeOpen = true;
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
path.updateTreeHtml(function() {
|
||||
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
});
|
||||
} else if ($indicator.hasClass("open")) {
|
||||
path.treeOpen = false;
|
||||
$indicator.removeClass("open");
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
$html.find("> ul.content").slideUp(function() {
|
||||
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
} else {
|
||||
path.treeOpen = true;
|
||||
$indicator.addClass("open");
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
$html.find("> ul.content").slideDown(function() {
|
||||
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
}
|
||||
});
|
||||
$html.addClass("initiatedIndicator");
|
||||
$blank.replaceWith($indicator);
|
||||
}
|
||||
|
||||
// is path the domain?
|
||||
if (path.isDomain) {
|
||||
$html.addClass("domain");
|
||||
$a.find(".icon img").attr("src", "/h5ai/icons/16x16/folder-home.png");
|
||||
}
|
||||
|
||||
// is path the current folder?
|
||||
if (path.isCurrentFolder) {
|
||||
$html.addClass("current");
|
||||
$a.find(".icon img").attr("src", "/h5ai/icons/16x16/folder-open.png");
|
||||
}
|
||||
|
||||
// does it have subfolders?
|
||||
if (!path.isEmpty()) {
|
||||
$ul = $("<ul class='content' />").appendTo($html);
|
||||
for (idx in path.content) {
|
||||
$("<li />").append(path.content[idx].updateTreeHtml()).appendTo($ul);
|
||||
}
|
||||
if (path.status === undefined || !path.treeOpen) {
|
||||
$ul.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// reflect folder status
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$a.find(".icon img").attr("src", "/h5ai/icons/16x16/folder-page.png");
|
||||
$a.append($("<span class='hint'><img src='/h5ai/images/page.png' /></span>"));
|
||||
} else {
|
||||
$html.addClass("error");
|
||||
$a.append($("<span class='hint'>" + path.status + "</span>"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$tree) {
|
||||
path.html.$tree.replaceWith($html);
|
||||
}
|
||||
path.html.$tree = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
init = function () {
|
||||
|
||||
var $tds, $img, $a, splits;
|
||||
|
||||
path = {
|
||||
// parentFolder: undefined,
|
||||
// label: undefined,
|
||||
// date: undefined,
|
||||
// size: undefined,
|
||||
// href: undefined,
|
||||
// absHref: undefined,
|
||||
// alt: undefined,
|
||||
// icon16: undefined,
|
||||
// icon48: undefined,
|
||||
// isFolder: undefined,
|
||||
// isParentFolder: undefined,
|
||||
// isCurrentFolder: undefined,
|
||||
// isDomain: undefined,
|
||||
|
||||
status: undefined, // undefined, "h5ai" or HTTP response code
|
||||
content: undefined, // associative array path.absHref -> path
|
||||
html: {
|
||||
$crumb: undefined,
|
||||
$extended: undefined,
|
||||
$tree: undefined
|
||||
},
|
||||
treeOpen: false,
|
||||
|
||||
isEmpty: isEmpty,
|
||||
onClick: onClick,
|
||||
updateHtml: updateHtml,
|
||||
updateCrumbHtml: updateCrumbHtml,
|
||||
updateExtendedHtml: updateExtendedHtml,
|
||||
updateTreeHtml: updateTreeHtml
|
||||
};
|
||||
|
||||
if (!pathCache.pathEndsWithSlash(folder)) {
|
||||
folder += "/";
|
||||
}
|
||||
|
||||
if (tableRow) {
|
||||
$tds = $(tableRow).find("td");
|
||||
$img = $tds.eq(0).find("img");
|
||||
$a = $tds.eq(1).find("a");
|
||||
|
||||
path.parentFolder = folder;
|
||||
path.label = $a.text();
|
||||
path.date = $tds.eq(2).text();
|
||||
path.size = $tds.eq(3).text();
|
||||
path.href = $a.attr("href");
|
||||
path.alt = $img.attr("alt");
|
||||
path.icon16 = $img.attr("src");
|
||||
} else {
|
||||
splits = pathCache.splitPathname(folder);
|
||||
|
||||
path.parentFolder = splits[0];
|
||||
path.label = checkedDecodeUri(splits[1]);
|
||||
if (path.label === "/") {
|
||||
path.label = checkedDecodeUri(document.domain) + "/";
|
||||
}
|
||||
path.date = "";
|
||||
path.size = "";
|
||||
path.href = splits[1];
|
||||
path.alt = "[DIR]";
|
||||
path.icon16 = "/h5ai/icons/16x16/folder.png";
|
||||
}
|
||||
|
||||
if (pathCache.pathEndsWithSlash(path.label)) {
|
||||
path.label = path.label.slice(0, -1);
|
||||
}
|
||||
|
||||
path.icon48 = path.icon16.replace("16x16", "48x48");
|
||||
path.isFolder = (path.alt === "[DIR]");
|
||||
path.isParentFolder = (path.isFolder && path.label === "Parent Directory");
|
||||
path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href;
|
||||
path.isCurrentFolder = (path.absHref === document.location.pathname);
|
||||
path.isDomain = (path.absHref === "/");
|
||||
|
||||
if (path.isParentFolder && h5ai.settings.setParentFolderLabels) {
|
||||
if (path.isDomain) {
|
||||
path.label = checkedDecodeUri(document.domain);
|
||||
} else {
|
||||
path.label = checkedDecodeUri(pathCache.splitPathname(pathCache.splitPathname(path.parentFolder)[0])[1].slice(0, -1));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
var PathCache = function () {
|
||||
"use strict";
|
||||
/*global $*/
|
||||
|
||||
|
||||
var pathnameRegEx = /^(\/(.*\/)*)([^\/]+\/?)$/;
|
||||
var pathCache,
|
||||
cache = {},
|
||||
rePathnameSplit = /^(\/(.*\/)*)([^\/]+\/?)$/,
|
||||
rePathEndsWithSlash = /\/$/,
|
||||
splitPathname = function (pathname) {
|
||||
|
||||
this.splitPathname = function ( pathname ) {
|
||||
|
||||
if ( pathname === "/" ) {
|
||||
return [ "", "/" ];
|
||||
};
|
||||
var match = pathnameRegEx.exec( pathname );
|
||||
return [ match[1], match[3] ];
|
||||
};
|
||||
var match;
|
||||
|
||||
if (pathname === "/") {
|
||||
return ["", "/"];
|
||||
}
|
||||
match = rePathnameSplit.exec(pathname);
|
||||
return [match[1], match[3]];
|
||||
},
|
||||
pathEndsWithSlash = function (pathname) {
|
||||
|
||||
this.cache = {};
|
||||
return rePathEndsWithSlash.test(pathname);
|
||||
},
|
||||
getAbsHref = function (folder, tableRow) {
|
||||
|
||||
var $a, isParentFolder, href;
|
||||
|
||||
this.loadCache = function () {
|
||||
if (!pathEndsWithSlash(folder)) {
|
||||
folder += "/";
|
||||
}
|
||||
if (!tableRow) {
|
||||
return folder;
|
||||
}
|
||||
$a = $(tableRow).find("td").eq(1).find("a");
|
||||
isParentFolder = ($a.text() === "Parent Directory");
|
||||
href = $a.attr("href");
|
||||
return isParentFolder ? undefined : folder + href;
|
||||
},
|
||||
getPath = function (folder, tableRow) {
|
||||
|
||||
var json = localStorage.getItem( "h5ai.cache" );
|
||||
var objs = $.evalJSON( json );
|
||||
var cache = {};
|
||||
for ( idx in objs ) {
|
||||
var obj = objs[idx];
|
||||
var path = this.objectToPath( obj );
|
||||
cache[path.absHref] = path;
|
||||
};
|
||||
return cache;
|
||||
};
|
||||
var absHref = getAbsHref(folder, tableRow),
|
||||
path = cache[absHref];
|
||||
|
||||
if (!path) {
|
||||
path = new Path(pathCache, folder, tableRow);
|
||||
if (!path.isParentFolder) {
|
||||
cache[path.absHref] = path;
|
||||
}
|
||||
}
|
||||
|
||||
this.storeCache = function () {
|
||||
return path;
|
||||
};
|
||||
|
||||
var objs = [];
|
||||
for ( ref in this.cache ) {
|
||||
var path = this.cache[ref];
|
||||
if ( path.isFolder ) {
|
||||
objs.push( this.pathToObject( path ) );
|
||||
};
|
||||
};
|
||||
var json = $.toJSON( objs );
|
||||
localStorage.setItem( "h5ai.cache", json );
|
||||
};
|
||||
|
||||
|
||||
this.pathToObject = function ( path ) {
|
||||
|
||||
var object = {
|
||||
r: path.absHref,
|
||||
s: path.status,
|
||||
c: [],
|
||||
o: path.treeOpen
|
||||
};
|
||||
|
||||
if ( path.content !== undefined ) {
|
||||
for ( ref in path.content ) {
|
||||
object.c.push( ref );
|
||||
};
|
||||
};
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
|
||||
this.objectToPath = function ( obj ) {
|
||||
|
||||
var path = this.getPathForFolder( obj.r );
|
||||
path.status = obj.s;
|
||||
path.content = {};
|
||||
path.treeOpen = obj.o;
|
||||
for ( idx in obj.c ) {
|
||||
var href = obj.c[idx];
|
||||
path.content[href] = this.getPathForFolder( href );
|
||||
};
|
||||
return path;
|
||||
};
|
||||
|
||||
|
||||
this.getPathForFolder = function ( folder ) {
|
||||
|
||||
return this.getCachedPath( new Path( this, folder ) );
|
||||
};
|
||||
|
||||
|
||||
this.getPathForTableRow = function ( parentFolder, tableRow ) {
|
||||
|
||||
return this.getCachedPath( new Path( this, parentFolder, tableRow ) );
|
||||
};
|
||||
|
||||
|
||||
this.getCachedPath = function ( path ) {
|
||||
|
||||
if ( path.isParentFolder ) {
|
||||
return path;
|
||||
};
|
||||
|
||||
var cachedPath = this.cache[path.absHref];
|
||||
if ( cachedPath !== undefined ) {
|
||||
return cachedPath;
|
||||
};
|
||||
|
||||
this.cache[path.absHref] = path;
|
||||
this.storeCache();
|
||||
return path;
|
||||
};
|
||||
|
||||
this.cache = this.loadCache();
|
||||
pathCache = {
|
||||
splitPathname: splitPathname,
|
||||
pathEndsWithSlash: pathEndsWithSlash,
|
||||
getPath: getPath
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
var Path = function ( pathCache, folder, tableRow ) {
|
||||
|
||||
if ( ! /\/$/.test( folder ) ) {
|
||||
folder += "/";
|
||||
};
|
||||
|
||||
if ( tableRow !== undefined ) {
|
||||
var $tds = $( tableRow ).find( "td" );
|
||||
var $img = $tds.eq( 0 ).find( "img" );
|
||||
var $a= $tds.eq( 1 ).find( "a" );
|
||||
|
||||
this.parentFolder = folder;
|
||||
this.icon16 = $img.attr( "src" );
|
||||
this.alt = $img.attr( "alt" );
|
||||
this.label = $a.text();
|
||||
this.href = $a.attr("href"); //decodeURI( $a.attr("href") );
|
||||
this.date = $tds.eq( 2 ).text();
|
||||
this.size = $tds.eq( 3 ).text();
|
||||
} else {
|
||||
var splits = pathCache.splitPathname( folder );
|
||||
|
||||
this.parentFolder = splits[0];
|
||||
this.href = splits[1];
|
||||
this.label = decodeURI( splits[1] );
|
||||
this.icon16 = "/h5ai/icons/16x16/folder.png";
|
||||
this.alt = "[DIR]";
|
||||
this.date = "";
|
||||
this.size = "";
|
||||
if ( this.label === "/" ) {
|
||||
this.label = decodeURI( document.domain ) + "/";
|
||||
};
|
||||
};
|
||||
|
||||
if ( /\/$/.test( this.label ) ) {
|
||||
this.label = this.label.slice( 0, -1 );
|
||||
};
|
||||
|
||||
this.icon48 = this.icon16.replace( "16x16", "48x48" );
|
||||
this.isFolder = ( this.alt === "[DIR]" );
|
||||
this.isParentFolder = ( this.isFolder && this.label === "Parent Directory" );
|
||||
this.absHref = this.isParentFolder ? this.href : this.parentFolder + this.href;
|
||||
this.isCurrentFolder = ( this.absHref === document.location.pathname );
|
||||
this.isDomain = ( this.absHref === "/" );
|
||||
|
||||
if ( this.isParentFolder && h5ai.config.setParentFolderLabels ) {
|
||||
if ( this.isDomain ) {
|
||||
this.label = decodeURI( document.domain );
|
||||
} else {
|
||||
this.label = decodeURI( pathCache.splitPathname( pathCache.splitPathname( this.parentFolder )[0] )[1].slice( 0, -1 ) );
|
||||
};
|
||||
};
|
||||
|
||||
this.status = undefined; // undefined, "h5ai" or HTTP response code
|
||||
this.content = undefined; // associative array path.absHref -> path
|
||||
this.html = {
|
||||
$crumb: undefined,
|
||||
$extended: undefined,
|
||||
$tree: undefined
|
||||
};
|
||||
this.treeOpen = false;
|
||||
|
||||
this.isEmpty = function() {
|
||||
|
||||
return this.content === undefined || $.isEmptyObject( this.content );
|
||||
};
|
||||
|
||||
|
||||
this.onClick = function ( context ) {
|
||||
|
||||
pathCache.storeCache();
|
||||
h5ai.triggerPathClick( this, context );
|
||||
};
|
||||
|
||||
|
||||
this.onHoverIn = function () {
|
||||
|
||||
if ( h5ai.config.linkHoverStates ) {
|
||||
for ( ref in this.html ) {
|
||||
$ref = this.html[ref];
|
||||
if ( $ref !== undefined ) {
|
||||
$ref.find( "> a" ).addClass( "hover" );
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.onHoverOut = function () {
|
||||
|
||||
if ( h5ai.config.linkHoverStates ) {
|
||||
for ( ref in this.html ) {
|
||||
$ref = this.html[ref];
|
||||
if ( $ref !== undefined ) {
|
||||
$ref.find( "> a" ).removeClass( "hover" );
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.updateHtml = function () {
|
||||
|
||||
this.updateCrumbHtml();
|
||||
this.updateExtendedHtml();
|
||||
this.updateTreeHtml();
|
||||
};
|
||||
|
||||
|
||||
this.updateCrumbHtml = function () {
|
||||
|
||||
var $html = $( "<li class='crumb' />" ).data( "path", this );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a><img src='/h5ai/images/crumb.png' alt='>' />" + this.label + "</a>" );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "crumb" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "crumb" ); }, this ), $.proxy( function() { this.onHoverOut( "crumb" ); }, this ) );
|
||||
$html.append( $a );
|
||||
|
||||
if ( this.isDomain ) {
|
||||
$html.addClass( "domain" );
|
||||
$a.find( "img" ).attr( "src", "/h5ai/images/home.png" );
|
||||
};
|
||||
|
||||
if ( this.isCurrentFolder ) {
|
||||
$html.addClass( "current" );
|
||||
};
|
||||
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$( "<img class='hint' src='/h5ai/images/page.png' alt='not listable' />" ).appendTo( $a );
|
||||
} else {
|
||||
$( "<span class='hint'>(" + this.status + ")</span>" ).appendTo( $a );
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$crumb !== undefined ) {
|
||||
this.html.$crumb.replaceWith( $html );
|
||||
};
|
||||
this.html.$crumb = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
|
||||
|
||||
this.updateExtendedHtml = function () {
|
||||
|
||||
var $html = $( "<li class='entry' />" ).data( "path", this );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a />" ).appendTo( $html );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "extended" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "extended" ); }, this ), $.proxy( function() { this.onHoverOut( "extended" ); }, this ) );
|
||||
|
||||
$( "<span class='icon small'><img src='" + this.icon16 + "' alt='" + this.alt + "' /></span>" ).appendTo( $a );
|
||||
$( "<span class='icon big'><img src='" + this.icon48 + "' alt='" + this.alt + "' /></span>" ).appendTo( $a );
|
||||
var $label = $( "<span class='label'>" + this.label + "</span>" ).appendTo( $a );
|
||||
$( "<span class='date'>" + this.date + "</span>" ).appendTo( $a );
|
||||
$( "<span class='size'>" + this.size + "</span>" ).appendTo( $a );
|
||||
|
||||
if ( this.isParentFolder ) {
|
||||
if ( !h5ai.config.setParentFolderLabels ) {
|
||||
$label.addClass( "l10n-parentDirectory" );
|
||||
};
|
||||
$html.addClass( "parentfolder" );
|
||||
};
|
||||
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$html.addClass( "page" );
|
||||
$a.find( ".icon.small img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.find( ".icon.big img" ).attr( "src", "/h5ai/icons/48x48/folder-page.png" );
|
||||
} else {
|
||||
$html.addClass( "error" );
|
||||
$label.append( $( "<span class='hint'> " + this.status + " </span>" ) );
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$extended !== undefined ) {
|
||||
this.html.$extended.replaceWith( $html );
|
||||
};
|
||||
this.html.$extended = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
|
||||
|
||||
this.updateTreeHtml = function () {
|
||||
|
||||
var $html = $( "<div class='entry' />" ).data( "path", this );
|
||||
var $blank = $( "<span class='blank' />" ).appendTo( $html );
|
||||
|
||||
try {
|
||||
$html.addClass( this.isFolder ? "folder" : "file" );
|
||||
var $a = $( "<a />" )
|
||||
.appendTo( $html )
|
||||
.append( $( "<span class='icon'><img src='" + this.icon16 + "' /></span>" ) )
|
||||
.append( $( "<span class='label'>" + this.label + "</span>" ) );
|
||||
$a.attr( "href", this.absHref );
|
||||
$a.click( $.proxy( function() { this.onClick( "tree" ); }, this ) );
|
||||
$a.hover( $.proxy( function() { this.onHoverIn( "tree" ); }, this ), $.proxy( function() { this.onHoverOut( "tree" ); }, this ) );
|
||||
|
||||
if ( this.isFolder ) {
|
||||
// indicator
|
||||
if ( this.status === undefined || !this.isEmpty() ) {
|
||||
var $indicator = $( "<span class='indicator'><img src='/h5ai/images/tree.png' /></span>" );
|
||||
if ( this.status === undefined ) {
|
||||
$indicator.addClass( "unknown" );
|
||||
} else if ( this.treeOpen ) {
|
||||
$indicator.addClass( "open" );
|
||||
};
|
||||
$indicator.click( $.proxy( function( event ) {
|
||||
if ( $indicator.hasClass( "unknown" ) ) {
|
||||
tree.fetchStatusAndContent( this.absHref, false, $.proxy( function ( status, content ) {
|
||||
this.status = status;
|
||||
this.content = content;
|
||||
this.treeOpen = true;
|
||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||
this.updateTreeHtml( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
}, this ) );
|
||||
} else if ( $indicator.hasClass( "open" ) ) {
|
||||
this.treeOpen = false;
|
||||
$indicator.removeClass( "open" );
|
||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||
$html.find( "> ul.content" ).slideUp( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
} else {
|
||||
this.treeOpen = true;
|
||||
$indicator.addClass( "open" );
|
||||
$( "#tree" ).get( 0 ).updateScrollbar( true );
|
||||
$html.find( "> ul.content" ).slideDown( function() {
|
||||
$( "#tree" ).get( 0 ).updateScrollbar();
|
||||
} );
|
||||
};
|
||||
}, this ) );
|
||||
$blank.replaceWith( $indicator );
|
||||
};
|
||||
|
||||
// is this the domain?
|
||||
if ( this.isDomain ) {
|
||||
$html.addClass( "domain" );
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-home.png" );
|
||||
};
|
||||
|
||||
// is this the current folder?
|
||||
if ( this.isCurrentFolder ) {
|
||||
$html.addClass( "current" );
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-open.png" );
|
||||
};
|
||||
|
||||
// does it have subfolders?
|
||||
if ( !this.isEmpty() ) {
|
||||
var $ul = $( "<ul class='content' />" ).appendTo( $html );
|
||||
for ( idx in this.content ) {
|
||||
$( "<li />" ).append( this.content[idx].updateTreeHtml() ).appendTo( $ul );
|
||||
};
|
||||
if ( this.status === undefined || !this.treeOpen ) {
|
||||
$ul.hide();
|
||||
};
|
||||
};
|
||||
|
||||
// reflect folder status
|
||||
if ( !isNaN( this.status ) ) {
|
||||
if ( this.status === 200 ) {
|
||||
$a.find( ".icon img" ).attr( "src", "/h5ai/icons/16x16/folder-page.png" );
|
||||
$a.append( $( "<span class='hint'><img src='/h5ai/images/page.png' /></span>" ) );
|
||||
} else {
|
||||
$html.addClass( "error" );
|
||||
$a.append( $( "<span class='hint'>" + this.status + "</span>" ) );
|
||||
};
|
||||
};
|
||||
};
|
||||
} catch( err ) {
|
||||
$( "<span class='fail'>failed</span>" ).appendTo( $html );
|
||||
};
|
||||
|
||||
if ( this.html.$tree !== undefined ) {
|
||||
this.html.$tree.replaceWith( $html );
|
||||
};
|
||||
this.html.$tree = $html;
|
||||
|
||||
return $html;
|
||||
};
|
||||
return pathCache;
|
||||
};
|
||||
|
@@ -1,287 +1,147 @@
|
||||
|
||||
var Tree = function ( pathCache, h5ai ) {
|
||||
var Tree = function (pathCache, h5ai) {
|
||||
"use strict";
|
||||
/*global $*/
|
||||
|
||||
var THIS = this;
|
||||
var contentTypeRegEx = /^text\/html;h5ai=/;
|
||||
var contentTypeRegEx = /^text\/html;h5ai=/,
|
||||
pathnameStatusCache = {},
|
||||
fetchStatus = function (pathname, callback) {
|
||||
|
||||
this.init = function () {
|
||||
if (h5ai.settings.folderStatus[pathname]) {
|
||||
callback(h5ai.settings.folderStatus[pathname]);
|
||||
return;
|
||||
} else if (pathnameStatusCache[pathname]) {
|
||||
callback(pathnameStatusCache[pathname]);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( h5ai.config.showTree ) {
|
||||
this.updatePaths();
|
||||
this.populateTree();
|
||||
};
|
||||
};
|
||||
$.ajax({
|
||||
url: pathname,
|
||||
type: "HEAD",
|
||||
complete: function (xhr) {
|
||||
|
||||
var status = xhr.status;
|
||||
|
||||
this.updatePath = function ( path ) {
|
||||
if (status === 200 && contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
|
||||
status = "h5ai";
|
||||
}
|
||||
pathnameStatusCache[pathname] = status;
|
||||
callback(status);
|
||||
}
|
||||
});
|
||||
},
|
||||
updatePath = function (path) {
|
||||
|
||||
if ( path.isFolder && !path.isParentFolder && path.status === undefined ) {
|
||||
this.fetchStatus( path.absHref, function ( status ) {
|
||||
if ( status !== "h5ai" ) {
|
||||
path.status = status;
|
||||
};
|
||||
path.updateHtml();
|
||||
} );
|
||||
};
|
||||
};
|
||||
if (path.isFolder && !path.isParentFolder && path.status === undefined) {
|
||||
fetchStatus(path.absHref, function (status) {
|
||||
|
||||
if (status !== "h5ai") {
|
||||
path.status = status;
|
||||
}
|
||||
path.updateHtml();
|
||||
h5ai.linkHoverStates();
|
||||
});
|
||||
}
|
||||
},
|
||||
updatePaths = function () {
|
||||
|
||||
this.updatePaths = function () {
|
||||
var ref;
|
||||
|
||||
for ( var ref in pathCache.cache ) {
|
||||
this.updatePath( pathCache.cache[ref] );
|
||||
};
|
||||
};
|
||||
for (ref in pathCache.cache) {
|
||||
updatePath(pathCache.cache[ref]);
|
||||
}
|
||||
},
|
||||
fetchStatusAndContent = function (pathname, includeParent, callback) {
|
||||
|
||||
fetchStatus(pathname, function (status) {
|
||||
|
||||
this.populateTree = function () {
|
||||
if (status !== "h5ai") {
|
||||
callback(status, {});
|
||||
return;
|
||||
}
|
||||
|
||||
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() } );
|
||||
};
|
||||
};
|
||||
};
|
||||
$.ajax({
|
||||
url: pathname,
|
||||
type: "GET",
|
||||
dataType: "html",
|
||||
error: function (xhr) {
|
||||
|
||||
$tree.hover( function () { shiftTree( true ); }, function () { shiftTree(); } );
|
||||
$( window ).resize( function() {
|
||||
shiftTree();
|
||||
} );
|
||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
||||
},
|
||||
success: function (html, status, xhr) {
|
||||
|
||||
this.fetchTree( document.location.pathname, function( path ) {
|
||||
$tree.append( path.updateTreeHtml() );
|
||||
$tree.show();
|
||||
scrollpanel( $tree );
|
||||
shiftTree( false, true );
|
||||
} );
|
||||
};
|
||||
var content = {};
|
||||
|
||||
if (!contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
|
||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchTree = function ( pathname, callback, childPath ) {
|
||||
$(html).find("#table td").closest("tr").each(function () {
|
||||
|
||||
this.fetchPath( pathname, $.proxy( function ( path ) {
|
||||
|
||||
path.treeOpen = true;
|
||||
|
||||
if ( childPath !== undefined ) {
|
||||
path.content[ childPath.absHref ] = childPath;
|
||||
};
|
||||
var path = pathCache.getPath(pathname, this);
|
||||
|
||||
var parent = pathCache.splitPathname( pathname )[0];
|
||||
if ( parent === "" ) {
|
||||
callback( path );
|
||||
} else {
|
||||
this.fetchTree( parent, callback, path );
|
||||
};
|
||||
}, this ) );
|
||||
};
|
||||
if (path.isFolder && (!path.isParentFolder || includeParent)) {
|
||||
content[path.absHref] = path;
|
||||
updatePath(path);
|
||||
}
|
||||
});
|
||||
callback("h5ai", content);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
fetchPath = function (pathname, callback) {
|
||||
|
||||
fetchStatusAndContent(pathname, false, function (status, content) {
|
||||
|
||||
this.fetchPath = function ( pathname, callback ) {
|
||||
var path = pathCache.getPath(pathname);
|
||||
|
||||
this.fetchStatusAndContent( pathname, false, function ( status, content ) {
|
||||
var path = pathCache.getPathForFolder( pathname );
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
callback( path );
|
||||
} );
|
||||
};
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
callback(path);
|
||||
});
|
||||
},
|
||||
fetchTree = function (pathname, callback, childPath) {
|
||||
|
||||
fetchPath(pathname, function (path) {
|
||||
|
||||
this.fetchStatusAndContent = function ( pathname, includeParent, callback ) {
|
||||
var parent = pathCache.splitPathname(pathname)[0];
|
||||
|
||||
this.fetchStatus( pathname, function ( status ) {
|
||||
path.treeOpen = true;
|
||||
if (childPath) {
|
||||
path.content[childPath.absHref] = childPath;
|
||||
}
|
||||
if (parent === "") {
|
||||
callback(path);
|
||||
} else {
|
||||
fetchTree(parent, callback, path);
|
||||
}
|
||||
});
|
||||
},
|
||||
populateTree = function () {
|
||||
|
||||
if ( status !== "h5ai" ) {
|
||||
callback( status, {} );
|
||||
return;
|
||||
};
|
||||
fetchTree(document.location.pathname, function (path) {
|
||||
$("#tree")
|
||||
.append(path.updateTreeHtml())
|
||||
.scrollpanel()
|
||||
.show();
|
||||
h5ai.shiftTree(false, true);
|
||||
h5ai.linkHoverStates();
|
||||
setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1);
|
||||
});
|
||||
},
|
||||
init = function () {
|
||||
|
||||
$.ajax( {
|
||||
url: pathname,
|
||||
type: "GET",
|
||||
dataType: "html",
|
||||
error: function ( xhr ) {
|
||||
callback( xhr.status, {} ); // since it was checked before this should never happen
|
||||
},
|
||||
success: function ( html, status, xhr ) {
|
||||
if ( !contentTypeRegEx.test( xhr.getResponseHeader( "Content-Type" ) ) ) {
|
||||
callback( xhr.status, {} ); // since it was checked before this should never happen
|
||||
return;
|
||||
};
|
||||
|
||||
var content = {};
|
||||
$( html ).find( "#table td" ).closest( "tr" ).each( function () {
|
||||
var path = pathCache.getPathForTableRow( pathname, this );
|
||||
if ( path.isFolder && ( !path.isParentFolder || includeParent ) ) {
|
||||
content[path.absHref] = path;
|
||||
THIS.updatePath( path );
|
||||
};
|
||||
} );
|
||||
callback( "h5ai", content );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
var pathnameStatusCache = {};
|
||||
|
||||
this.fetchStatus = function ( pathname, callback ) {
|
||||
|
||||
if ( h5ai.config.folderStatus[ pathname ] !== undefined ) {
|
||||
callback( h5ai.config.folderStatus[ pathname ] );
|
||||
return;
|
||||
} else if ( pathnameStatusCache[ pathname ] !== undefined ) {
|
||||
callback( pathnameStatusCache[ pathname ] );
|
||||
return;
|
||||
};
|
||||
|
||||
$.ajax( {
|
||||
url: pathname,
|
||||
type: "HEAD",
|
||||
complete: function ( xhr ) {
|
||||
var status = xhr.status;
|
||||
if ( status === 200 && contentTypeRegEx.test( xhr.getResponseHeader( "Content-Type" ) ) ) {
|
||||
status = "h5ai";
|
||||
};
|
||||
pathnameStatusCache[ pathname ] = status;
|
||||
callback( status );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
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();
|
||||
};
|
||||
if (h5ai.settings.showTree) {
|
||||
updatePaths();
|
||||
populateTree();
|
||||
}
|
||||
},
|
||||
tree = {
|
||||
fetchStatusAndContent: fetchStatusAndContent,
|
||||
init: init
|
||||
};
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
30
src/h5ai/js/main-js.js
Normal file
@@ -0,0 +1,30 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
/*global jQuery, h5aiOptions, h5aiLangs*/
|
||||
|
||||
// @include "inc/jquery.mousewheel.min.js"
|
||||
// @include "inc/jquery.scrollpanel.js"
|
||||
// @include "inc/jquery.utils.js"
|
||||
// @include "inc/jquery.fracs.js"
|
||||
// @include "inc/path.js"
|
||||
// @include "inc/h5ai.js"
|
||||
// @include "inc/extended.js"
|
||||
// @include "inc/tree.js"
|
||||
|
||||
var pathCache = new PathCache(),
|
||||
h5ai = new H5ai(h5aiOptions, h5aiLangs),
|
||||
extended = new Extended(pathCache, h5ai),
|
||||
tree = new Tree(pathCache, h5ai);
|
||||
|
||||
$.h5ai = {
|
||||
click: $.proxy(h5ai.pathClick, h5ai)
|
||||
};
|
||||
|
||||
$(function () {
|
||||
|
||||
extended.init();
|
||||
tree.init();
|
||||
h5ai.init();
|
||||
});
|
||||
|
||||
})(jQuery);
|
24
src/h5ai/js/main-php.js
Normal file
@@ -0,0 +1,24 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
/*global jQuery, h5aiOptions, h5aiLangs*/
|
||||
|
||||
// @include "inc/jquery.mousewheel.min.js"
|
||||
// @include "inc/jquery.scrollpanel.js"
|
||||
// @include "inc/jquery.utils.js"
|
||||
// @include "inc/jquery.fracs.js"
|
||||
// @include "inc/h5ai.js"
|
||||
|
||||
var h5ai = new H5ai(h5aiOptions, h5aiLangs);
|
||||
|
||||
$.h5ai = {
|
||||
click: $.proxy(h5ai.pathClick, h5ai)
|
||||
};
|
||||
|
||||
$(function () {
|
||||
|
||||
h5ai.init();
|
||||
$("#tree").scrollpanel();
|
||||
h5ai.shiftTree(false, true);
|
||||
});
|
||||
|
||||
})(jQuery);
|
@@ -1,43 +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"
|
||||
|
||||
|
||||
/*******************************
|
||||
* create
|
||||
*******************************/
|
||||
|
||||
var pathCache = new 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.storeCache();
|
||||
} );
|
||||
/////////////////////////////////////////////////////
|
||||
} );
|
||||
|
||||
} )( jQuery );
|
@@ -1,153 +1,325 @@
|
||||
/*
|
||||
* h5ai %BUILD_VERSION%
|
||||
* Options and localization
|
||||
* Options and localization
|
||||
*/
|
||||
|
||||
h5aiOptions = {
|
||||
|
||||
/*
|
||||
* An array of view modes the user may choose from. Currently there
|
||||
* are two possible values: "details" and "icons". The first value
|
||||
* indicates the default view mode. If only one value is given the
|
||||
* view mode is fixed and the selector buttons are hidden.
|
||||
* The user selected view mode is also stored local in modern browsers
|
||||
* so that it will be persistent.
|
||||
*/
|
||||
viewmodes: [ "details", "icons" ],
|
||||
/*
|
||||
* An array of view modes the user may choose from. Currently there
|
||||
* are two possible values: "details" and "icons". The first value
|
||||
* indicates the default view mode. If only one value is given the
|
||||
* view mode is fixed and the selector buttons are hidden.
|
||||
* The user selected view mode is also stored local in modern browsers
|
||||
* so that it will be persistent.
|
||||
*/
|
||||
"viewmodes": ["details", "icons"],
|
||||
|
||||
/*
|
||||
* Show a folder tree, boolean.
|
||||
* Note that this tree might have side effects as it sends HEAD requests
|
||||
* to the folders, and therefore will invoke index.php scripts. Use
|
||||
* folderStatus below to avoid such requests.
|
||||
* It might also affect performance significantly.
|
||||
*/
|
||||
showTree: true,
|
||||
/*
|
||||
* Default sort order. Valid values for column are "name", "date" and
|
||||
* "size".
|
||||
* If you are using the JavaScript version please make sure to change
|
||||
* IndexOrderDefault in js.htaccess as well.
|
||||
*/
|
||||
"sortorder": {
|
||||
"column": "name",
|
||||
"ascending": true
|
||||
},
|
||||
|
||||
/*
|
||||
* Associative array of folders and their HTTP status codes to
|
||||
* avoid HEAD requests to that folders. The key (folder) must start
|
||||
* and end with a slash (/).
|
||||
* For example:
|
||||
* "/some/folder/": 200
|
||||
* will always return HTTP status 200 (OK), which will be interpreted
|
||||
* as a non auto indexed folder, that means a folder containing an
|
||||
* appropriate default index file.
|
||||
*/
|
||||
folderStatus: {
|
||||
/*
|
||||
* for example:
|
||||
* "/some/folder/": 200
|
||||
*/
|
||||
},
|
||||
/*
|
||||
* Show a folder tree, boolean.
|
||||
* Note that this tree might have side effects as it sends HEAD requests
|
||||
* to the folders, and therefore will invoke index.php scripts. Use
|
||||
* folderStatus below to avoid such requests.
|
||||
* It might also affect performance significantly.
|
||||
*/
|
||||
"showTree": true,
|
||||
|
||||
/*
|
||||
* Localization, for example "en", "de" etc. - see h5aiLangs below for
|
||||
* possible values. Adjust it to your needs. If lang is not found in
|
||||
* h5aiLangs the displayed labels stay unchanged.
|
||||
*/
|
||||
lang: undefined,
|
||||
/*
|
||||
* Slide tree bar into viewport if there is enough space, boolean.
|
||||
*/
|
||||
"slideTree": true,
|
||||
|
||||
/*
|
||||
* Try to use browser language, falls back to previous specified lang.
|
||||
*/
|
||||
useBrowserLang: true,
|
||||
|
||||
/*
|
||||
* Set parent folder labels to real folder names.
|
||||
*/
|
||||
setParentFolderLabels: true,
|
||||
|
||||
/*
|
||||
* Link the hover effects between crumb, extended view and tree.
|
||||
*/
|
||||
linkHoverStates: true
|
||||
/*
|
||||
* Associative array of folders and their HTTP status codes to
|
||||
* avoid HEAD requests to that folders. The key (folder) must start
|
||||
* and end with a slash (/).
|
||||
* For example:
|
||||
* "/some/folder/": 200
|
||||
* will always return HTTP status 200 (OK), which will be interpreted
|
||||
* as a non auto indexed folder, that means a folder containing an
|
||||
* appropriate default index file.
|
||||
*/
|
||||
"folderStatus": {},
|
||||
|
||||
/*
|
||||
* Localization, for example "en", "de" etc. - see h5aiLangs below for
|
||||
* possible values. Adjust it to your needs. If lang is not found in
|
||||
* h5aiLangs it defaults to "en".
|
||||
*/
|
||||
"lang": null,
|
||||
|
||||
/*
|
||||
* Try to use browser language, falls back to previous specified lang.
|
||||
*/
|
||||
"useBrowserLang": true,
|
||||
|
||||
/*
|
||||
* Set parent folder labels to real folder names.
|
||||
*/
|
||||
"setParentFolderLabels": true,
|
||||
|
||||
/*
|
||||
* Link the hover effects between crumb, extended view and tree.
|
||||
*/
|
||||
"linkHoverStates": true,
|
||||
|
||||
/*
|
||||
* 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",
|
||||
|
||||
/*
|
||||
* IMPORTANT: PHP implementation doesn't care about Apache's
|
||||
* ignores, so you have to specify this here.
|
||||
*
|
||||
* 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": ["/^\\./"],
|
||||
|
||||
/*
|
||||
* Only used in PHP implementation.
|
||||
* Show thumbnails in Icons view.
|
||||
*/
|
||||
"showThumbs": true,
|
||||
|
||||
/*
|
||||
* Enable zipped download of selected entries. Requieres
|
||||
* PHP on the server.
|
||||
*/
|
||||
"zippedDownload": true
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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 = {
|
||||
|
||||
"en": {
|
||||
viewDetails: "details",
|
||||
viewIcons: "icons",
|
||||
columnName: "Name",
|
||||
columnLastModified: "Last modified",
|
||||
columnSize: "Size",
|
||||
footerUsing: "using",
|
||||
parentDirectory: "Parent Directory",
|
||||
empty: "empty"
|
||||
},
|
||||
"en": {
|
||||
"lang": "english",
|
||||
"details": "details",
|
||||
"icons": "icons",
|
||||
"name": "Name",
|
||||
"lastModified": "Last modified",
|
||||
"size": "Size",
|
||||
"parentDirectory": "Parent Directory",
|
||||
"empty": "empty",
|
||||
"folders": "folders",
|
||||
"files": "files",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"de": {
|
||||
viewDetails: "Details",
|
||||
viewIcons: "Icons",
|
||||
columnName: "Name",
|
||||
columnLastModified: "Geändert",
|
||||
columnSize: "Größe",
|
||||
footerUsing: "nutzt",
|
||||
parentDirectory: "Übergeordnetes Verzeichnis",
|
||||
empty: "leer"
|
||||
},
|
||||
|
||||
"fr": {
|
||||
viewDetails: "détails",
|
||||
viewIcons: "icônes",
|
||||
columnName: "Nom",
|
||||
columnLastModified: "Dernière modification",
|
||||
columnSize: "Taille",
|
||||
footerUsing: "utilise",
|
||||
parentDirectory: "Dossier parent",
|
||||
empty: "vide"
|
||||
},
|
||||
"de": {
|
||||
"lang": "deutsch",
|
||||
"details": "Details",
|
||||
"icons": "Icons",
|
||||
"name": "Name",
|
||||
"lastModified": "Geändert",
|
||||
"size": "Größe",
|
||||
"parentDirectory": "Übergeordnetes Verzeichnis",
|
||||
"empty": "leer",
|
||||
"folders": "Ordner",
|
||||
"files": "Dateien",
|
||||
"download": "Download"
|
||||
},
|
||||
|
||||
"nl": {
|
||||
viewDetails: "details",
|
||||
viewIcons: "iconen",
|
||||
columnName: "Naam",
|
||||
columnLastModified: "Laatste wijziging",
|
||||
columnSize: "Grootte",
|
||||
footerUsing: "gebruikt",
|
||||
parentDirectory: "Bovenliggende map",
|
||||
empty: "lege"
|
||||
},
|
||||
"fr": {
|
||||
"lang": "français",
|
||||
"details": "détails",
|
||||
"icons": "icônes",
|
||||
"name": "Nom",
|
||||
"lastModified": "Dernière modification",
|
||||
"size": "Taille",
|
||||
"parentDirectory": "Dossier parent",
|
||||
"empty": "vide",
|
||||
"folders": "Répertoires",
|
||||
"files": "Fichiers",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"sv": {
|
||||
viewDetails: "detaljerad",
|
||||
viewIcons: "ikoner",
|
||||
columnName: "Filnamn",
|
||||
columnLastModified: "Senast ändrad",
|
||||
columnSize: "Filstorlek",
|
||||
footerUsing: "använder",
|
||||
parentDirectory: "Till överordnad mapp",
|
||||
empty: "tom"
|
||||
},
|
||||
"nl": {
|
||||
"lang": "nederlands",
|
||||
"details": "details",
|
||||
"icons": "iconen",
|
||||
"name": "Naam",
|
||||
"lastModified": "Laatste wijziging",
|
||||
"size": "Grootte",
|
||||
"parentDirectory": "Bovenliggende map",
|
||||
"empty": "lege",
|
||||
"folders": "folders",
|
||||
"files": "files",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"cs": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Název",
|
||||
columnLastModified: "Upraveno",
|
||||
columnSize: "Velikost",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadřazený adresář",
|
||||
empty: "prázdný"
|
||||
},
|
||||
"sv": {
|
||||
"lang": "svenska",
|
||||
"details": "detaljerad",
|
||||
"icons": "ikoner",
|
||||
"name": "Filnamn",
|
||||
"lastModified": "Senast ändrad",
|
||||
"size": "Filstorlek",
|
||||
"parentDirectory": "Till överordnad mapp",
|
||||
"empty": "tom",
|
||||
"folders": "folders",
|
||||
"files": "files",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"sk": {
|
||||
viewDetails: "podrobnosti",
|
||||
viewIcons: "ikony",
|
||||
columnName: "Názov",
|
||||
columnLastModified: "Upravené",
|
||||
columnSize: "Velkosť",
|
||||
footerUsing: "používá",
|
||||
parentDirectory: "Nadriadený priečinok",
|
||||
empty: "prázdny"
|
||||
}
|
||||
|
||||
"cs": {
|
||||
"lang": "čeština",
|
||||
"details": "podrobnosti",
|
||||
"icons": "ikony",
|
||||
"name": "Název",
|
||||
"lastModified": "Upraveno",
|
||||
"size": "Velikost",
|
||||
"parentDirectory": "Nadřazený adresář",
|
||||
"empty": "prázdný",
|
||||
"folders": "složek",
|
||||
"files": "souborů",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"sk": {
|
||||
"lang": "slovenčina",
|
||||
"details": "podrobnosti",
|
||||
"icons": "ikony",
|
||||
"name": "Názov",
|
||||
"lastModified": "Upravené",
|
||||
"size": "Velkosť",
|
||||
"parentDirectory": "Nadriadený priečinok",
|
||||
"empty": "prázdny",
|
||||
"folders": "priečinkov",
|
||||
"files": "súborov",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"es": {
|
||||
"lang": "español",
|
||||
"details": "Detalles",
|
||||
"icons": "Íconos",
|
||||
"name": "Nombre",
|
||||
"lastModified": "Última modificación",
|
||||
"size": "Tamaño",
|
||||
"parentDirectory": "Directorio superior",
|
||||
"empty": "vacío",
|
||||
"folders": "folders",
|
||||
"files": "files",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"tr": {
|
||||
"lang": "türkçe",
|
||||
"details": "detaylar",
|
||||
"icons": "ikonlar",
|
||||
"name": "İsim",
|
||||
"lastModified": "Son Düzenleme",
|
||||
"size": "Boyut",
|
||||
"parentDirectory": "Üst Dizin",
|
||||
"empty": "boş",
|
||||
"folders": "folders",
|
||||
"files": "files",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"pt": {
|
||||
"lang": "português",
|
||||
"details": "detalhes",
|
||||
"icons": "ícones",
|
||||
"name": "Nome",
|
||||
"lastModified": "Última modificação",
|
||||
"size": "Tamanho",
|
||||
"parentDirectory": "Diretório superior",
|
||||
"empty": "vazio",
|
||||
"folders": "pastas",
|
||||
"files": "arquivos",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"bg": {
|
||||
"lang": "български",
|
||||
"details": "детайли",
|
||||
"icons": "икони",
|
||||
"name": "Име",
|
||||
"lastModified": "Последна промяна",
|
||||
"size": "Размер",
|
||||
"parentDirectory": "Предходна директория",
|
||||
"empty": "празно",
|
||||
"folders": "папки",
|
||||
"files": "файлове",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"lv": {
|
||||
"lang": "latviešu",
|
||||
"details": "detaļas",
|
||||
"icons": "ikonas",
|
||||
"name": "Nosaukums",
|
||||
"lastModified": "Pēdējoreiz modificēts",
|
||||
"size": "Izmērs",
|
||||
"parentDirectory": "Vecākdirektorijs",
|
||||
"empty": "tukšs",
|
||||
"folders": "mapes",
|
||||
"files": "faili",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"zh-cn": {
|
||||
"lang": "简体中文",
|
||||
"details": "详情",
|
||||
"icons": "图标",
|
||||
"name": "文件名",
|
||||
"lastModified": "上次修改",
|
||||
"size": "大小",
|
||||
"parentDirectory": "上层文件夹",
|
||||
"empty": "空文件夹",
|
||||
"folders": "文件夹",
|
||||
"files": "文件",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"pl": {
|
||||
"lang": "polski",
|
||||
"details": "szczegóły",
|
||||
"icons": "ikony",
|
||||
"name": "Nazwa",
|
||||
"lastModified": "Ostatnia modyfikacja",
|
||||
"size": "Rozmiar",
|
||||
"parentDirectory": "Katalog nadrzędny",
|
||||
"empty": "pusty",
|
||||
"folders": "foldery",
|
||||
"files": "pliki",
|
||||
"download": "download"
|
||||
},
|
||||
|
||||
"ru": {
|
||||
"lang": "русский",
|
||||
"details": "детали",
|
||||
"icons": "иконки",
|
||||
"name": "Имя",
|
||||
"lastModified": "Последние изменения",
|
||||
"size": "Размер",
|
||||
"parentDirectory": "Главная директория",
|
||||
"empty": "пусто",
|
||||
"folders": "папки",
|
||||
"files": "файлы",
|
||||
"download": "download"
|
||||
}
|
||||
};
|
||||
|
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 . ">") : "";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
223
src/h5ai/php/extended.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
require_once "thumbnail.php";
|
||||
|
||||
|
||||
class Entry {
|
||||
private $h5ai, $label, $absPath, $absHref, $date, $isFolder, $type, $size, $thumbTypes;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$this->thumbTypes = array("bmp", "gif", "ico", "image", "jpg", "png", "tiff");
|
||||
}
|
||||
|
||||
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;
|
||||
$smallImg = "/h5ai/icons/16x16/" . $this->type . ".png";
|
||||
$bigImg = "/h5ai/icons/48x48/" . $this->type . ".png";
|
||||
$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";
|
||||
$smallImg = "/h5ai/icons/16x16/folder-page.png";
|
||||
$bigImg = "/h5ai/icons/48x48/folder-page.png";
|
||||
} else {
|
||||
$classes .= " error";
|
||||
$hint = "<span class='hint'> " . $code . " </span>";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->h5ai->showThumbs() && in_array($this->type, $this->thumbTypes)) {
|
||||
$classes .= " thumb";
|
||||
$thumbnail = new Thumbnail($this->absPath, "square", 16, 16);
|
||||
$thumbnail->create();
|
||||
$smallImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
|
||||
$thumbnail = new Thumbnail($this->absPath, "rational", 96, 46);
|
||||
$thumbnail->create();
|
||||
$bigImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
|
||||
}
|
||||
|
||||
$html = "\t<li class='" . $classes . "'>\n";
|
||||
$html .= "\t\t<a href='" . $this->absHref . "'>\n";
|
||||
$html .= "\t\t\t<span class='icon small'><img src='" . $smallImg . "' alt='" . $img . "' /></span>\n";
|
||||
$html .= "\t\t\t<span class='icon big'><img src='" . $bigImg . "' alt='" . $img . "' /></span>\n";
|
||||
$html .= "\t\t\t<span class='label'>" . $this->label . $hint . "</span>\n";
|
||||
$html .= "\t\t\t<span class='date'>" . $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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
277
src/h5ai/php/h5ai.php
Normal file
@@ -0,0 +1,277 @@
|
||||
<?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"];
|
||||
|
||||
$defaultSortOrder = $this->options["options"]["sortorder"];
|
||||
$this->sortOrder = array(
|
||||
"column" => array_key_exists("col", $_REQUEST) ? $_REQUEST["col"] : $defaultSortOrder["column"],
|
||||
"ascending" => array_key_exists("asc", $_REQUEST) ? $_REQUEST["asc"] !== "false" : $defaultSortOrder["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;
|
||||
}
|
||||
$absHref = preg_replace("!^" . $this->docRoot . "!", "", $absPath);
|
||||
$parts = explode("/", $absHref);
|
||||
$encodedParts = array();
|
||||
foreach ($parts as $part) {
|
||||
$encodedParts[] = rawurlencode($part);
|
||||
}
|
||||
$endodedAbsHref = implode("/", $encodedParts);
|
||||
return $this->normalizePath($endodedAbsHref, $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 showThumbs() {
|
||||
|
||||
return $this->options["options"]["showThumbs"] === true;
|
||||
}
|
||||
|
||||
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 strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0;
|
||||
}
|
||||
|
||||
public function endsWith($sequence, $end) {
|
||||
|
||||
return strcasecmp(substr($sequence, -strlen($end)), $end) === 0;
|
||||
}
|
||||
|
||||
public function getHttpCode($absHref) {
|
||||
|
||||
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);
|
||||
|
||||
?>
|
202
src/h5ai/php/image.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
class Image {
|
||||
|
||||
private $sourceFile;
|
||||
private $source;
|
||||
private $width;
|
||||
private $height;
|
||||
private $type;
|
||||
|
||||
private $dest;
|
||||
|
||||
|
||||
public static function isUsable() {
|
||||
|
||||
return GD_VERSION != "GD_VERSION";
|
||||
}
|
||||
|
||||
|
||||
public function __construct($filename = null) {
|
||||
|
||||
$this->sourceFile = null;
|
||||
$this->source = null;
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
$this->type = null;
|
||||
|
||||
$this->dest = null;
|
||||
|
||||
$this->setSource($filename);
|
||||
}
|
||||
|
||||
|
||||
public function __destruct() {
|
||||
|
||||
$this->releaseSource();
|
||||
$this->releaseDest();
|
||||
}
|
||||
|
||||
|
||||
public function setSource($filename) {
|
||||
|
||||
$this->releaseSource();
|
||||
$this->releaseDest();
|
||||
|
||||
if (is_null($filename))
|
||||
return;
|
||||
|
||||
$this->sourceFile = $filename;
|
||||
|
||||
list($this->width, $this->height, $this->type) = getimagesize($this->sourceFile);
|
||||
|
||||
$this->source = imagecreatefromstring(file_get_contents($this->sourceFile));
|
||||
}
|
||||
|
||||
|
||||
public function showDest() {
|
||||
|
||||
if (!is_null($this->dest)) {
|
||||
header("Content-type: image/jpeg");
|
||||
imagejpeg($this->dest, null, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function saveDest($filename) {
|
||||
|
||||
if (!is_null($this->dest)) {
|
||||
@imagejpeg($this->dest, $filename, 90);
|
||||
@chmod($filename, 0775);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function releaseDest() {
|
||||
|
||||
if (!is_null($this->dest)) {
|
||||
imagedestroy($this->dest);
|
||||
$this->dest = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function releaseSource() {
|
||||
|
||||
if (!is_null($this->source)) {
|
||||
imagedestroy($this->source);
|
||||
$this->sourceFile = null;
|
||||
$this->source = null;
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
$this->type = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function showImage($filename) {
|
||||
|
||||
$image = file_get_contents($filename);
|
||||
header("content-type: image");
|
||||
echo $image;
|
||||
}
|
||||
|
||||
|
||||
private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) {
|
||||
|
||||
if (!is_null($canWidth) && !is_null($canHeight)) {
|
||||
$this->dest = imagecreatetruecolor($canWidth, $canHeight);
|
||||
} else {
|
||||
$this->dest = imagecreatetruecolor($destWidth, $destHeight);
|
||||
}
|
||||
|
||||
if (is_null($color)) {
|
||||
$color = array(255, 255, 255);
|
||||
}
|
||||
$icol = imagecolorallocate($this->dest, $color[0], $color[1], $color[2]);
|
||||
imagefill($this->dest, 0, 0, $icol);
|
||||
|
||||
imagecopyresampled($this->dest, $this->source, $destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight);
|
||||
}
|
||||
|
||||
|
||||
public function thumb($mode, $width, $height = null, $color = null) {
|
||||
|
||||
if ($height === null) {
|
||||
$height = $width;
|
||||
}
|
||||
if ($mode === "square") {
|
||||
$this->squareThumb($width);
|
||||
} elseif ($mode === "rational") {
|
||||
$this->rationalThumb($width, $height);
|
||||
} elseif ($mode === "center") {
|
||||
$this->centerThumb($width, $height, $color);
|
||||
} else {
|
||||
$this->freeThumb($width, $height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function squareThumb($width) {
|
||||
|
||||
$a = min($this->width, $this->height);
|
||||
$x = intval(($this->width - $a) / 2);
|
||||
$y = intval(($this->height - $a) / 2);
|
||||
|
||||
$this->magic(0, 0, $x, $y, $width, $width, $a, $a);
|
||||
}
|
||||
|
||||
|
||||
public function rationalThumb($width, $height) {
|
||||
|
||||
$r = 1.0 * $this->width / $this->height;
|
||||
|
||||
$h = $height;
|
||||
$w = $r * $h;
|
||||
|
||||
if ($w > $width) {
|
||||
|
||||
$w = $width;
|
||||
$h = 1.0 / $r * $w;
|
||||
}
|
||||
|
||||
$w = intval($w);
|
||||
$h = intval($h);
|
||||
|
||||
$this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
|
||||
}
|
||||
|
||||
|
||||
public function centerThumb($width, $height, $color = null) {
|
||||
|
||||
$r = 1.0 * $this->width / $this->height;
|
||||
|
||||
$h = $height;
|
||||
$w = $r * $h;
|
||||
|
||||
if ($w > $width) {
|
||||
|
||||
$w = $width;
|
||||
$h = 1.0 / $r * $w;
|
||||
}
|
||||
|
||||
$w = intval($w);
|
||||
$h = intval($h);
|
||||
|
||||
$x = intval(($width - $w) / 2);
|
||||
$y = intval(($height - $h) / 2);
|
||||
|
||||
$this->magic($x, $y, 0, 0, $w, $h, $this->width, $this->height, $width, $height, $color);
|
||||
}
|
||||
|
||||
|
||||
public function freeThumb($width, $height) {
|
||||
|
||||
$w = intval($width);
|
||||
$h = intval($height);
|
||||
|
||||
$this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
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);
|
||||
|
||||
?>
|
26
src/h5ai/php/thumb.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
require_once "thumbnail.php";
|
||||
|
||||
$src = $_REQUEST["src"];
|
||||
$width = $_REQUEST["width"];
|
||||
$height = $_REQUEST["height"];
|
||||
$mode = $_REQUEST["mode"];
|
||||
|
||||
if (!Thumbnail::isUsable()) {
|
||||
Image::showImage($src);
|
||||
exit;
|
||||
}
|
||||
|
||||
$thumbnail = new Thumbnail($src, $mode, $width, $height);
|
||||
$thumbnail->create(1);
|
||||
if (file_exists($thumbnail->getPath())) {
|
||||
Image::showImage($thumbnail->getPath());
|
||||
} else {
|
||||
$image = new Image();
|
||||
$image->setSource($src);
|
||||
$image->thumb($mode, $width, $height);
|
||||
$image->showDest();
|
||||
}
|
||||
|
||||
?>
|
56
src/h5ai/php/thumbnail.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
require_once "image.php";
|
||||
|
||||
class Thumbnail {
|
||||
|
||||
private $src, $width, $height, $name, $href, $path;
|
||||
|
||||
public static function isUsable() {
|
||||
|
||||
return Image::isUsable();
|
||||
}
|
||||
|
||||
public function __construct($src, $mode, $width, $height) {
|
||||
|
||||
$this->src = $src;
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
$this->mode = $mode;
|
||||
$this->name = sha1("$this->src-$this->width-$this->height-$this->mode");
|
||||
$this->href = "/h5ai/cache/thumb-" . $this->name . ".jpg";
|
||||
$this->path = getenv("DOCUMENT_ROOT") . $this->href;
|
||||
$this->liveHref = "/h5ai/php/thumb.php?src=" . $this->src . "&width=" . $this->width . "&height=" . $this->height . "&mode=" . $this->mode;
|
||||
}
|
||||
|
||||
public function create($force = 0) {
|
||||
|
||||
if (
|
||||
$force === 2
|
||||
|| ($force === 1 && !file_exists($this->path))
|
||||
|| (file_exists($this->path) && filemtime($this->src) >= filemtime($this->path))
|
||||
) {
|
||||
$image = new Image();
|
||||
$image->setSource($this->src);
|
||||
$image->thumb($this->mode, $this->width, $this->height);
|
||||
$image->saveDest($this->path);
|
||||
}
|
||||
}
|
||||
|
||||
public function getHref() {
|
||||
|
||||
return $this->href;
|
||||
}
|
||||
|
||||
public function getPath() {
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getLiveHref() {
|
||||
|
||||
return $this->liveHref;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
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();
|
||||
|
||||
?>
|
28
src/h5ai/php/zipcontent.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
if (!array_key_exists("hrefs", $_REQUEST)) {
|
||||
echo "failed";
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once "h5ai.php";
|
||||
require_once "zipit.php";
|
||||
|
||||
$h5ai = new H5ai();
|
||||
$zipit = new ZipIt($h5ai);
|
||||
|
||||
$hrefs = explode(":", trim($_REQUEST["hrefs"]));
|
||||
|
||||
$zipFile = $zipit->zip($hrefs);
|
||||
|
||||
if ($zipFile !== false) {
|
||||
header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\"");
|
||||
header("Content-Type: application/force-download");
|
||||
header("Content-Length: " . filesize($zipFile));
|
||||
header("Connection: close");
|
||||
readfile($zipFile);
|
||||
} else {
|
||||
echo "sorry, something went wrong while building the zip.";
|
||||
}
|
||||
|
||||
?>
|
63
src/h5ai/php/zipit.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
class ZipIt {
|
||||
private $h5ai;
|
||||
|
||||
public function __construct($h5ai) {
|
||||
|
||||
$this->h5ai = $h5ai;
|
||||
}
|
||||
|
||||
public function zip($hrefs) {
|
||||
|
||||
$zipFile = tempnam("/tmp", "h5ai-download");
|
||||
$zip = new ZipArchive();
|
||||
|
||||
if (!$zip->open($zipFile, ZIPARCHIVE::CREATE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($hrefs as $href) {
|
||||
$d = dirname($href);
|
||||
$n = basename($href);
|
||||
if ($this->h5ai->getHttpCode($this->h5ai->getAbsHref($d)) === "h5ai" && !$this->h5ai->ignoreThisFile($n)) {
|
||||
$localFile = $this->h5ai->getAbsPath($href);
|
||||
$file = preg_replace("!^" . $this->h5ai->getDocRoot() . "!", "", $localFile);
|
||||
if (is_dir($localFile)) {
|
||||
$this->zipDir($zip, $localFile, $file);
|
||||
} else {
|
||||
$this->zipFile($zip, $localFile, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
return $zipFile;
|
||||
}
|
||||
|
||||
private function zipFile($zip, $localFile, $file) {
|
||||
|
||||
if (is_readable($localFile)) {
|
||||
$zip->addFile($localFile, $file);
|
||||
}
|
||||
}
|
||||
|
||||
private function zipDir($zip, $localDir, $dir) {
|
||||
|
||||
if ($this->h5ai->getHttpCode($this->h5ai->getAbsHref($localDir)) === "h5ai") {
|
||||
$zip->addEmptyDir($dir);
|
||||
$files = $this->h5ai->readDir($localDir);
|
||||
foreach ($files as $file) {
|
||||
$localFile = $localDir . "/" . $file;
|
||||
$file = $dir . "/" . $file;
|
||||
if (is_dir($localFile)) {
|
||||
$this->zipDir($zip, $localFile, $file);
|
||||
} else {
|
||||
$this->zipFile($zip, $localFile, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
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
|
||||
|
113
src/js.htaccess
Normal file
@@ -0,0 +1,113 @@
|
||||
################################
|
||||
# %BUILD_NAME% %BUILD_VERSION% (js)
|
||||
# customized .htaccess
|
||||
################################
|
||||
|
||||
|
||||
# Options +Indexes
|
||||
# Options +FollowSymLinks
|
||||
|
||||
|
||||
################################
|
||||
# h5ai header and footer
|
||||
################################
|
||||
|
||||
HeaderName /h5ai/header.html
|
||||
ReadmeName /h5ai/footer.html
|
||||
|
||||
|
||||
################################
|
||||
# hide h5ai folder and config files from index
|
||||
################################
|
||||
|
||||
IndexIgnore h5ai h5ai.header.html h5ai.footer.html
|
||||
|
||||
|
||||
################################
|
||||
# table options
|
||||
################################
|
||||
|
||||
# syntax for default sort order is: IndexOrderDefault Ascending|Descending Name|Date|Size
|
||||
IndexOrderDefault Ascending Name
|
||||
|
||||
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
||||
IndexOptions Charset=UTF-8
|
||||
IndexOptions FancyIndexing
|
||||
IndexOptions HTMLTable
|
||||
IndexOptions XHTML
|
||||
IndexOptions SuppressHTMLPreamble
|
||||
IndexOptions SuppressRules
|
||||
IndexOptions SuppressDescription
|
||||
IndexOptions FoldersFirst
|
||||
IndexOptions IgnoreCase
|
||||
IndexOptions IconsAreLinks
|
||||
IndexOptions VersionSort
|
||||
IndexOptions NameWidth=*
|
||||
|
||||
|
||||
################################
|
||||
# icon mapping
|
||||
################################
|
||||
|
||||
AddIcon /h5ai/icons/16x16/folder-parent.png ..
|
||||
AddIcon /h5ai/icons/16x16/folder.png ^^DIRECTORY^^
|
||||
AddIcon /h5ai/icons/16x16/blank.png ^^BLANKICON^^
|
||||
|
||||
AddIcon /h5ai/icons/16x16/readme.png README
|
||||
AddIcon /h5ai/icons/16x16/copying.png COPYING LICENSE
|
||||
AddIcon /h5ai/icons/16x16/install.png INSTALL
|
||||
AddIcon /h5ai/icons/16x16/authors.png AUTHORS
|
||||
AddIcon /h5ai/icons/16x16/log.png LOG Log log
|
||||
|
||||
AddIcon /h5ai/icons/16x16/css.png .less
|
||||
AddIcon /h5ai/icons/16x16/script.png .conf .ini .sh .shar .csh .ksh .tcl
|
||||
AddIcon /h5ai/icons/16x16/makefile.png .pom pom.xml build.xml
|
||||
AddIcon /h5ai/icons/16x16/bin.png .so .o
|
||||
|
||||
AddIcon /h5ai/icons/16x16/archive.png .tar.gz .tgz .tar.bz2
|
||||
AddIcon /h5ai/icons/16x16/zip.png .zip .Z .z .jar .war .gz .bz2
|
||||
AddIcon /h5ai/icons/16x16/tar.png .tar
|
||||
AddIcon /h5ai/icons/16x16/pdf.png .pdf
|
||||
AddIcon /h5ai/icons/16x16/deb.png .deb
|
||||
AddIcon /h5ai/icons/16x16/rpm.png .rpm
|
||||
AddIcon /h5ai/icons/16x16/cd.png .iso .cue
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/png.png image/png
|
||||
AddIconByType /h5ai/icons/16x16/jpg.png image/jpeg
|
||||
AddIconByType /h5ai/icons/16x16/gif.png image/gif
|
||||
AddIconByType /h5ai/icons/16x16/ico.png image/x-icon
|
||||
AddIconByType /h5ai/icons/16x16/bmp.png image/x-ms-bmp
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/html.png text/html
|
||||
AddIconByType /h5ai/icons/16x16/css.png text/css
|
||||
AddIconByType /h5ai/icons/16x16/xml.png application/xml
|
||||
AddIconByType /h5ai/icons/16x16/js.png application/javascript application/json
|
||||
AddIconByType /h5ai/icons/16x16/php.png application/x-httpd-php
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/py.png text/x-python
|
||||
AddIconByType /h5ai/icons/16x16/rb.png application/x-ruby
|
||||
AddIconByType /h5ai/icons/16x16/java.png text/x-java
|
||||
AddIconByType /h5ai/icons/16x16/cpp.png text/x-c++src
|
||||
AddIconByType /h5ai/icons/16x16/hpp.png text/x-c++hdr
|
||||
AddIconByType /h5ai/icons/16x16/c.png text/x-csrc
|
||||
AddIconByType /h5ai/icons/16x16/h.png text/x-chdr
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/pdf.png application/pdf
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/rtf.png text/rtf application/rtf
|
||||
AddIconByType /h5ai/icons/16x16/tex.png text/x-tex
|
||||
AddIconByType /h5ai/icons/16x16/makefile.png text/x-makefile
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/bin.png application/java-vm
|
||||
AddIconByType /h5ai/icons/16x16/exe.png application/x-executable application/x-msdos-program
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/text.png text/*
|
||||
AddIconByType /h5ai/icons/16x16/image.png image/*
|
||||
AddIconByType /h5ai/icons/16x16/audio.png audio/*
|
||||
AddIconByType /h5ai/icons/16x16/video.png video/*
|
||||
|
||||
AddIconByEncoding /h5ai/icons/16x16/zip.png x-compress x-gzip x-bzip2
|
||||
|
||||
DefaultIcon /h5ai/icons/16x16/unknown.png
|
||||
|
||||
|
19
src/php.htaccess
Normal file
@@ -0,0 +1,19 @@
|
||||
################################
|
||||
# %BUILD_NAME% %BUILD_VERSION% (php)
|
||||
# customized .htaccess
|
||||
################################
|
||||
|
||||
|
||||
# Options +Indexes
|
||||
# Options +FollowSymLinks
|
||||
|
||||
|
||||
HeaderName /h5ai/header.php
|
||||
ReadmeName /h5ai/footer.php
|
||||
|
||||
IndexIgnore *
|
||||
|
||||
IndexOptions Type=text/html;h5ai=%BUILD_VERSION%
|
||||
IndexOptions Charset=UTF-8
|
||||
IndexOptions SuppressHTMLPreamble
|
||||
|
@@ -1,146 +0,0 @@
|
||||
################################
|
||||
# h5ai 0.11
|
||||
# customized .htaccess
|
||||
################################
|
||||
|
||||
|
||||
# Options +Indexes
|
||||
# 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
|
||||
# if you're running XAMPP you might need to replace the
|
||||
# following line with
|
||||
# <IfModule autoindex_color_module>
|
||||
################################
|
||||
<IfModule autoindex_module>
|
||||
|
||||
################################
|
||||
# uncomment the following line to force directory listing
|
||||
# even for directories with valid index files
|
||||
################################
|
||||
|
||||
# DirectoryIndex IGNORE-DEFAULT-INDEX-FILES
|
||||
|
||||
|
||||
################################
|
||||
# h5ai header and footer
|
||||
################################
|
||||
|
||||
HeaderName /h5ai/header.html
|
||||
ReadmeName /h5ai/footer.html
|
||||
|
||||
|
||||
################################
|
||||
# hide h5ai folder and config files from index
|
||||
################################
|
||||
|
||||
IndexIgnore h5ai h5ai.header.html h5ai.footer.html
|
||||
|
||||
|
||||
################################
|
||||
# table options
|
||||
################################
|
||||
|
||||
IndexOrderDefault Ascending Name
|
||||
|
||||
IndexOptions Type=text/html;h5ai=0.11
|
||||
IndexOptions Charset=UTF-8
|
||||
IndexOptions FancyIndexing
|
||||
IndexOptions HTMLTable
|
||||
IndexOptions XHTML
|
||||
IndexOptions SuppressHTMLPreamble
|
||||
IndexOptions SuppressRules
|
||||
IndexOptions SuppressDescription
|
||||
IndexOptions FoldersFirst
|
||||
IndexOptions IgnoreCase
|
||||
IndexOptions IconsAreLinks
|
||||
IndexOptions VersionSort
|
||||
IndexOptions NameWidth=*
|
||||
|
||||
|
||||
################################
|
||||
# icon mapping
|
||||
################################
|
||||
|
||||
AddIcon /h5ai/icons/16x16/parent.png ..
|
||||
AddIcon /h5ai/icons/16x16/folder.png ^^DIRECTORY^^
|
||||
AddIcon /h5ai/icons/16x16/blank.png ^^BLANKICON^^
|
||||
|
||||
AddIcon /h5ai/icons/16x16/readme.png README
|
||||
AddIcon /h5ai/icons/16x16/copying.png COPYING LICENSE
|
||||
AddIcon /h5ai/icons/16x16/install.png INSTALL
|
||||
AddIcon /h5ai/icons/16x16/authors.png AUTHORS
|
||||
AddIcon /h5ai/icons/16x16/log.png LOG Log log
|
||||
|
||||
AddIcon /h5ai/icons/16x16/css.png .less
|
||||
AddIcon /h5ai/icons/16x16/script.png .conf .ini .sh .shar .csh .ksh .tcl
|
||||
AddIcon /h5ai/icons/16x16/makefile.png .pom pom.xml build.xml
|
||||
AddIcon /h5ai/icons/16x16/bin.png .so .o
|
||||
|
||||
AddIcon /h5ai/icons/16x16/archive.png .tar.gz .tgz .tar.bz2
|
||||
AddIcon /h5ai/icons/16x16/zip.png .zip .Z .z .jar .war .gz .bz2
|
||||
AddIcon /h5ai/icons/16x16/tar.png .tar
|
||||
AddIcon /h5ai/icons/16x16/pdf.png .pdf
|
||||
AddIcon /h5ai/icons/16x16/deb.png .deb
|
||||
AddIcon /h5ai/icons/16x16/rpm.png .rpm
|
||||
AddIcon /h5ai/icons/16x16/cd.png .iso .cue
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/png.png image/png
|
||||
AddIconByType /h5ai/icons/16x16/jpg.png image/jpeg
|
||||
AddIconByType /h5ai/icons/16x16/gif.png image/gif
|
||||
AddIconByType /h5ai/icons/16x16/ico.png image/x-icon
|
||||
AddIconByType /h5ai/icons/16x16/bmp.png image/x-ms-bmp
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/html.png text/html
|
||||
AddIconByType /h5ai/icons/16x16/css.png text/css
|
||||
AddIconByType /h5ai/icons/16x16/xml.png application/xml
|
||||
AddIconByType /h5ai/icons/16x16/js.png application/javascript application/json
|
||||
AddIconByType /h5ai/icons/16x16/php.png application/x-httpd-php
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/py.png text/x-python
|
||||
AddIconByType /h5ai/icons/16x16/rb.png application/x-ruby
|
||||
AddIconByType /h5ai/icons/16x16/java.png text/x-java
|
||||
AddIconByType /h5ai/icons/16x16/cpp.png text/x-c++src
|
||||
AddIconByType /h5ai/icons/16x16/hpp.png text/x-c++hdr
|
||||
AddIconByType /h5ai/icons/16x16/c.png text/x-csrc
|
||||
AddIconByType /h5ai/icons/16x16/h.png text/x-chdr
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/pdf.png application/pdf
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/rtf.png text/rtf application/rtf
|
||||
AddIconByType /h5ai/icons/16x16/tex.png text/x-tex
|
||||
AddIconByType /h5ai/icons/16x16/makefile.png text/x-makefile
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/bin.png application/java-vm
|
||||
AddIconByType /h5ai/icons/16x16/exe.png application/x-executable application/x-msdos-program
|
||||
|
||||
AddIconByType /h5ai/icons/16x16/text.png text/*
|
||||
AddIconByType /h5ai/icons/16x16/image.png image/*
|
||||
AddIconByType /h5ai/icons/16x16/audio.png audio/*
|
||||
AddIconByType /h5ai/icons/16x16/video.png video/*
|
||||
|
||||
AddIconByEncoding /h5ai/icons/16x16/zip.png x-compress x-gzip x-bzip2
|
||||
|
||||
DefaultIcon /h5ai/icons/16x16/unknown.png
|
||||
|
||||
</IfModule>
|
||||
|
@@ -1,23 +0,0 @@
|
||||
<!-- generated code ends here -->
|
||||
</section>
|
||||
<section id="extended"></section>
|
||||
<footer></footer>
|
||||
</section>
|
||||
<section id="tree"></section>
|
||||
<footer>
|
||||
<a id="html5" href="http://www.w3.org/html/logo/" target="_blank" title="HTML5 semantics, storage & CSS3">
|
||||
<img class="logo" src="/h5ai/images/html5.png" alt="html5" />
|
||||
<img class="techclass" src="/h5ai/images/html5-semantics.png" alt="html5-semantics" />
|
||||
<img class="techclass" src="/h5ai/images/html5-storage.png" alt="html5-storage" />
|
||||
<img class="techclass" src="/h5ai/images/html5-css3.png" alt="html5-css3" />
|
||||
</a>
|
||||
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai 0.11</a>
|
||||
<span class="l10n-footerUsing">using</span>
|
||||
<a href="http://tiheum.deviantart.com/art/Faenza-Icons-173323228" target="_blank" title="icon theme for Gnome">Faenza icons</a>
|
||||
</footer>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/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/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@@ -1,35 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Directory index · styled with h5ai</title>
|
||||
<meta name="h5ai-version" content="h5ai 0.11">
|
||||
<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.css">
|
||||
<script src="/h5ai/js/lib/modernizr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="clearfix">
|
||||
<span class="jsDisabledFallback">Directory index · JavaScript is disabled</span>
|
||||
<ul>
|
||||
<li id="viewicons" class="view">
|
||||
<a href="#"><img src="/h5ai/images/view-icons.png" alt="view-icons" /><span class="l10n-viewIcons">icons</span></a>
|
||||
</li>
|
||||
<li id="viewdetails" class="view" >
|
||||
<a href="#"><img src="/h5ai/images/view-details.png" alt="view-details" /><span class="l10n-viewDetails">details</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section id="content">
|
||||
<header></header>
|
||||
<section id="table" class="jsDisabledFallback">
|
||||
<!--
|
||||
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
|
||||
removed via javascript. The actual page should render as perfect HTML 5, even if the produced
|
||||
source is not valid HTML 5.
|
||||
-->
|
Before Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 554 B |
Before Width: | Height: | Size: 492 B |
Before Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 663 B |
Before Width: | Height: | Size: 554 B |
Before Width: | Height: | Size: 506 B |
Before Width: | Height: | Size: 757 B |
Before Width: | Height: | Size: 699 B |
Before Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 671 B |
Before Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 679 B |
Before Width: | Height: | Size: 619 B |
Before Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 637 B |
Before Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 587 B |
Before Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 504 B |
Before Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 770 B |
Before Width: | Height: | Size: 792 B |
Before Width: | Height: | Size: 671 B |
Before Width: | Height: | Size: 788 B |
Before Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 675 B |
Before Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 423 B |
Before Width: | Height: | Size: 614 B |
Before Width: | Height: | Size: 614 B |
Before Width: | Height: | Size: 494 B |
Before Width: | Height: | Size: 799 B |