From dcfca3f60d3d0c95409bdc43744254b020ead41a Mon Sep 17 00:00:00 2001 From: Babar Saleh Hayat Date: Sun, 7 Apr 2024 07:33:53 +0500 Subject: [PATCH 1/2] feat: add smart text replacer, resolves #616 --- components.d.ts | 13 ++ locales/en.yml | 4 + locales/zh.yml | 4 + src/tools/index.ts | 2 + src/tools/smart-text-replacer/index.ts | 13 ++ .../smart-text-replacer.model.ts | 35 ++++ .../smart-text-replacer.vue | 155 ++++++++++++++++++ 7 files changed, 226 insertions(+) create mode 100644 src/tools/smart-text-replacer/index.ts create mode 100644 src/tools/smart-text-replacer/smart-text-replacer.model.ts create mode 100644 src/tools/smart-text-replacer/smart-text-replacer.vue diff --git a/components.d.ts b/components.d.ts index e31119b3..556aa5fd 100644 --- a/components.d.ts +++ b/components.d.ts @@ -89,7 +89,9 @@ declare module '@vue/runtime-core' { HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default'] IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default'] 'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default'] + 'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default'] 'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default'] + IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default'] IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default'] IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default'] IconMdiClose: typeof import('~icons/mdi/close')['default'] @@ -126,12 +128,16 @@ declare module '@vue/runtime-core' { MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] + NAlert: typeof import('naive-ui')['NAlert'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] + NCheckbox: typeof import('naive-ui')['NCheckbox'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] + NDatePicker: typeof import('naive-ui')['NDatePicker'] NDivider: typeof import('naive-ui')['NDivider'] NEllipsis: typeof import('naive-ui')['NEllipsis'] + NForm: typeof import('naive-ui')['NForm'] NFormItem: typeof import('naive-ui')['NFormItem'] NGi: typeof import('naive-ui')['NGi'] NGrid: typeof import('naive-ui')['NGrid'] @@ -139,12 +145,17 @@ declare module '@vue/runtime-core' { NH3: typeof import('naive-ui')['NH3'] NIcon: typeof import('naive-ui')['NIcon'] NInputNumber: typeof import('naive-ui')['NInputNumber'] + NInputText: typeof import('naive-ui')['NInputText'] NLabel: typeof import('naive-ui')['NLabel'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] NScrollbar: typeof import('naive-ui')['NScrollbar'] + NSlider: typeof import('naive-ui')['NSlider'] NSpin: typeof import('naive-ui')['NSpin'] + NStatistic: typeof import('naive-ui')['NStatistic'] + NSwitch: typeof import('naive-ui')['NSwitch'] + NTable: typeof import('naive-ui')['NTable'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] @@ -159,7 +170,9 @@ declare module '@vue/runtime-core' { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default'] + SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default'] SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default'] + SmartTextReplacer: typeof import('./src/tools/smart-text-replacer/smart-text-replacer.vue')['default'] SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default'] SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default'] StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default'] diff --git a/locales/en.yml b/locales/en.yml index 50d48af9..1c14d16d 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -388,6 +388,10 @@ tools: title: Encode/decode url formatted strings description: Encode to url-encoded format (also known as "percent-encoded") or decode from it. + smart-text-replacer: + title: Smart text replacer + description: Search and replace a word on single or multiple occurrences just like windows notepad search and replace. + text-to-binary: title: Text to ASCII binary description: Convert text to its ASCII binary representation and vice versa. diff --git a/locales/zh.yml b/locales/zh.yml index 160fe1fa..12d88849 100644 --- a/locales/zh.yml +++ b/locales/zh.yml @@ -387,3 +387,7 @@ tools: text-to-binary: title: 文本到 ASCII 二进制 description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。 + + smart-text-replacer: + title: 智能文本替换器 + description: 像windows记事本一样搜索和替换单个或多个出现的单词。 diff --git a/src/tools/index.ts b/src/tools/index.ts index aa861c93..63b9b7eb 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -72,6 +72,7 @@ import { tool as romanNumeralConverter } from './roman-numeral-converter'; import { tool as sqlPrettify } from './sql-prettify'; import { tool as svgPlaceholderGenerator } from './svg-placeholder-generator'; import { tool as temperatureConverter } from './temperature-converter'; +import { tool as smartTextReplacer } from './smart-text-replacer'; import { tool as textStatistics } from './text-statistics'; import { tool as tokenGenerator } from './token-generator'; import type { ToolCategory } from './tools.types'; @@ -170,6 +171,7 @@ export const toolsByCategory: ToolCategory[] = [ emojiPicker, stringObfuscator, textDiff, + smartTextReplacer, numeronymGenerator, asciiTextDrawer, ], diff --git a/src/tools/smart-text-replacer/index.ts b/src/tools/smart-text-replacer/index.ts new file mode 100644 index 00000000..2c10ad5a --- /dev/null +++ b/src/tools/smart-text-replacer/index.ts @@ -0,0 +1,13 @@ +import { Search } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.smart-text-replacer.title'), + path: '/smart-text-replacer', + description: translate('tools.smart-text-replacer.description'), + keywords: ['smart', 'text-replacer', 'search', 'replace'], + component: () => import('./smart-text-replacer.vue'), + icon: Search, + createdAt: new Date('2024-04-03'), +}); diff --git a/src/tools/smart-text-replacer/smart-text-replacer.model.ts b/src/tools/smart-text-replacer/smart-text-replacer.model.ts new file mode 100644 index 00000000..7f56dd1e --- /dev/null +++ b/src/tools/smart-text-replacer/smart-text-replacer.model.ts @@ -0,0 +1,35 @@ +import { get } from '@vueuse/core'; +import { type MaybeRef, computed } from 'vue'; + +export { obfuscateString, useObfuscateString }; + +function obfuscateString( + str: string, + { replacementChar = '*', keepFirst = 4, keepLast = 0, keepSpace = true }: { replacementChar?: string; keepFirst?: number; keepLast?: number; keepSpace?: boolean } = {}): string { + return str + .split('') + .map((char, index, array) => { + if (keepSpace && char === ' ') { + return char; + } + + return (index < keepFirst || index >= array.length - keepLast) ? char : replacementChar; + }) + .join(''); +} + +function useObfuscateString( + str: MaybeRef, + config: { replacementChar?: MaybeRef; keepFirst?: MaybeRef; keepLast?: MaybeRef; keepSpace?: MaybeRef } = {}, + +) { + return computed(() => obfuscateString( + get(str), + { + replacementChar: get(config.replacementChar), + keepFirst: get(config.keepFirst), + keepLast: get(config.keepLast), + keepSpace: get(config.keepSpace), + }, + )); +} diff --git a/src/tools/smart-text-replacer/smart-text-replacer.vue b/src/tools/smart-text-replacer/smart-text-replacer.vue new file mode 100644 index 00000000..926399bb --- /dev/null +++ b/src/tools/smart-text-replacer/smart-text-replacer.vue @@ -0,0 +1,155 @@ + + + + + From 839bafe035a1eab70dad546fa7b81591ea18934d Mon Sep 17 00:00:00 2001 From: Babar Saleh Hayat Date: Sun, 7 Apr 2024 10:01:26 +0500 Subject: [PATCH 2/2] removed extra file --- .../smart-text-replacer.model.ts | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/tools/smart-text-replacer/smart-text-replacer.model.ts diff --git a/src/tools/smart-text-replacer/smart-text-replacer.model.ts b/src/tools/smart-text-replacer/smart-text-replacer.model.ts deleted file mode 100644 index 7f56dd1e..00000000 --- a/src/tools/smart-text-replacer/smart-text-replacer.model.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { get } from '@vueuse/core'; -import { type MaybeRef, computed } from 'vue'; - -export { obfuscateString, useObfuscateString }; - -function obfuscateString( - str: string, - { replacementChar = '*', keepFirst = 4, keepLast = 0, keepSpace = true }: { replacementChar?: string; keepFirst?: number; keepLast?: number; keepSpace?: boolean } = {}): string { - return str - .split('') - .map((char, index, array) => { - if (keepSpace && char === ' ') { - return char; - } - - return (index < keepFirst || index >= array.length - keepLast) ? char : replacementChar; - }) - .join(''); -} - -function useObfuscateString( - str: MaybeRef, - config: { replacementChar?: MaybeRef; keepFirst?: MaybeRef; keepLast?: MaybeRef; keepSpace?: MaybeRef } = {}, - -) { - return computed(() => obfuscateString( - get(str), - { - replacementChar: get(config.replacementChar), - keepFirst: get(config.keepFirst), - keepLast: get(config.keepLast), - keepSpace: get(config.keepSpace), - }, - )); -}