From 907bee052741fa1b6c53c355c417dd9faf48d615 Mon Sep 17 00:00:00 2001 From: Sahatsawat Kanpai Date: Wed, 15 Jan 2025 17:58:02 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20init=20project=20with=20ckeditor5-e?= =?UTF-8?q?xport=20template,=20with=20new=20ckeditor.svg=20content=20resiz?= =?UTF-8?q?ed=20into=2020x20=20px?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 19 + .eslintrc.cjs | 46 + .gitattributes | 19 + .gitignore | 10 + .stylelintrc | 3 + LICENSE.md | 6 + README.md | 141 + ckeditor5-metadata.json | 17 + lang/contexts.json | 3 + package-lock.json | 21727 +++++++++++++++++++++++++++++ package.json | 99 + sample/ckeditor.ts | 205 + sample/dll.html | 172 + sample/index.html | 92 + scripts/build-dist.mjs | 65 + src/augmentation.ts | 7 + src/import.ts | 112 + src/index.ts | 8 + tests/import.ts | 55 + tests/index.ts | 17 + theme/icons/ckeditor.svg | 24 + tsconfig.dist.json | 11 + tsconfig.json | 38 + tsconfig.release.json | 12 + tsconfig.test.json | 15 + typings/ckeditor5-inspector.d.ts | 7 + typings/types.d.ts | 4 + vitest.config.ts | 40 + webpack.config.js | 27 + 29 files changed, 23001 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintrc.cjs create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .stylelintrc create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 ckeditor5-metadata.json create mode 100644 lang/contexts.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 sample/ckeditor.ts create mode 100644 sample/dll.html create mode 100644 sample/index.html create mode 100644 scripts/build-dist.mjs create mode 100644 src/augmentation.ts create mode 100644 src/import.ts create mode 100644 src/index.ts create mode 100644 tests/import.ts create mode 100644 tests/index.ts create mode 100644 theme/icons/ckeditor.svg create mode 100644 tsconfig.dist.json create mode 100644 tsconfig.json create mode 100644 tsconfig.release.json create mode 100644 tsconfig.test.json create mode 100644 typings/ckeditor5-inspector.d.ts create mode 100644 typings/types.d.ts create mode 100644 vitest.config.ts create mode 100644 webpack.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..37ea8ff --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# Configurations to normalize the IDE behavior. +# http://editorconfig.org/ + +root = true + +[*] +indent_style = tab +tab_width = 4 +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{js,jsx,ts}] +quote_type = single + +[package.json] +indent_style = space +tab_width = 2 diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..aa41a27 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,46 @@ +/* eslint-env node */ + +'use strict'; + +module.exports = { + extends: 'ckeditor5', + parser: '@typescript-eslint/parser', + plugins: [ + '@typescript-eslint' + ], + root: true, + ignorePatterns: [ + // Ignore the entire `dist/` (the NIM build). + 'dist/**', + // Ignore compiled JavaScript files, as they are generated automatically. + 'src/**/*.js', + // Also, do not check typing declarations, too. + 'src/**/*.d.ts' + ], + rules: { + // This rule disallows importing from any path other than the package main entrypoint. + 'ckeditor5-rules/allow-imports-only-from-main-package-entry-point': 'error', + // This rule ensures that all imports from `@ckeditor/*` packages are done through the main package entry points. + // This is required for the editor types to work properly and to ease migration to the installation methods + // introduced in CKEditor 5 version 42.0.0. + 'ckeditor5-rules/no-legacy-imports': 'error', + // As required by the ECMAScript (ESM) standard, all imports must include a file extension. + // If the import does not include it, this rule will try to automatically detect the correct file extension. + 'ckeditor5-rules/require-file-extensions-in-imports': [ + 'error', + { + extensions: [ '.ts', '.js', '.json' ] + } + ] + }, + overrides: [ + { + files: [ 'tests/**/*.[jt]s', 'sample/**/*.[jt]s' ], + rules: { + // To write complex tests, you may need to import files that are not exported in DLL files by default. + // Hence, imports CKEditor 5 packages in test files are not checked. + 'ckeditor5-rules/ckeditor-imports': 'off' + } + } + ] +}; diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..41be6fa --- /dev/null +++ b/.gitattributes @@ -0,0 +1,19 @@ +* text=auto + +*.htaccess eol=lf +*.cgi eol=lf +*.sh eol=lf + +*.css text +*.htm text +*.html text +*.js text +*.ts text +*.json text +*.php text +*.txt text +*.md text + +*.png -text +*.gif -text +*.jpg -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..437dda1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +build/ +coverage/ +dist/ +node_modules/ +tmp/ +sample/ckeditor.dist.js + +# Ignore compiled TypeScript files. +src/**/*.js +src/**/*.d.ts diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 0000000..1d86a41 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-ckeditor5" +} diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..de483eb --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,6 @@ +Software License Agreement +========================== + +Copyright (c) 2024. All rights reserved. + +Licensed under the terms of [MIT license](https://opensource.org/licenses/MIT). diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e888ef --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +@esi_package/ckeditor5-import +============================= + +This package was created by the [ckeditor5-package-generator](https://www.npmjs.com/package/ckeditor5-package-generator) package. + +## Table of contents + +* [Developing the package](#developing-the-package) +* [Available scripts](#available-scripts) + * [`start`](#start) + * [`test`](#test) + * [`lint`](#lint) + * [`stylelint`](#stylelint) + * [`build:dist`](#builddist) + * [`translations:synchronize`](#translationssynchronize) + * [`translations:validate`](#translationsvalidate) + * [`ts:build` and `ts:clear`](#tsbuild-and-tsclear) +* [License](#license) + +## Developing the package + +To read about the CKEditor 5 Framework, visit the [CKEditor 5 Framework documentation](https://ckeditor.com/docs/ckeditor5/latest/framework/index.html). + +## Available scripts + +NPM scripts are a convenient way to provide commands in a project. They are defined in the `package.json` file and shared with people contributing to the project. It ensures developers use the same command with the same options (flags). + +All the scripts can be executed by running `npm run + + + + + + + + + + + + + + + + + + + + diff --git a/sample/index.html b/sample/index.html new file mode 100644 index 0000000..ac31c8f --- /dev/null +++ b/sample/index.html @@ -0,0 +1,92 @@ + + + + + + + CKEditor 5 – Development Sample + + + + + +

