roosterjs-content-model-plugins 9.21.0 → 9.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +2 -0
  2. package/lib/autoFormat/AutoFormatPlugin.js +12 -0
  3. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  4. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
  5. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +92 -0
  6. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
  7. package/lib/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
  8. package/lib/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  9. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +2 -0
  10. package/lib-amd/autoFormat/AutoFormatPlugin.js +12 -1
  11. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  12. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
  13. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +91 -0
  14. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
  15. package/lib-amd/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
  16. package/lib-amd/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  17. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +2 -0
  18. package/lib-mjs/autoFormat/AutoFormatPlugin.js +12 -0
  19. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  20. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
  21. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +87 -0
  22. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
  23. package/lib-mjs/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
  24. package/lib-mjs/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  25. package/package.json +5 -5
@@ -19,6 +19,7 @@ export declare class AutoFormatPlugin implements EditorPlugin {
19
19
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
20
20
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
21
21
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
22
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
22
23
  */
23
24
  constructor(options?: AutoFormatOptions);
24
25
  /**
@@ -48,5 +49,6 @@ export declare class AutoFormatPlugin implements EditorPlugin {
48
49
  private features;
49
50
  private handleEditorInputEvent;
50
51
  private handleKeyDownEvent;
52
+ private handleEnterKey;
51
53
  private handleContentChangedEvent;
52
54
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AutoFormatPlugin = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
6
+ var checkAndInsertHorizontalLine_1 = require("./horizontalLine/checkAndInsertHorizontalLine");
6
7
  var createLink_1 = require("./link/createLink");
7
8
  var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
8
9
  var keyboardListTrigger_1 = require("./list/keyboardListTrigger");
@@ -22,6 +23,7 @@ var DefaultOptions = {
22
23
  autoFraction: false,
23
24
  autoOrdinals: false,
24
25
  removeListMargins: false,
26
+ autoHorizontalLine: false,
25
27
  };
26
28
  /**
27
29
  * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.
@@ -40,6 +42,7 @@ var AutoFormatPlugin = /** @class */ (function () {
40
42
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
41
43
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
42
44
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
45
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
43
46
  */
44
47
  function AutoFormatPlugin(options) {
45
48
  var _this = this;
@@ -221,9 +224,18 @@ var AutoFormatPlugin = /** @class */ (function () {
221
224
  apiName: 'autoToggleList',
222
225
  });
223
226
  }
227
+ break;
228
+ case 'Enter':
229
+ this.handleEnterKey(editor, event);
230
+ break;
224
231
  }
225
232
  }
226
233
  };
234
+ AutoFormatPlugin.prototype.handleEnterKey = function (editor, event) {
235
+ if (this.options.autoHorizontalLine) {
236
+ (0, checkAndInsertHorizontalLine_1.checkAndInsertHorizontalLine)(editor, event);
237
+ }
238
+ };
227
239
  AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
228
240
  var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
229
241
  if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
