11import Service from '@ember/service' ;
22import { getOwner } from '@ember/application' ;
33import { computed } from '@ember/object' ;
4+ import { resolve } from 'rsvp' ;
45import $ from 'jquery' ;
56import lunr from 'lunr' ;
67
7- export default Service . extend ( {
8- search ( phrase , { exact = false } = { } ) {
9- if ( ! exact ) {
10- phrase = `*${ phrase } *` ;
11- }
8+ const { Index, Query } = lunr ;
129
10+ export default Service . extend ( {
11+ search ( phrase ) {
1312 return this . loadSearchIndex ( )
1413 . then ( ( { index, documents } ) => {
15- return index . search ( phrase ) . map ( resultInfo => {
14+ let words = phrase . split ( / \s + / ) ;
15+ let results = index . query ( ( query ) => {
16+ // In the future we could boost results based on the field they come from
17+ for ( let word of words ) {
18+ query . term ( index . pipeline . runString ( word ) [ 0 ] , {
19+ wildcard : Query . wildcard . LEADING | Query . wildcard . TRAILING
20+ } ) ;
21+ }
22+ } )
23+
24+ return results . map ( resultInfo => {
1625 let document = documents [ resultInfo . ref ] ;
1726 return { resultInfo, document } ;
1827 } ) ;
1928 } ) ;
2029 } ,
2130
31+ // temporary; just useful for tuning search config for now
32+ searchAndLog ( phrase ) {
33+ /* eslint-disable no-console */
34+ this . search ( phrase )
35+ . then ( results => {
36+ console . group ( `Search For '${ phrase } '` ) ;
37+ for ( let result of results ) {
38+ let doc = result . document ;
39+ if ( doc . type === 'class' ) {
40+ console . groupCollapsed ( `Class: %c${ doc . title } ` , 'font-family: monospace' ) ;
41+ for ( let match of Object . values ( result . resultInfo . matchData . metadata ) ) {
42+ for ( let [ key , data ] of Object . entries ( match ) ) {
43+ if ( key === 'keywords' ) {
44+ for ( let position of data . position ) {
45+ console . log ( `%c${ extractKeyword ( doc . keywords , position ) } %c(field)` , 'font-family: monospace' , 'font-family: inherit' ) ;
46+ }
47+ } else {
48+ for ( let position of data . position ) {
49+ logSnippet ( doc , key , position ) ;
50+ }
51+ }
52+ }
53+ }
54+ console . groupEnd ( ) ;
55+ } else if ( doc . type === 'template' ) {
56+ console . groupCollapsed ( `Route: %c${ doc . route } ` , 'font-family: monospace' ) ;
57+ for ( let match of Object . values ( result . resultInfo . matchData . metadata ) ) {
58+ for ( let [ key , data ] of Object . entries ( match ) ) {
59+ for ( let position of data . position ) {
60+ logSnippet ( doc , key , position ) ;
61+ }
62+ }
63+ }
64+ console . groupEnd ( ) ;
65+ }
66+ }
67+ console . groupEnd ( ) ;
68+ } ) ;
69+ /* eslint-enable */
70+ } ,
71+
2272 loadSearchIndex ( ) {
2373 if ( ! this . _searchIndex ) {
24- this . _searchIndex = $ . get ( this . get ( '_indexURL' ) )
74+ this . _searchIndex = resolve ( $ . get ( this . get ( '_indexURL' ) ) )
2575 . then ( json => {
2676 return {
27- index : lunr . Index . load ( json . index ) ,
77+ index : Index . load ( json . index ) ,
2878 documents : json . documents
2979 } ;
3080 } ) ;
@@ -38,3 +88,23 @@ export default Service.extend({
3888 return `${ config . rootURL } ember-cli-addon-docs/search-index.json` ;
3989 } )
4090} ) ;
91+
92+ function extractKeyword ( keywords , position ) {
93+ let start = keywords . lastIndexOf ( '\0' , position [ 0 ] ) ;
94+ start = start === - 1 ? 0 : start ;
95+ let end = keywords . indexOf ( '\0' , position [ 0 ] + position [ 1 ] ) ;
96+ end = end === - 1 ? keywords . length : end ;
97+ return keywords . slice ( start , end - start ) ;
98+ }
99+
100+ function logSnippet ( doc , key , position ) {
101+ let field = doc [ key ] ;
102+ if ( ! field ) { return ; }
103+
104+ let start = Math . max ( position [ 0 ] - 15 , 0 ) ;
105+ let end = Math . min ( position [ 0 ] + position [ 1 ] + 15 , field . length ) ;
106+ let pre = `${ start === 0 ? '' : '...' } ${ field . slice ( start , position [ 0 ] ) } ` ;
107+ let snippet = field . slice ( position [ 0 ] , position [ 0 ] + position [ 1 ] ) ;
108+ let post = `${ field . slice ( position [ 0 ] + position [ 1 ] , end ) } ${ end === field . length ? '' : '...' } ` ;
109+ console . log ( `${ pre } %c${ snippet } %c${ post } (${ key } )` , 'font-weight: bold' , 'font-weight: regular' ) ; // eslint-disable-line no-console
110+ }
0 commit comments