Yuki Takei 2 лет назад
Родитель
Сommit
2f8e543f3b

+ 64 - 33
packages/remark-lsx/src/utils/page-node.spec.ts

@@ -18,16 +18,15 @@ function omitPageData(pageNode: PageNode): Omit<PageNode, 'page'> {
 
 describe('generatePageNodeTree()', () => {
 
-  it('returns with non-empty pages', () => {
+  it('returns when the pages are not empty', () => {
     // setup
     const pages: IPageHasId[] = [
       '/',
       '/Sandbox',
-      '/Sandbox/child1',
-      '/Sandbox/child2',
-      '/Sandbox/child2/child2-1',
-      '/Sandbox/child2/child2-2',
-      '/Sandbox/child2/child2-3',
+      '/Sandbox/level2',
+      '/Sandbox/level2/level3-1',
+      '/Sandbox/level2/level3-2',
+      '/Sandbox/level2/level3-3',
     ].map(path => mock<IPageHasId>({ path }));
 
     // when
@@ -40,22 +39,18 @@ describe('generatePageNodeTree()', () => {
         pagePath: '/Sandbox',
         children: [
           {
-            pagePath: '/Sandbox/child1',
-            children: [],
-          },
-          {
-            pagePath: '/Sandbox/child2',
+            pagePath: '/Sandbox/level2',
             children: [
               {
-                pagePath: '/Sandbox/child2/child2-1',
+                pagePath: '/Sandbox/level2/level3-1',
                 children: [],
               },
               {
-                pagePath: '/Sandbox/child2/child2-2',
+                pagePath: '/Sandbox/level2/level3-2',
                 children: [],
               },
               {
-                pagePath: '/Sandbox/child2/child2-3',
+                pagePath: '/Sandbox/level2/level3-3',
                 children: [],
               },
             ],
@@ -65,7 +60,7 @@ describe('generatePageNodeTree()', () => {
     ]);
   });
 
-  it('returns with empty pages', () => {
+  it('returns when the pages include some empty pages', () => {
     // setup
     const pages: IPageHasId[] = [
       '/',
@@ -81,7 +76,6 @@ describe('generatePageNodeTree()', () => {
 
     // then
     expect(resultWithoutPageData).toStrictEqual([
-
       {
         pagePath: '/user',
         children: [
@@ -130,39 +124,76 @@ describe('generatePageNodeTree()', () => {
   it("returns with 'depth=1:2'", () => {
     // setup
     const pages: IPageHasId[] = [
-      '/Sandbox/child1',
-      '/Sandbox/child2',
-      '/Sandbox/child2/child2-1',
-      '/Sandbox/child2/child2-2',
-      '/Sandbox/child2/child2-2/child2-2-1',
+      '/Sandbox',
+      '/Sandbox/level2-1',
+      '/Sandbox/level2-2',
+      '/user',
+      '/user/foo',
+      '/user/bar',
     ].map(path => mock<IPageHasId>({ path }));
 
     // when
     const depthRange = OptionParser.parseRange('1:2');
-    const result = generatePageNodeTree('/Sandbox', pages, depthRange);
+    const result = generatePageNodeTree('/', pages, depthRange);
     const resultWithoutPageData = result.map(pageNode => omitPageData(pageNode));
 
     // then
     expect(resultWithoutPageData).toStrictEqual([
       {
-        pagePath: '/Sandbox/child1',
-        children: [],
+        pagePath: '/Sandbox',
+        children: [
+          {
+            pagePath: '/Sandbox/level2-1',
+            children: [],
+          },
+          {
+            pagePath: '/Sandbox/level2-2',
+            children: [],
+          },
+        ],
       },
       {
-        pagePath: '/Sandbox/child2',
+        pagePath: '/user',
         children: [
           {
-            pagePath: '/Sandbox/child2/child2-1',
+            pagePath: '/user/foo',
             children: [],
           },
           {
-            pagePath: '/Sandbox/child2/child2-2',
-            children: [
-              {
-                pagePath: '/Sandbox/child2/child2-2/child2-2-1',
-                children: [],
-              },
-            ],
+            pagePath: '/user/bar',
+            children: [],
+          },
+        ],
+      },
+    ]);
+  });
+
+  it("returns with 'depth=2:3'", () => {
+    // setup
+    const pages: IPageHasId[] = [
+      '/foo/level2',
+      '/foo/level2',
+      '/foo/level2/level3-1',
+      '/foo/level2/level3-2',
+    ].map(path => mock<IPageHasId>({ path }));
+
+    // when
+    const depthRange = OptionParser.parseRange('2:3');
+    const result = generatePageNodeTree('/', pages, depthRange);
+    const resultWithoutPageData = result.map(pageNode => omitPageData(pageNode));
+
+    // then
+    expect(resultWithoutPageData).toStrictEqual([
+      {
+        pagePath: '/foo/level2',
+        children: [
+          {
+            pagePath: '/foo/level2/level3-1',
+            children: [],
+          },
+          {
+            pagePath: '/foo/level2/level3-2',
+            children: [],
           },
         ],
       },

+ 18 - 7
packages/remark-lsx/src/utils/page-node.ts

@@ -1,11 +1,15 @@
 import * as url from 'url';
 
 import { IPageHasId, ParseRangeResult, pathUtils } from '@growi/core';
+import { isTopPage } from '@growi/core/dist/utils/page-path-utils';
 
 import type { PageNode } from '../interfaces/page-node';
 
-function isEquals(path1: string, path2: string) {
-  return pathUtils.removeTrailingSlash(path1) === pathUtils.removeTrailingSlash(path2);
+function getDepthOfPath(path: string) {
+  if (isTopPage(path)) {
+    return 0;
+  }
+  return (path.match(/\//g) ?? []).length;
 }
 
 function getParentPath(path: string) {
@@ -21,9 +25,16 @@ function getParentPath(path: string) {
  * @returns
  * @memberof Lsx
  */
-function generatePageNode(pathToNodeMap: Record<string, PageNode>, rootPagePath: string, pagePath: string): PageNode | null {
-  // exclude rootPagePath itself
-  if (isEquals(pagePath, rootPagePath)) {
+function generatePageNode(
+    pathToNodeMap: Record<string, PageNode>, rootPagePath: string, pagePath: string, depthRange?: ParseRangeResult | null,
+): PageNode | null {
+
+  const depthStartToProcess = getDepthOfPath(rootPagePath) + (depthRange?.start ?? 0); // at least 1
+  const currentPageDepth = getDepthOfPath(pagePath);
+
+  // return by the depth restriction
+  // '/' will also return null because the depth is 0
+  if (currentPageDepth < depthStartToProcess) {
     return null;
   }
 
@@ -41,7 +52,7 @@ function generatePageNode(pathToNodeMap: Record<string, PageNode>, rootPagePath:
     */
   // get or create parent node
   const parentPath = getParentPath(pagePath);
-  const parentNode = generatePageNode(pathToNodeMap, rootPagePath, parentPath);
+  const parentNode = generatePageNode(pathToNodeMap, rootPagePath, parentPath, depthRange);
   // associate to patent
   if (parentNode != null) {
     parentNode.children.push(node);
@@ -54,7 +65,7 @@ export function generatePageNodeTree(rootPagePath: string, pages: IPageHasId[],
   const pathToNodeMap: Record<string, PageNode> = {};
 
   pages.forEach((page) => {
-    const node = generatePageNode(pathToNodeMap, rootPagePath, page.path); // this will not be null
+    const node = generatePageNode(pathToNodeMap, rootPagePath, page.path, depthRange); // this will not be null
 
     // exclude rootPagePath itself
     if (node == null) {