Skip to content

Commit 046036f

Browse files
authored
fix: github flavor always expanding to full width (#176)
1 parent b076d9d commit 046036f

4 files changed

Lines changed: 31 additions & 13 deletions

File tree

android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ object MeasurementStore {
349349
val widthPx = width.toInt().coerceAtLeast(1)
350350
val lastIndex = segments.lastIndex
351351
var totalHeightPx = 0f
352+
var maxContentWidthPx = 0f
352353

353354
for ((index, segment) in segments.withIndex()) {
354355
val isLastSegment = index == lastIndex
@@ -364,6 +365,9 @@ object MeasurementStore {
364365
val layout = createStaticLayout(styledText, fontSize, widthPx)
365366
totalHeightPx += layout.height
366367

368+
val segmentMaxLineWidth = (0 until layout.lineCount).maxOfOrNull { layout.getLineWidth(it) } ?: 0f
369+
maxContentWidthPx = maxOf(maxContentWidthPx, ceil(segmentMaxLineWidth))
370+
367371
if (includeBottomMargin) {
368372
totalHeightPx += segmentRenderer.getLastElementMarginBottom()
369373
}
@@ -372,6 +376,7 @@ object MeasurementStore {
372376
is MarkdownSegment.Table -> {
373377
totalHeightPx += style.tableStyle.marginTop
374378
totalHeightPx += TableContainerView.measureTableNodeHeight(segment.node, style, context)
379+
maxContentWidthPx = width
375380
if (includeBottomMargin) {
376381
totalHeightPx += style.tableStyle.marginBottom
377382
}
@@ -380,6 +385,7 @@ object MeasurementStore {
380385
is MarkdownSegment.Math -> {
381386
totalHeightPx += style.mathStyle.marginTop
382387
totalHeightPx += mathHeightByIndex[index] ?: 0f
388+
maxContentWidthPx = width
383389
if (includeBottomMargin) {
384390
totalHeightPx += style.mathStyle.marginBottom
385391
}
@@ -388,7 +394,8 @@ object MeasurementStore {
388394
}
389395

390396
val totalHeightDip = PixelUtil.toDIPFromPixel(totalHeightPx)
391-
val result = YogaMeasureOutput.make(PixelUtil.toDIPFromPixel(width), totalHeightDip)
397+
val measuredWidthDip = PixelUtil.toDIPFromPixel(maxContentWidthPx).coerceAtMost(PixelUtil.toDIPFromPixel(width))
398+
val result = YogaMeasureOutput.make(measuredWidthDip, totalHeightDip)
392399

393400
if (id != null) {
394401
data[id] = MeasurementParams(width, result, null, PaintParams(Typeface.DEFAULT, fontSize), propsHash)

ios/EnrichedMarkdown.mm

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,13 @@ - (instancetype)initWithFrame:(CGRect)frame
180180
return self;
181181
}
182182

183-
- (CGFloat)computeSegmentLayoutForWidth:(CGFloat)width applyFrames:(BOOL)applyFrames
183+
- (CGSize)computeSegmentLayoutForWidth:(CGFloat)width applyFrames:(BOOL)applyFrames
184184
{
185185
if (_segmentViews.count == 0)
186-
return 0.0;
186+
return CGSizeZero;
187187

188188
__block CGFloat yOffset = 0.0;
189+
__block CGFloat maxContentWidth = 0.0;
189190
const NSUInteger lastIndex = _segmentViews.count - 1;
190191

191192
[_segmentViews enumerateObjectsUsingBlock:^(RCTUIView *segment, NSUInteger i, BOOL *stop) {
@@ -197,16 +198,20 @@ - (CGFloat)computeSegmentLayoutForWidth:(CGFloat)width applyFrames:(BOOL)applyFr
197198
if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) {
198199
EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)segment;
199200
textView.allowTrailingMargin = shouldAddBottomMargin;
200-
segmentHeight = [textView measureHeight:width];
201+
CGSize textSize = [textView measureSize:width];
202+
segmentHeight = textSize.height;
203+
maxContentWidth = MAX(maxContentWidth, textSize.width);
201204

202205
} else if ([segment isKindOfClass:[TableContainerView class]]) {
203206
yOffset += _config.tableMarginTop;
204207
segmentHeight = [(TableContainerView *)segment measureHeight:width];
208+
maxContentWidth = width;
205209
}
206210
#if ENRICHED_MARKDOWN_MATH
207211
else if ([segment isKindOfClass:[ENRMMathContainerView class]]) {
208212
yOffset += _config.mathMarginTop;
209213
segmentHeight = [(ENRMMathContainerView *)segment measureHeight:width];
214+
maxContentWidth = width;
210215
}
211216
#endif
212217

@@ -236,19 +241,20 @@ - (CGFloat)computeSegmentLayoutForWidth:(CGFloat)width applyFrames:(BOOL)applyFr
236241
#endif
237242
}];
238243

239-
return yOffset;
244+
return CGSizeMake(maxContentWidth, yOffset);
240245
}
241246

242247
- (CGSize)measureSize:(CGFloat)maxWidth
243248
{
244249
CGFloat defaultHeight = UIFontLineHeight([UIFont systemFontOfSize:16.0]);
245-
CGFloat totalHeight = [self computeSegmentLayoutForWidth:maxWidth applyFrames:NO];
246-
if (totalHeight == 0)
250+
CGSize contentSize = [self computeSegmentLayoutForWidth:maxWidth applyFrames:NO];
251+
if (contentSize.height == 0)
247252
return CGSizeMake(maxWidth, defaultHeight);
248253

249-
// Round to pixel boundaries to match React Native's <Text> measurement
250254
CGFloat scale = RCTScreenScale();
251-
return CGSizeMake(maxWidth, ceil(totalHeight * scale) / scale);
255+
CGFloat measuredWidth = MIN(ceil(contentSize.width * scale) / scale, maxWidth);
256+
CGFloat measuredHeight = ceil(contentSize.height * scale) / scale;
257+
return CGSizeMake(measuredWidth, measuredHeight);
252258
}
253259

254260
- (BOOL)hasRenderedMarkdown:(NSString *)markdown

ios/views/EnrichedMarkdownInternalText.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
1616
- (void)applyAttributedText:(NSMutableAttributedString *)text context:(RenderContext *)context;
1717

1818
- (CGFloat)measureHeight:(CGFloat)maxWidth;
19+
- (CGSize)measureSize:(CGFloat)maxWidth;
1920

2021
@property (nonatomic, readonly) ENRMPlatformTextView *textView;
2122

ios/views/EnrichedMarkdownInternalText.m

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,26 @@ - (void)applyAttributedText:(NSMutableAttributedString *)text context:(RenderCon
8787
}
8888

8989
- (CGFloat)measureHeight:(CGFloat)maxWidth
90+
{
91+
return [self measureSize:maxWidth].height;
92+
}
93+
94+
- (CGSize)measureSize:(CGFloat)maxWidth
9095
{
9196
NSAttributedString *text = ENRMGetAttributedText(_textView);
9297
if (text.length == 0) {
93-
return 0;
98+
return CGSizeZero;
9499
}
95100

96101
ENRMTextLayoutResult layout = ENRMMeasureTextLayout(_textView, maxWidth);
97102

98103
CGFloat measuredHeight = layout.usedRect.size.height;
104+
CGFloat measuredWidth = layout.usedRect.size.width;
99105

100106
if (!CGRectIsEmpty(layout.extraLineFragmentRect)) {
101107
measuredHeight -= layout.extraLineFragmentRect.size.height;
102108
}
103109

104-
// Code block bottom padding compensation (same as EnrichedMarkdownText)
105110
if (isLastElementCodeBlock(text)) {
106111
measuredHeight += [_config codeBlockPadding];
107112
}
@@ -110,9 +115,8 @@ - (CGFloat)measureHeight:(CGFloat)maxWidth
110115
measuredHeight += _lastElementMarginBottom;
111116
}
112117

113-
// Round to pixel boundaries to match React Native's <Text> measurement
114118
CGFloat scale = RCTScreenScale();
115-
return ceil(measuredHeight * scale) / scale;
119+
return CGSizeMake(ceil(measuredWidth * scale) / scale, ceil(measuredHeight * scale) / scale);
116120
}
117121

118122
- (void)layoutSubviews

0 commit comments

Comments
 (0)