Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

prosemirror-commands

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prosemirror-commands - npm Package Compare versions

Comparing version 0.14.0 to 0.15.0

289

dist/commands.js

@@ -16,11 +16,3 @@ var ref = require("prosemirror-transform");

var extendTransformAction = ref$2.extendTransformAction;
var ref$3 = require("extending-char");
var isExtendingCharAt = ref$3.isExtendingCharAt;
var ref$4 = require("./platform");
var ios = ref$4.ios;
var mac = ref$4.mac;
var ref$5 = require("./char");
var charCategory = ref$5.charCategory;
// :: (EditorState, ?(action: Action)) → bool

@@ -35,3 +27,3 @@ // Delete the selection, if there is one.

// :: (EditorState, ?(action: Action)) → bool
// :: (EditorState, ?(action: Action), ?EditorView) → bool
// If the selection is empty and at the start of a textblock, move

@@ -41,8 +33,11 @@ // that block closer to the block before it, by lifting it out of its

// before it, moving it into a parent of that node, or joining it with
// that.
function joinBackward(state, onAction) {
// that. Will use the view for accurate start-of-textblock detection
// if given.
function joinBackward(state, onAction, view) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset > 0) { return false }
if (!empty || (view ? !view.endOfTextblock("backward", state)
: $head.parentOffset > 0))
{ return false }

@@ -59,12 +54,5 @@ // Find the node before this one

var range = $head.blockRange(), target = range && liftTarget(range)
if (target != null) {
if (onAction) { onAction(state.tr.lift(range, target).scrollAction()) }
return true
} else if ($head.depth == 1 && !$head.parent.content.size) {
// Else, if the cursor is in an empty textblock, delete it
if (onAction) { onAction(state.tr.delete($head.before(1), $head.after(1)).scrollAction()) }
return true
} else {
return false
}
if (target == null) { return false }
if (onAction) { onAction(state.tr.lift(range, target).scrollAction()) }
return true
}

@@ -94,3 +82,3 @@

// :: (EditorState, ?(action: Action)) → bool
// :: (EditorState, ?(action: Action), ?EditorView) → bool
// If the selection is empty and the cursor is at the end of a

@@ -100,8 +88,11 @@ // textblock, move the node after it closer to the node with the

// into parents of the cursor block, or joining the two when they are
// siblings).
function joinForward(state, onAction) {
// siblings). Will use the view for accurate start-of-textblock
// detection if given.
function joinForward(state, onAction, view) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset < $head.parent.content.size) { return false }
if (!empty || (view ? !view.endOfTextblock("forward", state)
: $head.parentOffset < $head.parent.content.size))
{ return false }

@@ -118,12 +109,4 @@ // Find the node after this one

// There is no node after this
if (!after) {
// If the cursor is in an empty block, delete that block
if ($head.depth == 1 && !$head.parent.content.size) {
if (onAction) { onAction(state.tr.delete($head.before(1), $head.after(1)).scrollAction()) }
return true
} else {
return false
}
}
// If there is no node after this, there's nothing to do
if (!after) { return false }

@@ -141,60 +124,2 @@ // If the node doesn't allow children, delete it

// :: (EditorState, ?(action: Action)) → bool
// Delete the character before the cursor, if the selection is empty
// and the cursor isn't at the start of a textblock.
function deleteCharBefore(state, onAction) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset == 0) { return false }
if (onAction) {
var dest = moveBackward($head, "char")
onAction(state.tr.delete(dest, $head.pos).scrollAction())
}
return true
}
exports.deleteCharBefore = deleteCharBefore
// :: (EditorState, ?(action: Action)) → bool
// Delete the word before the cursor, if the selection is empty and
// the cursor isn't at the start of a textblock.
function deleteWordBefore(state, onAction) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset == 0) { return false }
if (onAction)
{ onAction(state.tr.delete(moveBackward($head, "word"), $head.pos).scrollAction()) }
return true
}
exports.deleteWordBefore = deleteWordBefore
// :: (EditorState, ?(action: Action)) → bool
// Delete the character after the cursor, if the selection is empty
// and the cursor isn't at the end of its textblock.
function deleteCharAfter(state, onAction) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset == $head.parent.content.size) { return false }
if (onAction)
{ onAction(state.tr.delete($head.pos, moveForward($head, "char")).scrollAction()) }
return true
}
exports.deleteCharAfter = deleteCharAfter
// :: (EditorState, ?(action: Action)) → bool
// Delete the word after the cursor, if the selection is empty and the
// cursor isn't at the end of a textblock.
function deleteWordAfter(state, onAction) {
var ref = state.selection;
var $head = ref.$head;
var empty = ref.empty;
if (!empty || $head.parentOffset == $head.parent.content.size) { return false }
if (onAction)
{ onAction(state.tr.delete($head.pos, moveForward($head, "word")).scrollAction()) }
return true
}
exports.deleteWordAfter = deleteWordAfter
// :: (EditorState, ?(action: Action)) → bool
// Join the selected block or, if there is a text selection, the

