1
0
mirror of https://github.com/lrsjng/h5ai.git synced 2025-09-05 19:52:59 +02:00

Compare commits

..

38 Commits
v0.17 ... v0.18

Author SHA1 Message Date
Lars Jung
796fc75533 Merge branch 'develop' 2012-02-24 17:02:46 +01:00
Lars Jung
cc13005a1d Prepares release. 2012-02-24 16:52:31 +01:00
Lars Jung
cdb0f9035d Minor changes. 2012-02-24 16:37:37 +01:00
Lars Jung
041c172a55 Adds support for zipped download of htaccess restricted files. 2012-02-24 16:31:47 +01:00
Lars Jung
08cc2834df Adds en- and decoding for URL hashes. 2012-02-24 00:01:43 +01:00
Lars Jung
997f1cd80f Improves URL hashs. 2012-02-23 22:41:17 +01:00
Lars Jung
7c1feaebc0 Changes download button style while zipping. 2012-02-23 12:38:11 +01:00
Lars Jung
f1175f5149 More design changes. 2012-02-22 23:47:05 +01:00
Lars Jung
556d206ab8 Hide filter input field if no filter is set. 2012-02-22 13:18:46 +01:00
Lars Jung
bfebcb3bcd Changes design. 2012-02-22 11:38:53 +01:00
Lars Jung
32023fc86e Updates readme. 2012-02-22 07:22:04 +01:00
Lars Jung
78dc01d5b3 Merge pull request #38 from medicalwei/develop
Add translation to zh-tw, and fix translation on zh-cn.
2012-02-21 22:16:50 -08:00
Yao Wei (魏銘廷)
4e90a41614 added zh-tw translation. fix zh-cn translation. 2012-02-22 13:24:49 +08:00
Lars Jung
1b0c9d81ac Adds animated loading gif. 2012-02-21 21:29:47 +01:00
Lars Jung
84f543aca5 Filter accepts RegExp and primitive search sequences. 2012-02-21 01:59:19 +01:00
Lars Jung
749a87eaf7 Reduces number of HTTP requests. 2012-02-20 16:35:48 +01:00
Lars Jung
6901044518 Small js fixes. 2012-02-20 15:08:29 +01:00
Lars Jung
b39fbb8dc0 Removes console.log lines. 2012-02-20 03:12:12 +01:00
Lars Jung
d7b3bd79f8 Fixes build process. 2012-02-20 03:06:01 +01:00
Lars Jung
c8d079b826 Updates readme. 2012-02-20 02:47:00 +01:00
Lars Jung
8ee901517b Removes some redundancy. 2012-02-20 02:46:02 +01:00
Lars Jung
6bfbdb4d05 Adds optional QRCodes and filtering for displayed files. 2012-02-19 22:29:42 +01:00
Lars Jung
bc6e9fb150 Improves zipped download. 2012-02-17 23:21:13 +01:00
Lars Jung
f51a0b80a7 Js version uses settings.thumbTypes too. 2012-02-17 13:47:09 +01:00
Lars Jung
d56d0716cb Fixes problems with thumbnails for filenames with single and double quotes. 2012-02-17 11:28:08 +01:00
Lars Jung
42d3dfe80e Updates readme. 2012-02-17 03:25:57 +01:00
Lars Jung
1a8ef62188 Fixes broken links in custom headers/footers. Updates default options. 2012-02-17 03:23:42 +01:00
Lars Jung
ecf91b506e Disallows indexing the _h5ai folder by default. 2012-02-17 01:21:43 +01:00
Lars Jung
ca4d3ae315 Adds classes to <html> to distinguish h5ai versions. 2012-02-17 01:18:57 +01:00
Lars Jung
ba12154566 Updates build process. 2012-02-16 00:55:13 +01:00
Lars Jung
ba3e61c1d0 Moves thumbTypes to config.js. 2012-02-16 00:34:55 +01:00
Lars Jung
9f10e92175 Fixes include problems as well as Win path problems. 2012-02-15 18:41:13 +01:00
Lars Jung
d72ea22fb0 Small fix on initial tree view display. 2012-02-14 13:16:28 +01:00
Lars Jung
76f107cbfe Fixes problems with folder recognition in the JS version. 2012-02-13 00:11:19 +01:00
Lars Jung
cbdd185602 Makes custom headers/footers optional. Disabled by default. 2012-02-12 23:56:19 +01:00
Lars Jung
20858a1f43 Switches indentation to tabs. 2012-02-12 22:35:38 +01:00
Lars Jung
231ba3013b Updates es translation. 2012-02-12 21:59:17 +01:00
Lars Jung
47b6260186 Prepares for 0.18. 2012-02-12 02:40:14 +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

162
build.xml
View File

@@ -1,78 +1,116 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<project <project
name="h5ai" name="h5ai"
basedir="." basedir="."
default="release" default="release"
> >
<import file="tools/wepp.ant.xml" /> <target name="init">
<property file="build.properties" />
<tstamp>
<format property="build.stamp" pattern="yyyy-MM-dd-HHmmss" />
</tstamp>
<property name="build.label" value="${project.name} ${project.version} b${build.stamp}" />
<echo>Build: ${build.label}</echo>
</target>
<target name="init"> <target name="clean" depends="init">
<property file="build.properties" /> <delete dir="${build.dir}" />
<tstamp> <delete dir="${release.dir}" />
<format property="build.stamp" pattern="yyyy-MM-dd-HHmmss" /> </target>
</tstamp>
<property name="build.label" value="${project.name} ${project.version} b${build.stamp}" />
<echo>Build: ${build.label}</echo>
</target>
<target name="clean" depends="init"> <target name="build-prepare" depends="clean">
<delete dir="${build.dir}" /> <mkdir dir="${build.dir}" />
<delete dir="${release.dir}" /> <copy todir="${build.dir}">
</target> <fileset dir="${src.dir}" />
<fileset file="LICENSE.txt" />
<fileset file="README.md" />
</copy>
<replace dir="${build.dir}">
<replacefilter token="%BUILD%" value="${build.label}" />
<replacefilter token="%BUILD_NAME%" value="${project.name}" />
<replacefilter token="%BUILD_VERSION%" value="${project.version}" />
<replacefilter token="%BUILD_STAMP%" value="${build.stamp}" />
</replace>
</target>
<target name="build-prepare" depends="clean"> <target name="build" depends="build-prepare">
<mkdir dir="${build.dir}" /> <wepp-dir-min dir="${build.dir}/_h5ai/css" todir="${build.dir}/_h5ai/css" />
<copy todir="${build.dir}"> <wepp-dir-min dir="${build.dir}/_h5ai/js" todir="${build.dir}/_h5ai/js" />
<fileset dir="${src.dir}" /> </target>
<fileset file="LICENSE.txt" />
<fileset file="README.md" />
</copy>
<replace dir="${build.dir}">
<replacefilter token="%BUILD%" value="${build.label}" />
<replacefilter token="%BUILD_NAME%" value="${project.name}" />
<replacefilter token="%BUILD_VERSION%" value="${project.version}" />
<replacefilter token="%BUILD_STAMP%" value="${build.stamp}" />
</replace>
</target>
<target name="build" depends="build-prepare"> <target name="build-uncompressed" depends="build-prepare">
<wepp.dir dir="${build.dir}/_h5ai/css" /> <wepp-dir dir="${build.dir}/_h5ai/css" todir="${build.dir}/_h5ai/css" />
<wepp.dir dir="${build.dir}/_h5ai/js" /> <wepp-dir dir="${build.dir}/_h5ai/js" todir="${build.dir}/_h5ai/js" />
</target> </target>
<target name="build-uncompressed" depends="build-prepare"> <target name="release" depends="build">
<wepp.dir dir="${build.dir}/_h5ai/css" args="--nc" /> <mkdir dir="${release.dir}" />
<wepp.dir dir="${build.dir}/_h5ai/js" args="--nc" /> <zip destfile="${release.dir}/${project.name}-${project.version}.zip" basedir="${build.dir}" />
</target> </target>
<target name="release" depends="build"> <target name="lint" depends="build-prepare">
<mkdir dir="${release.dir}" /> <wepp file="${build.dir}/_h5ai/js/inc/main.js" tofile="${build.dir}/_h5ai/js/inc/main.js" />
<zip destfile="${release.dir}/${project.name}-${project.version}.zip" basedir="${build.dir}" /> <jslint files="${build.dir}/_h5ai/js/inc/main.js" />
<tar destfile="${release.dir}/${project.name}-${project.version}.tar" basedir="${build.dir}"/> </target>
<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 name="pre-xint" depends="build-prepare">
<wepp file="${tool.jsxint.file}" tofile="${tool.jsxint.file}" args="--nc" />
</target>
<target name="lint" depends="pre-xint"> <macrodef name="wepp-args">
<echo>JSLint "${tool.jsxint.file}"</echo> <attribute name="args" default="" />
<exec executable="${tool.jslint}" failonerror="true"> <sequential>
<arg value="${tool.jsxint.file}" /> <exec executable="${tool.wepp}" failonerror="true">
</exec> <arg line="@{args}" />
</target> </exec>
</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>
</exec> <wepp-args args="--nc --inFile '@{file}' --outFile '@{toFile}'" />
</target> </sequential>
</macrodef>
<target name="xint" depends="lint,hint"> <macrodef name="wepp-min">
</target> <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>
</sequential>
</macrodef>
</project> </project>

View File

@@ -1,5 +1,7 @@
Options -Indexes
AddType text/html .php AddType text/html .php
@@ -19,17 +21,17 @@ AddType text/html .php
# cache images, css and js for 52 weeks # cache images, css and js for 52 weeks
<IfModule headers_module> <IfModule headers_module>
<FilesMatch "\.png$"> <FilesMatch "\.png$">
Header set Cache-Control "max-age=31449600, public" Header set Cache-Control "max-age=31449600, public"
</FilesMatch> </FilesMatch>
<FilesMatch "\.css$"> <FilesMatch "\.css$">
Header set Cache-Control "max-age=31449600, public" Header set Cache-Control "max-age=31449600, public"
</FilesMatch> </FilesMatch>
<FilesMatch "\.js$"> <FilesMatch "\.js$">
Header set Cache-Control "max-age=31449600, public" Header set Cache-Control "max-age=31449600, public"
</FilesMatch> </FilesMatch>
<FilesMatch "thumb-.*\.jpg$"> <FilesMatch "thumb-.*\.jpg$">
Header set Cache-Control "max-age=31449600, public" Header set Cache-Control "max-age=31449600, public"
</FilesMatch> </FilesMatch>
</IfModule> </IfModule>

View File

