soiz1 commited on
Commit
4d70170
·
verified ·
1 Parent(s): c18d346

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .eslintrc.json +21 -0
  2. .gitattributes +9 -0
  3. .github/FUNDING.yml +2 -0
  4. .github/workflows/main.yml +31 -0
  5. .github/workflows/publish.yml +31 -0
  6. .gitignore +5 -0
  7. .gitmodules +3 -0
  8. .prettierignore +1 -0
  9. .prettierrc.json +5 -0
  10. CHANGELOG.md +15 -0
  11. LICENSE +21 -0
  12. README.md +30 -10
  13. index.html +38 -0
  14. package.json +56 -0
  15. src/back.js +221 -0
  16. src/index.js +45 -0
  17. src/style.scss +12 -0
  18. vue-devtools/.browserslistrc +2 -0
  19. vue-devtools/.circleci/config.yml +37 -0
  20. vue-devtools/.github/FUNDING.yml +1 -0
  21. vue-devtools/.github/ISSUE_TEMPLATE/bug_report.yml +78 -0
  22. vue-devtools/.github/ISSUE_TEMPLATE/config.yml +14 -0
  23. vue-devtools/.github/ISSUE_TEMPLATE/feature_request.yml +28 -0
  24. vue-devtools/.github/PULL_REQUEST_TEMPLATE.md +26 -0
  25. vue-devtools/.github/commit-convention.md +92 -0
  26. vue-devtools/.github/workflows/create-release.yml +24 -0
  27. vue-devtools/.gitignore +16 -0
  28. vue-devtools/.vscode/settings.json +3 -0
  29. vue-devtools/LICENSE +21 -0
  30. vue-devtools/README.md +46 -0
  31. vue-devtools/babel.config.js +11 -0
  32. vue-devtools/cypress.json +5 -0
  33. vue-devtools/cypress/.eslintrc.js +12 -0
  34. vue-devtools/cypress/.gitignore +2 -0
  35. vue-devtools/cypress/fixtures/example.json +5 -0
  36. vue-devtools/cypress/integration/component-data-edit.js +101 -0
  37. vue-devtools/cypress/integration/components-tab.js +146 -0
  38. vue-devtools/cypress/integration/events-tab.js +37 -0
  39. vue-devtools/cypress/integration/vuex-edit.js +111 -0
  40. vue-devtools/cypress/integration/vuex-tab.js +214 -0
  41. vue-devtools/cypress/plugins/index.js +24 -0
  42. vue-devtools/cypress/support/commands.js +48 -0
  43. vue-devtools/cypress/support/index.js +20 -0
  44. vue-devtools/cypress/utils/suite.js +9 -0
  45. vue-devtools/dist/.gitkeep +0 -0
  46. vue-devtools/eslint.config.js +43 -0
  47. vue-devtools/extension-zips.js +142 -0
  48. vue-devtools/lerna.json +11 -0
  49. vue-devtools/media/chrome-webstore/screenshot1-size.png +3 -0
  50. vue-devtools/media/chrome-webstore/screenshot1.png +3 -0
