diff --git a/WordPressShared/Core/Utility/RichContentFormatter.swift b/WordPressShared/Core/Utility/RichContentFormatter.swift index 5f7f82f..3415f75 100644 --- a/WordPressShared/Core/Utility/RichContentFormatter.swift +++ b/WordPressShared/Core/Utility/RichContentFormatter.swift @@ -28,6 +28,10 @@ import Foundation // Trailing BR Tags static let trailingBRTags = try! NSRegularExpression(pattern: "(\\s*\\s*)+$", options: .caseInsensitive) + + // Gutenberg Galleries + static let gutenbergGalleryList = try! NSRegularExpression(pattern: "(]+>)]+gallery-item[^>]+>
", options: .caseInsensitive) + static let gutenbergGalleryListItem = try! NSRegularExpression(pattern: "]+gallery-item[^>]+>(
)", options: .caseInsensitive) } @@ -50,6 +54,7 @@ import Foundation content = normalizeParagraphs(content) content = removeInlineStyles(content) content = (content as NSString).replacingHTMLEmoticonsWithEmoji() as String + content = formatGutenbergGallery(content) content = resizeGalleryImageURL(content, isPrivateSite: isPrivate) return content @@ -300,4 +305,36 @@ import Foundation return content } + + /// Removes unordered list markup from Gutenberg gallery images. + /// + /// - Parameters: + /// - string: The content string to format. + /// + /// - Returns: The formatted string. + /// + @objc public class func formatGutenbergGallery(_ string: String) -> String { + let mString = NSMutableString(string: string) + + // First, remove the gallery UL tags. + var matches = RegEx.gutenbergGalleryList.matches(in: mString as String, options: [], range: NSRange(location: 0, length: mString.length)) + for match in matches.reversed() { + if match.numberOfRanges < 2 { + continue + } + mString.replaceCharacters(in: match.range(at: 1), with: "") + } + + // Now discard the list item markup + matches = RegEx.gutenbergGalleryListItem.matches(in: mString as String, options: [], range: NSRange(location: 0, length: mString.length)) + for match in matches.reversed() { + if match.numberOfRanges < 2 { + continue + } + let image = mString.substring(with: match.range(at: 1)) + mString.replaceCharacters(in: match.range, with: image) + } + + return mString as String + } } diff --git a/WordPressSharedTests/RichContentFormatterTests.swift b/WordPressSharedTests/RichContentFormatterTests.swift index 76273a4..0bc9a74 100644 --- a/WordPressSharedTests/RichContentFormatterTests.swift +++ b/WordPressSharedTests/RichContentFormatterTests.swift @@ -45,4 +45,19 @@ class RichContentFormatterTests: XCTestCase { let sanitizedStr = RichContentFormatter.removeTrailingBreakTags(styleStr) XCTAssertTrue(str == sanitizedStr, "The inline styles were not removed.") } + + + func testRemoveGutenbergGalleryListMarkup() { + let str = "Some text. Some text." + let sanitizedString = RichContentFormatter.formatGutenbergGallery(str) as NSString + // Checks if the UL was removed. + var range = sanitizedString.range(of: "block-gallery") + XCTAssertTrue(range.location == NSNotFound) + // Checks if the LI was removed + range = sanitizedString.range(of: "blocks-gallery") + XCTAssertTrue(range.location == NSNotFound) + // Checks if the FIGCAPTION was kept. + range = sanitizedString.range(of: "figcaption") + XCTAssertTrue(range.location != NSNotFound) + } }