markupeditor 0.9.39 → 0.9.41
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/config/behaviorconfig.json +1 -0
- package/dist/markup-editor.js +202 -25
- package/package.json +1 -1
package/dist/markup-editor.js
CHANGED
|
@@ -15149,6 +15149,16 @@ const tNodes = tableNodes({
|
|
|
15149
15149
|
attrs.style = (attrs.style || '') + `background-color: ${value};`;
|
|
15150
15150
|
},
|
|
15151
15151
|
},
|
|
15152
|
+
align: {
|
|
15153
|
+
default: null,
|
|
15154
|
+
getFromDOM(dom) {
|
|
15155
|
+
return dom.style.textAlign || null;
|
|
15156
|
+
},
|
|
15157
|
+
setDOMAttr(value, attrs) {
|
|
15158
|
+
if (value)
|
|
15159
|
+
attrs.style = (attrs.style || '') + `text-align: ${value};`;
|
|
15160
|
+
},
|
|
15161
|
+
},
|
|
15152
15162
|
}
|
|
15153
15163
|
});
|
|
15154
15164
|
tNodes.table.attrs = {class: {default: null}};
|
|
@@ -32817,6 +32827,12 @@ function isRecognizedLanguage(name) {
|
|
|
32817
32827
|
* the same language for display/matching purposes, matching isRecognizedLanguage's
|
|
32818
32828
|
* own case-insensitivity.
|
|
32819
32829
|
*
|
|
32830
|
+
* Filtered through isRecognizedLanguage, so a genuinely custom/unrecognized
|
|
32831
|
+
* language name typed into one block is no longer suggested for reuse in
|
|
32832
|
+
* another. Trade-off accepted for a positive, Markdown-agnostic rule ("only
|
|
32833
|
+
* present languages this app actually supports") rather than a per-language
|
|
32834
|
+
* exclusion list.
|
|
32835
|
+
*
|
|
32820
32836
|
* @param {Node} doc A ProseMirror document node.
|
|
32821
32837
|
* @returns {string[]}
|
|
32822
32838
|
*/
|
|
@@ -32827,7 +32843,7 @@ function presentCodeLanguages(doc) {
|
|
|
32827
32843
|
languages.add(node.attrs.language.toLowerCase());
|
|
32828
32844
|
}
|
|
32829
32845
|
});
|
|
32830
|
-
return Array.from(languages).sort()
|
|
32846
|
+
return Array.from(languages).filter(isRecognizedLanguage).sort()
|
|
32831
32847
|
}
|
|
32832
32848
|
|
|
32833
32849
|
// hljs never has classPrefix reconfigured elsewhere in this codebase, so this
|
|
@@ -34834,7 +34850,7 @@ function _getSelectionState() {
|
|
|
34834
34850
|
state['thead'] = tableAttributes.thead;
|
|
34835
34851
|
state['tbody'] = tableAttributes.tbody;
|
|
34836
34852
|
state['header'] = tableAttributes.header;
|
|
34837
|
-
state['colspan'] = tableAttributes.colspan;
|
|
34853
|
+
state['colspan'] = (tableAttributes.colspan ?? 0) > 1; // A real boolean; Swift's SelectionState.colspan is typed Bool and cannot decode a raw JS number
|
|
34838
34854
|
state['rows'] = tableAttributes.rows;
|
|
34839
34855
|
state['cols'] = tableAttributes.cols;
|
|
34840
34856
|
state['row'] = tableAttributes.row;
|
|
@@ -35035,8 +35051,8 @@ function _getTableAttributes(state) {
|
|
|
35035
35051
|
case nodeTypes.table_header:
|
|
35036
35052
|
attributes.thead = true; // We selected the header
|
|
35037
35053
|
attributes.tbody = false;
|
|
35038
|
-
attributes.row =
|
|
35039
|
-
attributes.col = 1;
|
|
35054
|
+
attributes.row = 0; // Header cells are row 0 by definition, not a body row index
|
|
35055
|
+
attributes.col = $pos.index() + 1; // A header cell's own column position, whether colspanned or per-column
|
|
35040
35056
|
return true;
|
|
35041
35057
|
case nodeTypes.table_row:
|
|
35042
35058
|
attributes.row = $pos.index() + 1; // We are in some row, but could be the header row
|
|
@@ -35159,8 +35175,8 @@ function callbackInsertLink() {
|
|
|
35159
35175
|
|
|
35160
35176
|
/**
|
|
35161
35177
|
* Callback to signal that the user wants to insert an image.
|
|
35162
|
-
*
|
|
35163
|
-
* The messageHandler will need to bring up a dialog to identify
|
|
35178
|
+
*
|
|
35179
|
+
* The messageHandler will need to bring up a dialog to identify
|
|
35164
35180
|
* the image and then execute insertImage.
|
|
35165
35181
|
*/
|
|
35166
35182
|
function callbackInsertImage() {
|
|
@@ -35168,6 +35184,17 @@ function callbackInsertImage() {
|
|
|
35168
35184
|
_callback(JSON.stringify(messageDict));
|
|
35169
35185
|
}
|
|
35170
35186
|
|
|
35187
|
+
/**
|
|
35188
|
+
* Callback to signal that the user wants to insert or edit a table.
|
|
35189
|
+
*
|
|
35190
|
+
* The messageHandler will need to bring up a dialog to size a new table
|
|
35191
|
+
* (and then execute insertTable) or edit the table the selection is in.
|
|
35192
|
+
*/
|
|
35193
|
+
function callbackInsertTable() {
|
|
35194
|
+
let messageDict = { 'messageType' : 'insertTable' };
|
|
35195
|
+
_callback(JSON.stringify(messageDict));
|
|
35196
|
+
}
|
|
35197
|
+
|
|
35171
35198
|
/**
|
|
35172
35199
|
* Callback to signal that user-provided CSS and/or script files have
|
|
35173
35200
|
* been loaded.
|
|
@@ -36005,7 +36032,7 @@ function _copyImage(node) {
|
|
|
36005
36032
|
* @param {number} rows The number of rows in the table to be created.
|
|
36006
36033
|
* @param {number} cols The number of columns in the table to be created.
|
|
36007
36034
|
*/
|
|
36008
|
-
function insertTable(rows, cols) {
|
|
36035
|
+
function insertTable$1(rows, cols) {
|
|
36009
36036
|
const view = activeView();
|
|
36010
36037
|
if ((rows < 1) || (cols < 1)) return;
|
|
36011
36038
|
let command = insertTableCommand(rows, cols);
|
|
@@ -36015,6 +36042,7 @@ function insertTable(rows, cols) {
|
|
|
36015
36042
|
function insertTableCommand(rows, cols) {
|
|
36016
36043
|
const commandAdapter = (viewState, dispatch, view) => {
|
|
36017
36044
|
let state = view?.state ?? viewState;
|
|
36045
|
+
if (isTableSelected(state)) return false; // Tables cannot be nested
|
|
36018
36046
|
const nodeTypes = state.schema.nodes;
|
|
36019
36047
|
const table_rows = [];
|
|
36020
36048
|
for (let j = 0; j < rows; j++) {
|
|
@@ -36054,15 +36082,8 @@ function insertTableCommand(rows, cols) {
|
|
|
36054
36082
|
} return (pPos == undefined); // Keep going if pPos hasn't been defined
|
|
36055
36083
|
});
|
|
36056
36084
|
}
|
|
36057
|
-
// Set the selection in the first cell,
|
|
36058
|
-
|
|
36059
|
-
let empty = (view.state.doc.textContent.length == 0);
|
|
36060
|
-
let textSelection;
|
|
36061
|
-
if (empty) {
|
|
36062
|
-
textSelection = TextSelection.near(transaction.doc.resolve(pPos), -1);
|
|
36063
|
-
} else {
|
|
36064
|
-
textSelection = TextSelection.near(transaction.doc.resolve(pPos));
|
|
36065
|
-
}
|
|
36085
|
+
// Set the selection in the first cell, applied to the state and the view.
|
|
36086
|
+
let textSelection = TextSelection.near(transaction.doc.resolve(pPos));
|
|
36066
36087
|
transaction = transaction.setSelection(textSelection);
|
|
36067
36088
|
state = state.apply(transaction);
|
|
36068
36089
|
view.updateState(state);
|
|
@@ -36092,12 +36113,20 @@ function addRow(direction) {
|
|
|
36092
36113
|
return result;
|
|
36093
36114
|
}
|
|
36094
36115
|
function addRowCommand(direction) {
|
|
36095
|
-
const commandAdapter = (
|
|
36116
|
+
const commandAdapter = (viewState, dispatch, view) => {
|
|
36117
|
+
let state = view?.state ?? viewState;
|
|
36118
|
+
let result;
|
|
36096
36119
|
if (direction === 'BEFORE') {
|
|
36097
|
-
|
|
36120
|
+
result = addRowBefore(state, (tr) => { state = state.apply(tr); });
|
|
36098
36121
|
} else {
|
|
36099
|
-
|
|
36100
|
-
}
|
|
36122
|
+
result = addRowAfter(state, (tr) => { state = state.apply(tr); });
|
|
36123
|
+
} if (!result) return false;
|
|
36124
|
+
_propagateColumnAlign(state, (tr) => { state = state.apply(tr); });
|
|
36125
|
+
if (dispatch) {
|
|
36126
|
+
view.updateState(state);
|
|
36127
|
+
}
|
|
36128
|
+
return true;
|
|
36129
|
+
};
|
|
36101
36130
|
|
|
36102
36131
|
return commandAdapter;
|
|
36103
36132
|
}
|
|
@@ -36124,14 +36153,18 @@ function addColCommand(direction) {
|
|
|
36124
36153
|
let state = view?.state ?? viewState;
|
|
36125
36154
|
if (!isTableSelected(state)) return false;
|
|
36126
36155
|
const startSelection = new TextSelection(state.selection.$anchor, state.selection.$head);
|
|
36156
|
+
const wasColspannedHeader = _hasColspannedHeader(state);
|
|
36127
36157
|
let offset = 0;
|
|
36128
36158
|
if (direction === 'BEFORE') {
|
|
36129
36159
|
addColumnBefore(state, (tr) => { state = state.apply(tr); });
|
|
36130
36160
|
offset = 4; // An empty cell
|
|
36131
36161
|
} else {
|
|
36132
36162
|
addColumnAfter(state, (tr) => { state = state.apply(tr); });
|
|
36133
|
-
}
|
|
36134
|
-
|
|
36163
|
+
} // Re-merge only a colspanned caption header that this add just split into two cells.
|
|
36164
|
+
// A genuine per-column header must not be merged -- it should just gain one more cell.
|
|
36165
|
+
if (wasColspannedHeader) {
|
|
36166
|
+
_mergeHeaders(state, (tr) => { state = state.apply(tr); });
|
|
36167
|
+
}
|
|
36135
36168
|
if (dispatch) {
|
|
36136
36169
|
const $anchor = state.tr.doc.resolve(startSelection.from + offset);
|
|
36137
36170
|
const $head = state.tr.doc.resolve(startSelection.to + offset);
|
|
@@ -36174,7 +36207,8 @@ function addHeaderCommand(colspan = true) {
|
|
|
36174
36207
|
toggleHeaderRow(state, (tr) => { state = state.apply(tr); });
|
|
36175
36208
|
if (colspan) {
|
|
36176
36209
|
_mergeHeaders(state, (tr) => { state = state.apply(tr); });
|
|
36177
|
-
}
|
|
36210
|
+
} _propagateColumnAlign(state, (tr) => { state = state.apply(tr); });
|
|
36211
|
+
|
|
36178
36212
|
if (dispatch) {
|
|
36179
36213
|
// At this point, the state.selection is in the new header row we just added. By definition,
|
|
36180
36214
|
// the header is placed before the original selection, so we can add its size to the
|
|
@@ -36310,6 +36344,129 @@ function _mergeHeaders(state, dispatch) {
|
|
|
36310
36344
|
const newState = state.apply(transaction);
|
|
36311
36345
|
mergeCells(newState, dispatch);
|
|
36312
36346
|
}}
|
|
36347
|
+
/**
|
|
36348
|
+
* Return whether the table's header row is currently a single colspanned caption cell
|
|
36349
|
+
* (colspan > 1), as opposed to a genuine per-column header (multiple table_header cells,
|
|
36350
|
+
* each colspan 1) or no header at all. Used by addColCommand to decide whether adding a
|
|
36351
|
+
* column should re-merge the header row (maintaining a caption) or leave it alone (a real
|
|
36352
|
+
* per-column header simply gains one more per-column cell).
|
|
36353
|
+
*
|
|
36354
|
+
* @ignore
|
|
36355
|
+
*/
|
|
36356
|
+
function _hasColspannedHeader(state) {
|
|
36357
|
+
const nodeTypes = state.schema.nodes;
|
|
36358
|
+
const headers = [];
|
|
36359
|
+
let tableAttributes = _getTableAttributes(state);
|
|
36360
|
+
if (!tableAttributes.table) return false;
|
|
36361
|
+
state.tr.doc.nodesBetween(tableAttributes.from, tableAttributes.to, (node, pos) => {
|
|
36362
|
+
if (node.type == nodeTypes.table_header) {
|
|
36363
|
+
headers.push(node);
|
|
36364
|
+
return false;
|
|
36365
|
+
}
|
|
36366
|
+
return true;
|
|
36367
|
+
});
|
|
36368
|
+
return (headers.length === 1) && ((headers[0].attrs.colspan ?? 1) > 1);
|
|
36369
|
+
}
|
|
36370
|
+
/**
|
|
36371
|
+
* Propagate each column's existing alignment onto any cell in that column that doesn't have
|
|
36372
|
+
* one yet -- e.g., a cell in a row addRowCommand or addHeaderCommand just inserted, which
|
|
36373
|
+
* otherwise defaults to align: null and would silently drop the column's alignment on export.
|
|
36374
|
+
*
|
|
36375
|
+
* Columns are identified by a cell's index within its row, which assumes every row has the
|
|
36376
|
+
* same number of cells -- true for any table this editor can produce or import, since this
|
|
36377
|
+
* schema has no colspanned/rowspanned body cells (only a header row can be colspanned, and a
|
|
36378
|
+
* colspanned header cell is skipped here since it doesn't belong to a single column).
|
|
36379
|
+
*
|
|
36380
|
+
* @ignore
|
|
36381
|
+
*/
|
|
36382
|
+
function _propagateColumnAlign(state, dispatch) {
|
|
36383
|
+
const nodeTypes = state.schema.nodes;
|
|
36384
|
+
let tableAttributes = _getTableAttributes(state);
|
|
36385
|
+
if (!tableAttributes.table) return;
|
|
36386
|
+
const tr = state.tr;
|
|
36387
|
+
const columnAligns = {};
|
|
36388
|
+
tr.doc.nodesBetween(tableAttributes.from, tableAttributes.to, (node, pos) => {
|
|
36389
|
+
if ((node.type == nodeTypes.table_cell) || (node.type == nodeTypes.table_header)) {
|
|
36390
|
+
if ((node.attrs.colspan ?? 1) > 1) return false; // A colspanned caption cell doesn't belong to a single column
|
|
36391
|
+
const col = tr.doc.resolve(pos).index();
|
|
36392
|
+
if ((columnAligns[col] === undefined) && node.attrs.align) {
|
|
36393
|
+
columnAligns[col] = node.attrs.align;
|
|
36394
|
+
}
|
|
36395
|
+
return false;
|
|
36396
|
+
}
|
|
36397
|
+
return true;
|
|
36398
|
+
});
|
|
36399
|
+
if (Object.keys(columnAligns).length === 0) return;
|
|
36400
|
+
let changed = false;
|
|
36401
|
+
tr.doc.nodesBetween(tableAttributes.from, tableAttributes.to, (node, pos) => {
|
|
36402
|
+
if ((node.type == nodeTypes.table_cell) || (node.type == nodeTypes.table_header)) {
|
|
36403
|
+
if ((node.attrs.colspan ?? 1) > 1) return false;
|
|
36404
|
+
const col = tr.doc.resolve(pos).index();
|
|
36405
|
+
const align = columnAligns[col];
|
|
36406
|
+
if (align && !node.attrs.align) {
|
|
36407
|
+
tr.setNodeMarkup(pos, null, {...node.attrs, align});
|
|
36408
|
+
changed = true;
|
|
36409
|
+
}
|
|
36410
|
+
return false;
|
|
36411
|
+
}
|
|
36412
|
+
return true;
|
|
36413
|
+
});
|
|
36414
|
+
if (changed && dispatch) {
|
|
36415
|
+
dispatch(tr);
|
|
36416
|
+
}
|
|
36417
|
+
}
|
|
36418
|
+
/**
|
|
36419
|
+
* Justify (set text alignment on) the column containing the selection. Applies to every cell
|
|
36420
|
+
* in that column -- header and body alike -- not just the selected cell, since GFM's Markdown
|
|
36421
|
+
* alignment is a per-column, not per-cell, concept. A colspanned (single-cell caption) header
|
|
36422
|
+
* has no single column to target and is left untouched.
|
|
36423
|
+
*
|
|
36424
|
+
* @param {'left' | 'center' | 'right' | null} align The alignment to set, or null/falsy to clear it.
|
|
36425
|
+
*/
|
|
36426
|
+
function justifyColumn(align) {
|
|
36427
|
+
if (_tableSelected()) {
|
|
36428
|
+
const view = activeView();
|
|
36429
|
+
let command = justifyColumnCommand(align);
|
|
36430
|
+
let result = command(view.state, view.dispatch, view);
|
|
36431
|
+
stateChanged(view);
|
|
36432
|
+
view.focus();
|
|
36433
|
+
return result;
|
|
36434
|
+
}
|
|
36435
|
+
}
|
|
36436
|
+
function justifyColumnCommand(align) {
|
|
36437
|
+
// 'left' means "clear", matching an unaligned GFM column having no delimiter-row marker
|
|
36438
|
+
// at all -- an alias here rather than relying on every caller to pass null/undefined.
|
|
36439
|
+
const resolvedAlign = (align && align !== 'left') ? align : null;
|
|
36440
|
+
const commandAdapter = (state, dispatch, view) => {
|
|
36441
|
+
if (!isTableSelected(state)) return false;
|
|
36442
|
+
const nodeTypes = state.schema.nodes;
|
|
36443
|
+
const tableAttributes = _getTableAttributes(state);
|
|
36444
|
+
if (!tableAttributes.table) return false;
|
|
36445
|
+
if (tableAttributes.thead && (tableAttributes.colspan > 1)) return false; // Colspanned caption header selected; no single column to target
|
|
36446
|
+
const col = tableAttributes.col;
|
|
36447
|
+
if (!col) return false;
|
|
36448
|
+
const tr = state.tr;
|
|
36449
|
+
let changed = false;
|
|
36450
|
+
tr.doc.nodesBetween(tableAttributes.from, tableAttributes.to, (node, pos) => {
|
|
36451
|
+
if ((node.type == nodeTypes.table_cell) || (node.type == nodeTypes.table_header)) {
|
|
36452
|
+
if ((node.attrs.colspan ?? 1) > 1) return false; // Skip a colspanned caption cell; it doesn't belong to a single column
|
|
36453
|
+
if ((tr.doc.resolve(pos).index() + 1) === col) {
|
|
36454
|
+
tr.setNodeMarkup(pos, null, {...node.attrs, align: resolvedAlign});
|
|
36455
|
+
changed = true;
|
|
36456
|
+
}
|
|
36457
|
+
return false;
|
|
36458
|
+
}
|
|
36459
|
+
return true;
|
|
36460
|
+
});
|
|
36461
|
+
if (changed && dispatch) {
|
|
36462
|
+
dispatch(tr);
|
|
36463
|
+
}
|
|
36464
|
+
return changed;
|
|
36465
|
+
};
|
|
36466
|
+
|
|
36467
|
+
return commandAdapter;
|
|
36468
|
+
}
|
|
36469
|
+
|
|
36313
36470
|
function isHRuleSelected(state) {
|
|
36314
36471
|
let hRuleSelected = false;
|
|
36315
36472
|
state.doc.nodesBetween(state.selection.from, state.selection.to, (node) => {
|
|
@@ -37139,6 +37296,7 @@ var focusAfterLoad = true;
|
|
|
37139
37296
|
var selectImage = false;
|
|
37140
37297
|
var insertLink = false;
|
|
37141
37298
|
var insertImage = false;
|
|
37299
|
+
var insertTable = false;
|
|
37142
37300
|
var highlightCode = true;
|
|
37143
37301
|
var markdownShorthand = true;
|
|
37144
37302
|
var behaviorConfig = {
|
|
@@ -37146,6 +37304,7 @@ var behaviorConfig = {
|
|
|
37146
37304
|
selectImage: selectImage,
|
|
37147
37305
|
insertLink: insertLink,
|
|
37148
37306
|
insertImage: insertImage,
|
|
37307
|
+
insertTable: insertTable,
|
|
37149
37308
|
highlightCode: highlightCode,
|
|
37150
37309
|
markdownShorthand: markdownShorthand
|
|
37151
37310
|
};
|
|
@@ -37186,6 +37345,7 @@ var behaviorConfig = {
|
|
|
37186
37345
|
* "selectImage": false, // Whether to show a "Select..." button in the Insert Image dialog
|
|
37187
37346
|
* "insertLink": false, // Whether to defer to the MarkupDelegate rather than use the default LinkDialog
|
|
37188
37347
|
* "insertImage": false, // Whether to defer to the MarkupDelagate rather than use the default ImageDialog
|
|
37348
|
+
* "insertTable": false, // Whether to defer to the MarkupDelegate rather than use the default Table menu
|
|
37189
37349
|
* "highlightCode": true, // Whether to highlight code blocks and support language identificaton in UI
|
|
37190
37350
|
* "markdownShorthand": true // Whether typing markdown shorthand converts to formatting: block-level
|
|
37191
37351
|
* // (`> `, list markers, ``` ``` ```, `#`) and inline (**, *, _, `, ~~)
|
|
@@ -40333,6 +40493,19 @@ function hRuleItem(config) {
|
|
|
40333
40493
|
function tableMenuItems(config) {
|
|
40334
40494
|
let icons = config.toolbar.icons;
|
|
40335
40495
|
let help = config.toolbar.help;
|
|
40496
|
+
// If `behavior.insertTable` is true, the Table button just invokes the delegate's
|
|
40497
|
+
// `markupInsertTable` method instead of the dropdown below -- same reasoning as
|
|
40498
|
+
// LinkItem/ImageItem. Unlike Link/Image, the delegate decides what to show (an
|
|
40499
|
+
// insert-size picker or a table-editing menu) based on whether the selection is
|
|
40500
|
+
// already in a table, so a single enabled state covers both: "can insert a table
|
|
40501
|
+
// here" or "already in a table" (editing an existing table is always available).
|
|
40502
|
+
if (config.behavior.insertTable && config.delegate?.markupInsertTable) {
|
|
40503
|
+
return cmdItem(config.delegate.markupInsertTable, {
|
|
40504
|
+
enable: (state) => insertTableCommand(1, 1)(state) || isTableSelected(state),
|
|
40505
|
+
title: help.table + keyString('table', config.keymap),
|
|
40506
|
+
icon: icons.table
|
|
40507
|
+
})
|
|
40508
|
+
}
|
|
40336
40509
|
let items = [];
|
|
40337
40510
|
let { tableHeader, tableBorder } = config.toolbar.menus;
|
|
40338
40511
|
items.push(new TableCreateSubmenu({title: 'Insert table', label: 'Insert'}));
|
|
@@ -40840,7 +41013,9 @@ function buildKeymap(config, schema) {
|
|
|
40840
41013
|
// Insert
|
|
40841
41014
|
bind(keymap.link, new LinkItem(config).command);
|
|
40842
41015
|
bind(keymap.image, new ImageItem(config).command);
|
|
40843
|
-
|
|
41016
|
+
// Defers to the delegate when `behavior.insertTable` is set, same as Link/Image;
|
|
41017
|
+
// otherwise inserts a default-sized table, since there's no dialog to fall back to.
|
|
41018
|
+
bind(keymap.table, (config.behavior.insertTable && config.delegate?.markupInsertTable) ? config.delegate.markupInsertTable : insertTableCommand(2, 2));
|
|
40844
41019
|
// Styling
|
|
40845
41020
|
bind(keymap.p, setStyleCommand('P'));
|
|
40846
41021
|
bind(keymap.h1, setStyleCommand('H1'));
|
|
@@ -42771,6 +42946,7 @@ const MU = {
|
|
|
42771
42946
|
borderTable,
|
|
42772
42947
|
callbackInsertImage,
|
|
42773
42948
|
callbackInsertLink,
|
|
42949
|
+
callbackInsertTable,
|
|
42774
42950
|
callbackSelectImage,
|
|
42775
42951
|
cancelSearch,
|
|
42776
42952
|
canUndo,
|
|
@@ -42800,8 +42976,9 @@ const MU = {
|
|
|
42800
42976
|
insertImage: insertImage$1,
|
|
42801
42977
|
insertInternalLink,
|
|
42802
42978
|
insertLink: insertLink$1,
|
|
42803
|
-
insertTable,
|
|
42979
|
+
insertTable: insertTable$1,
|
|
42804
42980
|
insertHRule,
|
|
42981
|
+
justifyColumn,
|
|
42805
42982
|
loadUserFiles,
|
|
42806
42983
|
modifyImage,
|
|
42807
42984
|
openImageDialog,
|