@@ -260,7 +185,5 @@ // closest ancestor block of the selection that can be joined, with

var ref = state.selection;
var $from = ref.$from;
var $to = ref.$to;
var node = ref.node;
if (node) { return false }
if (!$from.parent.type.spec.code || $to.pos >= $from.end()) { return false }
var $head = ref.$head;
var anchor = ref.anchor;
if (!$head || !$head.parent.type.spec.code || $head.sharedDepth(anchor) != $head.depth) { return false }
if (onAction) { onAction(state.tr.insertText("\n").scrollAction()) }

@@ -272,2 +195,22 @@ return true

// :: (EditorState, ?(action: Action)) → bool
// When the selection is in a node with a truthy
// [`code`](#model.NodeSpec.code) property in its spec, create a
// default block after the code block, and move the cursor there.
function exitCode(state, onAction) {
var ref = state.selection;
var $head = ref.$head;
var anchor = ref.anchor;
if (!$head || !$head.parent.type.spec.code || $head.sharedDepth(anchor) != $head.depth) { return false }
var above = $head.node(-1), after = $head.indexAfter(-1), type = above.defaultContentType(after)
if (!above.canReplaceWith(after, after, type)) { return false }
if (onAction) {
var pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill())
tr.setSelection(Selection.near(tr.doc.resolve(pos), 1))
onAction(tr.scrollAction())
}
return true
}
exports.exitCode = exitCode
// :: (EditorState, ?(action: Action)) → bool
// If a block node is selected, create an empty paragraph before (if

@@ -369,12 +312,21 @@ // it is its parent's first child) or after it.

