From 8977c71f8842f19077fdd0bfe27a4f48f2bc4726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Tue, 3 Jul 2018 13:23:22 +0200 Subject: [PATCH] Mixin scss icon api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/accessibility/css/themedark.scss | 6 +- .../Controller/AccessibilityController.php | 1 + apps/encryption/css/settings-personal.scss | 2 +- apps/files/css/files.scss | 16 +- .../files/lib/Activity/Filter/FileChanges.php | 2 +- apps/files_external/css/settings.scss | 2 +- core/Controller/SvgController.php | 8 +- core/css/functions.scss | 9 +- core/css/icons.scss | 259 +++++++++--------- core/css/variables.scss | 4 +- core/img/actions/starred.svg | 1 - lib/private/Group/Group.php | 2 +- lib/private/Template/IconsCacher.php | 138 ++++++++++ lib/private/Template/SCSSCacher.php | 110 +++++--- settings/css/settings.scss | 10 +- 15 files changed, 376 insertions(+), 194 deletions(-) delete mode 100644 core/img/actions/starred.svg create mode 100644 lib/private/Template/IconsCacher.php diff --git a/apps/accessibility/css/themedark.scss b/apps/accessibility/css/themedark.scss index 685a226f10..ecde4ec4c8 100644 --- a/apps/accessibility/css/themedark.scss +++ b/apps/accessibility/css/themedark.scss @@ -17,10 +17,6 @@ $color-box-shadow: rgba(darken($color-main-background, 70%), 0.5); $color-border: lighten($color-main-background, 7%); $color-border-dark: lighten($color-main-background, 14%); -// invert svg icons colors -$color-white: #000; -$color-black: #fff; - #app-navigation > ul > li > a:first-child, #app-navigation > ul > li > ul > li > a:first-child, #expanddiv a { @@ -53,4 +49,4 @@ $color-black: #fff; [class^='icon-'], [class*=' icon-'] { filter: invert(100%); } -} \ No newline at end of file +} diff --git a/apps/accessibility/lib/Controller/AccessibilityController.php b/apps/accessibility/lib/Controller/AccessibilityController.php index ea4de77d7a..f5ec1b8fab 100644 --- a/apps/accessibility/lib/Controller/AccessibilityController.php +++ b/apps/accessibility/lib/Controller/AccessibilityController.php @@ -36,6 +36,7 @@ use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUserManager; use OCP\IUserSession; +use OC\Template\SCSSCacher; class AccessibilityController extends Controller { diff --git a/apps/encryption/css/settings-personal.scss b/apps/encryption/css/settings-personal.scss index 29e81a9968..d9846cc77f 100644 --- a/apps/encryption/css/settings-personal.scss +++ b/apps/encryption/css/settings-personal.scss @@ -11,5 +11,5 @@ /* icons for sidebar */ .nav-icon-basic-encryption-module { - background-image: icon-color('app', 'encryption', $color-black); + @include icon-color('app', 'encryption', $color-black); } \ No newline at end of file diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index a408776a30..6dcdec0711 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -84,26 +84,26 @@ /* icons for sidebar */ .nav-icon-files { - background-image: icon-color(folder, 'files', $color-black); + @include icon-color(folder, 'files', $color-black); } .nav-icon-recent { - background-image: icon-color(recent, 'files', $color-black); + @include icon-color(recent, 'files', $color-black); } .nav-icon-favorites { - background-image: icon-color(star, 'files', $color-black); + @include icon-color(star, 'files', $color-black); } .nav-icon-sharingin, .nav-icon-sharingout { - background-image: icon-color(share, 'files', $color-black); + @include icon-color(share, 'files', $color-black); } .nav-icon-sharinglinks { - background-image: icon-color(public, 'files', $color-black); + @include icon-color(public, 'files', $color-black); } .nav-icon-extstoragemounts { - background-image: icon-color(external, 'files', $color-black); + @include icon-color(external, 'files', $color-black); } .nav-icon-trashbin { - background-image: icon-color(delete, 'files', $color-black); + @include icon-color(delete, 'files', $color-black); } .nav-icon-deletedshares { background-image: url('../img/unshare.svg?v=1'); @@ -667,7 +667,7 @@ table.dragshadow td.size { background-image: none; } & .icon-starred { - background-image: url('../../../core/img/actions/starred.svg?v=1'); + @include icon-color('star-dark', 'actions', 'FC0', true); } } diff --git a/apps/files/lib/Activity/Filter/FileChanges.php b/apps/files/lib/Activity/Filter/FileChanges.php index 122dc4250f..c828755a65 100644 --- a/apps/files/lib/Activity/Filter/FileChanges.php +++ b/apps/files/lib/Activity/Filter/FileChanges.php @@ -74,7 +74,7 @@ class FileChanges implements IFilter { * @since 11.0.0 */ public function getIcon() { - return $this->url->getAbsoluteURL($this->url->imagePath('core', 'places/files-dark.svg')); + return $this->url->getAbsoluteURL($this->url->imagePath('core', 'places/files.svg')); } /** diff --git a/apps/files_external/css/settings.scss b/apps/files_external/css/settings.scss index 7784134bcd..04ecfc4162 100644 --- a/apps/files_external/css/settings.scss +++ b/apps/files_external/css/settings.scss @@ -122,5 +122,5 @@ td.mountPoint, td.backend { width:160px; } } .nav-icon-external-storage { - background-image: icon-color('app-dark', 'files_external', $color-black); + @include icon-color('app-dark', 'files_external', $color-black); } diff --git a/core/Controller/SvgController.php b/core/Controller/SvgController.php index b8e59d57d9..4d71152f54 100644 --- a/core/Controller/SvgController.php +++ b/core/Controller/SvgController.php @@ -31,6 +31,7 @@ use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\NotFoundException; use OCP\IRequest; +use OC\Template\IconsCacher; class SvgController extends Controller { @@ -40,13 +41,18 @@ class SvgController extends Controller { /** @var ITimeFactory */ protected $timeFactory; + /** @var IconsCacher */ + protected $iconsCacher; + public function __construct(string $appName, IRequest $request, - ITimeFactory $timeFactory) { + ITimeFactory $timeFactory, + IconsCacher $iconsCacher) { parent::__construct($appName, $request); $this->serverRoot = \OC::$SERVERROOT; $this->timeFactory = $timeFactory; + $this->iconsCacher = $iconsCacher; } /** diff --git a/core/css/functions.scss b/core/css/functions.scss index d7192ebe1c..19792456ed 100644 --- a/core/css/functions.scss +++ b/core/css/functions.scss @@ -30,14 +30,17 @@ * * @returns string the url to the svg api endpoint */ - @function icon-color($icon, $dir, $color, $core: false) { +@mixin icon-color($icon, $dir, $color, $core: false) { // remove # from color $index: str-index($color, '#'); @if $index { $color: str-slice($color, 2); } + $varName: "--icon-#{$icon}-#{$color}"; @if $core { - @return url('#{$webroot}/svg/core/#{$dir}/#{$icon}/#{$color}?v=1'); + #{$varName}: url('#{$webroot}/svg/core/#{$dir}/#{$icon}/#{$color}?v=1'); + } @else { + #{$varName}: url('#{$webroot}/svg/#{$dir}/#{$icon}/#{$color}?v=1'); } - @return url('#{$webroot}/svg/#{$dir}/#{$icon}/#{$color}?v=1'); + background-image: var(#{$varName}); } \ No newline at end of file diff --git a/core/css/icons.scss b/core/css/icons.scss index 6be063e2b3..b982a87d27 100644 --- a/core/css/icons.scss +++ b/core/css/icons.scss @@ -118,542 +118,543 @@ img, object, video, button, textarea, input, select, div[contenteditable='true'] /* ICONS ------------------------------------------------------------------- */ .icon-add { - background-image: icon-color('add', 'actions', $color-black, 'core'); + @include icon-color('add', 'actions', $color-black, true); } .icon-address { - background-image: icon-color('address', 'actions', $color-black, 'core'); + @include icon-color('address', 'actions', $color-black, true); } .icon-address-white { - background-image: icon-color('address', 'actions', $color-white, 'core'); + @include icon-color('address', 'actions', $color-white, true); } .icon-audio { - background-image: icon-color('audio', 'actions', $color-black, 'core'); + @include icon-color('audio', 'actions', $color-black, true); } .icon-audio-white { - background-image: icon-color('audio', 'actions', $color-white, 'core'); + @include icon-color('audio', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-audio-off { - background-image: icon-color('audio-off', 'actions', $color-black, 'core'); + @include icon-color('audio-off', 'actions', $color-black, true); } .icon-audio-off-white { - background-image: icon-color('audio-off', 'actions', $color-white, 'core'); + @include icon-color('audio-off', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-caret-white, .icon-caret { - background-image: icon-color('caret', 'actions', $color-white, 'core'); + @include icon-color('caret', 'actions', $color-white, true); } .icon-caret-dark { - background-image: icon-color('caret', 'actions', $color-black, 'core'); + @include icon-color('caret', 'actions', $color-black, true); } .icon-checkmark { - background-image: icon-color('checkmark', 'actions', $color-black, 'core'); + @include icon-color('checkmark', 'actions', $color-black, true); } .icon-checkmark-white { - background-image: icon-color('checkmark', 'actions', $color-white, 'core'); + @include icon-color('checkmark', 'actions', $color-white, true); } .icon-checkmark-color { - background-image: icon-color('checkmark', 'actions', $color-success, 'core'); + @include icon-color('checkmark', 'actions', $color-success, true); } .icon-clippy { - background-image: icon-color('clippy', 'actions', $color-black, 'core'); + @include icon-color('clippy', 'actions', $color-black, true); } .icon-close { - background-image: icon-color('close', 'actions', $color-black, 'core'); + @include icon-color('close', 'actions', $color-black, true); } .icon-close-white { - background-image: icon-color('close', 'actions', $color-white, 'core'); + @include icon-color('close', 'actions', $color-white, true); } .icon-comment { - background-image: icon-color('comment', 'actions', $color-black, 'core'); + @include icon-color('comment', 'actions', $color-black, true); } .icon-confirm { - background-image: icon-color('confirm', 'actions', $color-black, 'core'); + @include icon-color('confirm', 'actions', $color-black, true); } .icon-confirm-fade { - background-image: icon-color('confirm-fade', 'actions', $color-black, 'core'); + @include icon-color('confirm-fade', 'actions', $color-black, true); } .icon-confirm-white { - background-image: icon-color('confirm', 'actions', $color-white, 'core'); + @include icon-color('confirm', 'actions', $color-white, true); } .icon-delete { - background-image: icon-color('delete', 'actions', $color-black, 'core'); + @include icon-color('delete', 'actions', $color-black, true); &.no-permission { &:hover, &:focus { - background-image: icon-color('delete', 'actions', $color-black, 'core'); + @include icon-color('delete', 'actions', $color-black, true); } } &:hover, &:focus { - background-image: icon-color('delete', 'actions', $color-error, 'core'); + @include icon-color('delete', 'actions', $color-error, true); filter: initial; } } .icon-delete-white { - background-image: icon-color('delete', 'actions', $color-white, 'core'); + @include icon-color('delete', 'actions', $color-white, true); &.no-permission { &:hover, &:focus { - background-image: icon-color('delete', 'actions', $color-white, 'core'); + @include icon-color('delete', 'actions', $color-white, true); } } &:hover, &:focus { - background-image: icon-color('delete', 'actions', $color-error, 'core'); + @include icon-color('delete', 'actions', $color-error, true); } } .icon-details { - background-image: icon-color('details', 'actions', $color-black, 'core'); + @include icon-color('details', 'actions', $color-black, true); } .icon-download { - background-image: icon-color('download', 'actions', $color-black, 'core'); + @include icon-color('download', 'actions', $color-black, true); } .icon-download-white { - background-image: icon-color('download', 'actions', $color-white, 'core'); + @include icon-color('download', 'actions', $color-white, true); } .icon-edit { - background-image: icon-color('edit', 'actions', $color-black, 'core'); + @include icon-color('edit', 'actions', $color-black, true); } .icon-error { - background-image: icon-color('error', 'actions', $color-black, 'core'); + @include icon-color('error', 'actions', $color-black, true); } .icon-error-white { - background-image: icon-color('error', 'actions', $color-white, 'core'); + @include icon-color('error', 'actions', $color-white, true); } .icon-error-color { - background-image: icon-color('error', 'actions', $color-error, 'core'); + @include icon-color('error', 'actions', $color-error, true); } .icon-external { - background-image: icon-color('external', 'actions', $color-black, 'core'); + @include icon-color('external', 'actions', $color-black, true); } .icon-fullscreen { - background-image: icon-color('fullscreen', 'actions', $color-black, 'core'); + @include icon-color('fullscreen', 'actions', $color-black, true); } .icon-fullscreen-white { - background-image: icon-color('fullscreen', 'actions', $color-white, 'core'); + @include icon-color('fullscreen', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-history { - background-image: icon-color('history', 'actions', $color-black, 'core'); + @include icon-color('history', 'actions', $color-black, true); } .icon-info { - background-image: icon-color('info', 'actions', $color-black, 'core'); + @include icon-color('info', 'actions', $color-black, true); } .icon-info-white { - background-image: icon-color('info', 'actions', $color-white, 'core'); + @include icon-color('info', 'actions', $color-white, true); } .icon-logout { - background-image: icon-color('logout', 'actions', $color-black, 'core'); + @include icon-color('logout', 'actions', $color-black, true); } .icon-mail { - background-image: icon-color('mail', 'actions', $color-black, 'core'); + @include icon-color('mail', 'actions', $color-black, true); } .icon-menu { - background-image: icon-color('menu', 'actions', $color-black, 'core'); + @include icon-color('menu', 'actions', $color-black, true); } .icon-more { - background-image: icon-color('more', 'actions', $color-black, 'core'); + @include icon-color('more', 'actions', $color-black, true); } .icon-more-white { - background-image: icon-color('more', 'actions', $color-white) + @include icon-color('more', 'actions', $color-white) } .icon-password { - background-image: icon-color('password', 'actions', $color-black, 'core'); + @include icon-color('password', 'actions', $color-black, true); } .icon-pause { - background-image: icon-color('pause', 'actions', $color-black, 'core'); + @include icon-color('pause', 'actions', $color-black, true); } .icon-play { - background-image: icon-color('play', 'actions', $color-black, 'core'); + @include icon-color('play', 'actions', $color-black, true); } .icon-play-add { - background-image: icon-color('play-add', 'actions', $color-black, 'core'); + @include icon-color('play-add', 'actions', $color-black, true); } .icon-play-next { - background-image: icon-color('play-next', 'actions', $color-black, 'core'); + @include icon-color('play-next', 'actions', $color-black, true); } .icon-play-previous { - background-image: icon-color('play-previous', 'actions', $color-black, 'core'); + @include icon-color('play-previous', 'actions', $color-black, true); } .icon-public { - background-image: icon-color('public', 'actions', $color-black, 'core'); + @include icon-color('public', 'actions', $color-black, true); } .icon-quota { - background-image: icon-color('quota', 'actions', $color-black, 'core'); + @include icon-color('quota', 'actions', $color-black, true); } .icon-rename { - background-image: icon-color('rename', 'actions', $color-black, 'core'); + @include icon-color('rename', 'actions', $color-black, true); } .icon-screen { - background-image: icon-color('screen', 'actions', $color-black, 'core'); + @include icon-color('screen', 'actions', $color-black, true); } .icon-screen-white { - background-image: icon-color('screen', 'actions', $color-white, 'core'); + @include icon-color('screen', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-screen-off { - background-image: icon-color('screen-off', 'actions', $color-black, 'core'); + @include icon-color('screen-off', 'actions', $color-black, true); } .icon-screen-off-white { - background-image: icon-color('screen-off', 'actions', $color-white, 'core'); + @include icon-color('screen-off', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-search { - background-image: icon-color('search', 'actions', $color-black, 'core'); + @include icon-color('search', 'actions', $color-black, true); } .icon-search-white { - background-image: icon-color('search', 'actions', $color-white, 'core'); + @include icon-color('search', 'actions', $color-white, true); } /* default icon have a .5 opacity */ .icon-settings { - background-image: icon-color('settings', 'actions', $color-black, 'core'); + @include icon-color('settings', 'actions', $color-black, true); } .icon-settings-dark { - background-image: icon-color('settings-dark', 'actions', $color-black, 'core'); + @include icon-color('settings-dark', 'actions', $color-black, true); } .icon-settings-white { - background-image: icon-color('settings-dark', 'actions', $color-white, 'core'); + @include icon-color('settings-dark', 'actions', $color-white, true); } /* always use icon-shared, AdBlock blocks icon-share */ .icon-shared, .icon-share { - background-image: icon-color('share', 'actions', $color-black, 'core'); + @include icon-color('share', 'actions', $color-black, true); } .icon-sound { - background-image: icon-color('sound', 'actions', $color-black, 'core'); + @include icon-color('sound', 'actions', $color-black, true); } .icon-sound-off { - background-image: icon-color('sound-off', 'actions', $color-black, 'core'); + @include icon-color('sound-off', 'actions', $color-black, true); } .icon-favorite { - background-image: icon-color('star-dark', 'actions', $color-black, 'core'); + @include icon-color('star-dark', 'actions', $color-black, true); } .icon-star { - background-image: icon-color('star', 'actions', $color-black, 'core'); + @include icon-color('star', 'actions', $color-black, true); } .icon-star-dark { - background-image: icon-color('star-dark', 'actions', $color-black, 'core'); + @include icon-color('star-dark', 'actions', $color-black, true); } .icon-starred { &:hover, &:focus { - background-image: icon-color('star', 'actions', $color-black, 'core'); + @include icon-color('star', 'actions', $color-black, true); } - background-image: icon-color('starred', 'actions', $color-black, 'core'); + @include icon-color('star-dark', 'actions', 'FC0', true); } .icon-star { &:hover, &:focus { - background-image: icon-color('starred', 'actions', $color-black, 'core'); + @include icon-color('star-dark', 'actions', 'FC0', true); } } .icon-tag { - background-image: icon-color('tag', 'actions', $color-black, 'core'); + @include icon-color('tag', 'actions', $color-black, true); } .icon-timezone { - background-image: icon-color('timezone', 'actions', $color-black, 'core'); + @include icon-color('timezone', 'actions', $color-black, true); } .icon-toggle { - background-image: icon-color('toggle', 'actions', $color-black, 'core'); + @include icon-color('toggle', 'actions', $color-black, true); } .icon-toggle-background { - background-image: icon-color('toggle-background', 'actions', $color-black, 'core'); + @include icon-color('toggle-background', 'actions', $color-black, true); } .icon-toggle-pictures { - background-image: icon-color('toggle-pictures', 'actions', $color-black, 'core'); + @include icon-color('toggle-pictures', 'actions', $color-black, true); } .icon-triangle-e { - background-image: icon-color('triangle-e', 'actions', $color-black, 'core'); + @include icon-color('triangle-e', 'actions', $color-black, true); } .icon-triangle-n { - background-image: icon-color('triangle-n', 'actions', $color-black, 'core'); + @include icon-color('triangle-n', 'actions', $color-black, true); } .icon-triangle-s { - background-image: icon-color('triangle-s', 'actions', $color-black, 'core'); + @include icon-color('triangle-s', 'actions', $color-black, true); } .icon-upload { - background-image: icon-color('upload', 'actions', $color-black, 'core'); + @include icon-color('upload', 'actions', $color-black, true); } .icon-upload-white { - background-image: icon-color('upload', 'actions', $color-white, 'core'); + @include icon-color('upload', 'actions', $color-white, true); } .icon-user { - background-image: icon-color('user', 'actions', $color-black, 'core'); + @include icon-color('user', 'actions', $color-black, true); } .icon-video { - background-image: icon-color('video', 'actions', $color-black, 'core'); + @include icon-color('video', 'actions', $color-black, true); } .icon-video-white { - background-image: icon-color('video', 'actions', $color-white, 'core'); + @include icon-color('video', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-video-off { - background-image: icon-color('video-off', 'actions', $color-black, 'core'); + @include icon-color('video-off', 'actions', $color-black, true); } .icon-video-off-white { - background-image: icon-color('video-off', 'actions', $color-white, 'core'); + @include icon-color('video-off', 'actions', $color-white, true); filter: drop-shadow(1px 1px 4px var(--color-box-shadow)); } .icon-video-switch { - background-image: icon-color('video-switch', 'actions', $color-black, 'core'); + @include icon-color('video-switch', 'actions', $color-black, true); } .icon-view-close { - background-image: icon-color('view-close', 'actions', $color-black, 'core'); + @include icon-color('view-close', 'actions', $color-black, true); } .icon-view-download { - background-image: icon-color('view-download', 'actions', $color-black, 'core'); + @include icon-color('view-download', 'actions', $color-black, true); } .icon-view-next { - background-image: icon-color('arrow-right', 'actions', $color-black, 'core'); + @include icon-color('arrow-right', 'actions', $color-black, true); } .icon-view-pause { - background-image: icon-color('view-pause', 'actions', $color-black, 'core'); + @include icon-color('view-pause', 'actions', $color-black, true); } .icon-view-play { - background-image: icon-color('view-play', 'actions', $color-black, 'core'); + @include icon-color('view-play', 'actions', $color-black, true); } .icon-view-previous { - background-image: icon-color('arrow-left', 'actions', $color-black, 'core'); + @include icon-color('arrow-left', 'actions', $color-black, true); } .icon-disabled-user { - background-image: icon-color('disabled-user', 'actions', $color-black, 'core'); + @include icon-color('disabled-user', 'actions', $color-black, true); } .icon-disabled-users { - background-image: icon-color('disabled-users', 'actions', $color-black, 'core'); + @include icon-color('disabled-users', 'actions', $color-black, true); } .icon-user-admin { - background-image: icon-color('user-admin', 'actions', $color-black, 'core'); + @include icon-color('user-admin', 'actions', $color-black, true); } /* PLACES ------------------------------------------------------------------- */ .icon-calendar { - background-image: icon-color('calendar', 'places', $color-white, 'core'); + @include icon-color('calendar', 'places', $color-white, true); } .icon-calendar-dark { - background-image: icon-color('calendar', 'places', $color-black, 'core'); + @include icon-color('calendar', 'places', $color-black, true); } .icon-contacts { - background-image: icon-color('contacts', 'places', $color-white, 'core'); + @include icon-color('contacts', 'places', $color-white, true); } .icon-contacts-dark { - background-image: icon-color('contacts', 'places', $color-black, 'core'); + @include icon-color('contacts', 'places', $color-black, true); } .icon-files { - background-image: icon-color('files', 'places', $color-white, 'core'); + @include icon-color('files', 'places', $color-white, true); } .icon-files-dark { - background-image: icon-color('files', 'places', $color-black, 'core'); + @include icon-color('files', 'places', $color-black, true); } .icon-file, .icon-filetype-text { - background-image: icon-color('text', 'filetypes', $color-black, 'core'); + @include icon-color('text', 'filetypes', $color-black, true); } .icon-folder, .icon-filetype-folder { - background-image: icon-color('folder', 'filetypes', $color-black, 'core'); + @include icon-color('folder', 'filetypes', $color-black, true); } .icon-filetype-folder-drag-accept { - background-image: icon-color('folder-drag-accept', 'filetypes', $color-black) !important; + @include icon-color('folder-drag-accept', 'filetypes', $color-black); } .icon-home { - background-image: icon-color('home', 'places', $color-black, 'core'); + @include icon-color('home', 'places', $color-black, true); } .icon-link { - background-image: icon-color('link', 'places', $color-black, 'core'); + @include icon-color('link', 'places', $color-black, true); } .icon-music { - background-image: icon-color('music', 'places', $color-black, 'core'); + @include icon-color('music', 'places', $color-black, true); } .icon-picture { - background-image: icon-color('picture', 'places', $color-black, 'core'); + @include icon-color('picture', 'places', $color-black, true); } /* CLIENTS ------------------------------------------------------------------- */ .icon-desktop { - background-image: icon-color('desktop', 'clients', $color-black, 'core'); + @include icon-color('desktop', 'clients', $color-black, true); } .icon-phone { - background-image: icon-color('phone', 'clients', $color-black, 'core'); + @include icon-color('phone', 'clients', $color-black, true); } .icon-tablet { - background-image: icon-color('tablet', 'clients', $color-black, 'core'); + @include icon-color('tablet', 'clients', $color-black, true); } /* APP CATEGORIES ------------------------------------------------------------------- */ .icon-category-installed { - background-image: icon-color('user', 'actions', $color-black, 'core'); + @include icon-color('user', 'actions', $color-black, true); } .icon-category-enabled { - background-image: icon-color('checkmark', 'actions', $color-black, 'core'); + @include icon-color('checkmark', 'actions', $color-black, true); } .icon-category-disabled { - background-image: icon-color('close', 'actions', $color-black, 'core'); + @include icon-color('close', 'actions', $color-black, true); } .icon-category-app-bundles { - background-image: icon-color('bundles', 'categories', $color-black, 'core'); + @include icon-color('bundles', 'categories', $color-black, true); } .icon-category-updates { - background-image: icon-color('download', 'actions', $color-black, 'core'); + @include icon-color('download', 'actions', $color-black, true); } .icon-category-files { - background-image: icon-color('files', 'categories', $color-black, 'core'); + @include icon-color('files', 'categories', $color-black, true); } .icon-category-social { - background-image: icon-color('social', 'categories', $color-black, 'core'); + @include icon-color('social', 'categories', $color-black, true); } .icon-category-office { - background-image: icon-color('office', 'categories', $color-black, 'core'); + @include icon-color('office', 'categories', $color-black, true); } .icon-category-auth { - background-image: icon-color('auth', 'categories', $color-black, 'core'); + @include icon-color('auth', 'categories', $color-black, true); } .icon-category-monitoring { - background-image: icon-color('monitoring', 'categories', $color-black, 'core'); + @include icon-color('monitoring', 'categories', $color-black, true); } .icon-category-multimedia { - background-image: icon-color('multimedia', 'categories', $color-black, 'core'); + @include icon-color('multimedia', 'categories', $color-black, true); } .icon-category-organization { - background-image: icon-color('organization', 'categories', $color-black, 'core'); + @include icon-color('organization', 'categories', $color-black, true); } .icon-category-customization { - background-image: icon-color('customization', 'categories', $color-black, 'core'); + @include icon-color('customization', 'categories', $color-black, true); } .icon-category-integration { - background-image: icon-color('integration', 'categories', $color-black, 'core'); + @include icon-color('integration', 'categories', $color-black, true); } .icon-category-tools { - background-image: icon-color('settings-dark', 'actions', $color-black, 'core'); + @include icon-color('settings-dark', 'actions', $color-black, true); } .icon-category-games { - background-image: icon-color('games', 'categories', $color-black, 'core'); + @include icon-color('games', 'categories', $color-black, true); } .icon-category-security { - background-image: icon-color('password', 'actions', $color-black, 'core'); + @include icon-color('password', 'actions', $color-black, true); } .icon-category-search { - background-image: icon-color('search', 'actions', $color-black, 'core'); + @include icon-color('search', 'actions', $color-black, true); } + diff --git a/core/css/variables.scss b/core/css/variables.scss index 4d3d273f26..3cf7784939 100644 --- a/core/css/variables.scss +++ b/core/css/variables.scss @@ -50,8 +50,8 @@ $color-error: #e9322d; $color-warning: #eca700; $color-success: #46ba61; // used for svg -$color-white: #fff !default; -$color-black: #000 !default; +$color-white: #fff; +$color-black: #000; // rgb(118, 118, 118) / #767676 // min. color contrast for normal text on white background according to WCAG AA diff --git a/core/img/actions/starred.svg b/core/img/actions/starred.svg deleted file mode 100644 index 5635ea94e8..0000000000 --- a/core/img/actions/starred.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php index 0d54cf8e35..7f11487399 100644 --- a/lib/private/Group/Group.php +++ b/lib/private/Group/Group.php @@ -90,7 +90,7 @@ class Group implements IGroup { public function getDisplayName() { if (is_null($this->displayName)) { - return $this->gid; + return $this->gid.'-name'; } return $this->displayName; } diff --git a/lib/private/Template/IconsCacher.php b/lib/private/Template/IconsCacher.php new file mode 100644 index 0000000000..3f405cbf3c --- /dev/null +++ b/lib/private/Template/IconsCacher.php @@ -0,0 +1,138 @@ + + * + * @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 . + * + */ + +namespace OC\Template; + +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; +use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\ILogger; +use OCP\IURLGenerator; +use OC\Files\AppData\Factory; + +class IconsCacher { + + /** @var ILogger */ + protected $logger; + + /** @var IAppData */ + protected $appData; + + /** @var ISimpleFolder */ + private $folder; + + /** @var IURLGenerator */ + protected $urlGenerator; + + /** @var string */ + private $iconVarRE = '/--([a-z-]+): url\("([a-z0-9-\/]+)[^;]+;/m'; + + /** @var string */ + private $fileName = 'icons-vars.css'; + + /** + * @param ILogger $logger + * @param Factory $appDataFactory + * @param IURLGenerator $urlGenerator + */ + public function __construct(ILogger $logger, + Factory $appDataFactory, + IURLGenerator $urlGenerator) { + $this->logger = $logger; + $this->appData = $appDataFactory->get('css'); + $this->urlGenerator = $urlGenerator; + + try { + $this->folder = $this->appData->getFolder('icons'); + } catch (NotFoundException $e) { + $this->folder = $this->appData->newFolder('icons'); + } + } + + private function getIconsFromCss(string $css): array{ + preg_match_all($this->iconVarRE, $css, $matches, PREG_SET_ORDER); + $icons = []; + foreach ($matches as $icon) { + $icons[$icon[1]] = $icon[2]; + } + + return $icons; + } + /** + * Parse and cache css + * + * @param string $css + */ + public function setIconsCss(string $css) { + try { + $data = $this->folder->getFile($this->fileName)->getContent(); + } catch (NotFoundException $e) { + $data = ''; + } + $icons = $this->getIconsFromCss($data . $css); + + $data = ''; + foreach ($icons as $icon => $url) { + $data .= "--$icon: url('$url?v=1');"; + } + + if (strlen($data) > 0) { + try { + $cachedfile = $this->folder->getFile($this->fileName); + } catch (NotFoundException $e) { + $cachedfile = $this->folder->newFile($this->fileName); + } + + $data = ":root { + $data + }"; + $cachedfile->putContent($data); + } + + return preg_replace($this->iconVarRE, '', $css); + } + + /** + * Get icons css file + * @return ISimpleFile|boolean + */ + public function getCachedCSS() { + try { + return $this->folder->getFile($this->fileName); + } catch (NotFoundException $e) { + return false; + } + } + + public function injectCss() { + // Only inject once + foreach (\OC_Util::$headers as $header) { + if (strpos($header['attributes']['href'], $this->fileName) !== false) { + return; + } + } + $linkToCSS = substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['appName' => 'icons', 'fileName' => $this->fileName]), strlen(\OC::$WEBROOT)); + \OCP\Util::addHeader('link', ['rel' => 'stylesheet', 'href' => $linkToCSS]); + } + +} \ No newline at end of file diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php index 0b214755af..ed1383f8ea 100644 --- a/lib/private/Template/SCSSCacher.php +++ b/lib/private/Template/SCSSCacher.php @@ -32,7 +32,6 @@ use Leafo\ScssPhp\Compiler; use Leafo\ScssPhp\Exception\ParserException; use Leafo\ScssPhp\Formatter\Crunched; use Leafo\ScssPhp\Formatter\Expanded; -use OC\Files\AppData\Factory; use OCP\Files\IAppData; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -43,6 +42,8 @@ use OCP\ICacheFactory; use OCP\IConfig; use OCP\ILogger; use OCP\IURLGenerator; +use OC\Files\AppData\Factory; +use OC\Template\IconsCacher; class SCSSCacher { @@ -73,6 +74,9 @@ class SCSSCacher { /** @var ICacheFactory */ private $cacheFactory; + /** @var IconsCacher */ + private $iconsCacher; + /** * @param ILogger $logger * @param Factory $appDataFactory @@ -89,14 +93,20 @@ class SCSSCacher { \OC_Defaults $defaults, $serverRoot, ICacheFactory $cacheFactory) { - $this->logger = $logger; - $this->appData = $appDataFactory->get('css'); + $this->logger = $logger; + $this->appData = $appDataFactory->get('css'); $this->urlGenerator = $urlGenerator; - $this->config = $config; - $this->defaults = $defaults; - $this->serverRoot = $serverRoot; + $this->config = $config; + $this->defaults = $defaults; + $this->serverRoot = $serverRoot; $this->cacheFactory = $cacheFactory; - $this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl())); + $this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl())); + + $this->iconsCacher = new IconsCacher( + $this->logger, + $appDataFactory, + $this->urlGenerator + ); } /** @@ -112,23 +122,34 @@ class SCSSCacher { $path = explode('/', $root . '/' . $file); $fileNameSCSS = array_pop($path); - $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app); + $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app); - $path = implode('/', $path); + $path = implode('/', $path); $webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT); try { $folder = $this->appData->getFolder($app); - } catch(NotFoundException $e) { + } catch (NotFoundException $e) { // creating css appdata folder $folder = $this->appData->newFolder($app); } - - if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) { + if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) { + // Inject icons vars css if any + if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) { + $this->iconsCacher->injectCss(); + } return true; } - return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir); + + $cached = $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir); + + // Inject icons vars css if any + if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) { + $this->iconsCacher->injectCss(); + } + + return $cached; } /** @@ -137,8 +158,9 @@ class SCSSCacher { * @return ISimpleFile */ public function getCachedCSS(string $appName, string $fileName): ISimpleFile { - $folder = $this->appData->getFolder($appName); + $folder = $this->appData->getFolder($appName); $cachedFileName = $this->prependVersionPrefix($this->prependBaseurlPrefix($fileName), $appName); + return $folder->getFile($cachedFileName); } @@ -153,24 +175,26 @@ class SCSSCacher { $cachedFile = $folder->getFile($fileNameCSS); if ($cachedFile->getSize() > 0) { $depFileName = $fileNameCSS . '.deps'; - $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName); + $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName); if ($deps === null) { $depFile = $folder->getFile($depFileName); - $deps = $depFile->getContent(); + $deps = $depFile->getContent(); //Set to memcache for next run $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps); } $deps = json_decode($deps, true); - foreach ((array)$deps as $file=>$mtime) { + foreach ((array) $deps as $file => $mtime) { if (!file_exists($file) || filemtime($file) > $mtime) { return false; } } + return true; } + return false; - } catch(NotFoundException $e) { + } catch (NotFoundException $e) { return false; } } @@ -181,11 +205,13 @@ class SCSSCacher { */ private function variablesChanged(): bool { $injectedVariables = $this->getInjectedVariables(); - if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) { + if ($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) { $this->resetCache(); $this->config->setAppValue('core', 'scss.variables', md5($injectedVariables)); + return true; } + return false; } @@ -204,11 +230,12 @@ class SCSSCacher { $scss = new Compiler(); $scss->setImportPaths([ $path, - $this->serverRoot . '/core/css/', + $this->serverRoot . '/core/css/' ]); + // Continue after throw $scss->setIgnoreErrors(true); - if($this->config->getSystemValue('debug')) { + if ($this->config->getSystemValue('debug')) { // Debug mode $scss->setFormatter(Expanded::class); $scss->setLineNumberStyle(Compiler::LINE_COMMENTS); @@ -219,7 +246,7 @@ class SCSSCacher { try { $cachedfile = $folder->getFile($fileNameCSS); - } catch(NotFoundException $e) { + } catch (NotFoundException $e) { $cachedfile = $folder->newFile($fileNameCSS); } @@ -233,16 +260,20 @@ class SCSSCacher { // Compile try { $compiledScss = $scss->compile( - '$webroot: \'' . \OC::$WEBROOT. '\';'. - '@import "functions.scss";' . + '$webroot: \'' . \OC::$WEBROOT . '\';' . '@import "variables.scss";' . + '@import "functions.scss";' . $this->getInjectedVariables() . - '@import "'.$fileNameSCSS.'";'); - } catch(ParserException $e) { + '@import "' . $fileNameSCSS . '";'); + } catch (ParserException $e) { $this->logger->error($e, ['app' => 'core']); + return false; } + // Parse Icons and create related css variables + $compiledScss = $this->iconsCacher->setIconsCss($compiledScss); + // Gzip file try { $gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz @@ -257,10 +288,12 @@ class SCSSCacher { $depFile->putContent($deps); $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps); $gzipFile->putContent(gzencode($data, 9)); - $this->logger->debug('SCSSCacher: '.$webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']); + $this->logger->debug('SCSSCacher: ' . $webDir . '/' . $fileNameSCSS . ' compiled and successfully cached', ['app' => 'core']); + return true; - } catch(NotPermittedException $e) { + } catch (NotPermittedException $e) { $this->logger->error('SCSSCacher: unable to cache: ' . $fileNameSCSS); + return false; } } @@ -277,7 +310,7 @@ class SCSSCacher { foreach ($folder->getDirectoryListing() as $file) { try { $file->delete(); - } catch(NotPermittedException $e) { + } catch (NotPermittedException $e) { $this->logger->logException($e, ['message' => 'SCSSCacher: unable to delete file: ' . $file->getName()]); } } @@ -315,8 +348,9 @@ class SCSSCacher { * @return string */ private function rebaseUrls(string $css, string $webDir): string { - $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x'; - $subst = 'url(\''.$webDir.'/$1\')'; + $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x'; + $subst = 'url(\'' . $webDir . '/$1\')'; + return preg_replace($re, $subst, $css); } @@ -328,8 +362,8 @@ class SCSSCacher { */ public function getCachedSCSS(string $appName, string $fileName): string { $tmpfileLoc = explode('/', $fileName); - $fileName = array_pop($tmpfileLoc); - $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName); + $fileName = array_pop($tmpfileLoc); + $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName); return substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['fileName' => $fileName, 'appName' => $appName]), strlen(\OC::$WEBROOT) + 1); } @@ -341,6 +375,7 @@ class SCSSCacher { */ private function prependBaseurlPrefix(string $cssFile): string { $frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'); + return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 4) . '-' . $cssFile; } @@ -356,6 +391,7 @@ class SCSSCacher { return substr(md5($appVersion), 0, 4) . '-' . $cssFile; } $coreVersion = \OC_Util::getVersionString(); + return substr(md5($coreVersion), 0, 4) . '-' . $cssFile; } @@ -369,12 +405,14 @@ class SCSSCacher { */ private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string { // Detect if path is within server root AND if path is within an app path - if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) { + if (strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) { // Get the file path within the app directory $appDirectoryPath = explode($appName, $path)[1]; // Remove the webroot - return str_replace($webRoot, '', $appWebPath.$appDirectoryPath); + + return str_replace($webRoot, '', $appWebPath . $appDirectoryPath); } - return $webRoot.substr($path, strlen($serverRoot)); + + return $webRoot . substr($path, strlen($serverRoot)); } } diff --git a/settings/css/settings.scss b/settings/css/settings.scss index 3526e322ac..60c7f368bf 100644 --- a/settings/css/settings.scss +++ b/settings/css/settings.scss @@ -15,23 +15,23 @@ input { /* icons for sidebar */ .nav-icon-personal-settings { - background-image: icon-color('personal', 'settings', $color-black); + @include icon-color('personal', 'settings', $color-black); } .nav-icon-security { - background-image: icon-color('toggle-filelist', 'settings', $color-black); + @include icon-color('toggle-filelist', 'settings', $color-black); } .nav-icon-clientsbox { - background-image: icon-color('change', 'settings', $color-black); + @include icon-color('change', 'settings', $color-black); } .nav-icon-federated-cloud { - background-image: icon-color('share', 'settings', $color-black); + @include icon-color('share', 'settings', $color-black); } .nav-icon-second-factor-backup-codes, .nav-icon-ssl-root-certificate { - background-image: icon-color('password', 'settings', $color-black); + @include icon-color('password', 'settings', $color-black); } #avatarform {