|
1 | 1 | import Component from '@ember/component'; |
2 | 2 | import layout from './template'; |
3 | 3 | import { computed } from '@ember/object'; |
| 4 | +import { bool } from '@ember/object/computed'; |
4 | 5 |
|
5 | 6 | export default Component.extend({ |
6 | 7 | layout, |
@@ -40,48 +41,66 @@ export default Component.extend({ |
40 | 41 | matches: computed(function() { |
41 | 42 | let metadata = this.get('result.resultInfo.matchData.metadata'); |
42 | 43 |
|
43 | | - return Object.keys(metadata).reduce((matches, term) => { |
44 | | - let match = metadata[term]; |
45 | | - let query = this.get('query'); |
46 | | - let normalizedQuery = query.toLowerCase(); |
47 | | - Object.keys(match).forEach((key) => { |
48 | | - if (key === 'text') { |
49 | | - let text = this.get('result.document.text'); |
50 | | - let spaceIndices = text.split("") |
51 | | - .map((char, index) => (char === ' ') ? index : null) |
52 | | - .filter(val => val > 0); |
53 | | - |
54 | | - match.text.position.forEach(([ wordStart, length ]) => { |
55 | | - let spaceAfterWord = spaceIndices.find(i => i > wordStart); |
56 | | - let indexOfSpaceAfterWord = spaceIndices.indexOf(spaceAfterWord); |
57 | | - let indexOfSpaceBeforeWord = indexOfSpaceAfterWord - 1; |
58 | | - let indexOfStartingSpace = (indexOfSpaceBeforeWord > 3) ? indexOfSpaceBeforeWord - 3 : 0; |
59 | | - let indexOfEndingSpace = ((indexOfSpaceAfterWord + 3) < spaceIndices.length) ? indexOfSpaceAfterWord + 3 : spaceIndices.length; |
60 | | - let matchingText = text.slice(spaceIndices[indexOfStartingSpace], spaceIndices[indexOfEndingSpace]); |
61 | | - matchingText = this._highlight(matchingText, matchingText.indexOf(query), query.length); |
62 | | - |
63 | | - matches.push(matchingText); |
64 | | - }); |
65 | | - } else { |
66 | | - let normalizedTerm = term.toLowerCase(); |
67 | | - this.get('result.document.keywords').forEach((keyword) => { |
68 | | - let normalizedKeyword = keyword.toLowerCase(); |
69 | | - if (keyword.toLowerCase().indexOf(normalizedTerm) !== -1) { |
70 | | - let index = normalizedKeyword.indexOf(normalizedQuery); |
71 | | - matches.push(this._highlight(keyword, index, normalizedQuery.length)); |
72 | | - } |
73 | | - }); |
74 | | - } |
75 | | - }); |
76 | | - |
77 | | - return matches; |
78 | | - }, []) |
79 | | - .slice(0, 5) |
80 | | - .join(' · '); |
| 44 | + return Object.keys(metadata) |
| 45 | + .reduce((matches, term) => { |
| 46 | + let match = metadata[term]; |
| 47 | + let query = this.get('query'); |
| 48 | + let normalizedQuery = query.toLowerCase(); |
| 49 | + Object.keys(match).forEach((key) => { |
| 50 | + if (key === 'text') { |
| 51 | + let text = this.get('result.document.text'); |
| 52 | + let spaceIndices = text.split("") |
| 53 | + .map((char, index) => (char === ' ') ? index : null) |
| 54 | + .filter(val => val > 0); |
| 55 | + |
| 56 | + match.text.position.forEach(([ wordStart, length ]) => { |
| 57 | + let spaceAfterWord = spaceIndices.find(i => i > wordStart); |
| 58 | + let indexOfSpaceAfterWord = spaceIndices.indexOf(spaceAfterWord); |
| 59 | + let indexOfSpaceBeforeWord = indexOfSpaceAfterWord - 1; |
| 60 | + let indexOfStartingSpace = (indexOfSpaceBeforeWord > 3) ? indexOfSpaceBeforeWord - 3 : 0; |
| 61 | + let indexOfEndingSpace = ((indexOfSpaceAfterWord + 3) < spaceIndices.length) ? indexOfSpaceAfterWord + 3 : spaceIndices.length; |
| 62 | + let matchingText = text.slice(spaceIndices[indexOfStartingSpace], spaceIndices[indexOfEndingSpace]); |
| 63 | + matchingText = this._highlight(matchingText, matchingText.indexOf(query), query.length); |
| 64 | + |
| 65 | + matches.push(matchingText); |
| 66 | + }); |
| 67 | + } else { |
| 68 | + let normalizedTerm = term.toLowerCase(); |
| 69 | + this.get('result.document.keywords').forEach((keyword) => { |
| 70 | + let normalizedKeyword = keyword.toLowerCase(); |
| 71 | + if (keyword.toLowerCase().indexOf(normalizedTerm) !== -1) { |
| 72 | + let index = normalizedKeyword.indexOf(normalizedQuery); |
| 73 | + matches.push(this._highlight(keyword, index, normalizedQuery.length)); |
| 74 | + } |
| 75 | + }); |
| 76 | + } |
| 77 | + }); |
| 78 | + |
| 79 | + return matches; |
| 80 | + }, []); |
81 | 81 | }), |
82 | 82 |
|
| 83 | + bestMatch: computed('matches.[]', function() { |
| 84 | + // Right now this is arbitrarily returning the first match. Needs more work to find the "best" match on the page. |
| 85 | + return this.matches[0]; |
| 86 | + }), |
| 87 | + |
| 88 | + highlightedTitle: computed('result.document.title', 'query', function() { |
| 89 | + let title = this.result.document.title; |
| 90 | + let match = title.match(new RegExp(this.query, 'i')); |
| 91 | + |
| 92 | + if (match) { |
| 93 | + let start = match.index; |
| 94 | + let length = this.query.length; |
| 95 | + |
| 96 | + return `${title.slice(0, start)}<span class='docs-border-b-2 docs-border-brand'>${title.slice(start, start + length)}</span>${title.slice(start + length)}`; |
| 97 | + } |
| 98 | + }), |
| 99 | + |
| 100 | + titleMatchesQuery: bool('highlightedTitle'), |
| 101 | + |
83 | 102 | _highlight(text, start, length) { |
84 | | - return `${text.slice(0, start)}<em class='docs-bg-yellow'>${text.slice(start, start + length)}</em>${text.slice(start + length)}`; |
| 103 | + return `${text.slice(0, start)}<span class='docs-border-b-2 docs-border-brand'>${text.slice(start, start + length)}</span>${text.slice(start + length)}`; |
85 | 104 | }, |
86 | 105 |
|
87 | 106 | 'data-test-search-result': true, |
|
0 commit comments