@shelamkoff/rector 1.0.0 → 1.0.2

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 (94) hide show
  1. package/README.md +25 -23
  2. package/dist/core/clipboard/Clipboard.d.ts +2 -0
  3. package/dist/core/clipboard/Clipboard.js +52 -24
  4. package/dist/core/index.js +195 -194
  5. package/dist/core/locale/en.d.ts +1 -0
  6. package/dist/core/locale/en.js +1 -0
  7. package/dist/core/locale/ru.d.ts +1 -0
  8. package/dist/core/locale/ru.js +1 -0
  9. package/dist/core/themes/light.css +1 -1
  10. package/dist/core/themes/variables.css +72 -10
  11. package/dist/inline-plugins/mention/index.js +1 -2
  12. package/dist/locale/en.d.ts +41 -0
  13. package/dist/locale/ru.d.ts +41 -0
  14. package/dist/plugins/attaches/attaches.css +16 -14
  15. package/dist/plugins/attaches/index.js +997 -921
  16. package/dist/plugins/attaches/locale/en.d.ts +9 -0
  17. package/dist/plugins/attaches/locale/en.js +11 -2
  18. package/dist/plugins/attaches/locale/ru.d.ts +9 -0
  19. package/dist/plugins/attaches/locale/ru.js +11 -2
  20. package/dist/plugins/carousel/carousel.css +213 -49
  21. package/dist/plugins/carousel/index.js +918 -859
  22. package/dist/plugins/carousel/locale/en.d.ts +15 -0
  23. package/dist/plugins/carousel/locale/en.js +18 -3
  24. package/dist/plugins/carousel/locale/ru.d.ts +15 -0
  25. package/dist/plugins/carousel/locale/ru.js +18 -3
  26. package/dist/plugins/checklist/index.js +1 -2
  27. package/dist/plugins/code/index.js +1 -2
  28. package/dist/plugins/columns/index.js +1 -2
  29. package/dist/plugins/delimiter/index.js +1 -2
  30. package/dist/plugins/embed/index.js +1 -2
  31. package/dist/plugins/gallery/gallery.css +6 -1
  32. package/dist/plugins/gallery/index.js +375 -355
  33. package/dist/plugins/gallery/locale/en.d.ts +8 -0
  34. package/dist/plugins/gallery/locale/en.js +11 -3
  35. package/dist/plugins/gallery/locale/ru.d.ts +8 -0
  36. package/dist/plugins/gallery/locale/ru.js +11 -3
  37. package/dist/plugins/gallery/view-empty.d.ts +2 -0
  38. package/dist/plugins/gallery/view-empty.js +21 -15
  39. package/dist/plugins/gallery/view-filled.d.ts +2 -2
  40. package/dist/plugins/gallery/view-filled.js +61 -56
  41. package/dist/plugins/heading/index.js +1 -2
  42. package/dist/plugins/image/image.css +7 -2
  43. package/dist/plugins/image/index.js +365 -346
  44. package/dist/plugins/image/locale/en.d.ts +8 -0
  45. package/dist/plugins/image/locale/en.js +11 -3
  46. package/dist/plugins/image/locale/ru.d.ts +8 -0
  47. package/dist/plugins/image/locale/ru.js +11 -3
  48. package/dist/plugins/image/view-empty.d.ts +2 -0
  49. package/dist/plugins/image/view-empty.js +21 -15
  50. package/dist/plugins/image/view-filled.d.ts +2 -2
  51. package/dist/plugins/image/view-filled.js +77 -72
  52. package/dist/plugins/link-preview/index.js +1 -2
  53. package/dist/plugins/list/index.js +1 -2
  54. package/dist/plugins/paragraph/index.js +1 -2
  55. package/dist/plugins/person/index.js +1 -2
  56. package/dist/plugins/poll/index.js +1 -2
  57. package/dist/plugins/quote/index.js +1 -2
  58. package/dist/plugins/raw/index.js +1 -2
  59. package/dist/plugins/shared/dropzone.d.ts +6 -0
  60. package/dist/plugins/shared/dropzone.js +47 -36
  61. package/dist/plugins/shared/layer.d.ts +13 -0
  62. package/dist/plugins/shared/layer.js +45 -0
  63. package/dist/plugins/shared/sourceEditor.css +165 -0
  64. package/dist/plugins/shared/sourceEditor.d.ts +97 -0
  65. package/dist/plugins/shared/sourceEditor.js +260 -0
  66. package/dist/plugins/spoiler/index.js +1 -2
  67. package/dist/plugins/table/index.js +1 -2
  68. package/dist/plugins/toggle/index.js +1 -2
  69. package/dist/plugins/warning/index.js +1 -2
  70. package/dist/renderer/index.js +1 -2
  71. package/dist/renderer/renderers/attaches/index.js +1 -2
  72. package/dist/renderer/renderers/carousel/index.js +24 -24
  73. package/dist/renderer/renderers/carousel/styles.css +8 -2
  74. package/dist/renderer/renderers/checklist/index.js +1 -2
  75. package/dist/renderer/renderers/code/index.js +1 -2
  76. package/dist/renderer/renderers/columns/index.js +1 -2
  77. package/dist/renderer/renderers/delimiter/index.js +1 -2
  78. package/dist/renderer/renderers/embed/index.js +1 -2
  79. package/dist/renderer/renderers/gallery/index.js +1 -2
  80. package/dist/renderer/renderers/heading/index.js +1 -2
  81. package/dist/renderer/renderers/image/index.js +1 -2
  82. package/dist/renderer/renderers/link-preview/index.js +1 -2
  83. package/dist/renderer/renderers/list/index.js +1 -2
  84. package/dist/renderer/renderers/paragraph/index.js +1 -2
  85. package/dist/renderer/renderers/person/index.js +1 -2
  86. package/dist/renderer/renderers/poll/index.js +1 -2
  87. package/dist/renderer/renderers/quote/index.js +1 -2
  88. package/dist/renderer/renderers/spoiler/index.js +1 -2
  89. package/dist/renderer/renderers/table/index.js +1 -2
  90. package/dist/renderer/renderers/toggle/index.js +1 -2
  91. package/dist/renderer/renderers/warning/index.js +1 -2
  92. package/package.json +27 -29
  93. package/dist/shared/resolvePath.d.ts +0 -8
  94. package/dist/shared/resolvePath.js +0 -10
