Skip to content
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

Fix: AutoExitBlockRule should escape indented blocks #447

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/fleather/example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
source 'https://github.com/CocoaPods/Specs.git'
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'

Expand Down
8 changes: 4 additions & 4 deletions packages/fleather/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe

PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011
PODFILE CHECKSUM: c62e6854664f17080664e8e5a8d86662b9932c70

COCOAPODS: 1.15.2
90 changes: 45 additions & 45 deletions packages/fleather/example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
579F3F43C472D57D038DBF76 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E84E73ED0D07B6ABE22E87E5 /* Pods_Runner.framework */; };
6FCD0F328E579EDE82324EEE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B819042F3500D0B768B6367D /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
Expand All @@ -30,37 +30,56 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
06C05B9F27EA07665F1D8160 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
08DBA5ABDE7F627ACDF2F91A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8EFA1F9CCFDF71CA4AE07BC3 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B6FEBF576B05328480B261C6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
D26A8E67A4E7628D7F50B6E1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
E84E73ED0D07B6ABE22E87E5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B819042F3500D0B768B6367D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFEA77BB67DDC6B5C0ABC70F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
579F3F43C472D57D038DBF76 /* Pods_Runner.framework in Frameworks */,
6FCD0F328E579EDE82324EEE /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
4440A7BB6CD9F358B66D994E /* Pods */ = {
isa = PBXGroup;
children = (
06C05B9F27EA07665F1D8160 /* Pods-Runner.debug.xcconfig */,
BFEA77BB67DDC6B5C0ABC70F /* Pods-Runner.release.xcconfig */,
08DBA5ABDE7F627ACDF2F91A /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
93E0A0AE63BE9557B6A35595 /* Frameworks */ = {
isa = PBXGroup;
children = (
B819042F3500D0B768B6367D /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
Expand All @@ -78,8 +97,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
D85E56CEBB8657FA2DCC32C0 /* Pods */,
D165CBA148EA896DCEDFDECB /* Frameworks */,
4440A7BB6CD9F358B66D994E /* Pods */,
93E0A0AE63BE9557B6A35595 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -114,40 +133,21 @@
name = "Supporting Files";
sourceTree = "<group>";
};
D165CBA148EA896DCEDFDECB /* Frameworks */ = {
isa = PBXGroup;
children = (
E84E73ED0D07B6ABE22E87E5 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
D85E56CEBB8657FA2DCC32C0 /* Pods */ = {
isa = PBXGroup;
children = (
D26A8E67A4E7628D7F50B6E1 /* Pods-Runner.debug.xcconfig */,
B6FEBF576B05328480B261C6 /* Pods-Runner.release.xcconfig */,
8EFA1F9CCFDF71CA4AE07BC3 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
ACA395650376CD138DADC339 /* [CP] Check Pods Manifest.lock */,
607EEA6804E24507B8D93EC8 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9D44FB2BCE8AADD31260DF7A /* [CP] Embed Pods Frameworks */,
91FD0BD715CAE87352CA59CF /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -222,22 +222,29 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
607EEA6804E24507B8D93EC8 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
name = "Run Script";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9D44FB2BCE8AADD31260DF7A /* [CP] Embed Pods Frameworks */ = {
91FD0BD715CAE87352CA59CF /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -259,27 +266,20 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
ACA395650376CD138DADC339 /* [CP] Check Pods Manifest.lock */ = {
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
name = "Run Script";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
3 changes: 2 additions & 1 deletion packages/fleather/lib/src/widgets/editable_text_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ class EditableTextBlock extends StatelessWidget {
if (lastLevel != null) {
if (lastLevel == currentLevel) {
currentIndex = levelsIndexes[lastLevel]! + 1;
} else if (lastLevel > currentLevel) {
} else if (levelsIndexes.containsKey(currentLevel) &&
lastLevel > currentLevel) {
currentIndex = levelsIndexes[currentLevel]! + 1;
}
}
Expand Down
16 changes: 16 additions & 0 deletions packages/fleather/test/widgets/editable_text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ void main() {
await editor.pump();
expect(find.text('1.', findRichText: true), findsOneWidget);
});

testWidgets('multi-level numbered list', (tester) async {
final delta = Delta()
..insert('an item')
..insert('\n', {'block': 'ul'})
..insert('1')
..insert('\n', {'indent': 1, 'block': 'ol'})
..insert('1.1')
..insert('\n', {'block': 'ol'})
..insert('2')
..insert('\n');
final editor = EditorSandBox(
tester: tester, document: ParchmentDocument.fromDelta(delta));
await editor.pump();
expect(find.text('1.', findRichText: true), findsNWidgets(2));
});
});

testWidgets('headings', (tester) async {
Expand Down
9 changes: 8 additions & 1 deletion packages/parchment/lib/src/heuristics/insert_rules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,14 @@ class AutoExitBlockRule extends InsertRule {
// Here we now know that the line after `target` is not in the same block
// therefore we can exit this block.
final attributes = target.attributes ?? <String, dynamic>{};
attributes.addAll(ParchmentAttribute.block.unset.toJson());
final indent = attributes[ParchmentAttribute.indent.key];
// Unindent if this block is indented else unset the block attribute
if (indent != null && indent > 0) {
attributes[ParchmentAttribute.indent.key] = indent - 1;
} else {
attributes.addAll(ParchmentAttribute.block.unset.toJson());
}

return Delta()
..retain(index)
..retain(1, attributes);
Expand Down
14 changes: 14 additions & 0 deletions packages/parchment/test/heuristics/insert_rules_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,20 @@ void main() {
final actual = rule.apply(doc, 7, '\n');
expect(actual, isNull);
});

test('should unindent multi level list when rule is applied', () {
final doc = Delta()
..insert('Item 1')
..insert('\n', {'indent': 1, 'block': 'ul'})
..insert('Item 2')
..insert('\n\n', {'indent': 2, 'block': 'ul'});
final actual = rule.apply(doc, 14, '\n');
expect(actual, isNotNull);
final expected = Delta()
..retain(14)
..retain(1, {'indent': 1, 'block': 'ul'});
expect(actual, expected);
});
});

group('$PreserveInlineStylesRule', () {
Expand Down