diff --git a/.travis.yml b/.travis.yml index 5ad0c7230..b899c05c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,6 @@ install: - yarn build:packages script: + - yarn audit-ci - yarn lint - yarn test diff --git a/README.md b/README.md index b5c68ac88..882b7e7ca 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ export default { | `extensions` | `Array` | `[]` | A list of extensions used, by the editor. This can be `Nodes`, `Marks` or `Plugins`. | | `useBuiltInExtensions` | `Boolean` | `true` | By default tiptap adds a `Doc`, `Paragraph` and `Text` node to the Prosemirror schema. | | `dropCursor` | `Object` | `{}` | Config for `prosemirror-dropcursor`. | +| `parseOptions` | `Object` | `{}` | A list of [Prosemirror parseOptions](https://prosemirror.net/docs/ref/#model.ParseOptions). | | `onInit` | `Function` | `undefined` | This will return an Object with the current `state` and `view` of Prosemirror on init. | | `onFocus` | `Function` | `undefined` | This will return an Object with the `event` and current `state` and `view` of Prosemirror on focus. | | `onBlur` | `Function` | `undefined` | This will return an Object with the `event` and current `state` and `view` of Prosemirror on blur. | @@ -81,14 +82,15 @@ export default { | **Method** | **Arguments**| **Description** | | --- | :---: | --- | -| `setContent` | `content, emitUpdate` | Replace the current content. You can pass an HTML string or a JSON document. `emitUpdate` defaults to `false`. | +| `setContent` | `content, emitUpdate, parseOptions` | Replace the current content. You can pass an HTML string or a JSON document. `emitUpdate` defaults to `false`. `parseOptions` defaults to those provided in constructor. | | `clearContent` | `emitUpdate` | Clears the current content. `emitUpdate` defaults to `false`. | | `setOptions` | `options` | Overwrites the current editor properties. | | `registerPlugin` | `plugin` | Register a Prosemirror plugin. | | `getJSON` | – | Get the current content as JSON. | | `getHTML` | – | Get the current content as HTML. | -| `focus` | — | Focus the editor | -| `destroy` | – | Destroys the editor. | +| `focus` | – | Focus the editor. | +| `blur` | – | Blur the editor. | +| `destroy` | – | Destroy the editor. | ## Components @@ -298,6 +300,7 @@ The most powerful feature of tiptap is that you can create your own extensions. | `commands({ schema, attrs })` | `Object` | `null` | Define a command. | | `inputRules({ schema })` | `Array` | `[]` | Define a list of input rules. | | `pasteRules({ schema })` | `Array` | `[]` | Define a list of paste rules. | +| `get update()` | `Function` | `undefined` | Called when options of extension are changed via `editor.extensions.options` | ### Node|Mark Class @@ -473,6 +476,7 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details. - [Philipp Kühn](https://github.com/philippkuehn) - [Christoph Flathmann](https://github.com/Chrissi2812) +- [Erick Wilder](https://github.com/erickwilder) - [All Contributors](../../contributors) ## Packages Using Tiptap diff --git a/build/examples/webpack.config.js b/build/examples/webpack.config.js index 0d4e5fac3..cbc987a7c 100644 --- a/build/examples/webpack.config.js +++ b/build/examples/webpack.config.js @@ -1,5 +1,7 @@ import path from 'path' import webpack from 'webpack' +import Fiber from 'fibers' +import DartSass from 'dart-sass' import { VueLoaderPlugin } from 'vue-loader' import SvgStore from 'webpack-svgstore-plugin' import CopyWebpackPlugin from 'copy-webpack-plugin' @@ -87,7 +89,13 @@ export default { ifDev('vue-style-loader', MiniCssExtractPlugin.loader), 'css-loader', 'postcss-loader', - 'sass-loader', + { + loader: 'sass-loader', + options: { + implementation: DartSass, + fiber: Fiber, + }, + }, ]), }, { diff --git a/build/packages/build.js b/build/packages/build.js index 82a57e432..4f16997e0 100644 --- a/build/packages/build.js +++ b/build/packages/build.js @@ -1,7 +1,7 @@ import fs from 'fs' import path from 'path' import zlib from 'zlib' -import uglify from 'uglify-js' +import Terser from 'terser' import { rollup } from 'rollup' import config from './config' @@ -43,9 +43,8 @@ function buildEntry({ input, output }) { return rollup(input) .then(bundle => bundle.generate(output)) .then(response => { - // console.log({ bla }) if (isProd) { - const minified = uglify.minify(response.output[0].code, { + const minified = Terser.minify(response.output[0].code, { output: { preamble: output.banner, ascii_only: true, @@ -53,8 +52,6 @@ function buildEntry({ input, output }) { }).code return write(output.file, minified, true) } - // console.log({ isProd }) - // console.dir(response, { depth: null }) return write(output.file, response.output[0].code) }) } diff --git a/build/packages/config.js b/build/packages/config.js index 49ed49e7a..c3100f263 100644 --- a/build/packages/config.js +++ b/build/packages/config.js @@ -41,7 +41,7 @@ function genConfig(opts) { file: opts.file, format: opts.format, banner, - name: 'tiptap', + name: opts.outputName, }, } @@ -57,23 +57,28 @@ function genConfig(opts) { export default [ { package: 'tiptap', + outputName: 'tiptap', outputFileName: 'tiptap', }, { package: 'tiptap-commands', + outputName: 'tiptapCommands', outputFileName: 'commands', }, { package: 'tiptap-utils', + outputName: 'tiptapUtils', outputFileName: 'utils', }, { package: 'tiptap-extensions', + outputName: 'tiptapExtensions', outputFileName: 'extensions', }, ].map(item => [ { name: item.package, + outputName: item.outputName, package: resolve(`packages/${item.package}/package.json`), input: resolve(`packages/${item.package}/src/index.js`), file: resolve(`packages/${item.package}/dist/${item.outputFileName}.js`), @@ -82,6 +87,7 @@ export default [ }, { name: item.package, + outputName: item.outputName, package: resolve(`packages/${item.package}/package.json`), input: resolve(`packages/${item.package}/src/index.js`), file: resolve(`packages/${item.package}/dist/${item.outputFileName}.min.js`), @@ -90,6 +96,7 @@ export default [ }, { name: item.package, + outputName: item.outputName, package: resolve(`packages/${item.package}/package.json`), input: resolve(`packages/${item.package}/src/index.js`), file: resolve(`packages/${item.package}/dist/${item.outputFileName}.common.js`), @@ -97,6 +104,7 @@ export default [ }, { name: item.package, + outputName: item.outputName, package: resolve(`packages/${item.package}/package.json`), input: resolve(`packages/${item.package}/src/index.js`), file: resolve(`packages/${item.package}/dist/${item.outputFileName}.esm.js`), diff --git a/examples/Components/Navigation/index.vue b/examples/Components/Navigation/index.vue index 4a94ef614..89f41a0de 100644 --- a/examples/Components/Navigation/index.vue +++ b/examples/Components/Navigation/index.vue @@ -6,6 +6,9 @@
+ + Documentation + Contribute diff --git a/examples/Components/Routes/Embeds/Iframe.js b/examples/Components/Routes/Embeds/Iframe.js index cf90c77ea..4a81da32d 100644 --- a/examples/Components/Routes/Embeds/Iframe.js +++ b/examples/Components/Routes/Embeds/Iframe.js @@ -47,7 +47,7 @@ export default class Iframe extends Node { template: `
- +
`, } diff --git a/examples/Components/Routes/Images/index.vue b/examples/Components/Routes/Images/index.vue index cbc7bbcc7..aae665a34 100644 --- a/examples/Components/Routes/Images/index.vue +++ b/examples/Components/Routes/Images/index.vue @@ -51,7 +51,7 @@ export default {

This is basic example of implementing images. Try to drop new images here. Reordering also works.

- + `, }), } diff --git a/examples/Components/Routes/Links/index.vue b/examples/Components/Routes/Links/index.vue index 942dc2e24..460524aae 100644 --- a/examples/Components/Routes/Links/index.vue +++ b/examples/Components/Routes/Links/index.vue @@ -1,6 +1,6 @@ diff --git a/examples/Components/Routes/MenuBubble/index.vue b/examples/Components/Routes/MenuBubble/index.vue index 6a7780b59..c72625e3a 100644 --- a/examples/Components/Routes/MenuBubble/index.vue +++ b/examples/Components/Routes/MenuBubble/index.vue @@ -1,6 +1,6 @@ @@ -18,6 +19,7 @@ export default { }, data() { return { + placeholder: 'Write something …', editor: new Editor({ extensions: [ new BulletList(), @@ -25,6 +27,7 @@ export default { new Placeholder({ emptyClass: 'is-empty', emptyNodeText: 'Write something …', + showOnlyWhenEditable: true, }), ], }), @@ -33,6 +36,11 @@ export default { beforeDestroy() { this.editor.destroy() }, + watch: { + placeholder(newValue) { + this.editor.extensions.options.placeholder.emptyNodeText = newValue + }, + }, } diff --git a/examples/Components/Routes/Suggestions/index.vue b/examples/Components/Routes/Suggestions/index.vue index d4f28a077..6d96c6419 100644 --- a/examples/Components/Routes/Suggestions/index.vue +++ b/examples/Components/Routes/Suggestions/index.vue @@ -159,6 +159,7 @@ export default { filteredUsers: [], navigatedUserIndex: 0, insertMention: () => {}, + observer: null, } }, @@ -222,20 +223,35 @@ export default { interactive: true, theme: 'dark', placement: 'top-start', - performance: true, inertia: true, duration: [400, 200], showOnInit: true, arrow: true, arrowType: 'round', }) + + // we have to update tippy whenever the DOM is updated + if (MutationObserver) { + this.observer = new MutationObserver(() => { + this.popup.popperInstance.scheduleUpdate() + }) + this.observer.observe(this.$refs.suggestions, { + childList: true, + subtree: true, + characterData: true, + }) + } }, destroyPopup() { if (this.popup) { - this.popup.destroyAll() + this.popup.destroy() this.popup = null } + + if (this.observer) { + this.observer.disconnect() + } }, }, @@ -244,7 +260,6 @@ export default {