Skip to content

feat: NativeScript support #732

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

Merged
merged 14 commits into from
Sep 16, 2018
Merged
29 changes: 27 additions & 2 deletions cypress/integration/components-tab.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { suite } from '../utils/suite'

const baseInstanceCount = 10
const baseInstanceCount = 11

suite('components tab', () => {
beforeEach(() => cy.reload())

it('should detect instances inside shadow DOM', () => {
cy.get('.tree > .instance:last-child').contains('Shadow')
})
Expand All @@ -20,6 +22,26 @@ suite('components tab', () => {
cy.get('.instance').should('have.length', baseInstanceCount)
})

it('should detect functional components', () => {
cy.get('.tree > .instance .instance:nth-child(2)').within(() => {
cy.get('.arrow').click().then(() => {
cy.get('.instance:last-child').contains('Functional')
})
})
})

it('should detect components in transition', () => {
cy.get('.tree > .instance .instance:nth-child(7)').within(() => {
cy.get('.arrow').click().then(() => {
cy.get('.instance').eq(1).within(() => {
cy.get('.arrow').click().then(() => {
cy.get('.instance').contains('TestComponent')
})
})
})
})
})

it('should select child instance', () => {
cy.get('.instance .instance:nth-child(1) .self').eq(0).click()
cy.get('.action-header .title').contains('Counter')
Expand Down Expand Up @@ -50,6 +72,8 @@ suite('components tab', () => {
})

it('should add/remove component from app side', () => {
cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
cy.get('.instance').should('have.length', baseInstanceCount + 10)
cy.get('#target').iframe().then(({ get }) => {
get('.add').click({ force: true })
})
Expand All @@ -64,7 +88,7 @@ suite('components tab', () => {
cy.get('.left .search input').clear().type('counter')
cy.get('.instance').should('have.length', 1)
cy.get('.left .search input').clear().type('target')
cy.get('.instance').should('have.length', 15)
cy.get('.instance').should('have.length', 12)
cy.get('.left .search input').clear()
})

Expand All @@ -82,6 +106,7 @@ suite('components tab', () => {
})

it('should display render key', () => {
cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
cy.get('.instance .self .attr-title').contains('key')
cy.get('.instance .self .attr-value').contains('1')
})
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Cypress.Commands.add('vueCheckInit', () => {

// Add iframe support until becomes part of the framework
Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
const get = selector => cy.wrap($iframe.contents().find(selector))
const get = selector => cy.wait(500).wrap($iframe.contents().find(selector))

const el = $iframe[0]
const iframeDoc = el.contentDocument || el.contentWindow.document
Expand Down
2 changes: 1 addition & 1 deletion shells/dev/target/Target.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<input @keyup.enter="regex = new RegExp($event.target.value)"/>
<span>(Press enter to set)</span>
<br/>
<button class="add" @mouseup="add">Add</button>
<button class="add" @mouseup="add">Add 3</button>
<button class="remove" @mousedown="rm">Remove</button>
<input v-model="localMsg">
<other v-for="item in items" :key="item" :id="item"></other>
Expand Down
49 changes: 49 additions & 0 deletions shells/dev/target/TransitionExample.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<div>
<div data-test-id="transition">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<TestComponent v-if="show">hello</TestComponent>
</transition>
</div>

<div data-test-id="transition-list">
<button v-on:click="++count">Add</button>
<button v-on:click="--count">Remove</button>
<transition-group name="list" tag="p">
<component :is="'TestComponent'" v-for="item in count" v-bind:key="item" class="list-item">
{{ item }}
</component>
</transition-group>
</div>
</div>
</template>

<script>
export default {
data() {
return {
show: true,
count: 5
}
},
components: {
TestComponent: {
render(h) {
return h('div', {}, this.$slots.default)
}
}
}
}
</script>

<style scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
</style>
2 changes: 2 additions & 0 deletions shells/dev/target/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import NativeTypes from './NativeTypes.vue'
import Events from './Events.vue'
import MyClass from './MyClass.js'
import router from './router'
import TransitionExample from './TransitionExample.vue'
import Router from './router/Router.vue'

window.VUE_DEVTOOLS_CONFIG = {
Expand Down Expand Up @@ -40,6 +41,7 @@ new Vue({
h(Events, { key: 'foo' }),
h(NativeTypes, { key: new Date() }),
h(Router, { key: [] }),
h(TransitionExample),
h(VuexObject),
h(Init)
])
Expand Down
21 changes: 18 additions & 3 deletions shells/electron/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
require('./build/hook.js')

const target = typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {}

module.exports = {
connect: function (host, port) {
window.__VUE_DEVTOOLS_HOST__ = host
window.__VUE_DEVTOOLS_PORT__ = port
connect: function (host, port, { io, showToast, app } = {}) {
target.__VUE_DEVTOOLS_HOST__ = host
target.__VUE_DEVTOOLS_PORT__ = port
if (io) target.__VUE_DEVTOOLS_SOCKET__ = io
if (showToast) target.__VUE_DEVTOOLS_TOAST__ = showToast
if (app) target.__VUE_ROOT_INSTANCES__ = Array.isArray(app) ? app : [app]

require('./build/backend.js')
},
init: (Vue) => {
const tools = target.__VUE_DEVTOOLS_GLOBAL_HOOK__

tools.emit('init', Vue)
}
}
20 changes: 11 additions & 9 deletions shells/electron/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,30 @@ import io from 'socket.io-client'
import { initBackend } from 'src/backend'
import Bridge from 'src/bridge'
import { installToast } from 'src/backend/toast'
import { target } from 'src/devtools/env'

const host = window.__VUE_DEVTOOLS_HOST__ || 'http://localhost'
const port = window.__VUE_DEVTOOLS_PORT__ !== undefined ? window.__VUE_DEVTOOLS_PORT__ : 8098
const host = target.__VUE_DEVTOOLS_HOST__ || 'http://localhost'
const port = target.__VUE_DEVTOOLS_PORT__ !== undefined ? target.__VUE_DEVTOOLS_PORT__ : 8098
const fullHost = port ? host + ':' + port : host
const socket = io(fullHost)
const createSocket = target.__VUE_DEVTOOLS_SOCKET__ || io
const socket = createSocket(fullHost)

const connectedMessage = () => {
if (window.__VUE_DEVTOOLS_TOAST__) {
window.__VUE_DEVTOOLS_TOAST__('Remote Devtools Connected', 'normal')
if (target.__VUE_DEVTOOLS_TOAST__) {
target.__VUE_DEVTOOLS_TOAST__('Remote Devtools Connected', 'normal')
}
}

const disconnectedMessage = () => {
if (window.__VUE_DEVTOOLS_TOAST__) {
window.__VUE_DEVTOOLS_TOAST__('Remote Devtools Disconnected', 'error')
if (target.__VUE_DEVTOOLS_TOAST__) {
target.__VUE_DEVTOOLS_TOAST__('Remote Devtools Disconnected', 'error')
}
}

socket.on('connect', () => {
connectedMessage()
initBackend(bridge)
socket.emit('vue-devtools-init')
})

// Global disconnect handler. Fires in two cases:
Expand Down Expand Up @@ -52,5 +55,4 @@ bridge.on('shutdown', () => {
disconnectedMessage()
})

installToast(window)
socket.emit('vue-devtools-init')
installToast(target)
3 changes: 2 additions & 1 deletion shells/electron/src/hook.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { installHook } from 'src/backend/hook'
import { target } from 'src/devtools/env'

installHook(window)
installHook(target)
3 changes: 3 additions & 0 deletions src/backend/component-selector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { highlight, unHighlight } from './highlighter'
import { findRelatedComponent } from './utils'
import { isBrowser } from '../devtools/env'

export default class ComponentSelector {
constructor (bridge, instanceMap) {
Expand All @@ -16,6 +17,7 @@ export default class ComponentSelector {
* Adds event listeners for mouseover and mouseup
*/
startSelecting () {
if (!isBrowser) return
document.body.addEventListener('mouseover', this.elementMouseOver, true)
document.body.addEventListener('click', this.elementClicked, true)
document.body.addEventListener('mouseout', this.cancelEvent, true)
Expand All @@ -29,6 +31,7 @@ export default class ComponentSelector {
* Removes event listeners
*/
stopSelecting () {
if (!isBrowser) return
document.body.removeEventListener('mouseover', this.elementMouseOver, true)
document.body.removeEventListener('click', this.elementClicked, true)
document.body.removeEventListener('mouseout', this.cancelEvent, true)
Expand Down
70 changes: 47 additions & 23 deletions src/backend/highlighter.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import { inDoc, classify, getComponentName } from '../util'
import { getInstanceName } from './index'
import SharedData from 'src/shared-data'

const overlay = document.createElement('div')
overlay.style.backgroundColor = 'rgba(104, 182, 255, 0.35)'
overlay.style.position = 'fixed'
overlay.style.zIndex = '99999999999999'
overlay.style.pointerEvents = 'none'
overlay.style.display = 'flex'
overlay.style.alignItems = 'center'
overlay.style.justifyContent = 'center'
overlay.style.borderRadius = '3px'
const overlayContent = document.createElement('div')
overlayContent.style.backgroundColor = 'rgba(104, 182, 255, 0.9)'
overlayContent.style.fontFamily = 'monospace'
overlayContent.style.fontSize = '11px'
overlayContent.style.padding = '2px 3px'
overlayContent.style.borderRadius = '3px'
overlayContent.style.color = 'white'
overlay.appendChild(overlayContent)
import { isBrowser, target } from '../devtools/env'

let overlay
let overlayContent

function init () {
if (overlay || !isBrowser) return
overlay = document.createElement('div')
overlay.style.backgroundColor = 'rgba(104, 182, 255, 0.35)'
overlay.style.position = 'fixed'
overlay.style.zIndex = '99999999999999'
overlay.style.pointerEvents = 'none'
overlay.style.display = 'flex'
overlay.style.alignItems = 'center'
overlay.style.justifyContent = 'center'
overlay.style.borderRadius = '3px'
overlayContent = document.createElement('div')
overlayContent.style.backgroundColor = 'rgba(104, 182, 255, 0.9)'
overlayContent.style.fontFamily = 'monospace'
overlayContent.style.fontSize = '11px'
overlayContent.style.padding = '2px 3px'
overlayContent.style.borderRadius = '3px'
overlayContent.style.color = 'white'
overlay.appendChild(overlayContent)
}

/**
* Highlight an instance.
Expand All @@ -29,6 +36,13 @@ overlay.appendChild(overlayContent)
export function highlight (instance) {
if (!instance) return
const rect = getInstanceOrVnodeRect(instance)

if (!isBrowser) {
// TODO: Highlight rect area.
return
}

init()
if (rect) {
let content = ''
let name = instance.fnContext ? getComponentName(instance.fnOptions) : getInstanceName(instance)
Expand All @@ -43,20 +57,25 @@ export function highlight (instance) {
*/

export function unHighlight () {
if (overlay.parentNode) {
if (overlay && overlay.parentNode) {
document.body.removeChild(overlay)
}
}

/**
* Get the client rect for an instance.
*
* @param {Vue} instance
* @param {Vue|Vnode} instance
* @return {Object}
*/

export function getInstanceOrVnodeRect (instance) {
const el = instance.$el || instance.elm
if (!isBrowser) {
// TODO: Find position from instance or a vnode (for functional components).

return
}
if (!inDoc(el)) {
return
}
Expand Down Expand Up @@ -107,16 +126,19 @@ function getFragmentRect ({ _fragmentStart, _fragmentEnd }) {
}
}

let range
/**
* Get the bounding rect for a text node using a Range.
*
* @param {Text} node
* @return {Rect}
*/

const range = document.createRange()
function getTextRect (node) {
if (!isBrowser) return
if (!range) range = document.createRange()

range.selectNode(node)

return range.getBoundingClientRect()
}

Expand All @@ -127,6 +149,8 @@ function getTextRect (node) {
*/

function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, content = '') {
if (!isBrowser) return

overlay.style.width = ~~width + 'px'
overlay.style.height = ~~height + 'px'
overlay.style.top = ~~top + 'px'
Expand All @@ -142,5 +166,5 @@ function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, content = ''
*/

function util () {
return window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue.util
return target.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue.util
}
Loading