pebble/devsite/source/assets/js/search.js
2025-02-24 18:58:29 -08:00

148 lines
3.9 KiB
JavaScript

/**
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* export SearchResults */
/* export Search */
function SearchResults(results, type, limit) {
this.results = results;
this.type = type;
this.limit = limit;
};
SearchResults.prototype.render = function($container) {
this.results.hits.splice(this.limit, this.results.hits.length);
this.results.hits.forEach(processResult.bind(this));
var $resultGroup = $(Handlebars.templates['quicksearch-result-group']({
title: this.type.title,
results: this.results.hits
}));
$container.append($resultGroup);
};
function processResult(result) {
if (result._snippetResult && result._snippetResult.content) {
result.summary = result._snippetResult.content.value;
}
else if (result._snippetResult && result._snippetResult.summary) {
result.summary = result._snippetResult.summary.value;
}
if (this.type.section) {
result.section = this.type.section(result).join(' · ');
}
else {
result.section = '';
}
}
function Search(config) {
this.client = new AlgoliaSearch(config.appId, config.apiKey);
this.prefix = config.prefix;
this.searchNumber = 0;
this.lastQuery = null;
this.searchOptions = config.options;
}
heir.inherit(Search, EventEmitter);
Search.indexes = {
'guides': {
title: 'Guides',
cssClass: 'guides',
section: function (hit) {
var section = [ hit.group ];
if (hit.subgroup && hit.subgroup.length) {
section.push(hit.subgroup);
}
return section;
}
},
'documentation': {
title: 'Documentation',
cssClass: 'docs',
section: function (hit) {
return [ hit.language ]
}
},
'blog-posts': {
title: 'Blog Posts',
cssClass: 'more',
section: function (hit) {
var dateString = hit.posted.split(" ")[0];
if (!dateString) return "Invalid Date";
return [ moment(dateString).format('MMM DD YYYY')];
}
},
'examples': {
title: 'Examples',
cssClass: 'more',
},
'community-resources': {
title: 'Community Resources',
cssClass: 'community',
section: function (hit) {
switch(hit.resourceType) {
case 'community_tools':
return ['Tool'];
case 'community_apps':
return ['App'];
case 'community_libraries':
return ['Library']
}
return [];
}
},
'other': {
title: 'Other',
cssClass: 'other'
}
};
Search.prototype.search = function (query) {
if (query === this.lastQuery) {
return;
}
if (query.length <= 2) {
this.emitEvent('clear');
return;
}
this.searchNumber += 1;
var thisNumber = this.searchNumber;
this.client.startQueriesBatch();
Object.keys(Search.indexes).forEach(function (type) {
this.client.addQueryInBatch(this.prefix + type, query, this.searchOptions);
}.bind(this));
this.client.sendQueriesBatch(function (success, content) {
if (thisNumber !== this.searchNumber) {
return;
}
if (! success) {
this.emitEvent('error', new Error('Algolia responded with a failure event.'));
}
if (! content.results) {
this.emitEvent('error', new Error('No results returned from Algolia.'));
}
var results = {};
content.results.forEach(function (result) {
if (result.hits.length > 0) {
var index = result.index.replace(this.prefix, '');
results[index] = result;
}
}.bind(this));
this.emitEvent('results', [ results ]);
}.bind(this));
};