1
+ {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n autoHorizontalLine: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n break;\n case 'Enter':\n this.handleEnterKey(editor, event);\n break;\n }\n }\n }\n\n private handleEnterKey(editor: IEditor, event: KeyDownEvent) {\n if (this.options.autoHorizontalLine) {\n checkAndInsertHorizontalLine(editor, event);\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
@@ -0,0 +1,24 @@
1
+ import type { FormatContentModelContext, IEditor, KeyDownEvent, ShallowMutableContentModelDocument } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';
6
+ /**
7
+ * @internal exported only for unit test
8
+ *
9
+ * Create a horizontal line and insert it into the model
10
+ *
11
+ * @param model the model to insert horizontal line into
12
+ * @param context the formatting context
13
+ */
14
+ export declare function insertHorizontalLineIntoModel(model: ShallowMutableContentModelDocument, context: FormatContentModelContext, triggerChar: HorizontalLineTriggerCharacter): void;
15
+ /**
16
+ * @internal
17
+ *
18
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
19
+ *
20
+ * @param editor The editor to check and insert horizontal line
21
+ * @param event The keydown event
22
+ * @returns True if horizontal line is inserted, otherwise false
23
+ */
24
+ export declare function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent): boolean;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkAndInsertHorizontalLine = exports.insertHorizontalLineIntoModel = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
6
+ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
7
+ var HorizontalLineTriggerCharacters = [
8
+ '-',
9
+ '=',
10
+ '_',
11
+ '*',
12
+ '~',
13
+ '#',
14
+ ];
15
+ var commonStyles = {
16
+ width: '98%',
17
+ display: 'inline-block',
18
+ };
19
+ var HorizontalLineStyles = new Map([
20
+ [
21
+ '-',
22
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
23
+ ],
24
+ [
25
+ '=',
26
+ (0, tslib_1.__assign)({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt none', borderLeft: '3pt none' }, commonStyles),
27
+ ],
28
+ [
29
+ '_',
30
+ (0, tslib_1.__assign)({ borderTop: '1px solid', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
31
+ ],
32
+ [
33
+ '*',
34
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '3px dotted', borderLeft: '1px none' }, commonStyles),
35
+ ],
36
+ [
37
+ '~',
38
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
39
+ ],
40
+ [
41
+ '#',
42
+ (0, tslib_1.__assign)({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt double', borderLeft: '3pt none' }, commonStyles),
43
+ ],
44
+ ]);
45
+ /**
46
+ * @internal exported only for unit test
47
+ *
48
+ * Create a horizontal line and insert it into the model
49
+ *
50
+ * @param model the model to insert horizontal line into
51
+ * @param context the formatting context
52
+ */
53
+ function insertHorizontalLineIntoModel(model, context, triggerChar) {
54
+ var hr = (0, roosterjs_content_model_dom_1.createDivider)('hr', HorizontalLineStyles.get(triggerChar));
55
+ var doc = (0, roosterjs_content_model_dom_1.createContentModelDocument)();
56
+ (0, roosterjs_content_model_dom_1.addBlock)(doc, hr);
57
+ (0, roosterjs_content_model_dom_1.mergeModel)(model, doc, context);
58
+ }
59
+ exports.insertHorizontalLineIntoModel = insertHorizontalLineIntoModel;
60
+ /**
61
+ * @internal
62
+ *
63
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
64
+ *
65
+ * @param editor The editor to check and insert horizontal line
66
+ * @param event The keydown event
67
+ * @returns True if horizontal line is inserted, otherwise false
68
+ */
69
+ function checkAndInsertHorizontalLine(editor, event) {
70
+ return (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _, para, __, context) {
71
+ var allText = para.segments.reduce(function (acc, segment) { return (segment.segmentType === 'Text' ? acc + segment.text : acc); }, '');
72
+ // At least 3 characters are needed to trigger horizontal line
73
+ if (allText.length < 3) {
74
+ return false;
75
+ }
76
+ return HorizontalLineTriggerCharacters.some(function (triggerCharacter) {
77
+ var shouldFormat = allText.split('').every(function (char) { return char === triggerCharacter; });
78
+ if (shouldFormat) {
79
+ para.segments = para.segments.filter(function (s) { return s.segmentType != 'Text'; });
80
+ insertHorizontalLineIntoModel(model, context, triggerCharacter);
81
+ event.rawEvent.preventDefault();
82
+ context.canUndoByBackspace = true;
83
+ }
84
+ return shouldFormat;
85
+ });
86
+ }, {
87
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
88
+ apiName: 'autoHorizontalLine',
89
+ });
90
+ }
91
+ exports.checkAndInsertHorizontalLine = checkAndInsertHorizontalLine;
92
+ //# sourceMappingURL=checkAndInsertHorizontalLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkAndInsertHorizontalLine.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.ts"],"names":[],"mappings":";;;;AAAA,2EAAqF;AAQrF,2EAMqC;AAMrC,IAAM,+BAA+B,GAAqC;IACtE,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;CACN,CAAC;AAEF,IAAM,YAAY,GAA8B;IAC5C,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,cAAc;CAC1B,CAAC;AAEF,IAAM,oBAAoB,GAGtB,IAAI,GAAG,CAAC;IACR;QACI,GAAG;gCAEC,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,WAAW,EACzB,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;IACD;QACI,GAAG;gCAEC,SAAS,EAAE,YAAY,EACvB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,UAAU,EACxB,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;IACD;QACI,GAAG;gCAEC,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,WAAW,EACzB,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;IACD;QACI,GAAG;gCAEC,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;IACD;QACI,GAAG;gCAEC,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,WAAW,EACzB,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;IACD;QACI,GAAG;gCAEC,SAAS,EAAE,YAAY,EACvB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU,IACnB,YAAY;KAEtB;CACJ,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,SAAgB,6BAA6B,CACzC,KAAyC,EACzC,OAAkC,EAClC,WAA2C;IAE3C,IAAM,EAAE,GAAG,IAAA,2CAAa,EAAC,IAAI,EAAE,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACtE,IAAM,GAAG,GAAG,IAAA,wDAA0B,GAAE,CAAC;IACzC,IAAA,sCAAQ,EAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAElB,IAAA,wCAAU,EAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAVD,sEAUC;AAED;;;;;;;;GAQG;AACH,SAAgB,4BAA4B,CAAC,MAAe,EAAE,KAAmB;IAC7E,OAAO,IAAA,oEAAsC,EACzC,MAAM,EACN,UAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO;QACxB,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAChC,UAAC,GAAG,EAAE,OAAO,IAAK,OAAA,CAAC,OAAO,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAA3D,CAA2D,EAC7E,EAAE,CACL,CAAC;QACF,8DAA8D;QAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACpB,OAAO,KAAK,CAAC;SAChB;QAED,OAAO,+BAA+B,CAAC,IAAI,CAAC,UAAA,gBAAgB;YACxD,IAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,KAAK,gBAAgB,EAAzB,CAAyB,CAAC,CAAC;YAChF,IAAI,YAAY,EAAE;gBACd,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,MAAM,EAAvB,CAAuB,CAAC,CAAC;gBACnE,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBAChE,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAChC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;aACrC;YACD,OAAO,YAAY,CAAC;QACxB,CAAC,CAAC,CAAC;IACP,CAAC,EACD;QACI,YAAY,EAAE,0CAAY,CAAC,UAAU;QACrC,OAAO,EAAE,oBAAoB;KAChC,CACJ,CAAC;AACN,CAAC;AA7BD,oEA6BC","sourcesContent":["import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport type {\n ContentModelDividerFormat,\n FormatContentModelContext,\n IEditor,\n KeyDownEvent,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\nimport {\n addBlock,\n ChangeSource,\n createContentModelDocument,\n createDivider,\n mergeModel,\n} from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';\nconst HorizontalLineTriggerCharacters: HorizontalLineTriggerCharacter[] = [\n '-',\n '=',\n '_',\n '*',\n '~',\n '#',\n];\n\nconst commonStyles: ContentModelDividerFormat = {\n width: '98%',\n display: 'inline-block',\n};\n\nconst HorizontalLineStyles: Map<\n HorizontalLineTriggerCharacter,\n ContentModelDividerFormat\n> = new Map([\n [\n '-',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '=',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt none',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n [\n '_',\n {\n borderTop: '1px solid',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '*',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '3px dotted',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '~',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '#',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt double',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n]);\n\n/**\n * @internal exported only for unit test\n *\n * Create a horizontal line and insert it into the model\n *\n * @param model the model to insert horizontal line into\n * @param context the formatting context\n */\nexport function insertHorizontalLineIntoModel(\n model: ShallowMutableContentModelDocument,\n context: FormatContentModelContext,\n triggerChar: HorizontalLineTriggerCharacter\n) {\n const hr = createDivider('hr', HorizontalLineStyles.get(triggerChar));\n const doc = createContentModelDocument();\n addBlock(doc, hr);\n\n mergeModel(model, doc, context);\n}\n\n/**\n * @internal\n *\n * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed\n *\n * @param editor The editor to check and insert horizontal line\n * @param event The keydown event\n * @returns True if horizontal line is inserted, otherwise false\n */\nexport function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent) {\n return formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _, para, __, context) => {\n const allText = para.segments.reduce(\n (acc, segment) => (segment.segmentType === 'Text' ? acc + segment.text : acc),\n ''\n );\n // At least 3 characters are needed to trigger horizontal line\n if (allText.length < 3) {\n return false;\n }\n\n return HorizontalLineTriggerCharacters.some(triggerCharacter => {\n const shouldFormat = allText.split('').every(char => char === triggerCharacter);\n if (shouldFormat) {\n para.segments = para.segments.filter(s => s.segmentType != 'Text');\n insertHorizontalLineIntoModel(model, context, triggerCharacter);\n event.rawEvent.preventDefault();\n context.canUndoByBackspace = true;\n }\n return shouldFormat;\n });\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoHorizontalLine',\n }\n );\n}\n"]}
@@ -27,4 +27,8 @@ export interface AutoFormatOptions extends AutoLinkOptions {
27
27
  * Remove the margins of auto triggered list
28
28
  */
29
29
  removeListMargins?: boolean;
30
+ /**
31
+ * Auto Horizontal line
32
+ */
33
+ autoHorizontalLine?: boolean;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n}\n"]}
1
+ {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n\n /**\n * Auto Horizontal line\n */\n autoHorizontalLine?: boolean;\n}\n"]}
@@ -19,6 +19,7 @@ export declare class AutoFormatPlugin implements EditorPlugin {
19
19
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
20
20
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
21
21
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
22
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
22
23
  */
23
24
  constructor(options?: AutoFormatOptions);
24
25
  /**
@@ -48,5 +49,6 @@ export declare class AutoFormatPlugin implements EditorPlugin {
48
49
  private features;
49
50
  private handleEditorInputEvent;
50
51
  private handleKeyDownEvent;
52
+ private handleEnterKey;
51
53
  private handleContentChangedEvent;
52
54
  }
@@ -1,4 +1,4 @@
1
- define(["require", "exports", "tslib", "roosterjs-content-model-dom", "./link/createLink", "roosterjs-content-model-api", "./list/keyboardListTrigger", "./numbers/transformFraction", "./hyphen/transformHyphen", "./numbers/transformOrdinals", "./link/unlink"], function (require, exports, tslib_1, roosterjs_content_model_dom_1, createLink_1, roosterjs_content_model_api_1, keyboardListTrigger_1, transformFraction_1, transformHyphen_1, transformOrdinals_1, unlink_1) {
1
+ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "./horizontalLine/checkAndInsertHorizontalLine", "./link/createLink", "roosterjs-content-model-api", "./list/keyboardListTrigger", "./numbers/transformFraction", "./hyphen/transformHyphen", "./numbers/transformOrdinals", "./link/unlink"], function (require, exports, tslib_1, roosterjs_content_model_dom_1, checkAndInsertHorizontalLine_1, createLink_1, roosterjs_content_model_api_1, keyboardListTrigger_1, transformFraction_1, transformHyphen_1, transformOrdinals_1, unlink_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.AutoFormatPlugin = void 0;
@@ -14,6 +14,7 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "./link/cr
14
14
  autoFraction: false,
15
15
  autoOrdinals: false,
16
16
  removeListMargins: false,
17
+ autoHorizontalLine: false,
17
18
  };
18
19
  /**
19
20
  * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.
@@ -32,6 +33,7 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "./link/cr
32
33
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
33
34
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
34
35
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
36
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
35
37
  */
36
38
  function AutoFormatPlugin(options) {
37
39
  var _this = this;
@@ -213,9 +215,18 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "./link/cr
213
215
  apiName: 'autoToggleList',
214
216
  });
215
217
  }
218
+ break;
219
+ case 'Enter':
220
+ this.handleEnterKey(editor, event);
221
+ break;
216
222
  }
217
223
  }
218
224
  };
