Skip to content

Commit

Permalink
Merge pull request #6 from BazinC/mid_april24_midmay24_updates
Browse files Browse the repository at this point in the history
Mid april24 midmay24 updates
  • Loading branch information
BazinC authored May 15, 2024
2 parents 43c094f + f56a081 commit dcd0cb7
Show file tree
Hide file tree
Showing 61 changed files with 1,409 additions and 1,004 deletions.
8 changes: 8 additions & 0 deletions attributed_text/lib/src/attributed_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,14 @@ class AttributedText {
return spans.collapseSpans(contentLength: text.length);
}

/// Returns a copy of this [AttributedText].
AttributedText copy() {
return AttributedText(
text,
spans.copy(),
);
}

@override
bool operator ==(Object other) {
return identical(this, other) ||
Expand Down
71 changes: 71 additions & 0 deletions attributed_text/test/attributed_text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,77 @@ void main() {
expect(spans[1].end, 10);
});
});

group("copy >", () {
test("copies an AttributedText without any attributions", () {
final attributedText = AttributedText(
'Sample Text',
);

expect(attributedText.copy(), AttributedText('Sample Text'));
});

test("copies an AttributedText with attributions", () {
final attributedText = AttributedText(
'abcdefghij',
AttributedSpans(
attributions: [
const SpanMarker(
attribution: ExpectedSpans.bold,
offset: 2,
markerType: SpanMarkerType.start,
),
const SpanMarker(
attribution: ExpectedSpans.italics,
offset: 4,
markerType: SpanMarkerType.start,
),
const SpanMarker(
attribution: ExpectedSpans.bold,
offset: 5,
markerType: SpanMarkerType.end,
),
const SpanMarker(
attribution: ExpectedSpans.italics,
offset: 7,
markerType: SpanMarkerType.end,
),
],
),
);

expect(
attributedText.copy(),
AttributedText(
'abcdefghij',
AttributedSpans(
attributions: [
const SpanMarker(
attribution: ExpectedSpans.bold,
offset: 2,
markerType: SpanMarkerType.start,
),
const SpanMarker(
attribution: ExpectedSpans.italics,
offset: 4,
markerType: SpanMarkerType.start,
),
const SpanMarker(
attribution: ExpectedSpans.bold,
offset: 5,
markerType: SpanMarkerType.end,
),
const SpanMarker(
attribution: ExpectedSpans.italics,
offset: 7,
markerType: SpanMarkerType.end,
),
],
),
),
);
});
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ MutableDocument _createInitialDocument() {
AttributedSpans(
attributions: [
SpanMarker(
attribution: LinkAttribution(url: Uri.https('example.org', '')),
attribution: LinkAttribution.fromUri(Uri.https('example.org', '')),
offset: 30,
markerType: SpanMarkerType.start),
SpanMarker(
attribution: LinkAttribution(url: Uri.https('example.org', '')),
attribution: LinkAttribution.fromUri(Uri.https('example.org', '')),
offset: 35,
markerType: SpanMarkerType.end),
],
Expand Down
49 changes: 21 additions & 28 deletions super_editor/example/lib/demos/example_editor/_toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ class _EditorToolbarState extends State<EditorToolbar> {

final trimmedRange = _trimTextRangeWhitespace(text, selectionRange);

final linkAttribution = LinkAttribution(url: Uri.parse(url));
final linkAttribution = LinkAttribution.fromUri(Uri.parse(url));

widget.editor!.execute([
AddTextAttributionsRequest(
Expand Down Expand Up @@ -664,35 +664,28 @@ class _EditorToolbarState extends State<EditorToolbar> {
child: Row(
children: [
Expanded(
child: Focus(
child: SuperTextField(
focusNode: _urlFocusNode,
parentNode: _popoverFocusNode,
// We use a SuperTextField instead of a TextField because TextField
// automatically re-parents its FocusNode, which causes #609. Flutter
// #106923 tracks the TextField issue.
child: SuperTextField(
focusNode: _urlFocusNode,
textController: _urlController,
minLines: 1,
maxLines: 1,
inputSource: TextInputSource.ime,
hintBehavior: HintBehavior.displayHintUntilTextEntered,
hintBuilder: (context) {
return const Text(
"enter a url...",
style: TextStyle(
color: Colors.grey,
fontSize: 16,
),
);
},
textStyleBuilder: (_) {
return const TextStyle(
color: Colors.black,
textController: _urlController,
minLines: 1,
maxLines: 1,
inputSource: TextInputSource.ime,
hintBehavior: HintBehavior.displayHintUntilTextEntered,
hintBuilder: (context) {
return const Text(
"enter a url...",
style: TextStyle(
color: Colors.grey,
fontSize: 16,
);
},
),
),
);
},
textStyleBuilder: (_) {
return const TextStyle(
color: Colors.black,
fontSize: 16,
);
},
),
),
IconButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ Document createInitialDocument() {
"Built by the Flutter Bounty Hunters",
AttributedSpans(attributions: [
SpanMarker(
attribution: LinkAttribution(url: Uri.parse("https://flutterbountyhunters.com")),
attribution: LinkAttribution.fromUri(Uri.parse("https://flutterbountyhunters.com")),
offset: 13,
markerType: SpanMarkerType.start),
SpanMarker(
attribution: LinkAttribution(url: Uri.parse("https://flutterbountyhunters.com")),
attribution: LinkAttribution.fromUri(Uri.parse("https://flutterbountyhunters.com")),
offset: 34,
markerType: SpanMarkerType.end),
]),
Expand Down
49 changes: 21 additions & 28 deletions super_editor/example_docs/lib/toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ class _DocsEditorToolbarState extends State<DocsEditorToolbar> {

final trimmedRange = _trimTextRangeWhitespace(text, selectionRange);

final linkAttribution = LinkAttribution(url: Uri.parse(url));
final linkAttribution = LinkAttribution.fromUri(Uri.parse(url));

widget.editor.execute([
AddTextAttributionsRequest(
Expand Down Expand Up @@ -1156,35 +1156,28 @@ class _DocsEditorToolbarState extends State<DocsEditorToolbar> {
child: Row(
children: [
Expanded(
child: Focus(
child: SuperTextField(
focusNode: _urlFocusNode,

// We use a SuperTextField instead of a TextField because TextField
// automatically re-parents its FocusNode, which causes #609. Flutter
// #106923 tracks the TextField issue.
child: SuperTextField(
focusNode: _urlFocusNode,
textController: _urlController,
minLines: 1,
maxLines: 1,
inputSource: TextInputSource.ime,
hintBehavior: HintBehavior.displayHintUntilTextEntered,
hintBuilder: (context) {
return const Text(
"enter a url...",
style: TextStyle(
color: Colors.grey,
fontSize: 16,
),
);
},
textStyleBuilder: (_) {
return const TextStyle(
color: Colors.black,
textController: _urlController,
minLines: 1,
maxLines: 1,
inputSource: TextInputSource.ime,
hintBehavior: HintBehavior.displayHintUntilTextEntered,
hintBuilder: (context) {
return const Text(
"enter a url...",
style: TextStyle(
color: Colors.grey,
fontSize: 16,
);
},
),
),
);
},
textStyleBuilder: (_) {
return const TextStyle(
color: Colors.black,
fontSize: 16,
);
},
),
),
IconButton(
Expand Down
23 changes: 19 additions & 4 deletions super_editor/lib/src/default_editor/attributions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,29 @@ class FontSizeAttribution implements Attribution {
/// within [AttributedText]. This class doesn't have a special
/// relationship with [AttributedText].
class LinkAttribution implements Attribution {
LinkAttribution({
required this.url,
});
factory LinkAttribution.fromUri(Uri uri) {
return LinkAttribution(uri.toString());
}

const LinkAttribution(this.url);

@override
String get id => 'link';

final Uri url;
/// The URL associated with the attributed text, as a `String`.
final String url;

/// Attempts to parse the [url] as a [Uri], and returns `true` if the [url]
/// is successfully parsed, or `false` if parsing fails, such as due to the [url]
/// including an invalid scheme, separator syntax, extra segments, etc.
bool get hasValidUri => Uri.tryParse(url) != null;

/// The URL associated with the attributed text, as a `Uri`.
///
/// Accessing the [uri] throws an exception if the [url] isn't valid.
/// To access a URL that might not be valid, consider accessing the [url],
/// instead.
Uri get uri => Uri.parse(url);

@override
bool canMergeWith(Attribution other) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2380,7 +2380,7 @@ class PasteEditorCommand implements EditCommand {

if (link != null && link.hasScheme && link.hasAuthority) {
// Valid url. Apply [LinkAttribution] to the url
final linkAttribution = LinkAttribution(url: link);
final linkAttribution = LinkAttribution.fromUri(link);

final startOffset = wordBoundary.start;
// -1 because TextPosition's offset indexes the character after the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ class LinkifyReaction implements EditReaction {
final uri = _parseLink(word);

text.addAttribution(
LinkAttribution(url: uri),
LinkAttribution.fromUri(uri),
SpanRange(wordStartOffset, endOffset - 1),
);
}
Expand Down Expand Up @@ -798,8 +798,8 @@ class LinkifyReaction implements EditReaction {
// link attribution that reflects the edited URL text. We do that below.
if (updatePolicy == LinkUpdatePolicy.update) {
changedNodeText.addAttribution(
LinkAttribution(
url: _parseLink(changedNodeText.text.substring(rangeToUpdate.start, rangeToUpdate.end + 1)),
LinkAttribution.fromUri(
_parseLink(changedNodeText.text.substring(rangeToUpdate.start, rangeToUpdate.end + 1)),
),
rangeToUpdate,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ class CaretDocumentOverlayState extends DocumentLayoutLayerState<CaretDocumentOv
return null;
}

Rect caretRect = documentLayout.getEdgeForPosition(documentSelection.extent)!;
Rect caretRect =
documentLayout.getEdgeForPosition(documentSelection.extent)!.translate(-widget.caretStyle.width / 2, 0.0);

final overlayBox = context.findRenderObject() as RenderBox?;
if (overlayBox != null && overlayBox.hasSize && caretRect.left + widget.caretStyle.width >= overlayBox.size.width) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,13 +577,6 @@ class _DocumentMouseInteractorState extends State<DocumentMouseInteractor> with
}
}

/// Beginning with Flutter 3.3.3, we are responsible for starting and
/// stopping scroll momentum. This method cancels any scroll momentum
/// in our scroll controller.
void _cancelScrollMomentum() {
widget.autoScroller.goIdle();
}

void _updateDragSelection() {
if (_dragEndGlobal == null) {
// User isn't dragging. No need to update drag selection.
Expand Down Expand Up @@ -729,7 +722,6 @@ Updating drag selection:
}

void _onMouseMove(PointerHoverEvent event) {
_cancelScrollMomentum();
_updateMouseCursor(event.position);
_lastHoverOffset = event.position;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1750,11 +1750,7 @@ class SuperEditorAndroidControlsOverlayManagerState extends State<SuperEditorAnd
child: AndroidMagnifyingGlass(
key: magnifierKey,
magnificationScale: 1.5,
// In theory, the offsetFromFocalPoint should either be `-150` to match the actual
// offset, or it should be `-150 / magnificationLevel`. Neither of those align the
// focal point correctly. The following offset was found empirically to give the
// desired results, no matter how high the magnification.
offsetFromFocalPoint: const Offset(0, -58),
offsetFromFocalPoint: Offset(0, -150 / MediaQuery.devicePixelRatioOf(context)),
),
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:super_editor/src/core/document_layout.dart';
Expand All @@ -9,10 +8,10 @@ import 'package:super_editor/src/default_editor/debug_visualization.dart';
import 'package:super_editor/src/default_editor/document_gestures_touch_ios.dart';
import 'package:super_editor/src/default_editor/text.dart';
import 'package:super_editor/src/infrastructure/_logging.dart';
import 'package:super_editor/src/infrastructure/actions.dart';
import 'package:super_editor/src/infrastructure/flutter/flutter_scheduler.dart';
import 'package:super_editor/src/infrastructure/ime_input_owner.dart';
import 'package:super_editor/src/infrastructure/platforms/ios/ios_document_controls.dart';
import 'package:super_editor/src/infrastructure/platforms/mac/mac_ime.dart';
import 'package:super_editor/src/infrastructure/platforms/platform.dart';

import '../document_hardware_keyboard/document_input_keyboard.dart';
Expand Down Expand Up @@ -477,8 +476,8 @@ class SuperEditorImeInteractorState extends State<SuperEditorImeInteractor> impl
Widget build(BuildContext context) {
return SuperEditorImeDebugVisuals(
imeConnection: _imeConnection,
child: Actions(
actions: defaultTargetPlatform == TargetPlatform.macOS ? disabledMacIntents : {},
child: IntentBlocker(
intents: CurrentPlatform.isApple ? appleBlockedIntents : nonAppleBlockedIntents,
child: SuperEditorHardwareKeyHandler(
focusNode: _focusNode,
editContext: widget.editContext,
Expand Down
Loading

0 comments on commit dcd0cb7

Please sign in to comment.