Skip to content

Commit 0fa77ca

Browse files
authored
Slightly better search ui... (#324)
1 parent b12e521 commit 0fa77ca

File tree

4 files changed

+128
-54
lines changed

4 files changed

+128
-54
lines changed

addon/components/docs-header/search-result/component.js

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Component from '@ember/component';
22
import layout from './template';
33
import { computed } from '@ember/object';
4+
import { bool } from '@ember/object/computed';
45

56
export default Component.extend({
67
layout,
@@ -40,48 +41,66 @@ export default Component.extend({
4041
matches: computed(function() {
4142
let metadata = this.get('result.resultInfo.matchData.metadata');
4243

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(' &middot; ');
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+
}, []);
8181
}),
8282

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+
83102
_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)}`;
85104
},
86105

87106
'data-test-search-result': true,

addon/components/docs-header/search-result/template.hbs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,17 @@
88
<div class="docs-flex docs-items-center">
99
{{svg-jar icon height=28 width=28 class="docs-mr-2 docs-flex-no-shrink"}}
1010
<span class='docs-truncate'>
11-
{{result.document.title}}
11+
{{#if titleMatchesQuery}}
12+
{{{highlightedTitle}}}
13+
{{else}}
14+
{{result.document.title}}
15+
{{/if}}
1216
</span>
1317
</div>
14-
<small class='docs-text-grey-dark docs-inline-block'>
15-
{{{matches}}}
16-
</small>
18+
19+
{{#if (not titleMatchesQuery)}}
20+
<small class='docs-text-grey-dark docs-inline-block'>
21+
{{{bestMatch}}}
22+
</small>
23+
{{/if}}
1724
{{/link-to}}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"ember-fetch-adapter": "^0.4.3",
5454
"ember-href-to": "^1.15.1",
5555
"ember-keyboard": "^4.0.0",
56-
"ember-modal-dialog": "2.4.3",
56+
"ember-modal-dialog": "3.0.0-beta.3",
5757
"ember-responsive": "^3.0.0-beta.1",
5858
"ember-router-scroll": "^1.0.0",
5959
"ember-svg-jar": "^1.2.2",

yarn.lock

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,13 @@ babel-plugin-debug-macros@^0.2.0-beta.6:
16971697
dependencies:
16981698
semver "^5.3.0"
16991699

1700+
babel-plugin-debug-macros@^0.3.0:
1701+
version "0.3.0"
1702+
resolved "https://registry.yarnpkg.com/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.3.0.tgz#7a025944faef0777804ef3518c54e8b040197397"
1703+
integrity sha512-D6qYBI/3+FvcKVnRnH6FBUwXPp/5o/jnJNVFKqVaZpYAWx88+R8jNNyaEX7iQFs7UfCib6rcY/9+ICR4jhjFCQ==
1704+
dependencies:
1705+
semver "^5.3.0"
1706+
17001707
babel-plugin-ember-modules-api-polyfill@^2.5.0:
17011708
version "2.5.0"
17021709
resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.5.0.tgz#860aab9fecbf38c10d1fe0779c6979a854fff154"
@@ -2436,6 +2443,23 @@ broccoli-babel-transpiler@^7.1.0:
24362443
rsvp "^4.8.3"
24372444
workerpool "^2.3.1"
24382445

2446+
broccoli-babel-transpiler@^7.1.2:
2447+
version "7.1.2"
2448+
resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.1.2.tgz#fb5d6f8b9a805627ac3f2914ac9d86e82ca2413b"
2449+
integrity sha512-rljx86xgZJ2BjWt+xCSVfvyt3ONpCdMMXzMpeeVpAGdBHj3bqQICdPHZDAbzn1vKY/LIPsJZftvdxql1jiLGzw==
2450+
dependencies:
2451+
"@babel/core" "^7.0.0"
2452+
"@babel/polyfill" "^7.0.0"
2453+
broccoli-funnel "^2.0.1"
2454+
broccoli-merge-trees "^3.0.0"
2455+
broccoli-persistent-filter "^1.4.3"
2456+
clone "^2.1.2"
2457+
hash-for-dep "^1.2.3"
2458+
heimdalljs-logger "^0.1.9"
2459+
json-stable-stringify "^1.0.1"
2460+
rsvp "^4.8.3"
2461+
workerpool "^2.3.1"
2462+
24392463
broccoli-bridge@^1.0.0:
24402464
version "1.0.0"
24412465
resolved "https://registry.yarnpkg.com/broccoli-bridge/-/broccoli-bridge-1.0.0.tgz#6223fd64b62062c31333539f0f3c42d0acd92fb1"
@@ -4613,6 +4637,30 @@ ember-cli-babel@^7.1.0:
46134637
ensure-posix-path "^1.0.2"
46144638
semver "^5.5.0"
46154639

4640+
ember-cli-babel@^7.1.3:
4641+
version "7.4.3"
4642+
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.4.3.tgz#1ff35ffd54c6206d72635686f4e5bb1674c9eae5"
4643+
integrity sha512-jTAYz38q+iGXwMVTMQhYVHp//7NGJCvDOqFcn/pzozn+KU34Cvmlyi8MJBucKOA+t+khY8DSFz7jE667U993nA==
4644+
dependencies:
4645+
"@babel/core" "^7.0.0"
4646+
"@babel/plugin-transform-modules-amd" "^7.0.0"
4647+
"@babel/plugin-transform-runtime" "^7.2.0"
4648+
"@babel/polyfill" "^7.0.0"
4649+
"@babel/preset-env" "^7.0.0"
4650+
"@babel/runtime" "^7.2.0"
4651+
amd-name-resolver "^1.2.1"
4652+
babel-plugin-debug-macros "^0.3.0"
4653+
babel-plugin-ember-modules-api-polyfill "^2.6.0"
4654+
babel-plugin-module-resolver "^3.1.1"
4655+
broccoli-babel-transpiler "^7.1.2"
4656+
broccoli-debug "^0.6.4"
4657+
broccoli-funnel "^2.0.1"
4658+
broccoli-source "^1.1.0"
4659+
clone "^2.1.2"
4660+
ember-cli-version-checker "^2.1.2"
4661+
ensure-posix-path "^1.0.2"
4662+
semver "^5.5.0"
4663+
46164664
ember-cli-babel@^7.1.4:
46174665
version "7.2.0"
46184666
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.2.0.tgz#5c5bd877fb73f6fb198c878d3127ba9e18e9b8a0"
@@ -5259,7 +5307,7 @@ ember-href-to@^1.15.1:
52595307
ember-cli-babel "^6.8.2"
52605308
ember-router-service-polyfill "^1.0.2"
52615309

5262-
ember-ignore-children-helper@^1.0.0:
5310+
ember-ignore-children-helper@^1.0.1:
52635311
version "1.0.1"
52645312
resolved "https://registry.yarnpkg.com/ember-ignore-children-helper/-/ember-ignore-children-helper-1.0.1.tgz#f7c4aa17afb9c5685e1d4dcdb61c7b138ca7cdc3"
52655313
integrity sha512-AgKkrvd1/hIBWdLn42gITlweVsALUGPYF9fMpQ2IDqp7QnRmtO8ocRbZEmMddPDWY9Xu7W5qO2f35rbD7OSpYw==
@@ -5319,16 +5367,16 @@ ember-maybe-import-regenerator@^0.1.5:
53195367
ember-cli-babel "^6.0.0-beta.4"
53205368
regenerator-runtime "^0.9.5"
53215369

5322-
ember-modal-dialog@2.4.3:
5323-
version "2.4.3"
5324-
resolved "https://registry.yarnpkg.com/ember-modal-dialog/-/ember-modal-dialog-2.4.3.tgz#8e254185e95dae6ccf46987822a095acf42561b1"
5325-
integrity sha1-jiVBheldrmzPRph4IqCVrPQlYbE=
5370+
ember-modal-dialog@3.0.0-beta.3:
5371+
version "3.0.0-beta.3"
5372+
resolved "https://registry.yarnpkg.com/ember-modal-dialog/-/ember-modal-dialog-3.0.0-beta.3.tgz#8ba00c1a228d62d837f63dc7ce964e48f25d1326"
5373+
integrity sha512-R9vo3KftPmNJK89rIipKvoTEvTC3tMEtM4Yhy2gyMX3yrFCcNPlnTXTRyTePUtSVxPNq9lNT1n0YWMBT1xoJxg==
53265374
dependencies:
5327-
ember-cli-babel "^6.8.2"
5328-
ember-cli-htmlbars "^2.0.1"
5375+
ember-cli-babel "^7.1.3"
5376+
ember-cli-htmlbars "^3.0.0"
53295377
ember-cli-version-checker "^2.1.0"
5330-
ember-ignore-children-helper "^1.0.0"
5331-
ember-wormhole "^0.5.1"
5378+
ember-ignore-children-helper "^1.0.1"
5379+
ember-wormhole "^0.5.5"
53325380

53335381
ember-native-dom-helpers@^0.5.3:
53345382
version "0.5.10"
@@ -5516,7 +5564,7 @@ ember-try@^1.0.0:
55165564
rsvp "^4.7.0"
55175565
walk-sync "^0.3.3"
55185566

5519-
ember-wormhole@^0.5.1:
5567+
ember-wormhole@^0.5.5:
55205568
version "0.5.5"
55215569
resolved "https://registry.yarnpkg.com/ember-wormhole/-/ember-wormhole-0.5.5.tgz#db417ff748cb21e574cd5f233889897bc27096cb"
55225570
integrity sha512-z8l3gpoKmRA2BnTwvnYRk4jKVcETKHpddsD6kpS+EJ4EfyugadFS3zUqBmRDuJhFbNP8BVBLXlbbATj+Rk1Kgg==

0 commit comments

Comments
 (0)