UNPKG

upfront-editable

Version:
358 lines (309 loc) 13.2 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 _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); require("rangy/lib/rangy-textrange"); var _jquery = _interopRequireDefault(require("jquery")); var _cursor = _interopRequireDefault(require("./cursor")); var content = _interopRequireWildcard(require("./content")); var parser = _interopRequireWildcard(require("./parser")); var _config = _interopRequireDefault(require("./config")); var _highlightSupport = _interopRequireDefault(require("./highlight-support")); var _highlightText = _interopRequireDefault(require("./highlight-text")); 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; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } 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; } } /** * The Selection module provides a cross-browser abstraction layer for range * and selection. * * @module core * @submodule selection */ /** * Class that represents a selection and provides functionality to access or * modify the selection. * * @class Selection * @constructor */ var Selection = /*#__PURE__*/function (_Cursor) { (0, _inherits2["default"])(Selection, _Cursor); var _super = _createSuper(Selection); function Selection() { var _this; (0, _classCallCheck2["default"])(this, Selection); _this = _super.apply(this, arguments); delete _this.isCursor; _this.isSelection = true; return _this; } // Get the text inside the selection. (0, _createClass2["default"])(Selection, [{ key: "text", value: function text() { return this.range.toString(); } // Get the html inside the selection. }, { key: "html", value: function html() { return this.range.toHtml(); } }, { key: "isAllSelected", value: function isAllSelected() { return parser.isBeginningOfHost(this.host, this.range.startContainer, this.range.startOffset) && parser.isTextEndOfHost(this.host, this.range.endContainer, this.range.endOffset); } }, { key: "getTextRange", value: function getTextRange() { return this.range.toCharacterRange(this.host); } // Get the ClientRects of this selection. // Use this if you want more precision than getBoundingClientRect can give. }, { key: "getRects", value: function getRects() { // consider: translate into absolute positions // just like Cursor#getCoordinates() return this.range.nativeRange.getClientRects(); } }, { key: "link", value: function link(href) { var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var $link = (0, _jquery["default"])(this.createElement(_config["default"].linkMarkup.name, _config["default"].linkMarkup.attribs)); if (href) attrs.href = href; $link.attr(attrs); this.forceWrap($link[0]); } }, { key: "unlink", value: function unlink() { this.removeFormatting(_config["default"].linkMarkup.name); } }, { key: "toggleLink", value: function toggleLink(href, attrs) { var links = this.getTagsByName(_config["default"].linkMarkup.name); if (links.length >= 1) { var firstLink = links[0]; if (this.isExactSelection(firstLink, 'visible')) { this.unlink(); } else { this.expandTo(firstLink); } } else { this.link(href, attrs); } } // Manually add a highlight // Note: the current code does not work with newlines (LP) }, { key: "highlight", value: function highlight(_ref) { var highlightId = _ref.highlightId; var textBefore = this.textBefore(); var currentTextContent = this.text(); var marker = '<span class="highlight-comment"></span>'; var markerNode = _highlightSupport["default"].createMarkerNode(marker, this.win); markerNode.setAttribute('data-match', currentTextContent); var match = { startIndex: textBefore.length, endIndex: textBefore.length + currentTextContent.length, match: currentTextContent, marker: markerNode }; // Note: highlighting won't retain the selection _highlightText["default"].highlightMatches(this.host, [match]); } // toggle('<em>') }, { key: "toggle", value: function toggle(elem) { elem = this.adoptElement(elem); this.range = content.toggleTag(this.host, this.range, elem); this.setSelection(); } }, { key: "toggleCustom", value: function toggleCustom(_ref2) { var tagName = _ref2.tagName, attributes = _ref2.attributes; var customElem = this.createElement(tagName, attributes); this.toggle(customElem); } }, { key: "makeCustom", value: function makeCustom(_ref3) { var tagName = _ref3.tagName, attributes = _ref3.attributes; var customElem = this.createElement(tagName, attributes); this.forceWrap(customElem); } }, { key: "makeBold", value: function makeBold() { var bold = this.createElement(_config["default"].boldMarkup.name, _config["default"].boldMarkup.attribs); this.forceWrap(bold); } }, { key: "toggleBold", value: function toggleBold() { var bold = this.createElement(_config["default"].boldMarkup.name, _config["default"].boldMarkup.attribs); this.toggle(bold); } }, { key: "giveEmphasis", value: function giveEmphasis() { var em = this.createElement(_config["default"].italicMarkup.name, _config["default"].italicMarkup.attribs); this.forceWrap(em); } }, { key: "toggleEmphasis", value: function toggleEmphasis() { var em = this.createElement(_config["default"].italicMarkup.name, _config["default"].italicMarkup.attribs); this.toggle(em); } }, { key: "makeUnderline", value: function makeUnderline() { var u = this.createElement(_config["default"].underlineMarkup.name, _config["default"].underlineMarkup.attribs); this.forceWrap(u); } }, { key: "toggleUnderline", value: function toggleUnderline() { var u = this.createElement(_config["default"].underlineMarkup.name, _config["default"].underlineMarkup.attribs); this.toggle(u); } }, { key: "insertCharacter", value: function insertCharacter(character) { var cursor = this.deleteContent(); var textNode = cursor.createTextNode(character); cursor.insertBefore(textNode); cursor.setSelection(); return cursor; } // Surround the selection with characters like quotes. // // @param {String} E.g. '«' // @param {String} E.g. '»' }, { key: "surround", value: function surround(startCharacter, endCharacter) { this.range = content.surround(this.host, this.range, startCharacter, endCharacter); this.setSelection(); } }, { key: "removeSurround", value: function removeSurround(startCharacter, endCharacter) { this.range = content.deleteCharacter(this.host, this.range, startCharacter); this.range = content.deleteCharacter(this.host, this.range, endCharacter); this.setSelection(); } }, { key: "removeChars", value: function removeChars() { var chars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; for (var i = 0; i < chars.length; i++) { var _char = chars[i]; this.range = content.deleteCharacter(this.host, this.range, _char); } this.setSelection(); } }, { key: "toggleSurround", value: function toggleSurround(startCharacter, endCharacter) { if (this.containsString(startCharacter) && this.containsString(endCharacter)) { this.removeSurround(startCharacter, endCharacter); } else { this.surround(startCharacter, endCharacter); } } // @param {String} tagName. E.g. 'a' to remove all links; if undefined, remove all. }, { key: "removeFormatting", value: function removeFormatting(tagName) { this.range = content.removeFormatting(this.host, this.range, tagName); this.setSelection(); } // Delete the contents inside the range. After that the selection will be a // cursor. // // @return Cursor instance }, { key: "deleteContent", value: function deleteContent() { this.range.deleteContents(); return new _cursor["default"](this.host, this.range); } // Expand the current selection. // // @param {DOM Node} }, { key: "expandTo", value: function expandTo(elem) { this.range = content.expandTo(this.host, this.range, elem); this.setSelection(); } // Collapse the selection at the beginning of the selection // // @return Cursor instance }, { key: "collapseAtBeginning", value: function collapseAtBeginning(elem) { this.range.collapse(true); this.setSelection(); return new _cursor["default"](this.host, this.range); } // Collapse the selection at the end of the selection // // @return Cursor instance }, { key: "collapseAtEnd", value: function collapseAtEnd(elem) { this.range.collapse(false); this.setSelection(); return new _cursor["default"](this.host, this.range); } // Wrap the selection with the specified tag. If any other tag with // the same tagName is affecting the selection this tag will be // remove first. }, { key: "forceWrap", value: function forceWrap(elem) { elem = this.adoptElement(elem); this.range = content.forceWrap(this.host, this.range, elem); this.setSelection(); } // Check if the selection is the same as the elements contents. // // @method isExactSelection // @param {DOM Node} // @param {flag: undefined or 'visible'} if 'visible' is passed // whitespaces at the beginning or end of the selection will // be ignored. // @return {Boolean} }, { key: "isExactSelection", value: function isExactSelection(elem, onlyVisible) { return content.isExactSelection(this.range, elem, onlyVisible); } // Check if the selection contains the passed string. // // @method containsString // @return {Boolean} }, { key: "containsString", value: function containsString(str) { return content.containsString(this.range, str); } // Delete all occurrences of the specified character from the // selection. }, { key: "deleteCharacter", value: function deleteCharacter(character) { this.range = content.deleteCharacter(this.host, this.range, character); this.setSelection(); } }]); return Selection; }(_cursor["default"]); exports["default"] = Selection; module.exports = exports.default;