diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index acb13d9a..f02ca813 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -168,6 +168,7 @@ 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */; }; 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; }; 52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; }; + 5823ADF62AB0F7BA006045A7 /* ReplacementMoleculeBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5823ADF52AB0F7BA006045A7 /* ReplacementMoleculeBehavior.swift */; }; 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; }; 8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; }; 8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; }; @@ -754,6 +755,7 @@ 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnCompareChanges.swift; sourceTree = ""; }; 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = ""; }; 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = ""; }; + 5823ADF52AB0F7BA006045A7 /* ReplacementMoleculeBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplacementMoleculeBehavior.swift; sourceTree = ""; }; 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = ""; }; 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = ""; }; 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = ""; }; @@ -1390,6 +1392,7 @@ D23A900826125FFB007E14CE /* GetContactBehavior.swift */, D270E5662642F77300CDBED2 /* AddRemoveMoleculeBehavior.swift */, 22B678F829E7944E00CF4196 /* GetNotificationAuthStatusBehavior.swift */, + 5823ADF52AB0F7BA006045A7 /* ReplacementMoleculeBehavior.swift */, ); path = Behaviors; sourceTree = ""; @@ -2752,6 +2755,7 @@ 525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */, D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */, D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */, + 5823ADF62AB0F7BA006045A7 /* ReplacementMoleculeBehavior.swift in Sources */, D20F3B44252E00E4004B3F56 /* PageProtocol.swift in Sources */, AA37CBD3251907200027344C /* StarsModel.swift in Sources */, 8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1ButtonModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1ButtonModel.swift index cdb61a4d..9ed584a9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1ButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1ButtonModel.swift @@ -20,6 +20,11 @@ public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol, ParentMol [headlineBody, buttons] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + || replaceChildMolecule(at: &buttons, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1LandingPageHeaderModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1LandingPageHeaderModel.swift index 79705fd9..651a7f89 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1LandingPageHeaderModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1LandingPageHeaderModel.swift @@ -24,6 +24,15 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1NoButtonsBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1NoButtonsBodyTextModel.swift index 9d246d98..9f3e6133 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1NoButtonsBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H1/HeadersH1NoButtonsBodyTextModel.swift @@ -20,6 +20,10 @@ public class HeadersH1NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol [headlineBody] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2ButtonsModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2ButtonsModel.swift index 77bc25c1..8a5a3e64 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2ButtonsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2ButtonsModel.swift @@ -22,6 +22,11 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol, ParentMo [headlineBody, buttons] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + || replaceChildMolecule(at: &buttons, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2CaretLinkModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2CaretLinkModel.swift index e0831a40..c50fb736 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2CaretLinkModel.swift @@ -19,6 +19,11 @@ public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol, Parent [headlineBody, caretLink] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + || replaceChildMolecule(at: &caretLink, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2LinkModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2LinkModel.swift index 20d6afe2..ced6b47a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2LinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2LinkModel.swift @@ -21,6 +21,11 @@ public class HeadersH2LinkModel: HeaderModel, MoleculeModelProtocol, ParentMolec [headlineBody, link] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + || replaceChildMolecule(at: &link, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2NoButtonsBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2NoButtonsBodyTextModel.swift index 86d38707..774102da 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2NoButtonsBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2NoButtonsBodyTextModel.swift @@ -21,6 +21,10 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol [headlineBody] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2PricingTwoRowsModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2PricingTwoRowsModel.swift index ebca7e25..54a62b5b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2PricingTwoRowsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2PricingTwoRowsModel.swift @@ -25,6 +25,17 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2TinyButtonModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2TinyButtonModel.swift index e04ab07f..2a91c860 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2TinyButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/Headers/H2/HeadersH2TinyButtonModel.swift @@ -22,6 +22,11 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol, Paren [headlineBody, button] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + || replaceChildMolecule(at: &button, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift index 3ed92e02..ba7d4986 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift @@ -20,6 +20,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift index 46de07fa..c7a32e78 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconAllTextLinksModel.swift @@ -20,6 +20,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Method //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinksModel.swift index a4fed00e..9d5ce50b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretAllTextLinksModel.swift @@ -21,6 +21,12 @@ 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) + } + //----------------------------------------------------- // MARK: - Methods //----------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift index 633989d5..6b95c669 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyTextModel.swift @@ -21,6 +21,12 @@ 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) + } + //----------------------------------------------------- // MARK: - Methods //----------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift index 186ad988..a804b8d4 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretModel.swift @@ -21,6 +21,12 @@ 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) + } + //----------------------------------------------------- // MARK: - Methods //----------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyTextModel.swift index b4ef3495..808ee19e 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableRadioButtonBodyTextModel.swift @@ -20,9 +20,9 @@ open class ListLeftVariableRadioButtonBodyTextModel: ListItemModel, ParentMolecu [radioButton, headlineBody] } - public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { - return replace(childMolecule: &radioButton, with: replacementMolecule) - || replace(childMolecule: &headlineBody, with: replacementMolecule) + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &radioButton, with: replacementMolecule) + || replaceChildMolecule(at: &headlineBody, with: replacementMolecule) } //----------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyTextModel.swift index 94be5a53..aee85f74 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyTextModel.swift @@ -39,6 +39,10 @@ public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeMod return [headlineBody] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &headlineBody, with: molecule) + } + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableButtonAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableButtonAllTextAndLinksModel.swift index 21a4b08c..121db2f4 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableButtonAllTextAndLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableButtonAllTextAndLinksModel.swift @@ -40,6 +40,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinksModel.swift index e2bc1691..94d65c37 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinksModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/RightVariable/ListRightVariableRightCaretAlltextAndLinksModel.swift @@ -20,6 +20,11 @@ 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) + } + //----------------------------------------------------- // MARK: - Methods //----------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift index 89d32ca9..bb77c26a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift @@ -64,6 +64,12 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsectionModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsectionModel.swift index 8a039144..af226405 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsectionModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnFullWidthTextDividerSubsectionModel.swift @@ -22,6 +22,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShortModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShortModel.swift index 6a40ebf7..596b9ff0 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShortModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerShortModel.swift @@ -22,6 +22,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTallModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTallModel.swift index 09b462fe..ea4c3ce2 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTallModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/SectionDividers/OneColumn/ListOneColumnTextWithWhitespaceDividerTallModel.swift @@ -22,6 +22,11 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index b5d07c4a..fa8b51a8 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -24,6 +24,11 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { return [primaryButton, secondaryButton].compactMap { $0 } } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &primaryButton, with: molecule) + || replaceChildMolecule(at: &secondaryButton, with: molecule) + } + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift index dc8f2396..4925d03b 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -18,10 +18,19 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { public var bottomLeftLabel: LabelModel? public var bottomRightLabel: LabelModel? public var molecule: MoleculeModelProtocol? + public var children: [MoleculeModelProtocol] { [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 init(with molecule: MoleculeModelProtocol?) { self.molecule = molecule } diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift index 735e95c1..6860b40a 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift @@ -20,6 +20,10 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco return [molecule] } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &self.molecule, with: molecule) + } + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift index 84b1f38e..29017c96 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift @@ -16,5 +16,9 @@ public extension MoleculeContainerModelProtocol { var children: [MoleculeModelProtocol] { return [molecule] } + + func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &molecule, with: replacementMolecule) + } } diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 0d46916e..90f72be3 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -25,6 +25,13 @@ 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) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 4371fe34..76e26f77 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -24,9 +24,9 @@ [headline, body].compactMap { $0 } } - public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { - return replace(childMolecule:&headline, with: replacementMolecule) - || replace(childMolecule:&body, with: replacementMolecule) + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at:&headline, with: replacementMolecule) + || replaceChildMolecule(at:&body, with: replacementMolecule) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift index 5bfd8d0f..c18f0e95 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift @@ -180,4 +180,8 @@ extension CarouselModel { return molecules } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(in: &molecules, with: molecule) + } + } diff --git a/MVMCoreUI/Atomic/Organisms/StackModel.swift b/MVMCoreUI/Atomic/Organisms/StackModel.swift index cb8740ac..bc254727 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModel.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModel.swift @@ -21,22 +21,6 @@ public var spacing: CGFloat = Padding.Four public var useStackSpacingBeforeFirstItem = false - public var children: [MoleculeModelProtocol] { - return molecules - } - - public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { - // IDEALLY: - //return replace(inChildMolecules: &molecules, with: replacementMolecule) - - guard let replacementMolecule = replacementMolecule as? StackItemModelProtocol & MoleculeModelProtocol else { return false } - guard let matchingIndex = molecules.firstIndex(where: { molecule in - molecule.id == replacementMolecule.id - }) else { return false } - molecules[matchingIndex] = replacementMolecule - return true - } - //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Organisms/StackModelProtocol.swift b/MVMCoreUI/Atomic/Organisms/StackModelProtocol.swift index 068418f0..3d57fe72 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModelProtocol.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModelProtocol.swift @@ -19,4 +19,8 @@ extension StackModelProtocol { public var children: [MoleculeModelProtocol] { return molecules } + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(in: &molecules, with: molecule) + } + } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift index 19a3a711..3e16069e 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift @@ -8,11 +8,44 @@ import Foundation -public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol, AnyObject { +public protocol ParentModelProtocol: MoleculeTreeTraversalProtocol, AnyObject { var children: [MoleculeModelProtocol] { get } - func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool + func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool +} + +public extension ParentModelProtocol { + /// Top level test to replace child molecules. Each parent molecule should attempt to replace. + func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { return false } + + /// Helper function for replacing molecules. + func replaceChildMolecule(at childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol) throws -> Bool { + guard let childIdMolecule = childMolecule as? MoleculeModelProtocol else { return false } + if childIdMolecule.id == replacementMolecule.id { + guard let replacementMolecule = 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 + return true + } + return false + } + + func replaceChildMolecule(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 { + throw MolecularError.error("Molecular replacement '\(replacementMolecule.id)' does not type match \(type(of: T.self)) of \(type(of: self))") + } + molecules[matchingIndex] = replacementMolecule + return true + } +} + +public protocol ParentMoleculeModelProtocol: ParentModelProtocol, MoleculeModelProtocol { + } public extension ParentMoleculeModelProtocol { @@ -56,33 +89,4 @@ public extension ParentMoleculeModelProtocol { } // if options == .leafOnly don't call on self. } - - /// Top level test to replace child molecules. Each parent molecule should attempt to replace. - func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool { return false } - - /// Helper function for replacing molecules. - func replace(childMolecule: inout T?, with replacementMolecule: MoleculeModelProtocol) -> Bool { - if childMolecule != nil, childMolecule?.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { - childMolecule = newHeadline - return true - } - return false - } - - func replace(childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol) -> Bool { - if childMolecule.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { - childMolecule = newHeadline - return true - } - return false - } - - func replace(inChildMolecules molecules: inout [T], with replacementMolecule: MoleculeModelProtocol) -> Bool where T: MoleculeModelProtocol { - guard let replacementMolecule = replacementMolecule as? T else { return false } - guard let matchingIndex = molecules.firstIndex(where: { molecule in - molecule.id == replacementMolecule.id - }) else { return false } - molecules[matchingIndex] = replacementMolecule - return true - } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index 2cd233b0..34a8e13a 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -7,13 +7,17 @@ // -public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, MoleculeTreeTraversalProtocol { +public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, MoleculeTreeTraversalProtocol, ParentModelProtocol { var template: String { get } var rootMolecules: [MoleculeModelProtocol] { get } } public extension TemplateModelProtocol { + var children: [MoleculeModelProtocol] { + return rootMolecules + } + var template: String { get { return Self.identifier } } @@ -33,4 +37,28 @@ public extension TemplateModelProtocol { func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) { return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit) } + + func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool { + // Attempt root level replacement on the template model first. + if try self.replaceChildMolecule(with: replacementMolecule) { + return true + } + + var didReplaceMolecule = false + var possibleError: Error? + // Dive into each root thereafter. + depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in + guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return } + do { + didReplaceMolecule = try parentMolecule.replaceChildMolecule(with: replacementMolecule) + } catch { + possibleError = error + } + stop = didReplaceMolecule || possibleError != nil + } + if let error = possibleError { + throw error + } + return didReplaceMolecule + } } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift index f2f01b6c..6086849c 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeDelegateProtocol.swift @@ -9,6 +9,8 @@ public protocol MoleculeDelegateProtocol: AnyObject { + func getTemplateModel() -> TemplateModelProtocol? + func getRootMolecules() -> [MoleculeModelProtocol] /// returns a module for the corresponding module name. @@ -22,6 +24,10 @@ public protocol MoleculeDelegateProtocol: AnyObject { extension MoleculeDelegateProtocol { + public func getRootMolecules() -> [MoleculeModelProtocol] { + getTemplateModel()?.rootMolecules ?? [] + } + public func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { } public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? { @@ -42,6 +48,11 @@ extension MoleculeDelegateProtocol { } extension MoleculeDelegateProtocol where Self: TemplateProtocol { + + public func getTemplateModel() -> TemplateModelProtocol? { + return templateModel + } + public func getRootMolecules() -> [MoleculeModelProtocol] { templateModel?.rootMolecules ?? [] } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift index 48f5166b..f595af9b 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift @@ -38,7 +38,7 @@ public extension MoleculeTreeTraversalProtocol { func printMolecules(options: TreeTraversalOptions = .parentFirst) { depthFirstTraverse(options: options, depth: 1) { depth, molecule, stop in - print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]") + print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule): \(molecule.id)]") } } @@ -50,14 +50,4 @@ public extension MoleculeTreeTraversalProtocol { return accumulator } } - - func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { - var didReplaceMolecule = false - depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in - guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return } - didReplaceMolecule = parentMolecule.replaceChildMolecule(with: replacementMolecule) - stop = didReplaceMolecule - } - return didReplaceMolecule - } } diff --git a/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift b/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift index daa3aed1..ee6a0a77 100644 --- a/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/BaseTemplateModel.swift @@ -32,7 +32,11 @@ import Foundation public var tabBarIndex: Int? public var shouldMaskScreenWhileRecording: Bool? - + + public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try replaceChildMolecule(at: &navigationBar, with: molecule) + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift b/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift index fc71921e..e94f8153 100644 --- a/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift @@ -22,6 +22,11 @@ } 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)) + } //-------------------------------------------------- // MARK: - Initializer diff --git a/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift index 4796bed7..e1713b01 100644 --- a/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift @@ -26,6 +26,12 @@ 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) + } + /// This template requires content. func validateModelHasContent() throws { if header == nil, diff --git a/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift index 1ed663c2..d5d783d3 100644 --- a/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift @@ -16,7 +16,13 @@ public var moleculeStack: StackModel public override var rootMolecules: [MoleculeModelProtocol] { - [navigationBar, header, moleculeStack, footer].compactMap { $0 } + super.rootMolecules + [moleculeStack] + } + + public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try super.replaceChildMolecule(with: molecule) + || replaceChildMolecule(at: &navigationBar, with: molecule) + || replaceChildMolecule(at: &moleculeStack, with: molecule) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift index 9f130089..6ca05550 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift @@ -21,6 +21,12 @@ [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) + } + //-------------------------------------------------- // MARK: - Init //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift index ab4f29d5..d3acea86 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift @@ -22,6 +22,11 @@ return super.rootMolecules } + public override func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { + return try super.replaceChildMolecule(with: molecule) + || replaceChildMolecule(at: &middle, with: molecule) + } + //-------------------------------------------------- // MARK: - Init //-------------------------------------------------- diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 16c1500f..afd91ec0 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -513,9 +513,9 @@ import MVMCore // MARK: - MoleculeDelegateProtocol //-------------------------------------------------- - open func getRootMolecules() -> [MoleculeModelProtocol] { - model?.rootMolecules ?? [] - } + open func getTemplateModel() -> TemplateModelProtocol? { model } + + open func getRootMolecules() -> [MoleculeModelProtocol] { model?.rootMolecules ?? [] } // Needed otherwise when subclassed, the extension gets called. open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { } diff --git a/MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift b/MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift index 89a34f4a..d5e6d86c 100644 --- a/MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift +++ b/MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift @@ -9,27 +9,35 @@ import Foundation import MVMCore -public class ReplacableMoleculeBehaviorModel: PageBehaviorModelProtocol { +public class ReplaceableMoleculeBehaviorModel: PageBehaviorModelProtocol { public class var identifier: String { "replaceMoleculeBehavior" } public var shouldAllowMultipleInstances: Bool { true } public var moleculeIds: [String] } -public class ReplacableMoleculeBehavior: PageMoleculeTransformationBehavior { +public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior { var moleculeIds: [String] public required init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) { - moleculeIds = (model as! ReplacableMoleculeBehaviorModel).moleculeIds + moleculeIds = (model as! ReplaceableMoleculeBehaviorModel).moleculeIds } public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) { - var shouldRefreshUI = false + + guard let templateModel = delegateObject?.moleculeDelegate?.getTemplateModel() else { return } + + templateModel.printMolecules() + for moleculeId in moleculeIds { guard let replacementModel = delegateObject?.moleculeDelegate?.getModuleWithName(moleculeId) else { continue } - let didReplace = rootMolecules.contains(where: { model in - return model.replaceMolecule(with: replacementModel) - }) - shouldRefreshUI = shouldRefreshUI || didReplace + do { + let didReplace = try templateModel.replaceMolecule(with: replacementModel) + if !didReplace { + MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Failed to find '\(moleculeId)' in the current screen.", code: ErrorCode.viewControllerProcessingJSON.rawValue, domain: ErrorDomainSystem, location: String(describing: type(of: self)))!) + } + } catch { + MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject.createErrorObject(for: error, location: String(describing: type(of: self)))!) + } } } diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 91042b47..26e539bc 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -227,7 +227,7 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: PageGetContactBehavior.self, for: PageGetContactBehaviorModel.self) ModelRegistry.register(handler: AddRemoveMoleculesBehavior.self, for: AddRemoveMoleculesBehaviorModel.self) ModelRegistry.register(handler: GetNotificationAuthStatusBehavior.self, for: GetNotificationAuthStatusBehaviorModel.self) - ModelRegistry.register(handler: ReplacableMoleculeBehavior.self, for: ReplacableMoleculeBehaviorModel.self) + ModelRegistry.register(handler: ReplaceableMoleculeBehavior.self, for: ReplaceableMoleculeBehaviorModel.self) } open override class func registerActions() {