aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/SearchUtil.ts
diff options
context:
space:
mode:
authormonoguitari <113245090+monoguitari@users.noreply.github.com>2023-08-28 14:06:22 -0400
committermonoguitari <113245090+monoguitari@users.noreply.github.com>2023-08-28 14:06:22 -0400
commit8d8dd9fbe4c90ebeb5e05bce320facef6baed6e8 (patch)
treec2d66324d8d8ac894d4e161d413e49a55042d957 /src/client/util/SearchUtil.ts
parent06363e4bfa55d10075f72d39221c6ba7b92f9f6c (diff)
parentd98e6872ed8f567bf3cb45391a3c2068da148e76 (diff)
Merge branch 'master' into advanced-trails-2-jesus
Diffstat (limited to 'src/client/util/SearchUtil.ts')
-rw-r--r--src/client/util/SearchUtil.ts104
1 files changed, 103 insertions, 1 deletions
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index d154c48a4..64aa7ba9b 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -1,13 +1,115 @@
import * as rp from 'request-promise';
import { DocServer } from '../DocServer';
-import { Doc } from '../../fields/Doc';
+import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { Utils } from '../../Utils';
import { DocumentType } from '../documents/DocumentTypes';
+import { StrCast } from '../../fields/Types';
export namespace SearchUtil {
export type HighlightingResult = { [id: string]: { [key: string]: string[] } };
+ export function SearchCollection(rootDoc: Opt<Doc>, query: string) {
+ const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.CONFIG, DocumentType.KVP, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
+ const blockedKeys = [
+ 'x',
+ 'y',
+ 'proto',
+ 'width',
+ 'layout_autoHeight',
+ 'acl-Override',
+ 'acl-Guest',
+ 'embedContainer',
+ 'zIndex',
+ 'height',
+ 'text_scrollHeight',
+ 'text_height',
+ 'cloneFieldFilter',
+ 'isDataDoc',
+ 'text_annotations',
+ 'dragFactory_count',
+ 'text_noTemplate',
+ 'proto_embeddings',
+ 'isSystem',
+ 'layout_fieldKey',
+ 'isBaseProto',
+ 'xMargin',
+ 'yMargin',
+ 'links',
+ 'layout',
+ 'layout_keyValue',
+ 'layout_fitWidth',
+ 'type_collection',
+ 'title_custom',
+ 'freeform_panX',
+ 'freeform_panY',
+ 'freeform_scale',
+ ];
+ query = query.toLowerCase();
+
+ const results = new Map<Doc, string[]>();
+ if (rootDoc) {
+ const docs = DocListCast(rootDoc[Doc.LayoutFieldKey(rootDoc)]);
+ const docIDs: String[] = [];
+ SearchUtil.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
+ const dtype = StrCast(doc.type) as DocumentType;
+ if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth >= 0) {
+ const hlights = new Set<string>();
+ SearchUtil.documentKeys(doc).forEach(
+ key =>
+ Field.toString(doc[key] as Field)
+ .toLowerCase()
+ .includes(query) && hlights.add(key)
+ );
+ blockedKeys.forEach(key => hlights.delete(key));
+
+ if (Array.from(hlights.keys()).length > 0) {
+ results.set(doc, Array.from(hlights.keys()));
+ }
+ }
+ docIDs.push(doc[Id]);
+ });
+ }
+ return results;
+ }
+ /**
+ * @param {Doc} doc - doc for which keys are returned
+ *
+ * This method returns a list of a document doc's keys.
+ */
+ export function documentKeys(doc: Doc) {
+ const keys: { [key: string]: boolean } = {};
+ Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => (keys[key] = false)));
+ return Array.from(Object.keys(keys));
+ }
+
+ /**
+ * @param {Doc[]} docs - docs to be searched through recursively
+ * @param {number, Doc => void} func - function to be called on each doc
+ *
+ * This method iterates through an array of docs and all docs within those docs, calling
+ * the function func on each doc.
+ */
+ export function foreachRecursiveDoc(docs: Doc[], func: (depth: number, doc: Doc) => void) {
+ let newarray: Doc[] = [];
+ var depth = 0;
+ const visited: Doc[] = [];
+ while (docs.length > 0) {
+ newarray = [];
+ docs.filter(d => d && !visited.includes(d)).forEach(d => {
+ visited.push(d);
+ const fieldKey = Doc.LayoutFieldKey(d);
+ const annos = !Field.toString(Doc.LayoutField(d) as Field).includes('CollectionView');
+ const data = d[annos ? fieldKey + '_annotations' : fieldKey];
+ data && newarray.push(...DocListCast(data));
+ const sidebar = d[fieldKey + '_sidebar'];
+ sidebar && newarray.push(...DocListCast(sidebar));
+ func(depth, d);
+ });
+ docs = newarray;
+ depth++;
+ }
+ }
export interface IdSearchResult {
ids: string[];
lines: string[][];