mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-03-28 17:42:40 +01:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc21043053 | ||
|
|
b1816a0567 | ||
|
|
29b170a8bd | ||
|
|
3ed144f003 | ||
|
|
613d7f2adb | ||
|
|
82260d7030 | ||
|
|
dbd8b1c0ce | ||
|
|
d2a4a281a3 | ||
|
|
37021e7a0a | ||
|
|
02c171d64c | ||
|
|
a99f20b9f1 | ||
|
|
14d66203d3 | ||
|
|
6e1b28c59e | ||
|
|
53a1b19e07 | ||
|
|
87e735faa9 | ||
|
|
b2f0d51aa2 | ||
|
|
9a6403a6cd | ||
|
|
021b3952ec | ||
|
|
8ddeab7a88 | ||
|
|
bea11bf7df | ||
|
|
323807c0e1 | ||
|
|
d55b122d33 | ||
|
|
a118b461a7 | ||
|
|
c572a821e9 | ||
|
|
a3f18bb143 | ||
|
|
525a289a2c | ||
|
|
976a473d39 |
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
@@ -18,6 +18,18 @@
|
||||
],
|
||||
"preLaunchTask": "npm: build:ext"
|
||||
},
|
||||
{
|
||||
"name": "Attach Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/dist/**/*.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,8 +1,23 @@
|
||||
# Change Log
|
||||
|
||||
## [2.0.1] - 2020-07-27
|
||||
|
||||
- [#42](https://github.com/estruyf/vscode-front-matter/issues/42): Small enhancement to the table layout
|
||||
- [#43](https://github.com/estruyf/vscode-front-matter/issues/43): Fix for collapsible sections and taxonomy picker
|
||||
|
||||
## [2.0.0] - 2020-07-23
|
||||
|
||||
- Redesigned sidebar panel
|
||||
- Sidebar background styling match the VSCode defined sidebar color
|
||||
- Added support for `mdx` files
|
||||
- Added support for `enter` press in the combobox
|
||||
- [#41](https://github.com/estruyf/vscode-front-matter/issues/41): Word count implementation + extra details
|
||||
- [#40](https://github.com/estruyf/vscode-front-matter/issues/40): Added checks for the keyword usage in title, description, slug, and content
|
||||
|
||||
## [1.18.0] - 2020-07-20
|
||||
|
||||
- Updated README
|
||||
|
||||
## [1.17.1] - 2020-06-28
|
||||
|
||||
- [#34](https://github.com/estruyf/vscode-front-matter/issues/34): Fix that last modification date does not update the publication date
|
||||
|
||||
101
README.md
101
README.md
@@ -26,23 +26,72 @@ The extension will automatically verify if your title and description are SEO co
|
||||
|
||||
> If you see something missing in your article creation flow, please feel free to reach out.
|
||||
|
||||
## FrontMatter Panel (introduced in 1.10.0)
|
||||
**Version 2**
|
||||
|
||||
In version `1.10.0` of this extension, the FrontMatter panel got introduced. This panel allows you to perform most of the extension actions by just a click on the button.
|
||||
In version v2.0.0 we released the newly redesigned sidebar panel with improved SEO support. This extension makes it the only extension to manage your Markdown pages for your static sites in Visual Studio Code.
|
||||
|
||||

|
||||
<h2 id="table-of-contents">Table of Contents</h2>
|
||||
|
||||
<details open="open">
|
||||
<summary>Table of Contents</summary>
|
||||
<ol>
|
||||
<li><a href="#the-panel">The panel</a></li>
|
||||
<li><a href="#custom-actions">Custom actions</a></li>
|
||||
<li><a href="#creating-articles-from-templates">Create articles from templates</a></li>
|
||||
<li><a href="#syntax-highlighting-for-hugo-shortcodes">Syntax highlighting for Hugo Shortcodes</a></li>
|
||||
<li><a href="#available-commands">Available commands</a></li>
|
||||
<li><a href="#extension-settings">Extension settings</a></li>
|
||||
<li><a href="#feedback--issues--ideas">Feedback / issues / ideas</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
## The panel
|
||||
|
||||
The Front Matter panel allows you to perform most of the extension actions by just a click on the button and it shows the SEO statuses of your title, description, and more.
|
||||
|
||||
Initially, this panel has been created to make it easier to add tags and categories to your articles as the current VSCode multi-select is not optimal to use.
|
||||
|
||||
To leverage most of the capabilities of the extension. SEO information and everyday actions like slug optimization, updating the date, and publish/drafting the article.
|
||||
|
||||
The panel consists of the following sections:
|
||||
|
||||
**SEO Status**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/seo.png" alt="SEO article status" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**Actions**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/actions.png" alt="Actions" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**Metadata: Keywords, Tags, Categories**
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/metadata.png" alt="Article metadata" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
> **Info**: By default, the tags/categories picker allows you to insert existing and none tags/categories. When you enter a none existing tag/category, the panel shows an add `+` icon in front of that button. This functionality allows you to store this tag/category in your settings. If you want to disable this feature, you can do that by setting the `frontMatter.panel.freeform` setting to `false`.
|
||||
|
||||
Since version `1.15.0`, the extension allows you to create your own custom actions, by running Node.js scripts from your project. In order to use this functionality, you will need to configure the [`frontMatter.custom.scripts`](#frontMatter.custom.scripts) setting for your project.
|
||||
**Other actions**
|
||||
|
||||
At the bottom of the panel you can find the following actions:
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/other-actions.png" alt="Other actions" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
## Custom actions
|
||||
|
||||
Since version `1.15.0`, the extension allows you to create your own custom actions, by running Node.js scripts from your project. In order to use this functionality, you will need to configure the [`frontMatter.custom.scripts`](#frontmattercustomscripts) setting for your project.
|
||||
|
||||
Once a custom action has been configured, it will appear on the Front Matter panel.
|
||||
|
||||

|
||||
<p align="center">
|
||||
<img src="./assets/v2.0.0/custom-action.png" alt="Custom action" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
The current workspace-, file-path, and front matter data will be passed as an argument. In your script fetch these arguments as follows:
|
||||
|
||||
@@ -62,7 +111,9 @@ if (arguments && arguments.length > 0) {
|
||||
|
||||
The output of the script will be passed as a notification, and it allows you to copy the output.
|
||||
|
||||

|
||||
<p align="center">
|
||||
<img src="./assets/custom-action-notification.png" alt="Custom action notification" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
## Creating articles from templates
|
||||
|
||||
@@ -76,7 +127,9 @@ When adding files in the folder, you'll be able to run the `Front Matter: New ar
|
||||
|
||||
## Syntax highlighting for Hugo Shortcodes
|
||||
|
||||

|
||||
<p align="center">
|
||||
<img src="./assets/syntax-highlighting.png" alt="Shortcode syntax highlighting" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
## Available commands:
|
||||
|
||||
@@ -84,11 +137,13 @@ When adding files in the folder, you'll be able to run the `Front Matter: New ar
|
||||
|
||||
Creates a new <tag | category> and allows you to include it into your post automatically
|
||||
|
||||

|
||||
<p align="center">
|
||||
<img src="./assets/create-tag-category.gif" alt="Create tag or category" style="display: inline-block" />
|
||||
</p>
|
||||
|
||||
**Front Matter: Insert <tags | categories>**
|
||||
|
||||
Inserts a selected <tags | categories> into the front matter of your article/post/... - When using this command, the FrontMatter panel opens and focuses on the specified type.
|
||||
Inserts a selected <tags | categories> into the front matter of your article/post/... - When using this command, the Front Matter panel opens and focuses on the specified type.
|
||||
|
||||
> **Info**: This experience changed in version `1.11.0`.
|
||||
|
||||
@@ -119,6 +174,7 @@ Update the `lastmod` (last modified) property of the current article/post/... to
|
||||
This command generates a clean slug for your article. It removes known stop words, punctuations, and special characters.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
title: Just a sample page with a title
|
||||
slug: sample-page-title
|
||||
@@ -128,6 +184,13 @@ You can also specify a prefix and suffix, which can be added to the slug if you
|
||||
|
||||
> **Info**: At the moment, the extension only supports English stopwords.
|
||||
|
||||
### Usage
|
||||
|
||||
- Start by opening the command prompt:
|
||||
- Windows: ⇧+ctrl+P
|
||||
- Mac: ⇧+⌘+P
|
||||
- Use one of the commands from above
|
||||
|
||||
## Where is the data stored?
|
||||
|
||||
The tags and categories are stored in the project VSCode user settings. You can find them back under: `.vscode/settings.json`.
|
||||
@@ -139,7 +202,7 @@ The tags and categories are stored in the project VSCode user settings. You can
|
||||
}
|
||||
```
|
||||
|
||||
## Additional extension settings
|
||||
## Extension settings
|
||||
|
||||
The extension has more settings that allow you to configure it to your needs further. Here is a list of settings that you can set:
|
||||
|
||||
@@ -161,6 +224,17 @@ Specifies the optimal description length for SEO (set to `-1` to turn it off). D
|
||||
"frontMatter.taxonomy.seoDescriptionLength": 160
|
||||
}
|
||||
```
|
||||
|
||||
### `frontMatter.taxonomy.seoContentLength`
|
||||
|
||||
Specifies the optimal minimum length for your articles. Between 1,760 words – 2,400 is the absolute ideal article length for SEO in 2021. (set to `-1` to turn it off).
|
||||
|
||||
```json
|
||||
{
|
||||
"frontMatter.taxonomy.seoContentLength": 1760
|
||||
}
|
||||
```
|
||||
|
||||
### `frontMatter.taxonomy.seoDescriptionLength`
|
||||
|
||||
Specifies the name of the SEO description field for your page. Default is `description`.
|
||||
@@ -237,13 +311,6 @@ Allows you to specify a title and script path (starting relative from the root o
|
||||
|
||||
> **Important**: When the command execution would fail when it cannot find the `node` command. You are able to specify your path to the node app. This is for instance required when using `nvm`.
|
||||
|
||||
## Usage
|
||||
|
||||
- Start by opening the command prompt:
|
||||
- Windows: ⇧+ctrl+P
|
||||
- Mac: ⇧+⌘+P
|
||||
- Use one of the commands from above
|
||||
|
||||
## Feedback / issues / ideas
|
||||
|
||||
Please submit them via creating an issue in the project repository: [issue list](https://github.com/estruyf/vscode-front-matter/issues).
|
||||
|
||||
@@ -21,6 +21,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
.collapsible__body,
|
||||
.ext_settings {
|
||||
padding: 1rem 1.25rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#app, .frontmatter {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.spinner,
|
||||
.spinner:before,
|
||||
.spinner:after {
|
||||
@@ -58,6 +72,13 @@
|
||||
left: 3.5em;
|
||||
}
|
||||
|
||||
.frontmatter {
|
||||
padding-top: 0;
|
||||
padding-bottom: var(--input-margin-vertical);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.frontmatter h3 {
|
||||
margin-bottom: 1rem;
|
||||
@@ -69,22 +90,34 @@
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.seo__status__details {
|
||||
margin-bottom: 2rem;
|
||||
.article__tags h3,
|
||||
.seo__status h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.section {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section h3 svg {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.seo__status__details, .seo__status__keywords {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.collapsible__body h4 {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.not-valid {
|
||||
color: var(--vscode-errorForeground);
|
||||
}
|
||||
|
||||
.article__actions {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.article__action {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.article__tags {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
@@ -118,9 +151,15 @@
|
||||
|
||||
.article__tags__input button {
|
||||
position: absolute;
|
||||
bottom: 1px;
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
width: 30px;
|
||||
padding-bottom: 2px;
|
||||
padding-top: 2px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.article__tags ul {
|
||||
@@ -151,6 +190,12 @@
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.article__tags__items__item {
|
||||
display: inline-flex;
|
||||
margin-bottom: .5rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.article__tags__items__item {
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
@@ -199,18 +244,70 @@
|
||||
filter: contrast(60%);
|
||||
}
|
||||
|
||||
.ext_link_block {
|
||||
margin-bottom: .5rem;
|
||||
text-align: right;
|
||||
.article__actions > * + * {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.seo__status__details ul > * + *,
|
||||
.ext_settings > * + * {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.ext_link_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ext_link_block svg {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.ext_link_block button,
|
||||
.ext_link_block a {
|
||||
color: var(--vscode-textLink-foreground);
|
||||
align-items: center;
|
||||
color: var(--vscode-button-secondaryForeground);
|
||||
background-color: var(--vscode-button-secondaryBackground);
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
font-size: var(--vscode-font-size);
|
||||
font-weight: var(--vscode-font-weight);
|
||||
line-height: 26px;
|
||||
padding: 0px 14px;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.ext_link_block a:hover,
|
||||
.ext_link_block a:active,
|
||||
.ext_link_block a:focus,
|
||||
.ext_link_block a:visited {
|
||||
color: var(--vscode-textLink-activeForeground);
|
||||
color: var(--vscode-button-secondaryForeground);
|
||||
}
|
||||
|
||||
.table__cell {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table__title {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.table__cell__validation {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table__cell__validation .valid {
|
||||
color: #46EC86;
|
||||
}
|
||||
|
||||
.table__cell__validation .warning {
|
||||
color: #E6AF2E;
|
||||
}
|
||||
@@ -1,29 +1,26 @@
|
||||
:root {
|
||||
--container-paddding: 20px;
|
||||
--container-padding: 20px;
|
||||
--input-padding-vertical: 6px;
|
||||
--input-padding-horizontal: 4px;
|
||||
--input-margin-vertical: 4px;
|
||||
--input-margin-horizontal: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0 var(--container-paddding);
|
||||
color: var(--vscode-foreground);
|
||||
font-size: var(--vscode-font-size);
|
||||
font-weight: var(--vscode-font-weight);
|
||||
font-family: var(--vscode-font-family);
|
||||
background-color: var(--vscode-editor-background);
|
||||
background-color: var(--vscode-sideBar-background);
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: var(--container-paddding);
|
||||
}
|
||||
|
||||
body > *,
|
||||
form > * {
|
||||
margin-block-start: var(--input-margin-vertical);
|
||||
margin-block-end: var(--input-margin-vertical);
|
||||
padding-left: var(--container-padding);
|
||||
}
|
||||
|
||||
*:focus {
|
||||
@@ -53,6 +50,7 @@ button {
|
||||
outline-offset: 2px !important;
|
||||
color: var(--vscode-button-foreground);
|
||||
background: var(--vscode-button-background);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
|
||||
BIN
assets/v2.0.0/actions.png
Normal file
BIN
assets/v2.0.0/actions.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/v2.0.0/custom-action.png
Normal file
BIN
assets/v2.0.0/custom-action.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
assets/v2.0.0/metadata.png
Normal file
BIN
assets/v2.0.0/metadata.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
assets/v2.0.0/other-actions.png
Normal file
BIN
assets/v2.0.0/other-actions.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/v2.0.0/seo.png
Normal file
BIN
assets/v2.0.0/seo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
675
package-lock.json
generated
675
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vscode-front-matter",
|
||||
"version": "1.18.0",
|
||||
"version": "2.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -39,11 +39,14 @@
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@emotion/hash": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
|
||||
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
|
||||
"dev": true
|
||||
"@bendera/vscode-webview-elements": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@bendera/vscode-webview-elements/-/vscode-webview-elements-0.5.0.tgz",
|
||||
"integrity": "sha512-mlZi8RG+tsqr1bDbA7H82spyWzZyj/tsyHb9eta7kE0xRhvx7ON6w6DG4PONew1rVJv1knTKOAW4iQKVBYQhVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lit-element": "^2.5.1"
|
||||
}
|
||||
},
|
||||
"@iarna/toml": {
|
||||
"version": "2.2.3",
|
||||
@@ -51,123 +54,18 @@
|
||||
"integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==",
|
||||
"dev": true
|
||||
},
|
||||
"@material-ui/core": {
|
||||
"version": "4.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.1.tgz",
|
||||
"integrity": "sha512-aesI8lOaaw0DRIfNG+Anepf61NH5Q+cmkxJOZvI1oHkmD5cKubkZ0C7INqFKjfFpSFlFnqHkTasoM7ogFAvzOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/styles": "^4.11.1",
|
||||
"@material-ui/system": "^4.9.14",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.10.2",
|
||||
"@types/react-transition-group": "^4.2.0",
|
||||
"clsx": "^1.0.4",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"popper.js": "1.16.1-lts",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0",
|
||||
"react-transition-group": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"@material-ui/icons": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
|
||||
"integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4"
|
||||
}
|
||||
},
|
||||
"@material-ui/lab": {
|
||||
"version": "4.0.0-alpha.56",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz",
|
||||
"integrity": "sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.10.2",
|
||||
"clsx": "^1.0.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0"
|
||||
}
|
||||
},
|
||||
"@material-ui/styles": {
|
||||
"version": "4.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.1.tgz",
|
||||
"integrity": "sha512-GqzsFsVWT8jXa8OWAd1WD6WIaqtXr2mUPbRZ1EjkiM3Dlta4mCRaToDxkFVv6ZHfXlFjMJzdaIEvCpZOCvZTvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/hash": "^0.8.0",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.9.6",
|
||||
"clsx": "^1.0.4",
|
||||
"csstype": "^2.5.2",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"jss": "^10.0.3",
|
||||
"jss-plugin-camel-case": "^10.0.3",
|
||||
"jss-plugin-default-unit": "^10.0.3",
|
||||
"jss-plugin-global": "^10.0.3",
|
||||
"jss-plugin-nested": "^10.0.3",
|
||||
"jss-plugin-props-sort": "^10.0.3",
|
||||
"jss-plugin-rule-value-function": "^10.0.3",
|
||||
"jss-plugin-vendor-prefixer": "^10.0.3",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"csstype": {
|
||||
"version": "2.6.14",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
|
||||
"integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/system": {
|
||||
"version": "4.9.14",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz",
|
||||
"integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.9.6",
|
||||
"csstype": "^2.5.2",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"csstype": {
|
||||
"version": "2.6.14",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
|
||||
"integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/types": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
|
||||
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
|
||||
"dev": true
|
||||
},
|
||||
"@material-ui/utils": {
|
||||
"version": "4.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz",
|
||||
"integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0"
|
||||
}
|
||||
},
|
||||
"@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/debug": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.6.tgz",
|
||||
"integrity": "sha512-7fDOJFA/x8B+sO1901BmHlf5dE1cxBU8mRXj8QOEDnn16hhGJv/IHxJtZhvsabZsIMn0eLIyeOKAeqSNJJYTpA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
|
||||
@@ -196,6 +94,15 @@
|
||||
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mdast": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.7.tgz",
|
||||
"integrity": "sha512-YwR7OK8aPmaBvMMUi+pZXBNoW2unbVbfok4YRqGMJBe1dpDlzpRkJrYEYmvjxgs5JhuQmKfDexrN98u941Zasg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
@@ -239,15 +146,6 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-transition-group": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
|
||||
"integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/source-list-map": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
|
||||
@@ -277,6 +175,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/unist": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/vscode": {
|
||||
"version": "1.51.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.51.0.tgz",
|
||||
@@ -324,6 +228,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vscode/codicons": {
|
||||
"version": "0.0.20",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.20.tgz",
|
||||
"integrity": "sha512-LlO6K7nzrIWDCZN1Zi6J6ibxrpMibSAct+zNjAwpkNkwup6cJLx5diYvsOJODMPWOuQlBO21qkxtdkSRzW6+Jw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
||||
@@ -1004,6 +914,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"character-entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz",
|
||||
"integrity": "sha512-oHqMj3eAuJ77/P5PaIRcqk+C3hdfNwyCD2DAUcD5gyXkegAuF2USC40CEqPscDk4I8FRGMTojGJQkXDsN5QlJA==",
|
||||
"dev": true
|
||||
},
|
||||
"character-entities-legacy": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz",
|
||||
"integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==",
|
||||
"dev": true
|
||||
},
|
||||
"character-reference-invalid": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz",
|
||||
"integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==",
|
||||
"dev": true
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
|
||||
@@ -1086,12 +1014,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"clsx": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
|
||||
"dev": true
|
||||
},
|
||||
"collection-visit": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
||||
@@ -1286,16 +1208,6 @@
|
||||
"nth-check": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"css-vendor": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
|
||||
"integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.8.3",
|
||||
"is-in-browser": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
@@ -1320,6 +1232,15 @@
|
||||
"integrity": "sha512-C14oTzTZy8DH1Eq8N78owrCWvf3+cnJw88BTK/N3DYWVxDJuJzPaNdplzYxDYuuXXGvqBcO4Vy5SOrwAooXSWw==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
@@ -1426,16 +1347,6 @@
|
||||
"utila": "~0.4"
|
||||
}
|
||||
},
|
||||
"dom-helpers": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz",
|
||||
"integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.8.7",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
@@ -2279,15 +2190,6 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"homedir-polyfill": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||
@@ -2476,12 +2378,6 @@
|
||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
|
||||
"dev": true
|
||||
},
|
||||
"hyphenate-style-name": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
@@ -2510,15 +2406,6 @@
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"indefinite-observable": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz",
|
||||
"integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"symbol-observable": "1.2.0"
|
||||
}
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
@@ -2579,6 +2466,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-alphabetical": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.0.tgz",
|
||||
"integrity": "sha512-5OV8Toyq3oh4eq6sbWTYzlGdnMT/DPI5I0zxUBxjiigQsZycpkKF3kskkao3JyYGuYDHvhgJF+DrjMQp9SX86w==",
|
||||
"dev": true
|
||||
},
|
||||
"is-alphanumerical": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.0.tgz",
|
||||
"integrity": "sha512-t+2GlJ+hO9yagJ+jU3+HSh80VKvz/3cG2cxbGGm4S0hjKuhWQXgPVUVOZz3tqZzMjhmphZ+1TIJTlRZRoe6GCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-alphabetical": "^2.0.0",
|
||||
"is-decimal": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
@@ -2636,6 +2539,12 @@
|
||||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
|
||||
"dev": true
|
||||
},
|
||||
"is-decimal": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz",
|
||||
"integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
|
||||
@@ -2682,10 +2591,10 @@
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-in-browser": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
|
||||
"integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=",
|
||||
"is-hexadecimal": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz",
|
||||
"integrity": "sha512-vGOtYkiaxwIiR0+Ng/zNId+ZZehGfINwTzdrDqc6iubbnQWhnPuYymOzOKUDqa2cSl59yHnEh2h6MvRLQsyNug==",
|
||||
"dev": true
|
||||
},
|
||||
"is-number": {
|
||||
@@ -2796,99 +2705,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.5.0.tgz",
|
||||
"integrity": "sha512-B6151NvG+thUg3murLNHRPLxTLwQ13ep4SH5brj4d8qKtogOx/jupnpfkPGSHPqvcwKJaCLctpj2lEk+5yGwMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"csstype": "^3.0.2",
|
||||
"indefinite-observable": "^2.0.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-camel-case": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.0.tgz",
|
||||
"integrity": "sha512-GSjPL0adGAkuoqeYiXTgO7PlIrmjv5v8lA6TTBdfxbNYpxADOdGKJgIEkffhlyuIZHlPuuiFYTwUreLUmSn7rg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"hyphenate-style-name": "^1.0.3",
|
||||
"jss": "10.5.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-default-unit": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.0.tgz",
|
||||
"integrity": "sha512-rsbTtZGCMrbcb9beiDd+TwL991NGmsAgVYH0hATrYJtue9e+LH/Gn4yFD1ENwE+3JzF3A+rPnM2JuD9L/SIIWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.5.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-global": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.5.0.tgz",
|
||||
"integrity": "sha512-FZd9+JE/3D7HMefEG54fEC0XiQ9rhGtDHAT/ols24y8sKQ1D5KIw6OyXEmIdKFmACgxZV2ARQ5pAUypxkk2IFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.5.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-nested": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.5.0.tgz",
|
||||
"integrity": "sha512-ejPlCLNlEGgx8jmMiDk/zarsCZk+DV0YqXfddpgzbO9Toamo0HweCFuwJ3ZO40UFOfqKwfpKMVH/3HUXgxkTMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.5.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-props-sort": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.0.tgz",
|
||||
"integrity": "sha512-kTLRvrOetFKz5vM88FAhLNeJIxfjhCepnvq65G7xsAQ/Wgy7HwO1BS/2wE5mx8iLaAWC6Rj5h16mhMk9sKdZxg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.5.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-rule-value-function": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.0.tgz",
|
||||
"integrity": "sha512-jXINGr8BSsB13JVuK274oEtk0LoooYSJqTBCGeBu2cG/VJ3+4FPs1gwLgsq24xTgKshtZ+WEQMVL34OprLidRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.5.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-vendor-prefixer": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.0.tgz",
|
||||
"integrity": "sha512-rux3gmfwDdOKCLDx0IQjTwTm03IfBa+Rm/hs747cOw5Q7O3RaTUIMPKjtVfc31Xr/XI9Abz2XEupk1/oMQ7zRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"css-vendor": "^2.0.8",
|
||||
"jss": "10.5.0"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"lit-element": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.5.1.tgz",
|
||||
"integrity": "sha512-ogu7PiJTA33bEK0xGu1dmaX5vhcRjBXCFexPja0e7P7jqLhTpNKYRPmE+GmiCaRVAbiQKGkUgkh/i6+bh++dPQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lit-html": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"lit-html": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.4.1.tgz",
|
||||
"integrity": "sha512-B9btcSgPYb1q4oSOb/PrOT6Z/H+r6xuNzfH4lFli/AWhYwdtrgQkQWBbIc6mdnf6E2IL3gDXdkkqNktpU0OZQA==",
|
||||
"dev": true
|
||||
},
|
||||
"loader-runner": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
|
||||
@@ -2985,6 +2822,30 @@
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"mdast-util-from-markdown": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz",
|
||||
"integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"@types/unist": "^2.0.0",
|
||||
"mdast-util-to-string": "^3.0.0",
|
||||
"micromark": "^3.0.0",
|
||||
"micromark-util-decode-numeric-character-reference": "^1.0.0",
|
||||
"micromark-util-normalize-identifier": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0",
|
||||
"parse-entities": "^3.0.0",
|
||||
"unist-util-stringify-position": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"mdast-util-to-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz",
|
||||
"integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==",
|
||||
"dev": true
|
||||
},
|
||||
"memory-fs": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
|
||||
@@ -2995,6 +2856,222 @@
|
||||
"readable-stream": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"micromark": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.1.tgz",
|
||||
"integrity": "sha512-DqC0I0V6D3wy/XmJTK1Tn+JPlMk7phhtDQ7ZJIZgAzHTyeVXMDdOaHQ2WQ7i5z3Bh4JK66nLBmjtgMrWwe8eMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/debug": "^4.0.0",
|
||||
"debug": "^4.0.0",
|
||||
"micromark-core-commonmark": "^1.0.0",
|
||||
"micromark-factory-space": "^1.0.0",
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-chunked": "^1.0.0",
|
||||
"micromark-util-combine-extensions": "^1.0.0",
|
||||
"micromark-util-decode-numeric-character-reference": "^1.0.0",
|
||||
"micromark-util-encode": "^1.0.0",
|
||||
"micromark-util-normalize-identifier": "^1.0.0",
|
||||
"micromark-util-resolve-all": "^1.0.0",
|
||||
"micromark-util-sanitize-uri": "^1.0.0",
|
||||
"micromark-util-subtokenize": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0",
|
||||
"parse-entities": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-core-commonmark": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.0.tgz",
|
||||
"integrity": "sha512-y9g7zymcKRBHM/aNBekstvs/Grpf+y4OEBULUTYvGZcusnp+JeOxmilJY4GMpo2/xY7iHQL9fjz5pD9pSAud9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-factory-destination": "^1.0.0",
|
||||
"micromark-factory-label": "^1.0.0",
|
||||
"micromark-factory-space": "^1.0.0",
|
||||
"micromark-factory-title": "^1.0.0",
|
||||
"micromark-factory-whitespace": "^1.0.0",
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-chunked": "^1.0.0",
|
||||
"micromark-util-classify-character": "^1.0.0",
|
||||
"micromark-util-html-tag-name": "^1.0.0",
|
||||
"micromark-util-normalize-identifier": "^1.0.0",
|
||||
"micromark-util-resolve-all": "^1.0.0",
|
||||
"micromark-util-subtokenize": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0",
|
||||
"parse-entities": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-factory-destination": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
|
||||
"integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-factory-label": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.0.tgz",
|
||||
"integrity": "sha512-XWEucVZb+qBCe2jmlOnWr6sWSY6NHx+wtpgYFsm4G+dufOf6tTQRRo0bdO7XSlGPu5fyjpJenth6Ksnc5Mwfww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-factory-space": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz",
|
||||
"integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-factory-title": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.0.tgz",
|
||||
"integrity": "sha512-flvC7Gx0dWVWorXuBl09Cr3wB5FTuYec8pMGVySIp2ZlqTcIjN/lFohZcP0EG//krTptm34kozHk7aK/CleCfA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-factory-space": "^1.0.0",
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-factory-whitespace": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz",
|
||||
"integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-factory-space": "^1.0.0",
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-character": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.0.0.tgz",
|
||||
"integrity": "sha512-VdfDsHtUn/ocN2hGBkMunHHWcaN33llgwU0bmw2LA0tY1JvVkjHGvdiQSIk0pS3XeGCJLT6syS5i8y+1xbwDnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-chunked": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz",
|
||||
"integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-symbol": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-classify-character": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz",
|
||||
"integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-combine-extensions": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz",
|
||||
"integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-chunked": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-decode-numeric-character-reference": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz",
|
||||
"integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-symbol": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-encode": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz",
|
||||
"integrity": "sha512-cJpFVM768h6zkd8qJ1LNRrITfY4gwFt+tziPcIf71Ui8yFzY9wG3snZQqiWVq93PG4Sw6YOtcNiKJfVIs9qfGg==",
|
||||
"dev": true
|
||||
},
|
||||
"micromark-util-html-tag-name": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz",
|
||||
"integrity": "sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==",
|
||||
"dev": true
|
||||
},
|
||||
"micromark-util-normalize-identifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-symbol": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-resolve-all": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz",
|
||||
"integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-sanitize-uri": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz",
|
||||
"integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-character": "^1.0.0",
|
||||
"micromark-util-encode": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-subtokenize": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.0.tgz",
|
||||
"integrity": "sha512-EsnG2qscmcN5XhkqQBZni/4oQbLFjz9yk3ZM/P8a3YUjwV6+6On2wehr1ALx0MxK3+XXXLTzuBKHDFeDFYRdgQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"micromark-util-chunked": "^1.0.0",
|
||||
"micromark-util-symbol": "^1.0.0",
|
||||
"micromark-util-types": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"micromark-util-symbol": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz",
|
||||
"integrity": "sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==",
|
||||
"dev": true
|
||||
},
|
||||
"micromark-util-types": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.0.tgz",
|
||||
"integrity": "sha512-psf1WAaP1B77WpW4mBGDkTr+3RsPuDAgsvlP47GJzbH1jmjH8xjOx7Z6kp84L8oqHmy5pYO3Ev46odosZV+3AA==",
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
@@ -3114,6 +3191,12 @@
|
||||
"run-queue": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||
@@ -3394,6 +3477,20 @@
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"parse-entities": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz",
|
||||
"integrity": "sha512-AJlcIFDNPEP33KyJLguv0xJc83BNvjxwpuUIcetyXUsLpVXAUCePJ5kIoYtEN2R1ac0cYaRu/vk9dVFkewHQhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"character-entities": "^2.0.0",
|
||||
"character-entities-legacy": "^2.0.0",
|
||||
"character-reference-invalid": "^2.0.0",
|
||||
"is-alphanumerical": "^2.0.0",
|
||||
"is-decimal": "^2.0.0",
|
||||
"is-hexadecimal": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"parse-passwd": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
||||
@@ -3487,12 +3584,6 @@
|
||||
"find-up": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"popper.js": {
|
||||
"version": "1.16.1-lts",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==",
|
||||
"dev": true
|
||||
},
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
|
||||
@@ -3663,18 +3754,6 @@
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
|
||||
"integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"dom-helpers": "^5.0.1",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
@@ -4296,12 +4375,6 @@
|
||||
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
|
||||
"dev": true
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tapable": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
||||
@@ -4371,12 +4444,6 @@
|
||||
"setimmediate": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
|
||||
"dev": true
|
||||
},
|
||||
"to-arraybuffer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
||||
@@ -4570,6 +4637,15 @@
|
||||
"imurmurhash": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"unist-util-stringify-position": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz",
|
||||
"integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/unist": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unset-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
@@ -4979,6 +5055,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"wc-react": {
|
||||
"version": "github:estruyf/wc-react#0989e37af55d3ee97392bf2747a818e4873243fa",
|
||||
"from": "github:estruyf/wc-react",
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.44.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz",
|
||||
|
||||
17
package.json
17
package.json
@@ -3,7 +3,7 @@
|
||||
"displayName": "Front Matter",
|
||||
"description": "Simplifies working with front matter of your articles. Useful extension when you are using a static site generator like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...",
|
||||
"icon": "assets/front-matter.png",
|
||||
"version": "1.18.0",
|
||||
"version": "2.0.1",
|
||||
"preview": false,
|
||||
"publisher": "eliostruyf",
|
||||
"galleryBanner": {
|
||||
@@ -142,6 +142,11 @@
|
||||
"default": 160,
|
||||
"description": "Specifies the optimal description length for SEO (set to `-1` to turn it off)."
|
||||
},
|
||||
"frontMatter.taxonomy.seoContentLengh": {
|
||||
"type": "number",
|
||||
"default": 1760,
|
||||
"description": "Specifies the optimal minimum length for your articles. Between 1,760 words – 2,400 is the absolute ideal article length for SEO in 2021. (set to `-1` to turn it off)."
|
||||
},
|
||||
"frontMatter.taxonomy.seoDescriptionField": {
|
||||
"type": "string",
|
||||
"default": "description",
|
||||
@@ -238,10 +243,8 @@
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bendera/vscode-webview-elements": "0.5.0",
|
||||
"@iarna/toml": "2.2.3",
|
||||
"@material-ui/core": "4.11.1",
|
||||
"@material-ui/icons": "4.11.2",
|
||||
"@material-ui/lab": "4.0.0-alpha.56",
|
||||
"@types/glob": "7.1.3",
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/mocha": "^5.2.6",
|
||||
@@ -249,18 +252,22 @@
|
||||
"@types/react": "17.0.0",
|
||||
"@types/react-dom": "17.0.0",
|
||||
"@types/vscode": "1.51.0",
|
||||
"@vscode/codicons": "0.0.20",
|
||||
"date-fns": "2.0.1",
|
||||
"downshift": "6.0.6",
|
||||
"glob": "7.1.6",
|
||||
"gray-matter": "4.0.2",
|
||||
"html-loader": "1.3.2",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"mdast-util-from-markdown": "1.0.0",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"ts-loader": "8.0.3",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "4.0.2",
|
||||
"wc-react": "github:estruyf/wc-react",
|
||||
"webpack": "4.44.2",
|
||||
"webpack-cli": "3.3.12"
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class StatusListener {
|
||||
const publishMsg = "to publish";
|
||||
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
if (editor && editor.document && editor.document.languageId.toLowerCase() === "markdown") {
|
||||
if (editor && editor.document && (editor.document.languageId.toLowerCase() === "markdown" || editor.document.languageId.toLowerCase() === "mdx")) {
|
||||
try {
|
||||
const article = ArticleHelper.getFrontMatter(editor);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export const SETTING_FRONTMATTER_TYPE = "taxonomy.frontMatterType";
|
||||
|
||||
export const SETTING_SEO_TITLE_LENGTH = "taxonomy.seoTitleLength";
|
||||
export const SETTING_SEO_DESCRIPTION_LENGTH = "taxonomy.seoDescriptionLength";
|
||||
export const SETTING_SEO_CONTENT_MIN_LENGTH = "taxonomy.seoContentLengh";
|
||||
export const SETTING_SEO_DESCRIPTION_FIELD = "taxonomy.seoDescriptionField";
|
||||
|
||||
export const SETTING_TEMPLATES_FOLDER = "templates.folder";
|
||||
|
||||
@@ -113,6 +113,6 @@ const debounceShowDraftTrigger = () => {
|
||||
return (fnc: any, time: number) => {
|
||||
const functionCall = (...args: any[]) => fnc.apply(args);
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(functionCall, time);
|
||||
timeout = setTimeout(functionCall, time) as any;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,12 +9,13 @@ export class FilesHelper {
|
||||
public static async getMdFiles(): Promise<vscode.Uri[] | null> {
|
||||
const mdFiles = await vscode.workspace.findFiles('**/*.md', "**/node_modules/**,**/archetypes/**");
|
||||
const markdownFiles = await vscode.workspace.findFiles('**/*.markdown', "**/node_modules/**,**/archetypes/**");
|
||||
const mdxFiles = await vscode.workspace.findFiles('**/*.mdx', "**/node_modules/**,**/archetypes/**");
|
||||
if (!mdFiles && !markdownFiles) {
|
||||
vscode.window.showInformationMessage(`${EXTENSION_NAME}: No MD files found.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const allMdFiles = mdFiles.concat(markdownFiles);
|
||||
const allMdFiles = [...mdFiles, ...markdownFiles, ...mdxFiles];
|
||||
return allMdFiles;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ export interface PanelSettings {
|
||||
export interface SEO {
|
||||
title: number;
|
||||
description: number;
|
||||
content: number;
|
||||
descriptionField: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ export enum CommandToCode {
|
||||
publish = 'publish',
|
||||
updateTags = "update-tags",
|
||||
updateCategories = "update-categories",
|
||||
updateKeywords = "update-keywords",
|
||||
addTagToSettings = "add-tag",
|
||||
addCategoryToSettings = "add-category",
|
||||
openSettings = "open-settings",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export enum TagType {
|
||||
tags = "Tags",
|
||||
categories = "Categories"
|
||||
categories = "Categories",
|
||||
keywords = "Keywords"
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from './CommandToCode';
|
||||
import { Actions } from './components/Actions';
|
||||
import { Collapsible } from './components/Collapsible';
|
||||
import { BugIcon } from './components/Icons/BugIcon';
|
||||
import { FileIcon } from './components/Icons/FileIcon';
|
||||
import { FolderOpenedIcon } from './components/Icons/FolderOpenedIcon';
|
||||
import { ListUnorderedIcon } from './components/Icons/ListUnorderedIcon';
|
||||
import { SettingsIcon } from './components/Icons/SettingsIcon';
|
||||
import { SymbolKeywordIcon } from './components/Icons/SymbolKeywordIcon';
|
||||
import { TagIcon } from './components/Icons/TagIcon';
|
||||
import { SeoStatus } from './components/SeoStatus';
|
||||
import { Spinner } from './components/Spinner';
|
||||
import { TagPicker } from './components/TagPicker';
|
||||
@@ -42,48 +50,66 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (props: React
|
||||
|
||||
return (
|
||||
<div className="frontmatter">
|
||||
{
|
||||
settings && settings.seo && <SeoStatus seo={settings.seo} data={metadata} />
|
||||
}
|
||||
{
|
||||
settings && metadata && <Actions metadata={metadata} settings={settings} />
|
||||
}
|
||||
<div className={`ext_actions`}>
|
||||
{
|
||||
settings && settings.seo && <SeoStatus seo={settings.seo} data={metadata} />
|
||||
}
|
||||
{
|
||||
settings && metadata && <Actions metadata={metadata} settings={settings} />
|
||||
}
|
||||
|
||||
{
|
||||
(settings && settings.tags && settings.tags.length > 0) && (
|
||||
<TagPicker type={TagType.tags}
|
||||
crntSelected={metadata.tags || []}
|
||||
options={settings.tags}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.tags}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
{
|
||||
(settings && settings.categories && settings.categories.length > 0) && (
|
||||
<TagPicker type={TagType.categories}
|
||||
crntSelected={metadata.categories || []}
|
||||
options={settings.categories}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.categories}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="javascript:;" onClick={openSettings}>Open settings</a>
|
||||
<Collapsible title="Metadata" className={`absolute`}>
|
||||
{
|
||||
<TagPicker type={TagType.keywords}
|
||||
icon={<SymbolKeywordIcon />}
|
||||
crntSelected={metadata.keywords || []}
|
||||
options={[]}
|
||||
freeform={true}
|
||||
focussed={focusElm === TagType.keywords}
|
||||
unsetFocus={unsetFocus}
|
||||
disableConfigurable />
|
||||
}
|
||||
{
|
||||
(settings && settings.tags && settings.tags.length > 0) && (
|
||||
<TagPicker type={TagType.tags}
|
||||
icon={<TagIcon />}
|
||||
crntSelected={metadata.tags || []}
|
||||
options={settings.tags}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.tags}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
{
|
||||
(settings && settings.categories && settings.categories.length > 0) && (
|
||||
<TagPicker type={TagType.categories}
|
||||
icon={<ListUnorderedIcon />}
|
||||
crntSelected={metadata.categories || []}
|
||||
options={settings.categories}
|
||||
freeform={settings.freeform}
|
||||
focussed={focusElm === TagType.categories}
|
||||
unsetFocus={unsetFocus} />
|
||||
)
|
||||
}
|
||||
</Collapsible>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="javascript:;" onClick={openFile}>Reveal file in folder</a>
|
||||
</div>
|
||||
<div className={`ext_settings`}>
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openSettings}><SettingsIcon /> Open settings</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="javascript:;" onClick={openProject}>Reveal project folder</a>
|
||||
</div>
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openFile}><FileIcon /> Reveal file in folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub">Report an issue</a>
|
||||
<div className="ext_link_block">
|
||||
<button onClick={openProject}><FolderOpenedIcon /> Reveal project folder</button>
|
||||
</div>
|
||||
|
||||
<div className="ext_link_block">
|
||||
<a href="https://github.com/estruyf/vscode-front-matter/issues" title="Open an issue on GitHub"><BugIcon /> Report an issue</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { PanelSettings } from '../../models/PanelSettings';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { CustomScript } from './CustomScript';
|
||||
import { DateAction } from './DateAction';
|
||||
import { PublishAction } from './PublishAction';
|
||||
@@ -18,22 +19,22 @@ export const Actions: React.FunctionComponent<IActionsProps> = (props: React.Pro
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`article__actions`}>
|
||||
<h3>Actions</h3>
|
||||
<Collapsible title="Actions">
|
||||
<div className={`article__actions`}>
|
||||
{ metadata && metadata.title && <SlugAction value={metadata.title} crntValue={metadata.slug} slugOpts={settings.slug} /> }
|
||||
|
||||
{ metadata && metadata.title && <SlugAction value={metadata.title} crntValue={metadata.slug} slugOpts={settings.slug} /> }
|
||||
|
||||
<DateAction />
|
||||
<DateAction />
|
||||
|
||||
{ metadata && typeof metadata.draft !== undefined && <PublishAction draft={metadata.draft} />}
|
||||
{ metadata && typeof metadata.draft !== undefined && <PublishAction draft={metadata.draft} />}
|
||||
|
||||
{
|
||||
(settings && settings.scripts && settings.scripts.length > 0) && (
|
||||
settings.scripts.map((value) => (
|
||||
<CustomScript {...value} />
|
||||
))
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
(settings && settings.scripts && settings.scripts.length > 0) && (
|
||||
settings.scripts.map((value) => (
|
||||
<CustomScript key={value.title.replace(/ /g, '')} {...value} />
|
||||
))
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</Collapsible>
|
||||
);
|
||||
};
|
||||
49
src/viewpanel/components/ArticleDetails.tsx
Normal file
49
src/viewpanel/components/ArticleDetails.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import * as React from 'react';
|
||||
import { VsTable, VsTableBody, VsTableHeader, VsTableHeaderCell, VsTableRow, VsTableCell } from './VscodeComponents';
|
||||
|
||||
export interface IArticleDetailsProps {
|
||||
details: {
|
||||
headings: number;
|
||||
paragraphs: number;
|
||||
wordCount: number;
|
||||
}
|
||||
}
|
||||
|
||||
export const ArticleDetails: React.FunctionComponent<IArticleDetailsProps> = ({details}: React.PropsWithChildren<IArticleDetailsProps>) => {
|
||||
|
||||
if (!details || (details.headings === undefined && details.paragraphs === undefined)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`seo__status__details valid`}>
|
||||
<h4>More details</h4>
|
||||
|
||||
<VsTable bordered>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell>Type</VsTableHeaderCell>
|
||||
<VsTableHeaderCell>Total</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
{
|
||||
details?.headings !== undefined && (
|
||||
<VsTableRow>
|
||||
<VsTableCell>Headings</VsTableCell>
|
||||
<VsTableCell>{details.headings}</VsTableCell>
|
||||
</VsTableRow>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
details?.paragraphs !== undefined && (
|
||||
<VsTableRow>
|
||||
<VsTableCell>Paragraphs</VsTableCell>
|
||||
<VsTableCell>{details.paragraphs}</VsTableCell>
|
||||
</VsTableRow>
|
||||
)
|
||||
}
|
||||
</VsTableBody>
|
||||
</VsTable>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
32
src/viewpanel/components/Collapsible.tsx
Normal file
32
src/viewpanel/components/Collapsible.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import { VsCollapsible } from './VscodeComponents';
|
||||
|
||||
export interface ICollapsibleProps {
|
||||
title: string;
|
||||
className?: string;
|
||||
sendUpdate?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export const Collapsible: React.FunctionComponent<ICollapsibleProps> = ({children, title, sendUpdate, className}: React.PropsWithChildren<ICollapsibleProps>) => {
|
||||
const [ isOpen, setIsOpen ] = React.useState(true);
|
||||
|
||||
// This is a work around for a lit-element issue of duplicate slot names
|
||||
const triggerClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
if ((e.target as any).tagName.toUpperCase() === 'VSCODE-COLLAPSIBLE') {
|
||||
setIsOpen(prev => {
|
||||
if (sendUpdate) {
|
||||
sendUpdate(!prev);
|
||||
}
|
||||
return !prev;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<VsCollapsible title={title} onClick={triggerClick} open={isOpen}>
|
||||
<div className={`section collapsible__body ${className || ""}`} slot="body">
|
||||
{children}
|
||||
</div>
|
||||
</VsCollapsible>
|
||||
);
|
||||
};
|
||||
10
src/viewpanel/components/Icon.tsx
Normal file
10
src/viewpanel/components/Icon.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IIconProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const Icon: React.FunctionComponent<IIconProps> = ({ name }: React.PropsWithChildren<IIconProps>) => {
|
||||
|
||||
return (<i className={`codicon codicon-${name}`}></i>);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/AddIcon.tsx
Normal file
9
src/viewpanel/components/Icons/AddIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IAddIconProps {}
|
||||
|
||||
export const AddIcon: React.FunctionComponent<IAddIconProps> = (props: React.PropsWithChildren<IAddIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M14 7v1H8v6H7V8H1V7h6V1h1v6h6z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/ArchiveIcon.tsx
Normal file
9
src/viewpanel/components/Icons/ArchiveIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IArchiveIconProps {}
|
||||
|
||||
export const ArchiveIcon: React.FunctionComponent<IArchiveIconProps> = (props: React.PropsWithChildren<IArchiveIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M14.5 1h-13l-.5.5v3l.5.5H2v8.5l.5.5h11l.5-.5V5h.5l.5-.5v-3l-.5-.5zm-1 3H2V2h12v2h-.5zM3 13V5h10v8H3zm8-6H5v1h6V7z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/BugIcon.tsx
Normal file
9
src/viewpanel/components/Icons/BugIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IBugIconProps {}
|
||||
|
||||
export const BugIcon: React.FunctionComponent<IBugIconProps> = (props: React.PropsWithChildren<IBugIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M10.877 4.5v-.582a2.918 2.918 0 1 0-5.836 0V4.5h-.833L2.545 2.829l-.593.59 1.611 1.619-.019.049a8.03 8.03 0 0 0-.503 2.831c0 .196.007.39.02.58l.003.045H1v.836h2.169l.006.034c.172.941.504 1.802.954 2.531l.034.055L2.2 13.962l.592.592 1.871-1.872.058.066c.868.992 2.002 1.589 3.238 1.589 1.218 0 2.336-.579 3.199-1.544l.057-.064 1.91 1.92.593-.591-1.996-2.006.035-.056c.467-.74.81-1.619.986-2.583l.006-.034h2.171v-.836h-2.065l.003-.044a8.43 8.43 0 0 0 .02-.58 8.02 8.02 0 0 0-.517-2.866l-.019-.05 1.57-1.57-.592-.59L11.662 4.5h-.785zm-5 0v-.582a2.082 2.082 0 1 1 4.164 0V4.5H5.878zm5.697.837l.02.053c.283.753.447 1.61.447 2.528 0 1.61-.503 3.034-1.274 4.037-.77 1.001-1.771 1.545-2.808 1.545-1.036 0-2.037-.544-2.807-1.545-.772-1.003-1.275-2.427-1.275-4.037 0-.918.164-1.775.448-2.528l.02-.053h7.229z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/CheckIcon.tsx
Normal file
9
src/viewpanel/components/Icons/CheckIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface ICheckIconProps {}
|
||||
|
||||
export const CheckIcon: React.FunctionComponent<ICheckIconProps> = (props: React.PropsWithChildren<ICheckIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M14.431 3.323l-8.47 10-.79-.036-3.35-4.77.818-.574 2.978 4.24 8.051-9.506.764.646z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/FileIcon.tsx
Normal file
9
src/viewpanel/components/Icons/FileIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IFileIconProps {}
|
||||
|
||||
export const FileIcon: React.FunctionComponent<IFileIconProps> = (props: React.PropsWithChildren<IFileIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M13.71 4.29l-3-3L10 1H4L3 2v12l1 1h9l1-1V5l-.29-.71zM13 14H4V2h5v4h4v8zm-3-9V2l3 3h-3z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/FolderOpenedIcon.tsx
Normal file
9
src/viewpanel/components/Icons/FolderOpenedIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IFolderOpenedIconProps {}
|
||||
|
||||
export const FolderOpenedIcon: React.FunctionComponent<IFolderOpenedIconProps> = (props: React.PropsWithChildren<IFolderOpenedIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M1.5 14h11l.48-.37 2.63-7-.48-.63H14V3.5l-.5-.5H7.71l-.86-.85L6.5 2h-5l-.5.5v11l.5.5zM2 3h4.29l.86.85.35.15H13v2H8.5l-.35.15-.86.85H3.5l-.47.34-1 3.08L2 3zm10.13 10H2.19l1.67-5H7.5l.35-.15.86-.85h5.79l-2.37 6z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/ListUnorderedIcon.tsx
Normal file
9
src/viewpanel/components/Icons/ListUnorderedIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IListUnorderedIconProps {}
|
||||
|
||||
export const ListUnorderedIcon: React.FunctionComponent<IListUnorderedIconProps> = (props: React.PropsWithChildren<IListUnorderedIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M2 3H1v1h1V3zm0 3H1v1h1V6zM1 9h1v1H1V9zm1 3H1v1h1v-1zm2-9h11v1H4V3zm11 3H4v1h11V6zM4 9h11v1H4V9zm11 3H4v1h11v-1z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/SettingsIcon.tsx
Normal file
9
src/viewpanel/components/Icons/SettingsIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface ISettingsIconProps {}
|
||||
|
||||
export const SettingsIcon: React.FunctionComponent<ISettingsIconProps> = (props: React.PropsWithChildren<ISettingsIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M3.5 2h-1v5h1V2zm6.1 5H6.4L6 6.45v-1L6.4 5h3.2l.4.5v1l-.4.5zm-5 3H1.4L1 9.5v-1l.4-.5h3.2l.4.5v1l-.4.5zm3.9-8h-1v2h1V2zm-1 6h1v6h-1V8zm-4 3h-1v3h1v-3zm7.9 0h3.19l.4-.5v-.95l-.4-.5H11.4l-.4.5v.95l.4.5zm2.1-9h-1v6h1V2zm-1 10h1v2h-1v-2z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/SymbolKeywordIcon.tsx
Normal file
9
src/viewpanel/components/Icons/SymbolKeywordIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface ISymbolKeywordIconProps {}
|
||||
|
||||
export const SymbolKeywordIcon: React.FunctionComponent<ISymbolKeywordIconProps> = (props: React.PropsWithChildren<ISymbolKeywordIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M15 4h-5V3h5v1zm-1 3h-2v1h2V7zm-4 0H1v1h9V7zm2 6H1v1h11v-1zm-5-3H1v1h6v-1zm8 0h-5v1h5v-1zM8 2v3H1V2h7zM7 3H2v1h5V3z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/TagIcon.tsx
Normal file
9
src/viewpanel/components/Icons/TagIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface ITagIconProps {}
|
||||
|
||||
export const TagIcon: React.FunctionComponent<ITagIconProps> = (props: React.PropsWithChildren<ITagIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M13.2 2H8.017l-.353.146L1 8.81v.707L6.183 14.7h.707l2.215-2.215A4.48 4.48 0 0 0 15.65 9c.027-.166.044-.332.051-.5a4.505 4.505 0 0 0-2-3.74V2.5l-.5-.5zm-.5 2.259A4.504 4.504 0 0 0 11.2 4a.5.5 0 1 0 0 1 3.5 3.5 0 0 1 1.5.338v2.138L8.775 11.4a.506.506 0 0 0-.217.217l-2.022 2.022-4.475-4.476L8.224 3H12.7v1.259zm1 1.792a3.5 3.5 0 0 1 1 2.449 3.438 3.438 0 0 1-.051.5 3.487 3.487 0 0 1-4.793 2.735l3.698-3.698.146-.354V6.051z"/></svg>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/Icons/WarningIcon.tsx
Normal file
9
src/viewpanel/components/Icons/WarningIcon.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export interface IWarningIconProps {}
|
||||
|
||||
export const WarningIcon: React.FunctionComponent<IWarningIconProps> = (props: React.PropsWithChildren<IWarningIconProps>) => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28L2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z"/></svg>
|
||||
);
|
||||
};
|
||||
@@ -1,21 +1,41 @@
|
||||
import * as React from 'react';
|
||||
import { VsTable, VsTableBody, VsTableHeader, VsTableHeaderCell, VsTableRow, VsTableCell } from './VscodeComponents';
|
||||
|
||||
export interface ISeoDetailsProps {
|
||||
allowedLength: number;
|
||||
title: string;
|
||||
value: string;
|
||||
value: number;
|
||||
valueTitle: string;
|
||||
noValidation?: boolean;
|
||||
}
|
||||
|
||||
export const SeoDetails: React.FunctionComponent<ISeoDetailsProps> = (props: React.PropsWithChildren<ISeoDetailsProps>) => {
|
||||
const { allowedLength, title, value } = props;
|
||||
const { allowedLength, title, value, valueTitle, noValidation } = props;
|
||||
|
||||
const validate = () => {
|
||||
if (noValidation) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value <= allowedLength ? "valid" : "not-valid"
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`seo__status__details ${value.length <= allowedLength ? "valid" : "not-valid"}`}>
|
||||
<h4><strong>{title}</strong></h4>
|
||||
<ul>
|
||||
<li><b>Length</b>: {value.length}</li>
|
||||
<li><b>Recommended length</b>: {allowedLength}</li>
|
||||
</ul>
|
||||
<div className={`seo__status__details ${validate()}`}>
|
||||
<h4>{title}</h4>
|
||||
|
||||
<VsTable bordered>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell className={validate()}>{valueTitle}</VsTableHeaderCell>
|
||||
<VsTableHeaderCell>Recommended</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
<VsTableRow>
|
||||
<VsTableCell className={validate()}>{value}</VsTableCell>
|
||||
<VsTableCell>{allowedLength}</VsTableCell>
|
||||
</VsTableRow>
|
||||
</VsTableBody>
|
||||
</VsTable>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
22
src/viewpanel/components/SeoFieldInfo.tsx
Normal file
22
src/viewpanel/components/SeoFieldInfo.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as React from 'react';
|
||||
import { ValidInfo } from './ValidInfo';
|
||||
import { VsTableCell, VsTableRow } from './VscodeComponents';
|
||||
|
||||
export interface ISeoFieldInfoProps {
|
||||
title: string;
|
||||
value: any;
|
||||
recommendation: any;
|
||||
isValid?: boolean;
|
||||
}
|
||||
|
||||
export const SeoFieldInfo: React.FunctionComponent<ISeoFieldInfoProps> = ({ title, value, recommendation, isValid }: React.PropsWithChildren<ISeoFieldInfoProps>) => {
|
||||
return (
|
||||
<VsTableRow>
|
||||
<VsTableCell className={`table__cell table__title`}>{title}</VsTableCell>
|
||||
<VsTableCell className={`table__cell`}>{value}/{recommendation}</VsTableCell>
|
||||
<VsTableCell className={`table__cell table__cell__validation`}>
|
||||
{ isValid !== undefined ? <ValidInfo isValid={isValid} /> : <span>-</span> }
|
||||
</VsTableCell>
|
||||
</VsTableRow>
|
||||
);
|
||||
};
|
||||
32
src/viewpanel/components/SeoKeywordInfo.tsx
Normal file
32
src/viewpanel/components/SeoKeywordInfo.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import { ValidInfo } from './ValidInfo';
|
||||
import { VsTableCell, VsTableRow } from './VscodeComponents';
|
||||
|
||||
export interface ISeoKeywordInfoProps {
|
||||
keyword: string;
|
||||
title: string;
|
||||
description: string;
|
||||
slug: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export const SeoKeywordInfo: React.FunctionComponent<ISeoKeywordInfoProps> = ({keyword, title, description, slug, content}: React.PropsWithChildren<ISeoKeywordInfoProps>) => {
|
||||
|
||||
return (
|
||||
<VsTableRow>
|
||||
<VsTableCell className={`table__cell`}>{keyword}</VsTableCell>
|
||||
<VsTableCell className={`table__cell table__cell__validation`}>
|
||||
<ValidInfo isValid={!!title && title.toLowerCase().includes(keyword.toLowerCase())} />
|
||||
</VsTableCell>
|
||||
<VsTableCell className={`table__cell table__cell__validation`}>
|
||||
<ValidInfo isValid={!!description && description.toLowerCase().includes(keyword.toLowerCase())} />
|
||||
</VsTableCell>
|
||||
<VsTableCell className={`table__cell table__cell__validation`}>
|
||||
<ValidInfo isValid={!!slug && (slug.toLowerCase().includes(keyword.toLowerCase()) || slug.toLowerCase().includes(keyword.replace(/ /g, '-').toLowerCase()))} />
|
||||
</VsTableCell>
|
||||
<VsTableCell className={`table__cell table__cell__validation`}>
|
||||
<ValidInfo isValid={!!content && content.toLowerCase().includes(keyword.toLowerCase())} />
|
||||
</VsTableCell>
|
||||
</VsTableRow>
|
||||
);
|
||||
};
|
||||
46
src/viewpanel/components/SeoKeywords.tsx
Normal file
46
src/viewpanel/components/SeoKeywords.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import * as React from 'react';
|
||||
import { SeoKeywordInfo } from './SeoKeywordInfo';
|
||||
import { VsTable, VsTableBody, VsTableCell, VsTableHeader, VsTableHeaderCell, VsTableRow } from './VscodeComponents';
|
||||
|
||||
export interface ISeoKeywordsProps {
|
||||
keywords: string[] | null;
|
||||
|
||||
title: string;
|
||||
description: string;
|
||||
slug: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({keywords, ...data}: React.PropsWithChildren<ISeoKeywordsProps>) => {
|
||||
|
||||
if (!keywords || keywords.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`seo__status__keywords`}>
|
||||
<h4>Keywords</h4>
|
||||
|
||||
<VsTable bordered>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell className={`table__cell`}>Keyword</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Title</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Description</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Slug</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Content</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
{
|
||||
keywords.map((keyword, index) => {
|
||||
return (
|
||||
<SeoKeywordInfo key={index} keyword={keyword} {...data} />
|
||||
);
|
||||
})
|
||||
}
|
||||
</VsTableBody>
|
||||
</VsTable>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { SEO } from '../../models/PanelSettings';
|
||||
import { ArticleDetails } from './ArticleDetails';
|
||||
import { Collapsible } from './Collapsible';
|
||||
import { SeoDetails } from './SeoDetails';
|
||||
import { SeoFieldInfo } from './SeoFieldInfo';
|
||||
import { SeoKeywords } from './SeoKeywords';
|
||||
import { ValidInfo } from './ValidInfo';
|
||||
import { VsTable, VsTableBody, VsTableCell, VsTableHeader, VsTableHeaderCell, VsTableRow } from './VscodeComponents';
|
||||
|
||||
export interface ISeoStatusProps {
|
||||
seo: SEO;
|
||||
@@ -9,7 +15,8 @@ export interface ISeoStatusProps {
|
||||
|
||||
export const SeoStatus: React.FunctionComponent<ISeoStatusProps> = (props: React.PropsWithChildren<ISeoStatusProps>) => {
|
||||
const { data, seo } = props;
|
||||
const { title, description } = data;
|
||||
const { title } = data;
|
||||
const [ isOpen, setIsOpen ] = React.useState(true);
|
||||
|
||||
const { descriptionField } = seo;
|
||||
|
||||
@@ -17,11 +24,58 @@ export const SeoStatus: React.FunctionComponent<ISeoStatusProps> = (props: React
|
||||
return null;
|
||||
}
|
||||
|
||||
const renderContent = () => {
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={`seo__status__details`}>
|
||||
<h4>Recommendations</h4>
|
||||
|
||||
<VsTable bordered>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell className={`table__cell`}>Property</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Length</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Valid</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
{
|
||||
(title && seo.title > 0) && (
|
||||
<SeoFieldInfo title={`title`} value={title.length} recommendation={`${seo.title} chars`} isValid={title.length <= seo.title} />
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
(data[descriptionField] && seo.description > 0) && (
|
||||
<SeoFieldInfo title={descriptionField} value={data[descriptionField].length} recommendation={`${seo.description} chars`} isValid={data[descriptionField].length <= seo.description} />
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
(seo.content > 0 && data?.articleDetails?.wordCount) && (
|
||||
<SeoFieldInfo title={`Article length`} value={data?.articleDetails?.wordCount} recommendation={`${seo.content} words`} />
|
||||
)
|
||||
}
|
||||
</VsTableBody>
|
||||
</VsTable>
|
||||
</div>
|
||||
|
||||
<SeoKeywords keywords={data?.keywords}
|
||||
title={title}
|
||||
description={data[descriptionField]}
|
||||
slug={data.slug}
|
||||
content={data?.articleDetails?.content} />
|
||||
|
||||
<ArticleDetails details={data.articleDetails} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="seo__status">
|
||||
<h3>SEO Status</h3>
|
||||
{ (title && seo.title > 0) && <SeoDetails title="Title" allowedLength={seo.title} value={title} /> }
|
||||
{ (data[descriptionField] && seo.description > 0) && <SeoDetails title="Description" allowedLength={seo.description} value={data[descriptionField]} /> }
|
||||
</div>
|
||||
<Collapsible title="SEO Status" sendUpdate={(value) => setIsOpen(value)}>
|
||||
{ renderContent() }
|
||||
</Collapsible>
|
||||
);
|
||||
};
|
||||
@@ -1,26 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import AddIcon from '@material-ui/icons/Add';
|
||||
import DeleteIcon from '@material-ui/icons/Delete';
|
||||
import { AddIcon } from './Icons/AddIcon';
|
||||
import { ArchiveIcon } from './Icons/ArchiveIcon';
|
||||
|
||||
export interface ITagProps {
|
||||
className: string;
|
||||
value: string;
|
||||
title: string;
|
||||
|
||||
disableConfigurable?: boolean;
|
||||
|
||||
onCreate?: (tags: string) => void;
|
||||
onRemove: (tags: string) => void;
|
||||
}
|
||||
|
||||
export const Tag: React.FunctionComponent<ITagProps> = (props: React.PropsWithChildren<ITagProps>) => {
|
||||
const { value, className, title, onRemove, onCreate } = props;
|
||||
const { value, className, title, onRemove, onCreate, disableConfigurable } = props;
|
||||
|
||||
return (
|
||||
<div className={`article__tags__items__item`}>
|
||||
{
|
||||
onCreate &&
|
||||
!disableConfigurable && onCreate &&
|
||||
<button title={`Add ${value} to your settings`} className={`article__tags__items__item_add`} onClick={() => onCreate(value)}><AddIcon /></button>
|
||||
}
|
||||
<button title={title} className={`article__tags__items__item_delete ${className}`} onClick={() => onRemove(value)}>{value} <span><DeleteIcon /></span></button>
|
||||
<button title={title} className={`article__tags__items__item_delete ${className}`} onClick={() => onRemove(value)}>{value} <span><ArchiveIcon /></span></button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -5,18 +5,21 @@ import { CommandToCode } from '../CommandToCode';
|
||||
import { TagType } from '../TagType';
|
||||
import { MessageHelper } from '../helper/MessageHelper';
|
||||
import Downshift from 'downshift';
|
||||
import { AddIcon } from './Icons/AddIcon';
|
||||
|
||||
export interface ITagPickerProps {
|
||||
type: string;
|
||||
icon: JSX.Element;
|
||||
crntSelected: string[];
|
||||
options: string[];
|
||||
freeform: boolean;
|
||||
focussed: boolean;
|
||||
unsetFocus: () => void;
|
||||
disableConfigurable?: boolean;
|
||||
}
|
||||
|
||||
export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React.PropsWithChildren<ITagPickerProps>) => {
|
||||
const { type, crntSelected, options, freeform, focussed, unsetFocus } = props;
|
||||
const { icon, type, crntSelected, options, freeform, focussed, unsetFocus, disableConfigurable } = props;
|
||||
const [ selected, setSelected ] = React.useState<string[]>([]);
|
||||
const [ inputValue, setInputValue ] = React.useState<string>("");
|
||||
const prevSelected = usePrevious(crntSelected);
|
||||
@@ -47,7 +50,16 @@ export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React
|
||||
* @param values
|
||||
*/
|
||||
const sendUpdate = (values: string[]) => {
|
||||
const cmdType = type === TagType.tags ? CommandToCode.updateTags : CommandToCode.updateCategories;
|
||||
let cmdType = CommandToCode.updateCategories;
|
||||
|
||||
if (type === TagType.tags) {
|
||||
cmdType = CommandToCode.updateTags;
|
||||
} else if (type === TagType.categories) {
|
||||
cmdType = CommandToCode.updateCategories;
|
||||
} else if (type === TagType.keywords) {
|
||||
cmdType = CommandToCode.updateKeywords;
|
||||
}
|
||||
|
||||
MessageHelper.sendMessage(cmdType, values);
|
||||
};
|
||||
|
||||
@@ -114,8 +126,8 @@ export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React
|
||||
}, [crntSelected]);
|
||||
|
||||
return (
|
||||
<div className={`article__tags`}>
|
||||
<h3>{type}</h3>
|
||||
<div className={`section article__tags`}>
|
||||
<h3>{icon} {type}</h3>
|
||||
|
||||
<Downshift ref={dsRef}
|
||||
onChange={(selected) => onSelect(selected || "")}
|
||||
@@ -144,9 +156,12 @@ export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React
|
||||
|
||||
{
|
||||
freeform && (
|
||||
<button title={`Add the unknown tag`}
|
||||
<button className={`article__tags__input__button`}
|
||||
title={`Add the unknown tag`}
|
||||
disabled={!inputValue}
|
||||
onClick={() => insertUnkownTag(closeMenu)}>+</button>
|
||||
onClick={() => insertUnkownTag(closeMenu)}>
|
||||
<AddIcon />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
@@ -154,7 +169,7 @@ export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React
|
||||
<ul className={`article__tags__dropbox ${isOpen ? "open" : "closed" }`} {...getMenuProps()}>
|
||||
{
|
||||
isOpen ? options.filter((option) => filterList(option, inputValue)).map((item, index) => (
|
||||
<li {...getItemProps({ key: item, index, item })} >
|
||||
<li {...getItemProps({ key: item, index, item })}>
|
||||
{ item }
|
||||
</li>
|
||||
)) : null
|
||||
@@ -165,7 +180,7 @@ export const TagPicker: React.FunctionComponent<ITagPickerProps> = (props: React
|
||||
}
|
||||
</Downshift>
|
||||
|
||||
<Tags values={selected.sort((a: string, b: string) => a.toLowerCase() < b.toLowerCase() ? -1 : 1 )} onRemove={onRemove} onCreate={onCreate} options={options} />
|
||||
<Tags values={selected.sort((a: string, b: string) => a.toLowerCase() < b.toLowerCase() ? -1 : 1 )} onRemove={onRemove} onCreate={onCreate} options={options} disableConfigurable={!!disableConfigurable} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -5,12 +5,14 @@ export interface ITagsProps {
|
||||
values: string[];
|
||||
options: string[];
|
||||
|
||||
disableConfigurable?: boolean;
|
||||
|
||||
onCreate: (tags: string) => void;
|
||||
onRemove: (tags: string) => void;
|
||||
}
|
||||
|
||||
export const Tags: React.FunctionComponent<ITagsProps> = (props: React.PropsWithChildren<ITagsProps>) => {
|
||||
const { values, options, onCreate, onRemove } = props;
|
||||
const { values, options, onCreate, onRemove, disableConfigurable } = props;
|
||||
|
||||
const knownTags = values.filter(v => options.includes(v));
|
||||
const unknownTags = values.filter(v => !options.includes(v));
|
||||
@@ -24,7 +26,7 @@ export const Tags: React.FunctionComponent<ITagsProps> = (props: React.PropsWith
|
||||
}
|
||||
{
|
||||
unknownTags.map(t => (
|
||||
<Tag key={t.replace(/ /g, "_")} value={t} className={`article__tags__items__pill_notexists`} onRemove={onRemove} onCreate={onCreate} title={`Be aware, this tag "${t}" is not saved in your settings. Once removed, it will be gone forever.`} />
|
||||
<Tag key={t.replace(/ /g, "_")} value={t} className={`article__tags__items__pill_notexists`} onRemove={onRemove} onCreate={onCreate} title={`Be aware, this tag "${t}" is not saved in your settings. Once removed, it will be gone forever.`} disableConfigurable={disableConfigurable} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
21
src/viewpanel/components/ValidInfo.tsx
Normal file
21
src/viewpanel/components/ValidInfo.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import * as React from 'react';
|
||||
import { CheckIcon } from './Icons/CheckIcon';
|
||||
import { WarningIcon } from './Icons/WarningIcon';
|
||||
|
||||
export interface IValidInfoProps {
|
||||
isValid: boolean;
|
||||
}
|
||||
|
||||
export const ValidInfo: React.FunctionComponent<IValidInfoProps> = ({isValid}: React.PropsWithChildren<IValidInfoProps>) => {
|
||||
return (
|
||||
<>
|
||||
{
|
||||
isValid ? (
|
||||
<span className="valid"><CheckIcon /></span>
|
||||
) : (
|
||||
<span className="warning"><WarningIcon /></span>
|
||||
)
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
9
src/viewpanel/components/VscodeComponents.ts
Normal file
9
src/viewpanel/components/VscodeComponents.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import {wrapWc} from 'wc-react';
|
||||
|
||||
export const VsTable = wrapWc(`vscode-table`);
|
||||
export const VsTableHeader = wrapWc(`vscode-table-header`);
|
||||
export const VsTableHeaderCell = wrapWc(`vscode-table-header-cell`);
|
||||
export const VsTableBody = wrapWc(`vscode-table-body`);
|
||||
export const VsTableRow = wrapWc(`vscode-table-row`);
|
||||
export const VsTableCell = wrapWc(`vscode-table-cell`);
|
||||
export const VsCollapsible = wrapWc(`vscode-collapsible`);
|
||||
@@ -2,6 +2,15 @@ import * as React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { ViewPanel } from "./ViewPanel";
|
||||
|
||||
// require('@vscode/codicons/dist/codicon.css');
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table-header';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table-header-cell';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table-body';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table-row';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-table-cell';
|
||||
import '@bendera/vscode-webview-elements/dist/vscode-collapsible';
|
||||
|
||||
declare const acquireVsCodeApi: <T = unknown>() => {
|
||||
getState: () => T;
|
||||
setState: (data: T) => void;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SETTING_CUSTOM_SCRIPTS, SETTING_SEO_DESCRIPTION_FIELD } from './../constants/settings';
|
||||
import { SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD } from './../constants/settings';
|
||||
import * as os from 'os';
|
||||
import { PanelSettings, CustomScript } from './../models/PanelSettings';
|
||||
import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv } from "vscode";
|
||||
@@ -11,6 +11,8 @@ import { TagType } from '../viewpanel/TagType';
|
||||
import { TaxonomyType } from '../models';
|
||||
import { exec } from 'child_process';
|
||||
import * as path from 'path';
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown';
|
||||
import { Content } from 'mdast';
|
||||
|
||||
|
||||
export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
@@ -58,8 +60,6 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
*/
|
||||
public async resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): Promise<void> {
|
||||
|
||||
console.log(context);
|
||||
|
||||
this.panel = webviewView;
|
||||
|
||||
webviewView.webview.options = {
|
||||
@@ -98,6 +98,9 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
case CommandToCode.updateCategories:
|
||||
this.updateTags(TagType.categories, msg.data || []);
|
||||
break;
|
||||
case CommandToCode.updateKeywords:
|
||||
this.updateTags(TagType.keywords, msg.data || []);
|
||||
break;
|
||||
case CommandToCode.addTagToSettings:
|
||||
this.addTags(TagType.tags, msg.data);
|
||||
break;
|
||||
@@ -152,7 +155,10 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
* @param metadata
|
||||
*/
|
||||
public pushMetadata(metadata: any) {
|
||||
this.postWebviewMessage({ command: Command.metadata, data: metadata });
|
||||
this.postWebviewMessage({ command: Command.metadata, data: {
|
||||
...metadata,
|
||||
articleDetails: this.getArticleDetails()
|
||||
} });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,6 +227,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
seo: {
|
||||
title: config.get(SETTING_SEO_TITLE_LENGTH) as number || -1,
|
||||
description: config.get(SETTING_SEO_DESCRIPTION_LENGTH) as number || -1,
|
||||
content: config.get(SETTING_SEO_CONTENT_MIN_LENGTH) as number || -1,
|
||||
descriptionField: config.get(SETTING_SEO_DESCRIPTION_FIELD) as string || "description"
|
||||
},
|
||||
slug: {
|
||||
@@ -245,7 +252,10 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
|
||||
const article = ArticleHelper.getFrontMatter(editor);
|
||||
this.postWebviewMessage({ command: Command.metadata, data: article!.data });
|
||||
this.postWebviewMessage({ command: Command.metadata, data: {
|
||||
...article!.data,
|
||||
articleDetails: this.getArticleDetails()
|
||||
}});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,7 +273,10 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
if (article && article.data) {
|
||||
article.data[tagType.toLowerCase()] = values || [];
|
||||
ArticleHelper.update(editor, article);
|
||||
this.postWebviewMessage({ command: Command.metadata, data: article.data });
|
||||
this.postWebviewMessage({ command: Command.metadata, data: {
|
||||
...article.data,
|
||||
articleDetails: this.getArticleDetails()
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +300,59 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get article details
|
||||
*/
|
||||
private getArticleDetails() {
|
||||
const editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const article = ArticleHelper.getFrontMatter(editor);
|
||||
|
||||
if (article && article.content) {
|
||||
let content = article.content;
|
||||
content = content.replace(/({{(.*?)}})/g, ''); // remove hugo shortcodes
|
||||
|
||||
const mdTree = fromMarkdown(content);
|
||||
const headings = mdTree.children.filter(node => node.type === 'heading').length;
|
||||
const paragraphs = mdTree.children.filter(node => node.type === 'paragraph').length;
|
||||
const wordCount = this.wordCount(0, mdTree);
|
||||
|
||||
return {
|
||||
headings,
|
||||
paragraphs,
|
||||
wordCount,
|
||||
content: article.content
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private counts(acc: any, node: any) {
|
||||
// add 1 to an initial or existing value
|
||||
acc[node.type] = (acc[node.type] || 0) + 1;
|
||||
|
||||
// find and add up the counts from all of this node's children
|
||||
return (node.children || []).reduce(
|
||||
(childAcc: any, childNode: any) => this.counts(childAcc, childNode),
|
||||
acc
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the word count for the current document
|
||||
*/
|
||||
private wordCount(count: number, node: Content | any) {
|
||||
if (node.type === "text") {
|
||||
return count + node.value.split(" ").length;
|
||||
} else {
|
||||
return (node.children || []).reduce((childCount: number, childNode: any) => this.wordCount(childCount, childNode), count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post data to the panel
|
||||
* @param msg
|
||||
@@ -314,6 +380,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
const styleResetUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'reset.css'));
|
||||
const stylesUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'styles.css'));
|
||||
const scriptUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'dist', 'viewpanel.js'));
|
||||
|
||||
const nonce = this.getNonce();
|
||||
|
||||
return `
|
||||
@@ -326,7 +393,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
|
||||
<link href="${styleVSCodeUri}" rel="stylesheet">
|
||||
<link href="${stylesUri}" rel="stylesheet">
|
||||
|
||||
<title>FrontMatter</title>
|
||||
<title>Front Matter</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -49,13 +49,15 @@ module.exports = [
|
||||
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
loader: 'ts-loader'
|
||||
}]
|
||||
}]
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
loader: 'ts-loader'
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 400000,
|
||||
|
||||
Reference in New Issue
Block a user