Forráskód Böngészése

Merge pull request #10931 from growilabs/imprv/131523-lsx-allow-whitespace-path

imprv(lsx): Allow spaces in attribute names
mergify[bot] 4 napja
szülő
commit
5b1b9a9241

+ 50 - 0
packages/remark-lsx/src/client/services/renderer/lsx.spec.ts

@@ -0,0 +1,50 @@
+import type { LeafGrowiPluginDirective } from '@growi/remark-growi-directive';
+import { remarkGrowiDirectivePluginType } from '@growi/remark-growi-directive';
+
+import { remarkPlugin } from './lsx';
+
+const createNode = (
+  attributes: Record<string, string>,
+): LeafGrowiPluginDirective => ({
+  type: remarkGrowiDirectivePluginType.Leaf,
+  name: 'lsx',
+  attributes,
+  children: [],
+});
+
+const runPlugin = (node: LeafGrowiPluginDirective) => {
+  const tree = { type: 'root', children: [node] };
+  (remarkPlugin as () => (tree: unknown) => void)()(tree);
+};
+
+describe('remarkPlugin', () => {
+  describe('prefix extraction', () => {
+    it('case 1: should use explicit prefix attribute', () => {
+      // $lsx(prefix=/path)
+      const node = createNode({ prefix: '/path' });
+      runPlugin(node);
+      expect(node.data?.hProperties).toMatchObject({ prefix: '/path' });
+    });
+
+    it('case 2: should use first bare attribute as prefix', () => {
+      // $lsx(/path)
+      const node = createNode({ '/path': '' });
+      runPlugin(node);
+      expect(node.data?.hProperties).toMatchObject({ prefix: '/path' });
+    });
+
+    it('case 3: should prefer explicit prefix over bare attribute', () => {
+      // $lsx(/foo, prefix=/bar)
+      const node = createNode({ '/foo': '', prefix: '/bar' });
+      runPlugin(node);
+      expect(node.data?.hProperties).toMatchObject({ prefix: '/bar' });
+    });
+
+    it('case 4: should join consecutive bare attributes as prefix when path contains spaces', () => {
+      // $lsx(/foo bar) - micromark parser splits "/foo bar" into "/foo" and "bar"
+      const node = createNode({ '/foo': '', bar: '' });
+      runPlugin(node);
+      expect(node.data?.hProperties).toMatchObject({ prefix: '/foo bar' });
+    });
+  });
+});

+ 11 - 1
packages/remark-lsx/src/client/services/renderer/lsx.ts

@@ -53,6 +53,7 @@ export const remarkPlugin: Plugin = () => (tree) => {
       //   case 1: lsx(prefix=/path..., ...)    => prefix="/path"
       //   case 2: lsx(/path, ...)              => prefix="/path"
       //   case 3: lsx(/foo, prefix=/bar ...)   => prefix="/bar"
+      //   case 4: lsx(/foo bar, ...)           => prefix="/foo bar"
       if (attributes.prefix == null) {
         const attrEntries = Object.entries(attributes);
 
@@ -63,7 +64,16 @@ export const remarkPlugin: Plugin = () => (tree) => {
             firstAttrValue === '' &&
             !SUPPORTED_ATTRIBUTES.includes(firstAttrKey)
           ) {
-            attributes.prefix = firstAttrKey;
+            // Consecutive bare attributes are joined with spaces to restore the prefix path,
+            // because the micromark parser splits space-separated words into separate attributes.
+            const prefixParts: string[] = [];
+            for (const [key, value] of attrEntries) {
+              if (value !== '' || SUPPORTED_ATTRIBUTES.includes(key)) {
+                break;
+              }
+              prefixParts.push(key);
+            }
+            attributes.prefix = prefixParts.join(' ');
           }
         }
       }