Skip to content

Commit

Permalink
Converted TextStorage to PRTextStorage in Objc to fix performance iss…
Browse files Browse the repository at this point in the history
…ues (#66)

* Converted TextStorage to PRTextStorage in Objc to fix performance issues

* Changed Editor.maxHeight from float to an enum to allow for support for unbounded height

* Updated docs

Co-authored-by: Rob Chatfield <rchatfield@atlassian.com>
  • Loading branch information
rajdeep and Rob Chatfield committed Sep 20, 2020
1 parent 79ae357 commit cf35969
Show file tree
Hide file tree
Showing 154 changed files with 1,974 additions and 865 deletions.
Expand Up @@ -40,6 +40,8 @@ class FixedWidthAttachmentExampleViewController: ExamplesBaseViewController {
editor.layer.borderColor = UIColor.systemBlue.cgColor
editor.layer.borderWidth = 1.0

editor.maxHeight = .infinite

let button = UIButton(type: .system)
button.setTitle("Insert attachment", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
Expand Down
2 changes: 1 addition & 1 deletion ExampleApp/ExampleApp/Commands/PanelCommand.swift
Expand Up @@ -33,7 +33,7 @@ class PanelCommand: EditorCommand {
editor.insertAttachment(in: editor.selectedRange, attachment: attachment)

let panel = attachment.view
panel.editor.maxHeight = 300
panel.editor.maxHeight = .max(300)
panel.editor.registerProcessors(editor.registeredProcessors)
panel.editor.listFormattingProvider = editor.listFormattingProvider
panel.editor.replaceCharacters(in: .zero, with: selectedText)
Expand Down
36 changes: 31 additions & 5 deletions Proton/Proton.xcodeproj/project.pbxproj
Expand Up @@ -30,7 +30,7 @@
1B45CD9D23BEDA8F001EB196 /* UIView+Render.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CD9C23BEDA8F001EB196 /* UIView+Render.swift */; };
1B45CD9F23BEE997001EB196 /* SnapshotTestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CD9E23BEE997001EB196 /* SnapshotTestViewController.swift */; };
1B45CDA923BEED0E001EB196 /* AutogrowingTextViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDA823BEED0E001EB196 /* AutogrowingTextViewTests.swift */; };
1B45CDBA23BF10DF001EB196 /* TextStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDB923BF10DF001EB196 /* TextStorage.swift */; };
1B45CDBA23BF10DF001EB196 /* TextStorageDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDB923BF10DF001EB196 /* TextStorageDelegate.swift */; };
1B45CDBC23BF1174001EB196 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDBB23BF1174001EB196 /* Types.swift */; };
1B45CDBE23BF125D001EB196 /* NSAttributedString+ContentTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDBD23BF125D001EB196 /* NSAttributedString+ContentTypes.swift */; };
1B45CDC223BF131E001EB196 /* TextStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B45CDC023BF131B001EB196 /* TextStorageTests.swift */; };
Expand Down Expand Up @@ -100,6 +100,9 @@
1BD993B823C9AE4200563ACB /* NSAttributedString+Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BD993B723C9AE4200563ACB /* NSAttributedString+Content.swift */; };
1BD993C023C9EAA900563ACB /* TextTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BD993BF23C9EAA900563ACB /* TextTransformer.swift */; };
1BD993C423CACCE100563ACB /* MockAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BD993C323CACCE100563ACB /* MockAttachment.swift */; };
1BE8825F250DD7B600E2CC1B /* PRTextStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BE8825E250DD7B600E2CC1B /* PRTextStorage.m */; };
1BE88262250E3ABB00E2CC1B /* EditorContentName.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BE88261250E3ABB00E2CC1B /* EditorContentName.h */; };
1BE88264250E3ADB00E2CC1B /* EditorContentName.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BE88263250E3ADB00E2CC1B /* EditorContentName.m */; };
1BF90FB4245E503E00A411A3 /* TextBlockAttributeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF90FB3245E503E00A411A3 /* TextBlockAttributeTests.swift */; };
1BFFEF0523C308BF00D2BA35 /* MockAutogrowingTextViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFFEF0423C308BF00D2BA35 /* MockAutogrowingTextViewDelegate.swift */; };
1BFFEF0C23C30D5200D2BA35 /* EditorContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFFEF0B23C30D5200D2BA35 /* EditorContentView.swift */; };
Expand All @@ -109,6 +112,7 @@
1BFFEF1C23C334D200D2BA35 /* InlineEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFFEF1B23C334D200D2BA35 /* InlineEditorView.swift */; };
1BFFEF1F23C3366200D2BA35 /* MockAttachmentOffsetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFFEF1E23C3366200D2BA35 /* MockAttachmentOffsetProvider.swift */; };
1BFFEF2123C33EA900D2BA35 /* PanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFFEF2023C33EA900D2BA35 /* PanelView.swift */; };
3F79CCB2250EF065008C53C4 /* DefaultTextFormattingProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F79CCB1250EF065008C53C4 /* DefaultTextFormattingProviding.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -164,7 +168,7 @@
1B45CDA323BEEC3D001EB196 /* testRendersTextViewBasedOnContent@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testRendersTextViewBasedOnContent@3x.png"; sourceTree = "<group>"; };
1B45CDA423BEEC3D001EB196 /* testRendersMultilineTextViewBasedOnContent@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testRendersMultilineTextViewBasedOnContent@3x.png"; sourceTree = "<group>"; };
1B45CDA823BEED0E001EB196 /* AutogrowingTextViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutogrowingTextViewTests.swift; sourceTree = "<group>"; };
1B45CDB923BF10DF001EB196 /* TextStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextStorage.swift; sourceTree = "<group>"; };
1B45CDB923BF10DF001EB196 /* TextStorageDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextStorageDelegate.swift; sourceTree = "<group>"; };
1B45CDBB23BF1174001EB196 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
1B45CDBD23BF125D001EB196 /* NSAttributedString+ContentTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+ContentTypes.swift"; sourceTree = "<group>"; };
1B45CDC023BF131B001EB196 /* TextStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextStorageTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -253,6 +257,11 @@
1BD993B723C9AE4200563ACB /* NSAttributedString+Content.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Content.swift"; sourceTree = "<group>"; };
1BD993BF23C9EAA900563ACB /* TextTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextTransformer.swift; sourceTree = "<group>"; };
1BD993C323CACCE100563ACB /* MockAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAttachment.swift; sourceTree = "<group>"; };
1BE8825D250DD79E00E2CC1B /* PRTextStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PRTextStorage.h; sourceTree = "<group>"; };
1BE8825E250DD7B600E2CC1B /* PRTextStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PRTextStorage.m; sourceTree = "<group>"; };
1BE88260250DD81500E2CC1B /* Proton-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Proton-Bridging-Header.h"; sourceTree = "<group>"; };
1BE88261250E3ABB00E2CC1B /* EditorContentName.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EditorContentName.h; sourceTree = "<group>"; };
1BE88263250E3ADB00E2CC1B /* EditorContentName.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EditorContentName.m; sourceTree = "<group>"; };
1BF90FB3245E503E00A411A3 /* TextBlockAttributeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBlockAttributeTests.swift; sourceTree = "<group>"; };
1BFFEF0423C308BF00D2BA35 /* MockAutogrowingTextViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockAutogrowingTextViewDelegate.swift; sourceTree = "<group>"; };
1BFFEF0B23C30D5200D2BA35 /* EditorContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorContentView.swift; sourceTree = "<group>"; };
Expand All @@ -273,6 +282,7 @@
1BFFEF3123C342D800D2BA35 /* testWidthRangeRendering@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testWidthRangeRendering@3x.png"; sourceTree = "<group>"; };
1BFFEF3223C342D800D2BA35 /* testMatchContainerRendering@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testMatchContainerRendering@3x.png"; sourceTree = "<group>"; };
1BFFEF3323C342D800D2BA35 /* testFixedWidthRendering@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "testFixedWidthRendering@3x.png"; sourceTree = "<group>"; };
3F79CCB1250EF065008C53C4 /* DefaultTextFormattingProviding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTextFormattingProviding.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -424,7 +434,8 @@
1B45CDB823BF10C1001EB196 /* Core */ = {
isa = PBXGroup;
children = (
1B45CDB923BF10DF001EB196 /* TextStorage.swift */,
1B45CDB923BF10DF001EB196 /* TextStorageDelegate.swift */,
3F79CCB1250EF065008C53C4 /* DefaultTextFormattingProviding.swift */,
1B45CDCF23C007AF001EB196 /* RichTextView.swift */,
1BD21553246951090000BCE2 /* LayoutManager.swift */,
1B45CDD123C00856001EB196 /* TextContainer.swift */,
Expand All @@ -436,6 +447,10 @@
1BD9323D243CA506005E4136 /* CommandName.swift */,
1B45014E247E5AD9007B3EE9 /* SequenceGenerator.swift */,
1B30A35F2489CE3E00FA1D48 /* ListFormattingProvider.swift */,
1BE8825D250DD79E00E2CC1B /* PRTextStorage.h */,
1BE8825E250DD7B600E2CC1B /* PRTextStorage.m */,
1BE88261250E3ABB00E2CC1B /* EditorContentName.h */,
1BE88263250E3ADB00E2CC1B /* EditorContentName.m */,
);
path = Core;
sourceTree = "<group>";
Expand Down Expand Up @@ -640,6 +655,7 @@
1B45CDC323BF13B8001EB196 /* Helpers */,
1B91F4AF23C72D66003F9B55 /* TextProcessors */,
1BB214CA23BB2778008B84A0 /* Info.plist */,
1BE88260250DD81500E2CC1B /* Proton-Bridging-Header.h */,
);
path = Sources;
sourceTree = "<group>";
Expand Down Expand Up @@ -814,6 +830,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
1BE88262250E3ABB00E2CC1B /* EditorContentName.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -872,7 +889,7 @@
TargetAttributes = {
1BB214C523BB2778008B84A0 = {
CreatedOnToolsVersion = 11.3;
LastSwiftMigration = 1130;
LastSwiftMigration = 1160;
};
1BB214CE23BB2778008B84A0 = {
CreatedOnToolsVersion = 11.3;
Expand Down Expand Up @@ -929,6 +946,7 @@
1B7A985923C484BC00C34B14 /* RichTextViewDelegate.swift in Sources */,
1B45CDE123C05476001EB196 /* UIColor+Image.swift in Sources */,
1B45CD9123BDD7E6001EB196 /* AutogrowingTextView.swift in Sources */,
1BE88264250E3ADB00E2CC1B /* EditorContentName.m in Sources */,
1B45CDE623C05942001EB196 /* AttachmentSize.swift in Sources */,
1B975AFB23CD3E9B00EC410C /* RendererView.swift in Sources */,
1B164F1023D1BE9900A0869A /* AttributesDecoding.swift in Sources */,
Expand All @@ -951,14 +969,15 @@
1B2BC0DD23CF18C700407DEE /* EditorContentDecoding.swift in Sources */,
1B45CDC523BF13D4001EB196 /* NSRangeExtensions.swift in Sources */,
1BBAC3E023CE81F40088A1C8 /* RendererCommandExecutor.swift in Sources */,
1BE8825F250DD7B600E2CC1B /* PRTextStorage.m in Sources */,
1B45014F247E5AD9007B3EE9 /* SequenceGenerator.swift in Sources */,
1BD993B823C9AE4200563ACB /* NSAttributedString+Content.swift in Sources */,
1B975B0123CD45DC00EC410C /* RendererViewContext.swift in Sources */,
1B4B60CD247FC6AF002B63CF /* ListTextProcessor.swift in Sources */,
1BFFEF0C23C30D5200D2BA35 /* EditorContentView.swift in Sources */,
1B82570923C5674E0033A0A9 /* EditorCommand.swift in Sources */,
1B82570D23C5686F0033A0A9 /* EditorViewContext.swift in Sources */,
1B45CDBA23BF10DF001EB196 /* TextStorage.swift in Sources */,
1B45CDBA23BF10DF001EB196 /* TextStorageDelegate.swift in Sources */,
1B975AFF23CD454700EC410C /* RichTextViewContext.swift in Sources */,
1B45CDE823C05C0C001EB196 /* Focusable.swift in Sources */,
1B164F4123D2A4AB00A0869A /* String+NSRange.swift in Sources */,
Expand All @@ -970,6 +989,7 @@
1B45CDE423C05916001EB196 /* SelectionView.swift in Sources */,
1B30A3602489CE3E00FA1D48 /* ListFormattingProvider.swift in Sources */,
1BD9323E243CA506005E4136 /* CommandName.swift in Sources */,
3F79CCB2250EF065008C53C4 /* DefaultTextFormattingProviding.swift in Sources */,
1B82570B23C567B90033A0A9 /* EditorCommandExecutor.swift in Sources */,
1B183D8C23CEA90400AE83E5 /* EditorContentEncoding.swift in Sources */,
);
Expand Down Expand Up @@ -1176,6 +1196,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -1187,6 +1208,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.rajdeep.Proton;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Sources/Proton-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -1205,6 +1227,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -1216,6 +1239,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.rajdeep.Proton;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/Sources/Proton-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 12.0;
Expand All @@ -1238,6 +1262,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.rajdeep.ProtonTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand All @@ -1258,6 +1283,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.rajdeep.ProtonTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand Down
6 changes: 5 additions & 1 deletion Proton/Sources/Attachment/Attachment.swift
Expand Up @@ -38,6 +38,7 @@ public protocol AttachmentOffsetProviding: AnyObject {
func offset(for attachment: Attachment, in textContainer: NSTextContainer, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGPoint
}

@objc
class AttachmentContentView: UIView {
let name: EditorContent.Name
weak var attachment: Attachment?
Expand Down Expand Up @@ -91,11 +92,13 @@ open class Attachment: NSTextAttachment, BoundsObserving {
}
}

@objc
var spacer: NSAttributedString {
let spacer = isBlockAttachment == true ? "\n" : " "
return NSAttributedString(string: spacer)
}

@objc
func stringWithSpacers(appendPrev: Bool, appendNext: Bool) -> NSAttributedString {
let updatedString = NSMutableAttributedString()
// if appendPrev {
Expand Down Expand Up @@ -254,7 +257,8 @@ open class Attachment: NSTextAttachment, BoundsObserving {
}
}

func removeFromSuperView() {
@objc
func removeFromSuperview() {
view.removeFromSuperview()
}

Expand Down
1 change: 1 addition & 0 deletions Proton/Sources/Base/AutogrowingTextView.swift
Expand Up @@ -63,6 +63,7 @@ class AutogrowingTextView: UITextView {

override func layoutSubviews() {
super.layoutSubviews()
guard maxHeight != .greatestFiniteMagnitude else { return }
let bounds = self.bounds.integral
let fittingSize = self.calculatedSize(attributedText: attributedText, frame: frame, textContainerInset: textContainerInset)
self.isScrollEnabled = (fittingSize.height > bounds.height) || (self.maxHeight > 0 && self.maxHeight < fittingSize.height)
Expand Down
28 changes: 28 additions & 0 deletions Proton/Sources/Core/DefaultTextFormattingProviding.swift
@@ -0,0 +1,28 @@
//
// DefaultTextFormattingProviding.swift
// Proton
//
// Created by Rajdeep Kwatra on 3/1/20.
// Copyright © 2020 Rajdeep Kwatra. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import UIKit

@objc
protocol DefaultTextFormattingProviding: AnyObject {
var font: UIFont { get }
var paragraphStyle: NSMutableParagraphStyle { get }
var textColor: UIColor { get }
}
45 changes: 45 additions & 0 deletions Proton/Sources/Core/EditorContentName.h
@@ -0,0 +1,45 @@
//
// EditorContentName.h
// Proton
//
// Created by Rajdeep Kwatra on 13/9/20.
// Copyright © 2020 Rajdeep Kwatra. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef EditorContentName_h
#define EditorContentName_h


#endif /* EditorContentName_h */

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface EditorContentName : NSObject

@property (readonly, copy) NSString *rawValue;

- (instancetype)initWithRawValue:(NSString *)rawValue;

+ (EditorContentName *)paragraphName;
+ (EditorContentName *)viewOnlyName;
+ (EditorContentName *)newlineName;
+ (EditorContentName *)textName;
+ (EditorContentName *)unknownName;

@end

NS_ASSUME_NONNULL_END
53 changes: 53 additions & 0 deletions Proton/Sources/Core/EditorContentName.m
@@ -0,0 +1,53 @@
//
// EditorContentName.m
// Proton
//
// Created by Rajdeep Kwatra on 13/9/20.
// Copyright © 2020 Rajdeep Kwatra. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#import <Foundation/Foundation.h>
#import "EditorContentName.h"

@implementation EditorContentName

- (instancetype)initWithRawValue:(NSString *)rawValue {
self = [super init];
if (self) {
_rawValue = rawValue;
}
return self;
}

- (BOOL)isEqual:(id)other {
EditorContentName *otherName = (EditorContentName *)other;
return otherName.hash == self.hash;
}

- (NSUInteger)hash {
return _rawValue.hash;
}

- (NSString *)description {
return [NSString stringWithFormat:@"EditorContent.Name(rawValue: \"%@\")", [self rawValue]];
}

+ (EditorContentName *)paragraphName { return [[EditorContentName alloc] initWithRawValue:@"_paragraph"]; }
+ (EditorContentName *)viewOnlyName { return [[EditorContentName alloc] initWithRawValue:@"_viewOnly"]; }
+ (EditorContentName *)newlineName { return [[EditorContentName alloc] initWithRawValue:@"_newline"]; }
+ (EditorContentName *)textName { return [[EditorContentName alloc] initWithRawValue:@"_text"]; }
+ (EditorContentName *)unknownName { return [[EditorContentName alloc] initWithRawValue:@"_unknown"]; }

@end

0 comments on commit cf35969

Please sign in to comment.