diff --git a/gulpfile.js b/gulpfile.js index 0fd794cc730..e1356f90a9a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -58,9 +58,10 @@ var vendorBundles = { jquery: ['jquery'], bootstrap: ['bootstrap'], raven: ['raven-js'], + unorm: ['unorm'], }; -var vendorModules = ['jquery', 'bootstrap', 'raven-js']; -var vendorNoParseModules = ['jquery']; +var vendorModules = ['jquery', 'bootstrap', 'raven-js', 'unorm']; +var vendorNoParseModules = ['jquery', 'unorm']; // Builds the bundles containing vendor JS code gulp.task('build-vendor-js', function () { @@ -252,7 +253,7 @@ function runKarma(baseConfig, opts, done) { client: { mocha: { grep: taskArgs.grep, - } + }, }, }; diff --git a/h/assets.ini b/h/assets.ini index 2b2dac166af..4dff2b093b4 100644 --- a/h/assets.ini +++ b/h/assets.ini @@ -22,6 +22,9 @@ site_js = header_js = scripts/header.bundle.js +search_js = + scripts/unorm.bundle.js + site_css = styles/site.css styles/icomoon.css diff --git a/h/static/scripts/controllers/autosuggest-dropdown-controller.js b/h/static/scripts/controllers/autosuggest-dropdown-controller.js index 2f2b64a10d2..252a899c24a 100644 --- a/h/static/scripts/controllers/autosuggest-dropdown-controller.js +++ b/h/static/scripts/controllers/autosuggest-dropdown-controller.js @@ -84,6 +84,10 @@ class AutosuggestDropdownController extends Controller { }); this._setList(configOptions.list); + + + // Public API + this.setHeader = this._setHeader; } update(newState, prevState){ @@ -206,7 +210,7 @@ class AutosuggestDropdownController extends Controller { if (selection){ this.options.onSelect(selection); - this._toggleSuggestionsVisibility(/*show*/false); + this._filterAndToggleVisibility(); this.setState({ activeId: null, }); diff --git a/h/static/scripts/controllers/search-bar-controller.js b/h/static/scripts/controllers/search-bar-controller.js index 87360583e58..5f280b3d45d 100644 --- a/h/static/scripts/controllers/search-bar-controller.js +++ b/h/static/scripts/controllers/search-bar-controller.js @@ -1,9 +1,16 @@ 'use strict'; +var escapeHtml = require('escape-html'); + var Controller = require('../base/controller'); var LozengeController = require('./lozenge-controller'); var AutosuggestDropdownController = require('./autosuggest-dropdown-controller'); var SearchTextParser = require('../util/search-text-parser'); +var stringUtil = require('../util/string'); + +const FACET_TYPE = 'FACET'; +const TAG_TYPE = 'TAG'; +const MAX_SUGGESTIONS = 5; /** * Controller for the search bar. @@ -15,107 +22,11 @@ class SearchBarController extends Controller { this._input = this.refs.searchBarInput; this._lozengeContainer = this.refs.searchBarLozenges; - let explanationList = [ - { - title: 'user:', - explanation: 'search by username', - }, - { - title: 'tag:', - explanation: 'search for annotations with a tag', - }, - { - title: 'url:', - explanation: 'see all annotations on a page', - }, - { - title: 'group:', - explanation: 'show annotations created in a group you are a member of', - }, - ]; - - var selectFacet = facet => { - this._input.value = facet; - - setTimeout(()=>{ - this._input.focus(); - }, 0); - }; - var getTrimmedInputValue = () => { return this._input.value.trim(); }; - new AutosuggestDropdownController( this._input, { - - list: explanationList, - - header: 'Narrow your search', - - classNames: { - container: 'search-bar__dropdown-menu-container', - header: 'search-bar__dropdown-menu-header', - list: 'search-bar__dropdown-menu', - item: 'search-bar__dropdown-menu-item', - activeItem: 'js-search-bar-dropdown-menu-item--active', - }, - - renderListItem: (listItem)=>{ - - let itemContents = `
`; - - if (listItem.explanation){ - itemContents += ` `; - } - - return itemContents; - }, - - listFilter: function(list, currentInput){ - - currentInput = (currentInput || '').trim(); - - return list.filter((item)=>{ - - if (!currentInput){ - return item; - } else if (currentInput.indexOf(':') > -1) { - return false; - } - return item.title.toLowerCase().indexOf(currentInput) >= 0; - - }).sort((a,b)=>{ - - // this sort functions intention is to - // sort partial matches as lower index match - // value first. Then let natural sort of the - // original list take effect if they have equal - // index values or there is no current input value - - if (!currentInput){ - return 0; - } - - let aIndex = a.title.indexOf(currentInput); - let bIndex = b.title.indexOf(currentInput); - - if (aIndex > bIndex){ - return 1; - } else if (aIndex < bIndex){ - return -1; - } - return 0; - }); - }, - - onSelect: (itemSelected)=>{ - selectFacet(itemSelected.title); - }, - - }); - - /** * Insert a hidden with an empty value into the search