Problem/motivation

Data attributes of a new link are always applied to the FIRST link

Steps to reproduce

CKEditor5 + Linkit only (it's not other module's issue)

  1. create a new link, update href, displayed text etc
  2. create another link link, update href, displayed text etc
  3. create third link link, update href, displayed text etc
  4. update 2nd's link display text

result: data attributes are applied to first link! see video: https://youtu.be/bY3Kpu21NGc

Proposed resolution

issue is in getClosestSelectedLinkElement() in util.js - it alsways returns first link

This module uses Gitlab CI for automated testing of proposed code changes. To contribute code changes, create a merge request. Patch files will not trigger automated testing and are not sufficient for review.

Issue fork linkit-3555749

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jannakha created an issue. See original summary.

jannakha’s picture

Status: Active » Needs review

MR !149 fixes the issue
- tested on D11
- not tested with any other CKEditor5 plugins/modules

mark_fullmer’s picture

Assigned: Unassigned » mark_fullmer

Thanks so much for reporting this and for the proposed fix. Assigning myself for review...

mark_fullmer’s picture

Status: Needs review » Needs work

The first pass at the fix relies on trying to first read the selection's link Href attribute, and if it can't find that, using the raw href value. This won't work if there are two or more links with the same raw href value, as demonstrated in this video below. Screencast and steps to reproduce the problem:

https://www.youtube.com/watch?v=K7HvqUJAd0U

1. Create a node titled "First node"
2. Create a node titled "Second node"
3. Create a node with some body content. Create two links in the body content, both linking to "Second node."
4. Using "collapsed" selection (i.e., click inside the link), click the second link and update the display text and save.
5. Observe that the link is now split into two, since the link range is being defined by the first link, not the second link.

mark_fullmer’s picture

Status: Needs work » Needs review

Okay, since Linkit has the additional capability of updating the Link Href value, in order to find the correct link target when the selection is collapsed, we need to know the new href, not the "old" href. Testing shows that this behaves reliably with multiple links present, and when multiple links share the same href, because the range is being derived from the selection's first position -- i.e., where the cursor is located.

MR updated. This works for me, but a second confirmation would be greatly appreciated!

export function getCurrentLinkRange(model, selection, hrefSourceValue) {
  const position = selection.getFirstPosition();
  const linkRange = findAttributeRange(position, 'linkHref', hrefSourceValue, model);
  return linkRange;
};
jannakha’s picture

MR doesn't apply to 7.0.10 - is that because it's off latest unreleased dev?

mark_fullmer’s picture

MR doesn't apply to 7.0.10 - is that because it's off latest unreleased dev?

Yep! That's the typical merge request workflow: it's set to merge into the latest commit in the project's development branch, rather than representing a relationship to the latest tag for a project.

jannakha’s picture

ok, so, after another day of testing both editor advanced link and linkit (and digging into CKEditor's code)
link is getting split (https://youtu.be/b4Ir59uv7Ds) at the time when contextual balloon is visible (CKEditor is handling it here: _showFakeVisualSelection())

once cursor moves off - link is no longer split, but if you click on balloon while the link is split - it leads to random behaviour.

From CKEditor's code: they move cursor to the end of selection so the editor will not try to create a new link after cursor
see https://git.drupalcode.org/project/linkit/-/merge_requests/149/diffs#c91...
that's coming from how they handle link re-rendering (here's end result: https://youtu.be/hYwEEnF_gUk)

extra testing required: when decorators (target attribute) are enabled - displayedText and custom attributes are not part of args in the event handler (it leads to unnecessary re-calculation of ranges etc), maybe a good idea will be to check when decorators are involved - do not process custom attributes?

I've updated editor advanced link as well, I've tested them separately and together.

What do you think?

mark_fullmer’s picture

Fantastic sleuthing. I'll prioritize reviewing the proposed changes to both projects today. Thanks for the significant effort given to this problem!

mark_fullmer’s picture

Status: Needs review » Reviewed & tested by the community

Just a minor adjustment to ensure this doesn't break BC compatibility on sites still using CKEditor5 < v45 (Drupal < 10.5 / Drupal < 11.2).

This is not a concern for Editor Advanced Link, since its 2.3.x branch already sets Drupal core constraints to enforce CKEditor >= v45.

Summary of what I tested, using Linkit and Editor Advanced Link in conjunction:

(All scenarios below assume activating change to a link by clicking "inside" the link, what CKEditor calls a "collapsed" selection):

1. When two or more links are present, editing the displayed test of the second link correctly updates the text of the second link (where previously it was updating the first), and the link is not "split" into multiple mangled links.
2. When two or more links are present, editing the href of the second link correctly updates the href of the second link (where previously it was updating the first), and the link is not "split" into multiple mangled links.
3. When any of the "Link properties" interface are toggled (i.e., the "Open in new window" from Editor Advanced Link) and the link "Update" button is subsequently pressed, the cursor moves to the end of the link, and the link is not "split" into multiple mangled links.

mark_fullmer’s picture

Status: Reviewed & tested by the community » Fixed

Thanks again, @jannakha, for reporting this and contributing significant effort to pin down this squirrelly issue. I, for one, have a much better grasp of CKEditor5's API after this!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

jannakha’s picture

Sweet!!!
Thanks Mark for reviewing MRs!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.