• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { LogUtil } from '../../baseUtil/LogUtil'
17import NoteData from '../../model/databaseModel/NoteData'
18import util from '@ohos.util'
19import relationalStore from '@ohos.data.relationalStore';
20
21const TAG: string = 'SearchModel';
22
23interface TextSpan {
24  type: 0 | 1; // 0 表示正常文本,1 表示高亮关键词
25  text: string;
26}
27
28/**
29 * Search service class
30 */
31export class SearchModel {
32  private rdbStore: relationalStore.RdbStore | undefined = undefined;
33
34  /**
35   * Search
36   *
37   * @param query - query content
38   */
39  public async search(noteDataArray: NoteData[], query: string): Promise<NoteData[]> {
40    LogUtil.info(TAG, "query is " + query)
41    if (!query) {
42      LogUtil.info(TAG, "query is null")
43      return []
44    }
45    let searchData: NoteData[] = [];
46    noteDataArray.forEach((noteData) => {
47      let base64regex = new RegExp('/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/');
48      let contentTextValue: string
49      if (base64regex.test(noteData.content_text) && noteData.content_text.length > 0) {
50        let Base64 = new util.Base64()
51        let textDecoder = new util.TextDecoder("utf-8", { ignoreBOM: true }) // utf-8:编码格式为utf-8,ignoreBOM:是否忽略BOM标记
52        let decodeStr = Base64.decodeSync(noteData.content_text)
53        contentTextValue = textDecoder.decode(decodeStr, { stream: false }) // stream:在随后的decode()调用中是否跟随附加数据块
54      } else {
55        contentTextValue = noteData.content_text
56      }
57      if (contentTextValue.replace(new RegExp('/<[^>]+>/g'), "").toLowerCase().indexOf(query.toLowerCase()) != -1
58        || noteData.title.toLowerCase().indexOf(query.toLowerCase()) != -1) {
59        LogUtil.info(TAG, "uuid " + noteData.uuid)
60        searchData.push(noteData);
61      }
62    })
63    // 排序
64    return searchData;
65  }
66
67  splitToHighlightText(text: string, highlightKeyword: string): TextSpan[] {
68    let spans: TextSpan[] = [];
69    let lowerSpans: string[] = text.toLowerCase().split(highlightKeyword.toLowerCase());
70    let keywordStartIndex = 0;
71    let keywordLength = highlightKeyword.length;
72
73    for (let i = 0; i < lowerSpans.length; i++) {
74      let normalText = text.substr(keywordStartIndex, lowerSpans[i].length);
75      spans.push({
76        type: 0,
77        text: normalText
78      })
79      // if not at last, append highlight keyword
80      if (i != lowerSpans.length - 1) {
81        keywordStartIndex += lowerSpans[i].length
82        let keywordText = text.substr(keywordStartIndex, keywordLength);
83        spans.push({
84          type: 1,
85          text: keywordText
86        })
87        keywordStartIndex += keywordLength
88      }
89    }
90
91    return spans
92  }
93}
94
95let searchModel = new SearchModel()
96
97export default searchModel as SearchModel