Merge branch 'master' into feature/code-highlighting

This commit is contained in:
Philipp Kühn
2018-09-04 22:10:36 +02:00
9 changed files with 93 additions and 13 deletions

View File

@@ -4,6 +4,7 @@ import webpack from 'webpack'
import httpProxyMiddleware from 'http-proxy-middleware' import httpProxyMiddleware from 'http-proxy-middleware'
import webpackDevMiddleware from 'webpack-dev-middleware' import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
import historyApiFallbackMiddleware from 'connect-history-api-fallback'
import config from './webpack.config' import config from './webpack.config'
import { sassImport } from './utilities' import { sassImport } from './utilities'
import { srcPath, sassImportPath } from './paths' import { srcPath, sassImportPath } from './paths'
@@ -11,6 +12,8 @@ import { srcPath, sassImportPath } from './paths'
const bundler = webpack(config) const bundler = webpack(config)
const middlewares = [] const middlewares = []
middlewares.push(historyApiFallbackMiddleware())
// add webpack stuff // add webpack stuff
middlewares.push(webpackDevMiddleware(bundler, { middlewares.push(webpackDevMiddleware(bundler, {
publicPath: config.output.publicPath, publicPath: config.output.publicPath,

View File

@@ -41,6 +41,7 @@
"babel-eslint": "^9.0.0", "babel-eslint": "^9.0.0",
"babel-loader": "^8.0.2", "babel-loader": "^8.0.2",
"browser-sync": "^2.24.7", "browser-sync": "^2.24.7",
"connect-history-api-fallback": "^1.5.0",
"copy-webpack-plugin": "^4.5.2", "copy-webpack-plugin": "^4.5.2",
"css-loader": "^1.0.0", "css-loader": "^1.0.0",
"eslint": "^5.5.0", "eslint": "^5.5.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "tiptap-commands", "name": "tiptap-commands",
"version": "0.2.4", "version": "0.2.5",
"description": "Commands for tiptap", "description": "Commands for tiptap",
"homepage": "https://tiptap.scrumpy.io", "homepage": "https://tiptap.scrumpy.io",
"license": "MIT", "license": "MIT",

View File

@@ -0,0 +1,73 @@
// this is a copy of canSplit
// see https://github.com/ProseMirror/prosemirror-transform/blob/master/src/structure.js
function canSplit(doc, pos, depth = 1, typesAfter) {
let $pos = doc.resolve(pos), base = $pos.depth - depth
let innerType = (typesAfter && typesAfter[typesAfter.length - 1]) || $pos.parent
if (base < 0 || $pos.parent.type.spec.isolating ||
!$pos.parent.canReplace($pos.index(), $pos.parent.childCount) ||
!innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount)))
return false
for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {
let node = $pos.node(d), index = $pos.index(d)
if (node.type.spec.isolating) return false
let rest = node.content.cutByIndex(index, node.childCount)
let after = (typesAfter && typesAfter[i]) || node
if (after != node) rest = rest.replaceChild(0, after.type.create(after.attrs))
/* Change starts from here */
// if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest))
// return false
if (!node.canReplace(index + 1, node.childCount))
return false
/* Change ends here */
}
let index = $pos.indexAfter(base)
let baseType = typesAfter && typesAfter[0]
return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type)
}
// this is a copy of splitListItem
// see https://github.com/ProseMirror/prosemirror-schema-list/blob/master/src/schema-list.js
export default function (itemType) {
return function(state, dispatch) {
let {$from, $to, node} = state.selection
if ((node && node.isBlock) || $from.depth < 2 || !$from.sameParent($to)) return false
let grandParent = $from.node(-1)
if (grandParent.type != itemType) return false
if ($from.parent.content.size == 0) {
// In an empty block. If this is a nested list, the wrapping
// list item should be split. Otherwise, bail out and let next
// command handle lifting.
if ($from.depth == 2 || $from.node(-3).type != itemType ||
$from.index(-2) != $from.node(-2).childCount - 1) return false
if (dispatch) {
let wrap = Fragment.empty, keepItem = $from.index(-1) > 0
// Build a fragment containing empty versions of the structure
// from the outer list item to the parent node of the cursor
for (let d = $from.depth - (keepItem ? 1 : 2); d >= $from.depth - 3; d--)
wrap = Fragment.from($from.node(d).copy(wrap))
// Add a second list item with an empty default start node
wrap = wrap.append(Fragment.from(itemType.createAndFill()))
let tr = state.tr.replace($from.before(keepItem ? null : -1), $from.after(-3), new Slice(wrap, keepItem ? 3 : 2, 2))
tr.setSelection(state.selection.constructor.near(tr.doc.resolve($from.pos + (keepItem ? 3 : 2))))
dispatch(tr.scrollIntoView())
}
return true
}
let nextType = $to.pos == $from.end() ? grandParent.contentMatchAt($from.indexAfter(-1)).defaultType : null
let tr = state.tr.delete($from.pos, $to.pos)
/* Change starts from here */
// let types = nextType && [null, {type: nextType}]
let types = nextType && [{type: itemType}, {type: nextType}]
if (!types) types = [{type: itemType}, null]
/* Change ends here */
if (!canSplit(tr.doc, $from.pos, 2, types)) return false
if (dispatch) dispatch(tr.split($from.pos, 2, [{type: state.schema.nodes.todo_item, attrs: { done: false }}]).scrollIntoView())
return true
}
}

View File

@@ -40,6 +40,7 @@ import {
import markInputRule from './commands/markInputRule' import markInputRule from './commands/markInputRule'
import removeMark from './commands/removeMark' import removeMark from './commands/removeMark'
import splitToDefaultListItem from './commands/splitToDefaultListItem'
import toggleBlockType from './commands/toggleBlockType' import toggleBlockType from './commands/toggleBlockType'
import toggleList from './commands/toggleList' import toggleList from './commands/toggleList'
import updateMark from './commands/updateMark' import updateMark from './commands/updateMark'
@@ -85,6 +86,7 @@ export {
// custom // custom
markInputRule, markInputRule,
removeMark, removeMark,
splitToDefaultListItem,
toggleBlockType, toggleBlockType,
toggleList, toggleList,
updateMark, updateMark,

View File

@@ -1,6 +1,6 @@
{ {
"name": "tiptap-extensions", "name": "tiptap-extensions",
"version": "0.7.0", "version": "0.7.2",
"description": "Extensions for tiptap", "description": "Extensions for tiptap",
"homepage": "https://tiptap.scrumpy.io", "homepage": "https://tiptap.scrumpy.io",
"license": "MIT", "license": "MIT",
@@ -22,7 +22,7 @@
"dependencies": { "dependencies": {
"lowlight": "^1.10.0", "lowlight": "^1.10.0",
"prosemirror-history": "^1.0.2", "prosemirror-history": "^1.0.2",
"tiptap": "^0.9.0", "tiptap": "^0.9.2",
"tiptap-commands": "^0.2.4" "tiptap-commands": "^0.2.5"
} }
} }

View File

@@ -1,5 +1,5 @@
import { Node } from 'tiptap' import { Node } from 'tiptap'
import { splitListItem, liftListItem } from 'tiptap-commands' import { splitToDefaultListItem, liftListItem } from 'tiptap-commands'
export default class TodoItemNode extends Node { export default class TodoItemNode extends Node {
@@ -58,7 +58,7 @@ export default class TodoItemNode extends Node {
keys({ type }) { keys({ type }) {
return { return {
Enter: splitListItem(type), Enter: splitToDefaultListItem(type),
'Shift-Tab': liftListItem(type), 'Shift-Tab': liftListItem(type),
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "tiptap", "name": "tiptap",
"version": "0.9.0", "version": "0.9.2",
"description": "A rich-text editor for Vue.js", "description": "A rich-text editor for Vue.js",
"homepage": "https://tiptap.scrumpy.io", "homepage": "https://tiptap.scrumpy.io",
"license": "MIT", "license": "MIT",
@@ -31,7 +31,7 @@
"prosemirror-model": "^1.5.0", "prosemirror-model": "^1.5.0",
"prosemirror-state": "^1.2.1", "prosemirror-state": "^1.2.1",
"prosemirror-view": "^1.4.3", "prosemirror-view": "^1.4.3",
"tiptap-commands": "^0.2.4", "tiptap-commands": "^0.2.5",
"tiptap-utils": "^0.2.4" "tiptap-utils": "^0.2.4"
} }
} }

View File

@@ -204,22 +204,23 @@ export default {
}, },
dispatchTransaction(transaction) { dispatchTransaction(transaction) {
this.state = this.state.apply(transaction)
this.view.updateState(this.state)
this.updateMenuActions()
if (!transaction.docChanged) { if (!transaction.docChanged) {
return return
} }
this.state = this.state.apply(transaction)
this.view.updateState(this.state)
this.$emit('update', { this.$emit('update', {
getHTML: this.getHTML, getHTML: this.getHTML,
getJSON: this.getJSON, getJSON: this.getJSON,
state: this.state, state: this.state,
}) })
this.updateMenuActions()
}, },
getHTML() { getHTML() {
return this.contentNode.elm.innerHTML return this.view.dom.innerHTML
}, },
getJSON() { getJSON() {