123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- import $ from "autocomplete.js/zepto";
- const utils = {
- /*
- * Move the content of an object key one level higher.
- * eg.
- * {
- * name: 'My name',
- * hierarchy: {
- * lvl0: 'Foo',
- * lvl1: 'Bar'
- * }
- * }
- * Will be converted to
- * {
- * name: 'My name',
- * lvl0: 'Foo',
- * lvl1: 'Bar'
- * }
- * @param {Object} object Main object
- * @param {String} property Main object key to move up
- * @return {Object}
- * @throws Error when key is not an attribute of Object or is not an object itself
- */
- mergeKeyWithParent(object, property) {
- if (object[property] === undefined) {
- return object;
- }
- if (typeof object[property] !== 'object') {
- return object;
- }
- const newObject = $.extend({}, object, object[property]);
- delete newObject[property];
- return newObject;
- },
- /*
- * Group all objects of a collection by the value of the specified attribute
- * If the attribute is a string, use the lowercase form.
- *
- * eg.
- * groupBy([
- * {name: 'Tim', category: 'dev'},
- * {name: 'Vincent', category: 'dev'},
- * {name: 'Ben', category: 'sales'},
- * {name: 'Jeremy', category: 'sales'},
- * {name: 'AlexS', category: 'dev'},
- * {name: 'AlexK', category: 'sales'}
- * ], 'category');
- * =>
- * {
- * 'devs': [
- * {name: 'Tim', category: 'dev'},
- * {name: 'Vincent', category: 'dev'},
- * {name: 'AlexS', category: 'dev'}
- * ],
- * 'sales': [
- * {name: 'Ben', category: 'sales'},
- * {name: 'Jeremy', category: 'sales'},
- * {name: 'AlexK', category: 'sales'}
- * ]
- * }
- * @param {array} collection Array of objects to group
- * @param {String} property The attribute on which apply the grouping
- * @return {array}
- * @throws Error when one of the element does not have the specified property
- */
- groupBy(collection, property) {
- const newCollection = {};
- $.each(collection, (index, item) => {
- if (item[property] === undefined) {
- throw new Error(`[groupBy]: Object has no key ${property}`);
- }
- let key = item[property];
- if (typeof key === 'string') {
- key = key.toLowerCase();
- }
- // fix #171 the given data type of docsearch hits might be conflict with the properties of the native Object,
- // such as the constructor, so we need to do this check.
- if (!Object.prototype.hasOwnProperty.call(newCollection, key)) {
- newCollection[key] = [];
- }
- newCollection[key].push(item);
- });
- return newCollection;
- },
- /*
- * Return an array of all the values of the specified object
- * eg.
- * values({
- * foo: 42,
- * bar: true,
- * baz: 'yep'
- * })
- * =>
- * [42, true, yep]
- * @param {object} object Object to extract values from
- * @return {array}
- */
- values(object) {
- return Object.keys(object).map(key => object[key]);
- },
- /*
- * Flattens an array
- * eg.
- * flatten([1, 2, [3, 4], [5, 6]])
- * =>
- * [1, 2, 3, 4, 5, 6]
- * @param {array} array Array to flatten
- * @return {array}
- */
- flatten(array) {
- const results = [];
- array.forEach(value => {
- if (!Array.isArray(value)) {
- results.push(value);
- return;
- }
- value.forEach(subvalue => {
- results.push(subvalue);
- });
- });
- return results;
- },
- /*
- * Flatten all values of an object into an array, marking each first element of
- * each group with a specific flag
- * eg.
- * flattenAndFlagFirst({
- * 'devs': [
- * {name: 'Tim', category: 'dev'},
- * {name: 'Vincent', category: 'dev'},
- * {name: 'AlexS', category: 'dev'}
- * ],
- * 'sales': [
- * {name: 'Ben', category: 'sales'},
- * {name: 'Jeremy', category: 'sales'},
- * {name: 'AlexK', category: 'sales'}
- * ]
- * , 'isTop');
- * =>
- * [
- * {name: 'Tim', category: 'dev', isTop: true},
- * {name: 'Vincent', category: 'dev', isTop: false},
- * {name: 'AlexS', category: 'dev', isTop: false},
- * {name: 'Ben', category: 'sales', isTop: true},
- * {name: 'Jeremy', category: 'sales', isTop: false},
- * {name: 'AlexK', category: 'sales', isTop: false}
- * ]
- * @param {object} object Object to flatten
- * @param {string} flag Flag to set to true on first element of each group
- * @return {array}
- */
- flattenAndFlagFirst(object, flag) {
- const values = this.values(object).map(collection =>
- collection.map((item, index) => {
- // eslint-disable-next-line no-param-reassign
- item[flag] = index === 0;
- return item;
- })
- );
- return this.flatten(values);
- },
- /*
- * Removes all empty strings, null, false and undefined elements array
- * eg.
- * compact([42, false, null, undefined, '', [], 'foo']);
- * =>
- * [42, [], 'foo']
- * @param {array} array Array to compact
- * @return {array}
- */
- compact(array) {
- const results = [];
- array.forEach(value => {
- if (!value) {
- return;
- }
- results.push(value);
- });
- return results;
- },
- /*
- * Returns the highlighted value of the specified key in the specified object.
- * If no highlighted value is available, will return the key value directly
- * eg.
- * getHighlightedValue({
- * _highlightResult: {
- * text: {
- * value: '<mark>foo</mark>'
- * }
- * },
- * text: 'foo'
- * }, 'text');
- * =>
- * '<mark>foo</mark>'
- * @param {object} object Hit object returned by the Algolia API
- * @param {string} property Object key to look for
- * @return {string}
- **/
- getHighlightedValue(object, property) {
- if (
- object._highlightResult &&
- object._highlightResult.hierarchy_camel &&
- object._highlightResult.hierarchy_camel[property] &&
- object._highlightResult.hierarchy_camel[property].matchLevel &&
- object._highlightResult.hierarchy_camel[property].matchLevel !== 'none' &&
- object._highlightResult.hierarchy_camel[property].value
- ) {
- return object._highlightResult.hierarchy_camel[property].value;
- }
- if (
- object._highlightResult &&
- object._highlightResult &&
- object._highlightResult[property] &&
- object._highlightResult[property].value
- ) {
- return object._highlightResult[property].value;
- }
- return object[property];
- },
- /*
- * Returns the snippeted value of the specified key in the specified object.
- * If no highlighted value is available, will return the key value directly.
- * Will add starting and ending ellipsis (…) if we detect that a sentence is
- * incomplete
- * eg.
- * getSnippetedValue({
- * _snippetResult: {
- * text: {
- * value: '<mark>This is an unfinished sentence</mark>'
- * }
- * },
- * text: 'This is an unfinished sentence'
- * }, 'text');
- * =>
- * '<mark>This is an unfinished sentence</mark>…'
- * @param {object} object Hit object returned by the Algolia API
- * @param {string} property Object key to look for
- * @return {string}
- **/
- getSnippetedValue(object, property) {
- if (
- !object._snippetResult ||
- !object._snippetResult[property] ||
- !object._snippetResult[property].value
- ) {
- return object[property];
- }
- let snippet = object._snippetResult[property].value;
- if (snippet[0] !== snippet[0].toUpperCase()) {
- snippet = `…${snippet}`;
- }
- if (['.', '!', '?'].indexOf(snippet[snippet.length - 1]) === -1) {
- snippet = `${snippet}…`;
- }
- return snippet;
- },
- /*
- * Deep clone an object.
- * Note: This will not clone functions and dates
- * @param {object} object Object to clone
- * @return {object}
- */
- deepClone(object) {
- return JSON.parse(JSON.stringify(object));
- },
- };
- export default utils;
|