function joinMaybeClear(state, $pos, onAction) {
var before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index()
if (!before || !after || !before.type.compatibleContent(after.type)) { return false }
if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
if (onAction) { onAction(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollAction()) }
return true
}
if (!$pos.parent.canReplace(index, index + 1)) { return false }
if (onAction)
{ onAction(state.tr
.clearNonMatching($pos.pos, before.contentMatchAt(before.childCount))
.join($pos.pos)
.scrollAction()) }
return true
}
function deleteBarrier(state, cut, onAction) {
var $cut = state.doc.resolve(cut), before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match
if (canJoin(state.doc, cut)) {
if (onAction) {
var tr = state.tr.join(cut)
if (tr.steps.length && before.content.size == 0 && !before.sameMarkup(after) &&
$cut.parent.canReplace($cut.index() - 1, $cut.index()))
{ tr.setNodeType(cut - before.nodeSize, after.type, after.attrs) }
onAction(tr.scrollAction())
}
if (joinMaybeClear(state, $cut, onAction)) {
return true

@@ -389,6 +341,6 @@ } else if (after.isTextblock && $cut.parent.canReplace($cut.index(), $cut.index() + 1) &&

wrap = Fragment.from(before.copy(wrap))
var tr$1 = state.tr.step(new ReplaceAroundStep(cut - 1, end, cut, end, new Slice(wrap, 1, 0), conn.length, true))
var tr = state.tr.step(new ReplaceAroundStep(cut - 1, end, cut, end, new Slice(wrap, 1, 0), conn.length, true))
var joinAt = end + 2 * conn.length
if (canJoin(tr$1.doc, joinAt)) { tr$1.join(joinAt) }
onAction(tr$1.scrollAction())
if (canJoin(tr.doc, joinAt)) { tr.join(joinAt) }
onAction(tr.scrollAction())
}

@@ -410,93 +362,6 @@ return true

if (onAction)
{ onAction(NodeSelection.create(state.doc, cut - (dir > 0 ? 0 : node.nodeSize)).action()) }
{ onAction(NodeSelection.create(state.doc, cut - (dir > 0 ? 0 : node.nodeSize)).scrollAction()) }
return true
}
// :: (ResolvedPos, string) → number
// Get an offset moving backward from a current offset inside a node. If by is "char", it will
// consider one character back. If it is "word" it will work from the current position backwards
// through text of a singular character category (e.g. "cat" of "#!*") until reaching a character
// in a different category (i.e. the beginning of the word).
// Note that this method is at this point unlikely to work reliably for non-European scripts.
function moveBackward($pos, by) {
if (by != "char" && by != "word")
{ throw new RangeError("Unknown motion unit: " + by) }
var parent = $pos.parent, offset = $pos.parentOffset
var cat = null, counted = 0, pos = $pos.pos
for (;;) {
if (offset == 0) { return pos }
var ref = parent.childBefore(offset);
var start = ref.offset;
var node = ref.node;
if (!node) { return pos }
if (!node.isText) { return cat ? pos : pos - 1 }
if (by == "char") {
for (var i = offset - start; i > 0; i--) {
if (!isExtendingCharAt(node.text, i - 1))
{ return pos - 1 }
offset--
pos--
}
} else if (by == "word") {
// Work from the current position backwards through text of a singular
// character category (e.g. "cat" of "#!*") until reaching a character in a
// different category (i.e. the end of the word).
for (var i$1 = offset - start; i$1 > 0; i$1--) {
var nextCharCat = charCategory(node.text.charAt(i$1 - 1))
if (cat == null || counted == 1 && cat == "space") { cat = nextCharCat }
else if (cat != nextCharCat) { return pos }
offset--
pos--
counted++
}
}
}
}
exports.moveBackward = moveBackward
// :: (ResolvedPos, string) → number
// Get an offset moving forward from a current offset inside a node. If by is "char", it will
// consider one character forward. If it is "word" it will work from the current position forward
// through text of a singular character category (e.g. "cat" of "#!*") until reaching a character
// in a different category (i.e. the end of the word).
// Note that this method is at this point unlikely to work reliably for non-European scripts.
function moveForward($pos, by) {
if (by != "char" && by != "word")
{ throw new RangeError("Unknown motion unit: " + by) }
var parent = $pos.parent, offset = $pos.parentOffset, pos = $pos.pos
var cat = null, counted = 0
for (;;) {
if (offset == parent.content.size) { return pos }
var ref = parent.childAfter(offset);
var start = ref.offset;
var node = ref.node;
if (!node) { return pos }
if (!node.isText) { return cat ? pos : pos + 1 }
if (by == "char") {
for (var i = offset - start; i < node.text.length; i++) {
if (!isExtendingCharAt(node.text, i + 1))
{ return pos + 1 }
offset++
pos++
}
} else if (by == "word") {
for (var i$1 = offset - start; i$1 < node.text.length; i$1++) {
var nextCharCat = charCategory(node.text.charAt(i$1))
if (cat == null || counted == 1 && cat == "space") { cat = nextCharCat }
else if (cat != nextCharCat) { return pos }
offset++
pos++
counted++
}
}
}
}
exports.moveForward = moveForward
// Parameterized commands

@@ -551,3 +416,3 @@

onAction(state.tr
.clearMarkupFor(where, nodeType, attrs)
.clearNonMatching(where, nodeType.contentExpr.start(attrs))
.setNodeType(where, nodeType, attrs)

@@ -662,5 +527,5 @@ .scrollAction())

return function(state, onAction) {
return function(state, onAction, view) {
for (var i = 0; i < commands.length; i++)
{ if (commands[i](state, onAction)) { return true } }
{ if (commands[i](state, onAction, view)) { return true } }
return false

@@ -677,6 +542,7 @@ }

// * **Enter** to `newlineInCode`, `createParagraphNear`, `liftEmptyBlock`, `splitBlock`
// * **Backspace** to `deleteSelection`, `joinBackward`, `deleteCharBefore`
// * **Mod-Backspace** to `deleteSelection`, `joinBackward`, `deleteWordBefore`
// * **Delete** to `deleteSelection`, `joinForward`, `deleteCharAfter`
// * **Mod-Delete** to `deleteSelection`, `joinForward`, `deleteWordAfter`
// * **Mod-Enter** to `exitCode`
// * **Backspace** to `deleteSelection`, `joinBackward`
// * **Mod-Backspace** to `deleteSelection`, `joinBackward`
// * **Delete** to `deleteSelection`, `joinForward`
// * **Mod-Delete** to `deleteSelection`, `joinForward`
// * **Alt-ArrowUp** to `joinUp`

@@ -688,7 +554,8 @@ // * **Alt-ArrowDown** to `joinDown`

"Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock),
"Mod-Enter": exitCode,
"Backspace": ios ? chainCommands(deleteSelection, joinBackward) : chainCommands(deleteSelection, joinBackward, deleteCharBefore),
"Mod-Backspace": chainCommands(deleteSelection, joinBackward, deleteWordBefore),
"Delete": chainCommands(deleteSelection, joinForward, deleteCharAfter),
"Mod-Delete": chainCommands(deleteSelection, joinForward, deleteWordAfter),
"Backspace": chainCommands(deleteSelection, joinBackward),
"Mod-Backspace": chainCommands(deleteSelection, joinBackward),
"Delete": chainCommands(deleteSelection, joinForward),
"Mod-Delete": chainCommands(deleteSelection, joinForward),

@@ -701,2 +568,6 @@ "Alt-ArrowUp": joinUp,

// declare global: os, navigator
var mac = typeof navigator != "undefined" ? /Mac/.test(navigator.platform)
: typeof os != "undefined" ? os.platform() == "darwin" : false
if (mac) {

@@ -703,0 +574,0 @@ var extra = {

{
"name": "prosemirror-commands",
"version": "0.14.0",
"version": "0.15.0",
"description": "Editing commands for ProseMirror",

@@ -19,6 +19,5 @@ "main": "dist/commands.js",

"dependencies": {
"prosemirror-model": "^0.14.0",
"prosemirror-transform": "^0.14.0",
"prosemirror-state": "^0.14.0",
"extending-char": "^1.0.0"
"prosemirror-model": "^0.15.0",
"prosemirror-transform": "^0.15.0",
"prosemirror-state": "^0.15.0"
},

@@ -34,5 +33,4 @@ "devDependencies": {

"build": "rimraf dist && buble -i src -o dist",
"link-src": "rimraf dist && ln -s src dist",
"prepublish": "npm run build"
}
}
const {joinPoint, canJoin, findWrapping, liftTarget, canSplit, ReplaceAroundStep} = require("prosemirror-transform")
const {Slice, Fragment} = require("prosemirror-model")
const {Selection, TextSelection, NodeSelection, extendTransformAction} = require("prosemirror-state")
const {isExtendingCharAt} = require("extending-char")
const {ios, mac} = require("./platform")
const {charCategory} = require("./char")
// :: (EditorState, ?(action: Action)) → bool

@@ -18,3 +14,3 @@ // Delete the selection, if there is one.

// :: (EditorState, ?(action: Action)) → bool
// :: (EditorState, ?(action: Action), ?EditorView) → bool
// If the selection is empty and at the start of a textblock, move

@@ -24,6 +20,9 @@ // that block closer to the block before it, by lifting it out of its

// before it, moving it into a parent of that node, or joining it with
// that.
function joinBackward(state, onAction) {
// that. Will use the view for accurate start-of-textblock detection
// if given.
function joinBackward(state, onAction, view) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset > 0) return false
if (!empty || (view ? !view.endOfTextblock("backward", state)
: $head.parentOffset > 0))
return false

@@ -40,12 +39,5 @@ // Find the node before this one

let range = $head.blockRange(), target = range && liftTarget(range)
if (target != null) {
if (onAction) onAction(state.tr.lift(range, target).scrollAction())
return true
} else if ($head.depth == 1 && !$head.parent.content.size) {
// Else, if the cursor is in an empty textblock, delete it
if (onAction) onAction(state.tr.delete($head.before(1), $head.after(1)).scrollAction())
return true
} else {
return false
}
if (target == null) return false
if (onAction) onAction(state.tr.lift(range, target).scrollAction())
return true
}

@@ -75,3 +67,3 @@

// :: (EditorState, ?(action: Action)) → bool
// :: (EditorState, ?(action: Action), ?EditorView) → bool
// If the selection is empty and the cursor is at the end of a

@@ -81,6 +73,9 @@ // textblock, move the node after it closer to the node with the

// into parents of the cursor block, or joining the two when they are
// siblings).
function joinForward(state, onAction) {
// siblings). Will use the view for accurate start-of-textblock
// detection if given.
function joinForward(state, onAction, view) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset < $head.parent.content.size) return false
if (!empty || (view ? !view.endOfTextblock("forward", state)
: $head.parentOffset < $head.parent.content.size))
return false

@@ -97,12 +92,4 @@ // Find the node after this one

// There is no node after this
if (!after) {
// If the cursor is in an empty block, delete that block
if ($head.depth == 1 && !$head.parent.content.size) {
if (onAction) onAction(state.tr.delete($head.before(1), $head.after(1)).scrollAction())
return true
} else {
return false
}
}
// If there is no node after this, there's nothing to do
if (!after) return false

@@ -120,52 +107,2 @@ // If the node doesn't allow children, delete it

// :: (EditorState, ?(action: Action)) → bool
// Delete the character before the cursor, if the selection is empty
// and the cursor isn't at the start of a textblock.
function deleteCharBefore(state, onAction) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset == 0) return false
if (onAction) {
let dest = moveBackward($head, "char")
onAction(state.tr.delete(dest, $head.pos).scrollAction())
}
return true
}
exports.deleteCharBefore = deleteCharBefore
// :: (EditorState, ?(action: Action)) → bool
// Delete the word before the cursor, if the selection is empty and
// the cursor isn't at the start of a textblock.
function deleteWordBefore(state, onAction) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset == 0) return false
if (onAction)
onAction(state.tr.delete(moveBackward($head, "word"), $head.pos).scrollAction())
return true
}
exports.deleteWordBefore = deleteWordBefore
// :: (EditorState, ?(action: Action)) → bool
// Delete the character after the cursor, if the selection is empty
// and the cursor isn't at the end of its textblock.
function deleteCharAfter(state, onAction) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset == $head.parent.content.size) return false
if (onAction)
onAction(state.tr.delete($head.pos, moveForward($head, "char")).scrollAction())
return true
}
exports.deleteCharAfter = deleteCharAfter
// :: (EditorState, ?(action: Action)) → bool
// Delete the word after the cursor, if the selection is empty and the
// cursor isn't at the end of a textblock.
function deleteWordAfter(state, onAction) {
let {$head, empty} = state.selection
if (!empty || $head.parentOffset == $head.parent.content.size) return false
if (onAction)
onAction(state.tr.delete($head.pos, moveForward($head, "word")).scrollAction())
return true
}
exports.deleteWordAfter = deleteWordAfter
// :: (EditorState, ?(action: Action)) → bool
// Join the selected block or, if there is a text selection, the

