mirror of
https://github.com/enso-org/enso.git
synced 2024-12-19 13:21:37 +03:00
Visualization Registry integration (https://github.com/enso-org/ide/pull/433)
Original commit: 47468f311c
This commit is contained in:
parent
71bc491b28
commit
1ef0241bec
@ -150,6 +150,6 @@ scripts which maximally automate the process:
|
||||
[official source](https://chromedriver.chromium.org/downloads) and ensure it is in your `PATH`.
|
||||
|
||||
- **Linting**
|
||||
Please be sure to fix all errors reported by `node ./run line` before creating a pull request to
|
||||
Please be sure to fix all errors reported by `node ./run lint` before creating a pull request to
|
||||
this repository.
|
||||
|
||||
|
159
gui/src/js/package-lock.json
generated
159
gui/src/js/package-lock.json
generated
@ -390,9 +390,9 @@
|
||||
}
|
||||
},
|
||||
"@lerna/conventional-commits": {
|
||||
"version": "3.18.5",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.18.5.tgz",
|
||||
"integrity": "sha512-qcvXIEJ3qSgalxXnQ7Yxp5H9Ta5TVyai6vEor6AAEHc20WiO7UIdbLDCxBtiiHMdGdpH85dTYlsoYUwsCJu3HQ==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.22.0.tgz",
|
||||
"integrity": "sha512-z4ZZk1e8Mhz7+IS8NxHr64wyklHctCJyWpJKEZZPJiLFJ8yKto/x38O80R10pIzC0rr8Sy/OsjSH4bl0TbbgqA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@lerna/validation-error": "3.13.0",
|
||||
@ -409,9 +409,9 @@
|
||||
}
|
||||
},
|
||||
"@lerna/create": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.21.0.tgz",
|
||||
"integrity": "sha512-cRIopzKzE2vXJPmsiwCDMWo4Ct+KTmX3nvvkQLDoQNrrRK7w+3KQT3iiorbj1koD95RsVQA7mS2haWok9SIv0g==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.22.0.tgz",
|
||||
"integrity": "sha512-MdiQQzCcB4E9fBF1TyMOaAEz9lUjIHp1Ju9H7f3lXze5JK6Fl5NYkouAvsLgY6YSIhXMY8AHW2zzXeBDY4yWkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@evocateur/pacote": "^9.6.3",
|
||||
@ -527,13 +527,13 @@
|
||||
}
|
||||
},
|
||||
"@lerna/github-client": {
|
||||
"version": "3.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.5.tgz",
|
||||
"integrity": "sha512-rHQdn8Dv/CJrO3VouOP66zAcJzrHsm+wFuZ4uGAai2At2NkgKH+tpNhQy2H1PSC0Ezj9LxvdaHYrUzULqVK5Hw==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.22.0.tgz",
|
||||
"integrity": "sha512-O/GwPW+Gzr3Eb5bk+nTzTJ3uv+jh5jGho9BOqKlajXaOkMYGBELEAqV5+uARNGWZFvYAiF4PgqHb6aCUu7XdXg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@lerna/child-process": "3.16.5",
|
||||
"@octokit/plugin-enterprise-rest": "^3.6.1",
|
||||
"@octokit/plugin-enterprise-rest": "^6.0.1",
|
||||
"@octokit/rest": "^16.28.4",
|
||||
"git-url-parse": "^11.1.2",
|
||||
"npmlog": "^4.1.2"
|
||||
@ -567,9 +567,9 @@
|
||||
}
|
||||
},
|
||||
"@lerna/import": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.21.0.tgz",
|
||||
"integrity": "sha512-aISkL4XD0Dqf5asDaOZWu65jgj8fWUhuQseZWuQe3UfHxav69fTS2YLIngUfencaOSZVOcVCom28YCzp61YDxw==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.22.0.tgz",
|
||||
"integrity": "sha512-uWOlexasM5XR6tXi4YehODtH9Y3OZrFht3mGUFFT3OIl2s+V85xIGFfqFGMTipMPAGb2oF1UBLL48kR43hRsOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@lerna/child-process": "3.16.5",
|
||||
@ -831,9 +831,9 @@
|
||||
}
|
||||
},
|
||||
"@lerna/publish": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.21.0.tgz",
|
||||
"integrity": "sha512-JZ+ehZB9UCQ9nqH8Ld/Yqc/If++aK/7XIubkrB9sQ5hf2GeIbmI/BrJpMgLW/e9T5bKrUBZPUvoUN3daVipA5A==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.22.0.tgz",
|
||||
"integrity": "sha512-8LBeTLBN8NIrCrLGykRu+PKrfrCC16sGCVY0/bzq9TDioR7g6+cY0ZAw653Qt/0Kr7rg3J7XxVNdzj3fvevlwA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@evocateur/libnpmaccess": "^3.1.2",
|
||||
@ -857,7 +857,7 @@
|
||||
"@lerna/run-lifecycle": "3.16.2",
|
||||
"@lerna/run-topologically": "3.18.5",
|
||||
"@lerna/validation-error": "3.13.0",
|
||||
"@lerna/version": "3.21.0",
|
||||
"@lerna/version": "3.22.0",
|
||||
"figgy-pudding": "^3.5.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"npm-package-arg": "^6.1.0",
|
||||
@ -993,17 +993,17 @@
|
||||
}
|
||||
},
|
||||
"@lerna/version": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.21.0.tgz",
|
||||
"integrity": "sha512-nIT3u43fCNj6uSMN1dRxFnF4GhmIiOEqSTkGSjrMU+8kHKwzOqS/6X6TOzklBmCyEZOpF/fLlGqH3BZHnwLDzQ==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.22.0.tgz",
|
||||
"integrity": "sha512-6uhL6RL7/FeW6u1INEgyKjd5dwO8+IsbLfkfC682QuoVLS7VG6OOB+JmTpCvnuyYWI6fqGh1bRk9ww8kPsj+EA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@lerna/check-working-tree": "3.16.5",
|
||||
"@lerna/child-process": "3.16.5",
|
||||
"@lerna/collect-updates": "3.20.0",
|
||||
"@lerna/command": "3.21.0",
|
||||
"@lerna/conventional-commits": "3.18.5",
|
||||
"@lerna/github-client": "3.16.5",
|
||||
"@lerna/conventional-commits": "3.22.0",
|
||||
"@lerna/github-client": "3.22.0",
|
||||
"@lerna/gitlab-client": "3.15.0",
|
||||
"@lerna/output": "3.13.0",
|
||||
"@lerna/prerelease-id-from-version": "3.16.0",
|
||||
@ -1062,25 +1062,16 @@
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz",
|
||||
"integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==",
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.2.tgz",
|
||||
"integrity": "sha512-xs1mmCEZ2y4shXCpFjNq3UbmNR+bLzxtZim2L0zfEtj9R6O6kc4qLDvYw66hvO6lUsYzPTM5hMkltbuNAbRAcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/types": "^2.11.1",
|
||||
"@octokit/types": "^4.0.1",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"universal-user-agent": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/types": {
|
||||
"version": "2.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
|
||||
"integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": ">= 8"
|
||||
}
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
|
||||
@ -1108,9 +1099,9 @@
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-enterprise-rest": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-3.6.2.tgz",
|
||||
"integrity": "sha512-3wF5eueS5OHQYuAEudkpN+xVeUsg8vYEMMenEzLphUZ7PRZ8OJtDcsreL3ad9zxXmBbaFWzLmFcdob5CLyZftA==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz",
|
||||
"integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==",
|
||||
"dev": true
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
@ -1161,14 +1152,14 @@
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz",
|
||||
"integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==",
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.4.tgz",
|
||||
"integrity": "sha512-vqv1lz41c6VTxUvF9nM+a6U+vvP3vGk7drDpr0DVQg4zyqlOiKVrY17DLD6de5okj+YLHKcoqaUZTBtlNZ1BtQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.0.0",
|
||||
"@octokit/types": "^2.11.1",
|
||||
"@octokit/types": "^4.0.1",
|
||||
"deprecation": "^2.0.0",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"node-fetch": "^2.3.0",
|
||||
@ -1185,26 +1176,6 @@
|
||||
"@octokit/types": "^4.0.1",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/types": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-4.0.1.tgz",
|
||||
"integrity": "sha512-Ho6h7w2h9y8RRE8r656hIj1oiSbwbIHJGF5r9G5FOwS2VdDPq8QLGvsG4x6pKHpvyGK7j+43sAc2cJKMiFoIJw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": ">= 8"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "2.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
|
||||
"integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": ">= 8"
|
||||
}
|
||||
},
|
||||
"is-plain-object": {
|
||||
@ -1280,9 +1251,9 @@
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-4.0.1.tgz",
|
||||
"integrity": "sha512-Ho6h7w2h9y8RRE8r656hIj1oiSbwbIHJGF5r9G5FOwS2VdDPq8QLGvsG4x6pKHpvyGK7j+43sAc2cJKMiFoIJw==",
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-4.0.2.tgz",
|
||||
"integrity": "sha512-+4X6qfhT/fk/5FD66395NrFLxCzD6FsGlpPwfwvnukdyfYbhiZB/FJltiT1XM5Q63rGGBSf9FPaNV3WpNHm54A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": ">= 8"
|
||||
@ -2037,9 +2008,9 @@
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
|
||||
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz",
|
||||
"integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
@ -4371,9 +4342,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "12.12.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.41.tgz",
|
||||
"integrity": "sha512-Q+eSkdYQJ2XK1AJnr4Ji8Gvk3sRDybEwfTvtL9CA25FFUSD2EgZQewN6VCyWYZCXg5MWZdwogdTNBhlWRcWS1w=="
|
||||
"version": "12.12.42",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.42.tgz",
|
||||
"integrity": "sha512-R/9QdYFLL9dE9l5cWWzWIZByVGFd7lk7JVOJ7KD+E1SJ4gni7XJRLz9QTjyYQiHIqEAgku9VgxdLjMlhhUaAFg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -7529,9 +7500,9 @@
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"jake": {
|
||||
"version": "10.6.1",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.6.1.tgz",
|
||||
"integrity": "sha512-pHUK3+V0BjOb1XSi95rbBksrMdIqLVC9bJqDnshVyleYsET3H0XAq+3VB2E3notcYvv4wRdRHn13p7vobG+wfQ==",
|
||||
"version": "10.7.1",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.7.1.tgz",
|
||||
"integrity": "sha512-FUkLZXms1LSTQop5EJBdXVzbM0q6yYWMM4vo/TiLQeHJ4UMJVO8DBTZFiAgMBJctin9q92xnr2vdH7Wrpn7tTQ==",
|
||||
"requires": {
|
||||
"async": "0.9.x",
|
||||
"chalk": "^2.4.2",
|
||||
@ -7611,9 +7582,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
|
||||
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@ -7739,9 +7710,9 @@
|
||||
}
|
||||
},
|
||||
"lerna": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/lerna/-/lerna-3.21.0.tgz",
|
||||
"integrity": "sha512-ux8yOwQEgIXOZVUfq+T8nVzPymL19vlIoPbysOP3YA4hcjKlqQIlsjI/1ugBe6b4MF7W4iV5vS3gH9cGqBBc1A==",
|
||||
"version": "3.22.0",
|
||||
"resolved": "https://registry.npmjs.org/lerna/-/lerna-3.22.0.tgz",
|
||||
"integrity": "sha512-xWlHdAStcqK/IjKvjsSMHPZjPkBV1lS60PmsIeObU8rLljTepc4Sg/hncw4HWfQxPIewHAUTqhrxPIsqf9L2Eg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@lerna/add": "3.21.0",
|
||||
@ -7749,17 +7720,17 @@
|
||||
"@lerna/changed": "3.21.0",
|
||||
"@lerna/clean": "3.21.0",
|
||||
"@lerna/cli": "3.18.5",
|
||||
"@lerna/create": "3.21.0",
|
||||
"@lerna/create": "3.22.0",
|
||||
"@lerna/diff": "3.21.0",
|
||||
"@lerna/exec": "3.21.0",
|
||||
"@lerna/import": "3.21.0",
|
||||
"@lerna/import": "3.22.0",
|
||||
"@lerna/info": "3.21.0",
|
||||
"@lerna/init": "3.21.0",
|
||||
"@lerna/link": "3.21.0",
|
||||
"@lerna/list": "3.21.0",
|
||||
"@lerna/publish": "3.21.0",
|
||||
"@lerna/publish": "3.22.0",
|
||||
"@lerna/run": "3.21.0",
|
||||
"@lerna/version": "3.21.0",
|
||||
"@lerna/version": "3.22.0",
|
||||
"import-local": "^2.0.0",
|
||||
"npmlog": "^4.1.2"
|
||||
}
|
||||
@ -8627,9 +8598,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-gyp": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz",
|
||||
"integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz",
|
||||
"integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"env-paths": "^2.2.0",
|
||||
@ -9485,14 +9456,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
|
||||
"integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz",
|
||||
"integrity": "sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==",
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"napi-build-utils": "^1.0.1",
|
||||
"node-abi": "^2.7.0",
|
||||
@ -10916,9 +10887,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
|
||||
"integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
|
||||
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
|
||||
"requires": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
|
@ -29,6 +29,18 @@ pub struct Path {
|
||||
|
||||
}
|
||||
|
||||
impl From<&FileSystemObject> for Path {
|
||||
fn from(file_system_object:&FileSystemObject) -> Path {
|
||||
match file_system_object {
|
||||
FileSystemObject::Directory{name,path} => path.append_im(name),
|
||||
FileSystemObject::File{name,path} => path.append_im(name),
|
||||
FileSystemObject::DirectoryTruncated{name,path} => path.append_im(name),
|
||||
FileSystemObject::Other{name,path} => path.append_im(name),
|
||||
FileSystemObject::SymlinkLoop{name,path,..} => path.append_im(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Path {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "//{}/", self.root_id)?;
|
||||
@ -37,6 +49,25 @@ impl Display for Path {
|
||||
}
|
||||
|
||||
impl Path {
|
||||
/// Splits path into name and path to parent directory. e.g.:
|
||||
/// Path{root_id,segments:["foo","bar","qux"]} => ("qux",Path{root_id,segments:["foo","bar"]})
|
||||
pub fn split(mut self) -> Option<(Path,String)> {
|
||||
self.segments.pop().map(|name| (self,name))
|
||||
}
|
||||
|
||||
/// Creates a new clone appending a new `segment`.
|
||||
pub fn append_im(&self, segment:impl Str) -> Self {
|
||||
let mut clone = self.clone();
|
||||
clone.segments.push(segment.into());
|
||||
clone
|
||||
}
|
||||
|
||||
/// Returns the parent `Path` if the current `Path` is not `root`.
|
||||
pub fn parent(&self) -> Option<Self> {
|
||||
let mut parent = self.clone();
|
||||
parent.segments.pop().map(|_| parent)
|
||||
}
|
||||
|
||||
/// Returns the file name, i.e. the last segment if exists.
|
||||
pub fn file_name(&self) -> Option<&String> {
|
||||
self.segments.last()
|
||||
@ -173,6 +204,34 @@ pub enum FileSystemObject {
|
||||
}
|
||||
}
|
||||
|
||||
impl FileSystemObject {
|
||||
/// Creates a new Directory variant.
|
||||
pub fn new_directory(path:Path) -> Option<Self> {
|
||||
path.split().map(|(path,name)| Self::Directory{name,path})
|
||||
}
|
||||
|
||||
/// Creates a new DirectoryTruncated variant.
|
||||
pub fn new_directory_truncated(path:Path) -> Option<Self> {
|
||||
path.split().map(|(path,name)| Self::DirectoryTruncated{name,path})
|
||||
}
|
||||
|
||||
/// Creates a new File variant.
|
||||
pub fn new_file(path:Path) -> Option<Self> {
|
||||
path.split().map(|(path,name)| Self::File{name,path})
|
||||
}
|
||||
|
||||
/// Creates a new Other variant.
|
||||
pub fn new_other(path:Path) -> Option<Self> {
|
||||
path.split().map(|(path,name)| Self::Other{name,path})
|
||||
}
|
||||
|
||||
/// Creates a new SymlinkLoop variant.
|
||||
pub fn new_symlink_loop(path:Path,target:Path) -> Option<Self> {
|
||||
path.split().map(|(path,name)| Self::SymlinkLoop{name,path,target})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
|
4
gui/src/rust/ide/src/config.rs
Normal file
4
gui/src/rust/ide/src/config.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//! This module provides constants used throughout the crate.
|
||||
|
||||
/// Visualization folder where IDE can look for user-defined visualizations per project.
|
||||
pub const PROJECT_VISUALIZATION_FOLDER:&str = "visualization";
|
@ -19,12 +19,14 @@ pub mod graph;
|
||||
pub mod module;
|
||||
pub mod project;
|
||||
pub mod text;
|
||||
pub mod visualization;
|
||||
|
||||
pub use graph::Handle as Graph;
|
||||
pub use graph::executed::Handle as ExecutedGraph;
|
||||
pub use module::Handle as Module;
|
||||
pub use project::Handle as Project;
|
||||
pub use text::Handle as Text;
|
||||
pub use visualization::Handle as Visualization;
|
||||
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::controller::FilePath;
|
||||
use crate::controller::Visualization;
|
||||
|
||||
use enso_protocol::language_server;
|
||||
use enso_protocol::binary;
|
||||
@ -24,6 +25,7 @@ type ModulePath = controller::module::Path;
|
||||
#[derive(Debug)]
|
||||
pub struct Handle {
|
||||
pub language_server_rpc : Rc<language_server::Connection>,
|
||||
pub visualization : Visualization,
|
||||
pub language_server_bin : Rc<binary::Connection>,
|
||||
pub module_registry : Rc<model::registry::Registry<ModulePath,model::synchronized::Module>>,
|
||||
pub parser : Parser,
|
||||
@ -37,13 +39,15 @@ impl Handle {
|
||||
, language_server_client : language_server::Connection
|
||||
, language_server_binary : binary::Connection
|
||||
) -> Self {
|
||||
Handle {
|
||||
module_registry : default(),
|
||||
parser : Parser::new_or_panic(),
|
||||
language_server_rpc : Rc::new(language_server_client),
|
||||
language_server_bin : Rc::new(language_server_binary),
|
||||
logger : parent.sub("Project Controller"),
|
||||
}
|
||||
let module_registry = default();
|
||||
let parser = Parser::new_or_panic();
|
||||
let language_server_rpc = Rc::new(language_server_client);
|
||||
let language_server_bin = Rc::new(language_server_binary);
|
||||
let logger = parent.sub("Project Controller");
|
||||
let embedded_visualizations = default();
|
||||
let language_server = language_server_rpc.clone();
|
||||
let visualization = Visualization::new(language_server,embedded_visualizations);
|
||||
Handle {module_registry,parser,language_server_rpc,language_server_bin,logger,visualization}
|
||||
}
|
||||
|
||||
/// Returns a text controller for a given file path.
|
||||
|
250
gui/src/rust/ide/src/controller/visualization.rs
Normal file
250
gui/src/rust/ide/src/controller/visualization.rs
Normal file
@ -0,0 +1,250 @@
|
||||
//! Visualization controller.
|
||||
//!
|
||||
//! Ths Visualization Controller is Responsible identifying all the available visualizations
|
||||
//! natively embedded in IDE and available within the project's `visualization` folder.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::config::PROJECT_VISUALIZATION_FOLDER;
|
||||
|
||||
use enso_protocol::language_server;
|
||||
use graph_editor::component::visualization::class;
|
||||
use graph_editor::component::visualization::JsSourceClass;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Error ===
|
||||
// =============
|
||||
|
||||
/// Enumeration of errors used in `Visualization Controller`.
|
||||
#[derive(Debug,Fail)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum VisualizationError {
|
||||
#[fail(display = "Visualization \"{}\" not found.", identifier)]
|
||||
NotFound {
|
||||
identifier : VisualizationPath
|
||||
},
|
||||
#[fail(display = "JavaScript visualization \"{}\" failed to be instantiated.", identifier)]
|
||||
InstantiationError {
|
||||
identifier : VisualizationPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =========================
|
||||
// === VisualizationPath ===
|
||||
// =========================
|
||||
|
||||
/// This enum is used to provide a path to visualization either in the project folder or natively
|
||||
/// embedded in IDE.
|
||||
#[derive(Clone,Debug,Display,Eq,PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum VisualizationPath {
|
||||
Embedded(String),
|
||||
File(language_server::Path)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============================
|
||||
// === EmbeddedVisualizations ===
|
||||
// ==============================
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub type EmbeddedVisualizationName = String;
|
||||
|
||||
/// Embedded visualizations mapped from name to source code.
|
||||
#[derive(Shrinkwrap,Debug,Clone,Default)]
|
||||
#[shrinkwrap(mutable)]
|
||||
pub struct EmbeddedVisualizations {
|
||||
#[allow(missing_docs)]
|
||||
pub map:HashMap<EmbeddedVisualizationName,Rc<class::Handle>>
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Handle ===
|
||||
// ==============
|
||||
|
||||
/// Visualization Controller is responsible for listing and loading all the available
|
||||
/// visualizations on the project and the native ones embedded on IDE.
|
||||
#[derive(Debug,Clone,CloneRef)]
|
||||
pub struct Handle {
|
||||
language_server_rpc : Rc<language_server::Connection>,
|
||||
embedded_visualizations : Rc<RefCell<EmbeddedVisualizations>>
|
||||
}
|
||||
|
||||
impl Handle {
|
||||
/// Creates a new visualization controller.
|
||||
pub fn new
|
||||
( language_server_rpc : Rc<language_server::Connection>
|
||||
, embedded_visualizations : EmbeddedVisualizations) -> Self {
|
||||
let embedded_visualizations = Rc::new(RefCell::new(embedded_visualizations));
|
||||
Self {language_server_rpc,embedded_visualizations}
|
||||
}
|
||||
|
||||
async fn list_project_specific_visualizations
|
||||
(&self) -> FallibleResult<Vec<VisualizationPath>> {
|
||||
let root_id = self.language_server_rpc.content_root();
|
||||
let path = language_server::Path::new(root_id,&[PROJECT_VISUALIZATION_FOLDER]);
|
||||
let folder = self.language_server_rpc.file_exists(&path).await?;
|
||||
let file_list = if folder.exists {
|
||||
self.language_server_rpc.file_list(&path).await?.paths
|
||||
} else {
|
||||
default()
|
||||
};
|
||||
let result = file_list.iter().filter_map(|object| {
|
||||
if let language_server::FileSystemObject::File{..} = object {
|
||||
Some(VisualizationPath::File(object.into()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn list_embedded_visualizations(&self) -> Vec<VisualizationPath> {
|
||||
let embedded_visualizations = self.embedded_visualizations.borrow();
|
||||
let result = embedded_visualizations.keys().cloned();
|
||||
let result = result.map(VisualizationPath::Embedded);
|
||||
result.collect()
|
||||
}
|
||||
|
||||
/// Get a list of all available visualizations.
|
||||
pub async fn list_visualizations(&self) -> FallibleResult<Vec<VisualizationPath>> {
|
||||
let mut visualizations = self.list_embedded_visualizations();
|
||||
visualizations.extend_from_slice(&self.list_project_specific_visualizations().await?);
|
||||
Ok(visualizations)
|
||||
}
|
||||
|
||||
/// Load the source code of the specified visualization.
|
||||
pub async fn load_visualization
|
||||
(&self, visualization:&VisualizationPath) -> FallibleResult<Rc<class::Handle>> {
|
||||
match visualization {
|
||||
VisualizationPath::Embedded(identifier) => {
|
||||
let embedded_visualizations = self.embedded_visualizations.borrow();
|
||||
let result = embedded_visualizations.get(identifier);
|
||||
let identifier = visualization.clone();
|
||||
let error = || VisualizationError::NotFound{identifier}.into();
|
||||
result.cloned().ok_or_else(error)
|
||||
},
|
||||
VisualizationPath::File(path) => {
|
||||
let js_code = self.language_server_rpc.read_file(&path).await?.contents;
|
||||
let identifier = visualization.clone();
|
||||
let error = |_| VisualizationError::InstantiationError {identifier}.into();
|
||||
let js_class = JsSourceClass::from_js_source_raw(&js_code).map_err(error);
|
||||
js_class.map(|js_class| Rc::new(class::Handle::new(js_class)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Tests ===
|
||||
// =============
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use ensogl::display::Scene;
|
||||
use enso_protocol::language_server::FileSystemObject;
|
||||
use enso_protocol::language_server::Path;
|
||||
use graph_editor::component::visualization::{NativeConstructorClass, Signature, Visualization};
|
||||
use graph_editor::component::visualization::renderer::example::native::BubbleChart;
|
||||
use json_rpc::expect_call;
|
||||
|
||||
use wasm_bindgen_test::wasm_bindgen_test_configure;
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test(async)]
|
||||
async fn list_and_load() {
|
||||
let mock_client = language_server::MockClient::default();
|
||||
|
||||
let root_id = uuid::Uuid::default();
|
||||
let path = Path::new(root_id,&["visualization"]);
|
||||
let path0 = Path::new(root_id,&["visualization","histogram.js"]);
|
||||
let path1 = Path::new(root_id,&["visualization","graph.js"]);
|
||||
|
||||
let paths = vec![
|
||||
FileSystemObject::new_file(path0.clone()).unwrap(),
|
||||
FileSystemObject::new_file(path1.clone()).unwrap(),
|
||||
];
|
||||
let file_list_result = language_server::response::FileList{paths};
|
||||
expect_call!(mock_client.file_list(path=path.clone()) => Ok(file_list_result));
|
||||
|
||||
let file_content0 = r#"
|
||||
class Vis0 {
|
||||
static inputTypes = ["Float"]
|
||||
onDataReceived(root,data) {}
|
||||
setSize(root,size) {}
|
||||
}
|
||||
return Vis0
|
||||
"#.to_string();
|
||||
let file_content1 = r#"
|
||||
class Vis1 {
|
||||
static inputTypes = ["Float"]
|
||||
onDataReceived(root,data) {}
|
||||
setSize(root,size) {}
|
||||
}
|
||||
return Vis1
|
||||
"#.to_string();
|
||||
let read_result0 = language_server::response::Read{contents:file_content0.clone()};
|
||||
let read_result1 = language_server::response::Read{contents:file_content1.clone()};
|
||||
let exists_result0 = language_server::response::FileExists{exists:true};
|
||||
let exists_result1 = language_server::response::FileExists{exists:true};
|
||||
expect_call!(mock_client.file_exists(path=path.clone()) => Ok(exists_result0));
|
||||
expect_call!(mock_client.file_exists(path=path.clone()) => Ok(exists_result1));
|
||||
expect_call!(mock_client.read_file(path=path0.clone()) => Ok(read_result0));
|
||||
expect_call!(mock_client.read_file(path=path1.clone()) => Ok(read_result1));
|
||||
|
||||
let language_server = language_server::Connection::new_mock_rc(mock_client);
|
||||
let mut embedded_visualizations = EmbeddedVisualizations::default();
|
||||
let embedded_visualization = Rc::new(class::Handle::new(NativeConstructorClass::new(
|
||||
Signature {
|
||||
name : "Bubble Visualization (native)".to_string(),
|
||||
input_types : vec!["[[Float,Float,Float]]".to_string().into()],
|
||||
},
|
||||
|scene:&Scene| Ok(Visualization::new(BubbleChart::new(scene)))
|
||||
)));
|
||||
embedded_visualizations.insert("PointCloud".to_string(),embedded_visualization.clone());
|
||||
let vis_controller = Handle::new(language_server,embedded_visualizations);
|
||||
|
||||
let visualizations = vis_controller.list_visualizations().await;
|
||||
let visualizations = visualizations.expect("Couldn't list visualizations.");
|
||||
|
||||
assert_eq!(visualizations[0], VisualizationPath::Embedded("PointCloud".to_string()));
|
||||
assert_eq!(visualizations[1], VisualizationPath::File(path0));
|
||||
assert_eq!(visualizations[2], VisualizationPath::File(path1));
|
||||
assert_eq!(visualizations.len(),3);
|
||||
|
||||
let javascript_vis0 = JsSourceClass::from_js_source_raw(&file_content0);
|
||||
let javascript_vis1 = JsSourceClass::from_js_source_raw(&file_content1);
|
||||
let javascript_vis0 = javascript_vis0.expect("Couldn't create visualization class.");
|
||||
let javascript_vis1 = javascript_vis1.expect("Couldn't create visualization class.");
|
||||
let javascript_vis0 = Rc::new(class::Handle::new(javascript_vis0));
|
||||
let javascript_vis1 = Rc::new(class::Handle::new(javascript_vis1));
|
||||
|
||||
let expected_visualizations = vec![embedded_visualization,javascript_vis0,javascript_vis1];
|
||||
let zipped = visualizations.iter().zip(expected_visualizations.iter());
|
||||
for (visualization,expected_visualization) in zipped {
|
||||
let loaded_visualization = vis_controller.load_visualization(&visualization).await;
|
||||
let loaded_visualization = loaded_visualization.expect("Couldn't load visualization's content.");
|
||||
let loaded_class = loaded_visualization.class();
|
||||
let loaded_class = loaded_class.as_ref();
|
||||
let loaded_signature = loaded_class.expect("Couldn't get class.").signature();
|
||||
let expected_class = expected_visualization.class();
|
||||
let expected_class = expected_class.as_ref();
|
||||
let expected_signature = expected_class.expect("Couldn't get class.").signature();
|
||||
assert_eq!(loaded_signature,expected_signature);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
#![warn(missing_copy_implementations)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
|
||||
pub mod config;
|
||||
pub mod controller;
|
||||
pub mod double_representation;
|
||||
pub mod executor;
|
||||
|
@ -18,7 +18,7 @@ use nalgebra::Vector2;
|
||||
use nalgebra::zero;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use graph_editor::GraphEditor;
|
||||
|
||||
|
||||
// ==================
|
||||
@ -87,26 +87,30 @@ impl ViewLayoutData {
|
||||
|
||||
impl ViewLayout {
|
||||
/// Creates a new ViewLayout with a single TextEditor.
|
||||
pub fn new
|
||||
pub async fn new
|
||||
( logger : &Logger
|
||||
, kb_actions : &mut keyboard::Actions
|
||||
, application : &Application
|
||||
, text_controller : controller::Text
|
||||
, graph_controller : controller::ExecutedGraph
|
||||
, visualization_controller : controller::Visualization
|
||||
, fonts : &mut font::Registry
|
||||
) -> Self {
|
||||
) -> FallibleResult<Self> {
|
||||
let logger = logger.sub("ViewLayout");
|
||||
let world = &application.display;
|
||||
let text_editor = TextEditor::new(&logger,world,text_controller,kb_actions,fonts);
|
||||
let node_editor = NodeEditor::new(&logger,application,graph_controller.clone_ref());
|
||||
let node_searcher = NodeSearcher::new(world,&logger,graph_controller.graph.clone_ref(),fonts);
|
||||
let graph = graph_controller.graph.clone_ref();
|
||||
let node_searcher = NodeSearcher::new(world,&logger,graph,fonts);
|
||||
let graph_controller = graph_controller.clone_ref();
|
||||
let node_editor = NodeEditor::new
|
||||
(&logger,application,graph_controller,visualization_controller).await?;
|
||||
world.add_child(&text_editor.display_object());
|
||||
world.add_child(&node_editor);
|
||||
world.add_child(&node_searcher);
|
||||
let size = zero();
|
||||
let data = ViewLayoutData {text_editor,node_editor,node_searcher,size,logger};
|
||||
let rc = Rc::new(RefCell::new(data));
|
||||
Self {rc}.init(world,kb_actions)
|
||||
Ok(Self {rc}.init(world,kb_actions))
|
||||
}
|
||||
|
||||
fn init_keyboard(self, _keyboard_actions:&mut keyboard::Actions) -> Self {
|
||||
@ -120,4 +124,9 @@ impl ViewLayout {
|
||||
self.set_size(size);
|
||||
self.init_keyboard(keyboard_actions)
|
||||
}
|
||||
|
||||
/// Get GraphEditor.
|
||||
pub fn graph_editor(&self) -> GraphEditor {
|
||||
self.rc.borrow_mut().node_editor.graph.graph_editor()
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,13 @@ pub struct GraphEditorIntegratedWithController {
|
||||
network : frp::Network,
|
||||
}
|
||||
|
||||
impl GraphEditorIntegratedWithController {
|
||||
/// Get GraphEditor.
|
||||
pub fn graph_editor(&self) -> GraphEditor {
|
||||
self.model.editor.clone_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GraphEditorIntegratedWithControllerModel {
|
||||
logger : Logger,
|
||||
@ -438,19 +445,40 @@ impl GraphEditorIntegratedWithControllerModel {
|
||||
#[derive(Clone,CloneRef,Debug)]
|
||||
pub struct NodeEditor {
|
||||
display_object : display::object::Instance,
|
||||
graph : Rc<GraphEditorIntegratedWithController>,
|
||||
#[allow(missing_docs)]
|
||||
pub graph : Rc<GraphEditorIntegratedWithController>,
|
||||
controller : controller::ExecutedGraph,
|
||||
visualization : controller::Visualization
|
||||
}
|
||||
|
||||
impl NodeEditor {
|
||||
/// Create Node Editor Panel.
|
||||
pub fn new(logger:&Logger, app:&Application, controller:controller::ExecutedGraph) -> Self {
|
||||
pub async fn new
|
||||
( logger : &Logger
|
||||
, app : &Application
|
||||
, controller : controller::ExecutedGraph
|
||||
, visualization : controller::Visualization) -> FallibleResult<Self> {
|
||||
let logger = logger.sub("NodeEditor");
|
||||
let display_object = display::object::Instance::new(&logger);
|
||||
let graph = GraphEditorIntegratedWithController::new(logger,app,controller.clone_ref());
|
||||
let graph = Rc::new(graph);
|
||||
display_object.add_child(&graph.model.editor);
|
||||
NodeEditor {display_object,graph,controller}
|
||||
Ok(NodeEditor {display_object,graph,controller,visualization}.init().await?)
|
||||
}
|
||||
|
||||
async fn init(self) -> FallibleResult<Self> {
|
||||
let graph_editor = self.graph.graph_editor();
|
||||
let identifiers = self.visualization.list_visualizations().await;
|
||||
let identifiers = identifiers.unwrap_or_default();
|
||||
for identifier in identifiers {
|
||||
let visualization = self.visualization.load_visualization(&identifier).await;
|
||||
let visualization = visualization.map(|visualization| {
|
||||
let class_handle = &Some(visualization);
|
||||
graph_editor.frp.register_visualization_class.emit_event(class_handle);
|
||||
});
|
||||
visualization?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,8 +93,9 @@ impl ProjectView {
|
||||
let mut keyboard_actions = keyboard::Actions::new(&keyboard);
|
||||
let resize_callback = None;
|
||||
let mut fonts = font::Registry::new();
|
||||
let layout = ViewLayout::new(&logger,&mut keyboard_actions,&application,
|
||||
text_controller,graph_controller,&mut fonts);
|
||||
let visualization_controller = controller.visualization.clone();
|
||||
let layout = ViewLayout::new(&logger,&mut keyboard_actions,&application, text_controller,
|
||||
graph_controller,visualization_controller,&mut fonts).await?;
|
||||
let data = ProjectViewData {application,layout,resize_callback,controller,keyboard,
|
||||
keyboard_bindings,keyboard_actions};
|
||||
Ok(Self::new_from_data(data).init())
|
||||
|
@ -57,8 +57,6 @@ wasm_bindgen_test_configure!(run_in_browser);
|
||||
//#[wasm_bindgen_test::wasm_bindgen_test(async)]
|
||||
#[allow(dead_code)]
|
||||
async fn file_operations() {
|
||||
ensogl::system::web::set_stdout();
|
||||
|
||||
let ws = WebSocket::new_opened(default(),SERVER_ENDPOINT).await;
|
||||
let ws = ws.expect("Couldn't connect to WebSocket server.");
|
||||
let client = Client::new(ws);
|
||||
@ -201,7 +199,6 @@ async fn file_operations() {
|
||||
//#[wasm_bindgen_test::wasm_bindgen_test(async)]
|
||||
#[allow(dead_code)]
|
||||
async fn file_events() {
|
||||
ensogl::system::web::set_stdout();
|
||||
let ws = WebSocket::new_opened(default(),SERVER_ENDPOINT).await;
|
||||
let ws = ws.expect("Couldn't connect to WebSocket server.");
|
||||
let client = Client::new(ws);
|
||||
@ -256,7 +253,6 @@ async fn file_events() {
|
||||
/// * establishing a binary protocol connection with Language Server
|
||||
/// * writing and reading a file using the binary protocol
|
||||
async fn binary_protocol_test() {
|
||||
ensogl_system_web::set_stdout();
|
||||
// Setup project
|
||||
let _guard = ide::setup_global_executor();
|
||||
let logger = Logger::new("Test");
|
||||
|
@ -31,5 +31,6 @@ pub mod shape_system;
|
||||
pub mod sprite_system;
|
||||
pub mod text_field;
|
||||
pub mod text_typing;
|
||||
pub mod visualization;
|
||||
|
||||
pub use enso_prelude as prelude;
|
||||
|
@ -181,6 +181,8 @@ use graph_editor::component::node::port::Expression;
|
||||
|
||||
|
||||
pub fn expression_mock() -> Expression {
|
||||
let pattern_crumb = vec![Seq{right:false },Or,Or,Build];
|
||||
let _val = ast::crumbs::SegmentMatchCrumb::Body{val:pattern_crumb};
|
||||
let code = "open \"data.csv\"".into();
|
||||
let output_span_tree = default();
|
||||
let input_span_tree = span_tree::builder::TreeBuilder::new(15)
|
||||
|
124
gui/src/rust/lib/debug-scenes/src/visualization.rs
Normal file
124
gui/src/rust/lib/debug-scenes/src/visualization.rs
Normal file
@ -0,0 +1,124 @@
|
||||
//! This is a visualization example scene which creates a sinusoidal graph.
|
||||
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display::navigation::navigator::Navigator;
|
||||
use ensogl::system::web;
|
||||
use ensogl_core_msdf_sys::run_once_initialized;
|
||||
use graph_editor::component::visualization::Data;
|
||||
use graph_editor::component::visualization::JsSourceClass;
|
||||
use graph_editor::component::visualization::Registry;
|
||||
use js_sys::Math::sin;
|
||||
use nalgebra::Vector2;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
fn generate_data(seconds:f64) -> Vec<Vector2<f32>> {
|
||||
let mut data = Vec::new();
|
||||
for x in 0..100 {
|
||||
let x = x as f64 / 50.0 - 1.0;
|
||||
let y = sin(x * std::f64::consts::PI + seconds);
|
||||
data.push(Vector2::new(x as f32,y as f32));
|
||||
}
|
||||
data
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn constructor_graph() -> JsSourceClass {
|
||||
let fn_constructor = r#"
|
||||
class Graph {
|
||||
static inputTypes = ["[[Float,Float,Float]]"]
|
||||
|
||||
onDataReceived(root, data) {
|
||||
if (!root.canvas) {
|
||||
root.canvas = document.createElement("canvas");
|
||||
root.context = root.canvas.getContext("2d");
|
||||
root.appendChild(root.canvas);
|
||||
}
|
||||
|
||||
let first = data.shift();
|
||||
if (first) {
|
||||
root.context.clearRect(0,0,root.canvas.width,root.canvas.height);
|
||||
root.context.save();
|
||||
root.context.scale(root.canvas.width/2,root.canvas.height/2);
|
||||
root.context.translate(1,1);
|
||||
root.context.lineWidth = 1/Math.min(root.canvas.width,root.canvas.height);
|
||||
root.context.beginPath();
|
||||
root.context.moveTo(first[0],first[1]);
|
||||
data.forEach(data => {
|
||||
root.context.lineTo(data[0],data[1]);
|
||||
});
|
||||
root.context.stroke();
|
||||
root.context.restore();
|
||||
root.context.beginPath();
|
||||
root.context.moveTo(first[0],first[1]);
|
||||
root.context.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
setSize(root, size) {
|
||||
if (root.canvas) {
|
||||
root.canvas.width = size[0];
|
||||
root.canvas.height = size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Graph;
|
||||
"#;
|
||||
JsSourceClass::from_js_source_raw(fn_constructor).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(dead_code,missing_docs)]
|
||||
pub fn run_example_visualization() {
|
||||
web::forward_panic_hook_to_console();
|
||||
web::set_stdout();
|
||||
web::set_stack_trace_limit();
|
||||
run_once_initialized(|| {
|
||||
let app = Application::new(&web::get_html_element_by_id("root").unwrap());
|
||||
init(&app);
|
||||
std::mem::forget(app);
|
||||
});
|
||||
}
|
||||
|
||||
fn init(app:&Application) {
|
||||
let world = &app.display;
|
||||
let scene = world.scene();
|
||||
let camera = scene.camera();
|
||||
let navigator = Navigator::new(&scene,&camera);
|
||||
let registry = Registry::with_default_visualizations();
|
||||
|
||||
registry.register_class(constructor_graph());
|
||||
|
||||
let vis_factories = registry.valid_sources(&"[[Float,Float,Float]]".into());
|
||||
let vis_class = vis_factories.iter().find(|class| {
|
||||
class.signature().name == "Graph"
|
||||
}).expect("Couldn't find Graph class.");
|
||||
let visualization = vis_class.instantiate(&scene).expect("Couldn't create visualiser.");
|
||||
|
||||
let mut was_rendered = false;
|
||||
let mut loader_hidden = false;
|
||||
world.on_frame(move |time_info| {
|
||||
let _keep_alive = &navigator;
|
||||
|
||||
let data = generate_data((time_info.local / 1000.0).into());
|
||||
let data = Rc::new(data);
|
||||
let content = Rc::new(serde_json::to_value(data).unwrap());
|
||||
let data = Data::JSON{content};
|
||||
|
||||
visualization.frp.set_data.emit(Some(data));
|
||||
|
||||
// Temporary code removing the web-loader instance.
|
||||
// To be changed in the future.
|
||||
if was_rendered && !loader_hidden {
|
||||
web::get_element_by_id("loader").map(|t| {
|
||||
t.parent_node().map(|p| {
|
||||
p.remove_child(&t).unwrap()
|
||||
})
|
||||
}).ok();
|
||||
loader_hidden = true;
|
||||
}
|
||||
was_rendered = true;
|
||||
}).forget();
|
||||
}
|
@ -39,7 +39,7 @@ impl From<&str> for EnsoType {
|
||||
}
|
||||
|
||||
/// Contains general information about a visualization.
|
||||
#[derive(Clone,Debug)]
|
||||
#[derive(Clone,Debug,PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Signature {
|
||||
pub name : String,
|
||||
|
@ -244,7 +244,7 @@ ensogl::def_command_api! { Commands
|
||||
remove_selected_nodes,
|
||||
/// Remove all nodes from the graph.
|
||||
remove_all_nodes,
|
||||
/// Toggle the visibility of the selected visualizations
|
||||
/// Toggle the visibility of the selected visualizations.
|
||||
toggle_visualization_visibility,
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user