summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/Command/Db/AddMissingIndices.php91
-rw-r--r--core/Command/Maintenance/Repair.php2
-rw-r--r--core/Command/Maintenance/UpdateTheme.php2
-rw-r--r--core/Controller/LoginController.php1
-rw-r--r--core/Migrations/Version13000Date20170718121200.php1
-rw-r--r--core/css/fixes.scss7
-rw-r--r--core/css/header.scss14
-rw-r--r--core/css/mobile.scss2
-rw-r--r--core/css/styles.scss16
-rw-r--r--core/js/jquery.avatar.js77
-rw-r--r--core/js/lostpassword.js1
-rw-r--r--core/js/placeholder.js5
-rw-r--r--core/js/tests/specs/jquery.avatarSpec.js137
-rw-r--r--core/register_command.php1
-rw-r--r--core/templates/login.php2
15 files changed, 213 insertions, 146 deletions
diff --git a/core/Command/Db/AddMissingIndices.php b/core/Command/Db/AddMissingIndices.php
new file mode 100644
index 00000000000..314bed8ccb1
--- /dev/null
+++ b/core/Command/Db/AddMissingIndices.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\Core\Command\Db;
+
+use OC\DB\SchemaWrapper;
+use OCP\IDBConnection;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Class AddMissingIndices
+ *
+ * if you added any new indices to the database, this is the right place to add
+ * it your update routine for existing instances
+ *
+ * @package OC\Core\Command\Db
+ */
+class AddMissingIndices extends Command {
+
+ /** @var IDBConnection */
+ private $connection;
+
+ /**
+ * @param IDBConnection $connection
+ */
+ public function __construct(IDBConnection $connection) {
+ $this->connection = $connection;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('db:add-missing-indices')
+ ->setDescription('Add missing indices to the database tables');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->addShareTableIndicies($output);
+
+ }
+
+ /**
+ * add missing indices to the share table
+ *
+ * @param OutputInterface $output
+ * @throws \Doctrine\DBAL\Schema\SchemaException
+ */
+ private function addShareTableIndicies(OutputInterface $output) {
+
+ $output->writeln('<info>Check indices of the share table.</info>');
+
+ $schema = new SchemaWrapper($this->connection);
+ $updated = false;
+
+ if ($schema->hasTable("share")) {
+ $table = $schema->getTable("share");
+ if (!$table->hasIndex('share_with_index')) {
+ $output->writeln('<info>Adding additional index to the share table, this can take some time...</info>');
+ $table->addIndex(['share_with'], 'share_with_index');
+ $this->connection->migrateToSchema($schema->getWrappedSchema());
+ $updated = true;
+ $output->writeln('<info>Share table updated successfully.</info>');
+ }
+ }
+
+ if (!$updated) {
+ $output->writeln('<info>Done.</info>');
+ }
+ }
+}
diff --git a/core/Command/Maintenance/Repair.php b/core/Command/Maintenance/Repair.php
index 9401dafd26b..71d13cd29f3 100644
--- a/core/Command/Maintenance/Repair.php
+++ b/core/Command/Maintenance/Repair.php
@@ -86,7 +86,7 @@ class Repair extends Command {
$apps = $this->appManager->getInstalledApps();
foreach ($apps as $app) {
- if (!$appManager->isEnabledForUser($app)) {
+ if (!$this->appManager->isEnabledForUser($app)) {
continue;
}
$info = \OC_App::getAppInfo($app);
diff --git a/core/Command/Maintenance/UpdateTheme.php b/core/Command/Maintenance/UpdateTheme.php
index cf015b82635..2ab66a4ce75 100644
--- a/core/Command/Maintenance/UpdateTheme.php
+++ b/core/Command/Maintenance/UpdateTheme.php
@@ -57,7 +57,7 @@ class UpdateTheme extends UpdateJS {
parent::execute($input, $output);
// cleanup image cache
- $c = $this->cacheFactory->create('imagePath');
+ $c = $this->cacheFactory->createDistributed('imagePath');
$c->clear('');
$output->writeln('<info>Image cache cleared');
}
diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php
index e87e097e423..e53095a7de7 100644
--- a/core/Controller/LoginController.php
+++ b/core/Controller/LoginController.php
@@ -179,6 +179,7 @@ class LoginController extends Controller {
$parameters['alt_login'] = OC_App::getAlternativeLogIns();
$parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0;
+ $parameters['hideRemeberLoginState'] = !empty($redirect_url) && $this->session->exists('client.flow.state.token');
if (!is_null($user) && $user !== '') {
$parameters['loginName'] = $user;
diff --git a/core/Migrations/Version13000Date20170718121200.php b/core/Migrations/Version13000Date20170718121200.php
index 0ab777f6de2..e71debfcb4b 100644
--- a/core/Migrations/Version13000Date20170718121200.php
+++ b/core/Migrations/Version13000Date20170718121200.php
@@ -400,6 +400,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep {
$table->addIndex(['item_type', 'share_type'], 'item_share_type_index');
$table->addIndex(['file_source'], 'file_source_index');
$table->addIndex(['token'], 'token_index');
+ $table->addIndex(['share_with'], 'share_with_index');
}
if (!$schema->hasTable('jobs')) {
diff --git a/core/css/fixes.scss b/core/css/fixes.scss
index 3cb89c6599f..0303b4d751a 100644
--- a/core/css/fixes.scss
+++ b/core/css/fixes.scss
@@ -16,3 +16,10 @@ select {
visibility: hidden;
}
+.ie #header .menu,
+.ie .header-left #navigation,
+.ie .ui-datepicker,
+.ie .ui-timepicker.ui-widget,
+.ie #appmenu li span {
+ box-shadow: 0 1px 10px $color-box-shadow;
+}
diff --git a/core/css/header.scss b/core/css/header.scss
index 21305de0d02..b38c0bcb401 100644
--- a/core/css/header.scss
+++ b/core/css/header.scss
@@ -76,13 +76,16 @@
.menu {
top: 45px;
background-color: $color-main-background;
- filter: drop-shadow(0 1px 3px $color-box-shadow);
+ filter: drop-shadow(0 1px 10px $color-box-shadow);
border-radius: 0 0 3px 3px;
- display: none;
box-sizing: border-box;
z-index: 2000;
position: absolute;
+ &:not(.popovermenu) {
+ display: none;
+ }
+
/* Dropdown arrow */
&:after {
border: 10px solid transparent;
@@ -210,7 +213,7 @@ nav {
left: -100%;
width: 160px;
background-color: $color-main-background;
- filter: drop-shadow(0 1px 3px $color-box-shadow);
+ filter: drop-shadow(0 1px 10px $color-box-shadow);
&:after {
/* position of dropdown arrow */
left: 47%;
@@ -408,7 +411,6 @@ nav {
#expanddiv {
right: 13px;
background: $color-main-background;
- box-shadow: 0 1px 10px $color-box-shadow;
&:after {
/* position of dropdown arrow */
right: 13px;
@@ -483,7 +485,7 @@ nav {
display: none;
position: absolute;
overflow: visible;
- background-color: rgba($color-main-background, .97);
+ background-color: $color-main-background;
white-space: nowrap;
border: none;
border-radius: $border-radius;
@@ -496,7 +498,7 @@ nav {
top: 45px;
transform: translateX(-50%);
padding: 4px 10px;
- box-shadow: 0 1px 10px $color-box-shadow;
+ filter: drop-shadow(0 1px 10px $color-box-shadow);
}
li:hover span {
diff --git a/core/css/mobile.scss b/core/css/mobile.scss
index 19518479987..6f1583cb77a 100644
--- a/core/css/mobile.scss
+++ b/core/css/mobile.scss
@@ -83,9 +83,7 @@
/* position controls for apps with app-navigation */
#app-navigation+#app-content #controls {
- left: 0 !important;
padding-left: 44px;
- width: 100%;
}
/* .viewer-mode is when text editor, PDF viewer, etc is open */
diff --git a/core/css/styles.scss b/core/css/styles.scss
index 5474b41a2b4..1b76e3c68de 100644
--- a/core/css/styles.scss
+++ b/core/css/styles.scss
@@ -223,29 +223,23 @@ body {
#controls {
box-sizing: border-box;
- position: fixed;
- top: 45px;
- right: 0;
- left: 0;
+ position: -webkit-sticky;
+ position: sticky;
height: 44px;
- width: calc(100% - 250px);
padding: 0;
margin: 0;
background-color: rgba($color-main-background, 0.95);
- z-index: 50;
+ z-index: 55;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
- display: inline-flex;
+ display: flex;
+ top: 0;
}
/* position controls for apps with app-navigation */
-#app-navigation + #app-content #controls {
- left: 250px;
-}
-
.viewer-mode #app-navigation + #app-content #controls {
left: 0;
}
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 54518c75cc7..958f0f9edd7 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -106,54 +106,39 @@
});
}
- // If the displayname is not defined we use the old code path
- if (typeof(displayname) === 'undefined') {
- $.get(url).always(function(result, status) {
- // if there is an error or an object returned (contains user information):
- // -> show the fallback placeholder
- if (typeof(result) === 'object' || status === 'error') {
- if (!hidedefault) {
- if (result.data && result.data.displayname) {
- $div.imageplaceholder(user, result.data.displayname);
- } else {
- // User does not exist
- setAvatarForUnknownUser($div);
- }
- } else {
- $div.hide();
- }
- // else an image is transferred and should be shown
- } else {
- $div.show();
- if (ie8fix === true) {
- $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'#'+Math.floor(Math.random()*1000)+'" alt="">');
- } else {
- $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'" alt="">');
- }
- }
- if(typeof callback === 'function') {
- callback();
- }
- });
- } else {
- // We already have the displayname so set the placeholder (to show at least something)
- if (!hidedefault) {
- $div.imageplaceholder(displayname);
- }
+ var img = new Image();
+
+ // If the new image loads successfully set it.
+ img.onload = function() {
+ $div.text('');
+ $div.append(img);
+ $div.clearimageplaceholder();
- var img = new Image();
+ if(typeof callback === 'function') {
+ callback();
+ }
+ };
+ // Fallback when avatar loading fails:
+ // Use old placeholder when a displayname attribute is defined,
+ // otherwise show the unknown user placeholder.
+ img.onerror = function () {
+ $div.clearimageplaceholder();
+ if (typeof(displayname) !== 'undefined') {
+ $div.imageplaceholder(user, displayname);
+ } else {
+ setAvatarForUnknownUser($div);
+ $div.removeClass('icon-loading');
+ }
- // If the new image loads successfully set it.
- img.onload = function() {
- $div.show();
- $div.text('');
- $div.append(img);
- $div.clearimageplaceholder();
- };
+ if(typeof callback === 'function') {
+ callback();
+ }
+ };
- img.width = size;
- img.height = size;
- img.src = url;
- }
+ $div.addClass('icon-loading');
+ $div.show();
+ img.width = size;
+ img.height = size;
+ img.src = url;
};
}(jQuery));
diff --git a/core/js/lostpassword.js b/core/js/lostpassword.js
index 446d70d991e..b44962f552e 100644
--- a/core/js/lostpassword.js
+++ b/core/js/lostpassword.js
@@ -16,6 +16,7 @@ OC.Lostpassword = {
$('#lost-password').click(OC.Lostpassword.resetLink);
$('#lost-password-back').click(OC.Lostpassword.backToLogin);
$('form[name=login]').submit(OC.Lostpassword.onSendLink);
+ $('#reset-password #submit').click(OC.Lostpassword.resetPassword);
OC.Lostpassword.resetButtons();
},
diff --git a/core/js/placeholder.js b/core/js/placeholder.js
index f173e738676..5cf7b9095ad 100644
--- a/core/js/placeholder.js
+++ b/core/js/placeholder.js
@@ -2,7 +2,7 @@
* ownCloud
*
* @author John Molakvoæ
- * @copyright 2016 John Molakvoæ <fremulon@protonmail.com>
+ * @copyright 2016-2017 John Molakvoæ <skjnldsv@protonmail.com>
* @author Morris Jobke
* @copyright 2013 Morris Jobke <morris.jobke@gmail.com>
*
@@ -47,7 +47,7 @@
* <div id="albumart" style="background-color: hsl(123, 90%, 65%); ... ">A</div>
*
*/
-
+
/*
* Alternatively, you can use the prototype function to convert your string to hsl colors:
*
@@ -156,5 +156,6 @@
this.css('text-align', '');
this.css('line-height', '');
this.css('font-size', '');
+ this.removeClass('icon-loading');
};
}(jQuery));
diff --git a/core/js/tests/specs/jquery.avatarSpec.js b/core/js/tests/specs/jquery.avatarSpec.js
index b9351d2a8a0..bdd1fdcc163 100644
--- a/core/js/tests/specs/jquery.avatarSpec.js
+++ b/core/js/tests/specs/jquery.avatarSpec.js
@@ -19,6 +19,13 @@ describe('jquery.avatar tests', function() {
devicePixelRatio = window.devicePixelRatio;
window.devicePixelRatio = 1;
+
+ spyOn(window, 'Image').and.returnValue({
+ onload: function() {
+ },
+ onerror: function() {
+ }
+ });
});
afterEach(function() {
@@ -39,6 +46,9 @@ describe('jquery.avatar tests', function() {
$div.height(9);
$div.avatar('foo');
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
expect($div.height()).toEqual(9);
expect($div.width()).toEqual(9);
});
@@ -47,6 +57,9 @@ describe('jquery.avatar tests', function() {
$div.data('size', 10);
$div.avatar('foo');
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
expect($div.height()).toEqual(10);
expect($div.width()).toEqual(10);
});
@@ -55,6 +68,9 @@ describe('jquery.avatar tests', function() {
it('defined', function() {
$div.avatar('foo', 8);
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
+
expect($div.height()).toEqual(8);
expect($div.width()).toEqual(8);
});
@@ -73,16 +89,10 @@ describe('jquery.avatar tests', function() {
describe('no avatar', function() {
it('show placeholder for existing user', function() {
spyOn($div, 'imageplaceholder');
- $div.avatar('foo');
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {displayname: 'bar'}
- })
- );
+ $div.avatar('foo', undefined, undefined, undefined, undefined, 'bar');
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
expect($div.imageplaceholder).toHaveBeenCalledWith('foo', 'bar');
});
@@ -91,32 +101,23 @@ describe('jquery.avatar tests', function() {
spyOn($div, 'css');
$div.avatar('foo');
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {}
- })
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
expect($div.imageplaceholder).toHaveBeenCalledWith('?');
expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
- it('show no placeholder', function() {
+ it('show no placeholder is ignored', function() {
spyOn($div, 'imageplaceholder');
+ spyOn($div, 'css');
$div.avatar('foo', undefined, undefined, true);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify({
- data: {}
- })
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onerror();
- expect($div.imageplaceholder.calls.any()).toEqual(false);
- expect($div.css('display')).toEqual('none');
+ expect($div.imageplaceholder).toHaveBeenCalledWith('?');
+ expect($div.css).toHaveBeenCalledWith('background-color', '#b9b9b9');
});
});
@@ -129,24 +130,24 @@ describe('jquery.avatar tests', function() {
window.devicePixelRatio = 1;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/32');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('high DPI icon', function() {
window.devicePixelRatio = 4;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/128');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/128');
});
it('high DPI icon round up size', function() {
window.devicePixelRatio = 1.9;
$div.avatar('foo', 32);
- expect(fakeServer.requests[0].method).toEqual('GET');
- expect(fakeServer.requests[0].url).toEqual('http://localhost/index.php/avatar/foo/61');
+ expect(window.Image).toHaveBeenCalled();
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/61');
});
});
@@ -158,17 +159,12 @@ describe('jquery.avatar tests', function() {
it('default (no ie8 fix)', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- var img = $div.children('img')[0];
-
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/32');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('default high DPI icon', function() {
@@ -176,37 +172,23 @@ describe('jquery.avatar tests', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
-
- var img = $div.children('img')[0];
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/61');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/61');
});
- it('with ie8 fix', function() {
- sinon.stub(Math, 'random').callsFake(function() {
- return 0.5;
- });
-
+ it('with ie8 fix (ignored)', function() {
$div.avatar('foo', 32, true);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
- var img = $div.children('img')[0];
-
- expect(img.height).toEqual(32);
- expect(img.width).toEqual(32);
- expect(img.src).toEqual('http://localhost/index.php/avatar/foo/32#500');
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
});
it('unhide div', function() {
@@ -214,11 +196,12 @@ describe('jquery.avatar tests', function() {
$div.avatar('foo', 32);
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
+
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
expect($div.css('display')).toEqual('block');
});
@@ -232,12 +215,12 @@ describe('jquery.avatar tests', function() {
observer.callback();
});
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'image/jpeg' },
- ''
- );
+ expect(window.Image).toHaveBeenCalled();
+ window.Image().onload();
+ expect(window.Image().height).toEqual(32);
+ expect(window.Image().width).toEqual(32);
+ expect(window.Image().src).toEqual('http://localhost/index.php/avatar/foo/32');
expect(observer.callback).toHaveBeenCalled();
});
});
diff --git a/core/register_command.php b/core/register_command.php
index 60e151a5f2c..372d775dc14 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -90,6 +90,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig())));
$application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger()));
$application->add(new OC\Core\Command\Db\ConvertFilecacheBigInt(\OC::$server->getDatabaseConnection()));
+ $application->add(new OC\Core\Command\Db\AddMissingIndices(\OC::$server->getDatabaseConnection()));
$application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection()));
$application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection()));
$application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection()));
diff --git a/core/templates/login.php b/core/templates/login.php
index 82827bbef03..d28c92e36ef 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -70,6 +70,7 @@ script('core', 'merged-login');
<?php } ?>
<div class="login-additional">
+ <?php if (!$_['hideRemeberLoginState']) { ?>
<div class="remember-login-container">
<?php if ($_['rememberLoginState'] === 0) { ?>
<input type="checkbox" name="remember_login" value="1" id="remember_login" class="checkbox checkbox--white">
@@ -78,6 +79,7 @@ script('core', 'merged-login');
<?php } ?>
<label for="remember_login"><?php p($l->t('Stay logged in')); ?></label>
</div>
+ <?php } ?>
<?php if (!empty($_['canResetPassword'])) { ?>
<div class="lost-password-container">
<a id="lost-password" href="<?php p($_['resetPasswordLink']); ?>">