CKEditor 5 – Development Sample

+ +
+

ในการทดลองวัดความยาวของวัตถุชิ้นหนึ่งที่มีความยาวประมาณ + 6 เซนติเมตร ด้วยไม้บรรทัดที่มีความละเอียด 0.1 เซนติเมตร โดยทำการวัดทั้งหมด 5 ครั้ง ได้ข้อมูลดังนี้

+

5.84 6.00 6.26 5.90 + 12.25

+

ถ้าจะต้องรายงานค่าเฉลี่ยของการวัดความยาวครั้งนี้    +   + และรายงานความคลายเคลื่อนของความยาวเฉลี่ย    +   + ด้วยสูตร

+

+    +  

+

เมื่อ    +   + และ    +   + คือ ค่าที่มากที่สุด + และค่าที่น้อยที่สุดของข้อมูล ตามลำดับ

+

ข้อใดแสดงผลการรายงานการวัดความยาวได้ถูกต้อง +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ตารางเรียนปีการศึกษา 2567 ภาคปลาย (Spring2024)
วันเวลา0900 - 12001300 - 16001630 - 1900
วันพฤหัสProb StatSeminarComSys Security
lathmive + + + + + +
+
+
+ + + + + diff --git a/scripts/build-dist.mjs b/scripts/build-dist.mjs new file mode 100644 index 0000000..498384f --- /dev/null +++ b/scripts/build-dist.mjs @@ -0,0 +1,65 @@ +#!/usr/bin/env node + +/** + * @license Copyright (c) 2020-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* eslint-env node */ + +import { createRequire } from 'module'; +import upath from 'upath'; +import chalk from 'chalk'; +import { build } from '@ckeditor/ckeditor5-dev-build-tools'; + +function dist( path ) { + return upath.join( 'dist', path ); +} + +( async () => { + const tsconfig = 'tsconfig.dist.ckeditor5.json'; + + /** + * Step 1 + */ + console.log( chalk.cyan( '1/2: Generating NPM build...' ) ); + + const require = createRequire( import.meta.url ); + const pkg = require( upath.resolve( process.cwd(), './package.json' ) ); + + await build( { + input: 'src/index.ts', + output: dist( './index.js' ), + tsconfig: 'tsconfig.dist.json', + external: [ + 'ckeditor5', + 'ckeditor5-premium-features', + ...Object.keys( { + ...pkg.dependencies, + ...pkg.peerDependencies + } ) + ], + clean: true, + sourceMap: true, + declarations: true, + translations: '**/*.po' + } ); + + /** + * Step 2 + */ + console.log( chalk.cyan( '2/2: Generating browser build...' ) ); + + await build( { + output: dist( 'browser/index.js' ), + tsconfig, + sourceMap: true, + minify: true, + browser: true, + name: 'ckeditor5-import', + external: [ + 'ckeditor5', + 'ckeditor5-premium-features' + ] + } ); +} )(); diff --git a/src/augmentation.ts b/src/augmentation.ts new file mode 100644 index 0000000..b8e8650 --- /dev/null +++ b/src/augmentation.ts @@ -0,0 +1,7 @@ +import type { Import } from './index.js'; + +declare module '@ckeditor/ckeditor5-core' { + interface PluginsMap { + [ Import.pluginName ]: Import; + } +} diff --git a/src/import.ts b/src/import.ts new file mode 100644 index 0000000..f5a9ce6 --- /dev/null +++ b/src/import.ts @@ -0,0 +1,112 @@ +import { Plugin, ButtonView } from 'ckeditor5'; + +import ckeditor5Icon from '../theme/icons/ckeditor.svg'; + +import { asBlob } from 'html-docx-js-typescript'; +import { saveAs } from 'file-saver'; + +import Temml from 'temml'; + +export default class Import extends Plugin { + public static get pluginName() { + return 'Import' as const; + } + + public init(): void { + const editor = this.editor; + const t = editor.t; + const model = editor.model; + + // Add the "importButton" to feature components. + editor.ui.componentFactory.add( 'importButton', locale => { + const view = new ButtonView( locale ); + + view.set( { + label: t( 'Import' ), + icon: ckeditor5Icon, + tooltip: true + } ); + + // // Insert a text into the editor after clicking the button. + // this.listenTo( view, 'execute', () => { + // model.change( writer => { + // const textNode = writer.createText( 'Hello CKEditor 5!' ); + + // model.insertContent( textNode ); + // } ); + + // editor.editing.view.focus(); + // } ); + + // Insert a text into the editor after clicking the button. + // this.listenTo( view, 'execute', async () => { + // asBlob(this.editor.getData()).then((data: any) => { + // saveAs(data, 'file.docx') // save as docx file + // }) // asBlob() return Promise + + // editor.editing.view.focus(); + // } ); + + // POST fetch docx and download + this.listenTo( view, 'execute', async () => { + const parser = new DOMParser(); + const doc = parser.parseFromString(this.editor.getData(), "text/html"); + + // pre-process mathlive script to html MathML tag with the help of temml + for (const mathliveElement of doc.querySelectorAll('script[type="math/tex"]')) { + const temmlWrapperElement = document.createElement('span'); + const temmlMathMLString = Temml.render(mathliveElement.textContent ?? "", temmlWrapperElement); + mathliveElement.replaceWith(temmlWrapperElement); + } + + // pre-process for table + for (const table of doc.querySelectorAll('table')) { + // pre-process table for border and centering and inner border + table.style.borderCollapse = 'collapse'; + table.style.borderSpacing = '0'; + table.style.border = '1px solid #b3b3b3'; + table.style.margin = 'auto'; + // pre-process table for padding + for (const td of table.querySelectorAll('td')) { + td.style.padding = '8px'; + } + // pre-process table for inner border + for (const tr of table.querySelectorAll('tr')) { + for (const td of tr.querySelectorAll('td')) { + td.style.border = '1px solid #b3b3b3'; + } + } + // pre-process table for header background color rgba(0,0,0,.05) to hex #f2f2f2 + // and it's own border + // and padding + const ths = table.querySelectorAll('th'); + for (const th of ths) { + th.style.backgroundColor = '#f2f2f2'; + th.style.border = '1px solid #b3b3b3'; + th.style.padding = '8px'; + } + } + + console.log(doc.body.innerHTML); + + fetch('http://localhost:8080/aspose/html-to-word', { + method: 'POST', + body: doc.body.innerHTML, + headers: { + 'Content-Type': 'text/plain' + } + }) + .then(response => response.blob()) + .then(blob => { + saveAs(blob, 'stou.docx') // save as docx file + }) + .catch(error => { + console.error('Error:', error); + }); + editor.editing.view.focus(); + } ); + + return view; + } ); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..0a5fe4d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,8 @@ +import ckeditor from './../theme/icons/ckeditor.svg'; +import './augmentation.js'; + +export { default as Import } from './import.js'; + +export const icons = { + ckeditor +}; diff --git a/tests/import.ts b/tests/import.ts new file mode 100644 index 0000000..b600563 --- /dev/null +++ b/tests/import.ts @@ -0,0 +1,55 @@ +import { describe, expect, it, beforeEach, afterEach } from 'vitest'; +import { ClassicEditor, Essentials, Paragraph, Heading } from 'ckeditor5'; +import Import from '../src/import.js'; + +describe( 'Import', () => { + it( 'should be named', () => { + expect( Import.pluginName ).to.equal( 'Import' ); + } ); + + describe( 'init()', () => { + let domElement: HTMLElement, editor: ClassicEditor; + + beforeEach( async () => { + domElement = document.createElement( 'div' ); + document.body.appendChild( domElement ); + + editor = await ClassicEditor.create( domElement, { + plugins: [ + Paragraph, + Heading, + Essentials, + Import + ], + toolbar: [ + 'importButton' + ] + } ); + } ); + + afterEach( () => { + domElement.remove(); + return editor.destroy(); + } ); + + it( 'should load Import', () => { + const myPlugin = editor.plugins.get( 'Import' ); + + expect( myPlugin ).to.be.an.instanceof( Import ); + } ); + + it( 'should add an icon to the toolbar', () => { + expect( editor.ui.componentFactory.has( 'importButton' ) ).to.equal( true ); + } ); + + it( 'should add a text into the editor after clicking the icon', () => { + const icon = editor.ui.componentFactory.create( 'importButton' ); + + expect( editor.getData() ).to.equal( '' ); + + icon.fire( 'execute' ); + + expect( editor.getData() ).to.equal( '

