mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
0663870bf9
commit_hash:52ce6e4a9f35a44ddef28565cec76ddaabdc2d08
126 lines
3.6 KiB
Swift
126 lines
3.6 KiB
Swift
#if os(iOS)
|
|
import LayoutKit
|
|
import UIKit
|
|
import VGSL
|
|
|
|
extension DebugBlock: UIViewRenderable {
|
|
static func makeBlockView() -> any LayoutKit.BlockView {
|
|
DebugBlockView()
|
|
}
|
|
|
|
func canConfigureBlockView(_ view: any LayoutKit.BlockView) -> Bool {
|
|
view is DebugBlockView
|
|
}
|
|
|
|
func configureBlockView(
|
|
_ view: BlockView,
|
|
observer: ElementStateObserver?,
|
|
overscrollDelegate: ScrollDelegate?,
|
|
renderingDelegate: RenderingDelegate?
|
|
) {
|
|
(view as? DebugBlockView)?.configure(
|
|
child: child,
|
|
errorCollector: errorCollector,
|
|
showDebugInfo: showDebugInfo,
|
|
observer: observer,
|
|
overscrollDelegate: overscrollDelegate,
|
|
renderingDelegate: renderingDelegate
|
|
)
|
|
}
|
|
}
|
|
|
|
private final class DebugBlockView: BlockView, VisibleBoundsTrackingContainer {
|
|
private var childView: BlockView?
|
|
|
|
private var showDebugInfo: ((ViewType) -> Void)?
|
|
private var errorCollector: DebugErrorCollector?
|
|
private let disposePool = AutodisposePool()
|
|
|
|
private let errorsButton: UIButton = {
|
|
let button = UIButton(type: .custom)
|
|
button.isHidden = true
|
|
button.setTitle("0", for: .normal)
|
|
button.setTitleColor(.white, for: .normal)
|
|
button.backgroundColor = .red
|
|
button.accessibilityIdentifier = "divLayoutErrorCounter"
|
|
return button
|
|
}()
|
|
|
|
var effectiveBackgroundColor: UIColor? {
|
|
childView?.backgroundColor
|
|
}
|
|
|
|
var visibleBoundsTrackingSubviews: [VisibleBoundsTrackingView] {
|
|
childView.map { [$0] } ?? []
|
|
}
|
|
|
|
init() {
|
|
super.init(frame: .zero)
|
|
addSubview(errorsButton)
|
|
errorsButton.addTarget(self, action: #selector(errorsButtonTapped), for: .touchUpInside)
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder _: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
childView?.frame = bounds
|
|
errorsButton.frame = CGRect(
|
|
center: CGPoint(x: buttonSize / 2.0, y: bounds.midY),
|
|
size: CGSize(squareDimension: buttonSize)
|
|
)
|
|
errorsButton.layer.cornerRadius = buttonSize / 2.0
|
|
}
|
|
|
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
let result = super.hitTest(point, with: event)
|
|
return result === self ? nil : result
|
|
}
|
|
|
|
func configure(
|
|
child: Block,
|
|
errorCollector: DebugErrorCollector,
|
|
showDebugInfo: @escaping (ViewType) -> Void,
|
|
observer: ElementStateObserver?,
|
|
overscrollDelegate: ScrollDelegate?,
|
|
renderingDelegate: RenderingDelegate?
|
|
) {
|
|
childView = child.reuse(
|
|
childView,
|
|
observer: observer,
|
|
overscrollDelegate: overscrollDelegate,
|
|
renderingDelegate: renderingDelegate,
|
|
superview: self,
|
|
subviewPosition: .index(0)
|
|
)
|
|
self.showDebugInfo = showDebugInfo
|
|
if self.errorCollector !== errorCollector {
|
|
self.errorCollector = errorCollector
|
|
errorCollector.observableErrorCount.currentAndNewValues.addObserver { [weak self] _ in
|
|
self?.updateCountLabel()
|
|
}.dispose(in: disposePool)
|
|
}
|
|
setNeedsLayout()
|
|
}
|
|
|
|
@objc func errorsButtonTapped() {
|
|
guard let showDebugInfo, let errorCollector, errorCollector.totalErrorCount > 0 else { return }
|
|
showDebugInfo(ErrorListView(errors: errorCollector.errorList))
|
|
}
|
|
|
|
private func updateCountLabel() {
|
|
let errorsCount = errorCollector?.totalErrorCount ?? 0
|
|
let isHidden = errorsCount == 0
|
|
errorsButton.isHidden = isHidden
|
|
errorsButton.setTitle("\(min(maxCount, errorsCount))", for: .normal)
|
|
}
|
|
}
|
|
|
|
private let showOverlayURL = URL(string: "debugInfo://show")!
|
|
private let maxCount = 9999
|
|
private let buttonSize = 50.0
|
|
#endif
|