@@ -7,405 +7,455 @@
var H5AI_CONFIG = { var H5AI_CONFIG = {
"options": { "options": {
/* /*
* The absolute links to webroot and h5ai. * The absolute links to webroot and h5ai.
* Do not change this unless you know what you are doing. * Do not change this unless you know what you are doing.
*/ */
"rootAbsHref": "/", "rootAbsHref": "/",
"h5aiAbsHref": "/_h5ai/", "h5aiAbsHref": "/_h5ai/",
/* /*
* 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", * "customHeader": "_h5ai.header.html",
"customFooter": "_h5ai.footer.html", * "customFooter": "_h5ai.footer.html",
*
* This is disabled by default.
*/
"customHeader": null,
"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
* are two possible values: "details" and "icons". The first value * are two possible values: "details" and "icons". The first value
* indicates the default view mode. If only one value is given the * indicates the default view mode. If only one value is given the
* view mode is fixed and the selector buttons are hidden. * view mode is fixed and the selector buttons are hidden.
* The user selected view mode is also stored local in modern browsers * The user selected view mode is also stored local in modern browsers
* so that it will be persistent. * so that it will be persistent.
*/ */
"viewmodes": ["details", "icons"], "viewmodes": ["details", "icons"],
/* /*
* Default sort order is a two letter code. The first letter specifies * Default sort order is a two letter code. The first letter specifies
* the column: "n" for "Name", "d" for "Date" or "s" for "Size". The * the column: "n" for "Name", "d" for "Date" or "s" for "Size". The
* second letter specifies the sort order: "a" for "ascending" or "d" * second letter specifies the sort order: "a" for "ascending" or "d"
* for "descending". * for "descending".
*/ */
"sortorder": "na", "sortorder": "na",
/* /*
* Show a folder tree, boolean. * Show a folder tree, boolean.
* Note that this tree might have side effects as it sends HEAD requests * Note that this tree might have side effects as it sends HEAD requests
* to the folders, and therefore will invoke index.php scripts. Use * to the folders, and therefore will invoke index.php scripts. Use
* folderStatus below to avoid such requests. * folderStatus below to avoid such requests.
* It might also affect performance significantly. * It might also affect performance significantly.
*/ */
"showTree": true, "showTree": true,
/* /*
* Slide tree bar into viewport if there is enough space, boolean. * Slide tree bar into viewport if there is enough space, boolean.
*/ */
"slideTree": true, "slideTree": true,
/* /*
* Associative array of folders and their HTTP status codes to * Associative array of folders and their HTTP status codes to
* avoid HEAD requests to that folders. The key (folder) must start * avoid HEAD requests to that folders. The key (folder) must start
* and end with a slash (/). * and end with a slash (/).
* For example: * For example:
* "/some/folder/": 200 * "/some/folder/": 200
* will always return HTTP status 200 (OK), which will be interpreted * will always return HTTP status 200 (OK), which will be interpreted
* as a non auto indexed folder, that means a folder containing an * as a non auto indexed folder, that means a folder containing an
* appropriate default index file. * appropriate default index file.
*/ */
"folderStatus": {}, "folderStatus": {},
/* /*
* Localization, for example "en", "de" etc. - see h5aiLangs below for * Localization, for example "en", "de" etc. - see h5aiLangs below for
* possible values. Adjust it to your needs. If lang is not found in * possible values. Adjust it to your needs. If lang is not found in
* h5aiLangs it defaults to "en". * h5aiLangs it defaults to "en".
*/ */
"lang": "en", "lang": "en",
/* /*
* Try to use browser language, falls back to previous specified lang. * Try to use browser language, falls back to previous specified lang.
*/ */
"useBrowserLang": true, "useBrowserLang": true,
/* /*
* Set parent folder labels to real folder names. * Set parent folder labels to real folder names.
*/ */
"setParentFolderLabels": true, "setParentFolderLabels": true,
/* /*
* Link the hover effects between crumb, extended view and tree. * Link the hover effects between crumb, extended view and tree.
*/ */
"linkHoverStates": true, "linkHoverStates": true,
/* /*
* Date format in detailed view, for example: "yyyy-MM-dd HH:mm:ss" * Date format in detailed view, for example: "yyyy-MM-dd HH:mm:ss"
* Syntax as specified by date.js * Syntax as specified by date.js
* http://code.google.com/p/datejs/wiki/FormatSpecifiers * http://code.google.com/p/datejs/wiki/FormatSpecifiers
*/ */
"dateFormat": "yyyy-MM-dd HH:mm", "dateFormat": "yyyy-MM-dd HH:mm",
/* /*
* Requires PHP on the server. * Requires PHP on the server.
* Show thumbnails for image files. * Show thumbnails for image files.
*/ */
"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
},
/* /*
* File types mapped to file extensions. * File types mapped to file extensions.
*/ */
"types": { "types": {
"archive": [".tar.bz2", ".tar.gz", ".tgz"], "archive": [".tar.bz2", ".tar.gz", ".tgz"],
"audio": [".aif", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"], "audio": [".aif", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
"authors": ["authors"], "authors": ["authors"],
"bin": [".class", ".o", ".so"], "bin": [".class", ".o", ".so"],
"blank": [], "blank": [],
"bmp": [".bmp"], "bmp": [".bmp"],
"c": [".c"], "c": [".c"],
"calc": [".ods", ".ots", ".xlr", ".xls", ".xlsx"], "calc": [".ods", ".ots", ".xlr", ".xls", ".xlsx"],
"cd": [".cue", ".iso"], "cd": [".cue", ".iso"],
"copying": ["copying", "license"], "copying": ["copying", "license"],
"cpp": [".cpp"], "cpp": [".cpp"],
"css": [".css", ".less"], "css": [".css", ".less"],
"deb": [".deb"], "deb": [".deb"],
"default": [], "default": [],
"doc": [".doc", ".docx", ".odm", ".odt", ".ott"], "doc": [".doc", ".docx", ".odm", ".odt", ".ott"],
"draw": [".drw"], "draw": [".drw"],
"eps": [".eps"], "eps": [".eps"],
"exe": [".exe"], "exe": [".exe"],
"folder": [], "folder": [],
"folder-home": [], "folder-home": [],
"folder-open": [], "folder-open": [],
"folder-page": [], "folder-page": [],
"folder-parent": [], "folder-parent": [],
"gif": [".gif"], "gif": [".gif"],
"gzip": [".gz"], "gzip": [".gz"],
"h": [".h"], "h": [".h"],
"hpp": [".hpp"], "hpp": [".hpp"],
"html": [".htm", ".html", ".shtml"], "html": [".htm", ".html", ".shtml"],
"ico": [".ico"], "ico": [".ico"],
"image": [".xpm"], "image": [".xpm"],
"install": ["install"], "install": ["install"],
"java": [".java"], "java": [".java"],
"jpg": [".jpg", ".jpeg"], "jpg": [".jpg", ".jpeg"],
"js": [".js", ".json"], "js": [".js", ".json"],
"log": [".log", "changelog"], "log": [".log", "changelog"],
"makefile": [".pom", "build.xml", "pom.xml"], "makefile": [".pom", "build.xml", "pom.xml"],
"package": [], "package": [],
"pdf": [".pdf"], "pdf": [".pdf"],
"php": [".php"], "php": [".php"],
"playlist": [".m3u"], "playlist": [".m3u"],
"png": [".png"], "png": [".png"],
"pres": [".odp", ".otp", ".pps", ".ppt", ".pptx"], "pres": [".odp", ".otp", ".pps", ".ppt", ".pptx"],
"psd": [".psd"], "psd": [".psd"],
"py": [".py"], "py": [".py"],
"rar": [".rar"], "rar": [".rar"],
"rb": [".rb"], "rb": [".rb"],
"readme": ["readme"], "readme": ["readme"],
"rpm": [".rpm"], "rpm": [".rpm"],
"rss": [".rss"], "rss": [".rss"],
"rtf": [".rtf"], "rtf": [".rtf"],
"script": [".conf", ".csh", ".ini", ".ksh", ".sh", ".shar", ".tcl"], "script": [".conf", ".csh", ".ini", ".ksh", ".sh", ".shar", ".tcl"],
"source": [], "source": [],
"sql": [], "sql": [],
"tar": [".tar"], "tar": [".tar"],
"tex": [".tex"], "tex": [".tex"],
"text": [".markdown", ".md", ".text", ".txt"], "text": [".markdown", ".md", ".text", ".txt"],
"tiff": [".tiff"], "tiff": [".tiff"],
"unknown": [], "unknown": [],
"vcal": [".vcal"], "vcal": [".vcal"],
"video": [".avi", ".flv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"], "video": [".avi", ".flv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"],
"xml": [".xml"], "xml": [".xml"],
"zip": [".bz2", ".jar", ".war", ".z", ".Z", ".zip"] "zip": [".bz2", ".jar", ".war", ".z", ".Z", ".zip"]
}, },
/* /*
* Available translations. * Available translations.
*/ */
"langs": { "langs": {
"en": { "en": {
"lang": "english", "lang": "english",
"details": "details", "details": "details",
"icons": "icons", "icons": "icons",
"name": "Name", "name": "Name",
"lastModified": "Last modified", "lastModified": "Last modified",
"size": "Size", "size": "Size",
"parentDirectory": "Parent Directory", "parentDirectory": "Parent Directory",
"empty": "empty", "empty": "empty",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"bg": { "bg": {
"lang": "български", "lang": "български",
"details": "детайли", "details": "детайли",
"icons": "икони", "icons": "икони",
"name": "Име", "name": "Име",
"lastModified": "Последна промяна", "lastModified": "Последна промяна",
"size": "Размер", "size": "Размер",
"parentDirectory": "Предходна директория", "parentDirectory": "Предходна директория",
"empty": "празно", "empty": "празно",
"folders": "папки", "folders": "папки",
"files": "файлове", "files": "файлове",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"cs": { "cs": {
"lang": "čeština", "lang": "čeština",
"details": "podrobnosti", "details": "podrobnosti",
"icons": "ikony", "icons": "ikony",
"name": "Název", "name": "Název",
"lastModified": "Upraveno", "lastModified": "Upraveno",
"size": "Velikost", "size": "Velikost",
"parentDirectory": "Nadřazený adresář", "parentDirectory": "Nadřazený adresář",
"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": {
"lang": "deutsch", "lang": "deutsch",
"details": "Details", "details": "Details",
"icons": "Icons", "icons": "Icons",
"name": "Name", "name": "Name",
"lastModified": "Geändert", "lastModified": "Geändert",
"size": "Größe", "size": "Größe",
"parentDirectory": "Übergeordnetes Verzeichnis", "parentDirectory": "Übergeordnetes Verzeichnis",
"empty": "leer", "empty": "leer",
"folders": "Ordner", "folders": "Ordner",
"files": "Dateien", "files": "Dateien",
"download": "Download" "download": "Download",
}, "noMatch": "keine Treffer"
},
"es": { "es": {
"lang": "español", "lang": "español",
"details": "Detalles", "details": "Detalles",
"icons": "Íconos", "icons": "Íconos",
"name": "Nombre", "name": "Nombre",
"lastModified": "Última modificación", "lastModified": "Última modificación",
"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": {
"lang": "français", "lang": "français",
"details": "détails", "details": "détails",
"icons": "icônes", "icons": "icônes",
"name": "Nom", "name": "Nom",
"lastModified": "Dernière modification", "lastModified": "Dernière modification",
"size": "Taille", "size": "Taille",
"parentDirectory": "Dossier parent", "parentDirectory": "Dossier parent",
"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": {
"lang": "italiano", "lang": "italiano",
"details": "dettagli", "details": "dettagli",
"icons": "icone", "icons": "icone",
"name": "Nome", "name": "Nome",
"lastModified": "Ultima modifica", "lastModified": "Ultima modifica",
"size": "Dimensione", "size": "Dimensione",
"parentDirectory": "Cartella Superiore", "parentDirectory": "Cartella Superiore",
"empty": "vuota", "empty": "vuota",
"folders": "cartelle", "folders": "cartelle",
"files": "file", "files": "file",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"lv": { "lv": {
"lang": "latviešu", "lang": "latviešu",
"details": "detaļas", "details": "detaļas",
"icons": "ikonas", "icons": "ikonas",
"name": "Nosaukums", "name": "Nosaukums",
"lastModified": "Pēdējoreiz modificēts", "lastModified": "Pēdējoreiz modificēts",
"size": "Izmērs", "size": "Izmērs",
"parentDirectory": "Vecākdirektorijs", "parentDirectory": "Vecākdirektorijs",
"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": {
"lang": "nederlands", "lang": "nederlands",
"details": "details", "details": "details",
"icons": "iconen", "icons": "iconen",
"name": "Naam", "name": "Naam",
"lastModified": "Laatste wijziging", "lastModified": "Laatste wijziging",
"size": "Grootte", "size": "Grootte",
"parentDirectory": "Bovenliggende map", "parentDirectory": "Bovenliggende map",
"empty": "lege", "empty": "lege",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"pl": { "pl": {
"lang": "polski", "lang": "polski",
"details": "szczegóły", "details": "szczegóły",
"icons": "ikony", "icons": "ikony",
"name": "Nazwa", "name": "Nazwa",
"lastModified": "Ostatnia modyfikacja", "lastModified": "Ostatnia modyfikacja",
"size": "Rozmiar", "size": "Rozmiar",
"parentDirectory": "Katalog nadrzędny", "parentDirectory": "Katalog nadrzędny",
"empty": "pusty", "empty": "pusty",
"folders": "foldery", "folders": "foldery",
"files": "pliki", "files": "pliki",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"pt": { "pt": {
"lang": "português", "lang": "português",
"details": "detalhes", "details": "detalhes",
"icons": "ícones", "icons": "ícones",
"name": "Nome", "name": "Nome",
"lastModified": "Última modificação", "lastModified": "Última modificação",
"size": "Tamanho", "size": "Tamanho",
"parentDirectory": "Diretório superior", "parentDirectory": "Diretório superior",
"empty": "vazio", "empty": "vazio",
"folders": "pastas", "folders": "pastas",
"files": "arquivos", "files": "arquivos",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"ru": { "ru": {
"lang": "русский", "lang": "русский",
"details": "детали", "details": "детали",
"icons": "иконки", "icons": "иконки",
"name": "Имя", "name": "Имя",
"lastModified": "Последние изменения", "lastModified": "Последние изменения",
"size": "Размер", "size": "Размер",
"parentDirectory": "Главная директория", "parentDirectory": "Главная директория",
"empty": "пусто", "empty": "пусто",
"folders": "папки", "folders": "папки",
"files": "файлы", "files": "файлы",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"sk": { "sk": {
"lang": "slovenčina", "lang": "slovenčina",
"details": "podrobnosti", "details": "podrobnosti",
"icons": "ikony", "icons": "ikony",
"name": "Názov", "name": "Názov",
"lastModified": "Upravené", "lastModified": "Upravené",
"size": "Velkosť", "size": "Velkosť",
"parentDirectory": "Nadriadený priečinok", "parentDirectory": "Nadriadený priečinok",
"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": {
"lang": "svenska", "lang": "svenska",
"details": "detaljerad", "details": "detaljerad",
"icons": "ikoner", "icons": "ikoner",
"name": "Filnamn", "name": "Filnamn",
"lastModified": "Senast ändrad", "lastModified": "Senast ändrad",
"size": "Filstorlek", "size": "Filstorlek",
"parentDirectory": "Till överordnad mapp", "parentDirectory": "Till överordnad mapp",
"empty": "tom", "empty": "tom",
"folders": "folders", "folders": "folders",
"files": "files", "files": "files",
"download": "download" "download": "download",
}, "noMatch": "no match"
},
"tr": { "tr": {
"lang": "türkçe", "lang": "türkçe",
"details": "detaylar", "details": "detaylar",
"icons": "ikonlar", "icons": "ikonlar",
"name": "İsim", "name": "İsim",
"lastModified": "Son Düzenleme", "lastModified": "Son Düzenleme",
"size": "Boyut", "size": "Boyut",
"parentDirectory": "Üst Dizin", "parentDirectory": "Üst Dizin",
"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": {
"lang": "简体中文", "lang": "简体中文",
"details": "详情", "details": "详情",
"icons": "图标", "icons": "图标",
"name": "文件名", "name": "文件名",
"lastModified": "上次修改", "lastModified": "上次修改",
"size": "大小", "size": "大小",
"parentDirectory": "上层文件夹", "parentDirectory": "上层文件夹",
"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

@@ -1,280 +1,285 @@
#extended.details-view { #extended.details-view {
display: none; display: none;
ul { ul {
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
li { li {
position: relative; position: relative;
white-space: nowrap; white-space: nowrap;
clear: both; clear: both;
&.header { &.header {
a, a:active, a:visited { a, a:active, a:visited {
padding-bottom: 18px; padding-bottom: 18px;
color: #555; color: #555;
text-decoration: none; text-decoration: none;
opacity: 0.4; opacity: 0.4;
cursor: pointer; cursor: pointer;
.transition(all 0.2s ease-in-out); .transition(all 0.2s ease-in-out);
img.ascending, img.descending { img.ascending, img.descending {
position: relative; position: relative;
top: -2px; top: -2px;
display: none; display: none;
width: 12px; width: 12px;
height: 12px; height: 12px;
padding: 0 8px; padding: 0 8px;
} }
&:hover { &:hover {
color: #555; color: #555;
opacity: 0.9; opacity: 0.9;
} }
&.ascending img.ascending { &.ascending img.ascending {
display: inline; display: inline;
} }
&.descending img.descending { &.descending img.descending {
display: inline; display: inline;
} }
} }
} }
&.entry { &.entry {
a, a:active, a:visited { a, a:active, a:visited {
display: block; display: block;
color: #555; color: #555;
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
&:hover, &.hover { &:hover, &.hover {
background-color: #f6f6f6; background-color: #f6f6f6;
color: #e80; color: #e80;
} }
&.selected:not(.selecting), &.selecting:not(.selected) { &.selected:not(.selecting), &.selecting:not(.selected) {
border-color: rgba(240,100,0,0.2); border-color: rgba(240,100,0,0.2);
background-color: rgba(240,100,0,0.2); background-color: rgba(240,100,0,0.2);
} }
} }
&.error { &.error {
a, a:active, a:visited { a, a:active, a:visited {
color: #aaa; color: #aaa;
.label { .label {
.hint { .hint {
margin-left: 12px; margin-left: 12px;
font-size: 0.9em; font-size: 0.9em;
color: #c55; color: #c55;
} }
} }
&:hover, &.hover { &:hover, &.hover {
opacity: 1; opacity: 1;
background-color: #f6f6f6; background-color: #f6f6f6;
color: #e80; color: #e80;
} }
} }
} }
&.folder-parent { &.folder-parent {
.date, .size { .date, .size {
display: none; display: none;
} }
} }
&.folder { &.folder {
.size { .size {
display: none; display: none;
} }
} }
} }
.icon, .label, .date, .size { .icon, .label, .date, .size {
padding: 6px; padding: 6px;
} }
.icon { .icon {
display: inline-block; display: inline-block;
position: absolute; position: absolute;
left: 0; left: 0;
top: -2px; top: -2px;
width: 16px; width: 16px;
img { img {
width: 16px; width: 16px;
height: 16px; height: 16px;
&.thumb { &.thumb {
border: 1px solid #eee; border: 1px solid #eee;
} }
} }
} }
.icon.big { .icon.big {
display: none; display: none;
} }
.label { .label {
display: block; display: block;
margin: 0 270px 0 24px; margin: 0 270px 0 24px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-align: left; text-align: left;
} }
.date { .date {
position: absolute; position: absolute;
right: 100px; right: 100px;
top: 0; top: 0;
text-align: right; text-align: right;
width: 160px; width: 160px;
white-space: nowrap; white-space: nowrap;
} }
.size { .size {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
text-align: right; text-align: right;
width: 80px; width: 80px;
white-space: nowrap; white-space: nowrap;
} }
&.entry.thumb .icon.small { &.entry.thumb .icon.small {
overflow: hidden; overflow: hidden;
padding: 5px; padding: 5px;
img { img {
background-color: #eee; background-color: #eee;
width: 16px; width: 16px;
height: 16px; height: 16px;
border: 1px solid #ddd; border: 1px solid #ddd;
overflow: hidden; overflow: hidden;
} }
} }
} }
} }
.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;
}
} }
#selection-rect { #selection-rect {
display: none; display: none;
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
z-index: 2; z-index: 2;
border: 1px dashed rgba(240,100,0,0.5); border: 1px dashed rgba(240,100,0,0.5);
background-color: rgba(240,100,0,0.2); background-color: rgba(240,100,0,0.2);
} }
#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;
padding: 0; padding: 0;
list-style: none; list-style: none;
li { li {
&.header { &.header {
display: none; display: none;
} }
&.entry { &.entry {
float: left; float: left;
a, a:active, a:visited { a, a:active, a:visited {
display: block; display: block;
margin: 8px; margin: 8px;
padding: 8px; padding: 8px;
width: 100px; width: 100px;
height: 120px; height: 120px;
float: left; float: left;
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
overflow: hidden; overflow: hidden;
border-radius: 5px; border-radius: 5px;
color: #555; color: #555;
cursor: pointer; cursor: pointer;
border: 2px solid rgba(0,0,0,0); border: 2px solid rgba(0,0,0,0);
&:hover, &.hover { &:hover, &.hover {
color: #e80; color: #e80;
border-color: #eee; border-color: #eee;
background-color: #f6f6f6; background-color: #f6f6f6;
} }
&.selected:not(.selecting), &.selecting:not(.selected) { &.selected:not(.selecting), &.selecting:not(.selected) {
border-color: rgba(240,100,0,0.2); border-color: rgba(240,100,0,0.2);
background-color: rgba(240,100,0,0.2); background-color: rgba(240,100,0,0.2);
} }
.icon { .icon {
display: block; display: block;
img { img {
min-width: 48px; min-width: 48px;
min-height: 48px; min-height: 48px;
margin-bottom: 8px; margin-bottom: 8px;
&.thumb { &.thumb {
border: 1px solid #eee; border: 1px solid #eee;
} }
} }
} }
.icon.small { .icon.small {
display: none; display: none;
} }
.label { .label {
display: block; display: block;
word-wrap: break-word; word-wrap: break-word;
} }
.date, .size { .date, .size {
display: none; display: none;
} }
} }
&.error { &.error {
a, a:active, a:visited { a, a:active, a:visited {
color: #aaa; color: #aaa;
text-decoration: none; text-decoration: none;
.label { .label {
.hint { .hint {
padding: 0 6px; padding: 0 6px;
font-size: 0.9em; font-size: 0.9em;
color: #c55; color: #c55;
} }
} }
&:hover, &.hover { &:hover, &.hover {
color: #e80; color: #e80;
border-color: #eee; border-color: #eee;
background-color: #f6f6f6; background-color: #f6f6f6;
} }
} }
} }
} }
&.entry.thumb .icon.big { &.entry.thumb .icon.big {
width: 100px; width: 100px;
height: 58px; height: 58px;
overflow: hidden; overflow: hidden;
img { img {
background-color: #eee; background-color: #eee;
min-width: 46px; min-width: 46px;
min-height: 46px; min-height: 46px;
min-width: 12px; min-width: 12px;
min-height: 12px; min-height: 12px;
border: 1px solid #ddd; border: 1px solid #ddd;
overflow: hidden; overflow: hidden;
} }
} }
} }
} }
.empty { .empty, .no-match {
padding: 16px; margin: 0 120px;
height: 120px; padding: 16px;
text-align: center; height: 120px;
color: #ddd; text-align: center;
font-size: 5em; color: #ddd;
font-weight: bold; font-size: 5em;
} 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 */
transform: @transform; -o-transform: @transform; /* Opera 10.5 */
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

@@ -1,36 +1,36 @@
@media only screen and (max-width: 500px) { @media only screen and (max-width: 500px) {
body > nav { body > nav {
.view span { .view span {
display: none; display: none;
} }
} }
#extended.icons-view { #extended.icons-view {
padding: 0; padding: 0;
border: none; border: none;
margin: 0 -14px; margin: 0 -14px;
} }
} }
@media only screen and (max-width: 350px) { @media only screen and (max-width: 350px) {
body > nav { body > nav {
.crumb { .crumb {
display: none; display: none;
} }
.current { .current {
display: block; display: block;
} }
} }
#extended.details-view { #extended.details-view {
.header .label, .entry .label { .header .label, .entry .label {
margin-right: 110px; margin-right: 110px;
} }
.header .date, .entry .date { .header .date, .entry .date {
display: none; display: none;
} }
} }
body > footer { body > footer {
.center { .center {
display: none; display: none;
} }
} }
} }

View File

@@ -1,68 +1,68 @@
#table { #table {
table { table {
display: block; display: block;
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
th, td { th, td {
padding: 3px 6px; padding: 3px 6px;
text-align: left; text-align: left;
border: none; border: none;
} }
th { th {
padding-bottom: 18px; padding-bottom: 18px;
opacity: 0.4; opacity: 0.4;
.transition(all 0.2s ease-in-out); .transition(all 0.2s ease-in-out);
&:hover, &:hover a { &:hover, &:hover a {
color: #555; color: #555;
cursor: pointer; cursor: pointer;
opacity: 0.9; opacity: 0.9;
} }
a, a:visited { a, a:visited {
color: #555; color: #555;
font-weight: normal; font-weight: normal;
img { img {
width: 12px; width: 12px;
height: 12px; height: 12px;
padding: 0 8px; padding: 0 8px;
} }
} }
} }
td { td {
border: 1px solid #ddd; border: 1px solid #ddd;
border-left: none; border-left: none;
border-right: none; border-right: none;
} }
td:nth-child(1), th:nth-child(1) { td:nth-child(1), th:nth-child(1) {
text-align: center; text-align: center;
width: 16px; width: 16px;
img { img {
width: 16px; width: 16px;
height: 16px; height: 16px;
padding-top: 2px; padding-top: 2px;
} }
} }
td:nth-child(2), th:nth-child(2) { td:nth-child(2), th:nth-child(2) {
width: 682px; width: 682px;
max-width: 682px; max-width: 682px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
} }
td:nth-child(3), th:nth-child(3) { td:nth-child(3), th:nth-child(3) {
text-align: right; text-align: right;
width: 160px; width: 160px;
min-width: 160px; min-width: 160px;
white-space: nowrap; white-space: nowrap;
} }
td:nth-child(4), th:nth-child(4) { td:nth-child(4), th:nth-child(4) {
text-align: right; text-align: right;
width: 70px; width: 70px;
min-width: 70px; min-width: 70px;
white-space: nowrap; white-space: nowrap;
} }
} }
} }

View File

@@ -1,130 +1,129 @@
#tree { #tree {
display: none; display: none;
position: fixed; position: fixed;
left: 0; left: 0;
top: 82px; top: 31px;
z-index: 1; height: 100%;
overflow: auto; z-index: 3;
font-size: 0.85em; overflow: auto;
padding: 8px; font-size: 0.85em;
background-color: rgb(241,241,241); padding: 8px;
border: 1px solid rgb(210,210,210); background-color: rgb(241,241,241);
border-left: none; border-right: 2px solid rgb(221,221,221);
.border-radius(0 10px 10px 0);
> .scrollbar { > .scrollbar {
margin: 8px 8px 8px 0; margin: 8px 8px 8px 0;
width: 6px; width: 6px;
background-color: rgb(210,210,210); background-color: rgb(210,210,210);
.border-radius(3px); .border-radius(3px);
.drag { .drag {
background-color: rgb(180,180,180); background-color: rgb(180,180,180);
.border-radius(3px); .border-radius(3px);
} }
&.dragOn .drag { &.dragOn .drag {
background-color: rgb(150,150,150); background-color: rgb(150,150,150);
} }
} }
.entry { .entry {
.blank, .indicator { .blank, .indicator {
display: inline-block; display: inline-block;
width: 16px; width: 16px;
height: 25px; height: 25px;
float: left; float: left;
} }
.indicator { .indicator {
opacity: 0.7; opacity: 0.7;
.transition(all 0.2s ease-in-out); .transition(all 0.2s ease-in-out);
cursor: pointer; cursor: pointer;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
img { img {
position: relative; position: relative;
left: 0; left: 0;
top: 3px; top: 3px;
width: 12px; width: 12px;
height: 12px; height: 12px;
vertical-align: bottom; vertical-align: bottom;
.transition(all 0.2s ease-in-out); .transition(all 0.2s ease-in-out);
} }
&.open { &.open {
img { img {
.transform(rotate(90deg)); .transform(rotate(90deg));
} }
} }
&.unknown { &.unknown {
opacity: 0.3; opacity: 0.3;
} }
} }
> a, > a:active, > a.visited { > a, > a:active, > a.visited {
margin-left: 16px; margin-left: 16px;
padding: 4px 6px; padding: 4px 6px;
border: 1px solid rgba(0,0,0,0); border: 1px solid rgba(0,0,0,0);
.border-radius(5px); .border-radius(5px);
display: block; display: block;
color: #555; color: #555;
text-decoration: none; text-decoration: none;
opacity: 0.7; opacity: 0.7;
&:hover, &.hover { &:hover, &.hover {
color: #e80; color: #e80;
background-color: rgba(255,255,255,0.5); background-color: rgba(255,255,255,0.5);
opacity: 1; opacity: 1;
} }
.label { .label {
display: inline-block; display: inline-block;
} }
.icon { .icon {
display: inline-block; display: inline-block;
width: 20px; width: 20px;
img { img {
width: 16px; width: 16px;
height: 16px; height: 16px;
vertical-align: bottom; vertical-align: bottom;
} }
} }
.hint { .hint {
display: inline-block; display: inline-block;
margin-left: 12px; margin-left: 12px;
font-size: 0.9em; font-size: 0.9em;
color: #ccc; color: #ccc;
img { img {
width: 10px; width: 10px;
height: 10px; height: 10px;
vertical-align: baseline; vertical-align: baseline;
} }
} }
} }
&.file { &.file {
display: none; display: none;
} }
&.current { &.current {
> a, > a:active, > a:visited { > a, > a:active, > a:visited {
border: 1px solid rgb(221,221,221); border: 1px solid rgb(221,221,221);
background-color: rgba(255,255,255,0.5); background-color: rgba(255,255,255,0.5);
opacity: 1; opacity: 1;
} }
} }
&.error { &.error {
> a, > a:active, > a:visited { > a, > a:active, > a:visited {
color: #999; color: #999;
&:hover, &.hover { &:hover, &.hover {
color: #e80; color: #e80;
} }
} }
.hint { .hint {
color: #c55; color: #c55;
} }
} }
.content, ul.content { .content, ul.content {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0 0 0 24px; padding: 0 0 0 24px;
} }
} }
} }

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,34 +1,31 @@
<!-- generated code ends here --> <!-- generated code ends here -->
</section> </section>
<section id="extended" class="clearfix"></section> </section>
<footer></footer> <div id="selection-rect"></div>
</section> <footer class="clearfix">
<section id="tree"></section> <span class="left">
<footer class="clearfix"> <a id="h5ai-reference" href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION%</a>
<span class="left"> <span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span>
<a href="http://larsjung.de/h5ai" target="_blank" title="h5ai project page">h5ai %BUILD_VERSION% (js)</a> </span>
<span class="hideOnJs noJsMsg"> ⚡ JavaScript is disabled! ⚡ </span> <span class="right">
</span> <span id="langSelector">
<span class="right"> <span class="lang">en</span> - <span class="l10n-lang">english</span>
<span id="langSelector"> <span class="langOptions"></span>
<span class="lang">en</span> - <span class="l10n-lang">english</span> </span>
<span class="langOptions"></span> </span>
</span> <span class="center">
</span> <span class="hideOnNoJs">
<span class="center"> <span class="status default">
<span class="hideOnNoJs"> <span class="folderTotal"></span> <span class="l10n-folders">folders</span>
<span class="status default"> <span class='sep'>·</span>
<span class="folderTotal"></span> <span class="l10n-folders">folders</span> <span class="fileTotal"></span> <span class="l10n-files">files</span>
<span class='sep'>·</span> </span>
<span class="fileTotal"></span> <span class="l10n-files">files</span> <span class="status dynamic">
</span> </span>
<span class="status dynamic"> </span>
</span> </span>
</span> </footer>
</span> <script src="/_h5ai/config.js"></script>
</footer> <script src="/_h5ai/js/libs.js"></script>
<script src="/_h5ai/js/libs.js"></script>
<script src="/_h5ai/config.js"></script>
<script src="/_h5ai/js/main-js.js"></script>
</body> </body>
</html> </html>

View File

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

View File

@@ -2,30 +2,32 @@
<!--[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">
<title>Directory index · styled with h5ai</title> <title>Directory index · styled with h5ai</title>
<meta name="h5ai-version" content="h5ai %BUILD_VERSION% (js)"> <meta name="h5ai-version" content="h5ai %BUILD_VERSION% (js)">
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)"> <meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png"> <link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png"> <link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
<link rel="stylesheet" href="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="table" class="hideOnJs"> <section id="extended" class="clearfix"></section>
<!-- <footer></footer>
The following code was generated by Apache's autoindex module. It is not valid HTML5, but this <section id="table" class="hideOnJs">
section gets removed from the DOM tree as soon as its information is parsed. The actual page <!--
should render as valid HTML5, even if the produced source is not valid HTML5. The following code was generated by Apache's autoindex module. It is not valid HTML5, but this
--> section gets removed from the DOM tree as soon as its information is parsed. The actual page
should render as valid HTML5, even if the produced source is not valid HTML5.
-->

View File

@@ -2,59 +2,31 @@
<!--[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">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><?php echo $h5ai->getTitle(); ?></title> <title><?php echo $h5ai->getTitle(); ?></title>
<meta name="h5ai-version" content="h5ai %BUILD_VERSION% (php)"> <meta name="h5ai-version" content="h5ai %BUILD_VERSION% (php)">
<meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)"> <meta name="description" content="Directory index styled with h5ai (http://larsjung.de/h5ai)">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png"> <link rel="shortcut icon" type="image/png" href="/_h5ai/images/h5ai-16x16.png">
<link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png"> <link rel="apple-touch-icon" type="image/png" href="/_h5ai/images/h5ai-48x48.png">
<link rel="stylesheet" href="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(); ?> </ul>
</ul> </nav>
</nav> <?php echo $tree->toHtml(); ?>
<?php echo $tree->toHtml(); ?> <section id="content">
<section id="content"> <?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 id="table" class="hideOnJs">
</section> <!-- The following code was generated by Apache's autoindex module and gets ignored and removed from the DOM tree. -->
<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. -->

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

@@ -1,115 +1,115 @@
(function ($, H5AI) { (function ($, H5AI) {
H5AI.connector = (function () { H5AI.connector = (function () {
var cache = {}, var cache = {},
pathnameStatusCache = {}, pathnameStatusCache = {},
contentTypeRegEx = /^text\/html;h5ai=/, contentTypeRegEx = /^text\/html;h5ai=/,
getPath = function (folder, tableRow) { getPath = function (folder, tableRow) {
var absHref = H5AI.util.getAbsHref(folder, tableRow), var absHref = H5AI.util.getAbsHref(folder, tableRow),
path = cache[absHref]; path = cache[absHref];
if (!path) { if (!path) {
path = H5AI.Path(folder, tableRow); path = H5AI.Path(folder, tableRow);
if (!path.isParentFolder) { if (!path.isParentFolder) {
cache[path.absHref] = path; cache[path.absHref] = path;
} }
} }
return path; return path;
}, },
fetchStatus = function (pathname, callback) { fetchStatus = function (pathname, callback) {
if (H5AI.core.settings.folderStatus[pathname]) { if (H5AI.core.settings.folderStatus[pathname]) {
callback(H5AI.core.settings.folderStatus[pathname]); callback(H5AI.core.settings.folderStatus[pathname]);
return; return;
} else if (pathnameStatusCache[pathname]) { } else if (pathnameStatusCache[pathname]) {
callback(pathnameStatusCache[pathname]); callback(pathnameStatusCache[pathname]);
return; return;
} }
$.ajax({ $.ajax({
url: pathname, url: pathname,
type: "HEAD", type: "HEAD",
complete: function (xhr) { complete: function (xhr) {
var status = xhr.status; var status = xhr.status;
if (status === 200 && contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) { if (status === 200 && contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
status = "h5ai"; status = "h5ai";
} }
pathnameStatusCache[pathname] = status; pathnameStatusCache[pathname] = status;
callback(status); callback(status);
} }
}); });
}, },
updatePath = function (path) { updatePath = function (path) {
if (path.isFolder && !path.isParentFolder && path.status === undefined) { if (path.isFolder && !path.isParentFolder && path.status === undefined) {
fetchStatus(path.absHref, function (status) { fetchStatus(path.absHref, function (status) {
if (status !== "h5ai") { if (status !== "h5ai") {
path.status = status; path.status = status;
} }
H5AI.html.updateHtml(path); H5AI.html.updateHtml(path);
H5AI.core.linkHoverStates(); H5AI.core.linkHoverStates();
}); });
} }
}, },
updatePaths = function () { updatePaths = function () {
$.each(cache, function (ref, cached) { $.each(cache, function (ref, cached) {
updatePath(cached); updatePath(cached);
}); });
}, },
fetchStatusAndContent = function (pathname, includeParent, callback) { fetchStatusAndContent = function (pathname, includeParent, callback) {
fetchStatus(pathname, function (status) { fetchStatus(pathname, function (status) {
if (status !== "h5ai") { if (status !== "h5ai") {
callback(status, {}); callback(status, {});
return; return;
} }
$.ajax({ $.ajax({
url: pathname, url: pathname,
type: "GET", type: "GET",
dataType: "html", dataType: "html",
error: function (xhr) { error: function (xhr) {
callback(xhr.status, {}); // since it was checked before this should never happen callback(xhr.status, {}); // since it was checked before this should never happen
}, },
success: function (html, status, xhr) { success: function (html, status, xhr) {
var content = {}; var content = {};
if (!contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) { if (!contentTypeRegEx.test(xhr.getResponseHeader("Content-Type"))) {
callback(xhr.status, {}); // since it was checked before this should never happen callback(xhr.status, {}); // since it was checked before this should never happen
return; return;
} }
$(html).find("#table td").closest("tr").each(function () { $(html).find("#table td").closest("tr").each(function () {
var path = getPath(pathname, this); var path = getPath(pathname, this);
if (path.isFolder && (!path.isParentFolder || includeParent)) { if (path.isFolder && (!path.isParentFolder || includeParent)) {
content[path.absHref] = path; content[path.absHref] = path;
updatePath(path); updatePath(path);
} }
}); });
callback("h5ai", content); callback("h5ai", content);
} }
}); });
}); });
}; };
return { return {
getPath: getPath, getPath: getPath,
updatePaths: updatePaths, updatePaths: updatePaths,
fetchStatusAndContent: fetchStatusAndContent fetchStatusAndContent: fetchStatusAndContent
}; };
}()); }());
}(jQuery, H5AI)); }(jQuery, H5AI));

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

@@ -1,399 +1,439 @@
(function (window, $, H5AI, config) { (function (window, $, H5AI, config) {
H5AI.core = (function () { H5AI.core = (function () {
var $window = $(window), var $window = $(window),
defaults = { defaults = {
store: { store: {
viewmode: "h5ai.pref.viewmode", viewmode: "h5ai.pref.viewmode",
lang: "h5ai.pref.lang" lang: "h5ai.pref.lang"
}, },
callbacks: { callbacks: {
pathClick: [] pathClick: []
}, },
rootAbsHref: "/", rootAbsHref: "/",
h5aiAbsHref: "/_h5ai/", h5aiAbsHref: "/_h5ai/",
customHeader: "_h5ai.header.html", customHeader: null,
customFooter: "_h5ai.footer.html", customFooter: null,
viewmodes: ["details", "icons"],
sortorder: "na",
showTree: true,
slideTree: true,
folderStatus: {},
lang: "en",
useBrowserLang: true,
setParentFolderLabels: true,
linkHoverStates: true,
dateFormat: "yyyy-MM-dd HH:mm",
showThumbs: false,
thumbTypes: ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
zippedDownload: false,
qrCodesSize: null,
showFilter: false
},
settings = $.extend({}, defaults, config.options),
currentDateFormat = settings.dateFormat,
extToFileType = (function (types) {
var map = {};
$.each(types, function (type, exts) {
$.each(exts, function (idx, ext) {
map[ext] = type;
});
});
return map;
}(config.types)),
hash = function (obj) {
viewmodes: ["details", "icons"], if ($.isPlainObject(obj)) {
sortorder: "na", var hashStr = '';
showTree: true, $.each($.extend({}, hash(), obj), function (key, value) {
slideTree: true, if (value) {
folderStatus: {}, hashStr += '/' + encodeURIComponent(key) + '=' + encodeURIComponent(value);
lang: null, }
useBrowserLang: true, });
setParentFolderLabels: true, hashStr = '#!' + hashStr;
linkHoverStates: true, window.location.hash = hashStr;
dateFormat: "yyyy-MM-dd HH:mm", return hashStr;
showThumbs: false, } else {
zippedDownload: false var result = {},
}, parts = document.location.hash.split('/');
settings = $.extend({}, defaults, config.options),
currentDateFormat = settings.dateFormat,
extToFileType = (function (types) {
var map = {};
$.each(types, function (type, exts) {
$.each(exts, function (idx, ext) {
map[ext] = type;
});
});
return map;
}(config.types)),
api = function () {
return settings.h5aiAbsHref + "php/api.php"; if (parts.length >= 2 || parts[0] === '#!') {
}, parts.shift();
image = function (id) { $.each(parts, function (idx, part) {
return settings.h5aiAbsHref + "images/" + id + ".png"; var match = /^([^=]*)=(.*?)$/.exec(part);
}, if (match) {
icon = function (id, big) { result[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
});
}
return typeof obj === 'string' ? result[obj] : result;
}
},
api = function () {
return settings.h5aiAbsHref + "icons/" + (big ? "48x48" : "16x16") + "/" + id + ".png"; return settings.h5aiAbsHref + "php/api.php";
}, },
viewmode = function (viewmode) { image = function (id, noPngExt) {
var $viewDetails = $("#viewdetails"), return settings.h5aiAbsHref + "images/" + id + (noPngExt ? "" : ".png");
$viewIcons = $("#viewicons"), },
$extended = $("#extended"); icon = function (id, big) {
if (viewmode) { return settings.h5aiAbsHref + "icons/" + (big ? "48x48" : "16x16") + "/" + id + ".png";
amplify.store(settings.store.viewmode, viewmode); },
} else { viewmode = function (viewmode) {
viewmode = amplify.store(settings.store.viewmode);
}
viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
$viewDetails.add($viewIcons).removeClass("current"); var $viewDetails = $("#viewdetails"),
if (viewmode === "details") { $viewIcons = $("#viewicons"),
$viewDetails.addClass("current"); $extended = $("#extended");
$extended.addClass("details-view").removeClass("icons-view").show();
} else if (viewmode === "icons") {
$viewIcons.addClass("current");
$extended.removeClass("details-view").addClass("icons-view").show();
} else {
$extended.hide();
}
},
initTopSpace = function () {
var $body = $("body"), if (viewmode) {
$tree = $("#tree"), amplify.store(settings.store.viewmode, viewmode);
adjustTopSpace = function () { } else {
viewmode = amplify.store(settings.store.viewmode);
}
viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
H5AI.core.hash({view: viewmode});
var winHeight = $window.height(), $viewDetails.add($viewIcons).removeClass("current");
navHeight = $("body > nav").outerHeight(), if (viewmode === "details") {
footerHeight = $("body > footer").outerHeight(), $viewDetails.addClass("current");
contentSpacing = 50, $extended.addClass("details-view").removeClass("icons-view").show();
treeSpacing = 30; } else if (viewmode === "icons") {
$viewIcons.addClass("current");
$extended.removeClass("details-view").addClass("icons-view").show();
} else {
$extended.hide();
}
},
initTopSpace = function () {
$body.css({ var $body = $("body"),
"margin-top": navHeight + contentSpacing, $tree = $("#tree"),
"margin-bottom": footerHeight + contentSpacing adjustTopSpace = function () {
});
$tree.css({ var winHeight = $window.height(),
top: navHeight + treeSpacing, navHeight = $("body > nav").outerHeight(),
height: winHeight - navHeight - footerHeight - 18 - 2 * treeSpacing footerHeight = $("body > footer").outerHeight(),
}); contentSpacing = 50,
treeSpacing = 0;
try { $body.css({
$tree.get(0).updateScrollbar(); "margin-top": navHeight + contentSpacing,
} catch (err) {} "margin-bottom": footerHeight + contentSpacing
}; });
$window.resize(function () { $tree.css({
adjustTopSpace(); top: navHeight + treeSpacing,
}); height: winHeight - navHeight - footerHeight - 16 - 2 * treeSpacing
adjustTopSpace(); });
},
initViews = function () {
var $navbar = $("#navbar"), try {
$extended = $("#extended"); $tree.get(0).updateScrollbar();
} catch (err) {}
};
$("#table").remove(); $window.resize(function () {
adjustTopSpace();
});
adjustTopSpace();
},
initViews = function () {
if (settings.viewmodes.length > 1) { var $navbar = $("#navbar"),
if ($.inArray("icons", settings.viewmodes) >= 0) { $extended = $("#extended");
$("<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()
.click(function () { viewmode("icons"); })
.appendTo($navbar);
}
if ($.inArray("details", settings.viewmodes) >= 0) {
$("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>")
.find("img").attr("src", image("view-details")).end()
.click(function () { viewmode("details"); })
.appendTo($navbar);
}
}
// status update $("#table").remove();
$extended.find(".entry a").hover(
function () {
if ($extended.hasClass("icons-view")) {
var $this = $(this);
$(".status.default").hide();
$(".status.dynamic")
.empty()
.append($this.find(".label").clone())
.append($("<span class='sep'>·</span>"))
.append($this.find(".date").clone())
.show();
if (!$this.closest(".entry").hasClass("folder")) { if (settings.viewmodes.length > 1) {
$(".status.dynamic") if ($.inArray("icons", settings.viewmodes) >= 0) {
.append($("<span class='sep'>·</span>")) $("<li id='viewicons' class='view'><a href='#'><img alt='view-icons' /><span class='l10n-icons'>icons</span></a></li>")
.append($this.find(".size").clone()); .find("img").attr("src", image("view-icons")).end()
} .find("a").click(function (event) {
} viewmode("icons");
}, event.preventDefault();
function () { }).end()
$(".status.default").show(); .appendTo($navbar);
$(".status.dynamic").empty().hide(); }
} if ($.inArray("details", settings.viewmodes) >= 0) {
); $("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>")
}, .find("img").attr("src", image("view-details")).end()
shiftTree = function (forceVisible, dontAnimate) { .find("a").click(function (event) {
viewmode("details");
event.preventDefault();
}).end()
.appendTo($navbar);
}
}
var $tree = $("#tree"), // status update
$extended = $("#extended"); $extended.find(".entry a").hover(
function () {
if ($extended.hasClass("icons-view")) {
var $this = $(this);
$(".status.default").hide();
$(".status.dynamic")
.empty()
.append($this.find(".label").clone())
.append($("<span class='sep'>·</span>"))
.append($this.find(".date").clone())
.show();
if ((settings.slideTree && $tree.outerWidth() < $extended.offset().left) || forceVisible) { if (!$this.closest(".entry").hasClass("folder")) {
if (dontAnimate) { $(".status.dynamic")
$tree.stop().css({ left: 0 }); .append($("<span class='sep'>·</span>"))
} else { .append($this.find(".size").clone());
$tree.stop().animate({ left: 0 }); }
} }
} else { },
if (dontAnimate) { function () {
$tree.stop().css({ left: 18 - $tree.outerWidth() }); $(".status.default").show();
} else { $(".status.dynamic").empty().hide();
$tree.stop().animate({ left: 18 - $tree.outerWidth() }); }
} );
} },
}, shiftTree = function (forceVisible, dontAnimate) {
initTree = function () {
$("#tree").hover( var $tree = $("#tree"),
function () { shiftTree(true); }, $extended = $("#extended");
function () { shiftTree(); }
);
$window.resize(function () { shiftTree(); });
shiftTree(false, true);
},
selectLinks = function (href) {
var elements = []; if ((settings.slideTree && $tree.outerWidth() < $extended.offset().left) || forceVisible) {
$("a[href^='/']").each(function () { if (dontAnimate) {
$tree.stop().css({ left: 0 });
} else {
$tree.stop().animate({ left: 0 });
}
} else {
if (dontAnimate) {
$tree.stop().css({ left: 18 - $tree.outerWidth() });
} else {
$tree.stop().animate({ left: 18 - $tree.outerWidth() });
}
}
},
initTree = function () {
if ($(this).attr("href") === href) { $("#tree").hover(
elements.push(this); function () { shiftTree(true); },
} function () { shiftTree(); }
}); );
return $(elements); $window.resize(function () { shiftTree(); });
}, shiftTree(false, true);
linkHoverStates = function () { },
selectLinks = function (href) {
if (settings.linkHoverStates) { var elements = [];
$("a[href^='/']:not(.linkedHoverStates)").each(function () { $("a[href^='/']").each(function () {
var $a = $(this).addClass("linkedHoverStates"), if ($(this).attr("href") === href) {
href = $a.attr("href"); elements.push(this);
}
});
return $(elements);
},
linkHoverStates = function () {
$a.hover( if (settings.linkHoverStates) {
function () { selectLinks(href).addClass("hover"); }, $("a[href^='/']:not(.linkedHoverStates)").each(function () {
function () { selectLinks(href).removeClass("hover"); }
);
});
}
},
formatDates = function (dateFormat) {
if (dateFormat) { var $a = $(this).addClass("linkedHoverStates"),
currentDateFormat = dateFormat; href = $a.attr("href");
}
$("#extended .entry .date").each(function () { $a.hover(
function () { selectLinks(href).addClass("hover"); },
function () { selectLinks(href).removeClass("hover"); }
);
});
}
},
formatDates = function (dateFormat) {
var $this = $(this), if (dateFormat) {
time = $this.data("time"), currentDateFormat = dateFormat;
formattedDate = time ? new Date(time).toString(currentDateFormat) : ""; }
$this.text(formattedDate); $("#extended .entry .date").each(function () {
});
},
localize = function (langs, lang, useBrowserLang) {
var storedLang = amplify.store(settings.store.lang), var $this = $(this),
browserLang, selected, key; time = $this.data("time"),
formattedDate = time ? new Date(time).toString(currentDateFormat) : "";
if (langs[storedLang]) { $this.text(formattedDate);
lang = storedLang; });
} else if (useBrowserLang) { },
browserLang = navigator.language; localize = function (langs, lang, useBrowserLang) {
if (langs[browserLang]) {
lang = browserLang;
} else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
lang = browserLang.substr(0, 2);
}
}
if (!langs[lang]) { var storedLang = amplify.store(settings.store.lang),
lang = "en"; browserLang, selected, key;
}
selected = langs[lang]; if (langs[storedLang]) {
if (selected) { lang = storedLang;
$.each(selected, function (key, value) { } else if (useBrowserLang) {
$(".l10n-" + key).text(value); browserLang = navigator.language;
}); if (langs[browserLang]) {
$(".lang").text(lang); lang = browserLang;
$(".langOption").removeClass("current"); } else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
$(".langOption." + lang).addClass("current"); lang = browserLang.substr(0, 2);
} }
}
formatDates(selected.dateFormat || settings.dateFormat); if (!langs[lang]) {
}, lang = "en";
initLangSelector = function (langs) { }
var $langOptions = $("#langSelector .langOptions"), selected = langs[lang];
sortedLangsKeys = [], if (selected) {
$ul; $.each(selected, function (key, value) {
$(".l10n-" + key).text(value);
});
$(".lang").text(lang);
$(".langOption").removeClass("current");
$(".langOption." + lang).addClass("current");
H5AI.core.hash({lang: lang});
}
$.each(langs, function (lang) { formatDates(selected.dateFormat || settings.dateFormat);
sortedLangsKeys.push(lang); },
}); initLangSelector = function (langs) {
sortedLangsKeys.sort();
$ul = $("<ul />"); var $langOptions = $("#langSelector .langOptions"),
$.each(sortedLangsKeys, function (idx, lang) { sortedLangsKeys = [],
$("<li class='langOption' />") $ul;
.addClass(lang)
.text(lang + " - " + langs[lang].lang)
.appendTo($ul)
.click(function () {
amplify.store(settings.store.lang, lang);
localize(langs, lang, false);
});
});
$langOptions
.append($ul)
.scrollpanel();
$("#langSelector").hover( $.each(langs, function (lang) {
function () { sortedLangsKeys.push(lang);
$langOptions });
.css("top", "-" + $langOptions.outerHeight() + "px") sortedLangsKeys.sort();
.stop(true, true)
.fadeIn();
$langOptions.get(0).updateScrollbar();
},
function () {
$langOptions
.stop(true, true)
.fadeOut();
}
);
},
onIndicatorClick = function (event) {
var $indicator = $(this), $ul = $("<ul />");
$entry = $indicator.closest(".entry"), $.each(sortedLangsKeys, function (idx, lang) {
updateTreeScrollbar = $("#tree").get(0).updateScrollbar; $("<li class='langOption' />")
.addClass(lang)
.text(lang + " - " + langs[lang].lang)
.appendTo($ul)
.click(function () {
amplify.store(settings.store.lang, lang);
localize(langs, lang, false);
});
});
$langOptions
.append($ul)
.scrollpanel();
if ($indicator.hasClass("unknown")) { $("#langSelector").hover(
$.get(api(), { "action": "tree", "href": $entry.find("> a").attr("href") }, function (html) { function () {
$langOptions
.css("top", "-" + $langOptions.outerHeight() + "px")
.stop(true, true)
.fadeIn();
$langOptions.get(0).updateScrollbar();
},
function () {
$langOptions
.stop(true, true)
.fadeOut();
}
);
},
onIndicatorClick = function (event) {
var $content = $(html); var $indicator = $(this),
$entry = $indicator.closest(".entry"),
updateTreeScrollbar = $("#tree").get(0).updateScrollbar;
$indicator.removeClass("unknown"); if ($indicator.hasClass("unknown")) {
if ($content.find("> li").size() === 0) { $.get(api(), { "action": "tree", "href": $entry.find("> a").attr("href") }, function (html) {
$indicator.replaceWith($("<span class='blank' />"));
} else {
$indicator.addClass("open");
$entry.find("> .content").replaceWith($content);
updateTreeScrollbar();
$content.find(".indicator:not(.initiated)")
.click(onIndicatorClick)
.addClass("initiated");
}
});
} else if ($indicator.hasClass("open")) {
$indicator.removeClass("open");
updateTreeScrollbar(true);
$entry.find("> .content").slideUp(function () {
updateTreeScrollbar();
});
} else {
$indicator.addClass("open");
updateTreeScrollbar(true);
$entry.find("> .content").slideDown(function () {
updateTreeScrollbar();
});
}
},
initIndicators = function () {
$("#tree .entry.folder .indicator:not(.initiated)") var $content = $(html);
.click(onIndicatorClick)
.addClass("initiated");
},
getFileType = function (filename) {
var dotidx = filename.lastIndexOf('.'), $indicator.removeClass("unknown");
ext = dotidx >= 0 ? filename.substr(dotidx) : filename; if ($content.find("> li").size() === 0) {
$indicator.replaceWith($("<span class='blank' />"));
} else {
$indicator.addClass("open");
$entry.find("> .content").replaceWith($content);
updateTreeScrollbar();
$content.find(".indicator:not(.initiated)")
.click(onIndicatorClick)
.addClass("initiated");
}
});
} else if ($indicator.hasClass("open")) {
$indicator.removeClass("open");
updateTreeScrollbar(true);
$entry.find("> .content").slideUp(function () {
updateTreeScrollbar();
});
} else {
$indicator.addClass("open");
updateTreeScrollbar(true);
$entry.find("> .content").slideDown(function () {
updateTreeScrollbar();
});
}
},
initIndicators = function () {
return extToFileType[ext.toLowerCase()] || "unknown"; $("#tree .entry.folder .indicator:not(.initiated)")
}, .click(onIndicatorClick)
formatSizes = function () { .addClass("initiated");
},
getFileType = function (filename) {
$("#extended .entry .size").each(function () { var dotidx = filename.lastIndexOf('.'),
ext = dotidx >= 0 ? filename.substr(dotidx) : filename;
var $this = $(this), return extToFileType[ext.toLowerCase()] || "unknown";
bytes = $this.data("bytes"), },
formattedSize = bytes >= 0 ? H5AI.util.formatSize(bytes) : ""; formatSizes = function () {
$this.text(formattedSize); $("#extended .entry .size").each(function () {
});
},
setTotals = function () {
var $extended = $("#extended"); var $this = $(this),
bytes = $this.data("bytes"),
formattedSize = bytes >= 0 ? H5AI.util.formatSize(bytes) : "";
$(".folderTotal").text($extended.find(".entry.folder:not(.folder-parent)").length); $this.text(formattedSize);
$(".fileTotal").text($extended.find(".entry.file").length); });
}, },
init = function () { setTotals = function () {
initViews(); var $extended = $("#extended");
viewmode();
initTopSpace();
initTree();
linkHoverStates();
initLangSelector(config.langs);
localize(config.langs, settings.lang, settings.useBrowserLang);
formatSizes();
setTotals();
initIndicators();
};
return { $(".folderTotal").text($extended.find(".entry.folder:not(.folder-parent)").length);
settings: settings, $(".fileTotal").text($extended.find(".entry.file").length);
api: api, },
image: image, init = function () {
icon: icon,
shiftTree: shiftTree, initViews();
linkHoverStates: linkHoverStates, viewmode();
initIndicators: initIndicators, initTopSpace();
formatDates: formatDates, initTree();
getFileType: getFileType, linkHoverStates();
init: init initLangSelector(config.langs);
}; localize(config.langs, settings.lang, settings.useBrowserLang);
}()); formatSizes();
setTotals();
initIndicators();
};
return {
settings: settings,
hash: hash,
api: api,
image: image,
icon: icon,
shiftTree: shiftTree,
linkHoverStates: linkHoverStates,
initIndicators: initIndicators,
formatDates: formatDates,
getFileType: getFileType,
init: init
};
}());
}(window, jQuery, H5AI, H5AI_CONFIG)); }(window, jQuery, H5AI, H5AI_CONFIG));

View File

@@ -1,127 +1,132 @@
(function (document, $, H5AI) { (function (document, $, H5AI) {
H5AI.extended = (function () { H5AI.extended = (function () {
var initBreadcrumb = function () { var initBreadcrumb = function () {
var $ul = $("body > nav ul"), var $ul = $("body > nav ul"),
pathname = "/", pathname = "/",
path = H5AI.connector.getPath(pathname), path = H5AI.connector.getPath(pathname),
pathnameParts = document.location.pathname.split("/"), pathnameParts = document.location.pathname.split("/"),
lastPart = "", lastPart = "",
title = document.domain; title = document.domain;
$ul.append(H5AI.html.updateCrumbHtml(path)); $ul.append(H5AI.html.updateCrumbHtml(path));
$.each(pathnameParts, function (idx, part) { $.each(pathnameParts, function (idx, part) {
if (part !== "") { if (part !== "") {
pathname += part + "/"; pathname += part + "/";
$ul.append(H5AI.html.updateCrumbHtml(H5AI.connector.getPath(pathname))); $ul.append(H5AI.html.updateCrumbHtml(H5AI.connector.getPath(pathname)));
lastPart = part + " - "; lastPart = part + " - ";
title += " > " + part; title += " > " + part;
} }
}); });
document.title = H5AI.util.checkedDecodeUri(lastPart + title); document.title = H5AI.util.checkedDecodeUri(lastPart + title);
}, },
initExtendedView = function () { initExtendedView = function () {
var $ul, $li; var $ul, $li;
$ul = $("<ul/>"); $ul = $("<ul/>");
$li = $("<li class='header' />") $li = $("<li class='header' />")
.appendTo($ul) .appendTo($ul)
.append($("<a class='icon'></a>")) .append($("<a class='icon'></a>"))
.append($("<a class='label' href='#'><span class='l10n-name'></span></a>")) .append($("<a class='label' href='#'><span class='l10n-name'></span></a>"))
.append($("<a class='date' href='#'><span class='l10n-lastModified'></span></a>")) .append($("<a class='date' href='#'><span class='l10n-lastModified'></span></a>"))
.append($("<a class='size' href='#'><span class='l10n-size'></span></a>")); .append($("<a class='size' href='#'><span class='l10n-size'></span></a>"));
// entries // entries
$("#table td").closest("tr").each(function () { $("#table td").closest("tr").each(function () {
var path = H5AI.connector.getPath(document.location.pathname, this); var path = H5AI.connector.getPath(document.location.pathname, this);
$ul.append(H5AI.html.updateExtendedHtml(path)); $ul.append(H5AI.html.updateExtendedHtml(path));
}); });
$("#extended").append($ul); $("#extended").append($ul);
// empty // empty
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 () {
$.ajax({ if (H5AI.core.settings.customHeader) {
url: H5AI.core.settings.customHeader, $.ajax({
dataType: "html", url: H5AI.core.settings.customHeader,
success: function (data) { dataType: "html",
$("#content > header").append($(data)).show(); success: function (data) {
} $("#content > header").append($(data)).show();
}); }
});
}
$.ajax({ if (H5AI.core.settings.customFooter) {
url: H5AI.core.settings.customFooter, $.ajax({
dataType: "html", url: H5AI.core.settings.customFooter,
success: function (data) { dataType: "html",
$("#content > footer").prepend($(data)).show(); success: function (data) {
} $("#content > footer").prepend($(data)).show();
}); }
}, });
fetchPath = function (pathname, callback) { }
},
fetchPath = function (pathname, callback) {
H5AI.connector.fetchStatusAndContent(pathname, false, function (status, content) { H5AI.connector.fetchStatusAndContent(pathname, false, function (status, content) {
var path = H5AI.connector.getPath(pathname); var path = H5AI.connector.getPath(pathname);
path.status = status; path.status = status;
path.content = content; path.content = content;
callback(path); callback(path);
}); });
}, },
fetchTree = function (pathname, callback, childPath) { fetchTree = function (pathname, callback, childPath) {
fetchPath(pathname, function (path) { fetchPath(pathname, function (path) {
var parent = H5AI.util.splitPath(pathname).parent; var parent = H5AI.util.splitPath(pathname).parent;
path.treeOpen = true; path.treeOpen = true;
if (childPath) { if (childPath) {
path.content[childPath.absHref] = childPath; path.content[childPath.absHref] = childPath;
} }
if (parent === null) { if (parent === null) {
callback(path); callback(path);
} else { } else {
fetchTree(parent, callback, path); fetchTree(parent, callback, path);
} }
}); });
}, },
populateTree = function () { populateTree = function () {
fetchTree(document.location.pathname, function (path) { fetchTree(document.location.pathname, function (path) {
$("#tree") $("#tree")
.append(H5AI.html.updateTreeHtml(path)) .append(H5AI.html.updateTreeHtml(path))
.scrollpanel() .scrollpanel()
.show(); .show();
H5AI.core.shiftTree(false, true); H5AI.core.shiftTree(false, true);
H5AI.core.linkHoverStates(); H5AI.core.linkHoverStates();
setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1); setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1);
}); });
}, },
init = function () { init = function () {
initBreadcrumb(); initBreadcrumb();
initExtendedView(); initExtendedView();
customize(); customize();
H5AI.connector.updatePaths(); H5AI.connector.updatePaths();
if (H5AI.core.settings.showTree) { if (H5AI.core.settings.showTree) {
populateTree(); populateTree();
} }
}; };
return { return {
init: init init: init
}; };
}()); }());
}(document, jQuery, H5AI)); }(document, jQuery, H5AI));

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

@@ -1,264 +1,264 @@
(function ($, H5AI) { (function ($, H5AI) {
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) {
var $html, $a; var $html, $a;
if (path.html.$crumb && path.html.$crumb.data("status") === path.status) { if (path.html.$crumb && path.html.$crumb.data("status") === path.status) {
return path.html.$crumb; return path.html.$crumb;
} }
$html = $("<li class='crumb'><a><img alt='>' /><span></span></a></li>") $html = $("<li class='crumb'><a><img alt='>' /><span></span></a></li>")
.addClass(path.isFolder ? "folder" : "file"); .addClass(path.isFolder ? "folder" : "file");
if (path.status) { if (path.status) {
$html.data("status", path.status); $html.data("status", path.status);
} }
$a = $html.find("a") $a = $html.find("a")
.attr("href", path.absHref) .attr("href", path.absHref)
.click(function() { onClick(path, "crumb"); }) .click(function() { onClick(path, "crumb"); })
.find("img").attr("src", H5AI.core.image("crumb")).end() .find("img").attr("src", H5AI.core.image("crumb")).end()
.find("span").text(path.label).end(); .find("span").text(path.label).end();
if (path.isDomain) { if (path.isDomain) {
$html.addClass("domain"); $html.addClass("domain");
$a.find("img").attr("src", H5AI.core.image("home")); $a.find("img").attr("src", H5AI.core.image("home"));
} }
if (path.isCurrentFolder) { if (path.isCurrentFolder) {
$html.addClass("current"); $html.addClass("current");
} }
if (!isNaN(path.status)) { if (!isNaN(path.status)) {
if (path.status === 200) { if (path.status === 200) {
$a.append($("<img class='hint' src='" + H5AI.core.image("page") + "' alt='not listable' />")); $a.append($("<img class='hint' src='" + H5AI.core.image("page") + "' alt='not listable' />"));
} else { } else {
$a.append($("<span class='hint'>(" + path.status + ")</span>")); $a.append($("<span class='hint'>(" + path.status + ")</span>"));
} }
} }
if (path.html.$crumb) { if (path.html.$crumb) {
path.html.$crumb.replaceWith($html); path.html.$crumb.replaceWith($html);
} }
path.html.$crumb = $html; path.html.$crumb = $html;
return $html; return $html;
}, },
updateExtendedHtml = function (path) { updateExtendedHtml = function (path) {
var $html, $a, $label, var $html, $a, $label,
formattedDate = path.date ? path.date.toString(H5AI.core.settings.dateFormat) : "", formattedDate = path.date ? path.date.toString(H5AI.core.settings.dateFormat) : "",
imgClass = "", imgClass = "",
icon16 = H5AI.core.icon(path.type), icon16 = H5AI.core.icon(path.type),
icon48 = H5AI.core.icon(path.type, true); icon48 = H5AI.core.icon(path.type, true);
if (path.html.$extended && path.html.$extended.data("status") === path.status) { if (path.html.$extended && path.html.$extended.data("status") === path.status) {
return path.html.$extended; return path.html.$extended;
} }
$html = $("<li class='entry' />") $html = $("<li class='entry' />")
.data("path", path) .data("path", path)
.addClass(path.isFolder ? "folder" : "file"); .addClass(path.isFolder ? "folder" : "file");
if (path.status) { if (path.status) {
$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>");
$a = $("<a />") $a = $("<a />")
.attr("href", path.absHref) .attr("href", path.absHref)
.click(function() { onClick(path, "extended"); }) .click(function() { onClick(path, "extended"); })
.appendTo($html) .appendTo($html)
.append($("<span class='icon small'><img " + imgClass + " src='" + icon16 + "' alt='" + path.type + "' /></span>")) .append($("<span class='icon small'><img " + imgClass + " src='" + icon16 + "' alt='" + path.type + "' /></span>"))
.append($("<span class='icon big'><img " + imgClass + " src='" + icon48 + "' alt='" + path.type + "' /></span>")) .append($("<span class='icon big'><img " + imgClass + " src='" + icon48 + "' alt='" + path.type + "' /></span>"))
.append($label) .append($label)
.append($("<span class='date' data-time='" + path.time + "'></span>")) .append($("<span class='date' data-time='" + path.time + "'></span>"))
.append($("<span class='size' data-bytes='" + path.size + "'></span>")); .append($("<span class='size' data-bytes='" + path.size + "'></span>"));
$a.hover( $a.hover(
function () { function () {
if ($("#extended").hasClass("icons-view")) { if ($("#extended").hasClass("icons-view")) {
var $this = $(this); var $this = $(this);
$(".status.default").hide(); $(".status.default").hide();
$(".status.dynamic") $(".status.dynamic")
.empty() .empty()
.append($this.find(".label").clone()) .append($this.find(".label").clone())
.append($("<span class='sep'>·</span>")) .append($("<span class='sep'>·</span>"))
.append($this.find(".date").clone()) .append($this.find(".date").clone())
.show(); .show();
if (!$this.closest(".entry").hasClass("folder")) { if (!$this.closest(".entry").hasClass("folder")) {
$(".status.dynamic") $(".status.dynamic")
.append($("<span class='sep'>·</span>")) .append($("<span class='sep'>·</span>"))
.append($this.find(".size").clone()); .append($this.find(".size").clone());
} }
} }
}, },
function () { function () {
$(".status.default").show(); $(".status.default").show();
$(".status.dynamic").empty().hide(); $(".status.dynamic").empty().hide();
} }
); );
if (path.isParentFolder) { if (path.isParentFolder) {
if (!H5AI.core.settings.setParentFolderLabels) { if (!H5AI.core.settings.setParentFolderLabels) {
$label.addClass("l10n-parentDirectory"); $label.addClass("l10n-parentDirectory");
} }
$html.addClass("folder-parent"); $html.addClass("folder-parent");
} }
if (!isNaN(path.status)) { if (!isNaN(path.status)) {
if (path.status === 200) { if (path.status === 200) {
$html.addClass("page"); $html.addClass("page");
$a.find(".icon.small img").attr("src", H5AI.core.icon("folder-page")); $a.find(".icon.small img").attr("src", H5AI.core.icon("folder-page"));
$a.find(".icon.big img").attr("src", H5AI.core.icon("folder-page", true)); $a.find(".icon.big img").attr("src", H5AI.core.icon("folder-page", true));
} else { } else {
$html.addClass("error"); $html.addClass("error");
$label.append($("<span class='hint'> " + path.status + " </span>")); $label.append($("<span class='hint'> " + path.status + " </span>"));
} }
} }
if (path.html.$extended) { if (path.html.$extended) {
path.html.$extended.replaceWith($html); path.html.$extended.replaceWith($html);
H5AI.core.formatDates(); H5AI.core.formatDates();
} }
path.html.$extended = $html; path.html.$extended = $html;
return $html; return $html;
}, },
updateTreeHtml = function (path) { updateTreeHtml = function (path) {
var $html, $blank, $a, $indicator, $ul, idx; var $html, $blank, $a, $indicator, $ul, idx;
$html = $("<div class='entry' />") $html = $("<div class='entry' />")
.data("path", path) .data("path", path)
.addClass(path.isFolder ? "folder" : "file"); .addClass(path.isFolder ? "folder" : "file");
$blank = $("<span class='blank' />").appendTo($html); $blank = $("<span class='blank' />").appendTo($html);
$a = $("<a />") $a = $("<a />")
.attr("href", path.absHref) .attr("href", path.absHref)
.click(function() { onClick(path, "tree"); }) .click(function() { onClick(path, "tree"); })
.appendTo($html) .appendTo($html)
.append($("<span class='icon'><img src='" + H5AI.core.icon(path.type) + "' /></span>")) .append($("<span class='icon'><img src='" + H5AI.core.icon(path.type) + "' /></span>"))
.append($("<span class='label'>" + path.label + "</span>")); .append($("<span class='label'>" + path.label + "</span>"));
if (path.isFolder) { if (path.isFolder) {
// indicator // indicator
if (path.status === undefined || !path.isEmpty()) { if (path.status === undefined || !path.isEmpty()) {
$indicator = $("<span class='indicator initiated'><img src='" + H5AI.core.image("tree") + "' /></span>") $indicator = $("<span class='indicator initiated'><img src='" + H5AI.core.image("tree") + "' /></span>")
.click(function (event) { .click(function (event) {
var $entry = $indicator.closest(".entry"); // $html var $entry = $indicator.closest(".entry"); // $html
if ($indicator.hasClass("unknown")) { if ($indicator.hasClass("unknown")) {
H5AI.connector.fetchStatusAndContent(path.absHref, false, function (status, content) { H5AI.connector.fetchStatusAndContent(path.absHref, false, function (status, content) {
path.status = status; path.status = status;
path.content = content; path.content = content;
path.treeOpen = true; path.treeOpen = true;
$("#tree").get(0).updateScrollbar(true); $("#tree").get(0).updateScrollbar(true);
updateTreeHtml(path); updateTreeHtml(path);
$("#tree").get(0).updateScrollbar(); $("#tree").get(0).updateScrollbar();
}); });
} else if ($indicator.hasClass("open")) { } else if ($indicator.hasClass("open")) {
path.treeOpen = false; path.treeOpen = false;
$indicator.removeClass("open"); $indicator.removeClass("open");
$("#tree").get(0).updateScrollbar(true); $("#tree").get(0).updateScrollbar(true);
$entry.find("> ul.content").slideUp(function() { $entry.find("> ul.content").slideUp(function() {
$("#tree").get(0).updateScrollbar(); $("#tree").get(0).updateScrollbar();
}); });
} else { } else {
path.treeOpen = true; path.treeOpen = true;
$indicator.addClass("open"); $indicator.addClass("open");
$("#tree").get(0).updateScrollbar(true); $("#tree").get(0).updateScrollbar(true);
$entry.find("> ul.content").slideDown(function() { $entry.find("> ul.content").slideDown(function() {
$("#tree").get(0).updateScrollbar(); $("#tree").get(0).updateScrollbar();
}); });
} }
}); });
if (path.status === undefined) { if (path.status === undefined) {
$indicator.addClass("unknown"); $indicator.addClass("unknown");
} else if (path.treeOpen) { } else if (path.treeOpen) {
$indicator.addClass("open"); $indicator.addClass("open");
} }
$blank.replaceWith($indicator); $blank.replaceWith($indicator);
} }
// is path the domain? // is path the domain?
if (path.isDomain) { if (path.isDomain) {
$html.addClass("domain"); $html.addClass("domain");
$a.find(".icon img").attr("src", H5AI.core.icon("folder-home")); $a.find(".icon img").attr("src", H5AI.core.icon("folder-home"));
} }
// is path the current folder? // is path the current folder?
if (path.isCurrentFolder) { if (path.isCurrentFolder) {
$html.addClass("current"); $html.addClass("current");
$a.find(".icon img").attr("src", H5AI.core.icon("folder-open")); $a.find(".icon img").attr("src", H5AI.core.icon("folder-open"));
} }
// does it have subfolders? // does it have subfolders?
if (!path.isEmpty()) { if (!path.isEmpty()) {
$ul = $("<ul class='content' />").appendTo($html); $ul = $("<ul class='content' />").appendTo($html);
$.each(path.content, function (idx, entry) { $.each(path.content, function (idx, entry) {
$("<li />").append(updateTreeHtml(entry)).appendTo($ul); $("<li />").append(updateTreeHtml(entry)).appendTo($ul);
}); });
if (path.status === undefined || !path.treeOpen) { if (path.status === undefined || !path.treeOpen) {
$ul.hide(); $ul.hide();
} }
} }
// reflect folder status // reflect folder status
if (!isNaN(path.status)) { if (!isNaN(path.status)) {
if (path.status === 200) { if (path.status === 200) {
$a.find(".icon img").attr("src", H5AI.core.icon("folder-page")); $a.find(".icon img").attr("src", H5AI.core.icon("folder-page"));
$a.append($("<span class='hint'><img src='" + H5AI.core.image("page") + "' /></span>")); $a.append($("<span class='hint'><img src='" + H5AI.core.image("page") + "' /></span>"));
} else { } else {
$html.addClass("error"); $html.addClass("error");
$a.append($("<span class='hint'>" + path.status + "</span>")); $a.append($("<span class='hint'>" + path.status + "</span>"));
} }
} }
} }
if (path.html.$tree) { if (path.html.$tree) {
path.html.$tree.replaceWith($html); path.html.$tree.replaceWith($html);
} }
path.html.$tree = $html; path.html.$tree = $html;
return $html; return $html;
}, },
updateHtml = function (path) { updateHtml = function (path) {
updateCrumbHtml(path); updateCrumbHtml(path);
updateExtendedHtml(path); updateExtendedHtml(path);
updateTreeHtml(path); updateTreeHtml(path);
}; };
return { return {
updateCrumbHtml: updateCrumbHtml, updateCrumbHtml: updateCrumbHtml,
updateExtendedHtml: updateExtendedHtml, updateExtendedHtml: updateExtendedHtml,
updateTreeHtml: updateTreeHtml, updateTreeHtml: updateTreeHtml,
updateHtml: updateHtml updateHtml: updateHtml
}; };
}()); }());
}(jQuery, H5AI)); }(jQuery, H5AI));

View File

@@ -1,95 +1,95 @@
(function (document, $, H5AI) { (function (document, $, H5AI) {
H5AI.Path = function (folder, tableRow) { H5AI.Path = function (folder, tableRow) {
var path = {}, var path = {},
$tds, $a, date, size, splits; $tds, $a, date, size, splits;
// path.parentFolder: undefined // path.parentFolder: undefined
// path.label: undefined // path.label: undefined
// path.type: undefined // path.type: undefined
// path.href: undefined // path.href: undefined
// path.time: undefined // path.time: undefined
// path.size: undefined // path.size: undefined
// path.absHref: undefined // path.absHref: undefined
// path.isFolder: undefined // path.isFolder: undefined
// path.isParentFolder: undefined // path.isParentFolder: undefined
// path.isCurrentFolder: undefined // path.isCurrentFolder: undefined
// path.isDomain: undefined // path.isDomain: undefined
path.status = undefined; // undefined, "h5ai" or HTTP response code path.status = undefined; // undefined, "h5ai" or HTTP response code
path.content = undefined; // associative array path.absHref -> path path.content = undefined; // associative array path.absHref -> path
path.html = { path.html = {
$crumb: undefined, $crumb: undefined,
$extended: undefined, $extended: undefined,
$tree: undefined $tree: undefined
}; };
path.treeOpen = false; path.treeOpen = false;
if (!H5AI.util.pathEndsWithSlash(folder)) { if (!H5AI.util.pathEndsWithSlash(folder)) {
folder += "/"; folder += "/";
} }
if (tableRow) { if (tableRow) {
$tds = $(tableRow).find("td"); $tds = $(tableRow).find("td");
$a = $tds.eq(1).find("a"); $a = $tds.eq(1).find("a");
date = Date.parse($tds.eq(2).text()); date = Date.parse($tds.eq(2).text());
size = H5AI.util.parseSize($tds.eq(3).text()); size = H5AI.util.parseSize($tds.eq(3).text());
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;
} else { } else {
splits = H5AI.util.splitPath(folder); splits = H5AI.util.splitPath(folder);
path.parentFolder = splits.parent || ""; path.parentFolder = splits.parent || "";
path.label = H5AI.util.checkedDecodeUri(splits.name); path.label = H5AI.util.checkedDecodeUri(splits.name);
if (path.label === "/") { if (path.label === "/") {
path.label = H5AI.util.checkedDecodeUri(document.domain); path.label = H5AI.util.checkedDecodeUri(document.domain);
} }
path.type = "folder"; path.type = "folder";
path.href = splits.name; path.href = splits.name;
path.time = 0; path.time = 0;
path.size = -1; path.size = -1;
} }
if (H5AI.util.pathEndsWithSlash(path.label)) { if (H5AI.util.pathEndsWithSlash(path.label)) {
path.label = path.label.slice(0, -1); path.label = path.label.slice(0, -1);
} }
path.isFolder = (path.type === "folder"); path.isFolder = (path.type === "folder");
path.isParentFolder = (path.label === "Parent Directory"); path.isParentFolder = (path.label === "Parent Directory");
if (path.isParentFolder) { if (path.isParentFolder) {
path.isFolder = true; path.isFolder = true;
path.type = "folder-parent"; path.type = "folder-parent";
} }
path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href; path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href;
path.isCurrentFolder = (path.absHref === document.location.pathname); path.isCurrentFolder = (path.absHref === document.location.pathname);
path.isDomain = (path.absHref === "/"); path.isDomain = (path.absHref === "/");
if (path.isParentFolder && H5AI.core.settings.setParentFolderLabels) { if (path.isParentFolder && H5AI.core.settings.setParentFolderLabels) {
if (path.isDomain) { if (path.isDomain) {
path.label = H5AI.util.checkedDecodeUri(document.domain); path.label = H5AI.util.checkedDecodeUri(document.domain);
} else { } else {
splits = H5AI.util.splitPath(path.parentFolder); splits = H5AI.util.splitPath(path.parentFolder);
path.label = H5AI.util.checkedDecodeUri(splits.parentname); path.label = H5AI.util.checkedDecodeUri(splits.parentname);
} }
} }
path.isEmpty = function () { path.isEmpty = function () {
return !path.content || $.isEmptyObject(path.content); return !path.content || $.isEmptyObject(path.content);
}; };
path.onClick = function (context) { path.onClick = function (context) {
H5AI.core.triggerPathClick(path, context); H5AI.core.triggerPathClick(path, context);
}; };
return path; return path;
}; };
}(document, jQuery, H5AI)); }(document, jQuery, H5AI));

View File

@@ -1,157 +1,158 @@
(function ($, H5AI) { (function ($, H5AI) {
H5AI.sort = (function () { H5AI.sort = (function () {
var type = function (entry) { var type = function (entry) {
var $entry = $(entry); var $entry = $(entry);
if ($entry.hasClass("folder-parent")) { if ($entry.hasClass("folder-parent")) {
return 0; return 0;
} else if ($entry.hasClass("folder")) { } else if ($entry.hasClass("folder")) {
return 1; return 1;
} }
return 2; return 2;
}, },
cmp = function (entry1, entry2, rev, getVal) { cmp = function (entry1, entry2, rev, getVal) {
var res, val1, val2; var res, val1, val2;
res = type(entry1) - type(entry2); res = type(entry1) - type(entry2);
if (res !== 0) { if (res !== 0) {
return res; return res;
} }
val1 = getVal(entry1); val1 = getVal(entry1);
val2 = getVal(entry2); val2 = getVal(entry2);
if (val1 < val2) { if (val1 < val2) {
return rev ? 1 : -1; return rev ? 1 : -1;
} else if (val1 > val2) { } else if (val1 > val2) {
return rev ? -1 : 1; return rev ? -1 : 1;
} }
return 0; return 0;
}, },
cmpName = function (entry1, entry2) { cmpName = function (entry1, entry2) {
return cmp(entry1, entry2, false, function (entry) { return cmp(entry1, entry2, false, function (entry) {
return $(entry).find(".label").text().toLowerCase(); return $(entry).find(".label").text().toLowerCase();
}); });
}, },
cmpTime = function (entry1, entry2) { cmpTime = function (entry1, entry2) {
return cmp(entry1, entry2, false, function (entry) { return cmp(entry1, entry2, false, function (entry) {
return $(entry).find(".date").data("time"); return $(entry).find(".date").data("time");
}); });
}, },
cmpSize = function (entry1, entry2) { cmpSize = function (entry1, entry2) {
return cmp(entry1, entry2, false, function (entry) { return cmp(entry1, entry2, false, function (entry) {
return $(entry).find(".size").data("bytes"); return $(entry).find(".size").data("bytes");
}); });
}, },
cmpNameRev = function (entry1, entry2) { cmpNameRev = function (entry1, entry2) {
return cmp(entry1, entry2, true, function (entry) { return cmp(entry1, entry2, true, function (entry) {
return $(entry).find(".label").text().toLowerCase(); return $(entry).find(".label").text().toLowerCase();
}); });
}, },
cmpTimeRev = function (entry1, entry2) { cmpTimeRev = function (entry1, entry2) {
return cmp(entry1, entry2, true, function (entry) { return cmp(entry1, entry2, true, function (entry) {
return $(entry).find(".date").data("time"); return $(entry).find(".date").data("time");
}); });
}, },
cmpSizeRev = function (entry1, entry2) { cmpSizeRev = function (entry1, entry2) {
return cmp(entry1, entry2, true, function (entry) { return cmp(entry1, entry2, true, function (entry) {
return $(entry).find(".size").data("bytes"); return $(entry).find(".size").data("bytes");
}); });
}, },
sort = function (fn) { sort = function (fn) {
$("#extended .entry").detach().sort(fn).appendTo($("#extended > ul")); $("#extended .entry").detach().sort(fn).appendTo($("#extended > ul"));
}, },
$all, orders, $all, orders,
sortBy = function (id) { sortBy = function (id) {
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"),
$size = $header.find("a.size"); $size = $header.find("a.size");
$all = $header.find("a.label,a.date,a.size"); $all = $header.find("a.label,a.date,a.size");
orders = { orders = {
na: { na: {
head: $label, head: $label,
clas: "ascending", clas: "ascending",
fn: cmpName fn: cmpName
}, },
nd: { nd: {
head: $label, head: $label,
clas: "descending", clas: "descending",
fn: cmpNameRev fn: cmpNameRev
}, },
da: { da: {
head: $date, head: $date,
clas: "ascending", clas: "ascending",
fn: cmpTime fn: cmpTime
}, },
dd: { dd: {
head: $date, head: $date,
clas: "descending", clas: "descending",
fn: cmpTimeRev fn: cmpTimeRev
}, },
sa: { sa: {
head: $size, head: $size,
clas: "ascending", clas: "ascending",
fn: cmpSize fn: cmpSize
}, },
sd: { sd: {
head: $size, head: $size,
clas: "descending", clas: "descending",
fn: cmpSizeRev fn: cmpSizeRev
} }
}; };
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 (event) {
.click(function () { 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 (event) {
.click(function () { 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 (event) {
.click(function () { sortBy("s" + ($size.hasClass("ascending") ? "d" : "a"));
sortBy("s" + ($size.hasClass("ascending") ? "d" : "a")); event.preventDefault();
}); });
}; };
return { return {
init: init init: init
}; };
}()); }());
}(jQuery, H5AI)); }(jQuery, H5AI));

View File

@@ -1,115 +1,120 @@
(function ($, H5AI) { (function ($, H5AI) {
H5AI.util = (function () { H5AI.util = (function () {
var reSplitPath = /^\/([^\/]+\/?)$/, var reSplitPath = /^\/([^\/]+\/?)$/,
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/, reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
splitPath = function (pathname) { splitPath = function (pathname) {
var match; var match;
if (pathname === "/") { if (pathname === "/") {
return { return {
parent: null, parent: null,
parentname: null, parentname: null,
name: "/" name: "/"
}; };
} }
match = reSplitPath2.exec(pathname); match = reSplitPath2.exec(pathname);
if (match) { if (match) {
return { return {
parent: match[1], parent: match[1],
parentname: match[2], parentname: match[2],
name: match[3] name: match[3]
}; };
} }
match = reSplitPath.exec(pathname); match = reSplitPath.exec(pathname);
if (match) { if (match) {
return { return {
parent: "/", parent: "/",
parentname: "/", parentname: "/",
name: match[1] name: match[1]
}; };
} }
}, },
rePathEndsWithSlash = /\/$/, rePathEndsWithSlash = /\/$/,
pathEndsWithSlash = function (pathname) { pathEndsWithSlash = function (pathname) {
return rePathEndsWithSlash.test(pathname); return rePathEndsWithSlash.test(pathname);
}, },
getAbsHref = function (folder, tableRow) { getAbsHref = function (folder, tableRow) {
var $a, isParentFolder, href; var $a, isParentFolder, href;
if (!pathEndsWithSlash(folder)) { if (!pathEndsWithSlash(folder)) {
folder += "/"; folder += "/";
} }
if (!tableRow) { if (!tableRow) {
return folder; return folder;
} }
$a = $(tableRow).find("td").eq(1).find("a"); $a = $(tableRow).find("td").eq(1).find("a");
isParentFolder = ($a.text() === "Parent Directory"); isParentFolder = ($a.text() === "Parent Directory");
href = $a.attr("href"); href = $a.attr("href");
return isParentFolder ? undefined : folder + href; return isParentFolder ? undefined : folder + href;
}, },
kilo = 1000.0, kilo = 1000.0,
reParseSize = /^\s*([\.\d]+)\s*([kmg]?)b?\s*$/i, reParseSize = /^\s*([\.\d]+)\s*([kmg]?)b?\s*$/i,
parseSize = function (str) { parseSize = function (str) {
var match = reParseSize.exec(str), var match = reParseSize.exec(str),
val, unit; val, unit;
if (!match) { if (!match) {
return -1; return -1;
} }
val = parseFloat(match[1]); val = parseFloat(match[1]);
unit = match[2].toLowerCase(); unit = match[2].toLowerCase();
if (unit === "k") { if (unit === "k") {
val *= kilo; val *= kilo;
} else if (unit === "m") { } else if (unit === "m") {
val *= kilo * kilo; val *= kilo * kilo;
} else if (unit === "g") { } else if (unit === "g") {
val *= kilo * kilo * kilo; val *= kilo * kilo * kilo;
} else if (unit === "t") { } else if (unit === "t") {
val *= kilo * kilo * kilo * kilo; val *= kilo * kilo * kilo * kilo;
} }
return val; return val;
}, },
sizeUnits = ["B", "KB", "MB", "GB", "TB"], sizeUnits = ["B", "KB", "MB", "GB", "TB"],
formatSize = function (size) { formatSize = function (size) {
var th = 1000.0, var th = 1000.0,
i = 0, i = 0,
maxI = sizeUnits.length - 1; maxI = sizeUnits.length - 1;
if (isNaN(size)) { if (isNaN(size)) {
return size; return size;
} }
while (size >= th && i < maxI) { while (size >= th && i < maxI) {
size /= kilo; size /= kilo;
i += 1; i += 1;
} }
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + " " + sizeUnits[i]; return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + " " + sizeUnits[i];
}, },
checkedDecodeUri = function (uri) { checkedDecodeUri = function (uri) {
try { try {
return decodeURI(uri); return decodeURI(uri);
} catch (err) {} } catch (err) {}
return uri; return uri;
}; },
reEscape = function (sequence) {
return { return sequence.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
splitPath: splitPath, };
pathEndsWithSlash: pathEndsWithSlash,
getAbsHref: getAbsHref, return {
parseSize: parseSize, splitPath: splitPath,
formatSize: formatSize, pathEndsWithSlash: pathEndsWithSlash,
checkedDecodeUri: checkedDecodeUri getAbsHref: getAbsHref,
}; parseSize: parseSize,
}()); formatSize: formatSize,
checkedDecodeUri: checkedDecodeUri,
reEscape: reEscape
};
}());
}(jQuery, H5AI)); }(jQuery, H5AI));

View File

@@ -1,110 +1,191 @@
(function ($, H5AI) { (function ($, H5AI) {
H5AI.zippedDownload = (function () { H5AI.zippedDownload = (function () {
var x = 0, var x = 0,
y = 0, y = 0,
$document = $(document), $document = $(document),
$selectionRect = $("#selection-rect"), $selectionRect = $("#selection-rect"),
updateDownloadBtn = function () { selectedHrefsStr = "",
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
var $selected = $("#extended a.selected"), updateDownloadBtn = function () {
$downloadBtn = $("#download"),
query, href;
if ($selected.size() > 0) { var $selected = $("#extended a.selected"),
$selected.each(function () { $downloadBtn = $("#download");
href = $(this).attr("href");
query = query ? query + ":" + href : href;
});
query = H5AI.core.api() + "?action=zip&hrefs=" + query;
$downloadBtn.show().find("a").attr("href", query);
} else {
$downloadBtn.hide().find("a").attr("href", "#");
}
},
selectionUpdate = function (event) {
var l = Math.min(x, event.pageX), selectedHrefsStr = "";
t = Math.min(y, event.pageY), if ($selected.length) {
w = Math.abs(x - event.pageX), $selected.each(function () {
h = Math.abs(y - event.pageY),
selRect;
event.preventDefault(); var href = $(this).attr("href");
$selectionRect.css({left: l, top: t, width: w, height: h}); selectedHrefsStr = selectedHrefsStr ? selectedHrefsStr + ":" + href : href;
});
$downloadBtn.show();
} else {
$downloadBtn.hide();
$downloadAuth.hide();
}
},
selectionUpdate = function (event) {
selRect = $selectionRect.fracs("rect"); var l = Math.min(x, event.pageX),
$("#extended a").removeClass("selecting").each(function () { t = Math.min(y, event.pageY),
w = Math.abs(x - event.pageX),
h = Math.abs(y - event.pageY),
selRect;
var $a = $(this), event.preventDefault();
rect = $a.fracs("rect"), $selectionRect.css({left: l, top: t, width: w, height: h});
inter = selRect.intersection(rect);
if (inter && !$a.closest(".entry").hasClass("folder-parent")) {
$a.addClass("selecting");
}
});
},
selectionEnd = function (event) {
event.preventDefault(); selRect = $selectionRect.fracs("rect");
$document.off("mousemove", selectionUpdate); $("#extended a").removeClass("selecting").each(function () {
$selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
$("#extended a.selecting.selected").removeClass("selecting").removeClass("selected");
$("#extended a.selecting").removeClass("selecting").addClass("selected");
updateDownloadBtn();
},
selectionStart = function (event) {
var view = $.fracs.viewport(); var $a = $(this),
rect = $a.fracs("rect"),
inter = selRect.intersection(rect);
if (inter && !$a.closest(".entry").hasClass("folder-parent")) {
$a.addClass("selecting");
}
});
},
selectionEnd = function (event) {
x = event.pageX; event.preventDefault();
y = event.pageY; $document.off("mousemove", selectionUpdate);
// only on left button and don't block the scrollbars $selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
if (event.button !== 0 || x >= view.right || y >= view.bottom) { $("#extended a.selecting.selected").removeClass("selecting").removeClass("selected");
return; $("#extended a.selecting").removeClass("selecting").addClass("selected");
} updateDownloadBtn();
},
selectionStart = function (event) {
event.preventDefault(); var view = $.fracs.viewport();
if (!event.ctrlKey) {
$("#extended a").removeClass("selected");
updateDownloadBtn();
}
$selectionRect.show().css({left: x, top: y, width: 0, height: 0});
selectionUpdate(event);
$document x = event.pageX;
.on("mousemove", selectionUpdate) y = event.pageY;
.one("mouseup", selectionEnd); // only on left button and don't block the scrollbars
}, if (event.button !== 0 || x >= view.right || y >= view.bottom) {
noSelection = function (event) { return;
}
event.stopPropagation(); event.preventDefault();
return false; $(':focus').blur();
}, if (!event.ctrlKey) {
noSelectionUnlessCtrl = function (event) { $("#extended a").removeClass("selected");
updateDownloadBtn();
}
$selectionRect.show().css({left: x, top: y, width: 0, height: 0});
if (!event.ctrlKey) { $document
noSelection(event); .on("mousemove", selectionUpdate)
} .one("mouseup", selectionEnd);
}, },
init = function () { noSelection = function (event) {
if (H5AI.core.settings.zippedDownload) { event.stopImmediatePropagation();
$("<li id='download'><a href='#'><img alt='download' /><span class='l10n-download'>download</span></a></li>") return false;
.find("img").attr("src", H5AI.core.image("download")).end() },
.appendTo($("#navbar")); noSelectionUnlessCtrl = function (event) {
$("body>nav,body>footer,#tree").on("mousedown", noSelection); if (!event.ctrlKey) {
$("#extended").on("mousedown", "a", noSelectionUnlessCtrl); noSelection(event);
$document.on("mousedown", selectionStart); }
} },
}; failed = function () {
return { $download.addClass('failed');
init: init 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 () {
if (H5AI.core.settings.zippedDownload) {
$("<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("a").click(function (event) {
event.preventDefault();
$downloadAuth.hide();
requestZipping(selectedHrefsStr);
}).end()
.appendTo($("#navbar"));
$("<div id='download-auth'><input id='download-auth-user' type='text' value='' placeholder='user' /><input id='download-auth-password' type='text' value='' placeholder='password' /></div>")
.appendTo($("body"));
$download = $('#download');
$downloadAuth = $('#download-auth');
$downloadUser = $('#download-auth-user');
$downloadPassword = $('#download-auth-password');
$img = $download.find('img');
$("body>nav,body>footer,#tree,input").on("mousedown", noSelection);
$("#content").on("mousedown", "a", noSelectionUnlessCtrl);
$document.on("mousedown", selectionStart);
}
};
return {
init: init
};
}());
}(jQuery, H5AI)); }(jQuery, H5AI));

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

@@ -6,7 +6,7 @@
* Thanks to: Seamus Leahy for adding deltaX and deltaY * Thanks to: Seamus Leahy for adding deltaX and deltaY
* *
* Version: 3.0.5 * Version: 3.0.5
* *
* Requires: 1.2.2+ * Requires: 1.2.2+
*/ */
@@ -15,73 +15,70 @@
var types = ['DOMMouseScroll', 'mousewheel']; var types = ['DOMMouseScroll', 'mousewheel'];
if ($.event.fixHooks) { if ($.event.fixHooks) {
for ( var i=types.length; i; ) { for ( var i=types.length; i; ) {
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks; $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
} }
} }
$.event.special.mousewheel = { $.event.special.mousewheel = {
setup: function() { setup: function() {
if ( this.addEventListener ) { if ( this.addEventListener ) {
for ( var i=types.length; i; ) { for ( var i=types.length; i; ) {
this.addEventListener( types[--i], handler, false ); this.addEventListener( types[--i], handler, false );
} }
} else { } else {
this.onmousewheel = handler; this.onmousewheel = handler;
} }
}, },
teardown: function() { teardown: function() {
if ( this.removeEventListener ) { if ( this.removeEventListener ) {
for ( var i=types.length; i; ) { for ( var i=types.length; i; ) {
this.removeEventListener( types[--i], handler, false ); this.removeEventListener( types[--i], handler, false );
} }
} else { } else {
this.onmousewheel = null; this.onmousewheel = null;
} }
} }
}; };
$.fn.extend({ $.fn.extend({
mousewheel: function(fn) { mousewheel: function(fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
}, },
unmousewheel: function(fn) { unmousewheel: function(fn) {
return this.unbind("mousewheel", fn); return this.unbind("mousewheel", fn);
} }
}); });
function handler(event) { function handler(event) {
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent); event = $.event.fix(orgEvent);
event.type = "mousewheel"; event.type = "mousewheel";
// Old school scrollwheel delta // Old school scrollwheel delta
if ( event.wheelDelta ) { delta = event.wheelDelta/120; } if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
if ( event.detail ) { delta = -event.detail/3; } if ( event.detail ) { delta = -event.detail/3; }
// New school multidimensional scroll (touchpads) deltas // New school multidimensional scroll (touchpads) deltas
deltaY = delta; deltaY = delta;
// Gecko // Gecko
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaY = 0; deltaY = 0;
deltaX = -1*delta; deltaX = -1*delta;
} }
// Webkit // Webkit
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
// Add event and delta to the front of the arguments // Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY); args.unshift(event, delta, deltaX, deltaY);
return ($.event.dispatch || $.event.handle).apply(this, args); return ($.event.dispatch || $.event.handle).apply(this, args);
} }
})(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

@@ -2,156 +2,155 @@
* jQuery.scrollpanel * jQuery.scrollpanel
* 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";
var $window = $(window), var $window = $(window),
init = function (htmlElement) { init = function (htmlElement) {
var $element = $(htmlElement), var $element = $(htmlElement),
$scrollbar, $drag, $wrapper, $content, mouseOffsetY, updateId, $scrollbar, $drag, $wrapper, $content, mouseOffsetY, updateId,
update, scroll; update, scroll;
if (!$element.css("position") || $element.css("position") === "static") { if (!$element.css("position") || $element.css("position") === "static") {
$element.css("position", "relative"); $element.css("position", "relative");
} }
$scrollbar = $("<div class='scrollbar' />"); $scrollbar = $("<div class='scrollbar' />");
$drag = $("<div class='drag' />").appendTo($scrollbar); $drag = $("<div class='drag' />").appendTo($scrollbar);
$element $element
.wrapInner("<div class='wrapper'><div class='content' /></div>") .wrapInner("<div class='wrapper'><div class='content' /></div>")
.append($scrollbar); .append($scrollbar);
$wrapper = $element.find("> .wrapper"); $wrapper = $element.find("> .wrapper");
$content = $wrapper.find("> .content"); $content = $wrapper.find("> .content");
mouseOffsetY = 0; mouseOffsetY = 0;
update = function (repeat) { update = function (repeat) {
var visibleHeight, contentHeight, scrollTop, scrollTopFrac, visVertFrac; var visibleHeight, contentHeight, scrollTop, scrollTopFrac, visVertFrac;
if (updateId && !repeat) { if (updateId && !repeat) {
clearInterval(updateId); clearInterval(updateId);
updateId = undefined; updateId = undefined;
} else if (!updateId && repeat) { } else if (!updateId && repeat) {
updateId = setInterval(function() { update(true); }, 50); updateId = setInterval(function() { update(true); }, 50);
} }
$wrapper.css("height", $element.height()); $wrapper.css("height", $element.height());
visibleHeight = $element.height(); visibleHeight = $element.height();
contentHeight = $content.outerHeight(); contentHeight = $content.outerHeight();
scrollTop = $wrapper.scrollTop(); scrollTop = $wrapper.scrollTop();
scrollTopFrac = scrollTop / contentHeight; scrollTopFrac = scrollTop / contentHeight;
visVertFrac = Math.min(visibleHeight / contentHeight, 1); visVertFrac = Math.min(visibleHeight / contentHeight, 1);
if (visVertFrac < 1) { if (visVertFrac < 1) {
$scrollbar $scrollbar
.fadeIn(50) .fadeIn(50)
.css({ .css({
height: $element.innerHeight() + $scrollbar.height() - $scrollbar.outerHeight(true) height: $element.innerHeight() + $scrollbar.height() - $scrollbar.outerHeight(true)
}); });
$drag $drag
.css({ .css({
top: $scrollbar.height() * scrollTopFrac, top: $scrollbar.height() * scrollTopFrac,
height: $scrollbar.height() * visVertFrac height: $scrollbar.height() * visVertFrac
}); });
} else { } else {
$scrollbar.fadeOut(50); $scrollbar.fadeOut(50);
} }
}; };
scroll = function (event) { scroll = function (event) {
var clickFrac = (event.pageY - $scrollbar.offset().top - mouseOffsetY) / $scrollbar.height(); var clickFrac = (event.pageY - $scrollbar.offset().top - mouseOffsetY) / $scrollbar.height();
$wrapper.scrollTop($content.outerHeight() * clickFrac); $wrapper.scrollTop($content.outerHeight() * clickFrac);
update(); update();
event.preventDefault(); event.preventDefault();
}; };
$element $element
.mousewheel(function (event, delta) { .mousewheel(function (event, delta) {
$wrapper.scrollTop($wrapper.scrollTop() - 50 * delta);
update();
event.stopPropagation();
event.preventDefault();
})
.scroll(update);
$element.get(0).updateScrollbar = update;
$wrapper
.css({
"padding-right": $scrollbar.outerWidth(true),
height: $element.height(),
overflow: "hidden"
});
$scrollbar
.css({
position: "absolute",
top: 0,
right: 0,
overflow: "hidden",
cursor: "pointer"
})
.mousedown(function (event) {
mouseOffsetY = $drag.outerHeight() / 2; $wrapper.scrollTop($wrapper.scrollTop() - 50 * delta);
scroll(event); update();
$scrollbar.addClass("dragOn"); event.stopPropagation();
$window event.preventDefault();
.bind("mousemove", scroll) })
.one("mouseup", function (event) { .scroll(update);
$element.get(0).updateScrollbar = update;
$wrapper
.css({
"padding-right": $scrollbar.outerWidth(true),
height: $element.height(),
overflow: "hidden"
});
$scrollbar
.css({
position: "absolute",
top: 0,
right: 0,
overflow: "hidden",
cursor: "pointer"
})
.mousedown(function (event) {
$scrollbar.removeClass("dragOn"); mouseOffsetY = $drag.outerHeight() / 2;
$window.unbind("mousemove", scroll); scroll(event);
scroll(event); $scrollbar.addClass("dragOn");
event.stopPropagation(); $window
}); .bind("mousemove", scroll)
event.preventDefault(); .one("mouseup", function (event) {
})
.each(function () {
this.onselectstart = function () { $scrollbar.removeClass("dragOn");
$window.unbind("mousemove", scroll);
scroll(event);
event.stopPropagation();
});
event.preventDefault();
})
.each(function () {
return false; this.onselectstart = function () {
};
});
$drag
.css({
position: "absolute",
left: 0,
width: "100%"
})
.mousedown(function (event) {
mouseOffsetY = event.pageY - $drag.offset().top; return false;
scroll(event); };
$scrollbar.addClass("dragOn"); });
$window $drag
.bind("mousemove", scroll) .css({
.one("mouseup", function (event) { position: "absolute",
left: 0,
width: "100%"
})
.mousedown(function (event) {
$scrollbar.removeClass("dragOn"); mouseOffsetY = event.pageY - $drag.offset().top;
$window.unbind("mousemove", scroll); scroll(event);
scroll(event); $scrollbar.addClass("dragOn");
event.stopPropagation(); $window
}); .bind("mousemove", scroll)
event.stopPropagation(); .one("mouseup", function (event) {
});
update(); $scrollbar.removeClass("dragOn");
}; $window.unbind("mousemove", scroll);
scroll(event);
event.stopPropagation();
});
event.stopPropagation();
});
update();
};
$.fn.scrollpanel = function () { $.fn.scrollpanel = function () {
return this.each(function () { return this.each(function () {
init(this); init(this);
}); });
}; };
}(window, jQuery)); }(window, jQuery));

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,125 +1,150 @@
<?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) {
echo "$code: $msg"; echo "$code: $msg";
exit; exit;
} }
} }
function checkKeys($keys) { function checkKeys($keys) {
$values = array(); $values = array();
foreach ($keys as $key) { foreach ($keys as $key) {
fail(1, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST)); fail(1, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST));
$values[] = $_REQUEST[$key]; $values[] = $_REQUEST[$key];
} }
return $values; return $values;
} }
require_h5ai("/php/inc/H5ai.php");
$h5ai = new H5ai();
$options = $h5ai->getOptions();
list($action) = checkKeys(array("action")); list($action) = checkKeys(array("action"));
require_once "config.php";
require_once "inc/H5ai.php";
$h5ai = new H5ai();
$options = $h5ai->getOptions();
if ($action === "httpcodes") { if ($action === "httpcodes") {
list($hrefs) = checkKeys(array("hrefs")); list($hrefs) = checkKeys(array("hrefs"));
function getHttpCodes($h5ai, $hrefs) { function getHttpCodes($h5ai, $hrefs) {
$codes = array(); $codes = array();
foreach ($hrefs as $href) { foreach ($hrefs as $href) {
$href = trim($href); $href = trim($href);
if (strlen($href) > 0) { if (strlen($href) > 0) {
$codes[$href] = $h5ai->getHttpCode($href); $codes[$href] = $h5ai->getHttpCode($href);
} }
} }
return $codes; return $codes;
} }
$hrefs = preg_split("/;/", $hrefs); $hrefs = preg_split("/;/", $hrefs);
$codes = getHttpCodes($h5ai, $hrefs); $codes = getHttpCodes($h5ai, $hrefs);
echo count($codes) === 0 ? "{}" : json_encode($codes); echo count($codes) === 0 ? "{}" : json_encode($codes);
} }
else if ($action === "thumb") { 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);
exit; exit;
} }
$thumbnail = new Thumbnail($h5ai, $srcAbsHref, $mode, $width, $height); $thumbnail = new Thumbnail($h5ai, $srcAbsHref, $mode, $width, $height);
$thumbnail->create(1); $thumbnail->create(1);
if (file_exists($thumbnail->getPath())) { if (file_exists($thumbnail->getPath())) {
Image::showImage($thumbnail->getPath()); Image::showImage($thumbnail->getPath());
} else { } else {
$image = new Image(); $image = new Image();
$image->setSource($srcAbsPath); $image->setSource($srcAbsPath);
$image->thumb($mode, $width, $height); $image->thumb($mode, $width, $height);
$image->showDest(); $image->showDest();
} }
} }
else if ($action === "tree") { 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);
$tree = new TreeEntry($h5ai, $absPath, $absHref); $tree = new TreeEntry($h5ai, $absPath, $absHref);
$tree->loadContent(); $tree->loadContent();
echo $tree->contentToHtml(); echo $tree->contentToHtml();
} }
else if ($action === "zip") { 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);
}
header("Content-Disposition: attachment; filename=\"h5ai-selection.zip\"");
header("Content-Type: application/force-download"); else if ($action === "getzip") {
header("Content-Length: " . filesize($zipFile));
header("Connection: close"); list($id) = checkKeys(array("id"));
readfile($zipFile); 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-Type: application/octet-stream");
header("Content-Length: " . filesize($zipFile));
header("Connection: close");
readfile($zipFile);
} }
else { else {
fail(1, "unsupported 'action' specified"); fail(1, "unsupported 'action' specified");
} }

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,87 +7,93 @@
############################################## ##############################################
class Cache { class Cache {
private $dir;
function __construct($dir) { private $dir;
$this->dir = $dir;
}
private function _name($key) { function __construct($dir) {
return $this->dir . "/" . sha1($key); $this->dir = $dir;
} }
public function get($key, $expiration = 3600) {
if (!is_dir($this->dir) || !is_writable($this->dir)) { private function _name($key) {
return false;
}
$cache_path = $this->_name($key); return $this->dir . "/" . sha1($key);
}
if (!@file_exists($cache_path)) {
return false;
}
if (filemtime($cache_path) < (time() - $expiration)) { public function get($key, $expiration = 3600) {
$this->clear($key);
return false;
}
if (!$fp = @fopen($cache_path, "rb")) { if (!is_dir($this->dir) || !is_writable($this->dir)) {
return false; return false;
} }
flock($fp, LOCK_SH); $cache_path = $this->_name($key);
$cache = "";
if (filesize($cache_path) > 0) { if (!@file_exists($cache_path)) {
$cache = unserialize(fread($fp, filesize($cache_path))); return false;
} else { }
$cache = null;
}
flock($fp, LOCK_UN); if (filemtime($cache_path) < (time() - $expiration)) {
fclose($fp); $this->clear($key);
return false;
}
return $cache; if (!$fp = @fopen($cache_path, "rb")) {
} return false;
}
public function set($key, $data) { flock($fp, LOCK_SH);
$cache = "";
if (!is_dir($this->dir) || !is_writable($this->dir)) { if (filesize($cache_path) > 0) {
return false; $cache = unserialize(fread($fp, filesize($cache_path)));
} } else {
$cache = null;
}
$cache_path = $this->_name($key); flock($fp, LOCK_UN);
fclose($fp);
if (! $fp = fopen($cache_path, "wb")) { return $cache;
return false; }
}
if (flock($fp, LOCK_EX)) {
fwrite($fp, serialize($data));
flock($fp, LOCK_UN);
} else {
return false;
}
fclose($fp);
@chmod($cache_path, 0777);
return true;
}
public function clear($key) { public function set($key, $data) {
$cache_path = $this->_name($key); if (!is_dir($this->dir) || !is_writable($this->dir)) {
return false;
}
if (file_exists($cache_path)) { $cache_path = $this->_name($key);
unlink($cache_path);
return true; if (! $fp = fopen($cache_path, "wb")) {
} return false;
return false; }
}
if (flock($fp, LOCK_EX)) {
fwrite($fp, serialize($data));
flock($fp, LOCK_UN);
} else {
return false;
}
fclose($fp);
@chmod($cache_path, 0777);
return true;
}
public function clear($key) {
$cache_path = $this->_name($key);
if (file_exists($cache_path)) {
unlink($cache_path);
return true;
}
return false;
}
} }
?> ?>