Hello CKEditor 5!

' ); + } ); + } ); +} ); diff --git a/tests/index.ts b/tests/index.ts new file mode 100644 index 0000000..b25c644 --- /dev/null +++ b/tests/index.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; +import { Import as ImportDll, icons } from '../src/index.js'; +import Import from '../src/import.js'; + +import ckeditor from './../theme/icons/ckeditor.svg'; + +describe( 'CKEditor5 Import DLL', () => { + it( 'exports Import', () => { + expect( ImportDll ).to.equal( Import ); + } ); + + describe( 'icons', () => { + it( 'exports the "ckeditor" icon', () => { + expect( icons.ckeditor ).to.equal( ckeditor ); + } ); + } ); +} ); diff --git a/theme/icons/ckeditor.svg b/theme/icons/ckeditor.svg new file mode 100644 index 0000000..c0514eb --- /dev/null +++ b/theme/icons/ckeditor.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tsconfig.dist.json b/tsconfig.dist.json new file mode 100644 index 0000000..d174edb --- /dev/null +++ b/tsconfig.dist.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "bundler", + "rootDir": "./src", + "types": [ + "./typings/types" + ] + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..069e3cb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + /** + * TypeScript automagically loads typings from all "@types/*" packages if the "compilerOptions.types" array is not defined in + * this file. However, if some dependencies have "@types/*" packages as their dependencies, they'll also be loaded as well. + * As a result, TypeScript loaded "@types/node" which we don't want to use, because it allows using Node.js specific APIs that + * are not available in the browsers. + * + * To avoid such issues, we defined this empty "types" to disable automatic inclusion of the "@types/*" packages. + */ + "types": [], + "lib": [ + "ES2019", // Must match the "target". + "ES2020.String", + "DOM", + "DOM.Iterable" + ], + "noImplicitAny": true, + "noImplicitOverride": true, + "strict": true, + "target": "es2019", + "sourceMap": true, + "allowJs": true, + "moduleDetection": "force", + "moduleResolution": "NodeNext", + "module": "NodeNext", + "skipLibCheck": true, + "typeRoots": [ + "typings", + "node_modules/@types" + ] + }, + "include": [ + "./sample", + "./src", + "./typings" + ] +} diff --git a/tsconfig.release.json b/tsconfig.release.json new file mode 100644 index 0000000..b0b26a2 --- /dev/null +++ b/tsconfig.release.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "sourceMap": false, + "declaration": true + }, + "exclude": [ + "./tests/", + "./src", + "./sample/" + ] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..065d98e --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [ + "@types/mocha" + ], + "sourceMap": true + }, + "include": [ + "./sample", + "./src", + "./tests", + "./typings" + ] +} diff --git a/typings/ckeditor5-inspector.d.ts b/typings/ckeditor5-inspector.d.ts new file mode 100644 index 0000000..d50ee49 --- /dev/null +++ b/typings/ckeditor5-inspector.d.ts @@ -0,0 +1,7 @@ +declare module '@ckeditor/ckeditor5-inspector' { + const inspector: { + attach( editor: any ): void; + }; + + export default inspector; +} diff --git a/typings/types.d.ts b/typings/types.d.ts new file mode 100644 index 0000000..4333ece --- /dev/null +++ b/typings/types.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: string; + export default content; +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2758520 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,40 @@ +/** + * @license Copyright (c) 2023-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { defineConfig } from 'vitest/config'; +import svg from 'vite-plugin-svgo'; + +export default defineConfig( { + plugins: [ + svg() + ], + test: { + browser: { + enabled: true, + name: 'chrome', + provider: 'webdriverio', + providerOptions: {}, + headless: true, + ui: false + }, + include: [ + 'tests/**/*.[jt]s' + ], + globals: true, + watch: false, + coverage: { + thresholds: { + lines: 100, + functions: 100, + branches: 100, + statements: 100 + }, + provider: 'istanbul', + include: [ + 'src' + ] + } + } +} ); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..3d4c232 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,27 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.ts', // Entry point of your app + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.css$/, // Process CSS files + use: ['style-loader', 'css-loader'], + }, + { + test: /\.ts$/, // Process TypeScript files + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.ts', '.js'], // Resolve these extensions + }, + devtool: 'source-map', // Enable source maps for easier debugging + mode: 'development', // Set to 'production' for production builds +};