@ckeditor/ckeditor5-link 27.1.0 → 29.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +6 -2
  3. package/build/link.js +1 -1
  4. package/build/translations/ar.js +1 -0
  5. package/build/translations/ast.js +1 -0
  6. package/build/translations/az.js +1 -0
  7. package/build/translations/bg.js +1 -0
  8. package/build/translations/cs.js +1 -0
  9. package/build/translations/da.js +1 -0
  10. package/build/translations/de-ch.js +1 -0
  11. package/build/translations/de.js +1 -0
  12. package/build/translations/el.js +1 -0
  13. package/build/translations/en-au.js +1 -0
  14. package/build/translations/en-gb.js +1 -0
  15. package/build/translations/eo.js +1 -0
  16. package/build/translations/es.js +1 -0
  17. package/build/translations/et.js +1 -0
  18. package/build/translations/eu.js +1 -0
  19. package/build/translations/fa.js +1 -0
  20. package/build/translations/fi.js +1 -0
  21. package/build/translations/fr.js +1 -0
  22. package/build/translations/gl.js +1 -0
  23. package/build/translations/he.js +1 -0
  24. package/build/translations/hi.js +1 -0
  25. package/build/translations/hr.js +1 -0
  26. package/build/translations/hu.js +1 -0
  27. package/build/translations/id.js +1 -0
  28. package/build/translations/it.js +1 -0
  29. package/build/translations/ja.js +1 -0
  30. package/build/translations/km.js +1 -0
  31. package/build/translations/kn.js +1 -0
  32. package/build/translations/ko.js +1 -0
  33. package/build/translations/ku.js +1 -0
  34. package/build/translations/lt.js +1 -0
  35. package/build/translations/lv.js +1 -0
  36. package/build/translations/nb.js +1 -0
  37. package/build/translations/ne.js +1 -0
  38. package/build/translations/nl.js +1 -0
  39. package/build/translations/no.js +1 -0
  40. package/build/translations/pl.js +1 -0
  41. package/build/translations/pt-br.js +1 -0
  42. package/build/translations/pt.js +1 -0
  43. package/build/translations/ro.js +1 -0
  44. package/build/translations/ru.js +1 -0
  45. package/build/translations/sk.js +1 -0
  46. package/build/translations/sq.js +1 -0
  47. package/build/translations/sr-latn.js +1 -0
  48. package/build/translations/sr.js +1 -0
  49. package/build/translations/sv.js +1 -0
  50. package/build/translations/tk.js +1 -0
  51. package/build/translations/tr.js +1 -0
  52. package/build/translations/ug.js +1 -0
  53. package/build/translations/uk.js +1 -0
  54. package/build/translations/vi.js +1 -0
  55. package/build/translations/zh-cn.js +1 -0
  56. package/build/translations/zh.js +1 -0
  57. package/ckeditor5-metadata.json +76 -0
  58. package/lang/translations/de-ch.po +53 -0
  59. package/lang/translations/ro.po +1 -1
  60. package/package.json +25 -20
  61. package/src/index.js +7 -17
  62. package/src/link.js +14 -2
  63. package/src/linkcommand.js +13 -15
  64. package/src/linkediting.js +36 -18
  65. package/src/linkimageediting.js +79 -67
  66. package/src/linkimageui.js +21 -19
  67. package/src/linkui.js +20 -12
  68. package/src/unlinkcommand.js +6 -8
  69. package/src/utils/automaticdecorators.js +33 -6
  70. package/src/utils/manualdecorator.js +31 -1
  71. package/src/utils.js +3 -3
  72. package/theme/linkimage.css +9 -12
  73. package/build/link.js.map +0 -1
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ #
3
+ # !!! IMPORTANT !!!
4
+ #
5
+ # Before you edit this file, please keep in mind that contributing to the project
6
+ # translations is possible ONLY via the Transifex online service.
7
+ #
8
+ # To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
9
+ #
10
+ # To learn more, check out the official contributor's guide:
11
+ # https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
12
+ #
13
+ msgid ""
14
+ msgstr ""
15
+ "Language-Team: German (Switzerland) (https://www.transifex.com/ckeditor/teams/11143/de_CH/)\n"
16
+ "Language: de_CH\n"
17
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
+
19
+ msgctxt "Toolbar button tooltip for the Unlink feature."
20
+ msgid "Unlink"
21
+ msgstr "Link entfernen"
22
+
23
+ msgctxt "Toolbar button tooltip for the Link feature."
24
+ msgid "Link"
25
+ msgstr "Link"
26
+
27
+ msgctxt "Label for the URL input in the Link URL editing balloon."
28
+ msgid "Link URL"
29
+ msgstr "Link Adresse"
30
+
31
+ msgctxt "Label for the image link button."
32
+ msgid "Link image"
33
+ msgstr "Bild verlinken"
34
+
35
+ msgctxt "Button opening the Link URL editing balloon."
36
+ msgid "Edit link"
37
+ msgstr "Link bearbeiten"
38
+
39
+ msgctxt "Button opening the link in new browser tab."
40
+ msgid "Open link in new tab"
41
+ msgstr "Link in neuem Tab öffnen"
42
+
43
+ msgctxt "Label explaining that a link has no URL set (the URL is empty)."
44
+ msgid "This link has no URL"
45
+ msgstr "Dieser Link hat keine Adresse"
46
+
47
+ msgctxt "The label of the switch button that controls whether the edited link will open in a new tab."
48
+ msgid "Open in a new tab"
49
+ msgstr "In neuem Tab öffnen"
50
+
51
+ msgctxt "The label of the switch button that controls whether the edited link refers to downloadable resource."
52
+ msgid "Downloadable"
53
+ msgstr "Herunterladbar"
@@ -30,7 +30,7 @@ msgstr "Link URL"
30
30
 