225
+ AutoFormatPlugin.prototype.handleEnterKey = function (editor, event) {
226
+ if (this.options.autoHorizontalLine) {
227
+ (0, checkAndInsertHorizontalLine_1.checkAndInsertHorizontalLine)(editor, event);
228
+ }
229
+ };
219
230
  AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
220
231
  var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
221
232
  if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
1
+ {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n autoHorizontalLine: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n break;\n case 'Enter':\n this.handleEnterKey(editor, event);\n break;\n }\n }\n }\n\n private handleEnterKey(editor: IEditor, event: KeyDownEvent) {\n if (this.options.autoHorizontalLine) {\n checkAndInsertHorizontalLine(editor, event);\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
@@ -0,0 +1,24 @@
1
+ import type { FormatContentModelContext, IEditor, KeyDownEvent, ShallowMutableContentModelDocument } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';
6
+ /**
7
+ * @internal exported only for unit test
8
+ *
9
+ * Create a horizontal line and insert it into the model
10
+ *
11
+ * @param model the model to insert horizontal line into
12
+ * @param context the formatting context
13
+ */
14
+ export declare function insertHorizontalLineIntoModel(model: ShallowMutableContentModelDocument, context: FormatContentModelContext, triggerChar: HorizontalLineTriggerCharacter): void;
15
+ /**
16
+ * @internal
17
+ *
18
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
19
+ *
20
+ * @param editor The editor to check and insert horizontal line
21
+ * @param event The keydown event
22
+ * @returns True if horizontal line is inserted, otherwise false
23
+ */
24
+ export declare function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent): boolean;
@@ -0,0 +1,91 @@
1
+ define(["require", "exports", "tslib", "roosterjs-content-model-api", "roosterjs-content-model-dom"], function (require, exports, tslib_1, roosterjs_content_model_api_1, roosterjs_content_model_dom_1) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.checkAndInsertHorizontalLine = exports.insertHorizontalLineIntoModel = void 0;
5
+ var HorizontalLineTriggerCharacters = [
6
+ '-',
7
+ '=',
8
+ '_',
9
+ '*',
10
+ '~',
11
+ '#',
12
+ ];
13
+ var commonStyles = {
14
+ width: '98%',
15
+ display: 'inline-block',
16
+ };
17
+ var HorizontalLineStyles = new Map([
18
+ [
19
+ '-',
20
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
21
+ ],
22
+ [
23
+ '=',
24
+ (0, tslib_1.__assign)({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt none', borderLeft: '3pt none' }, commonStyles),
25
+ ],
26
+ [
27
+ '_',
28
+ (0, tslib_1.__assign)({ borderTop: '1px solid', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
29
+ ],
30
+ [
31
+ '*',
32
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '3px dotted', borderLeft: '1px none' }, commonStyles),
33
+ ],
34
+ [
35
+ '~',
36
+ (0, tslib_1.__assign)({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
37
+ ],
38
+ [
39
+ '#',
40
+ (0, tslib_1.__assign)({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt double', borderLeft: '3pt none' }, commonStyles),
41
+ ],
42
+ ]);
43
+ /**
44
+ * @internal exported only for unit test
45
+ *
46
+ * Create a horizontal line and insert it into the model
47
+ *
48
+ * @param model the model to insert horizontal line into
49
+ * @param context the formatting context
50
+ */
51
+ function insertHorizontalLineIntoModel(model, context, triggerChar) {
52
+ var hr = (0, roosterjs_content_model_dom_1.createDivider)('hr', HorizontalLineStyles.get(triggerChar));
53
+ var doc = (0, roosterjs_content_model_dom_1.createContentModelDocument)();
54
+ (0, roosterjs_content_model_dom_1.addBlock)(doc, hr);
55
+ (0, roosterjs_content_model_dom_1.mergeModel)(model, doc, context);
56
+ }
57
+ exports.insertHorizontalLineIntoModel = insertHorizontalLineIntoModel;
58
+ /**
59
+ * @internal
60
+ *
61
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
62
+ *
63
+ * @param editor The editor to check and insert horizontal line
64
+ * @param event The keydown event
65
+ * @returns True if horizontal line is inserted, otherwise false
66
+ */
67
+ function checkAndInsertHorizontalLine(editor, event) {
68
+ return (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _, para, __, context) {
69
+ var allText = para.segments.reduce(function (acc, segment) { return (segment.segmentType === 'Text' ? acc + segment.text : acc); }, '');
70
+ // At least 3 characters are needed to trigger horizontal line
71
+ if (allText.length < 3) {
72
+ return false;
73
+ }
74
+ return HorizontalLineTriggerCharacters.some(function (triggerCharacter) {
75
+ var shouldFormat = allText.split('').every(function (char) { return char === triggerCharacter; });
76
+ if (shouldFormat) {
77
+ para.segments = para.segments.filter(function (s) { return s.segmentType != 'Text'; });
78
+ insertHorizontalLineIntoModel(model, context, triggerCharacter);
79
+ event.rawEvent.preventDefault();
80
+ context.canUndoByBackspace = true;
81
+ }
82
+ return shouldFormat;
83
+ });
84
+ }, {
85
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
86
+ apiName: 'autoHorizontalLine',
87
+ });
88
+ }
89
+ exports.checkAndInsertHorizontalLine = checkAndInsertHorizontalLine;
90
+ });
91
+ //# sourceMappingURL=checkAndInsertHorizontalLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkAndInsertHorizontalLine.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport type {\n ContentModelDividerFormat,\n FormatContentModelContext,\n IEditor,\n KeyDownEvent,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\nimport {\n addBlock,\n ChangeSource,\n createContentModelDocument,\n createDivider,\n mergeModel,\n} from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';\nconst HorizontalLineTriggerCharacters: HorizontalLineTriggerCharacter[] = [\n '-',\n '=',\n '_',\n '*',\n '~',\n '#',\n];\n\nconst commonStyles: ContentModelDividerFormat = {\n width: '98%',\n display: 'inline-block',\n};\n\nconst HorizontalLineStyles: Map<\n HorizontalLineTriggerCharacter,\n ContentModelDividerFormat\n> = new Map([\n [\n '-',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '=',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt none',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n [\n '_',\n {\n borderTop: '1px solid',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '*',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '3px dotted',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '~',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '#',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt double',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n]);\n\n/**\n * @internal exported only for unit test\n *\n * Create a horizontal line and insert it into the model\n *\n * @param model the model to insert horizontal line into\n * @param context the formatting context\n */\nexport function insertHorizontalLineIntoModel(\n model: ShallowMutableContentModelDocument,\n context: FormatContentModelContext,\n triggerChar: HorizontalLineTriggerCharacter\n) {\n const hr = createDivider('hr', HorizontalLineStyles.get(triggerChar));\n const doc = createContentModelDocument();\n addBlock(doc, hr);\n\n mergeModel(model, doc, context);\n}\n\n/**\n * @internal\n *\n * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed\n *\n * @param editor The editor to check and insert horizontal line\n * @param event The keydown event\n * @returns True if horizontal line is inserted, otherwise false\n */\nexport function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent) {\n return formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _, para, __, context) => {\n const allText = para.segments.reduce(\n (acc, segment) => (segment.segmentType === 'Text' ? acc + segment.text : acc),\n ''\n );\n // At least 3 characters are needed to trigger horizontal line\n if (allText.length < 3) {\n return false;\n }\n\n return HorizontalLineTriggerCharacters.some(triggerCharacter => {\n const shouldFormat = allText.split('').every(char => char === triggerCharacter);\n if (shouldFormat) {\n para.segments = para.segments.filter(s => s.segmentType != 'Text');\n insertHorizontalLineIntoModel(model, context, triggerCharacter);\n event.rawEvent.preventDefault();\n context.canUndoByBackspace = true;\n }\n return shouldFormat;\n });\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoHorizontalLine',\n }\n );\n}\n"]}
@@ -27,4 +27,8 @@ export interface AutoFormatOptions extends AutoLinkOptions {
27
27
  * Remove the margins of auto triggered list
28
28
  */
29
29
  removeListMargins?: boolean;
30
+ /**
31
+ * Auto Horizontal line
32
+ */
33
+ autoHorizontalLine?: boolean;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n}\n"]}
1
+ {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n\n /**\n * Auto Horizontal line\n */\n autoHorizontalLine?: boolean;\n}\n"]}
@@ -19,6 +19,7 @@ export declare class AutoFormatPlugin implements EditorPlugin {
19
19
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
20
20
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
21
21
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
22
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
22
23
  */
23
24
  constructor(options?: AutoFormatOptions);
24
25
  /**
@@ -48,5 +49,6 @@ export declare class AutoFormatPlugin implements EditorPlugin {
48
49
  private features;
49
50
  private handleEditorInputEvent;
50
51
  private handleKeyDownEvent;
52
+ private handleEnterKey;
51
53
  private handleContentChangedEvent;
52
54
  }
@@ -1,5 +1,6 @@
1
1
  import { __values } from "tslib";
2
2
  import { ChangeSource } from 'roosterjs-content-model-dom';
3
+ import { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';
3
4
  import { createLink } from './link/createLink';
4
5
  import { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';
5
6
  import { keyboardListTrigger } from './list/keyboardListTrigger';
@@ -19,6 +20,7 @@ var DefaultOptions = {
19
20
  autoFraction: false,
20
21
  autoOrdinals: false,
21
22
  removeListMargins: false,
23
+ autoHorizontalLine: false,
22
24
  };
23
25
  /**
24
26
  * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.
@@ -37,6 +39,7 @@ var AutoFormatPlugin = /** @class */ (function () {
37
39
  * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
38
40
  * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
39
41
  * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
42
+ * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
40
43
  */
41
44
  function AutoFormatPlugin(options) {
42
45
  var _this = this;
@@ -218,9 +221,18 @@ var AutoFormatPlugin = /** @class */ (function () {
218
221
  apiName: 'autoToggleList',
219
222
  });
220
223
  }
224
+ break;
225
+ case 'Enter':
226
+ this.handleEnterKey(editor, event);
227
+ break;
221
228
  }
222
229
  }
223
230
  };
231
+ AutoFormatPlugin.prototype.handleEnterKey = function (editor, event) {
232
+ if (this.options.autoHorizontalLine) {
233
+ checkAndInsertHorizontalLine(editor, event);
234
+ }
235
+ };
224
236
  AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
225
237
  var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
226
238
  if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
1
+ {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ntype AutoFormatFeature = 'list' | 'link' | 'hyphen' | 'fraction' | 'ordinal';\n\n/**\n * @internal\n */\ninterface Feature {\n autoFormat: AutoFormatFeature;\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n autoHorizontalLine: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private features: Feature[] = [\n {\n autoFormat: 'list',\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n },\n {\n autoFormat: 'link',\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n },\n {\n autoFormat: 'hyphen',\n enabled: !!this.options.autoHyphen,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'fraction',\n enabled: !!this.options.autoFraction,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n autoFormat: 'ordinal',\n enabled: !!this.options.autoOrdinals,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let formatApplied: AutoFormatFeature | undefined = undefined;\n\n for (const feature of this.features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n formatApplied = feature.autoFormat;\n break;\n }\n }\n }\n\n if (formatApplied) {\n formatOptions.changeSource = getChangeSource(formatApplied);\n formatOptions.apiName = getApiName(formatApplied);\n }\n\n return !!formatApplied;\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n removeListMargins,\n } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n context.canUndoByBackspace = shouldList;\n }\n if (shouldList) {\n event.rawEvent.preventDefault();\n }\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n break;\n case 'Enter':\n this.handleEnterKey(editor, event);\n break;\n }\n }\n }\n\n private handleEnterKey(editor: IEditor, event: KeyDownEvent) {\n if (this.options.autoHorizontalLine) {\n checkAndInsertHorizontalLine(editor, event);\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (autoFormat: AutoFormatFeature) => {\n return autoFormat == 'list' || autoFormat == 'hyphen'\n ? ChangeSource.AutoFormat\n : autoFormat == 'link'\n ? ChangeSource.AutoLink\n : '';\n};\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
@@ -0,0 +1,24 @@
1
+ import type { FormatContentModelContext, IEditor, KeyDownEvent, ShallowMutableContentModelDocument } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';
6
+ /**
7
+ * @internal exported only for unit test
8
+ *
9
+ * Create a horizontal line and insert it into the model
10
+ *
11
+ * @param model the model to insert horizontal line into
12
+ * @param context the formatting context
13
+ */
14
+ export declare function insertHorizontalLineIntoModel(model: ShallowMutableContentModelDocument, context: FormatContentModelContext, triggerChar: HorizontalLineTriggerCharacter): void;
15
+ /**
16
+ * @internal
17
+ *
18
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
19
+ *
20
+ * @param editor The editor to check and insert horizontal line
21
+ * @param event The keydown event
22
+ * @returns True if horizontal line is inserted, otherwise false
23
+ */
24
+ export declare function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent): boolean;
@@ -0,0 +1,87 @@
1
+ import { __assign } from "tslib";
2
+ import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';
3
+ import { addBlock, ChangeSource, createContentModelDocument, createDivider, mergeModel, } from 'roosterjs-content-model-dom';
4
+ var HorizontalLineTriggerCharacters = [
5
+ '-',
6
+ '=',
7
+ '_',
8
+ '*',
9
+ '~',
10
+ '#',
11
+ ];
12
+ var commonStyles = {
13
+ width: '98%',
14
+ display: 'inline-block',
15
+ };
16
+ var HorizontalLineStyles = new Map([
17
+ [
18
+ '-',
19
+ __assign({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
20
+ ],
21
+ [
22
+ '=',
23
+ __assign({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt none', borderLeft: '3pt none' }, commonStyles),
24
+ ],
25
+ [
26
+ '_',
27
+ __assign({ borderTop: '1px solid', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
28
+ ],
29
+ [
30
+ '*',
31
+ __assign({ borderTop: '1px none', borderRight: '1px none', borderBottom: '3px dotted', borderLeft: '1px none' }, commonStyles),
32
+ ],
33
+ [
34
+ '~',
35
+ __assign({ borderTop: '1px none', borderRight: '1px none', borderBottom: '1px solid', borderLeft: '1px none' }, commonStyles),
36
+ ],
37
+ [
38
+ '#',
39
+ __assign({ borderTop: '3pt double', borderRight: '3pt none', borderBottom: '3pt double', borderLeft: '3pt none' }, commonStyles),
40
+ ],
41
+ ]);
42
+ /**
43
+ * @internal exported only for unit test
44
+ *
45
+ * Create a horizontal line and insert it into the model
46
+ *
47
+ * @param model the model to insert horizontal line into
48
+ * @param context the formatting context
49
+ */
50
+ export function insertHorizontalLineIntoModel(model, context, triggerChar) {
51
+ var hr = createDivider('hr', HorizontalLineStyles.get(triggerChar));
52
+ var doc = createContentModelDocument();
53
+ addBlock(doc, hr);
54
+ mergeModel(model, doc, context);
55
+ }
56
+ /**
57
+ * @internal
58
+ *
59
+ * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed
60
+ *
61
+ * @param editor The editor to check and insert horizontal line
62
+ * @param event The keydown event
63
+ * @returns True if horizontal line is inserted, otherwise false
64
+ */
65
+ export function checkAndInsertHorizontalLine(editor, event) {
66
+ return formatTextSegmentBeforeSelectionMarker(editor, function (model, _, para, __, context) {
67
+ var allText = para.segments.reduce(function (acc, segment) { return (segment.segmentType === 'Text' ? acc + segment.text : acc); }, '');
68
+ // At least 3 characters are needed to trigger horizontal line
69
+ if (allText.length < 3) {
70
+ return false;
71
+ }
72
+ return HorizontalLineTriggerCharacters.some(function (triggerCharacter) {
73
+ var shouldFormat = allText.split('').every(function (char) { return char === triggerCharacter; });
74
+ if (shouldFormat) {
75
+ para.segments = para.segments.filter(function (s) { return s.segmentType != 'Text'; });
76
+ insertHorizontalLineIntoModel(model, context, triggerCharacter);
77
+ event.rawEvent.preventDefault();
78
+ context.canUndoByBackspace = true;
79
+ }
80
+ return shouldFormat;
81
+ });
82
+ }, {
83
+ changeSource: ChangeSource.AutoFormat,
84
+ apiName: 'autoHorizontalLine',
85
+ });
86
+ }
87
+ //# sourceMappingURL=checkAndInsertHorizontalLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkAndInsertHorizontalLine.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport type {\n ContentModelDividerFormat,\n FormatContentModelContext,\n IEditor,\n KeyDownEvent,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\nimport {\n addBlock,\n ChangeSource,\n createContentModelDocument,\n createDivider,\n mergeModel,\n} from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport type HorizontalLineTriggerCharacter = '-' | '=' | '_' | '*' | '~' | '#';\nconst HorizontalLineTriggerCharacters: HorizontalLineTriggerCharacter[] = [\n '-',\n '=',\n '_',\n '*',\n '~',\n '#',\n];\n\nconst commonStyles: ContentModelDividerFormat = {\n width: '98%',\n display: 'inline-block',\n};\n\nconst HorizontalLineStyles: Map<\n HorizontalLineTriggerCharacter,\n ContentModelDividerFormat\n> = new Map([\n [\n '-',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '=',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt none',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n [\n '_',\n {\n borderTop: '1px solid',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '*',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '3px dotted',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '~',\n {\n borderTop: '1px none',\n borderRight: '1px none',\n borderBottom: '1px solid',\n borderLeft: '1px none',\n ...commonStyles,\n },\n ],\n [\n '#',\n {\n borderTop: '3pt double',\n borderRight: '3pt none',\n borderBottom: '3pt double',\n borderLeft: '3pt none',\n ...commonStyles,\n },\n ],\n]);\n\n/**\n * @internal exported only for unit test\n *\n * Create a horizontal line and insert it into the model\n *\n * @param model the model to insert horizontal line into\n * @param context the formatting context\n */\nexport function insertHorizontalLineIntoModel(\n model: ShallowMutableContentModelDocument,\n context: FormatContentModelContext,\n triggerChar: HorizontalLineTriggerCharacter\n) {\n const hr = createDivider('hr', HorizontalLineStyles.get(triggerChar));\n const doc = createContentModelDocument();\n addBlock(doc, hr);\n\n mergeModel(model, doc, context);\n}\n\n/**\n * @internal\n *\n * Check if the current line should be formatted as horizontal line, and insert horizontal line if needed\n *\n * @param editor The editor to check and insert horizontal line\n * @param event The keydown event\n * @returns True if horizontal line is inserted, otherwise false\n */\nexport function checkAndInsertHorizontalLine(editor: IEditor, event: KeyDownEvent) {\n return formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _, para, __, context) => {\n const allText = para.segments.reduce(\n (acc, segment) => (segment.segmentType === 'Text' ? acc + segment.text : acc),\n ''\n );\n // At least 3 characters are needed to trigger horizontal line\n if (allText.length < 3) {\n return false;\n }\n\n return HorizontalLineTriggerCharacters.some(triggerCharacter => {\n const shouldFormat = allText.split('').every(char => char === triggerCharacter);\n if (shouldFormat) {\n para.segments = para.segments.filter(s => s.segmentType != 'Text');\n insertHorizontalLineIntoModel(model, context, triggerCharacter);\n event.rawEvent.preventDefault();\n context.canUndoByBackspace = true;\n }\n return shouldFormat;\n });\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoHorizontalLine',\n }\n );\n}\n"]}
@@ -27,4 +27,8 @@ export interface AutoFormatOptions extends AutoLinkOptions {
27
27
  * Remove the margins of auto triggered list
28
28
  */
29
29
  removeListMargins?: boolean;
30
+ /**
31
+ * Auto Horizontal line
32
+ */
33
+ autoHorizontalLine?: boolean;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n}\n"]}
1
+ {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n\n /**\n * Remove the margins of auto triggered list\n */\n removeListMargins?: boolean;\n\n /**\n * Auto Horizontal line\n */\n autoHorizontalLine?: boolean;\n}\n"]}
package/package.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "description": "Plugins for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-core": "^9.21.0",
7
- "roosterjs-content-model-dom": "^9.21.0",
8
- "roosterjs-content-model-types": "^9.21.0",
9
- "roosterjs-content-model-api": "^9.21.0"
6
+ "roosterjs-content-model-core": "^9.22.0",
7
+ "roosterjs-content-model-dom": "^9.22.0",
8
+ "roosterjs-content-model-types": "^9.22.0",
9
+ "roosterjs-content-model-api": "^9.22.0"
10
10
  },
11
- "version": "9.21.0",
11
+ "version": "9.22.0",
12
12
  "main": "./lib/index.js",
13
13
  "typings": "./lib/index.d.ts",
14
14
  "module": "./lib-mjs/index.js",