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

Commit

Permalink
Merge branch 'master' into t/229
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Jul 1, 2019
2 parents 206c753 + 4161eb1 commit 7a4a297
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 28 deletions.
20 changes: 13 additions & 7 deletions src/linkediting.js
Expand Up @@ -156,17 +156,23 @@ export default class LinkEditing extends Plugin {
model: decorator.id,
view: ( manualDecoratorName, writer ) => {
if ( manualDecoratorName ) {
const element = writer.createAttributeElement(
'a',
manualDecorators.get( decorator.id ).attributes,
{
priority: 5
}
);
const attributes = manualDecorators.get( decorator.id ).attributes;
const element = writer.createAttributeElement( 'a', attributes, { priority: 5 } );
writer.setCustomProperty( 'link', true, element );

return element;
}
} } );

editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'a',
attributes: manualDecorators.get( decorator.id ).attributes
},
model: {
key: decorator.id
}
} );
} );
}

Expand Down
84 changes: 84 additions & 0 deletions tests/linkediting.js
Expand Up @@ -587,5 +587,89 @@ describe( 'LinkEditing', () => {
expect( editor.getData() ).to.equal( '<p><a href="http://example.com">foo</a>bar</p>' );
} );
} );

describe( 'upcast converter', () => {
it( 'should upcast attributes from initial data', done => {
VirtualTestEditor
.create( {
initialData: '<p><a href="url" target="_blank" rel="noopener noreferrer" download="file">Foo</a>' +
'<a href="example.com" download="file">Bar</a></p>',
plugins: [ Paragraph, LinkEditing, Enter ],
link: {
decorators: {
isExternal: {
mode: 'manual',
label: 'Open in a new window',
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
},
isDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
}
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;

expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
'<paragraph>' +
'<$text linkHref="url" linkIsDownloadable="true" linkIsExternal="true">Foo</$text>' +
'<$text linkHref="example.com" linkIsDownloadable="true">Bar</$text>' +
'</paragraph>'
);
} )
.then( done )
.catch( done );
} );

it( 'should not upcast partial and incorrect attributes', done => {
VirtualTestEditor
.create( {
initialData: '<p><a href="url" target="_blank" download="something">Foo</a>' +
'<a href="example.com" download="test">Bar</a></p>',
plugins: [ Paragraph, LinkEditing, Enter ],
link: {
decorators: {
isExternal: {
mode: 'manual',
label: 'Open in a new window',
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
},
isDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
}
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;

expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
'<paragraph>' +
'<$text linkHref="url">Foo</$text>' +
'<$text linkHref="example.com">Bar</$text>' +
'</paragraph>'
);
} )
.then( done )
.catch( done );
} );
} );
} );
} );
10 changes: 5 additions & 5 deletions tests/manual/linkdecorator.html
@@ -1,16 +1,16 @@
<h2>Manual decorators</h2>
<div id="editor">
<p>This is <a href="http://ckeditor.com">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
<p>This is <a href="//ckeditor.com">CKEditor5</a> as schemaless url.</p>
<p>This is <a href="http://ckeditor.com" target="_blank" rel="noopener noreferrer">CKEditor5</a> from <a href="http://cksource.com" download="download" target="_blank" rel="noopener noreferrer" >CKSource</a>.</p>
<p>This is <a href="//ckeditor.com" class="gallery">CKEditor5</a> as schemaless url.</p>
<p>This is <a href="#anchor">anchor</a> on this page.</p>
<p>This is some random <a href="ftp://127.0.0.1">ftp address</a>.</p>
<p>This is some random <a href="ftp://127.0.0.1" download="download">ftp address</a>.</p>
<p>This is some <a href="mailto:random@user.org">mail</a>.</p>
<p>This is some <a href="tel:123456789">phone number</a>.</p>
<p>This is some <a href="tel:123456789">phone number</a> with gallery decorator</p>
</div>

<h2>Automatic decorators</h2>
<div id="editor2">
<p>This is <a href="http://ckeditor.com">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
<p>This is <a href="http://ckeditor.com" target="_blank" rel="noopener noreferrer" download="download">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
<p>This is <a href="//ckeditor.com">CKEditor5</a> as schemaless url.</p>
<p>This is <a href="#anchor">anchor</a> on this page.</p>
<p>This is some random <a href="ftp://127.0.0.1">ftp address</a>.</p>
Expand Down
13 changes: 5 additions & 8 deletions tests/manual/linkdecorator.js
Expand Up @@ -3,7 +3,7 @@
* For licensing, see LICENSE.md.
*/

/* globals console:false, window, document */
/* globals console:false, window, document, CKEditorInspector */

import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import Enter from '@ckeditor/ckeditor5-enter/src/enter';
Expand All @@ -16,6 +16,8 @@ import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
// Just to have nicely styles switchbutton;
import '@ckeditor/ckeditor5-theme-lark/theme/ckeditor5-ui/components/list/list.css';

window.editors = {};

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Link, Typing, Paragraph, Clipboard, Undo, Enter ],
Expand Down Expand Up @@ -48,10 +50,7 @@ ClassicEditor
}
} )
.then( editor => {
if ( !window.editors ) {
window.editors = {};
}
window.editor = editor;
CKEditorInspector.attach( 'manual', editor );
window.editors.manualDecorators = editor;
} )
.catch( err => {
Expand Down Expand Up @@ -83,9 +82,7 @@ ClassicEditor
}
} )
.then( editor => {
if ( !window.editors ) {
window.editors = {};
}
CKEditorInspector.attach( 'automatic', editor );
window.editors.automaticDecorators = editor;
} )
.catch( err => {
Expand Down
21 changes: 13 additions & 8 deletions tests/manual/linkdecorator.md
Expand Up @@ -4,18 +4,23 @@

1. Should be available for every link.
2. Should be applied to the content only when "Save" was clicked.
3. There should be 3 manual decorators available:
* Open in new a new tab
* Downloadable
* Gallery link
4. State of the decorator switches should reflect the model of the currently selected link.
5. Switch buttons should be focusable (with the tab key), after the URL input. The "save" and "cancel" buttons should be focused last.
3. There should be initially set some decorators over specific links based on source data of the editor:
* `CKEditor5` has: "Open in a new tab"
* `CKSource` has: "Open in a new tab" and "Downloadable"
* `CKEditor5` (schemaless) has: "Gallery"
* `ftp address` has: "Downloadable"
4. There should be 3 manual decorators available:
* Open in new a new tab
* Downloadable
* Gallery link
5. State of the decorator switches should reflect the model of the currently selected link.
6. Switch buttons should be focusable (with the tab key), after the URL input. The "save" and "cancel" buttons should be focused last.

### Automatic decorators (window.editors.automaticDecorators).

1. There should be a default automatic decorator turned on, which adds `target="_blank"` and `rel="noopener noreferrer"` attributes to all external links (links starting with `http://`, `https://` or `//`).
2. There should be no changes to the model or the view of the editors.
3. Decorator data should be added during downcast (run `window.editors.automaticDecorators.getData()` to see how it works).
4. There are 2 additional decorators in this editor:
* phone, which detects all links starting with `tel:` and adds the `phone` CSS class to such link,
* internal, which adds the `internal` CSS class to all links starting with `#`.
* phone, which detects all links starting with `tel:` and adds the `phone` CSS class to such link,
* internal, which adds the `internal` CSS class to all links starting with `#`.

0 comments on commit 7a4a297

Please sign in to comment.