31
31
  msgctxt "Label for the image link button."
32
32
  msgid "Link image"
33
- msgstr ""
33
+ msgstr "Link imagine"
34
34
 
35
35
  msgctxt "Button opening the Link URL editing balloon."
36
36
  msgid "Edit link"
package/package.json CHANGED
@@ -1,36 +1,40 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-link",
3
- "version": "27.1.0",
3
+ "version": "29.2.0",
4
4
  "description": "Link feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
7
7
  "ckeditor5",
8
8
  "ckeditor 5",
9
9
  "ckeditor5-feature",
10
- "ckeditor5-plugin"
10
+ "ckeditor5-plugin",
11
+ "ckeditor5-dll"
11
12
  ],
12
13
  "main": "src/index.js",
13
14
  "dependencies": {
14
- "@ckeditor/ckeditor5-ui": "^27.1.0",
15
- "ckeditor5": "^27.1.0",
15
+ "@ckeditor/ckeditor5-ui": "^29.2.0",
16
+ "ckeditor5": "^29.2.0",
16
17
  "lodash-es": "^4.17.15"
17
18
  },
18
19
  "devDependencies": {
19
- "@ckeditor/ckeditor5-basic-styles": "^27.1.0",
20
- "@ckeditor/ckeditor5-block-quote": "^27.1.0",
21
- "@ckeditor/ckeditor5-clipboard": "^27.1.0",
22
- "@ckeditor/ckeditor5-code-block": "^27.1.0",
23
- "@ckeditor/ckeditor5-core": "^27.1.0",
24
- "@ckeditor/ckeditor5-dev-utils": "^24.0.0",
25
- "@ckeditor/ckeditor5-editor-classic": "^27.1.0",
26
- "@ckeditor/ckeditor5-engine": "^27.1.0",
27
- "@ckeditor/ckeditor5-enter": "^27.1.0",
28
- "@ckeditor/ckeditor5-image": "^27.1.0",
29
- "@ckeditor/ckeditor5-paragraph": "^27.1.0",
30
- "@ckeditor/ckeditor5-theme-lark": "^27.1.0",
31
- "@ckeditor/ckeditor5-typing": "^27.1.0",
32
- "@ckeditor/ckeditor5-undo": "^27.1.0",
33
- "@ckeditor/ckeditor5-utils": "^27.1.0",
20
+ "@ckeditor/ckeditor5-basic-styles": "^29.2.0",
21
+ "@ckeditor/ckeditor5-block-quote": "^29.2.0",
22
+ "@ckeditor/ckeditor5-clipboard": "^29.2.0",
23
+ "@ckeditor/ckeditor5-cloud-services": "^29.2.0",
24
+ "@ckeditor/ckeditor5-code-block": "^29.2.0",
25
+ "@ckeditor/ckeditor5-core": "^29.2.0",
26
+ "@ckeditor/ckeditor5-dev-utils": "^25.4.0",
27
+ "@ckeditor/ckeditor5-easy-image": "^29.2.0",
28
+ "@ckeditor/ckeditor5-editor-classic": "^29.2.0",
29
+ "@ckeditor/ckeditor5-engine": "^29.2.0",
30
+ "@ckeditor/ckeditor5-enter": "^29.2.0",
31
+ "@ckeditor/ckeditor5-image": "^29.2.0",
32
+ "@ckeditor/ckeditor5-paragraph": "^29.2.0",
33
+ "@ckeditor/ckeditor5-theme-lark": "^29.2.0",
34
+ "@ckeditor/ckeditor5-typing": "^29.2.0",
35
+ "@ckeditor/ckeditor5-undo": "^29.2.0",
36
+ "@ckeditor/ckeditor5-utils": "^29.2.0",
37
+ "@ckeditor/ckeditor5-widget": "^29.2.0",
34
38
  "webpack": "^4.43.0",
35
39
  "webpack-cli": "^3.3.11"
36
40
  },