View File

@@ -1,52 +1,55 @@
<?php <?php
class Crumb { class Crumb {
private $h5ai, $parts;
public function __construct($h5ai) { private $h5ai, $parts;
$this->h5ai = $h5ai;
$this->parts = array();
$href = $h5ai->getAbsHref(); public function __construct($h5ai) {
while ($href !== "/" && $href !== "//") {
$this->parts[] = $href;
$href = dirname($href) . "/";
}
$this->parts[] = "/";
$this->parts = array_reverse($this->parts); $this->h5ai = $h5ai;
} $this->parts = array();
public function toHtml() { $href = $h5ai->getAbsHref();
while ($href !== "/") {
$this->parts[] = $href;
$href = safe_dirname($href, true);
}
$this->parts[] = "/";
$html = ""; $this->parts = array_reverse($this->parts);
$idx = 0; }
foreach($this->parts as $href) {
$idx++;
$classes = "crumb folder" . ($idx === 1 ? " domain" : "") . ($idx === count($this->parts) ? " current" : "");
$image = $this->h5ai->image($idx === 1 ? "home" : "crumb");
$label = $this->h5ai->getLabel($href);
$hint = "";
$code = $this->h5ai->getHttpCode($href);
$classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$hint = "<img class='hint' src='" . $this->h5ai->image("page") . "' alt='page' />";
} else {
$hint = "<span class='hint'>(" . $code . ")</span>";
}
}
$html .= "<li class='$classes'>\n"; public function toHtml() {
$html .= "\t<a href='$href'>\n";
$html .= "\t\t<img src='$image' alt='>' /><span>" . $label . "</span>" . $hint . "\n"; $html = "";
$html .= "\t</a>\n"; $idx = 0;
$html .= "</li>\n"; foreach($this->parts as $href) {
} $idx++;
return $html; $classes = "crumb folder" . ($idx === 1 ? " domain" : "") . ($idx === count($this->parts) ? " current" : "");
} $image = $this->h5ai->image($idx === 1 ? "home" : "crumb");
$label = $this->h5ai->getLabel($href);
$hint = "";
$code = $this->h5ai->getHttpCode($href);
$classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$hint = "<img class='hint' src='" . $this->h5ai->image("page") . "' alt='page' />";
} else {
$hint = "<span class='hint'>(" . $code . ")</span>";
}
}
$html .= "<li class='$classes'>\n";
$html .= "\t<a href='$href'>\n";
$html .= "\t\t<img src='$image' alt='>' /><span>" . $label . "</span>" . $hint . "\n";
$html .= "\t</a>\n";
$html .= "</li>\n";
}
return $html;
}
} }
?> ?>