@@ -225,5 +162,4 @@ // closest ancestor block of the selection that can be joined, with

function newlineInCode(state, onAction) {
let {$from, $to, node} = state.selection
if (node) return false
if (!$from.parent.type.spec.code || $to.pos >= $from.end()) return false
let {$head, anchor} = state.selection
if (!$head || !$head.parent.type.spec.code || $head.sharedDepth(anchor) != $head.depth) return false
if (onAction) onAction(state.tr.insertText("\n").scrollAction())

@@ -235,2 +171,20 @@ return true

// :: (EditorState, ?(action: Action)) → bool
// When the selection is in a node with a truthy
// [`code`](#model.NodeSpec.code) property in its spec, create a
// default block after the code block, and move the cursor there.
function exitCode(state, onAction) {
let {$head, anchor} = state.selection
if (!$head || !$head.parent.type.spec.code || $head.sharedDepth(anchor) != $head.depth) return false
let above = $head.node(-1), after = $head.indexAfter(-1), type = above.defaultContentType(after)
if (!above.canReplaceWith(after, after, type)) return false
if (onAction) {
let pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill())
tr.setSelection(Selection.near(tr.doc.resolve(pos), 1))
onAction(tr.scrollAction())
}
return true
}
exports.exitCode = exitCode
// :: (EditorState, ?(action: Action)) → bool
// If a block node is selected, create an empty paragraph before (if

