Skip to content

Commit

Permalink
Merge pull request #2485 from microsoft/u/juliaroldi/auto-link-2
Browse files Browse the repository at this point in the history
[Part 2] Port Auto link
  • Loading branch information
juliaroldi authored Mar 8, 2024
2 parents be79cb0 + 4987166 commit 070d8d8
Show file tree
Hide file tree
Showing 6 changed files with 385 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createLink } from './link/createLink';
import { createLinkAfterSpace } from './link/createLinkAfterSpace';
import { keyboardListTrigger } from './list/keyboardListTrigger';
import { unlink } from './link/unlink';
import type {
Expand Down Expand Up @@ -106,18 +107,18 @@ export class AutoFormatPlugin implements EditorPlugin {
private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {
const rawEvent = event.rawEvent;
if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
const { autoBullet, autoNumbering, autoUnlink } = this.options;
const { autoBullet, autoNumbering, autoUnlink, autoLink } = this.options;
switch (rawEvent.key) {
case ' ':
if (autoBullet || autoNumbering) {
keyboardListTrigger(editor, rawEvent, autoBullet, autoNumbering);
keyboardListTrigger(editor, rawEvent, autoBullet, autoNumbering);
if (autoLink) {
createLinkAfterSpace(editor);
}
break;
case 'Backspace':
if (autoUnlink) {
unlink(editor, rawEvent);
}

break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ export function createLink(editor: IEditor) {
},
dataset: {},
});

return true;
}

return false;
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createText } from 'roosterjs-content-model-dom';
import { getSelectedSegmentsAndParagraphs } from 'roosterjs-content-model-core';
import { matchLink } from 'roosterjs-content-model-api';
import type { IEditor } from 'roosterjs-content-model-types';

/**
* @internal
*/
export function createLinkAfterSpace(editor: IEditor) {
editor.formatContentModel(model => {
const selectedSegmentsAndParagraphs = getSelectedSegmentsAndParagraphs(
model,
false /* includingFormatHolder */
);
if (selectedSegmentsAndParagraphs[0] && selectedSegmentsAndParagraphs[0][1]) {
const length = selectedSegmentsAndParagraphs[0][1].segments.length;
const marker = selectedSegmentsAndParagraphs[0][1].segments[length - 1];
const textSegment = selectedSegmentsAndParagraphs[0][1].segments[length - 2];
if (
marker.segmentType == 'SelectionMarker' &&
textSegment.segmentType == 'Text' &&
!textSegment.link
) {
const link = textSegment.text.split(' ').pop();
if (link && matchLink(link)) {
textSegment.text = textSegment.text.replace(link, '');
const linkSegment = createText(link, marker.format, {
format: {
href: link,
underline: true,
},
dataset: {},
});
selectedSegmentsAndParagraphs[0][1].segments.splice(length - 1, 0, linkSegment);
return true;
}
}
}

return false;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@ export function keyboardListTrigger(
shouldSearchForBullet: boolean = true,
shouldSearchForNumbering: boolean = true
) {
editor.formatContentModel((model, _context) => {
const listStyleType = getListTypeStyle(
model,
shouldSearchForBullet,
shouldSearchForNumbering
);
if (listStyleType) {
const segmentsAndParagraphs = getSelectedSegmentsAndParagraphs(model, false);
if (segmentsAndParagraphs[0] && segmentsAndParagraphs[0][1]) {
segmentsAndParagraphs[0][1].segments.splice(0, 1);
}
const { listType, styleType, index } = listStyleType;
triggerList(editor, model, listType, styleType, index);
rawEvent.preventDefault();
normalizeContentModel(model);
if (shouldSearchForBullet || shouldSearchForNumbering) {
editor.formatContentModel((model, _context) => {
const listStyleType = getListTypeStyle(
model,
shouldSearchForBullet,
shouldSearchForNumbering
);
if (listStyleType) {
const segmentsAndParagraphs = getSelectedSegmentsAndParagraphs(model, false);
if (segmentsAndParagraphs[0] && segmentsAndParagraphs[0][1]) {
segmentsAndParagraphs[0][1].segments.splice(0, 1);
}
const { listType, styleType, index } = listStyleType;
triggerList(editor, model, listType, styleType, index);
rawEvent.preventDefault();
normalizeContentModel(model);

return true;
}
return false;
});
return true;
}
return false;
});
}
}

const triggerList = (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as createLink from '../../lib/autoFormat/link/createLink';
import * as createLinkAfterSpace from '../../lib/autoFormat/link/createLinkAfterSpace';
import * as keyboardTrigger from '../../lib/autoFormat/list/keyboardListTrigger';
import * as unlink from '../../lib/autoFormat/link/unlink';
import { AutoFormatOptions, AutoFormatPlugin } from '../../lib/autoFormat/AutoFormatPlugin';
Expand Down Expand Up @@ -31,11 +32,9 @@ describe('Content Model Auto Format Plugin Test', () => {
options?: {
autoBullet: boolean;
autoNumbering: boolean;
autoUnlink: boolean;
autoLink: boolean;
}
) {
const plugin = new AutoFormatPlugin(options);
const plugin = new AutoFormatPlugin(options as AutoFormatOptions);
plugin.initialize(editor);

plugin.onPluginEvent(event);
Expand All @@ -44,8 +43,8 @@ describe('Content Model Auto Format Plugin Test', () => {
expect(keyboardListTriggerSpy).toHaveBeenCalledWith(
editor,
event.rawEvent,
options?.autoBullet ?? true,
options?.autoNumbering ?? true
options ? options.autoBullet : true,
options ? options.autoNumbering : true
);
} else {
expect(keyboardListTriggerSpy).not.toHaveBeenCalled();
Expand Down Expand Up @@ -78,7 +77,7 @@ describe('Content Model Auto Format Plugin Test', () => {
handledByEditFeature: false,
};

runTest(event, false, { autoBullet: false, autoNumbering: false } as AutoFormatOptions);
runTest(event, true, { autoBullet: false, autoNumbering: false } as AutoFormatOptions);
});

it('should trigger keyboardListTrigger with auto bullet only', () => {
Expand Down Expand Up @@ -225,4 +224,57 @@ describe('Content Model Auto Format Plugin Test', () => {
runTest(event, false);
});
});

describe('onPluginEvent - createLinkAfterSpace', () => {
let createLinkAfterSpaceSpy: jasmine.Spy;

beforeEach(() => {
createLinkAfterSpaceSpy = spyOn(createLinkAfterSpace, 'createLinkAfterSpace');
});

function runTest(
event: KeyDownEvent,
shouldCallTrigger: boolean,
options?: {
autoLink: boolean;
}
) {
const plugin = new AutoFormatPlugin(options as AutoFormatOptions);
plugin.initialize(editor);

plugin.onPluginEvent(event);

if (shouldCallTrigger) {
expect(createLinkAfterSpaceSpy).toHaveBeenCalledWith(editor);
} else {
expect(createLinkAfterSpaceSpy).not.toHaveBeenCalled();
}
}

it('should call createLinkAfterSpace', () => {
const event: KeyDownEvent = {
eventType: 'keyDown',
rawEvent: { key: ' ', preventDefault: () => {} } as any,
};
runTest(event, true);
});

it('should not call createLinkAfterSpace - disable options', () => {
const event: KeyDownEvent = {
eventType: 'keyDown',
rawEvent: { key: ' ', preventDefault: () => {} } as any,
};
runTest(event, false, {
autoLink: false,
});
});

it('should not call createLinkAfterSpace - not backspace', () => {
const event: KeyDownEvent = {
eventType: 'keyDown',
rawEvent: { key: 'Backspace', preventDefault: () => {} } as any,
};
runTest(event, false);
});
});
});
Loading

0 comments on commit 070d8d8

Please sign in to comment.