123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- (function($) {
- var Search = {
- /**
- * Kick-off the query
- *
- * @since 2.0
- * @param {Object} query The query
- * @return {Object} The response
- */
- query: function( query ) {
- var data = {},
- kind = null,
- results = {
- library: {}
- },
- foundItems = null;
- query = this.normalizeQuery(query);
- // Reduce data by kind
- if ( !_.isNull( query.kind ) ) {
- for( var i in query.kind ) {
- kind = query.kind[ i ];
- data[ kind ] = FLBuilderConfig.contentItems[ kind ];
- }
- } else {
- data = FLBuilderConfig.contentItems;
- }
- foundItems = this.findMatches( query, data );
- results.library = this.formatResults( foundItems, query );
- return results;
- },
- /**
- * Make sure the query object is well-formed.
- *
- * @since 2.0
- * @param {Object} query The query
- * @return {Object} The query
- */
- normalizeQuery: function( query ) {
- var defaultQuery = {
- kind: null,
- type: null,
- category: null,
- group: null,
- enabled: true, /* pertains only to modules */
- global: null, /* pertains only to user row and module templates */
- searchTerm: null,
- categorized: false,
- };
- query = _.extend(defaultQuery, query);
- if ( _.isString( query.kind ) ) {
- query.kind = [ query.kind ];
- }
- return query;
- },
- /**
- * Find the objects in the dataset that match query criteria.
- *
- * @since 2.0
- * @param {Object} query
- * @param {Object} data
- * @return {Object}
- */
- findMatches: function( query, data ) {
- var foundItems = {},
- typeName = null,
- objects = null,
- object = null,
- inArray = null,
- matches = null,
- i = null;
- for ( typeName in data ) {
- objects = data[ typeName ];
- foundItems[ typeName ] = {
- items: []
- };
- for ( i in objects ) {
- object = objects[i];
- // Test for category matches.
- if ( ! _.isUndefined( query.category ) && ! _.isNull( query.category ) ) {
- if ( ! this.matchesCategory( object.category, query.category ) ) {
- continue;
- }
- }
- switch ( typeName ) {
- case 'template':
- // Content type - module | row | layout
- if ( ! _.isUndefined( query.content ) && ! _.isNull( query.content ) ) {
- inArray = _.includes( query.content, object.content );
- matches = query.content === object.content;
- if ( ! inArray && ! matches) {
- continue;
- }
- }
- // Text type matches - core | user
- if ( ! _.isUndefined( query.type ) && ! _.isNull( query.type ) ) {
- if ( query.type !== object.type ) {
- continue;
- }
- }
- if ( !_.isNull( query.group ) ) {
- var queryGroup = query.group,
- objectGroup = object.group;
- // Normalize group into arrays
- if ( _.isString( queryGroup) ) {
- queryGroup = [ queryGroup ];
- }
- if ( _.isString( objectGroup) ) {
- objectGroup = [ objectGroup ];
- }
- if ( _.isEmpty( queryGroup ) || _.isEmpty( objectGroup ) ) {
- continue;
- }
- var hasGroup = false;
- for( i in queryGroup ) {
- var group = queryGroup[i];
- if ( _.includes( objectGroup, group ) ) {
- hasGroup = true;
- }
- }
- if ( !hasGroup ) {
- continue;
- }
- }
- break;
- case 'module':
- if ( ! _.isNull( query.group ) ) {
- if ( query.group === false && object.group.length > 0 ) {
- continue;
- }
- if ( query.group !== false && ! _.includes( object.group, query.group ) ) {
- continue;
- }
- }
- break;
- }
- if ( ! _.isUndefined( query.searchTerm ) && ! _.isNull( query.searchTerm ) ) {
- if ( ! this.matchesSearchTerm( object, query.searchTerm ) ) {
- continue;
- }
- }
- foundItems[ typeName ].items.push( object );
- }
- }
- return foundItems;
- },
- /**
- * @since 2.0
- * @param {Object} objectCat
- * @param {Object} queryCats
- * @return {Boolean}
- */
- matchesCategory: function( objectCat, queryCats ) {
- var queryCat, i, j, cat, key, value;
- if ( objectCat === queryCats ) {
- return true;
- }
- if ( _.isString( queryCats ) ) {
- queryCats = [queryCats];
- }
- // Loop over multipe query categories
- for ( i in queryCats ) {
- queryCat = queryCats[ i ];
- if ( _.isString( objectCat ) && objectCat === queryCat ) {
- return true;
- }
- if ( _.isArray( objectCat ) ) {
- for ( j in objectCat ) {
- cat = objectCat[ j ];
- if ( cat === queryCat ) {
- return true;
- }
- }
- }
- if ( _.isObject( objectCat ) ) {
- for ( key in objectCat ) {
- value = objectCat[ key ];
- if ( value === queryCat || key === queryCat ) {
- return true;
- }
- }
- }
- }
- return false;
- },
- /**
- * @since 2.0
- * @param {Object} obj
- * @param {String} term
- * @return {Boolean}
- */
- matchesSearchTerm: function( obj, term ) {
- var widgetLowercase,
- moduleWordLowercase,
- termLowercase = term.toLowerCase();
- // Match Slug
- if ( !_.isUndefined( obj.slug ) && obj.slug.toLowerCase().includes( termLowercase ) ) {
- return true;
- }
- // Match Name
- if ( !_.isUndefined( obj.name ) && obj.name.toLowerCase().includes( termLowercase ) ) {
- return true;
- }
- // Match Category
- if ( _.isString(obj.category) && obj.category.toLowerCase().includes( termLowercase ) ) {
- return true;
- }
- // Match Description
- if ( !_.isUndefined( obj.description ) && obj.description.toLowerCase().includes( termLowercase ) ) {
- return true;
- }
- // Match Widget Base ID (slug equivalent)
- if ( !_.isUndefined( obj.id_base ) && obj.id_base.includes(term)) {
- return true;
- }
- // If term matches "Widget" or "widget"
- if ( obj.isWidget ) {
- widgetLowercase = "widget";
- if ( widgetLowercase.includes( termLowercase ) ) {
- return true;
- }
- }
- // if term matches "Module" or "module"
- if ( !_.isUndefined( obj.editor_export ) ) {
- moduleWordLowercase = "module";
- if ( moduleWordLowercase.includes( termLowercase ) ) {
- return true;
- }
- }
- return false;
- },
- /**
- * @since 2.0
- * @param {Object} foundItems
- * @param {Object} query
- * @return {Object}
- */
- formatResults: function(foundItems, query) {
- if (query.categorized) {
- for( type in foundItems) {
- var items = foundItems[type].items;
- foundItems[type].categorized = this.groupBy(items, 'category');
- }
- }
- return foundItems;
- },
- /**
- * @since 2.0
- * @param {Object} items
- * @param {String} propertyName
- * @return {Object}
- */
- groupBy: function(items, propertyName) {
- var groups = {}, propertyValue, propertyValues;
- _.forEach(items, function(item, i, list) {
- propertyValue = item[propertyName];
- if ( _.isNull(propertyValue) || _.isUndefined(propertyValue) ) { return; }
- if ( _.isString(propertyValue) && item[propertyValue] === "") { return; }
- // Group item by single category
- if (_.isString(propertyValue)) {
- groups[propertyValue] = groups[propertyValue] || [];
- groups[propertyValue].push(item);
- }
- // Group item into each category in an array
- if (_.isArray(propertyValue)) {
- propertyValues = propertyValue;
- _.forEach(propertyValues, function(prop, j, list) {
- groups[prop] = groups[prop] || [];
- groups[prop].push(item);
- });
- }
- // Group item into each value of a hash.
- if (_.isObject(propertyValue)) {
- propertyValues = propertyValue;
- _.forEach(propertyValues, function(value, key, list) {
- groups[value] = groups[value] || [];
- groups[value].push(item);
- });
- }
- });
- // if any group only contains blank, lose it.
- return groups;
- },
- /**
- * @since 2.0
- * @param String The search term
- * @return {Object} The response
- */
- search: function(term) {
- var query = {
- searchTerm: term
- }
- var raw = this.query(query),
- response = {
- total: 0,
- term: term,
- sections: {}
- };
- if ( !_.isUndefined(raw.library.module.items) ) {
- var categorized = {};
- for(var i in raw.library.module.items) {
- var item = raw.library.module.items[i],
- group = item.group[0],
- cat = item.category,
- name = item.name;
- if ( _.isUndefined(categorized[group]) ) {
- categorized[group] = {};
- }
- if ( _.isUndefined(categorized[group][cat]) ) {
- categorized[group][cat] = [];
- }
- categorized[group][cat].push(item);
- }
- response.grouped = categorized;
- }
- for( var i in raw.library) {
- var type = raw.library[i];
- if ( !_.isUndefined(type.items) && type.items.length > 0) {
- response.sections[i] = {
- name: FLBuilderStrings.typeLabels[i],
- handle: i,
- type: "",
- items: type.items
- };
- response.total += type.items.length;
- }
- }
- return response;
- }
- }
- /**
- * Public Interface
- */
- FLBuilder.Search = {
- /**
- * Find items that match query object
- *
- * @since 2.0
- * @param {Object} query The query
- * @return {Object} The response
- */
- byQuery: function(query) {
- return Search.query(query);
- },
- /**
- * Find items by search term
- *
- * @since 2.0
- * @param String term
- * @return {Object} The response
- */
- byTerm: function(term) {
- var response = Search.search(term);
- return response;
- }
- }
- })(jQuery);
|