[TASK] Introduce icon state for IconFactory 82/42482/20
authorFrank Nägler <frank.naegler@typo3.org>
Mon, 10 Aug 2015 13:52:44 +0000 (15:52 +0200)
committerAndreas Fernandez <typo3@scripting-base.de>
Wed, 2 Sep 2015 14:42:57 +0000 (16:42 +0200)
Resolves: #69095
Releases: master
Change-Id: I4a1077a9267ed293f049f6457aef5d8012aa28d4
Reviewed-on: http://review.typo3.org/42482
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Tested-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
12 files changed:
Build/Resources/Public/Less/Component/icon.less
typo3/sysext/core/Classes/Imaging/Icon.php
typo3/sysext/core/Classes/Imaging/IconFactory.php
typo3/sysext/core/Classes/Type/Icon/IconState.php [new file with mode: 0644]
typo3/sysext/core/Classes/ViewHelpers/IconViewHelper.php
typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Imaging/DimensionTest.php
typo3/sysext/core/Tests/Unit/Imaging/IconFactoryTest.php
typo3/sysext/core/Tests/Unit/Imaging/IconProvider/FontawesomeIconProviderTest.php
typo3/sysext/core/Tests/Unit/Imaging/IconTest.php
typo3/sysext/core/Tests/Unit/ViewHelpers/IconViewHelperTest.php
typo3/sysext/t3skin/Resources/Public/Css/backend.css

index cd24960..9b023e4 100644 (file)
@@ -25,6 +25,7 @@
 @icon-size-default:      32px;
 @icon-size-large:        48px;
 @icon-unify-modifier:    0.86;
+@icon-opacity-disabled:  0.5;
 
 //
 // Component
 }
 
 //
+// States
+//
+.icon-state-disabled {
+       .icon-markup {
+               opacity: @icon-opacity-disabled;
+       }
+}
+
+//
 // Variants
 //
 .icon-size(@identifier; @size) {
index 18464e2..550791d 100644 (file)
@@ -13,6 +13,8 @@ namespace TYPO3\CMS\Core\Imaging;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -44,29 +46,40 @@ class Icon {
 
        /**
         * The identifier which the PHP code that calls the IconFactory hands over
+        *
         * @var string
         */
        protected $identifier;
 
        /**
         * The identifier for a possible overlay icon
+        *
         * @var Icon
         */
        protected $overlayIcon = NULL;
 
        /**
         * Contains the size string ("large", "small" or "default")
+        *
         * @var string
         */
        protected $size = '';
 
        /**
         * Flag to indicate if the icon has a spinning animation
+        *
         * @var bool
         */
        protected $spinning = FALSE;
 
        /**
+        * Contains the state information
+        *
+        * @var IconState
+        */
+       protected $state;
+
+       /**
         * @var Dimension
         */
        protected $dimension;
@@ -128,6 +141,7 @@ class Icon {
 
        /**
         * Sets the size and creates the new dimension
+        *
         * @param string $size
         */
        public function setSize($size) {
@@ -136,20 +150,36 @@ class Icon {
        }
 
        /**
-        * @return boolean
+        * @return bool
         */
        public function isSpinning() {
                return $this->spinning;
        }
 
        /**
-        * @param boolean $spinning
+        * @param bool $spinning
         */
        public function setSpinning($spinning) {
                $this->spinning = $spinning;
        }
 
        /**
+        * @return IconState
+        */
+       public function getState() {
+               return $this->state;
+       }
+
+       /**
+        * Sets the state of the icon
+        *
+        * @param IconState $state
+        */
+       public function setState(IconState $state) {
+               $this->state = $state;
+       }
+
+       /**
         * @return Dimension
         */
        public function getDimension() {
@@ -187,6 +217,7 @@ class Icon {
                $classes = array();
                $classes[] = 'icon';
                $classes[] = 'icon-size-' . $this->size;
+               $classes[] = 'icon-state-' . htmlspecialchars((string)$this->state);
                $classes[] = 'icon-' . $this->getIdentifier();
                if ($this->isSpinning()) {
                        $classes[] = 'icon-spin';
index 5407183..7453335 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Imaging;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -36,17 +37,19 @@ class IconFactory {
 
        /**
         * @param string $identifier
-        * @param string $size
+        * @param string $size "large", "small" or "default", see the constants of the Icon class
         * @param string $overlayIdentifier
+        * @param IconState $state
         *
         * @return Icon
         */
-       public function getIcon($identifier, $size = Icon::SIZE_DEFAULT, $overlayIdentifier = NULL) {
+       public function getIcon($identifier, $size = Icon::SIZE_DEFAULT, $overlayIdentifier = NULL, IconState $state = NULL) {
                if (!$this->iconRegistry->isRegistered($identifier)) {
                        $identifier = $this->iconRegistry->getDefaultIconIdentifier();
                }
 
                $iconConfiguration = $this->iconRegistry->getIconConfigurationByIdentifier($identifier);
+               $iconConfiguration['state'] = $state;
                $icon = $this->createIcon($identifier, $size, $overlayIdentifier, $iconConfiguration);
                /** @var IconProviderInterface $iconProvider */
                $iconProvider = GeneralUtility::makeInstance($iconConfiguration['provider']);
@@ -58,7 +61,7 @@ class IconFactory {
         * Creates an icon object
         *
         * @param string $identifier
-        * @param string $size "large" "small" or "default", see the constants of the Icon class
+        * @param string $size "large", "small" or "default", see the constants of the Icon class
         * @param string $overlayIdentifier
         * @param array $iconConfiguration the icon configuration array
         * @return Icon
@@ -67,6 +70,7 @@ class IconFactory {
                $icon = GeneralUtility::makeInstance(Icon::class);
                $icon->setIdentifier($identifier);
                $icon->setSize($size);
+               $icon->setState($iconConfiguration['state'] ?: new IconState());
                if ($overlayIdentifier !== NULL) {
                        $icon->setOverlayIcon($this->getIcon($overlayIdentifier, Icon::SIZE_OVERLAY));
                }
diff --git a/typo3/sysext/core/Classes/Type/Icon/IconState.php b/typo3/sysext/core/Classes/Type/Icon/IconState.php
new file mode 100644 (file)
index 0000000..a875193
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+namespace TYPO3\CMS\Core\Type\Icon;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * A class providing constants for icon states
+ */
+class IconState extends \TYPO3\CMS\Core\Type\Enumeration {
+
+       const __default = self::STATE_DEFAULT;
+
+       /**
+        * @var string the default state identifier
+        */
+       const STATE_DEFAULT = 'default';
+
+       /**
+        * @var string the disabled state identifier
+        */
+       const STATE_DISABLED = 'disabled';
+}
index 7032c06..be40d53 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\ViewHelpers;
 
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
 use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
@@ -32,14 +33,16 @@ class IconViewHelper extends AbstractViewHelper implements CompilableInterface {
         * @param string $identifier
         * @param string $size
         * @param string $overlay
+        * @param string $state
         * @return string
         */
-       public function render($identifier, $size = Icon::SIZE_SMALL, $overlay = NULL) {
+       public function render($identifier, $size = Icon::SIZE_SMALL, $overlay = NULL, $state = IconState::STATE_DEFAULT) {
                return static::renderStatic(
                        array(
                                'identifier' => $identifier,
                                'size' => $size,
-                               'overlay' => $overlay
+                               'overlay' => $overlay,
+                               'state' => $state
                        ),
                        $this->buildRenderChildrenClosure(),
                        $this->renderingContext
@@ -58,9 +61,10 @@ class IconViewHelper extends AbstractViewHelper implements CompilableInterface {
                $identifier = $arguments['identifier'];
                $size = $arguments['size'];
                $overlay = $arguments['overlay'];
+               $state = IconState::cast($arguments['state']);
                /** @var IconFactory $iconFactory */
                $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
-               return $iconFactory->getIcon($identifier, $size, $overlay)->render();
+               return $iconFactory->getIcon($identifier, $size, $overlay, $state)->render();
        }
 
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-69095-IntroduceIconStateForIconFactory.rst
new file mode 100644 (file)
index 0000000..30835b9
--- /dev/null
@@ -0,0 +1,39 @@
+======================================================
+Feature: #69095 - Introduce icon state for IconFactory
+======================================================
+
+Description
+===========
+
+A state (default or disabled) for icons has been added. The state "disabled" marks an icon as disabled and shows the icon with 50% opacity.
+
+
+Use an icon
+-----------
+
+The method ``IconFactory::getIcon()`` has now a fourth parameter for the state.
+
+The ``\TYPO3\CMS\Core\Type\Icon\IconState`` class provides only the following constants for icon states:
+
+* ``State::STATE_DEFAULT`` which currently means 100% opacity
+* ``State::STATE_DISABLED`` which currently means 50% opacity
+
+The states may change in future, so please make use of the constants for an unified layout.
+
+.. code-block:: php
+
+       $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+       $iconFactory->getIcon($identifier, Icon::SIZE_SMALL, $overlay, IconState::cast(IconState::STATE_DEFAULT))->render();
+
+
+ViewHelper
+----------
+
+The core provides a Fluid ViewHelper which makes it really easy to use icons within a Fluid view.
+This ViewHelper has an argument for the new state parameter.
+
+.. code-block:: html
+
+       {namespace core = TYPO3\CMS\Core\ViewHelpers}
+       <core:icon identifier="my-icon-identifier" size="small" state="disabled" />
+
index 6931be1..8e0eb45 100644 (file)
@@ -15,8 +15,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
  */
 
 use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Imaging\IconFactory;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Testcase for \TYPO3\CMS\Core\Imaging\Dimension
index f4da1fb..ada1dee 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
  */
 
 use Prophecy\Argument;
-use Prophecy\Prophecy\ObjectProphecy;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Imaging\IconProvider\FontawesomeIconProvider;
@@ -94,7 +93,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @test
         */
        public function getIconByIdentifierReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed() {
-               $this->assertContains('<span class="icon icon-size-default icon-actions-document-close">',
+               $this->assertContains('<span class="icon icon-size-default icon-state-default icon-actions-document-close">',
                        $this->subject->getIcon($this->registeredIconIdentifier)->render());
        }
 
@@ -103,7 +102,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @dataProvider differentSizesDataProvider
         */
        public function getIconByIdentifierAndSizeReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed($size) {
-               $this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-actions-document-close">',
+               $this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-state-default icon-actions-document-close">',
                        $this->subject->getIcon($this->registeredIconIdentifier, $size['input'])->render());
        }
 
@@ -129,7 +128,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                'additionalClasses' => 'fa-fw'
                        )
                ]);
-               $this->assertContains('<span class="icon icon-size-default icon-default-not-found">',
+               $this->assertContains('<span class="icon icon-size-default icon-state-default icon-default-not-found">',
                        $this->subject->getIcon($this->notRegisteredIconIdentifier)->render());
        }
 
@@ -147,7 +146,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                'additionalClasses' => 'fa-fw'
                        )
                ]);
-               $this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-default-not-found">',
+               $this->assertContains('<span class="icon icon-size-' . $size['expected'] . ' icon-state-default icon-default-not-found">',
                        $this->subject->getIcon($this->notRegisteredIconIdentifier, $size['input'])->render());
        }
 
@@ -163,7 +162,7 @@ class IconFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                                'spinning' => TRUE
                        )
                ]);
-               $this->assertContains('<span class="icon icon-size-default icon-' . $this->registeredSpinningIconIdentifier . ' icon-spin">',
+               $this->assertContains('<span class="icon icon-size-default icon-state-default icon-' . $this->registeredSpinningIconIdentifier . ' icon-spin">',
                        $this->subject->getIcon($this->registeredSpinningIconIdentifier)->render());
        }
 
index 0b0937a..cf90bf8 100644 (file)
@@ -53,14 +53,6 @@ class FontawesomeIconProviderTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * @test
-        */
-       public function prepareIconMarkupWithNameAndAdditionalClassesReturnsInstanceOfIconWithCorrectMarkup() {
-               $this->subject->prepareIconMarkup($this->icon, array('name' => 'times', 'additionalClasses' => 'foo'));
-               $this->assertEquals('<span class="icon-unify"><i class="fa fa-times foo"></i></span>', $this->icon->getMarkup());
-       }
-
-       /**
         * DataProvider for icon names
         *
         * @return array
index 86354ba..a915955 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Imaging;
 
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 
 /**
  * Testcase for \TYPO3\CMS\Core\Imaging\Icon
@@ -44,7 +45,7 @@ class IconTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         */
        protected function setUp() {
                $iconFactory = new IconFactory();
-               $this->subject = $iconFactory->getIcon($this->iconIdentifier, Icon::SIZE_SMALL, $this->overlayIdentifier);
+               $this->subject = $iconFactory->getIcon($this->iconIdentifier, Icon::SIZE_SMALL, $this->overlayIdentifier, IconState::cast(IconState::STATE_DISABLED));
        }
 
        /**
@@ -74,4 +75,12 @@ class IconTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        public function getSizedentifierReturnsCorrectIdentifier() {
                $this->assertEquals(Icon::SIZE_SMALL, $this->subject->getSize());
        }
+
+       /**
+        * @test
+        */
+       public function getStateReturnsCorrectIdentifier() {
+               $this->assertTrue($this->subject->getState()->equals(IconState::STATE_DISABLED));
+       }
+
 }
index 5e131c0..5c0c814 100644 (file)
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\ViewHelpers;
 use Prophecy\Argument;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Type\Icon\IconState;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\ViewHelpers\IconViewHelper;
 use TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\ViewHelperBaseTestcase;
@@ -41,12 +42,12 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
        /**
         * @test
         */
-       public function renderCallsIconFactoryWithDefaultSizeAndReturnsResult() {
+       public function renderCallsIconFactoryWithDefaultSizeAndDefaultStateAndReturnsResult() {
                $iconFactoryProphecy = $this->prophesize(IconFactory::class);
                GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
                $iconProphecy = $this->prophesize(Icon::class);
 
-               $iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL)->shouldBeCalled()->willReturn($iconProphecy->reveal());
+               $iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
                $iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
                $this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier'));
@@ -60,7 +61,7 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
                GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
                $iconProphecy = $this->prophesize(Icon::class);
 
-               $iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_LARGE, NULL)->shouldBeCalled()->willReturn($iconProphecy->reveal());
+               $iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_LARGE, NULL, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
                $iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
                $this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_LARGE));
@@ -69,15 +70,29 @@ class IconViewHelperTest extends ViewHelperBaseTestcase {
        /**
         * @test
         */
+       public function renderCallsIconFactoryWithGivenStateAndReturnsResult() {
+               $iconFactoryProphecy = $this->prophesize(IconFactory::class);
+               GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
+               $iconProphecy = $this->prophesize(Icon::class);
+
+               $iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DISABLED))->shouldBeCalled()->willReturn($iconProphecy->reveal());
+               $iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
+
+               $this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_SMALL, NULL, IconState::cast(IconState::STATE_DISABLED)));
+       }
+
+       /**
+        * @test
+        */
        public function renderCallsIconFactoryWithGivenOverlayAndReturnsResult() {
                $iconFactoryProphecy = $this->prophesize(IconFactory::class);
                GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
                $iconProphecy = $this->prophesize(Icon::class);
 
-               $iconFactoryProphecy->getIcon('myIdentifier', Argument::any(), 'overlayString')->shouldBeCalled()->willReturn($iconProphecy->reveal());
+               $iconFactoryProphecy->getIcon('myIdentifier', Argument::any(), 'overlayString', IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
                $iconProphecy->render()->shouldBeCalled()->willReturn('htmlFoo');
 
                $this->assertSame('htmlFoo', $this->viewHelper->render('myIdentifier', Icon::SIZE_LARGE, 'overlayString'));
        }
 
-}
\ No newline at end of file
+}
index b812a09..c2f602b 100644 (file)
@@ -1,14 +1,14 @@
-/*!
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
+/*!\r
+ * This file is part of the TYPO3 CMS project.\r
+ *\r
+ * It is free software; you can redistribute it and/or modify it under\r
+ * the terms of the GNU General Public License, either version 2\r
+ * of the License, or any later version.\r
+ *\r
+ * For the full copyright and license information, please read the\r
+ * LICENSE.txt file that was distributed with this source code.\r
+ *\r
+ * The TYPO3 project - inspiring people to share!\r
  */
 /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
 html {
@@ -7810,6 +7810,9 @@ button.close {
     transform: rotate(359deg);
   }
 }
+.icon-state-disabled .icon-markup {
+  opacity: 0.5;
+}
 .icon-size-small {
   height: 16px;
   width: 16px;