Skip to content

Commit 5b88991

Browse files
authored
SF-3542 Do not allow cut operations across multiple segments (#3745)
1 parent 9c84c0b commit 5b88991

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/SIL.XForge.Scripture/ClientApp/src/app/shared/text/text.component.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,36 @@ describe('TextComponent', () => {
516516
TestEnvironment.waitForPresenceTimer();
517517
}));
518518

519+
it('allows cut when valid selection', fakeAsync(() => {
520+
const { env, segmentRange }: { env: TestEnvironment; segmentRange: QuillRange } = basicSimpleText();
521+
522+
// When asked, the current selection will be called valid.
523+
const isValidSpy: jasmine.Spy<any> = spyOn<any>(env.component, 'isValidSelectionForCurrentSegment').and.returnValue(
524+
true
525+
);
526+
527+
// SUT
528+
const allowed: boolean = env.quillHandleCut(segmentRange);
529+
530+
expect(allowed).withContext('should have been allowed when valid selection').toBeTrue();
531+
expect(isValidSpy).withContext('the test may have worked for the wrong reason').toHaveBeenCalled();
532+
}));
533+
534+
it('disallows cut when invalid selection', fakeAsync(() => {
535+
const { env, segmentRange }: { env: TestEnvironment; segmentRange: QuillRange } = basicSimpleText();
536+
537+
// When asked, the current selection will be called invalid.
538+
const isValidSpy: jasmine.Spy<any> = spyOn<any>(env.component, 'isValidSelectionForCurrentSegment').and.returnValue(
539+
false
540+
);
541+
542+
// SUT
543+
const allowed: boolean = env.quillHandleCut(segmentRange);
544+
545+
expect(allowed).withContext('should have been disallowed when invalid selection').toBeFalse();
546+
expect(isValidSpy).withContext('the test may have worked for the wrong reason').toHaveBeenCalled();
547+
}));
548+
519549
it('"select all" adjusts selection to current segment', fakeAsync(() => {
520550
const env = new TestEnvironment();
521551
const testSegmentRefs = ['verse_1_1', 'verse_1_3'];
@@ -2047,6 +2077,21 @@ class TestEnvironment {
20472077
return matchingBindings[0].handler.call({ quill: this.component.editor }, range, {});
20482078
}
20492079

2080+
/**
2081+
* Find the desired handler method in quill keyboard's list of handlers for cut and call it.
2082+
*/
2083+
quillHandleCut(range: QuillRange): boolean {
2084+
const cutKeyCode = 'x';
2085+
const matchingBindings = (this.component.editor!.keyboard as any).bindings[cutKeyCode].filter(
2086+
(bindingItem: any) =>
2087+
(bindingItem.ctrlKey || bindingItem.metaKey) && bindingItem.handler.toString().includes('isDeleteAllowed')
2088+
);
2089+
expect(matchingBindings.length)
2090+
.withContext('setup: should be grabbing a single, specific binding in quill with the desired handler')
2091+
.toEqual(1);
2092+
return matchingBindings[0].handler.call({ quill: this.component.editor }, range, {});
2093+
}
2094+
20502095
/** Crudely go find the desired handler
20512096
* method in quill keyboard's list of handlers for delete and call it.
20522097
* */

src/SIL.XForge.Scripture/ClientApp/src/app/shared/text/text.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ export class TextComponent implements AfterViewInit, OnDestroy {
247247
this.editor.history.redo();
248248
}
249249
}
250+
},
251+
cut: {
252+
key: 'x',
253+
shortKey: true,
254+
handler: (range: Range) => this.isDeleteAllowed(range)
250255
}
251256
}
252257
},

0 commit comments

Comments
 (0)