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

prosemirror-transform

Package Overview
Dependencies
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prosemirror-transform - npm Package Compare versions

Comparing version 0.12.1 to 0.13.0

5

dist/mark_step.js

@@ -35,7 +35,8 @@ var ref = require("prosemirror-model");

var oldSlice = doc.slice(this.from, this.to)
var oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)
var parent = $from.node($from.sharedDepth(this.to))
var slice = new Slice(mapFragment(oldSlice.content, function (node, parent, index) {
if (!parent.contentMatchAt(index + 1).allowsMark(this$1.mark.type)) { return node }
return node.mark(this$1.mark.addToSet(node.marks))
}, oldSlice.possibleParent), oldSlice.openLeft, oldSlice.openRight)
}, parent), oldSlice.openLeft, oldSlice.openRight)
return StepResult.fromReplace(doc, this.from, this.to, slice)

@@ -42,0 +43,0 @@ };

2

dist/mark.js

@@ -70,3 +70,3 @@ var ref = require("prosemirror-model");

for (var i = 0; i < toRemove.length; i++) {
var style = toRemove[i], found$1 = void 0
var style = toRemove[i], found$1 = (void 0)
for (var j = 0; j < matched.length; j++) {

@@ -73,0 +73,0 @@ var m = matched[j]

@@ -10,4 +10,137 @@ var ref = require("prosemirror-model");

var Transform = ref$2.Transform;
var ref$3 = require("./structure");
var insertPoint = ref$3.insertPoint;
// :: (number, number, Slice) → Transform
// Replace a range of the document with a given slice, using `from`,
// `to`, and the slice's [`openLeft`](#model.Slice.openLeft) property
// as hints, rather than fixed start and end points. This method may
// grow the replaced area or close open nodes in the slice in order to
// get a fit that is more in line with WYSIWYG expectations, by
// dropping fully covered parent nodes of the replaced region when
// they are marked [non-defining](#model.NodeSpec.defining), or
// including an open parent node from the slice that _is_ marked as
// [defining](#model.NodeSpec.defining).
//
// This is the method, for example, to handle paste. The similar
// [`replace`](#transform.Transform.replace) method is a more
// primitive tool which will _not_ move the start and end of its given
// range, and is useful in situations where you need more precise
// control over what happens.
Transform.prototype.replaceRange = function(from, to, slice) {
var this$1 = this;
if (!slice.size) { return this.deleteRange(from, to) }
var $from = this.doc.resolve(from)
var canExpand = coveredDepths($from, this.doc.resolve(to)), preferredExpand = 0
canExpand.unshift($from.depth + 1)
for (var d = $from.depth; d > 0; d--) {
if ($from.node(d).type.spec.defining) { break }
var found = canExpand.indexOf(d, 1)
if (found > -1) { preferredExpand = found }
}
var leftNodes = [], preferredDepth = slice.openLeft
for (var content = slice.content, i = 0;; i++) {
var node = content.firstChild
leftNodes.push(node)
if (i == slice.openLeft) { break }
content = node.content
}
// Back up if the node directly above openLeft, or the node above
// that separated only by a non-defining textblock node, is defining.
if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining)
{ preferredDepth -= 1 }
else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining)
{ preferredDepth -= 2 }
for (var j = slice.openLeft; j >= 0; j--) {
var openDepth = (j + preferredDepth + 1) % (slice.openLeft + 1)
var insert = leftNodes[openDepth]
if (!insert) { continue }
for (var i$1 = 0; i$1 < canExpand.length; i$1++) {
// Loop over possible expansion levels, starting with the
// preferred one
var expandDepth = canExpand[(i$1 + preferredExpand) % canExpand.length]
var parent = $from.node(expandDepth - 1), index = $from.index(expandDepth - 1)
if (parent.canReplaceWith(index, index, insert.type, insert.attrs, insert.marks))
{ return this$1.replace($from.before(expandDepth), expandDepth > $from.depth ? to : $from.after(expandDepth),
new Slice(closeFragment(slice.content, 0, slice.openLeft, openDepth),
openDepth, slice.openRight)) }
}
}
return this.replace(from, to, slice)
}
function closeFragment(fragment, depth, oldOpen, newOpen, parent) {
if (depth < oldOpen) {
var first = fragment.firstChild
fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))
}
if (depth > newOpen)
{ fragment = parent.contentMatchAt(0).fillBefore(fragment).append(fragment) }
return fragment
}
// :: (number, number, Node) → Transform
// Replace the given range with a node, but use `from` and `to` as
// hints, rather than precise positions. When from and to are the same
// and are at the start or end of a parent node in which the given
// node doesn't fit, this method may _move_ them out towards a parent
// that does allow the given node to be placed. When the given range
// completely covers a parent node, this method may completely replace
// that parent node.
Transform.prototype.replaceRangeWith = function(from, to, node) {
if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {
var point = insertPoint(this.doc, from, node.type, node.attrs)
if (point != null) { from = to = point }
}
return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))
}
// :: (number, number) → Transform
// Delete the given range, and any fully covered parent nodes that are
// not allowed to be empty.
Transform.prototype.deleteRange = function(from, to) {
var $from = this.doc.resolve(from)
var covered = coveredDepths($from, this.doc.resolve(to)), grown = false
// Find the innermost covered node that allows its whole content to
// be deleted
for (var i = 0; i < covered.length; i++) {
if ($from.node(covered[i]).contentMatchAt(0).validEnd()) {
from = $from.start(covered[i])
to = $from.end(covered[i])
grown = true
break
}
}
// If no such node was found and the outermose covered node can be
// deleted entirely, do that
if (!grown && covered.length) {
var depth = covered[covered.length - 1]
if ($from.node(depth - 1).canReplace($from.index(depth - 1), $from.indexAfter(depth - 1))) {
from = $from.before(depth)
to = $from.after(depth)
}
}
return this.delete(from, to)
}
// : (ResolvedPos, ResolvedPos) → [number]
// Returns an array of all depths for which $from - $to spans the
// whole content of the node at that depth.
function coveredDepths($from, $to) {
var result = []
for (var i = 0; i < $from.depth; i++) {
var depth = $from.depth - i
if ($from.pos - i > $from.start(depth)) { break }
if ($to.depth >= depth && $to.pos + ($to.depth - depth) == $from.end(depth)) { result.push(depth) }
}
return result
}
// :: (number, number) → Transform
// Delete the content between the given positions.

@@ -239,2 +372,3 @@ Transform.prototype.delete = function(from, to) {

// : (ResolvedPos, Slice) → [{content: Fragment, openRight: number, depth: number}]
function placeSlice($from, slice) {

@@ -244,4 +378,7 @@ var dFrom = $from.depth, unplaced = null

// Loop over the open side of the slice, trying to find a place for
// each open fragment.
for (var dSlice = slice.openLeft;; --dSlice) {
var curType = void 0, curAttrs = void 0, curFragment = void 0
// Get the components of the node at this level
var curType = (void 0), curAttrs = (void 0), curFragment = (void 0)
if (dSlice >= 0) {

@@ -255,3 +392,3 @@ if (dSlice > 0) { // Inside slice

if (dSlice < slice.openLeft) { curFragment = curFragment.cut(curFragment.firstChild.nodeSize) }
} else { // Outside slice
} else { // Outside slice, in generated wrappers (see below)
curFragment = Fragment.empty

@@ -262,15 +399,19 @@ var parent = parents[parents.length + dSlice - 1]

}
if (unplaced)
{ curFragment = curFragment.addToStart(unplaced) }
// If the last iteration left unplaced content, include it in the fragment
if (unplaced) { curFragment = curFragment.addToStart(unplaced) }
// If there's nothing left to place, we're done
if (curFragment.size == 0 && dSlice <= 0) { break }
// FIXME cut/remove marks when it helps find a placement
// This will go through the positions in $from, down from dFrom,
// to find a fit
var found = findPlacement(curFragment, $from, dFrom)
if (found) {
if (found.fragment.size > 0) { placed[found.depth] = {
content: found.fill.append(found.fragment),
if (found && (found.depth || noMoreContent(slice, dSlice))) {
// If there was a fit, store it, and consider this content placed
if (curFragment.size > 0) { placed[found.depth] = {
content: found.fragment,
openRight: dSlice > 0 ? 0 : slice.openRight - dSlice,
depth: found.depth
} }
// If that was the last of the content, we're done
if (dSlice <= 0) { break }

@@ -281,14 +422,22 @@ unplaced = null

if (dSlice == 0) {
// This is the top of the slice, and we haven't found a place to insert it.
var top = $from.node(0)
parents = top.contentMatchAt($from.index(0)).findWrapping(curFragment.firstChild.type, curFragment.firstChild.attrs)
if (!parents) { break }
var last = parents[parents.length - 1]
if (last ? !last.type.contentExpr.matches(last.attrs, curFragment)
: !top.canReplace($from.indexAfter(0), $from.depth ? $from.index(0) : $from.indexAfter(0), curFragment)) { break }
parents = [{type: top.type, attrs: top.attrs}].concat(parents)
curType = parents[parents.length - 1].type
curAttrs = parents[parents.length - 1].type
// Try to find a wrapping that makes its first child fit in the top node.
var wrap = top.contentMatchAt($from.index(0)).findWrappingFor(curFragment.firstChild)
// If no such thing exists, give up.
if (!wrap || wrap.length == 0) { break }
var last = wrap[wrap.length - 1]
// Check that the fragment actually fits in the wrapping.
if (!last.type.contentExpr.matches(last.attrs, curFragment)) { break }
// Store the result for subsequent iterations.
parents = [{type: top.type, attrs: top.attrs}].concat(wrap)
;var assign$1;
((assign$1 = last, curType = assign$1.type, curAttrs = assign$1.attrs))
}
curFragment = curType.contentExpr.start(curAttrs).fillBefore(curFragment, true).append(curFragment)
unplaced = curType.create(curAttrs, curFragment)
if (curFragment.size) {
curFragment = curType.contentExpr.start(curAttrs).fillBefore(curFragment, true).append(curFragment)
unplaced = curType.create(curAttrs, curFragment)
} else {
unplaced = null
}
}

@@ -307,6 +456,6 @@ }

var match = startMatch.fillBefore(fragment)
if (match) { return {depth: d, fill: match, fragment: fragment} }
if (match) { return {depth: d, fragment: match.append(fragment)} }
if (hasMarks) {
var stripped = matchStrippingMarks(startMatch, fragment)
if (stripped) { return {depth: d, fill: Fragment.empty, fragment: stripped} }
if (stripped) { return {depth: d, fragment: stripped} }
}

@@ -326,1 +475,10 @@ }

}
function noMoreContent(slice, depth) {
if (depth <= 0) { return true }
for (var i = 0, content = slice.content;; i++) {
var next = content.firstChild
if (i == depth - 1) { return 2 * i + next.nodeSize == slice.content.size }
content = next.content
}
}

@@ -102,3 +102,3 @@ var ref = require("prosemirror-model");

var inner = parent.child(startIndex)
var inside = wrap.type.contentExpr.start(wrap.attrs).findWrapping(inner.type, inner.attrs)
var inside = wrap.type.contentExpr.start(wrap.attrs).findWrappingFor(inner)
if (!inside) { return null }

@@ -231,3 +231,3 @@ var last = inside.length ? inside[inside.length - 1] : wrap

for (var d = $pos.depth;; d--) {
var before = void 0, after = void 0
var before = (void 0), after = (void 0)
if (d == $pos.depth) {

@@ -234,0 +234,0 @@ before = $pos.nodeBefore

{
"name": "prosemirror-transform",
"version": "0.12.1",
"version": "0.13.0",
"description": "ProseMirror document transformations",

@@ -19,3 +19,3 @@ "main": "dist/index.js",

"dependencies": {
"prosemirror-model": "^0.12.0"
"prosemirror-model": "^0.13.0"
},

@@ -22,0 +22,0 @@ "devDependencies": {

# prosemirror-transform
[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) ]
[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror/blob/master/CHANGELOG.md) ]

@@ -5,0 +5,0 @@ ProseMirror is a well-behaved rich semantic content editor based on

@@ -26,7 +26,8 @@ const {Fragment, Slice} = require("prosemirror-model")

apply(doc) {
let oldSlice = doc.slice(this.from, this.to)
let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)
let parent = $from.node($from.sharedDepth(this.to))
let slice = new Slice(mapFragment(oldSlice.content, (node, parent, index) => {
if (!parent.contentMatchAt(index + 1).allowsMark(this.mark.type)) return node
return node.mark(this.mark.addToSet(node.marks))
}, oldSlice.possibleParent), oldSlice.openLeft, oldSlice.openRight)
}, parent), oldSlice.openLeft, oldSlice.openRight)
return StepResult.fromReplace(doc, this.from, this.to, slice)

@@ -33,0 +34,0 @@ }

@@ -5,4 +5,134 @@ const {Fragment, Slice} = require("prosemirror-model")

const {Transform} = require("./transform")
const {insertPoint} = require("./structure")
// :: (number, number, Slice) → Transform
// Replace a range of the document with a given slice, using `from`,
// `to`, and the slice's [`openLeft`](#model.Slice.openLeft) property
// as hints, rather than fixed start and end points. This method may
// grow the replaced area or close open nodes in the slice in order to
// get a fit that is more in line with WYSIWYG expectations, by
// dropping fully covered parent nodes of the replaced region when
// they are marked [non-defining](#model.NodeSpec.defining), or
// including an open parent node from the slice that _is_ marked as
// [defining](#model.NodeSpec.defining).
//
// This is the method, for example, to handle paste. The similar
// [`replace`](#transform.Transform.replace) method is a more
// primitive tool which will _not_ move the start and end of its given
// range, and is useful in situations where you need more precise
// control over what happens.
Transform.prototype.replaceRange = function(from, to, slice) {
if (!slice.size) return this.deleteRange(from, to)
let $from = this.doc.resolve(from)
let canExpand = coveredDepths($from, this.doc.resolve(to)), preferredExpand = 0
canExpand.unshift($from.depth + 1)
for (let d = $from.depth; d > 0; d--) {
if ($from.node(d).type.spec.defining) break
let found = canExpand.indexOf(d, 1)
if (found > -1) preferredExpand = found
}
let leftNodes = [], preferredDepth = slice.openLeft
for (let content = slice.content, i = 0;; i++) {
let node = content.firstChild
leftNodes.push(node)
if (i == slice.openLeft) break
content = node.content
}
// Back up if the node directly above openLeft, or the node above
// that separated only by a non-defining textblock node, is defining.
if (preferredDepth > 0 && leftNodes[preferredDepth - 1].type.spec.defining)
preferredDepth -= 1
else if (preferredDepth >= 2 && leftNodes[preferredDepth - 1].isTextblock && leftNodes[preferredDepth - 2].type.spec.defining)
preferredDepth -= 2
for (let j = slice.openLeft; j >= 0; j--) {
let openDepth = (j + preferredDepth + 1) % (slice.openLeft + 1)
let insert = leftNodes[openDepth]
if (!insert) continue
for (let i = 0; i < canExpand.length; i++) {
// Loop over possible expansion levels, starting with the
// preferred one
let expandDepth = canExpand[(i + preferredExpand) % canExpand.length]
let parent = $from.node(expandDepth - 1), index = $from.index(expandDepth - 1)
if (parent.canReplaceWith(index, index, insert.type, insert.attrs, insert.marks))
return this.replace($from.before(expandDepth), expandDepth > $from.depth ? to : $from.after(expandDepth),
new Slice(closeFragment(slice.content, 0, slice.openLeft, openDepth),
openDepth, slice.openRight))
}
}
return this.replace(from, to, slice)
}
function closeFragment(fragment, depth, oldOpen, newOpen, parent) {
if (depth < oldOpen) {
let first = fragment.firstChild
fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)))
}
if (depth > newOpen)
fragment = parent.contentMatchAt(0).fillBefore(fragment).append(fragment)
return fragment
}
// :: (number, number, Node) → Transform
// Replace the given range with a node, but use `from` and `to` as
// hints, rather than precise positions. When from and to are the same
// and are at the start or end of a parent node in which the given
// node doesn't fit, this method may _move_ them out towards a parent
// that does allow the given node to be placed. When the given range
// completely covers a parent node, this method may completely replace
// that parent node.
Transform.prototype.replaceRangeWith = function(from, to, node) {
if (!node.isInline && from == to && this.doc.resolve(from).parent.content.size) {
let point = insertPoint(this.doc, from, node.type, node.attrs)
if (point != null) from = to = point
}
return this.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0))
}
// :: (number, number) → Transform
// Delete the given range, and any fully covered parent nodes that are
// not allowed to be empty.
Transform.prototype.deleteRange = function(from, to) {
let $from = this.doc.resolve(from)
let covered = coveredDepths($from, this.doc.resolve(to)), grown = false
// Find the innermost covered node that allows its whole content to
// be deleted
for (let i = 0; i < covered.length; i++) {
if ($from.node(covered[i]).contentMatchAt(0).validEnd()) {
from = $from.start(covered[i])
to = $from.end(covered[i])
grown = true
break
}
}
// If no such node was found and the outermose covered node can be
// deleted entirely, do that
if (!grown && covered.length) {
let depth = covered[covered.length - 1]
if ($from.node(depth - 1).canReplace($from.index(depth - 1), $from.indexAfter(depth - 1))) {
from = $from.before(depth)
to = $from.after(depth)
}
}
return this.delete(from, to)
}
// : (ResolvedPos, ResolvedPos) → [number]
// Returns an array of all depths for which $from - $to spans the
// whole content of the node at that depth.
function coveredDepths($from, $to) {
let result = []
for (let i = 0; i < $from.depth; i++) {
let depth = $from.depth - i
if ($from.pos - i > $from.start(depth)) break
if ($to.depth >= depth && $to.pos + ($to.depth - depth) == $from.end(depth)) result.push(depth)
}
return result
}
// :: (number, number) → Transform
// Delete the content between the given positions.

