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

Improve performance of File block processor #22897

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* [*] Fix button overlap in the "Post Published" sheet on small devices [#23210]
* [*] [internal] Incorporate a parser to handle Gutenberg blocks more efficiently for improved performance [#22886]
* [**] Improve performance of Image and Gallery block processors to avoid long delay when saving a post [#22896]
* [*] Improve performance of File block processor [#22897]

24.9
-----
Expand Down
2 changes: 1 addition & 1 deletion WordPress/Classes/Services/PostCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ class PostCoordinator: NSObject {

// File block can upload any kind of media.
let gutenbergFileProcessor = GutenbergFileUploadProcessor(mediaUploadID: gutenbergMediaUploadID, serverMediaID: mediaID, remoteURLString: remoteURLStr)
gutenbergProcessors.append(gutenbergFileProcessor)
gutenbergBlockProcessors.append(gutenbergFileProcessor)

if media.mediaType == .image {
let gutenbergImgPostUploadProcessor = GutenbergImgUploadProcessor(mediaUploadID: gutenbergMediaUploadID, serverMediaID: mediaID, remoteURLString: imageURL)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Foundation
import Aztec
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aztec was imported in this file to use HTMLProcessor. Now the HTML processing is performed by using SwiftSoup.


class GutenbergFileUploadProcessor: Processor {
class GutenbergFileUploadProcessor: GutenbergProcessor {
private struct FileBlockKeys {
static var name = "wp:file"
static var id = "id"
Expand All @@ -18,38 +17,24 @@ class GutenbergFileUploadProcessor: Processor {
self.remoteURLString = remoteURLString
}

lazy var fileHtmlProcessor = HTMLProcessor(for: "a", replacer: { (file) in
var attributes = file.attributes
func processFileBlocks(_ blocks: [GutenbergParsedBlock]) {
blocks.filter { $0.name == FileBlockKeys.name }.forEach { block in
guard let mediaID = block.attributes[FileBlockKeys.id] as? Int,
mediaID == self.mediaUploadID else {
return
}

attributes.set(.string(self.remoteURLString), forKey: FileBlockKeys.href)
// Update attributes
block.attributes[FileBlockKeys.id] = self.serverMediaID
block.attributes[FileBlockKeys.href] = self.remoteURLString

var html = "<a "
let attributeSerializer = ShortcodeAttributeSerializer()
html += attributeSerializer.serialize(attributes)
html += ">\(file.content ?? "")</a>"
return html
})

lazy var fileBlockProcessor = GutenbergBlockProcessor(for: FileBlockKeys.name, replacer: { fileBlock in
guard let mediaID = fileBlock.attributes[FileBlockKeys.id] as? Int,
mediaID == self.mediaUploadID else {
return nil
}
var block = "<!-- \(FileBlockKeys.name) "
var attributes = fileBlock.attributes
attributes[FileBlockKeys.id] = self.serverMediaID
attributes[FileBlockKeys.href] = self.remoteURLString
if let jsonData = try? JSONSerialization.data(withJSONObject: attributes, options: .sortedKeys),
let jsonString = String(data: jsonData, encoding: .utf8) {
block += jsonString
// Update href of `a` tags
let aTags = try? block.elements.select("a")
aTags?.forEach { _ = try? $0.attr(FileBlockKeys.href, self.remoteURLString) }
}
block += " -->"
block += self.fileHtmlProcessor.process(fileBlock.content)
block += "<!-- /\(FileBlockKeys.name) -->"
return block
})
}

func process(_ text: String) -> String {
return fileBlockProcessor.process(text)
func process(_ blocks: [GutenbergParsedBlock]) {
processFileBlocks(blocks)
}
}
4 changes: 4 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,7 @@
1D91080729F847A2003F9A5E /* MediaServiceUpdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D91080629F847A2003F9A5E /* MediaServiceUpdateTests.m */; };
1DE9F2B02BA30C930044AA53 /* GutenbergProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE9F2AF2BA30C930044AA53 /* GutenbergProcessor.swift */; };
1DE9F2B12BA30C930044AA53 /* GutenbergProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE9F2AF2BA30C930044AA53 /* GutenbergProcessor.swift */; };
1DE9F2B32BA30E820044AA53 /* GutenbergFileUploadProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE9F2B22BA30E820044AA53 /* GutenbergFileUploadProcessorTests.swift */; };
1DF7A0CB2B9F66810003CBA3 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = 1DF7A0CA2B9F66810003CBA3 /* SwiftSoup */; };
1DF7A0CD2B9F66970003CBA3 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = 1DF7A0CC2B9F66970003CBA3 /* SwiftSoup */; };
1DF7A0CF2BA099760003CBA3 /* GutenbergContentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF7A0CE2BA099760003CBA3 /* GutenbergContentParser.swift */; };
Expand Down Expand Up @@ -6634,6 +6635,7 @@
1D6058910D05DD3D006BFB54 /* WordPress.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordPress.app; sourceTree = BUILT_PRODUCTS_DIR; };
1D91080629F847A2003F9A5E /* MediaServiceUpdateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MediaServiceUpdateTests.m; sourceTree = "<group>"; };
1DE9F2AF2BA30C930044AA53 /* GutenbergProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergProcessor.swift; sourceTree = "<group>"; };
1DE9F2B22BA30E820044AA53 /* GutenbergFileUploadProcessorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergFileUploadProcessorTests.swift; sourceTree = "<group>"; };
1DF7A0CE2BA099760003CBA3 /* GutenbergContentParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergContentParser.swift; sourceTree = "<group>"; };
1DF7A0D22BA0B1810003CBA3 /* GutenbergContentParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergContentParser.swift; sourceTree = "<group>"; };
1E0462152566938300EB98EF /* GutenbergFileUploadProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergFileUploadProcessor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -19010,6 +19012,7 @@
AEE082892681C23C00DCF54B /* GutenbergRefactoredGalleryUploadProcessorTests.swift */,
FE9438B12A050251006C40EC /* BlockEditorSettings_GutenbergEditorSettingsTests.swift */,
1DF7A0D22BA0B1810003CBA3 /* GutenbergContentParser.swift */,
1DE9F2B22BA30E820044AA53 /* GutenbergFileUploadProcessorTests.swift */,
);
name = Gutenberg;
sourceTree = "<group>";
Expand Down Expand Up @@ -24055,6 +24058,7 @@
F41D98E12B39C5CE004EC050 /* BlogDashboardDynamicCardCoordinatorTests.swift in Sources */,
FE2E3729281C839C00A1E82A /* BloggingPromptsServiceTests.swift in Sources */,
D848CC0720FF2BE200A9038F /* NotificationContentRangeFactoryTests.swift in Sources */,
1DE9F2B32BA30E820044AA53 /* GutenbergFileUploadProcessorTests.swift in Sources */,
732A473F21878EB10015DA74 /* WPRichContentViewTests.swift in Sources */,
8BDA5A6D247C2F8400AB124C /* ReaderDetailViewControllerTests.swift in Sources */,
82301B8F1E787420009C9C4E /* AppRatingUtilityTests.swift in Sources */,
Expand Down
30 changes: 30 additions & 0 deletions WordPress/WordPressTest/GutenbergFileUploadProcessorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import XCTest
@testable import WordPress

class GutenbergFileUploadProcessorTests: XCTestCase {

let postContent = """
<!-- wp:file {"id":-1626352752,"href":"file://file.pdf"} -->
<div class="wp-block-file"><a href="file://file.pdf">dummy.pdf</a><a href="file://file.pdf" class="wp-block-file__button wp-element-button" download>Download</a></div>
<!-- /wp:file -->
"""

let postResultContent = """
<!-- wp:file {"href":"http:\\/\\/www.wordpress.com\\/file.pdf","id":100} -->
<div class="wp-block-file"><a href="http://www.wordpress.com/file.pdf">dummy.pdf</a><a href="http://www.wordpress.com/file.pdf" class="wp-block-file__button wp-element-button" download>Download</a></div>
<!-- /wp:file -->
"""

func testFileBlockProcessor() {
let gutenbergMediaUploadID = Int32(-1626352752)
let mediaID = 100
let remoteURLStr = "http://www.wordpress.com/file.pdf"

let gutenbergFilePostUploadProcessor = GutenbergFileUploadProcessor(mediaUploadID: gutenbergMediaUploadID, serverMediaID: mediaID, remoteURLString: remoteURLStr)

let parser = GutenbergContentParser(for: postContent)
gutenbergFilePostUploadProcessor.process(parser.blocks)

XCTAssertEqual(parser.html(), postResultContent, "Post content should be updated correctly")
}
}