prosemirror-view
Version:
ProseMirror's view component
1,202 lines (1,201 loc) • 209 kB
JavaScript
'use strict';
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var prosemirrorState = require('prosemirror-state');
var prosemirrorModel = require('prosemirror-model');
var prosemirrorTransform = require('prosemirror-transform');
var domIndex = function domIndex(node) {
for (var index = 0;; index++) {
node = node.previousSibling;
if (!node) return index;
}
};
var parentNode = function parentNode(node) {
var parent = node.assignedSlot || node.parentNode;
return parent && parent.nodeType == 11 ? parent.host : parent;
};
var reusedRange = null;
var textRange = function textRange(node, from, to) {
var range = reusedRange || (reusedRange = document.createRange());
range.setEnd(node, to == null ? node.nodeValue.length : to);
range.setStart(node, from || 0);
return range;
};
var clearReusedRange = function clearReusedRange() {
reusedRange = null;
};
var isEquivalentPosition = function isEquivalentPosition(node, off, targetNode, targetOff) {
return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1));
};
var atomElements = /^(img|br|input|textarea|hr)$/i;
function scanFor(node, off, targetNode, targetOff, dir) {
var _a;
for (;;) {
if (node == targetNode && off == targetOff) return true;
if (off == (dir < 0 ? 0 : nodeSize(node))) {
var parent = node.parentNode;
if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") return false;
off = domIndex(node) + (dir < 0 ? 0 : 1);
node = parent;
} else if (node.nodeType == 1) {
var child = node.childNodes[off + (dir < 0 ? -1 : 0)];
if (child.nodeType == 1 && child.contentEditable == "false") {
if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection) off += dir;else return false;
} else {
node = child;
off = dir < 0 ? nodeSize(node) : 0;
}
} else {
return false;
}
}
}
function nodeSize(node) {
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
}
function textNodeBefore$1(node, offset) {
for (;;) {
if (node.nodeType == 3 && offset) return node;
if (node.nodeType == 1 && offset > 0) {
if (node.contentEditable == "false") return null;
node = node.childNodes[offset - 1];
offset = nodeSize(node);
} else if (node.parentNode && !hasBlockDesc(node)) {
offset = domIndex(node);
node = node.parentNode;
} else {
return null;
}
}
}
function textNodeAfter$1(node, offset) {
for (;;) {
if (node.nodeType == 3 && offset < node.nodeValue.length) return node;
if (node.nodeType == 1 && offset < node.childNodes.length) {
if (node.contentEditable == "false") return null;
node = node.childNodes[offset];
offset = 0;
} else if (node.parentNode && !hasBlockDesc(node)) {
offset = domIndex(node) + 1;
node = node.parentNode;
} else {
return null;
}
}
}
function isOnEdge(node, offset, parent) {
for (var atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;) {
if (node == parent) return true;
var index = domIndex(node);
node = node.parentNode;
if (!node) return false;
atStart = atStart && index == 0;
atEnd = atEnd && index == nodeSize(node);
}
}
function hasBlockDesc(dom) {
var desc;
for (var cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break;
return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom);
}
var selectionCollapsed = function selectionCollapsed(domSel) {
return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset);
};
function keyEvent(keyCode, key) {
var event = document.createEvent("Event");
event.initEvent("keydown", true, true);
event.keyCode = keyCode;
event.key = event.code = key;
return event;
}
function deepActiveElement(doc) {
var elt = doc.activeElement;
while (elt && elt.shadowRoot) elt = elt.shadowRoot.activeElement;
return elt;
}
function caretFromPoint(doc, x, y) {
if (doc.caretPositionFromPoint) {
try {
var pos = doc.caretPositionFromPoint(x, y);
if (pos) return {
node: pos.offsetNode,
offset: Math.min(nodeSize(pos.offsetNode), pos.offset)
};
} catch (_) {}
}
if (doc.caretRangeFromPoint) {
var range = doc.caretRangeFromPoint(x, y);
if (range) return {
node: range.startContainer,
offset: Math.min(nodeSize(range.startContainer), range.startOffset)
};
}
}
var nav = typeof navigator != "undefined" ? navigator : null;
var doc = typeof document != "undefined" ? document : null;
var agent = nav && nav.userAgent || "";
var ie_edge = /Edge\/(\d+)/.exec(agent);
var ie_upto10 = /MSIE \d/.exec(agent);
var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent);
var ie = !!(ie_upto10 || ie_11up || ie_edge);
var ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0;
var gecko = !ie && /gecko\/(\d+)/i.test(agent);
gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1];
var _chrome = !ie && /Chrome\/(\d+)/.exec(agent);
var chrome = !!_chrome;
var chrome_version = _chrome ? +_chrome[1] : 0;
var safari = !ie && !!nav && /Apple Computer/.test(nav.vendor);
var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
var mac = ios || (nav ? /Mac/.test(nav.platform) : false);
var windows = nav ? /Win/.test(nav.platform) : false;
var android = /Android \d/.test(agent);
var webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
function windowRect(doc) {
var vp = doc.defaultView && doc.defaultView.visualViewport;
if (vp) return {
left: 0,
right: vp.width,
top: 0,
bottom: vp.height
};
return {
left: 0,
right: doc.documentElement.clientWidth,
top: 0,
bottom: doc.documentElement.clientHeight
};
}
function getSide(value, side) {
return typeof value == "number" ? value : value[side];
}
function clientRect(node) {
var rect = node.getBoundingClientRect();
var scaleX = rect.width / node.offsetWidth || 1;
var scaleY = rect.height / node.offsetHeight || 1;
return {
left: rect.left,
right: rect.left + node.clientWidth * scaleX,
top: rect.top,
bottom: rect.top + node.clientHeight * scaleY
};
}
function scrollRectIntoView(view, rect, startDOM) {
var scrollThreshold = view.someProp("scrollThreshold") || 0,
scrollMargin = view.someProp("scrollMargin") || 5;
var doc = view.dom.ownerDocument;
for (var parent = startDOM || view.dom;;) {
if (!parent) break;
if (parent.nodeType != 1) {
parent = parentNode(parent);
continue;
}
var elt = parent;
var atTop = elt == doc.body;
var bounding = atTop ? windowRect(doc) : clientRect(elt);
var moveX = 0,
moveY = 0;
if (rect.top < bounding.top + getSide(scrollThreshold, "top")) moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top"));else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom");
if (rect.left < bounding.left + getSide(scrollThreshold, "left")) moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left"));else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) moveX = rect.right - bounding.right + getSide(scrollMargin, "right");
if (moveX || moveY) {
if (atTop) {
doc.defaultView.scrollBy(moveX, moveY);
} else {
var startX = elt.scrollLeft,
startY = elt.scrollTop;
if (moveY) elt.scrollTop += moveY;
if (moveX) elt.scrollLeft += moveX;
var dX = elt.scrollLeft - startX,
dY = elt.scrollTop - startY;
rect = {
left: rect.left - dX,
top: rect.top - dY,
right: rect.right - dX,
bottom: rect.bottom - dY
};
}
}
var pos = atTop ? "fixed" : getComputedStyle(parent).position;
if (/^(fixed|sticky)$/.test(pos)) break;
parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
}
}
function storeScrollPos(view) {
var rect = view.dom.getBoundingClientRect(),
startY = Math.max(0, rect.top);
var refDOM, refTop;
for (var x = (rect.left + rect.right) / 2, y = startY + 1; y < Math.min(innerHeight, rect.bottom); y += 5) {
var dom = view.root.elementFromPoint(x, y);
if (!dom || dom == view.dom || !view.dom.contains(dom)) continue;
var localRect = dom.getBoundingClientRect();
if (localRect.top >= startY - 20) {
refDOM = dom;
refTop = localRect.top;
break;
}
}
return {
refDOM: refDOM,
refTop: refTop,
stack: scrollStack(view.dom)
};
}
function scrollStack(dom) {
var stack = [],
doc = dom.ownerDocument;
for (var cur = dom; cur; cur = parentNode(cur)) {
stack.push({
dom: cur,
top: cur.scrollTop,
left: cur.scrollLeft
});
if (dom == doc) break;
}
return stack;
}
function resetScrollPos(_ref) {
var refDOM = _ref.refDOM,
refTop = _ref.refTop,
stack = _ref.stack;
var newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0;
restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop);
}
function restoreScrollStack(stack, dTop) {
for (var i = 0; i < stack.length; i++) {
var _stack$i = stack[i],
dom = _stack$i.dom,
top = _stack$i.top,
left = _stack$i.left;
if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop;
if (dom.scrollLeft != left) dom.scrollLeft = left;
}
}
var preventScrollSupported = null;
function focusPreventScroll(dom) {
if (dom.setActive) return dom.setActive();
if (preventScrollSupported) return dom.focus(preventScrollSupported);
var stored = scrollStack(dom);
dom.focus(preventScrollSupported == null ? {
get preventScroll() {
preventScrollSupported = {
preventScroll: true
};
return true;
}
} : undefined);
if (!preventScrollSupported) {
preventScrollSupported = false;
restoreScrollStack(stored, 0);
}
}
function findOffsetInNode(node, coords) {
var closest,
dxClosest = 2e8,
coordsClosest,
offset = 0;
var rowBot = coords.top,
rowTop = coords.top;
var firstBelow, coordsBelow;
for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
var rects = void 0;
if (child.nodeType == 1) rects = child.getClientRects();else if (child.nodeType == 3) rects = textRange(child).getClientRects();else continue;
for (var i = 0; i < rects.length; i++) {
var rect = rects[i];
if (rect.top <= rowBot && rect.bottom >= rowTop) {
rowBot = Math.max(rect.bottom, rowBot);
rowTop = Math.min(rect.top, rowTop);
var dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0;
if (dx < dxClosest) {
closest = child;
dxClosest = dx;
coordsClosest = dx && closest.nodeType == 3 ? {
left: rect.right < coords.left ? rect.right : rect.left,
top: coords.top
} : coords;
if (child.nodeType == 1 && dx) offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
continue;
}
} else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
firstBelow = child;
coordsBelow = {
left: Math.max(rect.left, Math.min(rect.right, coords.left)),
top: rect.top
};
}
if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) offset = childIndex + 1;
}
}
if (!closest && firstBelow) {
closest = firstBelow;
coordsClosest = coordsBelow;
dxClosest = 0;
}
if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest);
if (!closest || dxClosest && closest.nodeType == 1) return {
node: node,
offset: offset
};
return findOffsetInNode(closest, coordsClosest);
}
function findOffsetInText(node, coords) {
var len = node.nodeValue.length;
var range = document.createRange(),
result;
for (var i = 0; i < len; i++) {
range.setEnd(node, i + 1);
range.setStart(node, i);
var rect = singleRect(range, 1);
if (rect.top == rect.bottom) continue;
if (inRect(coords, rect)) {
result = {
node: node,
offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)
};
break;
}
}
range.detach();
return result || {
node: node,
offset: 0
};
}
function inRect(coords, rect) {
return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1;
}
function targetKludge(dom, coords) {
var parent = dom.parentNode;
if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) return parent;
return dom;
}
function posFromElement(view, elt, coords) {
var _findOffsetInNode = findOffsetInNode(elt, coords),
node = _findOffsetInNode.node,
offset = _findOffsetInNode.offset,
bias = -1;
if (node.nodeType == 1 && !node.firstChild) {
var rect = node.getBoundingClientRect();
bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
}
return view.docView.posFromDOM(node, offset, bias);
}
function posFromCaret(view, node, offset, coords) {
var outsideBlock = -1;
for (var cur = node, sawBlock = false;;) {
if (cur == view.dom) break;
var desc = view.docView.nearestDesc(cur, true),
rect = void 0;
if (!desc) return null;
if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
sawBlock = true;
}
if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) {
var before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2;
return before ? desc.posBefore : desc.posAfter;
}
}
cur = desc.dom.parentNode;
}
return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset, -1);
}
function elementFromPoint(element, coords, box) {
var len = element.childNodes.length;
if (len && box.top < box.bottom) {
for (var startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {
var child = element.childNodes[i];
if (child.nodeType == 1) {
var rects = child.getClientRects();
for (var j = 0; j < rects.length; j++) {
var rect = rects[j];
if (inRect(coords, rect)) return elementFromPoint(child, coords, rect);
}
}
if ((i = (i + 1) % len) == startI) break;
}
}
return element;
}
function _posAtCoords(view, coords) {
var doc = view.dom.ownerDocument,
node,
offset = 0;
var caret = caretFromPoint(doc, coords.left, coords.top);
if (caret) {
node = caret.node;
offset = caret.offset;
}
var elt = (view.root.elementFromPoint ? view.root : doc).elementFromPoint(coords.left, coords.top);
var pos;
if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {
var box = view.dom.getBoundingClientRect();
if (!inRect(coords, box)) return null;
elt = elementFromPoint(view.dom, coords, box);
if (!elt) return null;
}
if (safari) {
for (var p = elt; node && p; p = parentNode(p)) if (p.draggable) node = undefined;
}
elt = targetKludge(elt, coords);
if (node) {
if (gecko && node.nodeType == 1) {
offset = Math.min(offset, node.childNodes.length);
if (offset < node.childNodes.length) {
var next = node.childNodes[offset],
_box;
if (next.nodeName == "IMG" && (_box = next.getBoundingClientRect()).right <= coords.left && _box.bottom > coords.top) offset++;
}
}
var prev;
if (webkit && offset && node.nodeType == 1 && (prev = node.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) offset--;
if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) pos = view.state.doc.content.size;else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") pos = posFromCaret(view, node, offset, coords);
}
if (pos == null) pos = posFromElement(view, elt, coords);
var desc = view.docView.nearestDesc(elt, true);
return {
pos: pos,
inside: desc ? desc.posAtStart - desc.border : -1
};
}
function nonZero(rect) {
return rect.top < rect.bottom || rect.left < rect.right;
}
function singleRect(target, bias) {
var rects = target.getClientRects();
if (rects.length) {
var first = rects[bias < 0 ? 0 : rects.length - 1];
if (nonZero(first)) return first;
}
return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect();
}
var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
function _coordsAtPos(view, pos, side) {
var _view$docView$domFrom = view.docView.domFromPos(pos, side < 0 ? -1 : 1),
node = _view$docView$domFrom.node,
offset = _view$docView$domFrom.offset,
atom = _view$docView$domFrom.atom;
var supportEmptyRange = webkit || gecko;
if (node.nodeType == 3) {
if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
var rect = singleRect(textRange(node, offset, offset), side);
if (gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {
var rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1);
if (rectBefore.top == rect.top) {
var rectAfter = singleRect(textRange(node, offset, offset + 1), -1);
if (rectAfter.top != rect.top) return flattenV(rectAfter, rectAfter.left < rectBefore.left);
}
}
return rect;
} else {
var from = offset,
to = offset,
takeSide = side < 0 ? 1 : -1;
if (side < 0 && !offset) {
to++;
takeSide = -1;
} else if (side >= 0 && offset == node.nodeValue.length) {
from--;
takeSide = 1;
} else if (side < 0) {
from--;
} else {
to++;
}
return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
}
}
var $dom = view.state.doc.resolve(pos - (atom || 0));
if (!$dom.parent.inlineContent) {
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
var before = node.childNodes[offset - 1];
if (before.nodeType == 1) return flattenH(before.getBoundingClientRect(), false);
}
if (atom == null && offset < nodeSize(node)) {
var after = node.childNodes[offset];
if (after.nodeType == 1) return flattenH(after.getBoundingClientRect(), true);
}
return flattenH(node.getBoundingClientRect(), side >= 0);
}
if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
var _before = node.childNodes[offset - 1];
var target = _before.nodeType == 3 ? textRange(_before, nodeSize(_before) - (supportEmptyRange ? 0 : 1)) : _before.nodeType == 1 && (_before.nodeName != "BR" || !_before.nextSibling) ? _before : null;
if (target) return flattenV(singleRect(target, 1), false);
}
if (atom == null && offset < nodeSize(node)) {
var _after = node.childNodes[offset];
while (_after.pmViewDesc && _after.pmViewDesc.ignoreForCoords) _after = _after.nextSibling;
var _target = !_after ? null : _after.nodeType == 3 ? textRange(_after, 0, supportEmptyRange ? 0 : 1) : _after.nodeType == 1 ? _after : null;
if (_target) return flattenV(singleRect(_target, -1), true);
}
return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0);
}
function flattenV(rect, left) {
if (rect.width == 0) return rect;
var x = left ? rect.left : rect.right;
return {
top: rect.top,
bottom: rect.bottom,
left: x,
right: x
};
}
function flattenH(rect, top) {
if (rect.height == 0) return rect;
var y = top ? rect.top : rect.bottom;
return {
top: y,
bottom: y,
left: rect.left,
right: rect.right
};
}
function withFlushedState(view, state, f) {
var viewState = view.state,
active = view.root.activeElement;
if (viewState != state) view.updateState(state);
if (active != view.dom) view.focus();
try {
return f();
} finally {
if (viewState != state) view.updateState(viewState);
if (active != view.dom && active) active.focus();
}
}
function endOfTextblockVertical(view, state, dir) {
var sel = state.selection;
var $pos = dir == "up" ? sel.$from : sel.$to;
return withFlushedState(view, state, function () {
var _view$docView$domFrom2 = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1),
dom = _view$docView$domFrom2.node;
for (;;) {
var nearest = view.docView.nearestDesc(dom, true);
if (!nearest) break;
if (nearest.node.isBlock) {
dom = nearest.contentDOM || nearest.dom;
break;
}
dom = nearest.dom.parentNode;
}
var coords = _coordsAtPos(view, $pos.pos, 1);
for (var child = dom.firstChild; child; child = child.nextSibling) {
var boxes = void 0;
if (child.nodeType == 1) boxes = child.getClientRects();else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects();else continue;
for (var i = 0; i < boxes.length; i++) {
var box = boxes[i];
if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) return false;
}
}
return true;
});
}
var maybeRTL = /[\u0590-\u08ac]/;
function endOfTextblockHorizontal(view, state, dir) {
var $head = state.selection.$head;
if (!$head.parent.isTextblock) return false;
var offset = $head.parentOffset,
atStart = !offset,
atEnd = offset == $head.parent.content.size;
var sel = view.domSelection();
if (!sel) return $head.pos == $head.start() || $head.pos == $head.end();
if (!maybeRTL.test($head.parent.textContent) || !sel.modify) return dir == "left" || dir == "backward" ? atStart : atEnd;
return withFlushedState(view, state, function () {
var _view$domSelectionRan = view.domSelectionRange(),
oldNode = _view$domSelectionRan.focusNode,
oldOff = _view$domSelectionRan.focusOffset,
anchorNode = _view$domSelectionRan.anchorNode,
anchorOffset = _view$domSelectionRan.anchorOffset;
var oldBidiLevel = sel.caretBidiLevel;
sel.modify("move", dir, "character");
var parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom;
var _view$domSelectionRan2 = view.domSelectionRange(),
newNode = _view$domSelectionRan2.focusNode,
newOff = _view$domSelectionRan2.focusOffset;
var result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff;
try {
sel.collapse(anchorNode, anchorOffset);
if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) sel.extend(oldNode, oldOff);
} catch (_) {}
if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel;
return result;
});
}
var cachedState = null;
var cachedDir = null;
var cachedResult = false;
function _endOfTextblock(view, state, dir) {
if (cachedState == state && cachedDir == dir) return cachedResult;
cachedState = state;
cachedDir = dir;
return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir);
}
var NOT_DIRTY = 0,
CHILD_DIRTY = 1,
CONTENT_DIRTY = 2,
NODE_DIRTY = 3;
var ViewDesc = function () {
function ViewDesc(parent, children, dom, contentDOM) {
_classCallCheck(this, ViewDesc);
this.parent = parent;
this.children = children;
this.dom = dom;
this.contentDOM = contentDOM;
this.dirty = NOT_DIRTY;
dom.pmViewDesc = this;
}
_createClass(ViewDesc, [{
key: "matchesWidget",
value: function matchesWidget(widget) {
return false;
}
}, {
key: "matchesMark",
value: function matchesMark(mark) {
return false;
}
}, {
key: "matchesNode",
value: function matchesNode(node, outerDeco, innerDeco) {
return false;
}
}, {
key: "matchesHack",
value: function matchesHack(nodeName) {
return false;
}
}, {
key: "parseRule",
value: function parseRule() {
return null;
}
}, {
key: "stopEvent",
value: function stopEvent(event) {
return false;
}
}, {
key: "size",
get: function get() {
var size = 0;
for (var i = 0; i < this.children.length; i++) size += this.children[i].size;
return size;
}
}, {
key: "border",
get: function get() {
return 0;
}
}, {
key: "destroy",
value: function destroy() {
this.parent = undefined;
if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = undefined;
for (var i = 0; i < this.children.length; i++) this.children[i].destroy();
}
}, {
key: "posBeforeChild",
value: function posBeforeChild(child) {
for (var i = 0, pos = this.posAtStart;; i++) {
var cur = this.children[i];
if (cur == child) return pos;
pos += cur.size;
}
}
}, {
key: "posBefore",
get: function get() {
return this.parent.posBeforeChild(this);
}
}, {
key: "posAtStart",
get: function get() {
return this.parent ? this.parent.posBeforeChild(this) + this.border : 0;
}
}, {
key: "posAfter",
get: function get() {
return this.posBefore + this.size;
}
}, {
key: "posAtEnd",
get: function get() {
return this.posAtStart + this.size - 2 * this.border;
}
}, {
key: "localPosFromDOM",
value: function localPosFromDOM(dom, offset, bias) {
if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {
if (bias < 0) {
var domBefore, desc;
if (dom == this.contentDOM) {
domBefore = dom.childNodes[offset - 1];
} else {
while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
domBefore = dom.previousSibling;
}
while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling;
return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart;
} else {
var domAfter, _desc;
if (dom == this.contentDOM) {
domAfter = dom.childNodes[offset];
} else {
while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
domAfter = dom.nextSibling;
}
while (domAfter && !((_desc = domAfter.pmViewDesc) && _desc.parent == this)) domAfter = domAfter.nextSibling;
return domAfter ? this.posBeforeChild(_desc) : this.posAtEnd;
}
}
var atEnd;
if (dom == this.dom && this.contentDOM) {
atEnd = offset > domIndex(this.contentDOM);
} else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
atEnd = dom.compareDocumentPosition(this.contentDOM) & 2;
} else if (this.dom.firstChild) {
if (offset == 0) for (var search = dom;; search = search.parentNode) {
if (search == this.dom) {
atEnd = false;
break;
}
if (search.previousSibling) break;
}
if (atEnd == null && offset == dom.childNodes.length) for (var _search = dom;; _search = _search.parentNode) {
if (_search == this.dom) {
atEnd = true;
break;
}
if (_search.nextSibling) break;
}
}
return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart;
}
}, {
key: "nearestDesc",
value: function nearestDesc(dom) {
var onlyNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
for (var first = true, cur = dom; cur; cur = cur.parentNode) {
var desc = this.getDesc(cur),
nodeDOM = void 0;
if (desc && (!onlyNodes || desc.node)) {
if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) first = false;else return desc;
}
}
}
}, {
key: "getDesc",
value: function getDesc(dom) {
var desc = dom.pmViewDesc;
for (var cur = desc; cur; cur = cur.parent) if (cur == this) return desc;
}
}, {
key: "posFromDOM",
value: function posFromDOM(dom, offset, bias) {
for (var scan = dom; scan; scan = scan.parentNode) {
var desc = this.getDesc(scan);
if (desc) return desc.localPosFromDOM(dom, offset, bias);
}
return -1;
}
}, {
key: "descAt",
value: function descAt(pos) {
for (var i = 0, offset = 0; i < this.children.length; i++) {
var child = this.children[i],
end = offset + child.size;
if (offset == pos && end != offset) {
while (!child.border && child.children.length) {
for (var _i = 0; _i < child.children.length; _i++) {
var inner = child.children[_i];
if (inner.size) {
child = inner;
break;
}
}
}
return child;
}
if (pos < end) return child.descAt(pos - offset - child.border);
offset = end;
}
}
}, {
key: "domFromPos",
value: function domFromPos(pos, side) {
if (!this.contentDOM) return {
node: this.dom,
offset: 0,
atom: pos + 1
};
var i = 0,
offset = 0;
for (var curPos = 0; i < this.children.length; i++) {
var child = this.children[i],
end = curPos + child.size;
if (end > pos || child instanceof TrailingHackViewDesc) {
offset = pos - curPos;
break;
}
curPos = end;
}
if (offset) return this.children[i].domFromPos(offset - this.children[i].border, side);
for (var prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--) {}
if (side <= 0) {
var _prev,
enter = true;
for (;; i--, enter = false) {
_prev = i ? this.children[i - 1] : null;
if (!_prev || _prev.dom.parentNode == this.contentDOM) break;
}
if (_prev && side && enter && !_prev.border && !_prev.domAtom) return _prev.domFromPos(_prev.size, side);
return {
node: this.contentDOM,
offset: _prev ? domIndex(_prev.dom) + 1 : 0
};
} else {
var next,
_enter = true;
for (;; i++, _enter = false) {
next = i < this.children.length ? this.children[i] : null;
if (!next || next.dom.parentNode == this.contentDOM) break;
}
if (next && _enter && !next.border && !next.domAtom) return next.domFromPos(0, side);
return {
node: this.contentDOM,
offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length
};
}
}
}, {
key: "parseRange",
value: function parseRange(from, to) {
var base = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
if (this.children.length == 0) return {
node: this.contentDOM,
from: from,
to: to,
fromOffset: 0,
toOffset: this.contentDOM.childNodes.length
};
var fromOffset = -1,
toOffset = -1;
for (var offset = base, i = 0;; i++) {
var child = this.children[i],
end = offset + child.size;
if (fromOffset == -1 && from <= end) {
var childBase = offset + child.border;
if (from >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) return child.parseRange(from, to, childBase);
from = offset;
for (var j = i; j > 0; j--) {
var 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;
}
if (fromOffset > -1 && (end > to || i == this.children.length - 1)) {
to = end;
for (var _j = i + 1; _j < this.children.length; _j++) {
var 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;
}
offset = end;
}
return {
node: this.contentDOM,
from: from,
to: to,
fromOffset: fromOffset,
toOffset: toOffset
};
}
}, {
key: "emptyChildAt",
value: function emptyChildAt(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);
}
}, {
key: "domAfterPos",
value: function domAfterPos(pos) {
var _this$domFromPos = this.domFromPos(pos, 0),
node = _this$domFromPos.node,
offset = _this$domFromPos.offset;
if (node.nodeType != 1 || offset == node.childNodes.length) throw new RangeError("No node after pos " + pos);
return node.childNodes[offset];
}
}, {
key: "setSelection",
value: function setSelection(anchor, head, view) {
var force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var from = Math.min(anchor, head),
to = Math.max(anchor, head);
for (var i = 0, offset = 0; i < this.children.length; i++) {
var child = this.children[i],
end = offset + child.size;
if (from > offset && to < end) return child.setSelection(anchor - offset - child.border, head - offset - child.border, view, force);
offset = end;
}
var anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1);
var headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1);
var domSel = view.root.getSelection();
var selRange = view.domSelectionRange();
var brKludge = false;
if ((gecko || safari) && anchor == head) {
var _anchorDOM = anchorDOM,
node = _anchorDOM.node,
_offset = _anchorDOM.offset;
if (node.nodeType == 3) {
brKludge = !!(_offset && node.nodeValue[_offset - 1] == "\n");
if (brKludge && _offset == node.nodeValue.length) {
for (var scan = node, after; scan; scan = scan.parentNode) {
if (after = scan.nextSibling) {
if (after.nodeName == "BR") anchorDOM = headDOM = {
node: after.parentNode,
offset: domIndex(after) + 1
};
break;
}
var desc = scan.pmViewDesc;
if (desc && desc.node && desc.node.isBlock) break;
}
}
} else {
var prev = node.childNodes[_offset - 1];
brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false");
}
}
if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode.nodeType == 1) {
var _after2 = selRange.focusNode.childNodes[selRange.focusOffset];
if (_after2 && _after2.contentEditable == "false") force = true;
}
if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) return;
var domSelExtended = false;
if ((domSel.extend || anchor == head) && !(brKludge && gecko)) {
domSel.collapse(anchorDOM.node, anchorDOM.offset);
try {
if (anchor != head) domSel.extend(headDOM.node, headDOM.offset);
domSelExtended = true;
} catch (_) {}
}
if (!domSelExtended) {
if (anchor > head) {
var tmp = anchorDOM;
anchorDOM = headDOM;
headDOM = tmp;
}
var range = document.createRange();
range.setEnd(headDOM.node, headDOM.offset);
range.setStart(anchorDOM.node, anchorDOM.offset);
domSel.removeAllRanges();
domSel.addRange(range);
}
}
}, {
key: "ignoreMutation",
value: function ignoreMutation(mutation) {
return !this.contentDOM && mutation.type != "selection";
}
}, {
key: "contentLost",
get: function get() {
return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM);
}
}, {
key: "markDirty",
value: function markDirty(from, to) {
for (var offset = 0, i = 0; i < this.children.length; i++) {
var child = this.children[i],
end = offset + child.size;
if (offset == end ? from <= end && to >= offset : from < end && to > offset) {
var startInside = offset + child.border,
endInside = end - child.border;
if (from >= startInside && to <= endInside) {
this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY;
if (from == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY;else child.markDirty(from - startInside, to - startInside);
return;
} else {
child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY;
}
}
offset = end;
}
this.dirty = CONTENT_DIRTY;
}
}, {
key: "markParentsDirty",
value: function markParentsDirty() {
var level = 1;
for (var node = this.parent; node; node = node.parent, level++) {
var dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY;
if (node.dirty < dirty) node.dirty = dirty;
}
}
}, {
key: "domAtom",
get: function get() {
return false;
}
}, {
key: "ignoreForCoords",
get: function get() {
return false;
}
}, {
key: "ignoreForSelection",
get: function get() {
return false;
}
}, {
key: "isText",
value: function isText(text) {
return false;
}
}]);
return ViewDesc;
}();
var WidgetViewDesc = function (_ViewDesc) {
_inherits(WidgetViewDesc, _ViewDesc);
var _super = _createSuper(WidgetViewDesc);
function WidgetViewDesc(parent, widget, view, pos) {
var _this;
_classCallCheck(this, WidgetViewDesc);
var self,
dom = widget.type.toDOM;
if (typeof dom == "function") dom = dom(view, function () {
if (!self) return pos;
if (self.parent) return self.parent.posBeforeChild(self);
});
if (!widget.type.spec.raw) {
if (dom.nodeType != 1) {
var wrap = document.createElement("span");
wrap.appendChild(dom);
dom = wrap;
}
dom.contentEditable = "false";
dom.classList.add("ProseMirror-widget");
}
_this = _super.call(this, parent, [], dom, null);
_this.widget = widget;
_this.widget = widget;
self = _assertThisInitialized(_this);
return _this;
}
_createClass(WidgetViewDesc, [{
key: "matchesWidget",
value: function matchesWidget(widget) {
return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type);
}
}, {
key: "parseRule",
value: function parseRule() {
return {
ignore: true
};
}
}, {
key: "stopEvent",
value: function stopEvent(event) {
var stop = this.widget.spec.stopEvent;
return stop ? stop(event) : false;
}
}, {
key: "ignoreMutation",
value: function ignoreMutation(mutation) {
return mutation.type != "selection" || this.widget.spec.ignoreSelection;
}
}, {
key: "destroy",
value: function destroy() {
this.widget.type.destroy(this.dom);
_get(_getPrototypeOf(WidgetViewDesc.prototype), "destroy", this).call(this);
}
}, {
key: "domAtom",
get: function get() {
return true;
}
}, {
key: "ignoreForSelection",
get: function get() {
return !!this.widget.type.spec.relaxedSide;
}
}, {
key: "side",
get: function get() {
return this.widget.type.side;
}
}]);
return WidgetViewDesc;
}(ViewDesc);
var CompositionViewDesc = function (_ViewDesc2) {
_inherits(CompositionViewDesc, _ViewDesc2);
var _super2 = _createSuper(CompositionViewDesc);
function CompositionViewDesc(parent, dom, textDOM, text) {
var _this2;
_classCallCheck(this, CompositionViewDesc);
_this2 = _super2.call(this, parent, [], dom, null);
_this2.textDOM = textDOM;
_this2.text = text;
return _this2;
}
_createClass(CompositionViewDesc, [{
key: "size",
get: function get() {
return this.text.length;
}
}, {
key: "localPosFromDOM",
value: function localPosFromDOM(dom, offset) {
if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0);
return this.posAtStart + offset;
}
}, {
key: "domFromPos",
value: function domFromPos(pos) {
return {
node: this.textDOM,
offset: pos
};
}
}, {
key: "ignoreMutation",
value: function ignoreMutation(mut) {
return mut.type === 'characterData' && mut.target.nodeValue == mut.oldValue;
}
}]);
return CompositionViewDesc;
}(ViewDesc);
var MarkViewDesc = function (_ViewDesc3) {
_inherits(MarkViewDesc, _ViewDes