@@ -226,2 +356,3 @@ Transform.prototype.delete = function(from, to) {

// : (ResolvedPos, Slice) → [{content: Fragment, openRight: number, depth: number}]
function placeSlice($from, slice) {

@@ -231,3 +362,6 @@ let dFrom = $from.depth, unplaced = null

// Loop over the open side of the slice, trying to find a place for
// each open fragment.
for (let dSlice = slice.openLeft;; --dSlice) {
// Get the components of the node at this level
let curType, curAttrs, curFragment

@@ -241,3 +375,3 @@ if (dSlice >= 0) {

if (dSlice < slice.openLeft) curFragment = curFragment.cut(curFragment.firstChild.nodeSize)
} else { // Outside slice
} else { // Outside slice, in generated wrappers (see below)
curFragment = Fragment.empty

@@ -248,15 +382,19 @@ let parent = parents[parents.length + dSlice - 1]

}
if (unplaced)
curFragment = curFragment.addToStart(unplaced)
// If the last iteration left unplaced content, include it in the fragment
if (unplaced) curFragment = curFragment.addToStart(unplaced)
// If there's nothing left to place, we're done
if (curFragment.size == 0 && dSlice <= 0) break
// FIXME cut/remove marks when it helps find a placement
// This will go through the positions in $from, down from dFrom,
// to find a fit
let found = findPlacement(curFragment, $from, dFrom)
if (found) {
if (found.fragment.size > 0) placed[found.depth] = {
content: found.fill.append(found.fragment),
if (found && (found.depth || noMoreContent(slice, dSlice))) {
// If there was a fit, store it, and consider this content placed
if (curFragment.size > 0) placed[found.depth] = {
content: found.fragment,
openRight: dSlice > 0 ? 0 : slice.openRight - dSlice,
depth: found.depth
}
// If that was the last of the content, we're done
if (dSlice <= 0) break

@@ -267,14 +405,21 @@ unplaced = null

if (dSlice == 0) {
// This is the top of the slice, and we haven't found a place to insert it.
let top = $from.node(0)
parents = top.contentMatchAt($from.index(0)).findWrapping(curFragment.firstChild.type, curFragment.firstChild.attrs)
if (!parents) break
let last = parents[parents.length - 1]
if (last ? !last.type.contentExpr.matches(last.attrs, curFragment)
: !top.canReplace($from.indexAfter(0), $from.depth ? $from.index(0) : $from.indexAfter(0), curFragment)) break
parents = [{type: top.type, attrs: top.attrs}].concat(parents)
curType = parents[parents.length - 1].type
curAttrs = parents[parents.length - 1].type
// Try to find a wrapping that makes its first child fit in the top node.
let wrap = top.contentMatchAt($from.index(0)).findWrappingFor(curFragment.firstChild)
// If no such thing exists, give up.
if (!wrap || wrap.length == 0) break
let last = wrap[wrap.length - 1]
// Check that the fragment actually fits in the wrapping.
if (!last.type.contentExpr.matches(last.attrs, curFragment)) break
// Store the result for subsequent iterations.
parents = [{type: top.type, attrs: top.attrs}].concat(wrap)
;({type: curType, attrs: curAttrs} = last)
}
curFragment = curType.contentExpr.start(curAttrs).fillBefore(curFragment, true).append(curFragment)
unplaced = curType.create(curAttrs, curFragment)
if (curFragment.size) {
curFragment = curType.contentExpr.start(curAttrs).fillBefore(curFragment, true).append(curFragment)
unplaced = curType.create(curAttrs, curFragment)
} else {
unplaced = null
}
}

@@ -293,6 +438,6 @@ }

let match = startMatch.fillBefore(fragment)
if (match) return {depth: d, fill: match, fragment}
if (match) return {depth: d, fragment: match.append(fragment)}
if (hasMarks) {
let stripped = matchStrippingMarks(startMatch, fragment)
if (stripped) return {depth: d, fill: Fragment.empty, fragment: stripped}
if (stripped) return {depth: d, fragment: stripped}
}

@@ -312,1 +457,10 @@ }

}
function noMoreContent(slice, depth) {
if (depth <= 0) return true
for (let i = 0, content = slice.content;; i++) {
let next = content.firstChild
if (i == depth - 1) return 2 * i + next.nodeSize == slice.content.size
content = next.content
}
}

@@ -89,3 +89,3 @@ const {Slice, Fragment} = require("prosemirror-model")

let inner = parent.child(startIndex)
let inside = wrap.type.contentExpr.start(wrap.attrs).findWrapping(inner.type, inner.attrs)
let inside = wrap.type.contentExpr.start(wrap.attrs).findWrappingFor(inner)
if (!inside) return null

@@ -92,0 +92,0 @@ let last = inside.length ? inside[inside.length - 1] : wrap

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