Link.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import PropTypes from 'prop-types';
  2. import React from 'react';
  3. import Icon from '../../Icon/Icon';
  4. import TooltipEntity from '../decorators/TooltipEntity';
  5. const LINK_ICON = <Icon name="link" />;
  6. const BROKEN_LINK_ICON = <Icon name="warning" />;
  7. const MAIL_ICON = <Icon name="mail" />;
  8. const getEmailAddress = (mailto) => mailto.replace('mailto:', '').split('?')[0];
  9. const getPhoneNumber = (tel) => tel.replace('tel:', '').split('?')[0];
  10. const getDomainName = (url) => url.replace(/(^\w+:|^)\/\//, '').split('/')[0];
  11. // Determines how to display the link based on its type: page, mail, anchor or external.
  12. export const getLinkAttributes = (data) => {
  13. const url = data.url || null;
  14. let icon;
  15. let label;
  16. if (!url) {
  17. icon = BROKEN_LINK_ICON;
  18. label = gettext('Broken link');
  19. } else if (data.id) {
  20. icon = LINK_ICON;
  21. label = url;
  22. } else if (url.startsWith('mailto:')) {
  23. icon = MAIL_ICON;
  24. label = getEmailAddress(url);
  25. } else if (url.startsWith('tel:')) {
  26. icon = LINK_ICON;
  27. label = getPhoneNumber(url);
  28. } else if (url.startsWith('#')) {
  29. icon = LINK_ICON;
  30. label = url;
  31. } else {
  32. icon = LINK_ICON;
  33. label = getDomainName(url);
  34. }
  35. return {
  36. url,
  37. icon,
  38. label,
  39. };
  40. };
  41. /**
  42. * Represents a link within the editor's content.
  43. */
  44. const Link = (props) => {
  45. const { entityKey, contentState } = props;
  46. const data = contentState.getEntity(entityKey).getData();
  47. return <TooltipEntity {...props} {...getLinkAttributes(data)} />;
  48. };
  49. Link.propTypes = {
  50. entityKey: PropTypes.string.isRequired,
  51. contentState: PropTypes.object.isRequired,
  52. };
  53. export default Link;