mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-07 09:23:00 +02:00
init
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"ignorePatterns": ["./**/*.js", "./webpack/*.config.js", "./e2e/*.ts"],
|
||||
"rules": {
|
||||
"no-throw-literal": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"curly": "error",
|
||||
"class-methods-use-this": "warn"
|
||||
}
|
||||
}
|
||||
Vendored
+4
-7
@@ -1,8 +1,5 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"eliostruyf.vscode-typescript-exportallmodules"
|
||||
]
|
||||
}
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": ["eliostruyf.vscode-typescript-exportallmodules"]
|
||||
}
|
||||
|
||||
Vendored
+20
-28
@@ -3,32 +3,24 @@
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/dist/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm: build:ext"
|
||||
},
|
||||
{
|
||||
"name": "Attach Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/dist/**/*.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
|
||||
"preLaunchTask": "pnpm: build:ext"
|
||||
},
|
||||
{
|
||||
"name": "Attach Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+13
-13
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Recoil Atom": {
|
||||
"prefix": "sq-atom",
|
||||
"body": [
|
||||
"Recoil Atom": {
|
||||
"prefix": "sq-atom",
|
||||
"body": [
|
||||
"import { atom } from 'recoil';",
|
||||
"",
|
||||
"export const ${1:CollectionId}Atom = atom({",
|
||||
@@ -12,9 +12,9 @@
|
||||
"description": "Creates a new atom",
|
||||
"scope": "typescript"
|
||||
},
|
||||
"Recoil Selector (sync)": {
|
||||
"prefix": "sq-selector-sync",
|
||||
"body": [
|
||||
"Recoil Selector (sync)": {
|
||||
"prefix": "sq-selector-sync",
|
||||
"body": [
|
||||
"import { selector } from 'recoil';",
|
||||
"",
|
||||
"export const ${1:CollectionData}Selector = selector({",
|
||||
@@ -27,9 +27,9 @@
|
||||
"description": "Creates a new synchronous selector",
|
||||
"scope": "typescript"
|
||||
},
|
||||
"Recoil Selector (async)": {
|
||||
"prefix": "sq-selector-async",
|
||||
"body": [
|
||||
"Recoil Selector (async)": {
|
||||
"prefix": "sq-selector-async",
|
||||
"body": [
|
||||
"import { selector } from 'recoil';",
|
||||
"",
|
||||
"export const ${1:CollectionData}Selector = selector({",
|
||||
@@ -42,9 +42,9 @@
|
||||
"description": "Creates a new asynchronous selector",
|
||||
"scope": "typescript"
|
||||
},
|
||||
"Recoil selectorFamily": {
|
||||
"prefix": "sq-selector-fam",
|
||||
"body": [
|
||||
"Recoil selectorFamily": {
|
||||
"prefix": "sq-selector-fam",
|
||||
"body": [
|
||||
"import { selectorFamily } from 'recoil';",
|
||||
"",
|
||||
"export const ${1:CollectionData}Selector = selectorFamily({",
|
||||
@@ -63,4 +63,4 @@
|
||||
"description": "Include the translations",
|
||||
"scope": "typescriptreact"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+48
-48
@@ -1,52 +1,52 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"eliostruyf.writingstyleguide.terms.isDisabled": true,
|
||||
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
|
||||
"squarl.groups": [
|
||||
{
|
||||
"id": "dashboard",
|
||||
"name": "Dashboard"
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
{
|
||||
"id": "panel",
|
||||
"name": "Panel"
|
||||
}
|
||||
],
|
||||
"squarl.bookmarks": [
|
||||
{
|
||||
"name": "App.tsx",
|
||||
"path": "src/dashboardWebView/components/App.tsx",
|
||||
"description": "Start of dashboard",
|
||||
"type": "file",
|
||||
"groupId": "dashboard"
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"eliostruyf.writingstyleguide.terms.isDisabled": true,
|
||||
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
|
||||
"squarl.groups": [
|
||||
{
|
||||
"id": "dashboard",
|
||||
"name": "Dashboard"
|
||||
},
|
||||
{
|
||||
"id": "panel",
|
||||
"name": "Panel"
|
||||
}
|
||||
],
|
||||
"squarl.bookmarks": [
|
||||
{
|
||||
"name": "App.tsx",
|
||||
"path": "src/dashboardWebView/components/App.tsx",
|
||||
"description": "Start of dashboard",
|
||||
"type": "file",
|
||||
"groupId": "dashboard"
|
||||
},
|
||||
{
|
||||
"name": "ViewPanel.tsx",
|
||||
"path": "src/panelWebView/ViewPanel.tsx",
|
||||
"description": "Start of panel",
|
||||
"type": "file",
|
||||
"groupId": "panel"
|
||||
},
|
||||
{
|
||||
"name": "styles.css",
|
||||
"path": "src/panelWebView/styles.css",
|
||||
"description": "Panel styles",
|
||||
"type": "file",
|
||||
"groupId": "panel"
|
||||
},
|
||||
{
|
||||
"name": "settings.ts",
|
||||
"path": "src/constants/settings.ts",
|
||||
"description": "Settings names",
|
||||
"type": "file"
|
||||
}
|
||||
],
|
||||
}
|
||||
{
|
||||
"name": "ViewPanel.tsx",
|
||||
"path": "src/panelWebView/ViewPanel.tsx",
|
||||
"description": "Start of panel",
|
||||
"type": "file",
|
||||
"groupId": "panel"
|
||||
},
|
||||
{
|
||||
"name": "styles.css",
|
||||
"path": "src/panelWebView/styles.css",
|
||||
"description": "Panel styles",
|
||||
"type": "file",
|
||||
"groupId": "panel"
|
||||
},
|
||||
{
|
||||
"name": "settings.ts",
|
||||
"path": "src/constants/settings.ts",
|
||||
"description": "Settings names",
|
||||
"type": "file"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+24
-24
@@ -1,28 +1,28 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build:ext",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build:ext",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1
-2
@@ -5,7 +5,6 @@ src/**
|
||||
.gitignore
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/tslint.json
|
||||
**/*.map
|
||||
**/*.ts
|
||||
webpack.config.js
|
||||
@@ -28,4 +27,4 @@ frontmatter.json
|
||||
webpack
|
||||
README.beta.md
|
||||
e2e
|
||||
storage
|
||||
storage
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ async function main(): Promise<void> {
|
||||
|
||||
const exTester = new ExTester(storageFolder, ReleaseQuality.Stable, extFolder);
|
||||
await exTester.downloadCode(version);
|
||||
await exTester.installVsix();
|
||||
await exTester.installVsix({ useYarn: false });
|
||||
// await exTester.installFromMarketplace("eliostruyf.vscode-front-matter");
|
||||
await exTester.downloadChromeDriver(version);
|
||||
// await exTester.setupRequirements({vscodeVersion: version});
|
||||
@@ -30,4 +30,4 @@ async function main(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
main();
|
||||
|
||||
Generated
-19403
File diff suppressed because it is too large
Load Diff
+22
-9
@@ -208,7 +208,10 @@
|
||||
"description": "Defines a custom preview path for the folder."
|
||||
},
|
||||
"filePrefix": {
|
||||
"type": [ "null", "string" ],
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
],
|
||||
"description": "Defines a prefix for the file name."
|
||||
},
|
||||
"contentTypes": {
|
||||
@@ -462,7 +465,10 @@
|
||||
"scope": "Custom scripts"
|
||||
},
|
||||
"frontMatter.dashboard.content.pagination": {
|
||||
"type": ["boolean", "number"],
|
||||
"type": [
|
||||
"boolean",
|
||||
"number"
|
||||
],
|
||||
"default": true,
|
||||
"markdownDescription": "Specify if you want to enable/disable pagination for your content. You can define your page number up to 52. Default items per page is `16`. Disabling the pagination can be done by setting it to `false`. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.dashboard.content.pagination)",
|
||||
"scope": "Dashboard"
|
||||
@@ -2132,7 +2138,8 @@
|
||||
"clean": "rimraf dist",
|
||||
"start:site": "cd ./docs && npm run dev",
|
||||
"clean:test": "rm ./e2e/sample/frontmatter.json || exit 0 && rm -rf ./e2e/sample/.frontmatter || exit 0",
|
||||
"test": "tsc -p tsconfig.e2e.json && npm run clean:test && node ./e2e/out/runTests.js"
|
||||
"test": "tsc -p tsconfig.e2e.json && npm run clean:test && node ./e2e/out/runTests.js",
|
||||
"lint": "eslint --max-warnings=0 ./src/{commands,components}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.8.2",
|
||||
@@ -2153,6 +2160,7 @@
|
||||
"@types/lodash.omit": "^4.5.6",
|
||||
"@types/lodash.uniqby": "4.7.6",
|
||||
"@types/lodash.xor": "^4.5.6",
|
||||
"@types/mdast": "^3.0.10",
|
||||
"@types/mime-types": "^2.1.1",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/mustache": "^4.1.2",
|
||||
@@ -2162,17 +2170,20 @@
|
||||
"@types/react-datepicker": "^4.1.7",
|
||||
"@types/react-dom": "17.0.0",
|
||||
"@types/vscode": "^1.63.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@vscode/codicons": "0.0.20",
|
||||
"@vscode/extension-telemetry": "^0.4.7",
|
||||
"@vscode/webview-ui-toolkit": "^0.9.1",
|
||||
"@webpack-cli/serve": "^1.6.0",
|
||||
"ajv": "^8.8.2",
|
||||
"array-move": "^4.0.0",
|
||||
"autoprefixer": "^10.3.2",
|
||||
"autoprefixer": "10.3.3",
|
||||
"chai": "^4.3.6",
|
||||
"css-loader": "5.2.7",
|
||||
"date-fns": "2.23.0",
|
||||
"downshift": "6.0.6",
|
||||
"eslint": "^8.33.0",
|
||||
"fuse.js": "6.5.3",
|
||||
"glob": "7.1.6",
|
||||
"gray-matter": "4.0.3",
|
||||
@@ -2180,6 +2191,7 @@
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"image-size": "^1.0.0",
|
||||
"invariant": "^2.2.4",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lodash.omit": "^4.5.0",
|
||||
@@ -2189,6 +2201,7 @@
|
||||
"mime-types": "^2.1.35",
|
||||
"mocha": "^10.0.0",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"node-json-db": "^1.3.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"path-browserify": "^1.0.1",
|
||||
@@ -2199,6 +2212,7 @@
|
||||
"react-datepicker": "4.2.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-dropzone": "^11.3.4",
|
||||
"react-popper": "^2.3.0",
|
||||
"react-quill": "^2.0.0-beta.4",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-sortable-hoc": "^2.0.0",
|
||||
@@ -2211,14 +2225,13 @@
|
||||
"tailwindcss": "^2.2.7",
|
||||
"tailwindcss-nested-groups": "^1.2.4",
|
||||
"ts-loader": "8.0.3",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "^4.5.4",
|
||||
"typescript": "4.5.5",
|
||||
"uniforms": "^3.7.0",
|
||||
"uniforms-antd": "^3.7.0",
|
||||
"uniforms-bridge-json-schema": "^3.7.0",
|
||||
"uniforms-unstyled": "^3.7.0",
|
||||
"url-join-ts": "^1.0.5",
|
||||
"vscode-extension-tester": "^4.2.5",
|
||||
"vscode-extension-tester": "4.2.5",
|
||||
"wc-react": "github:estruyf/wc-react",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
@@ -2227,7 +2240,7 @@
|
||||
"yaml": "^1.10.2",
|
||||
"yawn-yaml": "^1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.7"
|
||||
"vsce": {
|
||||
"dependencies": false
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+7668
File diff suppressed because it is too large
Load Diff
+18
-18
@@ -1,7 +1,7 @@
|
||||
import { Folders } from './Folders';
|
||||
import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
|
||||
import { isValidFile } from './../helpers/isValidFile';
|
||||
import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
|
||||
import { SETTING_AUTO_UPDATE_DATE, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
|
||||
import * as vscode from 'vscode';
|
||||
import { CustomPlaceholder, Field, TaxonomyType } from "../models";
|
||||
import { format } from "date-fns";
|
||||
@@ -95,7 +95,7 @@ export class Article {
|
||||
return;
|
||||
}
|
||||
|
||||
article = this.updateDate(article, true);
|
||||
article = this.updateDate(article);
|
||||
|
||||
try {
|
||||
ArticleHelper.update(editor, article);
|
||||
@@ -106,10 +106,10 @@ export class Article {
|
||||
|
||||
/**
|
||||
* Update the date in the front matter
|
||||
* @param article
|
||||
* @param article
|
||||
*/
|
||||
public static updateDate(article: ParsedFrontMatter, forceCreate: boolean = false) {
|
||||
article.data = ArticleHelper.updateDates(article.data);
|
||||
public static updateDate(article: ParsedFrontMatter) {
|
||||
article.data = ArticleHelper.updateDates(article.data);
|
||||
return article;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export class Article {
|
||||
try {
|
||||
cloneArticle.data[dateField] = Article.formatDate(new Date());
|
||||
return cloneArticle;
|
||||
} catch (e: any) {
|
||||
} catch (e: unknown) {
|
||||
Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`);
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ export class Article {
|
||||
*/
|
||||
public static async updateSlug() {
|
||||
Telemetry.send(TelemetryEvent.generateSlug);
|
||||
|
||||
|
||||
const updateFileName = Settings.get(SETTING_SLUG_UPDATE_FILE_NAME) as string;
|
||||
let filePrefix = Settings.get<string>(SETTING_TEMPLATES_PREFIX);
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
@@ -220,13 +220,13 @@ export class Article {
|
||||
const titleField = "title";
|
||||
const articleTitle: string = article.data[titleField];
|
||||
const slugInfo = Article.generateSlug(articleTitle);
|
||||
|
||||
|
||||
if (slugInfo && slugInfo.slug && slugInfo.slugWithPrefixAndSuffix) {
|
||||
article.data["slug"] = slugInfo.slugWithPrefixAndSuffix;
|
||||
|
||||
if (contentType) {
|
||||
// Update the fields containing the slug placeholder
|
||||
let fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
|
||||
const fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
|
||||
for (const field of fieldsToUpdate) {
|
||||
article.data[field.name] = slugInfo.slug;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ export class Article {
|
||||
if (editor) {
|
||||
const ext = extname(editor.document.fileName);
|
||||
const fileName = basename(editor.document.fileName);
|
||||
|
||||
|
||||
let slugName = slugInfo.slug.startsWith("/") ? slugInfo.slug.substring(1) : slugInfo.slug;
|
||||
slugName = slugName.endsWith("/") ? slugName.substring(0, slugName.length - 1) : slugName;
|
||||
|
||||
@@ -270,8 +270,8 @@ export class Article {
|
||||
await vscode.workspace.fs.rename(editor.document.uri, vscode.Uri.file(newPath), {
|
||||
overwrite: false
|
||||
});
|
||||
} catch (e: any) {
|
||||
Notifications.error(`Failed to rename file: ${e?.message || e}`);
|
||||
} catch (e: unknown) {
|
||||
Notifications.error(`Failed to rename file: ${(e as Error).message || e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,7 +361,7 @@ export class Article {
|
||||
* Insert an image from the media dashboard into the article
|
||||
*/
|
||||
public static async insertMedia() {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
@@ -391,7 +391,7 @@ export class Article {
|
||||
* Insert a snippet into the article
|
||||
*/
|
||||
public static async insertSnippet() {
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
@@ -415,10 +415,10 @@ export class Article {
|
||||
|
||||
/**
|
||||
* Update the article date and return it
|
||||
* @param article
|
||||
* @param dateFormat
|
||||
* @param field
|
||||
* @param forceCreate
|
||||
* @param article
|
||||
* @param dateFormat
|
||||
* @param field
|
||||
* @param forceCreate
|
||||
*/
|
||||
private static articleDate(article: ParsedFrontMatter, field: string, forceCreate: boolean) {
|
||||
if (typeof article.data[field] !== "undefined" || forceCreate) {
|
||||
|
||||
+11
-11
@@ -14,7 +14,7 @@ import { GitListener, ModeListener } from '../listeners/general';
|
||||
export class Dashboard {
|
||||
private static webview: WebviewPanel | null = null;
|
||||
private static _viewData: DashboardData | undefined;
|
||||
private static isDisposed: boolean = true;
|
||||
private static isDisposed = true;
|
||||
|
||||
public static get viewData(): DashboardData | undefined {
|
||||
return Dashboard._viewData;
|
||||
@@ -35,7 +35,7 @@ export class Dashboard {
|
||||
*/
|
||||
public static async open(data?: DashboardData) {
|
||||
MediaLibrary.getInstance();
|
||||
|
||||
|
||||
Dashboard._viewData = data;
|
||||
|
||||
if (Dashboard.isOpen) {
|
||||
@@ -57,7 +57,7 @@ export class Dashboard {
|
||||
/**
|
||||
* Reveal the dashboard if it is open
|
||||
*/
|
||||
public static reveal(hasData: boolean = false) {
|
||||
public static reveal(hasData = false) {
|
||||
if (Dashboard.webview) {
|
||||
Dashboard.webview.reveal();
|
||||
|
||||
@@ -85,7 +85,7 @@ export class Dashboard {
|
||||
public static resetViewData() {
|
||||
Dashboard._viewData = undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the dashboard webview
|
||||
*/
|
||||
@@ -136,7 +136,7 @@ export class Dashboard {
|
||||
|
||||
Dashboard.webview.webview.onDidReceiveMessage(async (msg) => {
|
||||
Logger.info(`Receiving message from webview: ${msg.command}`);
|
||||
|
||||
|
||||
DashboardListener.process(msg);
|
||||
ExtensionListener.process(msg);
|
||||
MediaListener.process(msg);
|
||||
@@ -162,9 +162,9 @@ export class Dashboard {
|
||||
|
||||
/**
|
||||
* Post data to the dashboard
|
||||
* @param msg
|
||||
* @param msg
|
||||
*/
|
||||
public static postWebviewMessage(msg: { command: DashboardCommand, data?: any }) {
|
||||
public static postWebviewMessage(msg: { command: DashboardCommand, data?: unknown }) {
|
||||
if (Dashboard.isDisposed) {
|
||||
return;
|
||||
}
|
||||
@@ -173,10 +173,10 @@ export class Dashboard {
|
||||
Dashboard.webview?.webview.postMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the webview HTML contents
|
||||
* @param webView
|
||||
* @param webView
|
||||
*/
|
||||
private static getWebviewContent(webView: Webview, extensionPath: Uri): string {
|
||||
const dashboardFile = "dashboardWebView.js";
|
||||
@@ -188,7 +188,7 @@ export class Dashboard {
|
||||
if (isProd) {
|
||||
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
|
||||
} else {
|
||||
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
|
||||
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
|
||||
}
|
||||
|
||||
const nonce = WebviewHelper.getNonce();
|
||||
@@ -226,4 +226,4 @@ export class Dashboard {
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+48
-48
@@ -26,11 +26,11 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Add a media folder
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
public static async addMediaFolder(data?: {selectedFolder?: string}) {
|
||||
let wsFolder = Folders.getWorkspaceFolder();
|
||||
let staticFolder = Folders.getStaticFolderRelativePath();
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
const staticFolder = Folders.getStaticFolderRelativePath();
|
||||
|
||||
let startPath = "";
|
||||
|
||||
@@ -48,7 +48,7 @@ export class Folders {
|
||||
startPath = startPath.replace(STATIC_FOLDER_PLACEHOLDER.hexo.placeholder, STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder);
|
||||
}
|
||||
|
||||
const folderName = await window.showInputBox({
|
||||
const folderName = await window.showInputBox({
|
||||
title: `Add media folder`,
|
||||
prompt: `Which name would you like to give to your folder (use "/" to create multi-level folders)?`,
|
||||
value: startPath,
|
||||
@@ -60,7 +60,7 @@ export class Folders {
|
||||
Notifications.warning(`No folder name was specified.`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await Folders.createFolder(join(parseWinPath(wsFolder?.fsPath || ""), folderName));
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Create content in a registered folder
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
public static async create() {
|
||||
const selectedFolder = await Questions.SelectContentFolder();
|
||||
@@ -99,7 +99,7 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Register the new folder path
|
||||
* @param folderInfo
|
||||
* @param folderInfo
|
||||
*/
|
||||
public static async register(folderInfo: { title: string, path: Uri } | Uri) {
|
||||
let folderName = folderInfo instanceof Uri ? undefined : folderInfo.title;
|
||||
@@ -119,7 +119,7 @@ export class Folders {
|
||||
|
||||
if (!folderName) {
|
||||
folderName = await window.showInputBox({
|
||||
title: `Register folder`,
|
||||
title: `Register folder`,
|
||||
prompt: `Which name would you like to specify for this folder?`,
|
||||
placeHolder: `Folder name`,
|
||||
value: basename(folder.fsPath),
|
||||
@@ -137,7 +137,7 @@ export class Folders {
|
||||
|
||||
Notifications.info(`Folder registered`);
|
||||
|
||||
Telemetry.send(TelemetryEvent.registerFolder);
|
||||
Telemetry.send(TelemetryEvent.registerFolder);
|
||||
|
||||
SettingsListener.getSettings(true);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Unregister a folder path
|
||||
* @param folder
|
||||
* @param folder
|
||||
*/
|
||||
public static async unregister(folder: Uri) {
|
||||
if (folder && folder.path) {
|
||||
@@ -153,13 +153,13 @@ export class Folders {
|
||||
folders = folders.filter(f => f.path !== folder.fsPath);
|
||||
await Folders.update(folders);
|
||||
|
||||
Telemetry.send(TelemetryEvent.unregisterFolder);
|
||||
Telemetry.send(TelemetryEvent.unregisterFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the static folder its relative path
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
public static getStaticFolderRelativePath(): string | undefined {
|
||||
let staticFolder = Settings.get<string>(SETTING_CONTENT_STATIC_FOLDER);
|
||||
@@ -178,8 +178,8 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Retrieve the folder path
|
||||
* @param folder
|
||||
* @returns
|
||||
* @param folder
|
||||
* @returns
|
||||
*/
|
||||
public static getFolderPath(folder: Uri) {
|
||||
let folderPath = "";
|
||||
@@ -197,12 +197,12 @@ export class Folders {
|
||||
*/
|
||||
public static getWorkspaceFolder(): Uri | undefined {
|
||||
const folders = workspace.workspaceFolders;
|
||||
|
||||
|
||||
if (folders && folders.length === 1) {
|
||||
return folders[0].uri;
|
||||
} else if (folders && folders.length > 1) {
|
||||
let projectFolder = undefined;
|
||||
|
||||
let projectFolder = undefined;
|
||||
|
||||
for (const folder of folders) {
|
||||
if (!projectFolder && existsSync(join(folder.uri.fsPath, Settings.globalFile))) {
|
||||
projectFolder = folder.uri;
|
||||
@@ -223,7 +223,7 @@ export class Folders {
|
||||
|
||||
return projectFolder;
|
||||
}
|
||||
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -247,24 +247,24 @@ export class Folders {
|
||||
const wsFolder = parseWinPath(Folders.getWorkspaceFolder()?.fsPath || "");
|
||||
|
||||
if (folders && folders.length > 0) {
|
||||
let folderInfo: FolderInfo[] = [];
|
||||
|
||||
const folderInfo: FolderInfo[] = [];
|
||||
|
||||
for (const folder of folders) {
|
||||
try {
|
||||
let projectStart = parseWinPath(folder.path).replace(wsFolder, "");
|
||||
|
||||
|
||||
if (projectStart) {
|
||||
projectStart = projectStart.replace(/\\/g, '/');
|
||||
projectStart = projectStart.startsWith('/') ? projectStart.substring(1) : projectStart;
|
||||
|
||||
let files: Uri[] = [];
|
||||
|
||||
|
||||
for (const fileType of (supportedFiles || DEFAULT_FILE_TYPES)) {
|
||||
const filePath = join(projectStart, folder.excludeSubdir ? '/' : '**', `*${fileType.startsWith('.') ? '' : '.'}${fileType}`);
|
||||
const foundFiles = await workspace.findFiles(filePath, '**/node_modules/**');
|
||||
files = [...files, ...foundFiles];
|
||||
}
|
||||
|
||||
|
||||
if (files) {
|
||||
let fileStats: FileInfo[] = [];
|
||||
|
||||
@@ -272,7 +272,7 @@ export class Folders {
|
||||
try {
|
||||
const fileName = basename(file.fsPath);
|
||||
const folderName = dirname(file.fsPath).split(sep).pop();
|
||||
|
||||
|
||||
const stats = await workspace.fs.stat(file);
|
||||
|
||||
fileStats.push({
|
||||
@@ -287,7 +287,7 @@ export class Folders {
|
||||
}
|
||||
|
||||
fileStats = fileStats.sort((a, b) => b.mtime - a.mtime);
|
||||
|
||||
|
||||
if (limit) {
|
||||
fileStats = fileStats.slice(0, limit);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Get the folder settings
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
public static get(): ContentFolder[] {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
@@ -323,11 +323,11 @@ export class Folders {
|
||||
folder.title = basename(folder.path);
|
||||
}
|
||||
|
||||
let folderPath = Folders.absWsFolder(folder, wsFolder);
|
||||
const folderPath = Folders.absWsFolder(folder, wsFolder);
|
||||
if (!existsSync(folderPath)) {
|
||||
Notifications.errorShowOnce(`Folder "${folder.title} (${folder.path})" does not exist. Please remove it from the settings.`, "Remove folder").then(answer => {
|
||||
if (answer === "Remove folder") {
|
||||
let folders = Folders.get();
|
||||
const folders = Folders.get();
|
||||
Folders.update(folders.filter(f => f.path !== folder.path));
|
||||
}
|
||||
});
|
||||
@@ -339,20 +339,20 @@ export class Folders {
|
||||
path: folderPath
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return contentFolders.filter(folder => folder !== null) as ContentFolder[];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the folder settings
|
||||
* @param folders
|
||||
* @param folders
|
||||
*/
|
||||
public static async update(folders: ContentFolder[]) {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
|
||||
let folderDetails = folders.map(folder => ({
|
||||
const folderDetails = folders.map(folder => ({
|
||||
...folder,
|
||||
path: Folders.relWsFolder(folder, wsFolder)
|
||||
path: Folders.relWsFolder(folder, wsFolder)
|
||||
}));
|
||||
|
||||
await Settings.update(SETTING_CONTENT_PAGE_FOLDERS, folderDetails, true);
|
||||
@@ -363,8 +363,8 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Retrieve the absolute file path
|
||||
* @param filePath
|
||||
* @returns
|
||||
* @param filePath
|
||||
* @returns
|
||||
*/
|
||||
public static getAbsFilePath(filePath: string): string {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
@@ -376,9 +376,9 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Generate the absolute URL for the workspace
|
||||
* @param folder
|
||||
* @param wsFolder
|
||||
* @returns
|
||||
* @param folder
|
||||
* @param wsFolder
|
||||
* @returns
|
||||
*/
|
||||
private static absWsFolder(folder: ContentFolder, wsFolder?: Uri) {
|
||||
const isWindows = process.platform === 'win32';
|
||||
@@ -389,9 +389,9 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Generate relative folder path
|
||||
* @param folder
|
||||
* @param wsFolder
|
||||
* @returns
|
||||
* @param folder
|
||||
* @param wsFolder
|
||||
* @returns
|
||||
*/
|
||||
public static relWsFolder(folder: ContentFolder, wsFolder?: Uri) {
|
||||
const isWindows = process.platform === 'win32';
|
||||
@@ -417,7 +417,7 @@ export class Folders {
|
||||
Logger.error(`Something went wrong while searching for folders with pattern "${pattern}": ${(e as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Filter out the workspace folder
|
||||
if (wsFolder) {
|
||||
folders = folders.filter(folder => folder !== wsFolder.fsPath);
|
||||
@@ -429,8 +429,8 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Returns the file prefix for the given folder path
|
||||
* @param folderPath
|
||||
* @returns
|
||||
* @param folderPath
|
||||
* @returns
|
||||
*/
|
||||
public static getFilePrefixByFolderPath(folderPath: string) {
|
||||
const folders = Folders.get();
|
||||
@@ -446,8 +446,8 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Returns the file prefix for the given file path
|
||||
* @param filePath
|
||||
* @returns
|
||||
* @param filePath
|
||||
* @returns
|
||||
*/
|
||||
public static getFilePrefixBeFilePath(filePath: string) {
|
||||
const folders = Folders.get();
|
||||
@@ -474,8 +474,8 @@ export class Folders {
|
||||
|
||||
/**
|
||||
* Retrieve all content folders
|
||||
* @param pattern
|
||||
* @returns
|
||||
* @param pattern
|
||||
* @returns
|
||||
*/
|
||||
private static findFolders(pattern: string): Promise<string[]> {
|
||||
return new Promise(resolve => {
|
||||
|
||||
@@ -16,7 +16,7 @@ export class Project {
|
||||
title:
|
||||
slug:
|
||||
description:
|
||||
author:
|
||||
author:
|
||||
date: 2019-08-22T15:20:28.000Z
|
||||
lastmod: 2019-08-22T15:20:28.000Z
|
||||
draft: true
|
||||
@@ -44,7 +44,7 @@ categories: []
|
||||
} else {
|
||||
Notifications.info("Project initialized successfully.");
|
||||
}
|
||||
|
||||
|
||||
Telemetry.send(TelemetryEvent.initialization);
|
||||
|
||||
// Check if you can find the framework
|
||||
@@ -56,7 +56,8 @@ categories: []
|
||||
}
|
||||
|
||||
SettingsListener.getSettings(true);
|
||||
} catch (err: any) {
|
||||
} catch (error: unknown) {
|
||||
const err = (error as Error)
|
||||
Logger.error(`Project::init: ${err?.message || err}`);
|
||||
Notifications.error(`Sorry, something went wrong - ${err?.message || err}`);
|
||||
}
|
||||
@@ -64,8 +65,8 @@ categories: []
|
||||
|
||||
/**
|
||||
* Creates the templates folder + sample if needed
|
||||
* @param sampleTemplate
|
||||
* @returns
|
||||
* @param sampleTemplate
|
||||
* @returns
|
||||
*/
|
||||
public static async createSampleTemplate(sampleTemplate?: boolean) {
|
||||
const fileType = Settings.get<string>(SETTING_CONTENT_DEFAULT_FILETYPE);
|
||||
@@ -76,7 +77,7 @@ categories: []
|
||||
if (!folder || !templatePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const article = Uri.file(join(templatePath.fsPath, `article.${fileType}`));
|
||||
|
||||
if (!(await existsAsync(templatePath.fsPath))) {
|
||||
@@ -103,4 +104,4 @@ categories: []
|
||||
const templatePath = Uri.file(join(wsFolder.fsPath, folder));
|
||||
return templatePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export class Settings {
|
||||
}
|
||||
|
||||
const type = taxType === "Tag" ? TaxonomyType.Tag : TaxonomyType.Category;
|
||||
let options = SettingsHelper.getTaxonomy(type);
|
||||
const options = SettingsHelper.getTaxonomy(type);
|
||||
|
||||
if (!options || options.length === 0) {
|
||||
Notifications.info(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`);
|
||||
|
||||
@@ -10,12 +10,12 @@ import { commands } from 'vscode';
|
||||
import { Field } from '../models';
|
||||
|
||||
export class StatusListener {
|
||||
|
||||
|
||||
/**
|
||||
* Update the text of the status bar
|
||||
*
|
||||
* @param frontMatterSB
|
||||
* @param collection
|
||||
*
|
||||
* @param frontMatterSB
|
||||
* @param collection
|
||||
*/
|
||||
public static async verify(frontMatterSB: vscode.StatusBarItem, collection: vscode.DiagnosticCollection) {
|
||||
const draftMsg = "in draft";
|
||||
@@ -25,8 +25,8 @@ export class StatusListener {
|
||||
if (!draft || draft.type !== "boolean") {
|
||||
frontMatterSB.hide();
|
||||
}
|
||||
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (editor && ArticleHelper.isSupportedFile()) {
|
||||
try {
|
||||
commands.executeCommand('setContext', CONTEXT.isValidFile, true);
|
||||
@@ -52,11 +52,11 @@ export class StatusListener {
|
||||
const titleLength = Settings.get(SETTING_SEO_TITLE_LENGTH) as number || -1;
|
||||
const descLength = Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number || -1;
|
||||
const fieldName = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
|
||||
|
||||
|
||||
if (article.data.title && titleLength > -1) {
|
||||
SeoHelper.checkLength(editor, collection, article, "title", titleLength);
|
||||
}
|
||||
|
||||
|
||||
if (article.data[fieldName] && descLength > -1) {
|
||||
SeoHelper.checkLength(editor, collection, article, fieldName, descLength);
|
||||
}
|
||||
@@ -64,10 +64,10 @@ export class StatusListener {
|
||||
// Check the required fields
|
||||
StatusListener.verifyRequiredFields(editor, article, collection);
|
||||
}
|
||||
|
||||
|
||||
const panel = ExplorerView.getInstance();
|
||||
if (panel && panel.visible) {
|
||||
DataListener.pushMetadata(article!.data);
|
||||
DataListener.pushMetadata(article?.data);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -88,8 +88,8 @@ export class StatusListener {
|
||||
|
||||
/**
|
||||
* Verify the required fields
|
||||
* @param article
|
||||
* @param collection
|
||||
* @param article
|
||||
* @param collection
|
||||
*/
|
||||
private static verifyRequiredFields(editor: vscode.TextEditor, article: ParsedFrontMatter, collection: vscode.DiagnosticCollection) {
|
||||
// Check for missing fields
|
||||
@@ -110,13 +110,13 @@ export class StatusListener {
|
||||
|
||||
for (const field of fields) {
|
||||
const totalSpaces = level * (typeof editorSpaces === "string" ? parseInt(editorSpaces) : editorSpaces || 2);
|
||||
const crntIdx = StatusListener.findFieldLine(text, txtIdx, totalSpaces, field);
|
||||
const crntIdx = StatusListener.findFieldLine(text, txtIdx, totalSpaces, field);
|
||||
|
||||
if (crntIdx && crntIdx > txtIdx) {
|
||||
txtIdx = crntIdx;
|
||||
fieldName = field.name;
|
||||
}
|
||||
|
||||
|
||||
++level;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ export class StatusListener {
|
||||
requiredDiagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (collection.has(editor.document.uri)) {
|
||||
const otherDiag = collection.get(editor.document.uri) || [];
|
||||
collection.set(editor.document.uri, [...otherDiag, ...requiredDiagnostics]);
|
||||
@@ -153,11 +153,11 @@ export class StatusListener {
|
||||
|
||||
/**
|
||||
* Find the line of the field
|
||||
* @param text
|
||||
* @param startIdx
|
||||
* @param totalSpaces
|
||||
* @param field
|
||||
* @returns
|
||||
* @param text
|
||||
* @param startIdx
|
||||
* @param totalSpaces
|
||||
* @param field
|
||||
* @returns
|
||||
*/
|
||||
private static findFieldLine(text: string, startIdx: number, totalSpaces: number, field: Field): number | undefined {
|
||||
const crntIdx = text.indexOf(field.name, startIdx === -1 ? 0 : startIdx);
|
||||
@@ -179,4 +179,4 @@ export class StatusListener {
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export class Template {
|
||||
await Project.init(false);
|
||||
const templatePath = Project.templatePath();
|
||||
if (templatePath) {
|
||||
let fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data);
|
||||
const fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data);
|
||||
|
||||
const templateFile = path.join(templatePath.fsPath, `${titleValue}.${fileType}`);
|
||||
await writeFileAsync(templateFile, fileContents, { encoding: "utf-8" });
|
||||
@@ -127,7 +127,7 @@ export class Template {
|
||||
}
|
||||
|
||||
const fileExtension = extname(template.fsPath).replace(".", "");
|
||||
let newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension);
|
||||
const newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension);
|
||||
if (!newFilePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
+26
-26
@@ -20,10 +20,10 @@ export class Wysiwyg {
|
||||
|
||||
/**
|
||||
* Registers the markup commands for the WYSIWYG controls
|
||||
* @param subscriptions
|
||||
* @returns
|
||||
* @param subscriptions
|
||||
* @returns
|
||||
*/
|
||||
public static async registerCommands(subscriptions: any) {
|
||||
public static async registerCommands(subscriptions: unknown[]) {
|
||||
|
||||
const wysiwygEnabled = Settings.get(SETTING_CONTENT_WYSIWYG);
|
||||
|
||||
@@ -63,8 +63,8 @@ export class Wysiwyg {
|
||||
]
|
||||
|
||||
const option = await window.showQuickPick([ ...qpItems ], {
|
||||
title: "WYSIWYG Options",
|
||||
placeHolder: "Which type of markup would you like to insert?",
|
||||
title: "WYSIWYG Options",
|
||||
placeHolder: "Which type of markup would you like to insert?",
|
||||
canPickMany: false,
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
@@ -91,8 +91,8 @@ export class Wysiwyg {
|
||||
|
||||
/**
|
||||
* Add the markup to the content
|
||||
* @param type
|
||||
* @returns
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
private static async addMarkup(type: MarkupType) {
|
||||
const editor = window.activeTextEditor;
|
||||
@@ -118,13 +118,13 @@ export class Wysiwyg {
|
||||
// Replace the selection and surround with the markup
|
||||
const selectionText = editor.document.getText(selection);
|
||||
const txt = await this.insertText(markers, type, selectionText);
|
||||
|
||||
|
||||
editor.edit(builder => {
|
||||
builder.replace(selection, txt);
|
||||
});
|
||||
} else {
|
||||
const txt = await this.insertText(markers, type);
|
||||
|
||||
|
||||
// Insert the markers where cursor is located.
|
||||
const markerLength = this.isMarkupWrapping(type) ? txt.length + 1 : markers.length;
|
||||
let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markerLength);
|
||||
@@ -150,8 +150,8 @@ export class Wysiwyg {
|
||||
const linkText = hasTextSelection ? editor.document.getText(selection) : "";
|
||||
|
||||
const link = await window.showInputBox({
|
||||
title: "WYSIWYG Hyperlink",
|
||||
placeHolder: "Enter the URL",
|
||||
title: "WYSIWYG Hyperlink",
|
||||
placeHolder: "Enter the URL",
|
||||
prompt: "Enter the URL",
|
||||
value: linkText,
|
||||
ignoreFocusOut: true
|
||||
@@ -188,12 +188,12 @@ export class Wysiwyg {
|
||||
|
||||
/**
|
||||
* Check if the text will be wrapped
|
||||
* @param type
|
||||
* @returns
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
private static isMarkupWrapping(type: MarkupType) {
|
||||
private static isMarkupWrapping(type: MarkupType) {
|
||||
return (
|
||||
type === MarkupType.blockquote ||
|
||||
type === MarkupType.blockquote ||
|
||||
type === MarkupType.heading ||
|
||||
type === MarkupType.unorderedList ||
|
||||
type === MarkupType.orderedList ||
|
||||
@@ -210,15 +210,15 @@ export class Wysiwyg {
|
||||
if (this.isMarkupWrapping(type)) {
|
||||
if (type === MarkupType.heading) {
|
||||
const headingLvl = await window.showQuickPick([
|
||||
"Heading 1",
|
||||
"Heading 2",
|
||||
"Heading 3",
|
||||
"Heading 4",
|
||||
"Heading 5",
|
||||
"Heading 1",
|
||||
"Heading 2",
|
||||
"Heading 3",
|
||||
"Heading 4",
|
||||
"Heading 5",
|
||||
"Heading 6"
|
||||
], {
|
||||
title: "Heading Level",
|
||||
canPickMany: false,
|
||||
canPickMany: false,
|
||||
placeHolder: "Which heading level do you want to insert?",
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
@@ -247,8 +247,8 @@ export class Wysiwyg {
|
||||
|
||||
/**
|
||||
* Check if linebreak needs to be added
|
||||
* @param type
|
||||
* @returns
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
private static lineBreak(type: MarkupType) {
|
||||
if (type === MarkupType.codeblock) {
|
||||
@@ -259,8 +259,8 @@ export class Wysiwyg {
|
||||
|
||||
/**
|
||||
* Retrieve the type of markers
|
||||
* @param type
|
||||
* @returns
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
private static getMarkers(type: MarkupType) {
|
||||
switch(type) {
|
||||
@@ -288,4 +288,4 @@ export class Wysiwyg {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import * as invariant from 'invariant';
|
||||
import { createAutoField } from 'uniforms';
|
||||
import { PreviewImageField } from '../../panelWebView/components/Fields/PreviewImageField';
|
||||
export { AutoFieldProps } from 'uniforms';
|
||||
|
||||
import BoolField from './BoolField';
|
||||
|
||||
@@ -2,8 +2,9 @@ import { AutoForm } from 'uniforms';
|
||||
|
||||
import ValidatedQuickForm from './ValidatedQuickForm';
|
||||
|
||||
function Auto(parent: any) {
|
||||
class _ extends AutoForm.Auto(parent) {
|
||||
function Auto(parent: unknown) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
class _ extends AutoForm.Auto(parent as any) {
|
||||
static Auto = Auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BaseForm } from 'uniforms';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function Unstyled(parent: any) {
|
||||
class _ extends parent {
|
||||
static Unstyled = Unstyled;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Override, connectField, filterDOMProps } from 'uniforms';
|
||||
|
||||
export type ErrorFieldProps = Override<
|
||||
Omit<HTMLProps<HTMLDivElement>, 'onChange'>,
|
||||
{ error?: any; errorMessage?: string }
|
||||
{ error?: unknown; errorMessage?: string }
|
||||
>;
|
||||
|
||||
function Error({ children, error, errorMessage, ...props }: ErrorFieldProps) {
|
||||
|
||||
@@ -2,18 +2,20 @@ import * as React from 'react';
|
||||
import { HTMLProps, Ref, useEffect } from 'react';
|
||||
import { Override, filterDOMProps, useField } from 'uniforms';
|
||||
|
||||
type ValueType = string | number | readonly string[] | undefined
|
||||
export type HiddenFieldProps = Override<
|
||||
HTMLProps<HTMLInputElement>,
|
||||
{
|
||||
inputRef?: Ref<HTMLInputElement>;
|
||||
name: string;
|
||||
noDOM?: boolean;
|
||||
value?: any;
|
||||
value?: ValueType;
|
||||
}
|
||||
>;
|
||||
|
||||
export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
|
||||
const props = useField(rawProps.name, rawProps, { initialValue: false })[0];
|
||||
const defaultValue = props.value as ValueType ?? ''
|
||||
|
||||
useEffect(() => {
|
||||
if (value !== undefined && value !== props.value) {
|
||||
@@ -28,7 +30,7 @@ export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
|
||||
readOnly={props.readOnly}
|
||||
ref={props.inputRef}
|
||||
type="hidden"
|
||||
value={value ?? props.value ?? ''}
|
||||
value={value ?? defaultValue}
|
||||
{...filterDOMProps(props)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -9,8 +9,11 @@ import {
|
||||
} from 'uniforms';
|
||||
import './ListAddField.css';
|
||||
|
||||
type ParentFieldType = { initialCount?: number; maxCount?: number }
|
||||
type ValueType = string | readonly string[] | undefined
|
||||
|
||||
export type ListAddFieldProps = HTMLFieldProps<
|
||||
unknown,
|
||||
ValueType,
|
||||
HTMLSpanElement,
|
||||
{ initialCount?: number }
|
||||
>;
|
||||
@@ -25,13 +28,14 @@ function ListAdd({
|
||||
}: ListAddFieldProps) {
|
||||
const nameParts = joinName(null, name);
|
||||
const parentName = joinName(nameParts.slice(0, -1));
|
||||
const parent = useField<
|
||||
{ initialCount?: number; maxCount?: number },
|
||||
unknown[]
|
||||
>(parentName, { initialCount }, { absoluteName: true })[0];
|
||||
const parent = {
|
||||
maxCount: 0,
|
||||
value: [] as ValueType[],
|
||||
...useField<ParentFieldType, ValueType[]>(parentName, { initialCount }, { absoluteName: true })[0]
|
||||
};
|
||||
|
||||
const limitNotReached =
|
||||
!disabled && !(parent.maxCount! <= parent.value!.length);
|
||||
!disabled && !(parent.maxCount <= parent.value.length);
|
||||
|
||||
function onAction(event: React.KeyboardEvent | React.MouseEvent) {
|
||||
if (
|
||||
@@ -39,13 +43,14 @@ function ListAdd({
|
||||
!readOnly &&
|
||||
(!('key' in event) || event.key === 'Enter')
|
||||
) {
|
||||
parent.onChange(parent.value!.concat([Object.assign({}, value)]));
|
||||
parent.onChange(parent.value.concat([value]));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className='autoform__list_add_field'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
{...filterDOMProps(props as any)}
|
||||
onClick={onAction}
|
||||
onKeyDown={onAction}
|
||||
|
||||
@@ -15,14 +15,18 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
|
||||
const nameParts = joinName(null, name);
|
||||
const nameIndex = +nameParts[nameParts.length - 1];
|
||||
const parentName = joinName(nameParts.slice(0, -1));
|
||||
const parent = useField<{ minCount?: number }, unknown[]>(
|
||||
parentName,
|
||||
{},
|
||||
{ absoluteName: true },
|
||||
)[0];
|
||||
const parent = {
|
||||
minCount: 0,
|
||||
value: [],
|
||||
...useField<{ minCount?: number }, unknown[]>(
|
||||
parentName,
|
||||
{},
|
||||
{ absoluteName: true },
|
||||
)[0]
|
||||
};
|
||||
|
||||
const limitNotReached =
|
||||
!disabled && !(parent.minCount! >= parent.value!.length);
|
||||
!disabled && !(parent.minCount >= parent.value.length);
|
||||
|
||||
function onAction(
|
||||
event:
|
||||
@@ -34,7 +38,7 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
|
||||
!readOnly &&
|
||||
(!('key' in event) || event.key === 'Enter')
|
||||
) {
|
||||
const value = parent.value!.slice();
|
||||
const value = parent.value.slice();
|
||||
value.splice(nameIndex, 1);
|
||||
parent.onChange(value);
|
||||
}
|
||||
@@ -53,7 +57,7 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
|
||||
<TrashIcon />
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable class-methods-use-this */
|
||||
import { QuickForm } from 'uniforms';
|
||||
|
||||
import AutoField from './AutoField';
|
||||
@@ -5,6 +6,7 @@ import BaseForm from './BaseForm';
|
||||
import ErrorsField from './ErrorsField';
|
||||
import SubmitField from './SubmitField';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function Quick(parent: any) {
|
||||
class _ extends QuickForm.Quick(parent) {
|
||||
static Quick = Quick;
|
||||
|
||||
@@ -24,7 +24,7 @@ export type SelectFieldProps = HTMLFieldProps<
|
||||
>;
|
||||
|
||||
function Select({
|
||||
allowedValues,
|
||||
allowedValues = [],
|
||||
checkboxes,
|
||||
disabled,
|
||||
fieldType,
|
||||
@@ -38,20 +38,20 @@ function Select({
|
||||
required,
|
||||
disableItem,
|
||||
transform,
|
||||
value,
|
||||
value = [],
|
||||
...props
|
||||
}: SelectFieldProps) {
|
||||
const multiple = fieldType === Array;
|
||||
return (
|
||||
<div className='autoform__select_field' {...filterDOMProps(props)}>
|
||||
<LabelField label={label} id={id} required={required} />
|
||||
|
||||
|
||||
{checkboxes ? (
|
||||
allowedValues!.map(item => (
|
||||
allowedValues.map(item => (
|
||||
<div key={item}>
|
||||
<input
|
||||
checked={
|
||||
fieldType === Array ? value!.includes(item) : value === item
|
||||
fieldType === Array ? value.includes(item) : value === item
|
||||
}
|
||||
disabled={disableItem?.(item) ?? disabled}
|
||||
id={`${id}-${escape(item)}`}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ValidatedForm } from 'uniforms';
|
||||
|
||||
import BaseForm from './BaseForm';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function Validated(parent: any) {
|
||||
class _ extends ValidatedForm.Validated(parent) {
|
||||
static Validated = Validated;
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-string-throw": true,
|
||||
"no-unused-expression": true,
|
||||
"no-duplicate-variable": true,
|
||||
"curly": true,
|
||||
"class-name": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": true
|
||||
},
|
||||
"defaultSeverity": "warning"
|
||||
}
|
||||
Reference in New Issue
Block a user