├── template ├── src │ ├── Globals.d.ts │ ├── index.module.css │ ├── types │ │ └── index.ts │ └── index.ts ├── .gitignore ├── package.json ├── README.md ├── vite.config.js ├── index.html └── tsconfig.json ├── .gitignore ├── .github ├── dependabot.yml └── workflows │ ├── npm-publish.yml │ └── bump-version.yml ├── package.json ├── yarn.lock ├── LICENSE ├── bin └── create-tool.js └── README.md /template/src/Globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.module.css"; -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | node_modules 4 | *.log 5 | dist -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | .DS_Store 4 | node_modules 5 | *.log 6 | 7 | template/yarn.lock 8 | 9 | package-lock.json -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/template" 5 | schedule: 6 | interval: "daily" -------------------------------------------------------------------------------- /template/src/index.module.css: -------------------------------------------------------------------------------- 1 | .VAR_TOOL_NAME-tool { 2 | margin: 1em auto; 3 | height: 100px; 4 | 5 | background-color: #eee; 6 | border-radius: 8px; 7 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@editorjs/create-tool", 3 | "description": "Editor.js Tool single command generator", 4 | "version": "0.1.3", 5 | "license": "MIT", 6 | "bin": { 7 | "create-tool": "./bin/create-tool.js" 8 | }, 9 | "dependencies": { 10 | "get-all-files": "^4.1.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "get-all-files@^4.1.0": 6 | "integrity" "sha512-ZH0Sbr6VQLMCcjrWNWyK0Wii9Kfw7ALnaZL6/5tTYf2/9lMtTTx9jSVAU92D3HfH9K8veAIehq3PbCZA7yde2g==" 7 | "resolved" "https://registry.npmjs.org/get-all-files/-/get-all-files-4.1.0.tgz" 8 | "version" "4.1.0" 9 | -------------------------------------------------------------------------------- /template/src/types/index.ts: -------------------------------------------------------------------------------- 1 | import { BlockToolData } from '@editorjs/editorjs'; 2 | 3 | /** 4 | * VAR_TOOL_NAME Tool's input and output data format 5 | */ 6 | export interface VAR_TOOL_NAMEData extends BlockToolData {} 7 | 8 | /** 9 | * VAR_TOOL_NAME Tool's configuration object that passed through the initial Editor config 10 | */ 11 | export interface VAR_TOOL_NAMEConfig {} -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editorjs-VAR_TOOL_NAME", 3 | "description": "VAR_TOOL_NAME Tool for Editor.js", 4 | "version": "1.0.0", 5 | "main": "dist/VAR_TOOL_NAME.umd.js", 6 | "module": "dist/VAR_TOOL_NAME.mjs", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build" 10 | }, 11 | "devDependencies": { 12 | "@codexteam/icons": "^0.2.0", 13 | "@editorjs/editorjs": "^2.26.4", 14 | "@types/node": "^18.11.16", 15 | "ts-loader": "^9.1.0", 16 | "typescript": "^4.2.4", 17 | "vite": "^4.0.1", 18 | "vite-plugin-css-injected-by-js": "^2.1.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # VAR_TOOL_NAME Tool for Editor.js 2 | 3 | ## Installation 4 | 5 | Use your package manager to install the package `editorjs-VAR_TOOL_NAME`. 6 | 7 | ``` 8 | npm install editorjs-VAR_TOOL_NAME 9 | 10 | yarn add editorjs-VAR_TOOL_NAME 11 | ``` 12 | 13 | ## Development 14 | 15 | This tool uses [Vite](https://vitejs.dev/) as builder. 16 | 17 | `npm run dev` — run development environment with hot reload 18 | 19 | `npm run build` — build the tool for production to the `dist` folder 20 | 21 | ## Links 22 | 23 | [Editor.js](https://editorjs.io) • [Create Tool](https://github.com/editor-js/create-tool) -------------------------------------------------------------------------------- /template/vite.config.js: -------------------------------------------------------------------------------- 1 | import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'; 2 | import path from 'path'; 3 | 4 | /** 5 | * Trick to use Vite server.open option on macOS 6 | * @see https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768 7 | */ 8 | process.env.BROWSER = 'open'; 9 | 10 | export default { 11 | build: { 12 | lib: { 13 | entry: path.resolve(__dirname, 'src', 'index.ts'), 14 | name: 'VAR_TOOL_NAME', 15 | formats: ['umd', 'es'], 16 | fileName: 'VAR_TOOL_NAME' 17 | }, 18 | }, 19 | 20 | server: { 21 | port: 3300, 22 | open: true, 23 | }, 24 | 25 | plugins: [ 26 | cssInjectedByJsPlugin(), 27 | ] 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 CodeX Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Editor.js example page 4 | 5 | 10 | 11 | 12 |
13 | 14 | 15 |

16 | 
17 |   
50 | 
51 | 
52 | 
53 | 


--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
 1 | name: Publish package to NPM
 2 | 
 3 | on:
 4 |   push:
 5 |     branches:
 6 |       - main
 7 |       - master
 8 | 
 9 | jobs:
10 |   publish:
11 |     runs-on: ubuntu-latest
12 |     steps:
13 |       - uses: actions/checkout@v2
14 |       - uses: actions/setup-node@v1
15 |         with:
16 |           node-version: 18
17 |           registry-url: https://registry.npmjs.org/
18 | 
19 |       - run: yarn
20 |       - run: yarn publish --access=public --tag=next
21 |         env:
22 |           NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23 | 
24 |       - name: Get package info
25 |         id: package
26 |         uses: codex-team/action-nodejs-package-info@v1.1    
27 | 
28 |       - name: Add LATEST tag for the published package if this is not a -rc version
29 |         if: steps.package.outputs.is-release-candidate == 'false'
30 |         run: npm dist-tag add ${{ steps.package.outputs.name }}@${{ steps.package.outputs.version }} latest
31 |         env:
32 |           NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 
33 | 
34 |   notify:
35 |     needs: publish
36 |     runs-on: ubuntu-latest
37 |     steps:
38 |       - uses: actions/checkout@v2
39 |       - name: Get package info
40 |         id: package
41 |         uses: codex-team/action-nodejs-package-info@v1
42 |       - name: Send a message
43 |         uses: codex-team/action-codexbot-notify@v1
44 |         with:
45 |           webhook: ${{ secrets.CODEX_BOT_NOTIFY_EDITORJS_PUBLIC_CHAT }}
46 |           message: '📦 [${{ steps.package.outputs.name }}](${{ steps.package.outputs.npmjs-link }}) ${{ steps.package.outputs.version }} was published'
47 |           parse_mode: 'markdown'
48 |           disable_web_page_preview: true
49 | 


--------------------------------------------------------------------------------
/bin/create-tool.js:
--------------------------------------------------------------------------------
 1 | #! /usr/bin/env node
 2 | 
 3 | const fs = require('fs');
 4 | const path = require('path');
 5 | const getAllFiles = require('get-all-files');
 6 | 
 7 | /**
 8 |  * Get Tool Name from CLI arguments
 9 |  */
10 | const toolName = process.argv[2];
11 | 
12 | if (!toolName) {
13 |   console.log('Please specify tool name');
14 |   process.exit(1);
15 | }
16 | 
17 | /**
18 |  * Copy template folder to new Tool folder
19 |  */
20 | console.log('Creating tool', toolName);
21 | 
22 | const toolPath = path.join(process.cwd(), toolName);
23 | fs.mkdirSync(toolPath);
24 | 
25 | const templatePath = path.join(__dirname, '..', 'template');
26 | const files = getAllFiles.getAllFilesSync(templatePath).toArray();
27 | files.forEach(file => {
28 |   const relativePath = path.relative(templatePath, file);
29 | 
30 |   console.log(`Copying ${relativePath}`);
31 | 
32 |   /**
33 |    * Get file content and replace VAR_TOOL_NAME with tool name
34 |    */
35 |   const content = fs.readFileSync(file, 'utf-8');
36 |   const replacedContent = content.replace(/VAR_TOOL_NAME/g, toolName);
37 |   
38 |   /**
39 |    * Create folders if needed
40 |    */
41 |   const folder = path.dirname(path.join(toolPath, relativePath));
42 |   if (!fs.existsSync(folder)) {
43 |     fs.mkdirSync(folder, { recursive: true });
44 |   }
45 |   
46 |   /**
47 |    * Write file
48 |    */
49 |   fs.writeFileSync(path.join(toolPath, relativePath), replacedContent);
50 | });
51 | 
52 | console.log('');
53 | console.log('Done!');
54 | console.log('');
55 | 
56 | /**
57 |  * Show next steps message
58 |  */
59 | console.log('Now run:');
60 | console.log(`  cd ${toolName}`);
61 | console.log('  npm install');
62 | console.log('  npm run build:dev');
63 | 
64 | console.log('');


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | 🚧 Development in progress 🚧
 2 | 
 3 | # Editor.js Tool — starter kit package
 4 | 
 5 | Single command helper to generate a Tool template.
 6 | 
 7 | ## Usage
 8 | 
 9 | Use `create` command to generate Tool's starter kit.
10 | 
11 | ```
12 | npm create @editorjs/tool 
13 | yarn create @editorjs/tool 
14 | ```
15 | 
16 | ## Development
17 | 
18 | New project files will be used from `template` folder. You can work in this folder as in generated project: upgrade dependencies, add new files, run build and dev commands.
19 | 
20 | In templates there is a variable that will be replaced with user's input:
21 | 
22 | - `VAR_TOOL_NAME` — tool name
23 | 
24 | ### Local testing
25 | 
26 | To test the package locally, you have to create a symlink to the global `node_modules` folder. Use the package to generate a new tool. And then you need to unlink local package.
27 | 
28 | #### Linking
29 | 
30 | Run the following command in the root of this package repository:
31 | 
32 | ```
33 | npm link
34 | yarn link
35 | ```
36 | 
37 | In the folder where you want to create a new tool, link the local package:
38 | 
39 | ```
40 | npm link @editorjs/create-tool
41 | yarn link @editorjs/create-tool
42 | ```
43 | 
44 | #### Usage
45 | 
46 | Use this tool as usual:
47 | 
48 | ```
49 | npm create @editorjs/tool 
50 | yarn create @editorjs/tool 
51 | ```
52 | 
53 | #### Unlinking
54 | 
55 | To unlink the local package run the following in tool's parent folder where I had to link it earlier:
56 | 
57 | ```
58 | npm unlink @editorjs/create-tool
59 | yarn unlink @editorjs/create-tool
60 | ```
61 | 
62 | And then unlink the package in the root of this package repository:
63 | 
64 | ```
65 | npm unlink @editorjs/create-tool
66 | yarn unlink @editorjs/create-tool
67 | ```
68 | 


--------------------------------------------------------------------------------
/.github/workflows/bump-version.yml:
--------------------------------------------------------------------------------
 1 | name: Auto bump version
 2 | 
 3 | on:
 4 |   pull_request:
 5 |     branches:
 6 |       - main
 7 |       - master
 8 | 
 9 | jobs:
10 |   # If pull request was merged then we should check for a package version update
11 |   check-for-no-version-changing:
12 |     runs-on: ubuntu-latest
13 |     steps:
14 |       # Checkout to target branch
15 |       - uses: actions/checkout@v2
16 |         with:
17 |           fetch-depth: 0
18 | 
19 |       # Get package new version name
20 |       - name: Get package info
21 |         id: packageNew
22 |         uses: codex-team/action-nodejs-package-info@v1
23 | 
24 |       # Checkout to the base commit before merge
25 |       - name: Checkout to the base commit before merge
26 |         run: git checkout ${{ github.event.pull_request.base.sha }}
27 | 
28 |       # Get package old version name
29 |       - name: Get package info
30 |         id: packageOld
31 |         uses: codex-team/action-nodejs-package-info@v1
32 | 
33 |       # Stop workflow and do not bump version if it was changed already
34 |       - name: Stop workflow and do not bump version if it was changed already
35 |         uses: actions/github-script@v3
36 |         if: steps.packageOld.outputs.version != steps.packageNew.outputs.version
37 |         with:
38 |           script: |
39 |             core.setFailed('Version was changed! ${{ steps.packageOld.outputs.version }} -> ${{ steps.packageNew.outputs.version }}')
40 | 
41 |   bump-version:
42 |     needs: check-for-no-version-changing
43 |     runs-on: ubuntu-latest
44 |     steps:
45 |       # Checkout to target branch
46 |       - uses: actions/checkout@v2
47 | 
48 |       # Setup node environment
49 |       - uses: actions/setup-node@v1
50 |         with:
51 |           node-version: 18
52 | 
53 |       # Bump version to the next prerelease (patch) with rc suffix
54 |       - name: Suggest the new version
55 |         run: yarn version --prerelease --preid rc --no-git-tag-version
56 | 
57 |       # Get package new version name
58 |       - name: Get package info
59 |         id: package
60 |         uses: codex-team/action-nodejs-package-info@v1
61 | 
62 |       # Commit and push changes
63 |       - uses: EndBug/add-and-commit@v7
64 |         with:
65 |           author_name: github-actions
66 |           author_email: 41898282+github-actions[bot]@users.noreply.github.com
67 |           message: "Bump version up to ${{ steps.package.outputs.version }}"


--------------------------------------------------------------------------------
/template/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "compilerOptions": {
 3 |     /* Visit https://aka.ms/tsconfig.json to read more about this file */
 4 | 
 5 |     /* Basic Options */
 6 |     // "incremental": true,                         /* Enable incremental compilation */
 7 |     "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
 8 |     "module": "commonjs",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
 9 |     "lib": ["ES2020", "dom"],                       /* Specify library files to be included in the compilation. */
10 |     // "allowJs": true,                             /* Allow javascript files to be compiled. */
11 |     // "checkJs": true,                             /* Report errors in .js files. */
12 |     // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
13 |     // "declaration": true,                         /* Generates corresponding '.d.ts' file. */
14 |     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
15 |     // "sourceMap": true,                           /* Generates corresponding '.map' file. */
16 |     // "outFile": "./",                             /* Concatenate and emit output to single file. */
17 |     // "outDir": "./",                              /* Redirect output structure to the directory. */
18 |     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
19 |     // "composite": true,                           /* Enable project compilation */
20 |     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
21 |     // "removeComments": true,                      /* Do not emit comments to output. */
22 |     // "noEmit": true,                              /* Do not emit outputs. */
23 |     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
24 |     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25 |     // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26 | 
27 |     /* Strict Type-Checking Options */
28 |     "strict": true,                                 /* Enable all strict type-checking options. */
29 |     // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
30 |     // "strictNullChecks": true,                    /* Enable strict null checks. */
31 |     // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
32 |     // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33 |     // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
34 |     // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
35 |     // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */
36 | 
37 |     /* Additional Checks */
38 |     // "noUnusedLocals": true,                      /* Report errors on unused locals. */
39 |     // "noUnusedParameters": true,                  /* Report errors on unused parameters. */
40 |     // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
41 |     // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */
42 |     // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */
43 |     // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */
44 | 
45 |     /* Module Resolution Options */
46 |     // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
47 |     // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */
48 |     // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
49 |     // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
50 |     // "typeRoots": [],                             /* List of folders to include type definitions from. */
51 |     // "types": [],                                 /* Type declaration files to be included in compilation. */
52 |     // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
53 |     "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
54 |     // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
55 |     // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */
56 | 
57 |     /* Source Map Options */
58 |     // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */
59 |     // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */
60 |     // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */
61 |     // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
62 | 
63 |     /* Experimental Options */
64 |     // "experimentalDecorators": true,              /* Enables experimental support for ES7 decorators. */
65 |     // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */
66 | 
67 |     /* Advanced Options */
68 |     "skipLibCheck": true,                           /* Skip type checking of declaration files. */
69 |     "forceConsistentCasingInFileNames": true,       /* Disallow inconsistently-cased references to the same file. */
70 |     
71 |     "plugins": [{
72 |       "name": "typescript-plugin-css-modules"
73 |     }]
74 |   }
75 | }