View File

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

View File

@@ -1,144 +1,152 @@
<?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;
public function __construct($h5ai, $absPath, $absHref, $type = null, $label = null) { private $h5ai, $label, $absPath, $absHref, $date, $isFolder, $type, $size;
$this->h5ai = $h5ai;
$this->label = $label !== null ? $label : $this->h5ai->getLabel($absHref);
$this->absPath = $this->h5ai->normalizePath($absPath, false);
$this->isFolder = is_dir($this->absPath);
$this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
$this->date = filemtime($this->absPath); public function __construct($h5ai, $absPath, $absHref, $type = null, $label = null) {
if ($this->isFolder) { $this->h5ai = $h5ai;
$this->type = $type !== null ? $type : "folder"; $this->label = $label !== null ? $label : $this->h5ai->getLabel($absHref);
$this->size = ""; $this->absPath = $this->h5ai->normalizePath($absPath, false);
} else { $this->isFolder = is_dir($this->absPath);
$this->type = $type !== null ? $type : $this->h5ai->getType($this->absPath); $this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
$this->size = filesize($this->absPath);
}
$this->thumbTypes = array("bmp", "gif", "ico", "image", "jpg", "png", "tiff"); $this->date = filemtime($this->absPath);
}
public function isFolder() { if ($this->isFolder) {
$this->type = $type !== null ? $type : "folder";
$this->size = "";
} else {
$this->type = $type !== null ? $type : $this->h5ai->getType($this->absPath);
$this->size = filesize($this->absPath);
}
}
return $this->isFolder;
}
public function toHtml() { public function isFolder() {
$classes = "entry " . ($this->isFolder ? "folder " : "file ") . $this->type; return $this->isFolder;
$imgClass = ""; }
$img = $this->type;
$smallImg = $this->h5ai->icon($this->type);
$bigImg = $this->h5ai->icon($this->type, true);
$hint = "";
if ($this->isFolder && $this->type !== "folder-parent") {
$code = $this->h5ai->getHttpCode($this->absHref);
$classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$img = "folder-page";
$smallImg = $this->h5ai->icon("folder-page");
$bigImg = $this->h5ai->icon("folder-page", true);
} else {
$classes .= " error";
$hint = "<span class='hint'> " . $code . " </span>";
}
}
}
if ($this->h5ai->showThumbs() && in_array($this->type, $this->thumbTypes)) {
$imgClass = " class='thumb' ";
$thumbnail = new Thumbnail($this->h5ai, $this->absHref, "square", 16, 16);
$thumbnail->create();
$smallImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
$thumbnail = new Thumbnail($this->h5ai,$this->absHref, "rational", 96, 46);
$thumbnail->create();
$bigImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
}
$html = "\t<li class='" . $classes . "'>\n"; public function toHtml() {
$html .= "\t\t<a href='" . $this->absHref . "'>\n";
$html .= "\t\t\t<span class='icon small'><img " . $imgClass . " src='" . $smallImg . "' alt='" . $img . "' /></span>\n"; $classes = "entry " . ($this->isFolder ? "folder " : "file ") . $this->type;
$html .= "\t\t\t<span class='icon big'><img " . $imgClass . " src='" . $bigImg . "' alt='" . $img . "' /></span>\n"; $imgClass = "";
$html .= "\t\t\t<span class='label'>" . $this->label . $hint . "</span>\n"; $img = $this->type;
$html .= "\t\t\t<span class='date' data-time='" . $this->date . "000'></span>\n"; $smallImg = $this->h5ai->icon($this->type);
$html .= "\t\t\t<span class='size' data-bytes='" . $this->size . "'>" . $this->size . "</span>\n"; $bigImg = $this->h5ai->icon($this->type, true);
$html .= "\t\t</a>\n"; $hint = "";
$html .= "\t</li>\n";
return $html; if ($this->isFolder && $this->type !== "folder-parent") {
} $code = $this->h5ai->getHttpCode($this->absHref);
$classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$img = "folder-page";
$smallImg = $this->h5ai->icon("folder-page");
$bigImg = $this->h5ai->icon("folder-page", true);
} else {
$classes .= " error";
$hint = "<span class='hint'> " . $code . " </span>";
}
}
}
if ($this->h5ai->showThumbs() && in_array($this->type, $this->h5ai->getThumbTypes())) {
$imgClass = " class='thumb' ";
$thumbnail = new Thumbnail($this->h5ai, $this->absHref, "square", 16, 16);
$thumbnail->create();
$smallImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
$thumbnail = new Thumbnail($this->h5ai,$this->absHref, "rational", 96, 46);
$thumbnail->create();
$bigImg = file_exists($thumbnail->getPath()) ? $thumbnail->getHref() : $thumbnail->getLiveHref();
}
$html = "\t<li class='" . $classes . "'>\n";
$html .= "\t\t<a href='" . $this->absHref . "'>\n";
$html .= "\t\t\t<span class='icon small'><img " . $imgClass . " src='" . $smallImg . "' alt='" . $img . "' /></span>\n";
$html .= "\t\t\t<span class='icon big'><img " . $imgClass . " src='" . $bigImg . "' alt='" . $img . "' /></span>\n";
$html .= "\t\t\t<span class='label'>" . $this->label . $hint . "</span>\n";
$html .= "\t\t\t<span class='date' data-time='" . $this->date . "000'></span>\n";
$html .= "\t\t\t<span class='size' data-bytes='" . $this->size . "'>" . $this->size . "</span>\n";
$html .= "\t\t</a>\n";
$html .= "\t</li>\n";
return $html;
}
} }
class Extended { class Extended {
private $h5ai, $parent, $content;
public function __construct($h5ai) { private $h5ai, $parent, $content;
$this->h5ai = $h5ai;
$this->parent = null;
$this->content = array();
$this->loadContent();
}
private function loadContent() { public function __construct($h5ai) {
if ($this->h5ai->getAbsHref() !== "/") { $this->h5ai = $h5ai;
$options = $this->h5ai->getOptions(); $this->parent = null;
$parentPath = dirname($this->h5ai->getAbsPath()); $this->content = array();
$parentHref = dirname($this->h5ai->getAbsHref()); $this->loadContent();
$label = $options["setParentFolderLabels"] === true ? $this->h5ai->getLabel($parentHref) : "<span class='l10n-parentDirectory'>Parent Directory</span>"; }
$this->parent = new Entry($this->h5ai, $parentPath, $parentHref, "folder-parent", $label);
}
$this->content = array();
$files = $this->h5ai->readDir($this->h5ai->getAbsPath()); private function loadContent() {
foreach ($files as $file) {
$absPath = $this->h5ai->getAbsPath() . "/" . $file;
$absHref = $this->h5ai->getAbsHref() . rawurlencode($file);
$this->content[$absPath] = new Entry($this->h5ai, $absPath, $absHref);
}
}
public function toHtml() { if ($this->h5ai->getAbsHref() !== "/") {
$options = $this->h5ai->getOptions();
$parentPath = safe_dirname($this->h5ai->getAbsPath());
$parentHref = safe_dirname($this->h5ai->getAbsHref(), true);
$label = $options["setParentFolderLabels"] === true ? $this->h5ai->getLabel($parentHref) : "<span class='l10n-parentDirectory'>Parent Directory</span>";
$this->parent = new Entry($this->h5ai, $parentPath, $parentHref, "folder-parent", $label);
}
$html = "<section id='extended' class='" . $this->h5ai->getView() . "-view clearfix'>\n"; $this->content = array();
$html .= "<ul>\n";
$html .= $this->generateHeaders();
if ($this->parent !== null) {
$html .= $this->parent->toHtml();
}
foreach($this->content as $entry) {
$html .= $entry->toHtml();
}
$html .= "</ul>\n";
if (count($this->content) === 0) {
$html .= "<div class='empty l10n-empty'>empty</div>";
}
$html .="</section>";
return $html;
}
public function generateHeaders() { $files = $this->h5ai->readDir($this->h5ai->getAbsPath());
foreach ($files as $file) {
$absPath = $this->h5ai->getAbsPath() . "/" . $file;
$absHref = $this->h5ai->getAbsHref() . rawurlencode($file);
$this->content[$absPath] = new Entry($this->h5ai, $absPath, $absHref);
}
}
$html = "\t<li class='header'>\n";
$html .= "\t\t<a class='icon'></a>\n"; public function toHtml() {
$html .= "\t\t<a class='label' href='#'><span class='l10n-name'>Name</span></a>\n";
$html .= "\t\t<a class='date' href='#'><span class='l10n-lastModified'>Last modified</span></a>\n"; $html = "<section id='extended' class='" . $this->h5ai->getView() . "-view clearfix'>\n";
$html .= "\t\t<a class='size' href='#'><span class='l10n-size'>Size</span></a>\n"; $html .= "<ul>\n";
$html .= "\t</li>\n"; $html .= $this->generateHeaders();
return $html; if ($this->parent !== null) {
} $html .= $this->parent->toHtml();
}
foreach($this->content as $entry) {
$html .= $entry->toHtml();
}
$html .= "</ul>\n";
if (count($this->content) === 0) {
$html .= "<div class='empty l10n-empty'>empty</div>";
}
$html .= "<div class='no-match l10n-noMatch'>no match</div>";
$html .="</section>";
return $html;
}
private function generateHeaders() {
$html = "\t<li class='header'>\n";
$html .= "\t\t<a class='icon'></a>\n";
$html .= "\t\t<a class='label' href='#'><span class='l10n-name'>Name</span></a>\n";
$html .= "\t\t<a class='date' href='#'><span class='l10n-lastModified'>Last modified</span></a>\n";
$html .= "\t\t<a class='size' href='#'><span class='l10n-size'>Size</span></a>\n";
$html .= "\t</li>\n";
return $html;
}
} }
?> ?>

