prosemirror-transform
Advanced tools
Comparing version 0.12.1 to 0.13.0
@@ -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 @@ }; |
@@ -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 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
130149
2769
+ Addedprosemirror-model@0.13.0(transitive)
- Removedprosemirror-model@0.12.0(transitive)
Updatedprosemirror-model@^0.13.0