Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Lexical/Core/Editor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ public class Editor: NSObject {
for nodeKey in nodesToProcess where nodeKey != compositionKey && nodeKey != rootNode.key {
guard
let node = getNodeByKey(key: nodeKey),
let transforms = nodeTransforms[node.type],
let transforms = nodeTransforms[type(of: node).type],
node.isAttached()
else {
continue
Expand Down
11 changes: 11 additions & 0 deletions Lexical/Core/LexicalMacros.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// File.swift
//
//
// Created by Amy Worrall on 18/07/2023.
//

import Foundation

@attached(member, names: arbitrary)
public macro LexicalNode(_ type: NodeType) = #externalMacro(module: "LexicalMacrosBase", type: "NodeMacro")
7 changes: 4 additions & 3 deletions Lexical/Core/Nodes/CodeHighlightNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ public class CodeHighlightNode: TextNode {

public var highlightType: String?

open override class var type: NodeType {
.codeHighlight
}

override public init() {
super.init()
self.type = NodeType.codeHighlight
}

required init(text: String, highlightType: String?, key: NodeKey? = nil) {
super.init(text: text, key: key)
self.highlightType = highlightType
self.type = NodeType.codeHighlight
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try super.init(from: decoder)

self.highlightType = try container.decode(String.self, forKey: .highlightType)
self.type = NodeType.codeHighlight
}

public required convenience init(text: String, key: NodeKey?) {
Expand Down
7 changes: 4 additions & 3 deletions Lexical/Core/Nodes/CodeNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,24 @@ public class CodeNode: ElementNode {

private var language: String = ""

open override class var type: NodeType {
.code
}

override public init() {
super.init()
self.type = NodeType.code
}

required init(language: String, key: NodeKey? = nil) {
super.init(key)
self.language = language
self.type = NodeType.code
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try super.init(from: decoder)

self.language = try container.decode(String.self, forKey: .language)
self.type = NodeType.code
}

override public func encode(to encoder: Encoder) throws {
Expand Down
43 changes: 2 additions & 41 deletions Lexical/Core/Nodes/HeadingNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,49 +23,10 @@ enum HeadingDefaultFontSize: Float {
case h5 = 20
}

@LexicalNode(.heading)
public class HeadingNode: ElementNode {
enum CodingKeys: String, CodingKey {
case tag
}

private var tag: HeadingTagType

// MARK: - Init

public init(tag: HeadingTagType) {
self.tag = tag

super.init()
self.type = NodeType.heading
}

public required init(_ key: NodeKey?, tag: HeadingTagType) {
self.tag = tag
super.init(key)
self.type = NodeType.heading
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.tag = try container.decode(HeadingTagType.self, forKey: .tag)
try super.init(from: decoder)

self.type = NodeType.heading
}

override public func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.tag, forKey: .tag)
}

public func getTag() -> HeadingTagType {
tag
}

override public func clone() -> Self {
Self(key, tag: tag)
}
private var _tag: HeadingTagType

override public func getAttributedStringAttributes(theme: Theme) -> [NSAttributedString.Key: Any] {
switch tag {
Expand Down
8 changes: 5 additions & 3 deletions Lexical/Core/Nodes/LineBreakNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
*/

public class LineBreakNode: Node {

open override class var type: NodeType {
.linebreak
}

override public init() {
super.init()
self.type = NodeType.linebreak
}

override required init(_ key: NodeKey?) {
super.init(key)
self.type = NodeType.linebreak
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
self.type = NodeType.linebreak
}

override public func encode(to encoder: Encoder) throws {
Expand Down
23 changes: 10 additions & 13 deletions Lexical/Core/Nodes/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,26 @@ open class Node: Codable {
case version
}

open class var type: NodeType {
.unknown
}

public func getType() -> NodeType {
return Swift.type(of: self).type
}

public var key: NodeKey
var parent: NodeKey?
public var type: NodeType
public var version: Int

public init() {
self.type = Node.getType()
self.version = 1
self.key = LexicalConstants.uninitializedNodeKey

_ = try? generateKey(node: self)
}

public init(_ key: NodeKey?) {
self.type = Node.getType()
self.version = 1

if let key, key != LexicalConstants.uninitializedNodeKey {
Expand All @@ -49,7 +54,6 @@ open class Node: Codable {
public required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
key = LexicalConstants.uninitializedNodeKey
type = try NodeType(rawValue: values.decode(String.self, forKey: .type))
version = try values.decode(Int.self, forKey: .version)

_ = try? generateKey(node: self)
Expand All @@ -58,7 +62,7 @@ open class Node: Codable {
/// Used when serialising node to JSON
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.type.rawValue, forKey: .type)
try container.encode(Self.type.rawValue, forKey: .type)
try container.encode(self.version, forKey: .version)
}

Expand All @@ -68,13 +72,6 @@ open class Node: Codable {
*/
open func didMoveTo(newEditor editor: Editor) {}

// This is an initial value for `type`.
// static methods cannot be overridden in swift so,
// each subclass needs to assign the type property in their init method
static func getType() -> NodeType {
NodeType.unknown
}

/// Provides the **preamble** part of the node's content. Typically the preamble is used for control characters to represent embedded objects (see ``DecoratorNode``).
///
/// In Lexical iOS, a node's content is split into four parts: preamble, children, text, postamble. ``ElementNode`` subclasses can implement preamble/postamble, and TextNode subclasses can implement the text part.
Expand Down Expand Up @@ -137,7 +134,7 @@ open class Node: Codable {
Lexical's paragraph nodes!)
*/
open func getBlockLevelAttributes(theme: Theme) -> BlockLevelAttributes? {
return theme.getBlockLevelAttributes(self.type)
return theme.getBlockLevelAttributes(Self.type)
}

/// Returns a mutable version of the node. Will throw an error if called outside of a Lexical Editor ``Editor/update(_:)`` callback.
Expand Down
7 changes: 4 additions & 3 deletions Lexical/Core/Nodes/ParagraphNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
import UIKit

public class ParagraphNode: ElementNode {
open override class var type: NodeType {
.paragraph
}

override public init() {
super.init()
self.type = NodeType.paragraph
}

override required init(_ key: NodeKey?) {
super.init(key)
self.type = NodeType.paragraph
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
self.type = NodeType.paragraph
}

override public func encode(to encoder: Encoder) throws {
Expand Down
8 changes: 4 additions & 4 deletions Lexical/Core/Nodes/QuoteNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
import UIKit

public class QuoteNode: ElementNode {
open override class var type: NodeType {
.quote
}

override public init() {
super.init()
self.type = NodeType.quote
}

override public required init(_ key: NodeKey?) {
super.init(key)
self.type = NodeType.quote
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)

self.type = NodeType.quote
}

override public func encode(to encoder: Encoder) throws {
Expand Down
6 changes: 4 additions & 2 deletions Lexical/Core/Nodes/RootNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import UIKit

public class RootNode: ElementNode {

open override class var type: NodeType {
.root
}

override required init() {
super.init(kRootNodeKey)
self.type = NodeType.root
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
self.type = NodeType.root
}

override public func encode(to encoder: Encoder) throws {
Expand Down
9 changes: 5 additions & 4 deletions Lexical/Core/Nodes/TextNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,17 @@ open class TextNode: Node {
var detail = TextNodeDetail()
var style: String = ""

open override class var type: NodeType {
.text
}

override public init() {
super.init()
self.type = NodeType.text
}

public required init(text: String, key: NodeKey?) {
super.init(key)
self.text = text
self.type = NodeType.text
}

public convenience init(text: String) {
Expand All @@ -224,7 +226,6 @@ open class TextNode: Node {
let serializedDetail = try container.decode(SerializedTextNodeDetail.self, forKey: .detail)
self.detail = SerializedTextNodeDetail.convertToTextDetail(from: serializedDetail)
self.style = try container.decode(String.self, forKey: .style)
self.type = NodeType.text
}

override open func encode(to encoder: Encoder) throws {
Expand Down Expand Up @@ -530,7 +531,7 @@ open class TextNode: Node {
}

public func isSimpleText() -> Bool {
return type == NodeType.text && mode == .normal
return getType() == .text && mode == .normal
}

@discardableResult
Expand Down
2 changes: 2 additions & 0 deletions Lexical/Core/Nodes/UnknownNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ public class UnknownNode: Node {
}
}

private var type: NodeType = .unknown

public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()

Expand Down
2 changes: 1 addition & 1 deletion Lexical/Core/TextUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal func canShowPlaceholder(isComposing: Bool) -> Bool {
for childNode in children {
guard let childNode = childNode as? ElementNode else { return true }

if childNode.type != NodeType.paragraph {
if type(of: childNode).type != NodeType.paragraph {
return false
}

Expand Down
8 changes: 4 additions & 4 deletions Lexical/Core/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ public func getNodeHierarchy(editorState: EditorState?) throws -> String {
} else {
formatString = ""
}
description.append("\(indentation)(\(node.key)) \(node.type.rawValue) \"\(textNode.getTextPart())\" \(formatString)")
description.append("\(indentation)(\(node.key)) \(type(of: node).type.rawValue) \"\(textNode.getTextPart())\" \(formatString)")
} else {
description.append("\(indentation)(\(node.key)) \(node.type.rawValue)")
description.append("\(indentation)(\(node.key)) \(type(of: node).type.rawValue)")
}

if let elementNode = node as? ElementNode {
Expand All @@ -283,7 +283,7 @@ public func getNodeHierarchy(editorState: EditorState?) throws -> String {
} while !currentNodes.isEmpty

hierarchyString = description.joined(separator: "\n")
cacheString = sortedNodeMap.map({ node in "\(node.key): \(node.value.type)" }).joined(separator: ", ")
cacheString = sortedNodeMap.map({ node in "\(node.key): \(type(of: node.value).type)" }).joined(separator: ", ")
}

return "Tree:\n\(hierarchyString)\nCache:\n\(cacheString)"
Expand Down Expand Up @@ -463,7 +463,7 @@ public func getNearestNodeOfType<T: ElementNode>(
var parent: Node? = node

while let unwrappedParent = parent {
if unwrappedParent.type == type, let typedParent = unwrappedParent as? T {
if unwrappedParent.getType() == type, let typedParent = unwrappedParent as? T {
return typedParent as T
}

Expand Down
Loading