View File

@@ -1,303 +1,316 @@
<?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 $docRoot, $h5aiRoot, $h5aiAbsHref, $domain, private static $VIEWMODES = array("details", "icons");
$config, $options, $types, $langs,
$cache,
$absHref, $absPath,
$ignore, $ignoreRE,
$view;
public function __construct() { private $h5aiAbsPath,
$rootAbsPath, $ignore, $ignoreRE,
$config, $options, $types, $langs,
$cache,
$rootAbsHref, $h5aiAbsHref, $domain,
$absHref, $absPath,
$view;
global $H5AI_CONFIG;
$this->docRoot = $H5AI_CONFIG["DOCUMENT_ROOT"]; public function __construct() {
$this->h5aiRoot = $H5AI_CONFIG["H5AI_ROOT"];
$this->ignore = $H5AI_CONFIG["IGNORE"];
$this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"];
$this->config = $this->loadConfig($this->h5aiRoot . "/config.js"); $this->h5aiAbsPath = H5AI_ABS_PATH;
$this->options = $this->config["options"];
$this->types = $this->config["types"];
$this->langs = $this->config["langs"];
$this->cache = new Cache($this->h5aiRoot . "/cache"); global $H5AI_CONFIG;
$this->rootAbsPath = $H5AI_CONFIG["ROOT_ABS_PATH"];
$this->ignore = $H5AI_CONFIG["IGNORE"];
$this->ignoreRE = $H5AI_CONFIG["IGNORE_PATTERNS"];
$this->hrefRoot = $this->options["rootAbsHref"]; $this->config = $this->loadConfig($this->h5aiAbsPath . "/config.js");
$this->h5aiAbsHref = $this->options["h5aiAbsHref"]; $this->options = $this->config["options"];
$this->domain = getenv("HTTP_HOST"); $this->types = $this->config["types"];
$this->langs = $this->config["langs"];
$this->absHref = $this->normalizePath(preg_replace('/\\?.*/', '', getenv("REQUEST_URI")), true); $this->cache = new Cache($this->h5aiAbsPath . "/cache");
$this->absPath = $this->getAbsPath($this->absHref);
$this->view = $this->options["viewmodes"][0]; $this->rootAbsHref = $this->options["rootAbsHref"];
if (!in_array($this->view, H5ai::$VIEWMODES)) { $this->h5aiAbsHref = $this->options["h5aiAbsHref"];
$this->view = H5ai::$VIEWMODES[0]; $this->domain = getenv("HTTP_HOST");
}
}
$this->absHref = $this->normalizePath(preg_replace('/\\?.*/', '', getenv("REQUEST_URI")), true);
$this->absPath = $this->getAbsPath($this->absHref);
private function loadConfig($file) { $this->view = $this->options["viewmodes"][0];
if (!in_array($this->view, H5ai::$VIEWMODES)) {
$this->view = H5ai::$VIEWMODES[0];
}
}
$str = file_exists($file) ? file_get_contents($file) : "";
// remove comments and change expression to pure json private function loadConfig($file) {
$str = preg_replace("/\/\*.*?\*\//s", "", $str);
$str = preg_replace("/^.*H5AI_CONFIG\s*=\s*/s", "", $str);
$str = preg_replace("/;.*/s", "", $str);
$config = json_decode($str, true);
return $config; $str = file_exists($file) ? file_get_contents($file) : "";
}
// remove comments and change expression to pure json
$str = preg_replace("/\/\*.*?\*\//s", "", $str);
$str = preg_replace("/^.*H5AI_CONFIG\s*=\s*/s", "", $str);
$str = preg_replace("/;.*/s", "", $str);
$config = json_decode($str, true);
public function getDocRoot() { return $config;
}
return $this->docRoot;
}
public function getH5aiRoot() { public function getH5aiAbsPath() {
return $this->h5aiRoot; return $this->h5aiAbsPath;
} }
public function getHrefRoot() {
return $this->hrefRoot; public function getRootAbsPath() {
}
public function getH5aiAbsHref() { return $this->rootAbsPath;
}
return $this->h5aiAbsHref;
}
public function getDomain() { public function getRootAbsHref() {
return $this->domain; return $this->rootAbsHref;
} }
public function getView() {
return $this->view; public function getH5aiAbsHref() {
}
public function api() { return $this->h5aiAbsHref;
}
return $this->h5aiAbsHref . "php/api.php";
}
public function image($id) { public function getDomain() {
return $this->h5aiAbsHref . "images/" . $id . ".png"; return $this->domain;
} }
public function icon($id, $big = false) {
return $this->h5aiAbsHref . "icons/" . ($big ? "48x48" : "16x16") . "/" . $id . ".png"; public function getView() {
}
public function getOptions() { return $this->view;
}
return $this->options;
}
public function getLangs() { public function api() {
return $this->langs; return $this->h5aiAbsHref . "php/api.php";
} }
public function getAbsHref($absPath = null, $endWithSlash = true) {
if ($absPath === null) { public function image($id) {
return $this->absHref;
}
// return $this->h5aiAbsHref . "images/" . $id . ".png";
$absPath=substr($absPath, strlen($this->docRoot)); }
$absHref = preg_replace("!^" . $this->docRoot . "!", "", $absPath);
$parts = explode("/", $absHref);
$encodedParts = array();
foreach ($parts as $part) {
$encodedParts[] = rawurlencode($part);
}
$endodedAbsHref = implode("/", $encodedParts);
// public function icon($id, $big = false) {
$endodedAbsHref = $this->hrefRoot . $endodedAbsHref;
return $this->normalizePath($endodedAbsHref, $endWithSlash); return $this->h5aiAbsHref . "icons/" . ($big ? "48x48" : "16x16") . "/" . $id . ".png";
} }
public function getAbsPath($absHref = null) {
if ($absHref === null) { public function getOptions() {
return $this->absPath;
}
// return $this->options;
$absHref=substr($absHref, strlen($this->hrefRoot)); }
return $this->normalizePath($this->docRoot . "/" . rawurldecode($absHref), false);
}
public function showThumbs() { public function getLangs() {
return $this->options["showThumbs"] === true; return $this->langs;
} }
public function getTitle() {
$title = $this->domain . rawurldecode($this->absHref); public function normalizePath($path, $endWithSlash) {
$title = preg_replace("/\/$/", "", $title);
$title = preg_replace("/\//", " > ", $title);
if ($this->absHref !== "/") {
$title = basename($this->absPath) . " - " . $title;
}
return $title;
}
public function getType($absPath) { return preg_match("#^(\w:)?/$#", $path) ? $path : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
}
foreach($this->types as $type => $exts) {
foreach($exts as $ext) {
if ($this->endsWith($absPath, $ext)) {
return $type;
}
}
}
return "unknown";
}
public function ignoreThisFile($file) { public function getAbsHref($absPath = null, $endWithSlash = true) {
# always ignore if ($absPath === null) {
if ($file === "." || $file === ".." || $this->startsWith($file, '.ht')) { return $this->absHref;
return true; }
}
if (in_array($file, $this->ignore)) { $absPath = substr($absPath, strlen($this->rootAbsPath));
return true;
} $parts = explode("/", $absPath);
foreach ($this->ignoreRE as $re) { $encodedParts = array();
if (preg_match($re, $file)) { foreach ($parts as $part) {
return true; $encodedParts[] = rawurlencode($part);
} }
}
return $this->normalizePath($this->rootAbsHref . implode("/", $encodedParts), $endWithSlash);
return false; }
}
public function readDir($path) { public function getAbsPath($absHref = null) {
$content = array(); if ($absHref === null) {
if (is_dir($path)) { return $this->absPath;
if ($dir = opendir($path)) { }
while (($file = readdir($dir)) !== false) {
if (!$this->ignoreThisFile($file)) { $absHref = substr($absHref, strlen($this->rootAbsHref));
$content[] = $file;
} return $this->normalizePath($this->rootAbsPath . "/" . rawurldecode($absHref), false);
} }
closedir($dir);
}
} public function showThumbs() {
return $content;
} return $this->options["showThumbs"] === true;
}
public function getLabel($absHref) {
return $absHref === "/" ? $this->domain : rawurldecode(basename($absHref)); public function getThumbTypes() {
}
return $this->options["thumbTypes"];
public function normalizePath($path, $endWithSlash) { }
return ($path === "/") ? "/" : (preg_replace('#/$#', '', $path) . ($endWithSlash ? "/" : ""));
} public function getTitle() {
public function startsWith($sequence, $start) { $title = $this->domain . rawurldecode($this->absHref);
$title = preg_replace("/\/$/", "", $title);
return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0; $title = preg_replace("/\//", " > ", $title);
} if ($this->absHref !== "/") {
$title = basename($this->absPath) . " - " . $title;
public function endsWith($sequence, $end) { }
return $title;
return strcasecmp(substr($sequence, -strlen($end)), $end) === 0; }
}
public function getHttpCode($absHref) { public function getType($absPath) {
return $this->cachedHttpCode($absHref); foreach($this->types as $type => $exts) {
#return $this->fetchHttpCode($absHref); foreach($exts as $ext) {
#return $this->guessHttpCode($absHref); if ($this->endsWith($absPath, $ext)) {
} return $type;
}
public function cachedHttpCode($absHref) { }
}
$cached = $this->cache->get($absHref); return "unknown";
if ($cached === false) { }
$folderStatus = $this->options["folderStatus"];
if (array_key_exists($absHref, $folderStatus)) {
$code = $folderStatus[$absHref]; public function ignoreThisFile($file) {
} else {
$code = $this->fetchHttpCode($absHref); // always ignore
} if ($file === "." || $file === ".." || $this->startsWith($file, '.ht')) {
$cached = array("href" => $absHref, "code" => $code); return true;
$this->cache->set($absHref, $cached); }
}
return $cached["code"]; if (in_array($file, $this->ignore)) {
} return true;
}
public function fetchHttpCode($absHref) { foreach ($this->ignoreRE as $re) {
if (preg_match($re, $file)) {
$contentType = "Content-Type:"; return true;
$h5aiContentType = "Content-Type: text/html;h5ai="; }
$host = getenv("HTTP_HOST"); }
$port = getenv("SERVER_PORT");
$msg = "HEAD $absHref HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n"; return false;
if (isset($_SERVER['PHP_AUTH_USER'])) { }
$msg .= "Authorization: Basic " . base64_encode($_SERVER['PHP_AUTH_USER'] . ":" . $_SERVER['PHP_AUTH_PW']) . "\r\n";
}
$msg .= "\r\n"; public function readDir($path) {
$errno = ""; $content = array();
$errstr = ""; if (is_dir($path)) {
$socket = fsockopen($host, $port, $errno, $errstr, 30); if ($dir = opendir($path)) {
if($socket === 0) { while (($file = readdir($dir)) !== false) {
return null; if (!$this->ignoreThisFile($file)) {
} $content[] = $file;
}
fwrite($socket, $msg); }
$content = fgets($socket); closedir($dir);
$code = intval(trim(substr($content, 9, 4))); }
if ($code === 200) { }
while (! $this->startsWith($content, $contentType)) { return $content;
$content = fgets($socket); }
}
if ($this->startsWith($content, $h5aiContentType)) {
$code = "h5ai"; public function getLabel($absHref) {
}
} return $absHref === "/" ? $this->domain : rawurldecode(basename($absHref));
fclose($socket); }
return $code;
}
public function startsWith($sequence, $start) {
public function guessHttpCode($absHref) {
return strcasecmp(substr($sequence, 0, strlen($start)), $start) === 0;
$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) { public function endsWith($sequence, $end) {
if (in_array($file, $indexFiles)) {
return 200; return strcasecmp(substr($sequence, -strlen($end)), $end) === 0;
} }
}
return "h5ai";
} public function getHttpCode($absHref) {
//return $this->cachedHttpCode($absHref);
return $this->fetchHttpCode($absHref);
}
public function cachedHttpCode($absHref) {
$cached = $this->cache->get($absHref);
if ($cached === false) {
$folderStatus = $this->options["folderStatus"];
if (array_key_exists($absHref, $folderStatus)) {
$code = $folderStatus[$absHref];
} else {
$code = $this->fetchHttpCode($absHref);
}
$cached = array("href" => $absHref, "code" => $code);
$this->cache->set($absHref, $cached);
}
return $cached["code"];
}
public function fetchHttpCode($absHref) {
$contentType = "Content-Type:";
$h5aiContentType = "Content-Type: text/html;h5ai=";
$host = getenv("HTTP_HOST");
$port = getenv("SERVER_PORT");
$msg = "HEAD $absHref HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n";
if (isset($_SERVER['PHP_AUTH_USER'])) {
$msg .= "Authorization: Basic " . base64_encode($_SERVER['PHP_AUTH_USER'] . ":" . $_SERVER['PHP_AUTH_PW']) . "\r\n";
}
$msg .= "\r\n";
$errno = "";
$errstr = "";
$socket = fsockopen($host, $port, $errno, $errstr, 30);
if($socket === 0) {
return null;
}
fwrite($socket, $msg);
$content = fgets($socket);
$code = intval(trim(substr($content, 9, 4)));
if ($code === 200) {
while (! $this->startsWith($content, $contentType)) {
$content = fgets($socket);
}
if ($this->startsWith($content, $h5aiContentType)) {
$code = "h5ai";
}
}
fclose($socket);
return $code;
}
} }
?> ?>

