Digital PCT265 story ONEAPP-7249 - Prevent UI updates when there are no model changes.
This commit is contained in:
parent
fd296b9623
commit
31096a15a5
@ -172,6 +172,7 @@
|
||||
5822720C2B1FC55F00F75BAE /* RotorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5822720A2B1FC55F00F75BAE /* RotorHandler.swift */; };
|
||||
5846ABF62B4762A600FA6C76 /* PollingBehaviorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846ABF52B4762A600FA6C76 /* PollingBehaviorModel.swift */; };
|
||||
58A9DD7D2AC2103300F5E0B0 /* ReplaceableMoleculeBehaviorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A9DD7C2AC2103300F5E0B0 /* ReplaceableMoleculeBehaviorModel.swift */; };
|
||||
58E7561D2BE04C320088BB5D /* MoleculeComparisonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */; };
|
||||
608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */; };
|
||||
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; };
|
||||
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; };
|
||||
@ -780,6 +781,7 @@
|
||||
5878F0A42BD7E68800ADE23D /* mvmcoreui.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = mvmcoreui.xcconfig; sourceTree = "<group>"; };
|
||||
5878F0A52BD7E6BE00ADE23D /* mvmcoreui_dev.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = mvmcoreui_dev.xcconfig; sourceTree = "<group>"; };
|
||||
58A9DD7C2AC2103300F5E0B0 /* ReplaceableMoleculeBehaviorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaceableMoleculeBehaviorModel.swift; sourceTree = "<group>"; };
|
||||
58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeComparisonProtocol.swift; sourceTree = "<group>"; };
|
||||
608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingHandler.swift; sourceTree = "<group>"; };
|
||||
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = "<group>"; };
|
||||
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = "<group>"; };
|
||||
@ -1254,6 +1256,7 @@
|
||||
D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */,
|
||||
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
|
||||
27577DCC286CA959001EC47E /* MoleculeMaskingProtocol.swift */,
|
||||
58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */,
|
||||
);
|
||||
path = ModelProtocols;
|
||||
sourceTree = "<group>";
|
||||
@ -3010,6 +3013,7 @@
|
||||
EA1758482BC97ED800A5C0D9 /* BadgeIndicator.swift in Sources */,
|
||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||
0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */,
|
||||
58E7561D2BE04C320088BB5D /* MoleculeComparisonProtocol.swift in Sources */,
|
||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||
AF1C336928859778006B1001 /* ActionAlertHandler.swift in Sources */,
|
||||
9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */,
|
||||
|
||||
@ -186,4 +186,20 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
||||
try container.encodeIfPresent(accessibilityTraits, forKey: .accessibilityTraits)
|
||||
try container.encodeIfPresent(disabledAccessibilityTraits, forKey: .disabledAccessibilityTraits)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return title == model.title
|
||||
&& enabled == model.enabled
|
||||
&& inverted == model.inverted
|
||||
&& action.isEqual(to: model.action)
|
||||
&& accessibilityText == model.accessibilityText
|
||||
&& accessibilityIdentifier == model.accessibilityIdentifier
|
||||
&& style == model.style
|
||||
&& size == model.size
|
||||
&& groupName == model.groupName
|
||||
&& width == model.width
|
||||
&& accessibilityTraits == model.accessibilityTraits
|
||||
&& disabledAccessibilityTraits == model.disabledAccessibilityTraits
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
|
||||
[image].compactMap({$0})
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &image, with: molecule)
|
||||
}
|
||||
|
||||
|
||||
@ -99,6 +99,19 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
||||
try container.encodeIfPresent(size, forKey: .size)
|
||||
try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& title == model.title
|
||||
&& accessibilityText == model.accessibilityText
|
||||
&& accessibilityIdentifier == model.accessibilityIdentifier
|
||||
&& inverted == model.inverted
|
||||
&& enabled == model.enabled
|
||||
&& size == model.size
|
||||
&& shouldMaskRecordedView == model.shouldMaskRecordedView
|
||||
// && action.isEqual(to: model.action) // TODO: Move to isVisiuallyEquivalent.
|
||||
}
|
||||
}
|
||||
|
||||
extension LinkModel {
|
||||
|
||||
@ -130,4 +130,20 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
|
||||
try container.encode(indicatorColor, forKey: .indicatorColor)
|
||||
try container.encodeIfPresent(position, forKey: .position)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& numberOfPages == model.numberOfPages
|
||||
&& currentIndex == model.currentIndex
|
||||
&& alwaysSendAction == model.alwaysSendAction
|
||||
&& animated == model.animated
|
||||
&& hidesForSinglePage == model.hidesForSinglePage
|
||||
&& accessibilityHasSlidesInsteadOfPage == model.accessibilityHasSlidesInsteadOfPage
|
||||
&& enabled == model.enabled
|
||||
&& inverted == model.inverted
|
||||
&& disabledIndicatorColor == model.disabledIndicatorColor
|
||||
&& indicatorColor == model.indicatorColor
|
||||
&& position == model.position
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,4 +48,9 @@ open class LabelAttributeActionModel: LabelAttributeModel {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return action.isEqual(to: model.action)
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,4 +43,9 @@
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(textColor, forKey: .textColor)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return textColor == model.textColor
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,4 +55,11 @@
|
||||
try container.encodeIfPresent(name, forKey: .name)
|
||||
try container.encodeIfPresent(size, forKey: .size)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return style == model.style
|
||||
&& name == model.name
|
||||
&& size == model.size
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,4 +69,12 @@ class LabelAttributeImageModel: LabelAttributeModel {
|
||||
try container.encodeIfPresent(URL, forKey: .URL)
|
||||
try container.encodeIfPresent(tintColor, forKey: .tintColor)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return URL == model.URL
|
||||
&& name == model.name
|
||||
&& size == model.size
|
||||
&& tintColor == model.tintColor
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,4 +75,10 @@
|
||||
try container.encode(location, forKey: .location)
|
||||
try container.encode(length, forKey: .length)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return location == model.location
|
||||
&& length == model.length
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,6 +66,13 @@ import UIKit
|
||||
try container.encode(style, forKey: .style)
|
||||
try container.encodeIfPresent(pattern, forKey: .pattern)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return style == model.style
|
||||
&& color == model.color
|
||||
&& pattern == model.pattern
|
||||
}
|
||||
}
|
||||
|
||||
public enum UnderlineStyle: String, Codable {
|
||||
|
||||
@ -132,6 +132,26 @@ import VDS
|
||||
try container.encodeIfPresent(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
|
||||
try container.encodeIfPresent(accessibilityTraits, forKey: .accessibilityTraits)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& text == model.text
|
||||
&& accessibilityText == model.accessibilityText
|
||||
&& textColor == model.textColor
|
||||
&& fontStyle == model.fontStyle
|
||||
&& fontName == model.fontName
|
||||
&& fontSize == model.fontSize
|
||||
&& textAlignment == model.textAlignment
|
||||
&& attributes.areEqual(to: model.attributes)
|
||||
&& html == model.html
|
||||
&& hero == model.hero
|
||||
&& makeWholeViewClickable == model.makeWholeViewClickable
|
||||
&& numberOfLines == model.numberOfLines
|
||||
&& shouldMaskRecordedView == model.shouldMaskRecordedView
|
||||
&& accessibilityTraits == model.accessibilityTraits
|
||||
&& inverted == inverted
|
||||
}
|
||||
}
|
||||
|
||||
extension LabelModel {
|
||||
|
||||
@ -129,4 +129,12 @@ public class LineModel: MoleculeModelProtocol, Invertable {
|
||||
try container.encodeIfPresent(frequency, forKey: .frequency)
|
||||
try container.encode(orientation == .vertical, forKey: .useVerticalLine)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return type == model.type
|
||||
&& inverted == model.inverted
|
||||
&& frequency == model.frequency
|
||||
&& orientation == model.orientation
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ open class TileContainerModel: TileContainerBaseModel<TileContainer.Padding, Til
|
||||
return [molecule]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &self.molecule, with: molecule)
|
||||
}
|
||||
|
||||
|
||||
@ -21,9 +21,13 @@ public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol, ParentMol
|
||||
[titleLockup, buttons]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &titleLockup, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -24,13 +24,17 @@ public class HeadersH1LandingPageHeaderModel: HeaderModel, MoleculeModelProtocol
|
||||
[headline, headline2, subHeadline, body, link, buttons]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &headline2, with: molecule)
|
||||
|| replaceChildMolecule(at: &subHeadline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &headline2, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &subHeadline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -19,7 +19,7 @@ public class HeadersH1NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
||||
[titleLockup]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
}
|
||||
|
||||
|
||||
@ -23,9 +23,13 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol, ParentMo
|
||||
[titleLockup, buttons]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &titleLockup, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &buttons, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -20,9 +20,13 @@ public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol, Parent
|
||||
[titleLockup, caretLink]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
|| replaceChildMolecule(at: &caretLink, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &titleLockup, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &caretLink, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public class HeadersH2LinkModel: HeaderModel, MoleculeModelProtocol, ParentMoleculeModelProtocol {
|
||||
public class HeadersH2LinkModel: HeaderModel, ParentMoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -22,9 +22,13 @@ public class HeadersH2LinkModel: HeaderModel, MoleculeModelProtocol, ParentMolec
|
||||
[titleLockup, link]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &titleLockup, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -22,7 +22,7 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
|
||||
[titleLockup]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
}
|
||||
|
||||
|
||||
@ -25,15 +25,19 @@ public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol, P
|
||||
[headline, body, subBody, body2, subBody2, body3, subBody3].compactMap({$0})
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
|| replaceChildMolecule(at: &subBody, with: molecule)
|
||||
|| replaceChildMolecule(at: &body2, with: molecule)
|
||||
|| replaceChildMolecule(at: &body2, with: molecule)
|
||||
|| replaceChildMolecule(at: &subBody2, with: molecule)
|
||||
|| replaceChildMolecule(at: &body3, with: molecule)
|
||||
|| replaceChildMolecule(at: &subBody3, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &subBody, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body2, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body2, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &subBody2, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body3, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &subBody3, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -23,9 +23,13 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol, Paren
|
||||
[titleLockup, button]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &titleLockup, with: molecule)
|
||||
|| replaceChildMolecule(at: &button, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &titleLockup, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &button, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -20,9 +20,13 @@ open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelPr
|
||||
[checkbox, headlineBody]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &checkbox, with: molecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &checkbox, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -20,9 +20,13 @@ public class ListLeftVariableIconAllTextLinksModel: ListItemModel, MoleculeModel
|
||||
return [image, eyebrowHeadlineBodyLink]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &image, with: molecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &image, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -21,10 +21,14 @@ public class ListLeftVariableIconWithRightCaretAllTextLinksModel: ListItemModel,
|
||||
return [image, eyebrowHeadlineBodyLink, rightLabel]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &image, with: molecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &image, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -21,10 +21,14 @@ public class ListLeftVariableIconWithRightCaretBodyTextModel: ListItemModel, Par
|
||||
[image, headlineBody, rightLabel]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &image, with: molecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: molecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &image, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -21,10 +21,14 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, ParentMolec
|
||||
return [image, leftLabel, rightLabel]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &image, with: molecule)
|
||||
|| replaceChildMolecule(at: &leftLabel, with: molecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &image, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &leftLabel, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &rightLabel, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -20,9 +20,13 @@ open class ListLeftVariableRadioButtonBodyTextModel: ListItemModel, ParentMolecu
|
||||
[radioButton, headlineBody]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &radioButton, with: replacementMolecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: replacementMolecule)
|
||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &radioButton, with: replacementMolecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &headlineBody, with: replacementMolecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -39,7 +39,7 @@ public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeMod
|
||||
return [headlineBody]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &headlineBody, with: molecule)
|
||||
}
|
||||
|
||||
@ -68,4 +68,9 @@ public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeMod
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(headlineBody, forKey: .headlineBody)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return headlineBody.isEqual(to: headlineBody)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,9 +40,13 @@ public class ListRightVariableButtonAllTextAndLinksModel: ListItemModel, Molecul
|
||||
return [button, eyebrowHeadlineBodyLink]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &button, with: molecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &button, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -20,9 +20,13 @@ public class ListRightVariableRightCaretAllTextAndLinksModel: ListItemModel, Par
|
||||
[rightLabel, eyebrowHeadlineBodyLink]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &rightLabel, with: molecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &rightLabel, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &eyebrowHeadlineBodyLink, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import VDSTokens
|
||||
import VDS
|
||||
|
||||
public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
|
||||
public class TitleLockupModel: ParentMoleculeModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
@ -34,10 +34,24 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
|
||||
[eyebrow, title, subTitle].compactMap { (molecule: MoleculeModelProtocol?) in molecule }
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &eyebrow, with: molecule)
|
||||
|| replaceChildMolecule(at: &title, with: molecule)
|
||||
|| replaceChildMolecule(at: &subTitle, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &eyebrow, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &title, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &subTitle, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return textAlignment == model.textAlignment
|
||||
&& subTitleColor == model.subTitleColor
|
||||
&& alignment == model.alignment
|
||||
&& inverted == model.inverted
|
||||
&& backgroundColor == model.backgroundColor
|
||||
&& children.areEqual(to: model.children)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -22,9 +22,13 @@ public class ListOneColumnFullWidthTextDividerSubsectionModel: ListItemModel, Mo
|
||||
[headline, body].compactMap({$0})
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -22,9 +22,13 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
|
||||
[headline, body].compactMap({$0})
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -22,9 +22,13 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
|
||||
[headline, body].compactMap({$0})
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -23,9 +23,13 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol {
|
||||
|
||||
public var children: [MoleculeModelProtocol] { [primaryButton, secondaryButton].compactMap { $0 } }
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &primaryButton, with: molecule)
|
||||
|| replaceChildMolecule(at: &secondaryButton, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &primaryButton, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &secondaryButton, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -85,8 +85,19 @@
|
||||
try container.encodeIfPresent(peakingUI, forKey: .peakingUI)
|
||||
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
try container.encode(readOnly, forKey: .readOnly)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return peakingUI == model.peakingUI
|
||||
&& peakingArrowColor == model.peakingArrowColor
|
||||
&& analyticsData == model.analyticsData
|
||||
&& fieldValue == model.fieldValue
|
||||
&& enabled == model.enabled
|
||||
&& readOnly == model.readOnly
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
import MVMCore
|
||||
|
||||
@objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -73,4 +73,10 @@
|
||||
try container.encodeIfPresent(border, forKey: .border)
|
||||
try super.encode(to: encoder)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return action.isEqual(to: model.action)
|
||||
&& border == border
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,4 +52,18 @@ import MVMCore
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModel(molecule, forKey: .molecule)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& action.isEqual(to: model.action)
|
||||
&& hideArrow == model.hideArrow
|
||||
&& line.isEqual(to: model.line)
|
||||
&& style == model.style
|
||||
&& gone == model.gone
|
||||
&& molecule.isEqual(to: model.molecule)
|
||||
&& accessibilityTraits == model.accessibilityTraits
|
||||
&& accessibilityValue == model.accessibilityValue
|
||||
&& accessibilityText == model.accessibilityText
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,4 +58,12 @@
|
||||
try container.encodeIfPresent(percent, forKey: .percent)
|
||||
try container.encode(gone, forKey: .gone)
|
||||
}
|
||||
|
||||
public override func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard super.isEqual(to: model), let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& spacing == model.spacing
|
||||
&& percent == model.percent
|
||||
&& gone == model.gone
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,4 +36,12 @@
|
||||
required public init(from decoder: Decoder) throws {
|
||||
fatalError("init(from:) has not been implemented")
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& spacing == model.spacing
|
||||
&& percent == model.percent
|
||||
&& gone == model.gone
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,12 +23,16 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol {
|
||||
[molecule, topLeftLabel, topRightLabel, bottomLeftLabel, bottomRightLabel].compactMap { $0 }
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &self.molecule, with: molecule)
|
||||
|| replaceChildMolecule(at: &topLeftLabel, with: molecule)
|
||||
|| replaceChildMolecule(at: &topRightLabel, with: molecule)
|
||||
|| replaceChildMolecule(at: &bottomLeftLabel, with: molecule)
|
||||
|| replaceChildMolecule(at: &bottomRightLabel, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &self.molecule, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &topLeftLabel, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &topRightLabel, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &bottomLeftLabel, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &bottomRightLabel, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public init(with molecule: MoleculeModelProtocol?) {
|
||||
|
||||
@ -20,7 +20,7 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
|
||||
return [molecule]
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &self.molecule, with: molecule)
|
||||
}
|
||||
|
||||
@ -61,4 +61,10 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
|
||||
try container.encodeModel(molecule, forKey: .molecule)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return molecule.isEqual(to: model.molecule)
|
||||
&& backgroundColor == model.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ public extension MoleculeContainerModelProtocol {
|
||||
}
|
||||
|
||||
public extension MoleculeContainerModelProtocol where Self: AnyObject {
|
||||
mutating func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
mutating func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(at: &molecule, with: replacementMolecule)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
|
||||
public class EyebrowHeadlineBodyLinkModel: ParentMoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -25,11 +25,15 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule
|
||||
[eyebrow, headline, body, link].compactMap { (molecule: MoleculeModelProtocol?) in molecule }
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &eyebrow, with: molecule)
|
||||
|| replaceChildMolecule(at: &headline, with: molecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &eyebrow, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &headline, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &body, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &link, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -102,4 +106,10 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(link, forKey: .link)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& children.areEqual(to: model.children)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,9 +24,13 @@ open class HeadlineBodyModel: ParentMoleculeModelProtocol {
|
||||
[headline, body].compactMap { $0 }
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at:&headline, with: replacementMolecule)
|
||||
|| replaceChildMolecule(at:&body, with: replacementMolecule)
|
||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at:&headline, with: replacementMolecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at:&body, with: replacementMolecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -89,6 +93,14 @@ open class HeadlineBodyModel: ParentMoleculeModelProtocol {
|
||||
try container.encodeIfPresent(style, forKey: .style)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return headline.isEqual(to: model.headline)
|
||||
&& body.isEqual(to: model.body)
|
||||
&& style == style
|
||||
&& backgroundColor == backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
public extension HeadlineBodyModel {
|
||||
|
||||
@ -171,6 +171,29 @@ import UIKit
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
try container.encode(readOnly, forKey: .readOnly)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == backgroundColor
|
||||
&& molecules.areEqual(to: model.molecules)
|
||||
&& spacing == model.spacing
|
||||
&& border == model.border
|
||||
&& loop == model.loop
|
||||
&& height == model.height
|
||||
&& itemWidthPercent == model.itemWidthPercent
|
||||
&& itemAlignment == model.itemAlignment
|
||||
&& pagingMolecule.isEqual(to: model.pagingMolecule)
|
||||
&& paging == model.paging
|
||||
&& useHorizontalMargins == model.useHorizontalMargins
|
||||
&& leftPadding == model.leftPadding
|
||||
&& rightPadding == model.rightPadding
|
||||
&& accessibilityText == model.accessibilityText
|
||||
&& baseValue == model.baseValue
|
||||
&& fieldKey == model.fieldKey
|
||||
&& groupName == model.groupName
|
||||
&& enabled == model.enabled
|
||||
&& readOnly == model.readOnly
|
||||
}
|
||||
}
|
||||
|
||||
extension CarouselModel {
|
||||
@ -179,7 +202,7 @@ extension CarouselModel {
|
||||
return molecules
|
||||
}
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(in: &molecules, with: molecule)
|
||||
}
|
||||
|
||||
|
||||
@ -79,4 +79,11 @@
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
public func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return backgroundColor == model.backgroundColor
|
||||
&& molecules.areEqual(to: model.molecules)
|
||||
&& axis == model.axis
|
||||
&& spacing == model.spacing
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ extension StackModelProtocol {
|
||||
|
||||
extension StackModelProtocol where Self: AnyObject {
|
||||
|
||||
public mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
return try replaceChildMolecule(in: &molecules, with: molecule)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,3 +7,19 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol MoleculeModelComparisonProtocol: ModelProtocol {
|
||||
|
||||
/** True if there are no visual differences between models.
|
||||
|
||||
By default if the models are equal then they are visually equivalent. However, if there are parts of models that can be upddated without a UI update, this could be subset of properties.
|
||||
**/
|
||||
func isVisuallyEquivalent(to model: MoleculeModelComparisonProtocol) -> Bool
|
||||
}
|
||||
|
||||
extension MoleculeModelComparisonProtocol {
|
||||
|
||||
public func isVisuallyEquivalent(to model: MoleculeModelComparisonProtocol) -> Bool {
|
||||
return isEqual(to: model)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ public enum MolecularError: Swift.Error {
|
||||
case countImbalance(String)
|
||||
}
|
||||
|
||||
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol, MoleculeMaskingProtocol {
|
||||
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol, MoleculeMaskingProtocol, MoleculeModelComparisonProtocol, CustomDebugStringConvertible {
|
||||
var moleculeName: String { get }
|
||||
var backgroundColor: Color? { get set }
|
||||
var id: String { get }
|
||||
@ -18,6 +18,15 @@ public extension MoleculeModelProtocol {
|
||||
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
||||
|
||||
static var categoryCodingKey: String { "moleculeName" }
|
||||
|
||||
func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return id == model.id
|
||||
}
|
||||
|
||||
var debugDescription: String {
|
||||
return "\(moleculeName): \(id)"
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers made due to swift not able to reconcile which category.
|
||||
|
||||
@ -8,52 +8,70 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol ParentModelProtocol: MoleculeTreeTraversalProtocol {
|
||||
public protocol ParentModelProtocol: ModelProtocol, MoleculeTreeTraversalProtocol {
|
||||
|
||||
/// Returns the direct children of this component. (Does not recurse.)
|
||||
var children: [MoleculeModelProtocol] { get }
|
||||
|
||||
/// Method for replacing surface level children. (Does not recurse.)
|
||||
mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool
|
||||
mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol?
|
||||
}
|
||||
|
||||
public extension ParentModelProtocol where Self: AnyObject {
|
||||
|
||||
|
||||
/// Top level test to replace child molecules. Each parent molecule should attempt to replace.
|
||||
func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { return false }
|
||||
func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? { return nil }
|
||||
|
||||
func replaceChildMolecule<T>(at childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
return try replaceChildMolecule(at: &childMolecule, with: replacementMolecule, replaced: &replacedMolecule) ? replacedMolecule : nil
|
||||
}
|
||||
|
||||
/// Helper function for replacing a single molecules with type and optionality checks.
|
||||
func replaceChildMolecule<T>(at childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
func replaceChildMolecule<T>(at childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol, replaced: inout MoleculeModelProtocol?) throws -> Bool {
|
||||
guard let childIdMolecule = childMolecule as? MoleculeModelProtocol else { return false }
|
||||
if childIdMolecule.id == replacementMolecule.id {
|
||||
guard let replacementMolecule = replacementMolecule as? T else {
|
||||
guard let typedReplacementMolecule = replacementMolecule as? T else {
|
||||
throw MolecularError.error("Molecular replacement '\(replacementMolecule.id)' does not type match \(type(of: T.self)) of \(type(of: self))")
|
||||
}
|
||||
childMolecule = replacementMolecule
|
||||
replaced = childIdMolecule
|
||||
childMolecule = typedReplacementMolecule
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func replaceChildMolecule<T>(in molecules: inout [T], with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
return try replaceChildMolecule(at: &molecules, with: replacementMolecule, replaced: &replacedMolecule) ? replacedMolecule : nil
|
||||
}
|
||||
|
||||
/// Helper for replacing a molecule in place within an array. Note the "in".
|
||||
func replaceChildMolecule<T>(in molecules: inout [T], with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
guard let moleculeIdModels = molecules as? [MoleculeModelProtocol], let matchingIndex = moleculeIdModels.firstIndex(where: {
|
||||
$0.id == replacementMolecule.id
|
||||
}) else { return false }
|
||||
guard let replacementMolecule = replacementMolecule as? T else {
|
||||
func replaceChildMolecule<T>(in molecules: inout [T], with replacementMolecule: MoleculeModelProtocol, replaced: inout MoleculeModelProtocol?) throws -> Bool {
|
||||
guard let moleculeIdModels = molecules as? [MoleculeModelProtocol],
|
||||
let matchingIndex = moleculeIdModels.firstIndex(where: {
|
||||
$0.id == replacementMolecule.id
|
||||
})
|
||||
else { return false }
|
||||
guard let typedReplacementMolecule = replacementMolecule as? T else {
|
||||
throw MolecularError.error("Molecular replacement '\(replacementMolecule.id)' does not type match \(type(of: T.self)) of \(type(of: self))")
|
||||
}
|
||||
molecules[matchingIndex] = replacementMolecule
|
||||
replaced = molecules[matchingIndex] as? MoleculeModelProtocol
|
||||
molecules[matchingIndex] = typedReplacementMolecule
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public protocol ParentMoleculeModelProtocol: ParentModelProtocol, MoleculeModelProtocol {
|
||||
|
||||
}
|
||||
|
||||
public extension ParentMoleculeModelProtocol {
|
||||
|
||||
func isEqual(to model: any ModelProtocol) -> Bool {
|
||||
guard let model = model as? Self else { return false }
|
||||
return model.children.areEqual(to: model.children)
|
||||
}
|
||||
|
||||
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result {
|
||||
var result = initialResult
|
||||
if (options == .parentFirst) {
|
||||
@ -64,7 +82,7 @@ public extension ParentMoleculeModelProtocol {
|
||||
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
||||
return additionalParent.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||
}
|
||||
return molecule.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||
return nextPartialResult(result, molecule, depth + 1)
|
||||
}
|
||||
if (options == .childFirst) {
|
||||
result = nextPartialResult(result, self, depth)
|
||||
@ -88,7 +106,7 @@ public extension ParentMoleculeModelProtocol {
|
||||
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
||||
additionalParent.depthFirstTraverse(options: options, depth: depth + 1, onVisit: stopIntercept)
|
||||
} else {
|
||||
child.depthFirstTraverse(options: options, depth: depth + 1, onVisit: stopIntercept)
|
||||
onVisit(depth, child, &shouldStop)
|
||||
}
|
||||
guard !shouldStop else { return }
|
||||
}
|
||||
@ -98,3 +116,29 @@ public extension ParentMoleculeModelProtocol {
|
||||
// if options == .leafOnly don't call on self.
|
||||
}
|
||||
}
|
||||
|
||||
extension ParentModelProtocol {
|
||||
|
||||
func deepCompare(_ anotherParent: ParentModelProtocol, with test: (ModelProtocol, ModelProtocol)->Bool) -> (Bool, myChild: ModelProtocol?, theirChild: ModelProtocol?) {
|
||||
|
||||
guard test(self, anotherParent) else { return (false, myChild: self, theirChild: self)}
|
||||
|
||||
let myChildren = children
|
||||
let theirChildren = anotherParent.children
|
||||
guard myChildren.count == theirChildren.count else { return (false, myChild: self, theirChild: self) }
|
||||
for index in myChildren.indices {
|
||||
if let myChild = myChildren[index] as? ParentModelProtocol {
|
||||
if let theirChild = theirChildren[index] as? ParentModelProtocol {
|
||||
let result = myChild.deepCompare(theirChild, with: test)
|
||||
guard result.0 else { return result }
|
||||
} else {
|
||||
return (false, myChild: myChild, theirChild: theirChildren[index])
|
||||
}
|
||||
} else if !test(myChildren[index], theirChildren[index]) {
|
||||
return (false, myChild: myChildren[index], theirChild: theirChildren[index])
|
||||
}
|
||||
}
|
||||
|
||||
return (true, nil, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,27 +42,27 @@ public extension TemplateModelProtocol {
|
||||
extension TemplateModelProtocol {
|
||||
|
||||
/// Recursively finds and replaces the first child matching the replacement molecule id property.
|
||||
mutating func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||
mutating func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
// Attempt root level replacement on the template model first.
|
||||
if try replaceChildMolecule(with: replacementMolecule) {
|
||||
return true
|
||||
if let replacedMolecule = try replaceChildMolecule(with: replacementMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
|
||||
var didReplaceMolecule = false
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
var possibleError: Error?
|
||||
// Dive into each root thereafter.
|
||||
depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in
|
||||
guard var parentMolecule = molecule as? ParentMoleculeModelProtocol else { return }
|
||||
do {
|
||||
didReplaceMolecule = try parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
||||
replacedMolecule = try parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
||||
} catch {
|
||||
possibleError = error
|
||||
}
|
||||
stop = didReplaceMolecule || possibleError != nil
|
||||
stop = replacedMolecule != nil || possibleError != nil
|
||||
}
|
||||
if let error = possibleError {
|
||||
throw error
|
||||
}
|
||||
return didReplaceMolecule
|
||||
return replacedMolecule
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,8 +35,12 @@ import Foundation
|
||||
public var hideLeftPanel: Bool?
|
||||
public var hideRightPanel: Bool?
|
||||
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try replaceChildMolecule(at: &navigationBar, with: molecule)
|
||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &navigationBar, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -23,9 +23,14 @@
|
||||
return super.rootMolecules
|
||||
}
|
||||
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try super.replaceChildMolecule(with: molecule)
|
||||
|| (molecules != nil && replaceChildMolecule(in: &(molecules!), with: molecule))
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
if let replacedMolecule = try super.replaceChildMolecule(with: molecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
if molecules != nil, let replacedMolecule = try replaceChildMolecule(in: &(molecules!), with: molecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -28,10 +28,16 @@
|
||||
return super.rootMolecules
|
||||
}
|
||||
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try super.replaceChildMolecule(with: molecule)
|
||||
|| (molecules != nil && replaceChildMolecule(in: &(molecules!), with: molecule))
|
||||
|| replaceChildMolecule(at: &line, with: molecule)
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
if let replacedMolecule = try super.replaceChildMolecule(with: molecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try (molecules != nil && replaceChildMolecule(in: &(molecules!), with: molecule, replaced: &replacedMolecule))
|
||||
|| replaceChildMolecule(at: &line, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// This template requires content.
|
||||
|
||||
@ -19,10 +19,14 @@
|
||||
super.rootMolecules + [moleculeStack]
|
||||
}
|
||||
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
return try super.replaceChildMolecule(with: molecule)
|
||||
|| replaceChildMolecule(at: &navigationBar, with: molecule)
|
||||
|| replaceChildMolecule(at: &moleculeStack, with: molecule)
|
||||
if try replaceChildMolecule(at: &navigationBar, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &moleculeStack, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -21,10 +21,16 @@
|
||||
[navigationBar, header, footer].compactMap { $0 }
|
||||
}
|
||||
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try super.replaceChildMolecule(with: molecule)
|
||||
|| replaceChildMolecule(at: &header, with: molecule)
|
||||
|| replaceChildMolecule(at: &footer, with: molecule)
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
if let replacedMolecule = try super.replaceChildMolecule(with: molecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &header, with: molecule, replaced: &replacedMolecule)
|
||||
|| replaceChildMolecule(at: &footer, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -22,9 +22,15 @@
|
||||
return super.rootMolecules
|
||||
}
|
||||
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||
return try super.replaceChildMolecule(with: molecule)
|
||||
|| replaceChildMolecule(at: &middle, with: molecule)
|
||||
public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> MoleculeModelProtocol? {
|
||||
if let replacedMolecule = try super.replaceChildMolecule(with: molecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
if try replaceChildMolecule(at: &middle, with: molecule, replaced: &replacedMolecule) {
|
||||
return replacedMolecule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -513,27 +513,34 @@ import MVMCore
|
||||
|
||||
public func replaceMoleculeData(_ moleculeModels: [MoleculeModelProtocol], completionHandler: (([MoleculeModelProtocol])->Void)? = nil) {
|
||||
pageUpdateQueue.addOperation {
|
||||
let replacedModels:[MoleculeModelProtocol] = moleculeModels.compactMap { model in
|
||||
guard self.attemptToReplace(with: model) else {
|
||||
let replacedModels:[(MoleculeModelProtocol, MoleculeModelProtocol)] = moleculeModels.compactMap { model in
|
||||
guard let replacedMolecule = self.attemptToReplace(with: model) else {
|
||||
return nil
|
||||
}
|
||||
return model
|
||||
return (model, replacedMolecule)
|
||||
}
|
||||
if replacedModels.count > 0 {
|
||||
let uiUpdatedModels: [MoleculeModelProtocol] = replacedModels.compactMap { new, existing in
|
||||
guard !new.isVisuallyEquivalent(to: existing) else {
|
||||
return nil
|
||||
}
|
||||
return new
|
||||
}
|
||||
if uiUpdatedModels.count > 0 {
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Updating UI for molecules: \(uiUpdatedModels)")
|
||||
DispatchQueue.main.sync {
|
||||
self.updateUI(for: replacedModels)
|
||||
self.updateUI(for: uiUpdatedModels)
|
||||
}
|
||||
}
|
||||
completionHandler?(replacedModels)
|
||||
completionHandler?(replacedModels.map { $0.0 })
|
||||
}
|
||||
}
|
||||
|
||||
open func attemptToReplace(with replacementModel: MoleculeModelProtocol) -> Bool {
|
||||
guard var templateModel = getTemplateModel() else { return false }
|
||||
var didReplace = false
|
||||
open func attemptToReplace(with replacementModel: MoleculeModelProtocol) -> MoleculeModelProtocol? {
|
||||
guard var templateModel = getTemplateModel() else { return nil }
|
||||
var replacedMolecule: MoleculeModelProtocol?
|
||||
do {
|
||||
didReplace = try templateModel.replaceMolecule(with: replacementModel)
|
||||
if !didReplace {
|
||||
replacedMolecule = try templateModel.replaceMolecule(with: replacementModel)
|
||||
if replacedMolecule == nil {
|
||||
MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Failed to find '\(replacementModel.id)' in the current screen.", code: ErrorCode.viewControllerProcessingJSON.rawValue, domain: ErrorDomainSystem, location: String(describing: type(of: self)))!)
|
||||
}
|
||||
} catch {
|
||||
@ -543,7 +550,7 @@ import MVMCore
|
||||
}
|
||||
MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
|
||||
}
|
||||
return didReplace
|
||||
return replacedMolecule
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -14,6 +14,7 @@ import UIKit
|
||||
Int and String and can be used the same.
|
||||
*/
|
||||
public final class Color: Codable {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -151,3 +152,9 @@ public final class Color: Codable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Color: Equatable {
|
||||
public static func == (lhs: Color, rhs: Color) -> Bool {
|
||||
return lhs.hex == rhs.hex
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user