From df40349bd095ae7d9b175cbe8f17f0adfbcca5a5 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 20 May 2023 20:26:33 +0800 Subject: [PATCH 001/158] remove pnpm-lock, fix #4 --- .gitignore | 1 + pnpm-lock.yaml | 955 ------------------------------------------------- 2 files changed, 1 insertion(+), 955 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index 6d641ec..aa00657 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea .vscode .DS_Store +pnpm-lock.yaml package.zip node_modules dev diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index a0021e2..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,955 +0,0 @@ -lockfileVersion: '6.0' - -devDependencies: - '@sveltejs/vite-plugin-svelte': - specifier: ^2.0.3 - version: 2.0.3(svelte@3.59.1)(vite@4.3.7) - '@tsconfig/svelte': - specifier: ^4.0.1 - version: 4.0.1 - '@types/node': - specifier: ^20.2.0 - version: 20.2.0 - fast-glob: - specifier: ^3.2.12 - version: 3.2.12 - glob: - specifier: ^7.2.3 - version: 7.2.3 - minimist: - specifier: ^1.2.8 - version: 1.2.8 - rollup-plugin-livereload: - specifier: ^2.0.5 - version: 2.0.5 - sass: - specifier: ^1.62.1 - version: 1.62.1 - siyuan: - specifier: ^0.7.1 - version: 0.7.1 - svelte: - specifier: ^3.57.0 - version: 3.59.1 - ts-node: - specifier: ^10.9.1 - version: 10.9.1(@types/node@20.2.0)(typescript@5.0.4) - typescript: - specifier: ^5.0.4 - version: 5.0.4 - vite: - specifier: ^4.3.7 - version: 4.3.7(@types/node@20.2.0)(sass@1.62.1) - vite-plugin-static-copy: - specifier: ^0.15.0 - version: 0.15.0(vite@4.3.7) - vite-plugin-zip-pack: - specifier: ^1.0.5 - version: 1.0.5(vite@4.3.7) - -packages: - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@esbuild/android-arm64@0.17.19: - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.17.19: - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.17.19: - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.17.19: - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.17.19: - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.17.19: - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.17.19: - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.17.19: - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.17.19: - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.17.19: - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.17.19: - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.17.19: - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.17.19: - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.17.19: - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.17.19: - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.17.19: - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.17.19: - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.17.19: - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.17.19: - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.17.19: - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.17.19: - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.17.19: - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - dev: true - - /@sveltejs/vite-plugin-svelte@2.0.3(svelte@3.59.1)(vite@4.3.7): - resolution: {integrity: sha512-o+cguBFdwIGtRbNkYOyqTM7KvRUffxh5bfK4oJsWKG2obu+v/cbpT03tJrGl58C7tRXo/aEC0/axN5FVHBj0nA==} - engines: {node: ^14.18.0 || >= 16} - peerDependencies: - svelte: ^3.54.0 - vite: ^4.0.0 - dependencies: - debug: 4.3.4 - deepmerge: 4.3.1 - kleur: 4.1.5 - magic-string: 0.29.0 - svelte: 3.59.1 - svelte-hmr: 0.15.1(svelte@3.59.1) - vite: 4.3.7(@types/node@20.2.0)(sass@1.62.1) - vitefu: 0.2.4(vite@4.3.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - - /@tsconfig/svelte@4.0.1: - resolution: {integrity: sha512-B+XlGpmuAQzJqDoBATNCvEPqQg0HkO7S8pM14QDI5NsmtymzRexQ1N+nX2H6RTtFbuFgaZD4I8AAi8voGg0GLg==} - dev: true - - /@types/node@20.2.0: - resolution: {integrity: sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==} - dev: true - - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - dev: true - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - dev: true - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - dev: true - - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - dev: true - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - dev: true - - /immutable@4.3.0: - resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==} - dev: true - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - dependencies: - binary-extensions: 2.2.0 - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - - /jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.11 - dev: true - - /jszip@3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.8 - setimmediate: 1.0.5 - dev: true - - /kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: true - - /lie@3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - dependencies: - immediate: 3.0.6 - dev: true - - /livereload-js@3.4.1: - resolution: {integrity: sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==} - dev: true - - /livereload@0.9.3: - resolution: {integrity: sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==} - engines: {node: '>=8.0.0'} - hasBin: true - dependencies: - chokidar: 3.5.3 - livereload-js: 3.4.1 - opts: 2.0.2 - ws: 7.5.9 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: true - - /magic-string@0.29.0: - resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /opts@2.0.2: - resolution: {integrity: sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==} - dev: true - - /pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: true - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /postcss@8.4.23: - resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: true - - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: true - - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - dev: true - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - /rollup-plugin-livereload@2.0.5: - resolution: {integrity: sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==} - engines: {node: '>=8.3'} - dependencies: - livereload: 0.9.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: true - - /rollup@3.21.7: - resolution: {integrity: sha512-KXPaEuR8FfUoK2uHwNjxTmJ18ApyvD6zJpYv9FOJSqLStmt6xOY84l1IjK2dSolQmoXknrhEFRaPRgOPdqCT5w==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - - /sass@1.62.1: - resolution: {integrity: sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==} - engines: {node: '>=14.0.0'} - hasBin: true - dependencies: - chokidar: 3.5.3 - immutable: 4.3.0 - source-map-js: 1.0.2 - dev: true - - /setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: true - - /siyuan@0.7.1: - resolution: {integrity: sha512-Q7OZqpJ8h+axLDkn6afoAdKD6mHPAona/jsoUpf8UgFqHuOscNS6ub8RudhTCPKppDnQzBy5o35xhlecxnrbjQ==} - dev: true - - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - dev: true - - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /svelte-hmr@0.15.1(svelte@3.59.1): - resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} - engines: {node: ^12.20 || ^14.13.1 || >= 16} - peerDependencies: - svelte: '>=3.19.0' - dependencies: - svelte: 3.59.1 - dev: true - - /svelte@3.59.1: - resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==} - engines: {node: '>= 8'} - dev: true - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /ts-node@10.9.1(@types/node@20.2.0)(typescript@5.0.4): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.2.0 - acorn: 8.8.2 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.0.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} - hasBin: true - dev: true - - /universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /vite-plugin-static-copy@0.15.0(vite@4.3.7): - resolution: {integrity: sha512-Ww+/Ug9guV45oIfIi/lA2z8v3K+lLHV9zCJqTVO4FTdqrJoZBj68VgGBSH1fi0N4q/EHW32RsL3ympi4Wlsq5w==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 - dependencies: - chokidar: 3.5.3 - fast-glob: 3.2.12 - fs-extra: 11.1.1 - picocolors: 1.0.0 - vite: 4.3.7(@types/node@20.2.0)(sass@1.62.1) - dev: true - - /vite-plugin-zip-pack@1.0.5(vite@4.3.7): - resolution: {integrity: sha512-AY6F3GJL///Dc3d7fQhalJvWb08e0oIATVqHLwDAiK2/S1NCxbAFXfT4m2V+LtJRjHrRkHa0zbZvAI6/lb6vTQ==} - peerDependencies: - vite: '>=2.x' - dependencies: - jszip: 3.10.1 - vite: 4.3.7(@types/node@20.2.0)(sass@1.62.1) - dev: true - - /vite@4.3.7(@types/node@20.2.0)(sass@1.62.1): - resolution: {integrity: sha512-MTIFpbIm9v7Hh5b0wSBgkcWzSBz7SAa6K/cBTwS4kUiQJfQLFlZZRJRQgqunCVzhTPCk674tW+0Qaqh3Q00dBg==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 20.2.0 - esbuild: 0.17.19 - postcss: 8.4.23 - rollup: 3.21.7 - sass: 1.62.1 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /vitefu@0.2.4(vite@4.3.7): - resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 - peerDependenciesMeta: - vite: - optional: true - dependencies: - vite: 4.3.7(@types/node@20.2.0)(sass@1.62.1) - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /ws@7.5.9: - resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true From 14f3cf2f69e705105c1325062c8eecf1c32f6f44 Mon Sep 17 00:00:00 2001 From: Frostime Date: Sun, 21 May 2023 00:33:31 +0800 Subject: [PATCH 002/158] Update siyuan.d.ts --- src/siyuan.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/siyuan.d.ts b/src/siyuan.d.ts index fbca339..6616c55 100644 --- a/src/siyuan.d.ts +++ b/src/siyuan.d.ts @@ -18,7 +18,7 @@ declare module "siyuan" { sid: string } - declare interface IPluginDockTab { + interface IPluginDockTab { position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight", size: { width: number, height: number }, icon: string, @@ -182,4 +182,4 @@ declare module "siyuan" { close(): void; } -} \ No newline at end of file +} From 94469c4d5e16180089344a5b0e8bc75407d1932c Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 21:22:32 +0800 Subject: [PATCH 003/158] fix: api.getFile --- src/api.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api.ts b/src/api.ts index e8a007a..0fcd147 100644 --- a/src/api.ts +++ b/src/api.ts @@ -308,7 +308,8 @@ export async function getFile(path: string): Promise { path: path } let url = '/api/file/getFile'; - return request(url, data); + let file = await fetchSyncPost(url, data); + return file; } export async function putFile(path: string, isDir: boolean, file: any) { From aa19c762353f2a65a92106346e285f68820d1ea5 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 21:33:58 +0800 Subject: [PATCH 004/158] fix getFile with err --- src/api.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/api.ts b/src/api.ts index 0fcd147..0fa2013 100644 --- a/src/api.ts +++ b/src/api.ts @@ -308,8 +308,12 @@ export async function getFile(path: string): Promise { path: path } let url = '/api/file/getFile'; - let file = await fetchSyncPost(url, data); - return file; + try { + let file = await fetchSyncPost(url, data); + return file; + } catch (error_msg) { + return null; + } } export async function putFile(path: string, isDir: boolean, file: any) { From 831ba76c7ca170d03b20bdca80553ca457dbf91a Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 21:34:17 +0800 Subject: [PATCH 005/158] dev --- scripts/make_dev_link.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 893d9f9..003edef 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -11,7 +11,28 @@ const targetDir = ''; //******************************************************************************************** +async function getSiYuanDir() { + let url = 'http://127.0.0.1:6806/api/system/getConf'; + let header = { + // "Authorization": `Token ${token}`, + "Content-Type": "application/json", + } + try { + let conf = await fetch(url, { + method: 'POST', + headers: header + }); + console.log(conf); + } catch (e) { + console.log('Failed! Please make sure SiYuan is running'); + process.exit(1); + } +} +if (targetDir === '') { + await getSiYuanDir(); + process.exit(0); +} //Check if (!fs.existsSync(targetDir)) { From c29ea972404957ec24b76e50585be0915ab17018 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 21:34:17 +0800 Subject: [PATCH 006/158] commit --- scripts/make_dev_link.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 003edef..85131a2 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -11,10 +11,10 @@ const targetDir = ''; //******************************************************************************************** -async function getSiYuanDir() { +async function getSiYuanDir(token) { let url = 'http://127.0.0.1:6806/api/system/getConf'; let header = { - // "Authorization": `Token ${token}`, + "Authorization": `Token ${token}`, "Content-Type": "application/json", } try { @@ -24,13 +24,13 @@ async function getSiYuanDir() { }); console.log(conf); } catch (e) { - console.log('Failed! Please make sure SiYuan is running'); + console.log(e); process.exit(1); } } if (targetDir === '') { - await getSiYuanDir(); + await getSiYuanDir('es7zy9zewgibc6dt'); process.exit(0); } From 9007a64178c1fca7b7c334c8a4ff11286f43a209 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 22:20:40 +0800 Subject: [PATCH 007/158] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=AF=BB=E5=8F=96=20?= =?UTF-8?q?workspace=20=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/make_dev_link.js | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 85131a2..c813a56 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -10,34 +10,43 @@ const targetDir = ''; // const targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; //******************************************************************************************** +const log = console.log; -async function getSiYuanDir(token) { - let url = 'http://127.0.0.1:6806/api/system/getConf'; +async function getSiYuanDir() { + let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; let header = { - "Authorization": `Token ${token}`, + // "Authorization": `Token ${token}`, "Content-Type": "application/json", } + let conf = {}; try { - let conf = await fetch(url, { + let response = await fetch(url, { method: 'POST', headers: header }); - console.log(conf); + if (response.ok) { + conf = await response.json(); + } else { + log(`HTTP-Error: ${response.status}`); + process.exit(1); + } } catch (e) { - console.log(e); + log("Error:", e); process.exit(1); } + return conf.data; } if (targetDir === '') { - await getSiYuanDir('es7zy9zewgibc6dt'); + let res = await getSiYuanDir(); + log(res); process.exit(0); } //Check if (!fs.existsSync(targetDir)) { - console.log(`Failed! plugin directory not exists: "${targetDir}"`); - console.log(`Please set the plugin directory in scripts/make_dev_link.js`); + log(`Failed! plugin directory not exists: "${targetDir}"`); + log(`Please set the plugin directory in scripts/make_dev_link.js`); process.exit(1); } @@ -52,7 +61,7 @@ if (!fs.existsSync('./plugin.json')) { const plugin = JSON.parse(fs.readFileSync('./plugin.json', 'utf8')); const name = plugin?.name; if (!name || name === '') { - console.log('Failed! Please set plugin name in plugin.json'); + log('Failed! Please set plugin name in plugin.json'); process.exit(1); } @@ -66,11 +75,11 @@ if (!fs.existsSync(devDir)) { const targetPath = `${targetDir}/${name}`; //如果已经存在,就退出 if (fs.existsSync(targetPath)) { - console.log('Failed! Target directory already exists'); + log('Failed! Target directory already exists'); process.exit(1); } //创建软链接 fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); -console.log(`Done! Created symlink ${targetPath}`); +log(`Done! Created symlink ${targetPath}`); From c99faadc2ae73c5f4fdd3ab7d847f90326793138 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 22:39:14 +0800 Subject: [PATCH 008/158] auto detect workspace --- package.json | 2 +- scripts/make_dev_link.js | 53 +++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 2f98a3b..faf7e2d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "author": "", "license": "GPL-3.0", "scripts": { - "make-link": "node ./scripts/make_dev_link.js", + "make-link": "node --no-warnings ./scripts/make_dev_link.js", "dev": "vite build --watch", "build": "vite build" }, diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index c813a56..5c8ba19 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -1,11 +1,12 @@ import fs from 'fs'; +import readline from 'node:readline'; //************************************ Write you dir here ************************************ //Please write the "workspace/data/plugins" directory here //请在这里填写你的 "workspace/data/plugins" 目录 -const targetDir = ''; +let targetDir = ''; //Like this // const targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; //******************************************************************************************** @@ -28,19 +29,50 @@ async function getSiYuanDir() { conf = await response.json(); } else { log(`HTTP-Error: ${response.status}`); - process.exit(1); + return null; } } catch (e) { log("Error:", e); - process.exit(1); + return null; } return conf.data; } +async function chooseTarget(workspaces) { + let count = workspaces.length; + log(`Got ${count} SiYuan ${count > 1 ? 'workspaces' : 'workspace'}`) + for (let i = 0; i < workspaces.length; i++) { + log(`[${i}] ${workspaces[i].path}`); + } + + if (count == 1) { + return `${workspaces[0].path}/data/plugins`; + } else { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + let index = await new Promise((resolve, reject) => { + rl.question(`Please select a workspace[0-${count-1}]: `, (answer) => { + resolve(answer); + }); + }); + rl.close(); + return `${workspaces[index].path}/data/plugins`; + } +} + if (targetDir === '') { + log('"targetDir" is empty, try to get SiYuan directory automatically....') let res = await getSiYuanDir(); - log(res); - process.exit(0); + + if (res === null) { + log('Failed! Please set the plugin directory in scripts/make_dev_link.js'); + process.exit(1); + } + + targetDir = await chooseTarget(res); + log(`Got target directory: ${targetDir}`); } //Check @@ -75,11 +107,10 @@ if (!fs.existsSync(devDir)) { const targetPath = `${targetDir}/${name}`; //如果已经存在,就退出 if (fs.existsSync(targetPath)) { - log('Failed! Target directory already exists'); - process.exit(1); + log(`Failed! Target directory ${targetPath} already exists`); +} else { + //创建软链接 + fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); + log(`Done! Created symlink ${targetPath}`); } -//创建软链接 -fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); -log(`Done! Created symlink ${targetPath}`); - From b3088200b1c3baa951e7ae694049a40b9b0ec6c3 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 22:50:03 +0800 Subject: [PATCH 009/158] update readme --- README.md | 20 ++++++++++++++++++-- README_zh_CN.md | 18 +++++++++++++++++- package.json | 2 +- plugin.json | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d3edd63..9fcfcaa 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,27 @@ - Notice: we **don't recommand** you to place the folder under your `{workspace}/data/plugins/` folder. 3. Install NodeJS and pnpm, then run pnpm i in the command line under your repo folder -4. Create development symbolic links +4. **Auto create development symbolic links** + - Make sure that SiYuan is running + - Run `pnpm run make-link`, the script will detec all the siyuan workspace, please select + ```bash + >>> pnpm run make-link + > plugin-sample-vite-svelte@0.0.3 make-link H:\SrcCode\开源项目\plugin-sample-vite-svelte + > node --no-warnings ./scripts/make_dev_link.js + + "targetDir" is empty, try to get SiYuan directory automatically.... + Got 2 SiYuan workspaces + [0] H:\Media\SiYuan + [1] H:\临时文件夹\SiYuanDevSpace + Please select a workspace[0-1]: 0 + Got target directory: H:\Media\SiYuan/data/plugins + Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte + ``` +4. **Manually create development symbolic links** - Open `./scripts/make_dev_link.js` file, set `targetDir` to your SiYuan plugin directory `/data/plugins` - Run `pnpm run make-link`, succeed if following message is shown: ```bash - ❯❯❯ pnpm run make-link + >>> pnpm run make-link > plugin-sample-vite-svelte@0.0.1 make-link H:\SrcCode\plugin-sample-vite-svelte > node ./scripts/make_dev_link.js diff --git a/README_zh_CN.md b/README_zh_CN.md index dbcf283..5e40813 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -13,7 +13,23 @@ 2. 将你的库克隆到本地开发文件夹中 * 注意: 同 `plugin-sample` 不同, 本样例并不推荐直接把代码下载到 `{workspace}/data/plugins/` 3. 安装 [NodeJS](https://nodejs.org/en/download) 和 [pnpm](https://pnpm.io/installation),然后在开发文件夹下执行 `pnpm i` 安装所需要的依赖 -4. 创建开发需要的符号链接 +4. **自动创建符号链接** + - 打开思源笔记, 确保思源内核正在运行 + - 运行 `pnpm run make-link`, 脚本会自动检测所有思源的工作空间, 请在命令行中手动输入序号以选择工作空间 + ```bash + >>> pnpm run make-link + > plugin-sample-vite-svelte@0.0.3 make-link H:\SrcCode\开源项目\plugin-sample-vite-svelte + > node --no-warnings ./scripts/make_dev_link.js + + "targetDir" is empty, try to get SiYuan directory automatically.... + Got 2 SiYuan workspaces + [0] H:\Media\SiYuan + [1] H:\临时文件夹\SiYuanDevSpace + Please select a workspace[0-1]: 0 + Got target directory: H:\Media\SiYuan/data/plugins + Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte + ``` +4. **手动创建符号链接** - 打开 `./scripts/make_dev_link.js` 文件,更改 `targetDir` 为思源的插件目录 `/data/plugins` - 运行 `pnpm run make-link` 命令, 如果看到类似以下的消息,说明创建成功: ```bash diff --git a/package.json b/package.json index faf7e2d..b3ff9ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.0.2", + "version": "0.0.3", "type": "module", "description": "", "repository": "", diff --git a/plugin.json b/plugin.json index 60a4ede..f625d9f 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.0.2", + "version": "0.0.3", "displayName": { "en_US": "Plugin sample with vite and svelte", "zh_CN": "插件样例 vite + svelte 版" From 3853269e8243250aa0862f29b51f61427ae7525a Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 22 May 2023 22:53:25 +0800 Subject: [PATCH 010/158] log --- scripts/make_dev_link.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 5c8ba19..f00a456 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -33,6 +33,7 @@ async function getSiYuanDir() { } } catch (e) { log("Error:", e); + log("Please make sure SiYuan is running!!!"); return null; } return conf.data; @@ -67,7 +68,7 @@ if (targetDir === '') { let res = await getSiYuanDir(); if (res === null) { - log('Failed! Please set the plugin directory in scripts/make_dev_link.js'); + log('Failed! You can set the plugin directory in scripts/make_dev_link.js and try again'); process.exit(1); } From 8b19031d08f1ff155cdb47fb52155fd78294cb46 Mon Sep 17 00:00:00 2001 From: Frostime Date: Tue, 23 May 2023 00:20:42 +0800 Subject: [PATCH 011/158] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fcfcaa..8cd5876 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ 3. Install NodeJS and pnpm, then run pnpm i in the command line under your repo folder 4. **Auto create development symbolic links** - Make sure that SiYuan is running - - Run `pnpm run make-link`, the script will detec all the siyuan workspace, please select + - Run `pnpm run make-link`, the script will detect all the siyuan workspace, please select the targe workspace and the script will automatically create the symbolic link under the `{workspace}/data/plugins/` folder ```bash >>> pnpm run make-link > plugin-sample-vite-svelte@0.0.3 make-link H:\SrcCode\开源项目\plugin-sample-vite-svelte From b42d86b17a03cf8dfb8c94f4ba349f748c4bbe60 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 23 May 2023 15:02:56 +0800 Subject: [PATCH 012/158] add b3-typography to render plain text content --- src/hello.svelte | 7 +++++-- src/libs/b3-list.svelte | 8 -------- src/libs/b3-typography.svelte | 3 +++ 3 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 src/libs/b3-list.svelte create mode 100644 src/libs/b3-typography.svelte diff --git a/src/hello.svelte b/src/hello.svelte index b619b3f..749d62c 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -6,6 +6,8 @@ import { onDestroy, onMount } from "svelte"; import { version } from "./api"; import { showMessage } from "siyuan"; + import Typo from "./libs/b3-typography.svelte"; + export let name: string; export let i18n: any; @@ -43,9 +45,10 @@ -
+ +

Wellcome to plugin sample with vite & svelte

{@html i18n.makesure}

-
+ diff --git a/src/libs/b3-list.svelte b/src/libs/b3-list.svelte deleted file mode 100644 index edbab36..0000000 --- a/src/libs/b3-list.svelte +++ /dev/null @@ -1,8 +0,0 @@ -
    -
  • - - - - -
  • -
