Skip to content

Commit

Permalink
Merge pull request #9025 from weseek/impv/148445-151932-add-type-rema…
Browse files Browse the repository at this point in the history
…rk-growi-directive

imprv: Add types to remark-growi-directive
  • Loading branch information
reiji-h authored Aug 26, 2024
2 parents 7d0a6fa + 1834459 commit de819f5
Show file tree
Hide file tree
Showing 18 changed files with 491 additions and 322 deletions.
4 changes: 3 additions & 1 deletion apps/app/src/interfaces/services/rehype-sanitize.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { Attributes } from 'hast-util-sanitize/lib';
import type { defaultSchema } from 'hast-util-sanitize';

type Attributes = typeof defaultSchema.attributes;

export const RehypeSanitizeType = {
RECOMMENDED: 'Recommended',
Expand Down
9 changes: 9 additions & 0 deletions apps/app/src/services/renderer/recommended-whitelist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ describe('recommended-whitelist', () => {

test('.attributes should return data attributes', () => {
expect(attributes).not.toBeNull();

assert(attributes != null);

expect(Object.keys(attributes)).includes('*');
expect(attributes['*']).includes('alt');
expect(attributes['*']).includes('align');
Expand All @@ -25,12 +28,18 @@ describe('recommended-whitelist', () => {

test('.attributes should return iframe attributes', () => {
expect(attributes).not.toBeNull();

assert(attributes != null);

expect(Object.keys(attributes)).includes('iframe');
expect(attributes.iframe).includes('src');
});

test('.attributes should return video attributes', () => {
expect(attributes).not.toBeNull();

assert(attributes != null);

expect(Object.keys(attributes)).includes('video');
expect(attributes.iframe).includes('src');
});
Expand Down
3 changes: 2 additions & 1 deletion apps/app/src/services/renderer/recommended-whitelist.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { defaultSchema } from 'hast-util-sanitize';
import type { Attributes } from 'hast-util-sanitize/lib';
import deepmerge from 'ts-deepmerge';

type Attributes = typeof defaultSchema.attributes;

/**
* reference: https://meta.stackexchange.com/questions/1777/what-html-tags-are-allowed-on-stack-exchange-sites,
* https://github.com/jch/html-pipeline/blob/70b6903b025c668ff3c02a6fa382031661182147/lib/html/pipeline/sanitization_filter.rb#L41
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { pathUtils } from '@growi/core/dist/utils';
import type { TextGrowiPluginDirective, LeafGrowiPluginDirective } from '@growi/remark-growi-directive';
import { remarkGrowiDirectivePluginType } from '@growi/remark-growi-directive';
import type { Nodes as HastNode } from 'hast';
import type { Schema as SanitizeOption } from 'hast-util-sanitize';
Expand All @@ -21,11 +22,11 @@ const REFS_IMG_SUPPORTED_ATTRIBUTES = [
];

type DirectiveAttributes = Record<string, string>
type GrowiPluginDirective = TextGrowiPluginDirective | LeafGrowiPluginDirective

export const remarkPlugin: Plugin = function() {
return (tree) => {
visit(tree, (node: any) => {
// TODO: growi-directive types
visit(tree, (node: GrowiPluginDirective) => {
if (node.type === remarkGrowiDirectivePluginType.Text || node.type === remarkGrowiDirectivePluginType.Leaf) {
if (typeof node.name !== 'string') {
return;
Expand Down
1 change: 1 addition & 0 deletions packages/remark-growi-directive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"typings": "dist/index.d.ts",
"scripts": {
"build": "yarn tsc -p tsconfig.build.json",
"postbuild": "shx cp ./src/mdast-util-growi-directive/index.d.ts ./dist/mdast-util-growi-directive/index.d.ts",
"clean": "shx rm -rf dist",
"dev": "yarn build",
"watch": "yarn tsc -w",
Expand Down
9 changes: 7 additions & 2 deletions packages/remark-growi-directive/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { DirectiveType } from './mdast-util-growi-directive/consts.js';
import { remarkGrowiDirectivePlugin } from './remark-growi-directive.js';

export { DirectiveType as remarkGrowiDirectivePluginType };
export {
DirectiveTypeObject as remarkGrowiDirectivePluginType,
LeafGrowiPluginDirective,
TextGrowiPluginDirective,
LeafGrowiPluginDirectiveData,
TextGrowiPluginDirectiveData,
} from './mdast-util-growi-directive';

export default remarkGrowiDirectivePlugin;

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import type {
Data,
Parent,
PhrasingContent,
} from 'mdast';

import { DirectiveType as DirectiveTypeObject } from './lib/index.js';

export { directiveFromMarkdown, directiveToMarkdown } from './lib/index.js';
export { DirectiveTypeObject };

type DirectiveType = typeof DirectiveTypeObject;

/**
* Fields shared by directives.
*/
interface DirectiveFields {
/**
* Directive name.
*/
name: string

/**
* Directive attributes.
*/
attributes?: Record<string, string | null | undefined> | null | undefined
}

/**
* Markdown directive (leaf form).
*/
export interface LeafGrowiPluginDirective extends Parent, DirectiveFields {
/**
* Node type of leaf directive.
*/
type: DirectiveType['Leaf']

/**
* Children of leaf directive.
*/
children: PhrasingContent[]

/**
* Data associated with the mdast leaf directive.
*/
data?: LeafGrowiPluginDirectiveData | undefined
}

/**
* Info associated with mdast leaf directive nodes by the ecosystem.
*/
export interface LeafGrowiPluginDirectiveData extends Data {
hName?: string,
hProperties?: Record<string, string>
}

/**
* Markdown directive (text form).
*/
export interface TextGrowiPluginDirective extends Parent, DirectiveFields {
/**
* Node type of text directive.
*/
type: DirectiveType['Text']

/**
* Children of text directive.
*/
children: PhrasingContent[]

/**
* Data associated with the text leaf directive.
*/
data?: TextGrowiPluginDirectiveData | undefined
}

/**
* Info associated with mdast text directive nodes by the ecosystem.
*/
export interface TextGrowiPluginDirectiveData extends Data {
hName?: string,
hProperties?: Record<string, string>
}


/**
* Union of registered mdast directive nodes.
*
* It is not possible to register custom mdast directive node types.
*/
export type Directives = LeafGrowiPluginDirective | TextGrowiPluginDirective

// Add custom data tracked to turn markdown into a tree.
declare module 'mdast-util-from-markdown' {
interface CompileData {
/**
* Attributes for current directive.
*/
directiveAttributes?: Array<[string, string]> | undefined
}
}

// Add custom data tracked to turn a syntax tree into markdown.
declare module 'mdast-util-to-markdown' {
interface ConstructNameMap {
/**
* Whole leaf directive.
*
* ```markdown
* > | ::a
* ^^^
* ```
*/
leafGrowiPluginDirective: 'leafGrowiPluginDirective'

/**
* Label of a leaf directive.
*
* ```markdown
* > | ::a[b]
* ^^^
* ```
*/
leafGrowiPluginDirectiveLabel: 'leafGrowiPluginDirectiveLabel'

/**
* Whole text directive.
*
* ```markdown
* > | :a
* ^^
* ```
*/
textGrowiPluginDirective: 'textGrowiPluginDirective'

/**
* Label of a text directive.
*
* ```markdown
* > | :a[b]
* ^^^
* ```
*/
textGrowiPluginDirectiveLabel: 'textGrowiPluginDirectiveLabel'
}
}

// Add nodes to content, register `data` on paragraph.
declare module 'mdast' {
interface BlockContentMap {
/**
* Directive in flow content (such as in the root document, or block
* quotes), which contains nothing.
*/
leafGrowiPluginDirective: LeafGrowiPluginDirective
}

interface PhrasingContentMap {
/**
* Directive in phrasing content (such as in paragraphs, headings).
*/
textGrowiPluginDirective: TextGrowiPluginDirective
}

interface RootContentMap {
/**
* Directive in flow content (such as in the root document, or block
* quotes), which contains nothing.
*/
leafGrowiPluginDirective: LeafGrowiPluginDirective

/**
* Directive in phrasing content (such as in paragraphs, headings).
*/
textGrowiPluginDirective: TextGrowiPluginDirective
}
}
Loading

0 comments on commit de819f5

Please sign in to comment.