Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types and serialization improvements #1

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion shells/dev/target/NativeTypes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
import CompDef from './Other.vue'

export default {
components: {
Expand All @@ -30,7 +31,18 @@ export default {
data () {
return {
localDate: new Date(),
testComponent: null
reg: /abc/gi,
testComponent: null,
hello: function foo (a, b, c) {},
hey: function empty () {},
def: CompDef,
def2: {
name: 'MyComponent',
render () {}
},
def3: {
render () {}
}
}
},
computed: {
Expand Down
72 changes: 31 additions & 41 deletions src/backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,9 @@
import { highlight, unHighlight, getInstanceRect } from './highlighter'
import { initVuexBackend } from './vuex'
import { initEventsBackend } from './events'
import { stringify, classify, camelize, set, parse } from '../util'
import path from 'path'
import { stringify, classify, camelize, set, parse, getComponentName } from '../util'
import ComponentSelector from './component-selector'

// Use a custom basename functions instead of the shimed version
// because it doesn't work on Windows
function basename (filename, ext) {
return path.basename(
filename.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/'),
ext
)
}

// hook should have been injected before this executes.
const hook = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
const rootInstances = []
Expand Down Expand Up @@ -380,6 +370,7 @@ export function getCustomInstanceDetails (instance) {
type: 'component',
id: instance.__VUE_DEVTOOLS_UID__,
display: getInstanceName(instance),
tooltip: 'Component instance',
value: reduceStateList(state),
fields: {
abstract: true
Expand Down Expand Up @@ -408,14 +399,8 @@ export function reduceStateList (list) {
*/

export function getInstanceName (instance) {
const name = instance.$options.name || instance.$options._componentTag
if (name) {
return name
}
const file = instance.$options.__file // injected by vue-loader
if (file) {
return classify(basename(file, '.vue'))
}
const name = getComponentName(instance.$options)
if (name) return name
return instance.$root === instance
? 'Root'
: 'Anonymous Component'
Expand All @@ -441,11 +426,11 @@ function processProps (instance) {
type: 'props',
key: prop.path,
value: instance[prop.path],
meta: {
meta: options ? {
type: options.type ? getPropType(options.type) : 'any',
required: !!options.required,
mode: propModes[prop.mode]
}
} : {}
}
})
} else if ((props = instance.$options.props)) {
Expand All @@ -458,9 +443,11 @@ function processProps (instance) {
type: 'props',
key,
value: instance[key],
meta: {
meta: prop ? {
type: prop.type ? getPropType(prop.type) : 'any',
required: !!prop.required
} : {
type: 'invalid'
}
})
}
Expand Down Expand Up @@ -562,27 +549,30 @@ function processComputed (instance) {
*/

function processRouteContext (instance) {
const route = instance.$route
if (route) {
const { path, query, params } = route
const value = { path, query, params }
if (route.fullPath) value.fullPath = route.fullPath
if (route.hash) value.hash = route.hash
if (route.name) value.name = route.name
if (route.meta) value.meta = route.meta
return [{
key: '$route',
value: {
_custom: {
type: 'router',
abstract: true,
value
try {
const route = instance.$route
if (route) {
const { path, query, params } = route
const value = { path, query, params }
if (route.fullPath) value.fullPath = route.fullPath
if (route.hash) value.hash = route.hash
if (route.name) value.name = route.name
if (route.meta) value.meta = route.meta
return [{
key: '$route',
value: {
_custom: {
type: 'router',
abstract: true,
value
}
}
}
}]
} else {
return []
}]
}
} catch (e) {
// Invalid $router
}
return []
}

/**
Expand Down
19 changes: 19 additions & 0 deletions src/backend/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function isVueRouter (router) {
return router && router.constructor && router.constructor.name === 'VueRouter'
}

export function getCustomRouterDetails (router) {
return {
_custom: {
type: 'router',
display: 'VueRouter',
value: {
options: router.options,
currentRoute: router.currentRoute
},
fields: {
abstract: true
}
}
}
}
20 changes: 20 additions & 0 deletions src/backend/vuex.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,23 @@ export function initVuexBackend (hook, bridge) {
recording = enabled
})
}

export function isVuexStore (val) {
return val && val.state && val._vm
}

export function getCustomStoreDetails (store) {
return {
_custom: {
type: 'store',
display: 'Store',
value: {
state: store.state,
getters: store.getters
},
fields: {
abstract: true
}
}
}
}
22 changes: 20 additions & 2 deletions src/devtools/components/DataField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@
class="value"
:class="valueClass"
@dblclick="openEdit()"
>{{ formattedValue }}</span>
v-tooltip="valueTooltip"
v-html="formattedValue"
/>
<span class="actions">
<i
v-if="isValueEditable"
Expand Down Expand Up @@ -313,6 +315,15 @@ export default {
return this.formattedSubFields.slice(0, this.limit)
},

valueTooltip () {
const type = this.valueType
if (type === 'custom') {
return this.field.value._custom.tooltip
} else if (type.indexOf('native ' === 0)) {
return type.substr('native '.length)
}
},

fieldOptions () {
if (this.valueType === 'custom') {
return Object.assign({}, this.field, this.field.value._custom)
Expand Down Expand Up @@ -442,7 +453,7 @@ export default {
display inline-block
color #444
&.string, &.native
color #c41a16
color $red
&.null
color #999
&.literal
Expand All @@ -459,6 +470,13 @@ export default {
content '<'
&::after
content '>'
&.type-function
>>> span
color $green
&.type-component-definition
color $green
>>> span
color $darkerGrey
.dark &
color #bdc6cf
&.string, &.native
Expand Down
1 change: 1 addition & 0 deletions src/devtools/variables.styl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ $darkerGreen = #3BA776
$slate = #242424
$white = #FFFFFF
$orange = #DB6B00
$red = #c41a16
$black = #000000

// The min-width to give icons text...
Expand Down
2 changes: 1 addition & 1 deletion src/devtools/views/events/EventInspector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ section:not(:last-child)
margin 0 10px

.string
color: #c41a16
color: $red

.literal
color: #03c
Expand Down
2 changes: 1 addition & 1 deletion src/devtools/views/vuex/VuexStateInspector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function copyToClipboard (state) {
left initial
top 1px
font-size 12px
color #c41a16
color $red
background-color $background-color
.dark &
background-color $dark-background-color
Expand Down
68 changes: 67 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import path from 'path'

import CircularJSON from 'circular-json-es6'

import { instanceMap, getCustomInstanceDetails } from 'src/backend'
import { isVuexStore, getCustomStoreDetails } from 'src/backend/vuex'
import { isVueRouter, getCustomRouterDetails } from 'src/backend/router'

function cached (fn) {
const cache = Object.create(null)
Expand Down Expand Up @@ -71,10 +75,72 @@ function replacer (key) {
return `[native RegExp ${val.toString()}]`
} else if (val instanceof Date) {
return `[native Date ${val.toString()}]`
} else if (isVuexStore(val)) {
return getCustomStoreDetails(val)
} else if (isVueRouter(val)) {
return getCustomRouterDetails(val)
} else if (val && val._isVue) {
return getCustomInstanceDetails(val)
} else if (isComponentDefinition(val)) {
return getCustomComponentDefinitionDetails(val)
} else {
const type = typeof val
if (type === 'function') {
return getCustomFunctionDetails(val)
}
}
return sanitize(val)
}

export function isComponentDefinition (val) {
return val && typeof val.render === 'function'
}

// Use a custom basename functions instead of the shimed version
// because it doesn't work on Windows
function basename (filename, ext) {
return path.basename(
filename.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/'),
ext
)
}

export function getComponentName (options) {
const name = options.name || options._componentTag
if (name) {
return name
}
const file = options.__file // injected by vue-loader
if (file) {
return classify(basename(file, '.vue'))
}
}

export function getCustomComponentDefinitionDetails (def) {
let display = getComponentName(def)
if (display) {
if (def.name && def.__file) {
display += ` <span>(${def.__file})</span>`
}
} else {
return sanitize(val)
display = '<i>Unknown Component</i>'
}
return {
_custom: {
type: 'component-definition',
display,
tooltip: 'Component definition'
}
}
}

export function getCustomFunctionDetails (func) {
const args = func.toString().match(/\(.*\)/)[0]
return {
_custom: {
type: 'function',
display: `<span>${func.name}</span>${args}`
}
}
}

Expand Down