├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── README.md
├── docs
├── .gitignore
├── docs
│ ├── .vitepress
│ │ └── config.ts
│ └── index.md
├── package.json
├── scripts
│ └── gh-pages-deploy.js
├── vite.config.ts
└── yarn.lock
├── vue-dd
├── LICENSE
├── README.md
├── cypress.config.js
├── cypress
│ └── support
│ │ ├── common.ts
│ │ ├── component-index.html
│ │ ├── component.js
│ │ └── router
│ │ ├── About.vue
│ │ ├── Home.vue
│ │ ├── Page.vue
│ │ └── routes.js
├── demo
│ ├── App.vue
│ ├── main.ts
│ └── vite.config.ts
├── index.html
├── package.json
├── src
│ ├── NodeComplex.vue
│ ├── NodePrimitive.vue
│ ├── VueDd.spec.js
│ ├── VueDd.vue
│ ├── XRay.vue
│ ├── assets
│ │ ├── eye-full.svg
│ │ ├── eye.svg
│ │ └── fonts
│ │ │ ├── vue-dd-icons.eot
│ │ │ ├── vue-dd-icons.svg
│ │ │ ├── vue-dd-icons.ttf
│ │ │ └── vue-dd-icons.woff
│ ├── components
│ │ ├── XRayCheckbox.vue
│ │ └── XRaySelect.vue
│ ├── css
│ │ ├── VueDd.code.css
│ │ └── VueDd.css
│ ├── features
│ │ ├── setupFormComponent.js
│ │ └── uniqueId.js
│ ├── helpers.js
│ ├── highlight.js
│ │ ├── core.min.js
│ │ └── javascript.min.js
│ ├── index.ts
│ ├── shims-vue.d.ts
│ └── types.ts
├── test
│ ├── __snapshots__
│ │ └── basic.test.ts.snap
│ ├── as-async.test.ts
│ ├── async.test.ts
│ ├── basic.test.ts
│ ├── components
│ │ ├── AsAsync.vue
│ │ ├── AsyncComp.vue
│ │ ├── AsyncWrapper.vue
│ │ └── Hello.vue
│ ├── imports.test.ts
│ └── vue-dd.test.ts
├── tsconfig.json
├── vite-env.d.ts
├── vite.config.ts
├── vitest.config.ts
└── yarn.lock
├── vue2
├── .gitignore
├── README.md
├── babel.config.js
├── jsconfig.json
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── VueDdTest.vue
│ └── main.js
├── vue.config.js
└── yarn.lock
└── vue3
├── .eslintrc.cjs
├── .gitignore
├── .prettierrc.json
├── .vscode
└── extensions.json
├── README.md
├── cypress.config.ts
├── cypress
├── e2e
│ ├── example.cy.ts
│ └── tsconfig.json
├── fixtures
│ └── example.json
└── support
│ ├── commands.ts
│ └── e2e.ts
├── env.d.ts
├── index.html
├── package.json
├── public
└── favicon.ico
├── src
├── App.vue
├── assets
│ ├── base.css
│ ├── logo.svg
│ └── main.css
├── components
│ ├── BaseCheckbox.vue
│ ├── VueDdApiTest.vue
│ ├── VueDdTest.vue
│ ├── VueDdTest2.vue
│ ├── __tests__
│ │ ├── HelloWorld.spec.ts
│ │ ├── HelloWorld.vue
│ │ └── WelcomeItem.vue
│ └── icons
│ │ ├── IconCommunity.vue
│ │ ├── IconDocumentation.vue
│ │ ├── IconEcosystem.vue
│ │ ├── IconSupport.vue
│ │ └── IconTooling.vue
├── features
│ ├── setupFormComponent.js
│ └── uniqueId.js
├── main.ts
├── router
│ └── index.ts
├── stores
│ └── counter.ts
└── views
│ ├── AboutView.vue
│ └── HomeView.vue
├── tsconfig.app.json
├── tsconfig.config.json
├── tsconfig.json
├── tsconfig.vitest.json
├── vite.config.ts
└── yarn.lock
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 | on: [ push ]
3 |
4 | jobs:
5 | build:
6 | name: vitest
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 |
11 | - name: Set Node.js 16.x
12 | uses: actions/setup-node@v3
13 | with:
14 | node-version: 16.x
15 |
16 | - name: yarn install
17 | uses: borales/actions-yarn@v4
18 | with:
19 | cmd: install # will run `yarn install` command
20 | dir: 'vue-dd'
21 | - name: vitest vue-dd
22 | uses: borales/actions-yarn@v4
23 | with:
24 | cmd: test # will run `yarn test` command
25 | dir: 'vue-dd'
26 | docs-deploy:
27 | name: deploy docs
28 | runs-on: ubuntu-latest
29 | steps:
30 | - uses: actions/checkout@v3
31 |
32 | - name: Set Node.js 16.x
33 | uses: actions/setup-node@v3
34 | with:
35 | node-version: 16.x
36 |
37 | - name: Setup git
38 | run: |
39 | git config user.name "Evgeny Kalashnikov" && git config user.email "ekalashnikov@gmail.com"
40 | - name: yarn install
41 | uses: borales/actions-yarn@v4
42 | with:
43 | cmd: install # will run `yarn install` command
44 | dir: 'docs'
45 | - name: deploy docs
46 | uses: borales/actions-yarn@v4
47 | with:
48 | cmd: deploy # will run `yarn deploy` command
49 | dir: 'docs'
50 | # docs-deploy:
51 | # name: Deploying to gh-pages
52 | # runs-on: ubuntu-latest
53 | # steps:
54 | # - name: Setup Node.js for use with actions
55 | # uses: actions/setup-node@v2
56 | # with:
57 | # version: 12.x
58 | # - name: Checkout branch
59 | # uses: actions/checkout@v2
60 | #
61 | # - name: Clean install dependencies
62 | # run: npm ci
63 | #
64 | # - name: Run deploy script
65 | # run: |
66 | # git config user.name "Evgeny Kalashnikov" && git config user.email "ekalashnikov@gmail.com"
67 | #
68 | # cmd: deploy
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .vscode
3 | node_modules
4 | yarn-error.log
5 | .DS_Store
6 | /extras
7 | dist
8 | .vite
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## vue-dd — object viewer [](https://www.npmjs.com/package/vue-dd) [](https://github.com/infinite-system/vue-dd/actions/workflows/ci.yml)
2 |
3 | **vue-dd** — pronounced *vúed* or *vue dd* — is a Vue 3 object viewer for displaying complex JavaScript objects, Vue Reactive and Ref objects, Functions, Maps, Sets, Symbols and all JavaScript Primitives in order to monitor their changes **live** with full reactivity. Inspired by the Laravels **dd()** debugging function.
4 |
5 | https://user-images.githubusercontent.com/150185/213549880-e6b645bd-11f0-461a-b1a9-29c70c52f2ad.mov
6 |
7 | https://user-images.githubusercontent.com/150185/213549905-360698e2-0c6b-4fd1-8023-803e22b68e27.mov
8 |
9 | Video example code in Vue 3 `
5 | # Coming soon
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vitepress-project",
3 | "private": true,
4 | "type": "module",
5 | "scripts": {
6 | "dev": "vitepress dev docs",
7 | "build": "vitepress build docs",
8 | "serve": "vitepress serve docs",
9 | "deploy": "node scripts/gh-pages-deploy.js"
10 | },
11 | "devDependencies": {
12 | "cpy-cli": "^4.2.0",
13 | "execa": "latest",
14 | "vitepress": "^1.0.0-rc.12",
15 | "vue": "3.2.44"
16 | },
17 | "pnpm": {
18 | "peerDependencyRules": {
19 | "ignoreMissing": [
20 | "@algolia/client-search"
21 | ]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/docs/scripts/gh-pages-deploy.js:
--------------------------------------------------------------------------------
1 | import { execa } from 'execa'
2 | // import fs from "fs"
3 |
4 | (async () => {
5 | try {
6 | var datetime = new Date();
7 |
8 | // this will save potential changes that might get lost if you didn't commit them
9 | await execa("git", ["stash", "push", "-m", "before deploy on " + datetime]);
10 | await execa("git", ["checkout", "--orphan", "gh-pages"]);
11 |
12 | console.log("Building...")
13 |
14 | await execa("yarn", ["run", "build"])
15 | // Understand if it's dist or build folder
16 | const folderName = "docs/.vitepress/dist"
17 | await execa("git", ["--work-tree", folderName, "add", "--all"])
18 | await execa("git", ["--work-tree", folderName, "commit", "-m", "gh-pages"])
19 |
20 | console.log("Pushing to gh-pages...")
21 |
22 | await execa("git", ["push", "origin", "HEAD:gh-pages", "--force"])
23 | await execa("rm", ["-r", folderName])
24 | await execa("git", ["fetch"])
25 | await execa("git", ["checkout", "-f", "main"])
26 | await execa("git", ["branch", "-D", "gh-pages"])
27 |
28 | console.log("Successfully deployed")
29 | } catch (e) {
30 |
31 | console.log(e.message)
32 | process.exit(1)
33 | }
34 | })();
--------------------------------------------------------------------------------
/docs/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 |
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 |
9 | resolve: {
10 | alias: {
11 | '@': fileURLToPath(new URL('./src', import.meta.url))
12 | }
13 | },
14 | server: {
15 | fs: {
16 | allow: ['..']
17 | }
18 | },
19 |
20 | })
21 |
--------------------------------------------------------------------------------
/vue-dd/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2022 Evgeny Kalashnikov
2 | Copyright (c) 2017 Emanuel Buzek
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vue-dd/README.md:
--------------------------------------------------------------------------------
1 | ## vue-dd — object viewer [](https://www.npmjs.com/package/vue-dd) [](https://github.com/infinite-system/vue-dd/actions/workflows/ci.yml)
2 |
3 | **vue-dd** — pronounced *vúed* or *vue dd* — is a Vue 3 object viewer for displaying complex JavaScript objects, Vue Reactive and Ref objects, Functions, Maps, Sets, Symbols and all JavaScript Primitives in order to monitor their changes **live** with full reactivity. Inspired by the Laravels **dd()** debugging function.
4 |
5 | https://user-images.githubusercontent.com/150185/213549880-e6b645bd-11f0-461a-b1a9-29c70c52f2ad.mov
6 |
7 | https://user-images.githubusercontent.com/150185/213549905-360698e2-0c6b-4fd1-8023-803e22b68e27.mov
8 |
9 | Video example code in Vue 3 `
--------------------------------------------------------------------------------
/vue-dd/cypress/support/router/Home.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/vue-dd/cypress/support/router/Page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/vue-dd/cypress/support/router/routes.js:
--------------------------------------------------------------------------------
1 | import Home from './Home.vue'
2 | import Page from './Page.vue'
3 | import About from './About.vue'
4 |
5 | export const routes = [
6 | {
7 | component: Home,
8 | name: 'home',
9 | path: '/',
10 | },
11 | {
12 | component: Page,
13 | name: 'page',
14 | path: '/page',
15 | },
16 | {
17 | component: About,
18 | name: 'about',
19 | path: '/about',
20 | }
21 | ];
22 |
--------------------------------------------------------------------------------
/vue-dd/demo/App.vue:
--------------------------------------------------------------------------------
1 |
105 |
106 | vue-dd integration tests
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
130 |
--------------------------------------------------------------------------------
/vue-dd/demo/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from "vue";
2 | import { install } from "../src/index";
3 | import App from "./App.vue";
4 |
5 | const app = createApp(App);
6 |
7 | install(app);
8 |
9 | app.mount("#app");
10 |
--------------------------------------------------------------------------------
/vue-dd/demo/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import vue from "@vitejs/plugin-vue";
3 |
4 | export const vueDocsPlugin = () => ({
5 | name: "vue-docs",
6 | transform(code: any, id: any) {
7 | if (!/vue&type=docs/.test(id)) return;
8 | return `export default ''`;
9 | },
10 | });
11 |
12 | export default defineConfig({
13 | root: "./",
14 | // keep the same name as your github repos
15 | mode: "production",
16 | plugins: [vue(), vueDocsPlugin()],
17 | build: {
18 | outDir: "./dist-demo",
19 | },
20 | });
21 |
--------------------------------------------------------------------------------
/vue-dd/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | MyComponent
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/vue-dd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-dd",
3 | "version": "1.6.5",
4 | "description": "Vue.js component for displaying JavaScript objects with circular references, forked and ported to Vue 3",
5 | "exports": {
6 | ".": {
7 | "require": "./dist/index.umd.js",
8 | "import": "./dist/index.es.js",
9 | "types": "./dist/src/index.d.ts",
10 | "style": "./dist/style.css"
11 | }
12 | },
13 | "main": "./dist/index.umd.js",
14 | "module": "./dist/index.es.js",
15 | "types": "./dist/src/index.d.ts",
16 | "style": "./dist/style.css",
17 | "scripts": {
18 | "dev": "vite dev --host",
19 | "test": "vitest",
20 | "coverage": "vitest run --coverage",
21 | "cypress": "cypress run --component",
22 | "cypress:headed": "cypress run --component --browser chrome --headed --no-exit",
23 | "build": "cpy ./README.md ../ --cwd=./ && vite build"
24 | },
25 | "peerDependencies": {
26 | "vue": "^3.0.0"
27 | },
28 | "devDependencies": {
29 | "@cypress/vite-dev-server": "^5.0.2",
30 | "@cypress/vue": "^5.0.3",
31 | "@vitejs/plugin-vue": "^4.0.0",
32 | "@vitest/coverage-c8": "^0.26.2",
33 | "@vue/test-utils": "^2.2.7",
34 | "cpy-cli": "^4.2.0",
35 | "cypress": "^12.3.0",
36 | "jsdom": "^21.0.0",
37 | "vite": "^4.0.4",
38 | "vite-plugin-dts": "^1.7.1",
39 | "vite-plugin-libcss": "^1.0.5",
40 | "vitest": "^0.27.1",
41 | "vue": "^3.2.45",
42 | "vue-router": "^4.1.6"
43 | },
44 | "repository": {
45 | "type": "git",
46 | "url": "https://github.com/infinite-system/vue-dd"
47 | },
48 | "homepage": "https://github.com/infinite-system/vue-dd",
49 | "bugs": {
50 | "url": "https://github.com/infinite-system/vue-dd/issues",
51 | "email": "ekalashnikov@gmail.com"
52 | },
53 | "keywords": [
54 | "Vue",
55 | "VueJs",
56 | "vue-dd",
57 | "dd",
58 | "object",
59 | "reactive",
60 | "tree",
61 | "view",
62 | "json",
63 | "viewer",
64 | "lazy",
65 | "circular",
66 | "inspector"
67 | ],
68 | "author": {
69 | "name": "Evgeny Kalashnikov",
70 | "email": "ekalashnikov@gmail.com"
71 | },
72 | "license": "MIT"
73 | }
74 |
--------------------------------------------------------------------------------
/vue-dd/src/NodePrimitive.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
19 | {{ name }} :
25 | null
27 | undefined
29 | {{ modelValue }}
31 | {{ modelValue }}
33 | "{{ escapeQuotesFn(modelValue) }}"
35 | {{ modelValue }}
38 | {{ modelValue.toString() }}
40 | [unknown_type]{{ modelValue }}
42 | ,
43 |
44 |
45 |
127 |
--------------------------------------------------------------------------------
/vue-dd/src/VueDd.spec.js:
--------------------------------------------------------------------------------
1 | import VueDd from './VueDd.vue';
2 | import { flushPromises } from '@vue/test-utils'
3 |
4 | import { routes } from '../cypress/support/router/routes.js'
5 | import { createMemoryHistory, createRouter, createWebHistory, useRoute } from 'vue-router'
6 | // beforeEach(() => {
7 | // cy.mount(VueDd);
8 | // });
9 |
10 | // it('basic router', () => {
11 | // // cy.wrap(Cypress.router.push('/'))
12 | // // cy.getDataCy('home').should('not.be.visible');
13 | // const name = 'test';
14 | //
15 | // cy.mount(VueDd, {
16 | // props: {
17 | // modelValue: true,
18 | // name,
19 | // },
20 | // });
21 | //
22 | // // cy.log('test')
23 | // // cy.location('pathname').should('eq', '/');
24 | // cy.get('div.vue-dd').should('have.text', name + ':true');
25 | // });
26 |
27 | it('router changed', async () => {
28 | // cy.wrap(Cypress.router.push('/'))
29 | // cy.getDataCy('home').should('not.be.visible');
30 | const router = createRouter({
31 | routes: routes,
32 | history: createWebHistory(),
33 | })
34 |
35 |
36 | // Change location to `/login`,
37 | // and await on the promise with cy.wrap
38 | cy.wrap(router.push('/about')).then(() => {
39 |
40 | cy.log('currentRoute', JSON.stringify(router.currentRoute))
41 |
42 | // Pass the already initialized router for use
43 | const name = 'test';
44 |
45 | cy.mount(VueDd, {
46 | router,
47 | props: {
48 | modelValue: true,
49 | delimiter: '$',
50 | name,
51 | },
52 | });
53 |
54 | const route = useRoute()
55 |
56 | cy.log('route', JSON.stringify(route))
57 |
58 | cy.log(JSON.stringify(window.location))
59 | // cy.location('pathname').should('eq', '/');
60 | cy.get('#dd_1').should('have.length', 1)
61 | cy.get('#dd_1').should('have.text', 'test:true')
62 | // cy.get('#_dd_1').contains(name);
63 |
64 | })
65 | });
66 | //
67 | // it('window', () => {
68 | // // cy.wrap(Cypress.router.push('/'))
69 | // // cy.location('pathname').should('eq', '/');
70 | // // cy.getDataCy('home').should('not.be.visible');
71 | // const name = 'test';
72 | //
73 | // cy.mount(VueDd, {
74 | // props: {
75 | // modelValue: window,
76 | // name,
77 | // focus: 'crypto'
78 | // },
79 | // });
80 | // // cy.get('body').invoke('html').then((val) => console.log(JSON.stringify(val)))
81 | // console.log('yes')
82 | // cy.get(`#${CSS.escape('_dd_1.cypress')}`).should('be.visible');
83 | // });
84 |
85 | //
86 | // it('shows a navbar on board detail', () => {
87 | // // cy.wrap(Cypress.router.push('/board/1'));
88 | // // cy.location('pathname').should('eq', '/board/1');
89 | // cy.getDataCy('home').should('be.visible');
90 | // });
91 |
--------------------------------------------------------------------------------
/vue-dd/src/VueDd.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
37 |
83 |
84 |
85 |
572 |
576 |
--------------------------------------------------------------------------------
/vue-dd/src/XRay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello world
4 |
5 |
--------------------------------------------------------------------------------
/vue-dd/src/assets/eye-full.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-dd/src/assets/eye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue-dd/src/assets/fonts/vue-dd-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue-dd/src/assets/fonts/vue-dd-icons.eot
--------------------------------------------------------------------------------
/vue-dd/src/assets/fonts/vue-dd-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Generated by IcoMoon
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/vue-dd/src/assets/fonts/vue-dd-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue-dd/src/assets/fonts/vue-dd-icons.ttf
--------------------------------------------------------------------------------
/vue-dd/src/assets/fonts/vue-dd-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue-dd/src/assets/fonts/vue-dd-icons.woff
--------------------------------------------------------------------------------
/vue-dd/src/components/XRayCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
16 | {{ label }}
17 |
18 |
19 |
20 |
48 |
112 |
--------------------------------------------------------------------------------
/vue-dd/src/components/XRaySelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 | {{ label }}
7 |
8 |
17 | {{ option }}
22 |
23 |
24 |
25 |
72 |
--------------------------------------------------------------------------------
/vue-dd/src/css/VueDd.code.css:
--------------------------------------------------------------------------------
1 | /* highlight.js styles */
2 |
3 | .vue-dd .hljs {
4 | color: #abb2bf;
5 | background: #282c34;
6 | }
7 |
8 | .vue-dd .hljs-comment, .vue-dd .hljs-quote {
9 | color: #5c6370;
10 | font-style: italic;
11 | }
12 |
13 | .vue-dd .hljs-doctag, .vue-dd .hljs-formula, .vue-dd .hljs-keyword {
14 | color: #c678dd;
15 | }
16 |
17 | .vue-dd .hljs-deletion, .vue-dd .hljs-name, .vue-dd .hljs-section, .vue-dd .hljs-selector-tag, .vue-dd .hljs-subst {
18 | color: #e06c75;
19 | }
20 |
21 | .vue-dd .hljs-literal {
22 | color: #56b6c2;
23 | }
24 |
25 | .vue-dd .hljs-addition, .vue-dd .hljs-attribute, .vue-dd .hljs-meta .hljs-string, .vue-dd .hljs-regexp, .vue-dd .hljs-string {
26 | color: #98c379;
27 | }
28 |
29 | .vue-dd .hljs-attr, .vue-dd .hljs-number, .vue-dd .hljs-selector-attr, .vue-dd .hljs-selector-class, .vue-dd .hljs-selector-pseudo, .vue-dd .hljs-template-variable, .vue-dd .hljs-type, .vue-dd .hljs-variable {
30 | color: #d19a66;
31 | }
32 |
33 | .vue-dd .hljs-bullet, .vue-dd .hljs-link, .vue-dd .hljs-meta, .vue-dd .hljs-selector-id, .vue-dd .hljs-symbol, .vue-dd .hljs-title {
34 | color: #61aeee;
35 | }
36 |
37 | .vue-dd .hljs-built_in, .vue-dd .hljs-class .hljs-title, .vue-dd .hljs-title.class_ {
38 | color: #e6c07b;
39 | }
40 |
41 | .vue-dd .hljs-emphasis {
42 | font-style: italic;
43 | }
44 |
45 | .vue-dd .hljs-strong {
46 | font-weight: 700;
47 | }
48 |
49 | .vue-dd .hljs-link {
50 | text-decoration: underline;
51 | }
52 |
--------------------------------------------------------------------------------
/vue-dd/src/css/VueDd.css:
--------------------------------------------------------------------------------
1 | .vue-dd {
2 | max-height: var(--vue-dd-maxHeight);
3 | max-width: var(--vue-dd-maxWidth);
4 | }
5 |
6 |
7 | .vue-dd, .vue-dd pre {
8 | font-family: var(--vue-dd-fontFamily);
9 | font-size: var(--vue-dd-fontSize);
10 | line-height: var(--vue-dd-lineHeight);
11 | }
12 |
13 | .vue-dd {
14 | position: relative;
15 | text-align: left;
16 | color: #4e5e6b;
17 | padding: 2px 5px 2px 3px;
18 | transition: 0.2s;
19 | margin-bottom: 2px;
20 | background: #f9ffff;
21 | border-radius: 3px;
22 | border: 1px solid #d2dbe8;
23 | overflow-y: auto;
24 | overflow-x: auto;
25 | scroll-behavior: smooth;
26 | /* firefox scrollbar */
27 | scrollbar-color: rgba(0, 0, 0, 0.1) #f9ffff;
28 | scrollbar-width: thin;
29 | }
30 |
31 | .vue-dd div {
32 | /**
33 | * this is important for auto-scroll saveFocus positioning
34 | * some css frameworks set * { position: relative } and
35 | * vue 3 default main.css does as well,
36 | * position:relative on all (*) elements will break auto scroll in vue-dd
37 | * because the only relative element should be the root .vue-dd {}
38 | */
39 | position: static !important;
40 | }
41 |
42 | .vue-dd-no-arrow {
43 | padding-left: 5px;
44 | }
45 |
46 | .vue-dd-body {
47 | transition: 0.1s;
48 | }
49 |
50 | .vue-dd-open {
51 | }
52 |
53 | .vue-dd-open.vue-dd-inline {
54 | display: block;
55 | }
56 |
57 | .vue-dd-inline:not(.vue-dd-open) {
58 | display: inline-block;
59 | margin-right: 3px;
60 | }
61 |
62 | .vue-dd.vue-dd-dark {
63 | background: #000;
64 | border: 1px solid #000;
65 | /* firefox scrollbar */
66 | scrollbar-color: #111 #000;
67 | scrollbar-width: thin;
68 | }
69 |
70 | .vue-dd::-webkit-scrollbar {
71 | width: 4px;
72 | height: 4px;
73 | background: rgba(0, 0, 0, 0.05);
74 | }
75 |
76 | .vue-dd::-webkit-scrollbar-corner {
77 | background: rgba(0, 0, 0, 0.05);
78 | }
79 |
80 | .vue-dd::-webkit-scrollbar-thumb {
81 | border-radius: 5px;
82 | background: rgba(0, 0, 0, 0.1);
83 | }
84 |
85 | .vue-dd.vue-dd-dark::-webkit-scrollbar {
86 | background: rgba(255, 255, 255, 0.05);
87 | }
88 |
89 | .vue-dd.vue-dd-dark::-webkit-scrollbar-corner {
90 | background: rgba(255, 255, 255, 0.05);
91 | }
92 |
93 | .vue-dd.vue-dd-dark::-webkit-scrollbar-thumb {
94 | background: rgba(255, 255, 255, 0.2);
95 | }
96 |
97 | .vue-dd-box {
98 | display: block;
99 | overflow: visible;
100 | }
101 |
102 | .vue-dd-box > div {
103 | /*float: left;*/
104 | display: block;
105 | overflow: visible;
106 | }
107 |
108 | .vue-dd-box > div > div {
109 | display: block;
110 | padding-left: var(--vue-dd-paddingLeft);
111 | }
112 |
113 | .vue-dd-box-closed, .vue-dd-box-closed div, .vue-dd-box-closed div div {
114 | display: inline-block;
115 | cursor: default;
116 | white-space: nowrap;
117 | }
118 |
119 | div.vue-dd-start {
120 | display: inline-block;
121 | }
122 |
123 | /** focus **/
124 |
125 | @font-face {
126 | font-family: 'vue-dd-icons';
127 | src: url('../assets/fonts/vue-dd-icons.eot?w48gck');
128 | src: url('../assets/fonts/vue-dd-icons.eot?w48gck#iefix') format('embedded-opentype'),
129 | url('../assets/fonts/vue-dd-icons.ttf?w48gck') format('truetype'),
130 | url('../assets/fonts/vue-dd-icons.woff?w48gck') format('woff'),
131 | url('../assets/fonts/vue-dd-icons.svg?w48gck#vue-dd-icons') format('svg');
132 | font-weight: normal;
133 | font-style: normal;
134 | font-display: block;
135 | }
136 |
137 | [class^="vue-dd-icon-"], [class*=" vue-dd-icon-"] {
138 | /* use !important to prevent issues with browser extensions that change fonts */
139 | font-family: 'vue-dd-icons' !important;
140 | speak: never;
141 | font-style: normal;
142 | font-weight: normal;
143 | font-variant: normal;
144 | text-transform: none;
145 | font-size: 80%;
146 | line-height: 80%;
147 |
148 | /* Better Font Rendering =========== */
149 | -webkit-font-smoothing: antialiased;
150 | -moz-osx-font-smoothing: grayscale;
151 | }
152 |
153 | .vue-dd-focus.vue-dd-icon-eye:before {
154 | content: "\e900";
155 | }
156 |
157 | .vue-dd-focus.vue-dd-focus-selected.vue-dd-icon-eye:before {
158 | content: "\e901";
159 | background: -webkit-linear-gradient(60deg, #00ff95, #116dea 90%);
160 | -webkit-background-clip: text;
161 | -webkit-text-fill-color: transparent;
162 | }
163 |
164 | .vue-dd-focus {
165 | color: #afafaf;
166 | margin: 0 2px 0 0;
167 | display: inline-block;
168 | font-size: 150%;
169 | vertical-align: middle;
170 | cursor: default;
171 | transition: 0.1s
172 | }
173 |
174 | .vue-dd-focus-hover {
175 | color: #555;
176 | }
177 |
178 | .vue-dd-focus-selected {
179 | color: #116dea;
180 | }
181 |
182 | /** dark focus **/
183 |
184 | .vue-dd-dark .vue-dd-focus {
185 | color: #333;
186 | }
187 |
188 | .vue-dd-dark .vue-dd-focus-hover {
189 | color: #777;
190 | }
191 |
192 | .vue-dd-dark .vue-dd-focus-selected {
193 | color: #116dea;
194 | }
195 |
196 | span.vue-dd-expand {
197 | vertical-align: middle;
198 | background: none;
199 | border: 0;
200 | border-radius: 5px;
201 |
202 | padding: 3px 3px;
203 | font-size: 70%;
204 | line-height: 10px;
205 | cursor: default;
206 | color: grey;
207 | -webkit-user-select: none;
208 | user-select: none;
209 | letter-spacing: -0px;
210 | }
211 |
212 | span.vue-dd-expand:hover {
213 | background: rgba(0, 0, 0, 0.05);
214 | color: #21BA45;
215 | }
216 |
217 | .vue-dd-dark span.vue-dd-expand {
218 | /*background: rgba(19, 19, 19, 0.97);*/
219 | }
220 |
221 | .vue-dd-dark span.vue-dd-expand:hover {
222 | background: rgba(255, 255, 255, 0.05);
223 | }
224 |
225 | .vue-dd-box-closed .vue-dd-expand {
226 | /*font-style: italic;*/
227 | }
228 | /*.vue-dd-expand-more {*/
229 | /*}*/
230 |
231 | .vue-dd-size:has(+ .vue-dd-expand) {
232 | margin: 0;
233 | }
234 |
235 | span.vue-dd-expand:active {
236 | padding-top: 4px;
237 | padding-bottom: 2px !important;
238 | }
239 |
240 | .vue-dd-ref {
241 | -webkit-user-select: none;
242 | user-select: none;
243 | cursor: default;
244 | color: grey;
245 | font-family: Georgia, 'Courier', serif;
246 | font-size: 90%;
247 | font-style: italic;
248 | letter-spacing: -0.5px;
249 | display: inline-block;
250 | padding: 0 3px 0 0;
251 | }
252 |
253 | .vue-dd-r {
254 | -webkit-user-select: none;
255 | user-select: none;
256 | cursor: default;
257 | color: grey;
258 | font-family: Georgia, 'Courier', serif;
259 | font-size: 90%;
260 | font-style: italic;
261 | letter-spacing: -0.5px;
262 | display: inline-block;
263 | padding: 0 2px 0 0;
264 | }
265 |
266 | .vue-dd-getter {
267 | color: grey;
268 | font-style: italic;
269 | padding: 0 2px 0 0;
270 | cursor: pointer;
271 | border-radius: 3px;
272 | }
273 |
274 | .vue-dd-getter:hover {
275 | background: rgba(200,200,200,0.2)
276 | }
277 |
278 | .vue-dd-name + .vue-dd-r {
279 | padding-left: 2px;
280 | }
281 |
282 |
283 | .vue-dd-f {
284 | -webkit-user-select: none;
285 | user-select: none;
286 | cursor: default;
287 | color: grey;
288 | font-style: italic;
289 | font-family: Georgia, serif;
290 | font-size: 90%;
291 | letter-spacing: -1px;
292 | display: inline-block;
293 | padding: 0 5px 0 3px;
294 | }
295 |
296 | .vue-dd-f-inline {
297 | color: #4e5e6b;
298 | font-style: italic;
299 | }
300 |
301 | .vue-dd-f-start {
302 | display: inline;
303 | color: #55606a;
304 | }
305 |
306 | .vue-dd-dark pre.vue-dd-f-start {
307 | padding: 0;
308 | margin: 0;
309 | color: #cbeaff;
310 | }
311 |
312 | .vue-dd-dark pre.vue-dd-f-start .hljs-property {
313 | color: #6ec3ff;
314 | }
315 |
316 | .vue-dd-f-content {
317 | padding: 0;
318 | }
319 |
320 | .vue-dd-f-content pre {
321 | padding: 0;
322 | margin: 0;
323 | color: #333;
324 | }
325 |
326 | .vue-dd-dark .vue-dd-f-content pre .hljs-property {
327 | color: #6ec3ff;
328 | }
329 |
330 | .vue-dd-dark .vue-dd-f-content pre {
331 | padding: 0;
332 | margin: 0;
333 | color: #cbeaff;
334 | }
335 |
336 | span.vue-dd-arrow {
337 | border: none;
338 | display: inline-block;
339 | background: none;
340 | color: #8c9dad;
341 | cursor: default;
342 | -webkit-user-select: none;
343 | user-select: none;
344 | font-size: 80%;
345 | padding: 0 2px 0 2px;
346 | transition: 0.2s;
347 | vertical-align: middle;
348 | }
349 |
350 | span.vue-dd-arrow:hover {
351 | color: slategray;
352 | }
353 |
354 | span.vue-dd-arrow-collapsed {
355 | padding: 0 2px 0 2px;
356 | transform: rotate(-90deg);
357 | }
358 |
359 | .vue-dd-name {
360 | padding-right: 0px;
361 | cursor: default;
362 | color: #1b7ccf;
363 | }
364 |
365 | .vue-dd-dark .vue-dd-name {
366 | cursor: default;
367 | color: #09BAFF;
368 | }
369 |
370 | .vue-dd-name.vue-dd-f-name {
371 | color: #d114d1;
372 | font-weight: normal;
373 | }
374 |
375 | .vue-dd-instance {
376 | user-select: none;
377 | padding-left: 3px;
378 | font-style: italic;
379 | color: #21BA45;
380 | -webkit-user-select: none;
381 | }
382 |
383 | .vue-dd-dark .vue-dd-instance {
384 |
385 | }
386 |
387 | .vue-dd-instance + .vue-dd-size {
388 | margin-left: 2px;
389 | }
390 |
391 | .vue-dd-size {
392 | user-select: none;
393 | margin: 0 2px 0 0;
394 | padding: 3px;
395 | /*border-radius: 30px;*/
396 | /*background: #eee;*/
397 | color: #999;
398 | font-style: italic;
399 | font-size: 80%;
400 | line-height: 100%;
401 | }
402 |
403 | .vue-dd-dark .vue-dd-size {
404 | /*background: #131313;*/
405 | color: #555;
406 | }
407 |
408 | .vue-dd-size-bracket {
409 | display: none;
410 | color: #4e5e6b;
411 | }
412 |
413 | .vue-dd-promise-prototype {
414 | padding-right: 5px;
415 | padding-left: 0;
416 | }
417 |
418 | .vue-dd-promise-content {
419 | -webkit-user-select: none;
420 | user-select: none;
421 | padding: 0 4px;
422 | font-style: italic;
423 | }
424 |
425 | .vue-dd-highlight {
426 | animation: vue-dd-highlight 1s;
427 | }
428 |
429 | .vue-dd-dark .vue-dd-highlight {
430 | animation: vue-dd-highlight-on-dark 1s;
431 | }
432 |
433 | @keyframes vue-dd-highlight-on-dark {
434 | from {
435 | background-color: #0f99cb;
436 | border-radius: 5px;
437 | }
438 | }
439 |
440 | @keyframes vue-dd-highlight {
441 | from {
442 | background-color: #83cb0f;
443 | border-radius: 5px;
444 | }
445 | }
446 |
447 | .vue-dd-null, .vue-dd-undefined {
448 | color: slategrey;
449 | }
450 |
451 | .vue-dd-boolean {
452 | font-weight: bold;
453 | color: green;
454 | }
455 |
456 | .vue-dd-number {
457 | color: #3863be;
458 | }
459 |
460 | .vue-dd-dark .vue-dd-number {
461 | color: #4067b2;
462 | }
463 |
464 | .vue-dd-bigint {
465 | color: #5a38be;
466 | }
467 |
468 | .vue-dd-dark .vue-dd-bigint {
469 | color: #7046e8;
470 | }
471 |
472 | .vue-dd-false {
473 | color: #f34747;
474 | }
475 |
476 | .vue-dd-dark .vue-dd-false {
477 | color: #f34747;
478 | }
479 |
480 | .vue-dd-unknown {
481 | color: #f34747;
482 | }
483 |
484 | .vue-dd-dark .vue-dd-unknown {
485 | color: #f34747;
486 | }
487 |
488 | .vue-dd-string {
489 | color: #d77702;
490 | word-break: break-word;
491 | }
492 |
493 | .vue-dd-dark .vue-dd-string {
494 | color: #ffcc00;
495 | }
496 |
497 | .vue-dd-symbol {
498 | color: #188379;
499 | }
500 |
501 | .vue-dd-dark .vue-dd-symbol {
502 | color: #00f7ff;
503 | word-break: break-word;
504 | }
505 |
506 | .vue-dd-key {
507 | color: #384e61;
508 | padding-left: 1px;
509 | padding-right: 0;
510 | font-weight: normal;
511 | }
512 |
513 | .vue-dd-dark .vue-dd-key {
514 | color: #c7e5fe;
515 | }
516 |
517 | .vue-dd-key-of-array {
518 | user-select: none;
519 | color: #ddd;
520 | }
521 |
522 | .vue-dd-dark .vue-dd-key-of-array {
523 | color: #333;
524 | }
525 |
526 | .vue-dd-colon {
527 | color: #555;
528 | }
529 |
530 | .vue-dd-dark .vue-dd-colon {
531 | color: #ccc;
532 | }
533 |
534 | .vue-dd-key-of-array .vue-dd-colon {
535 | user-select: none;
536 | color: #ccc;
537 | }
538 |
539 | .vue-dd-dark .vue-dd-key-of-array .vue-dd-colon {
540 | color: #333;
541 | }
542 |
543 | .vue-dd-box > div > div > div > span > .vue-dd-key {
544 | /*you can set extra padding for primitive keys here*/
545 | /*padding-left: 0px;*/
546 | }
547 |
548 | .vue-dd-forget {
549 | margin-left: 10px;
550 | cursor: pointer;
551 | font-size: 80%;
552 | margin-right: 10px;
553 | background: rgba(0, 0, 0, 0.1);
554 | border: 1px solid rgba(0, 0, 0, 0.1);
555 | padding: 2px 5px;
556 | border-radius: 10px;
557 | transition: 0.2;
558 | opacity: 0.8;
559 | }
560 |
561 | .vue-dd-forget:hover {
562 | opacity: 1;
563 | }
564 |
565 | .vue-dd-dark .vue-dd-forget {
566 | background: rgba(255, 255, 255, 0.1);
567 | border: 1px solid rgba(255, 255, 255, 0.1);
568 | }
569 |
570 | .vue-dd .vue-dd-forget-q-ask {
571 | border: 0;
572 | background: none;
573 | padding: 2px 0;
574 | cursor: default;
575 | }
576 |
577 | .vue-dd .vue-dd-forget-yes {
578 | margin-left: 0;
579 | }
580 |
581 | .vue-dd .vue-dd-forget-no {
582 | margin-left: 0;
583 | background: none;
584 | }
585 |
586 | .vue-dd-forget-cleared {
587 | font-size: 80%;
588 | margin-right: 10px;
589 | padding: 2px 5px;
590 | }
591 |
592 | .vue-dd-comma {
593 | color: #999;
594 | padding-right: 1px;
595 | }
596 |
597 | .vue-dd-dark .vue-dd-comma {
598 | color: #333;
599 | }
600 |
601 | .vue-dd-colon + .vue-dd-obj-char {
602 | padding: 0 2px;
603 | }
604 |
605 | .vue-dd-obj-char {
606 | color: #7490ab;
607 | padding: 0 0px;
608 | }
609 |
610 | .vue-dd-dark .vue-dd-obj-char {
611 | color: #555;
612 | }
613 |
614 | .vue-dd-name + .vue-dd-obj-char {
615 | padding-left: 2px;
616 | }
617 |
618 | .vue-dd-arr-char {
619 | color: #7490ab;
620 | padding: 0 1px;
621 | }
622 |
623 | .vue-dd-dark .vue-dd-arr-char {
624 | color: #555;
625 | }
626 |
627 |
628 | .vue-dd-obj-char-start {
629 | padding: 0 1px;
630 | }
631 |
--------------------------------------------------------------------------------
/vue-dd/src/features/setupFormComponent.js:
--------------------------------------------------------------------------------
1 | export default function setupFormComponent (props, { emit }) {
2 | const updateValue = (event) => {
3 | let val = event.target.value
4 |
5 | if (event.target.type === 'select-one') val = JSON.parse(event.target.value)
6 | if (event.target.type === 'checkbox') val = event.target.checked
7 | if (event.target.type === 'radio') val = props.value
8 |
9 | emit('update:modelValue', val)
10 | }
11 |
12 | return { updateValue }
13 | }
14 |
--------------------------------------------------------------------------------
/vue-dd/src/features/uniqueId.js:
--------------------------------------------------------------------------------
1 | let UUID = 1
2 | export default function uniqueId () {
3 | UUID++
4 | return UUID
5 | }
6 |
--------------------------------------------------------------------------------
/vue-dd/src/helpers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns a hash code from a string
3 | * @param {String} str The string to hash.
4 | * @return {Number} A 32bit integer
5 | * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
6 | */
7 | export function hashCode (str) {
8 | let hash = 0;
9 | for (let i = 0, len = str.length; i < len; i++) {
10 | let chr = str.charCodeAt(i);
11 | hash = (hash << 5) - hash + chr;
12 | hash |= 0; // Convert to 32bit integer
13 | }
14 | return hash;
15 | }
16 |
17 | export function isObject (item) {
18 | return (item && typeof item === 'object' && !Array.isArray(item));
19 | }
20 |
21 | export function isPromise (p) {
22 | return p !== null &&
23 | typeof p === 'object' &&
24 | typeof p.then === 'function' &&
25 | typeof p.catch === 'function';
26 | }
27 |
28 | export function makeId (id, name, window) {
29 | if (id !== '') {
30 | return id
31 | } else {
32 | // auto-generate id
33 | const locationHash = getLocationHash(window)
34 | return `${name}_${locationHash}`
35 | }
36 | }
37 |
38 | function getLocationHash (window) {
39 |
40 | // determine router type without importing vue-router package
41 | // by analyzing the urls
42 | // hash router will have a forward slash after the # sign #/about
43 | const isHashRouter = window.location.hash
44 | && typeof window.location.hash[1] !== 'undefined'
45 | && window.location.hash[1] === '/'
46 |
47 | let smartLocation = ''
48 | if (isHashRouter) {
49 | // use full route path
50 | smartLocation = window.location.href.toString()
51 | } else {
52 | // if hash is not a location hash
53 | const url = new URL(window.location.href)
54 | url.hash = "" // strip away hash
55 | smartLocation = url.toString()
56 | }
57 |
58 | return hashCode(smartLocation).toString(16).replace('-', '_')
59 | }
60 |
61 | export function onFrame(callback, timeout = 0) {
62 | setTimeout(() => {
63 | window.requestAnimationFrame(() => window.requestAnimationFrame(callback))
64 | }, timeout)
65 | }
66 |
--------------------------------------------------------------------------------
/vue-dd/src/highlight.js/core.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Highlight.js v11.7.0 (git: 82688fad18)
3 | (c) 2006-2022 undefined and other contributors
4 | License: BSD-3-Clause
5 | */
6 | var e={exports:{}};function t(e){
7 | return e instanceof Map?e.clear=e.delete=e.set=()=>{
8 | throw Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{
9 | throw Error("set is read-only")
10 | }),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((n=>{var i=e[n]
11 | ;"object"!=typeof i||Object.isFrozen(i)||t(i)})),e}
12 | e.exports=t,e.exports.default=t;class n{constructor(e){
13 | void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
14 | ignoreMatch(){this.isMatchIgnored=!0}}function i(e){
15 | return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")
16 | }function r(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t]
17 | ;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n}
18 | const s=e=>!!e.scope||e.sublanguage&&e.language;class o{constructor(e,t){
19 | this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){
20 | this.buffer+=i(e)}openNode(e){if(!s(e))return;let t=""
21 | ;t=e.sublanguage?"language-"+e.language:((e,{prefix:t})=>{if(e.includes(".")){
22 | const n=e.split(".")
23 | ;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ")
24 | }return`${t}${e}`})(e.scope,{prefix:this.classPrefix}),this.span(t)}
25 | closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){
26 | this.buffer+=``}}const a=(e={})=>{const t={children:[]}
27 | ;return Object.assign(t,e),t};class c{constructor(){
28 | this.rootNode=a(),this.stack=[this.rootNode]}get top(){
29 | return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
30 | this.top.children.push(e)}openNode(e){const t=a({scope:e})
31 | ;this.add(t),this.stack.push(t)}closeNode(){
32 | if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
33 | for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
34 | walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){
35 | return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),
36 | t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){
37 | "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
38 | c._collapse(e)})))}}class l extends c{constructor(e){super(),this.options=e}
39 | addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}
40 | addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root
41 | ;n.sublanguage=!0,n.language=t,this.add(n)}toHTML(){
42 | return new o(this,this.options).value()}finalize(){return!0}}function g(e){
43 | return e?"string"==typeof e?e:e.source:null}function d(e){return p("(?=",e,")")}
44 | function u(e){return p("(?:",e,")*")}function h(e){return p("(?:",e,")?")}
45 | function p(...e){return e.map((e=>g(e))).join("")}function f(...e){const t=(e=>{
46 | const t=e[e.length-1]
47 | ;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{}
48 | })(e);return"("+(t.capture?"":"?:")+e.map((e=>g(e))).join("|")+")"}
49 | function b(e){return RegExp(e.toString()+"|").exec("").length-1}
50 | const m=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./
51 | ;function E(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n
52 | ;let i=g(e),r="";for(;i.length>0;){const e=m.exec(i);if(!e){r+=i;break}
53 | r+=i.substring(0,e.index),
54 | i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?r+="\\"+(Number(e[1])+t):(r+=e[0],
55 | "("===e[0]&&n++)}return r})).map((e=>`(${e})`)).join(t)}
56 | const x="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w={
57 | begin:"\\\\[\\s\\S]",relevance:0},y={scope:"string",begin:"'",end:"'",
58 | illegal:"\\n",contains:[w]},_={scope:"string",begin:'"',end:'"',illegal:"\\n",
59 | contains:[w]},O=(e,t,n={})=>{const i=r({scope:"comment",begin:e,end:t,
60 | contains:[]},n);i.contains.push({scope:"doctag",
61 | begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
62 | end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})
63 | ;const s=f("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)
64 | ;return i.contains.push({begin:p(/[ ]+/,"(",s,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i
65 | },v=O("//","$"),N=O("/\\*","\\*/"),k=O("#","$");var M=Object.freeze({
66 | __proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:"[a-zA-Z]\\w*",
67 | UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:x,
68 | BINARY_NUMBER_RE:"\\b(0b[01]+)",
69 | RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
70 | SHEBANG:(e={})=>{const t=/^#![ ]*\//
71 | ;return e.binary&&(e.begin=p(t,/.*\b/,e.binary,/\b.*/)),r({scope:"meta",begin:t,
72 | end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},
73 | BACKSLASH_ESCAPE:w,APOS_STRING_MODE:y,QUOTE_STRING_MODE:_,PHRASAL_WORDS_MODE:{
74 | begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
75 | },COMMENT:O,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:N,HASH_COMMENT_MODE:k,
76 | NUMBER_MODE:{scope:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},
77 | C_NUMBER_MODE:{scope:"number",begin:x,relevance:0},BINARY_NUMBER_MODE:{
78 | scope:"number",begin:"\\b(0b[01]+)",relevance:0},REGEXP_MODE:{
79 | begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//,end:/\/[gimuy]*/,
80 | illegal:/\n/,contains:[w,{begin:/\[/,end:/\]/,relevance:0,contains:[w]}]}]},
81 | TITLE_MODE:{scope:"title",begin:"[a-zA-Z]\\w*",relevance:0},
82 | UNDERSCORE_TITLE_MODE:{scope:"title",begin:"[a-zA-Z_]\\w*",relevance:0},
83 | METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},
84 | END_SAME_AS_BEGIN:e=>Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]
85 | },"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})})
86 | ;function S(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}function R(e,t){
87 | void 0!==e.className&&(e.scope=e.className,delete e.className)}function A(e,t){
88 | t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
89 | e.__beforeBegin=S,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
90 | void 0===e.relevance&&(e.relevance=0))}function j(e,t){
91 | Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function I(e,t){
92 | if(e.match){
93 | if(e.begin||e.end)throw Error("begin & end are not supported with match")
94 | ;e.begin=e.match,delete e.match}}function T(e,t){
95 | void 0===e.relevance&&(e.relevance=1)}const L=(e,t)=>{if(!e.beforeMatch)return
96 | ;if(e.starts)throw Error("beforeMatch cannot be used with starts")
97 | ;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t]
98 | })),e.keywords=n.keywords,e.begin=p(n.beforeMatch,d(n.begin)),e.starts={
99 | relevance:0,contains:[Object.assign(n,{endsParent:!0})]
100 | },e.relevance=0,delete n.beforeMatch
101 | },B=["of","and","for","in","not","or","if","then","parent","list","value"]
102 | ;function D(e,t,n="keyword"){const i=Object.create(null)
103 | ;return"string"==typeof e?r(n,e.split(" ")):Array.isArray(e)?r(n,e):Object.keys(e).forEach((n=>{
104 | Object.assign(i,D(e[n],t,n))})),i;function r(e,n){
105 | t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|")
106 | ;i[n[0]]=[e,H(n[0],n[1])]}))}}function H(e,t){
107 | return t?Number(t):(e=>B.includes(e.toLowerCase()))(e)?0:1}const P={},C=e=>{
108 | console.error(e)},$=(e,...t)=>{console.log("WARN: "+e,...t)},U=(e,t)=>{
109 | P[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),P[`${e}/${t}`]=!0)
110 | },z=Error();function K(e,t,{key:n}){let i=0;const r=e[n],s={},o={}
111 | ;for(let e=1;e<=t.length;e++)o[e+i]=r[e],s[e+i]=!0,i+=b(t[e-1])
112 | ;e[n]=o,e[n]._emit=s,e[n]._multi=!0}function W(e){(e=>{
113 | e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,
114 | delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={
115 | _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope
116 | }),(e=>{if(Array.isArray(e.begin)){
117 | if(e.skip||e.excludeBegin||e.returnBegin)throw C("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),
118 | z
119 | ;if("object"!=typeof e.beginScope||null===e.beginScope)throw C("beginScope must be object"),
120 | z;K(e,e.begin,{key:"beginScope"}),e.begin=E(e.begin,{joinWith:""})}})(e),(e=>{
121 | if(Array.isArray(e.end)){
122 | if(e.skip||e.excludeEnd||e.returnEnd)throw C("skip, excludeEnd, returnEnd not compatible with endScope: {}"),
123 | z
124 | ;if("object"!=typeof e.endScope||null===e.endScope)throw C("endScope must be object"),
125 | z;K(e,e.end,{key:"endScope"}),e.end=E(e.end,{joinWith:""})}})(e)}function X(e){
126 | function t(t,n){
127 | return RegExp(g(t),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(n?"g":""))
128 | }class n{constructor(){
129 | this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
130 | addRule(e,t){
131 | t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),
132 | this.matchAt+=b(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)
133 | ;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(E(e,{joinWith:"|"
134 | }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex
135 | ;const t=this.matcherRe.exec(e);if(!t)return null
136 | ;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n]
137 | ;return t.splice(0,n),Object.assign(t,i)}}class i{constructor(){
138 | this.rules=[],this.multiRegexes=[],
139 | this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
140 | if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n
141 | ;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),
142 | t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){
143 | return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){
144 | this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){
145 | const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex
146 | ;let n=t.exec(e)
147 | ;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{
148 | const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}
149 | return n&&(this.regexIndex+=n.position+1,
150 | this.regexIndex===this.count&&this.considerAll()),n}}
151 | if(e.compilerExtensions||(e.compilerExtensions=[]),
152 | e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.")
153 | ;return e.classNameAliases=r(e.classNameAliases||{}),function n(s,o){const a=s
154 | ;if(s.isCompiled)return a
155 | ;[R,I,W,L].forEach((e=>e(s,o))),e.compilerExtensions.forEach((e=>e(s,o))),
156 | s.__beforeBegin=null,[A,j,T].forEach((e=>e(s,o))),s.isCompiled=!0;let c=null
157 | ;return"object"==typeof s.keywords&&s.keywords.$pattern&&(s.keywords=Object.assign({},s.keywords),
158 | c=s.keywords.$pattern,
159 | delete s.keywords.$pattern),c=c||/\w+/,s.keywords&&(s.keywords=D(s.keywords,e.case_insensitive)),
160 | a.keywordPatternRe=t(c,!0),
161 | o&&(s.begin||(s.begin=/\B|\b/),a.beginRe=t(a.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),
162 | s.end&&(a.endRe=t(a.end)),
163 | a.terminatorEnd=g(a.end)||"",s.endsWithParent&&o.terminatorEnd&&(a.terminatorEnd+=(s.end?"|":"")+o.terminatorEnd)),
164 | s.illegal&&(a.illegalRe=t(s.illegal)),
165 | s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>r(e,{
166 | variants:null},t)))),e.cachedVariants?e.cachedVariants:Z(e)?r(e,{
167 | starts:e.starts?r(e.starts):null
168 | }):Object.isFrozen(e)?r(e):e))("self"===e?s:e)))),s.contains.forEach((e=>{n(e,a)
169 | })),s.starts&&n(s.starts,o),a.matcher=(e=>{const t=new i
170 | ;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin"
171 | }))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"
172 | }),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function Z(e){
173 | return!!e&&(e.endsWithParent||Z(e.starts))}class G extends Error{
174 | constructor(e,t){super(e),this.name="HTMLInjectionError",this.html=t}}
175 | const F=i,V=r,q=Symbol("nomatch");var J=(t=>{
176 | const i=Object.create(null),r=Object.create(null),s=[];let o=!0
177 | ;const a="Could not find the language '{}', did you forget to load/include a language module?",c={
178 | disableAutodetect:!0,name:"Plain text",contains:[]};let g={
179 | ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,
180 | languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
181 | cssSelector:"pre code",languages:null,__emitter:l};function b(e){
182 | return g.noHighlightRe.test(e)}function m(e,t,n){let i="",r=""
183 | ;"object"==typeof t?(i=e,
184 | n=t.ignoreIllegals,r=t.language):(U("10.7.0","highlight(lang, code, ...args) has been deprecated."),
185 | U("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
186 | r=e,i=t),void 0===n&&(n=!0);const s={code:i,language:r};k("before:highlight",s)
187 | ;const o=s.result?s.result:E(s.language,s.code,n)
188 | ;return o.code=s.code,k("after:highlight",o),o}function E(e,t,r,s){
189 | const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(S)
190 | ;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(S),n=""
191 | ;for(;t;){n+=S.substring(e,t.index)
192 | ;const r=y.case_insensitive?t[0].toLowerCase():t[0],s=(i=r,N.keywords[i]);if(s){
193 | const[e,i]=s
194 | ;if(M.addText(n),n="",c[r]=(c[r]||0)+1,c[r]<=7&&(R+=i),e.startsWith("_"))n+=t[0];else{
195 | const n=y.classNameAliases[e]||e;M.addKeyword(t[0],n)}}else n+=t[0]
196 | ;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(S)}var i
197 | ;n+=S.substring(e),M.addText(n)}function d(){null!=N.subLanguage?(()=>{
198 | if(""===S)return;let e=null;if("string"==typeof N.subLanguage){
199 | if(!i[N.subLanguage])return void M.addText(S)
200 | ;e=E(N.subLanguage,S,!0,k[N.subLanguage]),k[N.subLanguage]=e._top
201 | }else e=x(S,N.subLanguage.length?N.subLanguage:null)
202 | ;N.relevance>0&&(R+=e.relevance),M.addSublanguage(e._emitter,e.language)
203 | })():l(),S=""}function u(e,t){let n=1;const i=t.length-1;for(;n<=i;){
204 | if(!e._emit[n]){n++;continue}const i=y.classNameAliases[e[n]]||e[n],r=t[n]
205 | ;i?M.addKeyword(r,i):(S=r,l(),S=""),n++}}function h(e,t){
206 | return e.scope&&"string"==typeof e.scope&&M.openNode(y.classNameAliases[e.scope]||e.scope),
207 | e.beginScope&&(e.beginScope._wrap?(M.addKeyword(S,y.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),
208 | S=""):e.beginScope._multi&&(u(e.beginScope,t),S="")),N=Object.create(e,{parent:{
209 | value:N}}),N}function p(e,t,i){let r=((e,t)=>{const n=e&&e.exec(t)
210 | ;return n&&0===n.index})(e.endRe,i);if(r){if(e["on:end"]){const i=new n(e)
211 | ;e["on:end"](t,i),i.isMatchIgnored&&(r=!1)}if(r){
212 | for(;e.endsParent&&e.parent;)e=e.parent;return e}}
213 | if(e.endsWithParent)return p(e.parent,t,i)}function f(e){
214 | return 0===N.matcher.regexIndex?(S+=e[0],1):(I=!0,0)}function b(e){
215 | const n=e[0],i=t.substring(e.index),r=p(N,e,i);if(!r)return q;const s=N
216 | ;N.endScope&&N.endScope._wrap?(d(),
217 | M.addKeyword(n,N.endScope._wrap)):N.endScope&&N.endScope._multi?(d(),
218 | u(N.endScope,e)):s.skip?S+=n:(s.returnEnd||s.excludeEnd||(S+=n),
219 | d(),s.excludeEnd&&(S=n));do{
220 | N.scope&&M.closeNode(),N.skip||N.subLanguage||(R+=N.relevance),N=N.parent
221 | }while(N!==r.parent);return r.starts&&h(r.starts,e),s.returnEnd?0:n.length}
222 | let m={};function w(i,s){const a=s&&s[0];if(S+=i,null==a)return d(),0
223 | ;if("begin"===m.type&&"end"===s.type&&m.index===s.index&&""===a){
224 | if(S+=t.slice(s.index,s.index+1),!o){const t=Error(`0 width match regex (${e})`)
225 | ;throw t.languageName=e,t.badRule=m.rule,t}return 1}
226 | if(m=s,"begin"===s.type)return(e=>{
227 | const t=e[0],i=e.rule,r=new n(i),s=[i.__beforeBegin,i["on:begin"]]
228 | ;for(const n of s)if(n&&(n(e,r),r.isMatchIgnored))return f(t)
229 | ;return i.skip?S+=t:(i.excludeBegin&&(S+=t),
230 | d(),i.returnBegin||i.excludeBegin||(S=t)),h(i,e),i.returnBegin?0:t.length})(s)
231 | ;if("illegal"===s.type&&!r){
232 | const e=Error('Illegal lexeme "'+a+'" for mode "'+(N.scope||"")+'"')
233 | ;throw e.mode=N,e}if("end"===s.type){const e=b(s);if(e!==q)return e}
234 | if("illegal"===s.type&&""===a)return 1
235 | ;if(j>1e5&&j>3*s.index)throw Error("potential infinite loop, way more iterations than matches")
236 | ;return S+=a,a.length}const y=O(e)
237 | ;if(!y)throw C(a.replace("{}",e)),Error('Unknown language: "'+e+'"')
238 | ;const _=X(y);let v="",N=s||_;const k={},M=new g.__emitter(g);(()=>{const e=[]
239 | ;for(let t=N;t!==y;t=t.parent)t.scope&&e.unshift(t.scope)
240 | ;e.forEach((e=>M.openNode(e)))})();let S="",R=0,A=0,j=0,I=!1;try{
241 | for(N.matcher.considerAll();;){
242 | j++,I?I=!1:N.matcher.considerAll(),N.matcher.lastIndex=A
243 | ;const e=N.matcher.exec(t);if(!e)break;const n=w(t.substring(A,e.index),e)
244 | ;A=e.index+n}
245 | return w(t.substring(A)),M.closeAllNodes(),M.finalize(),v=M.toHTML(),{
246 | language:e,value:v,relevance:R,illegal:!1,_emitter:M,_top:N}}catch(n){
247 | if(n.message&&n.message.includes("Illegal"))return{language:e,value:F(t),
248 | illegal:!0,relevance:0,_illegalBy:{message:n.message,index:A,
249 | context:t.slice(A-100,A+100),mode:n.mode,resultSoFar:v},_emitter:M};if(o)return{
250 | language:e,value:F(t),illegal:!1,relevance:0,errorRaised:n,_emitter:M,_top:N}
251 | ;throw n}}function x(e,t){t=t||g.languages||Object.keys(i);const n=(e=>{
252 | const t={value:F(e),illegal:!1,relevance:0,_top:c,_emitter:new g.__emitter(g)}
253 | ;return t._emitter.addText(e),t})(e),r=t.filter(O).filter(N).map((t=>E(t,e,!1)))
254 | ;r.unshift(n);const s=r.sort(((e,t)=>{
255 | if(e.relevance!==t.relevance)return t.relevance-e.relevance
256 | ;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1
257 | ;if(O(t.language).supersetOf===e.language)return-1}return 0})),[o,a]=s,l=o
258 | ;return l.secondBest=a,l}function w(e){let t=null;const n=(e=>{
259 | let t=e.className+" ";t+=e.parentNode?e.parentNode.className:""
260 | ;const n=g.languageDetectRe.exec(t);if(n){const t=O(n[1])
261 | ;return t||($(a.replace("{}",n[1])),
262 | $("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}
263 | return t.split(/\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return
264 | ;if(k("before:highlightElement",{el:e,language:n
265 | }),e.children.length>0&&(g.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),
266 | console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),
267 | console.warn("The element with unescaped HTML:"),
268 | console.warn(e)),g.throwUnescapedHTML))throw new G("One of your code blocks includes unescaped HTML.",e.innerHTML)
269 | ;t=e;const i=t.textContent,s=n?m(i,{language:n,ignoreIllegals:!0}):x(i)
270 | ;e.innerHTML=s.value,((e,t,n)=>{const i=t&&r[t]||n
271 | ;e.classList.add("hljs"),e.classList.add("language-"+i)
272 | })(e,n,s.language),e.result={language:s.language,re:s.relevance,
273 | relevance:s.relevance},s.secondBest&&(e.secondBest={
274 | language:s.secondBest.language,relevance:s.secondBest.relevance
275 | }),k("after:highlightElement",{el:e,result:s,text:i})}let y=!1;function _(){
276 | "loading"!==document.readyState?document.querySelectorAll(g.cssSelector).forEach(w):y=!0
277 | }function O(e){return e=(e||"").toLowerCase(),i[e]||i[r[e]]}
278 | function v(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
279 | r[e.toLowerCase()]=t}))}function N(e){const t=O(e)
280 | ;return t&&!t.disableAutodetect}function k(e,t){const n=e;s.forEach((e=>{
281 | e[n]&&e[n](t)}))}
282 | "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
283 | y&&_()}),!1),Object.assign(t,{highlight:m,highlightAuto:x,highlightAll:_,
284 | highlightElement:w,
285 | highlightBlock:e=>(U("10.7.0","highlightBlock will be removed entirely in v12.0"),
286 | U("10.7.0","Please use highlightElement now."),w(e)),configure:e=>{g=V(g,e)},
287 | initHighlighting:()=>{
288 | _(),U("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},
289 | initHighlightingOnLoad:()=>{
290 | _(),U("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")
291 | },registerLanguage:(e,n)=>{let r=null;try{r=n(t)}catch(t){
292 | if(C("Language definition for '{}' could not be registered.".replace("{}",e)),
293 | !o)throw t;C(t),r=c}
294 | r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&v(r.aliases,{
295 | languageName:e})},unregisterLanguage:e=>{delete i[e]
296 | ;for(const t of Object.keys(r))r[t]===e&&delete r[t]},
297 | listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v,
298 | autoDetection:N,inherit:V,addPlugin:e=>{(e=>{
299 | e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{
300 | e["before:highlightBlock"](Object.assign({block:t.el},t))
301 | }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{
302 | e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),s.push(e)}
303 | }),t.debugMode=()=>{o=!1},t.safeMode=()=>{o=!0
304 | },t.versionString="11.7.0",t.regex={concat:p,lookahead:d,either:f,optional:h,
305 | anyNumberOfTimes:u};for(const t in M)"object"==typeof M[t]&&e.exports(M[t])
306 | ;return Object.assign(t,M),t})({});export{J as default};
307 |
--------------------------------------------------------------------------------
/vue-dd/src/highlight.js/javascript.min.js:
--------------------------------------------------------------------------------
1 | /*! `javascript` grammar compiled for Highlight.js 11.7.0 */
2 | var hljsGrammar=(()=>{"use strict"
3 | ;const e="[A-Za-z$_][0-9A-Za-z$_]*",n=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],a=["true","false","null","undefined","NaN","Infinity"],t=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],s=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],r=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],c=["arguments","this","super","console","window","document","localStorage","module","global"],i=[].concat(r,t,s)
4 | ;return o=>{const l=o.regex,b=e,d={begin:/<[A-Za-z0-9\\._:-]+/,
5 | end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{
6 | const a=e[0].length+e.index,t=e.input[a]
7 | ;if("<"===t||","===t)return void n.ignoreMatch();let s
8 | ;">"===t&&(((e,{after:n})=>{const a=""+e[0].slice(1)
9 | ;return-1!==e.input.indexOf(a,n)})(e,{after:a})||n.ignoreMatch())
10 | ;const r=e.input.substring(a)
11 | ;((s=r.match(/^\s*=/))||(s=r.match(/^\s+extends\s+/))&&0===s.index)&&n.ignoreMatch()
12 | }},g={$pattern:e,keyword:n,literal:a,built_in:i,"variable.language":c
13 | },u="\\.([0-9](_?[0-9])*)",m="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",E={
14 | className:"number",variants:[{
15 | begin:`(\\b(${m})((${u})|\\.)?|(${u}))[eE][+-]?([0-9](_?[0-9])*)\\b`},{
16 | begin:`\\b(${m})\\b((${u})\\b|\\.)?|(${u})\\b`},{
17 | begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{
18 | begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{
19 | begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{
20 | begin:"\\b0[0-7]+n?\\b"}],relevance:0},A={className:"subst",begin:"\\$\\{",
21 | end:"\\}",keywords:g,contains:[]},y={begin:"html`",end:"",starts:{end:"`",
22 | returnEnd:!1,contains:[o.BACKSLASH_ESCAPE,A],subLanguage:"xml"}},h={
23 | begin:"css`",end:"",starts:{end:"`",returnEnd:!1,
24 | contains:[o.BACKSLASH_ESCAPE,A],subLanguage:"css"}},N={className:"string",
25 | begin:"`",end:"`",contains:[o.BACKSLASH_ESCAPE,A]},_={className:"comment",
26 | variants:[o.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{
27 | begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",
28 | begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,
29 | excludeBegin:!0,relevance:0},{className:"variable",begin:b+"(?=\\s*(-)|$)",
30 | endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]
31 | }),o.C_BLOCK_COMMENT_MODE,o.C_LINE_COMMENT_MODE]
32 | },f=[o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,y,h,N,{match:/\$\d+/},E]
33 | ;A.contains=f.concat({begin:/\{/,end:/\}/,keywords:g,contains:["self"].concat(f)
34 | });const v=[].concat(_,A.contains),p=v.concat([{begin:/\(/,end:/\)/,keywords:g,
35 | contains:["self"].concat(v)}]),S={className:"params",begin:/\(/,end:/\)/,
36 | excludeBegin:!0,excludeEnd:!0,keywords:g,contains:p},w={variants:[{
37 | match:[/class/,/\s+/,b,/\s+/,/extends/,/\s+/,l.concat(b,"(",l.concat(/\./,b),")*")],
38 | scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{
39 | match:[/class/,/\s+/,b],scope:{1:"keyword",3:"title.class"}}]},R={relevance:0,
40 | match:l.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
41 | className:"title.class",keywords:{_:[...t,...s]}},O={variants:[{
42 | match:[/function/,/\s+/,b,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],
43 | className:{1:"keyword",3:"title.function"},label:"func.def",contains:[S],
44 | illegal:/%/},k={
45 | match:l.concat(/\b/,(I=[...r,"super","import"],l.concat("(?!",I.join("|"),")")),b,l.lookahead(/\(/)),
46 | className:"title.function",relevance:0};var I;const x={
47 | begin:l.concat(/\./,l.lookahead(l.concat(b,/(?![0-9A-Za-z$_(])/))),end:b,
48 | excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},T={
49 | match:[/get|set/,/\s+/,b,/(?=\()/],className:{1:"keyword",3:"title.function"},
50 | contains:[{begin:/\(\)/},S]
51 | },C="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+o.UNDERSCORE_IDENT_RE+")\\s*=>",M={
52 | match:[/const|var|let/,/\s+/,b,/\s*/,/=\s*/,/(async\s*)?/,l.lookahead(C)],
53 | keywords:"async",className:{1:"keyword",3:"title.function"},contains:[S]}
54 | ;return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:g,exports:{
55 | PARAMS_CONTAINS:p,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/,
56 | contains:[o.SHEBANG({label:"shebang",binary:"node",relevance:5}),{
57 | label:"use_strict",className:"meta",relevance:10,
58 | begin:/^\s*['"]use (strict|asm)['"]/
59 | },o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,y,h,N,_,{match:/\$\d+/},E,R,{
60 | className:"attr",begin:b+l.lookahead(":"),relevance:0},M,{
61 | begin:"("+o.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",
62 | keywords:"return throw case",relevance:0,contains:[_,o.REGEXP_MODE,{
63 | className:"function",begin:C,returnBegin:!0,end:"\\s*=>",contains:[{
64 | className:"params",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{
65 | className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,
66 | excludeEnd:!0,keywords:g,contains:p}]}]},{begin:/,/,relevance:0},{match:/\s+/,
67 | relevance:0},{variants:[{begin:"<>",end:">"},{
68 | match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:d.begin,
69 | "on:begin":d.isTrulyOpeningTag,end:d.end}],subLanguage:"xml",contains:[{
70 | begin:d.begin,end:d.end,skip:!0,contains:["self"]}]}]},O,{
71 | beginKeywords:"while if switch catch for"},{
72 | begin:"\\b(?!function)"+o.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
73 | returnBegin:!0,label:"func.def",contains:[S,o.inherit(o.TITLE_MODE,{begin:b,
74 | className:"title.function"})]},{match:/\.\.\./,relevance:0},x,{match:"\\$"+b,
75 | relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},
76 | contains:[S]},k,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
77 | className:"variable.constant"},w,T,{match:/\$[(.]/}]}}})()
78 | ;export default hljsGrammar;
79 |
--------------------------------------------------------------------------------
/vue-dd/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { App } from "vue";
2 |
3 | import VueDd from "./VueDd.vue";
4 | import XRay from "./XRay.vue";
5 |
6 | function install(app: App) {
7 | // Base entities
8 | app.component("VueDd", VueDd);
9 | app.component("XRay", XRay);
10 | }
11 |
12 | export {
13 | install,
14 | // Base entities
15 | VueDd,
16 | XRay
17 | };
18 |
--------------------------------------------------------------------------------
/vue-dd/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.vue" {
2 | import type { DefineComponent } from "vue";
3 | const component: DefineComponent<
4 | Record,
5 | Record,
6 | unknown
7 | >;
8 | export default component;
9 | }
10 |
--------------------------------------------------------------------------------
/vue-dd/src/types.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue-dd/src/types.ts
--------------------------------------------------------------------------------
/vue-dd/test/__snapshots__/basic.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1
2 |
3 | exports[`mount component 1`] = `
4 | "4 x 2 = 8
5 | x1 "
6 | `;
7 |
--------------------------------------------------------------------------------
/vue-dd/test/as-async.test.ts:
--------------------------------------------------------------------------------
1 | import { flushPromises, mount } from '@vue/test-utils'
2 | import AsAsync from './components/AsAsync.vue'
3 |
4 | test('mount component', async () => {
5 | expect(AsAsync).toBeTruthy()
6 |
7 | const wrapper = mount(AsAsync)
8 |
9 | await wrapper.find('button').trigger('click')
10 |
11 | await flushPromises() // start loading, so vitest started loading
12 | await vi.dynamicImportSettled()
13 |
14 | expect(wrapper.html()).toContain('1 x 2 = 2')
15 | })
16 |
--------------------------------------------------------------------------------
/vue-dd/test/async.test.ts:
--------------------------------------------------------------------------------
1 | import { nextTick } from 'vue'
2 | import { flushPromises, mount } from '@vue/test-utils'
3 | import AsyncWrapper from './components/AsyncWrapper.vue'
4 |
5 | test('async component with suspense', async () => {
6 | expect(AsyncWrapper).toBeTruthy()
7 |
8 | let resolve: Function
9 |
10 | const promise = new Promise(_resolve => resolve = _resolve)
11 | const wrapper = mount(AsyncWrapper, {
12 | props: {
13 | promise,
14 | },
15 | })
16 |
17 | await nextTick()
18 |
19 | expect(wrapper.text()).toContain('fallback')
20 |
21 | resolve()
22 |
23 | await flushPromises()
24 | await nextTick()
25 | await nextTick()
26 |
27 | const text = wrapper.text()
28 | expect(text).toContain('resolved')
29 | })
30 |
--------------------------------------------------------------------------------
/vue-dd/test/basic.test.ts:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils'
2 | import Hello from './components/Hello.vue'
3 |
4 | test('mount component', async () => {
5 | expect(Hello).toBeTruthy()
6 |
7 | const wrapper = mount(Hello, {
8 | props: {
9 | count: 4,
10 | },
11 | })
12 |
13 | expect(wrapper.text()).toContain('4 x 2 = 8')
14 | expect(wrapper.html()).toMatchSnapshot()
15 |
16 | await wrapper.get('button').trigger('click')
17 |
18 | expect(wrapper.text()).toContain('4 x 3 = 12')
19 |
20 | await wrapper.get('button').trigger('click')
21 |
22 | expect(wrapper.text()).toContain('4 x 4 = 16')
23 | })
24 |
--------------------------------------------------------------------------------
/vue-dd/test/components/AsAsync.vue:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 | Show Hello
15 |
16 |
17 |
Async component
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/vue-dd/test/components/AsyncComp.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | resolved
9 |
10 |
--------------------------------------------------------------------------------
/vue-dd/test/components/AsyncWrapper.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 | fallback
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/vue-dd/test/components/Hello.vue:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 | {{ count }} x {{ times }} = {{ result }}
14 |
15 | x1
16 |
17 |
18 |
--------------------------------------------------------------------------------
/vue-dd/test/imports.test.ts:
--------------------------------------------------------------------------------
1 | describe('import vue components', () => {
2 | test('normal imports as expected', async () => {
3 | const cmp = await import('./components/Hello.vue')
4 | expect(cmp).toBeDefined()
5 | })
6 |
7 | test('template string imports as expected', async () => {
8 | // eslint-disable-next-line @typescript-eslint/quotes
9 | const cmp = await import(`./components/Hello.vue`)
10 | expect(cmp).toBeDefined()
11 | })
12 |
13 | test('dynamic imports as expected', async () => {
14 | const name = 'Hello'
15 | const cmp = await import(`./components/${name}.vue`)
16 | expect(cmp).toBeDefined()
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/vue-dd/test/vue-dd.test.ts:
--------------------------------------------------------------------------------
1 | import { nextTick, ref } from 'vue'
2 | import { flushPromises, mount } from '@vue/test-utils'
3 | import VueDd from '../src/VueDd.vue'
4 |
5 | export default function sleep (ms) {
6 | return new Promise(resolve => setTimeout(resolve, ms));
7 | }
8 |
9 | const defaults = {
10 | arrow: true,
11 | arrowOpen: '-',
12 | arrowClosed: '+',
13 | }
14 |
15 | describe('vue dd init', () => {
16 |
17 | test('import', () => {
18 | expect(VueDd).toBeTruthy()
19 | })
20 |
21 | describe('primitives', () => {
22 |
23 | test('null', async () => {
24 |
25 | const modelValue = null
26 |
27 | const wrapper = mount(VueDd, {
28 | props: { ...defaults, modelValue }
29 | })
30 |
31 | await nextTick()
32 |
33 | const text = wrapper.text()
34 |
35 | expect(text).toContain('null')
36 | })
37 |
38 | test('undefined', async () => {
39 |
40 | const modelValue = undefined
41 | // const promise = new Promise(_resolve => resolve = _resolve)
42 | const wrapper = mount(VueDd, {
43 | props: { ...defaults, modelValue }
44 | })
45 |
46 | await nextTick()
47 |
48 | const text = wrapper.text()
49 |
50 | // console.log(text)
51 | expect(text).toContain('undefined')
52 | })
53 |
54 | test('string', async () => {
55 |
56 | const modelValue = 'string'
57 | // const promise = new Promise(_resolve => resolve = _resolve)
58 | const wrapper = mount(VueDd, {
59 | props: { ...defaults, modelValue }
60 | })
61 |
62 | await nextTick()
63 |
64 | const text = wrapper.text()
65 | console.log(text)
66 |
67 | expect(text).toContain('string')
68 | })
69 |
70 | test('number', async () => {
71 |
72 | const modelValue = 1000
73 |
74 | const wrapper = mount(VueDd, {
75 | props: { ...defaults, modelValue }
76 | })
77 |
78 | await nextTick()
79 |
80 | const text = wrapper.text()
81 |
82 | // console.log(text)
83 |
84 | expect(text).toContain(modelValue)
85 | })
86 |
87 | describe('complex', () => {
88 |
89 | test('object', async () => {
90 |
91 | const modelValue = { test: 1 }
92 |
93 | const wrapper = mount(VueDd, {
94 | props: { ...defaults, modelValue }
95 | })
96 |
97 | await nextTick()
98 |
99 | const text = wrapper.text()
100 |
101 | expect(text).toContain('test:1')
102 | })
103 |
104 | test('array', async () => {
105 |
106 | const modelValue = ['test']
107 |
108 | const wrapper = mount(VueDd, {
109 | props: { ...defaults, modelValue }
110 | })
111 |
112 | await nextTick()
113 |
114 | const text = wrapper.text()
115 |
116 | console.log(text)
117 | expect(text).toContain('test')
118 | })
119 | //
120 | // test('array of objects: test', async () => {
121 | //
122 | // const modelValue = Object.freeze([{ obj: { subobj: 'hello', unreachableObjectContent: { unreachable: true } } }, { obj: 2 }])
123 | //
124 | // const level = 3;
125 | //
126 | // const wrapper = mount(VueDd, {
127 | // props: {
128 | // ...defaults,
129 | // modelValue,
130 | // openLevel: level,
131 | // preview: 0 //disable previews to test for level 4 opening
132 | // },
133 | // })
134 | //
135 | // await nextTick()
136 | // await sleep(34 * level * 3)
137 | //
138 | // const text = wrapper.text()
139 | //
140 | // console.log('array of objects test')
141 | // console.log(text)
142 | //
143 | // expect(text).toContain('+unreachableObjectContent:{...}')
144 | //
145 | // })
146 | })
147 |
148 | // test('array of objects with refs', async () => {
149 | //
150 | // const modelValue = ref([22, { obj: ref(false) }, { obj: ref(true) }])
151 | //
152 | // // console.log(modelValue)
153 | // const level = 1
154 | // const wrapper = mount(VueDd, {
155 | // props: {
156 | // ...defaults,
157 | // modelValue,
158 | // openLevel: level,
159 | // openSpecific: ['_rawValue.1', '_rawValue.2'],
160 | // // preview: 5
161 | // },
162 | // })
163 | //
164 | // await nextTick()
165 | //
166 | // await sleep(34 * 1 * 3)
167 | // const text = wrapper.text()
168 | //
169 | // console.log(text)
170 | // expect(text).toContain('_value:R[[3]22,+R{...},+R{...}]')
171 | // // expect(text).toContain('_value:true')
172 | //
173 | // })
174 |
175 | })
176 |
177 | })
178 |
179 |
180 |
--------------------------------------------------------------------------------
/vue-dd/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "module": "ESNext",
5 | "target": "es2016",
6 | "lib": ["DOM", "ESNext"],
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "incremental": false,
10 | "skipLibCheck": true,
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "noUnusedLocals": true,
14 | "strictNullChecks": true,
15 | "allowJs": true,
16 | "noEmit": true,
17 | "forceConsistentCasingInFileNames": true,
18 | "types": ["vitest/globals"],
19 | "paths": {
20 | "~/*": ["src/*"]
21 | }
22 | },
23 | "exclude": ["dist", "node_modules"]
24 | }
25 |
--------------------------------------------------------------------------------
/vue-dd/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module '*.vue' {
4 | import type { DefineComponent } from 'vue'
5 | const component: DefineComponent<{}, {}, any>
6 | export default component
7 | }
8 |
--------------------------------------------------------------------------------
/vue-dd/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 | import dts from "vite-plugin-dts";
6 | import pkg from "./package.json";
7 | import libCss from 'vite-plugin-libcss';
8 |
9 | export const vueDocsPlugin = () => ({
10 | name: "vue-docs",
11 | transform (code: any, id: any) {
12 | if (!/vue&type=docs/.test(id)) return;
13 | return `export default ''`;
14 | }
15 | });
16 |
17 | // https://vitejs.dev/config/
18 | export default defineConfig({
19 | resolve: {
20 | alias: {
21 | '@': fileURLToPath(new URL('./src', import.meta.url))
22 | }
23 | },
24 | server: {
25 | fs: {
26 | allow: ['..']
27 | }
28 | },
29 | plugins: [
30 | vue({
31 | css: true
32 | }),
33 | dts({
34 | cleanVueFileName: true,
35 | }),
36 | vueDocsPlugin(),
37 | libCss()
38 | ],
39 | build: {
40 | cssCodeSplit: true,
41 | lib: {
42 | entry: "./src/index.ts",
43 | formats: ["es", "umd"],
44 | // the name expose in umd mode
45 | name: pkg.name,
46 | fileName: (format) => `index.${format}.js`,
47 | },
48 | rollupOptions: {
49 | external: ["vue"],
50 | output: {
51 | globals: {
52 | vue: "Vue"
53 | },
54 | },
55 | },
56 | },
57 | })
58 |
--------------------------------------------------------------------------------
/vue-dd/vitest.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import { defineConfig } from 'vite'
4 | import Vue from '@vitejs/plugin-vue'
5 |
6 | export default defineConfig({
7 | plugins: [
8 | Vue(),
9 | ],
10 | test: {
11 | globals: true,
12 | environment: 'jsdom',
13 | include: ["test/*.test.ts"],
14 | },
15 | })
16 |
--------------------------------------------------------------------------------
/vue2/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/vue2/README.md:
--------------------------------------------------------------------------------
1 | # vue2
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/vue2/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/vue2/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "baseUrl": "./",
6 | "moduleResolution": "node",
7 | "paths": {
8 | "@/*": [
9 | "src/*"
10 | ]
11 | },
12 | "lib": [
13 | "esnext",
14 | "dom",
15 | "dom.iterable",
16 | "scripthost"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vue2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue2",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.8.3",
12 | "vue": "^2.7.5",
13 | "vue-dd": "^1.2.0-dev.0"
14 | },
15 | "devDependencies": {
16 | "@babel/core": "^7.12.16",
17 | "@babel/eslint-parser": "^7.12.16",
18 | "@vue/cli-plugin-babel": "~5.0.0",
19 | "@vue/cli-plugin-eslint": "~5.0.0",
20 | "@vue/cli-service": "~5.0.0",
21 | "eslint": "^7.32.0",
22 | "eslint-plugin-vue": "^8.0.3",
23 | "vue-template-compiler": "^2.6.14"
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "env": {
28 | "node": true
29 | },
30 | "extends": [
31 | "plugin:vue/essential",
32 | "eslint:recommended"
33 | ],
34 | "parserOptions": {
35 | "parser": "@babel/eslint-parser"
36 | },
37 | "rules": {}
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not dead"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/vue2/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue2/public/favicon.ico
--------------------------------------------------------------------------------
/vue2/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/vue2/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
27 |
--------------------------------------------------------------------------------
/vue2/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue2/src/assets/logo.png
--------------------------------------------------------------------------------
/vue2/src/components/VueDdTest.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vue 2 test for
vue-dd
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 |
43 |
--------------------------------------------------------------------------------
/vue2/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | // import VueDd from 'vue-dd'
4 | // import VueDd from '../../vue-dd/src/VueDd.vue'
5 | import { VueDd } from 'vue-dd'
6 |
7 | Vue.config.productionTip = false
8 |
9 | new Vue({
10 | render: h => h(App)
11 | }).$mount('#app')
12 |
13 | Vue.component('VueDd', VueDd)
14 | // Vue.component('VueDdNpm', VueDdNpm)
--------------------------------------------------------------------------------
/vue2/vue.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('@vue/cli-service')
2 | module.exports = defineConfig({
3 | transpileDependencies: true
4 | })
5 |
--------------------------------------------------------------------------------
/vue3/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | require('@rushstack/eslint-patch/modern-module-resolution')
3 |
4 | module.exports = {
5 | root: true,
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended',
9 | '@vue/eslint-config-typescript',
10 | // '@vue/eslint-config-prettier'
11 | ],
12 | // "rules": {
13 | // "eqeqeq": "off",
14 | // "no-console": "off"
15 | // },
16 | overrides: [
17 | {
18 | files: [
19 | 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}'
20 | ],
21 | 'extends': [
22 | 'plugin:cypress/recommended'
23 | ]
24 | }
25 | ],
26 | parserOptions: {
27 | ecmaVersion: 'latest'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/vue3/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
--------------------------------------------------------------------------------
/vue3/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/vue3/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3 | }
4 |
--------------------------------------------------------------------------------
/vue3/README.md:
--------------------------------------------------------------------------------
1 | # vue3
2 |
3 | This template should help get you started developing with Vue 3 in Vite.
4 |
5 | ## Recommended IDE Setup
6 |
7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
8 |
9 | ## Type Support for `.vue` Imports in TS
10 |
11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
12 |
13 | If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
14 |
15 | 1. Disable the built-in TypeScript Extension
16 | 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
17 | 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
18 | 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
19 |
20 | ## Customize configuration
21 |
22 | See [Vite Configuration Reference](https://vitejs.dev/config/).
23 |
24 | ## Project Setup
25 |
26 | ```sh
27 | yarn
28 | ```
29 |
30 | ### Compile and Hot-Reload for Development
31 |
32 | ```sh
33 | yarn dev
34 | ```
35 |
36 | ### Type-Check, Compile and Minify for Production
37 |
38 | ```sh
39 | yarn build
40 | ```
41 |
42 | ### Run Unit Tests with [Vitest](https://vitest.dev/)
43 |
44 | ```sh
45 | yarn test:unit
46 | ```
47 |
48 | ### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
49 |
50 | ```sh
51 | yarn test:e2e:dev
52 | ```
53 |
54 | This runs the end-to-end tests against the Vite development server.
55 | It is much faster than the production build.
56 |
57 | But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
58 |
59 | ```sh
60 | yarn build
61 | yarn test:e2e
62 | ```
63 |
64 | ### Lint with [ESLint](https://eslint.org/)
65 |
66 | ```sh
67 | yarn lint
68 | ```
69 |
--------------------------------------------------------------------------------
/vue3/cypress.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'cypress'
2 |
3 | export default defineConfig({
4 | e2e: {
5 | specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
6 | baseUrl: 'http://localhost:5173'
7 | }
8 | })
9 |
--------------------------------------------------------------------------------
/vue3/cypress/e2e/example.cy.ts:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/api/introduction/api.html
2 |
3 | describe('My First Test', () => {
4 | it('visits the app root url', () => {
5 | cy.visit('/')
6 | cy.contains('span', 'window')
7 | })
8 | })
9 |
--------------------------------------------------------------------------------
/vue3/cypress/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.web.json",
3 | "include": ["./**/*", "../support/**/*"],
4 | "compilerOptions": {
5 | "isolatedModules": false,
6 | "target": "es5",
7 | "lib": ["es5", "dom"],
8 | "types": ["cypress"]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/vue3/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/vue3/cypress/support/commands.ts:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************
3 | // This example commands.ts shows you how to
4 | // create various custom commands and overwrite
5 | // existing commands.
6 | //
7 | // For more comprehensive examples of custom
8 | // commands please read more here:
9 | // https://on.cypress.io/custom-commands
10 | // ***********************************************
11 | //
12 | //
13 | // -- This is a parent command --
14 | // Cypress.Commands.add('login', (email, password) => { ... })
15 | //
16 | //
17 | // -- This is a child command --
18 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
19 | //
20 | //
21 | // -- This is a dual command --
22 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
23 | //
24 | //
25 | // -- This will overwrite an existing command --
26 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
27 | //
28 | // declare global {
29 | // namespace Cypress {
30 | // interface Chainable {
31 | // login(email: string, password: string): Chainable
32 | // drag(subject: string, options?: Partial): Chainable
33 | // dismiss(subject: string, options?: Partial): Chainable
34 | // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
35 | // }
36 | // }
37 | // }
38 |
39 | export {}
40 |
--------------------------------------------------------------------------------
/vue3/cypress/support/e2e.ts:
--------------------------------------------------------------------------------
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')
21 |
--------------------------------------------------------------------------------
/vue3/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/vue3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/vue3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "run-p type-check build-only",
8 | "preview": "vite preview",
9 | "test:unit": "vitest --environment jsdom --root src/",
10 | "test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
11 | "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
12 | "build-only": "vite build",
13 | "type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
14 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
15 | },
16 | "dependencies": {
17 | "pinia": "^2.0.28",
18 | "vue": "^3.2.45",
19 | "vue-dd": "^1.3.4",
20 | "vue-router": "^4.1.6"
21 | },
22 | "devDependencies": {
23 | "@rushstack/eslint-patch": "^1.1.4",
24 | "@types/jsdom": "^20.0.1",
25 | "@types/node": "^18.11.12",
26 | "@vitejs/plugin-vue": "^4.0.0",
27 | "@vue/eslint-config-prettier": "^7.0.0",
28 | "@vue/eslint-config-typescript": "^11.0.0",
29 | "@vue/test-utils": "^2.2.6",
30 | "@vue/tsconfig": "^0.1.3",
31 | "cypress": "^12.0.2",
32 | "eslint": "^8.22.0",
33 | "eslint-plugin-cypress": "^2.12.1",
34 | "eslint-plugin-vue": "^9.3.0",
35 | "highlight.js": "^11.7.0",
36 | "jsdom": "^20.0.3",
37 | "npm-run-all": "^4.1.5",
38 | "prettier": "^2.7.1",
39 | "start-server-and-test": "^1.15.2",
40 | "typescript": "~4.7.4",
41 | "vite": "^4.0.0",
42 | "vitest": "^0.25.6",
43 | "vue-tsc": "^1.0.12"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/vue3/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinite-system/vue-dd/fac5498a27bfdcc533601d1257c781deb1a6e34d/vue3/public/favicon.ico
--------------------------------------------------------------------------------
/vue3/src/App.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Vue 3 test for vue-dd
18 |
19 |
20 |
21 |
22 |
85 |
--------------------------------------------------------------------------------
/vue3/src/assets/base.css:
--------------------------------------------------------------------------------
1 | /* color palette from */
2 | :root {
3 | --vt-c-white: #ffffff;
4 | --vt-c-white-soft: #f8f8f8;
5 | --vt-c-white-mute: #f2f2f2;
6 |
7 | --vt-c-black: #181818;
8 | --vt-c-black-soft: #222222;
9 | --vt-c-black-mute: #282828;
10 |
11 | --vt-c-indigo: #2c3e50;
12 |
13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17 |
18 | --vt-c-text-light-1: var(--vt-c-indigo);
19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20 | --vt-c-text-dark-1: var(--vt-c-white);
21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22 | }
23 |
24 | /* semantic color variables for this project */
25 | :root {
26 | --color-background: var(--vt-c-white);
27 | --color-background-soft: var(--vt-c-white-soft);
28 | --color-background-mute: var(--vt-c-white-mute);
29 |
30 | --color-border: var(--vt-c-divider-light-2);
31 | --color-border-hover: var(--vt-c-divider-light-1);
32 |
33 | --color-heading: var(--vt-c-text-light-1);
34 | --color-text: var(--vt-c-text-light-1);
35 |
36 | --section-gap: 160px;
37 | }
38 |
39 | @media (prefers-color-scheme: dark) {
40 | :root {
41 | --color-background: var(--vt-c-black);
42 | --color-background-soft: var(--vt-c-black-soft);
43 | --color-background-mute: var(--vt-c-black-mute);
44 |
45 | --color-border: var(--vt-c-divider-dark-2);
46 | --color-border-hover: var(--vt-c-divider-dark-1);
47 |
48 | --color-heading: var(--vt-c-text-dark-1);
49 | --color-text: var(--vt-c-text-dark-2);
50 | }
51 | }
52 |
53 | *,
54 | *::before,
55 | *::after {
56 | box-sizing: border-box;
57 | margin: 0;
58 | position: relative;
59 | }
60 |
61 | body {
62 | min-height: 100vh;
63 | color: var(--color-text);
64 | background: var(--color-background);
65 | transition: color 0.5s, background-color 0.5s;
66 | line-height: 1.6;
67 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
68 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
69 | font-size: 15px;
70 | text-rendering: optimizeLegibility;
71 | -webkit-font-smoothing: antialiased;
72 | -moz-osx-font-smoothing: grayscale;
73 | }
74 |
--------------------------------------------------------------------------------
/vue3/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue3/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app {
4 | max-width: 1280px;
5 | margin: 0 auto;
6 | padding: 2rem;
7 |
8 | font-weight: normal;
9 | }
10 |
11 | a,
12 | .green {
13 | text-decoration: none;
14 | color: hsla(160, 100%, 37%, 1);
15 | transition: 0.4s;
16 | }
17 |
18 | @media (hover: hover) {
19 | a:hover {
20 | background-color: hsla(160, 100%, 37%, 0.2);
21 | }
22 | }
23 |
24 | @media (min-width: 1024px) {
25 | body {
26 | /*display: flex;*/
27 | /*place-items: center;*/
28 | }
29 |
30 | #app {
31 | /*display: grid;*/
32 | /*grid-template-columns: 1fr 1fr;*/
33 | /*padding: 0 2rem;*/
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/vue3/src/components/BaseCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
13 | {{ label }}
14 |
15 |
16 |
17 |
44 |
--------------------------------------------------------------------------------
/vue3/src/components/VueDdApiTest.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | My vue-dd plugin is useful for this:
4 |
5 | <vue-dd v-model="api" name="api" :open-level="2">
6 |
7 |
8 | Basic API Requests:
9 | fetch: {{ url }}
10 |
11 | Loading...
12 |
13 |
14 |
15 | previous
16 |
17 | next
18 |
19 |
20 |
21 |
22 | Name
23 | Height
24 | Mass
25 | Hair color
26 | Skin color
27 |
28 |
34 |
35 | {{ row.name }}
36 | {{ row.height }}
37 | {{ row.mass }}
38 | {{ row.hair_color }}
39 | {{ row.skin_color }}
40 |
41 |
42 |
43 |
44 |
45 | vue-dd advanced example 1:
46 | You can pre-open specific pointer in the object. Right now
47 | 'results.0' is opened, you can open specific object arguments
48 | with :open-specific="['obj.prop','obj.prop2',...]"
49 |
50 | <vue-dd v-model="api" max-height="400px" :open-specific="['results.0']" />
52 |
53 |
54 | vue-dd advanced example 2:
55 | You can pre-open levels with :open-level prop. Example below
56 | will open 2 levels deep right away, and scroll to the latest
57 | 'results.9' ,using focus="results.9" prop
58 |
59 | <vue-dd v-model="api" name="api" focus="results.9" max-height="400px" :open-level="2" />
61 |
68 |
69 | vue-dd advanced example 3:
70 | Open 3 levels deep, and scroll to the midpoint 'results.5' ,
71 | 'focus-sticky'
72 | prop will return the focus to correct element, even when data changes and you
73 | scrolled it somewhere, try scrolling somewhere, and then click 'next /
74 | previous' above in the API table.
75 |
76 | <vue-dd v-model="api" name="api" focus="results.5" :focus-sticky="true" max-height="400px" :open-level="3" />
78 |
86 |
87 | vue-dd sessionStorage like this:
88 |
89 | <vue-dd name="session" v-model="sessionStorage" :open-level="1" />
91 |
92 |
93 | How to install vue-dd?
94 |
95 | yarn add vue-dd
96 | # or
97 | npm install vue-dd
98 |
100 |
101 | import { VueDd } from 'vue-dd'
102 |
104 |
105 | <vue-dd v-model="object" />
106 |
111 |
112 |
113 |
212 |
213 |
292 |
--------------------------------------------------------------------------------
/vue3/src/components/VueDdTest.vue:
--------------------------------------------------------------------------------
1 |
111 |
112 |
113 | Test 1
114 | NPM:
115 |
116 |
117 | dark:
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/vue3/src/components/VueDdTest2.vue:
--------------------------------------------------------------------------------
1 |
84 |
85 |
86 | Test 2
87 | NPM:
88 |
89 |
90 | dark:
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/vue3/src/components/__tests__/HelloWorld.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 |
3 | import { mount } from '@vue/test-utils'
4 | import HelloWorld from './HelloWorld.vue'
5 |
6 | describe('HelloWorld', () => {
7 | it('renders properly', () => {
8 | const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
9 | expect(wrapper.text()).toContain('Hello Vitest')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/vue3/src/components/__tests__/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
{{ msg }}
10 |
11 | You’ve successfully created a project with
12 | Vite +
13 | Vue 3 . What's next?
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
46 |
--------------------------------------------------------------------------------
/vue3/src/components/__tests__/WelcomeItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
87 |
--------------------------------------------------------------------------------
/vue3/src/components/icons/IconCommunity.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue3/src/components/icons/IconDocumentation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue3/src/components/icons/IconEcosystem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue3/src/components/icons/IconSupport.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/vue3/src/components/icons/IconTooling.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/vue3/src/features/setupFormComponent.js:
--------------------------------------------------------------------------------
1 | export default function setupFormComponent (props, { emit }) {
2 | const updateValue = (event) => {
3 | let val = event.target.value
4 |
5 | if (event.target.type === 'checkbox') val = event.target.checked
6 | if (event.target.type === 'radio') val = props.value
7 |
8 | emit('update:modelValue', val)
9 | }
10 |
11 | return { updateValue }
12 | }
13 |
--------------------------------------------------------------------------------
/vue3/src/features/uniqueId.js:
--------------------------------------------------------------------------------
1 | let UUID = 1
2 | export default function uniqueId () {
3 | UUID++
4 | return UUID
5 | }
6 |
--------------------------------------------------------------------------------
/vue3/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import { createPinia } from 'pinia'
3 |
4 |
5 | import App from './App.vue'
6 | import router from './router'
7 | //
8 | import './assets/main.css'
9 |
10 | const app = createApp(App)
11 |
12 | app.use(createPinia())
13 | app.use(router)
14 |
15 |
16 | // const npm = false
17 | // let VueDd = await import(npm ? `../node_modules/vue-dd/dist/index.es.js` : `../../vue-dd/src/VueDd.vue`)
18 | // VueDd = npm ? VueDd.VueDd : VueDd.default
19 | //
20 | // app.component('VueDd', VueDd)
21 |
22 | app.mount('#app')
23 |
--------------------------------------------------------------------------------
/vue3/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHistory } from 'vue-router'
2 | import HomeView from '../views/HomeView.vue'
3 | import VueDdTest from '../components/VueDdTest.vue'
4 | import VueDdTest2 from '../components/VueDdTest2.vue'
5 | import VueDdApiTest from '../components/VueDdApiTest.vue'
6 |
7 | const router = createRouter({
8 | history: createWebHistory(import.meta.env.BASE_URL),
9 | routes: [
10 | {
11 | path: '/',
12 | name: 'home',
13 | component: HomeView,
14 | children: [
15 | {
16 | path: '',
17 | name: 'vue-dd',
18 | component: VueDdTest
19 | },
20 | {
21 | path: 'test-2',
22 | name: 'vue-dd-test-2',
23 | component: VueDdTest2
24 | },
25 | {
26 | path: 'api',
27 | name: 'vue-dd-api',
28 | component: VueDdApiTest
29 | }
30 | ]
31 | },
32 | {
33 | path: '/api',
34 | name: 'api',
35 | // route level code-splitting
36 | // this generates a separate chunk (About.[hash].js) for this route
37 | // which is lazy-loaded when the route is visited.
38 | component: VueDdApiTest
39 | }
40 | ]
41 | })
42 |
43 | export default router
44 |
--------------------------------------------------------------------------------
/vue3/src/stores/counter.ts:
--------------------------------------------------------------------------------
1 | import { ref, computed } from 'vue'
2 | import { defineStore } from 'pinia'
3 |
4 | export const useCounterStore = defineStore('counter', () => {
5 | const count = ref(0)
6 | const doubleCount = computed(() => count.value * 2)
7 | function increment() {
8 | count.value++
9 | }
10 |
11 | return { count, doubleCount, increment }
12 | })
13 |
--------------------------------------------------------------------------------
/vue3/src/views/AboutView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is an about page
4 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/vue3/src/views/HomeView.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | Test 1
8 | Test 2
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/vue3/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.web.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4 | "exclude": ["src/**/__tests__/*"],
5 | "compilerOptions": {
6 | "composite": true,
7 | "baseUrl": ".",
8 | "paths": {
9 | "@/*": ["./src/*"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/vue3/tsconfig.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.node.json",
3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"],
4 | "compilerOptions": {
5 | "composite": true,
6 | "types": ["node"]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/vue3/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | {
5 | "path": "./tsconfig.config.json"
6 | },
7 | {
8 | "path": "./tsconfig.app.json"
9 | },
10 | {
11 | "path": "./tsconfig.vitest.json"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/vue3/tsconfig.vitest.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.app.json",
3 | "exclude": [],
4 | "compilerOptions": {
5 | "composite": true,
6 | "lib": [],
7 | "types": ["node", "jsdom"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/vue3/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [vue()],
9 | resolve: {
10 | alias: {
11 | '@': fileURLToPath(new URL('./src', import.meta.url))
12 | }
13 | },
14 | server: {
15 | fs: {
16 | allow: ['..']
17 | }
18 | },
19 |
20 | })
21 |
--------------------------------------------------------------------------------