-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
FormatSelect.ts
97 lines (84 loc) · 3.09 KB
/
FormatSelect.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
import { AlloyTriggers, AlloyComponent } from '@ephox/alloy';
import { Element } from '@ephox/dom-globals';
import { Fun, Option } from '@ephox/katamari';
import Editor from 'tinymce/core/api/Editor';
import { updateMenuText } from '../../dropdown/CommonDropdown';
import { onActionToggleFormat } from './utils/Utils';
import { createMenuItems, createSelectButton, SelectSpec } from './BespokeSelect';
import { buildBasicSettingsDataset, Delimiter } from './SelectDatasets';
import { findNearest, getCurrentSelectionParents } from './utils/FormatDetection';
const defaultBlocks = (
'Paragraph=p;' +
'Heading 1=h1;' +
'Heading 2=h2;' +
'Heading 3=h3;' +
'Heading 4=h4;' +
'Heading 5=h5;' +
'Heading 6=h6;' +
'Preformatted=pre'
);
const getSpec = (editor): SelectSpec & { dataset } => {
const getMatchingValue = (nodeChangeEvent) => {
return findNearest(editor, () => dataset.data, nodeChangeEvent);
};
const isSelectedFor = (format) => {
return () => {
return editor.formatter.match(format);
};
};
const getPreviewFor = (format) => () => {
const fmt = editor.formatter.get(format);
return Option.some({
tag: fmt.length > 0 ? fmt[0].inline || fmt[0].block || 'div' : 'div',
styleAttr: editor.formatter.getCssText(format)
});
};
const updateSelectMenuText = (parents: Element[], comp: AlloyComponent) => {
const detectedFormat = getMatchingValue(parents);
const text = detectedFormat.fold(() => 'Paragraph', (fmt) => fmt.title);
AlloyTriggers.emitWith(comp, updateMenuText, {
text
});
};
const nodeChangeHandler = Option.some((comp: AlloyComponent) => {
return (e) => updateSelectMenuText(e.parents, comp);
});
const setInitialValue = Option.some((comp: AlloyComponent) => {
const parents = getCurrentSelectionParents(editor);
updateSelectMenuText(parents, comp);
});
const dataset = buildBasicSettingsDataset(editor, 'block_formats', defaultBlocks, Delimiter.SemiColon);
return {
tooltip: 'Blocks',
icon: Option.none(),
isSelectedFor,
getCurrentValue: Fun.constant(Option.none()),
getPreviewFor,
onAction: onActionToggleFormat(editor),
setInitialValue,
nodeChangeHandler,
dataset,
shouldHide: false,
isInvalid: (item) => !editor.formatter.canApply(item.format)
};
};
const createFormatSelect = (editor: Editor, backstage) => {
const spec = getSpec(editor);
return createSelectButton(editor, backstage, spec.dataset, spec);
};
// FIX: Test this!
const formatSelectMenu = (editor: Editor, backstage) => {
const spec = getSpec(editor);
const menuItems = createMenuItems(editor, backstage, spec.dataset, spec);
editor.ui.registry.addNestedMenuItem('blockformats', {
text: 'Blocks',
getSubmenuItems: () => menuItems.items.validateItems(menuItems.getStyleItems())
});
};
export { createFormatSelect, formatSelectMenu };