diff --git a/src/devtools/components/DataField.vue b/src/devtools/components/DataField.vue
index ad67e06ac..684b47640 100644
--- a/src/devtools/components/DataField.vue
+++ b/src/devtools/components/DataField.vue
@@ -8,12 +8,17 @@
hide: 0
}"
:open-group="'id' + _uid"
+ :class="{
+ 'force-toolbar': contextMenuOpen || editing,
+ }"
class="self"
popover-class="force-tooltip"
trigger="hover"
placement="left"
offset="24"
@click.native="onClick"
+ @mouseenter.native="onContextMenuMouseEnter"
+ @mouseleave.native="onContextMenuMouseLeave"
>
-
-
@@ -86,38 +91,62 @@
v-html="formattedValue"
/>
-
-
-
-
+
+
+
+
+
+
+
@@ -186,7 +215,8 @@ import {
sortByKey,
openInEditor,
escape,
- specialTokenToString
+ specialTokenToString,
+ copyToClipboard
} from 'src/util'
import DataFieldEdit from '../mixins/data-field-edit'
@@ -228,6 +258,7 @@ export default {
data () {
return {
+ contextMenuOpen: false,
limit: Array.isArray(this.field.value) ? 10 : Infinity,
expanded: this.depth === 0 && this.field.key !== '$route' && (subFieldCount(this.field.value) < 5)
}
@@ -399,6 +430,10 @@ export default {
},
methods: {
+ copyToClipboard () {
+ copyToClipboard(this.field.value)
+ },
+
onClick (event) {
// Cancel if target is interactive
if (event.target.tagName === 'INPUT' || event.target.className.includes('button')) {
@@ -422,7 +457,18 @@ export default {
}
},
- hyphen: v => v.replace(/\s/g, '-')
+ hyphen: v => v.replace(/\s/g, '-'),
+
+ onContextMenuMouseEnter () {
+ clearTimeout(this.$_contextMenuTimer)
+ },
+
+ onContextMenuMouseLeave () {
+ clearTimeout(this.$_contextMenuTimer)
+ this.$_contextMenuTimer = setTimeout(() => {
+ this.contextMenuOpen = false
+ }, 4000)
+ }
}
}
@@ -460,16 +506,20 @@ export default {
top -1px
.icon-button
user-select none
- width 16px
+ width 20px
height @width
&:first-child
margin-left 6px
&:not(:last-child)
margin-right 6px
+ .icon-button >>> .vue-ui-icon,
+ .small-icon
+ width 16px
+ height @width
.warning >>> svg
fill $orange
&:hover,
- &.editing
+ &.force-toolbar
.actions
visibility visible
.colon
@@ -499,6 +549,10 @@ export default {
.vue-ui-dark-mode &
color: #242424
+ .edit-overlay
+ display inline-flex
+ align-items center
+
.key
color #881391
.vue-ui-dark-mode &
@@ -599,4 +653,9 @@ export default {
.remove-field
margin-left 10px
+
+.context-menu-dropdown
+ .vue-ui-button
+ display block
+ width 100%
diff --git a/src/devtools/locales/en.js b/src/devtools/locales/en.js
index 6663d463f..988ae1937 100644
--- a/src/devtools/locales/en.js
+++ b/src/devtools/locales/en.js
@@ -27,6 +27,9 @@ export default {
tooltip: '[[{{keys.enter}}]] Submit change'
}
},
+ contextMenu: {
+ copyValue: 'Copy Value'
+ },
quickEdit: {
number: {
tooltip: `Quick Edit
diff --git a/src/util.js b/src/util.js
index bb4d9d5bc..3c3266c3a 100644
--- a/src/util.js
+++ b/src/util.js
@@ -546,3 +546,12 @@ export function escape (s) {
function escapeChar (a) {
return ESC[a] || a
}
+
+export function copyToClipboard (state) {
+ const dummyTextArea = document.createElement('textarea')
+ dummyTextArea.textContent = stringify(state)
+ document.body.appendChild(dummyTextArea)
+ dummyTextArea.select()
+ document.execCommand('copy')
+ document.body.removeChild(dummyTextArea)
+}