Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@
@implementation ENRMListMarkerDescriptor
@end

// NSArray's -hash is its count, so plain one-marker arrays all collide in the
// table that uniques attribute dictionaries, and each list item probes past
// every earlier one. Hashing by the item's own marker keeps rendering linear.
@interface ENRMListMarkerArray : NSArray
@end

@implementation ENRMListMarkerArray {
NSArray<ENRMListMarkerDescriptor *> *_markers;
}

- (instancetype)initWithMarkers:(NSArray<ENRMListMarkerDescriptor *> *)markers
{
if (self = [super init]) {
_markers = [markers copy];
}
return self;
}

- (NSUInteger)count
{
return _markers.count;
}

- (id)objectAtIndex:(NSUInteger)index
{
return _markers[index];
}

- (NSUInteger)hash
{
return _markers.lastObject.hash;
}

@end

@interface ListItemRenderer ()
- (void)applyCheckedDecorationsTo:(NSMutableAttributedString *)output
range:(NSRange)range
Expand Down Expand Up @@ -184,7 +219,9 @@ - (void)renderNodeContent:(MarkdownASTNode *)node
NSArray *existingMarkers = [output attribute:ListItemMarkerStartAttribute atIndex:anchorLocation effectiveRange:NULL];
NSArray *markers =
[existingMarkers isKindOfClass:[NSArray class]] ? [existingMarkers arrayByAddingObject:marker] : @[ marker ];
[output addAttribute:ListItemMarkerStartAttribute value:markers range:anchorRange];
[output addAttribute:ListItemMarkerStartAttribute
value:[[ENRMListMarkerArray alloc] initWithMarkers:markers]
range:anchorRange];

if (isTask && isChecked) {
[self applyCheckedDecorationsTo:output range:itemRange nestingLevel:nestingLevel];
Expand Down
Loading