diff options
Diffstat (limited to '')
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | package-lock.json | 22 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/router.js | 11 | ||||
-rw-r--r-- | src/routes/tools/MarkdownEditor.vue | 77 | ||||
-rw-r--r-- | src/utils/helpers.js | 12 |
6 files changed, 116 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a01cc22..abbbc29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [fix] [GithubContributors] ordered contributors by contribution count - [refactor] used vue-typecasting for number inputs - [feat] lazy loading tools routes +- [feat] added [markdown editor](/#/markdown-editor) ## 1.2.1 - [fix] [UuidGenerator] added quantity validation rules diff --git a/package-lock.json b/package-lock.json index e99f5c8..25952fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3139,6 +3139,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "highlight.js": { + "version": "9.18.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", + "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", + "dev": true + }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -4373,6 +4379,11 @@ "domelementtype": "1" } }, + "dompurify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.11.tgz", + "integrity": "sha512-qVoGPjIW9IqxRij7klDQQ2j6nSe4UNWANBhZNLnsS7ScTtLb+3YdxkRY8brNTpkUiTtcXsCJO+jS0UCDfenLuA==" + }, "domutils": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", @@ -6253,12 +6264,6 @@ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", "dev": true }, - "highlight.js": { - "version": "9.18.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", - "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", - "dev": true - }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -8103,6 +8108,11 @@ "object-visit": "^1.0.0" } }, + "marked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.1.0.tgz", + "integrity": "sha512-EkE7RW6KcXfMHy2PA7Jg0YJE1l8UPEZE8k45tylzmZM30/r1M1MUXWQfJlrSbsTeh7m/XTwHbWUENvAJZpp1YA==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", diff --git a/package.json b/package.json index b552be8..97cd7d8 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "color-convert": "^2.0.1", "color-name": "^1.1.4", "core-js": "^3.6.4", + "dompurify": "^2.0.11", + "marked": "^1.1.0", "register-service-worker": "^1.7.1", "roboto-fontface": "*", "vue": "^2.6.11", diff --git a/src/router.js b/src/router.js index 3547180..17cd3e9 100644 --- a/src/router.js +++ b/src/router.js @@ -85,15 +85,22 @@ const toolsComponents = [ ], }, { - title: 'Miscellaneous', + title: 'Text', child: [ { - icon: 'fa-align-left\n', + icon: 'fa-align-left', text: 'Text stats', path: '/text-stats', component: () => import('./routes/tools/TextStats'), keywords: ['word', 'count', 'size', 'bytes', 'length'] }, + { + icon: 'fab fa-markdown', + text: 'Markdown editor', + path: '/markdown-editor', + component: () => import('./routes/tools/MarkdownEditor'), + keywords: ['text', 'html', 'markdown'] + }, ], } ]; diff --git a/src/routes/tools/MarkdownEditor.vue b/src/routes/tools/MarkdownEditor.vue new file mode 100644 index 0000000..7a19b09 --- /dev/null +++ b/src/routes/tools/MarkdownEditor.vue @@ -0,0 +1,77 @@ +<template> + <v-row justify="center" align="center"> + <v-col cols="12" xl="5" lg="6" md="12"> + <v-card> + <v-card-text> + <v-textarea v-model="markdown" auto-grow outlined label="Markdown editor"/> + <div class="text-center"> + <v-btn @click="copy(markdown)">copy markdown</v-btn> + </div> + </v-card-text> + </v-card> + </v-col> + <v-col cols="12" xl="5" lg="6" md="12"> + <v-card> + <v-card-text > + <div class="preview" v-html="html"></div> + <div class="text-center"> + <v-divider /> + <br> + <v-btn @click="copy(html)">copy html</v-btn> + </div> + </v-card-text> + </v-card> + </v-col> + </v-row> +</template> + +<script> + // import {debounce} from "../../utils/helpers"; + import marked from 'marked' + import DOMPurify from 'dompurify'; + import {copyToClipboard} from "../../utils/helpers"; + + export default { + name: "MarkdownEditor", + data: () => ({ + markdown: '# Hello, World!\nLorem ipsum **dolor** sit *amet*, consectetur adipisicing elit. A aspernatur commodi consequuntur distinctio dolore doloribus eaque earum est ipsum nobis numquam pariatur perspiciatis quasi quis, sed, sunt tempore tenetur, veniam!\n', + }), + methods: { + copy(text){ + copyToClipboard(text) + this.$toast.success('Copied to clipboard.') + } + }, + computed: { + html() { + return DOMPurify.sanitize(marked(this.markdown)) + } + } + } +</script> + +<style scoped lang="less"> + ::v-deep { + .preview { + padding: 20px; + + h1{ + margin-bottom: 15px; + } + code{ + background-color: rgba(0, 0, 0, 0.3) !important; + box-shadow: none; + color: #9a9a9a; + font-weight: normal; + } + pre { + width: 100%; + + code { + width: 100% !important; + padding: 10px; + } + } + } + } +</style> diff --git a/src/utils/helpers.js b/src/utils/helpers.js index e847c42..f81190b 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -28,9 +28,19 @@ const isInt = (value) => { return Number.isInteger(value); } +const debounce = (callback, delay = 300) => { + let timer; + + return function(...args) { + clearTimeout(timer); + timer = setTimeout(() => callback(...args), delay); + } +} + export { copyToClipboard, fileIsImage, formatBytes, - isInt + isInt, + debounce }
\ No newline at end of file |