@wordpress/format-library
Version:
Format library for the WordPress editor.
174 lines (168 loc) • 5.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.link = void 0;
var _clipboard = _interopRequireDefault(require("@react-native-clipboard/clipboard"));
var _i18n = require("@wordpress/i18n");
var _element = require("@wordpress/element");
var _components = require("@wordpress/components");
var _blockEditor = require("@wordpress/block-editor");
var _richText = require("@wordpress/rich-text");
var _url = require("@wordpress/url");
var _icons = require("@wordpress/icons");
var _modal = _interopRequireDefault(require("./modal"));
var _utils = require("./utils");
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const name = 'core/link';
const link = exports.link = {
name,
title: (0, _i18n.__)('Link'),
tagName: 'a',
className: null,
attributes: {
url: 'href',
target: 'target',
rel: 'rel'
},
edit: (0, _components.withSpokenMessages)(class LinkEdit extends _element.Component {
constructor() {
super(...arguments);
this.addLink = this.addLink.bind(this);
this.stopAddingLink = this.stopAddingLink.bind(this);
this.onRemoveFormat = this.onRemoveFormat.bind(this);
this.getURLFromClipboard = this.getURLFromClipboard.bind(this);
this.state = {
addingLink: false
};
}
addLink() {
const {
value,
onChange
} = this.props;
const text = (0, _richText.getTextContent)((0, _richText.slice)(value));
if (text && (0, _url.isURL)(text) && (0, _utils.isValidHref)(text)) {
const newValue = (0, _richText.applyFormat)(value, {
type: name,
attributes: {
url: text
}
});
newValue.start = newValue.end;
newValue.activeFormats = [];
onChange({
...newValue,
needsSelectionUpdate: true
});
} else {
this.setState({
addingLink: true
});
this.getURLFromClipboard();
}
}
stopAddingLink() {
this.setState({
addingLink: false,
clipboardURL: undefined
});
}
getLinkSelection() {
const {
value,
isActive
} = this.props;
const startFormat = (0, _richText.getActiveFormat)(value, 'core/link');
// If the link isn't selected, get the link manually by looking around the cursor
// TODO: handle partly selected links.
if (startFormat && (0, _richText.isCollapsed)(value) && isActive) {
let startIndex = value.start;
let endIndex = value.end;
while (value.formats[startIndex]?.find(format => format?.type === startFormat.type)) {
startIndex--;
}
endIndex++;
while (value.formats[endIndex]?.find(format => format?.type === startFormat.type)) {
endIndex++;
}
return {
...value,
start: startIndex + 1,
end: endIndex
};
}
return value;
}
onRemoveFormat() {
const {
onChange,
speak,
value
} = this.props;
const startFormat = (0, _richText.getActiveFormat)(value, 'core/link');
// Before we try to remove anything we check if there is something at the caret position to remove.
if ((0, _richText.isCollapsed)(value) && startFormat === undefined) {
return;
}
const linkSelection = this.getLinkSelection();
onChange((0, _richText.removeFormat)(linkSelection, name));
speak((0, _i18n.__)('Link removed.'), 'assertive');
}
async getURLFromClipboard() {
const clipboardText = await _clipboard.default.getString();
if (!clipboardText) {
return;
}
// Check if pasted text is URL.
if (!(0, _url.isURL)(clipboardText)) {
return;
}
this.setState({
clipboardURL: clipboardText
});
}
render() {
const {
isActive,
activeAttributes,
onChange
} = this.props;
const linkSelection = this.getLinkSelection();
// If no URL is set and we have a clipboard URL let's use it.
if (!activeAttributes.url && this.state.clipboardURL) {
activeAttributes.url = this.state.clipboardURL;
}
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_modal.default, {
isVisible: this.state.addingLink,
isActive: isActive,
activeAttributes: activeAttributes,
onClose: this.stopAddingLink,
onChange: onChange,
onRemove: this.onRemoveFormat,
value: linkSelection
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.RichTextToolbarButton, {
name: "link",
icon: _icons.link,
title: (0, _i18n.__)('Link'),
onClick: this.addLink,
isActive: isActive,
shortcutType: "primary",
shortcutCharacter: "k"
})]
});
}
})
};
//# sourceMappingURL=index.native.js.map