From 180945088d6a83d4d0c87f3b84e011775a0c52e7 Mon Sep 17 00:00:00 2001 From: angelozerr Date: Mon, 11 Jan 2021 17:48:20 +0100 Subject: [PATCH] Provide embedded documentation Fixes #35 Signed-off-by: azerr --- README.md | 40 +-- docs/Consuming.md | 14 + docs/Explorer.md | 23 ++ docs/Producing.md | 35 +++ docs/README.md | 7 + docs/assets/open-doc-cmd.png | Bin 0 -> 6501 bytes {assets => docs/assets}/screen-1.png | Bin {assets => docs/assets}/screen-2.png | Bin {assets => docs/assets}/screen-3.png | Bin {assets => docs/assets}/screen-4.png | Bin package-lock.json | 404 ++++++++++++++++++++++++++- package.json | 21 +- src/docs/markdownPreviewProvider.ts | 122 ++++++++ src/extension.ts | 21 ++ webview-resources/document.css | 19 ++ webview-resources/highlight.css | 191 +++++++++++++ webview-resources/markdown.css | 218 +++++++++++++++ 17 files changed, 1089 insertions(+), 26 deletions(-) create mode 100644 docs/Consuming.md create mode 100644 docs/Explorer.md create mode 100644 docs/Producing.md create mode 100644 docs/README.md create mode 100644 docs/assets/open-doc-cmd.png rename {assets => docs/assets}/screen-1.png (100%) rename {assets => docs/assets}/screen-2.png (100%) rename {assets => docs/assets}/screen-3.png (100%) rename {assets => docs/assets}/screen-4.png (100%) create mode 100644 src/docs/markdownPreviewProvider.ts create mode 100644 webview-resources/document.css create mode 100644 webview-resources/highlight.css create mode 100644 webview-resources/markdown.css diff --git a/README.md b/README.md index 01de06e..3fe22eb 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,25 @@ Planned features in no particular order: - More administration features - Update configs -## Screenshots -![Screenshot-1](assets/screen-1.png) +You might also find useful information in the [Online Documentation](https://github.com/jlandersen/vscode-kafka/blob/master/docs/README.md) +or you can read this documentation inside your editor with the command `Open Documentation` available with `Ctrl+Shift+P`: -![Screenshot-2](assets/screen-2.png) +![Open Documentation](docs/assets/open-doc-cmd.png) -![Screenshot-3](assets/screen-3.png) +## Kafka explorer + +The Kafka explorer shows configured clusters with their topics, brokers, consumers and configurations. + +![Screenshot-1](docs/assets/screen-1.png) + +![Screenshot-2](docs/assets/screen-2.png) + +![Screenshot-3](docs/assets/screen-3.png) + +See [Kafka explorer](https://github.com/jlandersen/vscode-kafka/blob/master/docs/Explorer.md) section for more informations. + +## Producing messages -## Producing Producing can be done by creating a `.kafka` file. Write simple producers using the following format: ```json @@ -45,22 +56,15 @@ topic: json-events } ``` -For actually producing a single record, click on the "Produce record" link above the PRODUCER line; for producing 10 records, click on "Produce record x 10". -The log about produced messages is printed in the "Kafka Producer Log" Output view. - -Record content can be randomized by injecting mustache-like placeholders of [faker.js properties](https://github.com/Marak/faker.js#api-methods), like ``{{name.lastName}}`` or ``{{random.number}}``. Some randomized properties can be localized via the `kafka.producers.fakerjs.locale` setting. - -![Screenshot-4](assets/screen-4.png) +![Screenshot-4](docs/assets/screen-4.png) -## Consuming -Consuming topics can be done by right clicking a topic in the explorer or from the command palette. Some things to note about consuming: +See [Producing messages](https://github.com/jlandersen/vscode-kafka/blob/master/docs/Producing.md) section for more informations. -* UTF-8 encoded keys and values only. If data is encoded differently, it will not be pretty. -* One consumer group is created per topic (may change in the future to just have one for the extension). +## Consuming messages -Consumers are based on virtual documents, available in the VS Code extension API. A consumer will keep running even if you close the document in the editor. You should make sure to close the consumer explicitly, either via the command palette, the status bar element or the start/stop action button as well. The VS Code API does not support detecting if a virtual document is closed immediately. Instead, the underlying virtual document is automatically closed after two minutes if the document is closed in the editor. +Consuming topics can be done by right clicking a topic in the explorer or from the command palette. -You can configure start offset for new consumers in settings (earliest, latest). +See [Consuming messages](https://github.com/jlandersen/vscode-kafka/blob/master/docs/Consuming.md) section for more informations. ## CI Builds @@ -69,4 +73,4 @@ vscode-kafka is built using Github Actions. Here's how to download and install t - Click on the most recent run, - Locate the vscode-kafka artifact down the page and download it, - Unzip the archive, -- Install the vscode-kafka-*.vsix extension by following these [instructions](https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix). +- Install the vscode-kafka-*.vsix extension by following these [instructions](https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix). \ No newline at end of file diff --git a/docs/Consuming.md b/docs/Consuming.md new file mode 100644 index 0000000..d278bf8 --- /dev/null +++ b/docs/Consuming.md @@ -0,0 +1,14 @@ +# Consuming messages + +Consuming topics can be done by right clicking a topic in the explorer or from the command palette. Some things to note about consuming: + +* UTF-8 encoded keys and values only. If data is encoded differently, it will not be pretty. +* One consumer group is created per topic (may change in the future to just have one for the extension). + +Consumers are based on virtual documents, available in the VS Code extension API. A consumer will keep running even if you close the document in the editor. You should make sure to close the consumer explicitly, either via the command palette, the status bar element or the start/stop action button as well. The VS Code API does not support detecting if a virtual document is closed immediately. Instead, the underlying virtual document is automatically closed after two minutes if the document is closed in the editor. + +## Preferences + +### `kafka.consumers.offset` + +You can configure start offset for new consumers in settings (earliest, latest). diff --git a/docs/Explorer.md b/docs/Explorer.md new file mode 100644 index 0000000..e15dd87 --- /dev/null +++ b/docs/Explorer.md @@ -0,0 +1,23 @@ +# Explorer + +The Kafka explorer shows configured clusters with their topics, brokers, consumers and configurations. + +![Screenshot-1](assets/screen-1.png) + +![Screenshot-2](assets/screen-2.png) + +![Screenshot-3](assets/screen-3.png) + +## Preferences + +### `kafka.explorer.topics.sort` + +Choose sorting for topics in explorer. + +### `kafka.explorer.topics.filter` + +Glob patterns filtering topics out of the Kafka explorer. `*` matches any string, `?` matches a single character. + +### `kafka.explorer.consumers.filter` + +Glob patterns filtering consumer groups out of the Kafka explorer. `*` matches any string, `?` matches a single character. \ No newline at end of file diff --git a/docs/Producing.md b/docs/Producing.md new file mode 100644 index 0000000..714ace9 --- /dev/null +++ b/docs/Producing.md @@ -0,0 +1,35 @@ +# Producing messages + +Producing can be done by creating a `.kafka` file. Write simple producers using the following format: + +``` +PRODUCER keyed-message +topic: my-topic +key: mykeyq +record content + +### + +PRODUCER non-keyed-json-message +topic: json-events +{ + "type": "my_test_event" +} +``` + +For actually producing a single record, click on the `Produce record` link above the `PRODUCER` line; for producing 10 records, click on `Produce record x 10`. +The log about produced messages is printed in the `Kafka Producer Log` Output view. + +## Randomized content + +Record content can be randomized by injecting mustache-like placeholders of [faker.js properties](https://github.com/Marak/faker.js#api-methods), like ``{{name.lastName}}`` or ``{{random.number}}``. Some randomized properties can be localized via the `kafka.producers.fakerjs.locale` setting. + +![Screenshot-4](assets/screen-4.png) + +### `kafka.producers.fakerjs.enabled` + +Enable injection of [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates, using the mustache syntax. + +### `kafka.producers.fakerjs.locale` + +[experimental] The locale used to generate [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..759c0b4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# Kafka Documentation + +Welcome to the [vscode-kafka](https://github.com/jlandersen/vscode-kafka) documentation. + +* [Kafka Explorer](Explorer.md#explorer) +* [Producing messages](Producing.md#producing-messages) +* [Consuming messages](Consuming.md#consuming-messages) diff --git a/docs/assets/open-doc-cmd.png b/docs/assets/open-doc-cmd.png new file mode 100644 index 0000000000000000000000000000000000000000..81b6c6189c61dd63bb0d102f02e99d39a80f52d8 GIT binary patch literal 6501 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 DA{q^< literal 0 HcmV?d00001 diff --git a/assets/screen-1.png b/docs/assets/screen-1.png similarity index 100% rename from assets/screen-1.png rename to docs/assets/screen-1.png diff --git a/assets/screen-2.png b/docs/assets/screen-2.png similarity index 100% rename from assets/screen-2.png rename to docs/assets/screen-2.png diff --git a/assets/screen-3.png b/docs/assets/screen-3.png similarity index 100% rename from assets/screen-3.png rename to docs/assets/screen-3.png diff --git a/assets/screen-4.png b/docs/assets/screen-4.png similarity index 100% rename from assets/screen-4.png rename to docs/assets/screen-4.png diff --git a/package-lock.json b/package-lock.json index 0331ea4..752ecbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -135,6 +135,15 @@ "integrity": "sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw==", "dev": true }, + "@types/fs-extra": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.1.tgz", + "integrity": "sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -658,6 +667,18 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, + "azure-devops-node-api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", + "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", + "dev": true, + "requires": { + "os": "0.1.1", + "tunnel": "0.0.4", + "typed-rest-client": "1.2.0", + "underscore": "1.8.3" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -675,6 +696,12 @@ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -712,6 +739,12 @@ "node-releases": "^1.1.66" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -758,6 +791,34 @@ } } }, + "cheerio": { + "version": "1.0.0-rc.5", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.5.tgz", + "integrity": "sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==", + "dev": true, + "requires": { + "cheerio-select-tmp": "^0.1.0", + "dom-serializer": "~1.2.0", + "domhandler": "^4.0.0", + "entities": "~2.1.0", + "htmlparser2": "^6.0.0", + "parse5": "^6.0.0", + "parse5-htmlparser2-tree-adapter": "^6.0.0" + } + }, + "cheerio-select-tmp": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz", + "integrity": "sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==", + "dev": true, + "requires": { + "css-select": "^3.1.2", + "css-what": "^4.0.0", + "domelementtype": "^2.1.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.4" + } + }, "chokidar": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", @@ -895,6 +956,25 @@ "which": "^2.0.1" } }, + "css-select": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", + "dev": true + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -913,6 +993,12 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -937,6 +1023,43 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", + "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", + "dev": true + }, + "domhandler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "dev": true, + "requires": { + "domelementtype": "^2.1.0" + } + }, + "domutils": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz", + "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0" + } + }, "electron-to-chromium": { "version": "1.3.603", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.603.tgz", @@ -996,6 +1119,12 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + }, "envinfo": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", @@ -1336,6 +1465,15 @@ "reusify": "^1.0.4" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -1397,6 +1535,16 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1498,8 +1646,7 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "growl": { "version": "1.10.5", @@ -1528,6 +1675,18 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "htmlparser2": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.0.tgz", + "integrity": "sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.4.4", + "entities": "^2.0.0" + } + }, "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", @@ -1767,6 +1926,14 @@ "minimist": "^1.2.0" } }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, "kafkajs": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-1.15.0.tgz", @@ -1788,6 +1955,15 @@ "type-check": "~0.4.0" } }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "loader-runner": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", @@ -1866,6 +2042,33 @@ } } }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + } + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1878,6 +2081,12 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", @@ -2033,6 +2242,12 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, "nanoid": { "version": "3.1.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", @@ -2072,6 +2287,15 @@ "path-key": "^3.0.0" } }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -2109,6 +2333,34 @@ "word-wrap": "^1.2.3" } }, + "os": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", + "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "p-limit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", @@ -2142,6 +2394,30 @@ "callsites": "^3.0.0" } }, + "parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "requires": { + "semver": "^5.1.0" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + } + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -2171,6 +2447,12 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -2271,6 +2553,15 @@ "safe-buffer": "^5.1.0" } }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -2399,6 +2690,12 @@ "ajv-keywords": "^3.5.2" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -2661,6 +2958,15 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2707,6 +3013,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2722,6 +3034,16 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "typed-rest-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", + "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", + "dev": true, + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, "typescript": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", @@ -2734,6 +3056,23 @@ "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -2743,6 +3082,12 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", + "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", + "dev": true + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2755,6 +3100,42 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "vsce": { + "version": "1.83.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.83.0.tgz", + "integrity": "sha512-gyF/xtCOFcKO+EvC0FQu5jPECHz2XKMWcw62gqwJJ22lVvlj58t49sWe1IGl9S5NpxCek+QMm6V9i/cDwGWs/Q==", + "dev": true, + "requires": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^6.1.0", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + } + } + }, "vscode-test": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.1.tgz", @@ -3078,6 +3459,25 @@ "dev": true } } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } } } } diff --git a/package.json b/package.json index f2339cd..ced50e7 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "kafka" ], "activationEvents": [ + "onCommand:vscode-kafka.open.docs.home", + "onCommand:vscode-kafka.open.docs.page", "onCommand:vscode-kafka.explorer.addcluster", "onCommand:vscode-kafka.explorer.selectcluster", "onCommand:vscode-kafka.explorer.deletecluster", @@ -54,7 +56,7 @@ "latest" ], "default": "latest", - "description": "Initial offset to read from for new consumers." + "markdownDescription": "Initial offset to read from for new consumers. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Consuming%22%2C%22section%22%3A%22kafkaconsumersoffset%22%7D%5D) for more information." }, "kafka.explorer.topics.sort": { "type": "string", @@ -63,7 +65,7 @@ "partitions" ], "default": "name", - "description": "Choose sorting for topics in explorer" + "markdownDescription": "Choose sorting for topics in explorer. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Explorer%22%2C%22section%22%3A%22kafkaexplorertopicssort%22%7D%5D) for more information." }, "kafka.explorer.topics.filter": { "type": "array", @@ -72,17 +74,17 @@ "__transaction_state", "_schemas" ], - "markdownDescription": "Glob patterns filtering topics out of the Kafka explorer. `*` matches any string, `?` matches a single character." + "markdownDescription": "Glob patterns filtering topics out of the Kafka explorer. `*` matches any string, `?` matches a single character. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Explorer%22%2C%22section%22%3A%22kafkaexplorertopicsfilter%22%7D%5D) for more information." }, "kafka.explorer.consumers.filter": { "type": "array", "default": [], - "markdownDescription": "Glob patterns filtering consumer groups out of the Kafka explorer. `*` matches any string, `?` matches a single character." + "markdownDescription": "Glob patterns filtering consumer groups out of the Kafka explorer. `*` matches any string, `?` matches a single character. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Explorer%22%2C%22section%22%3A%22kafkaexplorerconsumersfilter%22%7D%5D) for more information." }, "kafka.producers.fakerjs.enabled": { "type": "boolean", "default": true, - "markdownDescription": "Enable injection of [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates, using the mustache syntax." + "markdownDescription": "Enable injection of [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates, using the mustache syntax. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Producing%22%2C%22section%22%3A%22kafkaproducersfakerjsenabled%22%7D%5D) for more information." }, "kafka.producers.fakerjs.locale": { "type": "string", @@ -133,7 +135,7 @@ "zh_TW" ], "default": "en", - "markdownDescription": "[experimental] The locale used to generate [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates." + "markdownDescription": "[experimental] The locale used to generate [faker.js](https://github.com/marak/Faker.js/#api-methods)-randomized data in record templates. See [here](command:vscode-kafka.open.docs.page?%5B%7B%22page%22%3A%22Producing%22%2C%22section%22%3A%22kafkaproducersfakerjslocale%22%7D%5D) for more information." } } }, @@ -174,6 +176,11 @@ } ], "commands": [ + { + "command": "vscode-kafka.open.docs.home", + "title": "Open Documentation", + "category": "Kafka" + }, { "command": "vscode-kafka.explorer.addcluster", "title": "Add Cluster", @@ -383,6 +390,7 @@ "package": "vsce package" }, "dependencies": { + "fs-extra": "^8.1.0", "glob": "^7.1.6", "js-yaml": "^3.14.0", "faker": "^5.1.0", @@ -390,6 +398,7 @@ }, "devDependencies": { "@types/faker": "^5.1.5", + "@types/fs-extra": "^8.0.0", "@types/glob": "^7.1.1", "@types/js-yaml": "^3.12.4", "@types/mocha": "^8.0.4", diff --git a/src/docs/markdownPreviewProvider.ts b/src/docs/markdownPreviewProvider.ts new file mode 100644 index 0000000..86b5e93 --- /dev/null +++ b/src/docs/markdownPreviewProvider.ts @@ -0,0 +1,122 @@ +import { Disposable, WebviewPanel, window, ViewColumn, commands, Uri, Webview, ExtensionContext, env } from "vscode"; +import * as fse from 'fs-extra'; +import * as path from 'path'; + +/** + * Render markdown string to html string + */ +const MARKDOWN_API_RENDER = 'markdown.api.render'; + +class MarkdownPreviewProvider implements Disposable { + private panel: WebviewPanel | undefined; + // a cache maps document path to rendered html + private documentCache: Map = new Map(); + private disposables: Disposable[] = []; + + public async show(markdownFilePath: string, title: string, section: string, context: ExtensionContext): Promise { + if (!this.panel) { + this.panel = window.createWebviewPanel('vscode-kafka.markdownPreview', title, ViewColumn.Active, { + localResourceRoots: [ + Uri.file(path.join(context.extensionPath, 'webview-resources')), + Uri.file(path.dirname(markdownFilePath)), + ], + retainContextWhenHidden: true, + enableFindWidget: true, + enableScripts: true, + enableCommandUris: true + }); + } + + this.disposables.push(this.panel.onDidDispose(() => { + this.panel = undefined; + })); + + this.panel.iconPath = Uri.file(path.join(context.extensionPath, 'icons', 'icon128.png')); + this.panel.webview.html = await this.getHtmlContent(this.panel.webview, markdownFilePath, section, context); + this.panel.title = title; + this.panel.reveal(this.panel.viewColumn); + } + + public dispose(): void { + if (this.panel) { + this.panel.dispose(); + } + for (const disposable of this.disposables) { + disposable.dispose(); + } + } + + protected async getHtmlContent(webview: Webview, markdownFilePath: string, section: string, context: ExtensionContext): Promise { + const nonce: string = this.getNonce(); + const styles: string = this.getStyles(webview, context); + let body: string | undefined = this.documentCache.get(markdownFilePath); + if (!body) { + let markdownString: string = await fse.readFile(markdownFilePath, 'utf8'); + markdownString = markdownString.replace(/__VSCODE_ENV_APPNAME_PLACEHOLDER__/, env.appName); + // HACK: This will not replace cross-page links if they don't have a section + // i.e. [here](OtherPage#section) gets replaced, but [here](OtherPage) doesn't + // Captures markdown links like this: [$1]($2#$3) + // where $1, $2, $3 are non empty strings that are then passed to the replace function + markdownString = markdownString.replace(/\[([^\]]+)\]\(([^#)]+)#([^)]*)\)/g, + (_match: string, linkText: string, page: string, section: string) => { + return `${linkText}` + }); + body = await commands.executeCommand(MARKDOWN_API_RENDER, markdownString); + if(body != undefined) { + this.documentCache.set(markdownFilePath, body); + } + } + return ` + + + + + + + ${styles} + + + + ${body} + + + + + `; + } + + protected getStyles(webview: Webview, context: ExtensionContext): string { + const styles: Uri[] = [ + Uri.file(path.join(context.extensionPath, 'webview-resources', 'highlight.css')), + Uri.file(path.join(context.extensionPath, 'webview-resources', 'markdown.css')), + Uri.file(path.join(context.extensionPath, 'webview-resources', 'document.css')), + ]; + return styles.map((styleUri: Uri) => ``).join('\n'); + } + + private getNonce(): string { + let text = ""; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; + } +} + +export const markdownPreviewProvider: MarkdownPreviewProvider = new MarkdownPreviewProvider(); diff --git a/src/extension.ts b/src/extension.ts index 02c9856..e77511e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -25,6 +25,8 @@ import { TopicGroupItem } from "./explorer/models/topics"; import { ConsumerStatusBarItem } from "./views/consumerStatusBarItem"; import { SelectedClusterStatusBarItem } from "./views/selectedClusterStatusBarItem"; import { NodeBase } from "./explorer/models/nodeBase"; +import * as path from 'path'; +import { markdownPreviewProvider } from "./docs/markdownPreviewProvider"; export function activate(context: vscode.ExtensionContext): void { Context.register(context); @@ -108,6 +110,7 @@ export function activate(context: vscode.ExtensionContext): void { context.subscriptions.push(vscode.commands.registerCommand( "vscode-kafka.consumer.toggle", handleErrors(() => toggleConsumerCommandHandler.execute()))); + registerVSCodeKafkaDocumentationCommands(context); // .kafka file related const documentSelector = [ @@ -127,3 +130,21 @@ export function activate(context: vscode.ExtensionContext): void { export function deactivate(): void { // noop } + +function registerVSCodeKafkaDocumentationCommands(context: vscode.ExtensionContext): void { + // Register commands for VSCode Kafka documentation + context.subscriptions.push(markdownPreviewProvider); + context.subscriptions.push(vscode.commands.registerCommand("vscode-kafka.open.docs.home", async () => { + const uri = 'README.md'; + const title = 'Kafka Documentation'; + const sectionId = ''; + markdownPreviewProvider.show(context.asAbsolutePath(path.join('docs', uri)), title, sectionId, context); + })); + context.subscriptions.push(vscode.commands.registerCommand("vscode-kafka.open.docs.page", async (params: { page: string, section: string }) => { + const page = params.page.endsWith('.md') ? params.page.substr(0, params.page.length - 3) : params.page; + const uri = page + '.md'; + const sectionId = params.section || ''; + const title = 'Kafka ' + page; + markdownPreviewProvider.show(context.asAbsolutePath(path.join('docs', uri)), title, sectionId, context); + })); +} diff --git a/webview-resources/document.css b/webview-resources/document.css new file mode 100644 index 0000000..316f864 --- /dev/null +++ b/webview-resources/document.css @@ -0,0 +1,19 @@ +.btn { + border: 0; + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-background); +} + +.btn svg { + fill: var(--vscode-button-foreground); +} + +.btn:hover { + background-color: var(--vscode-button-hoverBackground); +} + +.floating-bottom-right { + position: fixed; + bottom: 1rem; + right: 1rem; +} \ No newline at end of file diff --git a/webview-resources/highlight.css b/webview-resources/highlight.css new file mode 100644 index 0000000..8744f24 --- /dev/null +++ b/webview-resources/highlight.css @@ -0,0 +1,191 @@ +/* +https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs2015.css +*/ +/* + * Visual Studio 2015 dark style + * Author: Nicolas LLOBERA + */ + + + .hljs-keyword, + .hljs-literal, + .hljs-symbol, + .hljs-name { + color: #569CD6; + } + .hljs-link { + color: #569CD6; + text-decoration: underline; + } + + .hljs-built_in, + .hljs-type { + color: #4EC9B0; + } + + .hljs-number, + .hljs-class { + color: #B8D7A3; + } + + .hljs-string, + .hljs-meta-string { + color: #D69D85; + } + + .hljs-regexp, + .hljs-template-tag { + color: #9A5334; + } + + .hljs-subst, + .hljs-function, + .hljs-title, + .hljs-params, + .hljs-formula { + color: #DCDCDC; + } + + .hljs-comment, + .hljs-quote { + color: #57A64A; + font-style: italic; + } + + .hljs-doctag { + color: #608B4E; + } + + .hljs-meta, + .hljs-meta-keyword, + .hljs-tag { + color: #9B9B9B; + } + + .hljs-variable, + .hljs-template-variable { + color: #BD63C5; + } + + .hljs-attr, + .hljs-attribute, + .hljs-builtin-name { + color: #9CDCFE; + } + + .hljs-section { + color: gold; + } + + .hljs-emphasis { + font-style: italic; + } + + .hljs-strong { + font-weight: bold; + } + + /*.hljs-code { + font-family:'Monospace'; + }*/ + + .hljs-bullet, + .hljs-selector-tag, + .hljs-selector-id, + .hljs-selector-class, + .hljs-selector-attr, + .hljs-selector-pseudo { + color: #D7BA7D; + } + + .hljs-addition { + background-color: var(--vscode-diffEditor-insertedTextBackground, rgba(155, 185, 85, 0.2)); + color: rgb(155, 185, 85); + display: inline-block; + width: 100%; + } + + .hljs-deletion { + background: var(--vscode-diffEditor-removedTextBackground, rgba(255, 0, 0, 0.2)); + color: rgb(255, 0, 0); + display: inline-block; + width: 100%; + } + + + /* + From https://raw.githubusercontent.com/isagalaev/highlight.js/master/src/styles/vs.css + */ + /* + + Visual Studio-like style based on original C# coloring by Jason Diamond + + */ + + .vscode-light .hljs-function, + .vscode-light .hljs-params, + .vscode-light .hljs-number, + .vscode-light .hljs-class { + color: inherit; + } + + .vscode-light .hljs-comment, + .vscode-light .hljs-quote, + .vscode-light .hljs-number, + .vscode-light .hljs-class, + .vscode-light .hljs-variable { + color: #008000; + } + + .vscode-light .hljs-keyword, + .vscode-light .hljs-selector-tag, + .vscode-light .hljs-name, + .vscode-light .hljs-tag { + color: #00f; + } + + .vscode-light .hljs-built_in, + .vscode-light .hljs-builtin-name { + color: #007acc; + } + + .vscode-light .hljs-string, + .vscode-light .hljs-section, + .vscode-light .hljs-attribute, + .vscode-light .hljs-literal, + .vscode-light .hljs-template-tag, + .vscode-light .hljs-template-variable, + .vscode-light .hljs-type { + color: #a31515; + } + + .vscode-light .hljs-selector-attr, + .vscode-light .hljs-selector-pseudo, + .vscode-light .hljs-meta, + .vscode-light .hljs-meta-keyword { + color: #2b91af; + } + + .vscode-light .hljs-title, + .vscode-light .hljs-doctag { + color: #808080; + } + + .vscode-light .hljs-attr { + color: #f00; + } + + .vscode-light .hljs-symbol, + .vscode-light .hljs-bullet, + .vscode-light .hljs-link { + color: #00b0e8; + } + + + .vscode-light .hljs-emphasis { + font-style: italic; + } + + .vscode-light .hljs-strong { + font-weight: bold; + } \ No newline at end of file diff --git a/webview-resources/markdown.css b/webview-resources/markdown.css new file mode 100644 index 0000000..b9a1069 --- /dev/null +++ b/webview-resources/markdown.css @@ -0,0 +1,218 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +/*https://raw.githubusercontent.com/microsoft/vscode/master/extensions/markdown-language-features/media/markdown.css*/ + + html, body { + font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif); + font-size: var(--vscode-markdown-font-size, 14px); + padding: 0 26px; + line-height: var(--vscode-markdown-line-height, 22px); + word-wrap: break-word; +} + +#code-csp-warning { + position: fixed; + top: 0; + right: 0; + color: white; + margin: 16px; + text-align: center; + font-size: 12px; + font-family: sans-serif; + background-color:#444444; + cursor: pointer; + padding: 6px; + box-shadow: 1px 1px 1px rgba(0,0,0,.25); +} + +#code-csp-warning:hover { + text-decoration: none; + background-color:#007acc; + box-shadow: 2px 2px 2px rgba(0,0,0,.25); +} + +body.scrollBeyondLastLine { + margin-bottom: calc(100vh - 22px); +} + +body.showEditorSelection .code-line { + position: relative; +} + +body.showEditorSelection .code-active-line:before, +body.showEditorSelection .code-line:hover:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: -12px; + height: 100%; +} + +body.showEditorSelection li.code-active-line:before, +body.showEditorSelection li.code-line:hover:before { + left: -30px; +} + +.vscode-light.showEditorSelection .code-active-line:before { + border-left: 3px solid rgba(0, 0, 0, 0.15); +} + +.vscode-light.showEditorSelection .code-line:hover:before { + border-left: 3px solid rgba(0, 0, 0, 0.40); +} + +.vscode-light.showEditorSelection .code-line .code-line:hover:before { + border-left: none; +} + +.vscode-dark.showEditorSelection .code-active-line:before { + border-left: 3px solid rgba(255, 255, 255, 0.4); +} + +.vscode-dark.showEditorSelection .code-line:hover:before { + border-left: 3px solid rgba(255, 255, 255, 0.60); +} + +.vscode-dark.showEditorSelection .code-line .code-line:hover:before { + border-left: none; +} + +.vscode-high-contrast.showEditorSelection .code-active-line:before { + border-left: 3px solid rgba(255, 160, 0, 0.7); +} + +.vscode-high-contrast.showEditorSelection .code-line:hover:before { + border-left: 3px solid rgba(255, 160, 0, 1); +} + +.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before { + border-left: none; +} + +img { + max-width: 100%; + max-height: 100%; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:focus, +input:focus, +select:focus, +textarea:focus { + outline: 1px solid -webkit-focus-ring-color; + outline-offset: -1px; +} + +hr { + border: 0; + height: 2px; + border-bottom: 2px solid; +} + +h1 { + padding-bottom: 0.3em; + line-height: 1.2; + border-bottom-width: 1px; + border-bottom-style: solid; +} + +h1, h2, h3 { + font-weight: normal; +} + +table { + border-collapse: collapse; +} + +table > thead > tr > th { + text-align: left; + border-bottom: 1px solid; +} + +table > thead > tr > th, +table > thead > tr > td, +table > tbody > tr > th, +table > tbody > tr > td { + padding: 5px 10px; +} + +table > tbody > tr + tr > td { + border-top: 1px solid; +} + +blockquote { + margin: 0 7px 0 5px; + padding: 0 16px 0 10px; + border-left-width: 5px; + border-left-style: solid; +} + +code { + font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; + font-size: 1em; + line-height: 1.357em; +} + +body.wordWrap pre { + white-space: pre-wrap; +} + +pre:not(.hljs), +pre.hljs code > div { + padding: 16px; + border-radius: 3px; + overflow: auto; +} + +pre code { + color: var(--vscode-editor-foreground); + tab-size: 4; +} + +/** Theming */ + +.vscode-light pre { + background-color: rgba(220, 220, 220, 0.4); +} + +.vscode-dark pre { + background-color: rgba(10, 10, 10, 0.4); +} + +.vscode-high-contrast pre { + background-color: rgb(0, 0, 0); +} + +.vscode-high-contrast h1 { + border-color: rgb(0, 0, 0); +} + +.vscode-light table > thead > tr > th { + border-color: rgba(0, 0, 0, 0.69); +} + +.vscode-dark table > thead > tr > th { + border-color: rgba(255, 255, 255, 0.69); +} + +.vscode-light h1, +.vscode-light hr, +.vscode-light table > tbody > tr + tr > td { + border-color: rgba(0, 0, 0, 0.18); +} + +.vscode-dark h1, +.vscode-dark hr, +.vscode-dark table > tbody > tr + tr > td { + border-color: rgba(255, 255, 255, 0.18); +} \ No newline at end of file