Преглед изворни кода

ZF-9746: Adds support for the accesskey HTML attribute in Navigation links for Zend\Navigation

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@24451 44c647ce-9c0f-0410-b52a-842ac1e357ba
padraic пре 14 година
родитељ
комит
ffeceb27c5

+ 47 - 0
library/Zend/Navigation/Page.php

@@ -84,6 +84,18 @@ abstract class Zend_Navigation_Page extends Zend_Navigation_Container
     protected $_target;
 
     /**
+     * Accessibility key character
+     *
+     * This attribute assigns an access key to an element. An access key is a
+     * single character from the document character set.
+     *
+     * @link http://www.w3.org/TR/html401/interact/forms.html#access-keys
+     *
+     * @var string|null
+     */
+    protected $_accesskey;
+
+    /**
      * Forward links to other pages
      *
      * @link http://www.w3.org/TR/html4/struct/links.html#h-12.3.1
@@ -494,6 +506,40 @@ abstract class Zend_Navigation_Page extends Zend_Navigation_Container
     }
 
     /**
+     * Sets access key for this page
+     *
+     * @param  string|null $character     [optional] access key to set. Default
+     *                                    is null, which sets no access key.
+     * @return Zend_Navigation_Page       fluent interface, returns self
+     * @throws Zend_Navigation_Exception  if access key is not string or null or
+     *                                    if the string length not equal to one
+     */
+    public function setAccesskey($character = null)
+    {
+        if (null !== $character
+            && (!is_string($character) || 1 != strlen($character)))
+        {
+            require_once 'Zend/Navigation/Exception.php';
+            throw new Zend_Navigation_Exception(
+                'Invalid argument: $character must be a single character or null'
+            );
+        }
+ 
+        $this->_accesskey = $character;
+        return $this;
+    }
+
+     /**
+     * Returns page access key
+     *
+     * @return string|null  page access key or null
+     */
+    public function getAccesskey()
+    {
+        return $this->_accesskey;
+    }
+
+    /**
      * Sets the page's forward links to other pages
      *
      * This method expects an associative array of forward links to other pages,
@@ -1142,6 +1188,7 @@ abstract class Zend_Navigation_Page extends Zend_Navigation_Container
                 'class'     => $this->getClass(),
                 'title'     => $this->getTitle(),
                 'target'    => $this->getTarget(),
+                'accesskey' => $this->getAccesskey(),
                 'rel'       => $this->getRel(),
                 'rev'       => $this->getRev(),
                 'order'     => $this->getOrder(),

+ 1 - 0
library/Zend/View/Helper/Navigation/Menu.php

@@ -234,6 +234,7 @@ class Zend_View_Helper_Navigation_Menu
             $element = 'a';
             $attribs['href'] = $href;
             $attribs['target'] = $page->getTarget();
+            $attribs['accesskey'] = $page->getAccessKey();
         } else {
             $element = 'span';
         }

+ 32 - 1
tests/Zend/Navigation/PageTest.php

@@ -295,6 +295,35 @@ class Zend_Navigation_PageTest extends PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+     * @group ZF-9746
+     */
+    public function testSetAndGetAccesskey()
+    {
+        $page = Zend_Navigation_Page::factory(array(
+            'label' => 'foo',
+            'uri'   => '#',
+        ));
+        
+        $this->assertEquals(null, $page->getAccesskey());
+        $page->setAccesskey('b');
+        $this->assertEquals('b', $page->getAccesskey());
+        
+        $invalids = array('bar', 42, true, (object) null);
+        foreach ($invalids as $invalid) {
+            try {
+                $page->setAccesskey($invalid);
+                $this->fail('An invalid value was set, but a ' .
+                            'Zend_Navigation_Exception was not thrown');
+            } catch (Zend_Navigation_Exception $e) {
+                $this->assertContains(
+                    'Invalid argument: $character',
+                    $e->getMessage()
+                );
+            }
+        }
+    }
+
     public function testConstructingWithRelationsInArray()
     {
         $page = Zend_Navigation_Page::factory(array(
@@ -1137,6 +1166,7 @@ class Zend_Navigation_PageTest extends PHPUnit_Framework_TestCase
             'class'    => 'my-class',
             'title'    => 'my-title',
             'target'   => 'my-target',
+            'accesskey' => 'f',
             'rel'      => array(),
             'rev'      => array(),
             'order'    => 100,
@@ -1168,7 +1198,7 @@ class Zend_Navigation_PageTest extends PHPUnit_Framework_TestCase
         $options['type'] = 'Zend_Navigation_Page_Uri';
 
         // calculate diff between toArray() and $options
-        $diff = array_diff_assoc($toArray, $options);
+        $diff = array_diff_assoc($options, $toArray);
 
         // should be no diff
         $this->assertEquals(array(), $diff);
@@ -1184,6 +1214,7 @@ class Zend_Navigation_PageTest extends PHPUnit_Framework_TestCase
         $options['class'] = null;
         $options['title'] = null;
         $options['target'] = null;
+        $options['accesskey'] = null;
         $options['resource'] = null;
         $options['active'] = false;
         $options['visible'] = true;

+ 14 - 0
tests/Zend/View/Helper/Navigation/MenuTest.php

@@ -526,4 +526,18 @@ class Zend_View_Helper_Navigation_MenuTest
 
         $this->assertEquals($expected, $actual);
     }
+
+    /**
+     * @group ZF-9746
+     */
+    public function testRenderingWithAccesskey()
+    {
+        $this->_nav3->findOneBy('id', 'home')->setAccesskey('H');
+        $this->_nav3->findOneBy('uri', 'contact')->setAccesskey('c');
+        $this->_nav3->findOneBy('id', 'imprint')->setAccesskey('i');
+        
+        $expected = $this->_getExpected('menu/accesskey.html');
+        
+        $this->assertEquals($expected, $this->_helper->render($this->_nav3));
+    }
 }

+ 8 - 0
tests/Zend/View/Helper/Navigation/TestAbstract.php

@@ -81,6 +81,13 @@ abstract class Zend_View_Helper_Navigation_TestAbstract
      */
     protected $_nav2;
 
+    /**
+     * The third container in the config file (_files/navigation.xml)
+     *
+     * @var Zend_Navigation
+     */
+    protected $_nav3;
+
     private $_oldControllerDir;
 
     /**
@@ -98,6 +105,7 @@ abstract class Zend_View_Helper_Navigation_TestAbstract
         // setup containers from config
         $this->_nav1 = new Zend_Navigation($config->get('nav_test1'));
         $this->_nav2 = new Zend_Navigation($config->get('nav_test2'));
+        $this->_nav3 = new Zend_Navigation($config->get('nav_test3'));
 
         // setup view
         $view = new Zend_View();

+ 16 - 0
tests/Zend/View/Helper/Navigation/_files/expected/menu/accesskey.html

@@ -0,0 +1,16 @@
+<ul class="navigation">
+    <li>
+        <a id="menu-home" href="home" accesskey="H">Home</a>
+    </li>
+    <li class="active">
+        <a href="contact" accesskey="c">Contact</a>
+        <ul>
+            <li>
+                <a id="menu-privacy" href="contact/privacy">Privacy</a>
+            </li>
+            <li>
+                <a id="menu-imprint" href="contact/imprint" accesskey="i">Imprint</a>
+            </li>
+        </ul>
+    </li>
+</ul>

+ 32 - 0
tests/Zend/View/Helper/Navigation/_files/navigation.xml

@@ -208,5 +208,37 @@
         </site3>
         
     </nav_test2>
+
+    <nav_test3>
+
+        <home>
+            <label>Home</label>
+            <uri>home</uri>
+            <id>home</id>
+        </home>
+
+        <contact>
+            <label>Contact</label>
+            <uri>contact</uri>
+            <active>1</active>
+            <pages>
+
+                <privacy>
+                    <label>Privacy</label>
+                    <uri>contact/privacy</uri>
+                    <id>privacy</id>
+                </privacy>
+
+                <imprint>
+                    <label>Imprint</label>
+                    <uri>contact/imprint</uri>
+                    <id>imprint</id>
+                </imprint>
+
+            </pages>
+        </contact>
+
+
+    </nav_test3>
     
 </navigation_test>