prosemirror-utils
Advanced tools
Comparing version 0.2.0 to 0.2.1
@@ -27,12 +27,10 @@ 'use strict'; | ||
// (position: number, node: ProseMirrorNode) → (tr: Transaction) → Transaction | ||
// Returns a `delete` transaction that removes a node at a given position with the given `node`. | ||
// (position: number, content: union<ProseMirrorNode, Fragment>) → (tr: Transaction) → Transaction | ||
// Returns a `replace` transaction that replaces a node at a given position with the given `content`. | ||
// It will return the original transaction if replacing is not possible. | ||
var replaceNodeAtPos = function replaceNodeAtPos(position, node) { | ||
var replaceNodeAtPos = function replaceNodeAtPos(position, content) { | ||
return function (tr) { | ||
var $pos = tr.doc.resolve(position); | ||
var from = $pos.before($pos.depth); | ||
var to = $pos.after($pos.depth); | ||
if (tr.doc.canReplaceWith($pos.index($pos.depth), $pos.indexAfter($pos.depth), node.type)) { | ||
return cloneTr(tr.replaceWith(from, to, node)); | ||
if (canReplace($pos, tr.doc, content)) { | ||
return cloneTr(tr.replaceWith($pos.before($pos.depth), $pos.after($pos.depth), content)); | ||
} | ||
@@ -43,2 +41,16 @@ return tr; | ||
// ($pos: ResolvedPos, doc: ProseMirrorNode, content: union<ProseMirrorNode, Fragment>, ) → boolean | ||
// Checks if replacing a node at a given `$pos` inside of the `doc` node with the given `content` is possible. | ||
var canReplace = function canReplace($pos, doc, content) { | ||
var index = $pos.index($pos.depth); | ||
var indexAfter = $pos.indexAfter($pos.depth); | ||
if (content instanceof prosemirrorModel.Fragment) { | ||
return doc.canReplace(index, index, content); | ||
} else if (content instanceof prosemirrorModel.Node) { | ||
return doc.canReplaceWith(index, indexAfter, content.type); | ||
} | ||
return false; | ||
}; | ||
// (position: number) → (tr: Transaction) → Transaction | ||
@@ -76,7 +88,6 @@ // Returns a `delete` transaction that removes a node at a given position with the given `node`. | ||
var index = $pos.index(); | ||
// Fragment | ||
if (content instanceof prosemirrorModel.Fragment) { | ||
return $pos.parent.canReplace(index, index, content); | ||
} else if (content instanceof prosemirrorModel.Node) { | ||
// Node | ||
return $pos.parent.canReplaceWith(index, index, content.type); | ||
@@ -87,2 +98,8 @@ } | ||
// (node: ProseMirrorNode) → boolean | ||
// Checks if a given `node` is an empty paragraph | ||
var isEmptyParagraph = function isEmptyParagraph(node) { | ||
return !node || node.type.name === 'paragraph' && node.nodeSize === 2; | ||
}; | ||
// :: (predicate: (node: ProseMirrorNode) → boolean) → (selection: Selection) → ?{pos: number, node: ProseMirrorNode} | ||
@@ -607,10 +624,10 @@ // Iterates over parent nodes, returning the first node and its position `predicate` returns truthy for. | ||
// :: (nodeType: union<NodeType, [NodeType]>, node: ProseMirrorNode) → (tr: Transaction) → Transaction | ||
// Returns a new transaction that replaces parent node of a given `nodeType` with the given `node`. | ||
// :: (nodeType: union<NodeType, [NodeType]>, content: union<ProseMirrorNode, Fragment>) → (tr: Transaction) → Transaction | ||
// Returns a new transaction that replaces parent node of a given `nodeType` with the given `content`. | ||
// It will return the original transaction if parent node hasn't been found, or replacing is not possible. | ||
var replaceParentNodeOfType = function replaceParentNodeOfType(nodeType, node) { | ||
var replaceParentNodeOfType = function replaceParentNodeOfType(nodeType, content) { | ||
return function (tr) { | ||
var parent = findParentNodeOfType(nodeType)(tr.selection); | ||
if (parent) { | ||
return replaceNodeAtPos(parent.pos, node)(tr); | ||
return replaceNodeAtPos(parent.pos, content)(tr); | ||
} | ||
@@ -651,4 +668,19 @@ return tr; | ||
// :: (position: number) → (tr: Transaction) → Transaction | ||
// Tries to find a valid cursor selection **starting** at the given `position` and returns a new transaction. | ||
// If a valid cursor position hasn't been not found, it will return the original transaction. | ||
var setTextSelection = function setTextSelection(position) { | ||
return function (tr) { | ||
var nextSelection = prosemirrorState.Selection.findFrom(tr.doc.resolve(position), 1, true); | ||
if (nextSelection) { | ||
return tr.setSelection(nextSelection); | ||
} | ||
return tr; | ||
}; | ||
}; | ||
// :: (content: union<ProseMirrorNode, Fragment>) → (tr: Transaction) → Transaction | ||
// Returns a new transaction that inserts a given `node` at the current cursor position if it is allowed by schema. If schema restricts such nesting, it will try to find an appropriate place for a given `node` in the document, looping through parent nodes up until the root document node. | ||
// If cursor is inside of an empty paragraph at the top level (depth=0), it will try to replace that paragraph with the given `content`. | ||
// If insertion is successful and inserted node has content, it will set cursor inside of that content. | ||
// It will return the original transaction if the place for insertion hasn't been found. | ||
@@ -658,6 +690,16 @@ var safeInsert = function safeInsert(content) { | ||
var $from = tr.selection.$from; | ||
var parent = $from.parent, | ||
depth = $from.depth; | ||
// try to replace an empty paragraph at top level with inserted content | ||
if (isEmptyParagraph(parent) && depth === 1) { | ||
tr = replaceParentNodeOfType(parent.type, content)(tr); | ||
return setTextSelection($from.pos)(tr); | ||
} | ||
// given node is allowed at the current cursor position | ||
if (canInsert($from, content)) { | ||
return cloneTr(tr.insert($from.pos, content)); | ||
tr.insert($from.pos, content); | ||
return cloneTr(setTextSelection($from.pos)(tr)); | ||
} | ||
@@ -670,3 +712,4 @@ | ||
if (canInsert($pos, content)) { | ||
return cloneTr(tr.insert(pos, content)); | ||
tr.insert(pos, content); | ||
return cloneTr(setTextSelection(pos)(tr)); | ||
} | ||
@@ -756,2 +799,3 @@ } | ||
exports.replaceSelectedNode = replaceSelectedNode; | ||
exports.setTextSelection = setTextSelection; | ||
exports.safeInsert = safeInsert; | ||
@@ -758,0 +802,0 @@ exports.setParentNodeMarkup = setParentNodeMarkup; |
{ | ||
"name": "prosemirror-utils", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "Utils library for ProseMirror", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -183,4 +183,4 @@ # Utils library for ProseMirror | ||
* **`replaceParentNodeOfType`**`(nodeType: NodeType | [NodeType], node: ProseMirrorNode) → fn(tr: Transaction) → Transaction`\ | ||
Returns a new transaction that replaces parent node of a given `nodeType` with the given `node`. | ||
* **`replaceParentNodeOfType`**`(nodeType: NodeType | [NodeType], content: ProseMirrorNode | Fragment) → fn(tr: Transaction) → Transaction`\ | ||
Returns a new transaction that replaces parent node of a given `nodeType` with the given `content`. | ||
It will return the original transaction if parent node hasn't been found, or replacing is not possible. | ||
@@ -205,2 +205,4 @@ | ||
Returns a new transaction that inserts a given `node` at the current cursor position if it is allowed by schema. If schema restricts such nesting, it will try to find an appropriate place for a given `node` in the document, looping through parent nodes up until the root document node. | ||
If cursor is inside of an empty paragraph at the top level (depth=0), it will try to replace that paragraph with the given `content`. | ||
If insertion is successful and inserted node has content, it will set cursor inside of that content. | ||
It will return the original transaction if the place for insertion hasn't been found. | ||
@@ -221,2 +223,7 @@ | ||
* **`setTextSelection`**`(position: number) → fn(tr: Transaction) → Transaction`\ | ||
Tries to find a valid cursor selection **starting** at the given `position` and returns a new transaction. | ||
If a valid cursor position hasn't been not found, it will return the original transaction. | ||
## License | ||
@@ -223,0 +230,0 @@ |
@@ -101,1 +101,3 @@ import { Node as ProsemirrorNode, Schema, NodeType, Mark, MarkType, ResolvedPos, Fragment } from 'prosemirror-model'; | ||
export function removeNodeBefore(tr: Transaction): Transaction; | ||
export function setTextSelection(position: number): (tr: Transaction) => Transaction; |
Sorry, the diff of this file is not supported yet
93417
772
230