fix to use with sveltekit
This commit is contained in:
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
tab_width = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{md,yml,yaml,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{md,yml,yaml}]
|
||||
trim_trailing_whitespace = false
|
||||
9
.eslintignore
Normal file
9
.eslintignore
Normal file
@@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
.svelte-kit
|
||||
build
|
||||
coverage
|
||||
dist
|
||||
node_modules
|
||||
package
|
||||
.env*
|
||||
vite.config.js.timestamp-*
|
||||
65
.eslintrc.yaml
Normal file
65
.eslintrc.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
root: true
|
||||
env:
|
||||
es2022: true
|
||||
browser: true
|
||||
node: true
|
||||
parserOptions:
|
||||
ecmaVersion: 13
|
||||
sourceType: module
|
||||
extraFileExtensions: ['.svelte']
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:svelte/recommended
|
||||
- prettier
|
||||
# - plugin:unicorn/recommended
|
||||
rules:
|
||||
camelcase: off
|
||||
capitalized-comments: off
|
||||
indent: [error, tab]
|
||||
linebreak-style: [error, unix]
|
||||
no-console: off
|
||||
no-debugger: off
|
||||
# no-multi-assign: off
|
||||
# no-multiple-empty-lines:
|
||||
# - error
|
||||
# -
|
||||
# max: 2
|
||||
# maxBOF: 2
|
||||
# maxEOF: 0
|
||||
# no-new-func: off
|
||||
no-undef-init: off
|
||||
no-unused-expressions:
|
||||
- error
|
||||
- allowShortCircuit: true
|
||||
allowTernary: true
|
||||
allowTaggedTemplates: true
|
||||
padding-line-between-statements: off
|
||||
quotes: [error, single]
|
||||
semi: [error, never]
|
||||
semi-spacing:
|
||||
- error
|
||||
- before: false
|
||||
after: true
|
||||
spaced-comment: off
|
||||
svelte/no-at-html-tags: off
|
||||
# unicorn/consistent-destructuring: off
|
||||
unicorn/filename-case: off
|
||||
# unicorn/import-style:
|
||||
# - error
|
||||
# -
|
||||
# styles:
|
||||
# util: false
|
||||
# path:
|
||||
# named: true
|
||||
# unicorn/no-abusive-eslint-disable: off
|
||||
unicorn/no-array-reduce: off
|
||||
# unicorn/no-negated-condition: off
|
||||
# unicorn/no-null: off
|
||||
unicorn/no-useless-undefined: off
|
||||
unicorn/no-zero-fractions: off
|
||||
# unicorn/prefer-dom-node-dataset: off
|
||||
unicorn/prefer-includes: off
|
||||
# unicorn/prefer-object-from-entries: off
|
||||
unicorn/prefer-query-selector: off
|
||||
unicorn/prevent-abbreviations: off
|
||||
unicorn/prefer-top-level-await: off
|
||||
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.DS_Store
|
||||
.svelte-kit
|
||||
build
|
||||
coverage
|
||||
dist
|
||||
node_modules
|
||||
package
|
||||
.env*
|
||||
vite.config.js.timestamp-*
|
||||
|
||||
coverage/**
|
||||
!coverage/lcov.info
|
||||
33
.gitlab-ci.yml
Normal file
33
.gitlab-ci.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
include:
|
||||
- project: "inovacao/devops/template-cicd"
|
||||
file: "test-package-js.yaml"
|
||||
- project: "inovacao/devops/template-cicd"
|
||||
file: "sonar-js.yaml"
|
||||
- project: "inovacao/devops/template-cicd"
|
||||
file: "publish-package-js.yaml"
|
||||
- project: "inovacao/devops/template-cicd"
|
||||
file: "copy-package-js.yaml"
|
||||
|
||||
test:
|
||||
extends: .test
|
||||
|
||||
sonar:
|
||||
extends: .sonar_js
|
||||
variables:
|
||||
SONAR_SOURCE: "src"
|
||||
SONAR_TEST: "tests"
|
||||
|
||||
publish:
|
||||
extends: .publish
|
||||
script:
|
||||
- npm i
|
||||
- !reference [.publish, script]
|
||||
|
||||
copy:
|
||||
extends: .copy
|
||||
|
||||
stages:
|
||||
- test
|
||||
- sonar
|
||||
- release
|
||||
- copy
|
||||
3
.npmrc
Normal file
3
.npmrc
Normal file
@@ -0,0 +1,3 @@
|
||||
engine-strict=true
|
||||
resolution-mode=highest
|
||||
auto-install-peers=true
|
||||
15
.prettierignore
Normal file
15
.prettierignore
Normal file
@@ -0,0 +1,15 @@
|
||||
*.css
|
||||
.*
|
||||
bin
|
||||
build
|
||||
coverage
|
||||
dist
|
||||
node_modules
|
||||
package
|
||||
# template.js
|
||||
vite.config.js.timestamp-*
|
||||
|
||||
*.json
|
||||
*.yaml
|
||||
*.yml
|
||||
*.md
|
||||
23
.prettierrc.yaml
Normal file
23
.prettierrc.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
arrowParens: avoid
|
||||
bracketSameLine: false
|
||||
bracketSpacing: false
|
||||
# embeddedLanguageFormatting: auto
|
||||
insertPragma: false
|
||||
htmlWhitespaceSensitivity: css
|
||||
printWidth: 120
|
||||
proseWrap: preserve
|
||||
quoteProps: as-needed
|
||||
requirePragma: false
|
||||
semi: false
|
||||
singleAttributePerLine: false
|
||||
singleQuote: true
|
||||
trailingComma: all
|
||||
tabWidth: 4
|
||||
useTabs: true
|
||||
|
||||
overrides:
|
||||
- files: '*.svelte'
|
||||
options:
|
||||
parser: svelte
|
||||
plugins:
|
||||
- prettier-plugin-svelte
|
||||
71
README.md
Normal file
71
README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# svelte-editor-quill
|
||||
|
||||
[![NPM version][npm-img]][npm]
|
||||
[![Build Status][ci-img]][ci]
|
||||
|
||||
|
||||
[npm-img]: https://img.shields.io/npm/v/@tadashi/svelte-editor-quill.svg
|
||||
[npm]: https://www.npmjs.com/package/@tadashi/svelte-editor-quill
|
||||
[ci-img]: https://github.com/lagden/svelte-editor-quill/workflows/Node.js%20CI/badge.svg
|
||||
[ci]: https://github.com/lagden/svelte-editor-quill/actions?query=workflow%3A%22Node.js+CI%22
|
||||
|
||||
---
|
||||
|
||||
Svelte component
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm i @tadashi/svelte-editor-quill
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
See an example here: https://svelte.dev/repl/839ad6a3e1e24b149099c704e18df476?version=3.32.3
|
||||
|
||||
### options
|
||||
|
||||
> Type: object
|
||||
> Default: {theme: 'snow'}
|
||||
|
||||
See the `options` here: https://quilljs.com/docs/configuration/#options
|
||||
|
||||
|
||||
### options.plainclipboard
|
||||
|
||||
> Type: boolean
|
||||
> Default: false
|
||||
|
||||
Accept only paste plain text.
|
||||
|
||||
|
||||
### Sample
|
||||
|
||||
```html
|
||||
<script>
|
||||
import {Editor} from '@tadashi/svelte-editor-quill'
|
||||
|
||||
const options = {
|
||||
theme: 'snow',
|
||||
plainclipboard: true
|
||||
}
|
||||
|
||||
function onTextChange(event) {
|
||||
console.log(event.detail)
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="preconnect" href="https://cdn.quilljs.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://cdn.quilljs.com/1.3.7/quill.snow.css">
|
||||
</svelte:head>
|
||||
|
||||
<Editor {options} on:text-change={onTextChange} data='Apenas um show' />
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Thiago Lagden](https://github.com/lagden)
|
||||
54
bin/helper/fn
Executable file
54
bin/helper/fn
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
abort() {
|
||||
printf "\n \033[31mError: $@\033[0m\n\n" && exit 1
|
||||
}
|
||||
|
||||
ok() {
|
||||
printf "\n \033[32mOk: $@\033[0m\n\n"
|
||||
}
|
||||
|
||||
load_env() {
|
||||
_DIR="$(pwd)"
|
||||
ENVFILE_LOCAL="${2:-$_DIR}/.conf/local.sh"
|
||||
ENVFILE_OPT="${2:-$_DIR}/.conf/${1:-development}.sh"
|
||||
USE_LOCAL_ENV=0
|
||||
|
||||
if test ! -e $ENVFILE_OPT; then
|
||||
abort "Environment file not found"
|
||||
fi
|
||||
|
||||
set -a
|
||||
. ${ENVFILE_OPT}
|
||||
set +a
|
||||
|
||||
if test "${1}" = "development" -o "${1}" = "test"; then
|
||||
USE_LOCAL_ENV=1
|
||||
fi
|
||||
|
||||
if test -e $ENVFILE_LOCAL -a "${USE_LOCAL_ENV:-0}" = "1"; then
|
||||
set -a
|
||||
. ${ENVFILE_LOCAL}
|
||||
set +a
|
||||
fi
|
||||
}
|
||||
|
||||
gen_env() {
|
||||
_DIR="$(cd $(dirname $0) && pwd)"
|
||||
_BIN_DIR="$(cd $DIR/.. && pwd)"
|
||||
GEN_ENV="${2:-$_BIN_DIR}/node/env.js"
|
||||
|
||||
if test -z $1; then
|
||||
abort "Missing output"
|
||||
fi
|
||||
|
||||
if test ! -f "${GEN_ENV}"; then
|
||||
abort "File not found: ${GEN_ENV}"
|
||||
fi
|
||||
|
||||
_DIR_FILE=$(dirname $1)
|
||||
mkdir -p $_DIR_FILE
|
||||
|
||||
$GEN_ENV > $1
|
||||
ok "ENVs generated... ${1}"
|
||||
}
|
||||
32
bin/helper/wait
Executable file
32
bin/helper/wait
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
: ${SLEEP_LENGTH:=2}
|
||||
: ${TIMEOUT_LENGTH:=60}
|
||||
|
||||
DIR="$(cd $(dirname $0) && pwd)"
|
||||
BIN_DIR="$(cd $DIR/.. && pwd)"
|
||||
|
||||
# Import functions
|
||||
. $BIN_DIR/helper/fn
|
||||
|
||||
wait_for() {
|
||||
START="$(date +%s)"
|
||||
echo "Waiting for $1 to listen on $2..."
|
||||
while ! nc -z $1 $2; do
|
||||
if [ $(($(date +%s) - $START)) -gt $TIMEOUT_LENGTH ]; then
|
||||
abort "Service $1:$2 did not start within $TIMEOUT_LENGTH seconds. Aborting..."
|
||||
fi
|
||||
echo "sleeping"
|
||||
sleep $SLEEP_LENGTH
|
||||
done
|
||||
}
|
||||
|
||||
for var in "$@"
|
||||
do
|
||||
host=${var%:*}
|
||||
port=${var#*:}
|
||||
wait_for $host $port
|
||||
ok "Listening ${host}:${port}"
|
||||
done
|
||||
|
||||
exit 0
|
||||
68
bin/node/pkg.js
Executable file
68
bin/node/pkg.js
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import path from 'node:path'
|
||||
import {pathToFileURL} from 'node:url'
|
||||
import {createWriteStream} from 'node:fs'
|
||||
import {readFile} from 'node:fs/promises'
|
||||
import {promisify} from 'node:util'
|
||||
import child_process from 'node:child_process'
|
||||
|
||||
const exec = promisify(child_process.exec)
|
||||
|
||||
const packageFile = pathToFileURL(path.resolve(process.cwd(), 'package.json'))
|
||||
const packageBuf = await readFile(packageFile)
|
||||
const packageJson = JSON.parse(packageBuf)
|
||||
|
||||
const {
|
||||
dependencies,
|
||||
devDependencies,
|
||||
} = packageJson
|
||||
|
||||
let cc = 0
|
||||
|
||||
function _error(message) {
|
||||
process.stderr.write(message)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
function getLatestVersionPackage(data, prop) {
|
||||
if (!data) {
|
||||
return Promise.resolve('no data to show')
|
||||
}
|
||||
|
||||
const keys = Object.keys(data)
|
||||
return Promise.allSettled(
|
||||
keys.map(async name => {
|
||||
const cmd = `npm show ${name} version`
|
||||
let {stdout: version} = await exec(cmd)
|
||||
version = String(version).replace('\n', '')
|
||||
if (version && data[name] !== String(version)) {
|
||||
cc++
|
||||
process.stdout.write(`${name} --> ${version}\n`)
|
||||
packageJson[prop][name] = version
|
||||
return {name, version}
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
getLatestVersionPackage(dependencies, 'dependencies'),
|
||||
getLatestVersionPackage(devDependencies, 'devDependencies'),
|
||||
])
|
||||
|
||||
createWriteStream(packageFile)
|
||||
.on('finish', () => {
|
||||
process.stdout.write(cc > 0 ? 'All writes are now complete.' : 'No updates')
|
||||
})
|
||||
.on('close', () => {
|
||||
process.exit(0)
|
||||
})
|
||||
.on('error', error => {
|
||||
_error(error.message)
|
||||
})
|
||||
.end(`${JSON.stringify(packageJson, undefined, ' ')}\n`)
|
||||
} catch (error) {
|
||||
_error(error.message)
|
||||
}
|
||||
94
bin/node/zera
Executable file
94
bin/node/zera
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
DIR="$(cd $(dirname $0) && pwd)"
|
||||
BIN_DIR="$(cd $DIR/.. && pwd)"
|
||||
|
||||
# Import functions
|
||||
. $BIN_DIR/helper/fn
|
||||
|
||||
# Usage
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
|
||||
Usage: $0 [options...]
|
||||
|
||||
Options:
|
||||
-m, --manager <manager> Package manager: npm (default), yarn or pnpm
|
||||
-s, --shame Shamefully hoist (only pnpm)
|
||||
-h, --help Show usage
|
||||
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
unset CURR_FOLDER
|
||||
CURR_FOLDER="$(pwd)"
|
||||
|
||||
unset ACTION
|
||||
ACTION=npm
|
||||
|
||||
unset SHAME
|
||||
SHAME=""
|
||||
|
||||
unset VERBOSE
|
||||
VERBOSE=false
|
||||
|
||||
unset CMD_AVAILABLE
|
||||
CMD_AVAILABLE=("npm" "yarn" "pnpm")
|
||||
|
||||
for i in "$@"; do
|
||||
case $i in
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
-m|--manager)
|
||||
ACTION="${2}"
|
||||
shift
|
||||
;;
|
||||
-s|--shame)
|
||||
SHAME="--shamefully-hoist"
|
||||
shift
|
||||
;;
|
||||
-*|--*)
|
||||
abort "Unknown option $i"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check command available
|
||||
[[ ! " ${CMD_AVAILABLE[*]} " =~ " ${ACTION} " ]] && usage
|
||||
|
||||
# Go to current directory
|
||||
cd $CURR_FOLDER
|
||||
|
||||
# Remove current data
|
||||
rm -rf \
|
||||
"${CURR_FOLDER}/node_modules" \
|
||||
"${CURR_FOLDER}/package-lock.json" \
|
||||
"${CURR_FOLDER}/yarn.lock" \
|
||||
"${CURR_FOLDER}/.yarn" \
|
||||
"${CURR_FOLDER}/.yarnrc.yml" \
|
||||
"${CURR_FOLDER}/.pnp.*" \
|
||||
"${CURR_FOLDER}/pnpm-lock.yaml"
|
||||
|
||||
# Generate .yarnrc.yml
|
||||
if [ "${ACTION}" = "yarn" ]; then
|
||||
echo "" > "${CURR_FOLDER}/.yarnrc.yml"
|
||||
yarn set version stable
|
||||
echo "nodeLinker: node-modules" >> "${CURR_FOLDER}/.yarnrc.yml"
|
||||
fi
|
||||
|
||||
# Install packages
|
||||
if [ "${ACTION}" = "pnpm" ]; then
|
||||
$ACTION install $SHAME
|
||||
else
|
||||
$ACTION install
|
||||
fi
|
||||
|
||||
# Audit packages
|
||||
test $? -ne 0 && abort "${ACTION} failed" || ok "zerado..."
|
||||
test "${ACTION}" = "yarn" && yarn npm audit || $ACTION audit
|
||||
|
||||
exit 0
|
||||
12
jsconfig.json
Normal file
12
jsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "NodeNext",
|
||||
"module": "NodeNext"
|
||||
}
|
||||
}
|
||||
87
package.json
Normal file
87
package.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"name": "@tadashi/svelte-editor-quill",
|
||||
"version": "2.2.0",
|
||||
"description": "Svelte component",
|
||||
"author": "Thiago Lagden",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/lagden/svelte-editor-quill/issues"
|
||||
},
|
||||
"homepage": "https://github.com/lagden/svelte-editor-quill#readme",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"svelte",
|
||||
"editor",
|
||||
"quill",
|
||||
"component"
|
||||
],
|
||||
"svelte": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"svelte": "./dist/index.js"
|
||||
},
|
||||
"./dist/quill.js": {
|
||||
"types": "./dist/quill.d.ts",
|
||||
"svelte": "./dist/quill.js"
|
||||
},
|
||||
"./dist/Editor.svelte": {
|
||||
"types": "./dist/Editor.svelte.d.ts",
|
||||
"svelte": "./dist/Editor.svelte"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"!dist/**/*.test.*",
|
||||
"!dist/**/*.spec.*"
|
||||
],
|
||||
"scripts": {
|
||||
"rm": "rimraf dist",
|
||||
"dev": "vite dev",
|
||||
"build:vite": "vite build",
|
||||
"build": "run-s rm build:vite package",
|
||||
"preview": "vite preview",
|
||||
"package": "svelte-kit sync && svelte-package && publint",
|
||||
"prepublishOnly": "run-s test build",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
||||
"test": "run-s rm lint test:integration test:unit",
|
||||
"lint": "prettier --check --plugin prettier-plugin-svelte . && eslint .",
|
||||
"format": "prettier --write --plugin prettier-plugin-svelte .",
|
||||
"test:integration": "playwright test",
|
||||
"test:unit": "vitest --run --coverage",
|
||||
"test:ui": "vitest --ui --coverage"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": ">=3.50.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"quill": "1.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.40.1",
|
||||
"@sveltejs/adapter-auto": "2.1.1",
|
||||
"@sveltejs/kit": "1.28.0",
|
||||
"@sveltejs/package": "2.2.3",
|
||||
"@vitest/coverage-v8": "1.0.4",
|
||||
"@vitest/ui": "1.0.4",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-svelte": "2.35.1",
|
||||
"jsdom": "23.0.1",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "3.1.1",
|
||||
"prettier-plugin-svelte": "3.1.2",
|
||||
"publint": "0.2.6",
|
||||
"rimraf": "5.0.5",
|
||||
"svelte": "4.2.8",
|
||||
"svelte-check": "3.6.2",
|
||||
"tslib": "2.6.2",
|
||||
"typescript": "5.3.3",
|
||||
"vite": "4.5.1",
|
||||
"vitest": "1.0.4"
|
||||
}
|
||||
}
|
||||
12
playwright.config.js
Normal file
12
playwright.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
webServer: {
|
||||
command: 'env PREVIEW=1 npm run build && npm run preview',
|
||||
port: 4173,
|
||||
},
|
||||
testDir: 'tests/e2e',
|
||||
testMatch: /(.+\.)(test|spec)\.[jt]s/,
|
||||
outputDir: 'tests/e2e/__snapshots__',
|
||||
}
|
||||
|
||||
export default config
|
||||
4043
pnpm-lock.yaml
generated
Normal file
4043
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
src/app.d.ts
vendored
Normal file
14
src/app.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/** @format */
|
||||
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
14
src/app.html
Normal file
14
src/app.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!-- @format -->
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div>%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
30
src/lib/Editor.svelte
Normal file
30
src/lib/Editor.svelte
Normal file
@@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import {onMount, onDestroy} from 'svelte'
|
||||
|
||||
export let options = {}
|
||||
export let data = ''
|
||||
|
||||
let className = ''
|
||||
export {className as class}
|
||||
|
||||
options = {
|
||||
theme: 'snow',
|
||||
...options,
|
||||
}
|
||||
|
||||
let node
|
||||
let destroy
|
||||
|
||||
onMount(async () => {
|
||||
const {quill} = await import('./quill.js')
|
||||
destroy = quill(node, options)
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
destroy && destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class={className}>
|
||||
<div bind:this={node} on:text-change>{@html data}</div>
|
||||
</div>
|
||||
2
src/lib/index.js
Normal file
2
src/lib/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// prettier-ignore
|
||||
export {default as Editor} from './Editor.svelte'
|
||||
61
src/lib/quill.js
Normal file
61
src/lib/quill.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import Quill from 'quill'
|
||||
|
||||
const Clipboard = Quill.import('modules/clipboard')
|
||||
const Delta = Quill.import('delta')
|
||||
|
||||
class PlainClipboard extends Clipboard {
|
||||
convert(html) {
|
||||
if (typeof html === 'string') {
|
||||
this.container.innerHTML = html
|
||||
}
|
||||
const text = this.container.textContent
|
||||
this.container.innerHTML = ''
|
||||
return new Delta().insert(text)
|
||||
}
|
||||
}
|
||||
|
||||
export function quill(node, options) {
|
||||
const toolbar = [
|
||||
[{header: 1}, {header: 2}],
|
||||
['bold', 'italic', 'underline'],
|
||||
[{list: 'ordered'}, {list: 'bullet'}],
|
||||
['link', 'image', 'video'],
|
||||
['code-block', 'clean'],
|
||||
]
|
||||
|
||||
const {plainclipboard} = options
|
||||
if (plainclipboard) {
|
||||
Quill.register('modules/clipboard', PlainClipboard, true)
|
||||
}
|
||||
|
||||
if (Reflect.has(options, 'plainclipboard')) {
|
||||
Reflect.deleteProperty(options, 'plainclipboard')
|
||||
}
|
||||
|
||||
const q = new Quill(node, {
|
||||
modules: {
|
||||
toolbar,
|
||||
},
|
||||
placeholder: 'Digite algo...',
|
||||
...options,
|
||||
})
|
||||
|
||||
const _container = node.querySelector('.ql-editor')
|
||||
|
||||
const onTextChange = () => {
|
||||
const html = _container?.innerHTML ?? ''
|
||||
const customEvent = new CustomEvent('text-change', {
|
||||
detail: {
|
||||
html,
|
||||
text: q.getText(),
|
||||
},
|
||||
})
|
||||
node.dispatchEvent(customEvent)
|
||||
}
|
||||
|
||||
q.on('text-change', onTextChange)
|
||||
|
||||
return () => {
|
||||
q.off('text-change', onTextChange)
|
||||
}
|
||||
}
|
||||
19
src/routes/+page.svelte
Normal file
19
src/routes/+page.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script>
|
||||
import {Editor} from '$lib/index.js'
|
||||
|
||||
const options = {
|
||||
theme: 'snow',
|
||||
plainclipboard: true,
|
||||
}
|
||||
|
||||
function onTextChange(event) {
|
||||
console.debug(event.detail)
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="preconnect" href="https://cdn.quilljs.com" crossorigin />
|
||||
<link rel="stylesheet" href="https://cdn.quilljs.com/1.3.7/quill.snow.css" crossorigin />
|
||||
</svelte:head>
|
||||
|
||||
<Editor {options} on:text-change={onTextChange} data="Apenas um show" />
|
||||
BIN
static/favicon.png
Normal file
BIN
static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
10
svelte.config.js
Normal file
10
svelte.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import adapter from '@sveltejs/adapter-auto'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
BIN
tests/e2e/__snapshots__/index.spec.js.png
Normal file
BIN
tests/e2e/__snapshots__/index.spec.js.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
15
tests/e2e/index.spec.js
Normal file
15
tests/e2e/index.spec.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import {setTimeout} from 'node:timers/promises'
|
||||
import {
|
||||
// expect,
|
||||
test,
|
||||
} from '@playwright/test'
|
||||
|
||||
test('general', async ({page}) => {
|
||||
await page.goto('/')
|
||||
|
||||
await setTimeout(1000)
|
||||
|
||||
await page.screenshot({
|
||||
path: './tests/e2e/__snapshots__/index.spec.js.png',
|
||||
})
|
||||
})
|
||||
26
tests/unit/quill.spec.js
Normal file
26
tests/unit/quill.spec.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import {setTimeout} from 'timers/promises'
|
||||
import {test, expect, beforeAll} from 'vitest'
|
||||
import {Editor} from '$lib/index.js'
|
||||
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML = '<main id="xxx"></main>'
|
||||
})
|
||||
|
||||
function doc_query(selector) {
|
||||
const node = document.querySelector(selector)
|
||||
if (!node) {
|
||||
throw new Error(`No element found for selector: ${selector}`)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
test('Editor', async () => {
|
||||
const target = doc_query('main#xxx')
|
||||
// const component = new Editor({target})
|
||||
new Editor({target})
|
||||
|
||||
await setTimeout(3000)
|
||||
|
||||
// const div = doc_query('div.ql-editor')
|
||||
expect(target).toBeDefined()
|
||||
})
|
||||
39
vite.config.js
Normal file
39
vite.config.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import {sveltekit} from '@sveltejs/kit/vite'
|
||||
import {defineConfig} from 'vitest/config'
|
||||
|
||||
const preview = process?.env?.PREVIEW ?? false
|
||||
const config = {
|
||||
plugins: [sveltekit()],
|
||||
test: {
|
||||
include: ['tests/unit/**/*.{test,spec}.{js,ts}'],
|
||||
environment: 'jsdom',
|
||||
threads: false,
|
||||
globals: true,
|
||||
coverage: {
|
||||
// prettier-ignore
|
||||
include: ['src/lib/**'],
|
||||
// prettier-ignore
|
||||
reporter: [
|
||||
'text',
|
||||
'text-summary',
|
||||
'lcovonly',
|
||||
'cobertura'
|
||||
],
|
||||
},
|
||||
},
|
||||
build: {
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
// prettier-ignore
|
||||
external: [
|
||||
'quill',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if (preview) {
|
||||
Reflect.deleteProperty(config, 'build')
|
||||
}
|
||||
|
||||
export default defineConfig(config)
|
||||
Reference in New Issue
Block a user