Skip to content

Commit

Permalink
Fix iOS SR Text with padding
Browse files Browse the repository at this point in the history
  • Loading branch information
louiszawadzki committed Dec 1, 2023
1 parent 4a81885 commit 4e0d0c8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ internal struct RCTTextViewWireframesBuilder: SessionReplayNodeWireframesBuilder

let DEFAULT_FONT_COLOR = UIColor.black.cgColor

// Clipping should be 0 to avoid the text from overflowing when the
// numberOfLines prop is used.
private var clip: SRContentClip {
let top = abs(contentRect.origin.y)
let left = abs(contentRect.origin.x)
let bottom = max(contentRect.height - attributes.frame.height - top, 0)
let right = max(contentRect.width - attributes.frame.width - left, 0)
let top = 0.0
let left = 0.0
let bottom = 0.0
let right = 0.0
return SRContentClip.create(
bottom: Int64(withNoOverflow: bottom),
left: Int64(withNoOverflow: left),
Expand All @@ -110,19 +112,29 @@ internal struct RCTTextViewWireframesBuilder: SessionReplayNodeWireframesBuilder

private var relativeIntersectedRect: CGRect {
return CGRect(
x: attributes.frame.origin.x - contentRect.origin.x,
y: attributes.frame.origin.y - contentRect.origin.y ,
x: attributes.frame.origin.x,
y: attributes.frame.origin.y,
width: max(contentRect.width, attributes.frame.width),
height: max(contentRect.height, attributes.frame.height)
)
}

private var textFrame: CGRect {
return CGRect(
x: attributes.frame.origin.x + contentRect.origin.x,
y: attributes.frame.origin.y + contentRect.origin.y,
width: contentRect.width,
height: contentRect.height
)
}

public func buildWireframes(with builder: SessionReplayWireframesBuilder) -> [SRWireframe] {
return [
builder.createTextWireframe(
id: wireframeID,
frame: relativeIntersectedRect,
text: textObfuscator.mask(text: text ?? ""),
textFrame: textFrame,
textAlignment: .init(systemTextAlignment: textAlignment, vertical: .center),
clip: clip,
textColor: textColor ?? DEFAULT_FONT_COLOR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import XCTest
@testable import DatadogSessionReplay
import React

let BACKGROUND_RECT = CGRect(x: 50, y: 50, width: 100, height: 100)
// Simulates view with padding vertical of 10 and horizontal of 20.
let INNER_TEXT_RECT = CGRect(x: 20, y: 10, width: 60, height: 80) // position inside the background view

internal class RCTTextViewRecorderTests: XCTestCase {
let mockAttributes = SessionReplayViewAttributes(
frame: CGRect(x: 0, y: 0, width: 100, height: 100),
frame: BACKGROUND_RECT,
backgroundColor: UIColor.white.cgColor,
layerBorderColor: UIColor.blue.cgColor,
layerBorderWidth: CGFloat(1.0),
Expand All @@ -21,14 +25,14 @@ internal class RCTTextViewRecorderTests: XCTestCase {
isHidden: false,
intrinsicContentSize: CGSize(width: 100.0, height: 100.0)
)

let mockAllowContext = SessionReplayViewTreeRecordingContext(
recorder: .init(privacy: SessionReplayPrivacyLevel.allow, applicationID: "app_id", sessionID: "session_id", viewID: "view_id", viewServerTimeOffset: nil),
coordinateSpace: UIView(),
ids: .init(),
imageDataProvider: ImageDataProvider()
)

var mockShadowView: RCTTextShadowView {
// The shadow view must be initialized with a bridge so that we can insert React Subviews into it.
let shadowView: RCTTextShadowView = .init(bridge: MockRCTBridge(delegate: .none));
Expand All @@ -37,9 +41,11 @@ internal class RCTTextViewRecorderTests: XCTestCase {
rawTextShadowView.text = "This is the test text."
shadowView.insertReactSubview(rawTextShadowView, at: 0)

shadowView.layoutMetrics.contentFrame = INNER_TEXT_RECT

return shadowView
}

var mockShadowViewNestedText: RCTTextShadowView {
// The shadow view must be initialized with a bridge so that we can insert React Subviews into it.
let shadowView: RCTTextShadowView = .init(bridge: MockRCTBridge(delegate: .none));
Expand Down Expand Up @@ -79,7 +85,7 @@ internal class RCTTextViewRecorderTests: XCTestCase {
let element = try XCTUnwrap(result as? SessionReplayInvisibleElement)
XCTAssertEqual(element, SessionReplayInvisibleElement.constant)
}

func testReturnsBuilderWithCorrectInformation() throws {
let reactTag = NSNumber(value: 44)
let uiManagerMock = MockUIManager(reactTag: reactTag, shadowView: mockShadowView)
Expand All @@ -94,6 +100,19 @@ internal class RCTTextViewRecorderTests: XCTestCase {
XCTAssertEqual(element.nodes.count, 1)
let wireframe = try XCTUnwrap(element.nodes[0].wireframesBuilder.buildWireframes(with: .init())[0].getAsTextWireframe())
XCTAssertEqual(wireframe.text, "This is the test text.")

// Wireframe represents the background box.
XCTAssertEqual(wireframe.height, 100)
XCTAssertEqual(wireframe.width, 100)
XCTAssertEqual(wireframe.x, 50)
XCTAssertEqual(wireframe.y, 50)

// Padding around the test box in the background box.
XCTAssertEqual(wireframe.textPosition?.padding, .init(
bottom: Int64(BACKGROUND_RECT.height - INNER_TEXT_RECT.height - INNER_TEXT_RECT.minY),
left: Int64(INNER_TEXT_RECT.minX),
right: Int64(BACKGROUND_RECT.width - INNER_TEXT_RECT.width - INNER_TEXT_RECT.minX),
top: Int64(INNER_TEXT_RECT.minY)))
}

func testReturnsBuilderWithCorrectInformationWhenNestedTextComponents() throws {
Expand Down

0 comments on commit 4e0d0c8

Please sign in to comment.