-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LinkCommand should provide extension point for custom text attributes (linkTarget or similar) #9730
Comments
Just to sketch my solution which seems to work for now:
And implemented
This seems to do the trick and undo/redo works as expected. Nevertheless, I think it is a cumbersome approach. Any better extension point to |
Listening to "open form view": In order to provide a "clean fields" behavior like for fixing ckeditor/ckeditor5-link#78 (now: #4765) and ckeditor/ckeditor5-link#123 (now: #4793) as noted in
Doing so will be very error-prone with any CKEditor update. Again, a common extension point would be helpful here, at least providing some central event to listen to. The only feasible option we found in the end, was listening to private API:
|
Similar to `LinkUI` from CKEditor's Link Feature we must ensure, that target input field and behavior selector are reset each time the form view is opened. The previous approach only covered the use-case of doing so from action view by listening to edit-button. But, this neither deals with Ctrl+K keystroke nor with toolbar action. The only feasible workaround we found, was adding a decorator to the private method `LinkUI#_addFormView`, and thus refers to missing extension points as reported at ckeditor/ckeditor5#9730. See-also: ckeditor/ckeditor5#4765 See-also: ckeditor/ckeditor5#4793 See-also: ckeditor/ckeditor5#9730
I'm surprised this hasn't gotten more traction. Like @mmichaelis, I'm trying to set more attributes on |
@quicksketch, you also may want to take a look at #13594, where I sketched some required workaround to correctly handle custom attributes on cursor movement, unlinking, etc. Also, we learned late, that integrating these custom attributes into It also documents an important finding, that all attributes, that are meant to "belong to a link" should be prefixed with |
Thanks for the comments, I will try to take a deeper look at this topic. We also have a recent community PR (#13985) that informs about similar decorating issues and mentions the UI side as well. cc @niegowski. |
Thanks @mmichaelis, looks like you've really gone down the rabbit hole on CoreMedia. That will probably be a valuable resource for me. In the issue summary @mmichaelis suggests adding an event for const linkCommand = editor.commands.get( 'link' );
linkCommand.execute( 'http://example.com', {
linkTarget: '_blank',
} ); Or add a 3rd parameter to set arbitrary attributes and avoid over-complicating decorator configuration: const linkCommand = editor.commands.get( 'link' );
linkCommand.execute( 'http://example.com', {}, {
linkTarget: '_blank',
} ); It would be nice if the attribute could be configured to handle automatic upcast/downcast with a 1-to-1 value, but that's not too difficult to do through the existing conversion APIs so I'd consider that optional. |
It seems a Drupal contrib module actually implemented almost exactly my second suggestion, extending the link execute event to accept a 3rd argument of arbitrary attributes: https://git.drupalcode.org/project/editor_advanced_link/-/blob/2.x/js/ckeditor5_plugins/editorAdvancedLink/src/editoradvancedlinkediting.js Although they added all the additional attributes directly to the balloon and I plan to use a CMS-provided modal, the solution there works just as well for making it so that additional attributes can be tracked and updated. |
There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue. |
This is still a desired API feature. Both Drupal and Backdrop are re-implementing a large swath of the |
📝 Provide a description of the improvement
The only extension point of
LinkCommand
up to now for custom attributes are manual and automatic decorators. But they only provide boolean logic rather than the possibility to add for example text attributes.What is required is an extension point to string attributes stored in model, like for example an attribute
linkTarget
which may take any values like (you guessed it)_top
,_blank
or any string for named targets.Trying to implement such a feature is not really feasible, especially as
LinkCommand
may change the document selection during execution.Efforts so far
LabeledFieldView
and append it afterurlInputView
.UnlinkCommand
I added a post-fixer listening to removal oflinkHref
attribute, which automatically applies removinglinkTarget
attribute. This works fine and does not provide any hassle with undo/redo.LinkCommand
I tried a post-fixer approach as well, by having a "fake" command bound to the submit-button, which stores the selected target attribute from UI and forwards it to a post-fixer.linkHref
attribute got added, where alinkTarget
attribute should be added as well.This is feasible as long as the
linkHref
attribute got changed. But it fails for example, as soon as only the target attribute needs to be changed. In this case thesetAttribute
triggered withinLinkCommand
does not record any changes (as there are none, obviously). So, there is nothing to fix afterwards.I skipped the idea to listen to
LinkCommand.execute
asLinkCommand
itself may change the document selection (it jumps to the end on collapsed selection for example). And it most likely would create additional undo-records where should be only one.For now I will continue this path, which may require to duplicate some code from
LinkCommand
for certain scenarios.Suggested API: Events
⚡ set:attributes
Plural, as also the manual decorators may have set attributes.
Event Data:
linkHref
; possibly an array of ranges, so that we don't need to fire events with the for-loop applyinglinkHref
to several ranges.This would be fired, for uncollapsed selection or for collapsed selection, if the current selection has a
linkHref
set, which is about to be changed.There is one special case, which needs extra effort: If selection is collapsed, but has no
linkHref
set, thelinkHref
will be written as text to the model. In this case, we either need a way of adding attributes to the selection or the event needs to be fired as well, but a range has to be explicitly created. The latter one may be the best choice, as the existing listener could just be re-used.It is important, that this event is fired right before the selection adjustment triggered in some paths within
LinkCommand
.Implementors then only should take care in the
selection.collapsed
state, to also callwriter.removeSelectionAttribute
, so that when continuing typing, this custom attribute is not added to the following text.Possible Clash with Manual Decorators
At least in the given example, the approach may clash with manual decorators adding a
target
attribute as well. For my approach I will just document, that you must not use them.📃 Other details
Link
If you'd like to see this improvement implemented, add a 👍 reaction to this post.
The text was updated successfully, but these errors were encountered: