Added missing search link for mobile optimization
authorAlexander Ebert <ebert@woltlab.com>
Mon, 21 Mar 2016 12:08:23 +0000 (13:08 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 21 Mar 2016 12:08:29 +0000 (13:08 +0100)
com.woltlab.wcf/templates/pageHeaderUser.tpl
com.woltlab.wcf/templates/pageMenuMobile.tpl
wcfsetup/install/files/js/WoltLab/WCF/Ui/Dropdown/Simple.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Page/Header/Fixed.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Page/Menu/Abstract.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Page/Menu/User.js
wcfsetup/install/files/style/layout/pageHeader.scss
wcfsetup/install/files/style/layout/pageHeaderSticky.scss

index e32bd7d24289d6160781b0c08025f76736dbe321..57c3d80e8939c27a84335b93de53673cc5cce1de 100644 (file)
                                                {/capture}
                                                
                                                <form method="post" action="{link controller='Login'}{/link}">
-                                                       <section class="section">
+                                                       <{if $__3rdPartyButtons|trim}section{else}div{/if} class="section">
                                                                {if $__3rdPartyButtons|trim}<h2 class="sectionTitle">{lang}wcf.user.login{/lang}</h2>{/if}
                                                                
                                                                <dl>
                                                                        <dt><label for="username">{lang}wcf.user.usernameOrEmail{/lang}</label></dt>
                                                                        <dd>
-                                                                               <input type="text" id="username" name="username" value="" required="required" class="long" />
+                                                                               <input type="text" id="username" name="username" value="" required="required" class="long">
                                                                        </dd>
                                                                </dl>
                                                                
                                                                <dl>
                                                                        <dt><label for="password">{lang}wcf.user.password{/lang}</label></dt>
                                                                        <dd>
-                                                                               <input type="password" id="password" name="password" value="" class="long" />
+                                                                               <input type="password" id="password" name="password" value="" class="long">
                                                                        </dd>
                                                                </dl>
                                                                
                                                                {if $__wcf->getUserAuthenticationFactory()->getUserAuthentication()->supportsPersistentLogins()}
                                                                        <dl>
                                                                                <dt></dt>
-                                                                               <dd><label><input type="checkbox" id="useCookies" name="useCookies" value="1" checked="checked" /> {lang}wcf.user.useCookies{/lang}</label></dd>
+                                                                               <dd><label><input type="checkbox" id="useCookies" name="useCookies" value="1" checked="checked"> {lang}wcf.user.useCookies{/lang}</label></dd>
                                                                        </dl>
                                                                {/if}
                                                                
                                                                {event name='loginFields'}
                                                                
                                                                <div class="formSubmit">
-                                                                       <input type="submit" id="loginSubmitButton" name="submitButton" value="{lang}wcf.user.button.login{/lang}" accesskey="s" />
+                                                                       <input type="submit" id="loginSubmitButton" name="submitButton" value="{lang}wcf.user.button.login{/lang}" accesskey="s">
                                                                        <a class="button" href="{link controller='LostPassword'}{/link}"><span>{lang}wcf.user.lostPassword{/lang}</span></a>
-                                                                       <input type="hidden" name="url" value="{$__wcf->session->requestURI}" />
+                                                                       <input type="hidden" name="url" value="{$__wcf->session->requestURI}">
                                                                        {@SECURITY_TOKEN_INPUT_TAG}
                                                                </div>
-                                                       </section>
+                                                       </{if $__3rdPartyButtons|trim}section{else}div{/if}>
                                                        
                                                        {if $__3rdPartyButtons|trim}
                                                                <section class="section">
index b247eedb8c95fe9d9c7364e2f4e95330e2c88f83..5da65b6a5216416f0db83b197a2479c2cdab2149 100644 (file)
                                                        {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
                                                {/if}
                                                {/foreach}
-                                       </ol>
-                               </li>
-                               {hascontent}
-                                       <li class="menuOverlayItem">
-                                               <a href="#" class="menuOverlayItemLink box24">
-                                                       <span class="icon icon24 fa-gears"></span>
-                                                       <span class="menuOverlayItemTitle">TODO: page options</span>
-                                               </a>
-                                               <ol class="menuOverlayItemList">
-                                                       {content}
-                                                               {if !$__pageOptions|empty}
-                                                                       {@$__pageOptions}
-                                                               {/if}
-                                                               
-                                                               {event name='pageOptions'}
-                                                       {/content}
-                                               </ol>
-                                       </li>
-                               {/hascontent}
-                               {hascontent}
-                                       <li class="menuOverlayTitle">TODO: current location</li>
-                                       <li class="menuOverlayItem">
-                                               <a href="#" class="menuOverlayItemLink box24">
-                                                       <span class="icon icon24 fa-cogs"></span>
-                                                       <span class="menuOverlayItemTitle">TODO: current location</span>
-                                               </a>
-                                               <ol class="menuOverlayItemList">
-                                                       {content}
-                                                       {assign var=__breadcrumbsDepth value=0}
-                                                       {foreach from=$__wcf->getBreadcrumbs() item=$breadcrumb}
-                                                               <li class="menuOverlayItem">
-                                                                       <a href="{$breadcrumb->getURL()}" class="menuOverlayItemLink">
-                                                                               <span class="menuOverlayItemTitle"{if $__breadcrumbsDepth} style="padding-left: {$__breadcrumbsDepth * 10}px" {/if}>
-                                                                                       <span class="icon icon24 fa-{if $__breadcrumbsDepth}caret-right{else}home{/if}"></span>
-                                                                                       {$breadcrumb->getLabel()}
-                                                                               </span>
-                                                                       </a>
-                                                               </li>
-                                                               {assign var=__breadcrumbsDepth value=$__breadcrumbsDepth + 1}
-                                                       {/foreach}
-                                                       {/content}
-                                               </ol>
-                                       </li>
-                               {/hascontent}
                        </ol>
                </li>
+               {hascontent}
+                       <li class="menuOverlayItem">
+                               <a href="#" class="menuOverlayItemLink box24">
+                                       <span class="icon icon24 fa-gears"></span>
+                                       <span class="menuOverlayItemTitle">TODO: page options</span>
+                               </a>
+                               <ol class="menuOverlayItemList">
+                                       {content}
+                                               {if !$__pageOptions|empty}
+                                                       {@$__pageOptions}
+                                               {/if}
+                                               
+                                               {event name='pageOptions'}
+                                       {/content}
+                               </ol>
+                       </li>
+               {/hascontent}
+               {hascontent}
+                       <li class="menuOverlayTitle">TODO: current location</li>
+                       <li class="menuOverlayItem">
+                               <a href="#" class="menuOverlayItemLink box24">
+                                       <span class="icon icon24 fa-cogs"></span>
+                                       <span class="menuOverlayItemTitle">TODO: current location</span>
+                               </a>
+                               <ol class="menuOverlayItemList">
+                                       {content}
+                                       {assign var=__breadcrumbsDepth value=0}
+                                       {foreach from=$__wcf->getBreadcrumbs() item=$breadcrumb}
+                                               <li class="menuOverlayItem">
+                                                       <a href="{$breadcrumb->getURL()}" class="menuOverlayItemLink">
+                                                               <span class="menuOverlayItemTitle"{if $__breadcrumbsDepth} style="padding-left: {$__breadcrumbsDepth * 10}px" {/if}>
+                                                                       <span class="icon icon24 fa-{if $__breadcrumbsDepth}caret-right{else}home{/if}"></span>
+                                                                       {$breadcrumb->getLabel()}
+                                                               </span>
+                                                       </a>
+                                               </li>
+                                               {assign var=__breadcrumbsDepth value=$__breadcrumbsDepth + 1}
+                                       {/foreach}
+                                       {/content}
+                               </ol>
+                       </li>
+               {/hascontent}
+               
+               <li class="menuOverlayItemSpacer"></li>
+               <li class="menuOverlayItem" data-more="com.woltlab.wcf.search">
+                       <a href="#" class="menuOverlayItemLink box24">
+                               <span class="icon icon24 fa-search"></span>
+                               <span class="menuOverlayItemTitle">{lang}wcf.global.search{/lang}</span>
+                       </a>
+               </li>
        </ol>
 </div>
 
                        </li>
                        
                        {event name='guestUserMenuItems'}
-               
+                       
                        {if $__wcf->getLanguage()->getLanguages()|count > 1}
                                <li class="menuOverlayItemSpacer"></li>
                                <li class="menuOverlayTitle">{lang}wcf.user.language{/lang}</li>
                                <li class="menuOverlayItem">
                                        <a href="#" class="menuOverlayItemLink box24">
-                                               <img src="{$__wcf->getLanguage()->getIconPath()}">
+                                               <img src="{$__wcf->getLanguage()->getIconPath()}" alt="">
                                                <span class="menuOverlayItemTitle">{$__wcf->getLanguage()}</span>
                                        </a>
                                        <ol class="menuOverlayItemList" data-title="{lang}wcf.user.language{/lang}">
                                                {foreach from=$__wcf->getLanguage()->getLanguages() item=__language}
                                                        <li class="menuOverlayItem" data-more="com.woltlab.wcf.language" data-language-id="{@$__language->languageID}">
                                                                <a href="#" class="menuOverlayItemLink box24">
-                                                                       <img src="{$__language->getIconPath()}">
+                                                                       <img src="{$__language->getIconPath()}" alt="">
                                                                        <span class="menuOverlayItemTitle">{$__language}</span>
                                                                </a>
                                                        </li>
index 8d4208b347abdbf7ea8830baa86d91c75f1fdd40..14d088358049fe38e11b6ad6c0ee916cd91421eb 100644 (file)
@@ -85,7 +85,7 @@ define(
                        var containerId = DomUtil.identify(dropdown);
                        if (!_dropdowns.has(containerId)) {
                                button.classList.add('jsDropdownEnabled');
-                               button.addEventListener('click', this._toggle.bind(this));
+                               button.addEventListener(WCF_CLICK_EVENT, this._toggle.bind(this));
                                
                                _dropdowns.set(containerId, dropdown);
                                _menus.set(containerId, menu);
@@ -98,7 +98,7 @@ define(
                        elData(button, 'target', containerId);
                        
                        if (isLazyInitialization) {
-                               setTimeout(function() { Core.triggerEvent(button, 'click'); }, 10);
+                               setTimeout(function() { Core.triggerEvent(button, WCF_CLICK_EVENT); }, 10);
                        }
                },
                
index bebf4b538a6bb80685166b2e47e36fc45feff2c5..6e512ee3c146fde680ad332a42d845717563216b 100644 (file)
@@ -6,10 +6,10 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLab/WCF/Ui/Page/Header/Fixed
  */
-define(['Ui/CloseOverlay', 'Ui/SimpleDropdown'], function(UiCloseOverlay, UiSimpleDropdown) {
+define(['Core', 'EventHandler', 'Ui/CloseOverlay', 'Ui/Screen', 'Ui/SimpleDropdown'], function(Core, EventHandler, UiCloseOverlay, UiScreen, UiSimpleDropdown) {
        "use strict";
        
-       var _pageHeader, _pageHeaderContainer, _pageHeaderSearchInputContainer, _isFixed = false;
+       var _pageHeader, _pageHeaderContainer, _isFixed = false, _isMobile = false;
        
        /**
         * @exports     WoltLab/WCF/Ui/Page/Header/Fixed
@@ -21,10 +21,15 @@ define(['Ui/CloseOverlay', 'Ui/SimpleDropdown'], function(UiCloseOverlay, UiSimp
                init: function() {
                        _pageHeader = elById('pageHeader');
                        _pageHeaderContainer = elById('pageHeaderContainer');
-                       _pageHeaderSearchInputContainer = elById('pageHeaderSearchInputContainer');
                        
                        this._initStickyPageHeader();
                        this._initSearchBar();
+                       
+                       UiScreen.on({
+                               match: function() { _isMobile = true; },
+                               unmatch: function() { _isMobile = false; },
+                               setup: function() { _isMobile = true; }
+                       });
                },
                
                /**
@@ -49,15 +54,23 @@ define(['Ui/CloseOverlay', 'Ui/SimpleDropdown'], function(UiCloseOverlay, UiSimp
                        var searchInput = elById('pageHeaderSearchInput');
                        
                        UiSimpleDropdown.registerCallback('pageHeaderSearchInputContainer', function() {
-                               if (_isFixed && !_pageHeaderSearchInputContainer.classList.contains('open')) {
-                                       _pageHeaderSearchInputContainer.classList.add('open');
+                               if ((_isFixed || _isMobile) && !_pageHeader.classList.contains('searchBarOpen')) {
+                                       _pageHeader.classList.add('searchBarOpen');
                                        searchInput.focus();
                                }
                        });
                        
                        UiCloseOverlay.add('WoltLab/WCF/Ui/Page/Header/Fixed', function() {
-                               _pageHeaderSearchInputContainer.classList.remove('open');
+                               _pageHeader.classList.remove('searchBarOpen');
                        });
+                       
+                       EventHandler.add('com.woltlab.wcf.MainMenuMobile', 'more', (function(data) {
+                               if (data.identifier === 'com.woltlab.wcf.search') {
+                                       data.handler.close(true);
+                                       
+                                       Core.triggerEvent(elById('pageHeaderSearchInput'), WCF_CLICK_EVENT);
+                               }
+                       }).bind(this));
                },
                
                /**
@@ -71,7 +84,7 @@ define(['Ui/CloseOverlay', 'Ui/SimpleDropdown'], function(UiCloseOverlay, UiSimp
                        _pageHeader.classList[_isFixed ? 'add' : 'remove']('sticky');
                        _pageHeaderContainer.classList[_isFixed ? 'add' : 'remove']('stickyPageHeader');
                        
-                       _pageHeaderSearchInputContainer.classList.remove('open');
+                       _pageHeader.classList.remove('searchBarOpen');
                }
        };
 });
index 526c8035fa4981553263f95783e34ebd8b13f164..82a3f831a3c0887fc16a879ea6f0787961c44d24 100644 (file)
@@ -127,7 +127,26 @@ define(['Environment', 'EventHandler', 'ObjectMap', 'Dom/Traverse', 'Ui/Screen']
                 * @protected
                 */
                _initItem: function(item) {
-                       var itemList = item.nextElementSibling, parent = item.parentNode, wrapper;
+                       // check if it should contain a 'more' link w/ an external callback
+                       var parent = item.parentNode;
+                       var more = elData(parent, 'more');
+                       if (more) {
+                               item.addEventListener(WCF_CLICK_EVENT, (function(event) {
+                                       event.preventDefault();
+                                       event.stopPropagation();
+                                       
+                                       EventHandler.fire(this._eventIdentifier, 'more', {
+                                               handler: this,
+                                               identifier: more,
+                                               item: item,
+                                               parent: parent
+                                       });
+                               }).bind(this));
+                               
+                               return;
+                       }
+                       
+                       var itemList = item.nextElementSibling, wrapper;
                        if (itemList === null) {
                                return;
                        }
index e816776c88e110cb83433feedc6204f6d0900bc9..031ecbe6a65d0662c44ea45cf007155af2d6a4df 100644 (file)
@@ -24,36 +24,6 @@ define(['Core', 'EventHandler', './Abstract'], function(Core, EventHandler, UiPa
                                'pageUserMenuMobile',
                                '#pageHeader .userPanel'
                        );
-               },
-               
-               /**
-                * Overrides the `_initItem()` method to check for special items that do not
-                * act as a link but instead trigger an event for external processing.
-                * 
-                * @param       {Element}       item    menu item
-                * @protected
-                */
-               _initItem: function(item) {
-                       // check if it should contain a 'more' link w/ an external callback
-                       var parent = item.parentNode;
-                       var more = elData(parent, 'more');
-                       if (more) {
-                               item.addEventListener(WCF_CLICK_EVENT, (function(event) {
-                                       event.preventDefault();
-                                       event.stopPropagation();
-                                       
-                                       EventHandler.fire(this._eventIdentifier, 'more', {
-                                               handler: this,
-                                               identifier: more,
-                                               item: item,
-                                               parent: parent
-                                       });
-                               }).bind(this));
-                               
-                               return;
-                       }
-                       
-                       UiPageMenuUser._super.prototype._initItem.call(this, item);
                }
        });
        
index 4fd4c647b521c1c09c95af8c6e27b91816174203..933846882819d7fed184b92c96ed6fc043573e30 100644 (file)
@@ -61,6 +61,7 @@
 /* MAIN MENU */
 .mainMenu .boxMenu {
        display: flex;
+       flex-wrap: wrap;
        
        > li {
                flex: 0 0 auto;
 
 /* SEARCH AREA */
 .pageHeaderSearch {
-       margin-bottom: 15px;
-       text-align: right;
-       
-       .pageHeaderSearchLabel {
-               display: none;
+       @include large-screen-only {
+               margin-bottom: 15px;
+               text-align: right;
+               
+               .pageHeaderSearchLabel {
+                       display: none;
+               }
        }
 }
 
 .pageHeaderSearchInputContainer {
+       display: inline-block;
        position: relative;
        
        &:hover {
                }
        }
        
-       .pageHeaderSearch {
-               display: none;
+       .pageHeader {
+               &.searchBarOpen {
+                       .pageHeaderContainerLeft {
+                               display: none;
+                       }
+                       
+                       .pageHeaderContainerRight {
+                               flex: 0 0 100%;
+                               
+                               .pageHeaderSearch {
+                                       flex: 0 0 100%;
+                                       
+                                       .pageHeaderSearchInput {
+                                               width: 100%;
+                                       }
+                               }
+                               
+                               .userPanel {
+                                       display: none;
+                               }
+                       }
+               }
+               
+               &:not(.searchBarOpen) {
+                       .pageHeaderSearch {
+                               display: none;
+                       }
+               }
        }
 }
index 5ea347ef167beef3d5d5e656312f04e760f13a80..64e5b427f10d5e1d47b6e74435496c8cdd655e2e 100644 (file)
@@ -23,7 +23,7 @@
                
                
                .layoutBoundary {
-                       height: 50px;
+                       min-height: 50px;
                        
                        // remove padding, the vertical alignment is done using `align-items`
                        padding-bottom: 0;
                        order: 2;
                        margin: 0 20px;
                        
-                       .boxMenu > li > a {
-                               align-items: center;
-                               display: flex;
+                       .boxMenu {
+                               background-color: $wcfHeaderBackground;
+                               padding-bottom: 5px;
                                
-                               > span {
-                                       flex: 0 0 auto;
-                               }
-                               
-                               > .boxMenuLinkOutstandingItems {
-                                       margin-left: 5px;
+                               > li > a {
+                                       align-items: center;
+                                       display: flex;
+                                       
+                                       > span {
+                                               flex: 0 0 auto;
+                                       }
+                                       
+                                       > .boxMenuLinkOutstandingItems {
+                                               margin-left: 5px;
+                                       }
                                }
                        }
                }
                        order: 3;
                        
                        .pageHeaderSearchInput {
-                               height: 50px;
+                               height: 100%;
                                width: 100%;
                        }
                        
                        .pageHeaderSearchLabel {
                                background-color: $wcfHeaderSearchBoxBackground;
+                               bottom: 0;
                                cursor: pointer;
                                display: block;
-                               height: 50px;
+                               position: absolute;
+                               top: 0;
                                width: 50px;
                                
                                &:hover {
                                        font-family: FontAwesome;
                                        font-size: 28px;
                                        line-height: 32px;
-                                       position: relative;
+                                       position: absolute;
                                        right: 11px;
-                                       top: 9px;
+                                       top: 50%;
+                                       transform: translateY(-50%);
                                }
                        }
                }
                
-               .pageHeaderSearchInputContainer {
-                       &.open {
+               &:not(.searchBarOpen) {
+                       .pageHeaderSearch {
+                               font-size: 0;
+                               width: 50px;
+                       }
+                       
+                       .pageHeaderSearchInput,
+                       .pageHeaderSearchInputButton {
+                               display: none;
+                       }
+               }
+               
+               &.searchBarOpen {
+                       .pageHeaderSearchInputContainer {
                                bottom: 0;
                                left: 0;
                                position: absolute;
                                right: 0;
                                top: 0;
-                               z-index: 100;
-                               
-                               ~ .pageHeaderSearchLabel {
-                                       visibility: hidden;
-                               }
+                               z-index: 100; 
                        }
                        
-                       &:not(.open) {
-                               > .pageHeaderSearchInput,
-                               > .pageHeaderSearchInputButton {
-                                       display: none;
-                               }
+                       .pageHeaderSearchLabel {
+                               position: static;
+                               visibility: hidden;
+                               width: 50px;
                        }
                }
        }