8
0
فهرست منبع

Merge pull request #230 from ckeditor/t/229

Docs: Documentation for link's decorators. Closes #229.
Piotrek Koszuliński 6 سال پیش
والد
کامیت
b7deb1b4ad

+ 0 - 0
packages/ckeditor5-link/docs/_snippets/features/build-link-source.html


+ 12 - 0
packages/ckeditor5-link/docs/_snippets/features/build-link-source.js

@@ -0,0 +1,12 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals window */
+
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+window.ClassicEditor = ClassicEditor;
+window.CS_CONFIG = CS_CONFIG;

+ 1 - 4
packages/ckeditor5-link/docs/_snippets/features/link.js

@@ -3,10 +3,7 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
-/* globals console, window, document */
-
-import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
-import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+/* globals console, window, document, ClassicEditor, CS_CONFIG */
 
 ClassicEditor
 	.create( document.querySelector( '#snippet-link' ), {

+ 10 - 0
packages/ckeditor5-link/docs/_snippets/features/linkdecorators.html

@@ -0,0 +1,10 @@
+<div id="snippet-link-decorators">
+	<p>
+		An <a href="https://ckeditor.com">external page</a> and a
+		<a download="download" href="https://cdn.ckeditor.com/ckeditor5/12.2.0/classic/ckeditor.js">downloadable resource</a>.
+	</p>
+</div>
+
+<pre class="highlight">
+	<code class="html hljs" id="output-link-decorators"></code>
+</pre>

+ 70 - 0
packages/ckeditor5-link/docs/_snippets/features/linkdecorators.js

@@ -0,0 +1,70 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals console, window, document, Worker, setTimeout, ClassicEditor, CS_CONFIG */
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-link-decorators' ), {
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			items: [
+				'heading',
+				'|',
+				'bold',
+				'italic',
+				'link',
+				'bulletedList',
+				'numberedList',
+				'blockQuote',
+				'undo',
+				'redo'
+			],
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		},
+		link: {
+			addTargetToExternalLinks: true,
+			decorators: [
+				{
+					mode: 'manual',
+					label: 'Downloadable',
+					attributes: {
+						download: 'download'
+					}
+				}
+			]
+		}
+	} )
+	.then( editor => {
+		if ( !window.editors ) {
+			window.editors = {};
+		}
+		window.editors.decorators = editor;
+
+		const outputElement = document.querySelector( '#output-link-decorators' );
+		const worker = new Worker( window.umberto.relativeAppPath + '/highlight.worker.js' );
+
+		worker.addEventListener( 'message', evt => {
+			const data = JSON.parse( evt.data );
+
+			outputElement.innerHTML = data.payload;
+		} );
+
+		editor.model.document.on( 'change', () => {
+			worker.postMessage( JSON.stringify( {
+				payload: editor.getData(),
+				language: 'html'
+			} ) );
+		} );
+
+		setTimeout( () => {
+			worker.postMessage( JSON.stringify( {
+				payload: editor.getData(),
+				language: 'html'
+			} ) );
+		}, 500 );
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 106 - 2
packages/ckeditor5-link/docs/features/link.md

@@ -3,6 +3,8 @@ title: Link
 category: features
 ---
 
+{@snippet features/build-link-source}
+
 The {@link module:link/link~Link} feature brings support for link editing to the editor. It allows for inserting hyperlinks into the edited content and offers the UI to create and edit them.
 
 ## Demo
@@ -23,6 +25,105 @@ CKEditor 5 allows for typing both at inner and outer boundaries of links to make
 
 {@img assets/img/typing-before.gif 770 The animation showing typing before the link in CKEditor 5 rich text editor.}
 
+## Custom link attributes (decorators)
+
+By default, all links created in the editor have the `href="..."` attribute in the {@link builds/guides/integration/basic-api#getting-the-editor-data editor data}. If you want your links to have additional link attributes, {@link module:link/link~LinkConfig#decorators link decorators} provide an easy way to configure and manage them. There are two types of link decorators you can make use of:
+
+* [**automatic**](#adding-attributes-to-links-based-on-predefined-rules-automatic-decorators) – they match links against pre–defined rules and manage their attributes based on the results,
+* [**manual**](#adding-attributes-to-links-using-the-ui-manual-decorators) – they allow users to control link attributes individually using the editor UI.
+
+<info-box>
+	Link decorators are disabled by default and it takes a proper [configuration](#configuration) to enable them in your editor. If you do not want to use them in your application, you do not need to do anything.
+</info-box>
+
+### Demo
+
+In the editor below, all **external** links get the `target="_blank"` and `rel="noopener noreferrer"` attributes ([automatic decorator](#adding-attributes-to-links-based-on-predefined-rules-automatic-decorators)). Click a link and edit it to see that it is possible to control the `downloadable` attribute of specific links using the switch button in the editing balloon ([manual decorator](#adding-attributes-to-links-using-the-ui-manual-decorators)). Take a look at the editor data below (updated live) to see the additional link attributes.
+
+{@snippet features/linkdecorators}
+
+### Configuration
+
+Decorators are configured via definitions in {@link module:link/link~LinkConfig#decorators `config.link.decorators`}. Each decorator definition must have its own unique name. In case of [manual decorators](#adding-attributes-to-links-using-the-ui-manual-decorators), that name also represents the decorator in the {@link framework/guides/architecture/editing-engine#text-attributes document model}.
+
+<info-box warning>
+	Link decorators work independently and no conflict resolution mechanism exists. For example, configuring the `target` attribute using both an automatic and a manual decorator at a time could end up with quirky results. The same applies if multiple manual or automatic decorators were defined for the same attribute.
+</info-box>
+
+#### Adding `target` and `rel` attributes to external links
+
+A very common use case for (automatic) link decorators is adding `target="_blank"` and `rel="noopener noreferrer"` attributes to all external links in the document. A dedicated {@link module:link/link~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`} configuration has been created for that purpose. When this option is set `true`, all links staring with `http://`, `https://` or `//` are "decorated" with `target` and `rel` attributes.
+
+```js
+const config = {
+	link: {
+		addTargetToExternalLinks: true
+	}
+};
+```
+
+Internally, this configuration corresponds to an [automatic decorator](#adding-attributes-to-links-based-on-predefined-rules-automatic-decorators) with the following {@link module:link/link~LinkDecoratorAutomaticDefinition definition}:
+
+```js
+{
+	mode: 'automatic',
+	callback: url => /^(https?:)?\/\//.test( url ),
+	attributes: {
+		target: '_blank',
+		rel: 'noopener noreferrer'
+	}
+}
+```
+
+**Note**: If you want to leave the decision whether a link should open in new tab to the users, do not use the `config.link.addTargetToExternalLinks` configuration but define a new [manual decorator](#adding-attributes-to-links-using-the-ui-manual-decorators) with the proper definition:
+
+```js
+{
+	mode: 'manual',
+	label: 'Open link in a new tab',
+	attributes: {
+		target: '_blank',
+		rel: 'noopener noreferrer'
+	}
+}
+```
+
+#### Adding attributes to links based on pre–defined rules (automatic decorators)
+
+Automatic link decorators match all links in the editor content against a {@link module:link/link~LinkDecoratorAutomaticDefinition function} which decides whether the link should gain some set of attributes or not, considering the URL (`href`) of the link. These decorators work silently being applied during {@link framework/guides/architecture/editing-engine#conversion data downcast} only.
+
+For instance, to create an automatic decorator that adds the `download="file.pdf"` attribute to all links ending with the `".pdf"` extension, you should add the following {@link module:link/link~LinkDecoratorAutomaticDefinition definition} to {@link module:link/link~LinkConfig#decorators `config.link.decorators`}:
+
+```js
+{
+	mode: 'automatic',
+	callback: url => url.endsWith( '.pdf' ),
+	attributes: {
+		download: 'file.pdf'
+	}
+}
+```
+
+<info-box>
+	If you want `target` and `rel` attributes to be added to all external links in your content, we prepared a [dedicated configuration](#adding-target-and-rel-attributes-to-external-links) exactly for that purpose so you do not have to define the automatic decorator by yourself.
+</info-box>
+
+#### Adding attributes to links using the UI (manual decorators)
+
+Manual link decorators are represented in the link editing balloon as switch buttons users can use to control the presence of attributes of a particular link (check out the [demo](#demo) to learn more). Each manual decorator {@link module:link/link~LinkDecoratorManualDefinition definition} contains a human–readable label displayed next to the switch button in the link editing balloon. Make sure it is compact and precise for the convenience of the users.
+
+To configure a "Downloadable" switch button in the link editing balloon that adds the `download="file"` attribute to the link when turned on, add the following definition to {@link module:link/link~LinkConfig#decorators `config.link.decorators`}:
+
+```js
+{
+	mode: 'manual',
+	label: 'Downloadable',
+	attributes: {
+		download: 'file'
+	}
+}
+```
+
 ## Installation
 
 <info-box info>
@@ -63,11 +164,14 @@ The commands can be executed using the {@link module:core/editor/editor~Editor#e
 // When the selection is collapsed, it creates new text wrapped in a link.
 editor.execute( 'link', 'http://example.com' );
 
-// Removes the link from the selection.
+// If there are decorators configured, the command can set their state.
+editor.execute( 'link', 'http://example.com', { linkIsExternal: true } );
+
+// Removes the link from the selection (and all decorators if present).
 editor.execute( 'unlink' );
 ```
 
-Links are represented in the {@link module:engine/model/model~Model model} using the `linkHref` attribute.
+Links are represented in the {@link module:engine/model/model~Model model} using the `linkHref` attribute. [Manual link decorators](#adding-attributes-to-links-using-the-ui-manual-decorators) are represented in the model using text attributes corresponding to their names as configured in {@link module:link/link~LinkConfig#decorators `config.link.decorators`}.
 
 <info-box>
 	We recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector} for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more.

+ 14 - 4
packages/ckeditor5-link/src/link.js

@@ -61,6 +61,12 @@ export default class Link extends Plugin {
  * When set `true`, the `target="blank"` and `rel="noopener noreferrer"` attributes are automatically added to all external links
  * in the editor. By external are meant all links in the editor content starting with `http`, `https`, or `//`.
  *
+ *		const config = {
+ *			link: {
+ *				addTargetToExternalLinks: true
+ *			}
+ *		};
+ *
  * Internally, this option activates a predefined {@link module:link/link~LinkConfig#decorators automatic link decorator},
  * which extends all external links with the `target` and `rel` attributes without additional configuration.
  *
@@ -119,7 +125,7 @@ export default class Link extends Plugin {
  * and {@link module:link/link~LinkDecoratorManualDefinition manual} decorator option reference.
  *
  * **Warning:** Currently, link decorators work independently and no conflict resolution mechanism exists.
- * For example, configuring the `target` attribute using both an automatic and a manual decorator at a time could end up with a
+ * For example, configuring the `target` attribute using both an automatic and a manual decorator at a time could end up with
  * quirky results. The same applies if multiple manual or automatic decorators were defined for the same attribute.
  *
  * **Note**: Since the `target` attribute management for external links is a common use case, there is a predefined automatic decorator
@@ -127,18 +133,22 @@ export default class Link extends Plugin {
  * {@link module:link/link~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}
  * configuration description to learn more.
  *
+ * See also {@glink features/link#custom-link-attributes-decorators link's feature} guide for more information.
+ *
  * @member {Object.<String, module:link/link~LinkDecoratorDefinition>} module:link/link~LinkConfig#decorators
  */
 
 /**
- * Represents a link decorator definition {@link module:link/link~LinkDecoratorManualDefinition `'manual'`} or
- * {@link module:link/link~LinkDecoratorAutomaticDefinition `'automatic'`}.
+ * Represents a link decorator definition ({@link module:link/link~LinkDecoratorManualDefinition `'manual'`}
+ * or {@link module:link/link~LinkDecoratorAutomaticDefinition `'automatic'`}).
  *
  * @interface LinkDecoratorDefinition
  */
 
 /**
- * The kind of the decorator. `'manual'` for all manual decorators and `'automatic'` for all automatic decorators.
+ * The kind of the decorator.
+ *
+ * Check out the {@glink features/link#custom-link-attributes-decorators link feature} guide for more information.
  *
  * @member {'manual'|'automatic'} module:link/link~LinkDecoratorDefinition#mode
  */