8
0

utils.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module link/utils
  7. */
  8. import { upperFirst } from 'lodash-es';
  9. const ATTRIBUTE_WHITESPACES = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g; // eslint-disable-line no-control-regex
  10. const SAFE_URL = /^(?:(?:https?|ftps?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/i;
  11. /**
  12. * Returns `true` if a given view node is the link element.
  13. *
  14. * @param {module:engine/view/node~Node} node
  15. * @returns {Boolean}
  16. */
  17. export function isLinkElement( node ) {
  18. return node.is( 'attributeElement' ) && !!node.getCustomProperty( 'link' );
  19. }
  20. /**
  21. * Creates link {@link module:engine/view/attributeelement~AttributeElement} with the provided `href` attribute.
  22. *
  23. * @param {String} href
  24. * @returns {module:engine/view/attributeelement~AttributeElement}
  25. */
  26. export function createLinkElement( href, writer ) {
  27. // Priority 5 - https://github.com/ckeditor/ckeditor5-link/issues/121.
  28. const linkElement = writer.createAttributeElement( 'a', { href }, { priority: 5 } );
  29. writer.setCustomProperty( 'link', true, linkElement );
  30. return linkElement;
  31. }
  32. /**
  33. * Returns a safe URL based on a given value.
  34. *
  35. * A URL is considered safe if it is safe for the user (does not contain any malicious code).
  36. *
  37. * If a URL is considered unsafe, a simple `"#"` is returned.
  38. *
  39. * @protected
  40. * @param {*} url
  41. * @returns {String} Safe URL.
  42. */
  43. export function ensureSafeUrl( url ) {
  44. url = String( url );
  45. return isSafeUrl( url ) ? url : '#';
  46. }
  47. // Checks whether the given URL is safe for the user (does not contain any malicious code).
  48. //
  49. // @param {String} url URL to check.
  50. function isSafeUrl( url ) {
  51. const normalizedUrl = url.replace( ATTRIBUTE_WHITESPACES, '' );
  52. return normalizedUrl.match( SAFE_URL );
  53. }
  54. /**
  55. * Returns the {@link module:link/link~LinkConfig#decorators `config.link.decorators`} configuration processed
  56. * to respect the locale of the editor, i.e. to display the {@link module:link/link~LinkDecoratorManualDefinition label}
  57. * in the correct language.
  58. *
  59. * **Note**: Only the few most commonly used labels are translated automatically. Other labels should be manually
  60. * translated in the {@link module:link/link~LinkConfig#decorators `config.link.decorators`} configuration.
  61. *
  62. * @param {module:utils/locale~Locale#t} t shorthand for {@link module:utils/locale~Locale#t Locale#t}
  63. * @param {Array.<module:link/link~LinkDecoratorDefinition>} The decorator reference
  64. * where the label values should be localized.
  65. * @returns {Array.<module:link/link~LinkDecoratorDefinition>}
  66. */
  67. export function getLocalizedDecorators( t, decorators ) {
  68. const localizedDecoratorsLabels = {
  69. 'Open in a new tab': t( 'Open in a new tab' ),
  70. 'Downloadable': t( 'Downloadable' )
  71. };
  72. decorators.forEach( decorator => {
  73. if ( decorator.label && localizedDecoratorsLabels[ decorator.label ] ) {
  74. decorator.label = localizedDecoratorsLabels[ decorator.label ];
  75. }
  76. return decorator;
  77. } );
  78. return decorators;
  79. }
  80. /**
  81. * Converts an object with defined decorators to a normalized array of decorators. The `id` key is added for each decorator and
  82. * is used as the attribute's name in the model.
  83. *
  84. * @param {Object.<String, module:link/link~LinkDecoratorDefinition>} decorators
  85. * @returns {Array.<module:link/link~LinkDecoratorDefinition>}
  86. */
  87. export function normalizeDecorators( decorators ) {
  88. const retArray = [];
  89. if ( decorators ) {
  90. for ( const [ key, value ] of Object.entries( decorators ) ) {
  91. const decorator = Object.assign(
  92. {},
  93. value,
  94. { id: `link${ upperFirst( key ) }` }
  95. );
  96. retArray.push( decorator );
  97. }
  98. }
  99. return retArray;
  100. }