UNPKG

upfront-editable

Version:
251 lines (202 loc) 9.33 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 _jquery = _interopRequireDefault(require("jquery")); var nodeType = _interopRequireWildcard(require("./node-type")); var content = _interopRequireWildcard(require("./content")); var _highlightText = _interopRequireDefault(require("./highlight-text")); var _spellcheckService = _interopRequireDefault(require("./plugins/highlighting/spellcheck-service")); var _whitespaceHighlighting = _interopRequireDefault(require("./plugins/highlighting/whitespace-highlighting")); var _textHighlighting = _interopRequireDefault(require("./plugins/highlighting/text-highlighting")); var _matchCollection = _interopRequireDefault(require("./plugins/highlighting/match-collection")); var _highlightSupport = _interopRequireDefault(require("./highlight-support")); 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; } var Highlighting = /*#__PURE__*/function () { function Highlighting(editable, configuration, spellcheckConfig) { (0, _classCallCheck2["default"])(this, Highlighting); this.editable = editable; this.win = editable.win; this.focusedEditableHost = undefined; this.currentlyCheckedEditableHost = undefined; this.timeout = {}; var defaultConfig = { checkOnInit: false, checkOnFocus: false, checkOnChange: true, // unbounce rate in ms before calling the spellcheck service after changes throttle: 1000, // remove highlights after a change if the cursor is inside a highlight removeOnCorrection: true, spellcheck: { marker: '<span class="highlight-spellcheck"></span>', throttle: 1000, spellcheckService: function spellcheckService() {} }, whitespace: { marker: '<span class="highlight-whitespace"></span>' } }; this.config = _jquery["default"].extend(true, defaultConfig, configuration); var spellcheckService = this.config.spellcheck.spellcheckService; var spellcheckMarker = this.config.spellcheck.marker; var whitespaceMarker = this.config.whitespace.marker; var spellcheckMarkerNode = _highlightSupport["default"].createMarkerNode(spellcheckMarker, 'spellcheck', this.win); var whitespaceMarkerNode = _highlightSupport["default"].createMarkerNode(whitespaceMarker, 'spellcheck', this.win); this.spellcheckService = new _spellcheckService["default"](spellcheckService); this.spellcheck = new _textHighlighting["default"](spellcheckMarkerNode); this.whitespace = new _whitespaceHighlighting["default"](whitespaceMarkerNode); this.setupListeners(); } // Events // ------ (0, _createClass2["default"])(Highlighting, [{ key: "setupListeners", value: function setupListeners() { if (this.config.checkOnFocus) { this.editable.on('focus', _jquery["default"].proxy(this, 'onFocus')); this.editable.on('blur', _jquery["default"].proxy(this, 'onBlur')); } if (this.config.checkOnChange || this.config.removeOnCorrection) { this.editable.on('change', _jquery["default"].proxy(this, 'onChange')); } if (this.config.checkOnInit) { this.editable.on('init', _jquery["default"].proxy(this, 'onInit')); } } }, { key: "onInit", value: function onInit(editableHost) { this.highlight(editableHost); } }, { key: "onFocus", value: function onFocus(editableHost) { if (this.focusedEditableHost !== editableHost) { this.focusedEditableHost = editableHost; this.editableHasChanged(editableHost); } } }, { key: "onBlur", value: function onBlur(editableHost) { if (this.focusedEditableHost === editableHost) { this.focusedEditableHost = undefined; } } }, { key: "onChange", value: function onChange(editableHost) { if (this.config.checkOnChange) { this.editableHasChanged(editableHost, this.config.throttle); } if (this.config.removeOnCorrection) { this.removeHighlightsAtCursor(editableHost); } } // Manage Highlights // ----------------- }, { key: "editableHasChanged", value: function editableHasChanged(editableHost, throttle) { var _this = this; if (this.timeout.id && this.timeout.editableHost === editableHost) { clearTimeout(this.timeout.id); } var timeoutId = setTimeout(function () { _this.highlight(editableHost); _this.timeout = {}; }, throttle || 0); this.timeout = { id: timeoutId, editableHost: editableHost }; } }, { key: "highlight", value: function highlight(editableHost) { var _this2 = this; var text = _highlightText["default"].extractText(editableHost); // getSpellcheck this.spellcheckService.check(text, function (err, misspelledWords) { if (err) { return; } // refresh the text text = _highlightText["default"].extractText(editableHost); var matchCollection = new _matchCollection["default"](); var matches = _this2.spellcheck.findMatches(text, misspelledWords); matchCollection.addMatches('spellcheck', matches); matches = _this2.whitespace.findMatches(text); matchCollection.addMatches('whitespace', matches); _this2.safeHighlightMatches(editableHost, matchCollection.matches); }); } // Calls highlightMatches internally but ensures // that the selection stays the same }, { key: "safeHighlightMatches", value: function safeHighlightMatches(editableHost, matches) { var _this3 = this; var selection = this.editable.getSelection(editableHost); if (selection) { selection.retainVisibleSelection(function () { _this3.highlightMatches(editableHost, matches); }); } else { this.highlightMatches(editableHost, matches); } if (this.editable.dispatcher) { this.editable.dispatcher.notify('spellcheckUpdated', editableHost); } } }, { key: "highlightMatches", value: function highlightMatches(editableHost, matches) { // Remove old highlights this.removeHighlights(editableHost); // Create new highlights if (matches && matches.length > 0) { // const span = this.createMarkerNode() _highlightText["default"].highlightMatches(editableHost, matches); } } }, { key: "removeHighlights", value: function removeHighlights(editableHost) { (0, _jquery["default"])(editableHost).find('[data-highlight="spellcheck"]').each(function (index, elem) { content.unwrap(elem); }); } }, { key: "removeHighlightsAtCursor", value: function removeHighlightsAtCursor(editableHost) { var selection = this.editable.getSelection(editableHost); if (selection && selection.isCursor) { var elementAtCursor = selection.range.startContainer; if (elementAtCursor.nodeType === nodeType.textNode) { elementAtCursor = elementAtCursor.parentNode; } var wordId; do { if (elementAtCursor === editableHost) return; var highlightType = elementAtCursor.getAttribute('data-highlight'); if (highlightType === 'spellcheck') { wordId = elementAtCursor.getAttribute('data-word-id'); break; } } while (elementAtCursor = elementAtCursor.parentNode); if (wordId) { selection.retainVisibleSelection(function () { (0, _jquery["default"])(editableHost).find("[data-word-id=".concat(wordId, "]")).each(function (index, elem) { content.unwrap(elem); }); }); } } } }]); return Highlighting; }(); exports["default"] = Highlighting; module.exports = exports.default;