link.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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/link
  7. */
  8. import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
  9. import LinkEditing from './linkediting';
  10. import LinkUI from './linkui';
  11. import AutoLink from './autolink';
  12. /**
  13. * The link plugin.
  14. *
  15. * This is a "glue" plugin that loads the {@link module:link/linkediting~LinkEditing link editing feature}
  16. * and {@link module:link/linkui~LinkUI link UI feature}.
  17. *
  18. * @extends module:core/plugin~Plugin
  19. */
  20. export default class Link extends Plugin {
  21. /**
  22. * @inheritDoc
  23. */
  24. static get requires() {
  25. return [ LinkEditing, LinkUI, AutoLink ];
  26. }
  27. /**
  28. * @inheritDoc
  29. */
  30. static get pluginName() {
  31. return 'Link';
  32. }
  33. }
  34. /**
  35. * The configuration of the {@link module:link/link~Link} feature.
  36. *
  37. * Read more in {@link module:link/link~LinkConfig}.
  38. *
  39. * @member {module:link/link~LinkConfig} module:core/editor/editorconfig~EditorConfig#link
  40. */
  41. /**
  42. * The configuration of the {@link module:link/link~Link link feature}.
  43. *
  44. * ClassicEditor
  45. * .create( editorElement, {
  46. * link: ... // Link feature configuration.
  47. * } )
  48. * .then( ... )
  49. * .catch( ... );
  50. *
  51. * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
  52. * @interface LinkConfig
  53. */
  54. /**
  55. * When set, the editor will add the given protocol to the link when the user creates a link without one.
  56. * For example, when the user is creating a link and types `ckeditor.com` in the link form input, during link submission
  57. * the editor will automatically add the `http://` protocol, so the link will look as follows: `http://ckeditor.com`.
  58. *
  59. * The feature also provides email address auto-detection. When you submit `hello@example.com`,
  60. * the plugin will automatically change it to `mailto:hello@example.com`.
  61. *
  62. * ClassicEditor
  63. * .create( editorElement, {
  64. * link: {
  65. * defaultProtocol: 'http://'
  66. * }
  67. * } )
  68. * .then( ... )
  69. * .catch( ... );
  70. *
  71. * **NOTE:** If no configuration is provided, the editor will not auto-fix the links.
  72. *
  73. * @member {String} module:link/link~LinkConfig#defaultProtocol
  74. */
  75. /**
  76. * When set to `true`, the `target="blank"` and `rel="noopener noreferrer"` attributes are automatically added to all external links
  77. * in the editor. "External links" are all links in the editor content starting with `http`, `https`, or `//`.
  78. *
  79. * ClassicEditor
  80. * .create( editorElement, {
  81. * link: {
  82. * addTargetToExternalLinks: true
  83. * }
  84. * } )
  85. * .then( ... )
  86. * .catch( ... );
  87. *
  88. * Internally, this option activates a predefined {@link module:link/link~LinkConfig#decorators automatic link decorator}
  89. * that extends all external links with the `target` and `rel` attributes.
  90. *
  91. * **Note**: To control the `target` and `rel` attributes of specific links in the edited content, a dedicated
  92. * {@link module:link/link~LinkDecoratorManualDefinition manual} decorator must be defined in the
  93. * {@link module:link/link~LinkConfig#decorators `config.link.decorators`} array. In such scenario,
  94. * the `config.link.addTargetToExternalLinks` option should remain `undefined` or `false` to not interfere with the manual decorator.
  95. *
  96. * It is possible to add other {@link module:link/link~LinkDecoratorAutomaticDefinition automatic}
  97. * or {@link module:link/link~LinkDecoratorManualDefinition manual} link decorators when this option is active.
  98. *
  99. * More information about decorators can be found in the {@link module:link/link~LinkConfig#decorators decorators configuration}
  100. * reference.
  101. *
  102. * @default false
  103. * @member {Boolean} module:link/link~LinkConfig#addTargetToExternalLinks
  104. */
  105. /**
  106. * Decorators provide an easy way to configure and manage additional link attributes in the editor content. There are
  107. * two types of link decorators:
  108. *
  109. * * {@link module:link/link~LinkDecoratorAutomaticDefinition Automatic} – They match links against pre–defined rules and
  110. * manage their attributes based on the results.
  111. * * {@link module:link/link~LinkDecoratorManualDefinition Manual} – They allow users to control link attributes individually,
  112. * using the editor UI.
  113. *
  114. * Link decorators are defined as objects with key-value pairs, where the key is the name provided for a given decorator and the
  115. * value is the decorator definition.
  116. *
  117. * The name of the decorator also corresponds to the {@glink framework/guides/architecture/editing-engine#text-attributes text attribute}
  118. * in the model. For instance, the `isExternal` decorator below is represented as a `linkIsExternal` attribute in the model.
  119. *
  120. * ClassicEditor
  121. * .create( editorElement, {
  122. * link: {
  123. * decorators: {
  124. * isExternal: {
  125. * mode: 'automatic',
  126. * callback: url => url.startsWith( 'http://' ),
  127. * attributes: {
  128. * target: '_blank',
  129. * rel: 'noopener noreferrer'
  130. * }
  131. * },
  132. * isDownloadable: {
  133. * mode: 'manual',
  134. * label: 'Downloadable',
  135. * attributes: {
  136. * download: 'file.png',
  137. * }
  138. * },
  139. * // ...
  140. * }
  141. * }
  142. * } )
  143. * .then( ... )
  144. * .catch( ... );
  145. *
  146. * To learn more about the configuration syntax, check out the {@link module:link/link~LinkDecoratorAutomaticDefinition automatic}
  147. * and {@link module:link/link~LinkDecoratorManualDefinition manual} decorator option reference.
  148. *
  149. * **Warning:** Currently, link decorators work independently of one another and no conflict resolution mechanism exists.
  150. * For example, configuring the `target` attribute using both an automatic and a manual decorator at the same time could end up with
  151. * quirky results. The same applies if multiple manual or automatic decorators were defined for the same attribute.
  152. *
  153. * **Note**: Since the `target` attribute management for external links is a common use case, there is a predefined automatic decorator
  154. * dedicated for that purpose which can be enabled by turning a single option on. Check out the
  155. * {@link module:link/link~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}
  156. * configuration description to learn more.
  157. *
  158. * See also the {@glink features/link#custom-link-attributes-decorators link feature guide} for more information.
  159. *
  160. * @member {Object.<String, module:link/link~LinkDecoratorDefinition>} module:link/link~LinkConfig#decorators
  161. */
  162. /**
  163. * A link decorator definition. Two types implement this defition:
  164. *
  165. * * {@link module:link/link~LinkDecoratorManualDefinition}
  166. * * {@link module:link/link~LinkDecoratorAutomaticDefinition}
  167. *
  168. * Refer to their document for more information about available options or to the
  169. * {@glink features/link#custom-link-attributes-decorators link feature guide} for general information.
  170. *
  171. * @interface LinkDecoratorDefinition
  172. */
  173. /**
  174. * Link decorator type.
  175. *
  176. * Check out the {@glink features/link#custom-link-attributes-decorators link feature guide} for more information.
  177. *
  178. * @member {'manual'|'automatic'} module:link/link~LinkDecoratorDefinition#mode
  179. */
  180. /**
  181. * Describes an automatic {@link module:link/link~LinkConfig#decorators link decorator}. This decorator type matches
  182. * all links in the editor content against a function that decides whether the link should receive a pre–defined set of attributes.
  183. *
  184. * It takes an object with key-value pairs of attributes and a callback function that must return a Boolean value based on the link's
  185. * `href` (URL). When the callback returns `true`, attributes are applied to the link.
  186. *
  187. * For example, to add the `target="_blank"` attribute to all links in the editor starting with `http://`, the
  188. * configuration could look like this:
  189. *
  190. * {
  191. * mode: 'automatic',
  192. * callback: url => url.startsWith( 'http://' ),
  193. * attributes: {
  194. * target: '_blank'
  195. * }
  196. * }
  197. *
  198. * **Note**: Since the `target` attribute management for external links is a common use case, there is a predefined automatic decorator
  199. * dedicated for that purpose that can be enabled by turning a single option on. Check out the
  200. * {@link module:link/link~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}
  201. * configuration description to learn more.
  202. *
  203. * @typedef {Object} module:link/link~LinkDecoratorAutomaticDefinition
  204. * @property {'automatic'} mode Link decorator type. It is `'automatic'` for all automatic decorators.
  205. * @property {Function} callback Takes a `url` as a parameter and returns `true` if the `attributes` should be applied to the link.
  206. * @property {Object} attributes Key-value pairs used as link attributes added to the output during the
  207. * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
  208. * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
  209. */
  210. /**
  211. * Describes a manual {@link module:link/link~LinkConfig#decorators link decorator}. This decorator type is represented in
  212. * the link feature's {@link module:link/linkui user interface} as a switch that the user can use to control the presence
  213. * of a predefined set of attributes.
  214. *
  215. * For instance, to allow the users to manually control the presence of the `target="_blank"` and
  216. * `rel="noopener noreferrer"` attributes on specific links, the decorator could look as follows:
  217. *
  218. * {
  219. * mode: 'manual',
  220. * label: 'Open in a new tab',
  221. * defaultValue: true,
  222. * attributes: {
  223. * target: '_blank',
  224. * rel: 'noopener noreferrer'
  225. * }
  226. * }
  227. *
  228. * @typedef {Object} module:link/link~LinkDecoratorManualDefinition
  229. * @property {'manual'} mode Link decorator type. It is `'manual'` for all manual decorators.
  230. * @property {String} label The label of the UI button that the user can use to control the presence of link attributes.
  231. * @property {Object} attributes Key-value pairs used as link attributes added to the output during the
  232. * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
  233. * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
  234. * @property {Boolean} [defaultValue] Controls whether the decorator is "on" by default.
  235. */