UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

187 lines • 9.02 kB
import * as tslib_1 from "tslib"; import OpenIcon from '@atlaskit/icon/glyph/editor/open'; import UnlinkIcon from '@atlaskit/icon/glyph/editor/unlink'; import * as React from 'react'; import { PureComponent } from 'react'; import PanelTextInput from '../PanelTextInput'; import { Separator, Container, FloatingToolbar, ToolbarButton } from './styles'; import { normalizeUrl } from '../../plugins/hyperlink/utils'; import RecentSearch from '../RecentSearch'; var TEXT_NODE = 3; var HyperlinkEdit = (function (_super) { tslib_1.__extends(HyperlinkEdit, _super); function HyperlinkEdit() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { unlinkable: true, editorFocused: false, inputActive: false, active: false, showToolbarPanel: false, }; _this.setInputActive = function () { _this.setState({ inputActive: true, }); }; _this.resetInputActive = function () { _this.setState({ inputActive: false, }); }; /** * Dynamic offsets for hyperlink editing popup * because we need to show it next to cursor even without clear target for popup. */ _this.adjustPosition = function (position) { var pluginState = _this.props.pluginState; if (!pluginState.active) { var offsetParent = _this.getOffsetParent(); if (!offsetParent) { return position; } var coordinates = pluginState.getCoordinates(_this.props.editorView, offsetParent); if (position.left) { position.left = coordinates.left; } if (position.top) { position.top = coordinates.top; } if (position.bottom) { position.bottom = coordinates.bottom; } if (position.right) { position.right = coordinates.right; } } return position; }; // ED-1323 `onBlur` covers all the use cases (click outside, tab, etc) for this issue _this.handleOnBlur = function () { var _a = _this.props, editorView = _a.editorView, pluginState = _a.pluginState; var _b = _this.state, href = _b.href, text = _b.text; if (editorView.state.selection.empty && !pluginState.active) { pluginState.hideLinkPanel(); } else if (!href || href.length === 0) { pluginState.removeLink(editorView); } else { if (text && pluginState.text !== text) { pluginState.updateLinkText(text, editorView); _this.setState({ text: '' }); } if (href && pluginState.href !== href) { pluginState.updateLink({ href: href }, editorView); } } _this.resetInputActive(); }; _this.handleUnlink = function () { _this.props.pluginState.removeLink(_this.props.editorView); }; _this.handlePluginStateChange = function (pluginState) { var inputActive = _this.state.inputActive; var hrefNotPreset = pluginState.active && (!pluginState.href || pluginState.href.length === 0); _this.setState({ active: pluginState.active, target: pluginState.element, activeElement: pluginState.activeElement, href: pluginState.href, oldText: pluginState.text, oldHref: pluginState.href, textInputValue: pluginState.text, editorFocused: pluginState.editorFocused, inputActive: hrefNotPreset || inputActive, showToolbarPanel: pluginState.showToolbarPanel, }); }; _this.updateHref = function (href) { _this.setState({ href: href }); }; _this.updateText = function (text) { _this.setState({ text: text }); }; _this.updateLinkText = function (text) { if (text && text.length > 0 && text !== _this.state.oldText) { var _a = _this.props, editorView = _a.editorView, pluginState = _a.pluginState; pluginState.updateLinkText(text, editorView); _this.setState({ text: '' }); } }; _this.updateLinkHref = function (href) { var _a = _this.props, editorView = _a.editorView, pluginState = _a.pluginState; if (_this.state.oldHref) { pluginState.updateLink({ href: href }, editorView); } else { pluginState.addLink({ href: href }, editorView); } editorView.focus(); }; return _this; } HyperlinkEdit.prototype.componentDidMount = function () { this.props.pluginState.subscribe(this.handlePluginStateChange); }; HyperlinkEdit.prototype.componentWillUnmount = function () { this.props.pluginState.unsubscribe(this.handlePluginStateChange); }; HyperlinkEdit.prototype.getOffsetParent = function () { var popupTarget = this.getPopupTarget(); return this.props.popupsMountPoint ? this.props.popupsMountPoint.offsetParent : popupTarget && popupTarget.offsetParent; }; HyperlinkEdit.prototype.getPopupTarget = function () { var _a = this.state, target = _a.target, activeElement = _a.activeElement; var popupTarget = target; if (!popupTarget && activeElement) { popupTarget = activeElement.nodeType === TEXT_NODE ? activeElement.parentElement : activeElement; } return popupTarget; }; HyperlinkEdit.prototype.render = function () { var _a = this.state, href = _a.href, oldHref = _a.oldHref, unlinkable = _a.unlinkable, active = _a.active, editorFocused = _a.editorFocused, inputActive = _a.inputActive, showToolbarPanel = _a.showToolbarPanel; var popupTarget = this.getPopupTarget(); if (!popupTarget) { return null; } if ((active || showToolbarPanel) && (editorFocused || inputActive)) { var showOpenButton = !!oldHref; var showUnlinkButton = unlinkable && active && oldHref; return (React.createElement(FloatingToolbar, { target: popupTarget, offset: [0, 3], fitWidth: 230, onPositionCalculated: this.adjustPosition, popupsMountPoint: this.props.popupsMountPoint, popupsBoundariesElement: this.props.popupsBoundariesElement }, React.createElement(Container, null, !showOpenButton ? null : React.createElement(ToolbarButton, { href: href, target: "_blank", title: "Open link in new tab", iconBefore: React.createElement(OpenIcon, { label: "Open link" }) }), !showUnlinkButton ? null : React.createElement(ToolbarButton, { title: "Unlink", onClick: this.handleUnlink, iconBefore: React.createElement(UnlinkIcon, { label: "Unlink" }) }), !showUnlinkButton ? null : React.createElement(Separator, null), this.renderInput()))); } else { return null; } }; HyperlinkEdit.prototype.renderInput = function () { var _a = this.state, href = _a.href, oldHref = _a.oldHref, text = _a.text, oldText = _a.oldText; var _b = this.props, editorView = _b.editorView, pluginState = _b.pluginState, activityProvider = _b.activityProvider; var normalizedOldText = oldText && normalizeUrl(oldText); // insert new link with recently viewed dropdown if (activityProvider && !oldHref) { return (React.createElement(RecentSearch, { editorView: editorView, pluginState: pluginState, activityProvider: activityProvider })); } // edit link text if (normalizedOldText && href === normalizedOldText) { return (React.createElement(PanelTextInput, { placeholder: "Text to display", defaultValue: !text && href === normalizedOldText ? '' : text, onSubmit: this.updateLinkText, onChange: this.updateText, onMouseDown: this.setInputActive, onBlur: this.handleOnBlur })); } // edit link href when text has not been set return (React.createElement(PanelTextInput, { placeholder: "Paste link", autoFocus: !href || href.length === 0, defaultValue: href, onSubmit: this.updateLinkHref, onChange: this.updateHref, onMouseDown: this.setInputActive, onBlur: this.handleOnBlur })); }; return HyperlinkEdit; }(PureComponent)); export default HyperlinkEdit; //# sourceMappingURL=index.js.map