Use hash part of URL for IE8 in files app

Before this fix, the URL wasn't updated in IE8 when navigating into
folders.

This fix makes use of the hash part of URLs to make this work in IE8,
since IE8 doesn't support the history API nor changing the URL without
redirecting.

From now, both the regular query URL "?dir=somedir" and "#?dir=somedir"
will work in both IE8 and non-IE8 browsers.

In IE8, query based URLs are automatically converted to hash URLs upon
page load. The conversion is done on the server side by redirecting the
user to the updated URL.

When loading a page directly using a hash URL in the form
"#?dir=somedir" in IE8, the server doesn't get the hash, so it will not
return any results in that case and rely on ajax to load the first page.
This commit is contained in:
Vincent Petry 2013-08-29 21:56:14 +02:00 committed by Vincent Petry
parent 4d38441e72
commit 30a2f2f352
4 changed files with 84 additions and 16 deletions

View File

@ -41,13 +41,40 @@ if (!\OC\Files\Filesystem::is_dir($dir . '/')) {
exit();
}
$isIE8 = false;
preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $matches);
if (count($matches) > 0 && $matches[1] <= 8){
$isIE8 = true;
}
// if IE8 and "?dir=path" was specified, reformat the URL to use a hash like "#?dir=path"
if ($isIE8 && isset($_GET['dir'])){
if ($dir === ''){
$dir = '/';
}
header('Location: ' . OCP\Util::linkTo('files', 'index.php') . '#?dir=' . \OCP\Util::encodePath($dir));
exit();
}
$ajaxLoad = false;
$files = array();
$user = OC_User::getUser();
if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we need to upgrade the cache
$needUpgrade = true;
$freeSpace = 0;
} else {
$files = \OCA\files\lib\Helper::getFiles($dir);
if ($isIE8){
// after the redirect above, the URL will have a format
// like "files#?dir=path" which means that no path was given
// (dir is not set). In that specific case, we don't return any
// files because the client will take care of switching the dir
// to the one from the hash, then ajax-load the initial file list
$files = array();
$ajaxLoad = true;
}
else{
$files = \OCA\files\lib\Helper::getFiles($dir);
}
$freeSpace = \OC\Files\Filesystem::free_space($dir);
$needUpgrade = false;
}
@ -106,5 +133,6 @@ if ($needUpgrade) {
$tmpl->assign('publicUploadEnabled', $publicUploadEnabled);
$tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles());
$tmpl->assign('disableSharing', false);
$tmpl->assign('ajaxLoad', $ajaxLoad);
$tmpl->printPage();
}

View File

@ -160,23 +160,31 @@ var FileList={
* @param targetDir target directory (non URL encoded)
* @param changeUrl false if the URL must not be changed (defaults to true)
*/
changeDirectory: function(targetDir, changeUrl){
changeDirectory: function(targetDir, changeUrl, force){
var $dir = $('#dir'),
url,
currentDir = $dir.val() || '/';
targetDir = targetDir || '/';
if (currentDir === targetDir){
if (!force && currentDir === targetDir){
return;
}
FileList.setCurrentDir(targetDir, changeUrl);
FileList.reload();
},
linkTo: function(dir){
return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
},
setCurrentDir: function(targetDir, changeUrl){
$('#dir').val(targetDir);
// Note: IE8 handling ignored for now
if (window.history.pushState && changeUrl !== false){
url = OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(targetDir).replace(/%2F/g, '/'),
window.history.pushState({dir: targetDir}, '', url);
if (changeUrl !== false){
if (window.history.pushState && changeUrl !== false){
url = FileList.linkTo(targetDir);
window.history.pushState({dir: targetDir}, '', url);
}
// use URL hash for IE8
else{
window.location.hash = '?dir='+ encodeURIComponent(targetDir).replace(/%2F/g, '/');
}
}
},
/**
@ -837,6 +845,37 @@ $(document).ready(function(){
$(window).trigger('beforeunload');
});
function parseHashQuery(){
var hash = window.location.hash,
pos = hash.indexOf('?'),
query;
if (pos >= 0){
return hash.substr(pos + 1);
}
return '';
}
function parseCurrentDirFromUrl(){
var query = parseHashQuery(),
params,
dir = '/';
// try and parse from URL hash first
if (query){
params = OC.parseQueryString(query);
}
// else read from query attributes
if (!params){
params = OC.parseQueryString(location.search);
}
return (params && params.dir) || '/';
}
// fallback to hashchange when no history support
if (!window.history.pushState){
$(window).on('hashchange', function(){
FileList.changeDirectory(parseCurrentDirFromUrl(), false);
});
}
window.onpopstate = function(e){
var targetDir;
if (e.state && e.state.dir){
@ -844,12 +883,17 @@ $(document).ready(function(){
}
else{
// read from URL
targetDir = (OC.parseQueryString(location.search) || {dir: '/'}).dir || '/';
targetDir = parseCurrentDirFromUrl();
}
if (targetDir){
FileList.changeDirectory(targetDir, false);
}
}
if (parseInt($('#ajaxLoad').val(), 10) === 1){
// need to initially switch the dir to the one from the hash (IE8)
FileList.changeDirectory(parseCurrentDirFromUrl(), false, true);
}
FileList.createFileSummary();
});

View File

@ -55,7 +55,7 @@
<input type="hidden" name="permissions" value="<?php p($_['permissions']); ?>" id="permissions">
</div>
<div id="emptycontent" <?php if (!isset($_['files']) or !$_['isCreatable'] or count($_['files']) > 0):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div>
<div id="emptycontent" <?php if (!isset($_['files']) or !$_['isCreatable'] or count($_['files']) > 0 or !$_['ajaxLoad']):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div>
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input>
@ -120,6 +120,7 @@
</div>
<!-- config hints for javascript -->
<input type="hidden" name="ajaxLoad" id="ajaxLoad" value="<?php p($_['ajaxLoad']); ?>" />
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php p($_['allowZipDownload']); ?>" />
<input type="hidden" name="usedSpacePercent" id="usedSpacePercent" value="<?php p($_['usedSpacePercent']); ?>" />
<input type="hidden" name="encryptedFiles" id="encryptedFiles" value="<?php $_['encryptedFiles'] ? p('1') : p('0'); ?>" />

View File

@ -19,11 +19,6 @@ FileList.reload = function(){
});
}
FileList.setCurrentDir = function(targetDir, changeUrl){
$('#dir').val(targetDir);
// Note: IE8 handling ignored for now
if (window.history.pushState && changeUrl !== false){
url = OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(targetDir).replace(/%2F/g, '/'),
window.history.pushState({dir: targetDir}, '', url);
}
FileList.linkTo = function(dir){
return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
}