While working on a patch for Linkit I failed to set a custom attribute as link text without completely overriding the plugin.js of drupallink.
drupallink uses this code to create the link text: var text = new CKEDITOR.dom.text(returnValues.attributes.href.replace(/^mailto:/, ''), editor.document);
Do I have to override the complete plugin to use another attribute returned by the editor dialog?
Eventually the following code fragment would be an option (as a patch), but maybe there is a better way.
// Use link URL as text with a collapsed cursor.
if (range.collapsed) {
// Shorten mailto URLs to just the email address.
var text = new CKEDITOR.dom.text(returnValues.attributes.href.replace(/^mailto:/, ''), editor.document);
if (editor.config.hasOwnProperty('drupalLink_attributeText') && returnValues.attributes.hasOwnProperty(editor.config.drupalLink_attributeText) && returnValues.attributes[editor.config.drupalLink_attributeText].length) {
// Use custom attribute as link text.
text = new CKEDITOR.dom.text(returnValues.attributes[editor.config.drupalLink_attributeText], editor.document);
}
range.insertNode(text);
range.selectNodeContents(text);
}
| Comment | File | Size | Author |
|---|---|---|---|
| #103 | 2741945-103-core-10.4.patch | 3.2 KB | duaelfr |
| #103 | 2741945-103-ckeditor.patch | 8.1 KB | duaelfr |
Comments
Comment #2
wim leersWhat exactly were you trying to do? I don't quite understand.
Comment #3
stborchertSorry, if this sounds confusing. The issue I'm talking about is #2653246: Override link text using the title attribute.
Using LinkIt you are able to add links in CKEditor in a very comfortable way. Additionally, one can enter some attributes for the link (using Editor advanced link).
Unfortunately with the newest version of LinkIt is it not possible anymore to set the link text because the module uses the default Drupal plugin for links (drupallink).
My question is now: what is the best way to override the inserted link text? Do we need to override the complete plugin.js of drupalling or is it better to create a patch for drupallink so this can be done using a small function (or something else)?
Comment #4
wim leersOverride it in the
EditorImageDialogform's submit handler.Comment #5
wim leersOh wait, I see you're asking it for #2653246: Override link text using the title attribute. Which means you don't care about how
editormodule does things, you care about actual CKEditor plugin code.My answer is valid for LinkIt 5, you won't need to modify the CKEditor plugin anymore.
Comment #6
stborchertBut, uhm ... I'm confused, now. drupallink/plugin.js uses the following code to get the link title:
var text = new CKEDITOR.dom.text(returnValues.attributes.href.replace(/^mailto:/, ''), editor.document);I've actually no idea, how to use a different attribute here (i.e. "title") by simply overriding the submit function of the dialog :|
Comment #7
stborchertI must admit, I'm a little bit lost.
Let's assume,
returnValuescontains not only "href" as attribute, but also "title". How do I use this attribute as the link text without overriding drupallink/plugin.js?Comment #8
wim leersI'd recommend looking at https://www.drupal.org/project/editor_advanced_link as an example. That's how you can get additional attributes to work.
But I think that is not what you are asking. I think you're asking for help with CKEditor JS code. This is not the right place for that. I believe they provide support on Stack Overflow.
Comment #9
wim leersComment #10
stborchertI guess, we are talking of different things here. Editor advanced link adds some attributes to the link created by drupallink/plugin.js, so in case of
<a href="/node/1">/node/1</a>we can create links like<a href="/node/1" title="First article">/node/1</a>.With Linkit 4.x it was possible to create links like
<a href="/node/1" title="First article">First article</a>(the *text* of the link is created using the title attribute). This was possible, because the maintainer of Linkit has used a custom CKEditor plugin.In version 5.x this custom plugin is gone, so drupallink/plugin.js is used. I don't see a way to override the link *text* with a value of an attribute without using a custom CKEditor plugin since the text is hardcoded to
returnValues.hrefin drupallink/plugin.js.Comment #11
gifad commented@stBorchert : The patch you submitted in Linkit queue seems to be perfectly valid in core link plugin.
Additionally, it would be a nice addition for the users of editor advanced link.
Attached, your patch, just rerolled.
Comment #12
wim leersThe reason the LinkIt module doesn't do that anymore is explained in detail elsewhere. In short: it doesn't work when the title of linked content changes, or when a translated version is linked.
I don't see a valid use case for this?
Comment #13
anon@Wim Leers: As I see it, it is a request for adding "other" text to the element, not the source link or selected value.
Cosider the following where the bold text is the selected text.
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
Adding a link to /example
"Lorem ipsum dolor sit (Cursor here) amet, consectetur adipiscing elit." (Nothing selected)
Adding a link to /example
See the second example. Here the user has not selected any text to use for the element text. The URL will then be used by the default link plugin as the element text.
This is what the issue is about. The ability to configure the plugin to use some other texts here.
Comment #14
wim leersAhhh! Now I get it. Thanks, that really helps :)
So then the proposal here is that if there is a value specified for the
titleattribute, that we use that as the default link text instead of using the URL itself as the default link text?Comment #15
anonBasically yes.
Tho I'm not sure if the patch provided in #11 is the correct way to go. There might be a better structure that don't include the "attribute" name as it could be kind of confusing to other devs.
So maybe:
If there is a value specified for the element text, we use that as the default link text instead of using the URL itself as the default link text.
Comment #16
wim leersYou mean: you'd like to be able to specify link text, independently of the
titleattribute?Comment #17
stborchertThanks, @anon for explaining it better :)
My initial idea (if there would be no other way) was to allow overriding the way, the link text is being "generated" (if there is no text selected in the editor). Having this possibility, other modules may use
returnValues.attributes.titleor something completely different.So, yes ... specifying the link text independently of the
titleattribute would be great.Comment #18
wim leersOk, so that then is acceptable. It's a valid use case, although an edge casey one. We should retain the current behavior by default (changing it would break the expectation 99% of users have), but it's fine for contrib modules to override this in particular cases.
So then this would need to:
/editor/dialog/image/basic_html, because the dialog needs to be able to show the current data.Currently:
we'd need to add to that:
I think
textis acceptable, since it's not a valid attribute on<img>, so we can repurpose it. Thoughts about that?core/modules/ckeditor/js/plugins/drupallink/plugin.jsmuch like the existing patch does.Most painfully… this will need tests. JavaScript tests. Of which we have none yet for CKEditor yet. Because we've only had the ability to do JS tests since a few months. Sorry about that :(
Comment #19
anonDoes this means that there will be an additional input field in the dialog used for "texts"?
How should other modules alter this?
Is it an absolute requirement for js-tests in order to get a possible path committed to 8.2.x?
Comment #20
wim leersNot in Drupal core. But contrib modules could do that, yes. Of course, a contrib module can choose to not expose an
input[type=text]and instead set a value based on some logic in the submit handler.See above.
I'm not sure. It's the early days of JS tests, but I know that several other patches that were RTBC were un-RTBC'ed specifically because we can now write JS tests and hence they should have JS tests.
Comment #21
stborchertBack to "needs work". I'll have a look into this today.
Comment #22
stborchertSeems, "today" is a very flexible term ...
Anyway, here is a first draft of the patch. Unfortunately I couldn't get the javascript test to work, since the link dialog simply wouldn't open when the test clicks on the ckeditor button.
Any idea what is wrong in
DrupalLinkTest?PS: a patch to test overriding the link text can be found in #2653246-13: Override link text using the title attribute
Comment #24
wim leers#22:
My best guess is that CKEditor hasn't finished loading yet? Can you let your functional JS test first verify that the expected "DrupalLink" button actually exists?You already verify all that! No idea then :(However, if we look at the test output, it actually looks like you're hitting a bug in GastonJS:
However, this is also causing a fail in
CKEditorTest. Because there's now two text formats/editors being installed, instead of one. You shouldn't modifyckeditor_testto install additional formats/editors. You should instead let your test create the desired formats/editors! Then that problem goes away. :)Are you at DrupalDevDays Milan? Find dawehner, he will know how to debug that PhantomJS/GastonJS bug.
Comment #25
wim leersForgot to say: awesome work here — thanks! :)
Comment #26
stborchertJup, already noticed this and am on it :)
Unfortunately not, but I will talk to him afterwards.
I hope to create the next patch draft today ...
Comment #27
wim leersGreat — thanks so much!
Comment #28
stborchertNext try (
DrupalLinkTestwill fail because of the known problem).Its very strange, why the dialog does not open (it had opened exactly 2 times during my times and I don't know, why ... running the test again without modifying something and the dialog didn't open). I've looked at the tests provided by Views and couldn't find any differences :/
Comment #30
stborchertThanks to the help of dawehner I could finally fix the tests.
I'm not very happy with the javascript code I execute in the test but this was the only way to access the content of the ckeditor body.
$session->switchToIFrame()didn't work here, because the iframe doesn't have a name :/Comment #31
anonIndent errors.
Indent errors
Use arrays are use everywhere eles, should be used here aswell.
I have fixed this issues in this patch.
Comment #32
anonThe message should be positive.
The editor has
notbeen loaded.The message should be positive.
Inserted link text does
notequals expected text.Comment #33
anonFixed some coding standards and the test messages.
Comment #34
anonShould we open a new issue to add a name to the iframe? Other tests would benefit from that, i.e. DrupalImage and contrib modules like Linkit.
Comment #35
stborchertDone ;)
https://dev.ckeditor.com/ticket/14719
Comment #36
anonIs it ok to use simpletest classes in these tests?
Could be single lines?
Comment #37
anon@stBorchert: Great, thanks!
Lets see what they say about this. If they don't like it, can Drupal add a name attribute itself in any way?
Comment #38
stborchertWell,
ExposedFilterAJAXTestis doing this also, so I guess it is ok.Indeed. I had extra checks to test if the elements are accessible but removed this. So this can be merged into single lines.
Comment #39
anonThis patch contains fixes mentiond in #33.
Comment #40
anonCrap, messed up when re-rolled.
Comment #41
anonComment #42
anonThere is no need to create a node type in EditorLinkDialogTest.
Also made some minor cleanup.
Comment #45
anonRetriggered tests.
Comment #47
duaelfrWouldn't it be a good idea to always show that text field?
I mean, on most common tools (Word, GMail, Gdocs, etc.) when you want to create a link, the UI shows you the text of the link, prepopulated if something was selected. I think it's more convenient for the end user and probably less scary.
Google Docs add a link while a text is selected
Google Docs add a link while no text is selected
LibreOffice add a link while a text is selected
LibreOffice add a link while no text is selected
GMail add a link while a text is selected
GMail add a link while no text is selected
Comment #48
jonathanshawWhat your propose based on Gmail and Libre Office seems good to me. However, the maintainer rejected an additional input box like this in #20.
How about we keep this issue confined to adding to the API the ability to specify the text; then in an follow-up issue we can endlessly debate the best default UI for core? That way we unblock contrib/custom more quickly.
Comment #50
jonathanshawNeeds reroll against 8.3
Comment #51
MaskyS commented@jonathanshaw I think that's a good idea... Let's re-roll this in the meanwhile.
Comment #52
MaskyS commentedHi, I don't think this needs a re-roll since it applied cleanly on 8.3.x. Here is an interdiff for the last two patches though.
Comment #53
MaskyS commentedComment #56
jonathanshawComment #58
oknateThis patch is related to this issue, but reduces the scope of the changes significantly. I just need a way for other modules to override the default text, specifically linkit. If you click in ckeditor without highlighting text, it displays the href as the text of the link. There's no way, short of patching core for other modules to change this.
Comment #59
oknateThis is same as #58, but rerolled because #58 wasn't working on Drupal 8.4.2
Comment #62
wim leersWas reminded of this via #2640398-21: Allow <drupal-entity> elements to be inline CKEditor Widgets. Completely lost track of this. My focus has been API-First for the past two years. Very sorry.
This looks great.
@oknate: while well-intentioned, those other changes are just test coverage. I think having test coverage for this makes sense. So I'm bringing back @anon's patch from #42, but I do prefer your handling of the text over @anon's, because there is no
textattribute.Rerolling…
Comment #63
wim leersThis is a straight rebase of #42.
Comment #64
wim leersThis only allows the server to override the text on the client; the client doesn't pass the current value to the server.
textis not an attribute, so this should not be['attributes']['text'], but['text'].#58 did this better IMHO. This keeps the name
text, but stops putting it underattributes.This is repeating the exact same complex logic twice. Let's move it to a helper.
In the time that has passed, it's the
Editorthat became expected, not theFilterFormat.Nit: inheritdoc.
Comment #65
wim leersI messed that up.
Comment #66
wim leersI believe this can become quite a bit simpler.
Comment #73
firewaller commented+1
Comment #75
lukusHi there .. I've also come to this issue via (https://www.drupal.org/comment/12335702#comment-12335702).
Feels like all of the solutions for a particular problem I'm facing point towards LinkIt as the best approach.
I'm wondering what the status of this is now? Is there anything I can help out with?
Comment #76
jonathanshaw@lukus The failing test in #66 needs addressing.
Comment #77
ravi.shankar commentedPatch #66 not applying on Drupal 9.1.x.
Comment #78
akashkumar07 commentedComment #79
akashkumar07 commentedRerolled patch #66
Comment #80
akashkumar07 commentedComment #82
naresh_bavaskarComment #83
naresh_bavaskarPlease review, Fixing the failed test cases
Comment #84
duaelfrThank you all for moving this forward!
I did some testing and the patches does not entirely fill the issue, though.