@@ -51,7 +55,8 @@
51
55
  "lang",
52
56
  "src",
53
57
  "theme",
54
- "build"
58
+ "build",
59
+ "ckeditor5-metadata.json"
55
60
  ],
56
61
  "scripts": {
57
62
  "dll:build": "webpack"
package/src/index.js CHANGED
@@ -7,20 +7,10 @@
7
7
  * @module link
8
8
  */
9
9
 
10
- import Link from './link';
11
- import LinkEditing from './linkediting';
12
- import LinkUI from './linkui';
13
- import LinkImage from './linkimage';
14
- import LinkImageEditing from './linkimageediting';
15
- import LinkImageUI from './linkimageui';
16
- import AutoLink from './autolink';
17
-
18
- export default {
19
- Link,
20
- LinkEditing,
21
- LinkUI,
22
- LinkImage,
23
- LinkImageEditing,
24
- LinkImageUI,
25
- AutoLink
26
- };
10
+ export { default as Link } from './link';
11
+ export { default as LinkEditing } from './linkediting';
12
+ export { default as LinkUI } from './linkui';
13
+ export { default as LinkImage } from './linkimage';
14
+ export { default as LinkImageEditing } from './linkimageediting';
15
+ export { default as LinkImageUI } from './linkimageui';
16
+ export { default as AutoLink } from './autolink';
package/src/link.js CHANGED
@@ -215,9 +215,15 @@ export default class Link extends Plugin {
215
215
  * @typedef {Object} module:link/link~LinkDecoratorAutomaticDefinition
216
216
  * @property {'automatic'} mode Link decorator type. It is `'automatic'` for all automatic decorators.
217
217
  * @property {Function} callback Takes a `url` as a parameter and returns `true` if the `attributes` should be applied to the link.
218
- * @property {Object} attributes Key-value pairs used as link attributes added to the output during the
218
+ * @property {Object} [attributes] Key-value pairs used as link attributes added to the output during the
219
219
  * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
220
220
  * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
221
+ * @property {Object} [styles] Key-value pairs used as link styles added to the output during the
222
+ * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
223
+ * Styles should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
224
+ * @property {String|Array.<String>} [classes] Class names used as link classes added to the output during the
225
+ * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
226
+ * Classes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
221
227
  */
222
228
 
223
229
  /**
@@ -241,8 +247,14 @@ export default class Link extends Plugin {
241
247
  * @typedef {Object} module:link/link~LinkDecoratorManualDefinition
242
248
  * @property {'manual'} mode Link decorator type. It is `'manual'` for all manual decorators.
243
249
  * @property {String} label The label of the UI button that the user can use to control the presence of link attributes.
244
- * @property {Object} attributes Key-value pairs used as link attributes added to the output during the
250
+ * @property {Object} [attributes] Key-value pairs used as link attributes added to the output during the
245
251
  * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
246
252
  * Attributes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
253
+ * @property {Object} [styles] Key-value pairs used as link styles added to the output during the
254
+ * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
255
+ * Styles should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
256
+ * @property {String|Array.<String>} [classes] Class names used as link classes added to the output during the
257
+ * {@glink framework/guides/architecture/editing-engine#conversion downcasting}.
258
+ * Classes should follow the {@link module:engine/view/elementdefinition~ElementDefinition} syntax.
247
259
  * @property {Boolean} [defaultValue] Controls whether the decorator is "on" by default.
248
260
  */
@@ -9,10 +9,10 @@
9
9
 
10
10
  import { Command } from 'ckeditor5/src/core';
11
11
  import { findAttributeRange } from 'ckeditor5/src/typing';
12
- import { Collection, toMap, first } from 'ckeditor5/src/utils';
12
+ import { Collection, first, toMap } from 'ckeditor5/src/utils';
13
13
 
14
14
  import AutomaticDecorators from './utils/automaticdecorators';
15
- import { isImageAllowed } from './utils';
15
+ import { isLinkableElement } from './utils';
16
16
 
17
17
  /**
18
18
  * The link command. It is used by the {@link module:link/link~Link link feature}.
@@ -44,7 +44,7 @@ export default class LinkCommand extends Command {
44
44
 
45
45
  /**
46
46
  * An instance of the helper that ties together all {@link module:link/link~LinkDecoratorAutomaticDefinition}
47
- * that are used by the {@glink features/link link} and the {@glink features/image#linking-images linking images} features.
47
+ * that are used by the {@glink features/link link} and the {@glink features/images/images-linking linking images} features.
48
48
  *
49
49
  * @readonly
50
50
  * @type {module:link/utils~AutomaticDecorators}
@@ -66,18 +66,17 @@ export default class LinkCommand extends Command {
66
66
  */
67
67
  refresh() {
68
68
  const model = this.editor.model;
69
- const doc = model.document;
70
-
71
- const selectedElement = first( doc.selection.getSelectedBlocks() );
69
+ const selection = model.document.selection;
70
+ const selectedElement = selection.getSelectedElement() || first( selection.getSelectedBlocks() );
72
71
 
73
- // A check for the `LinkImage` plugin. If the selection contains an element, get values from the element.
72
+ // A check for any integration that allows linking elements (e.g. `LinkImage`).
74
73
  // Currently the selection reads attributes from text nodes only. See #7429 and #7465.
75
- if ( isImageAllowed( selectedElement, model.schema ) ) {
74
+ if ( isLinkableElement( selectedElement, model.schema ) ) {
76
75
  this.value = selectedElement.getAttribute( 'linkHref' );
77
76
  this.isEnabled = model.schema.checkAttribute( selectedElement, 'linkHref' );
78
77
  } else {
79
- this.value = doc.selection.getAttribute( 'linkHref' );
80
- this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'linkHref' );
78
+ this.value = selection.getAttribute( 'linkHref' );
79
+ this.isEnabled = model.schema.checkAttributeInSelection( selection, 'linkHref' );
81
80
  }
82
81
 
83
82
  for ( const manualDecorator of this.manualDecorators ) {
@@ -258,17 +257,16 @@ export default class LinkCommand extends Command {
258
257
  */
259
258
  _getDecoratorStateFromModel( decoratorName ) {
260
259
  const model = this.editor.model;
261
- const doc = model.document;
262
-
263
- const selectedElement = first( doc.selection.getSelectedBlocks() );
260
+ const selection = model.document.selection;
261
+ const selectedElement = selection.getSelectedElement();
264
262
 
265
263
  // A check for the `LinkImage` plugin. If the selection contains an element, get values from the element.
266
264
  // Currently the selection reads attributes from text nodes only. See #7429 and #7465.
267
- if ( isImageAllowed( selectedElement, model.schema ) ) {
265
+ if ( isLinkableElement( selectedElement, model.schema ) ) {
268
266
  return selectedElement.getAttribute( decoratorName );
269
267
  }
270
268
 
271
- return doc.selection.getAttribute( decoratorName );
269
+ return selection.getAttribute( decoratorName );
272
270
  }
273
271
 
274
272
  /**
@@ -184,14 +184,24 @@ export default class LinkEditing extends Plugin {
184
184
  editor.model.schema.extend( '$text', { allowAttributes: decorator.id } );
185
185
 
186
186
  // Keeps reference to manual decorator to decode its name to attributes during downcast.
187
- manualDecorators.add( new ManualDecorator( decorator ) );
187
+ decorator = new ManualDecorator( decorator );
188
+
189
+ manualDecorators.add( decorator );
188
190
 
189
191
  editor.conversion.for( 'downcast' ).attributeToElement( {
190
192
  model: decorator.id,
191
193
  view: ( manualDecoratorName, { writer } ) => {
192
194
  if ( manualDecoratorName ) {
193
- const attributes = manualDecorators.get( decorator.id ).attributes;
194
- const element = writer.createAttributeElement( 'a', attributes, { priority: 5 } );
195
+ const element = writer.createAttributeElement( 'a', decorator.attributes, { priority: 5 } );
196
+
197
+ if ( decorator.classes ) {
198
+ writer.addClass( decorator.classes, element );
199
+ }
200
+
201
+ for ( const key in decorator.styles ) {
202
+ writer.setStyle( key, decorator.styles[ key ], element );
203
+ }
204
+
195
205
  writer.setCustomProperty( 'link', true, element );
196
206
 
197
207
  return element;
@@ -201,7 +211,7 @@ export default class LinkEditing extends Plugin {
201
211
  editor.conversion.for( 'upcast' ).elementToAttribute( {
202
212
  view: {
203
213
  name: 'a',
204
- attributes: manualDecorators.get( decorator.id ).attributes
214
+ ...decorator._createPattern()
205
215
  },
206
216
  model: {
207
217
  key: decorator.id
@@ -225,7 +235,6 @@ export default class LinkEditing extends Plugin {
225
235
  const editor = this.editor;
226
236
  const model = editor.model;
227
237
  const selection = model.document.selection;
228
- const linkCommand = editor.commands.get( 'link' );
229
238
 
230
239
  this.listenTo( model, 'insertContent', () => {
231
240
  const nodeBefore = selection.anchor.nodeBefore;
@@ -295,7 +304,7 @@ export default class LinkEditing extends Plugin {
295
304
  }
296
305
 
297
306
  model.change( writer => {
298
- removeLinkAttributesFromSelection( writer, linkCommand.manualDecorators );
307
+ removeLinkAttributesFromSelection( writer, getLinkAttributesAllowedOnText( model.schema ) );
299
308
  } );
300
309
  }, { priority: 'low' } );
301
310
  }
@@ -313,7 +322,7 @@ export default class LinkEditing extends Plugin {
313
322
  */
314
323
  _enableClickingAfterLink() {
315
324
  const editor = this.editor;
316
- const linkCommand = editor.commands.get( 'link' );
325
+ const model = editor.model;
317
326
 
318
327
  editor.editing.view.addObserver( MouseObserver );
319
328
 
@@ -333,7 +342,7 @@ export default class LinkEditing extends Plugin {
333
342
  // ...and it was caused by the click...
334
343
  clicked = false;
335
344
 
336
- const selection = editor.model.document.selection;
345
+ const selection = model.document.selection;
337
346
 
338
347
  // ...and no text is selected...
339
348
  if ( !selection.isCollapsed ) {
@@ -346,13 +355,13 @@ export default class LinkEditing extends Plugin {
346
355
  }
347
356
 
348
357
  const position = selection.getFirstPosition();
349
- const linkRange = findAttributeRange( position, 'linkHref', selection.getAttribute( 'linkHref' ), editor.model );
358
+ const linkRange = findAttributeRange( position, 'linkHref', selection.getAttribute( 'linkHref' ), model );
350
359
 
351
360
  // ...check whether clicked start/end boundary of the link.
352
361
  // If so, remove the `linkHref` attribute.
353
362
  if ( position.isTouching( linkRange.start ) || position.isTouching( linkRange.end ) ) {
354
- editor.model.change( writer => {
355
- removeLinkAttributesFromSelection( writer, linkCommand.manualDecorators );
363
+ model.change( writer => {
364
+ removeLinkAttributesFromSelection( writer, getLinkAttributesAllowedOnText( model.schema ) );
356
365
  } );
357
366
  }
358
367
  } );
@@ -453,7 +462,6 @@ export default class LinkEditing extends Plugin {
453
462
  const model = editor.model;
454
463
  const selection = model.document.selection;
455
464
  const view = editor.editing.view;
456
- const linkCommand = editor.commands.get( 'link' );
457
465
 
458
466
  // A flag whether attributes `linkHref` attribute should be preserved.
459
467
  let shouldPreserveAttributes = false;
@@ -502,7 +510,7 @@ export default class LinkEditing extends Plugin {
502
510
 
503
511
  // Use `model.enqueueChange()` in order to execute the callback at the end of the changes process.
504
512
  editor.model.enqueueChange( writer => {
505
- removeLinkAttributesFromSelection( writer, linkCommand.manualDecorators );
513
+ removeLinkAttributesFromSelection( writer, getLinkAttributesAllowedOnText( model.schema ) );
506
514
  } );
507
515
  }, { priority: 'low' } );
508
516
  }
@@ -510,15 +518,15 @@ export default class LinkEditing extends Plugin {
510
518
 
511
519
  // Make the selection free of link-related model attributes.
512
520
  // All link-related model attributes start with "link". That includes not only "linkHref"
513
- // but also all decorator attributes (they have dynamic names).
521
+ // but also all decorator attributes (they have dynamic names), or even custom plugins.
514
522
  //
515
523
  // @param {module:engine/model/writer~Writer} writer
516
- // @param {module:utils/collection~Collection} manualDecorators
517
- function removeLinkAttributesFromSelection( writer, manualDecorators ) {
524
+ // @param {Array.<String>} linkAttributes
525
+ function removeLinkAttributesFromSelection( writer, linkAttributes ) {
518
526
  writer.removeSelectionAttribute( 'linkHref' );
519
527
 
520
- for ( const decorator of manualDecorators ) {
521
- writer.removeSelectionAttribute( decorator.id );
528
+ for ( const attribute of linkAttributes ) {
529
+ writer.removeSelectionAttribute( attribute );
522
530
  }
523
531
  }
524
532
 
@@ -573,3 +581,13 @@ function isTyping( editor ) {
573
581
 
574
582
  return input.isInput( editor.model.change( writer => writer.batch ) );
575
583
  }
584
+
585
+ // Returns an array containing names of the attributes allowed on `$text` that describes the link item.
586
+ //
587
+ // @param {module:engine/model/schema~Schema} schema
588
+ // @returns {Array.<String>}
589
+ function getLinkAttributesAllowedOnText( schema ) {
590
+ const textAttributes = schema.getDefinition( '$text' ).allowAttributes;
591
+
592
+ return textAttributes.filter( attribute => attribute.startsWith( 'link' ) );
593
+ }