Skip to content

Commit

Permalink
Changed linkification on paste to match URL parsing within the linkif…
Browse files Browse the repository at this point in the history
…ication reaction (Resolves superlistapp#2031) (superlistapp#2045)
  • Loading branch information
matthew-carroll authored and quaaantumdev committed Jun 1, 2024
1 parent 1df91dd commit d066ced
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 77 deletions.
19 changes: 14 additions & 5 deletions super_editor/lib/src/default_editor/common_editor_operations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import 'dart:ui';
import 'package:attributed_text/attributed_text.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:linkify/linkify.dart';
import 'package:super_editor/src/core/document.dart';
import 'package:super_editor/src/core/document_composer.dart';
import 'package:super_editor/src/core/document_layout.dart';
import 'package:super_editor/src/core/document_selection.dart';
import 'package:super_editor/src/core/editor.dart';
import 'package:super_editor/src/default_editor/default_document_editor_reactions.dart';
import 'package:super_editor/src/default_editor/list_items.dart';
import 'package:super_editor/src/default_editor/paragraph.dart';
import 'package:super_editor/src/default_editor/selection_upstream_downstream.dart';
Expand Down Expand Up @@ -2381,11 +2383,18 @@ class PasteEditorCommand implements EditCommand {

for (final wordBoundary in wordBoundaries) {
final word = wordBoundary.textInside(pastedText);
final link = Uri.tryParse(word);

if (link != null && link.hasScheme && link.hasAuthority) {
// Valid url. Apply [LinkAttribution] to the url
final linkAttribution = LinkAttribution.fromUri(link);
final extractedLinks = linkify(
word,
options: const LinkifyOptions(
humanize: false,
looseUrl: true,
),
);
final int linkCount = extractedLinks.fold(0, (value, element) => element is UrlElement ? value + 1 : value);
if (linkCount == 1) {
// The word is a single URL. Linkify it.
final uri = parseLink(word);

final startOffset = wordBoundary.start;
// -1 because TextPosition's offset indexes the character after the
Expand All @@ -2394,7 +2403,7 @@ class PasteEditorCommand implements EditCommand {

// Add link attribution.
linkAttributionSpans.addAttribution(
newAttribution: linkAttribution,
newAttribution: LinkAttribution.fromUri(uri),
start: startOffset,
end: endOffset,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ class LinkifyReaction implements EditReaction {
final int linkCount = extractedLinks.fold(0, (value, element) => element is UrlElement ? value + 1 : value);
if (linkCount == 1) {
// The word is a single URL. Linkify it.
final uri = _parseLink(word);
final uri = parseLink(word);

text.addAttribution(
LinkAttribution.fromUri(uri),
Expand Down Expand Up @@ -799,21 +799,24 @@ class LinkifyReaction implements EditReaction {
if (updatePolicy == LinkUpdatePolicy.update) {
changedNodeText.addAttribution(
LinkAttribution.fromUri(
_parseLink(changedNodeText.text.substring(rangeToUpdate.start, rangeToUpdate.end + 1)),
parseLink(changedNodeText.text.substring(rangeToUpdate.start, rangeToUpdate.end + 1)),
),
rangeToUpdate,
);
}
}
}

/// Parses the [text] as [Uri], prepending "https://" if it doesn't start
/// with "http://" or "https://".
Uri _parseLink(String text) {
final uri = text.startsWith("http://") || text.startsWith("https://") //
? Uri.parse(text)
: Uri.parse("https://$text");
return uri;
}
/// Parses the [text] as [Uri], prepending "https://" if it doesn't start
/// with "http://" or "https://".
// TODO: Make this private again. It was private, but we have some split linkification between the reaction
// and the paste behavior in common_editor_operations. Once we create a way for reactions to identify
// paste behaviors, move the paste linkification into the linkify reaction and make this private again.
Uri parseLink(String text) {
final uri = text.startsWith("http://") || text.startsWith("https://") //
? Uri.parse(text)
: Uri.parse("https://$text");
return uri;
}

/// Configuration for the action that should happen when a text containing
Expand Down
Loading

0 comments on commit d066ced

Please sign in to comment.