roosterjs-editor-adapter 0.26.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 (102) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +262 -0
  3. package/lib/corePlugins/BridgePlugin.d.ts +73 -0
  4. package/lib/corePlugins/BridgePlugin.js +124 -0
  5. package/lib/corePlugins/BridgePlugin.js.map +1 -0
  6. package/lib/corePlugins/EditPlugin.d.ts +6 -0
  7. package/lib/corePlugins/EditPlugin.js +89 -0
  8. package/lib/corePlugins/EditPlugin.js.map +1 -0
  9. package/lib/editor/DarkColorHandlerImpl.d.ts +6 -0
  10. package/lib/editor/DarkColorHandlerImpl.js +134 -0
  11. package/lib/editor/DarkColorHandlerImpl.js.map +1 -0
  12. package/lib/editor/EditorAdapter.d.ts +341 -0
  13. package/lib/editor/EditorAdapter.js +843 -0
  14. package/lib/editor/EditorAdapter.js.map +1 -0
  15. package/lib/editor/utils/buildRangeEx.d.ts +5 -0
  16. package/lib/editor/utils/buildRangeEx.js +81 -0
  17. package/lib/editor/utils/buildRangeEx.js.map +1 -0
  18. package/lib/editor/utils/eventConverter.d.ts +15 -0
  19. package/lib/editor/utils/eventConverter.js +463 -0
  20. package/lib/editor/utils/eventConverter.js.map +1 -0
  21. package/lib/editor/utils/insertNode.d.ts +7 -0
  22. package/lib/editor/utils/insertNode.js +147 -0
  23. package/lib/editor/utils/insertNode.js.map +1 -0
  24. package/lib/editor/utils/selectionConverter.d.ts +10 -0
  25. package/lib/editor/utils/selectionConverter.js +79 -0
  26. package/lib/editor/utils/selectionConverter.js.map +1 -0
  27. package/lib/index.d.ts +3 -0
  28. package/lib/index.js +6 -0
  29. package/lib/index.js.map +1 -0
  30. package/lib/publicTypes/BeforePasteAdapterEvent.d.ts +15 -0
  31. package/lib/publicTypes/BeforePasteAdapterEvent.js +3 -0
  32. package/lib/publicTypes/BeforePasteAdapterEvent.js.map +1 -0
  33. package/lib/publicTypes/EditorAdapterOptions.d.ts +20 -0
  34. package/lib/publicTypes/EditorAdapterOptions.js +3 -0
  35. package/lib/publicTypes/EditorAdapterOptions.js.map +1 -0
  36. package/lib-amd/corePlugins/BridgePlugin.d.ts +73 -0
  37. package/lib-amd/corePlugins/BridgePlugin.js +122 -0
  38. package/lib-amd/corePlugins/BridgePlugin.js.map +1 -0
  39. package/lib-amd/corePlugins/EditPlugin.d.ts +6 -0
  40. package/lib-amd/corePlugins/EditPlugin.js +90 -0
  41. package/lib-amd/corePlugins/EditPlugin.js.map +1 -0
  42. package/lib-amd/editor/DarkColorHandlerImpl.d.ts +6 -0
  43. package/lib-amd/editor/DarkColorHandlerImpl.js +135 -0
  44. package/lib-amd/editor/DarkColorHandlerImpl.js.map +1 -0
  45. package/lib-amd/editor/EditorAdapter.d.ts +341 -0
  46. package/lib-amd/editor/EditorAdapter.js +836 -0
  47. package/lib-amd/editor/EditorAdapter.js.map +1 -0
  48. package/lib-amd/editor/utils/buildRangeEx.d.ts +5 -0
  49. package/lib-amd/editor/utils/buildRangeEx.js +82 -0
  50. package/lib-amd/editor/utils/buildRangeEx.js.map +1 -0
  51. package/lib-amd/editor/utils/eventConverter.d.ts +15 -0
  52. package/lib-amd/editor/utils/eventConverter.js +463 -0
  53. package/lib-amd/editor/utils/eventConverter.js.map +1 -0
  54. package/lib-amd/editor/utils/insertNode.d.ts +7 -0
  55. package/lib-amd/editor/utils/insertNode.js +148 -0
  56. package/lib-amd/editor/utils/insertNode.js.map +1 -0
  57. package/lib-amd/editor/utils/selectionConverter.d.ts +10 -0
  58. package/lib-amd/editor/utils/selectionConverter.js +79 -0
  59. package/lib-amd/editor/utils/selectionConverter.js.map +1 -0
  60. package/lib-amd/index.d.ts +3 -0
  61. package/lib-amd/index.js +7 -0
  62. package/lib-amd/index.js.map +1 -0
  63. package/lib-amd/publicTypes/BeforePasteAdapterEvent.d.ts +15 -0
  64. package/lib-amd/publicTypes/BeforePasteAdapterEvent.js +5 -0
  65. package/lib-amd/publicTypes/BeforePasteAdapterEvent.js.map +1 -0
  66. package/lib-amd/publicTypes/EditorAdapterOptions.d.ts +20 -0
  67. package/lib-amd/publicTypes/EditorAdapterOptions.js +5 -0
  68. package/lib-amd/publicTypes/EditorAdapterOptions.js.map +1 -0
  69. package/lib-mjs/corePlugins/BridgePlugin.d.ts +73 -0
  70. package/lib-mjs/corePlugins/BridgePlugin.js +120 -0
  71. package/lib-mjs/corePlugins/BridgePlugin.js.map +1 -0
  72. package/lib-mjs/corePlugins/EditPlugin.d.ts +6 -0
  73. package/lib-mjs/corePlugins/EditPlugin.js +85 -0
  74. package/lib-mjs/corePlugins/EditPlugin.js.map +1 -0
  75. package/lib-mjs/editor/DarkColorHandlerImpl.d.ts +6 -0
  76. package/lib-mjs/editor/DarkColorHandlerImpl.js +130 -0
  77. package/lib-mjs/editor/DarkColorHandlerImpl.js.map +1 -0
  78. package/lib-mjs/editor/EditorAdapter.d.ts +341 -0
  79. package/lib-mjs/editor/EditorAdapter.js +840 -0
  80. package/lib-mjs/editor/EditorAdapter.js.map +1 -0
  81. package/lib-mjs/editor/utils/buildRangeEx.d.ts +5 -0
  82. package/lib-mjs/editor/utils/buildRangeEx.js +77 -0
  83. package/lib-mjs/editor/utils/buildRangeEx.js.map +1 -0
  84. package/lib-mjs/editor/utils/eventConverter.d.ts +15 -0
  85. package/lib-mjs/editor/utils/eventConverter.js +458 -0
  86. package/lib-mjs/editor/utils/eventConverter.js.map +1 -0
  87. package/lib-mjs/editor/utils/insertNode.d.ts +7 -0
  88. package/lib-mjs/editor/utils/insertNode.js +143 -0
  89. package/lib-mjs/editor/utils/insertNode.js.map +1 -0
  90. package/lib-mjs/editor/utils/selectionConverter.d.ts +10 -0
  91. package/lib-mjs/editor/utils/selectionConverter.js +74 -0
  92. package/lib-mjs/editor/utils/selectionConverter.js.map +1 -0
  93. package/lib-mjs/index.d.ts +3 -0
  94. package/lib-mjs/index.js +2 -0
  95. package/lib-mjs/index.js.map +1 -0
  96. package/lib-mjs/publicTypes/BeforePasteAdapterEvent.d.ts +15 -0
  97. package/lib-mjs/publicTypes/BeforePasteAdapterEvent.js +2 -0
  98. package/lib-mjs/publicTypes/BeforePasteAdapterEvent.js.map +1 -0
  99. package/lib-mjs/publicTypes/EditorAdapterOptions.d.ts +20 -0
  100. package/lib-mjs/publicTypes/EditorAdapterOptions.js +2 -0
  101. package/lib-mjs/publicTypes/EditorAdapterOptions.js.map +1 -0
  102. package/package.json +21 -0