--------------------------------------------------------------------------------
/template/src/index.ts:
--------------------------------------------------------------------------------
  1 | /**
  2 |  * Import styles library
  3 |  */
  4 | import styles from './index.module.css';
  5 | 
  6 | /**
  7 |  * Import icons
  8 |  */
  9 | import { IconStar } from '@codexteam/icons';
 10 | 
 11 | /**
 12 |  * Import types
 13 |  */
 14 | import { VAR_TOOL_NAMEData, VAR_TOOL_NAMEConfig } from './types';
 15 | import { API, BlockAPI, BlockTool } from '@editorjs/editorjs';
 16 | 
 17 | /**
 18 |  * VAR_TOOL_NAME Tool for Editor.js
 19 |  */
 20 | export default class VAR_TOOL_NAME implements BlockTool {
 21 |   /**
 22 |    * Code API — public methods to work with Editor
 23 |    * 
 24 |    * @link https://editorjs.io/api
 25 |    */
 26 |    private readonly api: API;
 27 | 
 28 |   /**
 29 |    * Block API — methods and properties to work with Block instance
 30 |    * 
 31 |    * @link https://editorjs.io/blockapi
 32 |    */
 33 |   private readonly block: BlockAPI;
 34 | 
 35 |   /**
 36 |    * Read-only mode flag
 37 |    */
 38 |   private readonly readOnly: boolean;
 39 | 
 40 |   /**
 41 |    * Tool data for input and output
 42 |    */
 43 |   private data: VAR_TOOL_NAMEData;
 44 | 
 45 |   /**
 46 |    * Configuration object that passed through the initial Editor configuration.
 47 |    */
 48 |   private config: VAR_TOOL_NAMEConfig;
 49 | 
 50 |   /**
 51 |    * Tool's HTML nodes
 52 |    */
 53 |   private nodes: {[key: string]: HTMLElement|null};
 54 | 
 55 |   /**
 56 |    * Class constructor
 57 |    * 
 58 |    * @link https://editorjs.io/tools-api#class-constructor
 59 |    */
 60 |   constructor({ data, config, api, block, readOnly }: { data: VAR_TOOL_NAMEData, config: VAR_TOOL_NAMEConfig, api: API, block: BlockAPI, readOnly: boolean }) {
 61 |     this.data = data;
 62 |     this.config = config;
 63 |     this.api = api;
 64 |     this.block = block;
 65 |     this.readOnly = readOnly;
 66 | 
 67 |     /**
 68 |      * Declare Tool's nodes
 69 |      */
 70 |     this.nodes = {
 71 |       wrapper: null,
 72 |     };
 73 |   }
 74 | 
 75 |   /**
 76 |    * PUBLIC METHODS
 77 |    * 
 78 |    * @link https://editorjs.io/tools-api#public-methods
 79 |    */
 80 | 
 81 |   /**
 82 |    * Creates UI of a Block
 83 |    * Required
 84 |    * @link https://editorjs.io/tools-api#render
 85 |    * 
 86 |    * @returns {HTMLElement}
 87 |    */
 88 |   render() {
 89 |     this.nodes.wrapper = document.createElement('div');
 90 |     this.nodes.wrapper.classList.add(styles['VAR_TOOL_NAME-tool']);
 91 | 
 92 |     return this.nodes.wrapper;
 93 |   }
 94 | 
 95 |   /**
 96 |    * Extracts Block data from the UI
 97 |    * Required
 98 |    * @link https://editorjs.io/tools-api#save
 99 |    * 
100 |    * @returns {VAR_TOOL_NAMEData} saved data
101 |    */
102 |   save(): VAR_TOOL_NAMEData {
103 |     return {};
104 |   }
105 | 
106 |   /**
107 |    * Validates Block data after saving
108 |    * @link https://editorjs.io/tools-api#validate
109 |    * 
110 |    * @param {VAR_TOOL_NAMEData} savedData
111 |    * @returns {boolean} true if data is valid, otherwise false
112 |    */ 
113 |   // validate() {}
114 | 
115 |   /**
116 |    * 
117 |    * Returns HTML that will be appended at the top of Block-settings
118 |    * @link https://editorjs.io/tools-api#render-settings
119 |    * 
120 |    * @returns {HTMLElement}
121 |    */ 
122 |   // renderSettings() {}
123 | 
124 |   /**
125 |    * Clear Tools stuff: cache, variables, events.
126 |    * Called when Editor instance is destroying.
127 |    * @link https://editorjs.io/tools-api#destroy
128 |    * 
129 |    * @returns {void}
130 |    */
131 |   // destroy() {}
132 | 
133 |   /**
134 |    * Handle content pasted by ways that described by pasteConfig static getter
135 |    * @link https://editorjs.io/tools-api#on-paste
136 |    * 
137 |    * @param {PasteEvent} event - event with pasted content
138 |    * @returns {void}
139 |    */  
140 |   // onPaste() {}
141 | 
142 |   /**
143 |    * Specifies how to merge two similar Blocks
144 |    * @link https://editorjs.io/tools-api#merge
145 |    * 
146 |    * @param {VAR_TOOL_NAMEData} data - data of second Block
147 |    * @returns {VAR_TOOL_NAMEData} - merged data
148 |    */
149 |   // merge() {} 
150 | 
151 |   /**
152 |    * STATIC GETTERS
153 |    * 
154 |    * @link https://editorjs.io/tools-api#static-getters
155 |    */
156 | 
157 |   /**
158 |    * Process pasted content before appending to the Editor
159 |    * @link https://editorjs.io/tools-api#pasteconfig
160 |    * 
161 |    * @returns {tags?: string[], files?: { mimeTypes: string[], extensions: string[] }, patterns?: { [string]: RegEx }}
162 |    */ 
163 |   // static get pasteConfig() {
164 |   //   return {
165 |   //     /**
166 |   //      * Paste HTML into Editor
167 |   //      */
168 |   //     tags: [],
169 |     
170 |   //     /**
171 |   //      * Paste URL of media into the Editor
172 |   //      */
173 |   //     patterns: {},
174 |     
175 |   //     /**
176 |   //      * Drag n drop file from into the Editor
177 |   //      */
178 |   //     files: {
179 |   //       mimeTypes: [ ],
180 |   //     },
181 |   //   };
182 |   // }
183 | 
184 |   /**
185 |    * Clean unwanted HTML tags or attributes
186 |    * @link https://editorjs.io/tools-api#sanitize
187 |    * 
188 |    * @returns {{[string]: boolean|object}} - Sanitizer rules
189 |    */
190 |   // static get sanitize() {
191 |   //   return {};
192 |   // } 
193 | 
194 |   /**
195 |    * Describe an icon and title here
196 |    * Required if Tools should be added to the Toolbox
197 |    * @link https://editorjs.io/tools-api#toolbox
198 |    * 
199 |    * @returns {{icon: string, title: string}}
200 |    */
201 |   static get toolbox() {
202 |     return {
203 |       title: 'VAR_TOOL_NAME',
204 |       icon: IconStar,
205 |     };
206 |   }
207 | 
208 |   /**
209 |    * Shortcut that fires render method and inserts new Block
210 |    * @link https://editorjs.io/tools-api#shortcut
211 |    * 
212 |    * @returns {string}
213 |    */
214 |   // static get shortcut() {
215 |   //   // return 'CMD+SHIFT+I';
216 |   // }
217 | 
218 |   /**
219 |    * Config allows Tool to specify how it can be converted into/from another Tool
220 |    * 
221 |    * @link https://editorjs.io/tools-api#conversionconfig
222 |    * 
223 |    * @returns {{export: string|function, import: string|function}}
224 |    */
225 |   // static get conversionConfig() {
226 |   //   // return {
227 |   //   //   export: (data) => {
228 |   //   //     return data.items.join('.'); // in this example, all list items will be concatenated to an export string
229 |   //   //   },
230 |   //   //  
231 |   //   //   /**
232 |   //   //    * In this example, List Tool creates items by splitting original text by a dot symbol. 
233 |   //   //    */
234 |   //   //   import: (string) => {
235 |   //   //     const items = string.split('.');
236 |   //   //
237 |   //   //     return {
238 |   //   //       items: items.filter( (text) => text.trim() !== ''),
239 |   //   //       type: 'unordered'
240 |   //   //     };
241 |   //   //   }
242 |   //   // };
243 |   // }
244 | 
245 |   /**
246 |    * With this option, Editor.js won't handle Enter keydowns
247 |    * @link https://editorjs.io/tools-api#enablelinebreaks
248 |    * 
249 |    * @returns {boolean}
250 |    */ 
251 |   // static get enableLineBreaks() {
252 |   //   return true;
253 |   // }
254 | 
255 |   /**
256 |    * This flag tells core that current tool supports the read-only mode
257 |    * @link https://editorjs.io/tools-api#isreadonlysupported
258 |    * 
259 |    * @returns {boolean}
260 |    */
261 |   // static get isReadOnlySupported() {
262 |   //   return true;
263 |   // } 
264 | 
265 |   /**
266 |    * LIFE CYCLE HOOKS
267 |    * 
268 |    * These methods are called by Editor.js core
269 |    * @link https://editorjs.io/tools-api#lifecycle-hooks
270 |    */
271 | 
272 |   /**
273 |    * Called after Block contents is added to the page
274 |    */
275 |   // rendered() {}
276 | 
277 |   /**
278 |    * Called each time Block contents is updated
279 |    */
280 |   // updated() {}
281 | 
282 |   /**
283 |    * Called after Block contents is removed from the page but before Block instance deleted
284 |    */
285 |   // removed() {}
286 | 
287 |   /**
288 |    * Called after Block is moved by move tunes or through API
289 |    * 
290 |    * @param {MoveEvent} event 
291 |    */
292 |   // moved(event) {}
293 | };


--------------------------------------------------------------------------------