diff --git a/nezha-fronted/src/assets/css/components/common/v-md-editor.scss b/nezha-fronted/src/assets/css/components/common/v-md-editor.scss
index 1cd46d142..d12b90ed9 100644
--- a/nezha-fronted/src/assets/css/components/common/v-md-editor.scss
+++ b/nezha-fronted/src/assets/css/components/common/v-md-editor.scss
@@ -21,6 +21,27 @@
code{
color: $--color-text-regular;
}
+ &.copy-code-mode .v-md-copy-code-btn{
+ top: 1em;
+ right: 1em;
+ background: transparent;
+ box-shadow: none;
+ width: 16px;
+ height: 16px;
+ i{
+ font-size: 16px;
+ color: $--color-text-regular;
+ }
+ }
+ }
+ blockquote{
+ font-size: 13px;
+ font-weight: 600;
+ padding: 3px 15px;
+ margin-bottom: -1px;
+ color: $--color-text-regular;
+ border: 1px solid $--border-color-light;
+ background: $--alert-rule-background-color;
}
}
}
\ No newline at end of file
diff --git a/nezha-fronted/src/assets/css/components/page/integration/integration.scss b/nezha-fronted/src/assets/css/components/page/integration/integration.scss
index ae64e5615..a8a5550b3 100644
--- a/nezha-fronted/src/assets/css/components/page/integration/integration.scss
+++ b/nezha-fronted/src/assets/css/components/page/integration/integration.scss
@@ -241,39 +241,6 @@
height: 100%;
overflow-y: auto;
}
- .integration-configuration-title{
- font-family: Roboto-Medium;
- font-size: 14px;
- color: $--color-text-primary;
- line-height: 20px;
- font-weight: 600;
- margin-top: 10px;
- }
- .integration-configuration-msg{
- font-family: Roboto-Regular;
- font-size: 14px;
- color: $--color-text-regular;
- line-height: 20px;
- font-weight: 400;
- margin-top: 6px;
- }
- .integration-configuration-pre{
- width: 100%;
- overflow-y: auto;
- box-sizing: border-box;
- overflow-wrap: break-word;
- word-break: break-word;
- white-space: pre-wrap;
- }
- blockquote{
- font-size: 13px;
- font-weight: 600;
- padding: 3px 15px;
- margin-bottom: -1px;
- color: $--color-text-regular;
- border: 1px solid $--border-color-light;
- background: $--alert-rule-background-color;
- }
}
.integration-dashboard{
diff --git a/nezha-fronted/src/components/common/copy-code/copy-code.css b/nezha-fronted/src/components/common/copy-code/copy-code.css
new file mode 100644
index 000000000..dc04c87cc
--- /dev/null
+++ b/nezha-fronted/src/components/common/copy-code/copy-code.css
@@ -0,0 +1,49 @@
+.v-md-pre-wrapper.copy-code-mode .v-md-copy-code-btn {
+ position: absolute;
+ top: 0.4em;
+ right: 0.4em;
+ z-index: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 24px;
+ padding: 0;
+ color: #ddd;
+ font-size: 14px;
+ background-color: #666;
+ border: none;
+ border-radius: 6px;
+ outline: none;
+ box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2);
+ visibility: hidden;
+ cursor: pointer;
+ opacity: 0;
+ transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;
+ user-select: none;
+}
+
+.v-md-pre-wrapper.copy-code-mode .v-md-copy-code-btn i {
+ display: inline-block;
+ color: inherit;
+ font-style: normal;
+ line-height: 0;
+ text-align: center;
+ text-transform: none;
+ vertical-align: -0.125em;
+ text-rendering: optimizeLegibility;
+ pointer-events: none;
+}
+
+.v-md-pre-wrapper.copy-code-mode::before {
+ transition: 0.3s;
+}
+
+.v-md-pre-wrapper.copy-code-mode:hover .v-md-copy-code-btn {
+ visibility: visible;
+ opacity: 1;
+}
+
+.v-md-pre-wrapper.copy-code-mode:hover::before {
+ display: none;
+}
diff --git a/nezha-fronted/src/components/common/copy-code/index.js b/nezha-fronted/src/components/common/copy-code/index.js
new file mode 100644
index 000000000..6749019d7
--- /dev/null
+++ b/nezha-fronted/src/components/common/copy-code/index.js
@@ -0,0 +1,21 @@
+'use strict'
+
+const _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault')
+
+exports.__esModule = true
+exports.default = createCopyCodePlugin
+
+const _markdownItCopyCode = _interopRequireDefault(require('./utils/markdown-it-copy-code'))
+
+const _preview = _interopRequireDefault(require('./preview'))
+
+function createCopyCodePlugin () {
+ return {
+ install: function install (VMdEditor) {
+ VMdEditor.extendMarkdown(function (mdParser) {
+ mdParser.use(_markdownItCopyCode.default)
+ })
+ VMdEditor.use((0, _preview.default)())
+ }
+ }
+}
diff --git a/nezha-fronted/src/components/common/copy-code/preview.js b/nezha-fronted/src/components/common/copy-code/preview.js
new file mode 100644
index 000000000..d48f622e9
--- /dev/null
+++ b/nezha-fronted/src/components/common/copy-code/preview.js
@@ -0,0 +1,63 @@
+'use strict'
+
+const _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault')
+
+exports.__esModule = true
+exports.default = createCopyCodePreview
+
+const _copyToClipboard = _interopRequireDefault(require('copy-to-clipboard'))
+
+function isCopyButton (el) {
+ return el.classList.contains('v-md-copy-code-btn')
+}
+
+function findCodeWrapperEl (el) {
+ if (el.classList.contains('v-md-pre-wrapper')) {
+ return el
+ }
+
+ return findCodeWrapperEl(el.parentNode)
+}
+
+function getPreviewEl (el) {
+ const previewElClass = 'v-md-editor-preview'
+ return el.classList.contains(previewElClass) ? el : el.querySelector('.' + previewElClass)
+}
+
+function createCopyCodePreview () {
+ return {
+ install: function install (VMdEditor) {
+ if (!VMdEditor.mixins) VMdEditor.mixins = []
+ VMdEditor.mixins.push({
+ mounted: function mounted () {
+ const _this = this
+
+ this.$nextTick(function () {
+ const previewEl = getPreviewEl(_this.$el)
+ previewEl.addEventListener('click', _this.handleCopyCodeClick)
+ })
+ },
+ beforeDestroy: function beforeDestroy () {
+ const previewEl = getPreviewEl(this.$el)
+ previewEl.removeEventListener('click', this.handleCopyCodeClick)
+ },
+ methods: {
+ handleCopyCodeClick: function handleCopyCodeClick (_ref) {
+ const target = _ref.target
+
+ if (isCopyButton(target)) {
+ const codeWrapper = findCodeWrapperEl(target.parentNode)
+
+ if (codeWrapper) {
+ const code = codeWrapper.querySelector('code').innerText;
+ // Set the MIME type of what you want to copy as. Use text/html to copy as HTML, text/plain to avoid inherited styles showing when pasted into rich text editor.
+ (0, _copyToClipboard.default)(code, { format: 'text/plain' })
+ this.$emit('copy-code-success', code)
+ }
+ }
+ }
+ }
+ })
+ }
+ }
+}
diff --git a/nezha-fronted/src/components/common/copy-code/utils/markdown-it-copy-code.js b/nezha-fronted/src/components/common/copy-code/utils/markdown-it-copy-code.js
new file mode 100644
index 000000000..6ac4f06d5
--- /dev/null
+++ b/nezha-fronted/src/components/common/copy-code/utils/markdown-it-copy-code.js
@@ -0,0 +1,21 @@
+'use strict'
+
+// markdown-it plugin for generating copy code button.
+// It depends on preWrapper plugin.
+
+/* eslint-disable max-len */
+module.exports = function (md) {
+ // === Start: 防止复制按钮不断被创建 ===
+ if (!md.renderer.rules.originalFence) {
+ md.renderer.rules.originalFence = md.renderer.rules.fence
+ }
+ // === End: Patch ===
+ const fence = md.renderer.rules.originalFence
+
+ md.renderer.rules.fence = function () {
+ const rawCode = fence.apply(void 0, arguments)
+ const button = '\n '
+ const finalCode = rawCode.replace('', button + '').replace('v-md-pre-wrapper', 'v-md-pre-wrapper copy-code-mode')
+ return finalCode
+ }
+}
diff --git a/nezha-fronted/src/components/page/integration/integration-tabs/configuration.vue b/nezha-fronted/src/components/page/integration/integration-tabs/configuration.vue
index bc57d453e..7191032d1 100644
--- a/nezha-fronted/src/components/page/integration/integration-tabs/configuration.vue
+++ b/nezha-fronted/src/components/page/integration/integration-tabs/configuration.vue
@@ -1,7 +1,7 @@
@@ -17,7 +17,9 @@ export default {
}
},
methods: {
-
+ handleCopyCodeSuccess (code) {
+ this.$message.success({ message: this.$t('overall.copySuccess') })
+ }
}
}
diff --git a/nezha-fronted/src/entrance/app/main.js b/nezha-fronted/src/entrance/app/main.js
index 895bdc3b4..c1841a4b9 100644
--- a/nezha-fronted/src/entrance/app/main.js
+++ b/nezha-fronted/src/entrance/app/main.js
@@ -50,24 +50,30 @@ import VMdPreview from '@kangc/v-md-editor/lib/preview'
import '@kangc/v-md-editor/lib/style/preview.css'
import githubTheme from '@kangc/v-md-editor/lib/theme/github.js'
import '@kangc/v-md-editor/lib/theme/style/github.css'
+import hljs from 'highlight.js'
+// markdown支持代码复制
+import createCopyCodePlugin from '@/components/common/copy-code/index'
+import '@/components/common/copy-code/copy-code.css'
+VMdPreview.use(githubTheme, {
+ Hljs: hljs
+})
+VMdPreview.use(createCopyCodePlugin())
+Vue.use(VMdPreview)
+
// Pace.on("done", function() {
// $self.isShowAuth = false;
// Pace.off("done");
// })
// highlightjs
-import hljs from 'highlight.js'
// Pace.start();
-VMdPreview.use(githubTheme, {
- Hljs: hljs
-})
+
Pace.options = {
minTime: 100,
ghostTime: 100,
restartOnRequestAfter: 100
}
window.Meta2d = Meta2d
-Vue.use(VMdPreview)
// Vue.use(Pace)
Vue.use(VueIntro)