View File

@@ -2,202 +2,196 @@
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() { return GD_VERSION != "GD_VERSION";
}
return GD_VERSION != "GD_VERSION";
}
public static function showImage($filename) {
public static function showImage($filename) { $image = file_get_contents($filename);
header("content-type: image");
echo $image;
}
$image = file_get_contents($filename);
header("content-type: image");
echo $image;
}
public function __construct($filename = null) {
public function __construct($filename = null) { $this->sourceFile = null;
$this->source = null;
$this->width = null;
$this->height = null;
$this->type = null;
$this->sourceFile = null; $this->dest = null;
$this->source = null;
$this->width = null;
$this->height = null;
$this->type = null;
$this->dest = null; $this->setSource($filename);
}
$this->setSource($filename);
}
public function __destruct() {
public function __destruct() { $this->releaseSource();
$this->releaseDest();
}
$this->releaseSource();
$this->releaseDest();
}
public function setSource($filename) {
public function setSource($filename) { $this->releaseSource();
$this->releaseDest();
$this->releaseSource(); if (is_null($filename)) {
$this->releaseDest(); return;
}
if (is_null($filename)) { $this->sourceFile = $filename;
return;
}
$this->sourceFile = $filename; list($this->width, $this->height, $this->type) = getimagesize($this->sourceFile);
list($this->width, $this->height, $this->type) = getimagesize($this->sourceFile); $this->source = imagecreatefromstring(file_get_contents($this->sourceFile));
}
$this->source = imagecreatefromstring(file_get_contents($this->sourceFile));
}
public function showDest() {
public function showDest() { if (!is_null($this->dest)) {
header("Content-type: image/jpeg");
imagejpeg($this->dest, null, 100);
}
}
if (!is_null($this->dest)) {
header("Content-type: image/jpeg");
imagejpeg($this->dest, null, 100);
}
}
public function saveDest($filename) {
public function saveDest($filename) { if (!is_null($this->dest)) {
@imagejpeg($this->dest, $filename, 90);
@chmod($filename, 0775);
}
}
if (!is_null($this->dest)) {
@imagejpeg($this->dest, $filename, 90);
@chmod($filename, 0775);
}
}
public function releaseDest() {
public function releaseDest() { if (!is_null($this->dest)) {
@imagedestroy($this->dest);
$this->dest = null;
}
}
if (!is_null($this->dest)) {
imagedestroy($this->dest);
$this->dest = null;
}
}
public function releaseSource() {
public function releaseSource() { if (!is_null($this->source)) {
@imagedestroy($this->source);
$this->sourceFile = null;
$this->source = null;
$this->width = null;
$this->height = null;
$this->type = null;
}
}
if (!is_null($this->source)) {
imagedestroy($this->source);
$this->sourceFile = null;
$this->source = null;
$this->width = null;
$this->height = null;
$this->type = null;
}
}
private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) {
private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) { if (!is_null($canWidth) && !is_null($canHeight)) {
$this->dest = imagecreatetruecolor($canWidth, $canHeight);
} else {
$this->dest = imagecreatetruecolor($destWidth, $destHeight);
}
if (!is_null($canWidth) && !is_null($canHeight)) { if (is_null($color)) {
$this->dest = imagecreatetruecolor($canWidth, $canHeight); $color = array(255, 255, 255);
} else { }
$this->dest = imagecreatetruecolor($destWidth, $destHeight); $icol = imagecolorallocate($this->dest, $color[0], $color[1], $color[2]);
} imagefill($this->dest, 0, 0, $icol);
if (is_null($color)) { imagecopyresampled($this->dest, $this->source, $destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight);
$color = array(255, 255, 255); }
}
$icol = imagecolorallocate($this->dest, $color[0], $color[1], $color[2]);
imagefill($this->dest, 0, 0, $icol);
imagecopyresampled($this->dest, $this->source, $destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight);
}
public function thumb($mode, $width, $height = null, $color = null) {
public function thumb($mode, $width, $height = null, $color = null) { if ($height === null) {
$height = $width;
}
if ($mode === "square") {
$this->squareThumb($width);
} elseif ($mode === "rational") {
$this->rationalThumb($width, $height);
} elseif ($mode === "center") {
$this->centerThumb($width, $height, $color);
} else {
$this->freeThumb($width, $height);
}
}
if ($height === null) {
$height = $width;
}
if ($mode === "square") {
$this->squareThumb($width);
} elseif ($mode === "rational") {
$this->rationalThumb($width, $height);
} elseif ($mode === "center") {
$this->centerThumb($width, $height, $color);
} else {
$this->freeThumb($width, $height);
}
}
public function squareThumb($width) {
public function squareThumb($width) { $a = min($this->width, $this->height);
$x = intval(($this->width - $a) / 2);
$y = intval(($this->height - $a) / 2);
$a = min($this->width, $this->height); $this->magic(0, 0, $x, $y, $width, $width, $a, $a);
$x = intval(($this->width - $a) / 2); }
$y = intval(($this->height - $a) / 2);
$this->magic(0, 0, $x, $y, $width, $width, $a, $a);
}
public function rationalThumb($width, $height) {
public function rationalThumb($width, $height) { $r = 1.0 * $this->width / $this->height;
$r = 1.0 * $this->width / $this->height; $h = $height;
$w = $r * $h;
$h = $height; if ($w > $width) {
$w = $r * $h;
if ($w > $width) { $w = $width;
$h = 1.0 / $r * $w;
}
$w = $width; $w = intval($w);
$h = 1.0 / $r * $w; $h = intval($h);
}
$w = intval($w); $this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
$h = intval($h); }
$this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
}
public function centerThumb($width, $height, $color = null) {
public function centerThumb($width, $height, $color = null) { $r = 1.0 * $this->width / $this->height;
$r = 1.0 * $this->width / $this->height; $h = $height;
$w = $r * $h;
$h = $height; if ($w > $width) {
$w = $r * $h;
if ($w > $width) { $w = $width;
$h = 1.0 / $r * $w;
}
$w = $width; $w = intval($w);
$h = 1.0 / $r * $w; $h = intval($h);
}
$w = intval($w); $x = intval(($width - $w) / 2);
$h = intval($h); $y = intval(($height - $h) / 2);
$x = intval(($width - $w) / 2); $this->magic($x, $y, 0, 0, $w, $h, $this->width, $this->height, $width, $height, $color);
$y = intval(($height - $h) / 2); }
$this->magic($x, $y, 0, 0, $w, $h, $this->width, $this->height, $width, $height, $color);
}
public function freeThumb($width, $height) {
public function freeThumb($width, $height) { $w = intval($width);
$h = intval($height);
$w = intval($width); $this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
$h = intval($height); }
$this->magic(0, 0, 0, 0, $w, $h, $this->width, $this->height);
}
} }
?> ?>

View File

@@ -1,59 +1,65 @@
<?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() {
return Image::isUsable(); public static function isUsable() {
}
public function __construct($h5ai, $absHref, $mode, $width, $height) { return Image::isUsable();
}
$this->h5ai = $h5ai;
$this->srcAbsHref = $absHref;
$this->srcAbsPath = $this->h5ai->getDocRoot() . urldecode($absHref);
$this->width = $width;
$this->height = $height;
$this->mode = $mode;
$this->name = sha1("$this->srcAbsPath-$this->width-$this->height-$this->mode");
$this->href = $this->h5ai->getH5aiAbsHref() . "/cache/thumb-" . $this->name . ".jpg";
$this->path = $this->h5ai->getDocRoot() . $this->href;
$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 __construct($h5ai, $absHref, $mode, $width, $height) {
if ( $this->h5ai = $h5ai;
$force === 2 $this->srcAbsHref = $absHref;
|| ($force === 1 && !file_exists($this->path)) $this->srcAbsPath = $this->h5ai->getRootAbsPath() . urldecode($absHref);
|| (file_exists($this->path) && filemtime($this->srcAbsPath) >= filemtime($this->path)) $this->width = $width;
) { $this->height = $height;
$image = new Image(); $this->mode = $mode;
$image->setSource($this->srcAbsPath); $this->name = sha1("$this->srcAbsPath-$this->width-$this->height-$this->mode");
$image->thumb($this->mode, $this->width, $this->height); $this->href = $this->h5ai->getH5aiAbsHref() . "cache/thumb-" . $this->name . ".jpg";
$image->saveDest($this->path); $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;
} }
public function getHref() {
return $this->href; public function create($force = 0) {
}
public function getPath() { if (
$force === 2
|| ($force === 1 && !file_exists($this->path))
|| (file_exists($this->path) && filemtime($this->srcAbsPath) >= filemtime($this->path))
) {
$image = new Image();
$image->setSource($this->srcAbsPath);
$image->thumb($this->mode, $this->width, $this->height);
$image->saveDest($this->path);
}
}
return $this->path;
}
public function getLiveHref() { public function getHref() {
return $this->liveHref; return $this->href;
} }
public function getPath() {
return $this->path;
}
public function getLiveHref() {
return $this->liveHref;
}
} }
?> ?>

View File

@@ -1,146 +1,157 @@
<?php <?php
class TreeEntry { class TreeEntry {
private $h5ai, $label, $absPath, $absHref, $isFolder, $type, $content;
public function __construct($h5ai, $absPath, $absHref, $type = null) { private $h5ai, $label, $absPath, $absHref, $isFolder, $type, $content;
$this->h5ai = $h5ai;
$this->label = $this->h5ai->getLabel($absHref); public function __construct($h5ai, $absPath, $absHref, $type = null) {
$this->absPath = $this->h5ai->normalizePath($absPath, false);
$this->isFolder = is_dir($this->absPath);
$this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
$this->type = $type !== null ? $type : ($this->isFolder ? "folder" : $this->h5ai->getType($this->absPath)); $this->h5ai = $h5ai;
$this->content = null;
}
public function loadContent() { $this->label = $this->h5ai->getLabel($absHref);
$this->absPath = $this->h5ai->normalizePath($absPath, false);
$this->isFolder = is_dir($this->absPath);
$this->absHref = $this->h5ai->normalizePath($absHref, $this->isFolder);
$this->content = array(); $this->type = $type !== null ? $type : ($this->isFolder ? "folder" : $this->h5ai->getType($this->absPath));
$this->content = null;
}
if ($this->h5ai->getHttpCode($this->absHref) !== "h5ai") {
return;
}
$files = $this->h5ai->readDir($this->absPath); public function loadContent() {
foreach ($files as $file) {
$tree = new TreeEntry($this->h5ai, $this->absPath . "/" . $file, $this->absHref . rawurlencode($file));
if ($tree->isFolder) { $this->content = array();
$this->content[$tree->absPath] = $tree;
}
}
$this->sort(); if ($this->h5ai->getHttpCode($this->absHref) !== "h5ai") {
} return;
}
public function cmpTrees($t1, $t2) { $files = $this->h5ai->readDir($this->absPath);
foreach ($files as $file) {
$tree = new TreeEntry($this->h5ai, $this->absPath . "/" . $file, $this->absHref . rawurlencode($file));
if ($t1->isFolder && !$t2->isFolder) { if ($tree->isFolder) {
return -1; $this->content[$tree->absPath] = $tree;
} }
if (!$t1->isFolder && $t2->isFolder) { }
return 1;
}
return strcasecmp($t1->absPath, $t2->absPath);
}
public function sort() { $this->sort();
}
if ($this->content !== null) {
uasort($this->content, array($this, "cmpTrees"));
}
}
public function toHtml() { public function cmpTrees($t1, $t2) {
$classes = "entry " . $this->type . ($this->absHref === $this->h5ai->getAbsHref() ? " current" : ""); if ($t1->isFolder && !$t2->isFolder) {
$icon = $this->type; return -1;
if ($this->absHref === "/") { }
$icon = "folder-home"; if (!$t1->isFolder && $t2->isFolder) {
} return 1;
$hint = ""; }
$code = "h5ai"; return strcasecmp($t1->absPath, $t2->absPath);
}
if ($this->isFolder) {
$code = $this->h5ai->getHttpCode($this->absHref);
$classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$icon = "folder-page";
$hint = "<span class='hint'><img src='" . $this->h5ai->image("page") . "' alt='page' /></span>";
} else {
$classes .= " error";
$hint = "<span class='hint'> " . $code . " </span>";
}
}
}
$html = "<div class='" . $classes ."'>\n"; public function sort() {
if ($this->content !== null && count($this->content) === 0 || $code !== "h5ai") {
$html .= "<span class='blank'></span>\n";
} else {
$indicatorState = $this->content === null ? " unknown" : " open";
$html .= "<span class='indicator" . $indicatorState . "'><img src='" . $this->h5ai->image("tree") . "' alt='>' /></span>\n";
}
$html .= "<a href='" . $this->absHref . "'>\n";
$html .= "<span class='icon'><img src='" . $this->h5ai->icon($icon) . "' alt='" . $icon . "' /></span>\n";
$html .= "<span class='label'>" . $this->label . "</span>" . $hint . "\n";
$html .= "</a>\n";
$html .= $this->contentToHtml();
$html .= "</div>\n";
return $html;
}
public function contentToHtml() { if ($this->content !== null) {
uasort($this->content, array($this, "cmpTrees"));
}
}
$html = "<ul class='content'>\n";
if ($this->content !== null) {
foreach($this->content as $tree) {
$html .= "<li>" . $tree->toHtml() . "</li>";
}
}
$html .= "</ul>\n";
return $html;
}
public function getRoot() { public function toHtml() {
if ($this->absHref === "/") { $classes = "entry " . $this->type . ($this->absHref === $this->h5ai->getAbsHref() ? " current" : "");
return $this; $icon = $this->type;
}; if ($this->absHref === "/") {
$icon = "folder-home";
}
$hint = "";
$code = "h5ai";
$tree = new TreeEntry($this->h5ai, dirname($this->absPath), dirname($this->absHref)); if ($this->isFolder) {
$tree->loadContent(); $code = $this->h5ai->getHttpCode($this->absHref);
$tree->content[$this->absPath] = $this; $classes .= " checkedHttpCode";
if ($code !== "h5ai") {
if ($code === 200) {
$icon = "folder-page";
$hint = "<span class='hint'><img src='" . $this->h5ai->image("page") . "' alt='page' /></span>";
} else {
$classes .= " error";
$hint = "<span class='hint'> " . $code . " </span>";
}
}
}
return $tree->getRoot(); $html = "<div class='" . $classes ."'>\n";
} if ($this->content !== null && count($this->content) === 0 || $code !== "h5ai") {
$html .= "<span class='blank'></span>\n";
} else {
$indicatorState = $this->content === null ? " unknown" : " open";
$html .= "<span class='indicator" . $indicatorState . "'><img src='" . $this->h5ai->image("tree") . "' alt='>' /></span>\n";
}
$html .= "<a href='" . $this->absHref . "'>\n";
$html .= "<span class='icon'><img src='" . $this->h5ai->icon($icon) . "' alt='" . $icon . "' /></span>";
$html .= "<span class='label'>" . $this->label . "</span>" . $hint . "\n";
$html .= "</a>\n";
$html .= $this->contentToHtml();
$html .= "</div>\n";
return $html;
}
public function contentToHtml() {
$html = "<ul class='content'>\n";
if ($this->content !== null) {
foreach($this->content as $tree) {
$html .= "<li>" . $tree->toHtml() . "</li>";
}
}
$html .= "</ul>\n";
return $html;
}
public function getRoot() {
if ($this->absHref === "/") {
return $this;
};
$tree = new TreeEntry($this->h5ai, safe_dirname($this->absPath), safe_dirname($this->absHref, true));
$tree->loadContent();
$tree->content[$this->absPath] = $this;
return $tree->getRoot();
}
} }
class Tree { class Tree {
private $h5ai;
public function __construct($h5ai) { private $h5ai;
$this->h5ai = $h5ai;
}
public function toHtml() { public function __construct($h5ai) {
$options = $this->h5ai->getOptions(); $this->h5ai = $h5ai;
if ($options["showTree"] === false) { }
return "";
}
$tree = new TreeEntry($this->h5ai, $this->h5ai->getAbsPath(), $this->h5ai->getAbsHref());
$tree->loadContent(); public function toHtml() {
$root = $tree->getRoot();
return "<section id='tree'>\n" . $root->toHtml() . "</section>\n"; $options = $this->h5ai->getOptions();
} if ($options["showTree"] === false) {
return "";
}
$tree = new TreeEntry($this->h5ai, $this->h5ai->getAbsPath(), $this->h5ai->getAbsHref());
$tree->loadContent();
$root = $tree->getRoot();
return "<section id='tree'>\n" . $root->toHtml() . "</section>\n";
}
} }

View File

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