Merge pull request #7724 from owncloud/mobile
[WIP] Mobile optimization for base layout and Files app
This commit is contained in:
commit
e3b951f412
|
@ -77,10 +77,10 @@
|
||||||
}
|
}
|
||||||
/* make sure there's enough room for the file actions */
|
/* make sure there's enough room for the file actions */
|
||||||
#body-user #filestable {
|
#body-user #filestable {
|
||||||
min-width: 750px;
|
min-width: 688px; /* 768 (mobile break) - 80 (nav width) */
|
||||||
}
|
}
|
||||||
#body-user #controls {
|
#body-user #controls {
|
||||||
min-width: 600px;
|
min-width: 688px; /* 768 (mobile break) - 80 (nav width) */
|
||||||
}
|
}
|
||||||
|
|
||||||
#filestable tbody tr { background-color:#fff; height:40px; }
|
#filestable tbody tr { background-color:#fff; height:40px; }
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
|
||||||
|
/* don’t require a minimum width for files table */
|
||||||
|
#body-user #filestable {
|
||||||
|
min-width: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not show Deleted Files on mobile, not optimized yet and button too long */
|
||||||
|
#controls #trash {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hide size and date columns */
|
||||||
|
table th#headerSize,
|
||||||
|
table td.filesize,
|
||||||
|
table th#headerDate,
|
||||||
|
table td.date {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove shift for multiselect bar to account for missing navigation */
|
||||||
|
table.multiselect thead {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restrict length of displayed filename to prevent overflow */
|
||||||
|
table td.filename .nametext {
|
||||||
|
max-width: 75% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* always show actions on mobile, not only on hover */
|
||||||
|
#fileList a.action {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)" !important;
|
||||||
|
filter: alpha(opacity=20) !important;
|
||||||
|
opacity: .2 !important;
|
||||||
|
display: inline !important;
|
||||||
|
}
|
||||||
|
/* do not show Rename or Versions on mobile */
|
||||||
|
#fileList .action.action-rename,
|
||||||
|
#fileList .action.action-versions {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/* some padding for better clickability */
|
||||||
|
#fileList a.action img {
|
||||||
|
padding: 0 6px 0 12px;
|
||||||
|
}
|
||||||
|
/* hide text of the actions on mobile */
|
||||||
|
#fileList a.action span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ellipsis on file names */
|
||||||
|
.nametext {
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* proper notification area for multi line messages */
|
||||||
|
#notification-container {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ OCP\User::checkLoggedIn();
|
||||||
// Load the files we need
|
// Load the files we need
|
||||||
OCP\Util::addStyle('files', 'files');
|
OCP\Util::addStyle('files', 'files');
|
||||||
OCP\Util::addStyle('files', 'upload');
|
OCP\Util::addStyle('files', 'upload');
|
||||||
|
OCP\Util::addStyle('files', 'mobile');
|
||||||
OCP\Util::addscript('files', 'file-upload');
|
OCP\Util::addscript('files', 'file-upload');
|
||||||
OCP\Util::addscript('files', 'jquery.iframe-transport');
|
OCP\Util::addscript('files', 'jquery.iframe-transport');
|
||||||
OCP\Util::addscript('files', 'jquery.fileupload');
|
OCP\Util::addscript('files', 'jquery.fileupload');
|
||||||
|
|
|
@ -15,21 +15,33 @@ var FileActions = {
|
||||||
defaults: {},
|
defaults: {},
|
||||||
icons: {},
|
icons: {},
|
||||||
currentFile: null,
|
currentFile: null,
|
||||||
register: function (mime, name, permissions, icon, action) {
|
register: function (mime, name, permissions, icon, action, displayName) {
|
||||||
if (!FileActions.actions[mime]) {
|
if (!FileActions.actions[mime]) {
|
||||||
FileActions.actions[mime] = {};
|
FileActions.actions[mime] = {};
|
||||||
}
|
}
|
||||||
if (!FileActions.actions[mime][name]) {
|
if (!FileActions.actions[mime][name]) {
|
||||||
FileActions.actions[mime][name] = {};
|
FileActions.actions[mime][name] = {};
|
||||||
}
|
}
|
||||||
|
if (!displayName) {
|
||||||
|
displayName = t('files', name);
|
||||||
|
}
|
||||||
FileActions.actions[mime][name]['action'] = action;
|
FileActions.actions[mime][name]['action'] = action;
|
||||||
FileActions.actions[mime][name]['permissions'] = permissions;
|
FileActions.actions[mime][name]['permissions'] = permissions;
|
||||||
|
FileActions.actions[mime][name]['displayName'] = displayName;
|
||||||
FileActions.icons[name] = icon;
|
FileActions.icons[name] = icon;
|
||||||
},
|
},
|
||||||
setDefault: function (mime, name) {
|
setDefault: function (mime, name) {
|
||||||
FileActions.defaults[mime] = name;
|
FileActions.defaults[mime] = name;
|
||||||
},
|
},
|
||||||
get: function (mime, type, permissions) {
|
get: function (mime, type, permissions) {
|
||||||
|
var actions = this.getActions(mime, type, permissions);
|
||||||
|
var filteredActions = {};
|
||||||
|
$.each(actions, function (name, action) {
|
||||||
|
filteredActions[name] = action.action;
|
||||||
|
});
|
||||||
|
return filteredActions;
|
||||||
|
},
|
||||||
|
getActions: function (mime, type, permissions) {
|
||||||
var actions = {};
|
var actions = {};
|
||||||
if (FileActions.actions.all) {
|
if (FileActions.actions.all) {
|
||||||
actions = $.extend(actions, FileActions.actions.all);
|
actions = $.extend(actions, FileActions.actions.all);
|
||||||
|
@ -51,7 +63,7 @@ var FileActions = {
|
||||||
var filteredActions = {};
|
var filteredActions = {};
|
||||||
$.each(actions, function (name, action) {
|
$.each(actions, function (name, action) {
|
||||||
if (action.permissions & permissions) {
|
if (action.permissions & permissions) {
|
||||||
filteredActions[name] = action.action;
|
filteredActions[name] = action;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return filteredActions;
|
return filteredActions;
|
||||||
|
@ -82,7 +94,7 @@ var FileActions = {
|
||||||
*/
|
*/
|
||||||
display: function (parent, triggerEvent) {
|
display: function (parent, triggerEvent) {
|
||||||
FileActions.currentFile = parent;
|
FileActions.currentFile = parent;
|
||||||
var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
|
var actions = FileActions.getActions(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
|
||||||
var file = FileActions.getCurrentFile();
|
var file = FileActions.getCurrentFile();
|
||||||
var nameLinks;
|
var nameLinks;
|
||||||
if (FileList.findFileEl(file).data('renaming')) {
|
if (FileList.findFileEl(file).data('renaming')) {
|
||||||
|
@ -105,15 +117,16 @@ var FileActions = {
|
||||||
event.data.actionFunc(file);
|
event.data.actionFunc(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
var addAction = function (name, action) {
|
var addAction = function (name, action, displayName) {
|
||||||
// NOTE: Temporary fix to prevent rename action in root of Shared directory
|
// NOTE: Temporary fix to prevent rename action in root of Shared directory
|
||||||
if (name === 'Rename' && $('#dir').val() === '/Shared') {
|
if (name === 'Rename' && $('#dir').val() === '/Shared') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') {
|
if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') {
|
||||||
|
|
||||||
var img = FileActions.icons[name],
|
var img = FileActions.icons[name],
|
||||||
actionText = t('files', name),
|
actionText = displayName,
|
||||||
actionContainer = 'a.name>span.fileactions';
|
actionContainer = 'a.name>span.fileactions';
|
||||||
|
|
||||||
if (name === 'Rename') {
|
if (name === 'Rename') {
|
||||||
|
@ -125,7 +138,7 @@ var FileActions = {
|
||||||
if (img.call) {
|
if (img.call) {
|
||||||
img = img(file);
|
img = img(file);
|
||||||
}
|
}
|
||||||
var html = '<a href="#" class="action" data-action="' + name + '">';
|
var html = '<a href="#" class="action action-' + name.toLowerCase() + '" data-action="' + name + '">';
|
||||||
if (img) {
|
if (img) {
|
||||||
html += '<img class ="svg" src="' + img + '" />';
|
html += '<img class ="svg" src="' + img + '" />';
|
||||||
}
|
}
|
||||||
|
@ -133,8 +146,7 @@ var FileActions = {
|
||||||
|
|
||||||
var element = $(html);
|
var element = $(html);
|
||||||
element.data('action', name);
|
element.data('action', name);
|
||||||
//alert(element);
|
element.on('click', {a: null, elem: parent, actionFunc: actions[name].action}, actionHandler);
|
||||||
element.on('click', {a: null, elem: parent, actionFunc: actions[name]}, actionHandler);
|
|
||||||
parent.find(actionContainer).append(element);
|
parent.find(actionContainer).append(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +154,15 @@ var FileActions = {
|
||||||
|
|
||||||
$.each(actions, function (name, action) {
|
$.each(actions, function (name, action) {
|
||||||
if (name !== 'Share') {
|
if (name !== 'Share') {
|
||||||
addAction(name, action);
|
displayName = action.displayName;
|
||||||
|
ah = action.action;
|
||||||
|
|
||||||
|
addAction(name, ah, displayName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(actions.Share && !($('#dir').val() === '/' && file === 'Shared')){
|
if(actions.Share && !($('#dir').val() === '/' && file === 'Shared')){
|
||||||
// t('files', 'Share')
|
displayName = t('files', 'Share');
|
||||||
addAction('Share', actions.Share);
|
addAction('Share', actions.Share, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the existing delete action
|
// remove the existing delete action
|
||||||
|
|
|
@ -196,11 +196,14 @@ var Files = {
|
||||||
if (width !== Files.lastWidth) {
|
if (width !== Files.lastWidth) {
|
||||||
if ((width < Files.lastWidth || firstRun) && width < Files.breadcrumbsWidth) {
|
if ((width < Files.lastWidth || firstRun) && width < Files.breadcrumbsWidth) {
|
||||||
if (Files.hiddenBreadcrumbs === 0) {
|
if (Files.hiddenBreadcrumbs === 0) {
|
||||||
Files.breadcrumbsWidth -= $(Files.breadcrumbs[1]).get(0).offsetWidth;
|
bc = $(Files.breadcrumbs[1]).get(0);
|
||||||
$(Files.breadcrumbs[1]).find('a').hide();
|
if (typeof bc != 'undefined') {
|
||||||
$(Files.breadcrumbs[1]).append('<span>...</span>');
|
Files.breadcrumbsWidth -= bc.offsetWidth;
|
||||||
Files.breadcrumbsWidth += $(Files.breadcrumbs[1]).get(0).offsetWidth;
|
$(Files.breadcrumbs[1]).find('a').hide();
|
||||||
Files.hiddenBreadcrumbs = 2;
|
$(Files.breadcrumbs[1]).append('<span>...</span>');
|
||||||
|
Files.breadcrumbsWidth += bc.offsetWidth;
|
||||||
|
Files.hiddenBreadcrumbs = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var i = Files.hiddenBreadcrumbs;
|
var i = Files.hiddenBreadcrumbs;
|
||||||
while (width < Files.breadcrumbsWidth && i > 1 && i < Files.breadcrumbs.length - 1) {
|
while (width < Files.breadcrumbsWidth && i > 1 && i < Files.breadcrumbs.length - 1) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 768px) {
|
||||||
|
|
||||||
/* make header scroll up for single shares, more view of content on small screens */
|
/* make header scroll up for single shares, more view of content on small screens */
|
||||||
#header.share-file {
|
#header.share-file {
|
||||||
|
@ -45,5 +45,13 @@ table td.filename .nametext {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ellipsis on file names */
|
||||||
|
.nametext {
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ $(document).ready(function(){
|
||||||
// Add versions button to 'files/index.php'
|
// Add versions button to 'files/index.php'
|
||||||
FileActions.register(
|
FileActions.register(
|
||||||
'file'
|
'file'
|
||||||
, t('files_versions', 'Versions')
|
, 'Versions'
|
||||||
, OC.PERMISSION_UPDATE
|
, OC.PERMISSION_UPDATE
|
||||||
, function() {
|
, function() {
|
||||||
// Specify icon for hitory button
|
// Specify icon for hitory button
|
||||||
|
@ -36,6 +36,7 @@ $(document).ready(function(){
|
||||||
createVersionsDropdown(filename, file);
|
createVersionsDropdown(filename, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
, t('files_versions', 'Versions')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 768px) {
|
||||||
|
|
||||||
|
/* show caret indicator next to logo to make clear it is tappable */
|
||||||
|
#owncloud.menutoggle {
|
||||||
|
background-image: url('../img/actions/caret.svg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right 26px;
|
||||||
|
padding-right: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* compress search box on mobile, expand when focused */
|
/* compress search box on mobile, expand when focused */
|
||||||
.searchbox input[type="search"] {
|
.searchbox input[type="search"] {
|
||||||
|
@ -18,5 +26,80 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* toggle navigation */
|
||||||
|
#content-wrapper {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navigation {
|
||||||
|
top: 45px;
|
||||||
|
bottom: initial;
|
||||||
|
width: 255px;
|
||||||
|
max-height: 90%;
|
||||||
|
margin-top: 0;
|
||||||
|
top: 45px;
|
||||||
|
background-color: rgba(36, 40, 47, .97);
|
||||||
|
overflow-x: initial;
|
||||||
|
border-bottom-right-radius: 7px;
|
||||||
|
border-bottom: 1px #333 solid;
|
||||||
|
border-right: 1px #333 solid;
|
||||||
|
box-shadow: 0 0 7px rgba(29,45,68,.97);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#navigation, #navigation * {
|
||||||
|
box-sizing:border-box; -moz-box-sizing:border-box;
|
||||||
|
}
|
||||||
|
#navigation li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#navigation a {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#navigation a span {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 13px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
#navigation .icon {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#navigation li:first-child .icon {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
/* Apps management as sticky footer */
|
||||||
|
#navigation .wrapper {
|
||||||
|
min-height: initial;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#apps-management, #navigation .push {
|
||||||
|
height: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* shift to account for missing navigation */
|
||||||
|
#body-user #controls,
|
||||||
|
#body-settings #controls {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don’t require a minimum width for controls bar */
|
||||||
|
#controls {
|
||||||
|
min-width: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* position share dropdown */
|
||||||
|
#dropdown {
|
||||||
|
margin-right: 10% !important;
|
||||||
|
width: 80% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,7 @@ input[type="submit"].enabled {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
top:45px;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
|
|
108
core/js/js.js
108
core/js/js.js
|
@ -482,6 +482,53 @@ var OC={
|
||||||
}).show();
|
}).show();
|
||||||
}, 'html');
|
}, 'html');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// for menu toggling
|
||||||
|
registerMenu: function($toggle, $menuEl) {
|
||||||
|
$menuEl.addClass('menu');
|
||||||
|
$toggle.addClass('menutoggle');
|
||||||
|
$toggle.on('click.menu', function(event) {
|
||||||
|
if ($menuEl.is(OC._currentMenu)) {
|
||||||
|
$menuEl.hide();
|
||||||
|
OC._currentMenu = null;
|
||||||
|
OC._currentMenuToggle = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// another menu was open?
|
||||||
|
else if (OC._currentMenu) {
|
||||||
|
// close it
|
||||||
|
OC._currentMenu.hide();
|
||||||
|
}
|
||||||
|
$menuEl.show();
|
||||||
|
OC._currentMenu = $menuEl;
|
||||||
|
OC._currentMenuToggle = $toggle;
|
||||||
|
return false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unregisterMenu: function($toggle, $menuEl) {
|
||||||
|
// close menu if opened
|
||||||
|
if ($menuEl.is(OC._currentMenu)) {
|
||||||
|
$menuEl.hide();
|
||||||
|
OC._currentMenu = null;
|
||||||
|
OC._currentMenuToggle = null;
|
||||||
|
}
|
||||||
|
$toggle.off('click.menu').removeClass('menutoggle');
|
||||||
|
$menuEl.removeClass('menu');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for matchMedia
|
||||||
|
*
|
||||||
|
* This is makes it possible for unit tests to
|
||||||
|
* stub matchMedia (which doesn't work in PhantomJS)
|
||||||
|
*/
|
||||||
|
_matchMedia: function(media) {
|
||||||
|
if (window.matchMedia) {
|
||||||
|
return window.matchMedia(media);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
OC.search.customResults={};
|
OC.search.customResults={};
|
||||||
|
@ -940,6 +987,67 @@ function initCore() {
|
||||||
$('a.action').tipsy({gravity:'s', fade:true, live:true});
|
$('a.action').tipsy({gravity:'s', fade:true, live:true});
|
||||||
$('td .modified').tipsy({gravity:'s', fade:true, live:true});
|
$('td .modified').tipsy({gravity:'s', fade:true, live:true});
|
||||||
$('input').tipsy({gravity:'w', fade:true});
|
$('input').tipsy({gravity:'w', fade:true});
|
||||||
|
|
||||||
|
// toggle for menus
|
||||||
|
$(document).on('mouseup.closemenus', function(event) {
|
||||||
|
var $el = $(event.target);
|
||||||
|
if ($el.closest('.menu').length || $el.closest('.menutoggle').length) {
|
||||||
|
// don't close when clicking on the menu directly or a menu toggle
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OC._currentMenu) {
|
||||||
|
OC._currentMenu.hide();
|
||||||
|
}
|
||||||
|
OC._currentMenu = null;
|
||||||
|
OC._currentMenuToggle = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the main menu toggle to react to media query changes.
|
||||||
|
* If the screen is small enough, the main menu becomes a toggle.
|
||||||
|
* If the screen is bigger, the main menu is not a toggle any more.
|
||||||
|
*/
|
||||||
|
function setupMainMenu() {
|
||||||
|
// toggle the navigation on mobile
|
||||||
|
if (!OC._matchMedia) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var mq = OC._matchMedia('(max-width: 768px)');
|
||||||
|
var lastMatch = mq.matches;
|
||||||
|
var $toggle = $('#header #owncloud');
|
||||||
|
var $navigation = $('#navigation');
|
||||||
|
|
||||||
|
function updateMainMenu() {
|
||||||
|
// mobile mode ?
|
||||||
|
if (lastMatch && !$toggle.hasClass('menutoggle')) {
|
||||||
|
// init the menu
|
||||||
|
OC.registerMenu($toggle, $navigation);
|
||||||
|
$toggle.data('oldhref', $toggle.attr('href'));
|
||||||
|
$toggle.attr('href', '#');
|
||||||
|
$navigation.hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OC.unregisterMenu($toggle, $navigation);
|
||||||
|
$toggle.attr('href', $toggle.data('oldhref'));
|
||||||
|
$navigation.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMainMenu();
|
||||||
|
|
||||||
|
// TODO: debounce this
|
||||||
|
$(window).resize(function() {
|
||||||
|
if (lastMatch !== mq.matches) {
|
||||||
|
lastMatch = mq.matches;
|
||||||
|
updateMainMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.matchMedia) {
|
||||||
|
setupMainMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(initCore);
|
$(document).ready(initCore);
|
||||||
|
|
|
@ -48,7 +48,7 @@ OC.Share={
|
||||||
var action = $(file).find('.fileactions .action[data-action="Share"]');
|
var action = $(file).find('.fileactions .action[data-action="Share"]');
|
||||||
var img = action.find('img').attr('src', image);
|
var img = action.find('img').attr('src', image);
|
||||||
action.addClass('permanent');
|
action.addClass('permanent');
|
||||||
action.html(' '+t('core', 'Shared')).prepend(img);
|
action.html(' <span>'+t('core', 'Shared')+'</span>').prepend(img);
|
||||||
} else {
|
} else {
|
||||||
var dir = $('#dir').val();
|
var dir = $('#dir').val();
|
||||||
if (dir.length > 1) {
|
if (dir.length > 1) {
|
||||||
|
@ -63,7 +63,7 @@ OC.Share={
|
||||||
if (img.attr('src') != OC.imagePath('core', 'actions/public')) {
|
if (img.attr('src') != OC.imagePath('core', 'actions/public')) {
|
||||||
img.attr('src', image);
|
img.attr('src', image);
|
||||||
$(action).addClass('permanent');
|
$(action).addClass('permanent');
|
||||||
$(action).html(' '+t('core', 'Shared')).prepend(img);
|
$(action).html(' <span>'+t('core', 'Shared')+'</span>').prepend(img);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -103,10 +103,10 @@ OC.Share={
|
||||||
var img = action.find('img').attr('src', image);
|
var img = action.find('img').attr('src', image);
|
||||||
if (shares) {
|
if (shares) {
|
||||||
action.addClass('permanent');
|
action.addClass('permanent');
|
||||||
action.html(' '+ escapeHTML(t('core', 'Shared'))).prepend(img);
|
action.html(' <span>'+ escapeHTML(t('core', 'Shared'))+'</span>').prepend(img);
|
||||||
} else {
|
} else {
|
||||||
action.removeClass('permanent');
|
action.removeClass('permanent');
|
||||||
action.html(' '+ escapeHTML(t('core', 'Share'))).prepend(img);
|
action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,5 +279,109 @@ describe('Core base tests', function() {
|
||||||
expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt');
|
expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Main menu mobile toggle', function() {
|
||||||
|
var oldMatchMedia;
|
||||||
|
var $toggle;
|
||||||
|
var $navigation;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
oldMatchMedia = OC._matchMedia;
|
||||||
|
// a separate method was needed because window.matchMedia
|
||||||
|
// cannot be stubbed due to a bug in PhantomJS:
|
||||||
|
// https://github.com/ariya/phantomjs/issues/12069
|
||||||
|
OC._matchMedia = sinon.stub();
|
||||||
|
$('#testArea').append('<div id="header">' +
|
||||||
|
'<a id="owncloud" href="#"></a>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div id="navigation"></div>');
|
||||||
|
$toggle = $('#owncloud');
|
||||||
|
$navigation = $('#navigation');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
OC._matchMedia = oldMatchMedia;
|
||||||
|
});
|
||||||
|
it('Sets up menu toggle in mobile mode', function() {
|
||||||
|
OC._matchMedia.returns({matches: true});
|
||||||
|
window.initCore();
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(true);
|
||||||
|
expect($navigation.hasClass('menu')).toEqual(true);
|
||||||
|
});
|
||||||
|
it('Does not set up menu toggle in desktop mode', function() {
|
||||||
|
OC._matchMedia.returns({matches: false});
|
||||||
|
window.initCore();
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(false);
|
||||||
|
expect($navigation.hasClass('menu')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('Switches on menu toggle when mobile mode changes', function() {
|
||||||
|
var mq = {matches: false};
|
||||||
|
OC._matchMedia.returns(mq);
|
||||||
|
window.initCore();
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(false);
|
||||||
|
mq.matches = true;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(true);
|
||||||
|
});
|
||||||
|
it('Switches off menu toggle when mobile mode changes', function() {
|
||||||
|
var mq = {matches: true};
|
||||||
|
OC._matchMedia.returns(mq);
|
||||||
|
window.initCore();
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(true);
|
||||||
|
mq.matches = false;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($toggle.hasClass('menutoggle')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('Clicking menu toggle toggles navigation in mobile mode', function() {
|
||||||
|
OC._matchMedia.returns({matches: true});
|
||||||
|
window.initCore();
|
||||||
|
$navigation.hide(); // normally done through media query triggered CSS
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
$toggle.click();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
$toggle.click();
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('Clicking menu toggle does not toggle navigation in desktop mode', function() {
|
||||||
|
OC._matchMedia.returns({matches: false});
|
||||||
|
window.initCore();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
$toggle.click();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
});
|
||||||
|
it('Switching to mobile mode hides navigation', function() {
|
||||||
|
var mq = {matches: false};
|
||||||
|
OC._matchMedia.returns(mq);
|
||||||
|
window.initCore();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
mq.matches = true;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('Switching to desktop mode shows navigation', function() {
|
||||||
|
var mq = {matches: true};
|
||||||
|
OC._matchMedia.returns(mq);
|
||||||
|
window.initCore();
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
mq.matches = false;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
});
|
||||||
|
it('Switch to desktop with opened menu then back to mobile resets toggle', function() {
|
||||||
|
var mq = {matches: true};
|
||||||
|
OC._matchMedia.returns(mq);
|
||||||
|
window.initCore();
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
$toggle.click();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
mq.matches = false;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
mq.matches = true;
|
||||||
|
$(window).trigger('resize');
|
||||||
|
expect($navigation.is(':visible')).toEqual(false);
|
||||||
|
$toggle.click();
|
||||||
|
expect($navigation.is(':visible')).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</title>
|
</title>
|
||||||
<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">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
|
||||||
<meta name="apple-itunes-app" content="app-id=543672169">
|
<meta name="apple-itunes-app" content="app-id=543672169">
|
||||||
<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
|
<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
|
||||||
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
|
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
|
||||||
|
|
Loading…
Reference in New Issue