@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
187 lines • 9.02 kB
JavaScript
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