diff --git a/src/libs/b3-typography.svelte b/src/libs/b3-typography.svelte new file mode 100644 index 0000000..60227cd --- /dev/null +++ b/src/libs/b3-typography.svelte @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file From d536f9b25da94c71850b4399b4d956c936a5c135 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 23 May 2023 15:09:41 +0800 Subject: [PATCH 013/158] remove copyrigth --- src/hello.svelte | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hello.svelte b/src/hello.svelte index 749d62c..40d97b7 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -1,7 +1,3 @@ - - -
-
- - - -
-
- {text} -
-
diff --git a/src/index.ts b/src/index.ts index 5e566c4..e2f27cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,7 @@ -import { Plugin, showMessage, confirm, Dialog, Menu, isMobile, openTab } from "siyuan"; +import { Plugin, showMessage, confirm, Dialog, Menu, isMobile, openTab, adaptHotkey } from "siyuan"; import "./index.scss"; import HelloExample from "./hello.svelte"; -import DockExample from "./dock.svelte"; import SettingPannel from "./libs/setting-panel.svelte"; const STORAGE_NAME = "menu-config"; @@ -48,7 +47,7 @@ export default class SamplePlugin extends Plugin { this.addDock({ config: { position: "LeftBottom", - size: { width: 200, height: 0 }, + size: {width: 200, height: 0}, icon: "iconEmoji", title: "Custom Dock", }, @@ -57,16 +56,22 @@ export default class SamplePlugin extends Plugin { }, type: DOCK_TYPE, init() { - this.component = new DockExample({ - target: this.element, - props: { - text: this.data.text, - } - }); + this.element.innerHTML = `
+
+ + + +
+
+ ${this.data.text} +
+
`; }, destroy() { console.log("destroy dock:", DOCK_TYPE); - this.component.$destroy(); } }); From 3cf80f7d2d25be369c33df084e95e97cde393410 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 26 May 2023 17:47:09 +0800 Subject: [PATCH 021/158] readme --- README.md | 3 +++ README_zh_CN.md | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 52b1004..bb51cad 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ [中文版](./README_zh_CN.md) +> Come up with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6). + + 1. Using vite for packaging 2. Use symbolic linking instead of putting the project into the plugins directory program development 3. Built-in support for the svelte framework diff --git a/README_zh_CN.md b/README_zh_CN.md index 81ec5b0..86a27a9 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -1,7 +1,11 @@ -[English](./README.md) # 使用 vite + svelte 的思源笔记插件示例 +[English](./README.md) + + +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6) 基本保持一致。 + 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 3. 内置对 svelte 框架的支持 From 876ee9c62fbb3cd7a3199be9079d506d9b9feae9 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 26 May 2023 17:48:39 +0800 Subject: [PATCH 022/158] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb51cad..6bee855 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Come up with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6). +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6). 1. Using vite for packaging From 439c2134b6f4bd41ab51db1da6a41b4c7413a04c Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 May 2023 21:39:25 +0800 Subject: [PATCH 023/158] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README=EF=BC=8C?= =?UTF-8?q?=E6=8C=87=E6=98=8E=20node=20=E7=89=88=E6=9C=AC=E5=9C=A8=2018=20?= =?UTF-8?q?=E4=BB=A5=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++-- README_zh_CN.md | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6bee855..352ada8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - Notice: we **don't recommand** you to place the folder under your `{workspace}/data/plugins/` folder. 3. Install NodeJS and pnpm, then run pnpm i in the command line under your repo folder -4. **Auto create development symbolic links** +4. **Auto create development symbolic links** (requires nodejs over version 18) - Make sure that SiYuan is running - Run `pnpm run make-link`, the script will detect all the siyuan workspace, please select the targe workspace and the script will automatically create the symbolic link under the `{workspace}/data/plugins/` folder ```bash @@ -36,7 +36,7 @@ Got target directory: H:\Media\SiYuan/data/plugins Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte ``` -4. **Manually create development symbolic links** +4. **Manually create development symbolic links** (requires nodejs over version 18) - Open `./scripts/make_dev_link.js` file, set `targetDir` to your SiYuan plugin directory `/data/plugins` - Run `pnpm run make-link`, succeed if following message is shown: ```bash @@ -50,6 +50,8 @@ 5. Execute pnpm run dev for real-time compilation 6. Open SiYuan marketplace and enable plugin in downloaded tab +> Notice: as the `make-link` script rely on the `fetch` function, please **ensure that at least version v18 of nodejs is installed** if you want to use make-link script. + ## I18n In terms of internationalization, our main consideration is to support multiple languages. Specifically, we need to diff --git a/README_zh_CN.md b/README_zh_CN.md index 86a27a9..f1b02db 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -17,7 +17,7 @@ 2. 将你的库克隆到本地开发文件夹中 * 注意: 同 `plugin-sample` 不同, 本样例并不推荐直接把代码下载到 `{workspace}/data/plugins/` 3. 安装 [NodeJS](https://nodejs.org/en/download) 和 [pnpm](https://pnpm.io/installation),然后在开发文件夹下执行 `pnpm i` 安装所需要的依赖 -4. **自动创建符号链接** +3. **自动创建符号链接** (需要 nodejs 版本在 18 以上) - 打开思源笔记, 确保思源内核正在运行 - 运行 `pnpm run make-link`, 脚本会自动检测所有思源的工作空间, 请在命令行中手动输入序号以选择工作空间 ```bash @@ -33,7 +33,7 @@ Got target directory: H:\Media\SiYuan/data/plugins Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte ``` -4. **手动创建符号链接** +4. **手动创建符号链接** (需要 nodejs 版本在 18 以上) - 打开 `./scripts/make_dev_link.js` 文件,更改 `targetDir` 为思源的插件目录 `/data/plugins` - 运行 `pnpm run make-link` 命令, 如果看到类似以下的消息,说明创建成功: ```bash @@ -47,6 +47,9 @@ 6. 在思源中打开集市并在下载选项卡中启用插件 +> 注意由于使用的 make-link 脚本依赖于 `fetch`,所以如果想要使用 make-link **请保证至少安装 v18 版本的 nodejs** + + ## 国际化 国际化方面我们主要考虑的是支持多语言,具体需要完成以下工作: From 78d576a19eae37c3c9fdec160b44c08281ff3a87 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 14:40:39 +0800 Subject: [PATCH 024/158] chore: update release.yml --- .github/workflows/release.yml | 100 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a6b0329..7bd6c4e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,62 +1,62 @@ name: Create Release on Tag Push on: - push: - tags: - - "v*" + push: + tags: + - "v*" jobs: - build: - runs-on: ubuntu-latest - steps: - # Checkout - - name: Checkout - uses: actions/checkout@v3 + build: + runs-on: ubuntu-latest + steps: + # Checkout + - name: Checkout + uses: actions/checkout@v3 - # Install Node.js - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - registry-url: "https://registry.npmjs.org" + # Install Node.js + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: "https://registry.npmjs.org" - # Install pnpm - - name: Install pnpm - uses: pnpm/action-setup@v2 - id: pnpm-install - with: - version: 8 - run_install: false + # Install pnpm + - name: Install pnpm + uses: pnpm/action-setup@v2 + id: pnpm-install + with: + version: 8 + run_install: false - # Get pnpm store directory - - name: Get pnpm store directory - id: pnpm-cache - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + # Get pnpm store directory + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - # Setup pnpm cache - - name: Setup pnpm cache - uses: actions/cache@v3 - with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- + # Setup pnpm cache + - name: Setup pnpm cache + uses: actions/cache@v3 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- - # Install dependencies - - name: Install dependencies - run: pnpm install + # Install dependencies + - name: Install dependencies + run: pnpm install - # Build for production, 这一步会生成一个 package.zip - - name: Build for production - run: pnpm build + # Build for production, 这一步会生成一个 package.zip + - name: Build for production + run: pnpm build - - name: Release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - artifactErrorsFailBuild: true - artifacts: 'package.zip' - token: ${{ secrets.GITHUB_TOKEN }} - prerelease: true + - name: Release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifactErrorsFailBuild: true + artifacts: "package.zip" + token: ${{ secrets.GITHUB_TOKEN }} + prerelease: true From bfb5887dd338b870c67df13a8a6a1f653778db00 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 14:41:48 +0800 Subject: [PATCH 025/158] chore: update siyuan to npm package latest --- package.json | 2 +- src/siyuan.d.ts | 314 ------------------------------------------------ 2 files changed, 1 insertion(+), 315 deletions(-) delete mode 100644 src/siyuan.d.ts diff --git a/package.json b/package.json index 20ff17f..c8f9d98 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "^0.7.1", + "siyuan": "latest", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/src/siyuan.d.ts b/src/siyuan.d.ts deleted file mode 100644 index 1d5b0a9..0000000 --- a/src/siyuan.d.ts +++ /dev/null @@ -1,314 +0,0 @@ -declare module "siyuan" { - type TEventBus = "ws-main" | "click-blockicon" | "click-editorcontent" | "click-pdf" | "click-editortitleicon" - - declare global { - interface Window { - Lute: Lute - } - } - - - interface IObject { - [key: string]: string; - } - - interface ILuteNode { - TokensStr: () => string; - __internal_object__: { - Parent: { - Type: number, - }, - HeadingLevel: string, - }; - } - - interface IWebSocketData { - cmd: string - callback?: string - data: any - msg: string - code: number - sid: string - } - - interface IPluginDockTab { - position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight", - size: { width: number, height: number }, - icon: string, - hotkey?: string, - title: string, - } - - interface IMenuItemOption { - label?: string, - click?: (element: HTMLElement) => void, - type?: "separator" | "submenu" | "readonly", - accelerator?: string, - action?: string, - id?: string, - submenu?: IMenuItemOption[] - disabled?: boolean - icon?: string - iconHTML?: string - current?: boolean - bind?: (element: HTMLElement) => void - } - - export function fetchPost(url: string, data?: any, cb?: (response: IWebSocketData) => void, headers?: IObject): void; - - export function fetchSyncPost(url: string, data?: any): Promise; - - export function fetchGet(url: string, cb: (response: IWebSocketData) => void): void; - - export function openTab(options: { - custom?: { - title: string, - icon: string, - data?: any - fn?: () => any, - } // card 和自定义页签 必填 - position?: "right" | "bottom", - keepCursor?: boolean // 是否跳转到新 tab 上 - removeCurrentTab?: boolean // 在当前页签打开时需移除原有页签 - afterOpen?: () => void // 打开后回调 - }): void - - export function isMobile(): boolean; - - export function adaptHotkey(hotkey: string): string; - - export function confirm(title: string, text: string, confirmCB?: () => void, cancelCB?: () => void): void; - - /** - * @param timeout - ms. 0: manual close;-1: always show; 6000: default - * @param {string} [type=info] - */ - export function showMessage(text: string, timeout?: number, type?: "info" | "error", id?: string): void; - - export class App { - plugins: Plugin[]; - } - - export abstract class Plugin { - eventBus: EventBus; - i18n: IObject; - data: any; - name: string; - - constructor(options: { - app: App, - id: string, - name: string, - i18n: IObject - }) - - onload(): void; - - onunload(): void; - - onLayoutReady(): void; - - /* - * @param {string} [options.position=right] - */ - addTopBar(options: { - icon: string, - title: string, - callback: (evt: MouseEvent) => void - position?: "right" | "left" - }): HTMLDivElement; - - openSetting(): void - - // registerCommand(command: IPluginCommand): void; - - // registerSettingRender(settingRender: SettingRender): void; - - loadData(storageName: string): Promise; - - saveData(storageName: string, content: any): Promise; - - removeData(storageName: string): Promise; - - addTab(options: { - type: string, - destroy?: () => void, - resize?: () => void, - update?: () => void, - init: () => void - }): () => any - - addDock(options: { - config: IPluginDockTab, - data: any, - type: string, - destroy?: () => void, - resize?: () => void, - update?: () => void, - init: () => void - }): any - - addFloatLayer(options: { - ids: string[], - defIds?: string[], - x?: number, - y?: number, - targetElement?: HTMLElement - }): void - } - - export class EventBus { - on(type: TEventBus, listener: (event: CustomEvent) => void): void; - - once(type: TEventBus, listener: (event: CustomEvent) => void): void; - - off(type: TEventBus, listener: (event: CustomEvent) => void): void; - - emit(type: TEventBus, detail?: any): boolean; - } - - export class Dialog { - - element: HTMLElement; - - constructor(options: { - title?: string, - transparent?: boolean, - content: string, - width?: string - height?: string, - destroyCallback?: (options?: IObject) => void - disableClose?: boolean - disableAnimation?: boolean - }); - - destroy(options?: IObject): void; - - bindInput(inputElement: HTMLInputElement | HTMLTextAreaElement, enterEvent?: () => void): void; - } - - export class Menu { - constructor(id?: string, closeCB?: () => void); - - showSubMenu(subMenuElement: HTMLElement): void; - - addItem(options: IMenuItemOption): HTMLElement; - - addSeparator(): void; - - open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }): void; - - /* - * @param {string} [position=all] - */ - fullscreen(position?: "bottom" | "all"): void; - - close(): void; - } - - declare class Lute { - public static WalkStop: number; - public static WalkSkipChildren: number; - public static WalkContinue: number; - public static Version: string; - public static Caret: string; - - public static New(): Lute; - - public static EChartsMindmapStr(text: string): string; - - public static NewNodeID(): string; - - public static Sanitize(html: string): string; - - public static EscapeHTMLStr(str: string): string; - - public static UnEscapeHTMLStr(str: string): string; - - public static GetHeadingID(node: ILuteNode): string; - - public static BlockDOM2Content(html: string): string; - - private constructor(); - - public BlockDOM2Content(text: string): string; - - public BlockDOM2EscapeMarkerContent(text: string): string; - - public SetTextMark(enable: boolean): void; - - public SetHeadingID(enable: boolean): void; - - public SetProtyleMarkNetImg(enable: boolean): void; - - public SetSpellcheck(enable: boolean): void; - - public SetFileAnnotationRef(enable: boolean): void; - - public SetSetext(enable: boolean): void; - - public SetYamlFrontMatter(enable: boolean): void; - - public SetChineseParagraphBeginningSpace(enable: boolean): void; - - public SetRenderListStyle(enable: boolean): void; - - public SetImgPathAllowSpace(enable: boolean): void; - - public SetKramdownIAL(enable: boolean): void; - - public BlockDOM2Md(html: string): string; - - public BlockDOM2StdMd(html: string): string; - - public SetGitConflict(enable: boolean): void; - - public SetSuperBlock(enable: boolean): void; - - public SetTag(enable: boolean): void; - - public SetMark(enable: boolean): void; - - public SetSub(enable: boolean): void; - - public SetSup(enable: boolean): void; - - public SetBlockRef(enable: boolean): void; - - public SetSanitize(enable: boolean): void; - - public SetHeadingAnchor(enable: boolean): void; - - public SetImageLazyLoading(imagePath: string): void; - - public SetInlineMathAllowDigitAfterOpenMarker(enable: boolean): void; - - public SetToC(enable: boolean): void; - - public SetIndentCodeBlock(enable: boolean): void; - - public SetParagraphBeginningSpace(enable: boolean): void; - - public SetFootnotes(enable: boolean): void; - - public SetLinkRef(enalbe: boolean): void; - - public SetEmojiSite(emojiSite: string): void; - - public PutEmojis(emojis: IObject): void; - - public SpinBlockDOM(html: string): string; - - public Md2BlockDOM(html: string): string; - - public SetProtyleWYSIWYG(wysiwyg: boolean): void; - - public MarkdownStr(name: string, md: string): string; - - public IsValidLinkDest(text: string): boolean; - - public BlockDOM2InlineBlockDOM(html: string): string; - - public BlockDOM2HTML(html: string): string; - } -} From c00d5c9373a4a93bce3a9a4de73deb9b9e747d43 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 14:42:40 +0800 Subject: [PATCH 026/158] chore siyuan version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8f9d98..db69246 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "latest", + "siyuan": "^0.7.2", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", From fbfc7467b5a7796cfa01da09553ff7f4927eff30 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 15:50:28 +0800 Subject: [PATCH 027/158] copy from `plugin-sample:index.ts` --- .gitignore | 1 + plugin.json | 2 +- src/index.ts | 293 +++++++++++++++++++++++---------- src/siyuan.d.ts | 424 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 630 insertions(+), 90 deletions(-) create mode 100644 src/siyuan.d.ts diff --git a/.gitignore b/.gitignore index aa00657..764e2d4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ node_modules dev dist build +tmp diff --git a/plugin.json b/plugin.json index 8558256..37acc2b 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.0.6", + "version": "0.1.3", "minAppVersion": "2.9.0", "displayName": { "en_US": "Plugin sample with vite and svelte", diff --git a/src/index.ts b/src/index.ts index e2f27cd..7c129b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,15 @@ -import { Plugin, showMessage, confirm, Dialog, Menu, isMobile, openTab, adaptHotkey } from "siyuan"; +import { + Plugin, + showMessage, + confirm, + Dialog, + Menu, + openTab, + adaptHotkey, + getFrontend, + getBackend, + IModel +} from "siyuan"; import "./index.scss"; import HelloExample from "./hello.svelte"; @@ -11,20 +22,53 @@ const DOCK_TYPE = "dock_tab"; export default class SamplePlugin extends Plugin { private customTab: () => any; + private isMobile: boolean; async onload() { - showMessage("Hello SiYuan Plugin"); - this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; + this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; + + const frontEnd = getFrontend(); + this.isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile"; + // 图标的制作参见帮助文档 + this.addIcons(` + + + + +`); const topBarElement = this.addTopBar({ - icon: "iconEmoji", + icon: "iconFace", title: this.i18n.addTopBarIcon, - position: "left", + position: "right", callback: () => { - this.addMenu(topBarElement.getBoundingClientRect()); + let rect = topBarElement.getBoundingClientRect(); + // 如果被隐藏,则使用更多按钮 + if (rect.width === 0) { + rect = document.querySelector("#barMore").getBoundingClientRect(); + } + this.addMenu(rect); } }); + const statusIconTemp = document.createElement("template"); + statusIconTemp.innerHTML = `
+ + + +
`; + statusIconTemp.content.firstElementChild.addEventListener("click", () => { + confirm("⚠️", this.i18n.confirmRemove.replace("${name}", this.name), () => { + this.removeData(STORAGE_NAME).then(() => { + this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; + showMessage(`[${this.name}]: ${this.i18n.removedData}`); + }); + }); + }); + this.addStatusBar({ + element: statusIconTemp.content.firstElementChild as HTMLElement, + }); + let div = document.createElement("div"); new HelloExample({ target: div, @@ -44,10 +88,18 @@ export default class SamplePlugin extends Plugin { } }); + this.addCommand({ + langKey: "showDialog", + hotkey: "⇧⌘M", + callback: () => { + this.showDialog(); + } + }); + this.addDock({ config: { position: "LeftBottom", - size: {width: 200, height: 0}, + size: { width: 200, height: 0 }, icon: "iconEmoji", title: "Custom Dock", }, @@ -79,6 +131,7 @@ export default class SamplePlugin extends Plugin { onLayoutReady() { this.loadData(STORAGE_NAME); + console.log(`frontend: ${getFrontend()}; backend: ${getBackend()}`); } onunload() { @@ -87,11 +140,27 @@ export default class SamplePlugin extends Plugin { console.log("onunload"); } - private wsEvent({ detail }: any) { + openSetting(): void { + let dialog = new Dialog({ + title: "SettingPannel", + content: `
`, + width: "600px", + destroyCallback: (options) => { + console.log("destroyCallback", options); + //You must destroy the component when the dialog is closed + pannel.$destroy(); + } + }); + let pannel = new SettingPannel({ + target: dialog.element.querySelector("#SettingPanel"), + }); + } + + private eventBusLog({ detail }: any) { console.log(detail); } - private blockIconEvent({detail}: any) { + private blockIconEvent({ detail }: any) { console.log(detail); detail.menu.addSeparator(0); const ids: string[] = []; @@ -106,70 +175,108 @@ export default class SamplePlugin extends Plugin { }); } - private async addMenu(rect: DOMRect) { + private showDialog() { + new Dialog({ + title: "Info", + content: '
This is a dialog
', + width: this.isMobile ? "92vw" : "520px", + }); + } + + private addMenu(rect: DOMRect) { const menu = new Menu("topBarSample", () => { console.log(this.i18n.byeMenu); }); - menu.addItem({ - icon: "iconHelp", - label: "Confirm", - click() { - confirm("Confirm", "Is this a confirm?", () => { - showMessage("confirm"); - }, () => { - showMessage("cancel"); - }); - } - }); - menu.addItem({ - icon: "iconFeedback", - label: "Message", - click: () => { - showMessage(this.i18n.helloPlugin); - } - }); menu.addItem({ icon: "iconInfo", label: "Dialog", - click: () => this.openHelloInDialog() + accelerator: this.commands[0].customHotkey, + click: this.showDialog }); - menu.addItem({ - icon: "iconLayoutBottom", - label: "Open Tab", - click: () => { - openTab({ - custom: { - icon: "iconEmoji", - title: "Custom Tab", - data: { - text: "This is my custom tab", + if (!this.isMobile) { + menu.addItem({ + icon: "iconLayoutBottom", + label: "Open Custom Tab", + click: () => { + const tab = openTab({ + app: this.app, + custom: { + icon: "iconFace", + title: "Custom Tab", + data: { + text: "This is my custom tab", + }, + fn: this.customTab }, - fn: this.customTab - }, - }); - } - }); - menu.addItem({ - icon: "iconLayout", - label: "Open Float Layer(open help)", - click: () => { - this.addFloatLayer({ - ids: ["20230523173319-xj1l3qu", "20230523173321-55o0w2n"], - defIds: ["20230523173323-imgm9tp", "20230523173324-cxu98t3"], - x: window.innerWidth - 768 - 120, - y: 32 - }); - } - }); - menu.addItem({ - icon: "iconTrashcan", - label: "Remove Data", - click: () => { - this.removeData(STORAGE_NAME).then(() => { - this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; - }); - } - }); + }); + console.log(tab) + } + }); + menu.addItem({ + icon: "iconLayoutBottom", + label: "Open Asset Tab(open help first)", + click: () => { + const tab = openTab({ + app: this.app, + asset: { + path: "assets/paragraph-20210512165953-ag1nib4.svg" + } + }); + console.log(tab) + } + }); + menu.addItem({ + icon: "iconLayoutBottom", + label: "Open Doc Tab(open help first)", + click: async () => { + const tab = await openTab({ + app: this.app, + doc: { + id: "20200812220555-lj3enxa", + } + }); + console.log(tab) + } + }); + menu.addItem({ + icon: "iconLayoutBottom", + label: "Open Search Tab", + click: () => { + const tab = openTab({ + app: this.app, + search: { + k: "SiYuan" + } + }); + console.log(tab) + } + }); + menu.addItem({ + icon: "iconLayoutBottom", + label: "Open Card Tab", + click: () => { + const tab = openTab({ + app: this.app, + card: { + type: "all" + } + }); + console.log(tab) + } + }); + menu.addItem({ + icon: "iconLayout", + label: "Open Float Layer(open help first)", + click: () => { + this.addFloatLayer({ + ids: ["20210428212840-8rqwn5o", "20201225220955-l154bn4"], + defIds: ["20230415111858-vgohvf3", "20200813131152-0wk5akh"], + x: window.innerWidth - 768 - 120, + y: 32 + }); + } + }); + } menu.addItem({ icon: "iconScrollHoriz", label: "Event Bus", @@ -178,13 +285,13 @@ export default class SamplePlugin extends Plugin { icon: "iconSelect", label: "On ws-main", click: () => { - this.eventBus.on("ws-main", this.wsEvent); + this.eventBus.on("ws-main", this.eventBusLog); } }, { icon: "iconClose", label: "Off ws-main", click: () => { - this.eventBus.off("ws-main", this.wsEvent); + this.eventBus.off("ws-main", this.eventBusLog); } }, { icon: "iconSelect", @@ -202,35 +309,59 @@ export default class SamplePlugin extends Plugin { icon: "iconSelect", label: "On click-pdf", click: () => { - this.eventBus.on("click-pdf", this.wsEvent); + this.eventBus.on("click-pdf", this.eventBusLog); } }, { icon: "iconClose", label: "Off click-pdf", click: () => { - this.eventBus.off("click-pdf", this.wsEvent); + this.eventBus.off("click-pdf", this.eventBusLog); } }, { icon: "iconSelect", label: "On click-editorcontent", click: () => { - this.eventBus.on("click-editorcontent", this.wsEvent); + this.eventBus.on("click-editorcontent", this.eventBusLog); } }, { icon: "iconClose", label: "Off click-editorcontent", click: () => { - this.eventBus.off("click-editorcontent", this.wsEvent); + this.eventBus.off("click-editorcontent", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On click-editortitleicon", + click: () => { + this.eventBus.on("click-editortitleicon", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off click-editortitleicon", + click: () => { + this.eventBus.off("click-editortitleicon", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-noneditableblock", + click: () => { + this.eventBus.on("open-noneditableblock", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-noneditableblock", + click: () => { + this.eventBus.off("open-noneditableblock", this.eventBusLog); } }] }); menu.addSeparator(); menu.addItem({ icon: "iconSparkles", - label: this.data[STORAGE_NAME] || "Readonly", + label: this.data[STORAGE_NAME].readonlyText || "Readonly", type: "readonly", }); - if (isMobile()) { + if (this.isMobile) { menu.fullscreen(); } else { menu.open({ @@ -241,22 +372,6 @@ export default class SamplePlugin extends Plugin { } } - openSetting(): void { - let dialog = new Dialog({ - title: "SettingPannel", - content: `
`, - width: "600px", - destroyCallback: (options) => { - console.log("destroyCallback", options); - //You must destroy the component when the dialog is closed - pannel.$destroy(); - } - }); - let pannel = new SettingPannel({ - target: dialog.element.querySelector("#SettingPanel"), - }); - } - private openHelloInDialog() { let dialog = new Dialog({ title: "Hello World", diff --git a/src/siyuan.d.ts b/src/siyuan.d.ts new file mode 100644 index 0000000..4c74dc5 --- /dev/null +++ b/src/siyuan.d.ts @@ -0,0 +1,424 @@ +type TEventBus = "ws-main" | "click-blockicon" | "click-editorcontent" | "click-pdf" | + "click-editortitleicon" | "open-noneditableblock" + +type TCardType = "doc" | "notebook" | "all" + +declare global { + interface Window { + Lute: Lute + } +} + +interface ITab { + id: string; + headElement: HTMLElement; + panelElement: HTMLElement; + model: IModel; + title: string; + icon: string; + docIcon: string; + updateTitle: (title: string) => void; + pin: () => void; + unpin: () => void; + setDocIcon: (icon: string) => void; + close: () => void; +} + +interface IModel { + element: Element; + tab: ITab; + data: any; + type: string; +} + +interface IObject { + [key: string]: string; +} + +interface ILuteNode { + TokensStr: () => string; + __internal_object__: { + Parent: { + Type: number, + }, + HeadingLevel: string, + }; +} + +interface ISearchOption { + page?: number + group?: number, // 0:不分组,1:按文档分组 + hasReplace?: boolean, + method?: number // 0:文本,1:查询语法,2:SQL,3:正则表达式 + hPath?: string + idPath?: string[] + k: string + r?: string + types?: { + mathBlock: boolean + table: boolean + blockquote: boolean + superBlock: boolean + paragraph: boolean + document: boolean + heading: boolean + list: boolean + listItem: boolean + codeBlock: boolean + htmlBlock: boolean + embedBlock: boolean + } +} + +interface IWebSocketData { + cmd: string + callback?: string + data: any + msg: string + code: number + sid: string +} + +declare interface IPluginDockTab { + position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight", + size: { width: number, height: number }, + icon: string, + hotkey?: string, + title: string, + index?: number, + show?: boolean +} + +interface IMenuItemOption { + label?: string, + click?: (element: HTMLElement) => void, + type?: "separator" | "submenu" | "readonly", + accelerator?: string, + action?: string, + id?: string, + submenu?: IMenuItemOption[] + disabled?: boolean + icon?: string + iconHTML?: string + current?: boolean + bind?: (element: HTMLElement) => void + index?: number + element?: HTMLElement +} + +interface ICommandOption { + langKey: string, // 多语言 key + /** + * 目前需使用 MacOS 符号标识,顺序按照 ⌥⇧⌘,入 ⌥⇧⌘A + * "Ctrl": "⌘", + * "Shift": "⇧", + * "Alt": "⌥", + * "Tab": "⇥", + * "Backspace": "⌫", + * "Delete": "⌦", + * "Enter": "↩", + */ + hotkey: string, + customHotkey?: string, + callback?: () => void + fileTreeCallback?: (file: any) => void + editorCallback?: (protyle: any) => void + dockCallback?: (element: HTMLElement) => void +} + +export function fetchPost(url: string, data?: any, callback?: (response: IWebSocketData) => void, headers?: IObject): void; + +export function fetchSyncPost(url: string, data?: any): Promise; + +export function fetchGet(url: string, callback: (response: IWebSocketData) => void): void; + +export function openTab(options: { + app: App, + doc?: { + id: string, // 块 id + action?: string [] // cb-get-all:获取所有内容;cb-get-focus:打开后光标定位在 id 所在的块;cb-get-hl: 打开后 id 块高亮 + zoomIn?: boolean // 是否缩放 + }, + pdf?: { + path: string, + page?: number, // pdf 页码 + id?: string, // File Annotation id + }, + asset?: { + path: string, + }, + search?: ISearchOption + card?: { + type: TCardType, + id?: string, // cardType 为 all 时不传,否则传文档或笔记本 id + title?: string // cardType 为 all 时不传,否则传文档或笔记本名称 + }, + custom?: { + title: string, + icon: string, + data?: any + fn?: () => IModel, + } + position?: "right" | "bottom", + keepCursor?: boolean // 是否跳转到新 tab 上 + removeCurrentTab?: boolean // 在当前页签打开时需移除原有页签 + afterOpen?: () => void // 打开后回调 +}): ITab + +export function getFrontend(): "desktop" | "desktop-window" | "mobile" | "browser-desktop" | "browser-mobile"; + +export function getBackend(): "windows" | "linux" | "darwin" | "docker" | "android" | "ios" + +export function adaptHotkey(hotkey: string): string; + +export function confirm(title: string, text: string, confirmCallback?: () => void, cancelCallback?: () => void): void; + +/** + * @param timeout - ms. 0: manual close;-1: always show; 6000: default + * @param {string} [type=info] + */ +export function showMessage(text: string, timeout?: number, type?: "info" | "error", id?: string): void; + +export class App { + plugins: Plugin[]; +} + +export abstract class Plugin { + eventBus: EventBus; + i18n: IObject; + data: any; + name: string; + app: App; + commands: ICommandOption[]; + + constructor(options: { + app: App, + name: string, + i18n: IObject + }) + + onload(): void; + + onunload(): void; + + onLayoutReady(): void; + + /** + * Must be executed before the synchronous function. + * @param {string} [options.position=right] + */ + addTopBar(options: { + icon: string, + title: string, + callback: (event: MouseEvent) => void + position?: "right" | "left" + }): HTMLElement; + + /** + * Must be executed before the synchronous function. + * @param {string} [options.position=right] + */ + addStatusBar(options: { + element: HTMLElement, + position?: "right" | "left" + }): HTMLElement + + openSetting(): void + + loadData(storageName: string): Promise; + + saveData(storageName: string, content: any): Promise; + + removeData(storageName: string): Promise; + + addIcons(svg: string): void; + + /** + * Must be executed before the synchronous function. + */ + addTab(options: { + type: string, + destroy?: () => void, + resize?: () => void, + update?: () => void, + init: () => void + }): () => IModel + + /** + * Must be executed before the synchronous function. + */ + addDock(options: { + config: IPluginDockTab, + data: any, + type: string, + destroy?: () => void, + resize?: () => void, + update?: () => void, + init: () => void + }): { config: IPluginDockTab, model: IModel } + + addCommand(options: ICommandOption): void + + addFloatLayer(options: { + ids: string[], + defIds?: string[], + x?: number, + y?: number, + targetElement?: HTMLElement + }): void +} + +export class EventBus { + on(type: TEventBus, listener: (event: CustomEvent) => void): void; + + once(type: TEventBus, listener: (event: CustomEvent) => void): void; + + off(type: TEventBus, listener: (event: CustomEvent) => void): void; + + emit(type: TEventBus, detail?: any): boolean; +} + +export class Dialog { + + element: HTMLElement; + + constructor(options: { + title?: string, + transparent?: boolean, + content: string, + width?: string + height?: string, + destroyCallback?: (options?: IObject) => void + disableClose?: boolean + disableAnimation?: boolean + }); + + destroy(options?: IObject): void; + + bindInput(inputElement: HTMLInputElement | HTMLTextAreaElement, enterEvent?: () => void): void; +} + +export class Menu { + constructor(id?: string, closeCallback?: () => void); + + showSubMenu(subMenuElement: HTMLElement): void; + + addItem(options: IMenuItemOption): HTMLElement; + + addSeparator(index?: number): void; + + open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }): void; + + /** + * @param {string} [position=all] + */ + fullscreen(position?: "bottom" | "all"): void; + + close(): void; +} + +declare class Lute { + public static WalkStop: number; + public static WalkSkipChildren: number; + public static WalkContinue: number; + public static Version: string; + public static Caret: string; + + public static New(): Lute; + + public static EChartsMindmapStr(text: string): string; + + public static NewNodeID(): string; + + public static Sanitize(html: string): string; + + public static EscapeHTMLStr(str: string): string; + + public static UnEscapeHTMLStr(str: string): string; + + public static GetHeadingID(node: ILuteNode): string; + + public static BlockDOM2Content(html: string): string; + + private constructor(); + + public BlockDOM2Content(text: string): string; + + public BlockDOM2EscapeMarkerContent(text: string): string; + + public SetTextMark(enable: boolean): void; + + public SetHeadingID(enable: boolean): void; + + public SetProtyleMarkNetImg(enable: boolean): void; + + public SetSpellcheck(enable: boolean): void; + + public SetFileAnnotationRef(enable: boolean): void; + + public SetSetext(enable: boolean): void; + + public SetYamlFrontMatter(enable: boolean): void; + + public SetChineseParagraphBeginningSpace(enable: boolean): void; + + public SetRenderListStyle(enable: boolean): void; + + public SetImgPathAllowSpace(enable: boolean): void; + + public SetKramdownIAL(enable: boolean): void; + + public BlockDOM2Md(html: string): string; + + public BlockDOM2StdMd(html: string): string; + + public SetGitConflict(enable: boolean): void; + + public SetSuperBlock(enable: boolean): void; + + public SetTag(enable: boolean): void; + + public SetMark(enable: boolean): void; + + public SetSub(enable: boolean): void; + + public SetSup(enable: boolean): void; + + public SetBlockRef(enable: boolean): void; + + public SetSanitize(enable: boolean): void; + + public SetHeadingAnchor(enable: boolean): void; + + public SetImageLazyLoading(imagePath: string): void; + + public SetInlineMathAllowDigitAfterOpenMarker(enable: boolean): void; + + public SetToC(enable: boolean): void; + + public SetIndentCodeBlock(enable: boolean): void; + + public SetParagraphBeginningSpace(enable: boolean): void; + + public SetFootnotes(enable: boolean): void; + + public SetLinkRef(enalbe: boolean): void; + + public SetEmojiSite(emojiSite: string): void; + + public PutEmojis(emojis: IObject): void; + + public SpinBlockDOM(html: string): string; + + public Md2BlockDOM(html: string): string; + + public SetProtyleWYSIWYG(wysiwyg: boolean): void; + + public MarkdownStr(name: string, md: string): string; + + public IsValidLinkDest(text: string): boolean; + + public BlockDOM2InlineBlockDOM(html: string): string; + + public BlockDOM2HTML(html: string): string; +} \ No newline at end of file From 2759bb4c13d39ee752f5b96de2ce8bfc09d65f67 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 15:51:29 +0800 Subject: [PATCH 028/158] plugin.json --- plugin.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin.json b/plugin.json index 37acc2b..311de7b 100644 --- a/plugin.json +++ b/plugin.json @@ -4,6 +4,8 @@ "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", "version": "0.1.3", "minAppVersion": "2.9.0", + "backends": ["windows", "linux", "darwin"], + "frontends": ["desktop"], "displayName": { "en_US": "Plugin sample with vite and svelte", "zh_CN": "插件样例 vite + svelte 版" From 4dbc215a0e660d1bfaf37fb3d52d008cc1192af1 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 16:32:43 +0800 Subject: [PATCH 029/158] i18n --- src/i18n/en_US.json | 3 +++ src/i18n/zh_CN.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 7e9425a..c336270 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -5,6 +5,9 @@ "byeMenu": "Bye, Menu!", "helloPlugin": "Hello, Plugin!", "byePlugin": "Bye, Plugin!", + "showDialog": "Show dialog", + "removedData": "Data deleted", + "confirmRemove": "Confirm to delete the data in ${name}?", "name": "SiYuan", "hello": { "makesure": "Before using this template, please read the offical sample, make sure that you've known about the pipeline for plugin developing." diff --git a/src/i18n/zh_CN.json b/src/i18n/zh_CN.json index 7eaa3eb..568cccd 100644 --- a/src/i18n/zh_CN.json +++ b/src/i18n/zh_CN.json @@ -5,6 +5,9 @@ "byeMenu": "再见,菜单!", "helloPlugin": "你好,插件!", "byePlugin": "再见,插件!", + "showDialog": "弹出一个对话框", + "removedData": "数据已删除", + "confirmRemove": "确认删除 ${name} 中的数据?", "name": "思源", "hello": { "makesure": "使用这个模板之前,请阅读官方教程, 确保自己已经理解了插件的基本开发流程。" From 9f8f1fb69e2b7295a56a06c9997645671b030d2c Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 16:34:30 +0800 Subject: [PATCH 030/158] `onload` done --- src/index.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7c129b5..ee7db52 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,13 +19,13 @@ const STORAGE_NAME = "menu-config"; const TAB_TYPE = "custom_tab"; const DOCK_TYPE = "dock_tab"; -export default class SamplePlugin extends Plugin { +export default class PluginSample extends Plugin { - private customTab: () => any; + private customTab: () => IModel; private isMobile: boolean; async onload() { - this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; + this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; const frontEnd = getFrontend(); this.isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile"; @@ -60,7 +60,7 @@ export default class SamplePlugin extends Plugin { statusIconTemp.content.firstElementChild.addEventListener("click", () => { confirm("⚠️", this.i18n.confirmRemove.replace("${name}", this.name), () => { this.removeData(STORAGE_NAME).then(() => { - this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; + this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; showMessage(`[${this.name}]: ${this.i18n.removedData}`); }); }); @@ -69,9 +69,9 @@ export default class SamplePlugin extends Plugin { element: statusIconTemp.content.firstElementChild as HTMLElement, }); - let div = document.createElement("div"); + let tabDiv = document.createElement("div"); new HelloExample({ - target: div, + target: tabDiv, props: { name: this.i18n.name, i18n: this.i18n.hello @@ -80,7 +80,7 @@ export default class SamplePlugin extends Plugin { this.customTab = this.addTab({ type: TAB_TYPE, init() { - this.element.appendChild(div); + this.element.appendChild(tabDiv); console.log(this.element); }, destroy() { @@ -99,8 +99,8 @@ export default class SamplePlugin extends Plugin { this.addDock({ config: { position: "LeftBottom", - size: { width: 200, height: 0 }, - icon: "iconEmoji", + size: {width: 200, height: 0}, + icon: "iconSaving", title: "Custom Dock", }, data: { From 8b11d429dad08f7cc1786644dc686bfcfce1278e Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 16:51:40 +0800 Subject: [PATCH 031/158] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/index.ts b/src/index.ts index ee7db52..8947cf8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,6 +27,8 @@ export default class PluginSample extends Plugin { async onload() { this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; + console.log("loading plugin-sample", this.i18n); + const frontEnd = getFrontend(); this.isMobile = frontEnd === "mobile" || frontEnd === "browser-mobile"; // 图标的制作参见帮助文档 @@ -127,6 +129,7 @@ export default class PluginSample extends Plugin { } }); + console.log(this.i18n.helloPlugin); } onLayoutReady() { @@ -156,19 +159,16 @@ export default class PluginSample extends Plugin { }); } - private eventBusLog({ detail }: any) { + private eventBusLog({detail}: any) { console.log(detail); } - private blockIconEvent({ detail }: any) { - console.log(detail); - detail.menu.addSeparator(0); + private blockIconEvent({detail}: any) { const ids: string[] = []; detail.blockElements.forEach((item: HTMLElement) => { ids.push(item.getAttribute("data-node-id")); }); detail.menu.addItem({ - index: 1, iconHTML: "", type: "readonly", label: "IDs
" + ids.join("
"), @@ -176,10 +176,21 @@ export default class PluginSample extends Plugin { } private showDialog() { - new Dialog({ - title: "Info", - content: '
This is a dialog
', - width: this.isMobile ? "92vw" : "520px", + let dialog = new Dialog({ + title: "Hello World", + content: `
`, + width: this.isMobile ? "92vw" : "720px", + destroyCallback(options) { + //Destroy the component when the dialog is closed + // hello.$destroy(); + }, + }); + let hello = new HelloExample({ + target: dialog.element.querySelector("#helloPanel"), + props: { + name: this.i18n.name, + i18n: this.i18n.hello + } }); } @@ -191,7 +202,7 @@ export default class PluginSample extends Plugin { icon: "iconInfo", label: "Dialog", accelerator: this.commands[0].customHotkey, - click: this.showDialog + click: () => this.showDialog() }); if (!this.isMobile) { menu.addItem({ @@ -371,22 +382,4 @@ export default class PluginSample extends Plugin { }); } } - - private openHelloInDialog() { - let dialog = new Dialog({ - title: "Hello World", - content: `
`, - destroyCallback(options) { - //You must destroy the component when the dialog is closed - hello.$destroy(); - }, - }); - let hello = new HelloExample({ - target: dialog.element.querySelector("#helloPanel"), - props: { - name: this.i18n.name, - i18n: this.i18n.hello - } - }); - } } From 5d9805a665e70aaabfbdeff71c534327a841913b Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 16:55:40 +0800 Subject: [PATCH 032/158] readme --- README.md | 38 +++++++++++++++++++++++++-------- README_zh_CN.md | 57 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 352ada8..c0a6958 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6). +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.3](https://github.com/siyuan-note/plugin-sample/tree/v0.1.3). + 1. Using vite for packaging @@ -62,7 +63,6 @@ complete the following tasks: * Text used in the plugin, such as button text and tooltips * src/i18n/*.json language configuration files * Use `this.i18.key` to get the text in the code -* Finally, declare the language supported by the plugin in the `i18n` field in plugin.json It is recommended that the plugin supports at least English and Simplified Chinese, so that more people can use it more conveniently. @@ -74,8 +74,10 @@ conveniently. "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.0.1", - "minAppVersion": "2.9.0", + "version": "0.1.3", + "minAppVersion": "2.8.8", + "backends": ["windows", "linux", "darwin"], + "frontends": ["desktop"], "displayName": { "en_US": "Plugin sample with vite and svelte", "zh_CN": "插件样例 vite + svelte 版" @@ -89,8 +91,11 @@ conveniently. "zh_CN": "README.md" }, "funding": { + "openCollective": "", + "patreon": "", + "github": "", "custom": [ - "" + "https://ld246.com/sponsor" ] } } @@ -102,6 +107,21 @@ conveniently. * `url`: Plugin repo URL * `version`: Plugin version number, it is recommended to follow the [semver](https://semver.org/) specification * `minAppVersion`: Minimum version number of SiYuan required to use this plugin +* `backends`: Backend environment required by the plugin, optional values are `windows`, `linux`, `darwin`, `docker`, `android`, `ios` and `all` + * `windows`: Windows desktop + * `linux`: Linux desktop + * `darwin`: macOS desktop + * `docker`: Docker + * `android`: Android APP + * `ios`: iOS APP + * `all`: All environments +* `frontends`: Frontend environment required by the plugin, optional values are `desktop`, `desktop-window`, `mobile`, `browser-desktop`, `browser-mobile` and `all` + * `desktop`: Desktop + * `desktop-window`: Desktop window converted from tab + * `mobile`: Mobile APP + * `browser-desktop`: Desktop browser + * `browser-mobile`: Mobile browser + * `all`: All environments * `displayName`: Template display name, mainly used for display in the marketplace list, supports multiple languages * `default`: Default language, must exist * `zh_CN`, `en_US` and other languages: optional, it is recommended to provide at least Chinese and English @@ -122,13 +142,13 @@ conveniently. No matter which method is used to compile and package, we finally need to generate a package.zip, which contains at least the following files: -* icon.png +* i18n/* +* icon.png (160*160) +* index.css * index.js * plugin.json -* preview.png +* preview.png (1024*768) * README*.md -* index.css (optional) -* i18n/* (optional) ## List on the marketplace diff --git a/README_zh_CN.md b/README_zh_CN.md index f1b02db..55ec0a7 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.0.6](https://github.com/siyuan-note/plugin-sample/tree/v0.0.6) 基本保持一致。 +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.3](https://github.com/siyuan-note/plugin-sample/tree/v0.1.3) 基本保持一致。 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 @@ -59,7 +59,6 @@ * 插件中使用的文本,比如按钮文字和提示信息 * src/i18n/*.json 语言配置文件 * 代码中使用 `this.i18.key` 获取文本 -* 最后在 plugin.json 中的 `i18n` 字段中声明该插件支持的语言 建议插件至少支持英文和简体中文,这样可以方便更多人使用。 @@ -70,8 +69,10 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.0.1", - "minAppVersion": "2.9.0", + "version": "0.1.3", + "minAppVersion": "2.8.8", + "backends": ["windows", "linux", "darwin"], + "frontends": ["desktop"], "displayName": { "en_US": "Plugin sample with vite and svelte", "zh_CN": "插件样例 vite + svelte 版" @@ -85,8 +86,11 @@ "zh_CN": "README.md" }, "funding": { + "openCollective": "", + "patreon": "", + "github": "", "custom": [ - "" + "https://ld246.com/sponsor" ] } } @@ -97,32 +101,47 @@ * `url`:插件仓库地址 * `version`:插件版本号,建议遵循 [semver](https://semver.org/lang/zh-CN/) 规范 * `minAppVersion`:插件支持的最低思源笔记版本号 +* `backends`:插件需要的后端环境,可选值为 `windows`, `linux`, `darwin`, `docker`, `android`, `ios` and `all` + * `windows`:Windows 桌面端 + * `linux`:Linux 桌面端 + * `darwin`:macOS 桌面端 + * `docker`:Docker 端 + * `android`:Android 端 + * `ios`:iOS 端 + * `all`:所有环境 +* `frontends`:插件需要的前端环境,可选值为 `desktop`, `desktop-window`, `mobile`, `browser-desktop`, `browser-mobile` and `all` + * `desktop`:桌面端 + * `desktop-window`:桌面端页签转换的独立窗口 + * `mobile`:移动端 + * `browser-desktop`:桌面端浏览器 + * `browser-mobile`:移动端浏览器 + * `all`:所有环境 * `displayName`:模板显示名称,主要用于模板集市列表中显示,支持多语言 - * `default`:默认语言,必须存在 - * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 + * `default`:默认语言,必须存在 + * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 * `description`:插件描述,主要用于插件集市列表中显示,支持多语言 - * `default`:默认语言,必须存在 - * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 + * `default`:默认语言,必须存在 + * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 * `readme`:自述文件名,主要用于插件集市详情页中显示,支持多语言 - * `default`:默认语言,必须存在 - * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 + * `default`:默认语言,必须存在 + * `zh_CN`、`en_US` 等其他语言:可选,建议至少提供中文和英文 * `funding`:插件赞助信息 - * `openCollective`:Open Collective 名称 - * `patreon`:Patreon 名称 - * `github`:GitHub 登录名 - * `custom`:自定义赞助链接列表 + * `openCollective`:Open Collective 名称 + * `patreon`:Patreon 名称 + * `github`:GitHub 登录名 + * `custom`:自定义赞助链接列表 ## 打包 无论使用何种方式编译打包,我们最终需要生成一个 package.zip,它至少包含如下文件: -* icon.png +* i18n/* +* icon.png (160*160) +* index.css * index.js * plugin.json -* preview.png +* preview.png (1024*768) * README*.md -* index.css (optional) -* i18n/* (optional) ## 上架集市 From ef0f739a9807d82afdb98da3977e149668564e2e Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 17:55:00 +0800 Subject: [PATCH 033/158] log + error --- scripts/make_dev_link.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index f00a456..8033048 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -11,7 +11,8 @@ let targetDir = ''; // const targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; //******************************************************************************************** -const log = console.log; +const log = (info) => console.log(`\x1B[36m%s\x1B[0m`, info); +const error = (info) => console.log(`\x1B[31m%s\x1B[0m`, info); async function getSiYuanDir() { let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; @@ -28,12 +29,12 @@ async function getSiYuanDir() { if (response.ok) { conf = await response.json(); } else { - log(`HTTP-Error: ${response.status}`); + error(`HTTP-Error: ${response.status}`); return null; } } catch (e) { - log("Error:", e); - log("Please make sure SiYuan is running!!!"); + error("Error:", e); + error("Please make sure SiYuan is running!!!"); return null; } return conf.data; @@ -78,23 +79,27 @@ if (targetDir === '') { //Check if (!fs.existsSync(targetDir)) { - log(`Failed! plugin directory not exists: "${targetDir}"`); - log(`Please set the plugin directory in scripts/make_dev_link.js`); + error(`Failed! plugin directory not exists: "${targetDir}"`); + error(`Please set the plugin directory in scripts/make_dev_link.js`); process.exit(1); } //check if plugin.json exists if (!fs.existsSync('./plugin.json')) { - console.error('Failed! plugin.json not found'); - process.exit(1); + //change dir to parent + process.chdir('../'); + if (!fs.existsSync('./plugin.json')) { + error('Failed! plugin.json not found'); + process.exit(1); + } } //load plugin.json const plugin = JSON.parse(fs.readFileSync('./plugin.json', 'utf8')); const name = plugin?.name; if (!name || name === '') { - log('Failed! Please set plugin name in plugin.json'); + error('Failed! Please set plugin name in plugin.json'); process.exit(1); } @@ -108,7 +113,7 @@ if (!fs.existsSync(devDir)) { const targetPath = `${targetDir}/${name}`; //如果已经存在,就退出 if (fs.existsSync(targetPath)) { - log(`Failed! Target directory ${targetPath} already exists`); + error(`Failed! Target directory ${targetPath} already exists`); } else { //创建软链接 fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); From e3304bbadeb837fe11cb0e3ed79681b931abb49f Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 18:09:57 +0800 Subject: [PATCH 034/158] =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=B7=B2=E7=BB=8F?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/make_dev_link.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 8033048..398a20b 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -6,9 +6,9 @@ import readline from 'node:readline'; //Please write the "workspace/data/plugins" directory here //请在这里填写你的 "workspace/data/plugins" 目录 -let targetDir = ''; +// let targetDir = ''; //Like this -// const targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; +const targetDir = `H:\\临时文件夹\\SiYuanDevSpace\\data\\plugins`; //******************************************************************************************** const log = (info) => console.log(`\x1B[36m%s\x1B[0m`, info); @@ -17,7 +17,7 @@ const error = (info) => console.log(`\x1B[31m%s\x1B[0m`, info); async function getSiYuanDir() { let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; let header = { - // "Authorization": `Token ${token}`, + // "Authorization": `Token 6j8dkekjqjwb5dqq`, "Content-Type": "application/json", } let conf = {}; @@ -104,19 +104,45 @@ if (!name || name === '') { } //dev directory -const devDir = `./dev`; +const devDir = `${process.cwd()}/dev`; //mkdir if not exists if (!fs.existsSync(devDir)) { fs.mkdirSync(devDir); } +function cmpPath(path1, path2) { + path1 = path1.replace(/\\/g, '/'); + path2 = path2.replace(/\\/g, '/'); + // sepertor at tail + if (path1[path1.length - 1] !== '/') { + path1 += '/'; + } + if (path2[path2.length - 1] !== '/') { + path2 += '/'; + } + return path1 === path2; +} + const targetPath = `${targetDir}/${name}`; //如果已经存在,就退出 if (fs.existsSync(targetPath)) { - error(`Failed! Target directory ${targetPath} already exists`); + let isSymbol = fs.lstatSync(targetPath).isSymbolicLink(); + + if (isSymbol) { + let srcPath = fs.readlinkSync(targetPath); + + if (cmpPath(srcPath, devDir)) { + log(`Good! ${targetPath} is already linked to ${devDir}`); + } else { + error(`Error! Already exists symbolic link ${targetPath}\nBut it links to ${srcPath}`); + } + } else { + error(`Failed! ${targetPath} already exists and is not a symbolic link`); + } + } else { //创建软链接 - fs.symlinkSync(`${process.cwd()}/dev`, targetPath, 'junction'); + fs.symlinkSync(devDir, targetPath, 'junction'); log(`Done! Created symlink ${targetPath}`); } From d365b88d097023fd39b852d0708852506f102f9a Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 18:11:57 +0800 Subject: [PATCH 035/158] header --- scripts/make_dev_link.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 398a20b..64fc467 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -14,17 +14,18 @@ const targetDir = `H:\\临时文件夹\\SiYuanDevSpace\\data\\plugins`; const log = (info) => console.log(`\x1B[36m%s\x1B[0m`, info); const error = (info) => console.log(`\x1B[31m%s\x1B[0m`, info); +let POST_HEADER = { + // "Authorization": `Token ${token}`, + "Content-Type": "application/json", +} + async function getSiYuanDir() { let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; - let header = { - // "Authorization": `Token 6j8dkekjqjwb5dqq`, - "Content-Type": "application/json", - } let conf = {}; try { let response = await fetch(url, { method: 'POST', - headers: header + headers: POST_HEADER }); if (response.ok) { conf = await response.json(); From 3f160a5b1fd719438a98e6fa3b2cecf1447ba826 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 18:18:25 +0800 Subject: [PATCH 036/158] targetDir --- scripts/make_dev_link.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 64fc467..392f734 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -6,9 +6,9 @@ import readline from 'node:readline'; //Please write the "workspace/data/plugins" directory here //请在这里填写你的 "workspace/data/plugins" 目录 -// let targetDir = ''; +let targetDir = ''; //Like this -const targetDir = `H:\\临时文件夹\\SiYuanDevSpace\\data\\plugins`; +// let targetDir = `H:\\SiYuanDevSpace\\data\\plugins`; //******************************************************************************************** const log = (info) => console.log(`\x1B[36m%s\x1B[0m`, info); From a4c5c962c2350aae1aaa320e52a7792ba4dc8742 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 18:25:18 +0800 Subject: [PATCH 037/158] fix #9 --- scripts/make_dev_link.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 392f734..26e3df7 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -1,4 +1,5 @@ import fs from 'fs'; +import http from 'node:http'; import readline from 'node:readline'; @@ -19,11 +20,34 @@ let POST_HEADER = { "Content-Type": "application/json", } +async function myfetch(url, options) { + //使用 http 模块,从而兼容那些不支持 fetch 的 nodejs 版本 + return new Promise((resolve, reject) => { + let req = http.request(url, options, (res) => { + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + res.on('end', () => { + resolve({ + ok: true, + status: res.statusCode, + json: () => JSON.parse(data) + }); + }); + }); + req.on('error', (e) => { + reject(e); + }); + req.end(); + }); +} + async function getSiYuanDir() { let url = 'http://127.0.0.1:6806/api/system/getWorkspaces'; let conf = {}; try { - let response = await fetch(url, { + let response = await myfetch(url, { method: 'POST', headers: POST_HEADER }); From 9b46057ab0f1884f98f6c636907394524c6fce8a Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 3 Jun 2023 18:27:26 +0800 Subject: [PATCH 038/158] README --- README.md | 4 ++-- README_zh_CN.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0a6958..5ee4380 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - Notice: we **don't recommand** you to place the folder under your `{workspace}/data/plugins/` folder. 3. Install NodeJS and pnpm, then run pnpm i in the command line under your repo folder -4. **Auto create development symbolic links** (requires nodejs over version 18) +4. **Auto create development symbolic links** - Make sure that SiYuan is running - Run `pnpm run make-link`, the script will detect all the siyuan workspace, please select the targe workspace and the script will automatically create the symbolic link under the `{workspace}/data/plugins/` folder ```bash @@ -37,7 +37,7 @@ Got target directory: H:\Media\SiYuan/data/plugins Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte ``` -4. **Manually create development symbolic links** (requires nodejs over version 18) +4. **Manually create development symbolic links** - Open `./scripts/make_dev_link.js` file, set `targetDir` to your SiYuan plugin directory `/data/plugins` - Run `pnpm run make-link`, succeed if following message is shown: ```bash diff --git a/README_zh_CN.md b/README_zh_CN.md index 55ec0a7..90b2ee1 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -17,7 +17,7 @@ 2. 将你的库克隆到本地开发文件夹中 * 注意: 同 `plugin-sample` 不同, 本样例并不推荐直接把代码下载到 `{workspace}/data/plugins/` 3. 安装 [NodeJS](https://nodejs.org/en/download) 和 [pnpm](https://pnpm.io/installation),然后在开发文件夹下执行 `pnpm i` 安装所需要的依赖 -3. **自动创建符号链接** (需要 nodejs 版本在 18 以上) +3. **自动创建符号链接** - 打开思源笔记, 确保思源内核正在运行 - 运行 `pnpm run make-link`, 脚本会自动检测所有思源的工作空间, 请在命令行中手动输入序号以选择工作空间 ```bash @@ -33,7 +33,7 @@ Got target directory: H:\Media\SiYuan/data/plugins Done! Created symlink H:\Media\SiYuan/data/plugins/plugin-sample-vite-svelte ``` -4. **手动创建符号链接** (需要 nodejs 版本在 18 以上) +4. **手动创建符号链接** - 打开 `./scripts/make_dev_link.js` 文件,更改 `targetDir` 为思源的插件目录 `/data/plugins` - 运行 `pnpm run make-link` 命令, 如果看到类似以下的消息,说明创建成功: ```bash From 57e008870efafa438c4c89bcdb6ec5ed82071f85 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 4 Jun 2023 13:49:30 +0800 Subject: [PATCH 039/158] add @types --- src/api.ts | 4 --- src/sy-dtype.d.ts | 70 -------------------------------------------- src/types/index.d.ts | 66 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 74 deletions(-) delete mode 100644 src/sy-dtype.d.ts create mode 100644 src/types/index.d.ts diff --git a/src/api.ts b/src/api.ts index 0fa2013..87cf22d 100644 --- a/src/api.ts +++ b/src/api.ts @@ -6,10 +6,6 @@ * API 文档见 [API_zh_CN.md](https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md) */ -import { - Block, Notebook, NotebookConf, NotebookId, DocumentId, BlockId, - doOperation, PreviousID, ParentID, BlockType, BlockSubType -} from "sy-dtype"; import { fetchSyncPost, IWebSocketData } from "siyuan"; diff --git a/src/sy-dtype.d.ts b/src/sy-dtype.d.ts deleted file mode 100644 index 0c3b465..0000000 --- a/src/sy-dtype.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2023 frostime. All rights reserved. - * https://github.com/frostime/sy-plugin-template-vite - */ - -/** - * Frequently used data structures in SiYuan - */ -declare module "sy-dtype" { - - export type DocumentId = string; - export type BlockId = string; - export type NotebookId = string; - export type PreviousID = BlockId; - export type ParentID = BlockId | DocumentId; - - export type Notebook = { - id: NotebookId; - name: string; - icon: string; - sort: number; - closed: boolean; - } - - export type NotebookConf = { - name: string; - closed: boolean; - refCreateSavePath: string; - createDocNameTemplate: string; - dailyNoteSavePath: string; - dailyNoteTemplatePath: string; - } - - export type BlockType = "d" | "s" | "h" | "t" | "i" | "p" | "f" | "audio" | "video" | "other"; - - export type BlockSubType = "d1" | "d2" | "s1" | "s2" | "s3" | "t1" | "t2" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "table" | "task" | "toggle" | "latex" | "quote" | "html" | "code" | "footnote" | "cite" | "collection" | "bookmark" | "attachment" | "comment" | "mindmap" | "spreadsheet" | "calendar" | "image" | "audio" | "video" | "other"; - - export type Block = { - id: BlockId; - parent_id?: BlockId; - root_id: DocumentId; - hash: string; - box: string; - path: string; - hpath: string; - name: string; - alias: string; - memo: string; - tag: string; - content: string; - fcontent?: string; - markdown: string; - length: number; - type: BlockType; - subtype: BlockSubType; - ial?: { [key: string]: string }; - sort: number; - created: string; - updated: string; - } - - export type doOperation = { - action: string; - data: string; - id: BlockId; - parentID: BlockId | DocumentId; - previousID: BlockId; - retData: null; - } -} \ No newline at end of file diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..96110dc --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2023 frostime. All rights reserved. + */ + +/** + * Frequently used data structures in SiYuan + */ +type DocumentId = string; +type BlockId = string; +type NotebookId = string; +type PreviousID = BlockId; +type ParentID = BlockId | DocumentId; + +type Notebook = { + id: NotebookId; + name: string; + icon: string; + sort: number; + closed: boolean; +} + +type NotebookConf = { + name: string; + closed: boolean; + refCreateSavePath: string; + createDocNameTemplate: string; + dailyNoteSavePath: string; + dailyNoteTemplatePath: string; +} + +type BlockType = "d" | "s" | "h" | "t" | "i" | "p" | "f" | "audio" | "video" | "other"; + +type BlockSubType = "d1" | "d2" | "s1" | "s2" | "s3" | "t1" | "t2" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "table" | "task" | "toggle" | "latex" | "quote" | "html" | "code" | "footnote" | "cite" | "collection" | "bookmark" | "attachment" | "comment" | "mindmap" | "spreadsheet" | "calendar" | "image" | "audio" | "video" | "other"; + +type Block = { + id: BlockId; + parent_id?: BlockId; + root_id: DocumentId; + hash: string; + box: string; + path: string; + hpath: string; + name: string; + alias: string; + memo: string; + tag: string; + content: string; + fcontent?: string; + markdown: string; + length: number; + type: BlockType; + subtype: BlockSubType; + ial?: { [key: string]: string }; + sort: number; + created: string; + updated: string; +} + +type doOperation = { + action: string; + data: string; + id: BlockId; + parentID: BlockId | DocumentId; + previousID: BlockId; + retData: null; +} \ No newline at end of file From 6b903d5a145785b036316813c94e57ee562237d1 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 6 Jun 2023 15:44:42 +0800 Subject: [PATCH 040/158] feat: Add `@` alias to `./src` --- src/hello.svelte | 4 ++-- src/index.ts | 6 +++--- tsconfig.json | 7 ++++++- vite.config.ts | 6 ++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/hello.svelte b/src/hello.svelte index 40d97b7..9094eb3 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -1,8 +1,8 @@ -
-
-
-

Hello {name} v{ver}

-
-
- {time_str} -
+
+
API demo:
+
+
+ System current time: {time}
- - -

Wellcome to plugin sample with vite & svelte

-

{@html i18n.makesure}

-
- +
+
+
Protyle demo: id = {blockID}
+
+
- diff --git a/src/index.ts b/src/index.ts index a5ccd12..e12c75c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,11 +83,7 @@ export default class PluginSample extends Plugin { let tabDiv = document.createElement("div"); new HelloExample({ - target: tabDiv, - props: { - name: this.i18n.name, - i18n: this.i18n.hello - } + target: tabDiv }); this.customTab = this.addTab({ type: TAB_TYPE, @@ -236,12 +232,8 @@ export default class PluginSample extends Plugin { // hello.$destroy(); }, }); - let hello = new HelloExample({ + new HelloExample({ target: dialog.element.querySelector("#helloPanel"), - props: { - name: this.i18n.name, - i18n: this.i18n.hello - } }); } From b1660caa305cbc7182264468ba390144766a2182 Mon Sep 17 00:00:00 2001 From: frostime Date: Wed, 28 Jun 2023 21:17:34 +0800 Subject: [PATCH 053/158] slider tooltips --- src/libs/setting-item.svelte | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/libs/setting-item.svelte b/src/libs/setting-item.svelte index 74e08b5..b728cf4 100644 --- a/src/libs/setting-item.svelte +++ b/src/libs/setting-item.svelte @@ -13,7 +13,7 @@ min: number; max: number; step: number; - } = {min: 0, max: 100, step: 1}; // Use it if type is slider + } = { min: 0, max: 100, step: 1 }; // Use it if type is slider const dispatch = createEventDispatcher(); @@ -76,15 +76,17 @@ {:else if type == "slider"} - +
+ +
{/if} From 34e3646add5c0fc69bc5304794be8fcc16a1be9d Mon Sep 17 00:00:00 2001 From: frostime Date: Wed, 28 Jun 2023 21:18:04 +0800 Subject: [PATCH 054/158] doc --- README.md | 2 +- README_zh_CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 71d9860..737800a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.5](https://github.com/siyuan-note/plugin-sample/tree/v0.1.5). +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.8](https://github.com/siyuan-note/plugin-sample/tree/v0.1.8). diff --git a/README_zh_CN.md b/README_zh_CN.md index 260eaf0..5177733 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.5](https://github.com/siyuan-note/plugin-sample/tree/v0.1.5) +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.8](https://github.com/siyuan-note/plugin-sample/tree/v0.1.8) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 From ddca3e0e24eeadbb136d6aef27864aa5ceafa0f2 Mon Sep 17 00:00:00 2001 From: frostime Date: Wed, 28 Jun 2023 21:28:38 +0800 Subject: [PATCH 055/158] fix: protyle --- src/hello.svelte | 9 +++++---- src/index.ts | 8 +++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/hello.svelte b/src/hello.svelte index 30665f1..6d10108 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -3,6 +3,8 @@ import { version, sql as query } from "@/api"; import { showMessage, fetchPost, Protyle } from "siyuan"; + export let app; + let time: string = ""; let ver: string; @@ -15,7 +17,7 @@ fetchPost("/api/system/currentTime", {}, (response) => { time = new Date(response.data).toString(); }); - await initProtyle(); + protyle = await initProtyle(); }); onDestroy(() => { @@ -27,9 +29,8 @@ let sql = "SELECT * FROM blocks ORDER BY RANDOM () LIMIT 1;"; let blocks: Block[] = await query(sql); blockID = blocks[0].id; - protyle = new Protyle(this.app, divProtyle, { - blockId: blockID, - mode: "preview" + return new Protyle(app, divProtyle, { + blockId: blockID }); } diff --git a/src/index.ts b/src/index.ts index e12c75c..897dcf1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,7 +83,10 @@ export default class PluginSample extends Plugin { let tabDiv = document.createElement("div"); new HelloExample({ - target: tabDiv + target: tabDiv, + props: { + app: this.app, + } }); this.customTab = this.addTab({ type: TAB_TYPE, @@ -234,6 +237,9 @@ export default class PluginSample extends Plugin { }); new HelloExample({ target: dialog.element.querySelector("#helloPanel"), + props: { + app: this.app, + } }); } From 519bece35b2ecdc9e37ae4f8db205df535a80598 Mon Sep 17 00:00:00 2001 From: Frostime Date: Sat, 8 Jul 2023 15:45:26 +0800 Subject: [PATCH 056/158] Update index.d.ts, fix ial type --- src/types/index.d.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 96110dc..68416a0 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -50,7 +50,10 @@ type Block = { length: number; type: BlockType; subtype: BlockSubType; - ial?: { [key: string]: string }; + /** string of { [key: string]: string } + * For instance: "{: custom-type=\"query-code\" id=\"20230613234017-zkw3pr0\" updated=\"20230613234509\"}" + */ + ial?: string; sort: number; created: string; updated: string; @@ -63,4 +66,4 @@ type doOperation = { parentID: BlockId | DocumentId; previousID: BlockId; retData: null; -} \ No newline at end of file +} From 38b8677c15b76056b8153329ef6a5a82bc31d1b0 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 15 Jul 2023 15:21:40 +0800 Subject: [PATCH 057/158] upgrade to v0.1.10 --- CHANGELOG.md | 9 ++++ README.md | 2 +- README_zh_CN.md | 2 +- package.json | 4 +- src/index.ts | 113 ++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 118 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd09d9c..19a59a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.1.10 + +* [Add `bind this` example for eventBus in plugins](https://github.com/siyuan-note/siyuan/issues/8668) +* [Add `open-menu-breadcrumbmore` event bus to plugins](https://github.com/siyuan-note/siyuan/issues/8666) + +## 0.1.9 + +* [Add `open-menu-xxx` event bus for plugins ](https://github.com/siyuan-note/siyuan/issues/8617) + ## 0.1.8 * [Add protyleSlash to the plugin](https://github.com/siyuan-note/siyuan/issues/8599) diff --git a/README.md b/README.md index 737800a..98b04e1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.8](https://github.com/siyuan-note/plugin-sample/tree/v0.1.8). +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.10](https://github.com/siyuan-note/plugin-sample/tree/v0.1.10) diff --git a/README_zh_CN.md b/README_zh_CN.md index 5177733..0f3203b 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.8](https://github.com/siyuan-note/plugin-sample/tree/v0.1.8) +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.10](https://github.com/siyuan-note/plugin-sample/tree/v0.1.10) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 diff --git a/package.json b/package.json index 901a1c1..829bbb5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.1.8", + "version": "0.1.10", "type": "module", "description": "", "repository": "", @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.7.5", + "siyuan": "0.7.7", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/src/index.ts b/src/index.ts index 897dcf1..661f792 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,9 +26,10 @@ export default class PluginSample extends Plugin { private customTab: () => IModel; private isMobile: boolean; + private blockIconEventBindThis = this.blockIconEvent.bind(this); async onload() { - this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; + this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; console.log("loading plugin-sample", this.i18n); @@ -72,7 +73,7 @@ export default class PluginSample extends Plugin { statusIconTemp.content.firstElementChild.addEventListener("click", () => { confirm("⚠️", this.i18n.confirmRemove.replace("${name}", this.name), () => { this.removeData(STORAGE_NAME).then(() => { - this.data[STORAGE_NAME] = {readonlyText: "Readonly"}; + this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; showMessage(`[${this.name}]: ${this.i18n.removedData}`); }); }); @@ -113,7 +114,7 @@ export default class PluginSample extends Plugin { this.addDock({ config: { position: "LeftBottom", - size: {width: 200, height: 0}, + size: { width: 200, height: 0 }, icon: "iconSaving", title: "Custom Dock", }, @@ -144,7 +145,7 @@ export default class PluginSample extends Plugin { const textareaElement = document.createElement("textarea"); this.setting = new Setting({ confirmCallback: () => { - this.saveData(STORAGE_NAME, {readonlyText: textareaElement.value}); + this.saveData(STORAGE_NAME, { readonlyText: textareaElement.value }); } }); this.setting.addItem({ @@ -210,11 +211,11 @@ export default class PluginSample extends Plugin { }); } - private eventBusLog({detail}: any) { + private eventBusLog({ detail }: any) { console.log(detail); } - private blockIconEvent({detail}: any) { + private blockIconEvent({ detail }: any) { const ids: string[] = []; detail.blockElements.forEach((item: HTMLElement) => { ids.push(item.getAttribute("data-node-id")); @@ -359,13 +360,13 @@ export default class PluginSample extends Plugin { icon: "iconSelect", label: "On click-blockicon", click: () => { - this.eventBus.on("click-blockicon", this.blockIconEvent); + this.eventBus.on("click-blockicon", this.blockIconEventBindThis); } }, { icon: "iconClose", label: "Off click-blockicon", click: () => { - this.eventBus.off("click-blockicon", this.blockIconEvent); + this.eventBus.off("click-blockicon", this.blockIconEventBindThis); } }, { icon: "iconSelect", @@ -427,6 +428,102 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.off("loaded-protyle", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On open-menu-blockref", + click: () => { + this.eventBus.on("open-menu-blockref", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-blockref", + click: () => { + this.eventBus.off("open-menu-blockref", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-fileannotationref", + click: () => { + this.eventBus.on("open-menu-fileannotationref", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-fileannotationref", + click: () => { + this.eventBus.off("open-menu-fileannotationref", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-tag", + click: () => { + this.eventBus.on("open-menu-tag", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-tag", + click: () => { + this.eventBus.off("open-menu-tag", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-link", + click: () => { + this.eventBus.on("open-menu-link", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-link", + click: () => { + this.eventBus.off("open-menu-link", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-image", + click: () => { + this.eventBus.on("open-menu-image", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-image", + click: () => { + this.eventBus.off("open-menu-image", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-av", + click: () => { + this.eventBus.on("open-menu-av", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-av", + click: () => { + this.eventBus.off("open-menu-av", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-content", + click: () => { + this.eventBus.on("open-menu-content", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-content", + click: () => { + this.eventBus.off("open-menu-content", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-menu-breadcrumbmore", + click: () => { + this.eventBus.on("open-menu-breadcrumbmore", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-breadcrumbmore", + click: () => { + this.eventBus.off("open-menu-breadcrumbmore", this.eventBusLog); + } }] }); menu.addSeparator(); From d5bf3cbc661d4cedcd1dcb8c024aac75c7c55639 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 15 Jul 2023 15:28:30 +0800 Subject: [PATCH 058/158] update make-link --- scripts/make_dev_link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 26e3df7..9095aad 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -93,7 +93,7 @@ if (targetDir === '') { log('"targetDir" is empty, try to get SiYuan directory automatically....') let res = await getSiYuanDir(); - if (res === null) { + if (res === null || res === undefined || res.length === 0) { log('Failed! You can set the plugin directory in scripts/make_dev_link.js and try again'); process.exit(1); } From d64c5b1c38c2d942dacb24cacb7baf25c9e06d10 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 23 Jul 2023 14:27:58 +0800 Subject: [PATCH 059/158] update make-link --- README.md | 7 ++++--- README_zh_CN.md | 6 ++++-- scripts/make_dev_link.js | 35 ++++++++++++++++++++++++----------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 98b04e1..7eba330 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,10 @@ Done! Created symlink H:/SiYuanDevSpace/data/plugins/plugin-sample-vite-svelte ``` - -5. Execute pnpm run dev for real-time compilation -6. Open SiYuan marketplace and enable plugin in downloaded tab +5. **Create development symbolic links by using environment variable** + - You can set environment variable `SIYUAN_PLUGIN_DIR` as `/data/plugins` +6. Execute pnpm run dev for real-time compilation +7. Open SiYuan marketplace and enable plugin in downloaded tab > Notice: as the `make-link` script rely on the `fetch` function, please **ensure that at least version v18 of nodejs is installed** if you want to use make-link script. diff --git a/README_zh_CN.md b/README_zh_CN.md index 0f3203b..6c2bf01 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -43,8 +43,10 @@ Done! Created symlink H:/SiYuanDevSpace/data/plugins/plugin-sample-vite-svelte ``` -5. 执行 `pnpm run dev` 进行实时编译 -6. 在思源中打开集市并在下载选项卡中启用插件 +5. **设置环境变量创建符号链接** + - 你也可以设置系统的环境变量 `SIYUAN_PLUGIN_DIR` 为 `/data/plugins` 的路径 +6. 执行 `pnpm run dev` 进行实时编译 +7. 在思源中打开集市并在下载选项卡中启用插件 > 注意由于使用的 make-link 脚本依赖于 `fetch`,所以如果想要使用 make-link **请保证至少安装 v18 版本的 nodejs** diff --git a/scripts/make_dev_link.js b/scripts/make_dev_link.js index 9095aad..845d298 100644 --- a/scripts/make_dev_link.js +++ b/scripts/make_dev_link.js @@ -54,12 +54,12 @@ async function getSiYuanDir() { if (response.ok) { conf = await response.json(); } else { - error(`HTTP-Error: ${response.status}`); + error(`\tHTTP-Error: ${response.status}`); return null; } } catch (e) { - error("Error:", e); - error("Please make sure SiYuan is running!!!"); + error(`\tError: ${e}`); + error("\tPlease make sure SiYuan is running!!!"); return null; } return conf.data; @@ -67,9 +67,9 @@ async function getSiYuanDir() { async function chooseTarget(workspaces) { let count = workspaces.length; - log(`Got ${count} SiYuan ${count > 1 ? 'workspaces' : 'workspace'}`) + log(`>>> Got ${count} SiYuan ${count > 1 ? 'workspaces' : 'workspace'}`) for (let i = 0; i < workspaces.length; i++) { - log(`[${i}] ${workspaces[i].path}`); + log(`\t[${i}] ${workspaces[i].path}`); } if (count == 1) { @@ -80,7 +80,7 @@ async function chooseTarget(workspaces) { output: process.stdout }); let index = await new Promise((resolve, reject) => { - rl.question(`Please select a workspace[0-${count-1}]: `, (answer) => { + rl.question(`\tPlease select a workspace[0-${count-1}]: `, (answer) => { resolve(answer); }); }); @@ -89,17 +89,30 @@ async function chooseTarget(workspaces) { } } +log('>>> Try to visit constant "targetDir" in make_dev_link.js...') + if (targetDir === '') { - log('"targetDir" is empty, try to get SiYuan directory automatically....') + log('>>> Constant "targetDir" is empty, try to get SiYuan directory automatically....') let res = await getSiYuanDir(); if (res === null || res === undefined || res.length === 0) { - log('Failed! You can set the plugin directory in scripts/make_dev_link.js and try again'); - process.exit(1); + log('>>> Can not get SiYuan directory automatically, try to visit environment variable "SIYUAN_PLUGIN_DIR"....'); + + // console.log(process.env) + let env = process.env?.SIYUAN_PLUGIN_DIR; + if (env !== undefined && env !== null && env !== '') { + targetDir = env; + log(`\tGot target directory from environment variable "SIYUAN_PLUGIN_DIR": ${targetDir}`); + } else { + error('\tCan not get SiYuan directory from environment variable "SIYUAN_PLUGIN_DIR", failed!'); + process.exit(1); + } + } else { + targetDir = await chooseTarget(res); } - targetDir = await chooseTarget(res); - log(`Got target directory: ${targetDir}`); + + log(`>>> Successfully got target directory: ${targetDir}`); } //Check From 014f90626343fd54f0f282eb7ffaf9d26ce1c964 Mon Sep 17 00:00:00 2001 From: Frostime Date: Sat, 29 Jul 2023 20:16:58 +0800 Subject: [PATCH 060/158] Update index.d.ts --- src/types/index.d.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 68416a0..1891c1a 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -67,3 +67,16 @@ type doOperation = { previousID: BlockId; retData: null; } + +interface Window { + siyuan: { + notebooks: any; + menus: any; + dialogs: any; + blockPanels: any; + storage: any; + user: any; + ws: any; + languages: any; + }; +} From 4fc8ef7afc62af4f595e28ea0d46455c4f79b673 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 15 Aug 2023 10:38:13 +0800 Subject: [PATCH 061/158] update to v0.1.12 --- CHANGELOG.md | 9 +++++++++ package.json | 4 ++-- plugin.json | 2 +- src/index.ts | 12 ++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a59a1..47d5ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.1.12 2023-08-01 + +* Upgrade siyuan to 0.7.9 + +## 0.1.11 + +* [Add `input-search` event bus to plugins](https://github.com/siyuan-note/siyuan/issues/8725) + + ## 0.1.10 * [Add `bind this` example for eventBus in plugins](https://github.com/siyuan-note/siyuan/issues/8668) diff --git a/package.json b/package.json index 829bbb5..9d1e0e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.1.10", + "version": "0.1.12", "type": "module", "description": "", "repository": "", @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.7.7", + "siyuan": "0.7.9", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/plugin.json b/plugin.json index 0cb1325..5def5dc 100644 --- a/plugin.json +++ b/plugin.json @@ -2,7 +2,7 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.1.8", + "version": "0.1.12", "minAppVersion": "2.9.0", "backends": ["all"], "frontends": ["all"], diff --git a/src/index.ts b/src/index.ts index 661f792..ed17f48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -524,6 +524,18 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.off("open-menu-breadcrumbmore", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On input-search", + click: () => { + this.eventBus.on("input-search", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off input-search", + click: () => { + this.eventBus.off("input-search", this.eventBusLog); + } }] }); menu.addSeparator(); From 811519bfd82b4de288fa70d5fca8e02e7b4316fb Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 15 Aug 2023 10:43:52 +0800 Subject: [PATCH 062/158] update --- CHANGELOG.md | 5 +++++ README.md | 2 +- README_zh_CN.md | 2 +- src/index.ts | 35 ++++++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d5ed1..a3d0833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.0 + +* [Add plugin event bus `open-siyuan-url-plugin` and `open-siyuan-url-block`](https://github.com/siyuan-note/siyuan/pull/8927) + + ## 0.1.12 2023-08-01 * Upgrade siyuan to 0.7.9 diff --git a/README.md b/README.md index 7eba330..4ed21ad 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.10](https://github.com/siyuan-note/plugin-sample/tree/v0.1.10) +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.12](https://github.com/siyuan-note/plugin-sample/tree/v0.1.12) diff --git a/README_zh_CN.md b/README_zh_CN.md index 6c2bf01..e3c15d8 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.10](https://github.com/siyuan-note/plugin-sample/tree/v0.1.10) +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.12](https://github.com/siyuan-note/plugin-sample/tree/v0.1.12) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 diff --git a/src/index.ts b/src/index.ts index ed17f48..53bfdb5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -108,7 +108,16 @@ export default class PluginSample extends Plugin { hotkey: "⇧⌘M", callback: () => { this.showDialog(); - } + }, + fileTreeCallback: (file: any) => { + console.log(file, "fileTreeCallback"); + }, + editorCallback: (protyle: any) => { + console.log(protyle, "editorCallback"); + }, + dockCallback: (element: HTMLElement) => { + console.log(element, "dockCallback"); + }, }); this.addDock({ @@ -536,6 +545,30 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.off("input-search", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On open-siyuan-url-plugin", + click: () => { + this.eventBus.on("open-siyuan-url-plugin", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-siyuan-url-plugin", + click: () => { + this.eventBus.off("open-siyuan-url-plugin", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On open-siyuan-url-block", + click: () => { + this.eventBus.on("open-siyuan-url-block", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-siyuan-url-block", + click: () => { + this.eventBus.off("open-siyuan-url-block", this.eventBusLog); + } }] }); menu.addSeparator(); From b7f633598f903ee080c3dc9f80fe77ce811ca45f Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 15 Aug 2023 10:52:47 +0800 Subject: [PATCH 063/158] =?UTF-8?q?feat:=20=E5=8D=95=E7=8B=AC=E6=8A=BD?= =?UTF-8?q?=E5=87=BA=20api.d.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api.ts | 66 +++++++++++----------------------------------- src/types/api.d.ts | 45 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 50 deletions(-) create mode 100644 src/types/api.d.ts diff --git a/src/api.ts b/src/api.ts index 0df6c12..1aacac4 100644 --- a/src/api.ts +++ b/src/api.ts @@ -18,11 +18,8 @@ async function request(url: string, data: any) { // **************************************** Noteboook **************************************** -export type ReslsNotebooks = { - notebooks: Notebook[]; -} -export async function lsNotebooks(): Promise { +export async function lsNotebooks(): Promise { let url = '/api/notebook/lsNotebooks'; return request(url, ''); } @@ -141,12 +138,8 @@ export async function getHPathByID(id: BlockId): Promise { } // **************************************** Asset Files **************************************** -export type ResUpload = { - errFiles: string[]; - succMap: { [key: string]: string }; -} -export async function upload(assetsDirPath: string, files: any[]): Promise { +export async function upload(assetsDirPath: string, files: any[]): Promise { let form = new FormData(); form.append('assetsDirPath', assetsDirPath); for (let file of files) { @@ -157,12 +150,8 @@ export async function upload(assetsDirPath: string, files: any[]): Promise { +export async function insertBlock(dataType: DataType, data: string, previousID: BlockId): Promise { let data1 = { dataType: dataType, data: data, @@ -173,7 +162,7 @@ export async function insertBlock(dataType: DataType, data: string, previousID: } -export async function appendBlock(dataType: DataType, data: string, parentID: BlockId | DocumentId): Promise { +export async function appendBlock(dataType: DataType, data: string, parentID: BlockId | DocumentId): Promise { let data1 = { dataType: dataType, data: data, @@ -184,7 +173,7 @@ export async function appendBlock(dataType: DataType, data: string, parentID: Bl } -export async function updateBlock(dataType: DataType, data: string, id: BlockId): Promise { +export async function updateBlock(dataType: DataType, data: string, id: BlockId): Promise { let data1 = { dataType: dataType, data: data, @@ -195,7 +184,7 @@ export async function updateBlock(dataType: DataType, data: string, id: BlockId) } -export async function deleteBlock(id: BlockId): Promise { +export async function deleteBlock(id: BlockId): Promise { let data = { id: id } @@ -204,7 +193,7 @@ export async function deleteBlock(id: BlockId): Promise { } -export async function moveBlock(id: BlockId, previousID: PreviousID | null = null, parentID: ParentID | null = null): Promise { +export async function moveBlock(id: BlockId, previousID: PreviousID | null = null, parentID: ParentID | null = null): Promise { let data = { id: id, previousID: previousID, @@ -215,12 +204,7 @@ export async function moveBlock(id: BlockId, previousID: PreviousID | null = nul } -export type ResGetBlockKramdown = { - id: BlockId; - kramdown: string; -} - -export async function getBlockKramdown(id: BlockId): Promise { +export async function getBlockKramdown(id: BlockId): Promise { let data = { id: id } @@ -228,12 +212,8 @@ export async function getBlockKramdown(id: BlockId): Promise { + +export async function getChildBlocks(id: BlockId): Promise { let data = { id: id } @@ -288,11 +268,7 @@ export async function getBlockByID(blockId: string): Promise { // **************************************** Template **************************************** -export type ResGetTemplates = { - content: string; - path: string; -} -export async function render(id: DocumentId, path: string): Promise { +export async function render(id: DocumentId, path: string): Promise { let data = { id: id, path: path @@ -343,11 +319,8 @@ export async function removeFile(path: string) { } -export type ResReadDir = { - isDir: boolean; - name: string; -} -export async function readDir(path: string): Promise { + +export async function readDir(path: string): Promise { let data = { path: path } @@ -356,11 +329,7 @@ export async function readDir(path: string): Promise { } -export type ResExportMdContent = { - hPath: string; - content: string; -} -export async function exportMdContent(id: DocumentId): Promise { +export async function exportMdContent(id: DocumentId): Promise { let data = { id: id } @@ -379,11 +348,8 @@ export async function pandoc(args: PandocArgs[]) { // **************************************** System **************************************** -export type ResBootProgress = { - progress: number; - details: string; -} -export async function bootProgress(): Promise { + +export async function bootProgress(): Promise { return request('/api/system/bootProgress', {}); } diff --git a/src/types/api.d.ts b/src/types/api.d.ts new file mode 100644 index 0000000..d363403 --- /dev/null +++ b/src/types/api.d.ts @@ -0,0 +1,45 @@ +interface IReslsNotebooks { + notebooks: Notebook[]; +} + +interface IResUpload { + errFiles: string[]; + succMap: { [key: string]: string }; +} + +interface IResdoOperations { + doOperations: doOperation[]; + undoOperations: doOperation[] | null; +} + +interface IResGetBlockKramdown { + id: BlockId; + kramdown: string; +} + +interface IResGetChildBlock { + id: BlockId; + type: BlockType; + subtype?: BlockSubType; +} + +interface IResGetTemplates { + content: string; + path: string; +} + +interface IResReadDir { + isDir: boolean; + name: string; +} + +interface IResExportMdContent { + hPath: string; + content: string; +} + +interface IResBootProgress { + progress: number; + details: string; +} + From 548f80a46fd6ebc64fc8c199f0ae8b40bd0c4370 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 15 Aug 2023 11:06:33 +0800 Subject: [PATCH 064/158] update api --- src/api.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/types/api.d.ts | 14 ++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/api.ts b/src/api.ts index 1aacac4..9d3a2fd 100644 --- a/src/api.ts +++ b/src/api.ts @@ -328,6 +328,27 @@ export async function readDir(path: string): Promise { return request(url, data); } +// /api/export/exportResources +/* +{ + "paths": [ + "/conf/appearance/boot", + "/conf/appearance/langs", + "/conf/appearance/emojis/conf.json", + "/conf/appearance/icons/index.html", + ], + "name": "zip-file-name" +} +*/ +export async function exportResources(paths: string[], name: string): Promise { + let data = { + paths: paths, + name: name + } + let url = '/api/export/exportResources'; + return request(url, data); +} + export async function exportMdContent(id: DocumentId): Promise { let data = { @@ -346,6 +367,23 @@ export async function pandoc(args: PandocArgs[]) { return request(url, data); } +// **************************************** Network **************************************** +export async function forwardProxy( + url: string, method: string, payload: any, + headers: any[], timeout: number = 7000, contentType: string = "text/html" +): Promise { + let data = { + url: url, + method: method, + timeout: timeout, + contentType: contentType, + headers: headers, + payload: payload + } + let url1 = '/api/network/forwardProxy'; + return request(url1, data); +} + // **************************************** System **************************************** diff --git a/src/types/api.d.ts b/src/types/api.d.ts index d363403..1163bb0 100644 --- a/src/types/api.d.ts +++ b/src/types/api.d.ts @@ -30,6 +30,7 @@ interface IResGetTemplates { interface IResReadDir { isDir: boolean; + isSymlink: boolean; name: string; } @@ -43,3 +44,16 @@ interface IResBootProgress { details: string; } +interface IResForwardProxy { + body: string; + contentType: string; + elapsed: number; + headers: { [key: string]: string }; + status: number; + url: string; +} + +interface IResExportResources { + path: string; +} + From 1f199a6dcf70501bf92501dbb749f9faf9c844b4 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 15 Aug 2023 23:29:23 +0800 Subject: [PATCH 065/158] udpate api.ts --- src/api.ts | 108 ++++++++++++++++++++++++++++----------------- src/types/api.d.ts | 6 +++ 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/api.ts b/src/api.ts index 9d3a2fd..3939d14 100644 --- a/src/api.ts +++ b/src/api.ts @@ -6,6 +6,7 @@ * API 文档见 [API_zh_CN.md](https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md) */ +import { time } from "console"; import { fetchSyncPost, IWebSocketData } from "siyuan"; @@ -54,14 +55,8 @@ export async function removeNotebook(notebook: NotebookId) { return request(url, { notebook: notebook }); } -export type ResGetNotebookConf = { - box: string; - conf: NotebookConf; - name: string; -} - -export async function getNotebookConf(notebook: NotebookId): Promise { +export async function getNotebookConf(notebook: NotebookId): Promise { let data = { notebook: notebook }; let url = '/api/notebook/getNotebookConf'; return request(url, data); @@ -75,7 +70,7 @@ export async function setNotebookConf(notebook: NotebookId, conf: NotebookConf): } -// **************************************** Document **************************************** +// **************************************** File Tree **************************************** export async function createDocWithMd(notebook: NotebookId, path: string, markdown: string): Promise { let data = { notebook: notebook, @@ -151,40 +146,56 @@ export async function upload(assetsDirPath: string, files: any[]): Promise { - let data1 = { +export async function insertBlock( + dataType: DataType, data: string, + nextID?: BlockId, previousID?: BlockId, parentID?: BlockId +): Promise { + let payload = { dataType: dataType, data: data, - previousID: previousID + nextID: nextID, + previousID: previousID, + parentID: parentID } let url = '/api/block/insertBlock'; - return request(url, data1); + return request(url, payload); } -export async function appendBlock(dataType: DataType, data: string, parentID: BlockId | DocumentId): Promise { - let data1 = { +export async function prependBlock(dataType: DataType, data: string, parentID: BlockId | DocumentId): Promise { + let payload = { + dataType: dataType, + data: data, + parentID: parentID + } + let url = '/api/block/prependBlock'; + return request(url, payload); +} + + +export async function appendBlock(dataType: DataType, data: string, parentID: BlockId | DocumentId): Promise { + let payload = { dataType: dataType, data: data, parentID: parentID } let url = '/api/block/appendBlock'; - return request(url, data1); + return request(url, payload); } -export async function updateBlock(dataType: DataType, data: string, id: BlockId): Promise { - let data1 = { +export async function updateBlock(dataType: DataType, data: string, id: BlockId): Promise { + let payload = { dataType: dataType, data: data, id: id } let url = '/api/block/updateBlock'; - return request(url, data1); + return request(url, payload); } -export async function deleteBlock(id: BlockId): Promise { +export async function deleteBlock(id: BlockId): Promise { let data = { id: id } @@ -193,7 +204,7 @@ export async function deleteBlock(id: BlockId): Promise { } -export async function moveBlock(id: BlockId, previousID: PreviousID | null = null, parentID: ParentID | null = null): Promise { +export async function moveBlock(id: BlockId, previousID?: PreviousID, parentID?: ParentID): Promise { let data = { id: id, previousID: previousID, @@ -328,27 +339,8 @@ export async function readDir(path: string): Promise { return request(url, data); } -// /api/export/exportResources -/* -{ - "paths": [ - "/conf/appearance/boot", - "/conf/appearance/langs", - "/conf/appearance/emojis/conf.json", - "/conf/appearance/icons/index.html", - ], - "name": "zip-file-name" -} -*/ -export async function exportResources(paths: string[], name: string): Promise { - let data = { - paths: paths, - name: name - } - let url = '/api/export/exportResources'; - return request(url, data); -} +// **************************************** Export **************************************** export async function exportMdContent(id: DocumentId): Promise { let data = { @@ -358,6 +350,17 @@ export async function exportMdContent(id: DocumentId): Promise { + let data = { + paths: paths, + name: name + } + let url = '/api/export/exportResources'; + return request(url, data); +} + +// **************************************** Convert **************************************** + export type PandocArgs = string; export async function pandoc(args: PandocArgs[]) { let data = { @@ -367,6 +370,31 @@ export async function pandoc(args: PandocArgs[]) { return request(url, data); } +// **************************************** Notification **************************************** + +// /api/notification/pushMsg +// { +// "msg": "test", +// "timeout": 7000 +// } +export async function pushMsg(msg: string, timeout: number = 7000) { + let payload = { + msg: msg, + timeout: timeout + }; + let url = "/api/notification/pushMsg"; + return request(url, payload); +} + +export async function pushErrMsg(msg: string, timeout: number = 7000) { + let payload = { + msg: msg, + timeout: timeout + }; + let url = "/api/notification/pushErrMsg"; + return request(url, payload); +} + // **************************************** Network **************************************** export async function forwardProxy( url: string, method: string, payload: any, diff --git a/src/types/api.d.ts b/src/types/api.d.ts index 1163bb0..3c08859 100644 --- a/src/types/api.d.ts +++ b/src/types/api.d.ts @@ -1,3 +1,9 @@ +interface IResGetNotebookConf { + box: string; + conf: NotebookConf; + name: string; +} + interface IReslsNotebooks { notebooks: Notebook[]; } From cfa959c1a8adcbeb0eab659425b12a2be6bccb84 Mon Sep 17 00:00:00 2001 From: Frostime Date: Thu, 17 Aug 2023 00:10:25 +0800 Subject: [PATCH 066/158] Update api.ts --- src/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api.ts b/src/api.ts index 3939d14..4b12999 100644 --- a/src/api.ts +++ b/src/api.ts @@ -397,8 +397,8 @@ export async function pushErrMsg(msg: string, timeout: number = 7000) { // **************************************** Network **************************************** export async function forwardProxy( - url: string, method: string, payload: any, - headers: any[], timeout: number = 7000, contentType: string = "text/html" + url: string, method: string = 'GET', payload: any = {}, + headers: any[] = [], timeout: number = 7000, contentType: string = "text/html" ): Promise { let data = { url: url, From f114305718486dd388769fb68297f7c2c9f17266 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 27 Aug 2023 16:47:42 +0800 Subject: [PATCH 067/158] update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d1e0e5..7b229f4 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.7.9", + "siyuan": "0.8.1", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", From 57e50e1ca81a5500ab81cc498714f741334fe587 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 16:16:56 +0800 Subject: [PATCH 068/158] udpate version --- CHANGELOG.md | 18 +++++++++++++++++- package.json | 4 ++-- plugin.json | 4 ++-- src/i18n/en_US.json | 1 + src/i18n/zh_CN.json | 1 + 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3d0833..7310325 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,20 @@ -## 0.2.0 +# Changelog + +## 0.2.3 2023-09-05 + +* [Plugin API add openWindow and command.globalCallback](https://github.com/siyuan-note/siyuan/issues/9032) + +## 0.2.2 2023-08-29 + +* [Add plugin event bus `destroy-protyle`](https://github.com/siyuan-note/siyuan/issues/9033) +* [Add plugin event bus `loaded-protyle-dynamic`](https://github.com/siyuan-note/siyuan/issues/9021) + +## 0.2.1 2023-08-21 + +* [Plugin API add getOpenedTab method](https://github.com/siyuan-note/siyuan/issues/9002) +* [Plugin API custom.fn => custom.id in openTab](https://github.com/siyuan-note/siyuan/issues/8944) + +## 0.2.0 2023-08-15 * [Add plugin event bus `open-siyuan-url-plugin` and `open-siyuan-url-block`](https://github.com/siyuan-note/siyuan/pull/8927) diff --git a/package.json b/package.json index 7b229f4..528917a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.1.12", + "version": "0.2.3", "type": "module", "description": "", "repository": "", @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.8.1", + "siyuan": "0.8.3", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/plugin.json b/plugin.json index 5def5dc..41c9250 100644 --- a/plugin.json +++ b/plugin.json @@ -2,8 +2,8 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.1.12", - "minAppVersion": "2.9.0", + "version": "0.2.3", + "minAppVersion": "2.10.3", "backends": ["all"], "frontends": ["all"], "displayName": { diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 58f63ff..4f21f86 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -9,6 +9,7 @@ "removedData": "Data deleted", "confirmRemove": "Confirm to delete the data in ${name}?", "insertEmoji": "Insert Emoji", + "getTab": "Print out all opened custom tabs in the debugger", "name": "SiYuan", "hello": { "makesure": "Before using this template, please read the offical sample, make sure that you've known about the pipeline for plugin developing." diff --git a/src/i18n/zh_CN.json b/src/i18n/zh_CN.json index a1ee598..5a586e1 100644 --- a/src/i18n/zh_CN.json +++ b/src/i18n/zh_CN.json @@ -9,6 +9,7 @@ "removedData": "数据已删除", "confirmRemove": "确认删除 ${name} 中的数据?", "insertEmoji": "插入表情", + "getTab": "在日志中打印出已打开的所有自定义页签", "name": "思源", "hello": { "makesure": "使用这个模板之前,请阅读官方教程, 确保自己已经理解了插件的基本开发流程。" From 2fa17e4a7b8e307bb80a4ef7a21342f17b4c2b1c Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 16:21:00 +0800 Subject: [PATCH 069/158] update index.ts --- src/index.ts | 56 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 53bfdb5..02aa494 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ import { IModel, Setting, fetchPost, - Protyle + Protyle, openWindow } from "siyuan"; import "@/index.scss"; @@ -105,7 +105,7 @@ export default class PluginSample extends Plugin { this.addCommand({ langKey: "showDialog", - hotkey: "⇧⌘M", + hotkey: "⇧⌘O", callback: () => { this.showDialog(); }, @@ -119,6 +119,13 @@ export default class PluginSample extends Plugin { console.log(element, "dockCallback"); }, }); + this.addCommand({ + langKey: "getTab", + hotkey: "⇧⌘M", + globalCallback: () => { + console.log(this.getOpenedTab()); + }, + }); this.addDock({ config: { @@ -267,7 +274,7 @@ export default class PluginSample extends Plugin { }); if (!this.isMobile) { menu.addItem({ - icon: "iconLayoutBottom", + icon: "iconFace", label: "Open Custom Tab", click: () => { const tab = openTab({ @@ -278,14 +285,14 @@ export default class PluginSample extends Plugin { data: { text: "This is my custom tab", }, - fn: this.customTab + id: this.name + TAB_TYPE }, }); console.log(tab); } }); menu.addItem({ - icon: "iconLayoutBottom", + icon: "iconImage", label: "Open Asset Tab(open help first)", click: () => { const tab = openTab({ @@ -298,7 +305,7 @@ export default class PluginSample extends Plugin { } }); menu.addItem({ - icon: "iconLayoutBottom", + icon: "iconFile", label: "Open Doc Tab(open help first)", click: async () => { const tab = await openTab({ @@ -311,7 +318,7 @@ export default class PluginSample extends Plugin { } }); menu.addItem({ - icon: "iconLayoutBottom", + icon: "iconSearch", label: "Open Search Tab", click: () => { const tab = openTab({ @@ -324,7 +331,7 @@ export default class PluginSample extends Plugin { } }); menu.addItem({ - icon: "iconLayoutBottom", + icon: "iconRiffCard", label: "Open Card Tab", click: () => { const tab = openTab({ @@ -348,6 +355,15 @@ export default class PluginSample extends Plugin { }); } }); + menu.addItem({ + icon: "iconOpenWindow", + label: "Open Doc Window(open help first)", + click: () => { + openWindow({ + doc: {id: "20200812220555-lj3enxa"} + }); + } + }); } menu.addItem({ icon: "iconScrollHoriz", @@ -431,6 +447,30 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.on("loaded-protyle", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On loaded-protyle-dynamic", + click: () => { + this.eventBus.on("loaded-protyle-dynamic", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off loaded-protyle-dynamic", + click: () => { + this.eventBus.off("loaded-protyle-dynamic", this.eventBusLog); + } + }, { + icon: "iconSelect", + label: "On destroy-protyle", + click: () => { + this.eventBus.on("destroy-protyle", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off destroy-protyle", + click: () => { + this.eventBus.off("destroy-protyle", this.eventBusLog); + } }, { icon: "iconClose", label: "Off loaded-protyle", From 06f598b18bdbdc470ac9963b4d6cc945f437fb08 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 16:22:25 +0800 Subject: [PATCH 070/158] doc --- README.md | 2 +- README_zh_CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ed21ad..d4ddddb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.12](https://github.com/siyuan-note/plugin-sample/tree/v0.1.12) +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.3](https://github.com/siyuan-note/plugin-sample/tree/v0.2.3) diff --git a/README_zh_CN.md b/README_zh_CN.md index e3c15d8..c8ad1fd 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.1.12](https://github.com/siyuan-note/plugin-sample/tree/v0.1.12) +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.3](https://github.com/siyuan-note/plugin-sample/tree/v0.2.3) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 From cdb5085f356b0c52e634421a5c190b38429ff11a Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 18:03:59 +0800 Subject: [PATCH 071/158] setting-utils --- src/index.ts | 81 +++++++++++++----- src/libs/index.d.ts | 20 +++++ src/libs/setting-utils.ts | 176 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 22 deletions(-) create mode 100644 src/libs/index.d.ts create mode 100644 src/libs/setting-utils.ts diff --git a/src/index.ts b/src/index.ts index 02aa494..b98b48a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,8 @@ import "@/index.scss"; import HelloExample from "@/hello.svelte"; import SettingPannel from "@/libs/setting-panel.svelte"; +import { SettingUtils } from "./libs/setting-utils"; + const STORAGE_NAME = "menu-config"; const TAB_TYPE = "custom_tab"; const DOCK_TYPE = "dock_tab"; @@ -27,6 +29,7 @@ export default class PluginSample extends Plugin { private customTab: () => IModel; private isMobile: boolean; private blockIconEventBindThis = this.blockIconEvent.bind(this); + private settingUtils: SettingUtils; async onload() { this.data[STORAGE_NAME] = { readonlyText: "Readonly" }; @@ -158,32 +161,66 @@ export default class PluginSample extends Plugin { } }); - const textareaElement = document.createElement("textarea"); - this.setting = new Setting({ - confirmCallback: () => { - this.saveData(STORAGE_NAME, { readonlyText: textareaElement.value }); + this.settingUtils = new SettingUtils(this, STORAGE_NAME); + this.settingUtils.addItem({ + key: "Input", + value: "", + type: "textinput", + title: "Readonly text", + description: "Input description", + }); + this.settingUtils.addItem({ + key: "InputArea", + value: "", + type: "textarea", + title: "Readonly text", + description: "Input description", + }); + this.settingUtils.addItem({ + key: "Select", + value: 1, + type: "select", + title: "Readonly text", + description: "Select description", + select: { + options: [ + { + val: 1, + text: "Option 1" + }, + { + val: 2, + text: "Option 2" + } + ] } }); - this.setting.addItem({ - title: "Readonly text", - createActionElement: () => { - textareaElement.className = "b3-text-field fn__block"; - textareaElement.placeholder = "Readonly text in the menu"; - textareaElement.value = this.data[STORAGE_NAME].readonlyText; - return textareaElement; - }, + this.settingUtils.addItem({ + key: "Slider", + value: 50, + type: "slider", + title: "Slider text", + description: "Slider description", + slider: { + min: 0, + max: 100, + step: 1, + } }); - const btnaElement = document.createElement("button"); - btnaElement.className = "b3-button b3-button--outline fn__flex-center fn__size200"; - btnaElement.textContent = "Open"; - btnaElement.addEventListener("click", () => { - window.open("https://github.com/siyuan-note/plugin-sample-vite-svelte"); - }); - this.setting.addItem({ - title: "Open plugin url", - description: "Open plugin url in browser", - actionElement: btnaElement, + this.settingUtils.addItem({ + key: "Btn", + value: "", + type: "button", + title: "Button", + description: "Button description", + button: { + label: "Button", + callback: () => { + showMessage("Button clicked"); + } + } }); + this.settingUtils.load(); this.protyleSlash = [{ filter: ["insert emoji 😊", "插入表情 😊", "crbqwx"], diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts new file mode 100644 index 0000000..b46f655 --- /dev/null +++ b/src/libs/index.d.ts @@ -0,0 +1,20 @@ +type TSettingItemType = "checkbox" | "select" | "textinput" | "textarea" | "slider" | "button"; +interface ISettingItem { + key: string; + value: any; + type: TSettingItemType; + title: string; + description?: string; + slider?: { + min: number; + max: number; + step: number; + }; + select?: { + options: {val: any; text: string}[]; + }; + button?: { + label: string; + callback: () => void; + } +} diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts new file mode 100644 index 0000000..5c5638b --- /dev/null +++ b/src/libs/setting-utils.ts @@ -0,0 +1,176 @@ +import { Plugin, Setting } from 'siyuan'; + +export class SettingUtils { + plugin: Plugin; + name: string; + file: string; + + settings: Map = new Map(); + elements: Map = new Map(); + + constructor(plugin: Plugin, name?: string, width?: string, height?: string) { + this.name = name ?? 'settings'; + this.plugin = plugin; + this.file = this.name.endsWith('.json') ? this.name : `${this.name}.json`; + this.plugin.setting = new Setting({ + width: width, + height: height, + confirmCallback: () => { + for (let key of this.settings.keys()) { + this.updateValue(key); + } + let data = this.dump(); + this.plugin.data[this.name] = data; + this.save(); + } + }); + } + + async load() { + let data = await this.plugin.loadData(this.file); + if (data) { + for (let [key, item] of this.settings) { + item.value = data?.[key] ?? item.value; + } + } + } + + async save() { + let data = this.dump(); + await this.plugin.saveData(this.file, this.dump()); + return data; + } + + /** + * Get setting item value + * @param key key name + * @returns setting item value + */ + get(key: string) { + return this.settings.get(key)?.value; + } + + /** + * 将设置项目导出为 JSON 对象 + * @returns object + */ + dump(): Object { + let data: any = {}; + for (let [key, item] of this.settings) { + if (item.type === 'button') continue; + data[key] = item.value; + } + return data; + } + + addItem(item: ISettingItem) { + this.settings.set(item.key, item); + let itemElement: HTMLElement; + switch (item.type) { + case 'checkbox': + let element: HTMLInputElement = document.createElement('input'); + element.type = 'checkbox'; + element.checked = item.value; + element.className = "b3-switch fn__flex-center"; + itemElement = element; + break; + case 'select': + let selectElement: HTMLSelectElement = document.createElement('select'); + selectElement.className = "b3-select fn__flex-center fn__size200"; + for (let option of item.select?.options ?? []) { + let optionElement = document.createElement('option'); + optionElement.value = option.val; + optionElement.text = option.text; + selectElement.appendChild(optionElement); + } + selectElement.value = item.value; + itemElement = selectElement; + break; + case 'slider': + let sliderElement: HTMLInputElement = document.createElement('input'); + sliderElement.type = 'range'; + sliderElement.className = 'b3-slider fn__size200'; + sliderElement.ariaLabel = item.value; + sliderElement.min = item.slider?.min.toString() ?? '0'; + sliderElement.max = item.slider?.max.toString() ?? '100'; + sliderElement.step = item.slider?.step.toString() ?? '1'; + sliderElement.value = item.value; + itemElement = sliderElement; + break; + case 'textinput': + let textInputElement: HTMLInputElement = document.createElement('input'); + textInputElement.className = 'b3-text-field fn__flex-center fn__size200'; + textInputElement.value = item.value; + itemElement = textInputElement; + break; + case 'textarea': + let textareaElement: HTMLTextAreaElement = document.createElement('textarea'); + textareaElement.className = "b3-text-field fn__block"; + textareaElement.value = item.value; + itemElement = textareaElement; + break; + case 'button': + let buttonElement: HTMLButtonElement = document.createElement('button'); + buttonElement.className = "b3-button b3-button--outline fn__flex-center fn__size200"; + buttonElement.innerText = item.button?.label ?? 'Button'; + buttonElement.onclick = item.button?.callback ?? (() => {}); + itemElement = buttonElement; + break; + } + this.elements.set(item.key, itemElement); + this.plugin.setting.addItem({ + title: item.title, + description: item?.description, + createActionElement: () => { + let element = this.getElement(item.key); + return element; + } + }) + } + + private getElement(key: string) { + let item = this.settings.get(key); + let element = this.elements.get(key) as any; + switch (item.type) { + case 'checkbox': + element.checked = item.value; + break; + case 'select': + element.value = item.value; + break; + case 'slider': + element.value = item.value; + break; + case 'textinput': + element.value = item.value; + break; + case 'textarea': + element.value = item.value; + break; + } + return element; + } + + private updateValue(key: string) { + let item = this.settings.get(key); + let element = this.elements.get(key) as any; + switch (item.type) { + case 'checkbox': + item.value = element.checked; + break; + case 'select': + item.value = element.value; + break; + case 'slider': + item.value = element.value; + break; + case 'textinput': + item.value = element.value; + break; + case 'textarea': + item.value = element.value; + break; + } + } + +} \ No newline at end of file From 1a0b1018c55cd600916131846011de75b5d862c1 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 18:17:41 +0800 Subject: [PATCH 072/158] =?UTF-8?q?=E4=BC=98=E5=8C=96=20setting-utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 14 +++++++++++--- src/libs/setting-utils.ts | 20 ++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index b98b48a..f65b4e1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -176,6 +176,13 @@ export default class PluginSample extends Plugin { title: "Readonly text", description: "Input description", }); + this.settingUtils.addItem({ + key: "Check", + value: true, + type: "checkbox", + title: "Checkbox text", + description: "Check description", + }); this.settingUtils.addItem({ key: "Select", value: 1, @@ -220,7 +227,6 @@ export default class PluginSample extends Plugin { } } }); - this.settingUtils.load(); this.protyleSlash = [{ filter: ["insert emoji 😊", "插入表情 😊", "crbqwx"], @@ -235,12 +241,14 @@ export default class PluginSample extends Plugin { } onLayoutReady() { - this.loadData(STORAGE_NAME); + // this.loadData(STORAGE_NAME); + this.settingUtils.load(); console.log(`frontend: ${getFrontend()}; backend: ${getBackend()}`); } - onunload() { + async onunload() { console.log(this.i18n.byePlugin); + await this.settingUtils.save(); showMessage("Goodbye SiYuan Plugin"); console.log("onunload"); } diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 5c5638b..ff78af8 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2023 by frostime. All Rights Reserved. + * @Author : frostime + * @Date : 2023-09-16 18:05:00 + * @FilePath : /src/libs/setting-utils.ts + * @LastEditTime : 2023-09-16 18:17:03 + * @Description : A utility for siyuan plugin settings + */ + import { Plugin, Setting } from 'siyuan'; export class SettingUtils { @@ -33,6 +42,9 @@ export class SettingUtils { item.value = data?.[key] ?? item.value; } } + this.plugin.data[this.name] = this.dump(); + console.log(data); + return data; } async save() { @@ -89,12 +101,15 @@ export class SettingUtils { case 'slider': let sliderElement: HTMLInputElement = document.createElement('input'); sliderElement.type = 'range'; - sliderElement.className = 'b3-slider fn__size200'; + sliderElement.className = 'b3-slider fn__size200 b3-tooltips b3-tooltips__n'; sliderElement.ariaLabel = item.value; sliderElement.min = item.slider?.min.toString() ?? '0'; sliderElement.max = item.slider?.max.toString() ?? '100'; sliderElement.step = item.slider?.step.toString() ?? '1'; sliderElement.value = item.value; + sliderElement.onchange = () => { + sliderElement.ariaLabel = sliderElement.value; + } itemElement = sliderElement; break; case 'textinput': @@ -154,6 +169,7 @@ export class SettingUtils { private updateValue(key: string) { let item = this.settings.get(key); let element = this.elements.get(key) as any; + console.log(element, element?.value); switch (item.type) { case 'checkbox': item.value = element.checked; @@ -162,7 +178,7 @@ export class SettingUtils { item.value = element.value; break; case 'slider': - item.value = element.value; + item.value = parseInt(element.value); break; case 'textinput': item.value = element.value; From 05c9f269e27341cc1d376f149ea12e65fa05888f Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 16 Sep 2023 18:37:00 +0800 Subject: [PATCH 073/158] update doc --- README.md | 2 ++ README_zh_CN.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index d4ddddb..279abc8 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,8 @@ The github action is included in this sample, you can use it to publish your new ## How to remove svelte dependencies +> Pure vite without svelte: https://github.com/frostime/plugin-sample-vite + This plugin is packaged in vite and provides a dependency on the svelte framework. However, in practice some developers may not want to use svelte and only want to use the vite package. In fact you can use this template without using svelte without any modifications at all. The compilation-related parts of the svelte compilation are loaded into the vite workflow as plugins, so even if you don't have svelte in your project, it won't matter much. diff --git a/README_zh_CN.md b/README_zh_CN.md index c8ad1fd..198be1d 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -195,6 +195,8 @@ PR 社区集市仓库。 ## 如何去掉 svelte 依赖 +> 无 Svelte 依赖版: https://github.com/frostime/plugin-sample-vite + 本插件使用 vite 打包,并提供了 svelte 框架依赖。不过实际情况下可能有些开发者并不想要 svelte,只希望使用 vite 打包。 实际上你可以完全不做任何修改,就可以在不使用 svelte 的前提下使用这个模板。与 svelte 编译的编译相关的部分是以插件的形式载入到 vite 的工作流中,所以即使你的项目里面没有 svelte,也不会有太大的影响。 From c2d3812e191d71d26178b729b5039a008e8c2585 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 27 Oct 2023 20:41:40 +0800 Subject: [PATCH 074/158] misc --- CHANGELOG.md | 16 ++++++++++++++++ README.md | 2 +- README_zh_CN.md | 2 +- package.json | 8 ++++---- plugin.json | 15 +++++++++++---- src/i18n/en_US.json | 1 + src/i18n/zh_CN.json | 1 + 7 files changed, 35 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7310325..aadd6ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,23 @@ # Changelog +## 0.2.7 2023-10 + +## 0.2.6 2023-10-24 + +* [Deprecated `loaded-protyle` use `loaded-protyle-static` instead](https://github.com/siyuan-note/siyuan/issues/9468) + +## 0.2.5 2023-10-10 + +* [Add plugin event bus `open-menu-doctree`](https://github.com/siyuan-note/siyuan/issues/9351) + +## 0.2.4 2023-09-19 + +* Supports use in windows +* [Add plugin function `transaction`](https://github.com/siyuan-note/siyuan/issues/9172) + ## 0.2.3 2023-09-05 +* [Add plugin function `transaction`](https://github.com/siyuan-note/siyuan/issues/9172) * [Plugin API add openWindow and command.globalCallback](https://github.com/siyuan-note/siyuan/issues/9032) ## 0.2.2 2023-08-29 diff --git a/README.md b/README.md index 279abc8..4a2b21b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.3](https://github.com/siyuan-note/plugin-sample/tree/v0.2.3) +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.6](https://github.com/siyuan-note/plugin-sample/tree/v0.2.6) diff --git a/README_zh_CN.md b/README_zh_CN.md index 198be1d..bf72da3 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.3](https://github.com/siyuan-note/plugin-sample/tree/v0.2.3) +> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.6](https://github.com/siyuan-note/plugin-sample/tree/v0.2.6) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 diff --git a/package.json b/package.json index 528917a..bfe4eb0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.2.3", + "version": "0.2.6", "type": "module", - "description": "", + "description": "This is a sample plugin based on vite and svelte for Siyuan (https://b3log.org/siyuan)", "repository": "", "homepage": "", "author": "", - "license": "GPL-3.0", + "license": "MIT", "scripts": { "make-link": "node --no-warnings ./scripts/make_dev_link.js", "dev": "vite build --watch", @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.8.3", + "siyuan": "0.8.7", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/plugin.json b/plugin.json index 41c9250..04236da 100644 --- a/plugin.json +++ b/plugin.json @@ -2,10 +2,17 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.2.3", - "minAppVersion": "2.10.3", - "backends": ["all"], - "frontends": ["all"], + "version": "0.2.6", + "minAppVersion": "2.10.12", + "backends": [ + "windows", + "linux", + "darwin" + ], + "frontends": [ + "desktop", + "desktop-window" + ], "displayName": { "en_US": "Plugin sample with vite and svelte", "zh_CN": "插件样例 vite + svelte 版" diff --git a/src/i18n/en_US.json b/src/i18n/en_US.json index 4f21f86..c7ed102 100644 --- a/src/i18n/en_US.json +++ b/src/i18n/en_US.json @@ -9,6 +9,7 @@ "removedData": "Data deleted", "confirmRemove": "Confirm to delete the data in ${name}?", "insertEmoji": "Insert Emoji", + "removeSpace": "Remove Space", "getTab": "Print out all opened custom tabs in the debugger", "name": "SiYuan", "hello": { diff --git a/src/i18n/zh_CN.json b/src/i18n/zh_CN.json index 5a586e1..49a7af8 100644 --- a/src/i18n/zh_CN.json +++ b/src/i18n/zh_CN.json @@ -9,6 +9,7 @@ "removedData": "数据已删除", "confirmRemove": "确认删除 ${name} 中的数据?", "insertEmoji": "插入表情", + "removeSpace": "移除空格", "getTab": "在日志中打印出已打开的所有自定义页签", "name": "思源", "hello": { From 8be20e023ce21b890c172f59fc5c8e560abd0f15 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 27 Oct 2023 20:52:25 +0800 Subject: [PATCH 075/158] update typescript --- src/index.ts | 69 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/index.ts b/src/index.ts index f65b4e1..353d472 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ import { IModel, Setting, fetchPost, - Protyle, openWindow + Protyle, openWindow, IOperation } from "siyuan"; import "@/index.scss"; @@ -68,7 +68,7 @@ export default class PluginSample extends Plugin { }); const statusIconTemp = document.createElement("template"); - statusIconTemp.innerHTML = `
+ statusIconTemp.innerHTML = `
@@ -272,19 +272,38 @@ export default class PluginSample extends Plugin { }); } + private eventBusPaste(event: any) { + // 如果需异步处理请调用 preventDefault, 否则会进行默认处理 + event.preventDefault(); + // 如果使用了 preventDefault,必须调用 resolve,否则程序会卡死 + event.detail.resolve({ + textPlain: event.detail.textPlain.trim(), + }); + } + private eventBusLog({ detail }: any) { console.log(detail); } private blockIconEvent({ detail }: any) { - const ids: string[] = []; - detail.blockElements.forEach((item: HTMLElement) => { - ids.push(item.getAttribute("data-node-id")); - }); detail.menu.addItem({ iconHTML: "", - type: "readonly", - label: "IDs
" + ids.join("
"), + label: this.i18n.removeSpace, + click: () => { + const doOperations: IOperation[] = []; + detail.blockElements.forEach((item: HTMLElement) => { + const editElement = item.querySelector('[contenteditable="true"]'); + if (editElement) { + editElement.textContent = editElement.textContent.replace(/ /g, ""); + doOperations.push({ + id: item.dataset.nodeId, + data: item.outerHTML, + action: "update" + }); + } + }); + detail.protyle.getInstance().transaction(doOperations); + } }); } @@ -488,9 +507,15 @@ export default class PluginSample extends Plugin { } }, { icon: "iconSelect", - label: "On loaded-protyle", + label: "On loaded-protyle-static", click: () => { - this.eventBus.on("loaded-protyle", this.eventBusLog); + this.eventBus.on("loaded-protyle-static", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off loaded-protyle-static", + click: () => { + this.eventBus.off("loaded-protyle-static", this.eventBusLog); } }, { icon: "iconSelect", @@ -517,10 +542,16 @@ export default class PluginSample extends Plugin { this.eventBus.off("destroy-protyle", this.eventBusLog); } }, { - icon: "iconClose", - label: "Off loaded-protyle", + icon: "iconSelect", + label: "On open-menu-doctree", click: () => { - this.eventBus.off("loaded-protyle", this.eventBusLog); + this.eventBus.on("open-menu-doctree", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off open-menu-doctree", + click: () => { + this.eventBus.off("open-menu-doctree", this.eventBusLog); } }, { icon: "iconSelect", @@ -630,6 +661,18 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.off("input-search", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On paste", + click: () => { + this.eventBus.on("paste", this.eventBusPaste); + } + }, { + icon: "iconClose", + label: "Off paste", + click: () => { + this.eventBus.off("paste", this.eventBusPaste); + } }, { icon: "iconSelect", label: "On open-siyuan-url-plugin", From bc635356dc37fb74e7a34a6ba2912931f27872f7 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 27 Oct 2023 21:04:12 +0800 Subject: [PATCH 076/158] fix protyle bug --- src/hello.svelte | 2 +- src/index.ts | 41 ++++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/hello.svelte b/src/hello.svelte index 6d10108..63a54a2 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -6,7 +6,7 @@ export let app; let time: string = ""; - let ver: string; + let ver: string = ""; let divProtyle: HTMLDivElement; let protyle: any; diff --git a/src/index.ts b/src/index.ts index 353d472..aa7bd75 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,27 +85,6 @@ export default class PluginSample extends Plugin { element: statusIconTemp.content.firstElementChild as HTMLElement, }); - let tabDiv = document.createElement("div"); - new HelloExample({ - target: tabDiv, - props: { - app: this.app, - } - }); - this.customTab = this.addTab({ - type: TAB_TYPE, - init() { - this.element.appendChild(tabDiv); - console.log(this.element); - }, - beforeDestroy() { - console.log("before destroy tab:", TAB_TYPE); - }, - destroy() { - console.log("destroy tab:", TAB_TYPE); - } - }); - this.addCommand({ langKey: "showDialog", hotkey: "⇧⌘O", @@ -244,6 +223,26 @@ export default class PluginSample extends Plugin { // this.loadData(STORAGE_NAME); this.settingUtils.load(); console.log(`frontend: ${getFrontend()}; backend: ${getBackend()}`); + let tabDiv = document.createElement("div"); + new HelloExample({ + target: tabDiv, + props: { + app: this.app, + } + }); + this.customTab = this.addTab({ + type: TAB_TYPE, + init() { + this.element.appendChild(tabDiv); + console.log(this.element); + }, + beforeDestroy() { + console.log("before destroy tab:", TAB_TYPE); + }, + destroy() { + console.log("destroy tab:", TAB_TYPE); + } + }); } async onunload() { From c580fb7a0040ecc6987bd00205927af76d790404 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 27 Oct 2023 22:11:43 +0800 Subject: [PATCH 077/158] update setting utils --- src/libs/setting-utils.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index ff78af8..17cc555 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -17,7 +17,7 @@ export class SettingUtils { settings: Map = new Map(); elements: Map = new Map(); - constructor(plugin: Plugin, name?: string, width?: string, height?: string) { + constructor(plugin: Plugin, name?: string, width?: string, height?: string, callback?: (data: any) => void) { this.name = name ?? 'settings'; this.plugin = plugin; this.file = this.name.endsWith('.json') ? this.name : `${this.name}.json`; @@ -29,8 +29,12 @@ export class SettingUtils { this.updateValue(key); } let data = this.dump(); - this.plugin.data[this.name] = data; - this.save(); + if (callback !== undefined) { + callback(data); + } else { + this.plugin.data[this.name] = data; + this.save(); + } } }); } From 3343eb7e5c57c9bed51aa199bca6299e74f70585 Mon Sep 17 00:00:00 2001 From: frostime Date: Fri, 27 Oct 2023 22:12:43 +0800 Subject: [PATCH 078/158] update --- src/libs/setting-utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 17cc555..79f35f4 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-09-16 18:05:00 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2023-09-16 18:17:03 + * @LastEditTime : 2023-10-27 22:12:37 * @Description : A utility for siyuan plugin settings */ @@ -17,7 +17,7 @@ export class SettingUtils { settings: Map = new Map(); elements: Map = new Map(); - constructor(plugin: Plugin, name?: string, width?: string, height?: string, callback?: (data: any) => void) { + constructor(plugin: Plugin, name?: string, callback?: (data: any) => void, width?: string, height?: string) { this.name = name ?? 'settings'; this.plugin = plugin; this.file = this.name.endsWith('.json') ? this.name : `${this.name}.json`; From 7d95423d24ba8154b0ab27e75619419680af6842 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 28 Oct 2023 16:52:03 +0800 Subject: [PATCH 079/158] update --- src/libs/setting-utils.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 79f35f4..b092a27 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-09-16 18:05:00 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2023-10-27 22:12:37 + * @LastEditTime : 2023-10-28 16:52:01 * @Description : A utility for siyuan plugin settings */ @@ -41,13 +41,13 @@ export class SettingUtils { async load() { let data = await this.plugin.loadData(this.file); + console.debug('Load config:', data); if (data) { for (let [key, item] of this.settings) { item.value = data?.[key] ?? item.value; } } this.plugin.data[this.name] = this.dump(); - console.log(data); return data; } @@ -159,6 +159,7 @@ export class SettingUtils { break; case 'slider': element.value = item.value; + element.ariaLabel = item.value; break; case 'textinput': element.value = item.value; @@ -173,7 +174,7 @@ export class SettingUtils { private updateValue(key: string) { let item = this.settings.get(key); let element = this.elements.get(key) as any; - console.log(element, element?.value); + // console.debug(element, element?.value); switch (item.type) { case 'checkbox': item.value = element.checked; @@ -182,7 +183,7 @@ export class SettingUtils { item.value = element.value; break; case 'slider': - item.value = parseInt(element.value); + item.value = element.value; break; case 'textinput': item.value = element.value; From 5f59ffefe42923a655b8381a9cf12c0bc6907fb6 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 28 Oct 2023 18:22:56 +0800 Subject: [PATCH 080/158] update keywords --- plugin.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugin.json b/plugin.json index 04236da..f3e2682 100644 --- a/plugin.json +++ b/plugin.json @@ -29,5 +29,8 @@ "custom": [ "https://afdian.net/a/frostime" ] - } + }, + "keywords": [ + "plugin", "sample", "插件样例" + ] } From 3de8bc61344ec06257d10c5b2c435ca2df831b52 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 19 Nov 2023 11:49:25 +0800 Subject: [PATCH 081/158] =?UTF-8?q?=F0=9F=90=B3=20chore(update):=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A8=A1=E6=9D=BF=E7=9A=84=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E3=80=81=E6=96=87=E6=A1=A3=E7=AD=89=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++++-- README_zh_CN.md | 8 ++++++-- package.json | 2 +- plugin.json | 4 ++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4a2b21b..4f79c10 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.6](https://github.com/siyuan-note/plugin-sample/tree/v0.2.6) +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.8](https://github.com/siyuan-note/plugin-sample/tree/v0.2.8) @@ -98,7 +98,10 @@ conveniently. "custom": [ "https://ld246.com/sponsor" ] - } + }, + "keywords": [ + "sample", "示例" + ] } ``` @@ -137,6 +140,7 @@ conveniently. * `patreon`: Patreon name * `github`: GitHub login name * `custom`: Custom sponsorship link list +* `keywords`: Search keyword list, used for marketplace search function ## Package diff --git a/README_zh_CN.md b/README_zh_CN.md index bf72da3..5b3e6e8 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例和 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.6](https://github.com/siyuan-note/plugin-sample/tree/v0.2.6) +> 本例同 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.2.8](https://github.com/siyuan-note/plugin-sample/tree/v0.2.8) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 @@ -95,7 +95,10 @@ "custom": [ "https://ld246.com/sponsor" ] - } + }, + "keywords": [ + "sample", "示例" + ] } ``` @@ -133,6 +136,7 @@ * `patreon`:Patreon 名称 * `github`:GitHub 登录名 * `custom`:自定义赞助链接列表 +* `keywords`:搜索关键字列表,用于集市搜索功能 ## 打包 diff --git a/package.json b/package.json index bfe4eb0..e4c06a2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.62.1", - "siyuan": "0.8.7", + "siyuan": "0.8.8", "svelte": "^3.57.0", "ts-node": "^10.9.1", "typescript": "^5.0.4", diff --git a/plugin.json b/plugin.json index f3e2682..7bb3bea 100644 --- a/plugin.json +++ b/plugin.json @@ -2,8 +2,8 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.2.6", - "minAppVersion": "2.10.12", + "version": "0.2.8", + "minAppVersion": "2.10.14", "backends": [ "windows", "linux", From 8e841a4a905f16c9accf2150e1e89b905fab0e5d Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 19 Nov 2023 12:17:42 +0800 Subject: [PATCH 082/158] =?UTF-8?q?=E2=9C=A8=20feat(update):=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=8F=92=E4=BB=B6=E6=A8=A1=E6=9D=BF=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 10 +++++++++- src/api.ts | 1 - src/hello.svelte | 5 +++++ src/index.ts | 24 ++++++++++++++++++++---- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadd6ee..4411dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog -## 0.2.7 2023-10 +## 0.2.8 2023-11-15 + +* [`resize` cannot be triggered after dragging to unpin the dock](https://github.com/siyuan-note/siyuan/issues/9640) + +## 0.2.7 2023-10-31 + +* [Export `Constants` to plugin](https://github.com/siyuan-note/siyuan/issues/9555) +* [Add plugin `app.appId`](https://github.com/siyuan-note/siyuan/issues/9538) +* [Add plugin event bus `switch-protyle`](https://github.com/siyuan-note/siyuan/issues/9454) ## 0.2.6 2023-10-24 diff --git a/src/api.ts b/src/api.ts index 4b12999..7202000 100644 --- a/src/api.ts +++ b/src/api.ts @@ -6,7 +6,6 @@ * API 文档见 [API_zh_CN.md](https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md) */ -import { time } from "console"; import { fetchSyncPost, IWebSocketData } from "siyuan"; diff --git a/src/hello.svelte b/src/hello.svelte index 63a54a2..cc9f0dd 100644 --- a/src/hello.svelte +++ b/src/hello.svelte @@ -36,6 +36,11 @@
+
appId:
+
+
${app?.appId}
+
+
API demo:
diff --git a/src/index.ts b/src/index.ts index aa7bd75..6fb4f0a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,9 +9,10 @@ import { getFrontend, getBackend, IModel, - Setting, - fetchPost, - Protyle, openWindow, IOperation + Protyle, + openWindow, + IOperation, + Constants } from "siyuan"; import "@/index.scss"; @@ -120,6 +121,9 @@ export default class PluginSample extends Plugin { text: "This is my custom dock" }, type: DOCK_TYPE, + resize() { + console.log(DOCK_TYPE + " resize"); + }, init() { this.element.innerHTML = `
@@ -308,7 +312,7 @@ export default class PluginSample extends Plugin { private showDialog() { let dialog = new Dialog({ - title: "Hello World", + title: `SiYuan ${Constants.SIYUAN_VERSION}`, content: `
`, width: this.isMobile ? "92vw" : "720px", destroyCallback(options) { @@ -528,6 +532,18 @@ export default class PluginSample extends Plugin { click: () => { this.eventBus.off("loaded-protyle-dynamic", this.eventBusLog); } + }, { + icon: "iconSelect", + label: "On switch-protyle", + click: () => { + this.eventBus.on("switch-protyle", this.eventBusLog); + } + }, { + icon: "iconClose", + label: "Off switch-protyle", + click: () => { + this.eventBus.off("switch-protyle", this.eventBusLog); + } }, { icon: "iconSelect", label: "On destroy-protyle", From 962f879fa25d0e682f6da3d78f91467109846b49 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 19 Nov 2023 12:30:11 +0800 Subject: [PATCH 083/158] =?UTF-8?q?=E2=9C=A8=20feat(api):=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=90=8E=E7=AB=AFAPI=20`getIDsByHPath`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/api.ts b/src/api.ts index 7202000..9a4ff3f 100644 --- a/src/api.ts +++ b/src/api.ts @@ -131,6 +131,16 @@ export async function getHPathByID(id: BlockId): Promise { return request(url, data); } + +export async function getIDsByHPath(notebook: NotebookId, path: string): Promise { + let data = { + notebook: notebook, + path: path + }; + let url = '/api/filetree/getIDsByHPath'; + return request(url, data); +} + // **************************************** Asset Files **************************************** export async function upload(assetsDirPath: string, files: any[]): Promise { From 7f57c40db532464a53e9699de38ef24da5fd9a4d Mon Sep 17 00:00:00 2001 From: Frostime Date: Tue, 21 Nov 2023 19:55:28 +0800 Subject: [PATCH 084/158] =?UTF-8?q?doc:=20=E5=AE=A3=E4=BC=A0=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E6=97=A0=20svelte=20=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ README_zh_CN.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 4f79c10..b7da17d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ 1. Using vite for packaging 2. Use symbolic linking instead of putting the project into the plugins directory program development 3. Built-in support for the svelte framework + + > If don't want svelte, turn to this template: [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) + 4. Provides a github action template to automatically generate package.zip and upload to new release diff --git a/README_zh_CN.md b/README_zh_CN.md index 5b3e6e8..950f11c 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -9,6 +9,9 @@ 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 3. 内置对 svelte 框架的支持 + + > 如果不想要 svelte,请移步 [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) + 4. 提供一个github action 模板,能自动生成package.zip并上传到新版本中 ## 开始 From ec8d768d2d9deb448f6a7932472e6f7ce308a89c Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 27 Nov 2023 09:28:36 +0800 Subject: [PATCH 085/158] =?UTF-8?q?:construction=5Fworker:=20ci:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20vite=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vite.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/vite.config.ts b/vite.config.ts index 2af9f2f..f83f26c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -57,6 +57,7 @@ export default defineConfig({ // 在这里自定义变量 define: { "process.env.DEV_MODE": `"${isWatch}"`, + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }, build: { From b0d28e2513d6edc2e221ce1ccdfdea101ba450fa Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 28 Nov 2023 21:24:19 +0800 Subject: [PATCH 086/158] =?UTF-8?q?:hammer:=20refactor(setting):=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BA=86Svelte=E8=AE=BE=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 SettingPanel 作为基本模板 - 更改了 settingitem 的类型定义 --- src/index.ts | 18 ++--- src/libs/index.d.ts | 5 +- src/libs/setting-item.svelte | 14 +++- src/libs/setting-panel.svelte | 139 +++++++++++----------------------- src/libs/setting-utils.ts | 10 ++- src/setting-example.svelte | 99 ++++++++++++++++++++++++ 6 files changed, 169 insertions(+), 116 deletions(-) create mode 100644 src/setting-example.svelte diff --git a/src/index.ts b/src/index.ts index 6fb4f0a..349aca6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,7 +17,7 @@ import { import "@/index.scss"; import HelloExample from "@/hello.svelte"; -import SettingPannel from "@/libs/setting-panel.svelte"; +import SettingExample from "@/setting-example.svelte"; import { SettingUtils } from "./libs/setting-utils"; @@ -173,16 +173,10 @@ export default class PluginSample extends Plugin { title: "Readonly text", description: "Select description", select: { - options: [ - { - val: 1, - text: "Option 1" - }, - { - val: 2, - text: "Option 2" - } - ] + options: { + 1: "Option 1", + 2: "Option 2" + } } }); this.settingUtils.addItem({ @@ -270,7 +264,7 @@ export default class PluginSample extends Plugin { pannel.$destroy(); } }); - let pannel = new SettingPannel({ + let pannel = new SettingExample({ target: dialog.element.querySelector("#SettingPanel"), }); } diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index b46f655..379d841 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -5,13 +5,16 @@ interface ISettingItem { type: TSettingItemType; title: string; description?: string; + text?: { + placeholder?: string; + }; slider?: { min: number; max: number; step: number; }; select?: { - options: {val: any; text: string}[]; + options: { [key: string | number]: string }; }; button?: { label: string; diff --git a/src/libs/setting-item.svelte b/src/libs/setting-item.svelte index b728cf4..6f17890 100644 --- a/src/libs/setting-item.svelte +++ b/src/libs/setting-item.svelte @@ -2,13 +2,13 @@ import { createEventDispatcher } from "svelte"; export let type: string; // Setting Type export let title: string; // Displayint Setting Title - export let text: string; // Displaying Setting Text + export let description: string; // Displaying Setting Text export let settingKey: string; export let settingValue: any; //Optional export let placeholder: string = ""; // Use it if type is input - export let options: { [key: string]: string } = {}; // Use it if type is select + export let options: { [key: string | number]: string } = {}; // Use it if type is select export let slider: { min: number; max: number; @@ -30,7 +30,7 @@
{title}
- {text} + {@html description}
@@ -53,6 +53,14 @@ bind:value={settingValue} on:change={changed} /> + {:else if type === "number"} + {:else if type === "button"} {:else if type === "select"} diff --git a/src/libs/setting-panel.svelte b/src/libs/setting-panel.svelte index fc5e508..038d890 100644 --- a/src/libs/setting-panel.svelte +++ b/src/libs/setting-panel.svelte @@ -3,7 +3,7 @@ Author : frostime Date : 2023-07-01 19:23:50 FilePath : /src/libs/setting-panel.svelte - LastEditTime : 2023-11-28 21:45:10 + LastEditTime : 2024-04-27 16:46:49 Description : --> @@ -83,6 +99,7 @@ settingItems={SettingItems} display={focusGroup === groups[0]} on:changed={onChanged} + on:click={({ detail }) => { console.debug("Click:", detail.key); }} >
💡 This is our default settings. From 56be185458ea2c96ca276305e3c6b687c4d4f1e6 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 28 Apr 2024 17:48:49 +0800 Subject: [PATCH 124/158] =?UTF-8?q?=E2=9C=A8=20misc(setting-utils)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 14 ++--- src/libs/setting-utils.ts | 114 ++++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9a47d54..49cc9c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -164,13 +164,6 @@ export default class PluginSample extends Plugin { }); this.settingUtils = new SettingUtils(this, STORAGE_NAME); - - try { - this.settingUtils.load(); - } catch (error) { - console.error("Error loading settings storage, probably empty config json:", error); - } - this.settingUtils.addItem({ key: "Input", value: "", @@ -274,6 +267,13 @@ export default class PluginSample extends Plugin { description: this.i18n.hintDesc, }); + try { + this.settingUtils.load(); + } catch (error) { + console.error("Error loading settings storage, probably empty config json:", error); + } + + this.protyleSlash = [{ filter: ["insert emoji 😊", "插入表情 😊", "crbqwx"], html: `
${this.i18n.insertEmoji}😊
`, diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index ddb576c..c5bff05 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,12 +3,44 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-27 16:38:09 + * @LastEditTime : 2024-04-28 17:43:43 * @Description : */ import { Plugin, Setting } from 'siyuan'; +const valueOf = (ele: HTMLElement) => { + if (ele instanceof HTMLInputElement) { + if (ele.type === 'checkbox') { + return ele.checked; + } else { + return ele.value; + } + } else if (ele instanceof HTMLSelectElement) { + return ele.value; + } else if (ele instanceof HTMLTextAreaElement) { + return ele.value; + } else { + return ele.textContent; + } +} + +const setValue = (ele: HTMLElement, value: any) => { + if (ele instanceof HTMLInputElement) { + if (ele.type === 'checkbox') { + ele.checked = value; + } else { + ele.value = value; + } + } else if (ele instanceof HTMLSelectElement) { + ele.value = value; + } else if (ele instanceof HTMLTextAreaElement) { + ele.value = value; + } else { + ele.textContent = value; + } +} + export class SettingUtils { plugin: Plugin; name: string; @@ -31,10 +63,9 @@ export class SettingUtils { let data = this.dump(); if (callback !== undefined) { callback(data); - } else { - this.plugin.data[this.name] = data; - this.save(); } + this.plugin.data[this.name] = data; + this.save(); }, destroyCallback: () => { //从值恢复元素 @@ -73,21 +104,6 @@ export class SettingUtils { return this.settings.get(key)?.value; } - /** - * Read in real time, - * do not read from the configuration file - * @param key key name - * @returns value in html - */ - take(key: string) { - let element = this.elements.get(key) as any; - if (!element){ - return - } - this.settings.set(key, element.value) - return element.value - } - /** * Set data to this.settings, * but do not save it to the configuration file @@ -113,20 +129,38 @@ export class SettingUtils { if (item) { item.value = value; this.updateElementFromValue(key); - await this.save() + await this.save(); } } + /** + * Read in the value of element instead of setting obj in real time + * @param key key name + * @param apply whether to apply the value to the setting object + * if true, the value will be applied to the setting object + * @returns value in html + */ + take(key: string, apply: boolean = false) { + let element = this.elements.get(key) as any; + if (!element){ + return + } + if (apply) { + this.updateValueFromElement(key); + } + return valueOf(element) + } + /** * Read data from html and save it * @param key key name * @param value value - * @return value in html + * @return value in html */ async takeAndSave(key: string) { - let value = this.take(key) - await this.save() - return value + let value = this.take(key, true); + await this.save(); + return value; } /** @@ -248,6 +282,7 @@ export class SettingUtils { title: item.title, description: item?.description, createActionElement: () => { + this.updateElementFromValue(item.key); let element = this.getElement(item.key); return element; } @@ -255,40 +290,19 @@ export class SettingUtils { } /** - * Set the value in the setting to the value of the element - * and return the element information + * return the setting element * @param key key name * @returns element */ getElement(key: string) { - let item = this.settings.get(key); + // let item = this.settings.get(key); let element = this.elements.get(key) as any; - switch (item.type) { - case 'checkbox': - element.value = element.checked ? true : false; - element.checked = item.value; - break; - case 'select': - element.value = item.value; - break; - case 'slider': - element.value = item.value; - element.ariaLabel = item.value; - break; - case 'textinput': - element.value = item.value; - break; - case 'textarea': - element.value = item.value; - break; - } return element; } private updateValueFromElement(key: string) { let item = this.settings.get(key); let element = this.elements.get(key) as any; - // console.debug(element, element?.value); switch (item.type) { case 'checkbox': item.value = element.checked; @@ -305,6 +319,9 @@ export class SettingUtils { case 'textarea': item.value = element.value; break; + case 'number': + item.value = parseInt(element.value); + break; } } @@ -327,6 +344,9 @@ export class SettingUtils { case 'textarea': element.value = item.value; break; + case 'number': + element.value = item.value; + break; } } } \ No newline at end of file From 57cc62f7b516a9331ad1cfaeb7f5fce3f163ead5 Mon Sep 17 00:00:00 2001 From: frostime Date: Sun, 28 Apr 2024 17:50:52 +0800 Subject: [PATCH 125/158] =?UTF-8?q?=F0=9F=8E=A8=20refactor:=20setting-util?= =?UTF-8?q?s=20args?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 4 +++- src/libs/setting-utils.ts | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 49cc9c4..704ad00 100644 --- a/src/index.ts +++ b/src/index.ts @@ -163,7 +163,9 @@ export default class PluginSample extends Plugin { } }); - this.settingUtils = new SettingUtils(this, STORAGE_NAME); + this.settingUtils = new SettingUtils({ + plugin: this, name: STORAGE_NAME + }); this.settingUtils.addItem({ key: "Input", value: "", diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index c5bff05..c839d1a 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-28 17:43:43 + * @LastEditTime : 2024-04-28 17:49:31 * @Description : */ @@ -49,20 +49,26 @@ export class SettingUtils { settings: Map = new Map(); elements: Map = new Map(); - constructor(plugin: Plugin, name?: string, callback?: (data: any) => void, width?: string, height?: string) { - this.name = name ?? 'settings'; - this.plugin = plugin; + constructor(args: { + plugin: Plugin, + name?: string, + callback?: (data: any) => void, + width?: string, + height?: string + }) { + this.name = args.name ?? 'settings'; + this.plugin = args.plugin; this.file = this.name.endsWith('.json') ? this.name : `${this.name}.json`; this.plugin.setting = new Setting({ - width: width, - height: height, + width: args.width, + height: args.height, confirmCallback: () => { for (let key of this.settings.keys()) { this.updateValueFromElement(key); } let data = this.dump(); - if (callback !== undefined) { - callback(data); + if (args.callback !== undefined) { + args.callback(data); } this.plugin.data[this.name] = data; this.save(); From 0df9ec29ea61f34655028b1f6ddaa331e1f8c3d0 Mon Sep 17 00:00:00 2001 From: frostime Date: Mon, 29 Apr 2024 17:43:02 +0800 Subject: [PATCH 126/158] =?UTF-8?q?=E2=9C=A8=20feat(setting-utils):=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/index.d.ts | 1 + src/libs/setting-utils.ts | 148 ++++++++++++++++++++++---------------- 2 files changed, 89 insertions(+), 60 deletions(-) diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index cdb1ea3..9e0b889 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -19,4 +19,5 @@ interface ISettingItem { label: string; callback: () => void; } + createElement?: (currentVal: any) => HTMLElement; } diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index c839d1a..f43ab36 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,35 +3,45 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-28 17:49:31 + * @LastEditTime : 2024-04-29 17:17:19 * @Description : */ import { Plugin, Setting } from 'siyuan'; -const valueOf = (ele: HTMLElement) => { +const valueOf = (ele: HTMLElement, parseNumber: Function=parseInt) => { + let val: any = null; if (ele instanceof HTMLInputElement) { if (ele.type === 'checkbox') { - return ele.checked; + val = ele.checked; } else { - return ele.value; + if (ele.type === 'number') { + val = parseNumber(ele.value); + } else { + val = ele.value; + } } } else if (ele instanceof HTMLSelectElement) { - return ele.value; + val = ele.value; } else if (ele instanceof HTMLTextAreaElement) { - return ele.value; + val = ele.value; } else { - return ele.textContent; + val = ele?.textContent; } + return val; } const setValue = (ele: HTMLElement, value: any) => { + if (ele === null || ele === undefined) return; if (ele instanceof HTMLInputElement) { if (ele.type === 'checkbox') { ele.checked = value; } else { ele.value = value; } + if (ele.type === 'range') { + ele.ariaLabel = value; + } } else if (ele instanceof HTMLSelectElement) { ele.value = value; } else if (ele instanceof HTMLTextAreaElement) { @@ -74,7 +84,7 @@ export class SettingUtils { this.save(); }, destroyCallback: () => { - //从值恢复元素 + //Restore the original value for (let key of this.settings.keys()) { this.updateElementFromValue(key); } @@ -197,8 +207,6 @@ export class SettingUtils { */ dump(): Object { let data: any = {}; - - for (let [key, item] of this.settings) { if (item.type === 'button') continue; data[key] = item.value; @@ -208,6 +216,33 @@ export class SettingUtils { addItem(item: ISettingItem) { this.settings.set(item.key, item); + if (item.createElement === undefined) { + let itemElement = this.createDefaultElement(item); + this.elements.set(item.key, itemElement); + this.plugin.setting.addItem({ + title: item.title, + description: item?.description, + createActionElement: () => { + this.updateElementFromValue(item.key); + let element = this.getElement(item.key); + return element; + } + }); + } else { + this.plugin.setting.addItem({ + title: item.title, + description: item?.description, + createActionElement: () => { + let val = this.get(item.key); + let element = item.createElement(val); + this.elements.set(item.key, element); + return element; + } + }); + } + } + + createDefaultElement(item: ISettingItem) { let itemElement: HTMLElement; switch (item.type) { case 'checkbox': @@ -283,16 +318,7 @@ export class SettingUtils { itemElement = hintElement; break; } - this.elements.set(item.key, itemElement); - this.plugin.setting.addItem({ - title: item.title, - description: item?.description, - createActionElement: () => { - this.updateElementFromValue(item.key); - let element = this.getElement(item.key); - return element; - } - }) + return itemElement; } /** @@ -309,50 +335,52 @@ export class SettingUtils { private updateValueFromElement(key: string) { let item = this.settings.get(key); let element = this.elements.get(key) as any; - switch (item.type) { - case 'checkbox': - item.value = element.checked; - break; - case 'select': - item.value = element.value; - break; - case 'slider': - item.value = element.value; - break; - case 'textinput': - item.value = element.value; - break; - case 'textarea': - item.value = element.value; - break; - case 'number': - item.value = parseInt(element.value); - break; - } + item.value = valueOf(element); + // switch (item.type) { + // case 'checkbox': + // item.value = element.checked; + // break; + // case 'select': + // item.value = element.value; + // break; + // case 'slider': + // item.value = element.value; + // break; + // case 'textinput': + // item.value = element.value; + // break; + // case 'textarea': + // item.value = element.value; + // break; + // case 'number': + // item.value = parseInt(element.value); + // break; + // } } private updateElementFromValue(key: string) { let item = this.settings.get(key); let element = this.elements.get(key) as any; - switch (item.type) { - case 'checkbox': - element.checked = item.value; - break; - case 'select': - element.value = item.value; - break; - case 'slider': - element.value = item.value; - break; - case 'textinput': - element.value = item.value; - break; - case 'textarea': - element.value = item.value; - break; - case 'number': - element.value = item.value; - break; - } + setValue(element, item.value); + // switch (item.type) { + // case 'checkbox': + // element.checked = item.value; + // break; + // case 'select': + // element.value = item.value; + // break; + // case 'slider': + // element.value = item.value; + // break; + // case 'textinput': + // element.value = item.value; + // break; + // case 'textarea': + // element.value = item.value; + // break; + // case 'number': + // element.value = item.value; + // break; + // } } } \ No newline at end of file From 4a9d0f39531157c69af1c212c2ab8e251bb08d3a Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 15:57:43 +0800 Subject: [PATCH 127/158] =?UTF-8?q?=F0=9F=94=A5=20remove=20eslint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 2 -- .eslintrc.cjs | 38 -------------------------------------- package.json | 1 - 3 files changed, 41 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index f06235c..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 0781605..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,38 +0,0 @@ -module.exports = { - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:svelte/recommended", - "turbo", - "prettier", - ], - - parser: "@typescript-eslint/parser", - - overrides: [ - { - files: ["*.svelte"], - parser: "svelte-eslint-parser", - // Parse the script in `.svelte` as TypeScript by adding the following configuration. - parserOptions: { - parser: "@typescript-eslint/parser", - }, - }, - ], - - plugins: ["@typescript-eslint", "prettier"], - - rules: { - // Note: you must disable the base rule as it can report incorrect errors - semi: "off", - quotes: "off", - "no-undef": "off", - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/no-this-alias": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-explicit-any": "off", - "turbo/no-undeclared-env-vars": "off", - "prettier/prettier": "error", - }, -} diff --git a/package.json b/package.json index df94e90..4bccd57 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@tsconfig/svelte": "^4.0.1", "@types/node": "^20.3.0", - "eslint": "^8.42.0", "fast-glob": "^3.2.12", "glob": "^7.2.3", "js-yaml": "^4.1.0", From 7159755c7074be1c7054141cc74bb50b0ece02f6 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 16:00:03 +0800 Subject: [PATCH 128/158] =?UTF-8?q?=F0=9F=94=A8=20=E8=B0=83=E6=95=B4=20set?= =?UTF-8?q?ting=20=E7=9A=84=20interface=20=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/index.d.ts | 32 +++++++++++++++++++++++++------- src/libs/setting-utils.ts | 8 ++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index 9e0b889..7ca733f 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -1,10 +1,17 @@ +/* + * Copyright (c) 2024 by frostime. All Rights Reserved. + * @Author : frostime + * @Date : 2024-04-19 18:30:12 + * @FilePath : /src/libs/index.d.ts + * @LastEditTime : 2024-04-30 15:53:15 + * @Description : + */ type TSettingItemType = "checkbox" | "select" | "textinput" | "textarea" | "number" | "slider" | "button" | "hint"; -interface ISettingItem { + +interface ISettingItemCore { + type: TSettingItemType; key: string; value: any; - type: TSettingItemType; - title: string; - description?: string; placeholder?: string; slider?: { min: number; @@ -12,12 +19,23 @@ interface ISettingItem { step: number; }; options?: { [key: string | number]: string }; - action?: { - callback: () => void; - } button?: { label: string; callback: () => void; } +} + +interface ISettingItem extends ISettingItemCore { + title: string; + description: string; +} + + +//Interface for setting-utils +interface ISettingUtilsItem extends ISettingItem { + direction?: "row" | "column"; + action?: { + callback: () => void; + } createElement?: (currentVal: any) => HTMLElement; } diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index f43ab36..2a3926b 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-29 17:17:19 + * @LastEditTime : 2024-04-30 15:50:07 * @Description : */ @@ -56,7 +56,7 @@ export class SettingUtils { name: string; file: string; - settings: Map = new Map(); + settings: Map = new Map(); elements: Map = new Map(); constructor(args: { @@ -214,7 +214,7 @@ export class SettingUtils { return data; } - addItem(item: ISettingItem) { + addItem(item: ISettingUtilsItem) { this.settings.set(item.key, item); if (item.createElement === undefined) { let itemElement = this.createDefaultElement(item); @@ -242,7 +242,7 @@ export class SettingUtils { } } - createDefaultElement(item: ISettingItem) { + createDefaultElement(item: ISettingUtilsItem) { let itemElement: HTMLElement; switch (item.type) { case 'checkbox': From 59daefa941e3fb2b2c590a58a8872c9ea8cfb519 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 16:15:58 +0800 Subject: [PATCH 129/158] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20siyuan:?= =?UTF-8?q?=20add=20`direction`=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- README_zh_CN.md | 2 +- package.json | 6 +++--- plugin.json | 4 ++-- src/index.ts | 1 + src/libs/setting-utils.ts | 6 +++++- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3c233a7..09c8cdd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [中文版](./README_zh_CN.md) -> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.3.4](https://github.com/siyuan-note/plugin-sample/tree/v0.3.4) +> Consistent with [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.3.5](https://github.com/siyuan-note/plugin-sample/tree/v0.3.5) diff --git a/README_zh_CN.md b/README_zh_CN.md index 1510f9b..ca35f7c 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -4,7 +4,7 @@ [English](./README.md) -> 本例同 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.3.4](https://github.com/siyuan-note/plugin-sample/tree/v0.3.4) +> 本例同 [siyuan/plugin-sample](https://github.com/siyuan-note/plugin-sample) [v0.3.5](https://github.com/siyuan-note/plugin-sample/tree/v0.3.5) 1. 使用 vite 打包 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 diff --git a/package.json b/package.json index 4bccd57..44cdd78 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "plugin-sample-vite-svelte", - "version": "0.3.2", + "version": "0.3.5", "type": "module", "description": "This is a sample plugin based on vite and svelte for Siyuan (https://b3log.org/siyuan)", "repository": "", "homepage": "", - "author": "", + "author": "frostime", "license": "MIT", "scripts": { "make-link": "node --no-warnings ./scripts/make_dev_link.js", @@ -23,7 +23,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.63.3", - "siyuan": "0.9.7", + "siyuan": "0.9.8", "svelte": "^4.2.0", "ts-node": "^10.9.1", "typescript": "^5.1.3", diff --git a/plugin.json b/plugin.json index b810268..071b2a3 100644 --- a/plugin.json +++ b/plugin.json @@ -2,8 +2,8 @@ "name": "plugin-sample-vite-svelte", "author": "frostime", "url": "https://github.com/siyuan-note/plugin-sample-vite-svelte", - "version": "0.3.4", - "minAppVersion": "3.0.0", + "version": "0.3.5", + "minAppVersion": "3.0.12", "backends": [ "windows", "linux", diff --git a/src/index.ts b/src/index.ts index 704ad00..4af2041 100644 --- a/src/index.ts +++ b/src/index.ts @@ -235,6 +235,7 @@ export default class PluginSample extends Plugin { type: "slider", title: "Slider text", description: "Slider description", + direction: "column", slider: { min: 0, max: 100, diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 2a3926b..e611ce8 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-30 15:50:07 + * @LastEditTime : 2024-04-30 16:09:54 * @Description : */ @@ -222,6 +222,7 @@ export class SettingUtils { this.plugin.setting.addItem({ title: item.title, description: item?.description, + direction: item?.direction, createActionElement: () => { this.updateElementFromValue(item.key); let element = this.getElement(item.key); @@ -232,6 +233,7 @@ export class SettingUtils { this.plugin.setting.addItem({ title: item.title, description: item?.description, + direction: item?.direction, createActionElement: () => { let val = this.get(item.key); let element = item.createElement(val); @@ -334,6 +336,7 @@ export class SettingUtils { private updateValueFromElement(key: string) { let item = this.settings.get(key); + if (item.type === 'button') return; let element = this.elements.get(key) as any; item.value = valueOf(element); // switch (item.type) { @@ -360,6 +363,7 @@ export class SettingUtils { private updateElementFromValue(key: string) { let item = this.settings.get(key); + if (item.type === 'button') return; let element = this.elements.get(key) as any; setValue(element, item.value); // switch (item.type) { From 29c494a3f4aa977341f103f0b794b692f0b73f5e Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 16:32:26 +0800 Subject: [PATCH 130/158] =?UTF-8?q?=E2=9C=A8=20feat(setting-utils):=20gett?= =?UTF-8?q?er=20and=20setting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 12 +-- src/libs/index.d.ts | 4 +- src/libs/setting-utils.ts | 153 ++++++++++++++++++-------------------- 3 files changed, 81 insertions(+), 88 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4af2041..6a59d4c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -176,7 +176,7 @@ export default class PluginSample extends Plugin { // Called when focus is lost and content changes callback: () => { // Return data and save it in real time - let value = this.settingUtils.takeAndSave("Input") + let value = this.settingUtils.takeAndSave("Input"); console.log(value); } } @@ -191,7 +191,7 @@ export default class PluginSample extends Plugin { action: { callback: () => { // Read data in real time - let value = this.settingUtils.take("InputArea") + let value = this.settingUtils.take("InputArea"); console.log(value); } } @@ -205,8 +205,8 @@ export default class PluginSample extends Plugin { action: { callback: () => { // Return data and save it in real time - let value = !this.settingUtils.get("Check") - this.settingUtils.set("Check", value) + let value = !this.settingUtils.get("Check"); + this.settingUtils.set("Check", value); console.log(value); } } @@ -224,7 +224,7 @@ export default class PluginSample extends Plugin { action: { callback: () => { // Read data in real time - let value = this.settingUtils.take("Select") + let value = this.settingUtils.take("Select"); console.log(value); } } @@ -244,7 +244,7 @@ export default class PluginSample extends Plugin { action:{ callback: () => { // Read data in real time - let value = this.settingUtils.take("Slider") + let value = this.settingUtils.take("Slider"); console.log(value); } } diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index 7ca733f..539076a 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2024-04-19 18:30:12 * @FilePath : /src/libs/index.d.ts - * @LastEditTime : 2024-04-30 15:53:15 + * @LastEditTime : 2024-04-30 16:26:23 * @Description : */ type TSettingItemType = "checkbox" | "select" | "textinput" | "textarea" | "number" | "slider" | "button" | "hint"; @@ -38,4 +38,6 @@ interface ISettingUtilsItem extends ISettingItem { callback: () => void; } createElement?: (currentVal: any) => HTMLElement; + getEleVal?: (ele: HTMLElement) => any; + setEleVal?: (ele: HTMLElement, val: any) => void; } diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index e611ce8..19952c4 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,60 +3,83 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-30 16:09:54 + * @LastEditTime : 2024-04-30 16:28:00 * @Description : */ import { Plugin, Setting } from 'siyuan'; -const valueOf = (ele: HTMLElement, parseNumber: Function=parseInt) => { - let val: any = null; - if (ele instanceof HTMLInputElement) { - if (ele.type === 'checkbox') { - val = ele.checked; - } else { - if (ele.type === 'number') { - val = parseNumber(ele.value); - } else { - val = ele.value; + +/** + * The default function to get the value of the element + * @param type + * @returns + */ +const createDefaultGetter = (type: TSettingItemType) => { + let getter: (ele: HTMLElement) => any; + switch (type) { + case 'checkbox': + getter = (ele: HTMLInputElement) => { + return ele.checked; } - } - } else if (ele instanceof HTMLSelectElement) { - val = ele.value; - } else if (ele instanceof HTMLTextAreaElement) { - val = ele.value; - } else { - val = ele?.textContent; + break; + case 'select': + case 'slider': + case 'textinput': + case 'textarea': + getter = (ele: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement) => { + return ele.value; + } + break; + case 'number': + getter = (ele: HTMLInputElement) => { + return parseInt(ele.value); + } + break; + default: + getter = (ele: HTMLElement) => { + return ele?.textContent; + } + break; } - return val; + return getter; } -const setValue = (ele: HTMLElement, value: any) => { - if (ele === null || ele === undefined) return; - if (ele instanceof HTMLInputElement) { - if (ele.type === 'checkbox') { - ele.checked = value; - } else { - ele.value = value; - } - if (ele.type === 'range') { - ele.ariaLabel = value; - } - } else if (ele instanceof HTMLSelectElement) { - ele.value = value; - } else if (ele instanceof HTMLTextAreaElement) { - ele.value = value; - } else { - ele.textContent = value; + +/** + * The default function to set the value of the element + * @param type + * @returns + */ +const createDefaultSetter = (type: TSettingItemType) => { + let setter: (ele: HTMLElement, value: any) => void; + switch (type) { + case 'checkbox': + setter = (ele: HTMLInputElement, value: any) => { + ele.checked = value; + } + break; + case 'select': + case 'slider': + case 'textinput': + case 'textarea': + case 'number': + setter = (ele: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement, value: any) => { + ele.value = value; + } + break; } + return setter; + } + export class SettingUtils { plugin: Plugin; name: string; file: string; - settings: Map = new Map(); + settings: Map = new Map(); elements: Map = new Map(); constructor(args: { @@ -157,14 +180,15 @@ export class SettingUtils { * @returns value in html */ take(key: string, apply: boolean = false) { + let item = this.settings.get(key); let element = this.elements.get(key) as any; - if (!element){ + if (!element) { return } if (apply) { this.updateValueFromElement(key); } - return valueOf(element) + return item.getEleVal(element); } /** @@ -216,6 +240,13 @@ export class SettingUtils { addItem(item: ISettingUtilsItem) { this.settings.set(item.key, item); + if (item.getEleVal === undefined) { + item.getEleVal = createDefaultGetter(item.type); + } + if (item.setEleVal === undefined) { + item.setEleVal = createDefaultSetter(item.type); + } + if (item.createElement === undefined) { let itemElement = this.createDefaultElement(item); this.elements.set(item.key, itemElement); @@ -338,53 +369,13 @@ export class SettingUtils { let item = this.settings.get(key); if (item.type === 'button') return; let element = this.elements.get(key) as any; - item.value = valueOf(element); - // switch (item.type) { - // case 'checkbox': - // item.value = element.checked; - // break; - // case 'select': - // item.value = element.value; - // break; - // case 'slider': - // item.value = element.value; - // break; - // case 'textinput': - // item.value = element.value; - // break; - // case 'textarea': - // item.value = element.value; - // break; - // case 'number': - // item.value = parseInt(element.value); - // break; - // } + item.value = item.getEleVal(element); } private updateElementFromValue(key: string) { let item = this.settings.get(key); if (item.type === 'button') return; let element = this.elements.get(key) as any; - setValue(element, item.value); - // switch (item.type) { - // case 'checkbox': - // element.checked = item.value; - // break; - // case 'select': - // element.value = item.value; - // break; - // case 'slider': - // element.value = item.value; - // break; - // case 'textinput': - // element.value = item.value; - // break; - // case 'textarea': - // element.value = item.value; - // break; - // case 'number': - // element.value = item.value; - // break; - // } + item.setEleVal(element, item.value); } } \ No newline at end of file From 3d565424aec01410a512c066f1d0ce3d94944439 Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 16:48:10 +0800 Subject: [PATCH 131/158] =?UTF-8?q?=F0=9F=8E=A8=20feat:=20Add=20"custom=20?= =?UTF-8?q?setting-items"=20example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 26 ++++++++++++++++++++++++-- src/libs/index.d.ts | 4 ++-- src/libs/setting-utils.ts | 24 ++++++++++++++++-------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6a59d4c..62a09a7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,7 +31,7 @@ const DOCK_TYPE = "dock_tab"; export default class PluginSample extends Plugin { - private customTab: () => IModel; + customTab: () => IModel; private isMobile: boolean; private blockIconEventBindThis = this.blockIconEvent.bind(this); private settingUtils: SettingUtils; @@ -262,6 +262,28 @@ export default class PluginSample extends Plugin { } } }); + this.settingUtils.addItem({ + key: "Custom Element", + value: "", + type: "custom", + direction: "row", + title: "Custom Element", + description: "Custom Element description", + //Any custom element must offer the following methods + createElement: (currentVal: any) => { + let div = document.createElement('div'); + div.style.border = "1px solid var(--b3-theme-primary)"; + div.contentEditable = "true"; + div.textContent = currentVal; + return div; + }, + getEleVal: (ele: HTMLElement) => { + return ele.textContent; + }, + setEleVal: (ele: HTMLElement, val: any) => { + ele.textContent = val; + } + }); this.settingUtils.addItem({ key: "Hint", value: "", @@ -437,7 +459,7 @@ export default class PluginSample extends Plugin { title: `SiYuan ${Constants.SIYUAN_VERSION}`, content: `
`, width: this.isMobile ? "92vw" : "720px", - destroyCallback(options) { + destroyCallback() { // hello.$destroy(); }, }); diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index 539076a..ab2f6c3 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -3,10 +3,10 @@ * @Author : frostime * @Date : 2024-04-19 18:30:12 * @FilePath : /src/libs/index.d.ts - * @LastEditTime : 2024-04-30 16:26:23 + * @LastEditTime : 2024-04-30 16:39:54 * @Description : */ -type TSettingItemType = "checkbox" | "select" | "textinput" | "textarea" | "number" | "slider" | "button" | "hint"; +type TSettingItemType = "checkbox" | "select" | "textinput" | "textarea" | "number" | "slider" | "button" | "hint" | "custom"; interface ISettingItemCore { type: TSettingItemType; diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 19952c4..948dc2f 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-30 16:28:00 + * @LastEditTime : 2024-04-30 16:42:23 * @Description : */ @@ -21,7 +21,7 @@ const createDefaultGetter = (type: TSettingItemType) => { case 'checkbox': getter = (ele: HTMLInputElement) => { return ele.checked; - } + }; break; case 'select': case 'slider': @@ -29,7 +29,7 @@ const createDefaultGetter = (type: TSettingItemType) => { case 'textarea': getter = (ele: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement) => { return ele.value; - } + }; break; case 'number': getter = (ele: HTMLInputElement) => { @@ -37,9 +37,7 @@ const createDefaultGetter = (type: TSettingItemType) => { } break; default: - getter = (ele: HTMLElement) => { - return ele?.textContent; - } + getter = () => null; break; } return getter; @@ -57,7 +55,7 @@ const createDefaultSetter = (type: TSettingItemType) => { case 'checkbox': setter = (ele: HTMLInputElement, value: any) => { ele.checked = value; - } + }; break; case 'select': case 'slider': @@ -66,7 +64,10 @@ const createDefaultSetter = (type: TSettingItemType) => { case 'number': setter = (ele: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement, value: any) => { ele.value = value; - } + }; + break; + default: + setter = () => {}; break; } return setter; @@ -240,6 +241,13 @@ export class SettingUtils { addItem(item: ISettingUtilsItem) { this.settings.set(item.key, item); + const IsCustom = item.type === 'custom'; + let error = IsCustom && (item.createElement === undefined || item.getEleVal === undefined || item.setEleVal === undefined); + if (error) { + console.error('The custom setting item must have createElement, getEleVal and setEleVal methods'); + return; + } + if (item.getEleVal === undefined) { item.getEleVal = createDefaultGetter(item.type); } From 9f54e7046cf6070ac2ae5547240ea8d45e0425ae Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 30 Apr 2024 22:15:50 +0800 Subject: [PATCH 132/158] =?UTF-8?q?=E2=9C=A8=20misc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/setting-utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 948dc2f..33c5cac 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-30 16:42:23 + * @LastEditTime : 2024-04-30 22:15:25 * @Description : */ @@ -105,7 +105,7 @@ export class SettingUtils { args.callback(data); } this.plugin.data[this.name] = data; - this.save(); + this.save(data); }, destroyCallback: () => { //Restore the original value @@ -128,8 +128,8 @@ export class SettingUtils { return data; } - async save() { - let data = this.dump(); + async save(data?: any) { + data = data ?? this.dump(); await this.plugin.saveData(this.file, this.dump()); console.debug('Save config:', data); return data; From 03ab34f5523274b3c416801359d8df32f8617141 Mon Sep 17 00:00:00 2001 From: frostime Date: Wed, 1 May 2024 17:45:05 +0800 Subject: [PATCH 133/158] =?UTF-8?q?=E2=9A=A1=20=E7=A6=81=E7=94=A8=E6=80=9D?= =?UTF-8?q?=E6=BA=90=E5=86=85=E9=83=A8=E7=9A=84=20enter=20confirm=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/setting-utils.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libs/setting-utils.ts b/src/libs/setting-utils.ts index 33c5cac..ae316e2 100644 --- a/src/libs/setting-utils.ts +++ b/src/libs/setting-utils.ts @@ -3,7 +3,7 @@ * @Author : frostime * @Date : 2023-12-17 18:28:19 * @FilePath : /src/libs/setting-utils.ts - * @LastEditTime : 2024-04-30 22:15:25 + * @LastEditTime : 2024-05-01 17:44:16 * @Description : */ @@ -285,6 +285,13 @@ export class SettingUtils { createDefaultElement(item: ISettingUtilsItem) { let itemElement: HTMLElement; + //阻止思源内置的回车键确认 + const preventEnterConfirm = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + e.stopImmediatePropagation(); + } + } switch (item.type) { case 'checkbox': let element: HTMLInputElement = document.createElement('input'); @@ -330,7 +337,7 @@ export class SettingUtils { textInputElement.value = item.value; textInputElement.onchange = item.action?.callback ?? (() => { }); itemElement = textInputElement; - + textInputElement.addEventListener('keydown', preventEnterConfirm); break; case 'textarea': let textareaElement: HTMLTextAreaElement = document.createElement('textarea'); @@ -345,6 +352,7 @@ export class SettingUtils { numberElement.className = 'b3-text-field fn__flex-center fn__size200'; numberElement.value = item.value; itemElement = numberElement; + numberElement.addEventListener('keydown', preventEnterConfirm); break; case 'button': let buttonElement: HTMLButtonElement = document.createElement('button'); From 67d6024a04dce60765347c35c6d2422c33971321 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 1 Jun 2024 16:29:07 +0800 Subject: [PATCH 134/158] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20kits=20about?= =?UTF-8?q?=20dialogs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/dialog.ts | 121 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/libs/dialog.ts diff --git a/src/libs/dialog.ts b/src/libs/dialog.ts new file mode 100644 index 0000000..ea2b187 --- /dev/null +++ b/src/libs/dialog.ts @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024 by frostime. All Rights Reserved. + * @Author : frostime + * @Date : 2024-03-23 21:37:33 + * @FilePath : /src/libs/dialog.ts + * @LastEditTime : 2024-06-01 16:28:30 + * @Description : Kits about dialogs + */ +import { Dialog } from "siyuan"; + +export const inputDialog = (args: { + title: string, placeholder?: string, defaultText?: string, + confirm?: (text: string) => void, cancel?: () => void, + width?: string, height?: string +}) => { + const dialog = new Dialog({ + title: args.title, + content: `
+
+
+
+
+ +
`, + width: args.width ?? "520px", + height: args.height + }); + const target: HTMLTextAreaElement = dialog.element.querySelector(".b3-dialog__content>div.ft__breakword>textarea"); + const btnsElement = dialog.element.querySelectorAll(".b3-button"); + btnsElement[0].addEventListener("click", () => { + if (args?.cancel) { + args.cancel(); + } + dialog.destroy(); + }); + btnsElement[1].addEventListener("click", () => { + if (args?.confirm) { + args.confirm(target.value); + } + dialog.destroy(); + }); +}; + +export const inputDialogSync = async (args: { + title: string, placeholder?: string, defaultText?: string, + width?: string, height?: string +}) => { + return new Promise((resolve) => { + let newargs = { + ...args, confirm: (text) => { + resolve(text); + }, cancel: () => { + resolve(null); + } + }; + inputDialog(newargs); + }); +} + + +interface IConfirmDialogArgs { + title: string; + content: string | HTMLElement; + confirm?: (ele?: HTMLElement) => void; + cancel?: (ele?: HTMLElement) => void; + width?: string; + height?: string; +} + +export const confirmDialog = (args: IConfirmDialogArgs) => { + const { title, content, confirm, cancel, width, height } = args; + + const dialog = new Dialog({ + title, + content: `
+
+
+
+
+
+ +
`, + width: width, + height: height + }); + + const target: HTMLElement = dialog.element.querySelector(".b3-dialog__content>div.ft__breakword"); + if (typeof content === "string") { + target.innerHTML = content; + } else { + target.appendChild(content); + } + + const btnsElement = dialog.element.querySelectorAll(".b3-button"); + btnsElement[0].addEventListener("click", () => { + if (cancel) { + cancel(target); + } + dialog.destroy(); + }); + btnsElement[1].addEventListener("click", () => { + if (confirm) { + confirm(target); + } + dialog.destroy(); + }); +}; + + +export const confirmDialogSync = async (args: IConfirmDialogArgs) => { + return new Promise((resolve) => { + let newargs = { + ...args, confirm: (ele: HTMLElement) => { + resolve(ele); + }, cancel: (ele: HTMLElement) => { + resolve(ele); + } + }; + confirmDialog(newargs); + }); +}; From 81d5bee160e9b8b505a09b523c27fea2f89d18a3 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 1 Jun 2024 16:35:02 +0800 Subject: [PATCH 135/158] =?UTF-8?q?=F0=9F=93=9Ddocs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 ++++- README.md | 2 +- README_zh_CN.md | 2 +- package.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce36ec8..af04807 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog -## 0.3.5 2024-03 +## v0.3.5 2024-04-30 + +* [Add `direction` to plugin method `Setting.addItem`](https://github.com/siyuan-note/siyuan/issues/11183) + ## 0.3.4 2024-02-20 diff --git a/README.md b/README.md index 09c8cdd..5f3c813 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 2. Use symbolic linking instead of putting the project into the plugins directory program development 3. Built-in support for the svelte framework - > If don't want svelte, turn to this template: [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) + > **If don't want svelte, turn to this template**: [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) 4. Provides a github action template to automatically generate package.zip and upload to new release diff --git a/README_zh_CN.md b/README_zh_CN.md index ca35f7c..9f447fa 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -10,7 +10,7 @@ 2. 使用符号链接、而不是把项目放到插件目录下的模式进行开发 3. 内置对 svelte 框架的支持 - > 如果不想要 svelte,请移步 [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) + > **如果不想要 svelte,请移步这个模板:** [frostime/plugin-sample-vite](https://github.com/frostime/plugin-sample-vite) 4. 提供一个github action 模板,能自动生成package.zip并上传到新版本中 diff --git a/package.json b/package.json index 44cdd78..fd49b9c 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "minimist": "^1.2.8", "rollup-plugin-livereload": "^2.0.5", "sass": "^1.63.3", - "siyuan": "0.9.8", + "siyuan": "0.9.9", "svelte": "^4.2.0", "ts-node": "^10.9.1", "typescript": "^5.1.3", From 9c7572b820189d61320b84f25132a1d44782f71b Mon Sep 17 00:00:00 2001 From: frostime Date: Tue, 4 Jun 2024 15:04:07 +0800 Subject: [PATCH 136/158] =?UTF-8?q?=F0=9F=90=9B=20getFile=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/api.ts b/src/api.ts index c227518..0a421ce 100644 --- a/src/api.ts +++ b/src/api.ts @@ -6,7 +6,7 @@ * API 文档见 [API_zh_CN.md](https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md) */ -import { fetchSyncPost, IWebSocketData } from "siyuan"; +import { fetchPost, fetchSyncPost, IWebSocketData } from "siyuan"; export async function request(url: string, data: any) { @@ -328,12 +328,11 @@ export async function getFile(path: string): Promise { path: path } let url = '/api/file/getFile'; - try { - let file = await fetchSyncPost(url, data); - return file; - } catch (error_msg) { - return null; - } + return new Promise((resolve, _) => { + fetchPost(url, data, (content: any) => { + resolve(content) + }); + }); } export async function putFile(path: string, isDir: boolean, file: any) { From 49eb06330da596e276afd399f993a340957f691f Mon Sep 17 00:00:00 2001 From: Frostime Date: Thu, 6 Jun 2024 22:31:20 +0800 Subject: [PATCH 137/158] =?UTF-8?q?=F0=9F=94=A8=20Remove=20the=20default?= =?UTF-8?q?=20fund=20in=20plugin.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.json b/plugin.json index 071b2a3..865a240 100644 --- a/plugin.json +++ b/plugin.json @@ -32,7 +32,7 @@ }, "funding": { "custom": [ - "https://afdian.net/a/frostime" + "" ] }, "keywords": [ From 6d75a46a56c0aad62a74b0ee7943fc4e1601fc56 Mon Sep 17 00:00:00 2001 From: frostime Date: Sat, 8 Jun 2024 18:30:53 +0800 Subject: [PATCH 138/158] =?UTF-8?q?=F0=9F=94=A8=20refactor:=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=9F=BA=E4=BA=8E=20svelte=20=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=9D=A2=E6=9D=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/index.d.ts | 2 +- src/libs/item-input.svelte | 108 ++++++++++++++++++++++++++++++++++ src/libs/item-wrap.svelte | 51 ++++++++++++++++ src/libs/setting-item.svelte | 105 --------------------------------- src/libs/setting-panel.svelte | 31 ++++++---- src/setting-example.svelte | 9 +++ 6 files changed, 187 insertions(+), 119 deletions(-) create mode 100644 src/libs/item-input.svelte create mode 100644 src/libs/item-wrap.svelte delete mode 100644 src/libs/setting-item.svelte diff --git a/src/libs/index.d.ts b/src/libs/index.d.ts index ab2f6c3..27a27ed 100644 --- a/src/libs/index.d.ts +++ b/src/libs/index.d.ts @@ -28,12 +28,12 @@ interface ISettingItemCore { interface ISettingItem extends ISettingItemCore { title: string; description: string; + direction?: "row" | "column"; } //Interface for setting-utils interface ISettingUtilsItem extends ISettingItem { - direction?: "row" | "column"; action?: { callback: () => void; } diff --git a/src/libs/item-input.svelte b/src/libs/item-input.svelte new file mode 100644 index 0000000..3a42b45 --- /dev/null +++ b/src/libs/item-input.svelte @@ -0,0 +1,108 @@ + + + +{#if type === "checkbox"} + + +{:else if type === "textinput"} + + +{:else if type === "textarea"} +