Merge branch 'develop'

This commit is contained in:
Lars Jung
2012-02-24 17:02:46 +01:00
61 changed files with 6066 additions and 3659 deletions

32
.gitignore vendored
View File

@@ -4,10 +4,8 @@ build
build.local.* build.local.*
release release
# Sublime
# Eclipse *.sublime-*
.classpath
.ant-targets-*
# Numerous always-ignore extensions # Numerous always-ignore extensions
*.diff *.diff
@@ -20,29 +18,3 @@ release
*.vi *.vi
*~ *~
*.sass-cache *.sass-cache
# OS or Editor folders
.DS_Store
.cache
.project
.settings
.tmproj
nbproject
Thumbs.db
# Dreamweaver added files
_notes
dwsync.xml
# Komodo
*.komodoproject
.komodotools
# Folders to ignore
.hg
.svn
.CVS
intermediate
publish
.idea

View File

@@ -1,4 +1,4 @@
Copyright (c) 2011 Lars Jung, http://larsjung.de Copyright (c) 2012 Lars Jung, http://larsjung.de
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@@ -23,11 +23,34 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* [jQuery](http://jquery.com) (MIT/GPL) * [jQuery](http://jquery.com) (MIT/GPL)
* [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) (MIT) * [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) (MIT)
* [modernizr](http://www.modernizr.com) (MIT/BSD) * [modernizr](http://www.modernizr.com) (MIT/BSD)
* [qrcode](http://www.d-project.com/qrcode/index.html) (MIT)
## Changelog ## Changelog
### v0.17 · *2011-11-28*
### v0.18 - *2012-02-24*
* adds optional QRCode display
* adds optional filtering for displayed files and folders
* updates design
* improves zipped download
* adds support for zipped download of htaccess restricted files
* changes h5ai.htaccess
* custom headers/footers are now optional and disabled by default
* fixes problems with folder recognition in the JS version
* fixes include problems in PHP version
* fixes path problems on servers running on Windows in PHP version
* fixes broken links in custom headers/footers while zipped download enabled
* fixes problems with thumbnails for files with single or double quotes in filename
* improves url hashes
* updates year in `LICENSE.TXT`
* updates es translation
* adds zh-tw translation by [Yao Wei](http://github.com/medicalwei)
* updates zh-cn translation
### v0.17 - *2011-11-28*
* h5ai is now located in `_h5ai` to reduce collisions * h5ai is now located in `_h5ai` to reduce collisions
* switches from HTML5 Boilerplate reset to normalization * switches from HTML5 Boilerplate reset to normalization
@@ -43,7 +66,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* adds support for use with userdir (requires some manual changes) * adds support for use with userdir (requires some manual changes)
### v0.16 · *2011-11-02* ### v0.16 - *2011-11-02*
* sorts translations in `options.js` * sorts translations in `options.js`
* improves HTML head sections * improves HTML head sections
@@ -57,25 +80,25 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* image thumbs and zipped download is disabled by default now, but works fine if PHP is configured * image thumbs and zipped download is disabled by default now, but works fine if PHP is configured
### v0.15.2 · *2011-09-18* ### v0.15.2 - *2011-09-18*
* added it translation by [Salvo Gentile](http://github.com/SalvoGentile) and [Marco Patriarca](http://github.com/Fexys) * added it translation by [Salvo Gentile](http://github.com/SalvoGentile) and [Marco Patriarca](http://github.com/Fexys)
* switched build process from scripp to wepp * switched build process from scripp to wepp
### v0.15.1 · *2011-09-06* ### v0.15.1 - *2011-09-06*
* fixed security issues with the zipped download feature * fixed security issues with the zipped download feature
* made zipped download optional (but enabled by default) * made zipped download optional (but enabled by default)
### v0.15 · *2011-09-04* ### v0.15 - *2011-09-04*
* added zipped download for selected files * added zipped download for selected files
* cleaned and refactored * cleaned and refactored
### v0.14.1 · *2011-09-01* ### v0.14.1 - *2011-09-01*
* display meta information in bottom bar (icon view) * display meta information in bottom bar (icon view)
* added zh-cn translation by [Dongsheng Cai](http://github.com/dongsheng) * added zh-cn translation by [Dongsheng Cai](http://github.com/dongsheng)
@@ -83,18 +106,18 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added ru translation by Богдан Илюхин * added ru translation by Богдан Илюхин
### v0.14 · *2011-08-16* ### v0.14 - *2011-08-16*
* added image thumbnails for PHP version * added image thumbnails for PHP version
* new option `slideTree` to turn off auto slide in * new option `slideTree` to turn off auto slide in
### v0.13.2 · *2011-08-12* ### v0.13.2 - *2011-08-12*
* changes in `/h5ai/.htaccess` ... PHP configuration ... * changes in `/h5ai/.htaccess` ... PHP configuration ...
### v0.13.1 · *2011-08-12* ### v0.13.1 - *2011-08-12*
* ~~hopefully fixed that PHP doesn't get interpreted~~ :/ * ~~hopefully fixed that PHP doesn't get interpreted~~ :/
* fixed initial tree display * fixed initial tree display
@@ -103,7 +126,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added lv translation by Sandis Veinbergs * added lv translation by Sandis Veinbergs
### v0.13 · *2011-08-06* ### v0.13 - *2011-08-06*
* added PHP implementation! (should work with PHP 5.2+) * added PHP implementation! (should work with PHP 5.2+)
* added new options * added new options
@@ -117,42 +140,42 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added bg translation by George Andonov * added bg translation by George Andonov
### v0.12.3 · *2011-07-30* ### v0.12.3 - *2011-07-30*
* added tr translation by [Batuhan Icoz](http://github.com/batuhanicoz) * added tr translation by [Batuhan Icoz](http://github.com/batuhanicoz)
### v0.12.2 · *2011-07-30* ### v0.12.2 - *2011-07-30*
* added es translation by Jose David Calderon Serrano * added es translation by Jose David Calderon Serrano
### v0.12.1 · *2011-07-29* ### v0.12.1 - *2011-07-29*
* fixed unchecked use of console.log * fixed unchecked use of console.log
### v0.12 · *2011-07-28* ### v0.12 - *2011-07-28*
* improved performance * improved performance
### v0.11 · *2011-07-27* ### v0.11 - *2011-07-27*
* changed license to MIT license, see `LICENSE.txt` * changed license to MIT license, see `LICENSE.txt`
### v0.10.2 · *2011-07-26* ### v0.10.2 - *2011-07-26*
* improved tree scrollbar * improved tree scrollbar
### v0.10.1 · *2011-07-24* ### v0.10.1 - *2011-07-24*
* fixed problems with ' in links * fixed problems with ' in links
### v0.10 · *2011-07-24* ### v0.10 - *2011-07-24*
* fixed problems with XAMPP on Windows (see `dot.htaccess` comments for instructions) * 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)) * fixed tree fade-in-fade-out effect for small displays ([issue #6](http://github.com/lrsjng/h5ai/issues/6))
@@ -161,7 +184,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added "empty" to localization (hope Google Translate did a good job here) * 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 * linked hover states between crumb, extended view and tree
* fixed size of tree view (now there's a ugly scrollbar, hopefully will be fixed) * fixed size of tree view (now there's a ugly scrollbar, hopefully will be fixed)
@@ -172,7 +195,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added sv translation by Oscar Carlsson * added sv translation by Oscar Carlsson
### v0.8 · *2011-07-08* ### v0.8 - *2011-07-08*
* removed slashes from folder labels * removed slashes from folder labels
* optionally rename parent folder entries to real folder names, see `options.js` * optionally rename parent folder entries to real folder names, see `options.js`
@@ -181,19 +204,19 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* refactored js a lot (again...) * refactored js a lot (again...)
### v0.7 · *2011-07-07* ### v0.7 - *2011-07-07*
* removed shadows * removed shadows
* smarter tree side bar * smarter tree side bar
### v0.6 · *2011-07-05* ### v0.6 - *2011-07-05*
* refactored js * refactored js
* added localization, see `options.js` * added localization, see `options.js`
### v0.5.3 · *2011-07-04* ### v0.5.3 - *2011-07-04*
* refactored js * refactored js
* added basic options support via `options.js` * added basic options support via `options.js`
@@ -201,24 +224,24 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* optional tree sidebar * optional tree sidebar
### v0.5.2 · *2011-07-02* ### v0.5.2 - *2011-07-02*
* details view adjusts to window width * details view adjusts to window width
* linked icon for *.gz and *.bz2 * linked icon for *.gz and *.bz2
### v0.5.1 · *2011-07-01* ### v0.5.1 - *2011-07-01*
* disabled tree sidebar for now, since it had unwanted side effects * disabled tree sidebar for now, since it had unwanted side effects
### v0.5 · *2011-07-01* ### v0.5 - *2011-07-01*
* added tree sidebar * added tree sidebar
* some refactorings * some refactorings
### v0.4 · *2011-06-27* ### v0.4 - *2011-06-27*
* added better fallback, in case JavaScript is disabled * added better fallback, in case JavaScript is disabled
* rewrote js, fixed middle-button click etc. problems * rewrote js, fixed middle-button click etc. problems
@@ -227,20 +250,20 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* updated dot.access * updated dot.access
### v0.3.2 · *2011-06-24* ### v0.3.2 - *2011-06-24*
* removed lib versions from file names * removed lib versions from file names
* added 'empty' indicator for icons view * added 'empty' indicator for icons view
### v0.3.1 · *2011-06-24* ### v0.3.1 - *2011-06-24*
* refactored js * refactored js
* added `folderClick` and `fileClick` callback hooks * added `folderClick` and `fileClick` callback hooks
* fixed .emtpy style * 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` * included build stuff, files previously found in the base directory are now located in folder `target`
* styles and scripts are now minified * styles and scripts are now minified
@@ -248,20 +271,20 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* updated jQuery to version 1.6.1 * updated jQuery to version 1.6.1
### v0.2.3 · *2011-06-17* ### v0.2.3 - *2011-06-17*
* more refactoring in main.js * more refactoring in main.js
* ~~added custom js support, and global includes~~ *removed, only custom top and bottom sections supported* * ~~added custom js support, and global includes~~ *removed, only custom top and bottom sections supported*
### v0.2.2 · *2011-06-16* ### v0.2.2 - *2011-06-16*
* refactored a lot, added some comments * refactored a lot, added some comments
* included fixes from [NumEricR](http://github.com/NumEricR) * included fixes from [NumEricR](http://github.com/NumEricR)
* added top/bottom message support, only basicly styled * added top/bottom message support, only basicly styled
### v0.2.1 · *2011-06-16* ### v0.2.1 - *2011-06-16*
* fixed croped filenames * fixed croped filenames
* fixed missing .png extension in header * fixed missing .png extension in header
@@ -269,7 +292,7 @@ h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h
* added changelog * added changelog
### v0.2 · *2011-06-15* ### v0.2 - *2011-06-15*
* added icon view * added icon view

View File

@@ -3,7 +3,7 @@ custom = true
# project # project
project.name = h5ai project.name = h5ai
project.version = 0.17 project.version = 0.18
# src # src
@@ -16,8 +16,6 @@ release.dir = release
# tools # tools
tool.wepp = tools/wepp tool.wepp = wepp
tool.jslint = jslint tool.jslint = jslint
tool.jshint = jshint
tool.jsxint.file = ${build.dir}/_h5ai/js/main-js.js

View File

@@ -5,8 +5,6 @@
default="release" default="release"
> >
<import file="tools/wepp.ant.xml" />
<target name="init"> <target name="init">
<property file="build.properties" /> <property file="build.properties" />
<tstamp> <tstamp>
@@ -37,42 +35,82 @@
</target> </target>
<target name="build" depends="build-prepare"> <target name="build" depends="build-prepare">
<wepp.dir dir="${build.dir}/_h5ai/css" /> <wepp-dir-min dir="${build.dir}/_h5ai/css" todir="${build.dir}/_h5ai/css" />
<wepp.dir dir="${build.dir}/_h5ai/js" /> <wepp-dir-min dir="${build.dir}/_h5ai/js" todir="${build.dir}/_h5ai/js" />
</target> </target>
<target name="build-uncompressed" depends="build-prepare"> <target name="build-uncompressed" depends="build-prepare">
<wepp.dir dir="${build.dir}/_h5ai/css" args="--nc" /> <wepp-dir dir="${build.dir}/_h5ai/css" todir="${build.dir}/_h5ai/css" />
<wepp.dir dir="${build.dir}/_h5ai/js" args="--nc" /> <wepp-dir dir="${build.dir}/_h5ai/js" todir="${build.dir}/_h5ai/js" />
</target> </target>
<target name="release" depends="build"> <target name="release" depends="build">
<mkdir dir="${release.dir}" /> <mkdir dir="${release.dir}" />
<zip destfile="${release.dir}/${project.name}-${project.version}.zip" basedir="${build.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> </target>
<target name="pre-xint" depends="build-prepare"> <target name="lint" depends="build-prepare">
<wepp file="${tool.jsxint.file}" tofile="${tool.jsxint.file}" args="--nc" /> <wepp file="${build.dir}/_h5ai/js/inc/main.js" tofile="${build.dir}/_h5ai/js/inc/main.js" />
<jslint files="${build.dir}/_h5ai/js/inc/main.js" />
</target> </target>
<target name="lint" depends="pre-xint">
<echo>JSLint "${tool.jsxint.file}"</echo> <macrodef name="wepp-args">
<exec executable="${tool.jslint}" failonerror="true"> <attribute name="args" default="" />
<arg value="${tool.jsxint.file}" /> <sequential>
<exec executable="${tool.wepp}" failonerror="true">
<arg line="@{args}" />
</exec> </exec>
</target> </sequential>
</macrodef>
<target name="hint" depends="pre-xint"> <macrodef name="wepp">
<echo>JSHint "${tool.jsxint.file}"</echo> <attribute name="file" />
<exec executable="${tool.jshint}" failonerror="true"> <attribute name="tofile" />
<arg value="${tool.jsxint.file}" /> <sequential>
<wepp-args args="--nc --inFile '@{file}' --outFile '@{toFile}'" />
</sequential>
</macrodef>
<macrodef name="wepp-min">
<attribute name="file" />
<attribute name="tofile" />
<sequential>
<wepp-args args="--inFile '@{file}' --outFile '@{toFile}'" />
<bytes file="@{file}" toFile="@{toFile}" />
</sequential>
</macrodef>
<macrodef name="wepp-dir">
<attribute name="dir" />
<attribute name="todir" />
<sequential>
<wepp-args args="--nc --inDir '@{dir}' --outDir '@{todir}'" />
<delete dir="@{todir}/inc" >
<fileset dir="." includes="@{todir}/**/*.less" />
</delete>
</sequential>
</macrodef>
<macrodef name="wepp-dir-min">
<attribute name="dir" />
<attribute name="todir" />
<sequential>
<wepp-args args="--inDir '@{dir}' --outDir '@{todir}'" />
<delete dir="@{todir}/inc" >
<fileset dir="." includes="@{todir}/**/*.less" />
</delete>
</sequential>
</macrodef>
<macrodef name="jslint">
<attribute name="files" />
<sequential>
<echo>JSLint @{files}</echo>
<exec executable="${tool.jslint}" failonerror="false">
<arg line="@{files}" />
</exec> </exec>
</target> </sequential>
</macrodef>
<target name="xint" depends="lint,hint">
</target>
</project> </project>

View File

@@ -1,5 +1,7 @@
Options -Indexes
AddType text/html .php AddType text/html .php

View File

@@ -18,10 +18,15 @@ var H5AI_CONFIG = {
/* /*
* Filenames of customized header and footer files to look for * Filenames of customized header and footer files to look for
* in each folder. * in each folder. For Example:
*
* "customHeader": "_h5ai.header.html",
* "customFooter": "_h5ai.footer.html",
*
* This is disabled by default.
*/ */
"customHeader": "_h5ai.header.html", "customHeader": null,
"customFooter": "_h5ai.footer.html", "customFooter": null,
/* /*
* An array of view modes the user may choose from. Currently there * An array of view modes the user may choose from. Currently there
@@ -100,13 +105,27 @@ var H5AI_CONFIG = {
* Requires PHP on the server. * Requires PHP on the server.
* Show thumbnails for image files. * Show thumbnails for image files.
*/ */
"showThumbs": false, "showThumbs": true,
"thumbTypes": ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
/* /*
* Requires PHP on the server. * Requires PHP on the server.
* Enable zipped download of selected entries. * Enable zipped download of selected entries.
*/ */
"zippedDownload": false "zippedDownload": false,
/*
* Show QRCodes on hovering files.
* Set this to the desired size in pixel or null to not display QRCodes.
* A good size to start with might be 150.
*/
"qrCodesSize": null,
/*
* Allow filtering the displayed files and folders.
* Filters are ment to be JavaScript regular expressions.
*/
"showFilter": false
}, },
@@ -195,7 +214,8 @@ var H5AI_CONFIG = {
"empty": "empty", "empty": "empty",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"bg": { "bg": {
@@ -209,7 +229,8 @@ var H5AI_CONFIG = {
"empty": "празно", "empty": "празно",
"folders": "папки", "folders": "папки",
"files": "файлове", "files": "файлове",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"cs": { "cs": {
@@ -223,7 +244,8 @@ var H5AI_CONFIG = {
"empty": "prázdný", "empty": "prázdný",
"folders": "složek", "folders": "složek",
"files": "souborů", "files": "souborů",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"de": { "de": {
@@ -237,7 +259,8 @@ var H5AI_CONFIG = {
"empty": "leer", "empty": "leer",
"folders": "Ordner", "folders": "Ordner",
"files": "Dateien", "files": "Dateien",
"download": "Download" "download": "Download",
"noMatch": "keine Treffer"
}, },
"es": { "es": {
@@ -249,9 +272,10 @@ var H5AI_CONFIG = {
"size": "Tamaño", "size": "Tamaño",
"parentDirectory": "Directorio superior", "parentDirectory": "Directorio superior",
"empty": "vacío", "empty": "vacío",
"folders": "folders", "folders": "Directorios",
"files": "files", "files": "Archivos",
"download": "download" "download": "Descargar",
"noMatch": "no match"
}, },
"fr": { "fr": {
@@ -265,7 +289,8 @@ var H5AI_CONFIG = {
"empty": "vide", "empty": "vide",
"folders": "Répertoires", "folders": "Répertoires",
"files": "Fichiers", "files": "Fichiers",
"download": "télécharger" "download": "télécharger",
"noMatch": "no match"
}, },
"it": { "it": {
@@ -279,7 +304,8 @@ var H5AI_CONFIG = {
"empty": "vuota", "empty": "vuota",
"folders": "cartelle", "folders": "cartelle",
"files": "file", "files": "file",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"lv": { "lv": {
@@ -293,7 +319,8 @@ var H5AI_CONFIG = {
"empty": "tukšs", "empty": "tukšs",
"folders": "mapes", "folders": "mapes",
"files": "faili", "files": "faili",
"download": "lejupielādēt" "download": "lejupielādēt",
"noMatch": "no match"
}, },
"nl": { "nl": {
@@ -307,7 +334,8 @@ var H5AI_CONFIG = {
"empty": "lege", "empty": "lege",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"pl": { "pl": {
@@ -321,7 +349,8 @@ var H5AI_CONFIG = {
"empty": "pusty", "empty": "pusty",
"folders": "foldery", "folders": "foldery",
"files": "pliki", "files": "pliki",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"pt": { "pt": {
@@ -335,7 +364,8 @@ var H5AI_CONFIG = {
"empty": "vazio", "empty": "vazio",
"folders": "pastas", "folders": "pastas",
"files": "arquivos", "files": "arquivos",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"ru": { "ru": {
@@ -349,7 +379,8 @@ var H5AI_CONFIG = {
"empty": "пусто", "empty": "пусто",
"folders": "папки", "folders": "папки",
"files": "файлы", "files": "файлы",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"sk": { "sk": {
@@ -363,7 +394,8 @@ var H5AI_CONFIG = {
"empty": "prázdny", "empty": "prázdny",
"folders": "priečinkov", "folders": "priečinkov",
"files": "súborov", "files": "súborov",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"sv": { "sv": {
@@ -377,7 +409,8 @@ var H5AI_CONFIG = {
"empty": "tom", "empty": "tom",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
"noMatch": "no match"
}, },
"tr": { "tr": {
@@ -391,7 +424,8 @@ var H5AI_CONFIG = {
"empty": "boş", "empty": "boş",
"folders": "klasörler", "folders": "klasörler",
"files": "dosyalar", "files": "dosyalar",
"download": "indir" "download": "indir",
"noMatch": "no match"
}, },
"zh-cn": { "zh-cn": {
@@ -405,7 +439,23 @@ var H5AI_CONFIG = {
"empty": "空文件夹", "empty": "空文件夹",
"folders": "文件夹", "folders": "文件夹",
"files": "文件", "files": "文件",
"download": "download" "download": "下载",
"noMatch": "no match"
},
"zh-tw": {
"lang": "正體中文",
"details": "詳細資料",
"icons": "圖示",
"name": "檔名",
"lastModified": "上次修改",
"size": "大小",
"parentDirectory": "上層目錄",
"empty": "空資料夾",
"folders": "資料夾",
"files": "檔案",
"download": "下載",
"noMatch": "no match"
} }
} }
}; };

29
src/_h5ai/config.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
/*
* h5ai %BUILD_VERSION%
*
* PHP Configuration
* filesystem paths and file ignore rules
*/
global $H5AI_CONFIG;
$H5AI_CONFIG = array(
/*
* This configuration assumes that h5ai is installed
* in the webroot directory of the Apache server.
*/
"ROOT_ABS_PATH" => safe_dirname(safe_dirname(__FILE__)),
/*
* Files/folders that should not be listed. Specified
* by the complete filename or by a regular expression.
* http://www.php.net/manual/en/function.preg-match.php
*/
"IGNORE" => array(),
"IGNORE_PATTERNS" => array("/^\\./", "/^_h5ai/")
);
?>

View File

@@ -0,0 +1,18 @@
#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;
}
}

View File

@@ -0,0 +1,22 @@
#context {
position: fixed;
z-index: 1;
display: none;
right: 16px;
bottom: 50px;
background-color: #fff;
border: 2px solid #ddd;
padding: 8px;
span {
display: block;
}
.qrcode {
canvas {
display: block;
}
}
}

View File

@@ -146,13 +146,16 @@
} }
} }
} }
.empty { .empty, .no-match {
text-align: center; text-align: center;
margin: 50px 0; margin: 50px 0;
color: #ddd; color: #ddd;
font-size: 5em; font-size: 5em;
font-weight: bold; font-weight: bold;
} }
.no-match {
display: none;
}
} }
@@ -170,8 +173,6 @@
#extended.icons-view { #extended.icons-view {
display: none; display: none;
padding: 3px; padding: 3px;
border: 1px solid #eee;
border-radius: 15px;
ul { ul {
margin: 0; margin: 0;
@@ -269,7 +270,8 @@
} }
} }
} }
.empty { .empty, .no-match {
margin: 0 120px;
padding: 16px; padding: 16px;
height: 120px; height: 120px;
text-align: center; text-align: center;
@@ -277,4 +279,7 @@
font-size: 5em; font-size: 5em;
font-weight: bold; font-weight: bold;
} }
.no-match {
display: none;
}
} }

View File

@@ -0,0 +1,108 @@
body > footer {
position: fixed;
z-index: 5;
width: 100%;
left: 0;
bottom: 0;
padding: 6px 0 8px 0;
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
border-top: 1px solid rgb(210,210,210);
color: #999;
font-size: 0.85em;
text-align: center;
a, a:active, a:visited {
color: #555;
text-decoration: none;
.transition(all 0.2s ease-in-out);
opacity: 0.7;
&:hover {
color: #e80;
opacity: 1;
}
}
.left {
display: block;
padding: 0 8px;
float: left
}
.center {
display: block;
margin: 0 100px;
}
.right {
display: block;
padding: 0 8px;
float: right
}
.noJsMsg {
color: #c33;
margin-left: 16px;
}
.status {
.sep {
display: inline-block;
padding: 0 6px;
}
&.default {
}
&.dynamic {
display: none;
}
}
#langSelector {
position: relative;
cursor: pointer;
.langOptions {
position: absolute;
z-index: 2;
overflow: auto;
display: none;
right: 0;
top: 0;
max-height: 200px;
background-color: rgb(241,241,241);
border: 1px solid rgb(210,210,210);
> .scrollbar {
margin: 0;
width: 6px;
background-color: rgb(210,210,210);
.drag {
background-color: rgb(180,180,180);
}
&.dragOn .drag {
background-color: rgb(150,150,150);
}
}
ul {
margin: 0;
padding: 0;
list-style: none;
text-align: left;
li {
padding: 8px 24px 10px 24px;
white-space: nowrap;
border-top: 1px solid rgb(231,231,231);
.transition(all 0.2s ease-in-out);
&.current {
color: #333;
background-color: rgba(255,255,255,0.8);
}
&:hover {
color: #e80;
background-color: rgba(255,255,255,0.8);
}
}
}
}
}
}

View File

@@ -1,237 +0,0 @@
@import "h5bp-norm";
@import "mixins";
html.js {
.hideOnJs {
display: none;
}
}
html.no-js {
.hideOnNoJs {
display: none;
}
}
body {
font-family: Ubuntu, sans-serif;
font-size: 16px;
color: #555;
background-color: #fff;
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 {
position: relative;
top: -2px;
width: 16px;
height: 16px;
}
img + span {
margin-left: 6px;
}
.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;
}
}
.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 100px;
}
.right {
display: block;
padding: 0 8px;
float: right
}
.noJsMsg {
color: #c33;
margin-left: 16px;
}
.status {
.sep {
display: inline-block;
padding: 0 6px;
}
&.default {
}
&.dynamic {
display: none;
}
}
#langSelector {
position: relative;
cursor: pointer;
.langOptions {
position: absolute;
z-index: 2;
overflow: auto;
display: none;
right: 0;
top: 0;
max-height: 200px;
background-color: rgb(241,241,241);
border: 1px solid rgb(210,210,210);
> .scrollbar {
margin: 0;
width: 6px;
background-color: rgb(210,210,210);
.drag {
background-color: rgb(180,180,180);
}
&.dragOn .drag {
background-color: rgb(150,150,150);
}
}
ul {
margin: 0;
padding: 0;
list-style: none;
text-align: left;
li {
padding: 8px 24px 10px 24px;
white-space: nowrap;
border-top: 1px solid rgb(231,231,231);
.transition(all 0.2s ease-in-out);
&.current {
color: #333;
background-color: rgba(255,255,255,0.8);
}
&:hover {
color: #e80;
background-color: rgba(255,255,255,0.8);
}
}
li:nth-child(3n+1) {
}
}
}
}
}
@import "responsive";

View File

@@ -1,38 +1,59 @@
.border-radius (@radius) { .border-radius (@radius) {
-moz-border-radius: @radius; -webkit-border-radius: @radius; /* Saf3-4, iOS 1-3.2, Android <1.6 */
-webkit-border-radius: @radius; -moz-border-radius: @radius; /* FF1-3.6 */
border-radius: @radius; border-radius: @radius; /* Opera 10.5, IE9, Saf5, Chrome, FF4, iOS 4, Android 2.1+ */
}
.background-clip () {
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
} }
.box-shadow (@shadow) { .box-shadow (@shadow) {
-moz-box-shadow: @shadow; -webkit-box-shadow: @shadow; /* Saf3-4 */
-webkit-box-shadow: @shadow; -moz-box-shadow: @shadow; /* FF3.5 - 3.6 */
box-shadow: @shadow; box-shadow: @shadow; /* Opera 10.5, IE9, FF4+, Chrome 10+ */
} }
.transition (@transition) { .transition (@transition) {
-moz-transition: @transition; -webkit-transition: @transition; /* Saf3.2+, Chrome */
-ms-transition: @transition; -moz-transition: @transition; /* FF4+ */
-o-transition: @transition; -ms-transition: @transition; /* IE10? */
-webkit-transition: @transition; -o-transition: @transition; /* Opera 10.5+ */
transition: @transition; transition: @transition;
} }
.transform (@transform) { .transform (@transform) {
-moz-transform: @transform; -webkit-transform: @transform; /* Saf3.1+, Chrome */
-o-transform: @transform; -moz-transform: @transform; /* FF3.5+ */
-webkit-transform: @transform; -ms-transform: @transform; /* IE9 */
-o-transform: @transform; /* Opera 10.5 */
transform: @transform; transform: @transform;
zoom: 1;
}
.vert-gradient (@top, @bottom) {
background-color: @top;
background-image: -webkit-gradient(linear, left top, left bottom, from(@top), to(@bottom)); /* Saf4+, Chrome */
background-image: -webkit-linear-gradient(top, @top, @bottom); /* Chrome 10+, Saf5.1+, iOS 5+ */
background-image: -moz-linear-gradient(top, @top, @bottom); /* FF3.6 */
background-image: -ms-linear-gradient(top, @top, @bottom); /* IE10 */
background-image: -o-linear-gradient(top, @top, @bottom); /* Opera 11.10+ */
background-image: linear-gradient(top, @top, @bottom);
} }
.background-size (@size) { .background-size (@size) {
-moz-background-size: @size; -webkit-background-size: @size; /* Saf3-4 */
-webkit-background-size: @size; -moz-background-size: @size; /* FF3.6 */
background-size: @size; background-size: @size; /* Opera, IE9, Saf5, Chrome, FF4 */
} }

135
src/_h5ai/css/inc/nav.less Normal file
View File

@@ -0,0 +1,135 @@
.nav-highlight {
background-color: rgba(255,255,255,0.5);
opacity: 1.0;
}
.nav-hover {
.nav-highlight;
color: #e80;
}
@nav-sep-border: 1px solid rgba(0,0,0,0.05);
.nav-left {
float: left;
border-right: @nav-sep-border;
}
.nav-right {
float: right;
border-left: @nav-sep-border;
}
body > nav {
position: fixed;
z-index: 5;
width: 100%;
left: 0;
top: 0;
font-size: 0.85em;
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
border-bottom: 1px solid rgb(210,210,210);
span.jsDisabledFallback {
display: block;
height: 30px;
line-height: 30px;
padding: 0 10px;
color: #999;
}
a, a:active, a:visited, span.element {
color: #555;
cursor: pointer;
text-decoration: none;
opacity: 0.7;
.transition(all 0.2s ease-in-out);
display: block;
height: 30px;
line-height: 30px;
padding: 0 10px;
&:hover, &.hover {
.nav-hover;
}
}
.current {
a, span.element {
.nav-highlight;
}
}
img {
position: relative;
top: -2px;
width: 16px;
height: 16px;
}
img + span, img + input {
margin-left: 6px;
}
.crumb {
.nav-left;
.hint {
margin-left: 8px;
font-style: italic;
color: #999;
}
img.hint {
width: 10px;
height: 10px;
}
}
.view {
.nav-right;
}
#download {
display: none;
.nav-right;
.transition(all 0.2s ease-in-out);
&.failed {
background-color: rgba(255,0,0,0.5);
}
}
#filter {
.nav-right;
input {
display: none;
border: none;
font-family: Ubuntu, sans-serif;
color: #555;
background-color: rgba(0,0,0,0);
width: 100px;
}
&.current {
input {
display: inline;
}
}
}
}
#download-auth {
display: none;
position: fixed;
z-index: 5;
left: 0;
top: 0;
font-size: 0.85em;
.vert-gradient(rgb(241,241,241), rgb(228,228,228));
border: 1px solid rgb(210,210,210);
input {
display: block;
margin: 4px 6px;
border: 1px solid rgb(210,210,210);
font-family: Ubuntu, sans-serif;
color: #555;
background-color: rgba(255,255,255,1);
width: 100px;
}
}

View File

@@ -3,15 +3,14 @@
display: none; display: none;
position: fixed; position: fixed;
left: 0; left: 0;
top: 82px; top: 31px;
z-index: 1; height: 100%;
z-index: 3;
overflow: auto; overflow: auto;
font-size: 0.85em; font-size: 0.85em;
padding: 8px; padding: 8px;
background-color: rgb(241,241,241); background-color: rgb(241,241,241);
border: 1px solid rgb(210,210,210); border-right: 2px solid rgb(221,221,221);
border-left: none;
.border-radius(0 10px 10px 0);
> .scrollbar { > .scrollbar {
margin: 8px 8px 8px 0; margin: 8px 8px 8px 0;

View File

@@ -1,3 +0,0 @@
@import "inc/main";

View File

@@ -1,17 +0,0 @@
@import "inc/main";
#table {
display: none;
}
#tree, #content > header, #content > footer {
display: block;
}
html.no-js {
#extended.details-view, #extended.icons-view {
display: block;
}
}

58
src/_h5ai/css/main.less Normal file
View File

@@ -0,0 +1,58 @@
@import "inc/h5bp-norm";
@import "inc/mixins";
body {
font-family: Ubuntu, sans-serif;
font-size: 16px;
color: #555;
background-color: #fff;
margin: 80px 30px;
}
@import "inc/nav";
@import "inc/content";
@import "inc/table";
@import "inc/extended";
@import "inc/tree";
@import "inc/context";
@import "inc/footer";
@import "inc/responsive";
html.js {
.hideOnJs {
display: none;
}
}
html.no-js {
.hideOnNoJs {
display: none;
}
}
html.h5ai-js {
#h5ai-reference:after {
content: " (js)";
}
}
html.h5ai-php {
#h5ai-reference:after {
content: " (php)";
}
#table {
display: none;
}
#tree, #content > header, #content > footer {
display: block;
}
html.no-js {
#extended.details-view, #extended.icons-view {
display: block;
}
}
}

View File

@@ -1,12 +1,10 @@
<!-- generated code ends here --> <!-- generated code ends here -->
</section> </section>
<section id="extended" class="clearfix"></section>
<footer></footer>
</section> </section>
<section id="tree"></section> <div id="selection-rect"></div>
<footer class="clearfix"> <footer class="clearfix">
<span class="left"> <span class="left">
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (js)</a> <a id="h5ai-reference" href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span> <span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
</span> </span>
<span class="right"> <span class="right">
@@ -27,8 +25,7 @@
</span> </span>
</span> </span>
</footer> </footer>
<script src="/_h5ai/js/libs.js"></script>
<script src="/_h5ai/config.js"></script> <script src="/_h5ai/config.js"></script>
<script src="/_h5ai/js/main-js.js"></script> <script src="/_h5ai/js/libs.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,4 +0,0 @@
<!-- generated code ends here -->
</section>
</body>
</html>

View File

@@ -2,7 +2,7 @@
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]--> <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> <!--[if gt IE 8]><!--> <html class="h5ai-js no-js" lang="en"> <!--<![endif]-->
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
@@ -13,16 +13,18 @@
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png"> <link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png"> <link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold"> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
<link rel="stylesheet" href="/_h5ai/css/main-js.css"> <link rel="stylesheet" href="/_h5ai/css/main.css">
<script src="/_h5ai/js/modernizr.min.js"></script> <script src="/_h5ai/js/modernizr.min.js"></script>
</head> </head>
<body> <body>
<div id="selection-rect"></div>
<nav class="clearfix hideOnNoJs"> <nav class="clearfix hideOnNoJs">
<ul id="navbar"></ul> <ul id="navbar"></ul>
</nav> </nav>
<section id="tree"></section>
<section id="content"> <section id="content">
<header></header> <header></header>
<section id="extended" class="clearfix"></section>
<footer></footer>
<section id="table" class="hideOnJs"> <section id="table" class="hideOnJs">
<!-- <!--
The following code was generated by Apache's autoindex module. It is not valid HTML5, but this The following code was generated by Apache's autoindex module. It is not valid HTML5, but this

View File

@@ -2,7 +2,7 @@
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]--> <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> <!--[if gt IE 8]><!--> <html class="h5ai-php no-js" lang="en"> <!--<![endif]-->
<?php include "php/main.php"; ?> <?php include "php/main.php"; ?>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@@ -14,11 +14,10 @@
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png"> <link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png"> <link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold"> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold">
<link rel="stylesheet" href="/_h5ai/css/main-php.css"> <link rel="stylesheet" href="/_h5ai/css/main.css">
<script src="/_h5ai/js/modernizr.min.js"></script> <script src="/_h5ai/js/modernizr.min.js"></script>
</head> </head>
<body> <body>
<div id="selection-rect"></div>
<nav class="clearfix"> <nav class="clearfix">
<ul id="navbar"> <ul id="navbar">
<?php echo $crumb->toHtml(); ?> <?php echo $crumb->toHtml(); ?>
@@ -29,32 +28,5 @@
<?php echo $customize->getHeader(); ?> <?php echo $customize->getHeader(); ?>
<?php echo $extended->toHtml(); ?> <?php echo $extended->toHtml(); ?>
<?php echo $customize->getFooter(); ?> <?php echo $customize->getFooter(); ?>
</section> <section id="table" class="hideOnJs">
<footer class="clearfix">
<span class="left">
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (php)</a>
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
</span>
<span class="right">
<span id="langSelector">
<span class="lang">en</span> - <span class="l10n-lang">english</span>
<span class="langOptions"></span>
</span>
</span>
<span class="center">
<span class="hideOnNoJs">
<span class="status default">
<span class="folderTotal"></span> <span class="l10n-folders">folders</span>
<span class='sep'>·</span>
<span class="fileTotal"></span> <span class="l10n-files">files</span>
</span>
<span class="status dynamic">
</span>
</span>
</span>
</footer>
<script src="/_h5ai/js/libs.js"></script>
<script src="/_h5ai/config.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 and removed from the DOM tree. --> <!-- The following code was generated by Apache's autoindex module and gets ignored and removed from the DOM tree. -->

BIN
src/_h5ai/images/filter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

View File

@@ -0,0 +1,55 @@
(function ($, H5AI) {
H5AI.context = (function () {
var $context,
qrCodesSize,
showQrCode = function ($a) {
var absHref = $a.attr('href'),
url = 'http://' + document.domain + absHref;
$context.find('.qrcode').empty().qrcode({
render: Modernizr.canvas ? 'canvas' : 'div',
width: qrCodesSize,
height: qrCodesSize,
color: '#333',
text: url
});
},
init = function () {
qrCodesSize = H5AI.core.settings.qrCodesSize;
if (!qrCodesSize) {
return;
}
var hideTimeoutId = null;
$context = $('<div id="context"><div class="qrcode"/></div>');
$context.appendTo('body');
$('#extended')
.on('mouseenter', '.entry.file a', function () {
showQrCode($(this));
clearTimeout(hideTimeoutId);
$context.stop(true, true).fadeIn(400);
})
.on('mouseleave', '.entry.file a', function () {
hideTimeoutId = setTimeout(function () {
$context.stop(true, true).fadeOut(400);
}, 200);
});
};
return {
init: init
};
}());
}(jQuery, H5AI));

View File

@@ -15,21 +15,23 @@
rootAbsHref: "/", rootAbsHref: "/",
h5aiAbsHref: "/_h5ai/", h5aiAbsHref: "/_h5ai/",
customHeader: "_h5ai.header.html", customHeader: null,
customFooter: "_h5ai.footer.html", customFooter: null,
viewmodes: ["details", "icons"], viewmodes: ["details", "icons"],
sortorder: "na", sortorder: "na",
showTree: true, showTree: true,
slideTree: true, slideTree: true,
folderStatus: {}, folderStatus: {},
lang: null, lang: "en",
useBrowserLang: true, useBrowserLang: true,
setParentFolderLabels: true, setParentFolderLabels: true,
linkHoverStates: true, linkHoverStates: true,
dateFormat: "yyyy-MM-dd HH:mm", dateFormat: "yyyy-MM-dd HH:mm",
showThumbs: false, showThumbs: false,
zippedDownload: false thumbTypes: ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
zippedDownload: false,
qrCodesSize: null,
showFilter: false
}, },
settings = $.extend({}, defaults, config.options), settings = $.extend({}, defaults, config.options),
currentDateFormat = settings.dateFormat, currentDateFormat = settings.dateFormat,
@@ -42,13 +44,42 @@
}); });
return map; return map;
}(config.types)), }(config.types)),
hash = function (obj) {
if ($.isPlainObject(obj)) {
var hashStr = '';
$.each($.extend({}, hash(), obj), function (key, value) {
if (value) {
hashStr += '/' + encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
});
hashStr = '#!' + hashStr;
window.location.hash = hashStr;
return hashStr;
} else {
var result = {},
parts = document.location.hash.split('/');
if (parts.length >= 2 || parts[0] === '#!') {
parts.shift();
$.each(parts, function (idx, part) {
var match = /^([^=]*)=(.*?)$/.exec(part);
if (match) {
result[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
});
}
return typeof obj === 'string' ? result[obj] : result;
}
},
api = function () { api = function () {
return settings.h5aiAbsHref + "php/api.php"; return settings.h5aiAbsHref + "php/api.php";
}, },
image = function (id) { image = function (id, noPngExt) {
return settings.h5aiAbsHref + "images/" + id + ".png"; return settings.h5aiAbsHref + "images/" + id + (noPngExt ? "" : ".png");
}, },
icon = function (id, big) { icon = function (id, big) {
@@ -66,6 +97,7 @@
viewmode = amplify.store(settings.store.viewmode); viewmode = amplify.store(settings.store.viewmode);
} }
viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0]; viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
H5AI.core.hash({view: viewmode});
$viewDetails.add($viewIcons).removeClass("current"); $viewDetails.add($viewIcons).removeClass("current");
if (viewmode === "details") { if (viewmode === "details") {
@@ -88,7 +120,7 @@
navHeight = $("body > nav").outerHeight(), navHeight = $("body > nav").outerHeight(),
footerHeight = $("body > footer").outerHeight(), footerHeight = $("body > footer").outerHeight(),
contentSpacing = 50, contentSpacing = 50,
treeSpacing = 30; treeSpacing = 0;
$body.css({ $body.css({
"margin-top": navHeight + contentSpacing, "margin-top": navHeight + contentSpacing,
@@ -97,7 +129,7 @@
$tree.css({ $tree.css({
top: navHeight + treeSpacing, top: navHeight + treeSpacing,
height: winHeight - navHeight - footerHeight - 18 - 2 * treeSpacing height: winHeight - navHeight - footerHeight - 16 - 2 * treeSpacing
}); });
try { try {
@@ -121,13 +153,19 @@
if ($.inArray("icons", settings.viewmodes) >= 0) { if ($.inArray("icons", settings.viewmodes) >= 0) {
$("<li id='viewicons' class='view'><a href='#'><img alt='view-icons' /><span class='l10n-icons'>icons</span></a></li>") $("<li id='viewicons' class='view'><a href='#'><img alt='view-icons' /><span class='l10n-icons'>icons</span></a></li>")
.find("img").attr("src", image("view-icons")).end() .find("img").attr("src", image("view-icons")).end()
.click(function () { viewmode("icons"); }) .find("a").click(function (event) {
viewmode("icons");
event.preventDefault();
}).end()
.appendTo($navbar); .appendTo($navbar);
} }
if ($.inArray("details", settings.viewmodes) >= 0) { if ($.inArray("details", settings.viewmodes) >= 0) {
$("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>") $("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>")
.find("img").attr("src", image("view-details")).end() .find("img").attr("src", image("view-details")).end()
.click(function () { viewmode("details"); }) .find("a").click(function (event) {
viewmode("details");
event.preventDefault();
}).end()
.appendTo($navbar); .appendTo($navbar);
} }
} }
@@ -255,6 +293,7 @@
$(".lang").text(lang); $(".lang").text(lang);
$(".langOption").removeClass("current"); $(".langOption").removeClass("current");
$(".langOption." + lang).addClass("current"); $(".langOption." + lang).addClass("current");
H5AI.core.hash({lang: lang});
} }
formatDates(selected.dateFormat || settings.dateFormat); formatDates(selected.dateFormat || settings.dateFormat);
@@ -384,6 +423,7 @@
return { return {
settings: settings, settings: settings,
hash: hash,
api: api, api: api,
image: image, image: image,
icon: icon, icon: icon,

View File

@@ -49,9 +49,11 @@
if ($ul.children(".entry:not(.folder-parent)").size() === 0) { if ($ul.children(".entry:not(.folder-parent)").size() === 0) {
$("#extended").append($("<div class='empty l10n-empty'>empty</div>")); $("#extended").append($("<div class='empty l10n-empty'>empty</div>"));
} }
$("#extended").append($("<div class='no-match l10n-noMatch'>no match</div>"));
}, },
customize = function () { customize = function () {
if (H5AI.core.settings.customHeader) {
$.ajax({ $.ajax({
url: H5AI.core.settings.customHeader, url: H5AI.core.settings.customHeader,
dataType: "html", dataType: "html",
@@ -59,7 +61,9 @@
$("#content > header").append($(data)).show(); $("#content > header").append($(data)).show();
} }
}); });
}
if (H5AI.core.settings.customFooter) {
$.ajax({ $.ajax({
url: H5AI.core.settings.customFooter, url: H5AI.core.settings.customFooter,
dataType: "html", dataType: "html",
@@ -67,6 +71,7 @@
$("#content > footer").prepend($(data)).show(); $("#content > footer").prepend($(data)).show();
} }
}); });
}
}, },
fetchPath = function (pathname, callback) { fetchPath = function (pathname, callback) {

111
src/_h5ai/js/inc/Finder.js Normal file
View File

@@ -0,0 +1,111 @@
(function ($, H5AI) {
H5AI.finder = (function () {
var filter = function (re) {
var match = [],
noMatch = [];
if (re) {
$('#extended .entry').each(function () {
var label = $(this).find('.label').text();
if (label.match(re)) {
match.push(this);
} else {
noMatch.push(this);
}
});
} else {
match = $('#extended .entry');
}
if ($(match).length) {
$('#extended .no-match').hide();
} else {
setTimeout(function () {
$('#extended .no-match').show();
}, 200);
}
$(match).fadeIn(200);
$(noMatch).fadeOut(200);
},
checkState = function (focus) {
var $filter = $('#filter'),
$input = $filter.find('input'),
val = $input.val();
if (val || focus) {
$filter.addClass('current');
} else {
$filter.removeClass('current');
}
H5AI.core.hash({filter: val});
},
parseFilterSequence = function (sequence) {
if (sequence.substr(0,3) === 're:') {
return new RegExp(sequence.substr(3));
}
sequence = $.map($.trim(sequence).split(/\s+/), function (part) {
return H5AI.util.reEscape(part);
}).join('|');
return new RegExp(sequence);
},
init = function () {
if (H5AI.core.settings.showFilter) {
$("<li id='filter'><span class='element'><img alt='filter' /><input type='text' value='' placeholder='filter' /></span></li>")
.on('click', function () {
var $input = $(this).find('input');
$input.focus();
})
.find("img").attr("src", H5AI.core.image("filter")).end()
.find("input")
.on('focus', function () {
checkState(true);
})
.on('blur', function () {
checkState(false);
})
.on('keyup', function () {
var $input = $(this),
val = $input.val();
if (val) {
filter(parseFilterSequence(val));
} else {
filter();
}
checkState($input.is(':focus'));
})
.end()
.appendTo($("#navbar"));
var initialFilter = H5AI.core.hash('filter');
if (initialFilter) {
$('#filter input').val(initialFilter);
checkState(false);
}
}
};
return {
init: init,
filter: filter
};
}());
}(jQuery, H5AI));

View File

@@ -3,8 +3,7 @@
H5AI.html = (function () { H5AI.html = (function () {
var thumbTypes = ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"], var onClick = function (path, context) {
onClick = function (path, context) {
}, },
updateCrumbHtml = function (path) { updateCrumbHtml = function (path) {
@@ -72,10 +71,11 @@
$html.data("status", path.status); $html.data("status", path.status);
} }
if (H5AI.core.settings.showThumbs === true && $.inArray(path.type, thumbTypes) >= 0) { if (H5AI.core.settings.showThumbs === true && $.inArray(path.type, H5AI.core.settings.thumbTypes) >= 0) {
imgClass = "class='thumb'"; imgClass = "class='thumb'";
icon16 = H5AI.core.api() + "?action=thumb&href=" + path.absHref + "&width=16&height=16&mode=square"; var escapedHref = path.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
icon48 = H5AI.core.api() + "?action=thumb&href=" + path.absHref + "&width=96&height=46&mode=rational"; icon16 = H5AI.core.api() + "?action=thumb&href=" + escapedHref + "&width=16&height=16&mode=square";
icon48 = H5AI.core.api() + "?action=thumb&href=" + escapedHref + "&width=96&height=46&mode=rational";
} }
$label = $("<span class='label'>" + path.label + "</span>"); $label = $("<span class='label'>" + path.label + "</span>");

View File

@@ -39,7 +39,7 @@
path.parentFolder = folder; path.parentFolder = folder;
path.label = $a.text(); path.label = $a.text();
path.type = $tds.eq(0).find("img").attr("alt") === "[DIR]" ? "folder" : H5AI.core.getFileType(path.label); path.type = H5AI.util.pathEndsWithSlash(path.label) ? "folder" : H5AI.core.getFileType(path.label);
path.href = $a.attr("href"); path.href = $a.attr("href");
path.time = date ? date.getTime() : 0; path.time = date ? date.getTime() : 0;
path.size = size; path.size = size;

View File

@@ -78,14 +78,15 @@
var order = orders[id]; var order = orders[id];
$all.removeClass("ascending").removeClass("descending"); $all.removeClass("ascending").removeClass("descending");
order.head.addClass(order.clas).attr("href", "#!/sort=" + id); order.head.addClass(order.clas);
sort(order.fn); sort(order.fn);
H5AI.core.hash({sort: id});
}, },
init = function () { init = function () {
var $ascending = $("<img src='" + H5AI.core.image("ascending") + "' class='sort ascending' alt='ascending' />"), var $ascending = $("<img src='" + H5AI.core.image("ascending") + "' class='sort ascending' alt='ascending' />"),
$descending = $("<img src='" + H5AI.core.image("descending") + "' class='sort descending' alt='descending' />"), $descending = $("<img src='" + H5AI.core.image("descending") + "' class='sort descending' alt='descending' />"),
initialOrder = /^.*#!.*\/sort=(.*?)(?:\/.*)?$/.exec(document.location), initialOrder = H5AI.core.hash('sort'),
$header = $("#extended li.header"), $header = $("#extended li.header"),
$label = $header.find("a.label"), $label = $header.find("a.label"),
$date = $header.find("a.date"), $date = $header.find("a.date"),
@@ -125,27 +126,27 @@
} }
}; };
sortBy(initialOrder ? initialOrder[1] : H5AI.core.settings.sortorder); sortBy(initialOrder ? initialOrder : H5AI.core.settings.sortorder);
$label $label
.attr("href", "#!/sort=na")
.append($ascending.clone()).append($descending.clone()) .append($ascending.clone()).append($descending.clone())
.click(function () { .click(function (event) {
sortBy("n" + ($label.hasClass("ascending") ? "d" : "a")); sortBy("n" + ($label.hasClass("ascending") ? "d" : "a"));
event.preventDefault();
}); });
$date $date
.attr("href", "#!/sort=da")
.prepend($ascending.clone()).prepend($descending.clone()) .prepend($ascending.clone()).prepend($descending.clone())
.click(function () { .click(function (event) {
sortBy("d" + ($date.hasClass("ascending") ? "d" : "a")); sortBy("d" + ($date.hasClass("ascending") ? "d" : "a"));
event.preventDefault();
}); });
$size $size
.attr("href", "#!/sort=sa")
.prepend($ascending.clone()).prepend($descending.clone()) .prepend($ascending.clone()).prepend($descending.clone())
.click(function () { .click(function (event) {
sortBy("s" + ($size.hasClass("ascending") ? "d" : "a")); sortBy("s" + ($size.hasClass("ascending") ? "d" : "a"));
event.preventDefault();
}); });
}; };

View File

@@ -100,6 +100,10 @@
return decodeURI(uri); return decodeURI(uri);
} catch (err) {} } catch (err) {}
return uri; return uri;
},
reEscape = function (sequence) {
return sequence.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}; };
return { return {
@@ -108,7 +112,8 @@
getAbsHref: getAbsHref, getAbsHref: getAbsHref,
parseSize: parseSize, parseSize: parseSize,
formatSize: formatSize, formatSize: formatSize,
checkedDecodeUri: checkedDecodeUri checkedDecodeUri: checkedDecodeUri,
reEscape: reEscape
}; };
}()); }());

View File

@@ -7,21 +7,25 @@
y = 0, y = 0,
$document = $(document), $document = $(document),
$selectionRect = $("#selection-rect"), $selectionRect = $("#selection-rect"),
selectedHrefsStr = "",
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
updateDownloadBtn = function () { updateDownloadBtn = function () {
var $selected = $("#extended a.selected"), var $selected = $("#extended a.selected"),
$downloadBtn = $("#download"), $downloadBtn = $("#download");
query, href;
if ($selected.size() > 0) { selectedHrefsStr = "";
if ($selected.length) {
$selected.each(function () { $selected.each(function () {
href = $(this).attr("href");
query = query ? query + ":" + href : href; var href = $(this).attr("href");
selectedHrefsStr = selectedHrefsStr ? selectedHrefsStr + ":" + href : href;
}); });
query = H5AI.core.api() + "?action=zip&hrefs=" + query; $downloadBtn.show();
$downloadBtn.show().find("a").attr("href", query);
} else { } else {
$downloadBtn.hide().find("a").attr("href", "#"); $downloadBtn.hide();
$downloadAuth.hide();
} }
}, },
selectionUpdate = function (event) { selectionUpdate = function (event) {
@@ -67,12 +71,12 @@
} }
event.preventDefault(); event.preventDefault();
$(':focus').blur();
if (!event.ctrlKey) { if (!event.ctrlKey) {
$("#extended a").removeClass("selected"); $("#extended a").removeClass("selected");
updateDownloadBtn(); updateDownloadBtn();
} }
$selectionRect.show().css({left: x, top: y, width: 0, height: 0}); $selectionRect.show().css({left: x, top: y, width: 0, height: 0});
selectionUpdate(event);
$document $document
.on("mousemove", selectionUpdate) .on("mousemove", selectionUpdate)
@@ -80,7 +84,7 @@
}, },
noSelection = function (event) { noSelection = function (event) {
event.stopPropagation(); event.stopImmediatePropagation();
return false; return false;
}, },
noSelectionUnlessCtrl = function (event) { noSelectionUnlessCtrl = function (event) {
@@ -89,15 +93,92 @@
noSelection(event); noSelection(event);
} }
}, },
failed = function () {
$download.addClass('failed');
setTimeout(function () {
$download.removeClass('failed');
}, 1000);
},
handleResponse = function (response) {
$download.removeClass('current');
$img.attr('src', H5AI.core.image("download"));
if (response) {
if (response.status === 'ok') {
window.location = H5AI.core.api() + '?action=getzip&id=' + response.id;
} else {
if (response.code === 401) {
$downloadAuth
.css({
left: $download.offset().left,
top: $download.offset().top + $download.outerHeight()
})
.show();
$downloadUser.focus();
}
failed();
}
} else {
failed();
}
},
requestZipping = function (hrefsStr) {
$download.addClass('current');
$img.attr('src', H5AI.core.image("loading.gif", true));
$.ajax({
url: H5AI.core.api(),
data: {
action: 'zip',
hrefs: selectedHrefsStr
},
type: 'POST',
dataType: 'json',
beforeSend: function (xhr) {
var user = $downloadUser.val(),
password = $downloadPassword.val();
if (user) {
xhr.setRequestHeader ('Authorization', 'Basic ' + Base64.encode(user + ':' + password));
}
},
success: function (response) {
handleResponse(response);
},
failed: function () {
handleResponse();
}
});
},
init = function () { init = function () {
if (H5AI.core.settings.zippedDownload) { if (H5AI.core.settings.zippedDownload) {
$("<li id='download'><a href='#'><img alt='download' /><span class='l10n-download'>download</span></a></li>") $("<li id='download'><a href='#'><img alt='download' /><span class='l10n-download'>download</span></a></li>")
.find("img").attr("src", H5AI.core.image("download")).end() .find("img").attr("src", H5AI.core.image("download")).end()
.appendTo($("#navbar")); .find("a").click(function (event) {
$("body>nav,body>footer,#tree").on("mousedown", noSelection); event.preventDefault();
$("#extended").on("mousedown", "a", noSelectionUnlessCtrl); $downloadAuth.hide();
requestZipping(selectedHrefsStr);
}).end()
.appendTo($("#navbar"));
$("<div id='download-auth'><input id='download-auth-user' type='text' value='' placeholder='user' /><input id='download-auth-password' type='text' value='' placeholder='password' /></div>")
.appendTo($("body"));
$download = $('#download');
$downloadAuth = $('#download-auth');
$downloadUser = $('#download-auth-user');
$downloadPassword = $('#download-auth-password');
$img = $download.find('img');
$("body>nav,body>footer,#tree,input").on("mousedown", noSelection);
$("#content").on("mousedown", "a", noSelectionUnlessCtrl);
$document.on("mousedown", selectionStart); $document.on("mousedown", selectionStart);
} }
}; };

View File

@@ -0,0 +1,137 @@
/*
* taken from here:
* http://www.webtoolkit.info/javascript-base64.html
* with minor modifications
*/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
return Base64._utf8_decode(output);
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}

View File

@@ -82,6 +82,3 @@ function handler(event) {
} }
})(jQuery); })(jQuery);

View File

@@ -0,0 +1,130 @@
/*!
* jQuery.qrcode
* author: Lars Jung
* license: MIT
*
* kudos to http://github.com/jeromeetienne/jquery-qrcode
*/
(function ($) {
'use strict';
// @include "qrcode.js"
var createQr = function (typeNumber, correctLevel, text) {
var qr = new qrcode(typeNumber, correctLevel);
qr.addData(text);
qr.make();
return qr;
},
createBestQr = function (text) {
for (var type = 2; type <= 10; type += 1) {
try {
return createQr(type, 'L', text);
} catch (err) {}
}
return null;
},
createCanvas = function (settings) {
var qr = createBestQr(settings.text),
$canvas = $('<canvas/>').attr('width', settings.width).attr('height', settings.height),
ctx = $canvas[0].getContext('2d');
if (settings.bgColor) {
ctx.fillStyle = settings.bgColor;
ctx.fillRect(0, 0, settings.width, settings.height);
}
if (qr) {
var moduleCount = qr.getModuleCount(),
moduleWidth = settings.width / moduleCount,
moduleHeight = settings.height / moduleCount,
row, col;
ctx.beginPath();
for (row = 0; row < moduleCount; row += 1) {
for (col = 0; col < moduleCount; col += 1) {
if (qr.isDark(row, col)) {
ctx.rect(col * moduleWidth, row * moduleHeight, moduleWidth, moduleHeight);
}
}
}
ctx.fillStyle = settings.color;
ctx.fill();
}
return $canvas;
},
createDiv = function (settings) {
var qr = createBestQr(settings.text),
$div = $('<div/>').css({
position: 'relative',
left: 0,
top: 0,
padding: 0,
margin: 0,
width: settings.width,
height: settings.height
});
if (settings.bgColor) {
$div.css('background-color', settings.bgColor);
}
if (qr) {
var moduleCount = qr.getModuleCount(),
moduleWidth = Math.floor(settings.width / moduleCount),
moduleHeight = Math.floor(settings.height / moduleCount),
offsetLeft = Math.floor(0.5 * (settings.width - moduleWidth * moduleCount)),
offsetTop = Math.floor(0.5 * (settings.height - moduleHeight * moduleCount)),
row, col;
for (row = 0; row < moduleCount; row++) {
for (col = 0; col < moduleCount; col++) {
if (qr.isDark(row, col)) {
$('<div/>')
.css({
left: offsetLeft + col * moduleWidth,
top: offsetTop + row * moduleHeight
})
.appendTo($div);
}
}
}
$div.children()
.css({
position: 'absolute',
padding: 0,
margin: 0,
width: moduleWidth,
height: moduleHeight,
'background-color': settings.color
});
}
return $div;
},
defaults = {
render: 'canvas',
width: 256,
height: 256,
color: '#000',
bgColor: null,
text: 'no text'
};
$.fn.qrcode = function(options) {
var settings = $.extend({}, defaults, options);
$(this).append(settings.render === 'canvas' ? createCanvas(settings) : createDiv(settings));
};
}(jQuery));

View File

@@ -3,9 +3,8 @@
* author: Lars Jung * author: Lars Jung
* license: MIT * license: MIT
* *
* bad and ugly coded! * still quick and dirty!
*/ */
(function (window, $) { (function (window, $) {
"use strict"; "use strict";

File diff suppressed because it is too large Load Diff

42
src/_h5ai/js/inc/main.js Normal file
View File

@@ -0,0 +1,42 @@
(function ($) {
'use strict';
/*jslint browser: true, confusion: true, regexp: true, vars: true, white: true */
/*global Modernizr, jQuery, amplify, H5AI_CONFIG */
var H5AI = {};
// @include "Util.js"
// @include "Core.js"
// @include "Sort.js"
// @include "ZippedDownload.js"
// @include "Finder.js"
// @include "Context.js"
// @include "Path.js"
// @include "Connector.js"
// @include "Html.js"
// @include "Extended.js"
$(function () {
var isPhp = $('html.h5ai-php').length > 0;
if (!isPhp) {
H5AI.extended.init();
}
H5AI.core.init();
H5AI.sort.init();
H5AI.finder.init();
H5AI.zippedDownload.init();
H5AI.context.init();
if (isPhp) {
$('#tree').scrollpanel();
H5AI.core.shiftTree(false, true);
}
});
}(jQuery));

View File

@@ -3,6 +3,10 @@
// @include "inc/lib/jquery.mousewheel.js" // @include "inc/lib/jquery.mousewheel.js"
// @include "inc/lib/jquery.fracs-core.min.js" // @include "inc/lib/jquery.fracs-core.min.js"
// @include "inc/lib/jquery.scrollpanel.js" // @include "inc/lib/jquery.scrollpanel.js"
// @include "inc/lib/jquery.qrcode.js"
// @include "inc/lib/amplify.min.js" // @include "inc/lib/amplify.min.js"
// @include "inc/lib/base64.js"
// @include "inc/lib/date.js" // @include "inc/lib/date.js"
// @include "inc/main.js"

View File

@@ -1,29 +0,0 @@
/*jslint browser: true, confusion: true, regexp: true, white: true */
/*jshint browser: true, confusion: true, regexp: false, white: false */
/*global jQuery, amplify, H5AI_CONFIG */
(function ($) {
"use strict";
var H5AI = {};
// @include "inc/Util.js"
// @include "inc/Core.js"
// @include "inc/Sort.js"
// @include "inc/ZippedDownload.js"
// @include "inc/Path.js"
// @include "inc/Connector.js"
// @include "inc/Html.js"
// @include "inc/Extended.js"
$(function () {
H5AI.extended.init();
H5AI.core.init();
H5AI.sort.init();
H5AI.zippedDownload.init();
});
}(jQuery));

View File

@@ -1,25 +0,0 @@
/*jslint browser: true, confusion: true, regexp: true, white: true */
/*jshint browser: true, confusion: true, regexp: false, white: false */
/*global jQuery, amplify, H5AI_CONFIG */
(function ($) {
"use strict";
var H5AI = {};
// @include "inc/Util.js"
// @include "inc/Core.js"
// @include "inc/Sort.js"
// @include "inc/ZippedDownload.js"
$(function () {
H5AI.core.init();
H5AI.sort.init();
H5AI.zippedDownload.init();
$("#tree").scrollpanel();
H5AI.core.shiftTree(false, true);
});
}(jQuery));

View File

@@ -1,5 +1,18 @@
<?php <?php
function safe_dirname($path, $endWithSlash = false) {
$path = str_replace("\\", "/", dirname($path));
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
}
define("H5AI_ABS_PATH", safe_dirname(safe_dirname(__FILE__)));
function require_h5ai($lib) {
require_once(H5AI_ABS_PATH . $lib);
}
function fail($code, $msg, $cond = true) { function fail($code, $msg, $cond = true) {
if ($cond) { if ($cond) {
@@ -18,15 +31,14 @@ function checkKeys($keys) {
} }
list($action) = checkKeys(array("action")); require_h5ai("/php/inc/H5ai.php");
require_once "config.php";
require_once "inc/H5ai.php";
$h5ai = new H5ai(); $h5ai = new H5ai();
$options = $h5ai->getOptions(); $options = $h5ai->getOptions();
list($action) = checkKeys(array("action"));
if ($action === "httpcodes") { if ($action === "httpcodes") {
list($hrefs) = checkKeys(array("hrefs")); list($hrefs) = checkKeys(array("hrefs"));
@@ -55,10 +67,10 @@ else if ($action === "thumb") {
fail(0, "thumbs are disabled", !$options["showThumbs"]); fail(0, "thumbs are disabled", !$options["showThumbs"]);
list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode")); list($srcAbsHref, $width, $height, $mode) = checkKeys(array("href", "width", "height", "mode"));
require_once "inc/Thumbnail.php"; require_h5ai("/php/inc/Thumbnail.php");
require_once "inc/Image.php"; require_h5ai("/php/inc/Image.php");
$srcAbsPath = $h5ai->getDocRoot() . rawurldecode($srcAbsHref); $srcAbsPath = $h5ai->getRootAbsPath() . rawurldecode($srcAbsHref);
if (!Thumbnail::isUsable()) { if (!Thumbnail::isUsable()) {
Image::showImage($srcAbsPath); Image::showImage($srcAbsPath);
@@ -82,7 +94,7 @@ else if ($action === "tree") {
list($href) = checkKeys(array("href")); list($href) = checkKeys(array("href"));
require_once "inc/Tree.php"; require_h5ai("/php/inc/Tree.php");
$absHref = trim($href); $absHref = trim($href);
$absPath = $h5ai->getAbsPath($absHref); $absPath = $h5ai->getAbsPath($absHref);
@@ -99,19 +111,32 @@ else if ($action === "zip") {
fail(0, "zipped download is disabled", !$options["zippedDownload"]); fail(0, "zipped download is disabled", !$options["zippedDownload"]);
list($hrefs) = checkKeys(array("hrefs")); list($hrefs) = checkKeys(array("hrefs"));
require_once "inc/ZipIt.php"; require_h5ai("/php/inc/ZipIt.php");
$zipit = new ZipIt($h5ai); $zipit = new ZipIt($h5ai);
$hrefs = explode(":", trim($hrefs)); $hrefs = explode(":", trim($hrefs));
$zipFile = $zipit->zip($hrefs); $zipFile = $zipit->zip($hrefs);
if ($zipFile === false) { if (is_string($zipFile)) {
fail(2, "something went wrong while building the zip"); $response = array('status' => 'ok', 'id' => basename($zipFile), 'size' => filesize($zipFile));
} else {
$response = array('status' => 'failed', 'code' => $zipFile);
} }
echo json_encode($response);
}
else if ($action === "getzip") {
list($id) = checkKeys(array("id"));
fail(1, "zipped file not found: " . $id, !preg_match("/^h5ai-zip-/", $id));
$zipFile = str_replace("\\", "/", sys_get_temp_dir()) . "/" . $id;
fail(2, "zipped file not found: " . $id, !file_exists($zipFile));
header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\""); header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\"");
header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($zipFile)); header("Content-Length: " . filesize($zipFile));
header("Connection: close"); header("Connection: close");
readfile($zipFile); readfile($zipFile);

View File

@@ -1,27 +0,0 @@
<?php
/*
* h5ai %BUILD_VERSION%
*
* PHP Configuration
* filesystem paths and file ignore rules
*/
global $H5AI_CONFIG;
$H5AI_CONFIG = array();
/*
* This configuration assumes that h5ai is installed
* in the webroot directory of the Apache server.
*/
$H5AI_CONFIG["H5AI_ROOT"] = dirname(dirname(__FILE__));
$H5AI_CONFIG["DOCUMENT_ROOT"] = dirname($H5AI_CONFIG["H5AI_ROOT"]);
/*
* Files/folders that should not be listed. Specified
* by the complete filename or by a regular expression.
* http://www.php.net/manual/en/function.preg-match.php
*/
$H5AI_CONFIG["IGNORE"] = array();
$H5AI_CONFIG["IGNORE_PATTERNS"] = array("/^\\./", "/^_h5ai/");
?>

View File

@@ -7,18 +7,22 @@
############################################## ##############################################
class Cache { class Cache {
private $dir; private $dir;
function __construct($dir) { function __construct($dir) {
$this->dir = $dir; $this->dir = $dir;
} }
private function _name($key) { private function _name($key) {
return $this->dir . "/" . sha1($key); return $this->dir . "/" . sha1($key);
} }
public function get($key, $expiration = 3600) { public function get($key, $expiration = 3600) {
if (!is_dir($this->dir) || !is_writable($this->dir)) { if (!is_dir($this->dir) || !is_writable($this->dir)) {
@@ -55,6 +59,7 @@ class Cache {
return $cache; return $cache;
} }
public function set($key, $data) { public function set($key, $data) {
if (!is_dir($this->dir) || !is_writable($this->dir)) { if (!is_dir($this->dir) || !is_writable($this->dir)) {
@@ -78,6 +83,7 @@ class Cache {
return true; return true;
} }
public function clear($key) { public function clear($key) {
$cache_path = $this->_name($key); $cache_path = $this->_name($key);

View File

@@ -1,23 +1,26 @@
<?php <?php
class Crumb { class Crumb {
private $h5ai, $parts; private $h5ai, $parts;
public function __construct($h5ai) { public function __construct($h5ai) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
$this->parts = array(); $this->parts = array();
$href = $h5ai->getAbsHref(); $href = $h5ai->getAbsHref();
while ($href !== "/" && $href !== "//") { while ($href !== "/") {
$this->parts[] = $href; $this->parts[] = $href;
$href = dirname($href) . "/"; $href = safe_dirname($href, true);
} }
$this->parts[] = "/"; $this->parts[] = "/";
$this->parts = array_reverse($this->parts); $this->parts = array_reverse($this->parts);
} }
public function toHtml() { public function toHtml() {
$html = ""; $html = "";

View File

@@ -1,29 +1,34 @@
<?php <?php
class Customize { class Customize {
private $customHeader, $customFooter; private $customHeader, $customFooter;
public function __construct($h5ai) { public function __construct($h5ai) {
$absPath = $h5ai->getAbsPath(); $absPath = $h5ai->getAbsPath();
$options = $h5ai->getOptions(); $options = $h5ai->getOptions();
$this->customHeader = $absPath . "/" . $options["customHeader"]; $this->customHeader = $options["customHeader"] ? $absPath . "/" . $options["customHeader"] : false;
$this->customFooter = $absPath . "/" . $options["customFooter"]; $this->customFooter = $options["customFooter"] ? $absPath . "/" . $options["customFooter"] : false;
} }
public function getHeader() { public function getHeader() {
return $this->getContent($this->customHeader, "header"); return $this->getContent($this->customHeader, "header");
} }
public function getFooter() { public function getFooter() {
return $this->getContent($this->customFooter, "footer"); return $this->getContent($this->customFooter, "footer");
} }
private function getContent($file, $tag) { private function getContent($file, $tag) {
return file_exists($file) ? ("<" . $tag . ">" . file_get_contents($file) . "</" . $tag . ">") : ""; return (is_string($file) && file_exists($file)) ? ("<$tag>" . file_get_contents($file) . "</$tag>") : "";
} }
} }

View File

@@ -1,10 +1,12 @@
<?php <?php
require_once "Thumbnail.php"; require_h5ai("/php/inc/Thumbnail.php");
class Entry { class Entry {
private $h5ai, $label, $absPath, $absHref, $date, $isFolder, $type, $size, $thumbTypes;
private $h5ai, $label, $absPath, $absHref, $date, $isFolder, $type, $size;
public function __construct($h5ai, $absPath, $absHref, $type = null, $label = null) { public function __construct($h5ai, $absPath, $absHref, $type = null, $label = null) {
@@ -23,15 +25,15 @@ class Entry {
$this->type = $type !== null ? $type : $this->h5ai->getType($this->absPath); $this->type = $type !== null ? $type : $this->h5ai->getType($this->absPath);
$this->size = filesize($this->absPath); $this->size = filesize($this->absPath);
} }
$this->thumbTypes = array("bmp", "gif", "ico", "image", "jpg", "png", "tiff");
} }
public function isFolder() { public function isFolder() {
return $this->isFolder; return $this->isFolder;
} }
public function toHtml() { public function toHtml() {
$classes = "entry " . ($this->isFolder ? "folder " : "file ") . $this->type; $classes = "entry " . ($this->isFolder ? "folder " : "file ") . $this->type;
@@ -55,7 +57,7 @@ class Entry {
} }
} }
} }
if ($this->h5ai->showThumbs() && in_array($this->type, $this->thumbTypes)) { if ($this->h5ai->showThumbs() && in_array($this->type, $this->h5ai->getThumbTypes())) {
$imgClass = " class='thumb' "; $imgClass = " class='thumb' ";
$thumbnail = new Thumbnail($this->h5ai, $this->absHref, "square", 16, 16); $thumbnail = new Thumbnail($this->h5ai, $this->absHref, "square", 16, 16);
$thumbnail->create(); $thumbnail->create();
@@ -80,8 +82,10 @@ class Entry {
class Extended { class Extended {
private $h5ai, $parent, $content; private $h5ai, $parent, $content;
public function __construct($h5ai) { public function __construct($h5ai) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
@@ -90,12 +94,13 @@ class Extended {
$this->loadContent(); $this->loadContent();
} }
private function loadContent() { private function loadContent() {
if ($this->h5ai->getAbsHref() !== "/") { if ($this->h5ai->getAbsHref() !== "/") {
$options = $this->h5ai->getOptions(); $options = $this->h5ai->getOptions();
$parentPath = dirname($this->h5ai->getAbsPath()); $parentPath = safe_dirname($this->h5ai->getAbsPath());
$parentHref = dirname($this->h5ai->getAbsHref()); $parentHref = safe_dirname($this->h5ai->getAbsHref(), true);
$label = $options["setParentFolderLabels"] === true ? $this->h5ai->getLabel($parentHref) : "<span class='l10n-parentDirectory'>Parent Directory</span>"; $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->parent = new Entry($this->h5ai, $parentPath, $parentHref, "folder-parent", $label);
} }
@@ -110,6 +115,7 @@ class Extended {
} }
} }
public function toHtml() { public function toHtml() {
$html = "<section id='extended' class='" . $this->h5ai->getView() . "-view clearfix'>\n"; $html = "<section id='extended' class='" . $this->h5ai->getView() . "-view clearfix'>\n";
@@ -125,11 +131,13 @@ class Extended {
if (count($this->content) === 0) { if (count($this->content) === 0) {
$html .= "<div class='empty l10n-empty'>empty</div>"; $html .= "<div class='empty l10n-empty'>empty</div>";
} }
$html .= "<div class='no-match l10n-noMatch'>no match</div>";
$html .="</section>"; $html .="</section>";
return $html; return $html;
} }
public function generateHeaders() {
private function generateHeaders() {
$html = "\t<li class='header'>\n"; $html = "\t<li class='header'>\n";
$html .= "\t\t<a class='icon'></a>\n"; $html .= "\t\t<a class='icon'></a>\n";

View File

@@ -1,34 +1,38 @@
<?php <?php
require_once "Cache.php"; require_h5ai("/config.php");
require_h5ai("/php/inc/Cache.php");
class H5ai { class H5ai {
private static $VIEWMODES = array("details", "icons"); private static $VIEWMODES = array("details", "icons");
private $docRoot, $h5aiRoot, $h5aiAbsHref, $domain, private $h5aiAbsPath,
$rootAbsPath, $ignore, $ignoreRE,
$config, $options, $types, $langs, $config, $options, $types, $langs,
$cache, $cache,
$rootAbsHref, $h5aiAbsHref, $domain,
$absHref, $absPath, $absHref, $absPath,
$ignore, $ignoreRE,
$view; $view;
public function __construct() { public function __construct() {
global $H5AI_CONFIG; $this->h5aiAbsPath = H5AI_ABS_PATH;
$this->docRoot = $H5AI_CONFIG["DOCUMENT_ROOT"]; global $H5AI_CONFIG;
$this->h5aiRoot = $H5AI_CONFIG["H5AI_ROOT"]; $this->rootAbsPath = $H5AI_CONFIG["ROOT_ABS_PATH"];
$this->ignore = $H5AI_CONFIG["IGNORE"]; $this->ignore = $H5AI_CONFIG["IGNORE"];
$this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"]; $this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"];
$this->config = $this->loadConfig($this->h5aiRoot . "/config.js"); $this->config = $this->loadConfig($this->h5aiAbsPath . "/config.js");
$this->options = $this->config["options"]; $this->options = $this->config["options"];
$this->types = $this->config["types"]; $this->types = $this->config["types"];
$this->langs = $this->config["langs"]; $this->langs = $this->config["langs"];
$this->cache = new Cache($this->h5aiRoot . "/cache"); $this->cache = new Cache($this->h5aiAbsPath . "/cache");
$this->hrefRoot = $this->options["rootAbsHref"]; $this->rootAbsHref = $this->options["rootAbsHref"];
$this->h5aiAbsHref = $this->options["h5aiAbsHref"]; $this->h5aiAbsHref = $this->options["h5aiAbsHref"];
$this->domain = getenv("HTTP_HOST"); $this->domain = getenv("HTTP_HOST");
@@ -56,101 +60,120 @@ class H5ai {
} }
public function getDocRoot() { public function getH5aiAbsPath() {
return $this->docRoot; return $this->h5aiAbsPath;
} }
public function getH5aiRoot() {
return $this->h5aiRoot; public function getRootAbsPath() {
return $this->rootAbsPath;
} }
public function getHrefRoot() {
return $this->hrefRoot; public function getRootAbsHref() {
return $this->rootAbsHref;
} }
public function getH5aiAbsHref() { public function getH5aiAbsHref() {
return $this->h5aiAbsHref; return $this->h5aiAbsHref;
} }
public function getDomain() { public function getDomain() {
return $this->domain; return $this->domain;
} }
public function getView() { public function getView() {
return $this->view; return $this->view;
} }
public function api() { public function api() {
return $this->h5aiAbsHref . "php/api.php"; return $this->h5aiAbsHref . "php/api.php";
} }
public function image($id) { public function image($id) {
return $this->h5aiAbsHref . "images/" . $id . ".png"; return $this->h5aiAbsHref . "images/" . $id . ".png";
} }
public function icon($id, $big = false) { public function icon($id, $big = false) {
return $this->h5aiAbsHref . "icons/" . ($big ? "48x48" : "16x16") . "/" . $id . ".png"; return $this->h5aiAbsHref . "icons/" . ($big ? "48x48" : "16x16") . "/" . $id . ".png";
} }
public function getOptions() { public function getOptions() {
return $this->options; return $this->options;
} }
public function getLangs() { public function getLangs() {
return $this->langs; return $this->langs;
} }
public function normalizePath($path, $endWithSlash) {
return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
}
public function getAbsHref($absPath = null, $endWithSlash = true) { public function getAbsHref($absPath = null, $endWithSlash = true) {
if ($absPath === null) { if ($absPath === null) {
return $this->absHref; return $this->absHref;
} }
// $absPath = substr($absPath, strlen($this->rootAbsPath));
$absPath=substr($absPath, strlen($this->docRoot));
$absHref = preg_replace("!^" . $this->docRoot . "!", "", $absPath); $parts = explode("/", $absPath);
$parts = explode("/", $absHref);
$encodedParts = array(); $encodedParts = array();
foreach ($parts as $part) { foreach ($parts as $part) {
$encodedParts[] = rawurlencode($part); $encodedParts[] = rawurlencode($part);
} }
$endodedAbsHref = implode("/", $encodedParts);
// return $this->normalizePath($this->rootAbsHref . implode("/", $encodedParts), $endWithSlash);
$endodedAbsHref = $this->hrefRoot . $endodedAbsHref;
return $this->normalizePath($endodedAbsHref, $endWithSlash);
} }
public function getAbsPath($absHref = null) { public function getAbsPath($absHref = null) {
if ($absHref === null) { if ($absHref === null) {
return $this->absPath; return $this->absPath;
} }
// $absHref = substr($absHref, strlen($this->rootAbsHref));
$absHref=substr($absHref, strlen($this->hrefRoot));
return $this->normalizePath($this->docRoot . "/" . rawurldecode($absHref), false); return $this->normalizePath($this->rootAbsPath . "/" . rawurldecode($absHref), false);
} }
public function showThumbs() { public function showThumbs() {
return $this->options["showThumbs"] === true; return $this->options["showThumbs"] === true;
} }
public function getThumbTypes() {
return $this->options["thumbTypes"];
}
public function getTitle() { public function getTitle() {
$title = $this->domain . rawurldecode($this->absHref); $title = $this->domain . rawurldecode($this->absHref);
@@ -162,6 +185,7 @@ class H5ai {
return $title; return $title;
} }
public function getType($absPath) { public function getType($absPath) {
foreach($this->types as $type => $exts) { foreach($this->types as $type => $exts) {
@@ -174,9 +198,10 @@ class H5ai {
return "unknown"; return "unknown";
} }
public function ignoreThisFile($file) { public function ignoreThisFile($file) {
# always ignore // always ignore
if ($file === "." || $file === ".." || $this->startsWith($file, '.ht')) { if ($file === "." || $file === ".." || $this->startsWith($file, '.ht')) {
return true; return true;
} }
@@ -193,6 +218,7 @@ class H5ai {
return false; return false;
} }
public function readDir($path) { public function readDir($path) {
$content = array(); $content = array();
@@ -209,33 +235,32 @@ class H5ai {
return $content; return $content;
} }
public function getLabel($absHref) { public function getLabel($absHref) {
return $absHref === "/" ? $this->domain : rawurldecode(basename($absHref)); return $absHref === "/" ? $this->domain : rawurldecode(basename($absHref));
} }
public function normalizePath($path, $endWithSlash) {
return ($path === "/") ? "/" : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
}
public function startsWith($sequence, $start) { public function startsWith($sequence, $start) {
return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0; return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0;
} }
public function endsWith($sequence, $end) { public function endsWith($sequence, $end) {
return strcasecmp(substr($sequence, -strlen($end)), $end) === 0; return strcasecmp(substr($sequence, -strlen($end)), $end) === 0;
} }
public function getHttpCode($absHref) { public function getHttpCode($absHref) {
return $this->cachedHttpCode($absHref); //return $this->cachedHttpCode($absHref);
#return $this->fetchHttpCode($absHref); return $this->fetchHttpCode($absHref);
#return $this->guessHttpCode($absHref);
} }
public function cachedHttpCode($absHref) { public function cachedHttpCode($absHref) {
$cached = $this->cache->get($absHref); $cached = $this->cache->get($absHref);
@@ -252,6 +277,7 @@ class H5ai {
return $cached["code"]; return $cached["code"];
} }
public function fetchHttpCode($absHref) { public function fetchHttpCode($absHref) {
$contentType = "Content-Type:"; $contentType = "Content-Type:";
@@ -285,19 +311,6 @@ class H5ai {
fclose($socket); fclose($socket);
return $code; 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";
}
} }
?> ?>

View File

@@ -2,13 +2,7 @@
class Image { class Image {
private $sourceFile; private $sourceFile, $source, $width, $height, $type, $dest;
private $source;
private $width;
private $height;
private $type;
private $dest;
public static function isUsable() { public static function isUsable() {
@@ -84,7 +78,7 @@ class Image {
public function releaseDest() { public function releaseDest() {
if (!is_null($this->dest)) { if (!is_null($this->dest)) {
imagedestroy($this->dest); @imagedestroy($this->dest);
$this->dest = null; $this->dest = null;
} }
} }
@@ -93,7 +87,7 @@ class Image {
public function releaseSource() { public function releaseSource() {
if (!is_null($this->source)) { if (!is_null($this->source)) {
imagedestroy($this->source); @imagedestroy($this->source);
$this->sourceFile = null; $this->sourceFile = null;
$this->source = null; $this->source = null;
$this->width = null; $this->width = null;

View File

@@ -1,31 +1,34 @@
<?php <?php
require_once "Image.php"; require_h5ai("/php/inc/Image.php");
class Thumbnail { class Thumbnail {
private $srcAbsHref, $srcAbsPath, $width, $height, $name, $href, $path; private $srcAbsHref, $srcAbsPath, $width, $height, $name, $href, $path;
public static function isUsable() { public static function isUsable() {
return Image::isUsable(); return Image::isUsable();
} }
public function __construct($h5ai, $absHref, $mode, $width, $height) { public function __construct($h5ai, $absHref, $mode, $width, $height) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
$this->srcAbsHref = $absHref; $this->srcAbsHref = $absHref;
$this->srcAbsPath = $this->h5ai->getDocRoot() . urldecode($absHref); $this->srcAbsPath = $this->h5ai->getRootAbsPath() . urldecode($absHref);
$this->width = $width; $this->width = $width;
$this->height = $height; $this->height = $height;
$this->mode = $mode; $this->mode = $mode;
$this->name = sha1("$this->srcAbsPath-$this->width-$this->height-$this->mode"); $this->name = sha1("$this->srcAbsPath-$this->width-$this->height-$this->mode");
$this->href = $this->h5ai->getH5aiAbsHref() . "/cache/thumb-" . $this->name . ".jpg"; $this->href = $this->h5ai->getH5aiAbsHref() . "cache/thumb-" . $this->name . ".jpg";
$this->path = $this->h5ai->getDocRoot() . $this->href; $this->path = $this->h5ai->getRootAbsPath() . $this->href;
$this->liveHref = $this->h5ai->api() . "?action=thumb&href=" . $this->srcAbsHref . "&width=" . $this->width . "&height=" . $this->height . "&mode=" . $this->mode; $this->liveHref = $this->h5ai->api() . "?action=thumb&href=" . $this->srcAbsHref . "&width=" . $this->width . "&height=" . $this->height . "&mode=" . $this->mode;
} }
public function create($force = 0) { public function create($force = 0) {
if ( if (
@@ -40,16 +43,19 @@ class Thumbnail {
} }
} }
public function getHref() { public function getHref() {
return $this->href; return $this->href;
} }
public function getPath() { public function getPath() {
return $this->path; return $this->path;
} }
public function getLiveHref() { public function getLiveHref() {
return $this->liveHref; return $this->liveHref;

View File

@@ -1,8 +1,10 @@
<?php <?php
class TreeEntry { class TreeEntry {
private $h5ai, $label, $absPath, $absHref, $isFolder, $type, $content; private $h5ai, $label, $absPath, $absHref, $isFolder, $type, $content;
public function __construct($h5ai, $absPath, $absHref, $type = null) { public function __construct($h5ai, $absPath, $absHref, $type = null) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
@@ -16,6 +18,7 @@ class TreeEntry {
$this->content = null; $this->content = null;
} }
public function loadContent() { public function loadContent() {
$this->content = array(); $this->content = array();
@@ -36,6 +39,7 @@ class TreeEntry {
$this->sort(); $this->sort();
} }
public function cmpTrees($t1, $t2) { public function cmpTrees($t1, $t2) {
if ($t1->isFolder && !$t2->isFolder) { if ($t1->isFolder && !$t2->isFolder) {
@@ -47,6 +51,7 @@ class TreeEntry {
return strcasecmp($t1->absPath, $t2->absPath); return strcasecmp($t1->absPath, $t2->absPath);
} }
public function sort() { public function sort() {
if ($this->content !== null) { if ($this->content !== null) {
@@ -54,6 +59,7 @@ class TreeEntry {
} }
} }
public function toHtml() { public function toHtml() {
$classes = "entry " . $this->type . ($this->absHref === $this->h5ai->getAbsHref() ? " current" : ""); $classes = "entry " . $this->type . ($this->absHref === $this->h5ai->getAbsHref() ? " current" : "");
@@ -86,7 +92,7 @@ class TreeEntry {
$html .= "<span class='indicator" . $indicatorState . "'><img src='" . $this->h5ai->image("tree") . "' alt='>' /></span>\n"; $html .= "<span class='indicator" . $indicatorState . "'><img src='" . $this->h5ai->image("tree") . "' alt='>' /></span>\n";
} }
$html .= "<a href='" . $this->absHref . "'>\n"; $html .= "<a href='" . $this->absHref . "'>\n";
$html .= "<span class='icon'><img src='" . $this->h5ai->icon($icon) . "' alt='" . $icon . "' /></span>\n"; $html .= "<span class='icon'><img src='" . $this->h5ai->icon($icon) . "' alt='" . $icon . "' /></span>";
$html .= "<span class='label'>" . $this->label . "</span>" . $hint . "\n"; $html .= "<span class='label'>" . $this->label . "</span>" . $hint . "\n";
$html .= "</a>\n"; $html .= "</a>\n";
$html .= $this->contentToHtml(); $html .= $this->contentToHtml();
@@ -94,6 +100,7 @@ class TreeEntry {
return $html; return $html;
} }
public function contentToHtml() { public function contentToHtml() {
$html = "<ul class='content'>\n"; $html = "<ul class='content'>\n";
@@ -106,13 +113,14 @@ class TreeEntry {
return $html; return $html;
} }
public function getRoot() { public function getRoot() {
if ($this->absHref === "/") { if ($this->absHref === "/") {
return $this; return $this;
}; };
$tree = new TreeEntry($this->h5ai, dirname($this->absPath), dirname($this->absHref)); $tree = new TreeEntry($this->h5ai, safe_dirname($this->absPath), safe_dirname($this->absHref, true));
$tree->loadContent(); $tree->loadContent();
$tree->content[$this->absPath] = $this; $tree->content[$this->absPath] = $this;
@@ -122,13 +130,16 @@ class TreeEntry {
class Tree { class Tree {
private $h5ai; private $h5ai;
public function __construct($h5ai) { public function __construct($h5ai) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
} }
public function toHtml() { public function toHtml() {
$options = $this->h5ai->getOptions(); $options = $this->h5ai->getOptions();

View File

@@ -1,30 +1,42 @@
<?php <?php
class ZipIt { class ZipIt {
private $h5ai; private $h5ai;
public function __construct($h5ai) { public function __construct($h5ai) {
$this->h5ai = $h5ai; $this->h5ai = $h5ai;
} }
public function zip($hrefs) { public function zip($hrefs) {
$zipFile = tempnam("/tmp", "h5ai-download"); $zipFile = tempnam(sys_get_temp_dir(), "h5ai-zip-");
$zip = new ZipArchive(); $zip = new ZipArchive();
if (!$zip->open($zipFile, ZIPARCHIVE::CREATE)) { if (!$zip->open($zipFile, ZIPARCHIVE::CREATE)) {
return false; return null;
} }
$zip->addEmptyDir("/");
foreach ($hrefs as $href) { foreach ($hrefs as $href) {
$d = dirname($href); $d = safe_dirname($href, true);
$n = basename($href); $n = basename($href);
if ($this->h5ai->getHttpCode($this->h5ai->getAbsHref($d)) === "h5ai" && !$this->h5ai->ignoreThisFile($n)) { $code = $this->h5ai->getHttpCode($d);
if ($code == 401) {
return $code;
}
if ($code == "h5ai" && !$this->h5ai->ignoreThisFile($n)) {
$localFile = $this->h5ai->getAbsPath($href); $localFile = $this->h5ai->getAbsPath($href);
$file = preg_replace("!^" . $this->h5ai->getDocRoot() . "!", "", $localFile); $file = preg_replace("!^" . $this->h5ai->getRootAbsPath() . "!", "", $localFile);
if (is_dir($localFile)) { if (is_dir($localFile)) {
$this->zipDir($zip, $localFile, $file); $rcode = $this->zipDir($zip, $localFile, $file);
if ($rcode == 401) {
return $rcode;
}
} else { } else {
$this->zipFile($zip, $localFile, $file); $this->zipFile($zip, $localFile, $file);
} }
@@ -32,9 +44,10 @@ class ZipIt {
} }
$zip->close(); $zip->close();
return $zipFile; return filesize($zipFile) ? $zipFile : null;
} }
private function zipFile($zip, $localFile, $file) { private function zipFile($zip, $localFile, $file) {
if (is_readable($localFile)) { if (is_readable($localFile)) {
@@ -42,21 +55,28 @@ class ZipIt {
} }
} }
private function zipDir($zip, $localDir, $dir) { private function zipDir($zip, $localDir, $dir) {
if ($this->h5ai->getHttpCode($this->h5ai->getAbsHref($localDir)) === "h5ai") { $code = $this->h5ai->getHttpCode($this->h5ai->getAbsHref($localDir));
if ($code == 'h5ai') {
$zip->addEmptyDir($dir); $zip->addEmptyDir($dir);
$files = $this->h5ai->readDir($localDir); $files = $this->h5ai->readDir($localDir);
foreach ($files as $file) { foreach ($files as $file) {
$localFile = $localDir . "/" . $file; $localFile = $localDir . "/" . $file;
$file = $dir . "/" . $file; $file = $dir . "/" . $file;
if (is_dir($localFile)) { if (is_dir($localFile)) {
$this->zipDir($zip, $localFile, $file); $rcode = $this->zipDir($zip, $localFile, $file);
if ($rcode == 401) {
return $rcode;
}
} else { } else {
$this->zipFile($zip, $localFile, $file); $this->zipFile($zip, $localFile, $file);
} }
} }
} }
return code;
} }
} }

View File

@@ -1,11 +1,23 @@
<?php <?php
require_once "config.php"; function safe_dirname($path, $endWithSlash = false) {
require_once "inc/H5ai.php";
require_once "inc/Crumb.php"; $path = str_replace("\\", "/", dirname($path));
require_once "inc/Customize.php"; return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
require_once "inc/Extended.php"; }
require_once "inc/Tree.php";
define("H5AI_ABS_PATH", safe_dirname(safe_dirname(__FILE__)));
function require_h5ai($lib) {
require_once(H5AI_ABS_PATH . $lib);
}
require_h5ai("/php/inc/H5ai.php");
require_h5ai("/php/inc/Crumb.php");
require_h5ai("/php/inc/Customize.php");
require_h5ai("/php/inc/Extended.php");
require_h5ai("/php/inc/Tree.php");
$h5ai = new H5ai(); $h5ai = new H5ai();
$crumb = new Crumb($h5ai); $crumb = new Crumb($h5ai);

View File

@@ -8,11 +8,11 @@
# pure JavaScript version # pure JavaScript version
HeaderName /_h5ai/header.html HeaderName /_h5ai/header.html
ReadmeName /_h5ai/footer.html
# PHP version # PHP version
# HeaderName /_h5ai/header.php # HeaderName /_h5ai/header.php
# ReadmeName /_h5ai/footer.php
ReadmeName /_h5ai/footer.html
IndexIgnore _h5ai* IndexIgnore _h5ai*

View File

@@ -1,4 +0,0 @@
#! /usr/bin/env node
// -*- js -*-
require("wepp").processArgs(process.argv);

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<project name="wepp.macros" basedir=".">
<macrodef name="wepp">
<attribute name="file" />
<attribute name="toFile" />
<attribute name="args" default="" />
<sequential>
<exec executable="${tool.wepp}">
<arg line="@{args}" />
<arg value="--in" />
<arg value="@{file}" />
<arg value="--out" />
<arg value="@{toFile}" />
</exec>
</sequential>
</macrodef>
<macrodef name="wepp.dir">
<attribute name="dir" />
<attribute name="args" default="" />
<sequential>
<exec executable="${tool.wepp}">
<arg line="@{args}" />
<arg value="--inDir" />
<arg value="@{dir}" />
<arg value="--outDir" />
<arg value="@{dir}" />
</exec>
<delete dir="@{dir}/inc">
<fileset
dir="."
includes="@{dir}/**/*.less"
excludes="@{dir}/inc/**,@{dir}/lib/**"
/>
</delete>
</sequential>
</macrodef>
</project>