@@ -30,12 +30,12 @@ import { TriggerManager } from './TriggerManager.js'
30
30
  import { InlinePatternMatcher } from './InlinePatternMatcher.js'
31
31
  import { PopupManager } from './PopupManager.js'
32
32
  import { injectStyleUrls } from './StyleInjector.js'
33
- import { resolveTuning } from './config.js'
34
- import {DEFAULT_BLOCK_TYPE, DEFAULT_THEME} from './constants.js'
35
- import { claimPluginInstances } from './PluginOwnership.js'
36
- import { claimEditorHolder } from './EditorHolderOwnership.js'
37
- import { LifecycleScope } from './LifecycleScope.js'
38
- import en from './locale/en.js'
33
+ import { resolveTuning } from './config.js'
34
+ import {DEFAULT_BLOCK_TYPE, DEFAULT_THEME} from './constants.js'
35
+ import { claimPluginInstances } from './PluginOwnership.js'
36
+ import { claimEditorHolder } from './EditorHolderOwnership.js'
37
+ import { LifecycleScope } from './LifecycleScope.js'
38
+ import en from './locale/en.js'
39
39
 
40
40
  /**
41
41
  * Resolve inline tools config into tool instances.
@@ -119,26 +119,26 @@ function injectPluginI18n(plugin, i18n) {
119
119
  * @param {number} [minHeight]
120
120
  * @returns {{ rootEl: HTMLElement, blocksEl: HTMLElement, clickArea: HTMLElement }}
121
121
  */
122
- function buildEditorDOM(holder, theme, minHeight) {
123
- const rootEl = el('div', `oe-editor oe-theme-${theme}`, { tabindex: '-1' })
124
- if (minHeight !== undefined) rootEl.style.minHeight = `${minHeight}px`
122
+ function buildEditorDOM(holder, theme, minHeight) {
123
+ const rootEl = el('div', `oe-editor oe-theme-${theme}`, { tabindex: '-1' })
124
+ if (minHeight !== undefined) rootEl.style.minHeight = `${minHeight}px`
125
125
  const blocksEl = el('div', 'oe-blocks')
126
126
  const clickArea = el('div', 'oe-click-area')
127
127
  rootEl.appendChild(blocksEl)
128
128
  rootEl.appendChild(clickArea)
129
- return { rootEl, blocksEl, clickArea }
130
- }
131
-
132
- /**
133
- * Synchronize the editor root's read-only class and accessibility state.
134
- * @param {HTMLElement} rootEl Editor root element.
135
- * @param {boolean} readOnly Whether document mutations are disabled.
136
- */
137
- function applyReadOnlyAttributes(rootEl, readOnly) {
138
- rootEl.classList.toggle('oe-editor--read-only', readOnly)
139
- if (readOnly) rootEl.setAttribute('aria-readonly', 'true')
140
- else rootEl.removeAttribute('aria-readonly')
141
- }
129
+ return { rootEl, blocksEl, clickArea }
130
+ }
131
+
132
+ /**
133
+ * Synchronize the editor root's read-only class and accessibility state.
134
+ * @param {HTMLElement} rootEl Editor root element.
135
+ * @param {boolean} readOnly Whether document mutations are disabled.
136
+ */
137
+ function applyReadOnlyAttributes(rootEl, readOnly) {
138
+ rootEl.classList.toggle('oe-editor--read-only', readOnly)
139
+ if (readOnly) rootEl.setAttribute('aria-readonly', 'true')
140
+ else rootEl.removeAttribute('aria-readonly')
141
+ }
142
142
 
