@modusoperandi/licit 1.4.3 → 1.4.7
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/BlockquoteInsertNewLineCommand.js.flow +70 -70
- package/BlockquoteNodeSpec.js.flow +29 -29
- package/BlockquoteToggleCommand.js.flow +56 -56
- package/BookmarkNodeSpec.js.flow +39 -39
- package/BulletListNodeSpec.js.flow +61 -61
- package/CZIProseMirror.js.flow +90 -90
- package/CodeBlockCommand.js.flow +65 -65
- package/CodeBlockNodeSpec.js.flow +24 -24
- package/CodeMarkSpec.js.flow +14 -14
- package/ContentPlaceholderPlugin.js.flow +183 -183
- package/CursorPlaceholderPlugin.js.flow +113 -113
- package/DocLayoutCommand.js.flow +97 -97
- package/DocNodeSpec.js.flow +62 -62
- package/EMMarkSpec.js.flow +39 -39
- package/EditorCommands.js.flow +124 -124
- package/EditorKeyMap.js.flow +173 -173
- package/EditorMarks.js +4 -2
- package/EditorMarks.js.flow +77 -74
- package/EditorNodes.js.flow +55 -55
- package/EditorPageLayoutPlugin.js.flow +67 -67
- package/EditorPlugins.js.flow +8 -8
- package/EditorSchema.js.flow +12 -12
- package/EditorState.js.flow +7 -7
- package/FontSizeMarkSpec.js.flow +54 -54
- package/FontTypeMarkSpec.js.flow +89 -89
- package/HTMLMutator.js.flow +58 -58
- package/HangingIndentMarkSpec.js +34 -0
- package/HangingIndentMarkSpec.js.flow +30 -0
- package/HardBreakNodeSpec.js.flow +15 -15
- package/HeadingNodeSpec.js.flow +42 -42
- package/HistoryRedoCommand.js.flow +41 -41
- package/HistoryUndoCommand.js.flow +41 -41
- package/HorizontalRuleCommand.js.flow +71 -71
- package/HorizontalRuleNodeSpec.js.flow +39 -39
- package/ImageUploadPlaceholderPlugin.js.flow +187 -187
- package/LICENSE +22 -22
- package/LinkMarkSpec.js +13 -3
- package/LinkMarkSpec.js.flow +41 -37
- package/LinkSetURLCommand.js.flow +129 -129
- package/LinkTooltipPlugin.js +34 -37
- package/LinkTooltipPlugin.js.flow +207 -217
- package/ListItemInsertNewLineCommand.js.flow +76 -76
- package/ListItemMergeCommand.js.flow +197 -197
- package/ListItemNodeSpec.js.flow +52 -52
- package/ListSplitCommand.js.flow +54 -54
- package/ListToggleCommand.js.flow +99 -99
- package/MarkNames.js +2 -1
- package/MarkNames.js.flow +20 -19
- package/MarksClearCommand.js.flow +66 -66
- package/NodeNames.js.flow +23 -23
- package/OrderedListNodeSpec.js.flow +131 -131
- package/OverrideMarkSpec.js.flow +49 -49
- package/ParagraphNodeSpec.js +21 -2
- package/ParagraphNodeSpec.js.flow +233 -215
- package/ParagraphSpacingCommand.js.flow +139 -139
- package/PrintCommand.js.flow +53 -53
- package/SelectionPlaceholderPlugin.js.flow +129 -129
- package/SpacerMarkSpec.js.flow +47 -47
- package/StrikeMarkSpec.js.flow +24 -24
- package/StrongMarkSpec.js.flow +39 -39
- package/StyleView.js.flow +18 -18
- package/TableBackgroundColorCommand.js.flow +79 -79
- package/TableBorderColorCommand.js +5 -3
- package/TableBorderColorCommand.js.flow +108 -106
- package/TableCellColorCommand.js.flow +73 -73
- package/TableCellMenuPlugin.js.flow +129 -129
- package/TableInsertCommand.js.flow +117 -117
- package/TableMergeCellsCommand.js.flow +113 -113
- package/TableNodesSpecs.js.flow +144 -144
- package/TablePlugins.js.flow +14 -14
- package/TableResizePlugin.js.flow +636 -636
- package/TextColorMarkSpec.js.flow +40 -40
- package/TextHighlightMarkSpec.js.flow +47 -47
- package/TextInsertTabSpaceCommand.js +0 -3
- package/TextInsertTabSpaceCommand.js.flow +103 -106
- package/TextNoWrapMarkSpec.js.flow +14 -14
- package/TextNodeSpec.js.flow +7 -7
- package/TextSelectionMarkSpec.js.flow +24 -24
- package/TextSubMarkSpec.js.flow +28 -28
- package/TextSuperMarkSpec.js.flow +28 -28
- package/TextUnderlineMarkSpec.js.flow +24 -24
- package/Types.js.flow +77 -77
- package/WebFontLoader.js.flow +22 -22
- package/blockQuoteInputRule.js.flow +36 -36
- package/bom.xml +9555 -9683
- package/browser.js.flow +7 -7
- package/buildEditorPlugins.js.flow +48 -48
- package/buildInputRules.js.flow +85 -85
- package/client/CollabConnector.js.flow +90 -90
- package/client/EditorConnection.js.flow +324 -324
- package/client/Licit.js +39 -39
- package/client/Licit.js.flow +649 -649
- package/client/Licit.test.js.flow +104 -104
- package/client/Reporter.js.flow +35 -35
- package/client/SimpleConnector.js.flow +61 -61
- package/client/http.js.flow +60 -60
- package/client/licit.css +12 -12
- package/client/throttle.js.flow +27 -27
- package/convertFromDOMElement.js.flow +33 -33
- package/convertFromHTML.js.flow +15 -15
- package/convertFromJSON.js.flow +53 -53
- package/convertToCSSPTValue.js.flow +19 -19
- package/convertToJSON.js.flow +7 -7
- package/createCommand.js.flow +62 -62
- package/createEditorKeyMap.js.flow +87 -87
- package/createEmptyEditorState.js.flow +29 -29
- package/createTableResizingPlugin.js.flow +86 -86
- package/findActionableCell.js.flow +74 -74
- package/findActiveMark.js.flow +32 -32
- package/hyphenize.js.flow +17 -17
- package/index.d.ts +167 -167
- package/index.js.flow +10 -10
- package/insertTable.js.flow +54 -54
- package/isEditorStateEmpty.js.flow +32 -32
- package/isTableNode.js.flow +15 -15
- package/joinDown.js.flow +25 -25
- package/joinListNode.js.flow +55 -55
- package/joinUp.js.flow +37 -37
- package/keymaps.js.flow +175 -175
- package/lookUpElement.js.flow +14 -14
- package/nodeAt.js.flow +12 -12
- package/normalizeHTML.js.flow +80 -80
- package/package.json +152 -152
- package/patchAnchorElements.js.flow +38 -38
- package/patchBreakElements.js.flow +22 -22
- package/patchElementInlineStyles.js.flow +92 -92
- package/patchListElements.js.flow +275 -275
- package/patchMathElements.js.flow +58 -58
- package/patchParagraphElements.js.flow +20 -20
- package/patchStyleElements.js.flow +197 -197
- package/patchTableElements.js.flow +88 -88
- package/rebaseDocWithSteps.js.flow +42 -42
- package/sanitizeURL.js.flow +13 -13
- package/splitListItem.js.flow +191 -191
- package/styles.css +46 -46
- package/toClosestFontPtSize.js.flow +22 -22
- package/toSafeHTMLDocument.js.flow +9 -9
- package/toggleBlockquote.js.flow +101 -101
- package/toggleCodeBlock.js.flow +102 -102
- package/ui/AlertInfo.js.flow +63 -63
- package/ui/BookmarkNodeView.js.flow +64 -64
- package/ui/CommandButton.js.flow +68 -68
- package/ui/CommandMenu.js.flow +74 -74
- package/ui/CommandMenuButton.js.flow +128 -128
- package/ui/CustomEditorView.js.flow +29 -29
- package/ui/CustomMenu.js.flow +14 -14
- package/ui/CustomMenuItem.js.flow +35 -35
- package/ui/CustomNodeView.js.flow +207 -207
- package/ui/CustomRadioButton.js.flow +63 -63
- package/ui/DocLayoutEditor.js.flow +130 -130
- package/ui/Editor.js.flow +281 -281
- package/ui/EditorFrameset.js.flow +79 -79
- package/ui/EditorToolbar.js.flow +197 -197
- package/ui/EditorToolbarConfig.js.flow +162 -162
- package/ui/FontSizeCommandMenuButton.js.flow +66 -66
- package/ui/FontTypeCommandMenuButton.js.flow +60 -60
- package/ui/Frag.js.flow +11 -11
- package/ui/Icon.js.flow +82 -82
- package/ui/ImageInlineEditor.js.flow +66 -66
- package/ui/KeyCodes.js.flow +12 -12
- package/ui/LinkTooltip.js.flow +51 -51
- package/ui/LinkURLEditor.js.flow +227 -227
- package/ui/ListItemNodeView.js.flow +101 -101
- package/ui/ListTypeButton.js.flow +121 -121
- package/ui/ListTypeCommandButton.js.flow +85 -85
- package/ui/ListTypeMenu.js.flow +78 -78
- package/ui/LoadingIndicator.js.flow +19 -19
- package/ui/PasteMenu.js.flow +52 -52
- package/ui/ResizeObserver.js.flow +105 -105
- package/ui/RichTextEditor.js.flow +133 -133
- package/ui/SelectionObserver.js.flow +134 -134
- package/ui/TableCellMenu.js.flow +49 -49
- package/ui/TableGridSizeEditor.js.flow +185 -185
- package/ui/TableNodeView.js.flow +36 -36
- package/ui/bindScrollHandler.js.flow +46 -46
- package/ui/canUseCSSFont.js.flow +42 -42
- package/ui/czi-body-layout-editor.css +16 -16
- package/ui/czi-bookmark-view.css +10 -10
- package/ui/czi-cursor-placeholder.css +36 -36
- package/ui/czi-custom-menu-button.css +18 -18
- package/ui/czi-custom-menu-item.css +30 -30
- package/ui/czi-custom-menu.css +8 -8
- package/ui/czi-custom-radio-button.css +80 -80
- package/ui/czi-custom-scrollbar.css +21 -21
- package/ui/czi-editor-frameset.css +81 -81
- package/ui/czi-editor-toolbar.css +122 -122
- package/ui/czi-editor.css +239 -216
- package/ui/czi-form.css +201 -201
- package/ui/czi-frag.css +3 -3
- package/ui/czi-heading.css +40 -40
- package/ui/czi-icon.css +72 -72
- package/ui/czi-image-resize-box.css +165 -165
- package/ui/czi-image-upload-editor.css +57 -57
- package/ui/czi-image-upload-placeholder.css +50 -50
- package/ui/czi-image-url-editor.css +38 -38
- package/ui/czi-image-view.css +121 -121
- package/ui/czi-indent.css +137 -137
- package/ui/czi-inline-editor.css +20 -20
- package/ui/czi-link-tooltip.css +112 -112
- package/ui/czi-list.css +406 -406
- package/ui/czi-loading-indicator.css +66 -66
- package/ui/czi-math-view.css +62 -62
- package/ui/czi-selection-placeholder.css +24 -24
- package/ui/czi-table-cell-menu.css +16 -16
- package/ui/czi-table-grid-size-editor.css +37 -37
- package/ui/czi-table.css +89 -89
- package/ui/czi-vars.css +47 -45
- package/ui/findActiveFontSize.js.flow +55 -55
- package/ui/findActiveFontType.js.flow +35 -35
- package/ui/fonts.css +460 -460
- package/ui/handleEditorDrop.js.flow +28 -28
- package/ui/handleEditorKeyDown.js.flow +39 -39
- package/ui/handleEditorPaste.js.flow +33 -33
- package/ui/htmlElementToRect.js.flow +18 -18
- package/ui/icon-font.css +9 -9
- package/ui/injectStyleSheet.js.flow +40 -40
- package/ui/isElementFullyVisible.js.flow +14 -14
- package/ui/isOffline.js.flow +8 -8
- package/ui/isReactClass.js.flow +12 -12
- package/ui/listType.css +21 -21
- package/ui/resolveImage.js.flow +121 -121
- package/ui/toCSSColor.js.flow +51 -51
- package/ui/toCSSLineSpacing.js.flow +53 -53
- package/ui/toHexColor.js.flow +26 -26
- package/ui/uuid.js.flow +9 -9
- package/uuid.js.flow +9 -9
package/ui/LinkURLEditor.js.flow
CHANGED
|
@@ -1,227 +1,227 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
|
|
6
|
-
import sanitizeURL from '../sanitizeURL.js';
|
|
7
|
-
import {
|
|
8
|
-
CustomButton,
|
|
9
|
-
preventEventDefault,
|
|
10
|
-
} from '@modusoperandi/licit-ui-commands';
|
|
11
|
-
import { ENTER } from './KeyCodes.js';
|
|
12
|
-
import { INNER_LINK } from '../Types.js';
|
|
13
|
-
import { Tooltip as ReactTooltip } from 'react-tooltip';
|
|
14
|
-
|
|
15
|
-
const BAD_CHARACTER_PATTER = /\s/;
|
|
16
|
-
|
|
17
|
-
class LinkURLEditor extends React.PureComponent<any, any> {
|
|
18
|
-
static propTypes = {
|
|
19
|
-
href: PropTypes.string,
|
|
20
|
-
close: PropTypes.func.isRequired,
|
|
21
|
-
selectedTab: this.state?.selectedTab,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
state = {
|
|
25
|
-
url: this.props.href_,
|
|
26
|
-
TOCselectedNode_: this.props.TOCselectedNode_,
|
|
27
|
-
selectionId: this.props.selectionId_,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
componentDidMount() {
|
|
31
|
-
const { selectionId } = this.state;
|
|
32
|
-
const defaultTab = selectionId ? 'innerlink' : 'webpage';
|
|
33
|
-
|
|
34
|
-
const selectedTab = this.props.selectedTab || defaultTab;
|
|
35
|
-
this.openForm(selectedTab);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
openForm = (formName) => {
|
|
39
|
-
let i;
|
|
40
|
-
const tabcontent = document.getElementsByClassName('tabcontent');
|
|
41
|
-
for (i = 0; i < tabcontent.length; i++) {
|
|
42
|
-
tabcontent[i].style.display = 'none';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const tablinks = document.getElementsByClassName('tablinks');
|
|
46
|
-
for (i = 0; i < tablinks.length; i++) {
|
|
47
|
-
tablinks[i].classList.remove('active');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const selectedTab = document.getElementById(formName);
|
|
51
|
-
if (selectedTab) {
|
|
52
|
-
selectedTab.style.display = 'block';
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const clickedButton = document.querySelector(
|
|
56
|
-
`.tablinks[data-form="${formName}"]`
|
|
57
|
-
);
|
|
58
|
-
if (clickedButton) {
|
|
59
|
-
clickedButton.classList.add('active');
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
render(): React.Element<any> {
|
|
64
|
-
const { url, TOCselectedNode_, selectionId } = this.state;
|
|
65
|
-
|
|
66
|
-
const isTOCValid = () => {
|
|
67
|
-
if (!TOCselectedNode_ || TOCselectedNode_.length === 0) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return TOCselectedNode_.some(
|
|
72
|
-
(item) => item?.content[0]?.text?.trim() !== ''
|
|
73
|
-
);
|
|
74
|
-
};
|
|
75
|
-
const isValid = isTOCValid();
|
|
76
|
-
const error = url ? BAD_CHARACTER_PATTER.test(url) : false;
|
|
77
|
-
|
|
78
|
-
let label = 'Apply';
|
|
79
|
-
let disabled;
|
|
80
|
-
if (this.props.href) {
|
|
81
|
-
label = url ? 'Apply' : 'Remove';
|
|
82
|
-
disabled = error;
|
|
83
|
-
} else {
|
|
84
|
-
disabled = error || !url;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<div className="czi-image-url-editor">
|
|
89
|
-
<div className="czi-form" style={{ padding: '10px', display: 'flex' }}>
|
|
90
|
-
<div className="tab">
|
|
91
|
-
<button
|
|
92
|
-
className="tablinks"
|
|
93
|
-
data-form="webpage"
|
|
94
|
-
onClick={() => this.openForm('webpage')}
|
|
95
|
-
>
|
|
96
|
-
Existing Web Page
|
|
97
|
-
</button>
|
|
98
|
-
<button
|
|
99
|
-
className="tablinks"
|
|
100
|
-
data-form="innerlink"
|
|
101
|
-
onClick={() => this.openForm('innerlink')}
|
|
102
|
-
>
|
|
103
|
-
Place in this Document
|
|
104
|
-
</button>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<div className="tabcontent" id="webpage">
|
|
108
|
-
<form onSubmit={preventEventDefault}>
|
|
109
|
-
<fieldset>
|
|
110
|
-
<label>Add a Link : </label>
|
|
111
|
-
<input
|
|
112
|
-
autoFocus={true}
|
|
113
|
-
onChange={this._onURLChange}
|
|
114
|
-
onKeyDown={this._onKeyDown}
|
|
115
|
-
placeholder="Paste a URL"
|
|
116
|
-
spellCheck={false}
|
|
117
|
-
type="text"
|
|
118
|
-
value={selectionId ? null : url}
|
|
119
|
-
/>
|
|
120
|
-
</fieldset>
|
|
121
|
-
<div className="czi-form-buttons">
|
|
122
|
-
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
123
|
-
<CustomButton
|
|
124
|
-
active={true}
|
|
125
|
-
disabled={disabled}
|
|
126
|
-
label={label}
|
|
127
|
-
onClick={() => {
|
|
128
|
-
this._apply();
|
|
129
|
-
}}
|
|
130
|
-
/>
|
|
131
|
-
</div>
|
|
132
|
-
</form>
|
|
133
|
-
</div>
|
|
134
|
-
{!isValid ? (
|
|
135
|
-
<div className="tabcontent" id="innerlink">
|
|
136
|
-
<p>No TOC/TOT/TOF styles</p>
|
|
137
|
-
<div className="czi-form-buttons">
|
|
138
|
-
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
) : (
|
|
142
|
-
<div className="tabcontent" id="innerlink">
|
|
143
|
-
<form action="#">
|
|
144
|
-
<label>Select the Inner Link</label>
|
|
145
|
-
<br></br>
|
|
146
|
-
<select
|
|
147
|
-
defaultValue={
|
|
148
|
-
TOCselectedNode_.some(
|
|
149
|
-
(res) => res?.content[0]?.text === url
|
|
150
|
-
)
|
|
151
|
-
? url
|
|
152
|
-
: null
|
|
153
|
-
}
|
|
154
|
-
id="toc"
|
|
155
|
-
name="toccontents"
|
|
156
|
-
size="3"
|
|
157
|
-
>
|
|
158
|
-
{TOCselectedNode_?.filter(
|
|
159
|
-
(res) => res?.content[0]?.text?.trim() !== ''
|
|
160
|
-
).map((res, index) => (
|
|
161
|
-
<option
|
|
162
|
-
data-tooltip-content={res?.content[0]?.text}
|
|
163
|
-
data-tooltip-id="select-toc-tooltip"
|
|
164
|
-
key={index}
|
|
165
|
-
onClick={() => {
|
|
166
|
-
this.handleOptionChange(
|
|
167
|
-
res?.content[0]?.text,
|
|
168
|
-
res?.attrs.selectionId
|
|
169
|
-
);
|
|
170
|
-
}}
|
|
171
|
-
value={res?.content[0]?.text}
|
|
172
|
-
>
|
|
173
|
-
{res?.content[0]?.text}
|
|
174
|
-
</option>
|
|
175
|
-
))}
|
|
176
|
-
</select>
|
|
177
|
-
<ReactTooltip
|
|
178
|
-
effect="solid"
|
|
179
|
-
id="select-toc-tooltip"
|
|
180
|
-
place="bottom"
|
|
181
|
-
/>
|
|
182
|
-
<br></br>
|
|
183
|
-
<div className="czi-form-buttons">
|
|
184
|
-
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
185
|
-
</div>
|
|
186
|
-
</form>
|
|
187
|
-
</div>
|
|
188
|
-
)}
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
handleOptionChange = (textContent_, selectionId) => {
|
|
195
|
-
const texthash = '';
|
|
196
|
-
const nodeconcat_UUID = texthash.concat(selectionId);
|
|
197
|
-
const textContent = nodeconcat_UUID.concat(INNER_LINK, textContent_);
|
|
198
|
-
this.props.close(textContent);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
_onKeyDown = (e: any) => {
|
|
202
|
-
if (e.keyCode === ENTER) {
|
|
203
|
-
e.preventDefault();
|
|
204
|
-
this._apply();
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
_onURLChange = (e: SyntheticInputEvent<>) => {
|
|
209
|
-
const url = e.target.value;
|
|
210
|
-
this.setState({
|
|
211
|
-
url,
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
_cancel = (): void => {
|
|
216
|
-
this.props.close();
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
_apply = (): void => {
|
|
220
|
-
const { url } = this.state;
|
|
221
|
-
if (url && !BAD_CHARACTER_PATTER.test(url)) {
|
|
222
|
-
this.props.close(sanitizeURL(url));
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export default LinkURLEditor;
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
|
|
6
|
+
import sanitizeURL from '../sanitizeURL.js';
|
|
7
|
+
import {
|
|
8
|
+
CustomButton,
|
|
9
|
+
preventEventDefault,
|
|
10
|
+
} from '@modusoperandi/licit-ui-commands';
|
|
11
|
+
import { ENTER } from './KeyCodes.js';
|
|
12
|
+
import { INNER_LINK } from '../Types.js';
|
|
13
|
+
import { Tooltip as ReactTooltip } from 'react-tooltip';
|
|
14
|
+
|
|
15
|
+
const BAD_CHARACTER_PATTER = /\s/;
|
|
16
|
+
|
|
17
|
+
class LinkURLEditor extends React.PureComponent<any, any> {
|
|
18
|
+
static propTypes = {
|
|
19
|
+
href: PropTypes.string,
|
|
20
|
+
close: PropTypes.func.isRequired,
|
|
21
|
+
selectedTab: this.state?.selectedTab,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
state = {
|
|
25
|
+
url: this.props.href_,
|
|
26
|
+
TOCselectedNode_: this.props.TOCselectedNode_,
|
|
27
|
+
selectionId: this.props.selectionId_,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
componentDidMount() {
|
|
31
|
+
const { selectionId } = this.state;
|
|
32
|
+
const defaultTab = selectionId ? 'innerlink' : 'webpage';
|
|
33
|
+
|
|
34
|
+
const selectedTab = this.props.selectedTab || defaultTab;
|
|
35
|
+
this.openForm(selectedTab);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
openForm = (formName) => {
|
|
39
|
+
let i;
|
|
40
|
+
const tabcontent = document.getElementsByClassName('tabcontent');
|
|
41
|
+
for (i = 0; i < tabcontent.length; i++) {
|
|
42
|
+
tabcontent[i].style.display = 'none';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const tablinks = document.getElementsByClassName('tablinks');
|
|
46
|
+
for (i = 0; i < tablinks.length; i++) {
|
|
47
|
+
tablinks[i].classList.remove('active');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const selectedTab = document.getElementById(formName);
|
|
51
|
+
if (selectedTab) {
|
|
52
|
+
selectedTab.style.display = 'block';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const clickedButton = document.querySelector(
|
|
56
|
+
`.tablinks[data-form="${formName}"]`
|
|
57
|
+
);
|
|
58
|
+
if (clickedButton) {
|
|
59
|
+
clickedButton.classList.add('active');
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
render(): React.Element<any> {
|
|
64
|
+
const { url, TOCselectedNode_, selectionId } = this.state;
|
|
65
|
+
|
|
66
|
+
const isTOCValid = () => {
|
|
67
|
+
if (!TOCselectedNode_ || TOCselectedNode_.length === 0) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return TOCselectedNode_.some(
|
|
72
|
+
(item) => item?.content[0]?.text?.trim() !== ''
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
const isValid = isTOCValid();
|
|
76
|
+
const error = url ? BAD_CHARACTER_PATTER.test(url) : false;
|
|
77
|
+
|
|
78
|
+
let label = 'Apply';
|
|
79
|
+
let disabled;
|
|
80
|
+
if (this.props.href) {
|
|
81
|
+
label = url ? 'Apply' : 'Remove';
|
|
82
|
+
disabled = error;
|
|
83
|
+
} else {
|
|
84
|
+
disabled = error || !url;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div className="czi-image-url-editor">
|
|
89
|
+
<div className="czi-form" style={{ padding: '10px', display: 'flex' }}>
|
|
90
|
+
<div className="tab">
|
|
91
|
+
<button
|
|
92
|
+
className="tablinks"
|
|
93
|
+
data-form="webpage"
|
|
94
|
+
onClick={() => this.openForm('webpage')}
|
|
95
|
+
>
|
|
96
|
+
Existing Web Page
|
|
97
|
+
</button>
|
|
98
|
+
<button
|
|
99
|
+
className="tablinks"
|
|
100
|
+
data-form="innerlink"
|
|
101
|
+
onClick={() => this.openForm('innerlink')}
|
|
102
|
+
>
|
|
103
|
+
Place in this Document
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div className="tabcontent" id="webpage">
|
|
108
|
+
<form onSubmit={preventEventDefault}>
|
|
109
|
+
<fieldset>
|
|
110
|
+
<label>Add a Link : </label>
|
|
111
|
+
<input
|
|
112
|
+
autoFocus={true}
|
|
113
|
+
onChange={this._onURLChange}
|
|
114
|
+
onKeyDown={this._onKeyDown}
|
|
115
|
+
placeholder="Paste a URL"
|
|
116
|
+
spellCheck={false}
|
|
117
|
+
type="text"
|
|
118
|
+
value={selectionId ? null : url}
|
|
119
|
+
/>
|
|
120
|
+
</fieldset>
|
|
121
|
+
<div className="czi-form-buttons">
|
|
122
|
+
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
123
|
+
<CustomButton
|
|
124
|
+
active={true}
|
|
125
|
+
disabled={disabled}
|
|
126
|
+
label={label}
|
|
127
|
+
onClick={() => {
|
|
128
|
+
this._apply();
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
</div>
|
|
132
|
+
</form>
|
|
133
|
+
</div>
|
|
134
|
+
{!isValid ? (
|
|
135
|
+
<div className="tabcontent" id="innerlink">
|
|
136
|
+
<p>No TOC/TOT/TOF styles</p>
|
|
137
|
+
<div className="czi-form-buttons">
|
|
138
|
+
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
) : (
|
|
142
|
+
<div className="tabcontent" id="innerlink">
|
|
143
|
+
<form action="#">
|
|
144
|
+
<label>Select the Inner Link</label>
|
|
145
|
+
<br></br>
|
|
146
|
+
<select
|
|
147
|
+
defaultValue={
|
|
148
|
+
TOCselectedNode_.some(
|
|
149
|
+
(res) => res?.content[0]?.text === url
|
|
150
|
+
)
|
|
151
|
+
? url
|
|
152
|
+
: null
|
|
153
|
+
}
|
|
154
|
+
id="toc"
|
|
155
|
+
name="toccontents"
|
|
156
|
+
size="3"
|
|
157
|
+
>
|
|
158
|
+
{TOCselectedNode_?.filter(
|
|
159
|
+
(res) => res?.content[0]?.text?.trim() !== ''
|
|
160
|
+
).map((res, index) => (
|
|
161
|
+
<option
|
|
162
|
+
data-tooltip-content={res?.content[0]?.text}
|
|
163
|
+
data-tooltip-id="select-toc-tooltip"
|
|
164
|
+
key={index}
|
|
165
|
+
onClick={() => {
|
|
166
|
+
this.handleOptionChange(
|
|
167
|
+
res?.content[0]?.text,
|
|
168
|
+
res?.attrs.selectionId
|
|
169
|
+
);
|
|
170
|
+
}}
|
|
171
|
+
value={res?.content[0]?.text}
|
|
172
|
+
>
|
|
173
|
+
{res?.content[0]?.text}
|
|
174
|
+
</option>
|
|
175
|
+
))}
|
|
176
|
+
</select>
|
|
177
|
+
<ReactTooltip
|
|
178
|
+
effect="solid"
|
|
179
|
+
id="select-toc-tooltip"
|
|
180
|
+
place="bottom"
|
|
181
|
+
/>
|
|
182
|
+
<br></br>
|
|
183
|
+
<div className="czi-form-buttons">
|
|
184
|
+
<CustomButton label="Cancel" onClick={this._cancel} />
|
|
185
|
+
</div>
|
|
186
|
+
</form>
|
|
187
|
+
</div>
|
|
188
|
+
)}
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
handleOptionChange = (textContent_, selectionId) => {
|
|
195
|
+
const texthash = '';
|
|
196
|
+
const nodeconcat_UUID = texthash.concat(selectionId);
|
|
197
|
+
const textContent = nodeconcat_UUID.concat(INNER_LINK, textContent_);
|
|
198
|
+
this.props.close(textContent);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
_onKeyDown = (e: any) => {
|
|
202
|
+
if (e.keyCode === ENTER) {
|
|
203
|
+
e.preventDefault();
|
|
204
|
+
this._apply();
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
_onURLChange = (e: SyntheticInputEvent<>) => {
|
|
209
|
+
const url = e.target.value;
|
|
210
|
+
this.setState({
|
|
211
|
+
url,
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
_cancel = (): void => {
|
|
216
|
+
this.props.close();
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
_apply = (): void => {
|
|
220
|
+
const { url } = this.state;
|
|
221
|
+
if (url && !BAD_CHARACTER_PATTER.test(url)) {
|
|
222
|
+
this.props.close(sanitizeURL(url));
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export default LinkURLEditor;
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import { Node } from 'prosemirror-model';
|
|
4
|
-
import { Decoration, EditorView } from 'prosemirror-view';
|
|
5
|
-
import { MARK_TEXT_COLOR, MARK_FONT_SIZE } from '../MarkNames.js';
|
|
6
|
-
|
|
7
|
-
// This implements the `NodeView` interface
|
|
8
|
-
// https://prosemirror.net/docs/ref/#view.NodeView
|
|
9
|
-
class ListItemNodeView {
|
|
10
|
-
// This implements the `NodeView` interface
|
|
11
|
-
// The outer DOM node that represents the list item element.
|
|
12
|
-
dom: HTMLLIElement;
|
|
13
|
-
|
|
14
|
-
// This implements the `NodeView` interface.
|
|
15
|
-
// The DOM node that should hold the node's content.
|
|
16
|
-
contentDOM: HTMLLIElement;
|
|
17
|
-
|
|
18
|
-
_nodeUpdated: ?Node;
|
|
19
|
-
|
|
20
|
-
constructor(
|
|
21
|
-
node: Node,
|
|
22
|
-
editorView: EditorView,
|
|
23
|
-
getPos: () => number,
|
|
24
|
-
decorations: Array<Decoration>
|
|
25
|
-
) {
|
|
26
|
-
const dom = document.createElement('li');
|
|
27
|
-
this.dom = dom;
|
|
28
|
-
this._editorView = editorView;
|
|
29
|
-
this.contentDOM = dom;
|
|
30
|
-
this._updateDOM(node);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// This implements the `NodeView` interface.
|
|
34
|
-
update(node: Node, decorations: Array<Decoration>): boolean {
|
|
35
|
-
return this._updateDOM(node);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
_updateDOM(node: Node): boolean {
|
|
39
|
-
if (this._nodeUpdated === node) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this._nodeUpdated = node;
|
|
44
|
-
|
|
45
|
-
const dom = this.dom;
|
|
46
|
-
// According to `ListItemNodeSpec`, a valid list item has the following
|
|
47
|
-
// structure: `li > paragraph > text`.
|
|
48
|
-
const paragraph = node.firstChild;
|
|
49
|
-
const initialContent = paragraph ? paragraph.firstChild : null;
|
|
50
|
-
|
|
51
|
-
// This resolves the styles for the counter by examines the marks for the
|
|
52
|
-
// first text node of the list item.
|
|
53
|
-
let marks =
|
|
54
|
-
initialContent && initialContent.isText && initialContent.textContent
|
|
55
|
-
? initialContent.marks
|
|
56
|
-
: null;
|
|
57
|
-
if (!marks) {
|
|
58
|
-
marks = this._editorView.state.tr.storedMarks;
|
|
59
|
-
}
|
|
60
|
-
let cssColor;
|
|
61
|
-
let cssFontSize;
|
|
62
|
-
let cssText = '';
|
|
63
|
-
if (Array.isArray(marks)) {
|
|
64
|
-
marks.forEach((mark) => {
|
|
65
|
-
const { attrs, type } = mark;
|
|
66
|
-
switch (type.name) {
|
|
67
|
-
case MARK_TEXT_COLOR:
|
|
68
|
-
cssColor = attrs.color;
|
|
69
|
-
break;
|
|
70
|
-
case MARK_FONT_SIZE:
|
|
71
|
-
cssFontSize = attrs.pt;
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// The counter of the list item is a pseudo-element that uses
|
|
78
|
-
// the CSS variables (e.g `--czi-list-style-color`) for styling.
|
|
79
|
-
// This defines the CSS variables scoped for the pseudo-element.
|
|
80
|
-
// See `src/ui/czi-list.css` for more details.
|
|
81
|
-
if (cssColor) {
|
|
82
|
-
cssText += `--czi-list-style-color: ${cssColor};`;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (cssFontSize) {
|
|
86
|
-
cssText += `--czi-list-style-font-size: ${cssFontSize}pt;`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
dom.style.cssText = cssText;
|
|
90
|
-
|
|
91
|
-
const { align } = node.attrs;
|
|
92
|
-
if (align) {
|
|
93
|
-
dom.setAttribute('data-align', align);
|
|
94
|
-
} else {
|
|
95
|
-
dom.removeAttribute('data-align');
|
|
96
|
-
}
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export default ListItemNodeView;
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import { Node } from 'prosemirror-model';
|
|
4
|
+
import { Decoration, EditorView } from 'prosemirror-view';
|
|
5
|
+
import { MARK_TEXT_COLOR, MARK_FONT_SIZE } from '../MarkNames.js';
|
|
6
|
+
|
|
7
|
+
// This implements the `NodeView` interface
|
|
8
|
+
// https://prosemirror.net/docs/ref/#view.NodeView
|
|
9
|
+
class ListItemNodeView {
|
|
10
|
+
// This implements the `NodeView` interface
|
|
11
|
+
// The outer DOM node that represents the list item element.
|
|
12
|
+
dom: HTMLLIElement;
|
|
13
|
+
|
|
14
|
+
// This implements the `NodeView` interface.
|
|
15
|
+
// The DOM node that should hold the node's content.
|
|
16
|
+
contentDOM: HTMLLIElement;
|
|
17
|
+
|
|
18
|
+
_nodeUpdated: ?Node;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
node: Node,
|
|
22
|
+
editorView: EditorView,
|
|
23
|
+
getPos: () => number,
|
|
24
|
+
decorations: Array<Decoration>
|
|
25
|
+
) {
|
|
26
|
+
const dom = document.createElement('li');
|
|
27
|
+
this.dom = dom;
|
|
28
|
+
this._editorView = editorView;
|
|
29
|
+
this.contentDOM = dom;
|
|
30
|
+
this._updateDOM(node);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// This implements the `NodeView` interface.
|
|
34
|
+
update(node: Node, decorations: Array<Decoration>): boolean {
|
|
35
|
+
return this._updateDOM(node);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_updateDOM(node: Node): boolean {
|
|
39
|
+
if (this._nodeUpdated === node) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this._nodeUpdated = node;
|
|
44
|
+
|
|
45
|
+
const dom = this.dom;
|
|
46
|
+
// According to `ListItemNodeSpec`, a valid list item has the following
|
|
47
|
+
// structure: `li > paragraph > text`.
|
|
48
|
+
const paragraph = node.firstChild;
|
|
49
|
+
const initialContent = paragraph ? paragraph.firstChild : null;
|
|
50
|
+
|
|
51
|
+
// This resolves the styles for the counter by examines the marks for the
|
|
52
|
+
// first text node of the list item.
|
|
53
|
+
let marks =
|
|
54
|
+
initialContent && initialContent.isText && initialContent.textContent
|
|
55
|
+
? initialContent.marks
|
|
56
|
+
: null;
|
|
57
|
+
if (!marks) {
|
|
58
|
+
marks = this._editorView.state.tr.storedMarks;
|
|
59
|
+
}
|
|
60
|
+
let cssColor;
|
|
61
|
+
let cssFontSize;
|
|
62
|
+
let cssText = '';
|
|
63
|
+
if (Array.isArray(marks)) {
|
|
64
|
+
marks.forEach((mark) => {
|
|
65
|
+
const { attrs, type } = mark;
|
|
66
|
+
switch (type.name) {
|
|
67
|
+
case MARK_TEXT_COLOR:
|
|
68
|
+
cssColor = attrs.color;
|
|
69
|
+
break;
|
|
70
|
+
case MARK_FONT_SIZE:
|
|
71
|
+
cssFontSize = attrs.pt;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// The counter of the list item is a pseudo-element that uses
|
|
78
|
+
// the CSS variables (e.g `--czi-list-style-color`) for styling.
|
|
79
|
+
// This defines the CSS variables scoped for the pseudo-element.
|
|
80
|
+
// See `src/ui/czi-list.css` for more details.
|
|
81
|
+
if (cssColor) {
|
|
82
|
+
cssText += `--czi-list-style-color: ${cssColor};`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (cssFontSize) {
|
|
86
|
+
cssText += `--czi-list-style-font-size: ${cssFontSize}pt;`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
dom.style.cssText = cssText;
|
|
90
|
+
|
|
91
|
+
const { align } = node.attrs;
|
|
92
|
+
if (align) {
|
|
93
|
+
dom.setAttribute('data-align', align);
|
|
94
|
+
} else {
|
|
95
|
+
dom.removeAttribute('data-align');
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export default ListItemNodeView;
|