From 5011c1c95d37893a19873e6e81a9bcc9cc4ef5c2 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 20 Mar 2023 13:19:32 +0100 Subject: [PATCH] #538 - encodeEmoji property support --- CHANGELOG.md | 1 + package.json | 5 +++++ src/helpers/ContentType.ts | 9 +++++---- src/listeners/panel/DataListener.ts | 5 +++++ src/models/PanelSettings.ts | 2 +- src/utils/encodeEmoji.ts | 14 ++++++++++++++ src/utils/index.ts | 1 + 7 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/utils/encodeEmoji.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8281801c..34601e4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ - [#523](https://github.com/estruyf/vscode-front-matter/issues/523): Added support for `floating`/`decimal` numbers with a new number field property called `numberOptions` - [#524](https://github.com/estruyf/vscode-front-matter/issues/524): Removed the **Global settings** view from the panel. You can still get it back by configuring a [custom view mode](https://frontmatter.codes/docs/panel#view-modes). - [#535](https://github.com/estruyf/vscode-front-matter/issues/535): Retain the scroll position after selecting a media file +- [#538](https://github.com/estruyf/vscode-front-matter/issues/538): Added support to encode emojis in the string field ### ⚡️ Optimizations diff --git a/package.json b/package.json index b8e8a96d..a0ae2287 100644 --- a/package.json +++ b/package.json @@ -1154,6 +1154,11 @@ "default": true, "description": "Specify if the field is editable" }, + "encodeEmoji": { + "type": "boolean", + "default": false, + "description": "Specify if the field should encode emoji" + }, "required": { "type": "boolean", "default": false, diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index 204b72b1..eb0c9c63 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -28,7 +28,7 @@ import { Telemetry } from './Telemetry'; import { processKnownPlaceholders } from './PlaceholderHelper'; import { basename } from 'path'; import { ParsedFrontMatter } from '../parsers'; -import { existsAsync, writeFileAsync } from '../utils'; +import { encodeEmoji, existsAsync, writeFileAsync } from '../utils'; export class ContentType { /** @@ -614,10 +614,11 @@ export class ContentType { return; } - // Check if the title needs to be encoded + titleValue = titleValue.trim(); + // Check if the title needs to encode the emoji's used in it const titleField = contentType.fields.find((f) => f.name === 'title'); - if (titleField && titleField.encode) { - titleValue = encodeURIComponent(titleValue); + if (titleField && titleField.encodeEmoji) { + titleValue = encodeEmoji(titleValue); } let templatePath = contentType.template; diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index 0f9c560f..2bc94f3b 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -18,6 +18,7 @@ import { Article } from '../../commands'; import { ParsedFrontMatter } from '../../parsers'; import { processKnownPlaceholders } from '../../helpers/PlaceholderHelper'; import { PostMessageData } from '../../models'; +import { encodeEmoji } from '../../utils'; const FILE_LIMIT = 10; @@ -173,6 +174,7 @@ export class DataListener extends BaseListener { const dateFields = contentType.fields.filter((f) => f.type === 'datetime'); const imageFields = contentType.fields.filter((f) => f.type === 'image' && f.multiple); const fileFields = contentType.fields.filter((f) => f.type === 'file' && f.multiple); + const fieldsWithEmojiEncoding = contentType.fields.filter((f) => f.encodeEmoji); // Support multi-level fields const parentObj = DataListener.getParentObject(article.data, article, parents, blockData); @@ -208,6 +210,9 @@ export class DataListener extends BaseListener { } } } else { + if (fieldsWithEmojiEncoding.some((f) => f.name === field)) { + value = encodeEmoji(value); + } parentObj[field] = value; } diff --git a/src/models/PanelSettings.ts b/src/models/PanelSettings.ts index b3412b8e..5fa9d5da 100644 --- a/src/models/PanelSettings.ts +++ b/src/models/PanelSettings.ts @@ -94,7 +94,7 @@ export interface Field { fileExtensions?: string[]; editable?: boolean; required?: boolean; - encode?: boolean; + encodeEmoji?: boolean; // Date fields isPublishDate?: boolean; diff --git a/src/utils/encodeEmoji.ts b/src/utils/encodeEmoji.ts new file mode 100644 index 00000000..1da59604 --- /dev/null +++ b/src/utils/encodeEmoji.ts @@ -0,0 +1,14 @@ +export const encodeEmoji = (text: string) => { + if (!text || !/\p{Extended_Pictographic}/u.test(text)) { + return text; + } + + const characters = [...text].map((el) => { + if (/\p{Extended_Pictographic}/u.test(el)) { + return `\\u${el.codePointAt(0)?.toString(16).toUpperCase()}`; + } + return el; + }); + + return characters.join(''); +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index 09cf93fe..3eecebc1 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ export * from './copyFileAsync'; +export * from './encodeEmoji'; export * from './existsAsync'; export * from './fetchWithTimeout'; export * from './fieldWhenClause';