1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-26 00:55:03 +02:00
Files
misskey/packages-private/diagnostics-shared/src/html.ts
かっこかり ab369784fb refactor(gh): CI用スクリプトをpackageとして整理 (#17727)
* refactor(gh): CI用スクリプトをpackageとして整理

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* remove old scripts

* migrate

* refactor 1

* refactor 2

* fix comment

* fix

* fix

* fix

* fix

* remove vite-node from changelog-checker

* fix lint

* fix

* refactor

* update deps

* fix

* spec: rename packages
2026-07-20 20:09:22 +09:00

59 lines
2.1 KiB
TypeScript

/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { escapeHtml } from './format';
/**
* エスケープ済み、あるいは意図的にエスケープしない生のHTML断片。
*
* ただの文字列と型で区別するためだけの存在ではなく、`html` が実行時に
* 「この値はもうエスケープしなくてよい」と判定するためのマーカーでもある。
* 型だけのブランドにすると実行時に判定できず、結局エスケープ漏れを防げない。
*/
export class Raw {
constructor(private readonly value: string) {}
toString() {
return this.value;
}
}
/**
* 文字列をエスケープせずそのまま埋め込む。
* 呼び出しが差分に残るので、レビューで「なぜ生で入れてよいのか」を確認できる。
*/
export function raw(value: string) {
return new Raw(value);
}
function interpolate(value: unknown): string {
if (value instanceof Raw) return value.toString();
// 配列をそのまま文字列化するとカンマ区切りで潰れるので、要素ごとに処理する
if (Array.isArray(value)) return value.map(interpolate).join('');
if (value == null) return '';
return escapeHtml(value);
}
/**
* HTMLを組み立てるタグ付きテンプレート。補間値は既定でエスケープされる。
* エスケープしたくない場合は `raw()` で包む必要があるため、
* 「うっかり生のまま埋め込む」ことが起きない。
*/
export function html(strings: TemplateStringsArray, ...values: unknown[]) {
let result = strings[0];
for (let i = 0; i < values.length; i++) {
result += interpolate(values[i]) + strings[i + 1];
}
return new Raw(result);
}
/**
* 断片を指定の区切り文字で連結する。
* `html` の配列補間は区切り無しで繋ぐので、改行などを挟みたいときはこちらを使う。
*/
export function joinHtml(parts: readonly Raw[], separator: string) {
return new Raw(parts.map(part => part.toString()).join(separator));
}