From f5528f0d44dc9cabfec63701418916486632bdb3 Mon Sep 17 00:00:00 2001 From: Greg Ichneumon Brown Date: Wed, 25 Sep 2019 21:43:25 +0000 Subject: [PATCH 1/7] Inserting search results into multiple themes working --- .../components/search-widget.jsx | 8 +-- modules/search/instant-search/index.jsx | 2 + modules/search/instant-search/lib/dom.js | 54 +++++++++++++++++-- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/modules/search/instant-search/components/search-widget.jsx b/modules/search/instant-search/components/search-widget.jsx index e2412e335ed9d..ae2ba7556f341 100644 --- a/modules/search/instant-search/components/search-widget.jsx +++ b/modules/search/instant-search/components/search-widget.jsx @@ -17,7 +17,7 @@ import SearchResults from './search-results'; import SearchFiltersWidget from './search-filters-widget'; import { search, buildFilterAggregations } from '../lib/api'; import { setSearchQuery, setFilterQuery, getFilterQuery } from '../lib/query-string'; -import { removeChildren, hideSearchHeader } from '../lib/dom'; +import { removeChildren, hideElements } from '../lib/dom'; class SearchApp extends Component { constructor() { @@ -40,8 +40,8 @@ class SearchApp extends Component { this.input.current.focus(); } - hideSearchHeader(); - removeChildren( document.querySelector( 'main' ) ); + hideElements( this.props.themeOptions.elem_selectors ); + removeChildren( document.querySelector( this.props.themeOptions.results_selector ) ); this.props.widgets.forEach( function( widget ) { removeChildren( document.getElementById( widget.widget_id ) ); } ); @@ -117,7 +117,7 @@ class SearchApp extends Component { ) ) } - + { render( @@ -18,6 +19,7 @@ const injectSearchWidget = grabFocus => { initialFilters={ getFilterQuery() } initialValue={ getSearchQuery() } options={ window.JetpackInstantSearchOptions } + themeOptions={ getThemeOptions( window.JetpackInstantSearchOptions ) } />, document.body ); diff --git a/modules/search/instant-search/lib/dom.js b/modules/search/instant-search/lib/dom.js index 5008236a771df..501e9ac16cd68 100644 --- a/modules/search/instant-search/lib/dom.js +++ b/modules/search/instant-search/lib/dom.js @@ -4,10 +4,13 @@ export function removeChildren( htmlElement ) { } } -export function hideSearchHeader() { - const title = document.querySelector( '#content .page-title' ); - if ( title ) { - title.style.display = 'none'; +export function hideElements( elem_selectors ) { + let elem = null; + for ( let i = 0; i < elem_selectors.length; i++ ) { + elem = document.querySelector( elem_selectors[ i ] ); + if ( elem ) { + elem.style.display = 'none'; + } } } @@ -16,3 +19,46 @@ export function getCheckedInputNames( parentDom ) { .filter( input => input.checked ) .map( input => input.name ); } + +export function getThemeOptions( searchOptions ) { + //the order here matters + const result_selectors = [ + //2015, 2016, 2017, 2019, argent, astra, storefront + 'main', + //2010, 2011, 2012, 2013, 2014 + '#content', + //colormag, shapely, sydney, zerif lite + '#primary', + //hemingway + '.content', + ]; + + const potential_removals = [ '#content .page-title', 'section.ast-archive-description' ]; + + let options = { + results_selector: null, + elem_selectors: [], + }; + + //sample the dom to try and find a location to mount results + for ( let i = 0; i < result_selectors.length; i++ ) { + if ( document.querySelector( result_selectors[ i ] ) ) { + options.results_selector = result_selectors[ i ]; + break; + } + } + + //look for elements we should remove + for ( let i = 0; i < potential_removals.length; i++ ) { + if ( document.querySelector( potential_removals[ i ] ) ) { + options.elem_selectors.push( potential_removals[ i ] ); + } + } + + if ( searchOptions.theme_options ) { + //apply overrides from user filters + options = { ...options, ...searchOptions.theme_options }; + } + + return options; +} From e9711a38be8afa2257a4e21024dbbd5ca4f0a61b Mon Sep 17 00:00:00 2001 From: Greg Ichneumon Brown Date: Thu, 26 Sep 2019 22:10:56 +0000 Subject: [PATCH 2/7] Get search boxes working in 2013 and improve css and styling. --- .../components/gridicon/index.jsx | 7 +++ .../instant-search/components/search-box.jsx | 36 ++++++++++++ .../instant-search/components/search-box.scss | 2 + .../components/search-results.jsx | 19 ++++--- .../components/search-results.scss | 11 +--- .../components/search-widget.jsx | 57 +++++++++++++------ modules/search/instant-search/index.jsx | 8 +-- .../search/instant-search/instant-search.scss | 1 + modules/search/instant-search/lib/dom.js | 7 ++- 9 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 modules/search/instant-search/components/search-box.jsx create mode 100644 modules/search/instant-search/components/search-box.scss diff --git a/modules/search/instant-search/components/gridicon/index.jsx b/modules/search/instant-search/components/gridicon/index.jsx index 6064300862dfd..795f048324181 100644 --- a/modules/search/instant-search/components/gridicon/index.jsx +++ b/modules/search/instant-search/components/gridicon/index.jsx @@ -143,6 +143,7 @@ class Gridicon extends Component { return { __( 'Has multiple images' ) }; case 'gridicons-image': return { __( 'Has an image' ) }; + case 'gridicons-jetpack-search': case 'gridicons-search': return { __( 'Search' ) }; case 'gridicons-tag': @@ -324,6 +325,12 @@ class Gridicon extends Component { ); + case 'gridicons-jetpack-search': + return ( + + + + ); case 'gridicons-star-outline': return ( diff --git a/modules/search/instant-search/components/search-box.jsx b/modules/search/instant-search/components/search-box.jsx new file mode 100644 index 0000000000000..b9e16a09a74fa --- /dev/null +++ b/modules/search/instant-search/components/search-box.jsx @@ -0,0 +1,36 @@ +/** @jsx h */ + +/** + * External dependencies + */ +import { h, Component } from 'preact'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import Gridicon from './gridicon'; + +class SearchBox extends Component { + render() { + const { query, onChangeQuery, appRef, showIcon = false } = this.props; + + return ( + + ); + } +} + +export default SearchBox; diff --git a/modules/search/instant-search/components/search-box.scss b/modules/search/instant-search/components/search-box.scss new file mode 100644 index 0000000000000..f5cc75c20b96e --- /dev/null +++ b/modules/search/instant-search/components/search-box.scss @@ -0,0 +1,2 @@ +label.jp-instant-search__box input:focus { +} diff --git a/modules/search/instant-search/components/search-results.jsx b/modules/search/instant-search/components/search-results.jsx index 61f57c077a792..c4999743da7d5 100644 --- a/modules/search/instant-search/components/search-results.jsx +++ b/modules/search/instant-search/components/search-results.jsx @@ -3,7 +3,7 @@ /** * External dependencies */ -import { __, sprintf } from '@wordpress/i18n'; +import { __, _n, sprintf } from '@wordpress/i18n'; import { h, Component } from 'preact'; /** @@ -23,7 +23,7 @@ class SearchResults extends Component { } render() { - const { results = [], query, total = 0, corrected_query = false } = this.props; + const { results = [], query, total = 0, corrected_query = false, loading = false } = this.props; if ( query === '' ) { return
; } @@ -36,16 +36,19 @@ class SearchResults extends Component {
); } + const num = new Intl.NumberFormat().format( total ); + const style = loading ? { opacity: 0.2 } : { opacity: 1 }; return ( -
- - { sprintf( __( '%d Results' ), total ) } - +

{ corrected_query !== false - ? sprintf( __( 'Showing results for "%s"' ), corrected_query ) - : sprintf( __( 'Results for "%s"' ), query ) } + ? sprintf( + _n( 'Showing %s result for "%s"', 'Showing %s results for "%s"', total ), + num, + corrected_query + ) + : sprintf( _n( '%s results for "%s"', '%s results for "%s"', total ), num, query ) }

{ corrected_query !== false && (

diff --git a/modules/search/instant-search/components/search-results.scss b/modules/search/instant-search/components/search-results.scss index 1a1b621e8d4fe..c2a4a60c29323 100644 --- a/modules/search/instant-search/components/search-results.scss +++ b/modules/search/instant-search/components/search-results.scss @@ -1,13 +1,8 @@ .jetpack-instant-search__search-results { - padding: 0.125em 0; - margin: 1em 0; + padding: 0.125em 2em; + margin: 1em auto; position: relative; -} - -.jetpack-instant-search__search-results-count { - float: right; - margin-left: 0.5em; - display: block; + max-width: 1080px; } .jetpack-instant-search__search-results-real-query { diff --git a/modules/search/instant-search/components/search-widget.jsx b/modules/search/instant-search/components/search-widget.jsx index ae2ba7556f341..99cfb8b61bf66 100644 --- a/modules/search/instant-search/components/search-widget.jsx +++ b/modules/search/instant-search/components/search-widget.jsx @@ -15,6 +15,7 @@ import debounce from 'lodash/debounce'; */ import SearchResults from './search-results'; import SearchFiltersWidget from './search-filters-widget'; +import SearchBox from './search-box'; import { search, buildFilterAggregations } from '../lib/api'; import { setSearchQuery, setFilterQuery, getFilterQuery } from '../lib/query-string'; import { removeChildren, hideElements } from '../lib/dom'; @@ -30,8 +31,9 @@ class SearchApp extends Component { this.state = { query: this.props.initialValue, results: {}, + loading: false, }; - this.getResults = debounce( this.getResults, 500 ); + this.getResults = debounce( this.getResults, 200 ); this.getResults( this.state.query, getFilterQuery() ); } @@ -45,6 +47,10 @@ class SearchApp extends Component { this.props.widgets.forEach( function( widget ) { removeChildren( document.getElementById( widget.widget_id ) ); } ); + const searchForms = document.querySelectorAll( this.props.themeOptions.search_form_selector ); + searchForms.forEach( function( elem ) { + removeChildren( elem ); + } ); } onChangeQuery = event => { @@ -64,6 +70,9 @@ class SearchApp extends Component { this.requestId++; const requestId = this.requestId; + this.setState( { + loading: true, + } ); search( { aggregations: this.props.aggregations, filter, @@ -74,41 +83,43 @@ class SearchApp extends Component { .then( response => response.json() ) .then( json => { if ( this.requestId === requestId ) { - this.setState( { results: json } ); + this.setState( { + results: json, + loading: false, + } ); } } ); } else { - this.setState( { results: [] } ); + this.setState( { + results: [], + loading: false, + } ); } }; render() { const { query, results } = this.state; + const searchForms = Array.from( + document.querySelectorAll( this.props.themeOptions.search_form_selector ) + ); return ( - { this.props.widgets.map( ( widget, index ) => ( + { this.props.widgets.map( widget => (

- { /* TODO: Add support for preserving label text */ } - -
) ) } + { searchForms && + searchForms.map( elem => ( + + + + ) ) } + diff --git a/modules/search/instant-search/index.jsx b/modules/search/instant-search/index.jsx index 77d10b1832e66..9dcb9ac116394 100644 --- a/modules/search/instant-search/index.jsx +++ b/modules/search/instant-search/index.jsx @@ -8,13 +8,13 @@ import { h, render } from 'preact'; /** * Internal dependencies */ -import SearchWidget from './components/search-widget'; +import SearchApp from './components/search-widget'; import { getSearchQuery, getFilterQuery } from './lib/query-string'; import { getThemeOptions } from './lib/dom'; -const injectSearchWidget = grabFocus => { +const injectSearchApp = grabFocus => { render( - Date: Fri, 27 Sep 2019 18:31:43 +0000 Subject: [PATCH 3/7] Rename search-widget to search-app --- .../components/{search-widget.jsx => search-app.jsx} | 0 modules/search/instant-search/index.jsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename modules/search/instant-search/components/{search-widget.jsx => search-app.jsx} (100%) diff --git a/modules/search/instant-search/components/search-widget.jsx b/modules/search/instant-search/components/search-app.jsx similarity index 100% rename from modules/search/instant-search/components/search-widget.jsx rename to modules/search/instant-search/components/search-app.jsx diff --git a/modules/search/instant-search/index.jsx b/modules/search/instant-search/index.jsx index 9dcb9ac116394..c8491cf94fad7 100644 --- a/modules/search/instant-search/index.jsx +++ b/modules/search/instant-search/index.jsx @@ -8,7 +8,7 @@ import { h, render } from 'preact'; /** * Internal dependencies */ -import SearchApp from './components/search-widget'; +import SearchApp from './components/search-app'; import { getSearchQuery, getFilterQuery } from './lib/query-string'; import { getThemeOptions } from './lib/dom'; From 6e2019f7d5b54d6c6b0fde6363c046e8b35d52f2 Mon Sep 17 00:00:00 2001 From: Greg Ichneumon Brown Date: Fri, 27 Sep 2019 21:53:19 +0000 Subject: [PATCH 4/7] Get search box working with twentyten --- .../instant-search/components/search-app.jsx | 28 +++++++++++++++---- .../instant-search/components/search-box.jsx | 13 +++------ .../instant-search/components/search-box.scss | 14 ++++++++++ .../components/search-filters-widget.jsx | 4 ++- modules/search/instant-search/lib/dom.js | 3 +- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/modules/search/instant-search/components/search-app.jsx b/modules/search/instant-search/components/search-app.jsx index 99cfb8b61bf66..77c1ab841f076 100644 --- a/modules/search/instant-search/components/search-app.jsx +++ b/modules/search/instant-search/components/search-app.jsx @@ -47,7 +47,10 @@ class SearchApp extends Component { this.props.widgets.forEach( function( widget ) { removeChildren( document.getElementById( widget.widget_id ) ); } ); - const searchForms = document.querySelectorAll( this.props.themeOptions.search_form_selector ); + const searchForms = [ + ...document.querySelectorAll( this.props.themeOptions.search_form_icon ), + ...document.querySelectorAll( this.props.themeOptions.search_form_no_icon ), + ]; searchForms.forEach( function( elem ) { removeChildren( elem ); } ); @@ -99,8 +102,11 @@ class SearchApp extends Component { render() { const { query, results } = this.state; - const searchForms = Array.from( - document.querySelectorAll( this.props.themeOptions.search_form_selector ) + const searchFormsIcon = Array.from( + document.querySelectorAll( this.props.themeOptions.search_form_icon ) + ); + const searchFormsNoIcon = Array.from( + document.querySelectorAll( this.props.themeOptions.search_form_no_icon ) ); return ( @@ -128,13 +134,25 @@ class SearchApp extends Component { ) ) } - { searchForms && - searchForms.map( elem => ( + { searchFormsIcon && + searchFormsIcon.map( elem => ( + + + + ) ) } + { searchFormsNoIcon && + searchFormsNoIcon.map( elem => ( ) ) } diff --git a/modules/search/instant-search/components/search-box.jsx b/modules/search/instant-search/components/search-box.jsx index b9e16a09a74fa..1c45db0701bbc 100644 --- a/modules/search/instant-search/components/search-box.jsx +++ b/modules/search/instant-search/components/search-box.jsx @@ -6,20 +6,15 @@ import { h, Component } from 'preact'; import { __ } from '@wordpress/i18n'; -/** - * Internal dependencies - */ -import Gridicon from './gridicon'; - class SearchBox extends Component { render() { - const { query, onChangeQuery, appRef, showIcon = false } = this.props; + const { query, onChangeQuery, appRef, showIcon } = this.props; + const cls = showIcon ? 'jp-instant-search__box-svg' : 'jp-instant-search__box'; return ( -