Plus, I've noticed that you directly edited the plugin.js file instead of the plugin.es6.js file which is the current way to contribute JS in Core.
I'll try to provide a new patch today.
Comment #85
duaelfrHere we go.

I feel like we should extend the test coverage for some of these cases but I have no idea of how to do that for those with selected text or existing link editing.
PS: I moved the text field above the attributes in the Dialog so contrib modules won't have to play with weights to look like most common tools (cf #47) when they will transform the field's type.
Comment #86
jonathanshawI think these tests would be more robust and easier to understand if we were adding a link to a page other than the one we are on e.g. /admin/some/destination "Some link text"
Comment #87
jonathanshaw#85
In slack @lendude said that Googling suggested that double clicking a word was perhaps the best way to accomplish selecting text in a test. He also provided these helper methods which I paste here in case they're of any use.
Comment #88
lukusThis applies well for 8.9.x.
Comment #90
dbielke1986 commentedComment #92
potem commentedI think that most of the time users just customize the link text.
So I changed the
$form['text']['#type']totextfield, no need to use hooks or modules to override theEditorLinkdialogComment #93
potem commentedComment #94
Oscaner commented@potem upload fail for patch 2741945-92.patch. So i help him to re-upload.
This patch just update type 'value' to type 'textfield'.
Comment #97
quietone commentedCKEditor has been removed from core, CKEditor 4 is removed from Drupal Core in 10.0.0
Comment #98
stuart_wilkes_wellcome commentedThe existing patch was failing with Drupal 9.5 - so have re-rolled for that:
Comment #99
coopernet commentedPatch 2741945-98.patch failed to apply with drupal 9.5.1 php 8.1
Comment #100
segi commentedHi, I re-rolled the patch and tested with 9.5.0 and 9.5.2.
Comment #101
burnellw_cit commentedComment #103
duaelfrI needed that on D10 to delay an upgrade so I rerolled and split the patch.
If you need that feature you have to apply:
2741945-103-ckeditor.patchon the ckeditor module2741945-103-core-10.4.patchon Drupal Core (tested on 10.4 but might also work on previous 10.x versions)