aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--inc/Ui/Search.php319
-rw-r--r--lib/scripts/search.js6
-rw-r--r--lib/tpl/dokuwiki/css/_search.css20
3 files changed, 245 insertions, 100 deletions
diff --git a/inc/Ui/Search.php b/inc/Ui/Search.php
index 5a01b6919..4f477f4d6 100644
--- a/inc/Ui/Search.php
+++ b/inc/Ui/Search.php
@@ -16,8 +16,8 @@ class Search extends Ui
/**
* Search constructor.
*
- * @param array $pageLookupResults
- * @param array $fullTextResults
+ * @param array $pageLookupResults
+ * @param array $fullTextResults
* @param string $highlight
*/
public function __construct(array $pageLookupResults, array $fullTextResults, $highlight)
@@ -90,11 +90,6 @@ class Search extends Ui
$searchForm->addHTML('FIXME Your query is too complex. Search assistance is unavailable. See <a href="https://doku.wiki/search">doku.wiki/search</a> for more help.');
$searchForm->addTagClose('span');
}
- if ($INPUT->str('sort') === 'mtime') {
- $this->searchState->addSearchLinkSort($searchForm, 'sort by hits', '');
- } else {
- $this->searchState->addSearchLinkSort($searchForm, 'sort by mtime', 'mtime');
- }
$searchForm->addFieldsetClose();
@@ -103,6 +98,59 @@ class Search extends Ui
return $searchForm->toHTML();
}
+ protected function addSortTool(Form $searchForm)
+ {
+ global $INPUT, $lang;
+
+ $options = [
+ 'hits' => [
+ 'label' => $lang['search_sort_by_hits'],
+ 'sort' => '',
+ ],
+ 'mtime' => [
+ 'label' => $lang['search_sort_by_mtime'],
+ 'sort' => 'mtime',
+ ],
+ ];
+ $activeOption = 'hits';
+
+ if ($INPUT->str('sort') === 'mtime') {
+ $activeOption = 'mtime';
+ }
+
+ $searchForm->addTagOpen('div')->addClass('search-tool js-search-tool');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('search-tool__current js-current');
+ if ($activeOption !== 'hits') {
+ $currentWrapper->addClass('search-tool__current--changed');
+ }
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->addClass('search-tool__options-list js-optionsList');
+
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li')->addClass('search-tool__options-list-item');
+
+ if ($key === $activeOption) {
+ $listItem->addClass('search-tool__options-list-item--active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $this->searchState->addSearchLinkSort(
+ $searchForm,
+ $option['label'],
+ $option['sort']
+ );
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
+
+ $searchForm->addTagClose('div');
+
+ }
+
/**
* Decide if the given query is simple enough to provide search assistance
*
@@ -136,7 +184,7 @@ class Search extends Ui
/**
* Add the elements to be used for search assistance
*
- * @param Form $searchForm
+ * @param Form $searchForm
*/
protected function addSearchAssistanceElements(Form $searchForm)
{
@@ -152,81 +200,143 @@ class Search extends Ui
$this->addFragmentBehaviorLinks($searchForm);
$this->addNamespaceSelector($searchForm);
$this->addDateSelector($searchForm);
+ $this->addSortTool($searchForm);
$searchForm->addTagClose('div');
}
protected function addFragmentBehaviorLinks(Form $searchForm)
{
- $searchForm->addTagOpen('div')->addClass('search-results-form__subwrapper');
- $searchForm->addHTML('fragment behavior: ');
-
- $this->searchState->addSearchLinkFragment(
- $searchForm,
- 'exact match',
- array_map(function($term){return trim($term, '*');},$this->parsedQuery['and'])
- );
-
- $searchForm->addHTML(', ');
+ global $lang;
- $this->searchState->addSearchLinkFragment(
- $searchForm,
- 'starts with',
- array_map(function($term){return trim($term, '*') . '*';},$this->parsedQuery['and'])
- );
+ $options = [
+ 'exact' => [
+ 'label' => $lang['search_exact_match'],
+ 'and' => array_map(function ($term) {
+ return trim($term, '*');
+ }, $this->parsedQuery['and']),
+ ],
+ 'starts' => [
+ 'label' => $lang['search_starts_with'],
+ 'and' => array_map(function ($term) {
+ return trim($term, '*') . '*';
+ }, $this->parsedQuery['and'])
+ ],
+ 'ends' => [
+ 'label' => $lang['search_ends_with'],
+ 'and' => array_map(function ($term) {
+ return '*' . trim($term, '*');
+ }, $this->parsedQuery['and'])
+ ],
+ 'contains' => [
+ 'label' => $lang['search_contains'],
+ 'and' => array_map(function ($term) {
+ return '*' . trim($term, '*') . '*';
+ }, $this->parsedQuery['and'])
+ ]
+ ];
+
+ // detect current
+ $activeOption = 'exact';
+ foreach ($options as $key => $option) {
+ if ($this->parsedQuery['and'] === $option['and']) {
+ $activeOption = $key;
+ }
+ }
- $searchForm->addHTML(', ');
+ $searchForm->addTagOpen('div')->addClass('search-tool js-search-tool');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('search-tool__current js-current');
+ if ($activeOption !== 'exact') {
+ $currentWrapper->addClass('search-tool__current--changed');
+ }
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
- $this->searchState->addSearchLinkFragment(
- $searchForm,
- 'ends with',
- array_map(function($term){return '*' . trim($term, '*');},$this->parsedQuery['and'])
- );
+ // render options list
+ $searchForm->addTagOpen('ul')->addClass('search-tool__options-list js-optionsList');
- $searchForm->addHTML(', ');
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li')->addClass('search-tool__options-list-item');
- $this->searchState->addSearchLinkFragment(
- $searchForm,
- 'contains',
- array_map(function($term){return '*' . trim($term, '*') . '*';},$this->parsedQuery['and'])
- );
+ if ($key === $activeOption) {
+ $listItem->addClass('search-tool__options-list-item--active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $this->searchState->addSearchLinkFragment(
+ $searchForm,
+ $option['label'],
+ $option['and']
+ );
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
$searchForm->addTagClose('div');
+
+ // render options list
}
/**
* Add the elements for the namespace selector
*
- * @param Form $searchForm
+ * @param Form $searchForm
*/
protected function addNamespaceSelector(Form $searchForm)
{
- $baseNS = empty($this->parsedQuery['ns']) ? '' : $this->parsedQuery['ns'][0];
- $searchForm->addTagOpen('div')->addClass('search-results-form__subwrapper');
+ global $lang;
+ $baseNS = empty($this->parsedQuery['ns']) ? '' : $this->parsedQuery['ns'][0];
$extraNS = $this->getAdditionalNamespacesFromResults($baseNS);
- if (!empty($extraNS) || $baseNS) {
- $searchForm->addTagOpen('div');
- $searchForm->addHTML('limit to namespace: ');
- if ($baseNS) {
+ $searchForm->addTagOpen('div')->addClass('search-tool js-search-tool');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('search-tool__current js-current');
+ if ($baseNS) {
+ $currentWrapper->addClass('search-tool__current--changed');
+ $searchForm->addHTML('@' . $baseNS);
+ } else {
+ $searchForm->addHTML($lang['search_any_ns']);
+ }
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->addClass('search-tool__options-list js-optionsList');
+
+ $listItem = $searchForm->addTagOpen('li')->addClass('search-tool__options-list-item');
+ if ($baseNS) {
+ $listItem->addClass('search-tool__options-list-item--active');
+ $this->searchState->addSeachLinkNS(
+ $searchForm,
+ $lang['search_any_ns'],
+ ''
+ );
+ } else {
+ $searchForm->addHTML($lang['search_any_ns']);
+ }
+ $searchForm->addTagClose('li');
+
+ foreach ($extraNS as $ns => $count) {
+ $listItem = $searchForm->addTagOpen('li')->addClass('search-tool__options-list-item');
+ $label = $ns . ($count ? " ($count)" : '');
+
+ if ($ns === $baseNS) {
+ $listItem->addClass('search-tool__options-list-item--active');
+ $searchForm->addHTML($label);
+ } else {
$this->searchState->addSeachLinkNS(
$searchForm,
- '(remove limit)',
- ''
+ $label,
+ $ns
);
}
-
- foreach ($extraNS as $ns => $count) {
- $searchForm->addHTML(' ');
- $label = $ns . ($count ? " ($count)" : '');
-
- $this->searchState->addSeachLinkNS($searchForm, $label, $ns);
- }
- $searchForm->addTagClose('div');
+ $searchForm->addTagClose('li');
}
+ $searchForm->addTagClose('ul');
$searchForm->addTagClose('div');
+
}
/**
@@ -264,58 +374,69 @@ class Search extends Ui
*
* @param Form $searchForm
*/
- protected function addDateSelector(Form $searchForm) {
- $searchForm->addTagOpen('div')->addClass('search-results-form__subwrapper');
- $searchForm->addHTML('limit by date: ');
-
- global $INPUT;
- if ($INPUT->has('before') || $INPUT->has('after')) {
- $this->searchState->addSearchLinkTime(
- $searchForm,
- '(remove limit)',
- false,
- false
- );
-
- $searchForm->addHTML(', ');
+ protected function addDateSelector(Form $searchForm)
+ {
+ global $INPUT, $lang;
+
+ $options = [
+ 'any' => [
+ 'before' => false,
+ 'after' => false,
+ 'label' => $lang['search_any_time'],
+ ],
+ 'week' => [
+ 'before' => false,
+ 'after' => '1 week ago',
+ 'label' => $lang['search_past_7_days'],
+ ],
+ 'month' => [
+ 'before' => false,
+ 'after' => '1 month ago',
+ 'label' => $lang['search_past_month'],
+ ],
+ 'year' => [
+ 'before' => false,
+ 'after' => '1 year ago',
+ 'label' => $lang['search_past_year'],
+ ],
+ ];
+ $activeOption = 'any';
+ foreach ($options as $key => $option) {
+ if ($INPUT->str('after') === $option['after']) {
+ $activeOption = $key;
+ break;
+ }
}
- if ($INPUT->str('after') === '1 week ago') {
- $searchForm->addHTML('<span class="active">past 7 days</span>');
- } else {
- $this->searchState->addSearchLinkTime(
- $searchForm,
- 'past 7 days',
- '1 week ago',
- false
- );
+ $searchForm->addTagOpen('div')->addClass('search-tool js-search-tool');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('search-tool__current js-current');
+ if ($INPUT->has('before') || $INPUT->has('after')) {
+ $currentWrapper->addClass('search-tool__current--changed');
}
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
- $searchForm->addHTML(', ');
-
- if ($INPUT->str('after') === '1 month ago') {
- $searchForm->addHTML('<span class="active">past month</span>');
- } else {
- $this->searchState->addSearchLinkTime(
- $searchForm,
- 'past month',
- '1 month ago',
- false
- );
- }
+ // render options list
+ $searchForm->addTagOpen('ul')->addClass('search-tool__options-list js-optionsList');
- $searchForm->addHTML(', ');
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li')->addClass('search-tool__options-list-item');
- if ($INPUT->str('after') === '1 year ago') {
- $searchForm->addHTML('<span class="active">past year</span>');
- } else {
- $this->searchState->addSearchLinkTime(
- $searchForm,
- 'past year',
- '1 year ago',
- false
- );
+ if ($key === $activeOption) {
+ $listItem->addClass('search-tool__options-list-item--active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $this->searchState->addSearchLinkTime(
+ $searchForm,
+ $option['label'],
+ $option['after'],
+ $option['before']
+ );
+ }
+ $searchForm->addTagClose('li');
}
+ $searchForm->addTagClose('ul');
$searchForm->addTagClose('div');
}
@@ -416,8 +537,8 @@ class Search extends Ui
$resultHeader[] = $cnt . ' ' . $lang['hits'];
if ($num < FT_SNIPPET_NUMBER) { // create snippets for the first number of matches only
$snippet = '<dd>' . ft_snippet($id, $highlight) . '</dd>';
- $lastMod = '<span class="search_results__lastmod">'. $lang['lastmod'] . ' ';
- $lastMod .= '<time datetime="' . date_iso8601($mtime) . '">'. dformat($mtime) . '</time>';
+ $lastMod = '<span class="search_results__lastmod">' . $lang['lastmod'] . ' ';
+ $lastMod .= '<time datetime="' . date_iso8601($mtime) . '">' . dformat($mtime) . '</time>';
$lastMod .= '</span>';
}
$num++;
diff --git a/lib/scripts/search.js b/lib/scripts/search.js
index bfde5490c..9bea9d1d7 100644
--- a/lib/scripts/search.js
+++ b/lib/scripts/search.js
@@ -19,5 +19,11 @@ jQuery(function () {
$toggleAssistanceButton.click();
}
+ $searchForm.find('.js-search-tool .js-current').on('click', function() {
+ $searchForm.find('.js-current').show();
+ $searchForm.find('.js-optionsList').hide();
+ jQuery(this).hide();
+ jQuery(this).next('.js-optionsList').show();
+ });
});
diff --git a/lib/tpl/dokuwiki/css/_search.css b/lib/tpl/dokuwiki/css/_search.css
index 8da2652a2..7e9b6c20a 100644
--- a/lib/tpl/dokuwiki/css/_search.css
+++ b/lib/tpl/dokuwiki/css/_search.css
@@ -13,7 +13,7 @@
}
.search-results-form .search-results-form__fieldset {
- width: 80vw;
+ width: 80%;
}
.search-results-form__show-assistance-button {
@@ -27,6 +27,24 @@
margin-top: -0.3em;
}
+.search-tool__current {
+ cursor: pointer;
+}
+
+.search-tool__current--changed {
+ font-weight: bold;
+}
+
+.search-tool__options-list {
+ display: none;
+
+ border: 1px solid @ini_border;
+}
+
+.search-tool__options-list-item {
+ list-style: none;
+}
+
/*____________ matching pagenames ____________*/