[FEATURE] Integrate typeahead.js for LiveSearch 19/40419/11
authorBenjamin Mack <benni@typo3.org>
Wed, 17 Jun 2015 17:05:22 +0000 (19:05 +0200)
committerAndreas Wolf <andreas.wolf@typo3.org>
Thu, 16 Jul 2015 08:35:18 +0000 (10:35 +0200)
The change removes ExtJS LiveSearch and introduces typeahead.js
as an AMD module alternative. The ExtDirect connector is thus
removed and a regular AJAX handler is added.

The special live search commands (the special treatments starting with #)
are put in the correct extensions where the DB table is set up.

Resolves: #67580
Releases: master
Change-Id: I3f5473164297b2d9121179ffd019af10caec821a
Reviewed-on: http://review.typo3.org/40419
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
19 files changed:
Build/Gruntfile.js
Build/Resources/Public/Less/TYPO3/_topbar.less
Build/bower.json
typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/LiveSearchToolbarItem.php
typo3/sysext/backend/Classes/Controller/LiveSearchController.php [new file with mode: 0644]
typo3/sysext/backend/Classes/Search/LiveSearch/ExtDirect/LiveSearchDataProvider.php [deleted file]
typo3/sysext/backend/Classes/Search/LiveSearch/LiveSearch.php
typo3/sysext/backend/Classes/Search/LiveSearch/QueryParser.php
typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/livesearch.js [deleted file]
typo3/sysext/backend/ext_localconf.php
typo3/sysext/core/Classes/Core/Bootstrap.php
typo3/sysext/core/Classes/Page/PageRenderer.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Resources/Public/JavaScript/Contrib/README.txt
typo3/sysext/core/Resources/Public/JavaScript/Contrib/typeahead.js [new file with mode: 0644]
typo3/sysext/frontend/ext_localconf.php
typo3/sysext/t3skin/Resources/Public/Css/backend.css

index 7f10342..6d688a9 100644 (file)
@@ -76,6 +76,7 @@ module.exports = function(grunt) {
                                        'placeholders.jquery.min.js': 'Placeholders.js/dist/placeholders.jquery.min.js',
                                        'taboverride.min.js': 'taboverride/build/output/taboverride.min.js',
                                        'bootstrap-slider.min.js': 'seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
+                                       'typeahead.js': 'typeahead.js/dist/typeahead.jquery.min.js',
 
                                        /**
                                         * copy needed files of scriptaculous
index b957e57..689baa1 100644 (file)
                        margin-right: -@topbar-dropdown-padding;
                        padding: (@topbar-dropdown-padding / 2) @topbar-dropdown-padding;
                }
-               .dropdown-intro {
+               .dropdown-intro,
+               .dropdown-info {
                        color: darken(@topbar-color, 20%);
                        margin-left: -@topbar-dropdown-padding;
                        margin-right: -@topbar-dropdown-padding;
        padding: 0;
        margin: 0;
        .form-group {
+               margin-top: 0;
+               margin-bottom: 0;
                &:before {
                        content: "\f002";
                        font: normal normal normal 14px/1 FontAwesome;
                }
        }
        .form-control {
-               box-sizing: content-box;
                background-color: @tobar-navigation-search-bg;
                color: @topbar-navigation-color;
-               height: @topbar-height - 27px;
+               height: @topbar-height;
+               width: 300px;
                padding: 14px 30px 13px 35px;
                border: none;
                border-left: 1px solid lighten(@topbar-navigation-border-color, 10%);
                }
                &:focus {
                        outline: none;
-                       border-left-color: lighten(@topbar-navigation-border-color, 15%);
+                       border-left-color: lighten(@topbar-navigation-border-color, 25%);
                        background-color: @tobar-navigation-search-focus-bg;
                        .box-shadow(none);
                }
                        margin-top: -8px;
                }
        }
-}
-
-// Livesearch
-.live-search-list {
-       .typo3-topbar-navigation-items .dropdown-menu();
-       right: auto;
-       padding: 0;
-       .x-toolbar {
-               padding: 0;
-               border: none;
-               background: transparent;
-       }
-       .x-combo-list-hd,
-       .x-combo-list-inner,
-       .x-combo-list-ft {
-               border: none;
-               background: transparent;
-               color: @topbar-dropdown-color;
-               padding: @topbar-dropdown-padding;
-       }
-       .x-combo-list-hd {
-               background-color: lighten(@topbar-dropdown-bg,3%);
-               border-top: 0;
-               border-bottom: 1px solid @topbar-navigation-border-color;
-       }
-       .x-combo-list-ft {
-               padding-top: 0;
-               border-bottom: 0;
-       }
-       .x-combo-list-inner {
-               padding-right: 0;
-               border-top: 1px solid lighten(@topbar-navigation-border-color, 10%);
-       }
-       .x-btn {
-               background: none;
-               border: none;
-               color: inherit;
-               .x-btn-tl,
-               .x-btn-tc,
-               .x-btn-tr,
-               .x-btn-ml,
-               .x-btn-mr,
-               .x-btn-bl,
-               .x-btn-bc,
-               .x-btn-br {
-                       display: none;
-               }
-               button {
-                       .btn();
-                       .btn-sm();
-                       .btn-default();
-                       height: auto!important;
-               }
-       }
-       .search-item-type {
-               padding: 5px 20px 5px 0;
-               white-space: nowrap;
+       .dropdown-menu {
+               left: auto!important; // Needs to be important to override inline styes of typeahead
+               width: 350px;
        }
-       .search-item-title {
-               border-radius: 2px 0 0 2px;
-               padding: 5px 20px 5px 10px;
-               &.x-combo-selected {
-                       border: none!important;
-                       background-color: lighten(@topbar-dropdown-bg, 10%);
+       .dropdown-list-link {
+               max-width: none;
+               .typeahead-highlight {
+                       font-weight: normal;
                }
        }
 }
-.search-list-help-content {
-       padding: @topbar-dropdown-padding;
-       strong {
-               display: block;
-               margin-bottom: 0.5em;
-       }
-       p {
-               margin-top: 0.5em;
-               margin-bottom: 0;
-       }
-}
index 179c21a..376e809 100644 (file)
@@ -40,6 +40,7 @@
     "imagesloaded": "3.1.8",
     "Placeholders.js": "4.0.1",
     "taboverride": "4.0.2",
-    "seiyria-bootstrap-slider": "4.8.1"
+    "seiyria-bootstrap-slider": "4.8.1",
+    "typeahead.js": "0.11.1"
   }
 }
index 867cade..fde586b 100644 (file)
@@ -35,7 +35,7 @@ class HelpToolbarItem implements ToolbarItemInterface {
        public function __construct() {
                /** @var BackendModuleRepository $backendModuleRepository */
                $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
-               /** @var \TYPO3\CMS\Backend\Domain\Model\Module\BackendModule $userModuleMenu */
+               /** @var \TYPO3\CMS\Backend\Domain\Model\Module\BackendModule $helpModuleMenu */
                $helpModuleMenu = $backendModuleRepository->findByModuleName('help');
                if ($helpModuleMenu && $helpModuleMenu->getChildren()->count() > 0) {
                        $this->helpModuleMenu = $helpModuleMenu;
index 92d8485..72882ca 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository;
 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
 use TYPO3\CMS\Backend\Module\ModuleLoader;
 use TYPO3\CMS\Core\Page\PageRenderer;
@@ -28,25 +29,23 @@ class LiveSearchToolbarItem implements ToolbarItemInterface {
         * Constructor
         */
        public function __construct() {
-               $this->getPageRenderer()->addJsFile('sysext/backend/Resources/Public/JavaScript/livesearch.js');
+               $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/LiveSearch');
        }
 
        /**
-        * Checks whether the user has access to this toolbar item
+        * Checks whether the user has access to this toolbar item,
+        * only allowed when the list module is available
         *
         * @return bool TRUE if user has access, FALSE if not
         */
        public function checkAccess() {
-               $access = FALSE;
-               // Loads the backend modules available for the logged in user.
-               $loadModules = GeneralUtility::makeInstance(ModuleLoader::class);
-               $loadModules->observeWorkspaces = TRUE;
-               $loadModules->load($GLOBALS['TBE_MODULES']);
+               /** @var BackendModuleRepository $backendModuleRepository */
+               $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
+               /** @var \TYPO3\CMS\Backend\Domain\Model\Module\BackendModule $listModule */
+
                // Live search is heavily dependent on the list module and only available when that module is.
-               if (is_array($loadModules->modules['web']['sub']['list'])) {
-                       $access = TRUE;
-               }
-               return $access;
+               $listModule = $backendModuleRepository->findByModuleName('web_list');
+               return $listModule !== NULL;
        }
 
        /**
@@ -56,9 +55,9 @@ class LiveSearchToolbarItem implements ToolbarItemInterface {
         */
        public function getItem() {
                return '
-                       <form class="typo3-topbar-navigation-search live-search-wrapper" role="search">
+                       <form class="typo3-topbar-navigation-search t3js-topbar-navigation-search live-search-wrapper" role="search">
                                <div class="form-group">
-                                       <input type="text" class="form-control" placeholder="Search" id="live-search-box">
+                                       <input type="text" class="form-control t3js-topbar-navigation-search-field" placeholder="Search" id="live-search-box" autocomplete="off">
                                </div>
                        </form>
                ';
diff --git a/typo3/sysext/backend/Classes/Controller/LiveSearchController.php b/typo3/sysext/backend/Classes/Controller/LiveSearchController.php
new file mode 100644 (file)
index 0000000..c86603e
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+namespace TYPO3\CMS\Backend\Controller;
+
+/*
+ * 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!
+ */
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Returns the results for any live searches, e.g. in the toolbar
+ */
+class LiveSearchController {
+
+       /**
+        * @var array
+        */
+       protected $searchResults = array();
+
+       /**
+        * Processes all AJAX calls and sends back a JSON object
+        *
+        * @param array $parameters
+        * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxRequestHandler
+        */
+       public function liveSearchAction($parameters, \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxRequestHandler) {
+               $queryString = GeneralUtility::_GET('q');
+               $liveSearch = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Search\LiveSearch\LiveSearch::class);
+               $queryParser = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Search\LiveSearch\QueryParser::class);
+
+               $searchResults = array();
+               $liveSearch->setQueryString($queryString);
+               // Jump & edit - find page and retrieve an edit link (this is only for pages
+               if ($queryParser->isValidPageJump($queryString)) {
+                       $searchResults[] = array_merge($liveSearch->findPage($queryString), array('type' => 'pageJump'));
+                       $commandQuery = $queryParser->getCommandForPageJump($queryString);
+                       if ($commandQuery) {
+                               $queryString = $commandQuery;
+                       }
+               }
+               // Search through the database and find records who match to the given search string
+               $resultArray = $liveSearch->find($queryString);
+               foreach ($resultArray as $resultFromTable) {
+                       foreach ($resultFromTable as $item) {
+                               $searchResults[] = $item;
+                       }
+               }
+               $ajaxRequestHandler->setContent($searchResults);
+               $ajaxRequestHandler->setContentFormat('json');
+       }
+}
diff --git a/typo3/sysext/backend/Classes/Search/LiveSearch/ExtDirect/LiveSearchDataProvider.php b/typo3/sysext/backend/Classes/Search/LiveSearch/ExtDirect/LiveSearchDataProvider.php
deleted file mode 100644 (file)
index 8b3576d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect;
-
-/*
- * 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!
- */
-
-/**
- * ExtDirect Class for handling backend live search.
- */
-class LiveSearchDataProvider {
-
-       /**
-        * @var array
-        */
-       protected $searchResults = array(
-               'pageJump' => '',
-               'searchItems' => array()
-       );
-
-       /**
-        * @var \TYPO3\CMS\Backend\Search\LiveSearch\LiveSearch
-        */
-       protected $liveSearch = NULL;
-
-       /**
-        * @var \TYPO3\CMS\Backend\Search\LiveSearch\QueryParser
-        */
-       protected $queryParser = NULL;
-
-       /**
-        * Initialize the live search
-        */
-       public function __construct() {
-               $this->liveSearch = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Search\LiveSearch\LiveSearch::class);
-               $this->queryParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Search\LiveSearch\QueryParser::class);
-       }
-
-       /**
-        * @param stdClass $command
-        * @return array
-        */
-       public function find($command) {
-               $this->liveSearch->setStartCount($command->start);
-               $this->liveSearch->setLimitCount($command->limit);
-               $this->liveSearch->setQueryString($command->query);
-               // Jump & edit - find page and retrieve an edit link (this is only for pages
-               if ($this->queryParser->isValidPageJump($command->query)) {
-                       $this->searchResults['pageJump'] = $this->liveSearch->findPage($command->query);
-                       $commandQuery = $this->queryParser->getCommandForPageJump($command->query);
-                       if ($commandQuery) {
-                               $command->query = $commandQuery;
-                       }
-               }
-               // Search through the database and find records who match to the given search string
-               $resultArray = $this->liveSearch->find($command->query);
-               foreach ($resultArray as $resultFromTable) {
-                       foreach ($resultFromTable as $item) {
-                               $this->searchResults['searchItems'][] = $item;
-                       }
-               }
-               return $this->searchResults;
-       }
-
-}
index 8422b26..74cf522 100644 (file)
@@ -212,9 +212,12 @@ class LiveSearch {
                        $collect[] = array(
                                'id' => $tableName . ':' . $row['uid'],
                                'pageId' => $tableName === 'pages' ? $row['uid'] : $row['pid'],
-                               'recordTitle' => $isFirst ? $this->getRecordTitlePrep($this->getTitleOfCurrentRecordType($tableName), self::GROUP_TITLE_MAX_LENGTH) : '',
+                               'table' => array(
+                                       'title' => $this->getTitleOfCurrentRecordType($tableName),
+                                       'name' => $tableName,
+                               ),
                                'iconHTML' => IconUtility::getSpriteIconForRecord($tableName, $row, array('title' => 'id=' . $row['uid'] . ', pid=' . $row['pid'])),
-                               'title' => $this->getRecordTitlePrep(BackendUtility::getRecordTitle($tableName, $row), self::RECORD_TITLE_MAX_LENGTH),
+                               'title' => BackendUtility::getRecordTitle($tableName, $row),
                                'editLink' => $this->getEditLink($tableName, $row)
                        );
                        $isFirst = FALSE;
@@ -435,7 +438,6 @@ class LiveSearch {
         * @return string Comma separated list of uids
         */
        protected function getAvailablePageIds($id, $depth) {
-               $idList = '';
                $tree = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\PageTreeView::class);
                $tree->init('AND ' . $this->userPermissions);
                $tree->makeHTML = 0;
index 384e5ee..83a4cf3 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Search\LiveSearch;
 
 /**
  * Class for parsing query parameters in backend live search.
+ * Detects searches for #pages:23 or #content:mycontent
  */
 class QueryParser {
 
@@ -46,9 +47,7 @@ class QueryParser {
         * @return string Command name
         */
        protected function extractKeyFromQuery($query) {
-               $keyAndValue = substr($query, 1);
-               $key = explode(':', $keyAndValue);
-               $this->commandKey = $key[0];
+               list($this->commandKey) = explode(':', substr($query, 1));
        }
 
        /**
@@ -71,7 +70,7 @@ class QueryParser {
        public function getTableNameFromCommand($query) {
                $tableName = '';
                $this->extractKeyFromQuery($query);
-               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']) && array_key_exists($this->commandKey, $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'])) {
+               if (array_key_exists($this->commandKey, $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'])) {
                        $tableName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'][$this->commandKey];
                }
                return $tableName;
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js b/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js
new file mode 100644 (file)
index 0000000..ea64121
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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!
+ */
+
+/**
+ * Global search to deal with everything in the backend that is search-related
+ */
+define('TYPO3/CMS/Backend/LiveSearch', ['jquery', 'typeaheadjs'], function ($) {
+
+       var containerSelector = '.t3js-topbar-navigation-search';
+       var searchFieldSelector = '.t3js-topbar-navigation-search-field';
+       var url = TYPO3.settings.ajaxUrls['LiveSearch'] + '&q=';
+       var cssPrefix = 'typeahead';
+
+       var initialize = function() {
+               var $searchField = $(searchFieldSelector);
+
+               var searchCall = function(query, syncResults, asyncResults) {
+                       $.ajax({
+                               url: url + rawurlencode(query.toString()),
+                               cache: false,
+                               success: function(results) {
+                                       asyncResults(results);
+                               }
+                       });
+               };
+
+               $searchField.typeahead({
+                       hint: false,
+                       highlight: true,
+                       limit: 10,
+                       minLength: 2,
+                       classNames: {
+                               wrapper: cssPrefix,
+                               input: cssPrefix + '-input',
+                               hint: cssPrefix + '-hint',
+                               menu: cssPrefix + '-menu dropdown-menu',
+                               dataset: 'dropdown-list ' + cssPrefix + '-dataset',
+                               suggestion: cssPrefix + '-suggestion',
+                               empty: cssPrefix + '-empty',
+                               open: cssPrefix + '-open',
+                               cursor: cssPrefix + '-cursor',
+                               highlight: cssPrefix + '-highlight'
+                       }
+               }, {
+                       name: 'databaseRecords',
+                       source: searchCall,
+                       limit: 1000,    // this needs to be very high, limiter is on PHP side
+                       display: function() {
+                               return $searchField.val();
+                       },
+                       templates: {
+                               empty: '<div class="dropdown-info typeahead-search-empty-message">' + TYPO3.LLL.liveSearch.listEmptyText + '</div>'
+                                       + '<div class="search-list-help-content"><strong>' + TYPO3.LLL.liveSearch.helpTitle + '</strong>'
+                                       + '<p>' + TYPO3.LLL.liveSearch.helpDescription + '<br>' + TYPO3.LLL.liveSearch.helpDescriptionPages + '</p>'
+                                       + '</div>'
+                               ,
+                               suggestion: function(result) {
+                                       return '' +
+                                               '<div data-table-name="' + result.table.name + '" data-table-title="' + result.table.title + '">' +
+                                                       '<a class="dropdown-list-link" href="#" data-pageid="' + result.pageId + '" data-target="' + result.editLink + '">' +
+                                                               result.iconHTML + ' ' + result.title +
+                                                       '</a>' +
+                                               '</div>';
+                               },
+                               footer: '' +
+                                               '<div>' +
+                                                       '<a href="#" class="btn btn-primary pull-right t3js-live-search-show-all">' +
+                                                               TYPO3.LLL.liveSearch.showAllResults +
+                                                       '</a>' +
+                                               '</div>'
+                       }
+               }).bind('typeahead:render', function(e) {
+                       var suggestions = [].slice.call(arguments, 1);
+                       var lastTable = '';
+                       $.each(suggestions, function(){
+                               if (lastTable !== this.table.name) {
+                                       lastTable = this.table.name;
+                                       var $dataSet = $(containerSelector + ' [data-table-name=' + this.table.name + ']');
+                                       $dataSet.first().before('<div class="dropdown-header">' + this.table.title + '</div>');
+                                       $dataSet.last().after('<div class="divider"></div>');
+                               }
+                       });
+               });
+
+               // set up the events
+               $(containerSelector).on('click', '.t3js-live-search-show-all', function() {
+                       TYPO3.ModuleMenu.App.showModule('web_list', 'id=0&search_levels=4&search_field=' + $searchField.val());
+                       $searchField.typeahead('close');
+               }).on('click', '.typeahead-suggestion a', function() {
+                       jump($(this).data('target'), 'web_list', 'web', $(this).data('pageid'));
+                       $searchField.typeahead('close');
+               });
+               $searchField.on('typeahead:change', function() {
+                       $searchField.typeahead('close');
+               });
+       };
+
+       $(document).ready(function() {
+               initialize();
+       });
+});
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/livesearch.js b/typo3/sysext/backend/Resources/Public/JavaScript/livesearch.js
deleted file mode 100644 (file)
index e85084e..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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!
- */
-
-Ext.namespace('TYPO3');
-
-TYPO3.BackendLiveSearch = Ext.extend(Ext.form.ComboBox, {
-       autoSelect: false,
-       ctCls: 'live-search-results',
-       dataProvider: null,
-       searchResultsPid : 0,
-       displayField: 'title',
-       emptyText: null,
-       enableKeyEvents: true,
-       helpTitle: null,
-       hideTrigger: true,
-       itemSelector: 'div.search-item-title',
-       listAlign : 'tr-br',
-       listClass: 'live-search-list',
-       listEmptyText: null,
-       listWidth: 400,
-       listHovered: false,
-       loadingText: null,
-       minChars: 1,
-       resizable: false,
-       title: null,
-       triggerClass : 'x-form-clear-trigger',
-       triggerConfig: '<span class="t3-icon fa fa-remove"></span>',
-       onTriggerClick: function() {
-               // Empty the form field, give it focus, and collapse the results
-               this.reset(this);
-               this.focus();
-               this.collapse();
-       },
-       tpl: new Ext.XTemplate(
-               '<table border="0" cellspacing="0">',
-                       '<tpl for=".">',
-                               '<tr class="search-item">',
-                                       '<td class="search-item-type">{recordTitle}</td>',
-                                       '<td class="search-item-content" width="95%">',
-                                               '<div class="search-item-title">{iconHTML} {title}</div>',
-                                       '</td>',
-                               '</tr>',
-                       '</tpl>',
-               '</table>'
-       ),
-
-       dataReader : new Ext.data.JsonReader({
-               idProperty : 'type',
-               root : 'searchItems',
-               fields : [
-                       {name: 'recordTitle'},
-                       {name: 'pageId'},
-                       {name: 'id'},
-                       {name: 'iconHTML'},
-                       {name: 'title'},
-                       {name: 'editLink'}
-               ]
-       }),
-       listeners: {
-               select : {
-                       scope: this,
-                       fn: function (combo, record, index) {
-                               jump(record.data.editLink, 'web_list', 'web', record.data.pageId);
-                       }
-               },
-               focus : {
-                       fn: function() {
-                               if (this.getValue() == this.emptyText) {
-                                       this.reset(this);
-                               }
-                       }
-               },
-               specialkey : function (field, e) {
-                       if (e.getKey() == e.RETURN || e.getKey() == e.ENTER) {
-                               if (this.dataReader.jsonData.pageJump != '') {
-                                       jump(this.dataReader.jsonData.pageJump, 'web_list', 'web');
-                               } else {
-                                       TYPO3.ModuleMenu.App.showModule('web_list', this.getSearchResultsUrl(this.getValue()));
-                               }
-                       }
-               },
-               keyup : function() {
-                       if ((this.getValue() == this.emptyText) || (this.getValue() == '')) {
-                               this.setHideTrigger(true);
-                       } else {
-                               this.setHideTrigger(false);
-                       }
-               }
-       },
-
-       /**
-        * Initializes the component.
-        */
-       initComponent: function() {
-               this.store = new Ext.data.DirectStore({
-                       directFn: this.dataProvider.find,
-                       reader: this.dataReader
-               });
-               TYPO3.BackendLiveSearch.superclass.initComponent.apply(this, arguments);
-       },
-
-       restrictHeight : function(){
-               this.innerList.dom.style.height = '';
-               this.innerList.dom.style.width = '';
-               this.list.beginUpdate();
-               this.list.setHeight('auto');
-               this.list.endUpdate();
-       },
-
-       initList : function () {
-               TYPO3.BackendLiveSearch.superclass.initList.apply(this, arguments);
-               var cls = 'x-combo-list';
-
-                       // Track whether the hovering over the results list or not, to aid in detecting iframe clicks.
-               this.mon(this.list, 'mouseover', function() {this.listHovered = true;}, this);
-               this.mon(this.list, 'mouseout', function() {this.listHovered = false; }, this);
-
-               /**
-                * Create bottom Toolbar to the result layer
-                */
-               this.footer = this.list.createChild({cls:cls+'-ft'});
-               this.pageTb = new Ext.Toolbar({
-                       renderTo:this.footer,
-                       items: [{
-                               xtype: 'tbfill',
-                               autoWidth : true
-                       },{
-                               xtype: 'button',
-                               text: TYPO3.LLL.liveSearch.showAllResults,
-                               shadow: false,
-                               listeners : {
-                                       scope : this,
-                                       click : function () {
-                                                       // go to db_list.php and search for given search value
-                                                       // @todo the current selected page ID from the page tree is required
-                                               TYPO3.ModuleMenu.App.showModule('web_list', this.getSearchResultsUrl(this.getValue()));
-                                               this.collapse();
-                                       }
-                               }
-                       }]
-               });
-       },
-
-       initQuery : function(){
-               TYPO3.BackendLiveSearch.superclass.initQuery.apply(this, arguments);
-               this.removeHelp();
-       },
-       initHelp : function () {
-               if(!this.helpList){
-                       var cls = 'search-list-help';
-
-                       this.helpList = new Ext.Layer({
-                               parentEl: this.getListParent(),
-                               shadow: false,
-                               cls: [cls, this.listClass].join(' '),
-                               constrain:false
-                       });
-
-                               // Track whether the hovering over the help list or not, to aid in detecting iframe clicks.
-                       this.mon(this.helpList, 'mouseover', function() {this.listHovered = true;}, this);
-                       this.mon(this.helpList, 'mouseout', function() {this.listHovered = false; }, this);
-
-                       this.helpList.swallowEvent('mousewheel');
-
-                       this.innerHelpList = this.helpList.createChild({cls:cls+'-inner'});
-                       this.mon(this.innerHelpList, 'mouseover', this.onViewOver, this);
-                       this.mon(this.innerHelpList, 'mousemove', this.onViewMove, this);
-
-                       if(!this.helpTpl){
-                               this.helpTpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
-                        }
-
-                       /**
-                       * The {@link Ext.DataView DataView} used to display the ComboBox's options.
-                       * @type Ext.DataView
-                       */
-                       this.helpView = new Ext.DataView({
-                               applyTo: this.innerHelpList,
-                               tpl: this.helpTpl,
-                               singleSelect: true,
-                               selectedClass: this.selectedClass,
-                               itemSelector: this.itemSelector || '.' + cls + '-item',
-                               emptyText: this.listEmptyText
-                       });
-
-                       this.helpList.createChild({
-                               cls: cls + '-content',
-                               // @todo Can we grab this content via ExtDirect?
-                               html: '<strong>' + this.helpTitle + '</strong><p>' + TYPO3.LLL.liveSearch.helpDescription + '<br /> ' + TYPO3.LLL.liveSearch.helpDescriptionPages + '</p>'
-                       });
-
-                       this.helpList.alignTo(this.wrap, this.listAlign);
-                       this.helpList.show();
-               }
-       },
-
-       removeHelp : function() {
-               if (this.helpList) {
-                       this.helpList.destroy();
-                       delete this.helpList;
-               }
-       },
-
-       onFocus : function() {
-               TYPO3.BackendLiveSearch.superclass.onFocus.apply(this, arguments);
-
-               // If search is blank, show the help on focus. Otherwise, show last results
-               if (this.getValue() == '') {
-                       this.initHelp();
-               } else {
-                       this.expand();
-               }
-       },
-
-       /**
-        * Fired when search results are clicked. We do not want the search result
-        * appear so we always set doFocus = false
-        */
-       onViewClick : function(doFocus){
-               doFocus = false;
-               TYPO3.BackendLiveSearch.superclass.onViewClick.apply(this, arguments);
-       },
-
-       postBlur : function() {
-               TYPO3.BackendLiveSearch.superclass.postBlur.apply(this, arguments);
-               this.removeHelp();
-       },
-
-       getTriggerWidth : function() {
-               // Trigger is inset, so width used in calculations is 0
-               return 0;
-       },
-
-       reset : function() {
-           this.originalValue = this.emptyText;
-               this.setHideTrigger(true);
-               TYPO3.BackendLiveSearch.superclass.reset.apply(this, arguments);
-       },
-
-       getSearchResultsUrl : function(searchTerm) {
-               return 'id=' + this.searchResultsPid + '&search_levels=4&search_field=' + searchTerm;
-       },
-
-       handleBlur : function(e) {
-
-               if (!this.listHovered) {
-                       this.hasFocus = false;
-                       if (this.getValue() == '') {
-                               this.reset();
-                       }
-                       this.postBlur();
-               }
-
-       }
-});
-
-var TYPO3LiveSearch;
-
-Ext.onReady(function() {
-       TYPO3LiveSearch = new TYPO3.BackendLiveSearch({
-               dataProvider: TYPO3.LiveSearchActions.ExtDirect,
-               title: TYPO3.LLL.liveSearch.title,
-               helpTitle: TYPO3.LLL.liveSearch.helpTitle,
-               emptyText: TYPO3.LLL.liveSearch.emptyText,
-               loadingText: TYPO3.LLL.liveSearch.loadingText,
-               listEmptyText: TYPO3.LLL.liveSearch.listEmptyText
-       });
-
-       TYPO3LiveSearch.applyToMarkup(Ext.get('live-search-box'));
-
-               // Add a blur event listener outside the ExtJS widget to handle clicks in iframes also.
-       Ext.get('live-search-box').on('blur', TYPO3LiveSearch.handleBlur, TYPO3LiveSearch);
-});
index a290d3f..bfc4c82 100644 (file)
@@ -25,3 +25,6 @@ if (TYPO3_MODE === 'BE') {
 }
 
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default'] = \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController::class;
+
+// Register search key shortcuts
+$GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']['page'] = 'pages';
index b2e19c0..0bf6b2d 100644 (file)
@@ -522,12 +522,6 @@ class Bootstrap {
                                \TYPO3\CMS\Backend\ContextMenu\Pagetree\Extdirect\ContextMenuConfiguration::class
                        );
                        ExtensionManagementUtility::registerExtDirectComponent(
-                               'TYPO3.LiveSearchActions.ExtDirect',
-                               \TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect\LiveSearchDataProvider::class,
-                               'web_list',
-                               'user,group'
-                       );
-                       ExtensionManagementUtility::registerExtDirectComponent(
                                'TYPO3.ExtDirectStateProvider.ExtDirect',
                                \TYPO3\CMS\Backend\InterfaceState\ExtDirect\DataProvider::class
                        );
index 58a7fc7..de307b9 100644 (file)
@@ -1565,6 +1565,7 @@ class PageRenderer implements \TYPO3\CMS\Core\SingletonInterface {
                                'autosize' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/autosize',
                                'taboverride' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/taboverride.min',
                                'twbs/bootstrap-slider' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap-slider.min',
+                               'typeaheadjs' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/typeahead',
                        );
                        // get all extensions that are loaded
                        $loadedExtensions = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray();
index 999d629..a15668b 100644 (file)
@@ -266,6 +266,7 @@ return array(
                                'svg' => 'image/svg+xml'
                        )
                ),
+               'livesearch' => array(),        // Array: keywords used for commands to search for specific tables
                'isInitialInstallationInProgress' => FALSE,             // Boolean: If TRUE, the installation is 'in progress'. This value is handled within the install tool step installer internally.
                'clearCacheSystem' => FALSE,            // Boolean: If set, the toolbar menu entry for clearing system caches (core cache, class cache, etc.) is visible for admin users.
                'formEngine' => array(
@@ -751,6 +752,10 @@ return array(
                        'ImageManipulationWizard::getHtmlForImageManipulationWizard' => array(
                                'callbackMethod' => \TYPO3\CMS\Backend\Form\Wizard\ImageManipulationWizard::class . '->getHtmlForImageManipulationWizard',
                                'csrfTokenCheck' => TRUE
+                       ),
+                       'LiveSearch' => array(
+                               'callbackMethod' => \TYPO3\CMS\Backend\Controller\LiveSearchController::class . '->liveSearchAction',
+                               'csrfTokenCheck' => TRUE
                        )
                ),
                'toolbarItems' => array(), // Array: Registered toolbar items classes
index 35a61bc..692476f 100644 (file)
@@ -16,4 +16,9 @@ the sources are fetched via bower.
 Twitter Bootstrap 3 is not shipped as an AMD module, and has been adapted to be
 wrapped as an AMD module called "bootstrap".
 
+- typeahead.js
+The typeahead.js AMD still has a bug that the AMD module is called wrongly, thus
+it is changed manually by TYPO3 to be called "typeaheadjs", and used like that in
+the Core.
+
 Benni, March 2015.
diff --git a/typo3/sysext/core/Resources/Public/JavaScript/Contrib/typeahead.js b/typo3/sysext/core/Resources/Public/JavaScript/Contrib/typeahead.js
new file mode 100644 (file)
index 0000000..9908ca1
--- /dev/null
@@ -0,0 +1,7 @@
+/*!
+ * typeahead.js 0.11.1
+ * https://github.com/twitter/typeahead.js
+ * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+!function(a,b){"function"==typeof define&&define.amd?define("typeaheadjs",["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},isElement:function(a){return!(!a||1!==a.nodeType)},isJQuery:function(b){return b instanceof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,identity:function(a){return a},clone:function(b){return a.extend(!0,{},b)},getIdGenerator:function(){var a=0;return function(){return a++}},templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},stringify:function(a){return b.isString(a)?a:JSON.stringify(a)},noop:function(){}}}(),c=function(){"use strict";function a(a){var g,h;return h=b.mixin({},f,a),g={css:e(),classes:h,html:c(h),selectors:d(h)},{css:g.css,html:g.html,classes:g.classes,selectors:g.selectors,mixin:function(a){b.mixin(a,g)}}}function c(a){return{wrapper:'<span class="'+a.wrapper+'"></span>',menu:'<div class="'+a.menu+'"></div>'}}function d(a){var c={};return b.each(a,function(a,b){c[b]="."+a}),c}function e(){var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},menu:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),a}var f={wrapper:"twitter-typeahead",input:"tt-input",hint:"tt-hint",menu:"tt-menu",dataset:"tt-dataset",suggestion:"tt-suggestion",selectable:"tt-selectable",empty:"tt-empty",open:"tt-open",cursor:"tt-cursor",highlight:"tt-highlight"};return a}(),d=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d,e;return d="typeahead:",e={render:"rendered",cursorchange:"cursorchanged",select:"selected",autocomplete:"autocompleted"},b.mixin(c.prototype,{_trigger:function(b,c){var e;return e=a.Event(d+b),(c=c||[]).unshift(e),this.$el.trigger.apply(this.$el,c),e},before:function(a){var b,c;return b=[].slice.call(arguments,1),c=this._trigger("before"+a,b),c.isDefaultPrevented()},trigger:function(a){var b;this._trigger(a,[].slice.call(arguments,1)),(b=e[a])&&this._trigger(b,[].slice.call(arguments,1))}}),c}(),e=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),f=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e<a.childNodes.length;e++)c=a.childNodes[e],c.nodeType===d?e+=b(c)?1:0:g(c,b)}var h;e=b.mixin({},d,e),e.node&&e.pattern&&(e.pattern=b.isArray(e.pattern)?e.pattern:[e.pattern],h=c(e.pattern,e.caseSensitive,e.wordsOnly),g(e.node,f))}}(window.document),g=function(){"use strict";function c(c,e){c=c||{},c.input||a.error("input is missing"),e.mixin(this),this.$hint=a(c.hint),this.$input=a(c.input),this.query=this.$input.val(),this.queryWhenFocused=this.hasFocus()?this.query:null,this.$overflowHelper=d(this.$input),this._checkLanguageDirection(),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop)}function d(b){return a('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function f(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function g(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var h;return h={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return b.toStr(a).replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,e,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.queryWhenFocused=this.query,this.trigger("focused")},_onKeydown:function(a){var b=h[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._setQuery(this.getInputValue()),this.clearHintIfInvalid(),this._checkLanguageDirection()},_managePreventDefault:function(a,b){var c;switch(a){case"up":case"down":c=!g(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!g(b);break;default:c=!0}return c},_checkLanguageDirection:function(){var a=(this.$input.css("direction")||"ltr").toLowerCase();this.dir!==a&&(this.dir=a,this.$hint.attr("dir",a),this.trigger("langDirChanged",a))},_setQuery:function(a,b){var c,d;c=f(a,this.query),d=c?this.query.length!==a.length:!1,this.query=a,b||c?!b&&d&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},bind:function(){var a,c,d,e,f=this;return a=b.bind(this._onBlur,this),c=b.bind(this._onFocus,this),d=b.bind(this._onKeydown,this),e=b.bind(this._onInput,this),this.$input.on("blur.tt",a).on("focus.tt",c).on("keydown.tt",d),!b.isMsie()||b.isMsie()>9?this.$input.on("input.tt",e):this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){h[a.which||a.keyCode]||b.defer(b.bind(f._onInput,f,a))}),this},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getLangDir:function(){return this.dir},getQuery:function(){return this.query||""},setQuery:function(a,b){this.setInputValue(a),this._setQuery(a,b)},hasQueryChangedSinceLastFocus:function(){return this.query!==this.queryWhenFocused},getInputValue:function(){return this.$input.val()},setInputValue:function(a){this.$input.val(a),this.clearHintIfInvalid(),this._checkLanguageDirection()},resetInputValue:function(){this.setInputValue(this.query)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},hasFocus:function(){return this.$input.is(":focus")},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$overflowHelper.remove(),this.$hint=this.$input=this.$overflowHelper=a("<div>")}}),c}(),h=function(){"use strict";function c(c,e){c=c||{},c.templates=c.templates||{},c.templates.notFound=c.templates.notFound||c.templates.empty,c.source||a.error("missing source"),c.node||a.error("missing node"),c.name&&!h(c.name)&&a.error("invalid dataset name: "+c.name),e.mixin(this),this.highlight=!!c.highlight,this.name=c.name||j(),this.limit=c.limit||5,this.displayFn=d(c.display||c.displayKey),this.templates=g(c.templates,this.displayFn),this.source=c.source.__ttAdapter?c.source.__ttAdapter():c.source,this.async=b.isUndefined(c.async)?this.source.length>2:!!c.async,this._resetLastSuggestion(),this.$el=a(c.node).addClass(this.classes.dataset).addClass(this.classes.dataset+"-"+this.name)}function d(a){function c(b){return b[a]}return a=a||b.stringify,b.isFunction(a)?a:c}function g(c,d){function e(b){return a("<div>").text(d(b))}return{notFound:c.notFound&&b.templatify(c.notFound),pending:c.pending&&b.templatify(c.pending),header:c.header&&b.templatify(c.header),footer:c.footer&&b.templatify(c.footer),suggestion:c.suggestion||e}}function h(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var i,j;return i={val:"tt-selectable-display",obj:"tt-selectable-object"},j=b.getIdGenerator(),c.extractData=function(b){var c=a(b);return c.data(i.obj)?{val:c.data(i.val)||"",obj:c.data(i.obj)||null}:null},b.mixin(c.prototype,e,{_overwrite:function(a,b){b=b||[],b.length?this._renderSuggestions(a,b):this.async&&this.templates.pending?this._renderPending(a):!this.async&&this.templates.notFound?this._renderNotFound(a):this._empty(),this.trigger("rendered",this.name,b,!1)},_append:function(a,b){b=b||[],b.length&&this.$lastSuggestion.length?this._appendSuggestions(a,b):b.length?this._renderSuggestions(a,b):!this.$lastSuggestion.length&&this.templates.notFound&&this._renderNotFound(a),this.trigger("rendered",this.name,b,!0)},_renderSuggestions:function(a,b){var c;c=this._getSuggestionsFragment(a,b),this.$lastSuggestion=c.children().last(),this.$el.html(c).prepend(this._getHeader(a,b)).append(this._getFooter(a,b))},_appendSuggestions:function(a,b){var c,d;c=this._getSuggestionsFragment(a,b),d=c.children().last(),this.$lastSuggestion.after(c),this.$lastSuggestion=d},_renderPending:function(a){var b=this.templates.pending;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_renderNotFound:function(a){var b=this.templates.notFound;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_empty:function(){this.$el.empty(),this._resetLastSuggestion()},_getSuggestionsFragment:function(c,d){var e,g=this;return e=document.createDocumentFragment(),b.each(d,function(b){var d,f;f=g._injectQuery(c,b),d=a(g.templates.suggestion(f)).data(i.obj,b).data(i.val,g.displayFn(b)).addClass(g.classes.suggestion+" "+g.classes.selectable),e.appendChild(d[0])}),this.highlight&&f({className:this.classes.highlight,node:e,pattern:c}),a(e)},_getFooter:function(a,b){return this.templates.footer?this.templates.footer({query:a,suggestions:b,dataset:this.name}):null},_getHeader:function(a,b){return this.templates.header?this.templates.header({query:a,suggestions:b,dataset:this.name}):null},_resetLastSuggestion:function(){this.$lastSuggestion=a()},_injectQuery:function(a,c){return b.isObject(c)?b.mixin({_query:a},c):c},update:function(b){function c(a){g||(g=!0,a=(a||[]).slice(0,e.limit),h=a.length,e._overwrite(b,a),h<e.limit&&e.async&&e.trigger("asyncRequested",b))}function d(c){c=c||[],!f&&h<e.limit&&(e.cancel=a.noop,h+=c.length,e._append(b,c.slice(0,e.limit-h)),e.async&&e.trigger("asyncReceived",b))}var e=this,f=!1,g=!1,h=0;this.cancel(),this.cancel=function(){f=!0,e.cancel=a.noop,e.async&&e.trigger("asyncCanceled",b)},this.source(b,c,d),!g&&c([])},cancel:a.noop,clear:function(){this._empty(),this.cancel(),this.trigger("cleared")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=a("<div>")}}),c}(),i=function(){"use strict";function c(c,d){function e(b){var c=f.$node.find(b.node).first();return b.node=c.length?c:a("<div>").appendTo(f.$node),new h(b,d)}var f=this;c=c||{},c.node||a.error("node is required"),d.mixin(this),this.$node=a(c.node),this.query=null,this.datasets=b.map(c.datasets,e)}return b.mixin(c.prototype,e,{_onSelectableClick:function(b){this.trigger("selectableClicked",a(b.currentTarget))},_onRendered:function(a,b,c,d){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetRendered",b,c,d)},_onCleared:function(){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetCleared")},_propagate:function(){this.trigger.apply(this,arguments)},_allDatasetsEmpty:function(){function a(a){return a.isEmpty()}return b.every(this.datasets,a)},_getSelectables:function(){return this.$node.find(this.selectors.selectable)},_removeCursor:function(){var a=this.getActiveSelectable();a&&a.removeClass(this.classes.cursor)},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$node.scrollTop(),e=this.$node.height()+parseInt(this.$node.css("paddingTop"),10)+parseInt(this.$node.css("paddingBottom"),10),0>b?this.$node.scrollTop(d+b):c>e&&this.$node.scrollTop(d+(c-e))},bind:function(){var a,c=this;return a=b.bind(this._onSelectableClick,this),this.$node.on("click.tt",this.selectors.selectable,a),b.each(this.datasets,function(a){a.onSync("asyncRequested",c._propagate,c).onSync("asyncCanceled",c._propagate,c).onSync("asyncReceived",c._propagate,c).onSync("rendered",c._onRendered,c).onSync("cleared",c._onCleared,c)}),this},isOpen:function(){return this.$node.hasClass(this.classes.open)},open:function(){this.$node.addClass(this.classes.open)},close:function(){this.$node.removeClass(this.classes.open),this._removeCursor()},setLanguageDirection:function(a){this.$node.attr("dir",a)},selectableRelativeToCursor:function(a){var b,c,d,e;return c=this.getActiveSelectable(),b=this._getSelectables(),d=c?b.index(c):-1,e=d+a,e=(e+1)%(b.length+1)-1,e=-1>e?b.length-1:e,-1===e?null:b.eq(e)},setCursor:function(a){this._removeCursor(),(a=a&&a.first())&&(a.addClass(this.classes.cursor),this._ensureVisible(a))},getSelectableData:function(a){return a&&a.length?h.extractData(a):null},getActiveSelectable:function(){var a=this._getSelectables().filter(this.selectors.cursor).first();return a.length?a:null},getTopSelectable:function(){var a=this._getSelectables().first();return a.length?a:null},update:function(a){function c(b){b.update(a)}var d=a!==this.query;return d&&(this.query=a,b.each(this.datasets,c)),d},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.query=null,this.$node.addClass(this.classes.empty)},destroy:function(){function c(a){a.destroy()}this.$node.off(".tt"),this.$node=a("<div>"),b.each(this.datasets,c)}}),c}(),j=function(){"use strict";function a(){i.apply(this,[].slice.call(arguments,0))}var c=i.prototype;return b.mixin(a.prototype,i.prototype,{open:function(){return!this._allDatasetsEmpty()&&this._show(),c.open.apply(this,[].slice.call(arguments,0))},close:function(){return this._hide(),c.close.apply(this,[].slice.call(arguments,0))},_onRendered:function(){return this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onRendered.apply(this,[].slice.call(arguments,0))},_onCleared:function(){return this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onCleared.apply(this,[].slice.call(arguments,0))},setLanguageDirection:function(a){return this.$node.css("ltr"===a?this.css.ltr:this.css.rtl),c.setLanguageDirection.apply(this,[].slice.call(arguments,0))},_hide:function(){this.$node.hide()},_show:function(){this.$node.css("display","block")}}),a}(),k=function(){"use strict";function c(c,e){var f,g,h,i,j,k,l,m,n,o,p;c=c||{},c.input||a.error("missing input"),c.menu||a.error("missing menu"),c.eventBus||a.error("missing event bus"),e.mixin(this),this.eventBus=c.eventBus,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.input=c.input,this.menu=c.menu,this.enabled=!0,this.active=!1,this.input.hasFocus()&&this.activate(),this.dir=this.input.getLangDir(),this._hacks(),this.menu.bind().onSync("selectableClicked",this._onSelectableClicked,this).onSync("asyncRequested",this._onAsyncRequested,this).onSync("asyncCanceled",this._onAsyncCanceled,this).onSync("asyncReceived",this._onAsyncReceived,this).onSync("datasetRendered",this._onDatasetRendered,this).onSync("datasetCleared",this._onDatasetCleared,this),f=d(this,"activate","open","_onFocused"),g=d(this,"deactivate","_onBlurred"),h=d(this,"isActive","isOpen","_onEnterKeyed"),i=d(this,"isActive","isOpen","_onTabKeyed"),j=d(this,"isActive","_onEscKeyed"),k=d(this,"isActive","open","_onUpKeyed"),l=d(this,"isActive","open","_onDownKeyed"),m=d(this,"isActive","isOpen","_onLeftKeyed"),n=d(this,"isActive","isOpen","_onRightKeyed"),o=d(this,"_openIfActive","_onQueryChanged"),p=d(this,"_openIfActive","_onWhitespaceChanged"),this.input.bind().onSync("focused",f,this).onSync("blurred",g,this).onSync("enterKeyed",h,this).onSync("tabKeyed",i,this).onSync("escKeyed",j,this).onSync("upKeyed",k,this).onSync("downKeyed",l,this).onSync("leftKeyed",m,this).onSync("rightKeyed",n,this).onSync("queryChanged",o,this).onSync("whitespaceChanged",p,this).onSync("langDirChanged",this._onLangDirChanged,this)}function d(a){var c=[].slice.call(arguments,1);return function(){var d=[].slice.call(arguments);b.each(c,function(b){return a[b].apply(a,d)})}}return b.mixin(c.prototype,{_hacks:function(){var c,d;c=this.input.$input||a("<div>"),d=this.menu.$node||a("<div>"),c.on("blur.tt",function(a){var e,f,g;e=document.activeElement,f=d.is(e),g=d.has(e).length>0,b.isMsie()&&(f||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){c.focus()}))}),d.on("mousedown.tt",function(a){a.preventDefault()})},_onSelectableClicked:function(a,b){this.select(b)},_onDatasetCleared:function(){this._updateHint()},_onDatasetRendered:function(a,b,c,d){this._updateHint(),this.eventBus.trigger("render",c,d,b)},_onAsyncRequested:function(a,b,c){this.eventBus.trigger("asyncrequest",c,b)},_onAsyncCanceled:function(a,b,c){this.eventBus.trigger("asynccancel",c,b)},_onAsyncReceived:function(a,b,c){this.eventBus.trigger("asyncreceive",c,b)},_onFocused:function(){this._minLengthMet()&&this.menu.update(this.input.getQuery())},_onBlurred:function(){this.input.hasQueryChangedSinceLastFocus()&&this.eventBus.trigger("change",this.input.getQuery())},_onEnterKeyed:function(a,b){var c;(c=this.menu.getActiveSelectable())&&this.select(c)&&b.preventDefault()},_onTabKeyed:function(a,b){var c;(c=this.menu.getActiveSelectable())?this.select(c)&&b.preventDefault():(c=this.menu.getTopSelectable())&&this.autocomplete(c)&&b.preventDefault()},_onEscKeyed:function(){this.close()},_onUpKeyed:function(){this.moveCursor(-1)},_onDownKeyed:function(){this.moveCursor(1)},_onLeftKeyed:function(){"rtl"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getTopSelectable())},_onRightKeyed:function(){"ltr"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getTopSelectable())},_onQueryChanged:function(a,b){this._minLengthMet(b)?this.menu.update(b):this.menu.empty()},_onWhitespaceChanged:function(){this._updateHint()},_onLangDirChanged:function(a,b){this.dir!==b&&(this.dir=b,this.menu.setLanguageDirection(b))},_openIfActive:function(){this.isActive()&&this.open()},_minLengthMet:function(a){return a=b.isString(a)?a:this.input.getQuery()||"",a.length>=this.minLength},_updateHint:function(){var a,c,d,e,f,h,i;a=this.menu.getTopSelectable(),c=this.menu.getSelectableData(a),d=this.input.getInputValue(),!c||b.isBlankString(d)||this.input.hasOverflow()?this.input.clearHint():(e=g.normalizeQuery(d),f=b.escapeRegExChars(e),h=new RegExp("^(?:"+f+")(.+$)","i"),i=h.exec(c.val),i&&this.input.setHint(d+i[1]))},isEnabled:function(){return this.enabled},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},isActive:function(){return this.active},activate:function(){return this.isActive()?!0:!this.isEnabled()||this.eventBus.before("active")?!1:(this.active=!0,this.eventBus.trigger("active"),!0)},deactivate:function(){return this.isActive()?this.eventBus.before("idle")?!1:(this.active=!1,this.close(),this.eventBus.trigger("idle"),!0):!0},isOpen:function(){return this.menu.isOpen()},open:function(){return this.isOpen()||this.eventBus.before("open")||(this.menu.open(),this._updateHint(),this.eventBus.trigger("open")),this.isOpen()},close:function(){return this.isOpen()&&!this.eventBus.before("close")&&(this.menu.close(),this.input.clearHint(),this.input.resetInputValue(),this.eventBus.trigger("close")),!this.isOpen()},setVal:function(a){this.input.setQuery(b.toStr(a))},getVal:function(){return this.input.getQuery()},select:function(a){var b=this.menu.getSelectableData(a);return b&&!this.eventBus.before("select",b.obj)?(this.input.setQuery(b.val,!0),this.eventBus.trigger("select",b.obj),this.close(),!0):!1},autocomplete:function(a){var b,c,d;return b=this.input.getQuery(),c=this.menu.getSelectableData(a),d=c&&b!==c.val,d&&!this.eventBus.before("autocomplete",c.obj)?(this.input.setQuery(c.val),this.eventBus.trigger("autocomplete",c.obj),!0):!1},moveCursor:function(a){var b,c,d,e,f;return b=this.input.getQuery(),c=this.menu.selectableRelativeToCursor(a),d=this.menu.getSelectableData(c),e=d?d.obj:null,f=this._minLengthMet()&&this.menu.update(b),f||this.eventBus.before("cursorchange",e)?!1:(this.menu.setCursor(c),d?this.input.setInputValue(d.val):(this.input.resetInputValue(),this._updateHint()),this.eventBus.trigger("cursorchange",e),!0)},destroy:function(){this.input.destroy(),this.menu.destroy()}}),c}();!function(){"use strict";function e(b,c){b.each(function(){var b,d=a(this);(b=d.data(p.typeahead))&&c(b,d)})}function f(a,b){return a.clone().addClass(b.classes.hint).removeData().css(b.css.hint).css(l(a)).prop("readonly",!0).removeAttr("id name placeholder required").attr({autocomplete:"off",spellcheck:"false",tabindex:-1})}function h(a,b){a.data(p.attrs,{dir:a.attr("dir"),autocomplete:a.attr("autocomplete"),spellcheck:a.attr("spellcheck"),style:a.attr("style")}),a.addClass(b.classes.input).attr({autocomplete:"off",spellcheck:!1});try{!a.attr("dir")&&a.attr("dir","auto")}catch(c){}return a}function l(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function m(a){var c,d;c=a.data(p.www),d=a.parent().filter(c.selectors.wrapper),b.each(a.data(p.attrs),function(c,d){b.isUndefined(c)?a.removeAttr(d):a.attr(d,c)}),a.removeData(p.typeahead).removeData(p.www).removeData(p.attr).removeClass(c.classes.input),d.length&&(a.detach().insertAfter(d),d.remove())}function n(c){var d,e;return d=b.isJQuery(c)||b.isElement(c),e=d?a(c).first():[],e.length?e:null}var o,p,q;o=a.fn.typeahead,p={www:"tt-www",attrs:"tt-attrs",typeahead:"tt-typeahead"},q={initialize:function(e,l){function m(){var c,m,q,r,s,t,u,v,w,x,y;b.each(l,function(a){a.highlight=!!e.highlight}),c=a(this),m=a(o.html.wrapper),q=n(e.hint),r=n(e.menu),s=e.hint!==!1&&!q,t=e.menu!==!1&&!r,s&&(q=f(c,o)),t&&(r=a(o.html.menu).css(o.css.menu)),q&&q.val(""),c=h(c,o),(s||t)&&(m.css(o.css.wrapper),c.css(s?o.css.input:o.css.inputWithNoHint),c.wrap(m).parent().prepend(s?q:null).append(t?r:null)),y=t?j:i,u=new d({el:c}),v=new g({hint:q,input:c},o),w=new y({node:r,datasets:l},o),x=new k({input:v,menu:w,eventBus:u,minLength:e.minLength},o),c.data(p.www,o),c.data(p.typeahead,x)}var o;return l=b.isArray(l)?l:[].slice.call(arguments,1),e=e||{},o=c(e.classNames),this.each(m)},isEnabled:function(){var a;return e(this.first(),function(b){a=b.isEnabled()}),a},enable:function(){return e(this,function(a){a.enable()}),this},disable:function(){return e(this,function(a){a.disable()}),this},isActive:function(){var a;return e(this.first(),function(b){a=b.isActive()}),a},activate:function(){return e(this,function(a){a.activate()}),this},deactivate:function(){return e(this,function(a){a.deactivate()}),this},isOpen:function(){var a;return e(this.first(),function(b){a=b.isOpen()}),a},open:function(){return e(this,function(a){a.open()}),this},close:function(){return e(this,function(a){a.close()}),this},select:function(b){var c=!1,d=a(b);return e(this.first(),function(a){c=a.select(d)}),c},autocomplete:function(b){var c=!1,d=a(b);return e(this.first(),function(a){c=a.autocomplete(d)}),c},moveCursor:function(a){var b=!1;return e(this.first(),function(c){b=c.moveCursor(a)}),b},val:function(a){var b;return arguments.length?(e(this,function(b){b.setVal(a)}),this):(e(this.first(),function(a){b=a.getVal()}),b)},destroy:function(){return e(this,function(a,b){m(b),a.destroy()}),this}},a.fn.typeahead=function(a){return q[a]?q[a].apply(this,[].slice.call(arguments,1)):q.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=o,this}}()});
index 90343d1..522ff4f 100644 (file)
@@ -56,9 +56,8 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['proc
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][] = \TYPO3\CMS\Frontend\Hooks\TreelistCacheUpdateHooks::class;
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['moveRecordClass'][] = \TYPO3\CMS\Frontend\Hooks\TreelistCacheUpdateHooks::class;
 
-// Register search keys
-$GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']['page'] = 'pages';
-$GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']['content'] = 'tt_content';
-
 // Register hook to show preview info
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['hook_previewInfo']['cms'] = \TYPO3\CMS\Frontend\Hooks\FrontendHooks::class . '->hook_previewInfo';
+
+// Register search key shortcuts
+$GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']['content'] = 'tt_content';
index 2ee2c88..fc7de7d 100644 (file)
@@ -12701,7 +12701,8 @@ iframe {
   margin-right: -16px;
   padding: 8px 16px;
 }
-.typo3-topbar-navigation-items .dropdown-list .dropdown-intro {
+.typo3-topbar-navigation-items .dropdown-list .dropdown-intro,
+.typo3-topbar-navigation-items .dropdown-list .dropdown-info {
   color: #aaaaaa;
   margin-left: -16px;
   margin-right: -16px;
@@ -12786,6 +12787,10 @@ iframe {
   padding: 0;
   margin: 0;
 }
+.typo3-topbar-navigation-search .form-group {
+  margin-top: 0;
+  margin-bottom: 0;
+}
 .typo3-topbar-navigation-search .form-group:before {
   content: "\f002";
   font: normal normal normal 14px/1 FontAwesome;
@@ -12796,10 +12801,10 @@ iframe {
   z-index: 1;
 }
 .typo3-topbar-navigation-search .form-control {
-  box-sizing: content-box;
   background-color: #222222;
   color: #dddddd;
-  height: 18px;
+  height: 45px;
+  width: 300px;
   padding: 14px 30px 13px 35px;
   border: none;
   border-left: 1px solid #2b2b2b;
@@ -12811,7 +12816,7 @@ iframe {
 }
 .typo3-topbar-navigation-search .form-control:focus {
   outline: none;
-  border-left-color: #373737;
+  border-left-color: #515151;
   background-color: #484848;
   -webkit-box-shadow: none;
   box-shadow: none;
@@ -12824,219 +12829,15 @@ iframe {
   margin-right: 0;
   margin-top: -8px;
 }
-.live-search-list {
-  left: auto;
-  right: 0;
-  margin: 0;
-  padding: 8px 16px;
-  color: #dddddd;
-  background-color: #222222;
-  border-color: #111111;
-  border-top: 1px solid #444444;
-  border-left: 0;
-  border-right: 0;
-  border-radius: 0 0 2px 2px;
-  -webkit-box-shadow: 0px 3px 0px rgba(0, 0, 0, 0.15);
-  box-shadow: 0px 3px 0px rgba(0, 0, 0, 0.15);
-  right: auto;
-  padding: 0;
-}
-.live-search-list a {
-  color: #dddddd;
-  white-space: nowrap;
-}
-.live-search-list > *:last-child {
-  margin-bottom: 0;
-}
-.live-search-list .x-toolbar {
-  padding: 0;
-  border: none;
-  background: transparent;
-}
-.live-search-list .x-combo-list-hd,
-.live-search-list .x-combo-list-inner,
-.live-search-list .x-combo-list-ft {
-  border: none;
-  background: transparent;
-  color: #dddddd;
-  padding: 16px;
-}
-.live-search-list .x-combo-list-hd {
-  background-color: #2a2a2a;
-  border-top: 0;
-  border-bottom: 1px solid #111111;
-}
-.live-search-list .x-combo-list-ft {
-  padding-top: 0;
-  border-bottom: 0;
-}
-.live-search-list .x-combo-list-inner {
-  padding-right: 0;
-  border-top: 1px solid #2b2b2b;
-}
-.live-search-list .x-btn {
-  background: none;
-  border: none;
-  color: inherit;
+.typo3-topbar-navigation-search .dropdown-menu {
+  left: auto!important;
+  width: 350px;
 }
-.live-search-list .x-btn .x-btn-tl,
-.live-search-list .x-btn .x-btn-tc,
-.live-search-list .x-btn .x-btn-tr,
-.live-search-list .x-btn .x-btn-ml,
-.live-search-list .x-btn .x-btn-mr,
-.live-search-list .x-btn .x-btn-bl,
-.live-search-list .x-btn .x-btn-bc,
-.live-search-list .x-btn .x-btn-br {
-  display: none;
+.typo3-topbar-navigation-search .dropdown-list-link {
+  max-width: none;
 }
-.live-search-list .x-btn button {
-  display: inline-block;
-  margin-bottom: 0;
+.typo3-topbar-navigation-search .dropdown-list-link .typeahead-highlight {
   font-weight: normal;
-  text-align: center;
-  vertical-align: middle;
-  touch-action: manipulation;
-  cursor: pointer;
-  background-image: none;
-  border: 1px solid transparent;
-  white-space: nowrap;
-  padding: 6px 6px;
-  font-size: 12px;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  padding: 4px 4px;
-  font-size: 11px;
-  line-height: 1.5;
-  border-radius: 2px;
-  color: #333333;
-  background-color: #eeeeee;
-  border-color: #bbbbbb;
-  height: auto!important;
-}
-.live-search-list .x-btn button:focus,
-.live-search-list .x-btn button:active:focus,
-.live-search-list .x-btn button.active:focus,
-.live-search-list .x-btn button.focus,
-.live-search-list .x-btn button:active.focus,
-.live-search-list .x-btn button.active.focus {
-  outline: thin dotted;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-.live-search-list .x-btn button:hover,
-.live-search-list .x-btn button:focus,
-.live-search-list .x-btn button.focus {
-  color: #333333;
-  text-decoration: none;
-}
-.live-search-list .x-btn button:active,
-.live-search-list .x-btn button.active {
-  outline: 0;
-  background-image: none;
-  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-}
-.live-search-list .x-btn button.disabled,
-.live-search-list .x-btn button[disabled],
-fieldset[disabled] .live-search-list .x-btn button {
-  cursor: not-allowed;
-  opacity: 0.65;
-  filter: alpha(opacity=65);
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-a.live-search-list .x-btn button.disabled,
-fieldset[disabled] a.live-search-list .x-btn button {
-  pointer-events: none;
-}
-.live-search-list .x-btn button .t3-icon {
-  margin: 0;
-}
-.live-search-list .x-btn button:focus,
-.live-search-list .x-btn button.focus {
-  color: #333333;
-  background-color: #d5d5d5;
-  border-color: #7b7b7b;
-}
-.live-search-list .x-btn button:hover {
-  color: #333333;
-  background-color: #d5d5d5;
-  border-color: #9c9c9c;
-}
-.live-search-list .x-btn button:active,
-.live-search-list .x-btn button.active,
-.open > .dropdown-toggle.live-search-list .x-btn button {
-  color: #333333;
-  background-color: #d5d5d5;
-  border-color: #9c9c9c;
-}
-.live-search-list .x-btn button:active:hover,
-.live-search-list .x-btn button.active:hover,
-.open > .dropdown-toggle.live-search-list .x-btn button:hover,
-.live-search-list .x-btn button:active:focus,
-.live-search-list .x-btn button.active:focus,
-.open > .dropdown-toggle.live-search-list .x-btn button:focus,
-.live-search-list .x-btn button:active.focus,
-.live-search-list .x-btn button.active.focus,
-.open > .dropdown-toggle.live-search-list .x-btn button.focus {
-  color: #333333;
-  background-color: #c3c3c3;
-  border-color: #7b7b7b;
-}
-.live-search-list .x-btn button:active,
-.live-search-list .x-btn button.active,
-.open > .dropdown-toggle.live-search-list .x-btn button {
-  background-image: none;
-}
-.live-search-list .x-btn button.disabled,
-.live-search-list .x-btn button[disabled],
-fieldset[disabled] .live-search-list .x-btn button,
-.live-search-list .x-btn button.disabled:hover,
-.live-search-list .x-btn button[disabled]:hover,
-fieldset[disabled] .live-search-list .x-btn button:hover,
-.live-search-list .x-btn button.disabled:focus,
-.live-search-list .x-btn button[disabled]:focus,
-fieldset[disabled] .live-search-list .x-btn button:focus,
-.live-search-list .x-btn button.disabled.focus,
-.live-search-list .x-btn button[disabled].focus,
-fieldset[disabled] .live-search-list .x-btn button.focus,
-.live-search-list .x-btn button.disabled:active,
-.live-search-list .x-btn button[disabled]:active,
-fieldset[disabled] .live-search-list .x-btn button:active,
-.live-search-list .x-btn button.disabled.active,
-.live-search-list .x-btn button[disabled].active,
-fieldset[disabled] .live-search-list .x-btn button.active {
-  background-color: #eeeeee;
-  border-color: #bbbbbb;
-}
-.live-search-list .x-btn button .badge {
-  color: #eeeeee;
-  background-color: #333333;
-}
-.live-search-list .search-item-type {
-  padding: 5px 20px 5px 0;
-  white-space: nowrap;
-}
-.live-search-list .search-item-title {
-  border-radius: 2px 0 0 2px;
-  padding: 5px 20px 5px 10px;
-}
-.live-search-list .search-item-title.x-combo-selected {
-  border: none!important;
-  background-color: #3c3c3c;
-}
-.search-list-help-content {
-  padding: 16px;
-}
-.search-list-help-content strong {
-  display: block;
-  margin-bottom: 0.5em;
-}
-.search-list-help-content p {
-  margin-top: 0.5em;
-  margin-bottom: 0;
 }
 #typo3-debug-console {
   background-color: #f5f5f5;