roosterjs-content-model-plugins 9.20.1 → 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.
- package/README.md +2 -0
- package/lib/autoFormat/AutoFormatPlugin.d.ts +3 -0
- package/lib/autoFormat/AutoFormatPlugin.js +96 -40
- package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
- package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
- package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +92 -0
- package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
- package/lib/autoFormat/hyphen/transformHyphen.js.map +1 -1
- package/lib/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
- package/lib/autoFormat/interface/AutoFormatOptions.js.map +1 -1
- package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +3 -0
- package/lib-amd/autoFormat/AutoFormatPlugin.js +95 -41
- package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
- package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
- package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +91 -0
- package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
- package/lib-amd/autoFormat/hyphen/transformHyphen.js.map +1 -1
- package/lib-amd/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
- package/lib-amd/autoFormat/interface/AutoFormatOptions.js.map +1 -1
- package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +3 -0
- package/lib-mjs/autoFormat/AutoFormatPlugin.js +96 -40
- package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
- package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +24 -0
- package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +87 -0
- package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -0
- package/lib-mjs/autoFormat/hyphen/transformHyphen.js.map +1 -1
- package/lib-mjs/autoFormat/interface/AutoFormatOptions.d.ts +4 -0
- package/lib-mjs/autoFormat/interface/AutoFormatOptions.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -88,6 +88,8 @@ API overrides in Editor options when creating the editor.
|
|
|
88
88
|
`roosterjs-content-model-api` provides APIs for scenario-based operations triggered by
|
|
89
89
|
user interaction.
|
|
90
90
|
|
|
91
|
+
`roosterjs-content-model-markdown` provides API to transform Markdown language in Content Model objects.
|
|
92
|
+
|
|
91
93
|
## Plugins
|
|
92
94
|
|
|
93
95
|
Rooster supports plugins. You can use built-in plugins or build your own.
|
|
@@ -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
|
/**
|
|
@@ -45,7 +46,9 @@ export declare class AutoFormatPlugin implements EditorPlugin {
|
|
|
45
46
|
* @param event The event to handle:
|
|
46
47
|
*/
|
|
47
48
|
onPluginEvent(event: PluginEvent): void;
|
|
49
|
+
private features;
|
|
48
50
|
private handleEditorInputEvent;
|
|
49
51
|
private handleKeyDownEvent;
|
|
52
|
+
private handleEnterKey;
|
|
50
53
|
private handleContentChangedEvent;
|
|
51
54
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AutoFormatPlugin = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
|
+
var checkAndInsertHorizontalLine_1 = require("./horizontalLine/checkAndInsertHorizontalLine");
|
|
5
7
|
var createLink_1 = require("./link/createLink");
|
|
6
8
|
var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
|
|
7
9
|
var keyboardListTrigger_1 = require("./list/keyboardListTrigger");
|
|
@@ -21,6 +23,7 @@ var DefaultOptions = {
|
|
|
21
23
|
autoFraction: false,
|
|
22
24
|
autoOrdinals: false,
|
|
23
25
|
removeListMargins: false,
|
|
26
|
+
autoHorizontalLine: false,
|
|
24
27
|
};
|
|
25
28
|
/**
|
|
26
29
|
* Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.
|
|
@@ -39,11 +42,60 @@ var AutoFormatPlugin = /** @class */ (function () {
|
|
|
39
42
|
* - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
|
|
40
43
|
* - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
|
|
41
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.
|
|
42
46
|
*/
|
|
43
47
|
function AutoFormatPlugin(options) {
|
|
48
|
+
var _this = this;
|
|
44
49
|
if (options === void 0) { options = DefaultOptions; }
|
|
45
50
|
this.options = options;
|
|
46
51
|
this.editor = null;
|
|
52
|
+
this.features = [
|
|
53
|
+
{
|
|
54
|
+
autoFormat: 'list',
|
|
55
|
+
enabled: !!(this.options.autoBullet || this.options.autoNumbering),
|
|
56
|
+
transformFunction: function (model, _previousSegment, paragraph, context) {
|
|
57
|
+
return (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, _this.options.autoBullet, _this.options.autoNumbering, _this.options.removeListMargins);
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
autoFormat: 'link',
|
|
62
|
+
enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),
|
|
63
|
+
transformFunction: function (_model, previousSegment, paragraph, context) {
|
|
64
|
+
var _a;
|
|
65
|
+
var _b = _this.options, autoLink = _b.autoLink, autoTel = _b.autoTel, autoMailto = _b.autoMailto;
|
|
66
|
+
var linkSegment = (0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
|
|
67
|
+
autoLink: autoLink,
|
|
68
|
+
autoTel: autoTel,
|
|
69
|
+
autoMailto: autoMailto,
|
|
70
|
+
});
|
|
71
|
+
if (linkSegment) {
|
|
72
|
+
return createAnchor(((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
autoFormat: 'hyphen',
|
|
79
|
+
enabled: !!this.options.autoHyphen,
|
|
80
|
+
transformFunction: function (_model, previousSegment, paragraph, context) {
|
|
81
|
+
return (0, transformHyphen_1.transformHyphen)(previousSegment, paragraph, context);
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
autoFormat: 'fraction',
|
|
86
|
+
enabled: !!this.options.autoFraction,
|
|
87
|
+
transformFunction: function (_model, previousSegment, paragraph, context) {
|
|
88
|
+
return (0, transformFraction_1.transformFraction)(previousSegment, paragraph, context);
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
autoFormat: 'ordinal',
|
|
93
|
+
enabled: !!this.options.autoOrdinals,
|
|
94
|
+
transformFunction: function (_model, previousSegment, paragraph, context) {
|
|
95
|
+
return (0, transformOrdinals_1.transformOrdinals)(previousSegment, paragraph, context);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
];
|
|
47
99
|
}
|
|
48
100
|
/**
|
|
49
101
|
* Get name of this plugin
|
|
@@ -105,45 +157,40 @@ var AutoFormatPlugin = /** @class */ (function () {
|
|
|
105
157
|
getChangeData: undefined,
|
|
106
158
|
};
|
|
107
159
|
(0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph, _markerFormat, context) {
|
|
108
|
-
var _a;
|
|
109
|
-
var
|
|
110
|
-
var
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
var
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
context.canUndoByBackspace = true;
|
|
160
|
+
var e_1, _a;
|
|
161
|
+
var formatApplied = undefined;
|
|
162
|
+
var _loop_1 = function (feature) {
|
|
163
|
+
if (feature.enabled) {
|
|
164
|
+
var result_1 = feature.transformFunction(model, previousSegment, paragraph, context);
|
|
165
|
+
if (result_1) {
|
|
166
|
+
if (typeof result_1 !== 'boolean') {
|
|
167
|
+
formatOptions_1.getChangeData = function () { return result_1; };
|
|
168
|
+
}
|
|
169
|
+
formatApplied = feature.autoFormat;
|
|
170
|
+
return "break";
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
for (var _b = (0, tslib_1.__values)(_this.features), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
176
|
+
var feature = _c.value;
|
|
177
|
+
var state_1 = _loop_1(feature);
|
|
178
|
+
if (state_1 === "break")
|
|
179
|
+
break;
|
|
129
180
|
}
|
|
130
181
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
182
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
183
|
+
finally {
|
|
184
|
+
try {
|
|
185
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
186
|
+
}
|
|
187
|
+
finally { if (e_1) throw e_1.error; }
|
|
136
188
|
}
|
|
137
|
-
if (
|
|
138
|
-
|
|
189
|
+
if (formatApplied) {
|
|
190
|
+
formatOptions_1.changeSource = getChangeSource(formatApplied);
|
|
191
|
+
formatOptions_1.apiName = getApiName(formatApplied);
|
|
139
192
|
}
|
|
140
|
-
|
|
141
|
-
formatOptions_1.changeSource = getChangeSource(shouldList, shouldHyphen, shouldLink);
|
|
142
|
-
return (shouldList ||
|
|
143
|
-
shouldHyphen ||
|
|
144
|
-
shouldLink ||
|
|
145
|
-
shouldFraction ||
|
|
146
|
-
shouldOrdinals);
|
|
193
|
+
return !!formatApplied;
|
|
147
194
|
}, formatOptions_1);
|
|
148
195
|
break;
|
|
149
196
|
}
|
|
@@ -177,9 +224,18 @@ var AutoFormatPlugin = /** @class */ (function () {
|
|
|
177
224
|
apiName: 'autoToggleList',
|
|
178
225
|
});
|
|
179
226
|
}
|
|
227
|
+
break;
|
|
228
|
+
case 'Enter':
|
|
229
|
+
this.handleEnterKey(editor, event);
|
|
230
|
+
break;
|
|
180
231
|
}
|
|
181
232
|
}
|
|
182
233
|
};
|
|
234
|
+
AutoFormatPlugin.prototype.handleEnterKey = function (editor, event) {
|
|
235
|
+
if (this.options.autoHorizontalLine) {
|
|
236
|
+
(0, checkAndInsertHorizontalLine_1.checkAndInsertHorizontalLine)(editor, event);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
183
239
|
AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
|
|
184
240
|
var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
|
|
185
241
|
if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
|
|
@@ -193,13 +249,13 @@ var AutoFormatPlugin = /** @class */ (function () {
|
|
|
193
249
|
return AutoFormatPlugin;
|
|
194
250
|
}());
|
|
195
251
|
exports.AutoFormatPlugin = AutoFormatPlugin;
|
|
196
|
-
var getApiName = function (
|
|
197
|
-
return
|
|
252
|
+
var getApiName = function (autoFormat) {
|
|
253
|
+
return autoFormat == 'list' ? 'autoToggleList' : autoFormat == 'hyphen' ? 'autoHyphen' : '';
|
|
198
254
|
};
|
|
199
|
-
var getChangeSource = function (
|
|
200
|
-
return
|
|
255
|
+
var getChangeSource = function (autoFormat) {
|
|
256
|
+
return autoFormat == 'list' || autoFormat == 'hyphen'
|
|
201
257
|
? roosterjs_content_model_dom_1.ChangeSource.AutoFormat
|
|
202
|
-
:
|
|
258
|
+
: autoFormat == 'link'
|
|
203
259
|
? roosterjs_content_model_dom_1.ChangeSource.AutoLink
|
|
204
260
|
: '';
|
|
205
261
|
};
|
|
@@ -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 EditorInputEvent,\n EditorPlugin,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\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 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 const {\n autoBullet,\n autoNumbering,\n autoLink,\n autoHyphen,\n autoFraction,\n autoOrdinals,\n autoMailto,\n autoTel,\n removeListMargins,\n } = this.options;\n let shouldHyphen = false;\n let shouldLink = false;\n let shouldList = false;\n let shouldFraction = false;\n let shouldOrdinals = false;\n\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering,\n removeListMargins\n );\n }\n\n if (autoLink || autoTel || autoMailto) {\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n const anchor = createAnchor(\n linkSegment.link?.format.href || '',\n linkSegment.text\n );\n formatOptions.getChangeData = () => anchor;\n\n shouldLink = true;\n context.canUndoByBackspace = true;\n }\n }\n\n if (autoHyphen) {\n shouldHyphen = transformHyphen(previousSegment, paragraph, context);\n }\n\n if (autoFraction) {\n shouldFraction = transformFraction(\n previousSegment,\n paragraph,\n context\n );\n }\n\n if (autoOrdinals) {\n shouldOrdinals = transformOrdinals(\n previousSegment,\n paragraph,\n context\n );\n }\n\n formatOptions.apiName = getApiName(shouldList, shouldHyphen);\n formatOptions.changeSource = getChangeSource(\n shouldList,\n shouldHyphen,\n shouldLink\n );\n\n return (\n shouldList ||\n shouldHyphen ||\n shouldLink ||\n shouldFraction ||\n shouldOrdinals\n );\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 = (shouldList: boolean, shouldHyphen: boolean) => {\n return shouldList ? 'autoToggleList' : shouldHyphen ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (shouldList: boolean, shouldHyphen: boolean, shouldLink: boolean) => {\n return shouldList || shouldHyphen\n ? ChangeSource.AutoFormat\n : shouldLink\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":"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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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformHyphen.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/hyphen/transformHyphen.ts"],"names":[],"mappings":";;;AAAA,2EAA+D;AAO/D;;GAEG;AACH,SAAgB,eAAe,CAC3B,eAAiC,EACjC,SAA8C,EAC9C,OAAkC;IAElC,IAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,IAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,MAAM,KAAK,IAAI,EAAE;QACjB,IAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzD,IAAM,WAAW,GAAG,IAAA,8CAAgB,EAAC,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"transformHyphen.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/hyphen/transformHyphen.ts"],"names":[],"mappings":";;;AAAA,2EAA+D;AAO/D;;GAEG;AACH,SAAgB,eAAe,CAC3B,eAAiC,EACjC,SAA8C,EAC9C,OAAkC;IAElC,IAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,IAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,MAAM,KAAK,IAAI,EAAE;QACjB,IAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzD,IAAM,WAAW,GAAG,IAAA,8CAAgB,EAAC,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QAC3F,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAClC,OAAO,IAAI,CAAC;KACf;SAAM;QACH,IAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAM,SAAS,GAAG,IAAI,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,IAAI,CAAC,IAAG,CAAC,CAAC,CAAC;QACnD,IAAI,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;YACnC,IAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrD,IAAM,WAAW,GAAG,IAAA,8CAAgB,EAChC,eAAe,EACf,SAAS,EACT,SAAS,EACT,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAC9B,CAAC;YAEF,IAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;YAC3C,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;gBACzE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACvD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;gBAClC,OAAO,IAAI,CAAC;aACf;SACJ;KACJ;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAlCD,0CAkCC","sourcesContent":["import { splitTextSegment } from 'roosterjs-content-model-api';\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function transformHyphen(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n): boolean {\n const segments = previousSegment.text.split(' ');\n const dashes = segments[segments.length - 2];\n if (dashes === '--') {\n const textIndex = previousSegment.text.lastIndexOf('--');\n const textSegment = splitTextSegment(previousSegment, paragraph, textIndex, textIndex + 2);\n textSegment.text = textSegment.text.replace('--', '—');\n context.canUndoByBackspace = true;\n return true;\n } else {\n const text = segments.pop();\n const hasDashes = text && text?.indexOf('--') > -1;\n if (hasDashes && text.trim() !== '--') {\n const textIndex = previousSegment.text.indexOf(text);\n const textSegment = splitTextSegment(\n previousSegment,\n paragraph,\n textIndex,\n textIndex + text.length - 1\n );\n\n const textLength = textSegment.text.length;\n if (textSegment.text[0] !== '-' && textSegment.text[textLength - 1] !== '-') {\n textSegment.text = textSegment.text.replace('--', '—');\n context.canUndoByBackspace = true;\n return true;\n }\n }\n }\n return false;\n}\n"]}
|
|
@@ -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
|
/**
|
|
@@ -45,7 +46,9 @@ export declare class AutoFormatPlugin implements EditorPlugin {
|
|
|
45
46
|
* @param event The event to handle:
|
|
46
47
|
*/
|
|
47
48
|
onPluginEvent(event: PluginEvent): void;
|
|
49
|
+
private features;
|
|
48
50
|
private handleEditorInputEvent;
|
|
49
51
|
private handleKeyDownEvent;
|
|
52
|
+
private handleEnterKey;
|
|
50
53
|
private handleContentChangedEvent;
|
|
51
54
|
}
|