@@ -324,12 +278,21 @@ // it is its parent's first child) or after it.

function joinMaybeClear(state, $pos, onAction) {
let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index()
if (!before || !after || !before.type.compatibleContent(after.type)) return false
if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
if (onAction) onAction(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollAction())
return true
}
if (!$pos.parent.canReplace(index, index + 1)) return false
if (onAction)
onAction(state.tr
.clearNonMatching($pos.pos, before.contentMatchAt(before.childCount))
.join($pos.pos)
.scrollAction())
return true
}
function deleteBarrier(state, cut, onAction) {
let $cut = state.doc.resolve(cut), before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match
if (canJoin(state.doc, cut)) {
if (onAction) {
let tr = state.tr.join(cut)
if (tr.steps.length && before.content.size == 0 && !before.sameMarkup(after) &&
$cut.parent.canReplace($cut.index() - 1, $cut.index()))
tr.setNodeType(cut - before.nodeSize, after.type, after.attrs)
onAction(tr.scrollAction())
}
if (joinMaybeClear(state, $cut, onAction)) {
return true

@@ -364,89 +327,6 @@ } else if (after.isTextblock && $cut.parent.canReplace($cut.index(), $cut.index() + 1) &&

if (onAction)
onAction(NodeSelection.create(state.doc, cut - (dir > 0 ? 0 : node.nodeSize)).action())
onAction(NodeSelection.create(state.doc, cut - (dir > 0 ? 0 : node.nodeSize)).scrollAction())
return true
}
// :: (ResolvedPos, string) → number
// Get an offset moving backward from a current offset inside a node. If by is "char", it will
// consider one character back. If it is "word" it will work from the current position backwards
// through text of a singular character category (e.g. "cat" of "#!*") until reaching a character
// in a different category (i.e. the beginning of the word).
// Note that this method is at this point unlikely to work reliably for non-European scripts.
function moveBackward($pos, by) {
if (by != "char" && by != "word")
throw new RangeError("Unknown motion unit: " + by)
let parent = $pos.parent, offset = $pos.parentOffset
let cat = null, counted = 0, pos = $pos.pos
for (;;) {
if (offset == 0) return pos
let {offset: start, node} = parent.childBefore(offset)
if (!node) return pos
if (!node.isText) return cat ? pos : pos - 1
if (by == "char") {
for (let i = offset - start; i > 0; i--) {
if (!isExtendingCharAt(node.text, i - 1))
return pos - 1
offset--
pos--
}
} else if (by == "word") {
// Work from the current position backwards through text of a singular
// character category (e.g. "cat" of "#!*") until reaching a character in a
// different category (i.e. the end of the word).
for (let i = offset - start; i > 0; i--) {
let nextCharCat = charCategory(node.text.charAt(i - 1))
if (cat == null || counted == 1 && cat == "space") cat = nextCharCat
else if (cat != nextCharCat) return pos
offset--
pos--
counted++
}
}
}
}
exports.moveBackward = moveBackward
// :: (ResolvedPos, string) → number
// Get an offset moving forward from a current offset inside a node. If by is "char", it will
// consider one character forward. If it is "word" it will work from the current position forward
// through text of a singular character category (e.g. "cat" of "#!*") until reaching a character
// in a different category (i.e. the end of the word).
// Note that this method is at this point unlikely to work reliably for non-European scripts.
function moveForward($pos, by) {
if (by != "char" && by != "word")
throw new RangeError("Unknown motion unit: " + by)
let parent = $pos.parent, offset = $pos.parentOffset, pos = $pos.pos
let cat = null, counted = 0
for (;;) {
if (offset == parent.content.size) return pos
let {offset: start, node} = parent.childAfter(offset)
if (!node) return pos
if (!node.isText) return cat ? pos : pos + 1
if (by == "char") {
for (let i = offset - start; i < node.text.length; i++) {
if (!isExtendingCharAt(node.text, i + 1))
return pos + 1
offset++
pos++
}
} else if (by == "word") {
for (let i = offset - start; i < node.text.length; i++) {
let nextCharCat = charCategory(node.text.charAt(i))
if (cat == null || counted == 1 && cat == "space") cat = nextCharCat
else if (cat != nextCharCat) return pos
offset++
pos++
counted++
}
}
}
}
exports.moveForward = moveForward
// Parameterized commands

@@ -493,3 +373,3 @@

onAction(state.tr
.clearMarkupFor(where, nodeType, attrs)
.clearNonMatching(where, nodeType.contentExpr.start(attrs))
.setNodeType(where, nodeType, attrs)

@@ -598,5 +478,5 @@ .scrollAction())

function chainCommands(...commands) {
return function(state, onAction) {
return function(state, onAction, view) {
for (let i = 0; i < commands.length; i++)
if (commands[i](state, onAction)) return true
if (commands[i](state, onAction, view)) return true
return false

@@ -613,6 +493,7 @@ }

// * **Enter** to `newlineInCode`, `createParagraphNear`, `liftEmptyBlock`, `splitBlock`
// * **Backspace** to `deleteSelection`, `joinBackward`, `deleteCharBefore`
// * **Mod-Backspace** to `deleteSelection`, `joinBackward`, `deleteWordBefore`
// * **Delete** to `deleteSelection`, `joinForward`, `deleteCharAfter`
// * **Mod-Delete** to `deleteSelection`, `joinForward`, `deleteWordAfter`
// * **Mod-Enter** to `exitCode`
// * **Backspace** to `deleteSelection`, `joinBackward`
// * **Mod-Backspace** to `deleteSelection`, `joinBackward`
// * **Delete** to `deleteSelection`, `joinForward`
// * **Mod-Delete** to `deleteSelection`, `joinForward`
// * **Alt-ArrowUp** to `joinUp`

@@ -624,7 +505,8 @@ // * **Alt-ArrowDown** to `joinDown`

"Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock),
"Mod-Enter": exitCode,
"Backspace": ios ? chainCommands(deleteSelection, joinBackward) : chainCommands(deleteSelection, joinBackward, deleteCharBefore),
"Mod-Backspace": chainCommands(deleteSelection, joinBackward, deleteWordBefore),
"Delete": chainCommands(deleteSelection, joinForward, deleteCharAfter),
"Mod-Delete": chainCommands(deleteSelection, joinForward, deleteWordAfter),
"Backspace": chainCommands(deleteSelection, joinBackward),
"Mod-Backspace": chainCommands(deleteSelection, joinBackward),
"Delete": chainCommands(deleteSelection, joinForward),
"Mod-Delete": chainCommands(deleteSelection, joinForward),

@@ -637,2 +519,6 @@ "Alt-ArrowUp": joinUp,

// declare global: os, navigator
const mac = typeof navigator != "undefined" ? /Mac/.test(navigator.platform)
: typeof os != "undefined" ? os.platform() == "darwin" : false
if (mac) {

@@ -639,0 +525,0 @@ let extra = {

@@ -15,8 +15,2 @@ This module exports a number of ‘commands‘, which are building block

@joinForward
@deleteCharBefore
@deleteWordBefore
@deleteCharAfter
@deleteWordAfter
@moveBackward
@moveForward
@joinUp

@@ -26,2 +20,3 @@ @joinDown

@newlineInCode
@exitCode
@createParagraphNear

@@ -28,0 +23,0 @@ @liftEmptyBlock

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc