diff --git a/src/_h5ai/client/css/inc/bottombar.less b/src/_h5ai/client/css/inc/bottombar.less
index 9d3b57df..74c3ef69 100644
--- a/src/_h5ai/client/css/inc/bottombar.less
+++ b/src/_h5ai/client/css/inc/bottombar.less
@@ -3,6 +3,7 @@
position: fixed;
z-index: 5;
width: 100%;
+ height: 18px;
left: 0;
bottom: 0;
padding: 6px 0 8px 0;
diff --git a/src/_h5ai/client/js/inc/core/server.js b/src/_h5ai/client/js/inc/core/server.js
index 759b81bb..8b49ff13 100644
--- a/src/_h5ai/client/js/inc/core/server.js
+++ b/src/_h5ai/client/js/inc/core/server.js
@@ -20,6 +20,8 @@ modulejs.define('core/server', ['$', '_', 'config'], function ($, _, config) {
callback();
}
});
+ } else if (server.backend === 'aai') {
+ return modulejs.require('core/server-request-mock-aai')(data, callback);
} else {
callback();
}
@@ -28,3 +30,126 @@ modulejs.define('core/server', ['$', '_', 'config'], function ($, _, config) {
return server;
});
+
+
+
+modulejs.define('core/server-request-mock-aai', ['$', '_', 'core/settings', 'core/format'], function ($, _, allsettings, format) {
+
+ var loadText = function (href) {
+
+ var deferred = $.Deferred();
+
+ $.ajax(href, {dataType: 'text'}).always(function (content) {
+
+ content = content.replace ? content : null;
+ deferred.resolve(content);
+ });
+
+ return deferred;
+ },
+
+ loadJson = function (href) {
+
+ var deferred = $.Deferred();
+
+ loadText(href).always(function (content) {
+
+ var json = content.replace ? JSON.parse(content.replace(/\/\*[\s\S]*?\*\/|\/\/.*?(\n|$)/g, '')) : {};
+ deferred.resolve(json);
+ });
+
+ return deferred;
+ },
+
+ parse = function (absHref, html) {
+
+ var id = '#data-apache-autoindex',
+ $html = $(html),
+ $id = $html.filter(id);
+
+ if (!$id.length) {
+ $id = $html.find(id);
+ }
+
+ return _.compact(_.map($id.find('table').find('td').closest('tr'), function (tr) {
+
+ var $tds = $(tr).find('td'),
+ $a = $tds.eq(1).find('a');
+
+ return $a.text() === 'Parent Directory' ? null : {
+ absHref: absHref + $a.attr('href'),
+ time: format.parseDate($tds.eq(2).text(), ['YYYY-MM-DD HH:mm', 'DD-MMM-YYYY HH:mm']),
+ size: format.parseSize($tds.eq(3).text())
+ };
+ }));
+ };
+
+ return function (data, callback) {
+
+ if (data.action === 'get' && data.l10n === true) {
+
+ var isoCodes = data.l10nCodes.split(':');
+ var isoCode = data.l10nCodes.split(':')[0];
+ loadJson(allsettings.h5aiAbsHref + 'conf/l10n/' + isoCode + '.json').done(function (json) {
+
+ var result = {code: 0, l10n: {}};
+
+ if (json) {
+ result.l10n[isoCode] = json;
+ }
+ callback(result);
+ });
+
+ } else if (data.action === 'get' && data.custom === true) {
+
+ $.when(
+ loadText('_h5ai.header.html'),
+ loadText('_h5ai.footer.html')
+ ).done(function (header, footer) {
+
+ callback({
+ code: 0,
+ custom: {
+ header: header,
+ footer: footer
+ }
+ });
+ });
+
+ } else if (data.action === 'get' && data.entries === true) {
+
+ var absHref = data.entriesHref,
+ what = data.entriesWhat,
+ magicSequence = '=h5ai=',
+ reContentType = /^text\/html;h5ai=/;
+
+ $.ajax({
+ url: absHref,
+ type: what === 0 ? 'HEAD' : 'GET',
+ complete: function (xhr) {
+
+ var entries = [],
+ status = xhr.status;
+
+ if (status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) {
+ status = magicSequence;
+ }
+
+ if (status === magicSequence && what > 0) {
+ entries = parse(absHref, xhr.responseText);
+ }
+ entries.push({absHref: absHref, status: status, content: what > 0});
+
+ callback({
+ code: 0,
+ entries: entries
+ });
+ }
+ });
+
+ } else {
+
+ callback();
+ }
+ };
+});
diff --git a/src/_h5ai/client/js/inc/ext/crumb.js b/src/_h5ai/client/js/inc/ext/crumb.js
index 7913e43c..dd631d41 100644
--- a/src/_h5ai/client/js/inc/ext/crumb.js
+++ b/src/_h5ai/client/js/inc/ext/crumb.js
@@ -82,11 +82,6 @@ modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/
_.each(crumb, function (e) {
$ul.append(update(e));
-
- e.fetchStatus(function (e) {
-
- update(e);
- });
});
event.sub('entry.created', onContentChanged);
diff --git a/src/_h5ai/client/js/inc/ext/custom.js b/src/_h5ai/client/js/inc/ext/custom.js
index 0811e04d..5da2495b 100644
--- a/src/_h5ai/client/js/inc/ext/custom.js
+++ b/src/_h5ai/client/js/inc/ext/custom.js
@@ -1,5 +1,5 @@
-modulejs.define('ext/custom', ['_', '$', 'core/settings'], function (_, $, allsettings) {
+modulejs.define('ext/custom', ['_', '$', 'core/settings', 'core/server'], function (_, $, allsettings, server) {
var settings = _.extend({
enabled: false,
@@ -7,46 +7,23 @@ modulejs.define('ext/custom', ['_', '$', 'core/settings'], function (_, $, allse
footer: '_h5ai.footer.html'
}, allsettings.custom),
- getHtml = function (url, callback) {
-
- $.ajax({
- url: url,
- type: 'POST',
- dataType: 'html',
- success: function (html) {
-
- callback(html);
- },
- error: function () {
-
- callback();
- }
- });
- },
-
init = function () {
if (!settings.enabled) {
return;
}
- if (_.isString(settings.header)) {
- getHtml(settings.header, function (html) {
+ server.request({action: 'get', custom: true}, function (response) {
- if (html) {
- $('
').prependTo('#content');
+ if (response) {
+ if (response.custom.header) {
+ $('').prependTo('#content');
}
- });
- }
-
- if (_.isString(settings.footer)) {
- getHtml(settings.footer, function (html) {
-
- if (html) {
- $('').appendTo('#content');
+ if (response.custom.footer) {
+ $('').appendTo('#content');
}
- });
- }
+ }
+ });
};
init();
diff --git a/src/_h5ai/client/js/inc/ext/l10n.js b/src/_h5ai/client/js/inc/ext/l10n.js
index eebc0b99..66a8a3de 100644
--- a/src/_h5ai/client/js/inc/ext/l10n.js
+++ b/src/_h5ai/client/js/inc/ext/l10n.js
@@ -1,5 +1,5 @@
-modulejs.define('ext/l10n', ['_', '$', 'core/settings', 'core/langs', 'core/format', 'core/store', 'core/event'], function (_, $, allsettings, langs, format, store, event) {
+modulejs.define('ext/l10n', ['_', '$', 'core/settings', 'core/langs', 'core/format', 'core/store', 'core/event', 'core/server'], function (_, $, allsettings, langs, format, store, event, server) {
var settings = _.extend({
enabled: false,
@@ -72,19 +72,11 @@ modulejs.define('ext/l10n', ['_', '$', 'core/settings', 'core/langs', 'core/form
callback(loaded[isoCode]);
} else {
- $.ajax({
- url: allsettings.h5aiAbsHref + 'conf/l10n/' + isoCode + '.json',
- dataType: 'json',
- success: function (json) {
+ server.request({action: 'get', l10n: true, l10nCodes: isoCode}, function (response) {
- loaded[isoCode] = _.extend({}, defaultTranslations, json, {isoCode: isoCode});
- callback(loaded[isoCode]);
- },
- error: function () {
-
- loaded[isoCode] = _.extend({}, defaultTranslations, {isoCode: isoCode});
- callback(loaded[isoCode]);
- }
+ var json = response.l10n && response.l10n[isoCode] ? response.l10n[isoCode] : {};
+ loaded[isoCode] = _.extend({}, defaultTranslations, json, {isoCode: isoCode});
+ callback(loaded[isoCode]);
});
}
},
diff --git a/src/_h5ai/client/js/inc/ext/tree.js b/src/_h5ai/client/js/inc/ext/tree.js
index ef30d301..5f0b8a92 100644
--- a/src/_h5ai/client/js/inc/ext/tree.js
+++ b/src/_h5ai/client/js/inc/ext/tree.js
@@ -1,5 +1,5 @@
-modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/event', 'core/entry', 'core/parser'], function (_, $, allsettings, resource, event, entry, parser) {
+modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/event', 'core/entry'], function (_, $, allsettings, resource, event, entry) {
var settings = _.extend({
enabled: false,
@@ -104,7 +104,7 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
return $html;
},
- createOnIndicatorClick = function (parser) {
+ createOnIndicatorClick = function () {
var $tree = $('#tree'),
slide = function (entry, $indicator, $content, down) {
@@ -127,7 +127,7 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
if ($indicator.hasClass('unknown')) {
- entry.fetchContent(parser, function (entry) {
+ entry.fetchContent(function (entry) {
entry.isContentVisible = false;
@@ -164,13 +164,13 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
}
},
- fetchTree = function (entry, parser, callback) {
+ fetchTree = function (entry, callback) {
entry.isContentVisible = true;
- entry.fetchContent(parser, function (entry) {
+ entry.fetchContent(function (entry) {
if (entry.parent) {
- fetchTree(entry.parent, parser, callback);
+ fetchTree(entry.parent, callback);
} else {
callback(entry);
}
@@ -202,7 +202,7 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
},
// creates the complete tree from entry down to the root
- init = function (entry, parser) {
+ init = function (entry) {
if (!settings.enabled) {
return;
@@ -211,7 +211,7 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
var $tree = $('')
.appendTo('body')
.scrollpanel()
- .on('click', '.indicator', createOnIndicatorClick(parser))
+ .on('click', '.indicator', createOnIndicatorClick())
.on('mouseenter', function () {
shiftTree(true);
@@ -221,7 +221,7 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
shiftTree();
});
- fetchTree(entry, parser, function (root) {
+ fetchTree(entry, function (root) {
$tree
.find('.sp-container').append(update(root)).end()
@@ -243,5 +243,5 @@ modulejs.define('ext/tree', ['_', '$', 'core/settings', 'core/resource', 'core/e
});
};
- init(entry, parser);
+ init(entry);
});
diff --git a/src/_h5ai/client/js/inc/model/entry.js b/src/_h5ai/client/js/inc/model/entry.js
index 1ab5b0be..dedd4b6b 100644
--- a/src/_h5ai/client/js/inc/model/entry.js
+++ b/src/_h5ai/client/js/inc/model/entry.js
@@ -1,5 +1,5 @@
-modulejs.define('model/entry', ['$', '_', 'core/types', 'core/event', 'core/settings', 'core/location'], function ($, _, types, event, settings, location) {
+modulejs.define('model/entry', ['$', '_', 'core/types', 'core/event', 'core/settings', 'core/location', 'core/server'], function ($, _, types, event, settings, location, server) {
var reEndsWithSlash = /\/$/,
@@ -36,40 +36,6 @@ modulejs.define('model/entry', ['$', '_', 'core/types', 'core/event', 'core/sett
}
},
- magicSequence = '=h5ai=',
- reContentType = /^text\/html;h5ai=/,
- getStatus = function (href, withContent, callback) {
-
- $.ajax({
- url: href,
- type: withContent ? 'GET' : 'HEAD',
- complete: function (xhr) {
-
- var res = {
- status: xhr.status,
- content: xhr.responseText
- };
-
- if (xhr.status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) {
- res.status = magicSequence;
- }
-
- callback(res);
- }
- });
- },
- ajaxRequest = function (self, parser, callback) {
-
- getStatus(self.absHref, parser, function (response) {
-
- self.status = response.status;
- if (parser && response.status === magicSequence) {
- parser.parse(self.absHref, response.content);
- }
- callback(self);
- });
- },
-
// Cache
@@ -144,28 +110,38 @@ modulejs.define('model/entry', ['$', '_', 'core/types', 'core/event', 'core/sett
var self = getEntry(absHref);
- if (self.status || !self.isFolder()) {
+ if (self.status !== null) {
callback(self);
} else {
- ajaxRequest(self, null, callback);
+ server.request({action: 'get', entries: true, entriesHref: self.absHref, entriesWhat: 0}, function (response) {
+
+ if (response.entries) {
+ _.each(response.entries, function (entry) {
+ getEntry(entry.absHref, entry.time, entry.size, entry.status, entry.content);
+ });
+ }
+
+ callback(self);
+ });
}
},
- fetchContent = function (absHref, parser, callback) {
+ fetchContent = function (absHref, callback) {
var self = getEntry(absHref);
if (self.isContentFetched) {
callback(self);
} else {
- fetchStatus(absHref, function (self) {
+ server.request({action: 'get', entries: true, entriesHref: self.absHref, entriesWhat: 1}, function (response) {
- self.isContentFetched = true;
- if (self.status === magicSequence) {
- ajaxRequest(self, parser, callback);
- } else {
- callback(self);
+ if (response.entries) {
+ _.each(response.entries, function (entry) {
+ getEntry(entry.absHref, entry.time, entry.size, entry.status, entry.content);
+ });
}
+
+ callback(self);
});
}
};
@@ -245,9 +221,9 @@ modulejs.define('model/entry', ['$', '_', 'core/types', 'core/event', 'core/sett
return fetchStatus(this.absHref, callback);
},
- fetchContent: function (parser, callback) {
+ fetchContent: function (callback) {
- return fetchContent(this.absHref, parser, callback);
+ return fetchContent(this.absHref, callback);
},
getCrumb: function () {
diff --git a/src/_h5ai/client/js/inc/view/extended.js b/src/_h5ai/client/js/inc/view/extended.js
index a3fccc50..42e81263 100644
--- a/src/_h5ai/client/js/inc/view/extended.js
+++ b/src/_h5ai/client/js/inc/view/extended.js
@@ -112,10 +112,8 @@ modulejs.define('view/extended', ['_', '$', 'core/settings', 'core/resource', 'c
$ul.append(update(e));
- e.fetchStatus(function (e) {
-
- update(e);
- });
+ // needed by aai
+ e.fetchStatus(function (e) { update(e); });
});
$extended.append($ul);
diff --git a/src/_h5ai/client/js/scripts.js b/src/_h5ai/client/js/scripts.js
index b14a9674..b487c71d 100644
--- a/src/_h5ai/client/js/scripts.js
+++ b/src/_h5ai/client/js/scripts.js
@@ -29,15 +29,6 @@
appHref = src.substr(0, src.length - filename.length),
- loadCommentedJson = function (href, callback) {
-
- $.ajax(href, {dataType: 'text'}).always(function (response) {
-
- var json = response.replace ? JSON.parse(response.replace(/\/\*[\s\S]*?\*\/|\/\/.*?(\n|$)/g, '')) : {};
- callback(json);
- });
- },
-
run = function (config) {
/*global amplify, Base64, jQuery, Modernizr, moment, _ */
@@ -66,22 +57,35 @@
} else if (backend === 'aai') {
- loadCommentedJson(appHref + 'conf/options.json', function (options) {
- loadCommentedJson(appHref + 'conf/types.json', function (types) {
- loadCommentedJson(appHref + 'conf/langs.json', function (langs) {
+ var loadJson = function (href) {
- run({
- options: options,
- types: types,
- langs: langs,
- server: {
- backend: backend,
- api: false,
- name: 'apache',
- version: null
- }
- });
+ var deferred = $.Deferred();
+
+ $.ajax(href, {dataType: 'text'}).always(function (content) {
+
+ var json = content.replace ? JSON.parse(content.replace(/\/\*[\s\S]*?\*\/|\/\/.*?(\n|$)/g, '')) : {};
+ deferred.resolve(json);
});
+
+ return deferred;
+ };
+
+ $.when(
+ loadJson(appHref + 'conf/options.json'),
+ loadJson(appHref + 'conf/types.json'),
+ loadJson(appHref + 'conf/langs.json')
+ ).done(function (options, types, langs) {
+
+ run({
+ options: options,
+ types: types,
+ langs: langs,
+ server: {
+ backend: backend,
+ api: false,
+ name: 'apache',
+ version: null
+ }
});
});
}
diff --git a/src/_h5ai/server/php/inc/Api.php b/src/_h5ai/server/php/inc/Api.php
index cbadb7fb..3e66af6c 100644
--- a/src/_h5ai/server/php/inc/Api.php
+++ b/src/_h5ai/server/php/inc/Api.php
@@ -40,7 +40,7 @@ class Api {
if (array_key_exists("l10n", $_REQUEST)) {
list($iso_codes) = use_request_params("l10nCodes", "l10n");
- $iso_codes = explode(",", $iso_codes);
+ $iso_codes = explode(":", $iso_codes);
$response["l10n"] = $this->app->get_l10n($iso_codes);
}
@@ -58,14 +58,14 @@ class Api {
if (array_key_exists("custom", $_REQUEST)) {
- list($abs_href) = use_request_params("customHref", "custom");
+ list($abs_href) = use_optional_request_params("customHref", "custom");
$response["custom"] = $this->app->get_customizations($abs_href);
}
if (array_key_exists("entries", $_REQUEST)) {
- list($abs_href, $what) = use_request_params("entriesHref", "entriesWhat", "entries");
- $what = intval($what, 10);
+ list($abs_href, $what) = use_optional_request_params("entriesHref", "entriesWhat", "entries");
+ $what = is_numeric($what) ? intval($what, 10) : 1;
$response["entries"] = $this->app->get_entries($abs_href, $what);
}
diff --git a/src/_h5ai/server/php/inc/App.php b/src/_h5ai/server/php/inc/App.php
index 6b67c46d..241a195f 100644
--- a/src/_h5ai/server/php/inc/App.php
+++ b/src/_h5ai/server/php/inc/App.php
@@ -197,11 +197,11 @@ class App {
$html = "";
$html .= " | Name | Last modified | Size |
";
if ($folder->get_parent($cache)) {
- $html .= "UP | Parent Directory | | |
";
+ $html .= " app_abs_href . "client/icons/16x16/folder-parent.png\"/> | Parent Directory | | |
";
}
foreach ($entries as $entry) {
$html .= "";
- $html .= "" . ($entry->is_folder ? "DIR" : "FILE") . " | ";
+ $html .= " app_abs_href . "client/icons/16x16/" . ($entry->is_folder ? "folder" : "default") . ".png\"/> | ";
$html .= "abs_href . "\">" . basename($entry->abs_path) . " | ";
$html .= "" . date("Y-m-d H:i", $entry->date) . " | ";
$html .= "" . ($entry->size !== null ? intval($entry->size / 1000) . " KB" : "" ) . " | ";
diff --git a/src/_h5ai/server/php/inc/init.php b/src/_h5ai/server/php/inc/init.php
index 28fbd352..2d90bade 100644
--- a/src/_h5ai/server/php/inc/init.php
+++ b/src/_h5ai/server/php/inc/init.php
@@ -23,7 +23,7 @@ $app = new App(APP_ABS_PATH, APP_ABS_HREF, ABS_HREF);
if (count($_REQUEST)) {
- header("Content-type: application/json;h5ai={{pkg.version}}");
+ header("Content-type: application/json");
normalized_require_once("/server/php/inc/Api.php");
$api = new Api($app);
@@ -33,8 +33,6 @@ if (count($_REQUEST)) {
} else {
- header("Content-type: text/html;h5ai={{pkg.version}}");
-
$HREF = $app->get_app_abs_href();
$JSON = $app->get_generic_json();
$FALLBACK = $app->get_no_js_fallback();
diff --git a/src/_h5ai/server/php/inc/util.php b/src/_h5ai/server/php/inc/util.php
index 4a1053f7..bed071e6 100644
--- a/src/_h5ai/server/php/inc/util.php
+++ b/src/_h5ai/server/php/inc/util.php
@@ -30,6 +30,24 @@ function use_request_params($keys) {
return $values;
}
+function use_optional_request_params($keys) {
+
+ if (!is_array($keys)) {
+ $keys = func_get_args();
+ }
+
+ $values = array();
+ foreach ($keys as $key) {
+ if (array_key_exists($key, $_REQUEST)) {
+ $values[] = $_REQUEST[$key];
+ unset($_REQUEST[$key]);
+ } else {
+ $values[] = null;
+ }
+ }
+ return $values;
+}
+
function delete_tempfile($file) {
@unlink($file);