.eslintrc.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "env": {
3
+ "browser": true,
4
+ "es6": true,
5
+ "amd": true,
6
+ "commonjs": true
7
+ },
8
+ "parserOptions": {
9
+ "ecmaVersion": "latest",
10
+ "sourceType": "module"
11
+ },
12
+ "extends": "eslint:recommended",
13
+ "globals": {
14
+ "process": "readonly"
15
+ },
16
+ "rules": {
17
+ "indent": ["error", 2],
18
+ "quotes": ["error", "single"],
19
+ "no-extra-semi": "off"
20
+ }
21
+ }
.gitattributes CHANGED
@@ -33,3 +33,12 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ vue-devtools/media/chrome-webstore/screenshot1-size.png filter=lfs diff=lfs merge=lfs -text
37
+ vue-devtools/media/chrome-webstore/screenshot1.png filter=lfs diff=lfs merge=lfs -text
38
+ vue-devtools/media/screenshot-rounded.png filter=lfs diff=lfs merge=lfs -text
39
+ vue-devtools/media/screenshot-shadow.png filter=lfs diff=lfs merge=lfs -text
40
+ vue-devtools/media/screenshot.png filter=lfs diff=lfs merge=lfs -text
41
+ vue-devtools/packages/app-frontend/src/assets/Roboto-Mono.ttf filter=lfs diff=lfs merge=lfs -text
42
+ vue-devtools/packages/docs/src/assets/dev-shell-url.png filter=lfs diff=lfs merge=lfs -text
43
+ vue-devtools/packages/docs/src/assets/edge-settings1.png filter=lfs diff=lfs merge=lfs -text
44
+ vue-devtools/packages/docs/src/public/logo-edge.png filter=lfs diff=lfs merge=lfs -text
.github/FUNDING.yml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ ko_fi: surunzi
2
+ open_collective: eruda
.github/workflows/main.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: CI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - 'master'
8
+ paths:
9
+ - 'src/**/*'
10
+
11
+ jobs:
12
+ ci:
13
+
14
+ runs-on: ubuntu-latest
15
+
16
+ strategy:
17
+ matrix:
18
+ node-version: [18.x]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Use Node.js ${{ matrix.node-version }}
23
+ uses: actions/setup-node@v2
24
+ with:
25
+ node-version: ${{ matrix.node-version }}
26
+ - run: |
27
+ npm install -g @liriliri/lsla
28
+ npm install -g yarn
29
+ npm run init
30
+ npm run init:front
31
+ npm run ci
.github/workflows/publish.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Publish to NPM
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [created]
7
+
8
+ jobs:
9
+ publish:
10
+
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Checkout
15
+ uses: actions/checkout@v2
16
+ - name: Setup Node
17
+ uses: actions/setup-node@v2
18
+ with:
19
+ node-version: '18.x'
20
+ registry-url: 'https://registry.npmjs.org'
21
+ - name: Build eruda-vue
22
+ run: |
23
+ npm install -g @liriliri/lsla
24
+ npm install -g yarn
25
+ npm run init
26
+ npm run init:front
27
+ npm run build
28
+ - name: Publish package on NPM
29
+ run: npm publish
30
+ env:
31
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ node_modules/
2
+ src/devtools.txt
3
+ eruda-vue.js
4
+ eruda-vue.js.map
5
+ package-lock.json
.gitmodules ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [submodule "vue-devtools"]
2
+ path = vue-devtools
3
+ url = https://github.com/liriliri/vue-devtools
.prettierignore ADDED
@@ -0,0 +1 @@
 
 
1
+ src/devtools.js
.prettierrc.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "singleQuote": true,
3
+ "tabWidth": 2,
4
+ "semi": false
5
+ }
CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## v1.1.1 (5 Sep 2024)
2
+
3
+ * fix: safari
4
+
5
+ ## v1.1.0 (4 Sep 2024)
6
+
7
+ * feat: force dev mode
8
+
9
+ ## v1.0.1 (16 Aug 2024)
10
+
11
+ * fix: initial theme not correct
12
+
13
+ ## v1.0.0 (15 Aug 2024)
14
+
15
+ Initial release.
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024-present liriliri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,10 +1,30 @@
1
- ---
2
- title: Eruda Vue
3
- emoji: 📚
4
- colorFrom: green
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # eruda-vue
2
+
3
+ [![NPM version][npm-image]][npm-url]
4
+ [![Build status][ci-image]][ci-url]
5
+ [![License][license-image]][npm-url]
6
+
7
+ [npm-image]: https://img.shields.io/npm/v/eruda-vue.svg
8
+ [npm-url]: https://npmjs.org/package/eruda-vue
9
+ [ci-image]: https://img.shields.io/github/actions/workflow/status/liriliri/eruda-vue/main.yml?branch=master&style=flat-square
10
+ [ci-url]: https://github.com/liriliri/eruda-vue/actions/workflows/main.yml
11
+ [license-image]: https://img.shields.io/npm/l/eruda-vue.svg
12
+
13
+ Eruda plugin for Vue.
14
+
15
+ ## Demo
16
+
17
+ Browse it on your phone:
18
+ [https://eruda.liriliri.io/?plugin=vue](https://eruda.liriliri.io/?plugin=vue)
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm install eruda-vue --save
24
+ ```
25
+
26
+ ```javascript
27
+ eruda.add(erudaVue);
28
+ ```
29
+
30
+ Make sure Eruda is loaded before this plugin, otherwise won't work.
index.html ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
8
+ />
9
+ <title>Eruda-vue</title>
10
+ <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
11
+ </head>
12
+ <body>
13
+ <div id="app">{{ message }}</div>
14
+ <script>
15
+ const { createApp, ref } = Vue
16
+
17
+ createApp({
18
+ setup() {
19
+ const message = ref('Hello vue!')
20
+ return {
21
+ message,
22
+ }
23
+ },
24
+ }).mount('#app')
25
+ </script>
26
+ <script src="node_modules/eruda/eruda.js"></script>
27
+ <script>
28
+ setTimeout(() => {
29
+ console.log(__VUE_DEVTOOLS_GLOBAL_HOOK__)
30
+ }, 3000)
31
+ eruda.init({ tool: ['console'] })
32
+ </script>
33
+ <script src="assets/eruda-vue.js"></script>
34
+ <script>
35
+ eruda.add(erudaVue).show('vue').show()
36
+ </script>
37
+ </body>
38
+ </html>
package.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "eruda-vue",
3
+ "version": "1.1.1",
4
+ "main": "eruda-vue.js",
5
+ "description": "Eruda plugin for Vue",
6
+ "files": [
7
+ "eruda-vue.js",
8
+ "eruda-vue.js.map"
9
+ ],
10
+ "scripts": {
11
+ "init": "git submodule init && git submodule update && npm install --force && cd vue-devtools && yarn && npm run build",
12
+ "init:front": "npm run build:front && npm run copy:front",
13
+ "build:front": "cd vue-devtools/packages/shell-eruda && npm run build",
14
+ "copy:front": "lsla shx cp -r vue-devtools/packages/shell-eruda/build/devtools.js src/devtools.txt",
15
+ "dev": "webpack-dev-server --host 0.0.0.0 --mode development",
16
+ "build": "webpack --mode production",
17
+ "ci": "npm run lint && npm run build",
18
+ "lint": "eslint src/**/*.js",
19
+ "format": "lsla prettier \"src/*.{js,scss}\" \"*.{json,html}\" --write"
20
+ },
21
+ "keywords": [
22
+ "eruda",
23
+ "vue",
24
+ "plugin"
25
+ ],
26
+ "author": "surunzi",
27
+ "license": "MIT",
28
+ "bugs": {
29
+ "url": "https://github.com/liriliri/eruda-vue/issues"
30
+ },
31
+ "homepage": "https://github.com/liriliri/eruda-vue#readme",
32
+ "devDependencies": {
33
+ "@babel/core": "^7.21.3",
34
+ "@babel/plugin-transform-runtime": "^7.21.0",
35
+ "@babel/preset-env": "^7.20.2",
36
+ "autoprefixer": "^10.4.14",
37
+ "babel-loader": "^9.1.2",
38
+ "css-loader": "^3.4.2",
39
+ "eruda": "^3.2.0",
40
+ "eslint": "^8.57.0",
41
+ "licia": "^1.41.1",
42
+ "path-browserify": "^1.0.1",
43
+ "postcss": "^8.4.21",
44
+ "postcss-class-prefix": "^0.3.0",
45
+ "postcss-loader": "^7.0.2",
46
+ "raw-loader": "^4.0.2",
47
+ "sass": "^1.77.8",
48
+ "sass-loader": "^14.2.1",
49
+ "webpack": "^5.93.0",
50
+ "webpack-cli": "^5.1.4",
51
+ "webpack-dev-server": "^4.12.0"
52
+ },
53
+ "workspaces": [
54
+ "vue-devtools/packages/*"
55
+ ]
56
+ }
src/back.js ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { installHook as _installHook } from '@back/hook'
2
+ import { Bridge } from '@utils/bridge'
3
+ import { SharedData } from '@utils/shared-data'
4
+ import createUrl from 'licia/createUrl'
5
+ import devtools from 'raw-loader!./devtools.txt'
6
+
7
+ let theme = 'auto'
8
+ let shareDataLoaded = false
9
+
10
+ export function installHook() {
11
+ if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
12
+ return
13
+ }
14
+ _installHook(window)
15
+ }
16
+
17
+ export function initDevtools(iframe) {
18
+ const bridge = new Bridge({
19
+ listen(fn) {
20
+ window.addEventListener('message', (evt) => {
21
+ if (process.env.NODE_ENV !== 'production') {
22
+ console.log('devtools -> backend', evt.data)
23
+ }
24
+ fn(evt.data)
25
+ })
26
+ },
27
+ send(data) {
28
+ if (process.env.NODE_ENV !== 'production') {
29
+ console.log('backend -> devtools', data)
30
+ }
31
+ iframe.contentWindow.postMessage(data, '*')
32
+ },
33
+ })
34
+ bridge.on('shared-data:load-complete', () => {
35
+ shareDataLoaded = true
36
+ setTheme(theme)
37
+ })
38
+ import('@back').then(({ initBackend }) => {
39
+ initBackend(bridge)
40
+ })
41
+
42
+ const devtoolsSrc = createUrl(devtools, { type: 'application/javascript' })
43
+
44
+ const devtoolsUrl = createUrl(
45
+ `<!DOCTYPE html>
46
+ <html>
47
+ <head>
48
+ <meta charset="utf-8">
49
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
50
+ </head>
51
+ <body>
52
+ <div id="app"></div>
53
+ <script src="${devtoolsSrc}"></script>
54
+ </body>
55
+ </html>`,
56
+ {
57
+ type: 'text/html',
58
+ }
59
+ )
60
+
61
+ iframe.__vdevtools__injected = true
62
+ iframe.src = devtoolsUrl
63
+ }
64
+
65
+ export function setTheme(value) {
66
+ theme = value
67
+ if (shareDataLoaded) {
68
+ SharedData.theme = value
69
+ }
70
+ }
71
+
72
+ // Modified from vue-devtools
73
+ export function forceEnable() {
74
+ if (!window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
75
+ return
76
+ }
77
+
78
+ let delay = 1000
79
+ let detectRemainingTries = 10
80
+
81
+ function runDetect() {
82
+ // Method 1: Check Nuxt.js
83
+ const nuxtDetected = !!(window.__NUXT__ || window.$nuxt)
84
+
85
+ if (nuxtDetected) {
86
+ let Vue
87
+
88
+ if (window.$nuxt) {
89
+ Vue = window.$nuxt.$root && window.$nuxt.$root.constructor
90
+ }
91
+
92
+ crack({
93
+ devtoolsEnabled:
94
+ (Vue && Vue.config.devtools) ||
95
+ (window.__VUE_DEVTOOLS_GLOBAL_HOOK__ &&
96
+ window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled),
97
+ vueDetected: true,
98
+ nuxtDetected: true,
99
+ })
100
+
101
+ return
102
+ }
103
+
104
+ // Method 2: Check Vue 3
105
+ const vueDetected = !!window.__VUE__
106
+ if (vueDetected) {
107
+ crack({
108
+ devtoolsEnabled:
109
+ window.__VUE_DEVTOOLS_GLOBAL_HOOK__ &&
110
+ window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled,
111
+ vueDetected: true,
112
+ })
113
+
114
+ return
115
+ }
116
+
117
+ // Method 3: Scan all elements inside document
118
+ const all = document.querySelectorAll('*')
119
+ let el
120
+ for (let i = 0; i < all.length; i++) {
121
+ if (all[i].__vue__) {
122
+ el = all[i]
123
+ break
124
+ }
125
+ }
126
+ if (el) {
127
+ let Vue = Object.getPrototypeOf(el.__vue__).constructor
128
+ while (Vue.super) {
129
+ Vue = Vue.super
130
+ }
131
+ crack({
132
+ devtoolsEnabled: Vue.config.devtools,
133
+ vueDetected: true,
134
+ })
135
+ return
136
+ }
137
+
138
+ if (detectRemainingTries > 0) {
139
+ detectRemainingTries--
140
+ setTimeout(() => {
141
+ runDetect()
142
+ }, delay)
143
+ delay *= 5
144
+ }
145
+ }
146
+
147
+ setTimeout(() => {
148
+ runDetect()
149
+ }, 100)
150
+ }
151
+
152
+ // https://github.com/hzmming/vue-force-dev
153
+ function crack(data) {
154
+ if (data.devtoolsEnabled) {
155
+ return
156
+ }
157
+
158
+ // Nuxt.js
159
+ if (data.nuxtDetected) {
160
+ let Vue
161
+
162
+ if (window.$nuxt) {
163
+ Vue = window.$nuxt.$root && window.$nuxt.$root.constructor
164
+ }
165
+
166
+ // Vue 2
167
+ if (Vue) {
168
+ crackVue2(Vue)
169
+ } else {
170
+ // Vue 3.2.14+
171
+ crackVue3()
172
+ }
173
+ }
174
+ // Vue 3
175
+ else if (window.__VUE__) {
176
+ crackVue3()
177
+ }
178
+ // Vue 2
179
+ else {
180
+ crackVue2()
181
+ }
182
+ }
183
+
184
+ function crackVue2(Vue) {
185
+ if (!Vue) {
186
+ const app = getVueRootInstance(2)
187
+ if (!app) return false // Vue may not be finished yet
188
+ Vue = Object.getPrototypeOf(app).constructor
189
+ while (Vue.super) {
190
+ Vue = Vue.super
191
+ }
192
+ }
193
+
194
+ const devtools = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
195
+ Vue.config.devtools = true
196
+ devtools.emit('init', Vue)
197
+ }
198
+
199
+ function crackVue3() {
200
+ const app = getVueRootInstance(3)
201
+ if (!app) return false // Vue may not be finished yet
202
+ const devtools = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
203
+ devtools.enabled = true
204
+ const version = app.version
205
+ devtools.emit('app:init' /* APP_INIT */, app, version, {
206
+ Fragment: Symbol.for('v-fgt'),
207
+ Text: Symbol.for('v-txt'),
208
+ Comment: Symbol.for('v-cmt'),
209
+ Static: Symbol.for('v-stc'),
210
+ })
211
+ }
212
+
213
+ function getVueRootInstance(version) {
214
+ const signProperty = version === 2 ? '__vue__' : '__vue_app__'
215
+ const all = document.querySelectorAll('*')
216
+ for (let i = 0; i < all.length; i++) {
217
+ if (all[i][signProperty]) {
218
+ return all[i][signProperty]
219
+ }
220
+ }
221
+ }
src/index.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { initDevtools, setTheme, installHook, forceEnable } = require('./back')
2
+
3
+ module.exports = function (eruda) {
4
+ let { evalCss } = eruda.util
5
+
6
+ class Vue extends eruda.Tool {
7
+ constructor() {
8
+ super()
9
+ this.name = 'vue'
10
+ this._style = evalCss(require('./style.scss'))
11
+ }
12
+ init($el, container) {
13
+ super.init($el, container)
14
+ $el.html('<iframe class="eruda-vue-devtools"></iframe>')
15
+ const iframe = $el.find('.eruda-vue-devtools').get(0)
16
+
17
+ installHook()
18
+ forceEnable()
19
+ initDevtools(iframe)
20
+
21
+ setTheme(this._getTheme())
22
+ eruda.get().config.on('change', this._onThemeChange)
23
+ }
24
+ show() {
25
+ super.show()
26
+ }
27
+ hide() {
28
+ super.hide()
29
+ }
30
+ destroy() {
31
+ super.destroy()
32
+ evalCss.remove(this._style)
33
+ }
34
+ _getTheme() {
35
+ return eruda.util.isDarkTheme() ? 'dark' : 'light'
36
+ }
37
+ _onThemeChange = (name) => {
38
+ if (name === 'theme') {
39
+ setTheme(this._getTheme())
40
+ }
41
+ }
42
+ }
43
+
44
+ return new Vue()
45
+ }
src/style.scss ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .vue {
2
+ padding: 0;
3
+ .tip {
4
+ padding: 10px;
5
+ background: #fff;
6
+ color: #263238;
7
+ }
8
+ .vue-devtools {
9
+ width: 100%;
10
+ height: 100%;
11
+ }
12
+ }
vue-devtools/.browserslistrc ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Chrome >= 52
2
+ Firefox >= 48
vue-devtools/.circleci/config.yml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ # specify the version you desire here
6
+ - image: node:current
7
+ - image: vuejs/ci
8
+ resource_class: medium+
9
+
10
+ working_directory: ~/repo
11
+
12
+ steps:
13
+ - checkout
14
+
15
+ # Download and cache dependencies
16
+ - restore_cache:
17
+ keys:
18
+ - v3-dependencies-{{ checksum "yarn.lock" }}
19
+ # fallback to using the latest cache if no exact match is found
20
+ - v3-dependencies-
21
+
22
+ - run: yarn install --pure-lockfile
23
+
24
+ - save_cache:
25
+ paths:
26
+ - node_modules
27
+ - ~/.cache/yarn
28
+ - ~/.cache/Cypress
29
+ key: v3-dependencies-{{ checksum "yarn.lock" }}
30
+
31
+ # run tests!
32
+ - run: yarn build && yarn test
33
+
34
+ - store_artifacts:
35
+ path: cypress/videos
36
+ - store_artifacts:
37
+ path: cypress/screenshots
vue-devtools/.github/FUNDING.yml ADDED
@@ -0,0 +1 @@
 
 
1
+ github: Akryum
vue-devtools/.github/ISSUE_TEMPLATE/bug_report.yml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: 🐞 Bug report
2
+ description: Create a report to help us improve
3
+ body:
4
+ - type: markdown
5
+ attributes:
6
+ value: |
7
+ **Before You Start...**
8
+
9
+ This form is only for submitting bug reports. If you have a usage question
10
+ or are unsure if this is really a bug, make sure to:
11
+
12
+ - Read the [docs](https://devtools.vuejs.org/)
13
+ - Read the [FAQ](https://devtools.vuejs.org/guide/faq.html)
14
+ - Ask on [GitHub Discussions](https://github.com/vuejs/devtools/discussions)
15
+ - Ask on [Discord Chat](https://chat.vuejs.org/)
16
+
17
+ Also try to search for your issue - it may have already been answered or even fixed in the development branch.
18
+ However, if you find that an old, closed issue still persists in the latest version,
19
+ you should open a new issue using the form below instead of commenting on the old issue.
20
+ - type: input
21
+ id: version
22
+ attributes:
23
+ label: Vue devtools version
24
+ description: |
25
+ Open your browser Extensions page and find the Vue devtools extension. Then write in this field the version number shown next to the Vue devtools extension name.
26
+ validations:
27
+ required: true
28
+ - type: input
29
+ id: reproduction-link
30
+ attributes:
31
+ label: Link to minimal reproduction
32
+ description: |
33
+ The easiest way to provide a reproduction is by showing the bug in [The SFC Playground](https://sfc.vuejs.org/).
34
+ If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue).
35
+ If neither of these are suitable, you can always provide a GitHub repository.
36
+
37
+ The reproduction should be **minimal** - i.e. it should contain only the bare minimum amount of code needed
38
+ to show the bug. See [Bug Reproduction Guidelines](https://github.com/vuejs/core/blob/main/.github/bug-repro-guidelines.md) for more details.
39
+
40
+ Please do not just fill in a random link. The issue will be closed if no valid reproduction is provided.
41
+ placeholder: Reproduction Link
42
+ validations:
43
+ required: true
44
+ - type: textarea
45
+ id: steps-to-reproduce
46
+ attributes:
47
+ label: Steps to reproduce & screenshots
48
+ description: |
49
+ What do we need to do after opening your repro in order to make the bug happen in the devtools? Clear and concise reproduction instructions are important for us to be able to triage your issue in a timely manner. Note that you can upload screenshots and use [Markdown](https://guides.github.com/features/mastering-markdown/) to format lists and code.
50
+ placeholder: Steps to reproduce
51
+ validations:
52
+ required: true
53
+ - type: textarea
54
+ id: expected
55
+ attributes:
56
+ label: What is expected?
57
+ validations:
58
+ required: true
59
+ - type: textarea
60
+ id: actually-happening
61
+ attributes:
62
+ label: What is actually happening?
63
+ validations:
64
+ required: true
65
+ - type: textarea
66
+ id: system-info
67
+ attributes:
68
+ label: System Info
69
+ description: Output of `npx envinfo --system --npmPackages vue --binaries --browsers`
70
+ render: shell
71
+ placeholder: System, Binaries, Browsers
72
+ validations:
73
+ required: true
74
+ - type: textarea
75
+ id: additional-comments
76
+ attributes:
77
+ label: Any additional comments?
78
+ description: e.g. some background/context of how you ran into this bug.
vue-devtools/.github/ISSUE_TEMPLATE/config.yml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: I have a performance issue
4
+ url: https://devtools.vuejs.org/guide/devtools-perf.html
5
+ about: Follow the guide to share performance profiling data with us!
6
+ - name: Questions & Discussions
7
+ url: https://github.com/vuejs/devtools/discussions
8
+ about: Use GitHub discussions for message-board style questions and discussions.
9
+ - name: Discord Chat
10
+ url: https://chat.vuejs.org
11
+ about: Ask questions and discuss with other Vue users in real time.
12
+ - name: GitHub Sponsor
13
+ url: https://github.com/sponsors/Akryum
14
+ about: Love the Vue devtools? Please consider supporting us via GitHub sponsors.
vue-devtools/.github/ISSUE_TEMPLATE/feature_request.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: 🚀 New feature proposal
2
+ description: Suggest an idea for this project
3
+ labels: [':sparkles: feature request']
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ **Before You Start...**
9
+
10
+ This form is only for submitting feature requests. If you have a usage question
11
+ or are unsure if this is really a bug, make sure to:
12
+
13
+ - Read the [docs](https://devtools.vuejs.org/)
14
+ - Read the [FAQ](https://devtools.vuejs.org/guide/faq.html)
15
+ - Ask on [GitHub Discussions](https://github.com/vuejs/devtools/discussions)
16
+ - Ask on [Discord Chat](https://chat.vuejs.org/)
17
+
18
+ Also try to search for your issue - another user may have already requested something similar!
19
+
20
+ - type: textarea
21
+ id: problem-description
22
+ attributes:
23
+ label: What problem does this feature solve?
24
+ description: |
25
+ Explain your use case, context, and rationale behind this feature request. More importantly, what is the **end user experience** you are trying to build that led to the need for this feature?
26
+ placeholder: Problem description
27
+ validations:
28
+ required: true
vue-devtools/.github/PULL_REQUEST_TEMPLATE.md ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- Thank you for contributing! -->
2
+
3
+ ### Description
4
+
5
+ <!-- Please insert your description here and provide especially info about the "what" this PR is solving -->
6
+
7
+ ### Additional context
8
+
9
+ <!-- e.g. is there anything you'd like reviewers to focus on? -->
10
+
11
+ ---
12
+
13
+ ### What is the purpose of this pull request? <!-- (put an "X" next to an item) -->
14
+
15
+ - [ ] Bug fix
16
+ - [ ] New Feature
17
+ - [ ] Documentation update
18
+ - [ ] Other
19
+
20
+ ### Before submitting the PR, please make sure you do the following
21
+
22
+ - [ ] Read the [Contributing Guidelines](https://devtools.vuejs.org/guide/contributing.html).
23
+ - [ ] Read the [Pull Request Guidelines](https://devtools.vuejs.org/guide/contributing.html#pull-request-guidelines) and follow the [Commit Convention](https://github.com/vuejs/devtools/blob/main/.github/commit-convention.md).
24
+ - [ ] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
25
+ - [ ] Provide a description in this PR that addresses **what** the PR is solving, or reference the issue that it solves (e.g. `fixes #123`).
26
+ <!-- @TODO tests - [ ] Ideally, include relevant tests that fail without this PR but pass with it. -->
vue-devtools/.github/commit-convention.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Git Commit Message Convention
2
+
3
+ > This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular).
4
+
5
+ #### TL;DR:
6
+
7
+ Messages must be matched by the following regex:
8
+
9
+ <!-- prettier-ignore -->
10
+ ```js
11
+ /^(revert: )?(feat|fix|docs|dx|refactor|perf|test|workflow|build|ci|chore|types|wip|release|deps)(\(.+\))?: .{1,50}/
12
+ ```
13
+
14
+ #### Examples
15
+
16
+ Appears under "Features" header, `dev` subheader:
17
+
18
+ ```
19
+ feat(dev): add 'comments' option
20
+ ```
21
+
22
+ Appears under "Bug Fixes" header, `dev` subheader, with a link to issue #28:
23
+
24
+ ```
25
+ fix(dev): fix dev error
26
+
27
+ close #28
28
+ ```
29
+
30
+ Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
31
+
32
+ ```
33
+ perf(build): remove 'foo' option
34
+
35
+ BREAKING CHANGE: The 'foo' option has been removed.
36
+ ```
37
+
38
+ The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
39
+
40
+ ```
41
+ revert: feat(compiler): add 'comments' option
42
+
43
+ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
44
+ ```
45
+
46
+ ### Full Message Format
47
+
48
+ A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
49
+
50
+ ```
51
+ <type>(<scope>): <subject>
52
+ <BLANK LINE>
53
+ <body>
54
+ <BLANK LINE>
55
+ <footer>
56
+ ```
57
+
58
+ The **header** is mandatory and the **scope** of the header is optional.
59
+
60
+ ### Revert
61
+
62
+ If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body, it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
63
+
64
+ ### Type
65
+
66
+ If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However, if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.
67
+
68
+ Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.
69
+
70
+ ### Scope
71
+
72
+ The scope could be anything specifying the place of the commit change. For example `dev`, `build`, `workflow`, `cli` etc...
73
+
74
+ ### Subject
75
+
76
+ The subject contains a succinct description of the change:
77
+
78
+ - use the imperative, present tense: "change" not "changed" nor "changes"
79
+ - don't capitalize the first letter
80
+ - no dot (.) at the end
81
+
82
+ ### Body
83
+
84
+ Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
85
+ The body should include the motivation for the change and contrast this with previous behavior.
86
+
87
+ ### Footer
88
+
89
+ The footer should contain any information about **Breaking Changes** and is also the place to
90
+ reference GitHub issues that this commit **Closes**.
91
+
92
+ **Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
vue-devtools/.github/workflows/create-release.yml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Create release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build:
10
+ name: Create Release
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@master
15
+ with:
16
+ fetch-depth: 0 # Fetch all tags
17
+
18
+ - name: Create Release for Tag
19
+ id: release_tag
20
+ uses: Akryum/[email protected]
21
+ env:
22
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23
+ with:
24
+ tag_name: ${{ github.ref }}
vue-devtools/.gitignore ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ node_modules
2
+ .DS_Store
3
+ build
4
+ /dist/*
5
+ *.zip
6
+ *.xpi
7
+ tests_output
8
+ selenium-debug.log
9
+ TODOs.md
10
+ .idea
11
+ .web-extension-id
12
+ yarn-error.log
13
+
14
+ /packages/*/lib
15
+ .amo.env.json
16
+ build-node
vue-devtools/.vscode/settings.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "typescript.tsdk": "node_modules/typescript/lib"
3
+ }
vue-devtools/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-present Evan You
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
vue-devtools/README.md ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Try the next iteration of Vue Devtools!
2
+
3
+ We have a brand new version of Devtools being developed at [vuejs/devtools-next](https://github.com/vuejs/devtools-next). It is now in beta, please help us [test it out](https://devtools-next.vuejs.org/getting-started/installation)!
4
+
5
+ ---
6
+
7
+ # vue-devtools
8
+
9
+ ![screenshot](./media/screenshot-shadow.png)
10
+
11
+ [Documentation](https://devtools.vuejs.org/) | [Install the extension](https://devtools.vuejs.org/guide/installation.html)
12
+
13
+ ## Monorepo
14
+
15
+ |Package|Description|
16
+ |-------|-----------|
17
+ [api](./packages/api) | The public devtools API that can be installed in Vue plugins |
18
+ [app-backend-api](./packages/app-backend-api) | Abstract API to link the Public API, the core and Vue handlers |
19
+ [app-backend-core](./packages/app-backend-core) | The main logic injected in the page to interact with Vue apps |
20
+ [app-backend-vue1](./packages/app-backend-vue1) | Decoupled handlers to support Vue 1 (soon) |
21
+ [app-backend-vue2](./packages/app-backend-vue2) | Decoupled handlers to support Vue 2 |
22
+ [app-backend-vue3](./packages/app-backend-vue3) | Decoupled handlers to support Vue 3 |
23
+ [app-frontend](./packages/app-frontend) | Vue app displayed in the browser devtools pane |
24
+ [shell-chrome](./packages/shell-chrome) | Chrome/Firefox extension |
25
+ [shell-electron](./packages/shell-electron) | Electron standalone app |
26
+ [shell-host](./packages/shell-host) | Development environment |
27
+ [shell-dev-vue2](./packages/shell-dev-vue2) | Demo app for development (Vue 2) |
28
+ [shell-dev-vue3](./packages/shell-dev-vue3) | Demo app for development (Vue 3) |
29
+
30
+ ## Contributing
31
+
32
+ See the [Contributing guide](https://devtools.vuejs.org/guide/contributing.html).
33
+
34
+ ## License
35
+
36
+ [MIT](http://opensource.org/licenses/MIT)
37
+
38
+ ## Sponsors
39
+
40
+ [💚️ Become a Sponsor](https://github.com/sponsors/Akryum)
41
+
42
+ <p align="center">
43
+ <a href="https://guillaume-chau.info/sponsors/" target="_blank">
44
+ <img src='https://akryum.netlify.app/sponsors.svg'/>
45
+ </a>
46
+ </p>
vue-devtools/babel.config.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ root: true,
3
+ presets: [
4
+ [
5
+ '@babel/env',
6
+ {
7
+ modules: false,
8
+ },
9
+ ],
10
+ ],
11
+ }
vue-devtools/cypress.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "viewportWidth": 1280,
3
+ "viewportHeight": 800,
4
+ "chromeWebSecurity": false
5
+ }
vue-devtools/cypress/.eslintrc.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: [
3
+ 'cypress',
4
+ ],
5
+ env: {
6
+ 'mocha': true,
7
+ 'cypress/globals': true,
8
+ },
9
+ rules: {
10
+ strict: 'off',
11
+ },
12
+ }
vue-devtools/cypress/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ /screenshots
2
+ /videos
vue-devtools/cypress/fixtures/example.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "name": "Using fixtures to represent data",
3
+ "email": "[email protected]",
4
+ "body": "Fixtures are a great way to mock data for responses to routes"
5
+ }
vue-devtools/cypress/integration/component-data-edit.js ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { suite } from '../utils/suite'
2
+
3
+ suite('component data edit', () => {
4
+ it('should edit data using the decrease button', () => {
5
+ // select Instance
6
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
7
+ cy.get('.component-state-inspector .data-type').should('contain', 'data')
8
+ cy.get('.data-field').eq(7).find('.actions .vue-ui-button').eq(1).click({ force: true })
9
+ cy.get('.component-state-inspector').within(() => {
10
+ cy.get('.key').contains('0').parent().get('.value').contains('0')
11
+ })
12
+ cy.get('.data-field').eq(7).find('.actions .vue-ui-button').eq(1).click({ force: true })
13
+ cy.get('.component-state-inspector').within(() => {
14
+ cy.get('.key').contains('0').parent().contains('-1')
15
+ })
16
+
17
+ // expect DOM element to be updated
18
+ cy.get('#target').iframe().then(({ get }) => {
19
+ get('#target div').eq(0).contains('-1')
20
+ })
21
+ })
22
+
23
+ it('should edit data using the increase button', () => {
24
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
25
+ cy.get('.component-state-inspector .data-type').should('contain', 'data')
26
+ cy.get('.data-field').eq(7).find('.actions .vue-ui-button').eq(2).click({ force: true })
27
+ cy.get('.component-state-inspector').within(() => {
28
+ cy.get('.key').contains('0').parent().get('.value').contains('0')
29
+ })
30
+
31
+ // expect DOM element to be updated
32
+ cy.get('#target').iframe().then(({ get }) => {
33
+ get('#target div').eq(0).contains('0')
34
+ })
35
+ })
36
+
37
+ it('should edit data using the edit input', () => {
38
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
39
+ cy.get('.data-field').eq(7).find('.actions .vue-ui-button').eq(0).click({ force: true })
40
+
41
+ cy.get('.edit-input').type('12')
42
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
43
+
44
+ cy.get('.component-state-inspector').within(() => {
45
+ cy.get('.key').contains('0').parent().get('.value').contains('12')
46
+ })
47
+
48
+ // expect DOM element to be updated
49
+ cy.get('#target').iframe().then(({ get }) => {
50
+ get('#target div').eq(0).contains('12')
51
+ })
52
+ })
53
+
54
+ it('should add elements to array', () => {
55
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
56
+ cy.get('.data-field').eq(6).find('.actions .vue-ui-button').eq(1).click({ force: true })
57
+
58
+ cy.get('.edit-input').type('55')
59
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
60
+
61
+ cy.get('.data-field').eq(6).find('.children .data-field').should('have.length', '3', { timeout: 5000 })
62
+ cy.get('.component-state-inspector').within(() => {
63
+ cy.get('.key').contains('2').parent().get('.value').contains('55')
64
+ })
65
+
66
+ // expect DOM element to be updated
67
+ cy.get('#target').iframe().then(({ get }) => {
68
+ get('#target div').eq(4).contains('55')
69
+ })
70
+ })
71
+
72
+ it('should remove elements from array', () => {
73
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
74
+ cy.get('.data-field').eq(9).find('.actions .vue-ui-button').eq(3).click({ force: true })
75
+
76
+ cy.get('.data-field').eq(6).find('.children .data-field').should('have.length', '2', { timeout: 5000 })
77
+ })
78
+
79
+ it('should parse object through edit input', () => {
80
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
81
+ cy.get('.data-field').eq(7).find('.actions .vue-ui-button').eq(0).click({ force: true })
82
+
83
+ cy.get('.edit-input').type('{{}"count":42}')
84
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
85
+
86
+ cy.get('.data-field').eq(7).should('contain', 'Object', { timeout: 5000 })
87
+ // expand object
88
+ cy.get('.data-field').eq(7).click()
89
+ cy.get('.data-field').eq(8).find('.key').should('contain', 'count', { timeout: 5000 })
90
+ cy.get('.data-field').eq(8).find('.value').should('contain', 42, { timeout: 5000 })
91
+ })
92
+
93
+ it('should rename object\'s property', () => {
94
+ cy.get('.instance:nth-child(1) .instance:nth-child(2)').eq(0).click()
95
+ cy.get('.data-field').eq(8).find('.actions .vue-ui-button').eq(0).click({ force: true })
96
+ cy.get('.edit-input.key-input').clear().type('name')
97
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
98
+
99
+ cy.get('.data-field').eq(8).find('.key').should('contain', 'name', { timeout: 5000 })
100
+ })
101
+ })
vue-devtools/cypress/integration/components-tab.js ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { suite } from '../utils/suite'
2
+
3
+ const baseInstanceCount = 12
4
+
5
+ suite('components tab', () => {
6
+ beforeEach(() => cy.reload())
7
+
8
+ it('should detect instances inside shadow DOM', () => {
9
+ cy.get('.tree > .instance:last-child').contains('Shadow')
10
+ })
11
+
12
+ it('should select instance', () => {
13
+ cy.get('.instance .self').eq(0).click().should('have.class', 'selected')
14
+ cy.get('.tree').should('be.visible')
15
+ cy.get('.action-header .title').contains('Root')
16
+ cy.get('.data-field').contains('$route')
17
+ })
18
+
19
+ it('should expand root by default', () => {
20
+ cy.get('.instance').should('have.length', baseInstanceCount)
21
+ })
22
+
23
+ it('should detect functional components', () => {
24
+ cy.get('.tree > .instance .instance:nth-child(2)').within(() => {
25
+ cy.get('.arrow').click().then(() => {
26
+ cy.get('.instance:last-child').contains('Functional')
27
+ })
28
+ })
29
+ })
30
+
31
+ it('should display 0 key', () => {
32
+ cy.get('.tree > .instance .instance:nth-child(2)').within(() => {
33
+ cy.get('.arrow').click().then(() => {
34
+ cy.get('.instance:nth-child(3) .attr').contains('key=0')
35
+ })
36
+ })
37
+ })
38
+
39
+ it('should detect components in transition', () => {
40
+ cy.get('.tree > .instance .instance:nth-child(7)').within(() => {
41
+ cy.get('.arrow').click().then(() => {
42
+ cy.get('.instance').eq(1).within(() => {
43
+ cy.get('.arrow').click().then(() => {
44
+ cy.get('.instance').contains('TestComponent')
45
+ })
46
+ })
47
+ })
48
+ })
49
+ })
50
+
51
+ it('should select child instance', () => {
52
+ cy.get('.instance .instance:nth-child(1) .self').eq(0).click()
53
+ cy.get('.action-header .title').contains('Counter')
54
+ cy.get('.data-el.vuex-bindings .data-field').contains('count:0')
55
+ cy.get('.data-el.computed .data-field').contains('test:1')
56
+ cy.get('.data-el.firebase-bindings .data-field').contains('hello:undefined')
57
+ })
58
+
59
+ it('should display prop of different types', () => {
60
+ cy.get('.instance .instance:nth-child(2) .self').eq(0).click()
61
+ cy.get('.action-header .title').contains('Target')
62
+ cy.get('.data-el.props .data-field:nth-child(1)').contains('ins:Object')
63
+ cy.get('.data-el.props .data-field:nth-child(2)').contains('msg:"hi"')
64
+ cy.get('.data-el.props .data-field:nth-child(3)').contains('obj:undefined')
65
+ // Regexp
66
+ cy.get('.data-el.data .data-field:nth-child(8)').then((el) => {
67
+ expect(el.text()).to.include('regex:/(a\\w+b)/g')
68
+ })
69
+ // Literals
70
+ cy.get('.data-el.data .data-field:nth-child(5)').contains('NaN')
71
+ cy.get('.data-el.data .data-field:nth-child(2)').contains('Infinity')
72
+ cy.get('.data-el.data .data-field:nth-child(6)').contains('-Infinity')
73
+ })
74
+
75
+ it('should expand child instance', () => {
76
+ cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
77
+ cy.get('.instance').should('have.length', baseInstanceCount + 10)
78
+ })
79
+
80
+ it('should add/remove component from app side', () => {
81
+ cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
82
+ cy.get('.instance').should('have.length', baseInstanceCount + 10)
83
+ cy.get('#target').iframe().then(({ get }) => {
84
+ get('.add').click({ force: true })
85
+ })
86
+ cy.get('.instance').should('have.length', baseInstanceCount + 13)
87
+ cy.get('#target').iframe().then(({ get }) => {
88
+ get('.remove').click({ force: true })
89
+ })
90
+ cy.get('.instance').should('have.length', baseInstanceCount + 12)
91
+ })
92
+
93
+ it('should filter components', () => {
94
+ cy.get('.left .search input').clear().type('counter')
95
+ cy.get('.instance').should('have.length', 2)
96
+ cy.get('.left .search input').clear().type('target')
97
+ cy.get('.instance').should('have.length', 12)
98
+ cy.get('.left .search input').clear()
99
+ })
100
+
101
+ it('should select component', () => {
102
+ cy.get('.select-component').click()
103
+ cy.get('#target').iframe().then(({ get }) => {
104
+ get('.mine').eq(0)
105
+ .trigger('mouseover', { force: true })
106
+ .click({ force: true })
107
+ })
108
+ cy.get('.action-header .title').contains('Mine')
109
+ cy.get('.tree').then((el) => {
110
+ expect(el.text()).to.include('<Mine>')
111
+ })
112
+ })
113
+
114
+ it('should display render key', () => {
115
+ cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
116
+ cy.get('.instance .self .attr-title').contains('key')
117
+ cy.get('.instance .self .attr-value').contains('1')
118
+ })
119
+
120
+ it('should display injected props', () => {
121
+ cy.get('.left .search input').clear().type('Mine')
122
+ cy.get('.instance').eq(1).click()
123
+ cy.get('.right .data-wrapper')
124
+ .should('contain', 'injected')
125
+ .should('contain', 'answer:42')
126
+ .should('contain', 'foo:"bar"')
127
+ .should('contain', 'noop:ƒ noop(a, b, c)')
128
+ cy.get('.left .search input').clear()
129
+ })
130
+
131
+ it('should display $refs', () => {
132
+ cy.get('.instance .item-name').contains('RefTester').click()
133
+ cy.get('.right .data-wrapper')
134
+ .should('contain', 'list:Array[4]')
135
+ .should('contain', '<li>')
136
+ .should('contain', 'tester:<p id="testing"')
137
+ })
138
+
139
+ it('should display $attrs', () => {
140
+ cy.get('.instance .instance:nth-child(2) .arrow-wrapper').click()
141
+ cy.get('.instance .instance .instance:nth-child(1) .item-name').click()
142
+ cy.get('.right .data-wrapper')
143
+ .should('contain', '$attrs')
144
+ .should('contain', 'attr:"some-attr"')
145
+ })
146
+ })
vue-devtools/cypress/integration/events-tab.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { suite } from '../utils/suite'
2
+
3
+ suite('events tab', () => {
4
+ it('should display new events counter', () => {
5
+ cy.get('#target').iframe().then(({ get }) => {
6
+ get('.btn-emit-event').click({ force: true })
7
+ get('.btn-emit-event1').click({ force: true })
8
+ get('.btn-emit-event2').click({ force: true })
9
+ })
10
+ cy.get('.events-tab .tag').contains(3)
11
+ cy.get('.events-tab').click()
12
+ cy.get('.events-tab .tag').should('not.be.visible')
13
+ })
14
+
15
+ it('should display events', () => {
16
+ cy.get('.history .entry').should('have.length', 3)
17
+ })
18
+
19
+ it('should add event', () => {
20
+ cy.get('#target').iframe().then(({ get }) => {
21
+ get('.btn-emit-log-event').click({ force: true })
22
+ })
23
+ cy.get('.history .entry').should('have.length', 4)
24
+ })
25
+
26
+ it('should search events', () => {
27
+ cy.get('.left .search input').clear().type('event')
28
+ cy.get('.history .entry[data-active="true"]').should('have.length', 3)
29
+ cy.get('.left .search input').clear().type('<eventchild1>')
30
+ cy.get('.history .entry[data-active="true"]').should('have.length', 1)
31
+ cy.get('.left .search input').clear().type('/^event$/')
32
+ cy.get('.history .entry[data-active="true"]').should('have.length', 1)
33
+ cy.get('.left .search input').clear()
34
+ cy.get('.button.reset').click()
35
+ cy.get('.history .entry[data-active="true"]').should('have.length', 0)
36
+ })
37
+ })
vue-devtools/cypress/integration/vuex-edit.js ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { suite } from '../utils/suite'
2
+
3
+ suite('vuex edit', () => {
4
+ it('should edit state using the decrease button', () => {
5
+ cy.get('.vuex-tab').click()
6
+ cy.get('[data-id="load-vuex-state"]').click()
7
+
8
+ // using the decrease button
9
+ cy.get('.state .data-field').eq(0)
10
+ .find('.actions .vue-ui-button').eq(1)
11
+ .click({ force: true })
12
+
13
+ cy.get('.vuex-state-inspector').within(() => {
14
+ cy.get('.key').contains('count').parent().contains('-1')
15
+ })
16
+
17
+ cy.get('.state .data-field').eq(0)
18
+ .find('.actions .vue-ui-button').eq(1)
19
+ .click({ force: true })
20
+
21
+ cy.get('.vuex-state-inspector').within(() => {
22
+ cy.get('.key').contains('count').parent().contains('-2')
23
+ })
24
+
25
+ cy.get('#target').iframe().then(({ get }) => {
26
+ get('#counter p').contains('-2')
27
+ })
28
+ })
29
+
30
+ it('should edit state using the increase button', () => {
31
+ // using the increase button
32
+ cy.get('.state .data-field').eq(0).click()
33
+ .find('.actions .vue-ui-button').eq(2)
34
+ .click({ force: true })
35
+
36
+ cy.get('.vuex-state-inspector').within(() => {
37
+ cy.get('.key').contains('count').parent().contains('-1')
38
+ })
39
+
40
+ cy.get('.state .data-field').eq(0).click()
41
+ .find('.actions .vue-ui-button').eq(2)
42
+ .click({ force: true })
43
+
44
+ cy.get('.vuex-state-inspector').within(() => {
45
+ cy.get('.key').contains('count').parent().contains('0')
46
+ })
47
+
48
+ cy.get('#target').iframe().then(({ get }) => {
49
+ get('#counter p').contains('0')
50
+ })
51
+ })
52
+
53
+ it('should edit state using the edit input', () => {
54
+ // using the edit input
55
+ cy.get('.state .data-field').eq(0).click()
56
+ .find('.actions .vue-ui-button').eq(0).click({ force: true })
57
+ cy.get('.edit-input').type('12')
58
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
59
+
60
+ cy.wait(200)
61
+ cy.get('#target').iframe().then(({ get }) => {
62
+ get('#counter p').contains('12')
63
+ })
64
+
65
+ // change count back to 1
66
+ cy.get('.state .data-field').eq(0).click()
67
+ .find('.actions .vue-ui-button').eq(0).click({ force: true })
68
+ cy.get('.edit-input').type('0')
69
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
70
+
71
+ cy.wait(200)
72
+ cy.get('#target').iframe().then(({ get }) => {
73
+ get('#counter p').contains('0')
74
+ })
75
+ })
76
+
77
+ it('should edit state nested field', () => {
78
+ // using the decrease button
79
+ cy.get('.data-field > .children > .data-field').eq(4)
80
+ .find('.actions .vue-ui-button').eq(1)
81
+ .click({ force: true })
82
+ .click({ force: true })
83
+
84
+ cy.wait(200)
85
+ cy.get('#target').iframe().then(({ get }) => {
86
+ get('#vuex-object pre').contains('-2')
87
+ })
88
+
89
+ // using the increase button
90
+ cy.get('.data-field > .children > .data-field').eq(4)
91
+ .find('.actions .vue-ui-button').eq(2)
92
+ .click({ force: true })
93
+ .click({ force: true })
94
+
95
+ cy.wait(200)
96
+ cy.get('#target').iframe().then(({ get }) => {
97
+ get('#vuex-object pre').contains('0')
98
+ })
99
+
100
+ // using the input
101
+ cy.get('.data-field > .children > .data-field').eq(4)
102
+ .find('.actions .vue-ui-button').eq(0).click({ force: true })
103
+ cy.get('.edit-input').eq(1).type('12')
104
+ cy.get('.edit-overlay > .actions > :nth-child(2) > .content > .vue-ui-icon').click()
105
+
106
+ cy.wait(200)
107
+ cy.get('#target').iframe().then(({ get }) => {
108
+ get('#vuex-object pre').contains('12')
109
+ })
110
+ })
111
+ })
vue-devtools/cypress/integration/vuex-tab.js ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { suite } from '../utils/suite'
2
+
3
+ suite('vuex tab', () => {
4
+ it('should display mutations history', () => {
5
+ cy.get('#target').iframe().then(({ get }) => {
6
+ get('.increment')
7
+ .click({ force: true })
8
+ .click({ force: true })
9
+ get('.decrement').click({ force: true })
10
+ get('#counter p').contains('1')
11
+ })
12
+ cy.get('.vuex-tab').click()
13
+ cy.get('.history .entry').should('have.length', 6)
14
+ cy.get('[data-id="load-vuex-state"]').click()
15
+ cy.get('.recording-vuex-state').should('not.be.visible')
16
+ cy.get('.loading-vuex-state').should('not.be.visible')
17
+ cy.get('.vuex-state-inspector')
18
+ .should('contain', 'type:"DECREMENT"')
19
+ .should('contain', 'count:1')
20
+ cy.get('.history .entry').eq(5).should('have.class', 'inspected').should('have.class', 'active')
21
+ })
22
+
23
+ it('should filter state & getters', () => {
24
+ cy.get('.right .search input').clear().type('cou')
25
+ cy.get('.data-field').should('have.length', 2)
26
+ cy.get('.right .search input').clear().type('no value')
27
+ cy.get('.data-field').should('have.length', 0)
28
+ cy.get('.right .search input').clear()
29
+ })
30
+
31
+ it('should filter history', () => {
32
+ cy.get('.left .search input').clear().type('inc')
33
+ cy.get('.history .entry[data-active="true"]').should('have.length', 2)
34
+ cy.get('.history .entry[data-active="true"].inspected').should('have.length', 0)
35
+ cy.get('.history .entry[data-active="true"].active').should('have.length', 0)
36
+
37
+ cy.get('.left .search input').clear().type('/dec/i')
38
+ cy.get('.history .entry[data-active="true"]').should('have.length', 1)
39
+ cy.get('.history .entry[data-active="true"].inspected').should('have.length', 0)
40
+ cy.get('.history .entry[data-active="true"].active').should('have.length', 0)
41
+
42
+ cy.get('.left .search input').clear().type('/dec)/i')
43
+ cy.get('.history .entry[data-active="true"]').should('have.length', 5)
44
+ cy.get('.history .entry[data-active="true"].inspected').should('have.length', 0)
45
+ cy.get('.history .entry[data-active="true"].active').should('have.length', 1)
46
+
47
+ cy.get('.left .search input').clear()
48
+ })
49
+
50
+ it('should inspect state', () => {
51
+ cy.get('.history .entry .mutation-type').eq(2).click()
52
+ cy.get('.history .entry').eq(2)
53
+ .should('have.class', 'inspected')
54
+ .should('not.have.class', 'active')
55
+ cy.get('.recording-vuex-state').should('not.be.visible')
56
+ cy.get('.loading-vuex-state').should('not.be.visible')
57
+ cy.get('.vuex-state-inspector').then((el) => {
58
+ expect(el.text()).to.include('type:"INCREMENT"')
59
+ expect(el.text()).to.include('count:2')
60
+ expect(el.text()).to.include('Error from getter')
61
+ })
62
+ cy.get('.data-field .key').contains('lastCountPayload').click()
63
+ cy.get('.vuex-state-inspector').then((el) => {
64
+ expect(el.text()).to.include('a:1')
65
+ expect(el.text()).to.include('b:Object')
66
+ })
67
+ cy.get('#target').iframe().then(({ get }) => {
68
+ get('#counter p').contains('1')
69
+ })
70
+ })
71
+
72
+ it('should time-travel', () => {
73
+ cy.get('.history .entry[data-index="4"] .entry-actions .action-time-travel').click({ force: true })
74
+ cy.get('.history .entry[data-index="4"]')
75
+ .should('have.class', 'inspected')
76
+ .should('have.class', 'active')
77
+ cy.get('#target').iframe().then(({ get }) => {
78
+ get('#counter p').contains('2')
79
+ })
80
+
81
+ cy.get('.history .entry[data-index="3"] .mutation-type').click({ force: true })
82
+ cy.get('.history .entry[data-index="3"]')
83
+ .should('have.class', 'inspected')
84
+ .should('not.have.class', 'active')
85
+ cy.get('.history .entry[data-index="4"]')
86
+ .should('not.have.class', 'inspected')
87
+ .should('have.class', 'active')
88
+ cy.get('.recording-vuex-state').should('not.be.visible')
89
+ cy.get('.loading-vuex-state').should('not.be.visible')
90
+ cy.get('.recording-vuex-state').should('not.be.visible')
91
+ cy.get('.vuex-state-inspector').then((el) => {
92
+ expect(el.text()).to.include('type:"INCREMENT"')
93
+ expect(el.text()).to.include('count:1')
94
+ })
95
+ cy.get('#target').iframe().then(({ get }) => {
96
+ get('#counter p').contains('2')
97
+ })
98
+ cy.get('.history .entry[data-index="3"] .entry-actions .action-time-travel').click({ force: true })
99
+ cy.get('.history .entry[data-index="3"]')
100
+ .should('have.class', 'inspected')
101
+ .should('have.class', 'active')
102
+ cy.get('.history .entry[data-index="4"]')
103
+ .should('not.have.class', 'inspected')
104
+ .should('not.have.class', 'active')
105
+ cy.get('#target').iframe().then(({ get }) => {
106
+ get('#counter p').contains('1')
107
+ })
108
+
109
+ // Base state
110
+ cy.get('.history .entry[data-index="0"] .mutation-type').click({ force: true })
111
+ cy.get('.history .entry[data-index="0"]')
112
+ .should('have.class', 'inspected')
113
+ .should('not.have.class', 'active')
114
+ cy.get('.vuex-state-inspector').then((el) => {
115
+ expect(el.text()).to.include('count:0')
116
+ })
117
+ cy.get('#target').iframe().then(({ get }) => {
118
+ get('#counter p').contains('1')
119
+ })
120
+ cy.get('.history .entry[data-index="2"] .entry-actions .action-time-travel').click({ force: true })
121
+ cy.get('.history .entry[data-index="2"]')
122
+ .should('have.class', 'inspected')
123
+ .should('have.class', 'active')
124
+ cy.get('#target').iframe().then(({ get }) => {
125
+ get('#counter p').contains('0')
126
+ })
127
+ })
128
+
129
+ it('should revert', () => {
130
+ cy.get('.history .entry[data-index="5"] .mutation-type').click({ force: true })
131
+ cy.get('.history .entry[data-index="5"]').find('.action-revert').click({ force: true })
132
+ cy.get('.history .entry[data-active="true"]').should('have.length', 5)
133
+ cy.get('.history .entry[data-index="4"]')
134
+ .should('have.class', 'inspected')
135
+ .should('have.class', 'active')
136
+ cy.get('.vuex-state-inspector').then((el) => {
137
+ expect(el.text()).to.include('count:2')
138
+ })
139
+ cy.get('#target').iframe().then(({ get }) => {
140
+ get('#counter p').contains('2')
141
+ })
142
+ })
143
+
144
+ it('should commit', () => {
145
+ cy.get('.history .entry[data-index="4"] .action-commit').click({ force: true })
146
+ cy.get('.history .entry[data-active="true"]').should('have.length', 1)
147
+ cy.get('.history .entry[data-index="0"]')
148
+ .should('have.class', 'inspected')
149
+ .should('have.class', 'active')
150
+ cy.get('.vuex-state-inspector').then((el) => {
151
+ expect(el.text()).to.include('count:2')
152
+ })
153
+ cy.get('#target').iframe().then(({ get }) => {
154
+ get('#counter p').contains('2')
155
+ })
156
+ })
157
+
158
+ it('should display getters', () => {
159
+ cy.get('.vuex-state-inspector').within(() => {
160
+ cy.get('.key').contains('count').parent().contains('2')
161
+ cy.get('.key').contains('isPositive').parent().contains('true')
162
+ })
163
+ cy.get('#target').iframe().then(({ get }) => {
164
+ get('.decrement')
165
+ .click({ force: true })
166
+ .click({ force: true })
167
+ .click({ force: true })
168
+ get('#counter p').contains('-1')
169
+ })
170
+ cy.get('.history .entry[data-index="3"]').click({ force: true })
171
+ cy.get('.recording-vuex-state').should('not.be.visible')
172
+ cy.get('.loading-vuex-state').should('not.be.visible')
173
+ cy.get('.vuex-state-inspector').within(() => {
174
+ cy.get('.key').contains('count').parent().contains('-1')
175
+ cy.get('.key').contains('isPositive').parent().contains('false')
176
+ })
177
+ })
178
+
179
+ it('should toggle recording', () => {
180
+ cy.get('.toggle-recording')
181
+ .click()
182
+ .contains('Paused')
183
+ cy.get('.toggle-recording .svg-icon').should('not.have.class', 'enabled')
184
+ // should not record
185
+ cy.get('#target').iframe().then(({ get }) => {
186
+ get('.increment').click({ force: true })
187
+ })
188
+ cy.get('.history .entry[data-active="true"]').should('have.length', 4)
189
+ })
190
+
191
+ it('should copy vuex state', () => {
192
+ cy.get('.export').click()
193
+ cy.get('.export .message')
194
+ .contains('(Copied to clipboard!)')
195
+ .should('not.be.visible', { timeout: 5000 })
196
+ })
197
+
198
+ it('should import vuex state', () => {
199
+ cy.get('.import').click()
200
+ cy.get('.import-state').should('be.visible')
201
+ cy.get('.import-state textarea').clear().type('{{}invalid: json}')
202
+ cy.get('.message.invalid-json').should('be.visible')
203
+ cy.get('.import-state textarea').clear().type('{{}"count":42,"date":"[native Date Fri Dec 22 2017 10:12:04 GMT+0100 (CET)]","nested":{{}"foo":"meow"},"instant":{{}"hey":"hi"}}')
204
+ cy.wait(500)
205
+ cy.get('.message.invalid-json').should('not.be.visible')
206
+ cy.wait(500)
207
+ cy.get('.vuex-state-inspector').then((el) => {
208
+ expect(el.text()).to.include('count:42')
209
+ expect(el.text()).to.include(`date:${new Date('Fri Dec 22 2017 10:12:04 GMT+0100 (CET)')}`)
210
+ })
211
+ cy.get('.import').click()
212
+ cy.get('.import-state').should('not.be.visible')
213
+ })
214
+ })
vue-devtools/cypress/plugins/index.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************************
2
+ // This example plugins/index.js can be used to load plugins
3
+ //
4
+ // You can change the location of this file or turn off loading
5
+ // the plugins file with the 'pluginsFile' configuration option.
6
+ //
7
+ // You can read more here:
8
+ // https://on.cypress.io/plugins-guide
9
+ // ***********************************************************
10
+
11
+ // This function is called when a project is opened or re-opened (e.g. due to
12
+ // the project's config changing)
13
+
14
+ module.exports = (_on, _config) => {
15
+ // `on` is used to hook into various events Cypress emits
16
+ // `config` is the resolved Cypress config
17
+
18
+ // on('before:browser:launch', (browser = {}, args) => {
19
+ // if (browser.name === 'chrome') {
20
+ // args.push('--disable-site-isolation-trials')
21
+ // return args
22
+ // }
23
+ // })
24
+ }
vue-devtools/cypress/support/commands.js ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************
2
+ // This example commands.js shows you how to
3
+ // create various custom commands and overwrite
4
+ // existing commands.
5
+ //
6
+ // For more comprehensive examples of custom
7
+ // commands please read more here:
8
+ // https://on.cypress.io/custom-commands
9
+ // ***********************************************
10
+ //
11
+ //
12
+ // -- This is a parent command --
13
+ // Cypress.Commands.add("login", (email, password) => { ... })
14
+ //
15
+ //
16
+ // -- This is a child command --
17
+ // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18
+ //
19
+ //
20
+ // -- This is a dual command --
21
+ // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22
+ //
23
+ //
24
+ // -- This is will overwrite an existing command --
25
+ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26
+
27
+ Cypress.Commands.add('vueCheckInit', () => {
28
+ cy.get('.message .text').should('be.visible', { timeout: 10000 }).then((el) => {
29
+ expect(el.text()).to.include('Ready. Detected Vue')
30
+ })
31
+ cy.get('.instance').eq(0).contains('Root')
32
+ })
33
+
34
+ // Add iframe support until becomes part of the framework
35
+ Cypress.Commands.add('iframe', { prevSubject: 'element' }, ($iframe) => {
36
+ const get = selector => cy.wait(500).wrap($iframe.contents().find(selector))
37
+
38
+ const el = $iframe[0]
39
+ const iframeDoc = el.contentDocument || el.contentWindow.document
40
+ if (iframeDoc.readyState === 'complete') {
41
+ return Cypress.Promise.resolve({ body: $iframe.contents().find('body'), get })
42
+ }
43
+ return new Cypress.Promise((resolve) => {
44
+ $iframe.on('load', () => {
45
+ resolve({ body: $iframe.contents().find('body'), get })
46
+ })
47
+ })
48
+ })
vue-devtools/cypress/support/index.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************************
2
+ // This example support/index.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')
vue-devtools/cypress/utils/suite.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ export function suite(description, tests) {
2
+ describe(description, () => {
3
+ before(() => {
4
+ cy.visit('/')
5
+ cy.vueCheckInit()
6
+ })
7
+ tests()
8
+ })
9
+ }
vue-devtools/dist/.gitkeep ADDED
File without changes
vue-devtools/eslint.config.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const antfu = require('@antfu/eslint-config').default
2
+
3
+ module.exports = antfu({
4
+ ignores: [
5
+ '**/dist',
6
+ ],
7
+ }, {
8
+ rules: {
9
+ 'curly': ['error', 'all'],
10
+ 'node/prefer-global/process': 'off',
11
+ },
12
+ }, {
13
+ files: [
14
+ 'packages/shell-dev*/**',
15
+ ],
16
+ rules: {
17
+ 'no-console': 'off',
18
+ 'unused-imports/no-unused-vars': 'off',
19
+ 'vue/require-explicit-emits': 'off',
20
+ 'vue/custom-event-name-casing': 'off',
21
+ 'vue/no-deprecated-functional-template': 'off',
22
+ 'vue/no-deprecated-filter': 'off',
23
+ 'vue/no-unused-refs': 'off',
24
+ 'vue/require-component-is': 'off',
25
+ 'vue/return-in-computed-property': 'off',
26
+ },
27
+ }, {
28
+ files: [
29
+ 'packages/shell-host/**',
30
+ ],
31
+ rules: {
32
+ 'no-console': 'off',
33
+ },
34
+ }, {
35
+ files: [
36
+ 'package.json',
37
+ 'packages/*/package.json',
38
+ 'packages/*/manifest.json',
39
+ ],
40
+ rules: {
41
+ 'style/eol-last': 'off',
42
+ },
43
+ })
vue-devtools/extension-zips.js ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // require modules
2
+ const fs = require('node:fs')
3
+ const path = require('node:path')
4
+ const process = require('node:process')
5
+ const archiver = require('archiver')
6
+
7
+ const IS_CI = !!(process.env.CIRCLECI || process.env.GITHUB_ACTIONS)
8
+ const ProgressBar = !IS_CI ? require('progress') : {}
9
+ const readDirGlob = !IS_CI ? require('readdir-glob') : {}
10
+
11
+ const INCLUDE_GLOBS = [
12
+ 'build/**',
13
+ 'icons/**',
14
+ 'popups/**',
15
+ 'devtools.html',
16
+ 'devtools-background.html',
17
+ 'manifest.json',
18
+ 'package.json',
19
+ ]
20
+ // SKIP_GLOBS makes glob searches more efficient
21
+ const SKIP_DIR_GLOBS = ['node_modules', 'src']
22
+
23
+ function bytesToSize(bytes) {
24
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
25
+ if (bytes === 0) {
26
+ return '0 Byte'
27
+ }
28
+ const i = Number.parseInt(Math.floor(Math.log(bytes) / Math.log(1024)))
29
+ return `${Math.round(bytes / 1024 ** i, 2)} ${sizes[i]}`
30
+ }
31
+
32
+ (async () => {
33
+ await writeZip('devtools-chrome.zip', 'shell-chrome')
34
+ await writeZip('devtools-firefox.zip', 'shell-firefox')
35
+
36
+ async function writeZip(fileName, packageDir) {
37
+ // create a file to stream archive data to.
38
+ const output = fs.createWriteStream(path.join(__dirname, 'dist', fileName))
39
+ const archive = archiver('zip', {
40
+ zlib: { level: 9 }, // Sets the compression level.
41
+ })
42
+
43
+ if (!IS_CI) {
44
+ const status = {
45
+ total: 0,
46
+ cFile: '...',
47
+ cSize: '0 Bytes',
48
+ tBytes: 0,
49
+ tSize: '0 Bytes',
50
+ }
51
+
52
+ async function parseFileStats() {
53
+ return new Promise((resolve, reject) => {
54
+ const globber = readDirGlob(path.join('packages', packageDir), { pattern: INCLUDE_GLOBS, skip: SKIP_DIR_GLOBS, mark: true, stat: true })
55
+ globber.on('match', (match) => {
56
+ if (!match.stat.isDirectory()) {
57
+ status.total++
58
+ }
59
+ })
60
+ globber.on('error', (err) => {
61
+ reject(err)
62
+ })
63
+ globber.on('end', () => {
64
+ resolve()
65
+ })
66
+ })
67
+ }
68
+ await parseFileStats().catch((err) => {
69
+ console.error(err)
70
+ process.exit(1)
71
+ })
72
+
73
+ const bar = new ProgressBar(`${fileName} @ :tSize [:bar] :current/:total :percent +:cFile@:cSize`, {
74
+ width: 18,
75
+ incomplete: ' ',
76
+ total: status.total,
77
+ })
78
+ bar.tick(0, status)
79
+
80
+ archive.on('entry', (entry) => {
81
+ if (!entry.stats.isDirectory()) {
82
+ const n = entry.name
83
+ status.written++
84
+ status.cFile = n.length > 14
85
+ ? `...${n.slice(n.length - 11)}`
86
+ : n
87
+ status.cSize = bytesToSize(entry.stats.size)
88
+ status.tBytes += entry.stats.size
89
+ status.tSize = bytesToSize(status.tBytes)
90
+ bar.tick(1, status)
91
+ }
92
+ })
93
+ }
94
+
95
+ const end = new Promise((resolve) => {
96
+ // listen for all archive data to be written
97
+ // 'close' event is fired only when a file descriptor is involved
98
+ output.on('close', () => {
99
+ if (archive.pointer() < 1000) {
100
+ console.warn(`Zip file (${fileName}) is only ${archive.pointer()} bytes`)
101
+ }
102
+ resolve()
103
+ })
104
+ })
105
+
106
+ // This event is fired when the data source is drained no matter what was the data source.
107
+ // It is not part of this library but rather from the NodeJS Stream API.
108
+ // @see: https://nodejs.org/api/stream.html#stream_event_end
109
+ output.on('end', () => {
110
+ 'nothing'
111
+ })
112
+
113
+ // good practice to catch warnings (ie stat failures and other non-blocking errors)
114
+ archive.on('warning', (err) => {
115
+ if (err.code !== 'ENOENT') {
116
+ // throw error
117
+ console.error(err)
118
+ process.exit(1)
119
+ }
120
+ })
121
+
122
+ // good practice to catch this error explicitly
123
+ archive.on('error', (err) => {
124
+ console.error(err)
125
+ process.exit(1)
126
+ })
127
+
128
+ // pipe archive data to the file
129
+ archive.pipe(output)
130
+
131
+ INCLUDE_GLOBS.forEach((glob) => {
132
+ // append files from a glob pattern
133
+ archive.glob(glob, { cwd: path.join('packages', packageDir), skip: SKIP_DIR_GLOBS })
134
+ })
135
+
136
+ // finalize the archive (ie we are done appending files but streams have to finish yet)
137
+ // 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
138
+ archive.finalize()
139
+
140
+ await end
141
+ }
142
+ })()
vue-devtools/lerna.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "npmClient": "yarn",
3
+ "useWorkspaces": true,
4
+ "version": "6.0.0-beta.2",
5
+ "packages": [
6
+ "packages/*"
7
+ ],
8
+ "ignoreChanges": [
9
+ "**/*.md"
10
+ ]
11
+ }
vue-devtools/media/chrome-webstore/screenshot1-size.png ADDED

Git LFS Details

  • SHA256: e3874b539d5004ce2941d13255d4b546ba466237ef6d10f5adbba031e5455cb1
  • Pointer size: 131 Bytes
  • Size of remote file: 130 kB
vue-devtools/media/chrome-webstore/screenshot1.png ADDED

Git LFS Details

  • SHA256: 9ac3cbf7afbade2a16a77c36b5866cc0404544533121016ccf46bab3c7f8c5ee
  • Pointer size: 131 Bytes
  • Size of remote file: 120 kB