Parcourir la source

79940 refactor & use highlight path properly

SULLEY\ryo-h il y a 4 ans
Parent
commit
cf525350e5

+ 3 - 4
packages/app/src/components/SearchPage/SearchResultListItem.tsx

@@ -1,6 +1,6 @@
 import React, { FC } from 'react';
 
-import { UserPicture, PageListMeta } from '@growi/ui';
+import { UserPicture, PageListMeta, PagePathLabel } from '@growi/ui';
 import { DevidedPagePath } from '@growi/core';
 
 import loggerFactory from '~/utils/logger';
@@ -15,7 +15,6 @@ type Props ={
     lastUpdateUser: any
     elasticSearchResult: {
       snippet: string,
-      highlightedPath: string
     }
   },
   onClickInvoked: (data: string) => void,
@@ -29,6 +28,7 @@ const SearchResultListItem: FC<Props> = (props:Props) => {
   const pageId = `#${page._id}`;
 
   const dPagePath = new DevidedPagePath(page.path, false, true);
+  const pagePathElem = <PagePathLabel page={page} isFormerOnly />;
 
   // TODO : send cetain  length of body (revisionBody) from elastisearch by adding some settings to the query and
   //         when keyword is not in page content, display revisionBody.
@@ -58,8 +58,7 @@ const SearchResultListItem: FC<Props> = (props:Props) => {
             {/* page path */}
             <small className="mb-1">
               <i className="icon-fw icon-home"></i>
-              {/* eslint-disable-next-line react/no-danger */}
-              <div dangerouslySetInnerHTML={{ __html: page.elasticSearchResult.highlightedPath }}></div>
+              {pagePathElem}
             </small>
             <div className="d-flex my-1 align-items-center">
               {/* page title */}

+ 15 - 0
packages/core/src/models/devided-page-path.js

@@ -4,6 +4,10 @@ import * as pathUtils from '../utils/path-utils';
 const PATTERN_INCLUDE_DATE = /^(.+\/[^/]+)\/(\d{4}|\d{4}\/\d{2}|\d{4}\/\d{2}\/\d{2})$/;
 // https://regex101.com/r/WVpPpY/1
 const PATTERN_DEFAULT = /^((.*)\/)?([^/]+)$/;
+// https://regex101.com/r/3u1NtT/1
+const PATTERN_PATH_HIGHLIGHTED = /^((.*)(?<!<)[/])(.*)$/;
+// https://regex101.com/r/4J4JuR/1
+const PATTERN_PATH_WITH_ANY_HTML_TAGS = /<("[^"]*"|'[^']*'|[^'">])*>/g;
 
 export class DevidedPagePath {
 
@@ -34,6 +38,17 @@ export class DevidedPagePath {
       }
     }
 
+    // highlighted path
+    const regex = new RegExp(PATTERN_PATH_WITH_ANY_HTML_TAGS);
+    // testing whether the html tags exists in the path or not
+    if (regex.test(pagePath)) {
+      const matchDefault = pagePath.match(PATTERN_PATH_HIGHLIGHTED);
+      this.isFormerRoot = matchDefault[1] === '/';
+      this.former = matchDefault[2];
+      this.latter = matchDefault[3];
+      return;
+    }
+
     const matchDefault = pagePath.match(PATTERN_DEFAULT);
     if (matchDefault != null) {
       this.isFormerRoot = matchDefault[1] === '/';

+ 11 - 6
packages/ui/src/components/PagePath/PagePathLabel.jsx

@@ -4,28 +4,33 @@ import PropTypes from 'prop-types';
 import { DevidedPagePath } from '@growi/core';
 
 export const PagePathLabel = (props) => {
-
-  const dPagePath = new DevidedPagePath(props.page.path, false, true);
+  const highlightedPath = props.page.elasticSearchResult.highlightedPath;
+  const dPagePath = new DevidedPagePath(highlightedPath, false, false);
 
   let classNames = [''];
   classNames = classNames.concat(props.additionalClassNames);
 
+  const displayPath = (reactElement) => {
+    // eslint-disable-next-line react/no-danger
+    return <span dangerouslySetInnerHTML={{ __html: reactElement.props.children }}></span>;
+  };
+
   if (props.isLatterOnly) {
-    return <span className={classNames.join(' ')}>{dPagePath.latter}</span>;
+    return displayPath(<>{dPagePath.latter}</>);
   }
 
   if (props.isFormerOnly) {
     const textElem = dPagePath.isFormerRoot
-      ? <>/</>
+      ? <></>
       : <>{dPagePath.former}</>;
-    return <span className={classNames.join(' ')}>{textElem}</span>;
+    return displayPath(textElem);
   }
 
   const textElem = dPagePath.isRoot
     ? <><strong>/</strong></>
     : <>{dPagePath.former}/<strong>{dPagePath.latter}</strong></>;
 
-  return <span className={classNames.join(' ')}>{textElem}</span>;
+  return displayPath(textElem);
 };
 
 PagePathLabel.propTypes = {