UNPKG

upfront-editable

Version:
164 lines (136 loc) 6.38 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _rangy = _interopRequireDefault(require("rangy")); var parser = _interopRequireWildcard(require("./parser")); var _rangeContainer = _interopRequireDefault(require("./range-container")); var _cursor = _interopRequireDefault(require("./cursor")); var _selection = _interopRequireDefault(require("./selection")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * The SelectionWatcher module watches for selection changes inside * of editable blocks. * * @module core * @submodule selectionWatcher */ var SelectionWatcher = /*#__PURE__*/function () { function SelectionWatcher(dispatcher, win) { (0, _classCallCheck2["default"])(this, SelectionWatcher); this.dispatcher = dispatcher; this.win = win || window; this.rangySelection = undefined; this.currentSelection = undefined; this.currentRange = undefined; } /** * Updates the internal selection pointer to the current rangy selection. * Returns true if no exception occurred. */ (0, _createClass2["default"])(SelectionWatcher, [{ key: "syncSelection", value: function syncSelection() { // it is possible that rangy has a problem with the nativeSelection try { this.rangySelection = _rangy["default"].getSelection(this.win); } catch (err) { return false; } return true; } /** * Return a RangeContainer if the current selection is within an editable * otherwise return an empty RangeContainer */ }, { key: "getRangeContainer", value: function getRangeContainer() { var successfulSync = this.syncSelection(); // rangeCount is 0 or 1 in all browsers except firefox // firefox can work with multiple ranges // (on a mac hold down the command key to select multiple ranges) if (this.rangySelection.rangeCount && successfulSync) { var range = this.rangySelection.getRangeAt(0); var hostNode = parser.getHost(range.commonAncestorContainer); if (hostNode) return new _rangeContainer["default"](hostNode, range); } // return an empty range container return new _rangeContainer["default"](); } /** * Gets a fresh RangeContainer with the current selection or cursor. * * @return RangeContainer instance */ }, { key: "getFreshRange", value: function getFreshRange() { return this.getRangeContainer(); } /** * Gets a fresh RangeContainer with the current selection or cursor. * * @return Either a Cursor or Selection instance or undefined if * there is neither a selection or cursor. */ }, { key: "getFreshSelection", value: function getFreshSelection() { var range = this.getRangeContainer(); return range.isCursor ? range.getCursor(this.win) : range.getSelection(this.win); } /** * Get the selection set by the last selectionChanged event. * Sometimes the event does not fire fast enough and the selection * you get is not the one the user sees. * In those cases use #getFreshSelection() * * @return Either a Cursor or Selection instance or undefined if * there is neither a selection or cursor. */ }, { key: "getSelection", value: function getSelection() { return this.currentSelection; } }, { key: "forceCursor", value: function forceCursor() { var range = this.getRangeContainer(); return range.forceCursor(); } }, { key: "selectionChanged", value: function selectionChanged() { var newRange = this.getRangeContainer(); if (newRange.isDifferentFrom(this.currentRange)) { var lastSelection = this.currentSelection; this.currentRange = newRange; // empty selection or cursor if (lastSelection) { if (lastSelection.isCursor && !this.currentRange.isCursor) { this.dispatcher.notify('cursor', lastSelection.host); } else if (lastSelection.isSelection && !this.currentRange.isSelection) { this.dispatcher.notify('selection', lastSelection.host); } } // set new selection or cursor and fire event if (this.currentRange.isCursor) { this.currentSelection = new _cursor["default"](this.currentRange.host, this.currentRange.range); this.dispatcher.notify('cursor', this.currentSelection.host, this.currentSelection); } else if (this.currentRange.isSelection) { this.currentSelection = new _selection["default"](this.currentRange.host, this.currentRange.range); this.dispatcher.notify('selection', this.currentSelection.host, this.currentSelection); } else { this.currentSelection = undefined; } } } }]); return SelectionWatcher; }(); exports["default"] = SelectionWatcher; module.exports = exports.default;