143
143
  /**
144
144
  * Wire focusin and input tracking on the editor root.
@@ -149,7 +149,7 @@ function applyReadOnlyAttributes(rootEl, readOnly) {
149
149
  */
150
150
  function wireInputTracking(rootEl, blocks, events) {
151
151
  const onFocusIn = (/** @type {FocusEvent} */ e) => {
152
- const target = /** @type {import('./types').DOMNode} */ (e.target)
152
+ const target = /** @type {import('./types').DOMNode} */ (e.target)
153
153
  const block = blocks.getBlockByChildNode(target)
154
154
  if (!block) return
155
155
  const index = blocks.getBlockIndex(block.id)
@@ -159,7 +159,7 @@ function wireInputTracking(rootEl, blocks, events) {
159
159
  }
160
160
 
161
161
  const onInput = (/** @type {InputEvent} */ event) => {
162
- const target = /** @type {import('./types').DOMNode} */ (event.target)
162
+ const target = /** @type {import('./types').DOMNode} */ (event.target)
163
163
  // Editor controls (URL/color/font inputs, filters, dialogs) also bubble
164
164
  // `input` through rootEl. They are not document mutations and must never
165
165
  // advance block history by falling back to the currently focused block.
@@ -199,8 +199,8 @@ function injectPluginStyles(plugins) {
199
199
  ? plugin.getPluginConfig()
200
200
  : undefined
201
201
  if (cfg?.injectStyles !== false) {
202
- const constructor = /** @type {import('./types').BlockPluginConstructor} */ (plugin.constructor)
203
- const urls = constructor.styles
202
+ const constructor = /** @type {import('./types').BlockPluginConstructor} */ (plugin.constructor)
203
+ const urls = constructor.styles
204
204
  if (urls) styleUrls.push(...urls)
205
205
  }
206
206
  if (cfg?.css) styleUrls.push(cfg.css)
@@ -227,10 +227,10 @@ function injectPluginStyles(plugins) {
227
227
  * @property {DocumentSnapshotStore} snapshots
228
228
  * @property {import('./config').EditorTuning} tuning
229
229
  * @property {import('./types').EditorConfig} config
230
- * @property {Diagnostics} diagnostics
231
- * @property {LifecycleScope} scope
232
- * @property {UndoManager} undoManager
233
- */
230
+ * @property {Diagnostics} diagnostics
231
+ * @property {LifecycleScope} scope
232
+ * @property {UndoManager} undoManager
233
+ */
234
234
 
235
235
  /**
236
236
  * Wire all edit-mode managers (toolbar, undo, clipboard, drag, keyboard, etc.).
@@ -241,19 +241,19 @@ function wireEditMode(deps) {
241
241
  const {
242
242
  rootEl, blocksEl, clickArea, plugins, blocks, selection,
243
243
  i18n, events, commands, crossBlockSelection, defaultBlockType,
244
- inlinePluginRegistry, inlinePluginCtx, facade, snapshots, tuning, config, diagnostics,
245
- scope, undoManager,
246
- } = deps
247
-
248
- const blockOps = new BlockOperations(blocks, selection, defaultBlockType, events)
249
- blocks.setPluginStructuralCommands({
250
- splitBlock: () => blockOps.splitBlock(),
251
- exitEmptyBlock: () => blockOps.exitEmptyBlock(),
252
- })
253
- scope.register({
254
- destroy: () => blocks.setPluginStructuralCommands({ splitBlock: null, exitEmptyBlock: null }),
255
- })
256
- const pluginMutations = commands
244
+ inlinePluginRegistry, inlinePluginCtx, facade, snapshots, tuning, config, diagnostics,
245
+ scope, undoManager,
246
+ } = deps
247
+
248
+ const blockOps = new BlockOperations(blocks, selection, defaultBlockType, events)
249
+ blocks.setPluginStructuralCommands({
250
+ splitBlock: () => blockOps.splitBlock(),
251
+ exitEmptyBlock: () => blockOps.exitEmptyBlock(),
252
+ })
253
+ scope.register({
254
+ destroy: () => blocks.setPluginStructuralCommands({ splitBlock: null, exitEmptyBlock: null }),
255
+ })
256
+ const pluginMutations = commands
257
257
 
258
258
  const duplicateBlock = (current, index) => {
259
259
  const snapshot = snapshots.capture().blocks.find(block => block.id === current.id)
@@ -283,12 +283,12 @@ function wireEditMode(deps) {
283
283
  moveAnimationMs: tuning.animations.blockMoveMs,
284
284
  },
285
285
  })
286
- scope.register(toolbar)
287
-
288
- const unsubscribeInlineInsert = events.on(EditorEvent.INLINE_PLUGIN_INSERT, (/** @type {{ type: string }} */ payload) => {
289
- facade.insertInlinePlugin(payload.type)
290
- })
291
- scope.register({ destroy: unsubscribeInlineInsert })
286
+ scope.register(toolbar)
287
+
288
+ const unsubscribeInlineInsert = events.on(EditorEvent.INLINE_PLUGIN_INSERT, (/** @type {{ type: string }} */ payload) => {
289
+ facade.insertInlinePlugin(payload.type)
290
+ })
291
+ scope.register({ destroy: unsubscribeInlineInsert })
292
292
 
293
293
  const inlineTools = resolveInlineTools(config.inlineTools, i18n, crossBlockSelection)
294
294
 
@@ -309,7 +309,7 @@ function wireEditMode(deps) {
309
309
  crossBlockSelection,
310
310
  commands,
311
311
  )
312
- scope.register(inlineToolbar)
312
+ scope.register(inlineToolbar)
313
313
 
314
314
  const shortcuts = new ShortcutRegistry()
315
315
  shortcuts.register('Mod+Z', () => undoManager.undo(), { scope: 'editor' })
@@ -326,7 +326,7 @@ function wireEditMode(deps) {
326
326
  inlinePluginRegistry,
327
327
  inlinePluginCtx,
328
328
  })
329
- scope.register(slashCommands)
329
+ scope.register(slashCommands)
330
330
 
331
331
  shortcuts.register('Escape', () => {
332
332
  toolbar.closeToolbox()
@@ -357,14 +357,14 @@ function wireEditMode(deps) {
357
357
  const uiActivePredicate = () => inlineToolbar.hasActiveUI() || slashCommands.isOpen
358
358
 
359
359
  const keyboardManager = new KeyboardManager(rootEl, blockOps, shortcuts, blocks, events, defaultBlockType, uiActivePredicate)
360
- scope.register(keyboardManager)
360
+ scope.register(keyboardManager)
361
361
 
362
362
  if (inlinePluginRegistry.hasTriggers) {
363
- scope.register(new TriggerManager(rootEl, inlinePluginRegistry, inlinePluginCtx, events))
363
+ scope.register(new TriggerManager(rootEl, inlinePluginRegistry, inlinePluginCtx, events))
364
364
  }
365
365
 
366
366
  if (inlinePluginRegistry.size > 0) {
367
- scope.register(new InlinePatternMatcher(
367
+ scope.register(new InlinePatternMatcher(
368
368
  rootEl,
369
369
  inlinePluginRegistry,
370
370
  inlinePluginCtx,
@@ -377,11 +377,12 @@ function wireEditMode(deps) {
377
377
  const clipboard = new Clipboard(rootEl, {
378
378
  blocks, selection, plugins, defaultBlockType, crossBlockSelection, events, commands,
379
379
  blockOps, inlinePluginRegistry, inlinePluginCtx, diagnostics, uiActivePredicate,
380
+ pendingPasteLabel: i18n.t('clipboard.processingFile'),
380
381
  captureSnapshot: () => snapshots.capture(),
381
382
  })
382
- scope.register(clipboard)
383
- scope.register(new DragManager(rootEl, blocks, toolbar.dragHandle, events, tuning.drag))
384
- scope.register(new MouseSelectionManager(rootEl, { blocksEl, clickArea, blocks, selection, events, crossBlockSelection, defaultBlockType }))
383
+ scope.register(clipboard)
384
+ scope.register(new DragManager(rootEl, blocks, toolbar.dragHandle, events, tuning.drag))
385
+ scope.register(new MouseSelectionManager(rootEl, { blocksEl, clickArea, blocks, selection, events, crossBlockSelection, defaultBlockType }))
385
386
 
386
387
  // Re-emit block:focused so Toolbar positions itself
387
388
  // (initial setCurrentIndex fired before Toolbar was created)
@@ -396,13 +397,13 @@ function wireEditMode(deps) {
396
397
  * @param {import('./types').EditorConfig} config
397
398
  * @returns {I18n}
398
399
  */
399
- function initI18n(config) {
400
- const localeMessages = /** @type {Record<string, import('./types').LocaleValue>} */ (
401
- config.locale ?? en
402
- )
403
- const configuredLang = localeMessages.__lang
404
- const lang = typeof configuredLang === 'string' ? configuredLang : 'en'
405
- return new I18n(localeMessages, localeMessages === en ? undefined : en, lang)
400
+ function initI18n(config) {
401
+ const localeMessages = /** @type {Record<string, import('./types').LocaleValue>} */ (
402
+ config.locale ?? en
403
+ )
404
+ const configuredLang = localeMessages.__lang
405
+ const lang = typeof configuredLang === 'string' ? configuredLang : 'en'
406
+ return new I18n(localeMessages, localeMessages === en ? undefined : en, lang)
406
407
  }
407
408
 
408
409
  /**
@@ -427,8 +428,8 @@ function registerPlugins(pluginList, i18n, defaultBlockType, placeholder) {
427
428
  throw new Error(`Duplicate block plugin type: "${plugin.type}"`)
428
429
  }
429
430
  injectPluginI18n(plugin, i18n)
430
- if (placeholder !== undefined && plugin.type === defaultBlockType && typeof plugin.setPlaceholder === 'function') {
431
- plugin.setPlaceholder(placeholder)
431
+ if (placeholder !== undefined && plugin.type === defaultBlockType && typeof plugin.setPlaceholder === 'function') {
432
+ plugin.setPlaceholder(placeholder)
432
433
  }
433
434
  plugins.set(plugin.type, plugin)
434
435
  }
@@ -444,27 +445,27 @@ function registerPlugins(pluginList, i18n, defaultBlockType, placeholder) {
444
445
  * @param {import('./types').EditorConfig} config
445
446
  * @returns {import('./types').IEditor}
446
447
  */
447
- export function createEditor(config) {
448
+ export function createEditor(config) {
448
449
  if (!(config?.holder instanceof HTMLElement)) {
449
450
  throw new TypeError('createEditor() requires an HTMLElement holder')
450
451
  }
451
- if (!Array.isArray(config.plugins)) {
452
- throw new TypeError('createEditor() requires a plugins array')
453
- }
454
- if (config.readOnly !== undefined && typeof config.readOnly !== 'boolean') {
455
- throw new TypeError('createEditor() readOnly must be a boolean')
456
- }
457
- if (config.placeholder !== undefined && typeof config.placeholder !== 'string') {
458
- throw new TypeError('createEditor() placeholder must be a string')
459
- }
460
- if (
461
- config.minHeight !== undefined
462
- && (typeof config.minHeight !== 'number' || !Number.isFinite(config.minHeight) || config.minHeight < 0)
463
- ) {
464
- throw new RangeError('createEditor() minHeight must be a finite number greater than or equal to 0')
465
- }
466
-
467
- let readOnly = config.readOnly ?? false
452
+ if (!Array.isArray(config.plugins)) {
453
+ throw new TypeError('createEditor() requires a plugins array')
454
+ }
455
+ if (config.readOnly !== undefined && typeof config.readOnly !== 'boolean') {
456
+ throw new TypeError('createEditor() readOnly must be a boolean')
457
+ }
458
+ if (config.placeholder !== undefined && typeof config.placeholder !== 'string') {
459
+ throw new TypeError('createEditor() placeholder must be a string')
460
+ }
461
+ if (
462
+ config.minHeight !== undefined
463
+ && (typeof config.minHeight !== 'number' || !Number.isFinite(config.minHeight) || config.minHeight < 0)
464
+ ) {
465
+ throw new RangeError('createEditor() minHeight must be a finite number greater than or equal to 0')
466
+ }
467
+
468
+ let readOnly = config.readOnly ?? false
468
469
  const defaultBlockType = config.defaultBlock
469
470
  || (config.plugins?.some(plugin => plugin?.type === DEFAULT_BLOCK_TYPE)
470
471
  ? DEFAULT_BLOCK_TYPE
@@ -475,10 +476,10 @@ export function createEditor(config) {
475
476
  let rootEl
476
477
  let blocks
477
478
  let inlinePluginRegistry
478
- let facade
479
- let pluginOwnership
480
- const diagnostics = new Diagnostics(config.onDiagnostic, config.diagnosticThresholds)
481
- const holderOwnership = claimEditorHolder(config.holder)
479
+ let facade
480
+ let pluginOwnership
481
+ const diagnostics = new Diagnostics(config.onDiagnostic, config.diagnosticThresholds)
482
+ const holderOwnership = claimEditorHolder(config.holder)
482
483
 
483
484
  try {
484
485
  pluginOwnership = claimPluginInstances([
@@ -495,8 +496,8 @@ export function createEditor(config) {
495
496
  const plugins = registerPlugins(config.plugins, i18n, defaultBlockType, config.placeholder)
496
497
 
497
498
  const dom = buildEditorDOM(config.holder, theme, config.minHeight)
498
- rootEl = dom.rootEl
499
- applyReadOnlyAttributes(rootEl, readOnly)
499
+ rootEl = dom.rootEl
500
+ applyReadOnlyAttributes(rootEl, readOnly)
500
501
  const { blocksEl, clickArea } = dom
501
502
 
502
503
  blocks = new BlockManager(
@@ -528,13 +529,13 @@ export function createEditor(config) {
528
529
 
529
530
  const crossBlockSelection = new CrossBlockSelection()
530
531
 
531
- const inlinePluginCtx = new PopupManager(
532
- events,
533
- EditorEvent.CHANGED,
534
- blocks,
535
- commands,
536
- () => readOnly,
537
- )
532
+ const inlinePluginCtx = new PopupManager(
533
+ events,
534
+ EditorEvent.CHANGED,
535
+ blocks,
536
+ commands,
537
+ () => readOnly,
538
+ )
538
539
  inlinePluginCtx.setRoot(rootEl)
539
540
  inlinePluginRegistry.mount(rootEl, inlinePluginCtx)
540
541
 
@@ -551,12 +552,12 @@ export function createEditor(config) {
551
552
  diagnostics,
552
553
  initialDocument?.version ?? documentSchema.currentVersion,
553
554
  )
554
- const publicBlocks = new EditorBlocksApi(blocks, events)
555
+ const publicBlocks = new EditorBlocksApi(blocks, events)
555
556
  const publicEvents = new EditorEventSubscriptions(events)
556
- facade = new EditorFacade(rootEl, {
557
- blocks,
558
- selection,
559
- events,
557
+ facade = new EditorFacade(rootEl, {
558
+ blocks,
559
+ selection,
560
+ events,
560
561
  defaultBlockType,
561
562
  inlinePluginRegistry,
562
563
  inlinePluginCtx,
@@ -565,96 +566,96 @@ export function createEditor(config) {
565
566
  documentSchema,
566
567
  diagnostics,
567
568
  snapshots,
568
- publicBlocks,
569
- publicEvents,
570
- readOnly,
571
- })
572
- facade.registerDestroyable(holderOwnership)
573
- facade.registerDestroyable(pluginOwnership)
569
+ publicBlocks,
570
+ publicEvents,
571
+ readOnly,
572
+ })
573
+ facade.registerDestroyable(holderOwnership)
574
+ facade.registerDestroyable(pluginOwnership)
574
575
  facade.registerDestroyable(inlinePluginCtx)
575
576
  facade.registerDestroyable(inlinePluginRegistry)
576
577
  commands.configureRollback(
577
578
  () => snapshots.capture(),
578
579
  document => facade.render(document),
579
580
  )
580
- const changeNotifier = new ChangeNotifier(() => facade.save(), config.onChange, tuning.change.debounceMs)
581
- facade.registerDestroyable(changeNotifier)
582
- events.on(EditorEvent.CHANGED, () => changeNotifier.schedule())
583
-
584
- const undoManager = new UndoManager(
585
- blocks, events,
586
- () => snapshots.capture(),
587
- (data, caret) => facade.render(data, caret),
588
- () => selection.getCaret(),
589
- tuning.undo,
590
- )
591
- undoManager.setCommandsEnabled(!readOnly, { notify: false })
592
- facade.configureHistory(undoManager)
593
- facade.registerDestroyable(undoManager)
594
-
595
- /** @type {LifecycleScope | null} */
596
- let editModeScope = null
597
- const mountEditMode = () => {
598
- if (editModeScope) return
599
- const scope = new LifecycleScope()
600
- try {
601
- scope.register(wireInputTracking(rootEl, blocks, events))
602
- wireEditMode({
603
- rootEl, blocksEl, clickArea, plugins, blocks, selection,
604
- i18n, events, commands, crossBlockSelection, defaultBlockType,
605
- inlinePluginRegistry, inlinePluginCtx, facade, snapshots, tuning, config, diagnostics,
606
- scope, undoManager,
607
- })
608
- editModeScope = scope
609
- } catch (error) {
610
- scope.destroy()
611
- throw error
612
- }
613
- }
614
-
615
- const unmountEditMode = () => {
616
- editModeScope?.destroy()
617
- editModeScope = null
618
- crossBlockSelection.deactivate(rootEl)
619
- blocks.clearSelection()
620
- }
621
- facade.registerDestroyable({ destroy: unmountEditMode })
622
-
623
- facade.configureReadOnlyTransition(nextReadOnly => {
624
- const previousReadOnly = facade.readOnly
625
- // Cancel transient widget previews before capturing the canonical
626
- // document. Otherwise a preview could be serialized as a committed edit.
627
- inlinePluginCtx.hidePopup()
628
- undoManager.commit()
629
- const document = facade.save()
630
- unmountEditMode()
631
- readOnly = nextReadOnly
632
- blocks.setReadOnly(nextReadOnly)
633
- applyReadOnlyAttributes(rootEl, nextReadOnly)
634
-
635
- try {
636
- facade.render(document, undefined, { focus: false, notifyChange: false })
637
- if (!nextReadOnly) mountEditMode()
638
- undoManager.setCommandsEnabled(!nextReadOnly, { notify: false })
639
- } catch (transitionError) {
640
- unmountEditMode()
641
- readOnly = previousReadOnly
642
- blocks.setReadOnly(previousReadOnly)
643
- applyReadOnlyAttributes(rootEl, previousReadOnly)
644
- try {
645
- facade.render(document, undefined, { focus: false, notifyChange: false })
646
- if (!previousReadOnly) mountEditMode()
647
- } catch (rollbackError) {
648
- throw new AggregateError(
649
- [transitionError, rollbackError],
650
- 'Editor read-only transition and rollback failed',
651
- )
652
- }
653
- throw transitionError
654
- }
655
- })
656
-
657
- if (!readOnly) mountEditMode()
581
+ const changeNotifier = new ChangeNotifier(() => facade.save(), config.onChange, tuning.change.debounceMs)
582
+ facade.registerDestroyable(changeNotifier)
583
+ events.on(EditorEvent.CHANGED, () => changeNotifier.schedule())
584
+
585
+ const undoManager = new UndoManager(
586
+ blocks, events,
587
+ () => snapshots.capture(),
588
+ (data, caret) => facade.render(data, caret),
589
+ () => selection.getCaret(),
590
+ tuning.undo,
591
+ )
592
+ undoManager.setCommandsEnabled(!readOnly, { notify: false })
593
+ facade.configureHistory(undoManager)
594
+ facade.registerDestroyable(undoManager)
595
+
596
+ /** @type {LifecycleScope | null} */
597
+ let editModeScope = null
598
+ const mountEditMode = () => {
599
+ if (editModeScope) return
600
+ const scope = new LifecycleScope()
601
+ try {
602
+ scope.register(wireInputTracking(rootEl, blocks, events))
603
+ wireEditMode({
604
+ rootEl, blocksEl, clickArea, plugins, blocks, selection,
605
+ i18n, events, commands, crossBlockSelection, defaultBlockType,
606
+ inlinePluginRegistry, inlinePluginCtx, facade, snapshots, tuning, config, diagnostics,
607
+ scope, undoManager,
608
+ })
609
+ editModeScope = scope
610
+ } catch (error) {
611
+ scope.destroy()
612
+ throw error
613
+ }
614
+ }
615
+
616
+ const unmountEditMode = () => {
617
+ editModeScope?.destroy()
618
+ editModeScope = null
619
+ crossBlockSelection.deactivate(rootEl)
620
+ blocks.clearSelection()
621
+ }
622
+ facade.registerDestroyable({ destroy: unmountEditMode })
623
+
624
+ facade.configureReadOnlyTransition(nextReadOnly => {
625
+ const previousReadOnly = facade.readOnly
626
+ // Cancel transient widget previews before capturing the canonical
627
+ // document. Otherwise a preview could be serialized as a committed edit.
628
+ inlinePluginCtx.hidePopup()
629
+ undoManager.commit()
630
+ const document = facade.save()
631
+ unmountEditMode()
632
+ readOnly = nextReadOnly
633
+ blocks.setReadOnly(nextReadOnly)
634
+ applyReadOnlyAttributes(rootEl, nextReadOnly)
635
+
636
+ try {
637
+ facade.render(document, undefined, { focus: false, notifyChange: false })
638
+ if (!nextReadOnly) mountEditMode()
639
+ undoManager.setCommandsEnabled(!nextReadOnly, { notify: false })
640
+ } catch (transitionError) {
641
+ unmountEditMode()
642
+ readOnly = previousReadOnly
643
+ blocks.setReadOnly(previousReadOnly)
644
+ applyReadOnlyAttributes(rootEl, previousReadOnly)
645
+ try {
646
+ facade.render(document, undefined, { focus: false, notifyChange: false })
647
+ if (!previousReadOnly) mountEditMode()
648
+ } catch (rollbackError) {
649
+ throw new AggregateError(
650
+ [transitionError, rollbackError],
651
+ 'Editor read-only transition and rollback failed',
652
+ )
653
+ }
654
+ throw transitionError
655
+ }
656
+ })
657
+
658
+ if (!readOnly) mountEditMode()
658
659
 
659
660
  const styleCleanup = injectPluginStyles(plugins)
660
661
  if (styleCleanup) facade.registerDestroyable(styleCleanup)
@@ -677,12 +678,12 @@ export function createEditor(config) {
677
678
  diagnostics.emit('editor.create.failed', { errorName: diagnostics.errorName(error) })
678
679
  if (facade) {
679
680
  facade.destroy()
680
- } else {
681
- blocks?.clear()
682
- inlinePluginRegistry?.destroy()
683
- pluginOwnership?.destroy()
684
- holderOwnership.destroy()
685
- rootEl?.remove()
681
+ } else {
682
+ blocks?.clear()
683
+ inlinePluginRegistry?.destroy()
684
+ pluginOwnership?.destroy()
685
+ holderOwnership.destroy()
686
+ rootEl?.remove()
686
687
  }
687
688
  throw error
688
689
  }
@@ -699,5 +700,5 @@ export { createColorSwatchPlugin } from '../inline-plugins/color.js'
699
700
  export { createMentionPlugin } from '../inline-plugins/mention/index.js'
700
701
 
701
702
  // Block plugins are NOT re-exported here — import them directly from their
702
- // own entry points to keep bundles tree-shakeable. See demo.html for the
703
- // canonical import shape.
703
+ // own entry points to keep bundles tree-shakeable. See index.html for the
704
+ // canonical import shape.
@@ -30,6 +30,7 @@ declare const _default: {
30
30
  'block.convertTo': string;
31
31
  'block.back': string;
32
32
  'block.unsupported': string;
33
+ 'clipboard.processingFile': string;
33
34
  'slash.noResults': string;
34
35
  };
35
36
  export default _default;
@@ -33,5 +33,6 @@ export default {
33
33
  'block.back': 'Back',
34
34
  'block.unsupported': 'Unsupported block type: {type}',
35
35
 
36
+ 'clipboard.processingFile': 'Processing file',
36
37
  'slash.noResults': 'No results',
37
38
  }
@@ -30,6 +30,7 @@ declare const _default: {
30
30
  'block.convertTo': string;
31
31
  'block.back': string;
32
32
  'block.unsupported': string;
33
+ 'clipboard.processingFile': string;
33
34
  'slash.noResults': string;
34
35
  };
35
36
  export default _default;
@@ -33,5 +33,6 @@ export default {
33
33
  'block.back': 'Назад',
34
34
  'block.unsupported': 'Неподдерживаемый тип блока: {type}',
35
35
 
36
+ 'clipboard.processingFile': 'Обработка файла',
36
37
  'slash.noResults': 'Ничего не найдено',
37
38
  }
@@ -7,7 +7,7 @@
7
7
  --oe-border-hover: #d4d4d4;
8
8
  --oe-text-1: #1a1a1a;
9
9
  --oe-text-2: #525252;
10
- --oe-text-3: #a3a3a3;
10
+ --oe-text-3: #737373;
11
11
  --oe-accent: #4357b4;
12
12
  --oe-accent-alpha: rgba(67, 87, 180, 0.1);
13
13
  --oe-accent-text: #4357b4;