Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge df55264 into 1dd2a54
Browse files Browse the repository at this point in the history
  • Loading branch information
msamsel committed Jun 17, 2019
2 parents 1dd2a54 + df55264 commit 3ac181a
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 4 deletions.
Empty file.
12 changes: 12 additions & 0 deletions 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;
5 changes: 1 addition & 4 deletions docs/_snippets/features/link.js
Expand Up @@ -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' ), {
Expand Down
14 changes: 14 additions & 0 deletions docs/_snippets/features/linkdecorators.html
@@ -0,0 +1,14 @@
<div id="snippet-link-decorators">
<h2>Links list</h2>
<ol>
<li>
<a href="https://ckeditor.com">Link to external page</a>
</li>
<li>
<a href="/">Link to internal page</a>
</li>
</ol>
</div>
<pre class="highlight">
<code class="html hljs" id="output-link-decorators"></code>
</pre>
70 changes: 70 additions & 0 deletions 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: {
targetDecorator: 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 );
} );
78 changes: 78 additions & 0 deletions docs/features/link.md
Expand Up @@ -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
Expand All @@ -23,6 +25,82 @@ 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.}

## Decorators

Decorator feature provides an easy way to configure and extend links with additional attributes. A decorator is an object defined in the configuration, which describes additional rules applied to the link feature. There are 2 types of decorators: "automatic" and "manual". More information about each of them might be found in sections below or in {@link module:link/link~LinkConfig#decorators the API documentation}.

<info-box warning>
**Warning:** It is not recommended to modify the same attribute through two or more decorators. All decorators work independent and its state is not reflected between them in any way. This also includes mixing manual and automatic decorators.
</info-box>

### Demo

In editor below is presented automatic and manual decorator feature. All external links gets automatically `target="_blank"` and `rel="noopener noreferrer"` attributes, what is done with {@link module:link/link~LinkConfig#targetDecorator} feature described below. The second decorator is a manual one, which adds a UI switch button with `"Downloadable"` label. Output data can be found in container below editor (its content updates automatically).

{@snippet features/linkdecorators}

### Automatic decorators

This type of decorator is applied automatically based on the link's URL. The automatic decorator has defined a callback function in {@link module:link/link~LinkDecoratorAutomaticOption the configuration}, which decides whether given decorators should be executed or not. There might be multiple decorators configured for the same link, however, each of them should implement different attribute's set without overlaps.

Automatic decorators are applied during {@link framework/guides/architecture/editing-engine#conversion downcasting data}, which means that result of working decorator is visible neither in the editor's model nor the UI in any way.

For example, this decorator will add `download="download"` attribute to every link ending with `.pdf`:
```js
const config = {
link: {
decorators: [
{
mode: 'automatic',
callback: url => url.endsWith( '.pdf' ),
attributes: {
download: 'download'
}
}
]
}
}
```

#### Target decorator

Automatic decorators might be very handy in one particular situation. Mentioned case is to add `target="_blank"` and `rel="noopener noreferrer"` attributes to all external links in document. A request for this feature is quite common, and because of that, there is a {@link module:link/link~LinkConfig#targetDecorator configuration option}, which registers such automatic decorator. When `targetDecorator` option is set to `true`, then all links started with `http://`, `https://` or `//` are decorated with `target` and `rel` attributes, without need to implement own decorator.

Code of automatic decorator comes with `targetDecorator` option:
```js
{
mode: 'automatic',
callback: url => /^(https?:)?\/\//.test( url ),
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}
```

<info-box>
If it is necessary to have a UI option, where the user decides, which links should be open in a new window, then `targetDecorator` options should remain `undefined` and there should be created a new **manual decorator** with proper configuration.
</info-box>



### Manual decorators

This type of decorator registers a UI element which can be switched by the user. Toggleable elements are located in editing view of the link. Modifying the state of this element and applying changes is reflected in the editor's model, what later is downcasted to attributes defined in {@link module:link/link~LinkDecoratorManualOption the manual decorator}.

Configuration of manual decorator contains a label field used in a UI to describe given attributes set. It should be a compact and descriptive name for the user convenience.

For example, this decorator will add "Downloadable" switch button, which extends link with `download="download"` attribute when is turned on:
```js
{
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'download'
}
}
```

## Installation

<info-box info>
Expand Down
2 changes: 2 additions & 0 deletions src/link.js
Expand Up @@ -139,6 +139,8 @@ export default class Link extends Plugin {
* For example, configuring the `target` attribute using both an automatic and a manual decorator at a time could end up with a
* quirky behavior. The same applies if multiple manual or automatic decorators were defined for the same attribute.
*
* See also {@glink features/link#decorators} guide.
*
* @member {Array.<module:link/link~LinkDecoratorAutomaticOption|module:link/link~LinkDecoratorManualOption>}
* module:link/link~LinkConfig#decorators
*/
Expand Down

0 comments on commit 3ac181a

Please sign in to comment.