diff --git a/Modules/Package.swift b/Modules/Package.swift
index 9d07d6b80bb7..4fbf4c4122d6 100644
--- a/Modules/Package.swift
+++ b/Modules/Package.swift
@@ -318,9 +318,7 @@ let package = Package(
"FormattableContentKit",
"SFHFKeychainUtils",
"WordPressShared",
- "WordPressSharedUI",
"WordPressKit",
- "WordPressUI",
.product(name: "CocoaLumberjack", package: "CocoaLumberjack"),
.product(name: "CocoaLumberjackSwift", package: "CocoaLumberjack"),
.product(name: "Gravatar", package: "Gravatar-SDK-iOS"),
diff --git a/Modules/Sources/WordPressData/Mapping/ReaderPost+Mapping.swift b/Modules/Sources/WordPressData/Mapping/ReaderPost+Mapping.swift
index 0dc60ac81fa8..8c7e26e41a6b 100644
--- a/Modules/Sources/WordPressData/Mapping/ReaderPost+Mapping.swift
+++ b/Modules/Sources/WordPressData/Mapping/ReaderPost+Mapping.swift
@@ -1,7 +1,6 @@
import CoreData
import WordPressKit
import WordPressShared
-import WordPressSharedUI
extension ReaderPost {
/// Finds an existing `ReaderPost` matching the given `globalID` and `topic`,
diff --git a/Modules/Sources/WordPressData/Swift/ManagedPerson.swift b/Modules/Sources/WordPressData/Swift/ManagedPerson.swift
index aea4c9e0e328..08d8cfa95220 100644
--- a/Modules/Sources/WordPressData/Swift/ManagedPerson.swift
+++ b/Modules/Sources/WordPressData/Swift/ManagedPerson.swift
@@ -1,7 +1,6 @@
import Foundation
import CoreData
import WordPressKit
-import WordPressUI
import Gravatar
public typealias Person = RemotePerson
diff --git a/Modules/Sources/WordPressSharedUI/RichContentFormatter.swift b/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift
similarity index 78%
rename from Modules/Sources/WordPressSharedUI/RichContentFormatter.swift
rename to Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift
index b9cfc55e7cb0..38530a2d2043 100644
--- a/Modules/Sources/WordPressSharedUI/RichContentFormatter.swift
+++ b/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift
@@ -1,7 +1,4 @@
import Foundation
-import UIKit
-import WordPressShared
-import WordPressSharedObjCUI
/// Contains methods for formatting post or comment content for display.
///
@@ -28,7 +25,7 @@ import WordPressSharedObjCUI
static let styleAttr = try! NSRegularExpression(pattern: "\\s*style=\"[^\"]*\"", options: .caseInsensitive)
// Gallery Images
- static let galleryImgTags = try! NSRegularExpression(pattern: "
]*data-orig-file[^>]*/>", options: .caseInsensitive)
+ public static let galleryImgTags = try! NSRegularExpression(pattern: "
]*data-orig-file[^>]*/>", options: .caseInsensitive)
// Trailing BR Tags
static let trailingBRTags = try! NSRegularExpression(pattern: "(\\s*
\\s*)+$", options: .caseInsensitive)
@@ -38,31 +35,6 @@ import WordPressSharedObjCUI
static let gutenbergGalleryListItem = try! NSRegularExpression(pattern: "
]+gallery-item[^>]+>(
)", options: .caseInsensitive)
}
- /// Formats the specified content string for display. Forbidden HTML tags are
- /// removed, paragraphs are normalized, etc.
- ///
- /// - Parameters:
- /// - string: The content string to format.
- /// - isPrivate: Whether the content is from a private blog.
- ///
- /// - Returns: The formatted string.
- ///
- @objc public class func formatContentString(_ string: String, isPrivateSite isPrivate: Bool) -> String {
- guard !string.isEmpty else {
- return string
- }
-
- var content = string
- content = removeForbiddenTags(content)
- content = normalizeParagraphs(content)
- content = removeInlineStyles(content)
- content = (content as NSString).replacingHTMLEmoticonsWithEmoji() as String
- content = formatGutenbergGallery(content)
- content = resizeGalleryImageURL(content, isPrivateSite: isPrivate)
- content = formatVideoTags(content)
- return content
- }
-
/// Removes forbidden HTML tags from the specified string.
///
/// - Parameters:
@@ -197,59 +169,6 @@ import WordPressSharedObjCUI
return content
}
- /// Mutates gallery image URLs to be correctly sized.
- ///
- /// - Parameters:
- /// - string: The content string to format.
- /// - isPrivate: Whether the content is from a private blog.
- ///
- /// - Returns: The formatted string.
- ///
- @objc public class func resizeGalleryImageURL(_ string: String, isPrivateSite isPrivate: Bool) -> String {
- guard !string.isEmpty else {
- return string
- }
-
- let imageSize = UIScreen.main.bounds.size
- let scale = UIScreen.main.scale
- let scaledSize = imageSize.applying(CGAffineTransform(scaleX: scale, y: scale))
-
- let mContent = NSMutableString(string: string)
-
- let matches = RegEx.galleryImgTags.matches(in: mContent as String, options: [], range: NSRange(location: 0, length: mContent.length))
-
- for match in matches.reversed() {
- let imgElementStr = mContent.substring(with: match.range)
- let srcImgURLStr = parseValueForAttribute("src", inElement: imgElementStr)
- let originalImgURLStr = parseValueForAttribute("data-orig-file", inElement: imgElementStr)
-
- guard let originalURL = URL(string: originalImgURLStr) else {
- continue
- }
-
- var modifiedURL: URL
- if isPrivate {
- modifiedURL = WPImageURLHelper.imageURLWithSize(scaledSize, forImageURL: originalURL)
- } else {
- modifiedURL = PhotonImageURLHelper.photonURL(with: imageSize, forImageURL: originalURL)
- }
-
- guard modifiedURL.absoluteString.isEmpty() == false else {
- continue
- }
-
- let mImageStr = NSMutableString(string: imgElementStr)
- mImageStr.replaceOccurrences(of: srcImgURLStr,
- with: modifiedURL.absoluteString,
- options: .literal,
- range: NSRange(location: 0, length: imgElementStr.count))
-
- mContent.replaceCharacters(in: match.range, with: mImageStr as String)
- }
-
- return mContent as String
- }
-
/// Parses the specified string for the value of the specified attribute.
///
/// - Parameters:
diff --git a/Modules/Sources/WordPressSharedUI/RichContentFormatter+DisplayPipeline.swift b/Modules/Sources/WordPressSharedUI/RichContentFormatter+DisplayPipeline.swift
new file mode 100644
index 000000000000..84cf672f4f2a
--- /dev/null
+++ b/Modules/Sources/WordPressSharedUI/RichContentFormatter+DisplayPipeline.swift
@@ -0,0 +1,97 @@
+import Foundation
+import UIKit
+import WordPressShared
+import WordPressSharedObjCUI
+
+/// UIKit-dependent additions to `RichContentFormatter`.
+///
+/// The platform-independent text transformations live in `WordPressShared`. The
+/// display pipeline below depends on the screen (for gallery image sizing) and on
+/// `WordPressSharedObjCUI`'s Photon helper, so it stays in the UI layer.
+///
+extension RichContentFormatter {
+
+ /// Formats the specified content string for display. Forbidden HTML tags are
+ /// removed, paragraphs are normalized, etc.
+ ///
+ /// - Parameters:
+ /// - string: The content string to format.
+ /// - isPrivate: Whether the content is from a private blog.
+ ///
+ /// - Returns: The formatted string.
+ ///
+ @objc public class func formatContentString(_ string: String, isPrivateSite isPrivate: Bool) -> String {
+ guard !string.isEmpty else {
+ return string
+ }
+
+ var content = string
+ content = removeForbiddenTags(content)
+ content = normalizeParagraphs(content)
+ content = removeInlineStyles(content)
+ content = (content as NSString).replacingHTMLEmoticonsWithEmoji() as String
+ content = formatGutenbergGallery(content)
+ content = resizeGalleryImageURL(content, isPrivateSite: isPrivate)
+ content = formatVideoTags(content)
+ return content
+ }
+
+ /// Mutates gallery image URLs to be correctly sized.
+ ///
+ /// - Parameters:
+ /// - string: The content string to format.
+ /// - isPrivate: Whether the content is from a private blog.
+ ///
+ /// - Returns: The formatted string.
+ ///
+ @objc public class func resizeGalleryImageURL(_ string: String, isPrivateSite isPrivate: Bool) -> String {
+ guard !string.isEmpty else {
+ return string
+ }
+
+ let imageSize = UIScreen.main.bounds.size
+ let scale = UIScreen.main.scale
+ let scaledSize = imageSize.applying(CGAffineTransform(scaleX: scale, y: scale))
+
+ let mContent = NSMutableString(string: string)
+
+ let matches = RegEx.galleryImgTags.matches(
+ in: mContent as String,
+ options: [],
+ range: NSRange(location: 0, length: mContent.length)
+ )
+
+ for match in matches.reversed() {
+ let imgElementStr = mContent.substring(with: match.range)
+ let srcImgURLStr = parseValueForAttribute("src", inElement: imgElementStr)
+ let originalImgURLStr = parseValueForAttribute("data-orig-file", inElement: imgElementStr)
+
+ guard let originalURL = URL(string: originalImgURLStr) else {
+ continue
+ }
+
+ var modifiedURL: URL
+ if isPrivate {
+ modifiedURL = WPImageURLHelper.imageURLWithSize(scaledSize, forImageURL: originalURL)
+ } else {
+ modifiedURL = PhotonImageURLHelper.photonURL(with: imageSize, forImageURL: originalURL)
+ }
+
+ guard modifiedURL.absoluteString.isEmpty() == false else {
+ continue
+ }
+
+ let mImageStr = NSMutableString(string: imgElementStr)
+ mImageStr.replaceOccurrences(
+ of: srcImgURLStr,
+ with: modifiedURL.absoluteString,
+ options: .literal,
+ range: NSRange(location: 0, length: imgElementStr.count)
+ )
+
+ mContent.replaceCharacters(in: match.range, with: mImageStr as String)
+ }
+
+ return mContent as String
+ }
+}
diff --git a/Modules/Tests/WordPressSharedTests/RichContentFormatterTests.swift b/Modules/Tests/WordPressSharedTests/RichContentFormatterTests.swift
index e5068f17e019..b594c5482908 100644
--- a/Modules/Tests/WordPressSharedTests/RichContentFormatterTests.swift
+++ b/Modules/Tests/WordPressSharedTests/RichContentFormatterTests.swift
@@ -1,6 +1,5 @@
import XCTest
@testable import WordPressShared
-@testable import WordPressSharedUI
class RichContentFormatterTests: XCTestCase {
@@ -32,10 +31,6 @@ class RichContentFormatterTests: XCTestCase {
XCTAssertTrue(str == sanitizedStr, "Not all paragraphs were normalized.")
}
- func testResizeGalleryImageURLsForContentEmptyString() {
- XCTAssertTrue("" == RichContentFormatter.resizeGalleryImageURL("", isPrivateSite: false))
- }
-
func testRemoveTrailingBRTags() {
let str = "test
test
"
let styleStr = "test
test
"
diff --git a/Modules/Tests/WordPressSharedTests/RichContentFormatterUITests.swift b/Modules/Tests/WordPressSharedTests/RichContentFormatterUITests.swift
new file mode 100644
index 000000000000..8efaddb06f04
--- /dev/null
+++ b/Modules/Tests/WordPressSharedTests/RichContentFormatterUITests.swift
@@ -0,0 +1,10 @@
+import XCTest
+@testable import WordPressShared
+@testable import WordPressSharedUI
+
+class RichContentFormatterUITests: XCTestCase {
+
+ func testResizeGalleryImageURLsForContentEmptyString() {
+ XCTAssertTrue("" == RichContentFormatter.resizeGalleryImageURL("", isPrivateSite: false))
+ }
+}
diff --git a/Package.swift b/Package.swift
index 6a9397e7670e..c2eabdc904ba 100644
--- a/Package.swift
+++ b/Package.swift
@@ -43,7 +43,7 @@ let package = Package(
path: "Modules/Tests/WordPressSharedTests",
exclude: [
"WordPressShared.xctestplan",
- "RichContentFormatterTests.swift",
+ "RichContentFormatterUITests.swift",
"WPUserAgentTests.swift"
],
swiftSettings: [.swiftLanguageMode(.v5)]