-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Added autolink typing support #2197
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't look into code as there are several issues with the behaviour:
- After autolinking, there is no undo step to return to unlinked text.
- I'm not sure, if all the commit keys should be supported. E.g. pressing left arrow suggest that I made mistake in the text I've just written. There is no need to convert it into link. Right arrow in most cases won't do anything as link will be the last element inside the editor. I also have doubts about up arrow and down arrow, end, home, page down and page up. These keys are used for scrolling content. It's quite unexpected that content is replaced while pressing them. Word replaces links
- At the same moment Tab is not working as it focuses the next element after the editor, even when
tab
plugin is loaded.
plugins/autolink/plugin.js
Outdated
* @member CKEDITOR.config | ||
*/ | ||
CKEDITOR.config.autolink_emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/g; | ||
// Regex by (https://www.w3.org/TR/html5/forms.html#valid-e-mail-address). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it's no longer in HTML 5.x, now it's only in HTML LS.
aa2fc87
to
8700c2d
Compare
I refactored code to expose I also changed undo behavior - now it requires 3 undo steps to remove a link:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
The third undo step seems totally unnecessary and confusing, especially when user typed something after the link:
- Type
https://cksource.com
. - Press Space.
- Type something.
- Press Undo twice.
Instead of unlinking we just deleted space after the link.
- Type
-
Enter seems to stop working in built version of editor. It's probably connected with
enterkey
plugin. -
Can't the part of new logic (especially connected with
textmatch
plugin) be used inside paste handler? In fact I'm quite sure that binding currentkeydown
handler (without, of course, check for commit keys) toafterPaste
event would do the trick and would greatly reduce complexity of the whole plugin. -
There is some strange bug that removes part of the content between two links if they are divided by one word.
- Type
https://cksource.com
. - Press Space.
- Type
Comandeer
. - Press Space
- Type
https://ckeditor.com
. - Press Space
Instead of two links with
Comandeer
between, we gethttps://cksource.com Comhttps://ckeditor.com
. It's reproducible only in Blink and only if both links have the same beginnings (eg.http://cksource.com
andhttp://ckeditor.com
but nothttps://cksource.com
andhttp://ckeditor.com
as protocols don't match). Not sure if it isn't connected with fix for Mentions dropdown doesn't show up after activating styling #2038. - Type
/** | ||
* The [Autolink](https://ckeditor.com/cke4/addon/autolink) plugin keystrokes used to finish link completion. | ||
* | ||
* ```javascript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We traditionally use indent-based code blocks in our docs.
Webkit issue was caused by moving selection at the end of the link ( which is not required on this browser ) and in the result, it created |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, now I understand why there were 3 steps for autolink, not two… With the current version it's actually impossible to not autolink something on typing, e.g.
- Type https://www.comandeer.pl
- Press Space.
- Press Ctrl/Cmd + Z.
Expected:
In Word undo removes link, but leaves space. Second undo removes everything (URL + space).
Actual:
In our implementation undo removes link with space. Adding that space also autolinks URL, so we're back to square one…
In both cases (three step and two step but without keeping space) our Undo behaves quite counter-intuitive. But, honestly, I don't know if there is any good solution to this issue (due to how our Undo works).
There is also one other issue with undo: after unlinking URL is selected. I'm not sure how to control selection in our Undo, but it's definitely worth further research.
plugins/autolink/plugin.js
Outdated
|
||
// If we found "<" it means that most likely there's some tag and we don't want to touch it. | ||
if ( data.indexOf( '<' ) > -1 ) { | ||
var matched = CKEDITOR.plugins.textMatch.match( editor.getSelection().getRanges()[ 0 ], matchCallback ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code here is nearly the same as in afterPaste
handler above. I'd try to move it into separate, dedicated function. Condition – the only part that differs – could be passed as parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could look something like that:
function autolink( editor, condition ) {
var matched = CKEDITOR.plugins.textMatch.match( editor.getSelection().getRanges()[ 0 ], matchCallback );
if ( !condition( matched ) ) {
return;
}
insertLink( matched );
}
editor.on( 'paste', function( evt ) {
// Pasted text may be encoded. Decode it so we will be able to compare its length with match.
var text = CKEDITOR.tools.htmlDecode( evt.data.dataValue );
// Attach afterPaste event here to avoid race condition between events.
editor.once( 'afterPaste', function() {
autolink( editor, function( matched ) {
return matched && matched.text.length === text.length;
} )
} );
} );
[…]
editor.on( 'contentDom', function() {
var commitKeystrokes = editor.config.autolink_commitKeystrokes || CKEDITOR.config.autolink_commitKeystrokes;
editor.editable().on( 'keydown', function( evt ) {
if ( CKEDITOR.tools.indexOf( commitKeystrokes, evt.data.getKey() ) == -1 ) {
return;
}
autolink( editor, function( matched ) {
return matched;
} );
// Handle event ASAP thus some plugins may change
// editor selection or cancel keydown events e.g. wysiwygarea, enterkey.
}, null, null, 0 );
} );
I extracted #2197 (review) issues into separate tickets so they will be easy to track and don't block this feature. See #2221 and #2220. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're lacking unit and manual tests for Blink issue.
if ( data != evt.data.dataValue ) { | ||
evt.data.type = 'html'; | ||
} | ||
if ( !CKEDITOR.env.webkit ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it Blink only issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it occurs also on Edge.
The unit test for continuous typing is disabled for WebKit thus it will result in a false negative. Although I kept manual test for each browser so we will have some safety net for the issue. |
I added an additional manual test for filling char sequence Webkit issue. However, I wasn't able to add a unit test for this issue thus Webkit behaves differently when manually typing text inside the editor and when changing editors content using javascript. In manual testing Webkit doesn't extend anchors when typing, however inserting text using javascript changes anchors text node which gives invalid testing results. The issue doesn't exist in normal feature path, it was caused by special treatment for Firefox and Edge where anchors are extended by typing, so I believe the manual test could be enough for this case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one issue in WebKit, connected with the fix for filling char sequence issue:
- Paste
https://comandeer.pl
. - Paste
http://comandeer.pl
(just after the first pasted link, without any space or selection change)
Only one link is created as the selection is still inside the first link.
<div id="editor"></div> | ||
|
||
<script> | ||
CKEDITOR.replace( 'editor' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should be ignored also in IE as our plugin does not run there.
plugins/autolink/plugin.js
Outdated
|
||
editor.on( 'contentDom', function() { | ||
var commitKeystrokes = editor.config.autolink_commitKeystrokes || CKEDITOR.config.autolink_commitKeystrokes; | ||
editor.editable().on( 'keydown', function( evt ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have dedicated event for key handling in editor, key
.
plugins/autolink/plugin.js
Outdated
return matched; | ||
} ); | ||
|
||
// Handle event ASAP thus some plugins may change |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we should interfere with other plugins in such way. If something is trying to stop keyboard event propagation, then it has some important reason for doing it.
Rebased onto latest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
What is the purpose of this pull request?
New feature
Does your PR contain necessary tests?
All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.
This PR contains
What changes did you make?
I used
textmatch
plugin to provideautolink
typing support. Pattern matching is a little complicated but it's required if we want to utilize the same URL/Email regex for both pastings from clipboard and typing.Closes #1815