prosemirror-view
Advanced tools
Comparing version 0.19.0 to 0.19.1
@@ -14,7 +14,6 @@ var ref = require("prosemirror-model"); | ||
var DOMChange = function(view, id, composing) { | ||
var DOMChange = function(view, composing) { | ||
var this$1 = this; | ||
this.view = view | ||
this.id = id | ||
this.state = view.state | ||
@@ -104,4 +103,3 @@ this.composing = composing | ||
} else { | ||
var id = Math.floor(Math.random() * 0xffffffff) | ||
view.inDOMChange = new DOMChange(view, id, composing) | ||
view.inDOMChange = new DOMChange(view, composing) | ||
} | ||
@@ -118,20 +116,9 @@ return view.inDOMChange | ||
function parseBetween(view, oldState, from, to) { | ||
var ref = view.docView.domFromPos(from, -1); | ||
function parseBetween(view, oldState, range) { | ||
var ref = view.docView.parseRange(range.from, range.to); | ||
var parent = ref.node; | ||
var startOff = ref.offset; | ||
var ref$1 = view.docView.domFromPos(to, 1); | ||
var parentRight = ref$1.node; | ||
var endOff = ref$1.offset; | ||
if (parent != parentRight) { return null } | ||
// If there's non-view nodes directly after the end of this region, | ||
// fail and let the caller try again with a wider range. | ||
if (endOff == parent.childNodes.length) { for (var scan = parent; scan != view.dom;) { | ||
if (!scan) { return null } | ||
if (scan.nextSibling) { | ||
if (!scan.nextSibling.pmViewDesc) { return null } | ||
break | ||
} | ||
scan = scan.parentNode | ||
} } | ||
var fromOffset = ref.fromOffset; | ||
var toOffset = ref.toOffset; | ||
var from = ref.from; | ||
var to = ref.to; | ||
@@ -151,4 +138,4 @@ var domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode | ||
topOpen: true, | ||
from: startOff, | ||
to: endOff, | ||
from: fromOffset, | ||
to: toOffset, | ||
preserveWhitespace: true, | ||
@@ -165,3 +152,3 @@ editableContent: true, | ||
} | ||
return {doc: doc, sel: sel} | ||
return {doc: doc, sel: sel, from: from, to: to} | ||
} | ||
@@ -227,20 +214,10 @@ | ||
function readDOMChange(view, mapping, oldState, range) { | ||
var parseResult, doc = oldState.doc | ||
var parse = parseBetween(view, oldState, range) | ||
for (;;) { | ||
parseResult = parseBetween(view, oldState, range.from, range.to) | ||
if (parseResult) { break } | ||
var $from$1 = doc.resolve(range.from), $to$1 = doc.resolve(range.to) | ||
range = {from: $from$1.depth ? $from$1.before() : 0, | ||
to: $to$1.depth ? $to$1.after() : doc.content.size} | ||
} | ||
var parsed = parseResult.doc; | ||
var parsedSel = parseResult.sel; | ||
var doc = oldState.doc, compare = doc.slice(parse.from, parse.to) | ||
var change = findDiff(compare.content, parse.doc.content, parse.from, oldState.selection.from) | ||
var compare = doc.slice(range.from, range.to) | ||
var change = findDiff(compare.content, parsed.content, range.from, oldState.selection.from) | ||
if (!change) { | ||
if (parsedSel) { | ||
var sel = resolveSelection(view, view.state.doc, mapping, parsedSel) | ||
if (parse.sel) { | ||
var sel = resolveSelection(view, view.state.doc, mapping, parse.sel) | ||
if (sel && !sel.eq(view.state.selection)) { view.dispatch(view.state.tr.setSelection(sel)) } | ||
@@ -251,9 +228,9 @@ } | ||
var $from = parsed.resolveNoCache(change.start - range.from) | ||
var $to = parsed.resolveNoCache(change.endB - range.from) | ||
var $from = parse.doc.resolveNoCache(change.start - parse.from) | ||
var $to = parse.doc.resolveNoCache(change.endB - parse.from) | ||
var nextSel | ||
// If this looks like the effect of pressing Enter, just dispatch an | ||
// Enter key instead. | ||
if (!$from.sameParent($to) && $from.pos < parsed.content.size && | ||
(nextSel = Selection.findFrom(parsed.resolve($from.pos + 1), 1, true)) && | ||
if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && | ||
(nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && | ||
nextSel.head == $to.pos && | ||
@@ -293,5 +270,5 @@ view.someProp("handleKeyDown", function (f) { return f(view, keyEvent(13, "Enter")); })) | ||
if (!tr) | ||
{ tr = view.state.tr.replace(from, to, parsed.slice(change.start - range.from, change.endB - range.from)) } | ||
if (parsedSel) { | ||
var sel$1 = resolveSelection(view, tr.doc, mapping, parsedSel) | ||
{ tr = view.state.tr.replace(from, to, parse.doc.slice(change.start - parse.from, change.endB - parse.from)) } | ||
if (parse.sel) { | ||
var sel$1 = resolveSelection(view, tr.doc, mapping, parse.sel) | ||
if (sel$1) { tr.setSelection(sel$1) } | ||
@@ -298,0 +275,0 @@ } |
@@ -333,3 +333,4 @@ var ref = require("prosemirror-model"); | ||
var spec = {isCursorWrapper: true, marks: marks, raw: true} | ||
if (!view.cursorWrapper || !Mark.sameSet(view.cursorWrapper.spec.marks, marks)) | ||
if (!view.cursorWrapper || !Mark.sameSet(view.cursorWrapper.spec.marks, marks) || | ||
view.cursorWrapper.type.widget.textContent != "\ufeff") | ||
{ view.cursorWrapper = Decoration.widget($cursor.pos, cursorWrapperDOM(), spec) } | ||
@@ -336,0 +337,0 @@ else if (view.cursorWrapper.pos != $cursor.pos) |
@@ -116,3 +116,3 @@ var ref = require("prosemirror-state"); | ||
var $to = ref.$to; | ||
if (node || !$from.sameParent($to)) { | ||
if (node || !$from.sameParent($to) || !(view.state.selection instanceof TextSelection)) { | ||
var text = String.fromCharCode(event.charCode) | ||
@@ -119,0 +119,0 @@ if (!view.someProp("handleTextInput", function (f) { return f(view, $from.pos, $to.pos, text); })) |
@@ -264,4 +264,4 @@ var ref = require("prosemirror-model"); | ||
// : (number, ?bool) → {node: dom.Node, offset: number} | ||
ViewDesc.prototype.domFromPos = function (pos, searchDOM) { | ||
// : (number) → {node: dom.Node, offset: number} | ||
ViewDesc.prototype.domFromPos = function (pos) { | ||
var this$1 = this; | ||
@@ -272,7 +272,6 @@ | ||
if (offset == pos) | ||
{ return {node: this$1.contentDOM, | ||
offset: searchDOM ? this$1.findDOMOffset(i, searchDOM) : i} } | ||
{ return {node: this$1.contentDOM, offset: i} } | ||
if (i == this$1.children.length) { throw new Error("Invalid position " + pos) } | ||
var child = this$1.children[i], end = offset + child.size | ||
if (pos < end) { return child.domFromPos(pos - offset - child.border, searchDOM) } | ||
if (pos < end) { return child.domFromPos(pos - offset - child.border) } | ||
offset = end | ||
@@ -282,27 +281,53 @@ } | ||
// If the DOM was directly edited, we can't trust the child view | ||
// desc offsets anymore, so we search the actual DOM to figure out | ||
// the offset that corresponds to a given child. | ||
ViewDesc.prototype.findDOMOffset = function (i, searchDOM) { | ||
// Used to find a DOM range in a single parent for a given changed | ||
// range. | ||
ViewDesc.prototype.parseRange = function (from, to, base) { | ||
var this$1 = this; | ||
if ( base === void 0 ) base = 0; | ||
if (searchDOM < 0) { | ||
for (var j = i - 1; j >= 0; j--) { | ||
var child = this$1.children[j] | ||
if (!child.size) { continue } | ||
var found = domIndex(child.dom) | ||
if (found > -1) { return found + 1 } | ||
var fromOffset = -1, toOffset = -1 | ||
for (var offset = 0, i = 0;; i++) { | ||
var child = this$1.children[i], end = offset + child.size | ||
if (fromOffset == -1 && from <= end) { | ||
var childBase = offset + child.border | ||
// FIXME maybe descend mark views to parse a narrower range? | ||
if (from >= childBase && to <= end - child.border && child.node && | ||
child.contentDOM && this$1.contentDOM.contains(child.contentDOM)) | ||
{ return child.parseRange(from - childBase, to - childBase, base + childBase) } | ||
from = base + offset | ||
for (var j = i; j > 0; j--) { | ||
var prev = this$1.children[j - 1] | ||
if (prev.size && prev.dom.parentNode == this$1.contentDOM && !prev.emptyChildAt(1)) { | ||
fromOffset = domIndex(prev.dom) + 1 | ||
break | ||
} | ||
from -= prev.size | ||
} | ||
if (fromOffset == -1) { fromOffset = 0 } | ||
} | ||
return 0 | ||
} else { | ||
for (var j$1 = i; j$1 < this.children.length; j$1++) { | ||
var child$1 = this$1.children[j$1] | ||
if (!child$1.size) { continue } | ||
var found$1 = domIndex(child$1.dom) | ||
if (found$1 > -1) { return found$1 } | ||
if (fromOffset > -1 && to <= end) { | ||
to = base + end | ||
for (var j$1 = i + 1; j$1 < this.children.length; j$1++) { | ||
var next = this$1.children[j$1] | ||
if (next.size && next.dom.parentNode == this$1.contentDOM && !next.emptyChildAt(-1)) { | ||
toOffset = domIndex(next.dom) | ||
break | ||
} | ||
to += next.size | ||
} | ||
if (toOffset == -1) { toOffset = this$1.contentDOM.childNodes.length } | ||
break | ||
} | ||
return this.contentDOM.childNodes.length | ||
offset = end | ||
} | ||
return {node: this.contentDOM, from: from, to: to, fromOffset: fromOffset, toOffset: toOffset} | ||
}; | ||
ViewDesc.prototype.emptyChildAt = function (side) { | ||
if (this.border || !this.contentDOM || !this.children.length) { return false } | ||
var child = this.children[side < 0 ? 0 : this.children.length - 1] | ||
return child.size == 0 || child.emptyChildAt(side) | ||
}; | ||
// : (number) → dom.Node | ||
@@ -700,4 +725,4 @@ ViewDesc.prototype.domAfterPos = function (pos) { | ||
TextViewDesc.prototype.domFromPos = function (pos, searchDOM) { | ||
return {node: this.nodeDOM, offset: searchDOM ? Math.max(pos, this.nodeDOM.nodeValue.length) : pos} | ||
TextViewDesc.prototype.domFromPos = function (pos) { | ||
return {node: this.nodeDOM, offset: pos} | ||
}; | ||
@@ -704,0 +729,0 @@ |
{ | ||
"name": "prosemirror-view", | ||
"version": "0.19.0", | ||
"version": "0.19.1", | ||
"description": "ProseMirror's view component", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -9,5 +9,4 @@ const {Fragment, DOMParser} = require("prosemirror-model") | ||
class DOMChange { | ||
constructor(view, id, composing) { | ||
constructor(view, composing) { | ||
this.view = view | ||
this.id = id | ||
this.state = view.state | ||
@@ -95,4 +94,3 @@ this.composing = composing | ||
} else { | ||
let id = Math.floor(Math.random() * 0xffffffff) | ||
view.inDOMChange = new DOMChange(view, id, composing) | ||
view.inDOMChange = new DOMChange(view, composing) | ||
} | ||
@@ -110,16 +108,4 @@ return view.inDOMChange | ||
function parseBetween(view, oldState, from, to) { | ||
let {node: parent, offset: startOff} = view.docView.domFromPos(from, -1) | ||
let {node: parentRight, offset: endOff} = view.docView.domFromPos(to, 1) | ||
if (parent != parentRight) return null | ||
// If there's non-view nodes directly after the end of this region, | ||
// fail and let the caller try again with a wider range. | ||
if (endOff == parent.childNodes.length) for (let scan = parent; scan != view.dom;) { | ||
if (!scan) return null | ||
if (scan.nextSibling) { | ||
if (!scan.nextSibling.pmViewDesc) return null | ||
break | ||
} | ||
scan = scan.parentNode | ||
} | ||
function parseBetween(view, oldState, range) { | ||
let {node: parent, fromOffset, toOffset, from, to} = view.docView.parseRange(range.from, range.to) | ||
@@ -139,4 +125,4 @@ let domSel = view.root.getSelection(), find = null, anchor = domSel.anchorNode | ||
topOpen: true, | ||
from: startOff, | ||
to: endOff, | ||
from: fromOffset, | ||
to: toOffset, | ||
preserveWhitespace: true, | ||
@@ -153,3 +139,3 @@ editableContent: true, | ||
} | ||
return {doc, sel} | ||
return {doc, sel, from, to} | ||
} | ||
@@ -214,19 +200,10 @@ | ||
function readDOMChange(view, mapping, oldState, range) { | ||
let parseResult, doc = oldState.doc | ||
let parse = parseBetween(view, oldState, range) | ||
for (;;) { | ||
parseResult = parseBetween(view, oldState, range.from, range.to) | ||
if (parseResult) break | ||
let $from = doc.resolve(range.from), $to = doc.resolve(range.to) | ||
range = {from: $from.depth ? $from.before() : 0, | ||
to: $to.depth ? $to.after() : doc.content.size} | ||
} | ||
let {doc: parsed, sel: parsedSel} = parseResult | ||
let doc = oldState.doc, compare = doc.slice(parse.from, parse.to) | ||
let change = findDiff(compare.content, parse.doc.content, parse.from, oldState.selection.from) | ||
let compare = doc.slice(range.from, range.to) | ||
let change = findDiff(compare.content, parsed.content, range.from, oldState.selection.from) | ||
if (!change) { | ||
if (parsedSel) { | ||
let sel = resolveSelection(view, view.state.doc, mapping, parsedSel) | ||
if (parse.sel) { | ||
let sel = resolveSelection(view, view.state.doc, mapping, parse.sel) | ||
if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel)) | ||
@@ -237,9 +214,9 @@ } | ||
let $from = parsed.resolveNoCache(change.start - range.from) | ||
let $to = parsed.resolveNoCache(change.endB - range.from) | ||
let $from = parse.doc.resolveNoCache(change.start - parse.from) | ||
let $to = parse.doc.resolveNoCache(change.endB - parse.from) | ||
let nextSel | ||
// If this looks like the effect of pressing Enter, just dispatch an | ||
// Enter key instead. | ||
if (!$from.sameParent($to) && $from.pos < parsed.content.size && | ||
(nextSel = Selection.findFrom(parsed.resolve($from.pos + 1), 1, true)) && | ||
if (!$from.sameParent($to) && $from.pos < parse.doc.content.size && | ||
(nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && | ||
nextSel.head == $to.pos && | ||
@@ -279,5 +256,5 @@ view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) | ||
if (!tr) | ||
tr = view.state.tr.replace(from, to, parsed.slice(change.start - range.from, change.endB - range.from)) | ||
if (parsedSel) { | ||
let sel = resolveSelection(view, tr.doc, mapping, parsedSel) | ||
tr = view.state.tr.replace(from, to, parse.doc.slice(change.start - parse.from, change.endB - parse.from)) | ||
if (parse.sel) { | ||
let sel = resolveSelection(view, tr.doc, mapping, parse.sel) | ||
if (sel) tr.setSelection(sel) | ||
@@ -284,0 +261,0 @@ } |
@@ -312,3 +312,4 @@ const {Mark} = require("prosemirror-model") | ||
let spec = {isCursorWrapper: true, marks, raw: true} | ||
if (!view.cursorWrapper || !Mark.sameSet(view.cursorWrapper.spec.marks, marks)) | ||
if (!view.cursorWrapper || !Mark.sameSet(view.cursorWrapper.spec.marks, marks) || | ||
view.cursorWrapper.type.widget.textContent != "\ufeff") | ||
view.cursorWrapper = Decoration.widget($cursor.pos, cursorWrapperDOM(), spec) | ||
@@ -315,0 +316,0 @@ else if (view.cursorWrapper.pos != $cursor.pos) |
@@ -100,3 +100,3 @@ const {Selection, NodeSelection, TextSelection} = require("prosemirror-state") | ||
let {node, $from, $to} = view.state.selection | ||
if (node || !$from.sameParent($to)) { | ||
if (node || !$from.sameParent($to) || !(view.state.selection instanceof TextSelection)) { | ||
let text = String.fromCharCode(event.charCode) | ||
@@ -103,0 +103,0 @@ if (!view.someProp("handleTextInput", f => f(view, $from.pos, $to.pos, text))) |
@@ -244,12 +244,11 @@ const {DOMSerializer, Fragment} = require("prosemirror-model") | ||
// : (number, ?bool) → {node: dom.Node, offset: number} | ||
domFromPos(pos, searchDOM) { | ||
// : (number) → {node: dom.Node, offset: number} | ||
domFromPos(pos) { | ||
if (!this.contentDOM) return {node: this.dom, offset: 0} | ||
for (let offset = 0, i = 0;; i++) { | ||
if (offset == pos) | ||
return {node: this.contentDOM, | ||
offset: searchDOM ? this.findDOMOffset(i, searchDOM) : i} | ||
return {node: this.contentDOM, offset: i} | ||
if (i == this.children.length) throw new Error("Invalid position " + pos) | ||
let child = this.children[i], end = offset + child.size | ||
if (pos < end) return child.domFromPos(pos - offset - child.border, searchDOM) | ||
if (pos < end) return child.domFromPos(pos - offset - child.border) | ||
offset = end | ||
@@ -259,25 +258,50 @@ } | ||
// If the DOM was directly edited, we can't trust the child view | ||
// desc offsets anymore, so we search the actual DOM to figure out | ||
// the offset that corresponds to a given child. | ||
findDOMOffset(i, searchDOM) { | ||
if (searchDOM < 0) { | ||
for (let j = i - 1; j >= 0; j--) { | ||
let child = this.children[j] | ||
if (!child.size) continue | ||
let found = domIndex(child.dom) | ||
if (found > -1) return found + 1 | ||
// Used to find a DOM range in a single parent for a given changed | ||
// range. | ||
parseRange(from, to, base = 0) { | ||
let fromOffset = -1, toOffset = -1 | ||
for (let offset = 0, i = 0;; i++) { | ||
let child = this.children[i], end = offset + child.size | ||
if (fromOffset == -1 && from <= end) { | ||
let childBase = offset + child.border | ||
// FIXME maybe descend mark views to parse a narrower range? | ||
if (from >= childBase && to <= end - child.border && child.node && | ||
child.contentDOM && this.contentDOM.contains(child.contentDOM)) | ||
return child.parseRange(from - childBase, to - childBase, base + childBase) | ||
from = base + offset | ||
for (let j = i; j > 0; j--) { | ||
let prev = this.children[j - 1] | ||
if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { | ||
fromOffset = domIndex(prev.dom) + 1 | ||
break | ||
} | ||
from -= prev.size | ||
} | ||
if (fromOffset == -1) fromOffset = 0 | ||
} | ||
return 0 | ||
} else { | ||
for (let j = i; j < this.children.length; j++) { | ||
let child = this.children[j] | ||
if (!child.size) continue | ||
let found = domIndex(child.dom) | ||
if (found > -1) return found | ||
if (fromOffset > -1 && to <= end) { | ||
to = base + end | ||
for (let j = i + 1; j < this.children.length; j++) { | ||
let next = this.children[j] | ||
if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { | ||
toOffset = domIndex(next.dom) | ||
break | ||
} | ||
to += next.size | ||
} | ||
if (toOffset == -1) toOffset = this.contentDOM.childNodes.length | ||
break | ||
} | ||
return this.contentDOM.childNodes.length | ||
offset = end | ||
} | ||
return {node: this.contentDOM, from, to, fromOffset, toOffset} | ||
} | ||
emptyChildAt(side) { | ||
if (this.border || !this.contentDOM || !this.children.length) return false | ||
let child = this.children[side < 0 ? 0 : this.children.length - 1] | ||
return child.size == 0 || child.emptyChildAt(side) | ||
} | ||
// : (number) → dom.Node | ||
@@ -630,4 +654,4 @@ domAfterPos(pos) { | ||
domFromPos(pos, searchDOM) { | ||
return {node: this.nodeDOM, offset: searchDOM ? Math.max(pos, this.nodeDOM.nodeValue.length) : pos} | ||
domFromPos(pos) { | ||
return {node: this.nodeDOM, offset: pos} | ||
} | ||
@@ -634,0 +658,0 @@ |
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
325340
7700