Open porg opened 1 year ago
The paste handler for links uses isURL
to determine if the text is a link.
Under the hood, it just uses new URL()
to try creating a url instance, and return false if it fails. I don't think we can allow every possible URIs to be pasted as links (imaging pasting relative links). Whether anchor text should be treated as a link is up to discussion, one could also say that it's a hashtag and should be pasted as plain text too. Let's wait for other people's opinions if we all think that this is unexpected and confusing to work with :)
@kevin940726 Thanks for identifying the responsible code and explaining how it works.
@all regarding the UX aspects:
tel://
or ftps://
or file://
or intranet-app://
on purpose — Why forbid it?The negative implications of the limitating clipboard pasting of various URL/link formats far outweights the possibility of a false positive, which is very unlikely, as I will prove now:
/topic-a
or /topic-a/
or /topic-b/subtopic-x/
are not common in prose text.subtopic-y/
or ./cats/
or ../topic-x/
are not normal prose text either.this/that
or deep/deeper/deepest
could be normal valid prose text indeed.#topic
could be a hashtag text.#topic-with-longer-title
cannot be hashtags as those are without hyphens.#
character in front of an existing word designated as a hashtag or you will simply paste the hashtag at the cursor.Misinterpretation is very unlikely. Plenty workarounds available. Very good reasons to handle link pasting as easy and flexible as possible!
Anchor links with multiple hyphen separated words like
#topic-with-longer-title
cannot be hashtags as those are without hyphens.
This depends on what the hashtag platform you're copying from. Some platforms allow hashtags with hyphens and it's implemented differently for each platform.
Slashes and hashbang are pretty generic and could be seen in other languages or context as well. It's always a trade-off. Unless we have more feedback and data collected, I don't think we should rush into any solution.
This discussion could be a great starting point though. I appreciate your feedback a lot! Let's wait for others' inputs or decide how we can make this more visible to others if you think it's worth pursuing!
Thanks for pointing out that 2a5) #hashtags-with-multiple-words-hyphen-separated are maybe found on some hashtag platforms, so maybe in 0.2% of use cases this plays a role.
But then again, the strongest argument, overarching all others, is anyhow 2b2) the interaction in that scenario: That selecting a single word or multiple words/sentences/paragraphs and then pasting a continuous string without spaces (different forms of links), is highly unlikely, and if intentional plenty alternatives are available: just insert at cursor, or first delete then insert at cursor.
Independently of this, overall, let's have some further input:
CC: @getdave @mtias @annezazu @talldan @mrfoxtalbot
Great discussion here - thank you.
I've recently raised a PR to make the "URL" detection a little looser and based more on sensible heuristics rather than hard rulesets.
https://github.com/WordPress/gutenberg/pull/51011
I think we should test that PR and see if it resolves the issue described.
Thanks for the appreciation!
Is there a test server instance which runs this your PR? I would test there and give you feedback then. I now PM you on WordPress Slack, so that you could potentially give me credentials, if a test server exists.
WordPress Gutenberg PR 51011 as of 2023-06-06 11:11 +0200
Thank you. Any chance you could paste your test content here in text form? That will allow me to write tests against these criteria 🙇
Yes. Will follow soon.
Oh I just realised @kevin940726 said that this code was responsible
That's outside the scope of https://github.com/WordPress/gutenberg/pull/51011 as it's a separate area of the codebase. Apologies for confusion here. Plain text on that test data would still be useful however.
<!-- wp:columns {"align":"wide"} -->
<div class="wp-block-columns alignwide"><!-- wp:column -->
<div class="wp-block-column"><!-- wp:heading -->
<h2 class="wp-block-heading">Pasteboard</h2>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>#one
#two-words
/elsewhere
/elsewhere/
/elsewhere/dreaming
/elsewhere/dreaming/
wordpress.org
www.wordpress.org
https://wordpress.org
wordpress.org/plugins
www.wordpress.org/plugins
https://wordpress.org/plugins
wordpress.org/plugins/
www.wordpress.org/plugins/
https://wordpress.org/plugins/
file:///Applications/
ftp://ftp.gnu.org/gnu/diffutils/
tel://+1-877-273-3049</code></pre>
<!-- /wp:code --></div>
<!-- /wp:column -->
<!-- wp:column -->
<div class="wp-block-column"><!-- wp:heading -->
<h2 class="wp-block-heading">Rich Text Section</h2>
<!-- /wp:heading -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Anchor links</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>with one word: One</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Anchor link with two words: Two Words</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Absolute path link Level 1: Elsewhere</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Absolute path link Level 1 with slash: Elsewhere</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Absolute path link Level 2: Dreaming</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Absolute path link Level 2 with slash: Dreaming</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Links to Homepage</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Homepage as URL as domain name only: WordPress</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Homepage as URL on www subdomain: WordPress</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Homepage as full URL with scheme and on main domain: WordPress</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Links to page without final slash</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>URL without scheme with domain to page: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>URL without scheme with www subdomain to page: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>URL with scheme on main domain to page: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Links to page with final slash</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>URL without scheme with domain to page/: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>URL without scheme with www subdomain to page/: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>URL with scheme on main domain to page/: Plugins</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Custom Scheme Links</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>File scheme link: Apps</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>FTP scheme link: GNU Diffutils</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Telephone Number: Call support</p>
<!-- /wp:paragraph --></div>
<!-- /wp:column --></div>
<!-- /wp:columns -->
<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity"/>
<!-- /wp:separator -->
<!-- wp:heading -->
<h2 class="wp-block-heading">Local Link Targets</h2>
<!-- /wp:heading -->
<!-- wp:heading {"level":3,"anchor":"link-target-one"} -->
<h3 class="wp-block-heading" id="link-target-one">One</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Anchor links lead to me which could also be interpreted as hashtag text. But its unlikely that you first select a word to then replace it with a hashtag. And if the less likely scenario still has plenty workarounds: Select, delete, then paste the literal hashtag. Or paste the hashtag and then remove outdated text portions.</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3,"anchor":"link-target-one"} -->
<h3 class="wp-block-heading" id="link-target-one">Two Words</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Anchor links lead to me which could be interpreted as hashtags on platforms which allow multiple hyphen separated words. This in itself is very unlikely. And it becomes even more unlikely that you select multiple words to then replace with a multi-word-hashtag. And again for this edge case various workarounds exist. Hence it has to make place to first and foremost serve the commonplace scenario conveniently.</p>
<!-- /wp:paragraph -->
Scope here or elsewhere — I'd appreciate if someone changes it. And I hope that my concrete test data set can help for test evaluation.
Reproduction
#introduction
to your clipboard with⌘-C
.⌘-V
Result
Actual: The anchor link gets pasted as raw text and replaces the selected text.
Proposed: The selected text gets a link to a local anchor. HTML result should be:
As mentioned in the<a href="#introduction">intro</a> you have…
Workaround: Open link dialog with
⌘-K
and paste the anchor link there and then apply it.Video Recording of status quo and workarround