From c64f943ca8a1213aa9da5ce018d785c079ac8fb1 Mon Sep 17 00:00:00 2001 From: Grol Grol Date: Sun, 13 Jul 2025 21:03:02 +0300 Subject: [PATCH] fix bug propagete modify to grandparent --- __tests__/core/CheckboxUtils2.test.ts | 49 +++++++++++++++++-- src/core/CheckboxUtils2.ts | 11 +++++ src/core/model/ContextFactory.ts | 14 ++++++ src/core/model/TreeNode.ts | 6 ++- .../PropagateStateToChildrenProcess.ts | 2 + 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/__tests__/core/CheckboxUtils2.test.ts b/__tests__/core/CheckboxUtils2.test.ts index e85bffd..f3d72bf 100644 --- a/__tests__/core/CheckboxUtils2.test.ts +++ b/__tests__/core/CheckboxUtils2.test.ts @@ -146,7 +146,7 @@ describe('CheckboxUtils2', () => { expect(utils.syncText(textBefore, textBefore)).toBe(textBefore); }); - it('checkbox, list', ()=> { + it('checkbox, list', () => { const utils = new CheckboxUtils2(createSettings({ enableAutomaticChildState: true, enableAutomaticParentState: true, @@ -171,7 +171,7 @@ describe('CheckboxUtils2', () => { expect(utils.syncText(actualText, textBefore)).toBe(expectedText); }); - it('checkbox, plain text', ()=> { + it('checkbox, plain text', () => { const utils = new CheckboxUtils2(createSettings({ enableAutomaticChildState: true, enableAutomaticParentState: true, @@ -305,7 +305,50 @@ describe('CheckboxUtils2', () => { ' Child3', ].join('\n'); expect(utils.syncText(actualText, textBefore)).toBe(expected); - }); + }); + }); + + describe('bags', () => { + it('bag 1', () => { + const utils = new CheckboxUtils2(createSettings({ + enableAutomaticChildState: true, + enableAutomaticParentState: true, + })); + const oldText = [ + '- [ ] 3д детали', + ' - [ ] грузики для веревки ^be5c11', + ' - [ ] привод жалюзи ^202ccf', + ' - [ ] 3д детали', + ' - [ ] корпус', + ' - [ ] бобина для веревки', + ' - [ ] основной редуктор', + ' - [ ] червячный редуктор', + ' - [ ] подшипник', + ].join('\n'); + const actualText = [ + '- [ ] 3д детали', + ' - [ ] грузики для веревки ^be5c11', + ' - [ ] привод жалюзи ^202ccf', + ' - [x] 3д детали', + ' - [ ] корпус', + ' - [ ] бобина для веревки', + ' - [ ] основной редуктор', + ' - [ ] червячный редуктор', + ' - [ ] подшипник', + ].join('\n'); + const expected = [ + '- [ ] 3д детали', + ' - [ ] грузики для веревки ^be5c11', + ' - [ ] привод жалюзи ^202ccf', + ' - [x] 3д детали', + ' - [x] корпус', + ' - [x] бобина для веревки', + ' - [ ] основной редуктор', + ' - [ ] червячный редуктор', + ' - [ ] подшипник', + ].join('\n'); + expect(utils.syncText(actualText, oldText)).toBe(expected); + }); }); }); diff --git a/src/core/CheckboxUtils2.ts b/src/core/CheckboxUtils2.ts index d70f9b8..319b9dc 100644 --- a/src/core/CheckboxUtils2.ts +++ b/src/core/CheckboxUtils2.ts @@ -19,11 +19,22 @@ export class CheckboxUtils2 implements ICheckboxUtils { if (text === textBefore) { return text; } + console.log(`text before:`); + console.log(text); + console.log("___"); + const context = ContextFactory.createContext(text, textBefore, this.settings); this.propagateStateToChildrenProcess.process(context); + + this.propagateStateToParentProcess.process(context); + console.log(`text after:`); + const res = context.getResultText() + console.log(res); + console.log("___"); + return context.getResultText(); } } diff --git a/src/core/model/ContextFactory.ts b/src/core/model/ContextFactory.ts index 5d843c6..911d7d4 100644 --- a/src/core/model/ContextFactory.ts +++ b/src/core/model/ContextFactory.ts @@ -35,8 +35,14 @@ export class ContextFactory { private static createFlatNodesFromLines(lines: Line[]): TreeNode[] { const nodes: TreeNode[] = []; const stack: TreeNode[] = []; + + let changeNode: null | TreeNode = null; + for (const line of lines) { const node = new TreeNode(line); + if (line instanceof CheckboxLine && line.isChange()) { + changeNode = node; + } // найти родителя let parent = undefined; @@ -56,6 +62,12 @@ export class ContextFactory { nodes.push(node); stack.push(node); } + + let parentChangeNode = changeNode?.getParent(); + while (parentChangeNode) { + parentChangeNode.setModify(true); + parentChangeNode = parentChangeNode?.getParent(); + } return nodes; } @@ -93,6 +105,8 @@ export class ContextFactory { oldLine.getState() !== actualLine.getState() ) { actualLine.setChange(true); + const text = actualLine.toResultText(); + console.log(`ContextFactory:markChangeIfNeeded: ${text} is change`); } } diff --git a/src/core/model/TreeNode.ts b/src/core/model/TreeNode.ts index 4e7b56d..5f8d593 100644 --- a/src/core/model/TreeNode.ts +++ b/src/core/model/TreeNode.ts @@ -24,6 +24,10 @@ export class TreeNode { return this.modify; } + setModify(isModify:boolean){ + this.modify = isModify; + } + private setParent(parent: TreeNode) { this.parent = parent; } @@ -35,8 +39,6 @@ export class TreeNode { addChildren(children: TreeNode) { this.childrens.push(children); children.setParent(this); - - this.modify = this.modify || children.isModify(); } hasChildren(): boolean { diff --git a/src/core/process/PropagateStateToChildrenProcess.ts b/src/core/process/PropagateStateToChildrenProcess.ts index d8416c3..2259619 100644 --- a/src/core/process/PropagateStateToChildrenProcess.ts +++ b/src/core/process/PropagateStateToChildrenProcess.ts @@ -11,12 +11,14 @@ export class PropagateStateToChildrenProcess implements CheckboxProcess { return; } if (!context.textBeforeChangeIsPresent()) { + console.log("PropagateStateToChildrenProcess: textBeforeChange is not present"); return; } // получить представление текста const view = context.getView(); if (!view.isModify()) { + console.log("PropagateStateToChildrenProcess: not modify"); return; }