UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

217 lines 8.54 kB
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } var NODE_NAME_ATTRIBUTE = 'data-prosemirror-node-name'; /** * Tracks block DOM nodes that intersect the browser viewport. The browser owns clipping and * visibility decisions; this helper only translates observer targets back to PM positions. */ export var observeSurfaceViewport = function observeSurfaceViewport(view, onChange) { var win = view.dom.ownerDocument.defaultView; if (!win || typeof win.IntersectionObserver === 'undefined') { return { update: function update() {}, destroy: function destroy() {} }; } var targets = new Map(); var visibleTargets = new Set(); var previousPositions = []; var previousDoc = view.state.doc; var destroyed = false; var resolvePosition = function resolvePosition(element) { try { var domPosition = view.posAtDOM(element, 0); var nodeName = element.getAttribute(NODE_NAME_ATTRIBUTE); var directNode = view.state.doc.nodeAt(domPosition); if (directNode !== null && directNode !== void 0 && directNode.isBlock && directNode.type.name === nodeName && view.nodeDOM(domPosition) === element) { return domPosition; } var $position = view.state.doc.resolve(domPosition); for (var depth = $position.depth; depth > 0; depth--) { var node = $position.node(depth); if (!node.isBlock || node.type.name !== nodeName) { continue; } var position = $position.before(depth); var nodeDOM = view.nodeDOM(position); if (nodeDOM === element || nodeDOM instanceof Node && (nodeDOM.contains(element) || element.contains(nodeDOM))) { return position; } } return undefined; } catch (_unused) { return undefined; } }; var getVisiblePositions = function getVisiblePositions() { var positions = new Set(); visibleTargets.forEach(function (element) { var _targets$get; var position = (_targets$get = targets.get(element)) === null || _targets$get === void 0 ? void 0 : _targets$get.position; if (position !== undefined) { positions.add(position); } }); return Array.from(positions).sort(function (first, second) { return first - second; }); }; var emit = function emit() { if (destroyed) { return; } var positions = getVisiblePositions(); if (positions.length !== previousPositions.length || positions.some(function (position, index) { return position !== previousPositions[index]; })) { previousPositions = positions; onChange(positions); } }; var intersectionObserver = new win.IntersectionObserver(function (entries) { var changed = false; var _iterator = _createForOfIteratorHelper(entries), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var entry = _step.value; var element = entry.target; var target = targets.get(element); if (!target || !view.dom.contains(element)) { continue; } var isIntersecting = entry.isIntersecting; if (target.isIntersecting !== isIntersecting) { target.isIntersecting = isIntersecting; if (isIntersecting) { target.position = resolvePosition(element); if (target.position !== undefined) { visibleTargets.add(element); } else { target.isIntersecting = false; } } else { visibleTargets.delete(element); } changed = true; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (changed) { emit(); } }, { root: null, threshold: 0 }); var removeTarget = function removeTarget(element) { var target = targets.get(element); if (!target) { return; } targets.delete(element); visibleTargets.delete(element); intersectionObserver.unobserve(element); }; var observeElement = function observeElement(element) { var _view$state$schema$no; var nodeName = element.getAttribute(NODE_NAME_ATTRIBUTE); if (element === view.dom || !nodeName || !((_view$state$schema$no = view.state.schema.nodes[nodeName]) !== null && _view$state$schema$no !== void 0 && _view$state$schema$no.isBlock) || !view.dom.contains(element)) { return; } if (targets.has(element)) { return; } targets.set(element, { isIntersecting: false }); intersectionObserver.observe(element); }; var observeSubtree = function observeSubtree(node) { if (node.nodeType !== Node.ELEMENT_NODE) { return; } var element = node; observeElement(element); var descendants = element.querySelectorAll("[".concat(NODE_NAME_ATTRIBUTE, "]")); for (var index = 0; index < descendants.length; index++) { observeElement(descendants[index]); } }; var unobserveSubtree = function unobserveSubtree(node) { if (node.nodeType !== Node.ELEMENT_NODE) { return; } var element = node; removeTarget(element); var descendants = element.querySelectorAll("[".concat(NODE_NAME_ATTRIBUTE, "]")); for (var index = 0; index < descendants.length; index++) { removeTarget(descendants[index]); } }; var mutationObserver = new win.MutationObserver(function (records) { var removedVisibleTarget = false; var _iterator2 = _createForOfIteratorHelper(records), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var record = _step2.value; for (var index = 0; index < record.removedNodes.length; index++) { var node = record.removedNodes[index]; if (node.nodeType === Node.ELEMENT_NODE) { if (view.dom.contains(node)) { continue; } var before = visibleTargets.size; unobserveSubtree(node); removedVisibleTarget || (removedVisibleTarget = before !== visibleTargets.size); } } for (var _index = 0; _index < record.addedNodes.length; _index++) { observeSubtree(record.addedNodes[_index]); } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } if (removedVisibleTarget) { emit(); } }); var initialTargets = view.dom.querySelectorAll("[".concat(NODE_NAME_ATTRIBUTE, "]")); for (var index = 0; index < initialTargets.length; index++) { observeElement(initialTargets[index]); } mutationObserver.observe(view.dom, { childList: true, subtree: true }); return { update: function update() { if (previousDoc !== view.state.doc) { previousDoc = view.state.doc; visibleTargets.forEach(function (element) { var target = targets.get(element); if (target) { target.position = resolvePosition(element); } }); emit(); } }, destroy: function destroy() { destroyed = true; mutationObserver.disconnect(); intersectionObserver.disconnect(); targets.clear(); visibleTargets.clear(); } }; };