Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
To recreate
- Insert one link
- type some text
- Insert the same name again
Result: mangled code because first instance is also replaced. Replace function should only replace the last occurence.
Comment | File | Size | Author |
---|---|---|---|
#10 | ckeditor_mentions-insert-code-replacement-2030269-10.patch | 9.18 KB | rudiedirkx |
Comments
Comment #1
rudiedirkx CreditAttribution: rudiedirkx commentedNot the last occurrence. The relevant occurrence. The last occurence might not be the one you're typing on. It might not even be the same exact name you're typing. You might have search for
@alber
first and@alb
second. You must somehow remember where the user was typing =)Comment #2
askibinski CreditAttribution: askibinski commentedI tried the whole "remember where the user was typing" idea, but it was a complete nightmare. As far as I could see there is no ckeditor function for this and trying to figure it out yourself is very difficult.
But you are right it's not necessarily the last occurence.
So instead, I'm thinking (aloud) that we could use the methods (A,B,C):
example:
typed = "@rudie"
A: look for "@rudie" without a link surrounding it
B: just replace "@rudie" with the whole name without "@" thus removing the problem for next insert.
C: replace any occurence of "@rudie" BUT use a character entity for "@" (@)
I would prefer A or B.
C seems a bit dirty and I'm not sure if it at all works or if it would cause other problems.
Comment #3
rudiedirkx CreditAttribution: rudiedirkx commentedI think B and C are flawed because I could already have added a user
@rudiedirkx
and then want to add a user@rudie
by typing@rudi
. The@rudie
from the last@rudi
would replace the "rudie" in@rudiedirkx
, right?A might work, IF you're always adding a link.
Tricky stuff.
Another idea: remember the element you're in. CKEditor has methods for that. I've used that in CKEditor 3 before. If you're typing inside a P, you can keep that P and replace only its content. There could still be several
@mentions
in that P, but that problem will always exist without remembering exactly where the cursos was.Comment #4
askibinski CreditAttribution: askibinski commentedRight. Tricky stuff indeed. But [A] should cover 99% of all usecases I think. Except perhaps when an email adress starts with the same letters, but that seems like an edge case.
Anybody now how to enhance below regexp (js) to make it replace "only $typed when $typed is not already link (between a href tag)"?
Comment #5
mcoirault CreditAttribution: mcoirault commentedI'm working on that regexp to fit the A case. If I can, I'll try to cover that e-mail edge case.
Comment #6
mcoirault CreditAttribution: mcoirault commentedI'm struggling with that regex. Here is my work so far : http://www.rubular.com/r/sHOuAa7vpE
The point is to search for
not(an opening <a>) @user not(a closing </a>)
.Any clue how we could make those not(substring) work properly?
Comment #7
rudiedirkx CreditAttribution: rudiedirkx commentedRegex and HTML are always a bad idea (HTML is not regexable, that's why DOCTYPE/DTD was invented). I'm pretty sure it's easier to just remember where your cursor is (the element, not the position) and then text-replace its contents.
Otherwise MAYBE negative lookahead and
</a>
will do the trick. Nope. Negative lookahead will match until a zero-width match (like</a>
). It won't stop the entire match. (I might be wrong.)Maybe it is possible with regex if you make a few assumptions, like
<A>
tag<A>
attributesbut I don't know it.
Comment #8
askibinski CreditAttribution: askibinski commentedThe element you say, not position. But the element will be most likely a
<p>
and contain multiple mentions... So that won't be 100% foolproof. In fact when I would just start typing and mention the same name twice in a row (without enter) it would fail.I agree regex is not the best solution but I wonder if a slightly different approach might be easier/better:
When typing an "@", we could maybe put this character between a temporary span as a marker. For example:
<span>@</span>
.Then, when inserting, we swap the span out. But it will be easy to locate the string because it will always be something like "
<span>@</span>rudie
". Or am I overlooking something?Of course, on cancel/stop observing, the span should be swapped out too.
Comment #9
rudiedirkx CreditAttribution: rudiedirkx commentedI fixed it! Beautifully too! Now all that's left is to position the caret so you can keep typing. I'll upload a patch in a minute.
Comment #10
rudiedirkx CreditAttribution: rudiedirkx commentedStupid Drupal file upload crashed after I typed a nice message, so fuck it. See attached patch.
Comment #11
askibinski CreditAttribution: askibinski commentedThanks! Will test it asap.
Comment #12
askibinski CreditAttribution: askibinski commentedThe replacing seems to work well indeed, solving this issues problem. However, the patch needs some work:
Also I think the menu callback needs to have:
Comment #13
askibinski CreditAttribution: askibinski commentedFixed and comitted to dev!
I fixed above issues and also added a check to see if the view has results. If none, the html is not appended (else an empty container might appear).
Comment #14
askibinski CreditAttribution: askibinski commentedThis resulted however, in a bug with IE9/10 (didn't test it with IE8) which now makes inserting multiple mentions in IE impossible:
#2033739: IE9+ replacement problems when inserting existing strings
Comment #15.0
(not verified) CreditAttribution: commentedbold