@@ -0,0 +1,90 @@
1
+ define(["require", "exports", "roosterjs-editor-dom"], function (require, exports, roosterjs_editor_dom_1) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createEditPlugin = void 0;
5
+ /**
6
+ * Edit Component helps handle Content edit features
7
+ */
8
+ var EditPlugin = /** @class */ (function () {
9
+ /**
10
+ * Construct a new instance of EditPlugin
11
+ * @param options The editor options
12
+ */
13
+ function EditPlugin() {
14
+ this.editor = null;
15
+ this.state = {
16
+ features: {},
17
+ };
18
+ }
19
+ /**
20
+ * Get a friendly name of this plugin
21
+ */
22
+ EditPlugin.prototype.getName = function () {
23
+ return 'Edit';
24
+ };
25
+ /**
26
+ * Initialize this plugin. This should only be called from Editor
27
+ * @param editor Editor instance
28
+ */
29
+ EditPlugin.prototype.initialize = function (editor) {
30
+ this.editor = editor;
31
+ };
32
+ /**
33
+ * Dispose this plugin
34
+ */
35
+ EditPlugin.prototype.dispose = function () {
36
+ this.editor = null;
37
+ };
38
+ /**
39
+ * Get plugin state object
40
+ */
41
+ EditPlugin.prototype.getState = function () {
42
+ return this.state;
43
+ };
44
+ /**
45
+ * Handle events triggered from editor
46
+ * @param event PluginEvent object
47
+ */
48
+ EditPlugin.prototype.onPluginEvent = function (event) {
49
+ var _a;
50
+ var hasFunctionKey = false;
51
+ var features = null;
52
+ var ctrlOrMeta = false;
53
+ var isKeyDownEvent = event.eventType == 0 /* KeyDown */;
54
+ if (isKeyDownEvent) {
55
+ var rawEvent = event.rawEvent;
56
+ var range = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getSelectionRange();
57
+ ctrlOrMeta = (0, roosterjs_editor_dom_1.isCtrlOrMetaPressed)(rawEvent);
58
+ hasFunctionKey = ctrlOrMeta || rawEvent.altKey;
59
+ features =
60
+ this.state.features[rawEvent.which] ||
61
+ (range && !range.collapsed && this.state.features[258 /* RANGE */]);
62
+ }
63
+ else if (event.eventType == 7 /* ContentChanged */) {
64
+ features = this.state.features[257 /* CONTENTCHANGED */];
65
+ }
66
+ for (var i = 0; features && i < (features === null || features === void 0 ? void 0 : features.length); i++) {
67
+ var feature = features[i];
68
+ if ((feature.allowFunctionKeys || !hasFunctionKey) &&
69
+ this.editor &&
70
+ feature.shouldHandleEvent(event, this.editor, ctrlOrMeta)) {
71
+ feature.handleEvent(event, this.editor);
72
+ if (isKeyDownEvent) {
73
+ event.handledByEditFeature = true;
74
+ }
75
+ break;
76
+ }
77
+ }
78
+ };
79
+ return EditPlugin;
80
+ }());
81
+ /**
82
+ * @internal
83
+ * Create a new instance of EditPlugin.
84
+ */
85
+ function createEditPlugin() {
86
+ return new EditPlugin();
87
+ }
88
+ exports.createEditPlugin = createEditPlugin;
89
+ });
90
+ //# sourceMappingURL=EditPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-editor-adapter/lib/corePlugins/EditPlugin.ts"],"names":[],"mappings":";;;;IAUA;;OAEG;IACH;QAII;;;WAGG;QACH;YAPQ,WAAM,GAAmB,IAAI,CAAC;YAQlC,IAAI,CAAC,KAAK,GAAG;gBACT,QAAQ,EAAE,EAAE;aACf,CAAC;QACN,CAAC;QAED;;WAEG;QACH,4BAAO,GAAP;YACI,OAAO,MAAM,CAAC;QAClB,CAAC;QAED;;;WAGG;QACH,+BAAU,GAAV,UAAW,MAAe;YACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACzB,CAAC;QAED;;WAEG;QACH,4BAAO,GAAP;YACI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvB,CAAC;QAED;;WAEG;QACH,6BAAQ,GAAR;YACI,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QAED;;;WAGG;QACH,kCAAa,GAAb,UAAc,KAAkB;;YAC5B,IAAI,cAAc,GAAG,KAAK,CAAC;YAC3B,IAAI,QAAQ,GAAoD,IAAI,CAAC;YACrE,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAM,cAAc,GAAG,KAAK,CAAC,SAAS,mBAA2B,CAAC;YAElE,IAAI,cAAc,EAAE;gBAChB,IAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,IAAM,KAAK,GAAG,MAAA,IAAI,CAAC,MAAM,0CAAE,iBAAiB,EAAE,CAAC;gBAE/C,UAAU,GAAG,IAAA,0CAAmB,EAAC,QAAQ,CAAC,CAAC;gBAC3C,cAAc,GAAG,UAAU,IAAI,QAAQ,CAAC,MAAM,CAAC;gBAC/C,QAAQ;oBACJ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;wBACnC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,iBAAY,CAAC,CAAC;aACtE;iBAAM,IAAI,KAAK,CAAC,SAAS,0BAAkC,EAAE;gBAC1D,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,0BAAqB,CAAC;aACvD;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,IAAI,CAAC,IAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAAA,EAAE,CAAC,EAAE,EAAE;gBACnD,IAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC5B,IACI,CAAC,OAAO,CAAC,iBAAiB,IAAI,CAAC,cAAc,CAAC;oBAC9C,IAAI,CAAC,MAAM;oBACX,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAC3D;oBACE,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;oBACxC,IAAI,cAAc,EAAE;wBAChB,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;qBACrC;oBACD,MAAM;iBACT;aACJ;QACL,CAAC;QACL,iBAAC;IAAD,CAAC,AAjFD,IAiFC;IAED;;;OAGG;IACH,SAAgB,gBAAgB;QAC5B,OAAO,IAAI,UAAU,EAAE,CAAC;IAC5B,CAAC;IAFD,4CAEC","sourcesContent":["import { isCtrlOrMetaPressed } from 'roosterjs-editor-dom';\r\nimport { Keys, PluginEventType } from 'roosterjs-editor-types';\r\nimport type {\r\n EditPluginState,\r\n GenericContentEditFeature,\r\n IEditor,\r\n PluginEvent,\r\n PluginWithState,\r\n} from 'roosterjs-editor-types';\r\n\r\n/**\r\n * Edit Component helps handle Content edit features\r\n */\r\nclass EditPlugin implements PluginWithState<EditPluginState> {\r\n private editor: IEditor | null = null;\r\n private state: EditPluginState;\r\n\r\n /**\r\n * Construct a new instance of EditPlugin\r\n * @param options The editor options\r\n */\r\n constructor() {\r\n this.state = {\r\n features: {},\r\n };\r\n }\r\n\r\n /**\r\n * Get a friendly name of this plugin\r\n */\r\n getName() {\r\n return 'Edit';\r\n }\r\n\r\n /**\r\n * Initialize this plugin. This should only be called from Editor\r\n * @param editor Editor instance\r\n */\r\n initialize(editor: IEditor) {\r\n this.editor = editor;\r\n }\r\n\r\n /**\r\n * Dispose this plugin\r\n */\r\n dispose() {\r\n this.editor = null;\r\n }\r\n\r\n /**\r\n * Get plugin state object\r\n */\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * Handle events triggered from editor\r\n * @param event PluginEvent object\r\n */\r\n onPluginEvent(event: PluginEvent) {\r\n let hasFunctionKey = false;\r\n let features: GenericContentEditFeature<PluginEvent>[] | null = null;\r\n let ctrlOrMeta = false;\r\n const isKeyDownEvent = event.eventType == PluginEventType.KeyDown;\r\n\r\n if (isKeyDownEvent) {\r\n const rawEvent = event.rawEvent;\r\n const range = this.editor?.getSelectionRange();\r\n\r\n ctrlOrMeta = isCtrlOrMetaPressed(rawEvent);\r\n hasFunctionKey = ctrlOrMeta || rawEvent.altKey;\r\n features =\r\n this.state.features[rawEvent.which] ||\r\n (range && !range.collapsed && this.state.features[Keys.RANGE]);\r\n } else if (event.eventType == PluginEventType.ContentChanged) {\r\n features = this.state.features[Keys.CONTENTCHANGED];\r\n }\r\n\r\n for (let i = 0; features && i < features?.length; i++) {\r\n const feature = features[i];\r\n if (\r\n (feature.allowFunctionKeys || !hasFunctionKey) &&\r\n this.editor &&\r\n feature.shouldHandleEvent(event, this.editor, ctrlOrMeta)\r\n ) {\r\n feature.handleEvent(event, this.editor);\r\n if (isKeyDownEvent) {\r\n event.handledByEditFeature = true;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * @internal\r\n * Create a new instance of EditPlugin.\r\n */\r\nexport function createEditPlugin(): PluginWithState<EditPluginState> {\r\n return new EditPlugin();\r\n}\r\n"]}
@@ -0,0 +1,6 @@
1
+ import type { DarkColorHandler } from 'roosterjs-editor-types';
2
+ import type { DarkColorHandler as StandaloneDarkColorHandler } from 'roosterjs-content-model-types';
3
+ /**
4
+ * @internal
5
+ */
6
+ export declare function createDarkColorHandler(innerHandler: StandaloneDarkColorHandler): DarkColorHandler;
@@ -0,0 +1,135 @@
1
+ define(["require", "exports", "roosterjs-content-model-dom"], function (require, exports, roosterjs_content_model_dom_1) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createDarkColorHandler = void 0;
5
+ var VARIABLE_REGEX = /^\s*var\(\s*(\-\-[a-zA-Z0-9\-_]+)\s*(?:,\s*(.*))?\)\s*$/;
6
+ var VARIABLE_PREFIX = 'var(';
7
+ var COLOR_VAR_PREFIX = 'darkColor';
8
+ var DarkColorHandlerImpl = /** @class */ (function () {
9
+ function DarkColorHandlerImpl(innerHandler) {
10
+ this.innerHandler = innerHandler;
11
+ }
12
+ /**
13
+ * Get a copy of known colors
14
+ * @returns
15
+ */
16
+ DarkColorHandlerImpl.prototype.getKnownColorsCopy = function () {
17
+ return Object.values(this.innerHandler.knownColors);
18
+ };
19
+ /**
20
+ * Given a light mode color value and an optional dark mode color value, register this color
21
+ * so that editor can handle it, then return the CSS color value for current color mode.
22
+ * @param lightModeColor Light mode color value
23
+ * @param isDarkMode Whether current color mode is dark mode
24
+ * @param darkModeColor Optional dark mode color value. If not passed, we will calculate one.
25
+ */
26
+ DarkColorHandlerImpl.prototype.registerColor = function (lightModeColor, isDarkMode, darkModeColor) {
27
+ var parsedColor = this.parseColorValue(lightModeColor);
28
+ var colorKey;
29
+ if (parsedColor) {
30
+ lightModeColor = parsedColor.lightModeColor;
31
+ darkModeColor = parsedColor.darkModeColor || darkModeColor;
32
+ colorKey = parsedColor.key;
33
+ }
34
+ if (isDarkMode && lightModeColor) {
35
+ colorKey =
36
+ colorKey || "--" + COLOR_VAR_PREFIX + "_" + lightModeColor.replace(/[^\d\w]/g, '_');
37
+ this.innerHandler.updateKnownColor(isDarkMode, colorKey, {
38
+ lightModeColor: lightModeColor,
39
+ darkModeColor: darkModeColor || this.innerHandler.getDarkColor(lightModeColor),
40
+ });
41
+ return "var(" + colorKey + ", " + lightModeColor + ")";
42
+ }
43
+ else {
44
+ return lightModeColor;
45
+ }
46
+ };
47
+ /**
48
+ * Reset known color record, clean up registered color variables.
49
+ */
50
+ DarkColorHandlerImpl.prototype.reset = function () {
51
+ this.innerHandler.reset();
52
+ };
53
+ /**
54
+ * Parse an existing color value, if it is in variable-based color format, extract color key,
55
+ * light color and query related dark color if any
56
+ * @param color The color string to parse
57
+ * @param isInDarkMode Whether current content is in dark mode. When set to true, if the color value is not in dark var format,
58
+ * we will treat is as a dark mode color and try to find a matched dark mode color.
59
+ */
60
+ DarkColorHandlerImpl.prototype.parseColorValue = function (color, isInDarkMode) {
61
+ var _a;
62
+ var key;
63
+ var lightModeColor = '';
64
+ var darkModeColor;
65
+ if (color) {
66
+ var match = color.startsWith(VARIABLE_PREFIX) ? VARIABLE_REGEX.exec(color) : null;
67
+ if (match) {
68
+ if (match[2]) {
69
+ key = match[1];
70
+ lightModeColor = match[2];
71
+ darkModeColor = (_a = this.innerHandler.knownColors[key]) === null || _a === void 0 ? void 0 : _a.darkModeColor;
72
+ }
73
+ else {
74
+ lightModeColor = '';
75
+ }
76
+ }
77
+ else if (isInDarkMode) {
78
+ // If editor is in dark mode but the color is not in dark color format, it is possible the color was inserted from external code
79
+ // without any light color info. So we first try to see if there is a known dark color can match this color, and use its related
80
+ // light color as light mode color. Otherwise we need to drop this color to avoid show "white on white" content.
81
+ lightModeColor = this.findLightColorFromDarkColor(color) || '';
82
+ if (lightModeColor) {
83
+ darkModeColor = color;
84
+ }
85
+ }
86
+ else {
87
+ lightModeColor = color;
88
+ }
89
+ }
90
+ return { key: key, lightModeColor: lightModeColor, darkModeColor: darkModeColor };
91
+ };
92
+ /**
93
+ * Find related light mode color from dark mode color.
94
+ * @param darkColor The existing dark color
95
+ */
96
+ DarkColorHandlerImpl.prototype.findLightColorFromDarkColor = function (darkColor) {
97
+ var rgbSearch = (0, roosterjs_content_model_dom_1.parseColor)(darkColor);
98
+ var knownColors = this.innerHandler.knownColors;
99
+ if (rgbSearch) {
100
+ var key = (0, roosterjs_content_model_dom_1.getObjectKeys)(knownColors).find(function (key) {
101
+ var rgbCurrent = (0, roosterjs_content_model_dom_1.parseColor)(knownColors[key].darkModeColor);
102
+ return (rgbCurrent &&
103
+ rgbCurrent[0] == rgbSearch[0] &&
104
+ rgbCurrent[1] == rgbSearch[1] &&
105
+ rgbCurrent[2] == rgbSearch[2]);
106
+ });
107
+ if (key) {
108
+ return knownColors[key].lightModeColor;
109
+ }
110
+ }
111
+ return null;
112
+ };
113
+ /**
114
+ * Transform element color, from dark to light or from light to dark
115
+ * @param element The element to transform color
116
+ * @param fromDarkMode Whether this is transforming color from dark mode
117
+ * @param toDarkMode Whether this is transforming color to dark mode
118
+ */
119
+ DarkColorHandlerImpl.prototype.transformElementColor = function (element, fromDarkMode, toDarkMode) {
120
+ var textColor = (0, roosterjs_content_model_dom_1.getColor)(element, false /*isBackground*/, !toDarkMode, this.innerHandler);
121
+ var backColor = (0, roosterjs_content_model_dom_1.getColor)(element, true /*isBackground*/, !toDarkMode, this.innerHandler);
122
+ (0, roosterjs_content_model_dom_1.setColor)(element, textColor, false /*isBackground*/, toDarkMode, this.innerHandler);
123
+ (0, roosterjs_content_model_dom_1.setColor)(element, backColor, true /*isBackground*/, toDarkMode, this.innerHandler);
124
+ };
125
+ return DarkColorHandlerImpl;
126
+ }());
127
+ /**
128
+ * @internal
129
+ */
130
+ function createDarkColorHandler(innerHandler) {
131
+ return new DarkColorHandlerImpl(innerHandler);
132
+ }
133
+ exports.createDarkColorHandler = createDarkColorHandler;
134
+ });
135
+ //# sourceMappingURL=DarkColorHandlerImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DarkColorHandlerImpl.js","sourceRoot":"","sources":["../../../../packages/roosterjs-editor-adapter/lib/editor/DarkColorHandlerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { getColor, getObjectKeys, parseColor, setColor } from 'roosterjs-content-model-dom';\r\nimport type { ColorKeyAndValue, DarkColorHandler } from 'roosterjs-editor-types';\r\nimport type { DarkColorHandler as StandaloneDarkColorHandler } from 'roosterjs-content-model-types';\r\n\r\nconst VARIABLE_REGEX = /^\\s*var\\(\\s*(\\-\\-[a-zA-Z0-9\\-_]+)\\s*(?:,\\s*(.*))?\\)\\s*$/;\r\nconst VARIABLE_PREFIX = 'var(';\r\nconst COLOR_VAR_PREFIX = 'darkColor';\r\n\r\nclass DarkColorHandlerImpl implements DarkColorHandler {\r\n constructor(private innerHandler: StandaloneDarkColorHandler) {}\r\n\r\n /**\r\n * Get a copy of known colors\r\n * @returns\r\n */\r\n getKnownColorsCopy() {\r\n return Object.values(this.innerHandler.knownColors);\r\n }\r\n\r\n /**\r\n * Given a light mode color value and an optional dark mode color value, register this color\r\n * so that editor can handle it, then return the CSS color value for current color mode.\r\n * @param lightModeColor Light mode color value\r\n * @param isDarkMode Whether current color mode is dark mode\r\n * @param darkModeColor Optional dark mode color value. If not passed, we will calculate one.\r\n */\r\n registerColor(lightModeColor: string, isDarkMode: boolean, darkModeColor?: string): string {\r\n const parsedColor = this.parseColorValue(lightModeColor);\r\n let colorKey: string | undefined;\r\n\r\n if (parsedColor) {\r\n lightModeColor = parsedColor.lightModeColor;\r\n darkModeColor = parsedColor.darkModeColor || darkModeColor;\r\n colorKey = parsedColor.key;\r\n }\r\n\r\n if (isDarkMode && lightModeColor) {\r\n colorKey =\r\n colorKey || `--${COLOR_VAR_PREFIX}_${lightModeColor.replace(/[^\\d\\w]/g, '_')}`;\r\n\r\n this.innerHandler.updateKnownColor(isDarkMode, colorKey, {\r\n lightModeColor,\r\n darkModeColor: darkModeColor || this.innerHandler.getDarkColor(lightModeColor),\r\n });\r\n\r\n return `var(${colorKey}, ${lightModeColor})`;\r\n } else {\r\n return lightModeColor;\r\n }\r\n }\r\n\r\n /**\r\n * Reset known color record, clean up registered color variables.\r\n */\r\n reset(): void {\r\n this.innerHandler.reset();\r\n }\r\n\r\n /**\r\n * Parse an existing color value, if it is in variable-based color format, extract color key,\r\n * light color and query related dark color if any\r\n * @param color The color string to parse\r\n * @param isInDarkMode Whether current content is in dark mode. When set to true, if the color value is not in dark var format,\r\n * we will treat is as a dark mode color and try to find a matched dark mode color.\r\n */\r\n parseColorValue(color: string | undefined | null, isInDarkMode?: boolean): ColorKeyAndValue {\r\n let key: string | undefined;\r\n let lightModeColor = '';\r\n let darkModeColor: string | undefined;\r\n\r\n if (color) {\r\n const match = color.startsWith(VARIABLE_PREFIX) ? VARIABLE_REGEX.exec(color) : null;\r\n\r\n if (match) {\r\n if (match[2]) {\r\n key = match[1];\r\n lightModeColor = match[2];\r\n darkModeColor = this.innerHandler.knownColors[key]?.darkModeColor;\r\n } else {\r\n lightModeColor = '';\r\n }\r\n } else if (isInDarkMode) {\r\n // If editor is in dark mode but the color is not in dark color format, it is possible the color was inserted from external code\r\n // without any light color info. So we first try to see if there is a known dark color can match this color, and use its related\r\n // light color as light mode color. Otherwise we need to drop this color to avoid show \"white on white\" content.\r\n lightModeColor = this.findLightColorFromDarkColor(color) || '';\r\n\r\n if (lightModeColor) {\r\n darkModeColor = color;\r\n }\r\n } else {\r\n lightModeColor = color;\r\n }\r\n }\r\n\r\n return { key, lightModeColor, darkModeColor };\r\n }\r\n\r\n /**\r\n * Find related light mode color from dark mode color.\r\n * @param darkColor The existing dark color\r\n */\r\n findLightColorFromDarkColor(darkColor: string): string | null {\r\n const rgbSearch = parseColor(darkColor);\r\n const knownColors = this.innerHandler.knownColors;\r\n\r\n if (rgbSearch) {\r\n const key = getObjectKeys(knownColors).find(key => {\r\n const rgbCurrent = parseColor(knownColors[key].darkModeColor);\r\n\r\n return (\r\n rgbCurrent &&\r\n rgbCurrent[0] == rgbSearch[0] &&\r\n rgbCurrent[1] == rgbSearch[1] &&\r\n rgbCurrent[2] == rgbSearch[2]\r\n );\r\n });\r\n\r\n if (key) {\r\n return knownColors[key].lightModeColor;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Transform element color, from dark to light or from light to dark\r\n * @param element The element to transform color\r\n * @param fromDarkMode Whether this is transforming color from dark mode\r\n * @param toDarkMode Whether this is transforming color to dark mode\r\n */\r\n transformElementColor(element: HTMLElement, fromDarkMode: boolean, toDarkMode: boolean): void {\r\n const textColor = getColor(element, false /*isBackground*/, !toDarkMode, this.innerHandler);\r\n const backColor = getColor(element, true /*isBackground*/, !toDarkMode, this.innerHandler);\r\n\r\n setColor(element, textColor, false /*isBackground*/, toDarkMode, this.innerHandler);\r\n setColor(element, backColor, true /*isBackground*/, toDarkMode, this.innerHandler);\r\n }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport function createDarkColorHandler(innerHandler: StandaloneDarkColorHandler): DarkColorHandler {\r\n return new DarkColorHandlerImpl(innerHandler);\r\n}\r\n"]}
@@ -0,0 +1,341 @@
1
+ import { StandaloneEditor } from 'roosterjs-content-model-core';
2
+ import { ChangeSource, ColorTransformDirection, ContentPosition, GetContentMode, PluginEventType, QueryScope, RegionType } from 'roosterjs-editor-types';
3
+ import type { BlockElement, ClipboardData, ContentChangedData, DOMEventHandler, DefaultFormat, EditorUndoState, ExperimentalFeatures, GenericContentEditFeature, IContentTraverser, IPositionContentSearcher, InsertOption, NodePosition, PendableFormatState, PluginEvent, PluginEventData, PluginEventFromType, PositionType, Region, SelectionPath, SelectionRangeEx, SizeTransformer, StyleBasedFormatState, TableSelection, DarkColorHandler, IEditor } from 'roosterjs-editor-types';
4
+ import type { CompatibleChangeSource, CompatibleColorTransformDirection, CompatibleContentPosition, CompatibleExperimentalFeatures, CompatibleGetContentMode, CompatiblePluginEventType, CompatibleQueryScope, CompatibleRegionType } from 'roosterjs-editor-types/lib/compatibleTypes';
5
+ import type { EditorAdapterOptions } from '../publicTypes/EditorAdapterOptions';
6
+ import type { IStandaloneEditor } from 'roosterjs-content-model-types';
7
+ /**
8
+ * Editor for Content Model.
9
+ * (This class is still under development, and may still be changed in the future with some breaking changes)
10
+ */
11
+ export declare class EditorAdapter extends StandaloneEditor implements IEditor {
12
+ private contentModelEditorCore;
13
+ /**
14
+ * Creates an instance of Editor
15
+ * @param contentDiv The DIV HTML element which will be the container element of editor
16
+ * @param options An optional options object to customize the editor
17
+ */
18
+ constructor(contentDiv: HTMLDivElement, options?: EditorAdapterOptions);
19
+ /**
20
+ * Dispose this editor, dispose all plugins and custom data
21
+ */
22
+ dispose(): void;
23
+ /**
24
+ * Get whether this editor is disposed
25
+ * @returns True if editor is disposed, otherwise false
26
+ */
27
+ isDisposed(): boolean;
28
+ /**
29
+ * Insert node into editor
30
+ * @param node The node to insert
31
+ * @param option Insert options. Default value is:
32
+ * position: ContentPosition.SelectionStart
33
+ * updateCursor: true
34
+ * replaceSelection: true
35
+ * insertOnNewLine: false
36
+ * @returns true if node is inserted. Otherwise false
37
+ */
38
+ insertNode(node: Node, option?: InsertOption): boolean;
39
+ /**
40
+ * Delete a node from editor content
41
+ * @param node The node to delete
42
+ * @returns true if node is deleted. Otherwise false
43
+ */
44
+ deleteNode(node: Node): boolean;
45
+ /**
46
+ * Replace a node in editor content with another node
47
+ * @param existingNode The existing node to be replaced
48
+ * @param toNode node to replace to
49
+ * @param transformColorForDarkMode (optional) Whether to transform new node to dark mode. Default is false
50
+ * @returns true if node is replaced. Otherwise false
51
+ */
52
+ replaceNode(existingNode: Node, toNode: Node, transformColorForDarkMode?: boolean): boolean;
53
+ /**
54
+ * Get BlockElement at given node
55
+ * @param node The node to create InlineElement
56
+ * @returns The BlockElement result
57
+ */
58
+ getBlockElementAtNode(node: Node): BlockElement | null;
59
+ contains(arg: Node | Range | null): boolean;
60
+ queryElements(selector: string, scopeOrCallback?: QueryScope | CompatibleQueryScope | ((node: Node) => any), callback?: (node: Node) => any): HTMLElement[];
61
+ /**
62
+ * Collapse nodes within the given start and end nodes to their common ancestor node,
63
+ * split parent nodes if necessary
64
+ * @param start The start node
65
+ * @param end The end node
66
+ * @param canSplitParent True to allow split parent node there are nodes before start or after end under the same parent
67
+ * and the returned nodes will be all nodes from start through end after splitting
68
+ * False to disallow split parent
69
+ * @returns When canSplitParent is true, returns all node from start through end after splitting,
70
+ * otherwise just return start and end
71
+ */
72
+ collapseNodes(start: Node, end: Node, canSplitParent: boolean): Node[];
73
+ /**
74
+ * Check whether the editor contains any visible content
75
+ * @param trim Whether trim the content string before check. Default is false
76
+ * @returns True if there's no visible content, otherwise false
77
+ */
78
+ isEmpty(trim?: boolean): boolean;
79
+ /**
80
+ * Get current editor content as HTML string
81
+ * @param mode specify what kind of HTML content to retrieve
82
+ * @returns HTML string representing current editor content
83
+ */
84
+ getContent(mode?: GetContentMode | CompatibleGetContentMode): string;
85
+ /**
86
+ * Set HTML content to this editor. All existing content will be replaced. A ContentChanged event will be triggered
87
+ * @param content HTML content to set in
88
+ * @param triggerContentChangedEvent True to trigger a ContentChanged event. Default value is true
89
+ */
90
+ setContent(content: string, triggerContentChangedEvent?: boolean): void;
91
+ /**
92
+ * Insert HTML content into editor
93
+ * @param HTML content to insert
94
+ * @param option Insert options. Default value is:
95
+ * position: ContentPosition.SelectionStart
96
+ * updateCursor: true
97
+ * replaceSelection: true
98
+ * insertOnNewLine: false
99
+ */
100
+ insertContent(content: string, option?: InsertOption): void;
101
+ /**
102
+ * Delete selected content
103
+ */
104
+ deleteSelectedContent(): NodePosition | null;
105
+ /**
106
+ * Paste into editor using a clipboardData object
107
+ * @param clipboardData Clipboard data retrieved from clipboard
108
+ * @param pasteAsText Force pasting as plain text. Default value is false
109
+ * @param applyCurrentStyle True if apply format of current selection to the pasted content,
110
+ * false to keep original format. Default value is false. When pasteAsText is true, this parameter is ignored
111
+ * @param pasteAsImage: When set to true, if the clipboardData contains a imageDataUri will paste the image to the editor
112
+ */
113
+ paste(clipboardData: ClipboardData, pasteAsText?: boolean, applyCurrentFormat?: boolean, pasteAsImage?: boolean): void;
114
+ /**
115
+ * Get current selection range from Editor.
116
+ * It does a live pull on the selection, if nothing retrieved, return whatever we have in cache.
117
+ * @param tryGetFromCache Set to true to retrieve the selection range from cache if editor doesn't own the focus now.
118
+ * Default value is true
119
+ * @returns current selection range, or null if editor never got focus before
120
+ */
121
+ getSelectionRange(tryGetFromCache?: boolean): Range | null;
122
+ /**
123
+ * Get current selection range from Editor.
124
+ * It does a live pull on the selection, if nothing retrieved, return whatever we have in cache.
125
+ * @param tryGetFromCache Set to true to retrieve the selection range from cache if editor doesn't own the focus now.
126
+ * Default value is true
127
+ * @returns current selection range, or null if editor never got focus before
128
+ */
129
+ getSelectionRangeEx(): SelectionRangeEx;
130
+ /**
131
+ * Get current selection in a serializable format
132
+ * It does a live pull on the selection, if nothing retrieved, return whatever we have in cache.
133
+ * @returns current selection path, or null if editor never got focus before
134
+ */
135
+ getSelectionPath(): SelectionPath | null;
136
+ select(arg1: Range | SelectionRangeEx | NodePosition | Node | SelectionPath | null, arg2?: NodePosition | number | PositionType | TableSelection | null, arg3?: Node, arg4?: number | PositionType): boolean;
137
+ /**
138
+ * Get current focused position. Return null if editor doesn't have focus at this time.
139
+ */
140
+ getFocusedPosition(): NodePosition | null;
141
+ /**
142
+ * Get an HTML element from current cursor position.
143
+ * When expectedTags is not specified, return value is the current node (if it is HTML element)
144
+ * or its parent node (if current node is a Text node).
145
+ * When expectedTags is specified, return value is the first ancestor of current node which has
146
+ * one of the expected tags.
147
+ * If no element found within editor by the given tag, return null.
148
+ * @param selector Optional, an HTML selector to find HTML element with.
149
+ * @param startFrom Start search from this node. If not specified, start from current focused position
150
+ * @param event Optional, if specified, editor will try to get cached result from the event object first.
151
+ * If it is not cached before, query from DOM and cache the result into the event object
152
+ */
153
+ getElementAtCursor(selector?: string, startFrom?: Node, event?: PluginEvent): HTMLElement | null;
154
+ /**
155
+ * Check if this position is at beginning of the editor.
156
+ * This will return true if all nodes between the beginning of target node and the position are empty.
157
+ * @param position The position to check
158
+ * @returns True if position is at beginning of the editor, otherwise false
159
+ */
160
+ isPositionAtBeginning(position: NodePosition): boolean;
161
+ /**
162
+ * Get impacted regions from selection
163
+ */
164
+ getSelectedRegions(type?: RegionType | CompatibleRegionType): Region[];
165
+ addDomEventHandler(nameOrMap: string | Record<string, DOMEventHandler>, handler?: DOMEventHandler): () => void;
166
+ /**
167
+ * Trigger an event to be dispatched to all plugins
168
+ * @param eventType Type of the event
169
+ * @param data data of the event with given type, this is the rest part of PluginEvent with the given type
170
+ * @param broadcast indicates if the event needs to be dispatched to all plugins
171
+ * True means to all, false means to allow exclusive handling from one plugin unless no one wants that
172
+ * @returns the event object which is really passed into plugins. Some plugin may modify the event object so
173
+ * the result of this function provides a chance to read the modified result
174
+ */
175
+ triggerPluginEvent<T extends PluginEventType | CompatiblePluginEventType>(eventType: T, data: PluginEventData<T>, broadcast?: boolean): PluginEventFromType<T>;
176
+ /**
177
+ * Trigger a ContentChangedEvent
178
+ * @param source Source of this event, by default is 'SetContent'
179
+ * @param data additional data for this event
180
+ */
181
+ triggerContentChangedEvent(source?: ChangeSource | CompatibleChangeSource | string, data?: any): void;
182
+ /**
183
+ * Undo last edit operation
184
+ */
185
+ undo(): void;
186
+ /**
187
+ * Redo next edit operation
188
+ */
189
+ redo(): void;
190
+ /**
191
+ * Add undo snapshot, and execute a format callback function, then add another undo snapshot, then trigger
192
+ * ContentChangedEvent with given change source.
193
+ * If this function is called nested, undo snapshot will only be added in the outside one
194
+ * @param callback The callback function to perform formatting, returns a data object which will be used as
195
+ * the data field in ContentChangedEvent if changeSource is not null.
196
+ * @param changeSource The change source to use when fire ContentChangedEvent. When the value is not null,
197
+ * a ContentChangedEvent will be fired with change source equal to this value
198
+ * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).
199
+ */
200
+ addUndoSnapshot(callback?: (start: NodePosition | null, end: NodePosition | null) => any, changeSource?: ChangeSource | CompatibleChangeSource | string, canUndoByBackspace?: boolean, additionalData?: ContentChangedData): void;
201
+ /**
202
+ * Whether there is an available undo/redo snapshot
203
+ */
204
+ getUndoState(): EditorUndoState;
205
+ /**
206
+ * Get custom data related to this editor
207
+ * @param key Key of the custom data
208
+ * @param getter Getter function. If custom data for the given key doesn't exist,
209
+ * call this function to get one and store it if it is specified. Otherwise return undefined
210
+ * @param disposer An optional disposer function to dispose this custom data when
211
+ * dispose editor.
212
+ */
213
+ getCustomData<T>(key: string, getter?: () => T, disposer?: (value: T) => void): T;
214
+ /**
215
+ * Get default format of this editor
216
+ * @returns Default format object of this editor
217
+ */
218
+ getDefaultFormat(): DefaultFormat;
219
+ /**
220
+ * Get a content traverser for the whole editor
221
+ * @param startNode The node to start from. If not passed, it will start from the beginning of the body
222
+ */
223
+ getBodyTraverser(startNode?: Node): IContentTraverser;
224
+ /**
225
+ * Get a content traverser for current selection
226
+ * @returns A content traverser, or null if editor never got focus before
227
+ */
228
+ getSelectionTraverser(range?: Range): IContentTraverser | null;
229
+ /**
230
+ * Get a content traverser for current block element start from specified position
231
+ * @param startFrom Start position of the traverser. Default value is ContentPosition.SelectionStart
232
+ * @returns A content traverser, or null if editor never got focus before
233
+ */
234
+ getBlockTraverser(startFrom?: ContentPosition | CompatibleContentPosition): IContentTraverser | null;
235
+ /**
236
+ * Get a text traverser of current selection
237
+ * @param event Optional, if specified, editor will try to get cached result from the event object first.
238
+ * If it is not cached before, query from DOM and cache the result into the event object
239
+ * @returns A content traverser, or null if editor never got focus before
240
+ */
241
+ getContentSearcherOfCursor(event?: PluginEvent): IPositionContentSearcher | null;
242
+ /**
243
+ * Run a callback function asynchronously
244
+ * @param callback The callback function to run
245
+ * @returns a function to cancel this async run
246
+ */
247
+ runAsync(callback: (editor: IEditor & IStandaloneEditor) => void): () => void;
248
+ /**
249
+ * Set DOM attribute of editor content DIV
250
+ * @param name Name of the attribute
251
+ * @param value Value of the attribute
252
+ */
253
+ setEditorDomAttribute(name: string, value: string | null): void;
254
+ /**
255
+ * Get DOM attribute of editor content DIV, null if there is no such attribute.
256
+ * @param name Name of the attribute
257
+ */
258
+ getEditorDomAttribute(name: string): string | null;
259
+ /**
260
+ * @deprecated Use getVisibleViewport() instead.
261
+ *
262
+ * Get current relative distance from top-left corner of the given element to top-left corner of editor content DIV.
263
+ * @param element The element to calculate from. If the given element is not in editor, return value will be null
264
+ * @param addScroll When pass true, The return value will also add scrollLeft and scrollTop if any. So the value
265
+ * may be different than what user is seeing from the view. When pass false, scroll position will be ignored.
266
+ * @returns An [x, y] array which contains the left and top distances, or null if the given element is not in editor.
267
+ */
268
+ getRelativeDistanceToEditor(element: HTMLElement, addScroll?: boolean): number[] | null;
269
+ /**
270
+ * Add a Content Edit feature.
271
+ * @param feature The feature to add
272
+ */
273
+ addContentEditFeature(feature: GenericContentEditFeature<PluginEvent>): void;
274
+ /**
275
+ * Remove a Content Edit feature.
276
+ * @param feature The feature to remove
277
+ */
278
+ removeContentEditFeature(feature: GenericContentEditFeature<PluginEvent>): void;
279
+ /**
280
+ * @deprecated
281
+ * Get style based format state from current selection, including font name/size and colors
282
+ */
283
+ getStyleBasedFormatState(): StyleBasedFormatState;
284
+ /**
285
+ * @deprecated
286
+ * Get the pendable format such as underline and bold
287
+ * @returns The pending format state
288
+ */
289
+ getPendableFormatState(): PendableFormatState;
290
+ /**
291
+ * @deprecated
292
+ * Ensure user will type into a container element rather than into the editor content DIV directly
293
+ * @param position The position that user is about to type to
294
+ * @param keyboardEvent Optional keyboard event object
295
+ */
296
+ ensureTypeInContainer(position: NodePosition, keyboardEvent?: KeyboardEvent): void;
297
+ /**
298
+ * Transform the given node and all its child nodes to dark mode color if editor is in dark mode
299
+ * @param node The node to transform
300
+ * @param direction The transform direction. @default ColorTransformDirection.LightToDark
301
+ */
302
+ transformToDarkColor(node: Node, direction?: ColorTransformDirection | CompatibleColorTransformDirection): void;
303
+ /**
304
+ * Check if the given experimental feature is enabled
305
+ * @param feature The feature to check
306
+ */
307
+ isFeatureEnabled(feature: ExperimentalFeatures | CompatibleExperimentalFeatures): boolean;
308
+ /**
309
+ * Get current zoom scale, default value is 1
310
+ * When editor is put under a zoomed container, need to pass the zoom scale number using EditorOptions.zoomScale
311
+ * to let editor behave correctly especially for those mouse drag/drop behaviors
312
+ * @returns current zoom scale number
313
+ */
314
+ getZoomScale(): number;
315
+ /**
316
+ * Set current zoom scale, default value is 1
317
+ * When editor is put under a zoomed container, need to pass the zoom scale number using EditorOptions.zoomScale
318
+ * to let editor behave correctly especially for those mouse drag/drop behaviors
319
+ * @param scale The new scale number to set. It should be positive number and no greater than 10, otherwise it will be ignored.
320
+ */
321
+ setZoomScale(scale: number): void;
322
+ /**
323
+ * @deprecated Use getZoomScale() instead
324
+ */
325
+ getSizeTransformer(): SizeTransformer;
326
+ /**
327
+ * Get a darkColorHandler object for this editor.
328
+ */
329
+ getDarkColorHandler(): DarkColorHandler;
330
+ /**
331
+ * Check if editor is in IME input sequence
332
+ * @returns True if editor is in IME input sequence, otherwise false
333
+ */
334
+ isInIME(): boolean;
335
+ private retrieveFormatState;
336
+ /**
337
+ * @returns the current EditorAdapterCore object
338
+ * @throws a standard Error if there's no core object
339
+ */
340
+ private getContentModelEditorCore;
341
+ }