grep-components 2.7.0-GREPF-2633.1 → 2.7.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.
- package/dist/components/GrepDateRange/index.d.ts +1 -1
- package/dist/components/GrepDialog/dialog.d.ts +1 -1
- package/dist/components/GrepDialog/stories/dialog.stories.d.ts +4 -4
- package/dist/components/GrepEditor/components/plugins/CustomHtmlExport.d.ts +2 -2
- package/dist/components/GrepEditor/components/plugins/ToolbarPlugin.d.ts +1 -1
- package/dist/components/GrepEditor/entities/index.d.ts +1 -1
- package/dist/components/GrepTable/index.d.ts +2 -2
- package/dist/components/SortableTable/components/cell.d.ts +1 -1
- package/dist/components/SortableTable/components/row.d.ts +0 -1
- package/dist/components/SortableTable/index.d.ts +1 -1
- package/dist/hooks/use-date.d.ts +1 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3632 -282
- package/dist/index.js.map +1 -1
- package/dist/styling/makeStyles.d.ts +2 -2
- package/package.json +19 -19
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
2
|
import LocalizedFormatPlugin from 'dayjs/plugin/localizedFormat';
|
|
3
3
|
import isBetweenPlugin from 'dayjs/plugin/isBetween';
|
|
4
|
-
import {
|
|
4
|
+
import { blueGrey, grey, brown, deepOrange, orange, amber, yellow, lime, lightGreen, green, teal, cyan, lightBlue, blue, indigo, deepPurple, purple, pink, red } from '@mui/material/colors';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import React__default, { useRef, useMemo as useMemo$1, createContext, useContext, forwardRef, createElement, useState, useCallback as useCallback$1, useEffect, useLayoutEffect } from 'react';
|
|
7
7
|
import AccountCircle from '@mui/icons-material/AccountCircle';
|
|
@@ -39,25 +39,25 @@ import Close from '@mui/icons-material/Close';
|
|
|
39
39
|
import Search from '@mui/icons-material/Search';
|
|
40
40
|
import CircularProgress$1 from '@mui/material/CircularProgress';
|
|
41
41
|
import Info from '@mui/icons-material/Info';
|
|
42
|
-
import Grid from '@mui/material/Grid';
|
|
43
42
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
44
43
|
import { LocalizationProvider, DesktopDatePicker } from '@mui/x-date-pickers';
|
|
44
|
+
import Grid2 from '@mui/material/Grid2';
|
|
45
45
|
import ListItem$1 from '@mui/material/ListItem';
|
|
46
46
|
import Collapse$1 from '@mui/material/Collapse';
|
|
47
47
|
import ExpandLess from '@mui/icons-material/ExpandLess';
|
|
48
48
|
import Warning from '@mui/icons-material/Warning';
|
|
49
49
|
import ReactDOM, { flushSync, createPortal } from 'react-dom';
|
|
50
|
-
import {
|
|
50
|
+
import { bindActionCreators, createStore as createStore$1, compose, applyMiddleware } from 'redux';
|
|
51
51
|
import { connect, Provider } from 'react-redux';
|
|
52
52
|
import DragIndicator from '@mui/icons-material/DragIndicator';
|
|
53
53
|
import { LexicalComposer } from '@lexical/react/LexicalComposer';
|
|
54
54
|
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
|
55
55
|
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
|
56
56
|
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
|
|
57
|
-
import
|
|
57
|
+
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
|
|
58
58
|
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
|
|
59
59
|
import { EditorRefPlugin } from '@lexical/react/LexicalEditorRefPlugin';
|
|
60
|
-
import
|
|
60
|
+
import require$$3, { BLUR_COMMAND, COMMAND_PRIORITY_EDITOR, FOCUS_COMMAND, TextNode, ParagraphNode, PASTE_COMMAND, $createTextNode, $insertNodes, RootNode, LineBreakNode, $getSelection, $isRangeSelection, $isTextNode, $isParagraphNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND, $createParagraphNode } from 'lexical';
|
|
61
61
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
62
62
|
import FormatBold from '@mui/icons-material/FormatBold';
|
|
63
63
|
import FormatItalic from '@mui/icons-material/FormatItalic';
|
|
@@ -550,8 +550,6 @@ function memoize(fn) {
|
|
|
550
550
|
};
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
-
var isDevelopment = false;
|
|
554
|
-
|
|
555
553
|
var hyphenateRegex = /[A-Z]|^ms/g;
|
|
556
554
|
var animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g;
|
|
557
555
|
|
|
@@ -592,8 +590,6 @@ var processStyleValue = function processStyleValue(key, value) {
|
|
|
592
590
|
return value;
|
|
593
591
|
};
|
|
594
592
|
|
|
595
|
-
var noComponentSelectorMessage = 'Component selectors can only be used in conjunction with ' + '@emotion/babel-plugin, the swc Emotion plugin, or another Emotion-aware ' + 'compiler transform.';
|
|
596
|
-
|
|
597
593
|
function handleInterpolation(mergedProps, registered, interpolation) {
|
|
598
594
|
if (interpolation == null) {
|
|
599
595
|
return '';
|
|
@@ -644,7 +640,6 @@ function handleInterpolation(mergedProps, registered, interpolation) {
|
|
|
644
640
|
}
|
|
645
641
|
|
|
646
642
|
var styles = serializedStyles.styles + ";";
|
|
647
|
-
|
|
648
643
|
return styles;
|
|
649
644
|
}
|
|
650
645
|
|
|
@@ -683,9 +678,6 @@ function createStringFromObject(mergedProps, registered, obj) {
|
|
|
683
678
|
string += processStyleName(key) + ":" + processStyleValue(key, asString) + ";";
|
|
684
679
|
}
|
|
685
680
|
} else {
|
|
686
|
-
if (key === 'NO_COMPONENT_SELECTOR' && isDevelopment) {
|
|
687
|
-
throw new Error(noComponentSelectorMessage);
|
|
688
|
-
}
|
|
689
681
|
|
|
690
682
|
if (Array.isArray(value) && typeof value[0] === 'string' && (registered == null || registered[value[0]] === undefined)) {
|
|
691
683
|
for (var _i = 0; _i < value.length; _i++) {
|
|
@@ -718,10 +710,9 @@ function createStringFromObject(mergedProps, registered, obj) {
|
|
|
718
710
|
return string;
|
|
719
711
|
}
|
|
720
712
|
|
|
721
|
-
var labelPattern = /label:\s*([^\s
|
|
713
|
+
var labelPattern = /label:\s*([^\s;{]+)\s*(;|$)/g; // this is the cursor for keyframes
|
|
722
714
|
// keyframes are stored on the SerializedStyles object as a linked list
|
|
723
715
|
|
|
724
|
-
|
|
725
716
|
var cursor;
|
|
726
717
|
function serializeStyles(args, registered, mergedProps) {
|
|
727
718
|
if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && args[0].styles !== undefined) {
|
|
@@ -751,7 +742,7 @@ function serializeStyles(args, registered, mergedProps) {
|
|
|
751
742
|
|
|
752
743
|
styles += templateStringsArr[i];
|
|
753
744
|
}
|
|
754
|
-
}
|
|
745
|
+
} // using a global regex with .exec is stateful so lastIndex has to be reset each time
|
|
755
746
|
|
|
756
747
|
|
|
757
748
|
labelPattern.lastIndex = 0;
|
|
@@ -778,7 +769,7 @@ function getRegisteredStyles(registered, registeredStyles, classNames) {
|
|
|
778
769
|
classNames.split(' ').forEach(function (className) {
|
|
779
770
|
if (registered[className] !== undefined) {
|
|
780
771
|
registeredStyles.push(registered[className] + ";");
|
|
781
|
-
} else {
|
|
772
|
+
} else if (className) {
|
|
782
773
|
rawClassName += className + " ";
|
|
783
774
|
}
|
|
784
775
|
});
|
|
@@ -1113,7 +1104,6 @@ function createMakeStyles(params) {
|
|
|
1113
1104
|
css,
|
|
1114
1105
|
cx,
|
|
1115
1106
|
"name": name !== null && name !== void 0 ? name : "makeStyle no name",
|
|
1116
|
-
"idOfUseStyles": uniqId,
|
|
1117
1107
|
muiStyleOverridesParams,
|
|
1118
1108
|
// NOTE: If it's not a Mui Theme the plugin is resilient, it will not crash
|
|
1119
1109
|
"theme": theme
|
|
@@ -1987,10 +1977,12 @@ const useFooterStyles = makeStyles()((theme) => ({
|
|
|
1987
1977
|
|
|
1988
1978
|
const Footer = ({ items, serviceNameText, udirLink, udirLogo, }) => {
|
|
1989
1979
|
const { classes } = useFooterStyles();
|
|
1990
|
-
const renderItem = (item) => item.onClickItem ? (React__default.createElement(Button, { className: classes.itemBtn.concat(' ' + classes.itemText), onClick: item.onClickItem }, item.label)) : (React__default.createElement(ListItemText, { className: classes.itemText, primary: item.label,
|
|
1991
|
-
|
|
1980
|
+
const renderItem = (item) => item.onClickItem ? (React__default.createElement(Button, { className: classes.itemBtn.concat(' ' + classes.itemText), onClick: item.onClickItem }, item.label)) : (React__default.createElement(ListItemText, { className: classes.itemText, primary: item.label, slotProps: {
|
|
1981
|
+
primary: {
|
|
1982
|
+
style: { fontSize: 14, fontFamily: 'Montserrat', fontWeight: 400 },
|
|
1983
|
+
},
|
|
1992
1984
|
} }));
|
|
1993
|
-
return (React__default.createElement(
|
|
1985
|
+
return (React__default.createElement("footer", { className: classes.footer },
|
|
1994
1986
|
React__default.createElement(Box, { className: classes.content },
|
|
1995
1987
|
React__default.createElement("a", { href: udirLink },
|
|
1996
1988
|
React__default.createElement("img", { src: udirLogo, alt: "Utdanningsdirektoratet logo", style: { height: '43px', width: '150px' } })),
|
|
@@ -2000,9 +1992,8 @@ const Footer = ({ items, serviceNameText, udirLink, udirLogo, }) => {
|
|
|
2000
1992
|
paddingRight: '16px !important',
|
|
2001
1993
|
} },
|
|
2002
1994
|
React__default.createElement("span", { className: classes.serviceNameText }, serviceNameText),
|
|
2003
|
-
React__default.createElement(List, { className: classes.list }, items.map((item, i) => (React__default.createElement(ListItem, { key: i, classes: {
|
|
1995
|
+
React__default.createElement(List, { className: classes.list }, items.map((item, i) => (React__default.createElement(ListItem, { key: i + item.label, classes: {
|
|
2004
1996
|
root: classes.item,
|
|
2005
|
-
//button: onClickItem ? classes.itemBtn : undefined,
|
|
2006
1997
|
} }, item.render
|
|
2007
1998
|
? item.render(() => renderItem(item))
|
|
2008
1999
|
: renderItem(item)))))))));
|
|
@@ -2012,9 +2003,11 @@ const LinkList = (props) => (React__default.createElement(Box$1, { width: "100%"
|
|
|
2012
2003
|
React__default.createElement(Typography$1, { style: { fontSize: 24, color: Colors.black, marginBottom: 20 } }, props.title),
|
|
2013
2004
|
React__default.createElement(List$1, null, props.pages.map((page) => (React__default.createElement(Box$1, { key: page.id },
|
|
2014
2005
|
React__default.createElement(ListItemButton, { onClick: () => props.onPageClick(page), style: { padding: '12px 4px' } },
|
|
2015
|
-
React__default.createElement(ListItemText$1, { primary: page.label,
|
|
2016
|
-
|
|
2017
|
-
|
|
2006
|
+
React__default.createElement(ListItemText$1, { primary: page.label, slotProps: {
|
|
2007
|
+
primary: {
|
|
2008
|
+
color: 'primary',
|
|
2009
|
+
style: { fontSize: 18 },
|
|
2010
|
+
}
|
|
2018
2011
|
} }),
|
|
2019
2012
|
React__default.createElement(ListItemIcon, { style: { justifyContent: 'flex-end' } },
|
|
2020
2013
|
React__default.createElement(ArrowForward, { color: "primary" }))),
|
|
@@ -2199,13 +2192,15 @@ const PaginationActions = ({ count, page, rowsPerPage, onPageChange }) => {
|
|
|
2199
2192
|
|
|
2200
2193
|
const GrepTablePagination = (props) => {
|
|
2201
2194
|
const { classes } = usePaginationStyles();
|
|
2202
|
-
return (React__default.createElement(TablePagination, { classes: classes, rowsPerPageOptions: props.rowsPerPageOptions,
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2195
|
+
return (React__default.createElement(TablePagination, { classes: classes, rowsPerPageOptions: props.rowsPerPageOptions, slotProps: {
|
|
2196
|
+
select: {
|
|
2197
|
+
inputProps: {
|
|
2198
|
+
title: 'Velg antall elementer',
|
|
2199
|
+
},
|
|
2200
|
+
style: {
|
|
2201
|
+
gridArea: 'left',
|
|
2202
|
+
justifySelf: 'start',
|
|
2203
|
+
},
|
|
2209
2204
|
},
|
|
2210
2205
|
}, ActionsComponent: (actions) => (React__default.createElement(PaginationActions, { ...actions })), ...props }));
|
|
2211
2206
|
};
|
|
@@ -2532,7 +2527,7 @@ const useStyles$a = makeStyles()({
|
|
|
2532
2527
|
|
|
2533
2528
|
const SearchBar = (props) => {
|
|
2534
2529
|
const inputRef = React.useRef(null);
|
|
2535
|
-
const [value, setValue] = React.useState(props.initValue
|
|
2530
|
+
const [value, setValue] = React.useState(props.initValue ?? '');
|
|
2536
2531
|
const { classes } = useStyles$a();
|
|
2537
2532
|
React.useEffect(() => {
|
|
2538
2533
|
if (props.autoFocus && inputRef.current) {
|
|
@@ -2554,14 +2549,16 @@ const SearchBar = (props) => {
|
|
|
2554
2549
|
} },
|
|
2555
2550
|
React.createElement(Box, { className: classes.icon },
|
|
2556
2551
|
React.createElement(Search, null)),
|
|
2557
|
-
React.createElement(TextField, { id: props.id, role: "search", className: classes.input, value: value, variant: "standard", inputRef: inputRef, onChange: _handleChange, autoFocus: props.autoFocus, placeholder: props.placeholder,
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2552
|
+
React.createElement(TextField, { id: props.id, role: "search", className: classes.input, value: value, variant: "standard", inputRef: inputRef, onChange: _handleChange, autoFocus: props.autoFocus, placeholder: props.placeholder, slotProps: {
|
|
2553
|
+
input: {
|
|
2554
|
+
disableUnderline: true,
|
|
2555
|
+
fullWidth: true,
|
|
2556
|
+
inputProps: {
|
|
2557
|
+
title: props.title,
|
|
2558
|
+
},
|
|
2562
2559
|
},
|
|
2563
2560
|
} }),
|
|
2564
|
-
React.createElement(Box, { className: classes.icon, style: { cursor: 'pointer' } }, !!value.length && (React.createElement(Close, { "data-testid": "searchBarClearBtn", tabIndex: 0, onClick: _handleClear,
|
|
2561
|
+
React.createElement(Box, { className: classes.icon, style: { cursor: 'pointer' } }, !!value.length && (React.createElement(Close, { "data-testid": "searchBarClearBtn", tabIndex: 0, onClick: _handleClear, onKeyDown: keyboard.onActivation(_handleClear) })))),
|
|
2565
2562
|
React.createElement("div", { style: { display: 'flex', alignItems: 'center' } },
|
|
2566
2563
|
props.helpText && (React.createElement(Typography, { className: classes.helptext }, props.helpText)),
|
|
2567
2564
|
props.searchAllText && props.onSearchAll && (React.createElement(Button, { color: "primary", onClick: props.onSearchAll }, props.searchAllText)))));
|
|
@@ -2600,7 +2597,9 @@ const useStyles$8 = makeStyles()((theme) => ({
|
|
|
2600
2597
|
},
|
|
2601
2598
|
}));
|
|
2602
2599
|
|
|
2603
|
-
const renderField$1 = (id, label, value) => (React.createElement(TextField, { id: id, disabled: true, label: label, value: value, variant: "outlined", style: { margin: '10px 0' },
|
|
2600
|
+
const renderField$1 = (id, label, value) => (React.createElement(TextField, { id: id, disabled: true, label: label, value: value, variant: "outlined", style: { margin: '10px 0' }, slotProps: {
|
|
2601
|
+
input: { style: { color: 'rgb(84, 84, 84)' } }
|
|
2602
|
+
} }));
|
|
2604
2603
|
const ProfileInfo = (props) => {
|
|
2605
2604
|
const { classes } = useStyles$8();
|
|
2606
2605
|
return (React.createElement(Box, { className: classes.container },
|
|
@@ -2658,7 +2657,9 @@ const GDPR = ({ children }) => {
|
|
|
2658
2657
|
const GrepInput = ({ variant = 'standard', ...props }) => {
|
|
2659
2658
|
const { errorMessage, helperText, shrink, value, ...rest } = props;
|
|
2660
2659
|
const error = errorMessage ? errorMessage.length > 0 : false;
|
|
2661
|
-
return (React.createElement(TextField, { ...rest, variant: variant, helperText: errorMessage
|
|
2660
|
+
return (React.createElement(TextField, { ...rest, variant: variant, helperText: errorMessage ?? helperText, value: value === null ? '' : value, error: error || rest.error, slotProps: {
|
|
2661
|
+
inputLabel: { shrink },
|
|
2662
|
+
} }));
|
|
2662
2663
|
};
|
|
2663
2664
|
|
|
2664
2665
|
const GrepSelect = (props) => {
|
|
@@ -3229,10 +3230,10 @@ const GrepDateRange = ({ onChange, spacing = 3, style, fullWidth, from: fromProp
|
|
|
3229
3230
|
const [to, setTo] = useDate(toProperties.value);
|
|
3230
3231
|
const { minDate, maxDate, ...commonProperties } = properties;
|
|
3231
3232
|
useEffect(() => onChange(new DateRangeValue(from, to)), [String(from), String(to)]);
|
|
3232
|
-
return (React__default.createElement(
|
|
3233
|
-
React__default.createElement(
|
|
3233
|
+
return (React__default.createElement(Grid2, { container: true, spacing: spacing, style: style },
|
|
3234
|
+
React__default.createElement(Grid2, { size: { xs: 12, sm: fullWidth ? 12 : 6 } },
|
|
3234
3235
|
React__default.createElement(DatePicker, { id: String(fromProperties.label), fullWidth: true, minDate: minDate, ...commonProperties, ...fromProperties, value: from, maxDate: to?.subtract(1, 'day') || undefined, onChange: setFrom })),
|
|
3235
|
-
React__default.createElement(
|
|
3236
|
+
React__default.createElement(Grid2, { size: { xs: 12, sm: fullWidth ? 12 : 6 } },
|
|
3236
3237
|
React__default.createElement(DatePicker, { id: String(toProperties.label), fullWidth: true, maxDate: maxDate, ...commonProperties, ...toProperties, value: to, minDate: from?.add(1, 'day') || undefined, onChange: setTo }))));
|
|
3237
3238
|
};
|
|
3238
3239
|
|
|
@@ -3404,6 +3405,48 @@ const ServiceMessage = ({ id, message, isPublic, onDismiss }) => {
|
|
|
3404
3405
|
React.createElement(Close, { className: classes.close })))));
|
|
3405
3406
|
};
|
|
3406
3407
|
|
|
3408
|
+
function areInputsEqual$1(newInputs, lastInputs) {
|
|
3409
|
+
if (newInputs.length !== lastInputs.length) {
|
|
3410
|
+
return false;
|
|
3411
|
+
}
|
|
3412
|
+
|
|
3413
|
+
for (var i = 0; i < newInputs.length; i++) {
|
|
3414
|
+
if (newInputs[i] !== lastInputs[i]) {
|
|
3415
|
+
return false;
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3419
|
+
return true;
|
|
3420
|
+
}
|
|
3421
|
+
|
|
3422
|
+
function useMemoOne(getResult, inputs) {
|
|
3423
|
+
var initial = useState(function () {
|
|
3424
|
+
return {
|
|
3425
|
+
inputs: inputs,
|
|
3426
|
+
result: getResult()
|
|
3427
|
+
};
|
|
3428
|
+
})[0];
|
|
3429
|
+
var isFirstRun = useRef(true);
|
|
3430
|
+
var committed = useRef(initial);
|
|
3431
|
+
var useCache = isFirstRun.current || Boolean(inputs && committed.current.inputs && areInputsEqual$1(inputs, committed.current.inputs));
|
|
3432
|
+
var cache = useCache ? committed.current : {
|
|
3433
|
+
inputs: inputs,
|
|
3434
|
+
result: getResult()
|
|
3435
|
+
};
|
|
3436
|
+
useEffect(function () {
|
|
3437
|
+
isFirstRun.current = false;
|
|
3438
|
+
committed.current = cache;
|
|
3439
|
+
}, [cache]);
|
|
3440
|
+
return cache.result;
|
|
3441
|
+
}
|
|
3442
|
+
function useCallbackOne(callback, inputs) {
|
|
3443
|
+
return useMemoOne(function () {
|
|
3444
|
+
return callback;
|
|
3445
|
+
}, inputs);
|
|
3446
|
+
}
|
|
3447
|
+
var useMemo = useMemoOne;
|
|
3448
|
+
var useCallback = useCallbackOne;
|
|
3449
|
+
|
|
3407
3450
|
var isProduction$2 = process.env.NODE_ENV === 'production';
|
|
3408
3451
|
var prefix$2 = 'Invariant failed';
|
|
3409
3452
|
function invariant$1(condition, message) {
|
|
@@ -3564,6 +3607,56 @@ var getBox = function getBox(el) {
|
|
|
3564
3607
|
return calculateBox(borderBox, styles);
|
|
3565
3608
|
};
|
|
3566
3609
|
|
|
3610
|
+
var safeIsNaN = Number.isNaN ||
|
|
3611
|
+
function ponyfill(value) {
|
|
3612
|
+
return typeof value === 'number' && value !== value;
|
|
3613
|
+
};
|
|
3614
|
+
function isEqual$2(first, second) {
|
|
3615
|
+
if (first === second) {
|
|
3616
|
+
return true;
|
|
3617
|
+
}
|
|
3618
|
+
if (safeIsNaN(first) && safeIsNaN(second)) {
|
|
3619
|
+
return true;
|
|
3620
|
+
}
|
|
3621
|
+
return false;
|
|
3622
|
+
}
|
|
3623
|
+
function areInputsEqual(newInputs, lastInputs) {
|
|
3624
|
+
if (newInputs.length !== lastInputs.length) {
|
|
3625
|
+
return false;
|
|
3626
|
+
}
|
|
3627
|
+
for (var i = 0; i < newInputs.length; i++) {
|
|
3628
|
+
if (!isEqual$2(newInputs[i], lastInputs[i])) {
|
|
3629
|
+
return false;
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
return true;
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3635
|
+
function memoizeOne(resultFn, isEqual) {
|
|
3636
|
+
if (isEqual === void 0) { isEqual = areInputsEqual; }
|
|
3637
|
+
var cache = null;
|
|
3638
|
+
function memoized() {
|
|
3639
|
+
var newArgs = [];
|
|
3640
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
3641
|
+
newArgs[_i] = arguments[_i];
|
|
3642
|
+
}
|
|
3643
|
+
if (cache && cache.lastThis === this && isEqual(newArgs, cache.lastArgs)) {
|
|
3644
|
+
return cache.lastResult;
|
|
3645
|
+
}
|
|
3646
|
+
var lastResult = resultFn.apply(this, newArgs);
|
|
3647
|
+
cache = {
|
|
3648
|
+
lastResult: lastResult,
|
|
3649
|
+
lastArgs: newArgs,
|
|
3650
|
+
lastThis: this,
|
|
3651
|
+
};
|
|
3652
|
+
return lastResult;
|
|
3653
|
+
}
|
|
3654
|
+
memoized.clear = function clear() {
|
|
3655
|
+
cache = null;
|
|
3656
|
+
};
|
|
3657
|
+
return memoized;
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3567
3660
|
var rafSchd = function rafSchd(fn) {
|
|
3568
3661
|
var lastArgs = [];
|
|
3569
3662
|
var frameId = null;
|
|
@@ -3813,49 +3906,6 @@ const preset = {
|
|
|
3813
3906
|
onDragEnd
|
|
3814
3907
|
};
|
|
3815
3908
|
|
|
3816
|
-
function isEqual$2(first, second) {
|
|
3817
|
-
if (first === second) {
|
|
3818
|
-
return true;
|
|
3819
|
-
}
|
|
3820
|
-
if (Number.isNaN(first) && Number.isNaN(second)) {
|
|
3821
|
-
return true;
|
|
3822
|
-
}
|
|
3823
|
-
return false;
|
|
3824
|
-
}
|
|
3825
|
-
function areInputsEqual(newInputs, lastInputs) {
|
|
3826
|
-
if (newInputs.length !== lastInputs.length) {
|
|
3827
|
-
return false;
|
|
3828
|
-
}
|
|
3829
|
-
for (let i = 0; i < newInputs.length; i++) {
|
|
3830
|
-
if (!isEqual$2(newInputs[i], lastInputs[i])) {
|
|
3831
|
-
return false;
|
|
3832
|
-
}
|
|
3833
|
-
}
|
|
3834
|
-
return true;
|
|
3835
|
-
}
|
|
3836
|
-
|
|
3837
|
-
function useMemo(getResult, inputs) {
|
|
3838
|
-
const initial = useState(() => ({
|
|
3839
|
-
inputs,
|
|
3840
|
-
result: getResult()
|
|
3841
|
-
}))[0];
|
|
3842
|
-
const isFirstRun = useRef(true);
|
|
3843
|
-
const committed = useRef(initial);
|
|
3844
|
-
const useCache = isFirstRun.current || Boolean(inputs && committed.current.inputs && areInputsEqual(inputs, committed.current.inputs));
|
|
3845
|
-
const cache = useCache ? committed.current : {
|
|
3846
|
-
inputs,
|
|
3847
|
-
result: getResult()
|
|
3848
|
-
};
|
|
3849
|
-
useEffect(() => {
|
|
3850
|
-
isFirstRun.current = false;
|
|
3851
|
-
committed.current = cache;
|
|
3852
|
-
}, [cache]);
|
|
3853
|
-
return cache.result;
|
|
3854
|
-
}
|
|
3855
|
-
function useCallback(callback, inputs) {
|
|
3856
|
-
return useMemo(() => callback, inputs);
|
|
3857
|
-
}
|
|
3858
|
-
|
|
3859
3909
|
const origin = {
|
|
3860
3910
|
x: 0,
|
|
3861
3911
|
y: 0
|
|
@@ -3999,26 +4049,6 @@ var scrollDroppable = (droppable, newScroll) => {
|
|
|
3999
4049
|
return result;
|
|
4000
4050
|
};
|
|
4001
4051
|
|
|
4002
|
-
function memoizeOne(resultFn, isEqual = areInputsEqual) {
|
|
4003
|
-
let cache = null;
|
|
4004
|
-
function memoized(...newArgs) {
|
|
4005
|
-
if (cache && cache.lastThis === this && isEqual(newArgs, cache.lastArgs)) {
|
|
4006
|
-
return cache.lastResult;
|
|
4007
|
-
}
|
|
4008
|
-
const lastResult = resultFn.apply(this, newArgs);
|
|
4009
|
-
cache = {
|
|
4010
|
-
lastResult,
|
|
4011
|
-
lastArgs: newArgs,
|
|
4012
|
-
lastThis: this
|
|
4013
|
-
};
|
|
4014
|
-
return lastResult;
|
|
4015
|
-
}
|
|
4016
|
-
memoized.clear = function clear() {
|
|
4017
|
-
cache = null;
|
|
4018
|
-
};
|
|
4019
|
-
return memoized;
|
|
4020
|
-
}
|
|
4021
|
-
|
|
4022
4052
|
const toDroppableMap = memoizeOne(droppables => droppables.reduce((previous, current) => {
|
|
4023
4053
|
previous[current.descriptor.id] = current;
|
|
4024
4054
|
return previous;
|
|
@@ -5770,7 +5800,6 @@ var adjustAdditionsForScrollChanges = ({
|
|
|
5770
5800
|
return moved;
|
|
5771
5801
|
});
|
|
5772
5802
|
};
|
|
5773
|
-
|
|
5774
5803
|
var publishWhileDraggingInVirtual = ({
|
|
5775
5804
|
state,
|
|
5776
5805
|
published
|
|
@@ -8383,7 +8412,9 @@ function useHiddenTextElement({
|
|
|
8383
8412
|
var AppContext = React__default.createContext(null);
|
|
8384
8413
|
|
|
8385
8414
|
var peerDependencies = {
|
|
8386
|
-
react: "^18.0.0
|
|
8415
|
+
react: "^18.0.0",
|
|
8416
|
+
"react-dom": "^18.0.0"
|
|
8417
|
+
};
|
|
8387
8418
|
|
|
8388
8419
|
const semver = /(\d+)\.(\d+)\.(\d+)/;
|
|
8389
8420
|
const getVersion = value => {
|
|
@@ -11099,6 +11130,7 @@ const ConnectedDroppable = connect(makeMapStateToProps, mapDispatchToProps, (sta
|
|
|
11099
11130
|
context: StoreContext,
|
|
11100
11131
|
areStatePropsEqual: isStrictEqual
|
|
11101
11132
|
})(Droppable);
|
|
11133
|
+
var ConnectedDroppable$1 = ConnectedDroppable;
|
|
11102
11134
|
|
|
11103
11135
|
const setDimensions = (el) => {
|
|
11104
11136
|
const { width, height } = el.getBoundingClientRect();
|
|
@@ -11110,7 +11142,7 @@ const clearDimensions = (el) => {
|
|
|
11110
11142
|
el.style.removeProperty('width');
|
|
11111
11143
|
};
|
|
11112
11144
|
function SortableTableCell({ locked, children, ...props }) {
|
|
11113
|
-
const ref = useRef(
|
|
11145
|
+
const ref = useRef();
|
|
11114
11146
|
useMemo$1(() => {
|
|
11115
11147
|
if (ref.current) {
|
|
11116
11148
|
locked ? setDimensions(ref.current) : clearDimensions(ref.current);
|
|
@@ -11189,7 +11221,7 @@ const SortableTable = ({ columns, items, identify, headerValue, cellValue, disab
|
|
|
11189
11221
|
return (React__default.createElement(SortableTableCell, { key: `header-${index}`, locked: isDragging, ...properties }, value));
|
|
11190
11222
|
}))),
|
|
11191
11223
|
React__default.createElement(DragDropContext, { onDragEnd: onDragEnd, onBeforeDragStart: onDragStart },
|
|
11192
|
-
React__default.createElement(ConnectedDroppable, { droppableId: "droppable", direction: "vertical" }, (provided) => (React__default.createElement(TableBody, { ref: provided.innerRef, ...provided.droppableProps },
|
|
11224
|
+
React__default.createElement(ConnectedDroppable$1, { droppableId: "droppable", direction: "vertical" }, (provided) => (React__default.createElement(TableBody, { ref: provided.innerRef, ...provided.droppableProps },
|
|
11193
11225
|
records.map((item, index) => {
|
|
11194
11226
|
const props = {
|
|
11195
11227
|
id: identify(item),
|
|
@@ -11203,174 +11235,3493 @@ const SortableTable = ({ columns, items, identify, headerValue, cellValue, disab
|
|
|
11203
11235
|
provided.placeholder))))));
|
|
11204
11236
|
};
|
|
11205
11237
|
|
|
11206
|
-
|
|
11207
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11208
|
-
*
|
|
11209
|
-
* This source code is licensed under the MIT license found in the
|
|
11210
|
-
* LICENSE file in the root directory of this source tree.
|
|
11211
|
-
*
|
|
11212
|
-
*/
|
|
11238
|
+
var LexicalRichText_dev = {};
|
|
11213
11239
|
|
|
11214
|
-
|
|
11240
|
+
var LexicalClipboard_dev = {};
|
|
11215
11241
|
|
|
11216
|
-
|
|
11217
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11218
|
-
*
|
|
11219
|
-
* This source code is licensed under the MIT license found in the
|
|
11220
|
-
* LICENSE file in the root directory of this source tree.
|
|
11221
|
-
*
|
|
11222
|
-
*/
|
|
11242
|
+
var LexicalHtml_dev = {};
|
|
11223
11243
|
|
|
11224
|
-
|
|
11244
|
+
var LexicalSelection_dev = {};
|
|
11225
11245
|
|
|
11226
11246
|
/**
|
|
11227
11247
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11228
11248
|
*
|
|
11229
11249
|
* This source code is licensed under the MIT license found in the
|
|
11230
11250
|
* LICENSE file in the root directory of this source tree.
|
|
11231
|
-
*
|
|
11232
11251
|
*/
|
|
11233
11252
|
|
|
11234
|
-
|
|
11253
|
+
var hasRequiredLexicalSelection_dev;
|
|
11235
11254
|
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
* This source code is licensed under the MIT license found in the
|
|
11240
|
-
* LICENSE file in the root directory of this source tree.
|
|
11241
|
-
*
|
|
11242
|
-
*/
|
|
11255
|
+
function requireLexicalSelection_dev () {
|
|
11256
|
+
if (hasRequiredLexicalSelection_dev) return LexicalSelection_dev;
|
|
11257
|
+
hasRequiredLexicalSelection_dev = 1;
|
|
11243
11258
|
|
|
11244
|
-
|
|
11259
|
+
var lexical = require$$3;
|
|
11245
11260
|
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
position: 'absolute',
|
|
11255
|
-
top: -5,
|
|
11256
|
-
left: 0,
|
|
11257
|
-
right: 0,
|
|
11258
|
-
bottom: 0,
|
|
11259
|
-
lineHeight: '11px',
|
|
11260
|
-
zIndex: hasFocus ? 0 : 1,
|
|
11261
|
-
paddingLeft: 10,
|
|
11262
|
-
borderStyle: 'solid',
|
|
11263
|
-
borderRadius: theme.shape.borderRadius,
|
|
11264
|
-
borderWidth: hasFocus ? 2 : 1,
|
|
11265
|
-
borderColor: hasFocus
|
|
11266
|
-
? theme.palette.primary.main
|
|
11267
|
-
: hex2rgba('#000', 0.23),
|
|
11268
|
-
'&:hover': {
|
|
11269
|
-
borderColor: hasFocus
|
|
11270
|
-
? theme.palette.primary.main
|
|
11271
|
-
: theme.palette.text.primary,
|
|
11272
|
-
},
|
|
11273
|
-
transition: theme.transitions.create(['border-color'], {
|
|
11274
|
-
duration: theme.transitions.duration.shorter,
|
|
11275
|
-
easing: theme.transitions.easing.easeOut,
|
|
11276
|
-
}),
|
|
11277
|
-
},
|
|
11278
|
-
editor: {
|
|
11279
|
-
padding: '.8rem 1rem',
|
|
11280
|
-
position: 'relative',
|
|
11281
|
-
zIndex: hasFocus || readOnly ? 1 : 0,
|
|
11282
|
-
'& .unstyled': {
|
|
11283
|
-
margin: '.5rem 0',
|
|
11284
|
-
},
|
|
11285
|
-
},
|
|
11286
|
-
label: {
|
|
11287
|
-
position: 'absolute',
|
|
11288
|
-
top: 0,
|
|
11289
|
-
left: 0,
|
|
11290
|
-
zIndex: 1,
|
|
11291
|
-
transform: hasFocus || hasContent
|
|
11292
|
-
? 'translate(6px, -14px) scale(0.75)'
|
|
11293
|
-
: 'translate(6px, 12px) scale(1)',
|
|
11294
|
-
transformOrigin: 'top left',
|
|
11295
|
-
transition: theme.transitions.create(['color', 'transform'], {
|
|
11296
|
-
duration: theme.transitions.duration.shorter,
|
|
11297
|
-
easing: theme.transitions.easing.easeOut,
|
|
11298
|
-
}),
|
|
11299
|
-
color: hasFocus
|
|
11300
|
-
? theme.palette.primary[theme.palette.mode === 'light' ? 'dark' : 'light']
|
|
11301
|
-
: theme.palette.text.secondary,
|
|
11302
|
-
fontSize: '1.1428571428571428rem',
|
|
11303
|
-
// hack @todo when time
|
|
11304
|
-
backgroundColor: 'white',
|
|
11305
|
-
padding: '2px 10px',
|
|
11306
|
-
},
|
|
11307
|
-
helpertext: {
|
|
11308
|
-
margin: 0,
|
|
11309
|
-
opacity: hasFocus ? 1 : 0,
|
|
11310
|
-
transition: theme.transitions.create(['opacity'], {
|
|
11311
|
-
duration: theme.transitions.duration.shorter,
|
|
11312
|
-
easing: theme.transitions.easing.easeOut,
|
|
11313
|
-
}),
|
|
11314
|
-
fontSize: 'small',
|
|
11315
|
-
// hack @todo when time
|
|
11316
|
-
backgroundColor: 'white',
|
|
11317
|
-
padding: '2px 10px',
|
|
11318
|
-
},
|
|
11319
|
-
charcount: {
|
|
11320
|
-
margin: 0,
|
|
11321
|
-
transition: theme.transitions.create(['opacity'], {
|
|
11322
|
-
duration: theme.transitions.duration.shorter,
|
|
11323
|
-
easing: theme.transitions.easing.easeOut,
|
|
11324
|
-
}),
|
|
11325
|
-
fontSize: 'small',
|
|
11326
|
-
// hack @todo when time
|
|
11327
|
-
backgroundColor: 'white',
|
|
11328
|
-
padding: '2px 10px',
|
|
11329
|
-
},
|
|
11330
|
-
}));
|
|
11261
|
+
/**
|
|
11262
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11263
|
+
*
|
|
11264
|
+
* This source code is licensed under the MIT license found in the
|
|
11265
|
+
* LICENSE file in the root directory of this source tree.
|
|
11266
|
+
*
|
|
11267
|
+
*/
|
|
11268
|
+
const CSS_TO_STYLES = new Map();
|
|
11331
11269
|
|
|
11332
|
-
|
|
11270
|
+
/**
|
|
11271
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11272
|
+
*
|
|
11273
|
+
* This source code is licensed under the MIT license found in the
|
|
11274
|
+
* LICENSE file in the root directory of this source tree.
|
|
11275
|
+
*
|
|
11276
|
+
*/
|
|
11277
|
+
function getDOMTextNode(element) {
|
|
11278
|
+
let node = element;
|
|
11279
|
+
while (node != null) {
|
|
11280
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
11281
|
+
return node;
|
|
11282
|
+
}
|
|
11283
|
+
node = node.firstChild;
|
|
11284
|
+
}
|
|
11285
|
+
return null;
|
|
11286
|
+
}
|
|
11287
|
+
function getDOMIndexWithinParent(node) {
|
|
11288
|
+
const parent = node.parentNode;
|
|
11289
|
+
if (parent == null) {
|
|
11290
|
+
throw new Error('Should never happen');
|
|
11291
|
+
}
|
|
11292
|
+
return [parent, Array.from(parent.childNodes).indexOf(node)];
|
|
11293
|
+
}
|
|
11333
11294
|
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11295
|
+
/**
|
|
11296
|
+
* Creates a selection range for the DOM.
|
|
11297
|
+
* @param editor - The lexical editor.
|
|
11298
|
+
* @param anchorNode - The anchor node of a selection.
|
|
11299
|
+
* @param _anchorOffset - The amount of space offset from the anchor to the focus.
|
|
11300
|
+
* @param focusNode - The current focus.
|
|
11301
|
+
* @param _focusOffset - The amount of space offset from the focus to the anchor.
|
|
11302
|
+
* @returns The range of selection for the DOM that was created.
|
|
11303
|
+
*/
|
|
11304
|
+
function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffset) {
|
|
11305
|
+
const anchorKey = anchorNode.getKey();
|
|
11306
|
+
const focusKey = focusNode.getKey();
|
|
11307
|
+
const range = document.createRange();
|
|
11308
|
+
let anchorDOM = editor.getElementByKey(anchorKey);
|
|
11309
|
+
let focusDOM = editor.getElementByKey(focusKey);
|
|
11310
|
+
let anchorOffset = _anchorOffset;
|
|
11311
|
+
let focusOffset = _focusOffset;
|
|
11312
|
+
if (lexical.$isTextNode(anchorNode)) {
|
|
11313
|
+
anchorDOM = getDOMTextNode(anchorDOM);
|
|
11314
|
+
}
|
|
11315
|
+
if (lexical.$isTextNode(focusNode)) {
|
|
11316
|
+
focusDOM = getDOMTextNode(focusDOM);
|
|
11317
|
+
}
|
|
11318
|
+
if (anchorNode === undefined || focusNode === undefined || anchorDOM === null || focusDOM === null) {
|
|
11319
|
+
return null;
|
|
11320
|
+
}
|
|
11321
|
+
if (anchorDOM.nodeName === 'BR') {
|
|
11322
|
+
[anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM);
|
|
11323
|
+
}
|
|
11324
|
+
if (focusDOM.nodeName === 'BR') {
|
|
11325
|
+
[focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM);
|
|
11326
|
+
}
|
|
11327
|
+
const firstChild = anchorDOM.firstChild;
|
|
11328
|
+
if (anchorDOM === focusDOM && firstChild != null && firstChild.nodeName === 'BR' && anchorOffset === 0 && focusOffset === 0) {
|
|
11329
|
+
focusOffset = 1;
|
|
11330
|
+
}
|
|
11331
|
+
try {
|
|
11332
|
+
range.setStart(anchorDOM, anchorOffset);
|
|
11333
|
+
range.setEnd(focusDOM, focusOffset);
|
|
11334
|
+
} catch (e) {
|
|
11335
|
+
return null;
|
|
11336
|
+
}
|
|
11337
|
+
if (range.collapsed && (anchorOffset !== focusOffset || anchorKey !== focusKey)) {
|
|
11338
|
+
// Range is backwards, we need to reverse it
|
|
11339
|
+
range.setStart(focusDOM, focusOffset);
|
|
11340
|
+
range.setEnd(anchorDOM, anchorOffset);
|
|
11341
|
+
}
|
|
11342
|
+
return range;
|
|
11343
|
+
}
|
|
11344
|
+
|
|
11345
|
+
/**
|
|
11346
|
+
* Creates DOMRects, generally used to help the editor find a specific location on the screen.
|
|
11347
|
+
* @param editor - The lexical editor
|
|
11348
|
+
* @param range - A fragment of a document that can contain nodes and parts of text nodes.
|
|
11349
|
+
* @returns The selectionRects as an array.
|
|
11350
|
+
*/
|
|
11351
|
+
function createRectsFromDOMRange(editor, range) {
|
|
11352
|
+
const rootElement = editor.getRootElement();
|
|
11353
|
+
if (rootElement === null) {
|
|
11354
|
+
return [];
|
|
11355
|
+
}
|
|
11356
|
+
const rootRect = rootElement.getBoundingClientRect();
|
|
11357
|
+
const computedStyle = getComputedStyle(rootElement);
|
|
11358
|
+
const rootPadding = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
|
|
11359
|
+
const selectionRects = Array.from(range.getClientRects());
|
|
11360
|
+
let selectionRectsLength = selectionRects.length;
|
|
11361
|
+
//sort rects from top left to bottom right.
|
|
11362
|
+
selectionRects.sort((a, b) => {
|
|
11363
|
+
const top = a.top - b.top;
|
|
11364
|
+
// Some rects match position closely, but not perfectly,
|
|
11365
|
+
// so we give a 3px tolerance.
|
|
11366
|
+
if (Math.abs(top) <= 3) {
|
|
11367
|
+
return a.left - b.left;
|
|
11368
|
+
}
|
|
11369
|
+
return top;
|
|
11370
|
+
});
|
|
11371
|
+
let prevRect;
|
|
11372
|
+
for (let i = 0; i < selectionRectsLength; i++) {
|
|
11373
|
+
const selectionRect = selectionRects[i];
|
|
11374
|
+
// Exclude rects that overlap preceding Rects in the sorted list.
|
|
11375
|
+
const isOverlappingRect = prevRect && prevRect.top <= selectionRect.top && prevRect.top + prevRect.height > selectionRect.top && prevRect.left + prevRect.width > selectionRect.left;
|
|
11376
|
+
// Exclude selections that span the entire element
|
|
11377
|
+
const selectionSpansElement = selectionRect.width + rootPadding === rootRect.width;
|
|
11378
|
+
if (isOverlappingRect || selectionSpansElement) {
|
|
11379
|
+
selectionRects.splice(i--, 1);
|
|
11380
|
+
selectionRectsLength--;
|
|
11381
|
+
continue;
|
|
11382
|
+
}
|
|
11383
|
+
prevRect = selectionRect;
|
|
11384
|
+
}
|
|
11385
|
+
return selectionRects;
|
|
11386
|
+
}
|
|
11387
|
+
|
|
11388
|
+
/**
|
|
11389
|
+
* Creates an object containing all the styles and their values provided in the CSS string.
|
|
11390
|
+
* @param css - The CSS string of styles and their values.
|
|
11391
|
+
* @returns The styleObject containing all the styles and their values.
|
|
11392
|
+
*/
|
|
11393
|
+
function getStyleObjectFromRawCSS(css) {
|
|
11394
|
+
const styleObject = {};
|
|
11395
|
+
const styles = css.split(';');
|
|
11396
|
+
for (const style of styles) {
|
|
11397
|
+
if (style !== '') {
|
|
11398
|
+
const [key, value] = style.split(/:([^]+)/); // split on first colon
|
|
11399
|
+
if (key && value) {
|
|
11400
|
+
styleObject[key.trim()] = value.trim();
|
|
11401
|
+
}
|
|
11402
|
+
}
|
|
11403
|
+
}
|
|
11404
|
+
return styleObject;
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11407
|
+
/**
|
|
11408
|
+
* Given a CSS string, returns an object from the style cache.
|
|
11409
|
+
* @param css - The CSS property as a string.
|
|
11410
|
+
* @returns The value of the given CSS property.
|
|
11411
|
+
*/
|
|
11412
|
+
function getStyleObjectFromCSS(css) {
|
|
11413
|
+
let value = CSS_TO_STYLES.get(css);
|
|
11414
|
+
if (value === undefined) {
|
|
11415
|
+
value = getStyleObjectFromRawCSS(css);
|
|
11416
|
+
CSS_TO_STYLES.set(css, value);
|
|
11417
|
+
}
|
|
11418
|
+
{
|
|
11419
|
+
// Freeze the value in DEV to prevent accidental mutations
|
|
11420
|
+
Object.freeze(value);
|
|
11421
|
+
}
|
|
11422
|
+
return value;
|
|
11423
|
+
}
|
|
11424
|
+
|
|
11425
|
+
/**
|
|
11426
|
+
* Gets the CSS styles from the style object.
|
|
11427
|
+
* @param styles - The style object containing the styles to get.
|
|
11428
|
+
* @returns A string containing the CSS styles and their values.
|
|
11429
|
+
*/
|
|
11430
|
+
function getCSSFromStyleObject(styles) {
|
|
11431
|
+
let css = '';
|
|
11432
|
+
for (const style in styles) {
|
|
11433
|
+
if (style) {
|
|
11434
|
+
css += `${style}: ${styles[style]};`;
|
|
11435
|
+
}
|
|
11436
|
+
}
|
|
11437
|
+
return css;
|
|
11438
|
+
}
|
|
11439
|
+
|
|
11440
|
+
/**
|
|
11441
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11442
|
+
*
|
|
11443
|
+
* This source code is licensed under the MIT license found in the
|
|
11444
|
+
* LICENSE file in the root directory of this source tree.
|
|
11445
|
+
*
|
|
11446
|
+
*/
|
|
11447
|
+
function $updateElementNodeProperties(target, source) {
|
|
11448
|
+
target.__first = source.__first;
|
|
11449
|
+
target.__last = source.__last;
|
|
11450
|
+
target.__size = source.__size;
|
|
11451
|
+
target.__format = source.__format;
|
|
11452
|
+
target.__indent = source.__indent;
|
|
11453
|
+
target.__dir = source.__dir;
|
|
11454
|
+
return target;
|
|
11455
|
+
}
|
|
11456
|
+
function $updateTextNodeProperties(target, source) {
|
|
11457
|
+
target.__format = source.__format;
|
|
11458
|
+
target.__style = source.__style;
|
|
11459
|
+
target.__mode = source.__mode;
|
|
11460
|
+
target.__detail = source.__detail;
|
|
11461
|
+
return target;
|
|
11462
|
+
}
|
|
11463
|
+
|
|
11464
|
+
/**
|
|
11465
|
+
* Returns a copy of a node, but generates a new key for the copy.
|
|
11466
|
+
* @param node - The node to be cloned.
|
|
11467
|
+
* @returns The clone of the node.
|
|
11468
|
+
*/
|
|
11469
|
+
function $cloneWithProperties(node) {
|
|
11470
|
+
const constructor = node.constructor;
|
|
11471
|
+
// @ts-expect-error
|
|
11472
|
+
const clone = constructor.clone(node);
|
|
11473
|
+
clone.__parent = node.__parent;
|
|
11474
|
+
clone.__next = node.__next;
|
|
11475
|
+
clone.__prev = node.__prev;
|
|
11476
|
+
if (lexical.$isElementNode(node) && lexical.$isElementNode(clone)) {
|
|
11477
|
+
return $updateElementNodeProperties(clone, node);
|
|
11478
|
+
}
|
|
11479
|
+
if (lexical.$isTextNode(node) && lexical.$isTextNode(clone)) {
|
|
11480
|
+
return $updateTextNodeProperties(clone, node);
|
|
11481
|
+
}
|
|
11482
|
+
return clone;
|
|
11483
|
+
}
|
|
11484
|
+
|
|
11485
|
+
/**
|
|
11486
|
+
* Generally used to append text content to HTML and JSON. Grabs the text content and "slices"
|
|
11487
|
+
* it to be generated into the new TextNode.
|
|
11488
|
+
* @param selection - The selection containing the node whose TextNode is to be edited.
|
|
11489
|
+
* @param textNode - The TextNode to be edited.
|
|
11490
|
+
* @returns The updated TextNode.
|
|
11491
|
+
*/
|
|
11492
|
+
function $sliceSelectedTextNodeContent(selection, textNode) {
|
|
11493
|
+
const anchorAndFocus = selection.getStartEndPoints();
|
|
11494
|
+
if (textNode.isSelected(selection) && !textNode.isSegmented() && !textNode.isToken() && anchorAndFocus !== null) {
|
|
11495
|
+
const [anchor, focus] = anchorAndFocus;
|
|
11496
|
+
const isBackward = selection.isBackward();
|
|
11497
|
+
const anchorNode = anchor.getNode();
|
|
11498
|
+
const focusNode = focus.getNode();
|
|
11499
|
+
const isAnchor = textNode.is(anchorNode);
|
|
11500
|
+
const isFocus = textNode.is(focusNode);
|
|
11501
|
+
if (isAnchor || isFocus) {
|
|
11502
|
+
const [anchorOffset, focusOffset] = lexical.$getCharacterOffsets(selection);
|
|
11503
|
+
const isSame = anchorNode.is(focusNode);
|
|
11504
|
+
const isFirst = textNode.is(isBackward ? focusNode : anchorNode);
|
|
11505
|
+
const isLast = textNode.is(isBackward ? anchorNode : focusNode);
|
|
11506
|
+
let startOffset = 0;
|
|
11507
|
+
let endOffset = undefined;
|
|
11508
|
+
if (isSame) {
|
|
11509
|
+
startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
|
|
11510
|
+
endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
|
|
11511
|
+
} else if (isFirst) {
|
|
11512
|
+
const offset = isBackward ? focusOffset : anchorOffset;
|
|
11513
|
+
startOffset = offset;
|
|
11514
|
+
endOffset = undefined;
|
|
11515
|
+
} else if (isLast) {
|
|
11516
|
+
const offset = isBackward ? anchorOffset : focusOffset;
|
|
11517
|
+
startOffset = 0;
|
|
11518
|
+
endOffset = offset;
|
|
11519
|
+
}
|
|
11520
|
+
textNode.__text = textNode.__text.slice(startOffset, endOffset);
|
|
11521
|
+
return textNode;
|
|
11522
|
+
}
|
|
11523
|
+
}
|
|
11524
|
+
return textNode;
|
|
11525
|
+
}
|
|
11526
|
+
|
|
11527
|
+
/**
|
|
11528
|
+
* Determines if the current selection is at the end of the node.
|
|
11529
|
+
* @param point - The point of the selection to test.
|
|
11530
|
+
* @returns true if the provided point offset is in the last possible position, false otherwise.
|
|
11531
|
+
*/
|
|
11532
|
+
function $isAtNodeEnd(point) {
|
|
11533
|
+
if (point.type === 'text') {
|
|
11534
|
+
return point.offset === point.getNode().getTextContentSize();
|
|
11535
|
+
}
|
|
11536
|
+
const node = point.getNode();
|
|
11537
|
+
if (!lexical.$isElementNode(node)) {
|
|
11538
|
+
throw Error(`isAtNodeEnd: node must be a TextNode or ElementNode`);
|
|
11539
|
+
}
|
|
11540
|
+
return point.offset === node.getChildrenSize();
|
|
11541
|
+
}
|
|
11542
|
+
|
|
11543
|
+
/**
|
|
11544
|
+
* Trims text from a node in order to shorten it, eg. to enforce a text's max length. If it deletes text
|
|
11545
|
+
* that is an ancestor of the anchor then it will leave 2 indents, otherwise, if no text content exists, it deletes
|
|
11546
|
+
* the TextNode. It will move the focus to either the end of any left over text or beginning of a new TextNode.
|
|
11547
|
+
* @param editor - The lexical editor.
|
|
11548
|
+
* @param anchor - The anchor of the current selection, where the selection should be pointing.
|
|
11549
|
+
* @param delCount - The amount of characters to delete. Useful as a dynamic variable eg. textContentSize - maxLength;
|
|
11550
|
+
*/
|
|
11551
|
+
function trimTextContentFromAnchor(editor, anchor, delCount) {
|
|
11552
|
+
// Work from the current selection anchor point
|
|
11553
|
+
let currentNode = anchor.getNode();
|
|
11554
|
+
let remaining = delCount;
|
|
11555
|
+
if (lexical.$isElementNode(currentNode)) {
|
|
11556
|
+
const descendantNode = currentNode.getDescendantByIndex(anchor.offset);
|
|
11557
|
+
if (descendantNode !== null) {
|
|
11558
|
+
currentNode = descendantNode;
|
|
11559
|
+
}
|
|
11560
|
+
}
|
|
11561
|
+
while (remaining > 0 && currentNode !== null) {
|
|
11562
|
+
if (lexical.$isElementNode(currentNode)) {
|
|
11563
|
+
const lastDescendant = currentNode.getLastDescendant();
|
|
11564
|
+
if (lastDescendant !== null) {
|
|
11565
|
+
currentNode = lastDescendant;
|
|
11566
|
+
}
|
|
11567
|
+
}
|
|
11568
|
+
let nextNode = currentNode.getPreviousSibling();
|
|
11569
|
+
let additionalElementWhitespace = 0;
|
|
11570
|
+
if (nextNode === null) {
|
|
11571
|
+
let parent = currentNode.getParentOrThrow();
|
|
11572
|
+
let parentSibling = parent.getPreviousSibling();
|
|
11573
|
+
while (parentSibling === null) {
|
|
11574
|
+
parent = parent.getParent();
|
|
11575
|
+
if (parent === null) {
|
|
11576
|
+
nextNode = null;
|
|
11577
|
+
break;
|
|
11578
|
+
}
|
|
11579
|
+
parentSibling = parent.getPreviousSibling();
|
|
11580
|
+
}
|
|
11581
|
+
if (parent !== null) {
|
|
11582
|
+
additionalElementWhitespace = parent.isInline() ? 0 : 2;
|
|
11583
|
+
nextNode = parentSibling;
|
|
11584
|
+
}
|
|
11585
|
+
}
|
|
11586
|
+
let text = currentNode.getTextContent();
|
|
11587
|
+
// If the text is empty, we need to consider adding in two line breaks to match
|
|
11588
|
+
// the content if we were to get it from its parent.
|
|
11589
|
+
if (text === '' && lexical.$isElementNode(currentNode) && !currentNode.isInline()) {
|
|
11590
|
+
// TODO: should this be handled in core?
|
|
11591
|
+
text = '\n\n';
|
|
11592
|
+
}
|
|
11593
|
+
const currentNodeSize = text.length;
|
|
11594
|
+
if (!lexical.$isTextNode(currentNode) || remaining >= currentNodeSize) {
|
|
11595
|
+
const parent = currentNode.getParent();
|
|
11596
|
+
currentNode.remove();
|
|
11597
|
+
if (parent != null && parent.getChildrenSize() === 0 && !lexical.$isRootNode(parent)) {
|
|
11598
|
+
parent.remove();
|
|
11599
|
+
}
|
|
11600
|
+
remaining -= currentNodeSize + additionalElementWhitespace;
|
|
11601
|
+
currentNode = nextNode;
|
|
11602
|
+
} else {
|
|
11603
|
+
const key = currentNode.getKey();
|
|
11604
|
+
// See if we can just revert it to what was in the last editor state
|
|
11605
|
+
const prevTextContent = editor.getEditorState().read(() => {
|
|
11606
|
+
const prevNode = lexical.$getNodeByKey(key);
|
|
11607
|
+
if (lexical.$isTextNode(prevNode) && prevNode.isSimpleText()) {
|
|
11608
|
+
return prevNode.getTextContent();
|
|
11609
|
+
}
|
|
11610
|
+
return null;
|
|
11611
|
+
});
|
|
11612
|
+
const offset = currentNodeSize - remaining;
|
|
11613
|
+
const slicedText = text.slice(0, offset);
|
|
11614
|
+
if (prevTextContent !== null && prevTextContent !== text) {
|
|
11615
|
+
const prevSelection = lexical.$getPreviousSelection();
|
|
11616
|
+
let target = currentNode;
|
|
11617
|
+
if (!currentNode.isSimpleText()) {
|
|
11618
|
+
const textNode = lexical.$createTextNode(prevTextContent);
|
|
11619
|
+
currentNode.replace(textNode);
|
|
11620
|
+
target = textNode;
|
|
11621
|
+
} else {
|
|
11622
|
+
currentNode.setTextContent(prevTextContent);
|
|
11623
|
+
}
|
|
11624
|
+
if (lexical.$isRangeSelection(prevSelection) && prevSelection.isCollapsed()) {
|
|
11625
|
+
const prevOffset = prevSelection.anchor.offset;
|
|
11626
|
+
target.select(prevOffset, prevOffset);
|
|
11627
|
+
}
|
|
11628
|
+
} else if (currentNode.isSimpleText()) {
|
|
11629
|
+
// Split text
|
|
11630
|
+
const isSelected = anchor.key === key;
|
|
11631
|
+
let anchorOffset = anchor.offset;
|
|
11632
|
+
// Move offset to end if it's less than the remaining number, otherwise
|
|
11633
|
+
// we'll have a negative splitStart.
|
|
11634
|
+
if (anchorOffset < remaining) {
|
|
11635
|
+
anchorOffset = currentNodeSize;
|
|
11636
|
+
}
|
|
11637
|
+
const splitStart = isSelected ? anchorOffset - remaining : 0;
|
|
11638
|
+
const splitEnd = isSelected ? anchorOffset : offset;
|
|
11639
|
+
if (isSelected && splitStart === 0) {
|
|
11640
|
+
const [excessNode] = currentNode.splitText(splitStart, splitEnd);
|
|
11641
|
+
excessNode.remove();
|
|
11642
|
+
} else {
|
|
11643
|
+
const [, excessNode] = currentNode.splitText(splitStart, splitEnd);
|
|
11644
|
+
excessNode.remove();
|
|
11645
|
+
}
|
|
11646
|
+
} else {
|
|
11647
|
+
const textNode = lexical.$createTextNode(slicedText);
|
|
11648
|
+
currentNode.replace(textNode);
|
|
11649
|
+
}
|
|
11650
|
+
remaining = 0;
|
|
11651
|
+
}
|
|
11652
|
+
}
|
|
11653
|
+
}
|
|
11654
|
+
|
|
11655
|
+
/**
|
|
11656
|
+
* Gets the TextNode's style object and adds the styles to the CSS.
|
|
11657
|
+
* @param node - The TextNode to add styles to.
|
|
11658
|
+
*/
|
|
11659
|
+
function $addNodeStyle(node) {
|
|
11660
|
+
const CSSText = node.getStyle();
|
|
11661
|
+
const styles = getStyleObjectFromRawCSS(CSSText);
|
|
11662
|
+
CSS_TO_STYLES.set(CSSText, styles);
|
|
11663
|
+
}
|
|
11664
|
+
function $patchStyle(target, patch) {
|
|
11665
|
+
const prevStyles = getStyleObjectFromCSS('getStyle' in target ? target.getStyle() : target.style);
|
|
11666
|
+
const newStyles = Object.entries(patch).reduce((styles, [key, value]) => {
|
|
11667
|
+
if (value instanceof Function) {
|
|
11668
|
+
styles[key] = value(prevStyles[key]);
|
|
11669
|
+
} else if (value === null) {
|
|
11670
|
+
delete styles[key];
|
|
11671
|
+
} else {
|
|
11672
|
+
styles[key] = value;
|
|
11673
|
+
}
|
|
11674
|
+
return styles;
|
|
11675
|
+
}, {
|
|
11676
|
+
...prevStyles
|
|
11677
|
+
} || {});
|
|
11678
|
+
const newCSSText = getCSSFromStyleObject(newStyles);
|
|
11679
|
+
target.setStyle(newCSSText);
|
|
11680
|
+
CSS_TO_STYLES.set(newCSSText, newStyles);
|
|
11681
|
+
}
|
|
11682
|
+
|
|
11683
|
+
/**
|
|
11684
|
+
* Applies the provided styles to the TextNodes in the provided Selection.
|
|
11685
|
+
* Will update partially selected TextNodes by splitting the TextNode and applying
|
|
11686
|
+
* the styles to the appropriate one.
|
|
11687
|
+
* @param selection - The selected node(s) to update.
|
|
11688
|
+
* @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }. Can also accept a function that returns the new property value.
|
|
11689
|
+
*/
|
|
11690
|
+
function $patchStyleText(selection, patch) {
|
|
11691
|
+
const selectedNodes = selection.getNodes();
|
|
11692
|
+
const selectedNodesLength = selectedNodes.length;
|
|
11693
|
+
const anchorAndFocus = selection.getStartEndPoints();
|
|
11694
|
+
if (anchorAndFocus === null) {
|
|
11695
|
+
return;
|
|
11696
|
+
}
|
|
11697
|
+
const [anchor, focus] = anchorAndFocus;
|
|
11698
|
+
const lastIndex = selectedNodesLength - 1;
|
|
11699
|
+
let firstNode = selectedNodes[0];
|
|
11700
|
+
let lastNode = selectedNodes[lastIndex];
|
|
11701
|
+
if (selection.isCollapsed() && lexical.$isRangeSelection(selection)) {
|
|
11702
|
+
$patchStyle(selection, patch);
|
|
11703
|
+
return;
|
|
11704
|
+
}
|
|
11705
|
+
const firstNodeText = firstNode.getTextContent();
|
|
11706
|
+
const firstNodeTextLength = firstNodeText.length;
|
|
11707
|
+
const focusOffset = focus.offset;
|
|
11708
|
+
let anchorOffset = anchor.offset;
|
|
11709
|
+
const isBefore = anchor.isBefore(focus);
|
|
11710
|
+
let startOffset = isBefore ? anchorOffset : focusOffset;
|
|
11711
|
+
let endOffset = isBefore ? focusOffset : anchorOffset;
|
|
11712
|
+
const startType = isBefore ? anchor.type : focus.type;
|
|
11713
|
+
const endType = isBefore ? focus.type : anchor.type;
|
|
11714
|
+
const endKey = isBefore ? focus.key : anchor.key;
|
|
11715
|
+
|
|
11716
|
+
// This is the case where the user only selected the very end of the
|
|
11717
|
+
// first node so we don't want to include it in the formatting change.
|
|
11718
|
+
if (lexical.$isTextNode(firstNode) && startOffset === firstNodeTextLength) {
|
|
11719
|
+
const nextSibling = firstNode.getNextSibling();
|
|
11720
|
+
if (lexical.$isTextNode(nextSibling)) {
|
|
11721
|
+
// we basically make the second node the firstNode, changing offsets accordingly
|
|
11722
|
+
anchorOffset = 0;
|
|
11723
|
+
startOffset = 0;
|
|
11724
|
+
firstNode = nextSibling;
|
|
11725
|
+
}
|
|
11726
|
+
}
|
|
11727
|
+
|
|
11728
|
+
// This is the case where we only selected a single node
|
|
11729
|
+
if (selectedNodes.length === 1) {
|
|
11730
|
+
if (lexical.$isTextNode(firstNode) && firstNode.canHaveFormat()) {
|
|
11731
|
+
startOffset = startType === 'element' ? 0 : anchorOffset > focusOffset ? focusOffset : anchorOffset;
|
|
11732
|
+
endOffset = endType === 'element' ? firstNodeTextLength : anchorOffset > focusOffset ? anchorOffset : focusOffset;
|
|
11733
|
+
|
|
11734
|
+
// No actual text is selected, so do nothing.
|
|
11735
|
+
if (startOffset === endOffset) {
|
|
11736
|
+
return;
|
|
11737
|
+
}
|
|
11738
|
+
|
|
11739
|
+
// The entire node is selected, so just format it
|
|
11740
|
+
if (startOffset === 0 && endOffset === firstNodeTextLength) {
|
|
11741
|
+
$patchStyle(firstNode, patch);
|
|
11742
|
+
firstNode.select(startOffset, endOffset);
|
|
11743
|
+
} else {
|
|
11744
|
+
// The node is partially selected, so split it into two nodes
|
|
11745
|
+
// and style the selected one.
|
|
11746
|
+
const splitNodes = firstNode.splitText(startOffset, endOffset);
|
|
11747
|
+
const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];
|
|
11748
|
+
$patchStyle(replacement, patch);
|
|
11749
|
+
replacement.select(0, endOffset - startOffset);
|
|
11750
|
+
}
|
|
11751
|
+
} // multiple nodes selected.
|
|
11752
|
+
} else {
|
|
11753
|
+
if (lexical.$isTextNode(firstNode) && startOffset < firstNode.getTextContentSize() && firstNode.canHaveFormat()) {
|
|
11754
|
+
if (startOffset !== 0) {
|
|
11755
|
+
// the entire first node isn't selected, so split it
|
|
11756
|
+
firstNode = firstNode.splitText(startOffset)[1];
|
|
11757
|
+
startOffset = 0;
|
|
11758
|
+
anchor.set(firstNode.getKey(), startOffset, 'text');
|
|
11759
|
+
}
|
|
11760
|
+
$patchStyle(firstNode, patch);
|
|
11761
|
+
}
|
|
11762
|
+
if (lexical.$isTextNode(lastNode) && lastNode.canHaveFormat()) {
|
|
11763
|
+
const lastNodeText = lastNode.getTextContent();
|
|
11764
|
+
const lastNodeTextLength = lastNodeText.length;
|
|
11765
|
+
|
|
11766
|
+
// The last node might not actually be the end node
|
|
11767
|
+
//
|
|
11768
|
+
// If not, assume the last node is fully-selected unless the end offset is
|
|
11769
|
+
// zero.
|
|
11770
|
+
if (lastNode.__key !== endKey && endOffset !== 0) {
|
|
11771
|
+
endOffset = lastNodeTextLength;
|
|
11772
|
+
}
|
|
11773
|
+
|
|
11774
|
+
// if the entire last node isn't selected, split it
|
|
11775
|
+
if (endOffset !== lastNodeTextLength) {
|
|
11776
|
+
[lastNode] = lastNode.splitText(endOffset);
|
|
11777
|
+
}
|
|
11778
|
+
if (endOffset !== 0 || endType === 'element') {
|
|
11779
|
+
$patchStyle(lastNode, patch);
|
|
11780
|
+
}
|
|
11781
|
+
}
|
|
11782
|
+
|
|
11783
|
+
// style all the text nodes in between
|
|
11784
|
+
for (let i = 1; i < lastIndex; i++) {
|
|
11785
|
+
const selectedNode = selectedNodes[i];
|
|
11786
|
+
const selectedNodeKey = selectedNode.getKey();
|
|
11787
|
+
if (lexical.$isTextNode(selectedNode) && selectedNode.canHaveFormat() && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
|
|
11788
|
+
$patchStyle(selectedNode, patch);
|
|
11789
|
+
}
|
|
11790
|
+
}
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11793
|
+
|
|
11794
|
+
/**
|
|
11795
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11796
|
+
*
|
|
11797
|
+
* This source code is licensed under the MIT license found in the
|
|
11798
|
+
* LICENSE file in the root directory of this source tree.
|
|
11799
|
+
*
|
|
11800
|
+
*/
|
|
11801
|
+
|
|
11802
|
+
/**
|
|
11803
|
+
* Converts all nodes in the selection that are of one block type to another.
|
|
11804
|
+
* @param selection - The selected blocks to be converted.
|
|
11805
|
+
* @param createElement - The function that creates the node. eg. $createParagraphNode.
|
|
11806
|
+
*/
|
|
11807
|
+
function $setBlocksType(selection, createElement) {
|
|
11808
|
+
if (selection === null) {
|
|
11809
|
+
return;
|
|
11810
|
+
}
|
|
11811
|
+
const anchorAndFocus = selection.getStartEndPoints();
|
|
11812
|
+
const anchor = anchorAndFocus ? anchorAndFocus[0] : null;
|
|
11813
|
+
if (anchor !== null && anchor.key === 'root') {
|
|
11814
|
+
const element = createElement();
|
|
11815
|
+
const root = lexical.$getRoot();
|
|
11816
|
+
const firstChild = root.getFirstChild();
|
|
11817
|
+
if (firstChild) {
|
|
11818
|
+
firstChild.replace(element, true);
|
|
11819
|
+
} else {
|
|
11820
|
+
root.append(element);
|
|
11821
|
+
}
|
|
11822
|
+
return;
|
|
11823
|
+
}
|
|
11824
|
+
const nodes = selection.getNodes();
|
|
11825
|
+
const firstSelectedBlock = anchor !== null ? $getAncestor(anchor.getNode(), INTERNAL_$isBlock) : false;
|
|
11826
|
+
if (firstSelectedBlock && nodes.indexOf(firstSelectedBlock) === -1) {
|
|
11827
|
+
nodes.push(firstSelectedBlock);
|
|
11828
|
+
}
|
|
11829
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
11830
|
+
const node = nodes[i];
|
|
11831
|
+
if (!INTERNAL_$isBlock(node)) {
|
|
11832
|
+
continue;
|
|
11833
|
+
}
|
|
11834
|
+
if (!lexical.$isElementNode(node)) {
|
|
11835
|
+
throw Error(`Expected block node to be an ElementNode`);
|
|
11836
|
+
}
|
|
11837
|
+
const targetElement = createElement();
|
|
11838
|
+
targetElement.setFormat(node.getFormatType());
|
|
11839
|
+
targetElement.setIndent(node.getIndent());
|
|
11840
|
+
node.replace(targetElement, true);
|
|
11841
|
+
}
|
|
11842
|
+
}
|
|
11843
|
+
function isPointAttached(point) {
|
|
11844
|
+
return point.getNode().isAttached();
|
|
11845
|
+
}
|
|
11846
|
+
function $removeParentEmptyElements(startingNode) {
|
|
11847
|
+
let node = startingNode;
|
|
11848
|
+
while (node !== null && !lexical.$isRootOrShadowRoot(node)) {
|
|
11849
|
+
const latest = node.getLatest();
|
|
11850
|
+
const parentNode = node.getParent();
|
|
11851
|
+
if (latest.getChildrenSize() === 0) {
|
|
11852
|
+
node.remove(true);
|
|
11853
|
+
}
|
|
11854
|
+
node = parentNode;
|
|
11855
|
+
}
|
|
11856
|
+
}
|
|
11857
|
+
|
|
11858
|
+
/**
|
|
11859
|
+
* @deprecated
|
|
11860
|
+
* Wraps all nodes in the selection into another node of the type returned by createElement.
|
|
11861
|
+
* @param selection - The selection of nodes to be wrapped.
|
|
11862
|
+
* @param createElement - A function that creates the wrapping ElementNode. eg. $createParagraphNode.
|
|
11863
|
+
* @param wrappingElement - An element to append the wrapped selection and its children to.
|
|
11864
|
+
*/
|
|
11865
|
+
function $wrapNodes(selection, createElement, wrappingElement = null) {
|
|
11866
|
+
const anchorAndFocus = selection.getStartEndPoints();
|
|
11867
|
+
const anchor = anchorAndFocus ? anchorAndFocus[0] : null;
|
|
11868
|
+
const nodes = selection.getNodes();
|
|
11869
|
+
const nodesLength = nodes.length;
|
|
11870
|
+
if (anchor !== null && (nodesLength === 0 || nodesLength === 1 && anchor.type === 'element' && anchor.getNode().getChildrenSize() === 0)) {
|
|
11871
|
+
const target = anchor.type === 'text' ? anchor.getNode().getParentOrThrow() : anchor.getNode();
|
|
11872
|
+
const children = target.getChildren();
|
|
11873
|
+
let element = createElement();
|
|
11874
|
+
element.setFormat(target.getFormatType());
|
|
11875
|
+
element.setIndent(target.getIndent());
|
|
11876
|
+
children.forEach(child => element.append(child));
|
|
11877
|
+
if (wrappingElement) {
|
|
11878
|
+
element = wrappingElement.append(element);
|
|
11879
|
+
}
|
|
11880
|
+
target.replace(element);
|
|
11881
|
+
return;
|
|
11882
|
+
}
|
|
11883
|
+
let topLevelNode = null;
|
|
11884
|
+
let descendants = [];
|
|
11885
|
+
for (let i = 0; i < nodesLength; i++) {
|
|
11886
|
+
const node = nodes[i];
|
|
11887
|
+
// Determine whether wrapping has to be broken down into multiple chunks. This can happen if the
|
|
11888
|
+
// user selected multiple Root-like nodes that have to be treated separately as if they are
|
|
11889
|
+
// their own branch. I.e. you don't want to wrap a whole table, but rather the contents of each
|
|
11890
|
+
// of each of the cell nodes.
|
|
11891
|
+
if (lexical.$isRootOrShadowRoot(node)) {
|
|
11892
|
+
$wrapNodesImpl(selection, descendants, descendants.length, createElement, wrappingElement);
|
|
11893
|
+
descendants = [];
|
|
11894
|
+
topLevelNode = node;
|
|
11895
|
+
} else if (topLevelNode === null || topLevelNode !== null && lexical.$hasAncestor(node, topLevelNode)) {
|
|
11896
|
+
descendants.push(node);
|
|
11897
|
+
} else {
|
|
11898
|
+
$wrapNodesImpl(selection, descendants, descendants.length, createElement, wrappingElement);
|
|
11899
|
+
descendants = [node];
|
|
11900
|
+
}
|
|
11901
|
+
}
|
|
11902
|
+
$wrapNodesImpl(selection, descendants, descendants.length, createElement, wrappingElement);
|
|
11903
|
+
}
|
|
11904
|
+
|
|
11905
|
+
/**
|
|
11906
|
+
* Wraps each node into a new ElementNode.
|
|
11907
|
+
* @param selection - The selection of nodes to wrap.
|
|
11908
|
+
* @param nodes - An array of nodes, generally the descendants of the selection.
|
|
11909
|
+
* @param nodesLength - The length of nodes.
|
|
11910
|
+
* @param createElement - A function that creates the wrapping ElementNode. eg. $createParagraphNode.
|
|
11911
|
+
* @param wrappingElement - An element to wrap all the nodes into.
|
|
11912
|
+
* @returns
|
|
11913
|
+
*/
|
|
11914
|
+
function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingElement = null) {
|
|
11915
|
+
if (nodes.length === 0) {
|
|
11916
|
+
return;
|
|
11917
|
+
}
|
|
11918
|
+
const firstNode = nodes[0];
|
|
11919
|
+
const elementMapping = new Map();
|
|
11920
|
+
const elements = [];
|
|
11921
|
+
// The below logic is to find the right target for us to
|
|
11922
|
+
// either insertAfter/insertBefore/append the corresponding
|
|
11923
|
+
// elements to. This is made more complicated due to nested
|
|
11924
|
+
// structures.
|
|
11925
|
+
let target = lexical.$isElementNode(firstNode) ? firstNode : firstNode.getParentOrThrow();
|
|
11926
|
+
if (target.isInline()) {
|
|
11927
|
+
target = target.getParentOrThrow();
|
|
11928
|
+
}
|
|
11929
|
+
let targetIsPrevSibling = false;
|
|
11930
|
+
while (target !== null) {
|
|
11931
|
+
const prevSibling = target.getPreviousSibling();
|
|
11932
|
+
if (prevSibling !== null) {
|
|
11933
|
+
target = prevSibling;
|
|
11934
|
+
targetIsPrevSibling = true;
|
|
11935
|
+
break;
|
|
11936
|
+
}
|
|
11937
|
+
target = target.getParentOrThrow();
|
|
11938
|
+
if (lexical.$isRootOrShadowRoot(target)) {
|
|
11939
|
+
break;
|
|
11940
|
+
}
|
|
11941
|
+
}
|
|
11942
|
+
const emptyElements = new Set();
|
|
11943
|
+
|
|
11944
|
+
// Find any top level empty elements
|
|
11945
|
+
for (let i = 0; i < nodesLength; i++) {
|
|
11946
|
+
const node = nodes[i];
|
|
11947
|
+
if (lexical.$isElementNode(node) && node.getChildrenSize() === 0) {
|
|
11948
|
+
emptyElements.add(node.getKey());
|
|
11949
|
+
}
|
|
11950
|
+
}
|
|
11951
|
+
const movedNodes = new Set();
|
|
11952
|
+
|
|
11953
|
+
// Move out all leaf nodes into our elements array.
|
|
11954
|
+
// If we find a top level empty element, also move make
|
|
11955
|
+
// an element for that.
|
|
11956
|
+
for (let i = 0; i < nodesLength; i++) {
|
|
11957
|
+
const node = nodes[i];
|
|
11958
|
+
let parent = node.getParent();
|
|
11959
|
+
if (parent !== null && parent.isInline()) {
|
|
11960
|
+
parent = parent.getParent();
|
|
11961
|
+
}
|
|
11962
|
+
if (parent !== null && lexical.$isLeafNode(node) && !movedNodes.has(node.getKey())) {
|
|
11963
|
+
const parentKey = parent.getKey();
|
|
11964
|
+
if (elementMapping.get(parentKey) === undefined) {
|
|
11965
|
+
const targetElement = createElement();
|
|
11966
|
+
targetElement.setFormat(parent.getFormatType());
|
|
11967
|
+
targetElement.setIndent(parent.getIndent());
|
|
11968
|
+
elements.push(targetElement);
|
|
11969
|
+
elementMapping.set(parentKey, targetElement);
|
|
11970
|
+
// Move node and its siblings to the new
|
|
11971
|
+
// element.
|
|
11972
|
+
parent.getChildren().forEach(child => {
|
|
11973
|
+
targetElement.append(child);
|
|
11974
|
+
movedNodes.add(child.getKey());
|
|
11975
|
+
if (lexical.$isElementNode(child)) {
|
|
11976
|
+
// Skip nested leaf nodes if the parent has already been moved
|
|
11977
|
+
child.getChildrenKeys().forEach(key => movedNodes.add(key));
|
|
11978
|
+
}
|
|
11979
|
+
});
|
|
11980
|
+
$removeParentEmptyElements(parent);
|
|
11981
|
+
}
|
|
11982
|
+
} else if (emptyElements.has(node.getKey())) {
|
|
11983
|
+
if (!lexical.$isElementNode(node)) {
|
|
11984
|
+
throw Error(`Expected node in emptyElements to be an ElementNode`);
|
|
11985
|
+
}
|
|
11986
|
+
const targetElement = createElement();
|
|
11987
|
+
targetElement.setFormat(node.getFormatType());
|
|
11988
|
+
targetElement.setIndent(node.getIndent());
|
|
11989
|
+
elements.push(targetElement);
|
|
11990
|
+
node.remove(true);
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11993
|
+
if (wrappingElement !== null) {
|
|
11994
|
+
for (let i = 0; i < elements.length; i++) {
|
|
11995
|
+
const element = elements[i];
|
|
11996
|
+
wrappingElement.append(element);
|
|
11997
|
+
}
|
|
11998
|
+
}
|
|
11999
|
+
let lastElement = null;
|
|
12000
|
+
|
|
12001
|
+
// If our target is Root-like, let's see if we can re-adjust
|
|
12002
|
+
// so that the target is the first child instead.
|
|
12003
|
+
if (lexical.$isRootOrShadowRoot(target)) {
|
|
12004
|
+
if (targetIsPrevSibling) {
|
|
12005
|
+
if (wrappingElement !== null) {
|
|
12006
|
+
target.insertAfter(wrappingElement);
|
|
12007
|
+
} else {
|
|
12008
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
12009
|
+
const element = elements[i];
|
|
12010
|
+
target.insertAfter(element);
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
} else {
|
|
12014
|
+
const firstChild = target.getFirstChild();
|
|
12015
|
+
if (lexical.$isElementNode(firstChild)) {
|
|
12016
|
+
target = firstChild;
|
|
12017
|
+
}
|
|
12018
|
+
if (firstChild === null) {
|
|
12019
|
+
if (wrappingElement) {
|
|
12020
|
+
target.append(wrappingElement);
|
|
12021
|
+
} else {
|
|
12022
|
+
for (let i = 0; i < elements.length; i++) {
|
|
12023
|
+
const element = elements[i];
|
|
12024
|
+
target.append(element);
|
|
12025
|
+
lastElement = element;
|
|
12026
|
+
}
|
|
12027
|
+
}
|
|
12028
|
+
} else {
|
|
12029
|
+
if (wrappingElement !== null) {
|
|
12030
|
+
firstChild.insertBefore(wrappingElement);
|
|
12031
|
+
} else {
|
|
12032
|
+
for (let i = 0; i < elements.length; i++) {
|
|
12033
|
+
const element = elements[i];
|
|
12034
|
+
firstChild.insertBefore(element);
|
|
12035
|
+
lastElement = element;
|
|
12036
|
+
}
|
|
12037
|
+
}
|
|
12038
|
+
}
|
|
12039
|
+
}
|
|
12040
|
+
} else {
|
|
12041
|
+
if (wrappingElement) {
|
|
12042
|
+
target.insertAfter(wrappingElement);
|
|
12043
|
+
} else {
|
|
12044
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
12045
|
+
const element = elements[i];
|
|
12046
|
+
target.insertAfter(element);
|
|
12047
|
+
lastElement = element;
|
|
12048
|
+
}
|
|
12049
|
+
}
|
|
12050
|
+
}
|
|
12051
|
+
const prevSelection = lexical.$getPreviousSelection();
|
|
12052
|
+
if (lexical.$isRangeSelection(prevSelection) && isPointAttached(prevSelection.anchor) && isPointAttached(prevSelection.focus)) {
|
|
12053
|
+
lexical.$setSelection(prevSelection.clone());
|
|
12054
|
+
} else if (lastElement !== null) {
|
|
12055
|
+
lastElement.selectEnd();
|
|
12056
|
+
} else {
|
|
12057
|
+
selection.dirty = true;
|
|
12058
|
+
}
|
|
12059
|
+
}
|
|
12060
|
+
|
|
12061
|
+
/**
|
|
12062
|
+
* Determines if the default character selection should be overridden. Used with DecoratorNodes
|
|
12063
|
+
* @param selection - The selection whose default character selection may need to be overridden.
|
|
12064
|
+
* @param isBackward - Is the selection backwards (the focus comes before the anchor)?
|
|
12065
|
+
* @returns true if it should be overridden, false if not.
|
|
12066
|
+
*/
|
|
12067
|
+
function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
|
|
12068
|
+
const possibleNode = lexical.$getAdjacentNode(selection.focus, isBackward);
|
|
12069
|
+
return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() || lexical.$isElementNode(possibleNode) && !possibleNode.isInline() && !possibleNode.canBeEmpty();
|
|
12070
|
+
}
|
|
12071
|
+
|
|
12072
|
+
/**
|
|
12073
|
+
* Moves the selection according to the arguments.
|
|
12074
|
+
* @param selection - The selected text or nodes.
|
|
12075
|
+
* @param isHoldingShift - Is the shift key being held down during the operation.
|
|
12076
|
+
* @param isBackward - Is the selection selected backwards (the focus comes before the anchor)?
|
|
12077
|
+
* @param granularity - The distance to adjust the current selection.
|
|
12078
|
+
*/
|
|
12079
|
+
function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
|
|
12080
|
+
selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
|
|
12081
|
+
}
|
|
12082
|
+
|
|
12083
|
+
/**
|
|
12084
|
+
* Tests a parent element for right to left direction.
|
|
12085
|
+
* @param selection - The selection whose parent is to be tested.
|
|
12086
|
+
* @returns true if the selections' parent element has a direction of 'rtl' (right to left), false otherwise.
|
|
12087
|
+
*/
|
|
12088
|
+
function $isParentElementRTL(selection) {
|
|
12089
|
+
const anchorNode = selection.anchor.getNode();
|
|
12090
|
+
const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
|
|
12091
|
+
return parent.getDirection() === 'rtl';
|
|
12092
|
+
}
|
|
12093
|
+
|
|
12094
|
+
/**
|
|
12095
|
+
* Moves selection by character according to arguments.
|
|
12096
|
+
* @param selection - The selection of the characters to move.
|
|
12097
|
+
* @param isHoldingShift - Is the shift key being held down during the operation.
|
|
12098
|
+
* @param isBackward - Is the selection backward (the focus comes before the anchor)?
|
|
12099
|
+
*/
|
|
12100
|
+
function $moveCharacter(selection, isHoldingShift, isBackward) {
|
|
12101
|
+
const isRTL = $isParentElementRTL(selection);
|
|
12102
|
+
$moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
|
|
12103
|
+
}
|
|
12104
|
+
|
|
12105
|
+
/**
|
|
12106
|
+
* Expands the current Selection to cover all of the content in the editor.
|
|
12107
|
+
* @param selection - The current selection.
|
|
12108
|
+
*/
|
|
12109
|
+
function $selectAll(selection) {
|
|
12110
|
+
const anchor = selection.anchor;
|
|
12111
|
+
const focus = selection.focus;
|
|
12112
|
+
const anchorNode = anchor.getNode();
|
|
12113
|
+
const topParent = anchorNode.getTopLevelElementOrThrow();
|
|
12114
|
+
const root = topParent.getParentOrThrow();
|
|
12115
|
+
let firstNode = root.getFirstDescendant();
|
|
12116
|
+
let lastNode = root.getLastDescendant();
|
|
12117
|
+
let firstType = 'element';
|
|
12118
|
+
let lastType = 'element';
|
|
12119
|
+
let lastOffset = 0;
|
|
12120
|
+
if (lexical.$isTextNode(firstNode)) {
|
|
12121
|
+
firstType = 'text';
|
|
12122
|
+
} else if (!lexical.$isElementNode(firstNode) && firstNode !== null) {
|
|
12123
|
+
firstNode = firstNode.getParentOrThrow();
|
|
12124
|
+
}
|
|
12125
|
+
if (lexical.$isTextNode(lastNode)) {
|
|
12126
|
+
lastType = 'text';
|
|
12127
|
+
lastOffset = lastNode.getTextContentSize();
|
|
12128
|
+
} else if (!lexical.$isElementNode(lastNode) && lastNode !== null) {
|
|
12129
|
+
lastNode = lastNode.getParentOrThrow();
|
|
12130
|
+
}
|
|
12131
|
+
if (firstNode && lastNode) {
|
|
12132
|
+
anchor.set(firstNode.getKey(), 0, firstType);
|
|
12133
|
+
focus.set(lastNode.getKey(), lastOffset, lastType);
|
|
12134
|
+
}
|
|
12135
|
+
}
|
|
12136
|
+
|
|
12137
|
+
/**
|
|
12138
|
+
* Returns the current value of a CSS property for Nodes, if set. If not set, it returns the defaultValue.
|
|
12139
|
+
* @param node - The node whose style value to get.
|
|
12140
|
+
* @param styleProperty - The CSS style property.
|
|
12141
|
+
* @param defaultValue - The default value for the property.
|
|
12142
|
+
* @returns The value of the property for node.
|
|
12143
|
+
*/
|
|
12144
|
+
function $getNodeStyleValueForProperty(node, styleProperty, defaultValue) {
|
|
12145
|
+
const css = node.getStyle();
|
|
12146
|
+
const styleObject = getStyleObjectFromCSS(css);
|
|
12147
|
+
if (styleObject !== null) {
|
|
12148
|
+
return styleObject[styleProperty] || defaultValue;
|
|
12149
|
+
}
|
|
12150
|
+
return defaultValue;
|
|
12151
|
+
}
|
|
12152
|
+
|
|
12153
|
+
/**
|
|
12154
|
+
* Returns the current value of a CSS property for TextNodes in the Selection, if set. If not set, it returns the defaultValue.
|
|
12155
|
+
* If all TextNodes do not have the same value, it returns an empty string.
|
|
12156
|
+
* @param selection - The selection of TextNodes whose value to find.
|
|
12157
|
+
* @param styleProperty - The CSS style property.
|
|
12158
|
+
* @param defaultValue - The default value for the property, defaults to an empty string.
|
|
12159
|
+
* @returns The value of the property for the selected TextNodes.
|
|
12160
|
+
*/
|
|
12161
|
+
function $getSelectionStyleValueForProperty(selection, styleProperty, defaultValue = '') {
|
|
12162
|
+
let styleValue = null;
|
|
12163
|
+
const nodes = selection.getNodes();
|
|
12164
|
+
const anchor = selection.anchor;
|
|
12165
|
+
const focus = selection.focus;
|
|
12166
|
+
const isBackward = selection.isBackward();
|
|
12167
|
+
const endOffset = isBackward ? focus.offset : anchor.offset;
|
|
12168
|
+
const endNode = isBackward ? focus.getNode() : anchor.getNode();
|
|
12169
|
+
if (selection.isCollapsed() && selection.style !== '') {
|
|
12170
|
+
const css = selection.style;
|
|
12171
|
+
const styleObject = getStyleObjectFromCSS(css);
|
|
12172
|
+
if (styleObject !== null && styleProperty in styleObject) {
|
|
12173
|
+
return styleObject[styleProperty];
|
|
12174
|
+
}
|
|
12175
|
+
}
|
|
12176
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
12177
|
+
const node = nodes[i];
|
|
12178
|
+
|
|
12179
|
+
// if no actual characters in the end node are selected, we don't
|
|
12180
|
+
// include it in the selection for purposes of determining style
|
|
12181
|
+
// value
|
|
12182
|
+
if (i !== 0 && endOffset === 0 && node.is(endNode)) {
|
|
12183
|
+
continue;
|
|
12184
|
+
}
|
|
12185
|
+
if (lexical.$isTextNode(node)) {
|
|
12186
|
+
const nodeStyleValue = $getNodeStyleValueForProperty(node, styleProperty, defaultValue);
|
|
12187
|
+
if (styleValue === null) {
|
|
12188
|
+
styleValue = nodeStyleValue;
|
|
12189
|
+
} else if (styleValue !== nodeStyleValue) {
|
|
12190
|
+
// multiple text nodes are in the selection and they don't all
|
|
12191
|
+
// have the same style.
|
|
12192
|
+
styleValue = '';
|
|
12193
|
+
break;
|
|
12194
|
+
}
|
|
12195
|
+
}
|
|
12196
|
+
}
|
|
12197
|
+
return styleValue === null ? defaultValue : styleValue;
|
|
12198
|
+
}
|
|
12199
|
+
|
|
12200
|
+
/**
|
|
12201
|
+
* This function is for internal use of the library.
|
|
12202
|
+
* Please do not use it as it may change in the future.
|
|
12203
|
+
*/
|
|
12204
|
+
function INTERNAL_$isBlock(node) {
|
|
12205
|
+
if (lexical.$isDecoratorNode(node)) {
|
|
12206
|
+
return false;
|
|
12207
|
+
}
|
|
12208
|
+
if (!lexical.$isElementNode(node) || lexical.$isRootOrShadowRoot(node)) {
|
|
12209
|
+
return false;
|
|
12210
|
+
}
|
|
12211
|
+
const firstChild = node.getFirstChild();
|
|
12212
|
+
const isLeafElement = firstChild === null || lexical.$isLineBreakNode(firstChild) || lexical.$isTextNode(firstChild) || firstChild.isInline();
|
|
12213
|
+
return !node.isInline() && node.canBeEmpty() !== false && isLeafElement;
|
|
12214
|
+
}
|
|
12215
|
+
function $getAncestor(node, predicate) {
|
|
12216
|
+
let parent = node;
|
|
12217
|
+
while (parent !== null && parent.getParent() !== null && !predicate(parent)) {
|
|
12218
|
+
parent = parent.getParentOrThrow();
|
|
12219
|
+
}
|
|
12220
|
+
return predicate(parent) ? parent : null;
|
|
12221
|
+
}
|
|
12222
|
+
|
|
12223
|
+
LexicalSelection_dev.$addNodeStyle = $addNodeStyle;
|
|
12224
|
+
LexicalSelection_dev.$cloneWithProperties = $cloneWithProperties;
|
|
12225
|
+
LexicalSelection_dev.$getSelectionStyleValueForProperty = $getSelectionStyleValueForProperty;
|
|
12226
|
+
LexicalSelection_dev.$isAtNodeEnd = $isAtNodeEnd;
|
|
12227
|
+
LexicalSelection_dev.$isParentElementRTL = $isParentElementRTL;
|
|
12228
|
+
LexicalSelection_dev.$moveCaretSelection = $moveCaretSelection;
|
|
12229
|
+
LexicalSelection_dev.$moveCharacter = $moveCharacter;
|
|
12230
|
+
LexicalSelection_dev.$patchStyleText = $patchStyleText;
|
|
12231
|
+
LexicalSelection_dev.$selectAll = $selectAll;
|
|
12232
|
+
LexicalSelection_dev.$setBlocksType = $setBlocksType;
|
|
12233
|
+
LexicalSelection_dev.$shouldOverrideDefaultCharacterSelection = $shouldOverrideDefaultCharacterSelection;
|
|
12234
|
+
LexicalSelection_dev.$sliceSelectedTextNodeContent = $sliceSelectedTextNodeContent;
|
|
12235
|
+
LexicalSelection_dev.$wrapNodes = $wrapNodes;
|
|
12236
|
+
LexicalSelection_dev.createDOMRange = createDOMRange;
|
|
12237
|
+
LexicalSelection_dev.createRectsFromDOMRange = createRectsFromDOMRange;
|
|
12238
|
+
LexicalSelection_dev.getStyleObjectFromCSS = getStyleObjectFromCSS;
|
|
12239
|
+
LexicalSelection_dev.trimTextContentFromAnchor = trimTextContentFromAnchor;
|
|
12240
|
+
return LexicalSelection_dev;
|
|
12241
|
+
}
|
|
12242
|
+
|
|
12243
|
+
var LexicalSelection_prod = {};
|
|
12244
|
+
|
|
12245
|
+
/**
|
|
12246
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12247
|
+
*
|
|
12248
|
+
* This source code is licensed under the MIT license found in the
|
|
12249
|
+
* LICENSE file in the root directory of this source tree.
|
|
12250
|
+
*/
|
|
12251
|
+
|
|
12252
|
+
var hasRequiredLexicalSelection_prod;
|
|
12253
|
+
|
|
12254
|
+
function requireLexicalSelection_prod () {
|
|
12255
|
+
if (hasRequiredLexicalSelection_prod) return LexicalSelection_prod;
|
|
12256
|
+
hasRequiredLexicalSelection_prod = 1;
|
|
12257
|
+
var k=require$$3;let v=new Map;function w(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild;}return null}function x(a){let b=a.parentNode;if(null==b)throw Error("Should never happen");return [b,Array.from(b.childNodes).indexOf(a)]}function y(a){let b={};a=a.split(";");for(let c of a)if(""!==c){let [e,d]=c.split(/:([^]+)/);e&&d&&(b[e.trim()]=d.trim());}return b}function z(a){let b=v.get(a);void 0===b&&(b=y(a),v.set(a,b));return b}
|
|
12258
|
+
function A(a){let b="";for(let c in a)c&&(b+=`${c}: ${a[c]};`);return b}function B(a,b){let c=z("getStyle"in a?a.getStyle():a.style);b=Object.entries(b).reduce((d,[g,h])=>{h instanceof Function?d[g]=h(c[g]):null===h?delete d[g]:d[g]=h;return d},{...c});let e=A(b);a.setStyle(e);v.set(e,b);}function C(a){for(;null!==a&&!k.$isRootOrShadowRoot(a);){let b=a.getLatest(),c=a.getParent();0===b.getChildrenSize()&&a.remove(true);a=c;}}
|
|
12259
|
+
function D(a,b,c,e,d=null){if(0!==b.length){var g=b[0],h=new Map,f=[];g=k.$isElementNode(g)?g:g.getParentOrThrow();g.isInline()&&(g=g.getParentOrThrow());for(var l=false;null!==g;){var m=g.getPreviousSibling();if(null!==m){g=m;l=true;break}g=g.getParentOrThrow();if(k.$isRootOrShadowRoot(g))break}m=new Set;for(var p=0;p<c;p++){var q=b[p];k.$isElementNode(q)&&0===q.getChildrenSize()&&m.add(q.getKey());}var n=new Set;for(p=0;p<c;p++){q=b[p];var r=q.getParent();null!==r&&r.isInline()&&(r=r.getParent());if(null!==
|
|
12260
|
+
r&&k.$isLeafNode(q)&&!n.has(q.getKey())){if(q=r.getKey(),void 0===h.get(q)){let t=e();t.setFormat(r.getFormatType());t.setIndent(r.getIndent());f.push(t);h.set(q,t);r.getChildren().forEach(u=>{t.append(u);n.add(u.getKey());k.$isElementNode(u)&&u.getChildrenKeys().forEach(H=>n.add(H));});C(r);}}else if(m.has(q.getKey())){if(!k.$isElementNode(q))throw Error("Expected node in emptyElements to be an ElementNode");r=e();r.setFormat(q.getFormatType());r.setIndent(q.getIndent());f.push(r);q.remove(true);}}if(null!==
|
|
12261
|
+
d)for(b=0;b<f.length;b++)d.append(f[b]);b=null;if(k.$isRootOrShadowRoot(g))if(l)if(null!==d)g.insertAfter(d);else for(d=f.length-1;0<=d;d--)g.insertAfter(f[d]);else if(l=g.getFirstChild(),k.$isElementNode(l)&&(g=l),null===l)if(d)g.append(d);else for(d=0;d<f.length;d++)l=f[d],g.append(l),b=l;else if(null!==d)l.insertBefore(d);else for(g=0;g<f.length;g++)d=f[g],l.insertBefore(d),b=d;else if(d)g.insertAfter(d);else for(d=f.length-1;0<=d;d--)l=f[d],g.insertAfter(l),b=l;f=k.$getPreviousSelection();k.$isRangeSelection(f)&&
|
|
12262
|
+
f.anchor.getNode().isAttached()&&f.focus.getNode().isAttached()?k.$setSelection(f.clone()):null!==b?b.selectEnd():a.dirty=true;}}function E(a,b,c,e){a.modify(b?"extend":"move",c,e);}function F(a){a=a.anchor.getNode();return "rtl"===(k.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}
|
|
12263
|
+
function G(a){if(k.$isDecoratorNode(a)||!k.$isElementNode(a)||k.$isRootOrShadowRoot(a))return false;var b=a.getFirstChild();b=null===b||k.$isLineBreakNode(b)||k.$isTextNode(b)||b.isInline();return !a.isInline()&&false!==a.canBeEmpty()&&b}LexicalSelection_prod.$addNodeStyle=function(a){a=a.getStyle();let b=y(a);v.set(a,b);};
|
|
12264
|
+
LexicalSelection_prod.$cloneWithProperties=function(a){let b=a.constructor.clone(a);b.__parent=a.__parent;b.__next=a.__next;b.__prev=a.__prev;if(k.$isElementNode(a)&&k.$isElementNode(b))return b.__first=a.__first,b.__last=a.__last,b.__size=a.__size,b.__format=a.__format,b.__indent=a.__indent,b.__dir=a.__dir,b;k.$isTextNode(a)&&k.$isTextNode(b)&&(b.__format=a.__format,b.__style=a.__style,b.__mode=a.__mode,b.__detail=a.__detail);return b};
|
|
12265
|
+
LexicalSelection_prod.$getSelectionStyleValueForProperty=function(a,b,c=""){let e=null,d=a.getNodes();var g=a.anchor,h=a.focus,f=a.isBackward();let l=f?h.offset:g.offset;g=f?h.getNode():g.getNode();if(a.isCollapsed()&&""!==a.style&&(a=z(a.style),null!==a&&b in a))return a[b];for(a=0;a<d.length;a++){var m=d[a];if((0===a||0!==l||!m.is(g))&&k.$isTextNode(m))if(h=b,f=c,m=m.getStyle(),m=z(m),h=null!==m?m[h]||f:f,null===e)e=h;else if(e!==h){e="";break}}return null===e?c:e};
|
|
12266
|
+
LexicalSelection_prod.$isAtNodeEnd=function(a){if("text"===a.type)return a.offset===a.getNode().getTextContentSize();let b=a.getNode();if(!k.$isElementNode(b))throw Error("isAtNodeEnd: node must be a TextNode or ElementNode");return a.offset===b.getChildrenSize()};LexicalSelection_prod.$isParentElementRTL=F;LexicalSelection_prod.$moveCaretSelection=E;LexicalSelection_prod.$moveCharacter=function(a,b,c){let e=F(a);E(a,b,c?!e:e,"character");};
|
|
12267
|
+
LexicalSelection_prod.$patchStyleText=function(a,b){var c=a.getNodes(),e=c.length,d=a.getStartEndPoints();if(null!==d){var [g,h]=d;--e;d=c[0];var f=c[e];if(a.isCollapsed()&&k.$isRangeSelection(a))B(a,b);else {var l=d.getTextContent().length,m=h.offset,p=g.offset,q=g.isBefore(h),n=q?p:m;a=q?m:p;var r=q?g.type:h.type,t=q?h.type:g.type;q=q?h.key:g.key;if(k.$isTextNode(d)&&n===l){let u=d.getNextSibling();k.$isTextNode(u)&&(n=p=0,d=u);}if(1===c.length)k.$isTextNode(d)&&d.canHaveFormat()&&(n="element"===r?0:p>m?m:p,a=
|
|
12268
|
+
"element"===t?l:p>m?p:m,n!==a&&(0===n&&a===l?(B(d,b),d.select(n,a)):(c=d.splitText(n,a),c=0===n?c[0]:c[1],B(c,b),c.select(0,a-n))));else for(k.$isTextNode(d)&&n<d.getTextContentSize()&&d.canHaveFormat()&&(0!==n&&(d=d.splitText(n)[1],n=0,g.set(d.getKey(),n,"text")),B(d,b)),k.$isTextNode(f)&&f.canHaveFormat()&&(n=f.getTextContent().length,f.__key!==q&&0!==a&&(a=n),a!==n&&([f]=f.splitText(a)),0===a&&"element"!==t||B(f,b)),a=1;a<e;a++)n=c[a],t=n.getKey(),k.$isTextNode(n)&&n.canHaveFormat()&&t!==d.getKey()&&
|
|
12269
|
+
t!==f.getKey()&&!n.isToken()&&B(n,b);}}};LexicalSelection_prod.$selectAll=function(a){let b=a.anchor;a=a.focus;var c=b.getNode().getTopLevelElementOrThrow().getParentOrThrow();let e=c.getFirstDescendant();c=c.getLastDescendant();let d="element",g="element",h=0;k.$isTextNode(e)?d="text":k.$isElementNode(e)||null===e||(e=e.getParentOrThrow());k.$isTextNode(c)?(g="text",h=c.getTextContentSize()):k.$isElementNode(c)||null===c||(c=c.getParentOrThrow());e&&c&&(b.set(e.getKey(),0,d),a.set(c.getKey(),h,g));};
|
|
12270
|
+
LexicalSelection_prod.$setBlocksType=function(a,b){if(null!==a){var c=a.getStartEndPoints();c=c?c[0]:null;if(null!==c&&"root"===c.key)b=b(),a=k.$getRoot(),(c=a.getFirstChild())?c.replace(b,true):a.append(b);else {a=a.getNodes();if(null!==c){for(c=c.getNode();null!==c&&null!==c.getParent()&&!G(c);)c=c.getParentOrThrow();c=G(c)?c:null;}else c=false;c&&-1===a.indexOf(c)&&a.push(c);for(c=0;c<a.length;c++){let e=a[c];if(!G(e))continue;if(!k.$isElementNode(e))throw Error("Expected block node to be an ElementNode");let d=b();
|
|
12271
|
+
d.setFormat(e.getFormatType());d.setIndent(e.getIndent());e.replace(d,true);}}}};LexicalSelection_prod.$shouldOverrideDefaultCharacterSelection=function(a,b){a=k.$getAdjacentNode(a.focus,b);return k.$isDecoratorNode(a)&&!a.isIsolated()||k.$isElementNode(a)&&!a.isInline()&&!a.canBeEmpty()};
|
|
12272
|
+
LexicalSelection_prod.$sliceSelectedTextNodeContent=function(a,b){var c=a.getStartEndPoints();if(b.isSelected(a)&&!b.isSegmented()&&!b.isToken()&&null!==c){let [f,l]=c;c=a.isBackward();var e=f.getNode(),d=l.getNode(),g=b.is(e),h=b.is(d);if(g||h){let [m,p]=k.$getCharacterOffsets(a);a=e.is(d);g=b.is(c?d:e);d=b.is(c?e:d);e=0;h=void 0;a?(e=m>p?p:m,h=m>p?m:p):g?(e=c?p:m,h=void 0):d&&(c=c?m:p,e=0,h=c);b.__text=b.__text.slice(e,h);}}return b};
|
|
12273
|
+
LexicalSelection_prod.$wrapNodes=function(a,b,c=null){var e=a.getStartEndPoints(),d=e?e[0]:null;e=a.getNodes();let g=e.length;if(null!==d&&(0===g||1===g&&"element"===d.type&&0===d.getNode().getChildrenSize())){a="text"===d.type?d.getNode().getParentOrThrow():d.getNode();e=a.getChildren();let f=b();f.setFormat(a.getFormatType());f.setIndent(a.getIndent());e.forEach(l=>f.append(l));c&&(f=c.append(f));a.replace(f);}else {d=null;var h=[];for(let f=0;f<g;f++){let l=e[f];k.$isRootOrShadowRoot(l)?(D(a,h,h.length,b,c),h=
|
|
12274
|
+
[],d=l):null===d||null!==d&&k.$hasAncestor(l,d)?h.push(l):(D(a,h,h.length,b,c),h=[l]);}D(a,h,h.length,b,c);}};
|
|
12275
|
+
LexicalSelection_prod.createDOMRange=function(a,b,c,e,d){let g=b.getKey(),h=e.getKey(),f=document.createRange(),l=a.getElementByKey(g);a=a.getElementByKey(h);k.$isTextNode(b)&&(l=w(l));k.$isTextNode(e)&&(a=w(a));if(void 0===b||void 0===e||null===l||null===a)return null;"BR"===l.nodeName&&([l,c]=x(l));"BR"===a.nodeName&&([a,d]=x(a));b=l.firstChild;l===a&&null!=b&&"BR"===b.nodeName&&0===c&&0===d&&(d=1);try{f.setStart(l,c),f.setEnd(a,d);}catch(m){return null}!f.collapsed||c===d&&g===h||(f.setStart(a,d),f.setEnd(l,
|
|
12276
|
+
c));return f};LexicalSelection_prod.createRectsFromDOMRange=function(a,b){var c=a.getRootElement();if(null===c)return [];a=c.getBoundingClientRect();c=getComputedStyle(c);c=parseFloat(c.paddingLeft)+parseFloat(c.paddingRight);b=Array.from(b.getClientRects());let e=b.length;b.sort((g,h)=>{let f=g.top-h.top;return 3>=Math.abs(f)?g.left-h.left:f});let d;for(let g=0;g<e;g++){let h=b[g],f=h.width+c===a.width;d&&d.top<=h.top&&d.top+d.height>h.top&&d.left+d.width>h.left||f?(b.splice(g--,1),e--):d=h;}return b};
|
|
12277
|
+
LexicalSelection_prod.getStyleObjectFromCSS=z;
|
|
12278
|
+
LexicalSelection_prod.trimTextContentFromAnchor=function(a,b,c){let e=b.getNode();if(k.$isElementNode(e)){var d=e.getDescendantByIndex(b.offset);null!==d&&(e=d);}for(;0<c&&null!==e;){k.$isElementNode(e)&&(d=e.getLastDescendant(),null!==d&&(e=d));var g=e.getPreviousSibling(),h=0;if(null===g){d=e.getParentOrThrow();for(var f=d.getPreviousSibling();null===f;){d=d.getParent();if(null===d){g=null;break}f=d.getPreviousSibling();}null!==d&&(h=d.isInline()?0:2,g=f);}f=e.getTextContent();""===f&&k.$isElementNode(e)&&!e.isInline()&&
|
|
12279
|
+
(f="\n\n");d=f.length;if(!k.$isTextNode(e)||c>=d)f=e.getParent(),e.remove(),null==f||0!==f.getChildrenSize()||k.$isRootNode(f)||f.remove(),c-=d+h,e=g;else {let l=e.getKey();h=a.getEditorState().read(()=>{const p=k.$getNodeByKey(l);return k.$isTextNode(p)&&p.isSimpleText()?p.getTextContent():null});g=d-c;let m=f.slice(0,g);null!==h&&h!==f?(c=k.$getPreviousSelection(),d=e,e.isSimpleText()?e.setTextContent(h):(d=k.$createTextNode(h),e.replace(d)),k.$isRangeSelection(c)&&c.isCollapsed()&&(c=c.anchor.offset,
|
|
12280
|
+
d.select(c,c))):e.isSimpleText()?(h=b.key===l,f=b.offset,f<c&&(f=d),c=h?f-c:0,d=h?f:g,h&&0===c?([c]=e.splitText(c,d),c.remove()):([,c]=e.splitText(c,d),c.remove())):(c=k.$createTextNode(m),e.replace(c));c=0;}}};
|
|
12281
|
+
return LexicalSelection_prod;
|
|
12282
|
+
}
|
|
12283
|
+
|
|
12284
|
+
/**
|
|
12285
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12286
|
+
*
|
|
12287
|
+
* This source code is licensed under the MIT license found in the
|
|
12288
|
+
* LICENSE file in the root directory of this source tree.
|
|
12289
|
+
*/
|
|
12290
|
+
|
|
12291
|
+
var LexicalSelection_1;
|
|
12292
|
+
var hasRequiredLexicalSelection;
|
|
12293
|
+
|
|
12294
|
+
function requireLexicalSelection () {
|
|
12295
|
+
if (hasRequiredLexicalSelection) return LexicalSelection_1;
|
|
12296
|
+
hasRequiredLexicalSelection = 1;
|
|
12297
|
+
const LexicalSelection = process.env.NODE_ENV === 'development' ? requireLexicalSelection_dev() : requireLexicalSelection_prod();
|
|
12298
|
+
LexicalSelection_1 = LexicalSelection;
|
|
12299
|
+
return LexicalSelection_1;
|
|
12300
|
+
}
|
|
12301
|
+
|
|
12302
|
+
var LexicalUtils_dev = {};
|
|
12303
|
+
|
|
12304
|
+
/**
|
|
12305
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12306
|
+
*
|
|
12307
|
+
* This source code is licensed under the MIT license found in the
|
|
12308
|
+
* LICENSE file in the root directory of this source tree.
|
|
12309
|
+
*/
|
|
12310
|
+
|
|
12311
|
+
var hasRequiredLexicalUtils_dev;
|
|
12312
|
+
|
|
12313
|
+
function requireLexicalUtils_dev () {
|
|
12314
|
+
if (hasRequiredLexicalUtils_dev) return LexicalUtils_dev;
|
|
12315
|
+
hasRequiredLexicalUtils_dev = 1;
|
|
12316
|
+
|
|
12317
|
+
var selection = requireLexicalSelection();
|
|
12318
|
+
var lexical = require$$3;
|
|
12319
|
+
|
|
12320
|
+
/**
|
|
12321
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12322
|
+
*
|
|
12323
|
+
* This source code is licensed under the MIT license found in the
|
|
12324
|
+
* LICENSE file in the root directory of this source tree.
|
|
12325
|
+
*
|
|
12326
|
+
*/
|
|
12327
|
+
|
|
12328
|
+
/**
|
|
12329
|
+
* Returns a function that will execute all functions passed when called. It is generally used
|
|
12330
|
+
* to register multiple lexical listeners and then tear them down with a single function call, such
|
|
12331
|
+
* as React's useEffect hook.
|
|
12332
|
+
* @example
|
|
12333
|
+
* ```ts
|
|
12334
|
+
* useEffect(() => {
|
|
12335
|
+
* return mergeRegister(
|
|
12336
|
+
* editor.registerCommand(...registerCommand1 logic),
|
|
12337
|
+
* editor.registerCommand(...registerCommand2 logic),
|
|
12338
|
+
* editor.registerCommand(...registerCommand3 logic)
|
|
12339
|
+
* )
|
|
12340
|
+
* }, [editor])
|
|
12341
|
+
* ```
|
|
12342
|
+
* In this case, useEffect is returning the function returned by mergeRegister as a cleanup
|
|
12343
|
+
* function to be executed after either the useEffect runs again (due to one of its dependencies
|
|
12344
|
+
* updating) or the component it resides in unmounts.
|
|
12345
|
+
* Note the functions don't neccesarily need to be in an array as all arguements
|
|
12346
|
+
* are considered to be the func argument and spread from there.
|
|
12347
|
+
* @param func - An array of functions meant to be executed by the returned function.
|
|
12348
|
+
* @returns the function which executes all the passed register command functions.
|
|
12349
|
+
*/
|
|
12350
|
+
function mergeRegister(...func) {
|
|
12351
|
+
return () => {
|
|
12352
|
+
func.forEach(f => f());
|
|
12353
|
+
};
|
|
12354
|
+
}
|
|
12355
|
+
|
|
12356
|
+
/**
|
|
12357
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12358
|
+
*
|
|
12359
|
+
* This source code is licensed under the MIT license found in the
|
|
12360
|
+
* LICENSE file in the root directory of this source tree.
|
|
12361
|
+
*
|
|
12362
|
+
*/
|
|
12363
|
+
|
|
12364
|
+
function px(value) {
|
|
12365
|
+
return `${value}px`;
|
|
12366
|
+
}
|
|
12367
|
+
|
|
12368
|
+
/**
|
|
12369
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12370
|
+
*
|
|
12371
|
+
* This source code is licensed under the MIT license found in the
|
|
12372
|
+
* LICENSE file in the root directory of this source tree.
|
|
12373
|
+
*
|
|
12374
|
+
*/
|
|
12375
|
+
const mutationObserverConfig = {
|
|
12376
|
+
attributes: true,
|
|
12377
|
+
characterData: true,
|
|
12378
|
+
childList: true,
|
|
12379
|
+
subtree: true
|
|
12380
|
+
};
|
|
12381
|
+
function positionNodeOnRange(editor, range, onReposition) {
|
|
12382
|
+
let rootDOMNode = null;
|
|
12383
|
+
let parentDOMNode = null;
|
|
12384
|
+
let observer = null;
|
|
12385
|
+
let lastNodes = [];
|
|
12386
|
+
const wrapperNode = document.createElement('div');
|
|
12387
|
+
function position() {
|
|
12388
|
+
if (!(rootDOMNode !== null)) {
|
|
12389
|
+
throw Error(`Unexpected null rootDOMNode`);
|
|
12390
|
+
}
|
|
12391
|
+
if (!(parentDOMNode !== null)) {
|
|
12392
|
+
throw Error(`Unexpected null parentDOMNode`);
|
|
12393
|
+
}
|
|
12394
|
+
const {
|
|
12395
|
+
left: rootLeft,
|
|
12396
|
+
top: rootTop
|
|
12397
|
+
} = rootDOMNode.getBoundingClientRect();
|
|
12398
|
+
const parentDOMNode_ = parentDOMNode;
|
|
12399
|
+
const rects = selection.createRectsFromDOMRange(editor, range);
|
|
12400
|
+
if (!wrapperNode.isConnected) {
|
|
12401
|
+
parentDOMNode_.append(wrapperNode);
|
|
12402
|
+
}
|
|
12403
|
+
let hasRepositioned = false;
|
|
12404
|
+
for (let i = 0; i < rects.length; i++) {
|
|
12405
|
+
const rect = rects[i];
|
|
12406
|
+
// Try to reuse the previously created Node when possible, no need to
|
|
12407
|
+
// remove/create on the most common case reposition case
|
|
12408
|
+
const rectNode = lastNodes[i] || document.createElement('div');
|
|
12409
|
+
const rectNodeStyle = rectNode.style;
|
|
12410
|
+
if (rectNodeStyle.position !== 'absolute') {
|
|
12411
|
+
rectNodeStyle.position = 'absolute';
|
|
12412
|
+
hasRepositioned = true;
|
|
12413
|
+
}
|
|
12414
|
+
const left = px(rect.left - rootLeft);
|
|
12415
|
+
if (rectNodeStyle.left !== left) {
|
|
12416
|
+
rectNodeStyle.left = left;
|
|
12417
|
+
hasRepositioned = true;
|
|
12418
|
+
}
|
|
12419
|
+
const top = px(rect.top - rootTop);
|
|
12420
|
+
if (rectNodeStyle.top !== top) {
|
|
12421
|
+
rectNode.style.top = top;
|
|
12422
|
+
hasRepositioned = true;
|
|
12423
|
+
}
|
|
12424
|
+
const width = px(rect.width);
|
|
12425
|
+
if (rectNodeStyle.width !== width) {
|
|
12426
|
+
rectNode.style.width = width;
|
|
12427
|
+
hasRepositioned = true;
|
|
12428
|
+
}
|
|
12429
|
+
const height = px(rect.height);
|
|
12430
|
+
if (rectNodeStyle.height !== height) {
|
|
12431
|
+
rectNode.style.height = height;
|
|
12432
|
+
hasRepositioned = true;
|
|
12433
|
+
}
|
|
12434
|
+
if (rectNode.parentNode !== wrapperNode) {
|
|
12435
|
+
wrapperNode.append(rectNode);
|
|
12436
|
+
hasRepositioned = true;
|
|
12437
|
+
}
|
|
12438
|
+
lastNodes[i] = rectNode;
|
|
12439
|
+
}
|
|
12440
|
+
while (lastNodes.length > rects.length) {
|
|
12441
|
+
lastNodes.pop();
|
|
12442
|
+
}
|
|
12443
|
+
if (hasRepositioned) {
|
|
12444
|
+
onReposition(lastNodes);
|
|
12445
|
+
}
|
|
12446
|
+
}
|
|
12447
|
+
function stop() {
|
|
12448
|
+
parentDOMNode = null;
|
|
12449
|
+
rootDOMNode = null;
|
|
12450
|
+
if (observer !== null) {
|
|
12451
|
+
observer.disconnect();
|
|
12452
|
+
}
|
|
12453
|
+
observer = null;
|
|
12454
|
+
wrapperNode.remove();
|
|
12455
|
+
for (const node of lastNodes) {
|
|
12456
|
+
node.remove();
|
|
12457
|
+
}
|
|
12458
|
+
lastNodes = [];
|
|
12459
|
+
}
|
|
12460
|
+
function restart() {
|
|
12461
|
+
const currentRootDOMNode = editor.getRootElement();
|
|
12462
|
+
if (currentRootDOMNode === null) {
|
|
12463
|
+
return stop();
|
|
12464
|
+
}
|
|
12465
|
+
const currentParentDOMNode = currentRootDOMNode.parentElement;
|
|
12466
|
+
if (!(currentParentDOMNode instanceof HTMLElement)) {
|
|
12467
|
+
return stop();
|
|
12468
|
+
}
|
|
12469
|
+
stop();
|
|
12470
|
+
rootDOMNode = currentRootDOMNode;
|
|
12471
|
+
parentDOMNode = currentParentDOMNode;
|
|
12472
|
+
observer = new MutationObserver(mutations => {
|
|
12473
|
+
const nextRootDOMNode = editor.getRootElement();
|
|
12474
|
+
const nextParentDOMNode = nextRootDOMNode && nextRootDOMNode.parentElement;
|
|
12475
|
+
if (nextRootDOMNode !== rootDOMNode || nextParentDOMNode !== parentDOMNode) {
|
|
12476
|
+
return restart();
|
|
12477
|
+
}
|
|
12478
|
+
for (const mutation of mutations) {
|
|
12479
|
+
if (!wrapperNode.contains(mutation.target)) {
|
|
12480
|
+
// TODO throttle
|
|
12481
|
+
return position();
|
|
12482
|
+
}
|
|
12483
|
+
}
|
|
12484
|
+
});
|
|
12485
|
+
observer.observe(currentParentDOMNode, mutationObserverConfig);
|
|
12486
|
+
position();
|
|
12487
|
+
}
|
|
12488
|
+
const removeRootListener = editor.registerRootListener(restart);
|
|
12489
|
+
return () => {
|
|
12490
|
+
removeRootListener();
|
|
12491
|
+
stop();
|
|
12492
|
+
};
|
|
12493
|
+
}
|
|
12494
|
+
|
|
12495
|
+
/**
|
|
12496
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12497
|
+
*
|
|
12498
|
+
* This source code is licensed under the MIT license found in the
|
|
12499
|
+
* LICENSE file in the root directory of this source tree.
|
|
12500
|
+
*
|
|
12501
|
+
*/
|
|
12502
|
+
function markSelection(editor, onReposition) {
|
|
12503
|
+
let previousAnchorNode = null;
|
|
12504
|
+
let previousAnchorOffset = null;
|
|
12505
|
+
let previousFocusNode = null;
|
|
12506
|
+
let previousFocusOffset = null;
|
|
12507
|
+
let removeRangeListener = () => {};
|
|
12508
|
+
function compute(editorState) {
|
|
12509
|
+
editorState.read(() => {
|
|
12510
|
+
const selection = lexical.$getSelection();
|
|
12511
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
12512
|
+
// TODO
|
|
12513
|
+
previousAnchorNode = null;
|
|
12514
|
+
previousAnchorOffset = null;
|
|
12515
|
+
previousFocusNode = null;
|
|
12516
|
+
previousFocusOffset = null;
|
|
12517
|
+
removeRangeListener();
|
|
12518
|
+
removeRangeListener = () => {};
|
|
12519
|
+
return;
|
|
12520
|
+
}
|
|
12521
|
+
const {
|
|
12522
|
+
anchor,
|
|
12523
|
+
focus
|
|
12524
|
+
} = selection;
|
|
12525
|
+
const currentAnchorNode = anchor.getNode();
|
|
12526
|
+
const currentAnchorNodeKey = currentAnchorNode.getKey();
|
|
12527
|
+
const currentAnchorOffset = anchor.offset;
|
|
12528
|
+
const currentFocusNode = focus.getNode();
|
|
12529
|
+
const currentFocusNodeKey = currentFocusNode.getKey();
|
|
12530
|
+
const currentFocusOffset = focus.offset;
|
|
12531
|
+
const currentAnchorNodeDOM = editor.getElementByKey(currentAnchorNodeKey);
|
|
12532
|
+
const currentFocusNodeDOM = editor.getElementByKey(currentFocusNodeKey);
|
|
12533
|
+
const differentAnchorDOM = previousAnchorNode === null || currentAnchorNodeDOM === null || currentAnchorOffset !== previousAnchorOffset || currentAnchorNodeKey !== previousAnchorNode.getKey() || currentAnchorNode !== previousAnchorNode && (!(previousAnchorNode instanceof lexical.TextNode) || currentAnchorNode.updateDOM(previousAnchorNode, currentAnchorNodeDOM, editor._config));
|
|
12534
|
+
const differentFocusDOM = previousFocusNode === null || currentFocusNodeDOM === null || currentFocusOffset !== previousFocusOffset || currentFocusNodeKey !== previousFocusNode.getKey() || currentFocusNode !== previousFocusNode && (!(previousFocusNode instanceof lexical.TextNode) || currentFocusNode.updateDOM(previousFocusNode, currentFocusNodeDOM, editor._config));
|
|
12535
|
+
if (differentAnchorDOM || differentFocusDOM) {
|
|
12536
|
+
const anchorHTMLElement = editor.getElementByKey(anchor.getNode().getKey());
|
|
12537
|
+
const focusHTMLElement = editor.getElementByKey(focus.getNode().getKey());
|
|
12538
|
+
// TODO handle selection beyond the common TextNode
|
|
12539
|
+
if (anchorHTMLElement !== null && focusHTMLElement !== null && anchorHTMLElement.tagName === 'SPAN' && focusHTMLElement.tagName === 'SPAN') {
|
|
12540
|
+
const range = document.createRange();
|
|
12541
|
+
let firstHTMLElement;
|
|
12542
|
+
let firstOffset;
|
|
12543
|
+
let lastHTMLElement;
|
|
12544
|
+
let lastOffset;
|
|
12545
|
+
if (focus.isBefore(anchor)) {
|
|
12546
|
+
firstHTMLElement = focusHTMLElement;
|
|
12547
|
+
firstOffset = focus.offset;
|
|
12548
|
+
lastHTMLElement = anchorHTMLElement;
|
|
12549
|
+
lastOffset = anchor.offset;
|
|
12550
|
+
} else {
|
|
12551
|
+
firstHTMLElement = anchorHTMLElement;
|
|
12552
|
+
firstOffset = anchor.offset;
|
|
12553
|
+
lastHTMLElement = focusHTMLElement;
|
|
12554
|
+
lastOffset = focus.offset;
|
|
12555
|
+
}
|
|
12556
|
+
const firstTextNode = firstHTMLElement.firstChild;
|
|
12557
|
+
if (!(firstTextNode !== null)) {
|
|
12558
|
+
throw Error(`Expected text node to be first child of span`);
|
|
12559
|
+
}
|
|
12560
|
+
const lastTextNode = lastHTMLElement.firstChild;
|
|
12561
|
+
if (!(lastTextNode !== null)) {
|
|
12562
|
+
throw Error(`Expected text node to be first child of span`);
|
|
12563
|
+
}
|
|
12564
|
+
range.setStart(firstTextNode, firstOffset);
|
|
12565
|
+
range.setEnd(lastTextNode, lastOffset);
|
|
12566
|
+
removeRangeListener();
|
|
12567
|
+
removeRangeListener = positionNodeOnRange(editor, range, domNodes => {
|
|
12568
|
+
for (const domNode of domNodes) {
|
|
12569
|
+
const domNodeStyle = domNode.style;
|
|
12570
|
+
if (domNodeStyle.background !== 'Highlight') {
|
|
12571
|
+
domNodeStyle.background = 'Highlight';
|
|
12572
|
+
}
|
|
12573
|
+
if (domNodeStyle.color !== 'HighlightText') {
|
|
12574
|
+
domNodeStyle.color = 'HighlightText';
|
|
12575
|
+
}
|
|
12576
|
+
if (domNodeStyle.zIndex !== '-1') {
|
|
12577
|
+
domNodeStyle.zIndex = '-1';
|
|
12578
|
+
}
|
|
12579
|
+
if (domNodeStyle.pointerEvents !== 'none') {
|
|
12580
|
+
domNodeStyle.pointerEvents = 'none';
|
|
12581
|
+
}
|
|
12582
|
+
if (domNodeStyle.marginTop !== px(-1.5)) {
|
|
12583
|
+
domNodeStyle.marginTop = px(-1.5);
|
|
12584
|
+
}
|
|
12585
|
+
if (domNodeStyle.paddingTop !== px(4)) {
|
|
12586
|
+
domNodeStyle.paddingTop = px(4);
|
|
12587
|
+
}
|
|
12588
|
+
if (domNodeStyle.paddingBottom !== px(0)) {
|
|
12589
|
+
domNodeStyle.paddingBottom = px(0);
|
|
12590
|
+
}
|
|
12591
|
+
}
|
|
12592
|
+
if (onReposition !== undefined) {
|
|
12593
|
+
onReposition(domNodes);
|
|
12594
|
+
}
|
|
12595
|
+
});
|
|
12596
|
+
}
|
|
12597
|
+
}
|
|
12598
|
+
previousAnchorNode = currentAnchorNode;
|
|
12599
|
+
previousAnchorOffset = currentAnchorOffset;
|
|
12600
|
+
previousFocusNode = currentFocusNode;
|
|
12601
|
+
previousFocusOffset = currentFocusOffset;
|
|
12602
|
+
});
|
|
12603
|
+
}
|
|
12604
|
+
compute(editor.getEditorState());
|
|
12605
|
+
return mergeRegister(editor.registerUpdateListener(({
|
|
12606
|
+
editorState
|
|
12607
|
+
}) => compute(editorState)), removeRangeListener, () => {
|
|
12608
|
+
removeRangeListener();
|
|
12609
|
+
});
|
|
12610
|
+
}
|
|
12611
|
+
|
|
12612
|
+
/** @module @lexical/utils */
|
|
12613
|
+
/**
|
|
12614
|
+
* Takes an HTML element and adds the classNames passed within an array,
|
|
12615
|
+
* ignoring any non-string types. A space can be used to add multiple classes
|
|
12616
|
+
* eg. addClassNamesToElement(element, ['element-inner active', true, null])
|
|
12617
|
+
* will add both 'element-inner' and 'active' as classes to that element.
|
|
12618
|
+
* @param element - The element in which the classes are added
|
|
12619
|
+
* @param classNames - An array defining the class names to add to the element
|
|
12620
|
+
*/
|
|
12621
|
+
function addClassNamesToElement(element, ...classNames) {
|
|
12622
|
+
classNames.forEach(className => {
|
|
12623
|
+
if (typeof className === 'string') {
|
|
12624
|
+
const classesToAdd = className.split(' ').filter(n => n !== '');
|
|
12625
|
+
element.classList.add(...classesToAdd);
|
|
12626
|
+
}
|
|
12627
|
+
});
|
|
12628
|
+
}
|
|
12629
|
+
|
|
12630
|
+
/**
|
|
12631
|
+
* Takes an HTML element and removes the classNames passed within an array,
|
|
12632
|
+
* ignoring any non-string types. A space can be used to remove multiple classes
|
|
12633
|
+
* eg. removeClassNamesFromElement(element, ['active small', true, null])
|
|
12634
|
+
* will remove both the 'active' and 'small' classes from that element.
|
|
12635
|
+
* @param element - The element in which the classes are removed
|
|
12636
|
+
* @param classNames - An array defining the class names to remove from the element
|
|
12637
|
+
*/
|
|
12638
|
+
function removeClassNamesFromElement(element, ...classNames) {
|
|
12639
|
+
classNames.forEach(className => {
|
|
12640
|
+
if (typeof className === 'string') {
|
|
12641
|
+
element.classList.remove(...className.split(' '));
|
|
12642
|
+
}
|
|
12643
|
+
});
|
|
12644
|
+
}
|
|
12645
|
+
|
|
12646
|
+
/**
|
|
12647
|
+
* Returns true if the file type matches the types passed within the acceptableMimeTypes array, false otherwise.
|
|
12648
|
+
* The types passed must be strings and are CASE-SENSITIVE.
|
|
12649
|
+
* eg. if file is of type 'text' and acceptableMimeTypes = ['TEXT', 'IMAGE'] the function will return false.
|
|
12650
|
+
* @param file - The file you want to type check.
|
|
12651
|
+
* @param acceptableMimeTypes - An array of strings of types which the file is checked against.
|
|
12652
|
+
* @returns true if the file is an acceptable mime type, false otherwise.
|
|
12653
|
+
*/
|
|
12654
|
+
function isMimeType(file, acceptableMimeTypes) {
|
|
12655
|
+
for (const acceptableType of acceptableMimeTypes) {
|
|
12656
|
+
if (file.type.startsWith(acceptableType)) {
|
|
12657
|
+
return true;
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
return false;
|
|
12661
|
+
}
|
|
12662
|
+
|
|
12663
|
+
/**
|
|
12664
|
+
* Lexical File Reader with:
|
|
12665
|
+
* 1. MIME type support
|
|
12666
|
+
* 2. batched results (HistoryPlugin compatibility)
|
|
12667
|
+
* 3. Order aware (respects the order when multiple Files are passed)
|
|
12668
|
+
*
|
|
12669
|
+
* const filesResult = await mediaFileReader(files, ['image/']);
|
|
12670
|
+
* filesResult.forEach(file => editor.dispatchCommand('INSERT_IMAGE', {
|
|
12671
|
+
* src: file.result,
|
|
12672
|
+
* }));
|
|
12673
|
+
*/
|
|
12674
|
+
function mediaFileReader(files, acceptableMimeTypes) {
|
|
12675
|
+
const filesIterator = files[Symbol.iterator]();
|
|
12676
|
+
return new Promise((resolve, reject) => {
|
|
12677
|
+
const processed = [];
|
|
12678
|
+
const handleNextFile = () => {
|
|
12679
|
+
const {
|
|
12680
|
+
done,
|
|
12681
|
+
value: file
|
|
12682
|
+
} = filesIterator.next();
|
|
12683
|
+
if (done) {
|
|
12684
|
+
return resolve(processed);
|
|
12685
|
+
}
|
|
12686
|
+
const fileReader = new FileReader();
|
|
12687
|
+
fileReader.addEventListener('error', reject);
|
|
12688
|
+
fileReader.addEventListener('load', () => {
|
|
12689
|
+
const result = fileReader.result;
|
|
12690
|
+
if (typeof result === 'string') {
|
|
12691
|
+
processed.push({
|
|
12692
|
+
file,
|
|
12693
|
+
result
|
|
12694
|
+
});
|
|
12695
|
+
}
|
|
12696
|
+
handleNextFile();
|
|
12697
|
+
});
|
|
12698
|
+
if (isMimeType(file, acceptableMimeTypes)) {
|
|
12699
|
+
fileReader.readAsDataURL(file);
|
|
12700
|
+
} else {
|
|
12701
|
+
handleNextFile();
|
|
12702
|
+
}
|
|
12703
|
+
};
|
|
12704
|
+
handleNextFile();
|
|
12705
|
+
});
|
|
12706
|
+
}
|
|
12707
|
+
|
|
12708
|
+
/**
|
|
12709
|
+
* "Depth-First Search" starts at the root/top node of a tree and goes as far as it can down a branch end
|
|
12710
|
+
* before backtracking and finding a new path. Consider solving a maze by hugging either wall, moving down a
|
|
12711
|
+
* branch until you hit a dead-end (leaf) and backtracking to find the nearest branching path and repeat.
|
|
12712
|
+
* It will then return all the nodes found in the search in an array of objects.
|
|
12713
|
+
* @param startingNode - The node to start the search, if ommitted, it will start at the root node.
|
|
12714
|
+
* @param endingNode - The node to end the search, if ommitted, it will find all descendants of the startingNode.
|
|
12715
|
+
* @returns An array of objects of all the nodes found by the search, including their depth into the tree.
|
|
12716
|
+
* {depth: number, node: LexicalNode} It will always return at least 1 node (the ending node) so long as it exists
|
|
12717
|
+
*/
|
|
12718
|
+
function $dfs(startingNode, endingNode) {
|
|
12719
|
+
const nodes = [];
|
|
12720
|
+
const start = (startingNode || lexical.$getRoot()).getLatest();
|
|
12721
|
+
const end = endingNode || (lexical.$isElementNode(start) ? start.getLastDescendant() : start);
|
|
12722
|
+
let node = start;
|
|
12723
|
+
let depth = $getDepth(node);
|
|
12724
|
+
while (node !== null && !node.is(end)) {
|
|
12725
|
+
nodes.push({
|
|
12726
|
+
depth,
|
|
12727
|
+
node
|
|
12728
|
+
});
|
|
12729
|
+
if (lexical.$isElementNode(node) && node.getChildrenSize() > 0) {
|
|
12730
|
+
node = node.getFirstChild();
|
|
12731
|
+
depth++;
|
|
12732
|
+
} else {
|
|
12733
|
+
// Find immediate sibling or nearest parent sibling
|
|
12734
|
+
let sibling = null;
|
|
12735
|
+
while (sibling === null && node !== null) {
|
|
12736
|
+
sibling = node.getNextSibling();
|
|
12737
|
+
if (sibling === null) {
|
|
12738
|
+
node = node.getParent();
|
|
12739
|
+
depth--;
|
|
12740
|
+
} else {
|
|
12741
|
+
node = sibling;
|
|
12742
|
+
}
|
|
12743
|
+
}
|
|
12744
|
+
}
|
|
12745
|
+
}
|
|
12746
|
+
if (node !== null && node.is(end)) {
|
|
12747
|
+
nodes.push({
|
|
12748
|
+
depth,
|
|
12749
|
+
node
|
|
12750
|
+
});
|
|
12751
|
+
}
|
|
12752
|
+
return nodes;
|
|
12753
|
+
}
|
|
12754
|
+
function $getDepth(node) {
|
|
12755
|
+
let innerNode = node;
|
|
12756
|
+
let depth = 0;
|
|
12757
|
+
while ((innerNode = innerNode.getParent()) !== null) {
|
|
12758
|
+
depth++;
|
|
12759
|
+
}
|
|
12760
|
+
return depth;
|
|
12761
|
+
}
|
|
12762
|
+
|
|
12763
|
+
/**
|
|
12764
|
+
* Takes a node and traverses up its ancestors (toward the root node)
|
|
12765
|
+
* in order to find a specific type of node.
|
|
12766
|
+
* @param node - the node to begin searching.
|
|
12767
|
+
* @param klass - an instance of the type of node to look for.
|
|
12768
|
+
* @returns the node of type klass that was passed, or null if none exist.
|
|
12769
|
+
*/
|
|
12770
|
+
function $getNearestNodeOfType(node, klass) {
|
|
12771
|
+
let parent = node;
|
|
12772
|
+
while (parent != null) {
|
|
12773
|
+
if (parent instanceof klass) {
|
|
12774
|
+
return parent;
|
|
12775
|
+
}
|
|
12776
|
+
parent = parent.getParent();
|
|
12777
|
+
}
|
|
12778
|
+
return null;
|
|
12779
|
+
}
|
|
12780
|
+
|
|
12781
|
+
/**
|
|
12782
|
+
* Returns the element node of the nearest ancestor, otherwise throws an error.
|
|
12783
|
+
* @param startNode - The starting node of the search
|
|
12784
|
+
* @returns The ancestor node found
|
|
12785
|
+
*/
|
|
12786
|
+
function $getNearestBlockElementAncestorOrThrow(startNode) {
|
|
12787
|
+
const blockNode = $findMatchingParent(startNode, node => lexical.$isElementNode(node) && !node.isInline());
|
|
12788
|
+
if (!lexical.$isElementNode(blockNode)) {
|
|
12789
|
+
{
|
|
12790
|
+
throw Error(`Expected node ${startNode.__key} to have closest block element node.`);
|
|
12791
|
+
}
|
|
12792
|
+
}
|
|
12793
|
+
return blockNode;
|
|
12794
|
+
}
|
|
12795
|
+
/**
|
|
12796
|
+
* Starts with a node and moves up the tree (toward the root node) to find a matching node based on
|
|
12797
|
+
* the search parameters of the findFn. (Consider JavaScripts' .find() function where a testing function must be
|
|
12798
|
+
* passed as an argument. eg. if( (node) => node.__type === 'div') ) return true; otherwise return false
|
|
12799
|
+
* @param startingNode - The node where the search starts.
|
|
12800
|
+
* @param findFn - A testing function that returns true if the current node satisfies the testing parameters.
|
|
12801
|
+
* @returns A parent node that matches the findFn parameters, or null if one wasn't found.
|
|
12802
|
+
*/
|
|
12803
|
+
const $findMatchingParent = (startingNode, findFn) => {
|
|
12804
|
+
let curr = startingNode;
|
|
12805
|
+
while (curr !== lexical.$getRoot() && curr != null) {
|
|
12806
|
+
if (findFn(curr)) {
|
|
12807
|
+
return curr;
|
|
12808
|
+
}
|
|
12809
|
+
curr = curr.getParent();
|
|
12810
|
+
}
|
|
12811
|
+
return null;
|
|
12812
|
+
};
|
|
12813
|
+
|
|
12814
|
+
/**
|
|
12815
|
+
* Attempts to resolve nested element nodes of the same type into a single node of that type.
|
|
12816
|
+
* It is generally used for marks/commenting
|
|
12817
|
+
* @param editor - The lexical editor
|
|
12818
|
+
* @param targetNode - The target for the nested element to be extracted from.
|
|
12819
|
+
* @param cloneNode - See {@link $createMarkNode}
|
|
12820
|
+
* @param handleOverlap - Handles any overlap between the node to extract and the targetNode
|
|
12821
|
+
* @returns The lexical editor
|
|
12822
|
+
*/
|
|
12823
|
+
function registerNestedElementResolver(editor, targetNode, cloneNode, handleOverlap) {
|
|
12824
|
+
const $isTargetNode = node => {
|
|
12825
|
+
return node instanceof targetNode;
|
|
12826
|
+
};
|
|
12827
|
+
const $findMatch = node => {
|
|
12828
|
+
// First validate we don't have any children that are of the target,
|
|
12829
|
+
// as we need to handle them first.
|
|
12830
|
+
const children = node.getChildren();
|
|
12831
|
+
for (let i = 0; i < children.length; i++) {
|
|
12832
|
+
const child = children[i];
|
|
12833
|
+
if ($isTargetNode(child)) {
|
|
12834
|
+
return null;
|
|
12835
|
+
}
|
|
12836
|
+
}
|
|
12837
|
+
let parentNode = node;
|
|
12838
|
+
let childNode = node;
|
|
12839
|
+
while (parentNode !== null) {
|
|
12840
|
+
childNode = parentNode;
|
|
12841
|
+
parentNode = parentNode.getParent();
|
|
12842
|
+
if ($isTargetNode(parentNode)) {
|
|
12843
|
+
return {
|
|
12844
|
+
child: childNode,
|
|
12845
|
+
parent: parentNode
|
|
12846
|
+
};
|
|
12847
|
+
}
|
|
12848
|
+
}
|
|
12849
|
+
return null;
|
|
12850
|
+
};
|
|
12851
|
+
const elementNodeTransform = node => {
|
|
12852
|
+
const match = $findMatch(node);
|
|
12853
|
+
if (match !== null) {
|
|
12854
|
+
const {
|
|
12855
|
+
child,
|
|
12856
|
+
parent
|
|
12857
|
+
} = match;
|
|
12858
|
+
|
|
12859
|
+
// Simple path, we can move child out and siblings into a new parent.
|
|
12860
|
+
|
|
12861
|
+
if (child.is(node)) {
|
|
12862
|
+
handleOverlap(parent, node);
|
|
12863
|
+
const nextSiblings = child.getNextSiblings();
|
|
12864
|
+
const nextSiblingsLength = nextSiblings.length;
|
|
12865
|
+
parent.insertAfter(child);
|
|
12866
|
+
if (nextSiblingsLength !== 0) {
|
|
12867
|
+
const newParent = cloneNode(parent);
|
|
12868
|
+
child.insertAfter(newParent);
|
|
12869
|
+
for (let i = 0; i < nextSiblingsLength; i++) {
|
|
12870
|
+
newParent.append(nextSiblings[i]);
|
|
12871
|
+
}
|
|
12872
|
+
}
|
|
12873
|
+
if (!parent.canBeEmpty() && parent.getChildrenSize() === 0) {
|
|
12874
|
+
parent.remove();
|
|
12875
|
+
}
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
};
|
|
12879
|
+
return editor.registerNodeTransform(targetNode, elementNodeTransform);
|
|
12880
|
+
}
|
|
12881
|
+
|
|
12882
|
+
/**
|
|
12883
|
+
* Clones the editor and marks it as dirty to be reconciled. If there was a selection,
|
|
12884
|
+
* it would be set back to its previous state, or null otherwise.
|
|
12885
|
+
* @param editor - The lexical editor
|
|
12886
|
+
* @param editorState - The editor's state
|
|
12887
|
+
*/
|
|
12888
|
+
function $restoreEditorState(editor, editorState) {
|
|
12889
|
+
const FULL_RECONCILE = 2;
|
|
12890
|
+
const nodeMap = new Map();
|
|
12891
|
+
const activeEditorState = editor._pendingEditorState;
|
|
12892
|
+
for (const [key, node] of editorState._nodeMap) {
|
|
12893
|
+
const clone = selection.$cloneWithProperties(node);
|
|
12894
|
+
if (lexical.$isTextNode(clone)) {
|
|
12895
|
+
if (!lexical.$isTextNode(node)) {
|
|
12896
|
+
throw Error(`Expected node be a TextNode`);
|
|
12897
|
+
}
|
|
12898
|
+
clone.__text = node.__text;
|
|
12899
|
+
}
|
|
12900
|
+
nodeMap.set(key, clone);
|
|
12901
|
+
}
|
|
12902
|
+
if (activeEditorState) {
|
|
12903
|
+
activeEditorState._nodeMap = nodeMap;
|
|
12904
|
+
}
|
|
12905
|
+
editor._dirtyType = FULL_RECONCILE;
|
|
12906
|
+
const selection$1 = editorState._selection;
|
|
12907
|
+
lexical.$setSelection(selection$1 === null ? null : selection$1.clone());
|
|
12908
|
+
}
|
|
12909
|
+
|
|
12910
|
+
/**
|
|
12911
|
+
* If the selected insertion area is the root/shadow root node (see {@link lexical!$isRootOrShadowRoot}),
|
|
12912
|
+
* the node will be appended there, otherwise, it will be inserted before the insertion area.
|
|
12913
|
+
* If there is no selection where the node is to be inserted, it will be appended after any current nodes
|
|
12914
|
+
* within the tree, as a child of the root node. A paragraph node will then be added after the inserted node and selected.
|
|
12915
|
+
* @param node - The node to be inserted
|
|
12916
|
+
* @returns The node after its insertion
|
|
12917
|
+
*/
|
|
12918
|
+
function $insertNodeToNearestRoot(node) {
|
|
12919
|
+
const selection = lexical.$getSelection() || lexical.$getPreviousSelection();
|
|
12920
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
12921
|
+
const {
|
|
12922
|
+
focus
|
|
12923
|
+
} = selection;
|
|
12924
|
+
const focusNode = focus.getNode();
|
|
12925
|
+
const focusOffset = focus.offset;
|
|
12926
|
+
if (lexical.$isRootOrShadowRoot(focusNode)) {
|
|
12927
|
+
const focusChild = focusNode.getChildAtIndex(focusOffset);
|
|
12928
|
+
if (focusChild == null) {
|
|
12929
|
+
focusNode.append(node);
|
|
12930
|
+
} else {
|
|
12931
|
+
focusChild.insertBefore(node);
|
|
12932
|
+
}
|
|
12933
|
+
node.selectNext();
|
|
12934
|
+
} else {
|
|
12935
|
+
let splitNode;
|
|
12936
|
+
let splitOffset;
|
|
12937
|
+
if (lexical.$isTextNode(focusNode)) {
|
|
12938
|
+
splitNode = focusNode.getParentOrThrow();
|
|
12939
|
+
splitOffset = focusNode.getIndexWithinParent();
|
|
12940
|
+
if (focusOffset > 0) {
|
|
12941
|
+
splitOffset += 1;
|
|
12942
|
+
focusNode.splitText(focusOffset);
|
|
12943
|
+
}
|
|
12944
|
+
} else {
|
|
12945
|
+
splitNode = focusNode;
|
|
12946
|
+
splitOffset = focusOffset;
|
|
12947
|
+
}
|
|
12948
|
+
const [, rightTree] = lexical.$splitNode(splitNode, splitOffset);
|
|
12949
|
+
rightTree.insertBefore(node);
|
|
12950
|
+
rightTree.selectStart();
|
|
12951
|
+
}
|
|
12952
|
+
} else {
|
|
12953
|
+
if (selection != null) {
|
|
12954
|
+
const nodes = selection.getNodes();
|
|
12955
|
+
nodes[nodes.length - 1].getTopLevelElementOrThrow().insertAfter(node);
|
|
12956
|
+
} else {
|
|
12957
|
+
const root = lexical.$getRoot();
|
|
12958
|
+
root.append(node);
|
|
12959
|
+
}
|
|
12960
|
+
const paragraphNode = lexical.$createParagraphNode();
|
|
12961
|
+
node.insertAfter(paragraphNode);
|
|
12962
|
+
paragraphNode.select();
|
|
12963
|
+
}
|
|
12964
|
+
return node.getLatest();
|
|
12965
|
+
}
|
|
12966
|
+
|
|
12967
|
+
/**
|
|
12968
|
+
* Wraps the node into another node created from a createElementNode function, eg. $createParagraphNode
|
|
12969
|
+
* @param node - Node to be wrapped.
|
|
12970
|
+
* @param createElementNode - Creates a new lexical element to wrap the to-be-wrapped node and returns it.
|
|
12971
|
+
* @returns A new lexical element with the previous node appended within (as a child, including its children).
|
|
12972
|
+
*/
|
|
12973
|
+
function $wrapNodeInElement(node, createElementNode) {
|
|
12974
|
+
const elementNode = createElementNode();
|
|
12975
|
+
node.replace(elementNode);
|
|
12976
|
+
elementNode.append(node);
|
|
12977
|
+
return elementNode;
|
|
12978
|
+
}
|
|
12979
|
+
|
|
12980
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12981
|
+
|
|
12982
|
+
/**
|
|
12983
|
+
* @param object = The instance of the type
|
|
12984
|
+
* @param objectClass = The class of the type
|
|
12985
|
+
* @returns Whether the object is has the same Klass of the objectClass, ignoring the difference across window (e.g. different iframs)
|
|
12986
|
+
*/
|
|
12987
|
+
function objectKlassEquals(object, objectClass) {
|
|
12988
|
+
return object !== null ? Object.getPrototypeOf(object).constructor.name === objectClass.name : false;
|
|
12989
|
+
}
|
|
12990
|
+
|
|
12991
|
+
/**
|
|
12992
|
+
* Filter the nodes
|
|
12993
|
+
* @param nodes Array of nodes that needs to be filtered
|
|
12994
|
+
* @param filterFn A filter function that returns node if the current node satisfies the condition otherwise null
|
|
12995
|
+
* @returns Array of filtered nodes
|
|
12996
|
+
*/
|
|
12997
|
+
|
|
12998
|
+
function $filter(nodes, filterFn) {
|
|
12999
|
+
const result = [];
|
|
13000
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
13001
|
+
const node = filterFn(nodes[i]);
|
|
13002
|
+
if (node !== null) {
|
|
13003
|
+
result.push(node);
|
|
13004
|
+
}
|
|
13005
|
+
}
|
|
13006
|
+
return result;
|
|
13007
|
+
}
|
|
13008
|
+
/**
|
|
13009
|
+
* Appends the node before the first child of the parent node
|
|
13010
|
+
* @param parent A parent node
|
|
13011
|
+
* @param node Node that needs to be appended
|
|
13012
|
+
*/
|
|
13013
|
+
function $insertFirst(parent, node) {
|
|
13014
|
+
const firstChild = parent.getFirstChild();
|
|
13015
|
+
if (firstChild !== null) {
|
|
13016
|
+
firstChild.insertBefore(node);
|
|
13017
|
+
} else {
|
|
13018
|
+
parent.append(node);
|
|
13019
|
+
}
|
|
13020
|
+
}
|
|
13021
|
+
|
|
13022
|
+
LexicalUtils_dev.$splitNode = lexical.$splitNode;
|
|
13023
|
+
LexicalUtils_dev.isHTMLAnchorElement = lexical.isHTMLAnchorElement;
|
|
13024
|
+
LexicalUtils_dev.isHTMLElement = lexical.isHTMLElement;
|
|
13025
|
+
LexicalUtils_dev.$dfs = $dfs;
|
|
13026
|
+
LexicalUtils_dev.$filter = $filter;
|
|
13027
|
+
LexicalUtils_dev.$findMatchingParent = $findMatchingParent;
|
|
13028
|
+
LexicalUtils_dev.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestorOrThrow;
|
|
13029
|
+
LexicalUtils_dev.$getNearestNodeOfType = $getNearestNodeOfType;
|
|
13030
|
+
LexicalUtils_dev.$insertFirst = $insertFirst;
|
|
13031
|
+
LexicalUtils_dev.$insertNodeToNearestRoot = $insertNodeToNearestRoot;
|
|
13032
|
+
LexicalUtils_dev.$restoreEditorState = $restoreEditorState;
|
|
13033
|
+
LexicalUtils_dev.$wrapNodeInElement = $wrapNodeInElement;
|
|
13034
|
+
LexicalUtils_dev.addClassNamesToElement = addClassNamesToElement;
|
|
13035
|
+
LexicalUtils_dev.isMimeType = isMimeType;
|
|
13036
|
+
LexicalUtils_dev.markSelection = markSelection;
|
|
13037
|
+
LexicalUtils_dev.mediaFileReader = mediaFileReader;
|
|
13038
|
+
LexicalUtils_dev.mergeRegister = mergeRegister;
|
|
13039
|
+
LexicalUtils_dev.objectKlassEquals = objectKlassEquals;
|
|
13040
|
+
LexicalUtils_dev.positionNodeOnRange = positionNodeOnRange;
|
|
13041
|
+
LexicalUtils_dev.registerNestedElementResolver = registerNestedElementResolver;
|
|
13042
|
+
LexicalUtils_dev.removeClassNamesFromElement = removeClassNamesFromElement;
|
|
13043
|
+
return LexicalUtils_dev;
|
|
13044
|
+
}
|
|
13045
|
+
|
|
13046
|
+
var LexicalUtils_prod = {};
|
|
13047
|
+
|
|
13048
|
+
/**
|
|
13049
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13050
|
+
*
|
|
13051
|
+
* This source code is licensed under the MIT license found in the
|
|
13052
|
+
* LICENSE file in the root directory of this source tree.
|
|
13053
|
+
*/
|
|
13054
|
+
|
|
13055
|
+
var hasRequiredLexicalUtils_prod;
|
|
13056
|
+
|
|
13057
|
+
function requireLexicalUtils_prod () {
|
|
13058
|
+
if (hasRequiredLexicalUtils_prod) return LexicalUtils_prod;
|
|
13059
|
+
hasRequiredLexicalUtils_prod = 1;
|
|
13060
|
+
var h=requireLexicalSelection(),B=require$$3;function C(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}function D(...a){return ()=>{a.forEach(b=>b());}}let E={attributes:true,characterData:true,childList:true,subtree:true};
|
|
13061
|
+
function F(a,b,c){function e(){if(null===g)throw Error("Unexpected null rootDOMNode");if(null===n)throw Error("Unexpected null parentDOMNode");let {left:p,top:z}=g.getBoundingClientRect();var q=n;let r=h.createRectsFromDOMRange(a,b);t.isConnected||q.append(t);q=false;for(let x=0;x<r.length;x++){var w=r[x];let u=k[x]||document.createElement("div"),y=u.style;"absolute"!==y.position&&(y.position="absolute",q=true);var l=`${w.left-p}px`;y.left!==l&&(y.left=l,q=true);l=`${w.top-z}px`;y.top!==l&&(u.style.top=
|
|
13062
|
+
l,q=true);l=`${w.width}px`;y.width!==l&&(u.style.width=l,q=true);w=`${w.height}px`;y.height!==w&&(u.style.height=w,q=true);u.parentNode!==t&&(t.append(u),q=true);k[x]=u;}for(;k.length>r.length;)k.pop();q&&c(k);}function d(){g=n=null;null!==m&&m.disconnect();m=null;t.remove();for(let p of k)p.remove();k=[];}function f(){let p=a.getRootElement();if(null===p)return d();let z=p.parentElement;if(!(z instanceof HTMLElement))return d();d();g=p;n=z;m=new MutationObserver(q=>{let r=a.getRootElement(),w=r&&r.parentElement;
|
|
13063
|
+
if(r!==g||w!==n)return f();for(let l of q)if(!t.contains(l.target))return e()});m.observe(z,E);e();}let g=null,n=null,m=null,k=[],t=document.createElement("div"),A=a.registerRootListener(f);return ()=>{A();d();}}function G(a,b){for(let c of b)if(a.type.startsWith(c))return true;return false}let H=(a,b)=>{for(;a!==B.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent();}return null};LexicalUtils_prod.$splitNode=B.$splitNode;LexicalUtils_prod.isHTMLAnchorElement=B.isHTMLAnchorElement;LexicalUtils_prod.isHTMLElement=B.isHTMLElement;
|
|
13064
|
+
LexicalUtils_prod.$dfs=function(a,b){let c=[];a=(a||B.$getRoot()).getLatest();b=b||(B.$isElementNode(a)?a.getLastDescendant():a);for(var e=a,d=0;null!==(e=e.getParent());)d++;for(e=d;null!==a&&!a.is(b);)if(c.push({depth:e,node:a}),B.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),e++;else for(d=null;null===d&&null!==a;)d=a.getNextSibling(),null===d?(a=a.getParent(),e--):a=d;null!==a&&a.is(b)&&c.push({depth:e,node:a});return c};
|
|
13065
|
+
LexicalUtils_prod.$filter=function(a,b){let c=[];for(let e=0;e<a.length;e++){let d=b(a[e]);null!==d&&c.push(d);}return c};LexicalUtils_prod.$findMatchingParent=H;LexicalUtils_prod.$getNearestBlockElementAncestorOrThrow=function(a){let b=H(a,c=>B.$isElementNode(c)&&!c.isInline());B.$isElementNode(b)||C(4,a.__key);return b};LexicalUtils_prod.$getNearestNodeOfType=function(a,b){for(;null!=a;){if(a instanceof b)return a;a=a.getParent();}return null};LexicalUtils_prod.$insertFirst=function(a,b){let c=a.getFirstChild();null!==c?c.insertBefore(b):a.append(b);};
|
|
13066
|
+
LexicalUtils_prod.$insertNodeToNearestRoot=function(a){var b=B.$getSelection()||B.$getPreviousSelection();if(B.$isRangeSelection(b)){var {focus:c}=b;b=c.getNode();c=c.offset;if(B.$isRootOrShadowRoot(b))c=b.getChildAtIndex(c),null==c?b.append(a):c.insertBefore(a),a.selectNext();else {let e,d;B.$isTextNode(b)?(e=b.getParentOrThrow(),d=b.getIndexWithinParent(),0<c&&(d+=1,b.splitText(c))):(e=b,d=c);[,b]=B.$splitNode(e,d);b.insertBefore(a);b.selectStart();}}else null!=b?(b=b.getNodes(),b[b.length-1].getTopLevelElementOrThrow().insertAfter(a)):
|
|
13067
|
+
B.$getRoot().append(a),b=B.$createParagraphNode(),a.insertAfter(b),b.select();return a.getLatest()};LexicalUtils_prod.$restoreEditorState=function(a,b){let c=new Map,e=a._pendingEditorState;for(let [d,f]of b._nodeMap){let g=h.$cloneWithProperties(f);if(B.$isTextNode(g)){if(!B.$isTextNode(f))throw Error("Expected node be a TextNode");g.__text=f.__text;}c.set(d,g);}e&&(e._nodeMap=c);a._dirtyType=2;a=b._selection;B.$setSelection(null===a?null:a.clone());};
|
|
13068
|
+
LexicalUtils_prod.$wrapNodeInElement=function(a,b){b=b();a.replace(b);b.append(a);return b};LexicalUtils_prod.addClassNamesToElement=function(a,...b){b.forEach(c=>{"string"===typeof c&&(c=c.split(" ").filter(e=>""!==e),a.classList.add(...c));});};LexicalUtils_prod.isMimeType=G;
|
|
13069
|
+
LexicalUtils_prod.markSelection=function(a,b){function c(m){m.read(()=>{var k=B.$getSelection();if(B.$isRangeSelection(k)){var {anchor:t,focus:A}=k;k=t.getNode();var p=k.getKey(),z=t.offset,q=A.getNode(),r=q.getKey(),w=A.offset,l=a.getElementByKey(p),x=a.getElementByKey(r);p=null===e||null===l||z!==d||p!==e.getKey()||k!==e&&(!(e instanceof B.TextNode)||k.updateDOM(e,l,a._config));r=null===f||null===x||w!==g||r!==f.getKey()||q!==f&&(!(f instanceof B.TextNode)||q.updateDOM(f,x,a._config));if(p||r){l=a.getElementByKey(t.getNode().getKey());
|
|
13070
|
+
var u=a.getElementByKey(A.getNode().getKey());if(null!==l&&null!==u&&"SPAN"===l.tagName&&"SPAN"===u.tagName){r=document.createRange();A.isBefore(t)?(p=u,x=A.offset,u=l,l=t.offset):(p=l,x=t.offset,l=A.offset);p=p.firstChild;if(null===p)throw Error("Expected text node to be first child of span");u=u.firstChild;if(null===u)throw Error("Expected text node to be first child of span");r.setStart(p,x);r.setEnd(u,l);n();n=F(a,r,y=>{for(let I of y){let v=I.style;"Highlight"!==v.background&&(v.background="Highlight");
|
|
13071
|
+
"HighlightText"!==v.color&&(v.color="HighlightText");"-1"!==v.zIndex&&(v.zIndex="-1");"none"!==v.pointerEvents&&(v.pointerEvents="none");"-1.5px"!==v.marginTop&&(v.marginTop="-1.5px");"4px"!==v.paddingTop&&(v.paddingTop="4px");"0px"!==v.paddingBottom&&(v.paddingBottom="0px");} void 0!==b&&b(y);});}}e=k;d=z;f=q;g=w;}else g=f=d=e=null,n(),n=()=>{};});}let e=null,d=null,f=null,g=null,n=()=>{};c(a.getEditorState());return D(a.registerUpdateListener(({editorState:m})=>c(m)),n,()=>{n();})};
|
|
13072
|
+
LexicalUtils_prod.mediaFileReader=function(a,b){let c=a[Symbol.iterator]();return new Promise((e,d)=>{let f=[],g=()=>{const {done:n,value:m}=c.next();if(n)return e(f);const k=new FileReader;k.addEventListener("error",d);k.addEventListener("load",()=>{const t=k.result;"string"===typeof t&&f.push({file:m,result:t});g();});G(m,b)?k.readAsDataURL(m):g();};g();})};LexicalUtils_prod.mergeRegister=D;LexicalUtils_prod.objectKlassEquals=function(a,b){return null!==a?Object.getPrototypeOf(a).constructor.name===b.name:false};
|
|
13073
|
+
LexicalUtils_prod.positionNodeOnRange=F;
|
|
13074
|
+
LexicalUtils_prod.registerNestedElementResolver=function(a,b,c,e){return a.registerNodeTransform(b,d=>{a:{var f=d.getChildren();for(var g=0;g<f.length;g++)if(f[g]instanceof b){f=null;break a}for(f=d;null!==f;)if(g=f,f=f.getParent(),f instanceof b){f={child:g,parent:f};break a}f=null;}if(null!==f){const {child:n,parent:m}=f;if(n.is(d)){e(m,d);d=n.getNextSiblings();f=d.length;m.insertAfter(n);if(0!==f){g=c(m);n.insertAfter(g);for(let k=0;k<f;k++)g.append(d[k]);}m.canBeEmpty()||0!==m.getChildrenSize()||m.remove();}}})};
|
|
13075
|
+
LexicalUtils_prod.removeClassNamesFromElement=function(a,...b){b.forEach(c=>{"string"===typeof c&&a.classList.remove(...c.split(" "));});};
|
|
13076
|
+
return LexicalUtils_prod;
|
|
13077
|
+
}
|
|
13078
|
+
|
|
13079
|
+
/**
|
|
13080
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13081
|
+
*
|
|
13082
|
+
* This source code is licensed under the MIT license found in the
|
|
13083
|
+
* LICENSE file in the root directory of this source tree.
|
|
13084
|
+
*/
|
|
13085
|
+
|
|
13086
|
+
var LexicalUtils_1;
|
|
13087
|
+
var hasRequiredLexicalUtils;
|
|
13088
|
+
|
|
13089
|
+
function requireLexicalUtils () {
|
|
13090
|
+
if (hasRequiredLexicalUtils) return LexicalUtils_1;
|
|
13091
|
+
hasRequiredLexicalUtils = 1;
|
|
13092
|
+
const LexicalUtils = process.env.NODE_ENV === 'development' ? requireLexicalUtils_dev() : requireLexicalUtils_prod();
|
|
13093
|
+
LexicalUtils_1 = LexicalUtils;
|
|
13094
|
+
return LexicalUtils_1;
|
|
13095
|
+
}
|
|
13096
|
+
|
|
13097
|
+
/**
|
|
13098
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13099
|
+
*
|
|
13100
|
+
* This source code is licensed under the MIT license found in the
|
|
13101
|
+
* LICENSE file in the root directory of this source tree.
|
|
13102
|
+
*/
|
|
13103
|
+
|
|
13104
|
+
var hasRequiredLexicalHtml_dev;
|
|
13105
|
+
|
|
13106
|
+
function requireLexicalHtml_dev () {
|
|
13107
|
+
if (hasRequiredLexicalHtml_dev) return LexicalHtml_dev;
|
|
13108
|
+
hasRequiredLexicalHtml_dev = 1;
|
|
13109
|
+
|
|
13110
|
+
var selection = requireLexicalSelection();
|
|
13111
|
+
var utils = requireLexicalUtils();
|
|
13112
|
+
var lexical = require$$3;
|
|
13113
|
+
|
|
13114
|
+
/** @module @lexical/html */
|
|
13115
|
+
|
|
13116
|
+
/**
|
|
13117
|
+
* How you parse your html string to get a document is left up to you. In the browser you can use the native
|
|
13118
|
+
* DOMParser API to generate a document (see clipboard.ts), but to use in a headless environment you can use JSDom
|
|
13119
|
+
* or an equivilant library and pass in the document here.
|
|
13120
|
+
*/
|
|
13121
|
+
function $generateNodesFromDOM(editor, dom) {
|
|
13122
|
+
const elements = dom.body ? dom.body.childNodes : [];
|
|
13123
|
+
let lexicalNodes = [];
|
|
13124
|
+
for (let i = 0; i < elements.length; i++) {
|
|
13125
|
+
const element = elements[i];
|
|
13126
|
+
if (!IGNORE_TAGS.has(element.nodeName)) {
|
|
13127
|
+
const lexicalNode = $createNodesFromDOM(element, editor);
|
|
13128
|
+
if (lexicalNode !== null) {
|
|
13129
|
+
lexicalNodes = lexicalNodes.concat(lexicalNode);
|
|
13130
|
+
}
|
|
13131
|
+
}
|
|
13132
|
+
}
|
|
13133
|
+
return lexicalNodes;
|
|
13134
|
+
}
|
|
13135
|
+
function $generateHtmlFromNodes(editor, selection) {
|
|
13136
|
+
if (typeof document === 'undefined' || typeof window === 'undefined' && typeof commonjsGlobal.window === 'undefined') {
|
|
13137
|
+
throw new Error('To use $generateHtmlFromNodes in headless mode please initialize a headless browser implementation such as JSDom before calling this function.');
|
|
13138
|
+
}
|
|
13139
|
+
const container = document.createElement('div');
|
|
13140
|
+
const root = lexical.$getRoot();
|
|
13141
|
+
const topLevelChildren = root.getChildren();
|
|
13142
|
+
for (let i = 0; i < topLevelChildren.length; i++) {
|
|
13143
|
+
const topLevelNode = topLevelChildren[i];
|
|
13144
|
+
$appendNodesToHTML(editor, topLevelNode, container, selection);
|
|
13145
|
+
}
|
|
13146
|
+
return container.innerHTML;
|
|
13147
|
+
}
|
|
13148
|
+
function $appendNodesToHTML(editor, currentNode, parentElement, selection$1 = null) {
|
|
13149
|
+
let shouldInclude = selection$1 !== null ? currentNode.isSelected(selection$1) : true;
|
|
13150
|
+
const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('html');
|
|
13151
|
+
let target = currentNode;
|
|
13152
|
+
if (selection$1 !== null) {
|
|
13153
|
+
let clone = selection.$cloneWithProperties(currentNode);
|
|
13154
|
+
clone = lexical.$isTextNode(clone) && selection$1 !== null ? selection.$sliceSelectedTextNodeContent(selection$1, clone) : clone;
|
|
13155
|
+
target = clone;
|
|
13156
|
+
}
|
|
13157
|
+
const children = lexical.$isElementNode(target) ? target.getChildren() : [];
|
|
13158
|
+
const registeredNode = editor._nodes.get(target.getType());
|
|
13159
|
+
let exportOutput;
|
|
13160
|
+
|
|
13161
|
+
// Use HTMLConfig overrides, if available.
|
|
13162
|
+
if (registeredNode && registeredNode.exportDOM !== undefined) {
|
|
13163
|
+
exportOutput = registeredNode.exportDOM(editor, target);
|
|
13164
|
+
} else {
|
|
13165
|
+
exportOutput = target.exportDOM(editor);
|
|
13166
|
+
}
|
|
13167
|
+
const {
|
|
13168
|
+
element,
|
|
13169
|
+
after
|
|
13170
|
+
} = exportOutput;
|
|
13171
|
+
if (!element) {
|
|
13172
|
+
return false;
|
|
13173
|
+
}
|
|
13174
|
+
const fragment = document.createDocumentFragment();
|
|
13175
|
+
for (let i = 0; i < children.length; i++) {
|
|
13176
|
+
const childNode = children[i];
|
|
13177
|
+
const shouldIncludeChild = $appendNodesToHTML(editor, childNode, fragment, selection$1);
|
|
13178
|
+
if (!shouldInclude && lexical.$isElementNode(currentNode) && shouldIncludeChild && currentNode.extractWithChild(childNode, selection$1, 'html')) {
|
|
13179
|
+
shouldInclude = true;
|
|
13180
|
+
}
|
|
13181
|
+
}
|
|
13182
|
+
if (shouldInclude && !shouldExclude) {
|
|
13183
|
+
if (utils.isHTMLElement(element)) {
|
|
13184
|
+
element.append(fragment);
|
|
13185
|
+
}
|
|
13186
|
+
parentElement.append(element);
|
|
13187
|
+
if (after) {
|
|
13188
|
+
const newElement = after.call(target, element);
|
|
13189
|
+
if (newElement) element.replaceWith(newElement);
|
|
13190
|
+
}
|
|
13191
|
+
} else {
|
|
13192
|
+
parentElement.append(fragment);
|
|
13193
|
+
}
|
|
13194
|
+
return shouldInclude;
|
|
13195
|
+
}
|
|
13196
|
+
function getConversionFunction(domNode, editor) {
|
|
13197
|
+
const {
|
|
13198
|
+
nodeName
|
|
13199
|
+
} = domNode;
|
|
13200
|
+
const cachedConversions = editor._htmlConversions.get(nodeName.toLowerCase());
|
|
13201
|
+
let currentConversion = null;
|
|
13202
|
+
if (cachedConversions !== undefined) {
|
|
13203
|
+
for (const cachedConversion of cachedConversions) {
|
|
13204
|
+
const domConversion = cachedConversion(domNode);
|
|
13205
|
+
if (domConversion !== null && (currentConversion === null || (currentConversion.priority || 0) < (domConversion.priority || 0))) {
|
|
13206
|
+
currentConversion = domConversion;
|
|
13207
|
+
}
|
|
13208
|
+
}
|
|
13209
|
+
}
|
|
13210
|
+
return currentConversion !== null ? currentConversion.conversion : null;
|
|
13211
|
+
}
|
|
13212
|
+
const IGNORE_TAGS = new Set(['STYLE', 'SCRIPT']);
|
|
13213
|
+
function $createNodesFromDOM(node, editor, forChildMap = new Map(), parentLexicalNode) {
|
|
13214
|
+
let lexicalNodes = [];
|
|
13215
|
+
if (IGNORE_TAGS.has(node.nodeName)) {
|
|
13216
|
+
return lexicalNodes;
|
|
13217
|
+
}
|
|
13218
|
+
let currentLexicalNode = null;
|
|
13219
|
+
const transformFunction = getConversionFunction(node, editor);
|
|
13220
|
+
const transformOutput = transformFunction ? transformFunction(node) : null;
|
|
13221
|
+
let postTransform = null;
|
|
13222
|
+
if (transformOutput !== null) {
|
|
13223
|
+
postTransform = transformOutput.after;
|
|
13224
|
+
const transformNodes = transformOutput.node;
|
|
13225
|
+
currentLexicalNode = Array.isArray(transformNodes) ? transformNodes[transformNodes.length - 1] : transformNodes;
|
|
13226
|
+
if (currentLexicalNode !== null) {
|
|
13227
|
+
for (const [, forChildFunction] of forChildMap) {
|
|
13228
|
+
currentLexicalNode = forChildFunction(currentLexicalNode, parentLexicalNode);
|
|
13229
|
+
if (!currentLexicalNode) {
|
|
13230
|
+
break;
|
|
13231
|
+
}
|
|
13232
|
+
}
|
|
13233
|
+
if (currentLexicalNode) {
|
|
13234
|
+
lexicalNodes.push(...(Array.isArray(transformNodes) ? transformNodes : [currentLexicalNode]));
|
|
13235
|
+
}
|
|
13236
|
+
}
|
|
13237
|
+
if (transformOutput.forChild != null) {
|
|
13238
|
+
forChildMap.set(node.nodeName, transformOutput.forChild);
|
|
13239
|
+
}
|
|
13240
|
+
}
|
|
13241
|
+
|
|
13242
|
+
// If the DOM node doesn't have a transformer, we don't know what
|
|
13243
|
+
// to do with it but we still need to process any childNodes.
|
|
13244
|
+
const children = node.childNodes;
|
|
13245
|
+
let childLexicalNodes = [];
|
|
13246
|
+
for (let i = 0; i < children.length; i++) {
|
|
13247
|
+
childLexicalNodes.push(...$createNodesFromDOM(children[i], editor, new Map(forChildMap), currentLexicalNode));
|
|
13248
|
+
}
|
|
13249
|
+
if (postTransform != null) {
|
|
13250
|
+
childLexicalNodes = postTransform(childLexicalNodes);
|
|
13251
|
+
}
|
|
13252
|
+
if (currentLexicalNode == null) {
|
|
13253
|
+
// If it hasn't been converted to a LexicalNode, we hoist its children
|
|
13254
|
+
// up to the same level as it.
|
|
13255
|
+
lexicalNodes = lexicalNodes.concat(childLexicalNodes);
|
|
13256
|
+
} else {
|
|
13257
|
+
if (lexical.$isElementNode(currentLexicalNode)) {
|
|
13258
|
+
// If the current node is a ElementNode after conversion,
|
|
13259
|
+
// we can append all the children to it.
|
|
13260
|
+
currentLexicalNode.append(...childLexicalNodes);
|
|
13261
|
+
}
|
|
13262
|
+
}
|
|
13263
|
+
return lexicalNodes;
|
|
13264
|
+
}
|
|
13265
|
+
|
|
13266
|
+
LexicalHtml_dev.$generateHtmlFromNodes = $generateHtmlFromNodes;
|
|
13267
|
+
LexicalHtml_dev.$generateNodesFromDOM = $generateNodesFromDOM;
|
|
13268
|
+
return LexicalHtml_dev;
|
|
13269
|
+
}
|
|
13270
|
+
|
|
13271
|
+
var LexicalHtml_prod = {};
|
|
13272
|
+
|
|
13273
|
+
/**
|
|
13274
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13275
|
+
*
|
|
13276
|
+
* This source code is licensed under the MIT license found in the
|
|
13277
|
+
* LICENSE file in the root directory of this source tree.
|
|
13278
|
+
*/
|
|
13279
|
+
|
|
13280
|
+
var hasRequiredLexicalHtml_prod;
|
|
13281
|
+
|
|
13282
|
+
function requireLexicalHtml_prod () {
|
|
13283
|
+
if (hasRequiredLexicalHtml_prod) return LexicalHtml_prod;
|
|
13284
|
+
hasRequiredLexicalHtml_prod = 1;
|
|
13285
|
+
var m=requireLexicalSelection(),p=requireLexicalUtils(),q=require$$3;
|
|
13286
|
+
function u(c,e,h,a=null){let f=null!==a?e.isSelected(a):true,k=q.$isElementNode(e)&&e.excludeFromCopy("html");var d=e;null!==a&&(d=m.$cloneWithProperties(e),d=q.$isTextNode(d)&&null!==a?m.$sliceSelectedTextNodeContent(a,d):d);let g=q.$isElementNode(d)?d.getChildren():[];var b=c._nodes.get(d.getType());b=b&&void 0!==b.exportDOM?b.exportDOM(c,d):d.exportDOM(c);let {element:l,after:r}=b;if(!l)return false;b=document.createDocumentFragment();for(let n=0;n<g.length;n++){let t=g[n],x=u(c,t,b,a);!f&&q.$isElementNode(e)&&
|
|
13287
|
+
x&&e.extractWithChild(t,a,"html")&&(f=true);}f&&!k?(p.isHTMLElement(l)&&l.append(b),h.append(l),r&&(c=r.call(d,l))&&l.replaceWith(c)):h.append(b);return f}let v=new Set(["STYLE","SCRIPT"]);
|
|
13288
|
+
function w(c,e,h=new Map,a){let f=[];if(v.has(c.nodeName))return f;let k=null;var d,{nodeName:g}=c,b=e._htmlConversions.get(g.toLowerCase());g=null;if(void 0!==b)for(d of b)b=d(c),null!==b&&(null===g||(g.priority||0)<(b.priority||0))&&(g=b);g=(d=null!==g?g.conversion:null)?d(c):null;d=null;if(null!==g){d=g.after;b=g.node;k=Array.isArray(b)?b[b.length-1]:b;if(null!==k){for(var [,l]of h)if(k=l(k,a),!k)break;k&&f.push(...(Array.isArray(b)?b:[k]));}null!=g.forChild&&h.set(c.nodeName,g.forChild);}c=c.childNodes;
|
|
13289
|
+
a=[];for(l=0;l<c.length;l++)a.push(...w(c[l],e,new Map(h),k));null!=d&&(a=d(a));null==k?f=f.concat(a):q.$isElementNode(k)&&k.append(...a);return f}
|
|
13290
|
+
LexicalHtml_prod.$generateHtmlFromNodes=function(c,e){if("undefined"===typeof document||"undefined"===typeof window&&"undefined"===typeof commonjsGlobal.window)throw Error("To use $generateHtmlFromNodes in headless mode please initialize a headless browser implementation such as JSDom before calling this function.");let h=document.createElement("div"),a=q.$getRoot().getChildren();for(let f=0;f<a.length;f++)u(c,a[f],h,e);return h.innerHTML};
|
|
13291
|
+
LexicalHtml_prod.$generateNodesFromDOM=function(c,e){e=e.body?e.body.childNodes:[];let h=[];for(let f=0;f<e.length;f++){var a=e[f];v.has(a.nodeName)||(a=w(a,c),null!==a&&(h=h.concat(a)));}return h};
|
|
13292
|
+
return LexicalHtml_prod;
|
|
13293
|
+
}
|
|
13294
|
+
|
|
13295
|
+
/**
|
|
13296
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13297
|
+
*
|
|
13298
|
+
* This source code is licensed under the MIT license found in the
|
|
13299
|
+
* LICENSE file in the root directory of this source tree.
|
|
13300
|
+
*/
|
|
13301
|
+
|
|
13302
|
+
var LexicalHtml_1;
|
|
13303
|
+
var hasRequiredLexicalHtml;
|
|
13304
|
+
|
|
13305
|
+
function requireLexicalHtml () {
|
|
13306
|
+
if (hasRequiredLexicalHtml) return LexicalHtml_1;
|
|
13307
|
+
hasRequiredLexicalHtml = 1;
|
|
13308
|
+
const LexicalHtml = process.env.NODE_ENV === 'development' ? requireLexicalHtml_dev() : requireLexicalHtml_prod();
|
|
13309
|
+
LexicalHtml_1 = LexicalHtml;
|
|
13310
|
+
return LexicalHtml_1;
|
|
13311
|
+
}
|
|
13312
|
+
|
|
13313
|
+
/**
|
|
13314
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13315
|
+
*
|
|
13316
|
+
* This source code is licensed under the MIT license found in the
|
|
13317
|
+
* LICENSE file in the root directory of this source tree.
|
|
13318
|
+
*/
|
|
13319
|
+
|
|
13320
|
+
var hasRequiredLexicalClipboard_dev;
|
|
13321
|
+
|
|
13322
|
+
function requireLexicalClipboard_dev () {
|
|
13323
|
+
if (hasRequiredLexicalClipboard_dev) return LexicalClipboard_dev;
|
|
13324
|
+
hasRequiredLexicalClipboard_dev = 1;
|
|
13325
|
+
|
|
13326
|
+
var html = requireLexicalHtml();
|
|
13327
|
+
var selection = requireLexicalSelection();
|
|
13328
|
+
var utils = requireLexicalUtils();
|
|
13329
|
+
var lexical = require$$3;
|
|
13330
|
+
|
|
13331
|
+
/**
|
|
13332
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13333
|
+
*
|
|
13334
|
+
* This source code is licensed under the MIT license found in the
|
|
13335
|
+
* LICENSE file in the root directory of this source tree.
|
|
13336
|
+
*
|
|
13337
|
+
*/
|
|
13338
|
+
|
|
13339
|
+
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
13340
|
+
|
|
13341
|
+
/**
|
|
13342
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13343
|
+
*
|
|
13344
|
+
* This source code is licensed under the MIT license found in the
|
|
13345
|
+
* LICENSE file in the root directory of this source tree.
|
|
13346
|
+
*
|
|
13347
|
+
*/
|
|
13348
|
+
const getDOMSelection = targetWindow => CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
|
|
13349
|
+
|
|
13350
|
+
/**
|
|
13351
|
+
* Returns the *currently selected* Lexical content as an HTML string, relying on the
|
|
13352
|
+
* logic defined in the exportDOM methods on the LexicalNode classes. Note that
|
|
13353
|
+
* this will not return the HTML content of the entire editor (unless all the content is included
|
|
13354
|
+
* in the current selection).
|
|
13355
|
+
*
|
|
13356
|
+
* @param editor - LexicalEditor instance to get HTML content from
|
|
13357
|
+
* @returns a string of HTML content
|
|
13358
|
+
*/
|
|
13359
|
+
function $getHtmlContent(editor) {
|
|
13360
|
+
const selection = lexical.$getSelection();
|
|
13361
|
+
if (selection == null) {
|
|
13362
|
+
{
|
|
13363
|
+
throw Error(`Expected valid LexicalSelection`);
|
|
13364
|
+
}
|
|
13365
|
+
}
|
|
13366
|
+
|
|
13367
|
+
// If we haven't selected anything
|
|
13368
|
+
if (lexical.$isRangeSelection(selection) && selection.isCollapsed() || selection.getNodes().length === 0) {
|
|
13369
|
+
return '';
|
|
13370
|
+
}
|
|
13371
|
+
return html.$generateHtmlFromNodes(editor, selection);
|
|
13372
|
+
}
|
|
13373
|
+
|
|
13374
|
+
/**
|
|
13375
|
+
* Returns the *currently selected* Lexical content as a JSON string, relying on the
|
|
13376
|
+
* logic defined in the exportJSON methods on the LexicalNode classes. Note that
|
|
13377
|
+
* this will not return the JSON content of the entire editor (unless all the content is included
|
|
13378
|
+
* in the current selection).
|
|
13379
|
+
*
|
|
13380
|
+
* @param editor - LexicalEditor instance to get the JSON content from
|
|
13381
|
+
* @returns
|
|
13382
|
+
*/
|
|
13383
|
+
function $getLexicalContent(editor) {
|
|
13384
|
+
const selection = lexical.$getSelection();
|
|
13385
|
+
if (selection == null) {
|
|
13386
|
+
{
|
|
13387
|
+
throw Error(`Expected valid LexicalSelection`);
|
|
13388
|
+
}
|
|
13389
|
+
}
|
|
13390
|
+
|
|
13391
|
+
// If we haven't selected anything
|
|
13392
|
+
if (lexical.$isRangeSelection(selection) && selection.isCollapsed() || selection.getNodes().length === 0) {
|
|
13393
|
+
return null;
|
|
13394
|
+
}
|
|
13395
|
+
return JSON.stringify($generateJSONFromSelectedNodes(editor, selection));
|
|
13396
|
+
}
|
|
13397
|
+
|
|
13398
|
+
/**
|
|
13399
|
+
* Attempts to insert content of the mime-types text/plain or text/uri-list from
|
|
13400
|
+
* the provided DataTransfer object into the editor at the provided selection.
|
|
13401
|
+
* text/uri-list is only used if text/plain is not also provided.
|
|
13402
|
+
*
|
|
13403
|
+
* @param dataTransfer an object conforming to the [DataTransfer interface] (https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface)
|
|
13404
|
+
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
|
13405
|
+
*/
|
|
13406
|
+
function $insertDataTransferForPlainText(dataTransfer, selection) {
|
|
13407
|
+
const text = dataTransfer.getData('text/plain') || dataTransfer.getData('text/uri-list');
|
|
13408
|
+
if (text != null) {
|
|
13409
|
+
selection.insertRawText(text);
|
|
13410
|
+
}
|
|
13411
|
+
}
|
|
13412
|
+
|
|
13413
|
+
/**
|
|
13414
|
+
* Attempts to insert content of the mime-types application/x-lexical-editor, text/html,
|
|
13415
|
+
* text/plain, or text/uri-list (in descending order of priority) from the provided DataTransfer
|
|
13416
|
+
* object into the editor at the provided selection.
|
|
13417
|
+
*
|
|
13418
|
+
* @param dataTransfer an object conforming to the [DataTransfer interface] (https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface)
|
|
13419
|
+
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
|
13420
|
+
* @param editor the LexicalEditor the content is being inserted into.
|
|
13421
|
+
*/
|
|
13422
|
+
function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
|
13423
|
+
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
|
13424
|
+
if (lexicalString) {
|
|
13425
|
+
try {
|
|
13426
|
+
const payload = JSON.parse(lexicalString);
|
|
13427
|
+
if (payload.namespace === editor._config.namespace && Array.isArray(payload.nodes)) {
|
|
13428
|
+
const nodes = $generateNodesFromSerializedNodes(payload.nodes);
|
|
13429
|
+
return $insertGeneratedNodes(editor, nodes, selection);
|
|
13430
|
+
}
|
|
13431
|
+
} catch (_unused) {
|
|
13432
|
+
// Fail silently.
|
|
13433
|
+
}
|
|
13434
|
+
}
|
|
13435
|
+
const htmlString = dataTransfer.getData('text/html');
|
|
13436
|
+
if (htmlString) {
|
|
13437
|
+
try {
|
|
13438
|
+
const parser = new DOMParser();
|
|
13439
|
+
const dom = parser.parseFromString(htmlString, 'text/html');
|
|
13440
|
+
const nodes = html.$generateNodesFromDOM(editor, dom);
|
|
13441
|
+
return $insertGeneratedNodes(editor, nodes, selection);
|
|
13442
|
+
} catch (_unused2) {
|
|
13443
|
+
// Fail silently.
|
|
13444
|
+
}
|
|
13445
|
+
}
|
|
13446
|
+
|
|
13447
|
+
// Multi-line plain text in rich text mode pasted as separate paragraphs
|
|
13448
|
+
// instead of single paragraph with linebreaks.
|
|
13449
|
+
// Webkit-specific: Supports read 'text/uri-list' in clipboard.
|
|
13450
|
+
const text = dataTransfer.getData('text/plain') || dataTransfer.getData('text/uri-list');
|
|
13451
|
+
if (text != null) {
|
|
13452
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
13453
|
+
const parts = text.split(/(\r?\n|\t)/);
|
|
13454
|
+
if (parts[parts.length - 1] === '') {
|
|
13455
|
+
parts.pop();
|
|
13456
|
+
}
|
|
13457
|
+
for (let i = 0; i < parts.length; i++) {
|
|
13458
|
+
const part = parts[i];
|
|
13459
|
+
if (part === '\n' || part === '\r\n') {
|
|
13460
|
+
selection.insertParagraph();
|
|
13461
|
+
} else if (part === '\t') {
|
|
13462
|
+
selection.insertNodes([lexical.$createTabNode()]);
|
|
13463
|
+
} else {
|
|
13464
|
+
selection.insertText(part);
|
|
13465
|
+
}
|
|
13466
|
+
}
|
|
13467
|
+
} else {
|
|
13468
|
+
selection.insertRawText(text);
|
|
13469
|
+
}
|
|
13470
|
+
}
|
|
13471
|
+
}
|
|
13472
|
+
|
|
13473
|
+
/**
|
|
13474
|
+
* Inserts Lexical nodes into the editor using different strategies depending on
|
|
13475
|
+
* some simple selection-based heuristics. If you're looking for a generic way to
|
|
13476
|
+
* to insert nodes into the editor at a specific selection point, you probably want
|
|
13477
|
+
* {@link lexical.$insertNodes}
|
|
13478
|
+
*
|
|
13479
|
+
* @param editor LexicalEditor instance to insert the nodes into.
|
|
13480
|
+
* @param nodes The nodes to insert.
|
|
13481
|
+
* @param selection The selection to insert the nodes into.
|
|
13482
|
+
*/
|
|
13483
|
+
function $insertGeneratedNodes(editor, nodes, selection) {
|
|
13484
|
+
if (!editor.dispatchCommand(lexical.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND, {
|
|
13485
|
+
nodes,
|
|
13486
|
+
selection
|
|
13487
|
+
})) {
|
|
13488
|
+
selection.insertNodes(nodes);
|
|
13489
|
+
}
|
|
13490
|
+
return;
|
|
13491
|
+
}
|
|
13492
|
+
function exportNodeToJSON(node) {
|
|
13493
|
+
const serializedNode = node.exportJSON();
|
|
13494
|
+
const nodeClass = node.constructor;
|
|
13495
|
+
if (serializedNode.type !== nodeClass.getType()) {
|
|
13496
|
+
{
|
|
13497
|
+
throw Error(`LexicalNode: Node ${nodeClass.name} does not implement .exportJSON().`);
|
|
13498
|
+
}
|
|
13499
|
+
}
|
|
13500
|
+
if (lexical.$isElementNode(node)) {
|
|
13501
|
+
const serializedChildren = serializedNode.children;
|
|
13502
|
+
if (!Array.isArray(serializedChildren)) {
|
|
13503
|
+
{
|
|
13504
|
+
throw Error(`LexicalNode: Node ${nodeClass.name} is an element but .exportJSON() does not have a children array.`);
|
|
13505
|
+
}
|
|
13506
|
+
}
|
|
13507
|
+
}
|
|
13508
|
+
return serializedNode;
|
|
13509
|
+
}
|
|
13510
|
+
function $appendNodesToJSON(editor, selection$1, currentNode, targetArray = []) {
|
|
13511
|
+
let shouldInclude = selection$1 !== null ? currentNode.isSelected(selection$1) : true;
|
|
13512
|
+
const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('html');
|
|
13513
|
+
let target = currentNode;
|
|
13514
|
+
if (selection$1 !== null) {
|
|
13515
|
+
let clone = selection.$cloneWithProperties(currentNode);
|
|
13516
|
+
clone = lexical.$isTextNode(clone) && selection$1 !== null ? selection.$sliceSelectedTextNodeContent(selection$1, clone) : clone;
|
|
13517
|
+
target = clone;
|
|
13518
|
+
}
|
|
13519
|
+
const children = lexical.$isElementNode(target) ? target.getChildren() : [];
|
|
13520
|
+
const serializedNode = exportNodeToJSON(target);
|
|
13521
|
+
|
|
13522
|
+
// TODO: TextNode calls getTextContent() (NOT node.__text) within it's exportJSON method
|
|
13523
|
+
// which uses getLatest() to get the text from the original node with the same key.
|
|
13524
|
+
// This is a deeper issue with the word "clone" here, it's still a reference to the
|
|
13525
|
+
// same node as far as the LexicalEditor is concerned since it shares a key.
|
|
13526
|
+
// We need a way to create a clone of a Node in memory with it's own key, but
|
|
13527
|
+
// until then this hack will work for the selected text extract use case.
|
|
13528
|
+
if (lexical.$isTextNode(target)) {
|
|
13529
|
+
const text = target.__text;
|
|
13530
|
+
// If an uncollapsed selection ends or starts at the end of a line of specialized,
|
|
13531
|
+
// TextNodes, such as code tokens, we will get a 'blank' TextNode here, i.e., one
|
|
13532
|
+
// with text of length 0. We don't want this, it makes a confusing mess. Reset!
|
|
13533
|
+
if (text.length > 0) {
|
|
13534
|
+
serializedNode.text = text;
|
|
13535
|
+
} else {
|
|
13536
|
+
shouldInclude = false;
|
|
13537
|
+
}
|
|
13538
|
+
}
|
|
13539
|
+
for (let i = 0; i < children.length; i++) {
|
|
13540
|
+
const childNode = children[i];
|
|
13541
|
+
const shouldIncludeChild = $appendNodesToJSON(editor, selection$1, childNode, serializedNode.children);
|
|
13542
|
+
if (!shouldInclude && lexical.$isElementNode(currentNode) && shouldIncludeChild && currentNode.extractWithChild(childNode, selection$1, 'clone')) {
|
|
13543
|
+
shouldInclude = true;
|
|
13544
|
+
}
|
|
13545
|
+
}
|
|
13546
|
+
if (shouldInclude && !shouldExclude) {
|
|
13547
|
+
targetArray.push(serializedNode);
|
|
13548
|
+
} else if (Array.isArray(serializedNode.children)) {
|
|
13549
|
+
for (let i = 0; i < serializedNode.children.length; i++) {
|
|
13550
|
+
const serializedChildNode = serializedNode.children[i];
|
|
13551
|
+
targetArray.push(serializedChildNode);
|
|
13552
|
+
}
|
|
13553
|
+
}
|
|
13554
|
+
return shouldInclude;
|
|
13555
|
+
}
|
|
13556
|
+
|
|
13557
|
+
// TODO why $ function with Editor instance?
|
|
13558
|
+
/**
|
|
13559
|
+
* Gets the Lexical JSON of the nodes inside the provided Selection.
|
|
13560
|
+
*
|
|
13561
|
+
* @param editor LexicalEditor to get the JSON content from.
|
|
13562
|
+
* @param selection Selection to get the JSON content from.
|
|
13563
|
+
* @returns an object with the editor namespace and a list of serializable nodes as JavaScript objects.
|
|
13564
|
+
*/
|
|
13565
|
+
function $generateJSONFromSelectedNodes(editor, selection) {
|
|
13566
|
+
const nodes = [];
|
|
13567
|
+
const root = lexical.$getRoot();
|
|
13568
|
+
const topLevelChildren = root.getChildren();
|
|
13569
|
+
for (let i = 0; i < topLevelChildren.length; i++) {
|
|
13570
|
+
const topLevelNode = topLevelChildren[i];
|
|
13571
|
+
$appendNodesToJSON(editor, selection, topLevelNode, nodes);
|
|
13572
|
+
}
|
|
13573
|
+
return {
|
|
13574
|
+
namespace: editor._config.namespace,
|
|
13575
|
+
nodes
|
|
13576
|
+
};
|
|
13577
|
+
}
|
|
13578
|
+
|
|
13579
|
+
/**
|
|
13580
|
+
* This method takes an array of objects conforming to the BaseSeralizedNode interface and returns
|
|
13581
|
+
* an Array containing instances of the corresponding LexicalNode classes registered on the editor.
|
|
13582
|
+
* Normally, you'd get an Array of BaseSerialized nodes from {@link $generateJSONFromSelectedNodes}
|
|
13583
|
+
*
|
|
13584
|
+
* @param serializedNodes an Array of objects conforming to the BaseSerializedNode interface.
|
|
13585
|
+
* @returns an Array of Lexical Node objects.
|
|
13586
|
+
*/
|
|
13587
|
+
function $generateNodesFromSerializedNodes(serializedNodes) {
|
|
13588
|
+
const nodes = [];
|
|
13589
|
+
for (let i = 0; i < serializedNodes.length; i++) {
|
|
13590
|
+
const serializedNode = serializedNodes[i];
|
|
13591
|
+
const node = lexical.$parseSerializedNode(serializedNode);
|
|
13592
|
+
if (lexical.$isTextNode(node)) {
|
|
13593
|
+
selection.$addNodeStyle(node);
|
|
13594
|
+
}
|
|
13595
|
+
nodes.push(node);
|
|
13596
|
+
}
|
|
13597
|
+
return nodes;
|
|
13598
|
+
}
|
|
13599
|
+
const EVENT_LATENCY = 50;
|
|
13600
|
+
let clipboardEventTimeout = null;
|
|
13601
|
+
|
|
13602
|
+
// TODO custom selection
|
|
13603
|
+
// TODO potentially have a node customizable version for plain text
|
|
13604
|
+
/**
|
|
13605
|
+
* Copies the content of the current selection to the clipboard in
|
|
13606
|
+
* text/plain, text/html, and application/x-lexical-editor (Lexical JSON)
|
|
13607
|
+
* formats.
|
|
13608
|
+
*
|
|
13609
|
+
* @param editor the LexicalEditor instance to copy content from
|
|
13610
|
+
* @param event the native browser ClipboardEvent to add the content to.
|
|
13611
|
+
* @returns
|
|
13612
|
+
*/
|
|
13613
|
+
async function copyToClipboard(editor, event) {
|
|
13614
|
+
if (clipboardEventTimeout !== null) {
|
|
13615
|
+
// Prevent weird race conditions that can happen when this function is run multiple times
|
|
13616
|
+
// synchronously. In the future, we can do better, we can cancel/override the previously running job.
|
|
13617
|
+
return false;
|
|
13618
|
+
}
|
|
13619
|
+
if (event !== null) {
|
|
13620
|
+
return new Promise((resolve, reject) => {
|
|
13621
|
+
editor.update(() => {
|
|
13622
|
+
resolve($copyToClipboardEvent(editor, event));
|
|
13623
|
+
});
|
|
13624
|
+
});
|
|
13625
|
+
}
|
|
13626
|
+
const rootElement = editor.getRootElement();
|
|
13627
|
+
const windowDocument = editor._window == null ? window.document : editor._window.document;
|
|
13628
|
+
const domSelection = getDOMSelection(editor._window);
|
|
13629
|
+
if (rootElement === null || domSelection === null) {
|
|
13630
|
+
return false;
|
|
13631
|
+
}
|
|
13632
|
+
const element = windowDocument.createElement('span');
|
|
13633
|
+
element.style.cssText = 'position: fixed; top: -1000px;';
|
|
13634
|
+
element.append(windowDocument.createTextNode('#'));
|
|
13635
|
+
rootElement.append(element);
|
|
13636
|
+
const range = new Range();
|
|
13637
|
+
range.setStart(element, 0);
|
|
13638
|
+
range.setEnd(element, 1);
|
|
13639
|
+
domSelection.removeAllRanges();
|
|
13640
|
+
domSelection.addRange(range);
|
|
13641
|
+
return new Promise((resolve, reject) => {
|
|
13642
|
+
const removeListener = editor.registerCommand(lexical.COPY_COMMAND, secondEvent => {
|
|
13643
|
+
if (utils.objectKlassEquals(secondEvent, ClipboardEvent)) {
|
|
13644
|
+
removeListener();
|
|
13645
|
+
if (clipboardEventTimeout !== null) {
|
|
13646
|
+
window.clearTimeout(clipboardEventTimeout);
|
|
13647
|
+
clipboardEventTimeout = null;
|
|
13648
|
+
}
|
|
13649
|
+
resolve($copyToClipboardEvent(editor, secondEvent));
|
|
13650
|
+
}
|
|
13651
|
+
// Block the entire copy flow while we wait for the next ClipboardEvent
|
|
13652
|
+
return true;
|
|
13653
|
+
}, lexical.COMMAND_PRIORITY_CRITICAL);
|
|
13654
|
+
// If the above hack execCommand hack works, this timeout code should never fire. Otherwise,
|
|
13655
|
+
// the listener will be quickly freed so that the user can reuse it again
|
|
13656
|
+
clipboardEventTimeout = window.setTimeout(() => {
|
|
13657
|
+
removeListener();
|
|
13658
|
+
clipboardEventTimeout = null;
|
|
13659
|
+
resolve(false);
|
|
13660
|
+
}, EVENT_LATENCY);
|
|
13661
|
+
windowDocument.execCommand('copy');
|
|
13662
|
+
element.remove();
|
|
13663
|
+
});
|
|
13664
|
+
}
|
|
13665
|
+
|
|
13666
|
+
// TODO shouldn't pass editor (pass namespace directly)
|
|
13667
|
+
function $copyToClipboardEvent(editor, event) {
|
|
13668
|
+
const domSelection = getDOMSelection(editor._window);
|
|
13669
|
+
if (!domSelection) {
|
|
13670
|
+
return false;
|
|
13671
|
+
}
|
|
13672
|
+
const anchorDOM = domSelection.anchorNode;
|
|
13673
|
+
const focusDOM = domSelection.focusNode;
|
|
13674
|
+
if (anchorDOM !== null && focusDOM !== null && !lexical.isSelectionWithinEditor(editor, anchorDOM, focusDOM)) {
|
|
13675
|
+
return false;
|
|
13676
|
+
}
|
|
13677
|
+
event.preventDefault();
|
|
13678
|
+
const clipboardData = event.clipboardData;
|
|
13679
|
+
const selection = lexical.$getSelection();
|
|
13680
|
+
if (clipboardData === null || selection === null) {
|
|
13681
|
+
return false;
|
|
13682
|
+
}
|
|
13683
|
+
const htmlString = $getHtmlContent(editor);
|
|
13684
|
+
const lexicalString = $getLexicalContent(editor);
|
|
13685
|
+
let plainString = '';
|
|
13686
|
+
if (selection !== null) {
|
|
13687
|
+
plainString = selection.getTextContent();
|
|
13688
|
+
}
|
|
13689
|
+
if (htmlString !== null) {
|
|
13690
|
+
clipboardData.setData('text/html', htmlString);
|
|
13691
|
+
}
|
|
13692
|
+
if (lexicalString !== null) {
|
|
13693
|
+
clipboardData.setData('application/x-lexical-editor', lexicalString);
|
|
13694
|
+
}
|
|
13695
|
+
clipboardData.setData('text/plain', plainString);
|
|
13696
|
+
return true;
|
|
13697
|
+
}
|
|
13698
|
+
|
|
13699
|
+
LexicalClipboard_dev.$generateJSONFromSelectedNodes = $generateJSONFromSelectedNodes;
|
|
13700
|
+
LexicalClipboard_dev.$generateNodesFromSerializedNodes = $generateNodesFromSerializedNodes;
|
|
13701
|
+
LexicalClipboard_dev.$getHtmlContent = $getHtmlContent;
|
|
13702
|
+
LexicalClipboard_dev.$getLexicalContent = $getLexicalContent;
|
|
13703
|
+
LexicalClipboard_dev.$insertDataTransferForPlainText = $insertDataTransferForPlainText;
|
|
13704
|
+
LexicalClipboard_dev.$insertDataTransferForRichText = $insertDataTransferForRichText;
|
|
13705
|
+
LexicalClipboard_dev.$insertGeneratedNodes = $insertGeneratedNodes;
|
|
13706
|
+
LexicalClipboard_dev.copyToClipboard = copyToClipboard;
|
|
13707
|
+
return LexicalClipboard_dev;
|
|
13708
|
+
}
|
|
13709
|
+
|
|
13710
|
+
var LexicalClipboard_prod = {};
|
|
13711
|
+
|
|
13712
|
+
/**
|
|
13713
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13714
|
+
*
|
|
13715
|
+
* This source code is licensed under the MIT license found in the
|
|
13716
|
+
* LICENSE file in the root directory of this source tree.
|
|
13717
|
+
*/
|
|
13718
|
+
|
|
13719
|
+
var hasRequiredLexicalClipboard_prod;
|
|
13720
|
+
|
|
13721
|
+
function requireLexicalClipboard_prod () {
|
|
13722
|
+
if (hasRequiredLexicalClipboard_prod) return LexicalClipboard_prod;
|
|
13723
|
+
hasRequiredLexicalClipboard_prod = 1;
|
|
13724
|
+
var f=requireLexicalHtml(),m=requireLexicalSelection(),q=requireLexicalUtils(),r=require$$3;function t(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
|
13725
|
+
let u="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement;function v(a){let b=r.$getSelection();if(null==b)throw Error("Expected valid LexicalSelection");return r.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":f.$generateHtmlFromNodes(a,b)}
|
|
13726
|
+
function w(a){let b=r.$getSelection();if(null==b)throw Error("Expected valid LexicalSelection");return r.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(x(a,b))}function y(a,b,c){a.dispatchCommand(r.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND,{nodes:b,selection:c})||c.insertNodes(b);}
|
|
13727
|
+
function z(a,b,c,d=[]){let e=null!==b?c.isSelected(b):true,h=r.$isElementNode(c)&&c.excludeFromCopy("html");var g=c;if(null!==b){var k=m.$cloneWithProperties(c);g=k=r.$isTextNode(k)&&null!==b?m.$sliceSelectedTextNodeContent(b,k):k;}let n=r.$isElementNode(g)?g.getChildren():[];var l=g;k=l.exportJSON();var p=l.constructor;k.type!==p.getType()&&t(58,p.name);r.$isElementNode(l)&&(Array.isArray(k.children)||t(59,p.name));r.$isTextNode(g)&&(g=g.__text,0<g.length?k.text=g:e=false);for(g=0;g<n.length;g++)l=n[g],
|
|
13728
|
+
p=z(a,b,l,k.children),!e&&r.$isElementNode(c)&&p&&c.extractWithChild(l,b,"clone")&&(e=true);if(e&&!h)d.push(k);else if(Array.isArray(k.children))for(a=0;a<k.children.length;a++)d.push(k.children[a]);return e}function x(a,b){let c=[],d=r.$getRoot().getChildren();for(let e=0;e<d.length;e++)z(a,b,d[e],c);return {namespace:a._config.namespace,nodes:c}}function A(a){let b=[];for(let c=0;c<a.length;c++){let d=r.$parseSerializedNode(a[c]);r.$isTextNode(d)&&m.$addNodeStyle(d);b.push(d);}return b}let B=null;
|
|
13729
|
+
function C(a,b){var c=u?(a._window||window).getSelection():null;if(!c)return false;var d=c.anchorNode;c=c.focusNode;if(null!==d&&null!==c&&!r.isSelectionWithinEditor(a,d,c))return false;b.preventDefault();b=b.clipboardData;d=r.$getSelection();if(null===b||null===d)return false;c=v(a);a=w(a);let e="";null!==d&&(e=d.getTextContent());null!==c&&b.setData("text/html",c);null!==a&&b.setData("application/x-lexical-editor",a);b.setData("text/plain",e);return true}LexicalClipboard_prod.$generateJSONFromSelectedNodes=x;
|
|
13730
|
+
LexicalClipboard_prod.$generateNodesFromSerializedNodes=A;LexicalClipboard_prod.$getHtmlContent=v;LexicalClipboard_prod.$getLexicalContent=w;LexicalClipboard_prod.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain")||a.getData("text/uri-list");null!=a&&b.insertRawText(a);};
|
|
13731
|
+
LexicalClipboard_prod.$insertDataTransferForRichText=function(a,b,c){var d=a.getData("application/x-lexical-editor");if(d)try{let h=JSON.parse(d);if(h.namespace===c._config.namespace&&Array.isArray(h.nodes)){let g=A(h.nodes);return y(c,g,b)}}catch(h){}if(d=a.getData("text/html"))try{var e=(new DOMParser).parseFromString(d,"text/html");let h=f.$generateNodesFromDOM(c,e);return y(c,h,b)}catch(h){}a=a.getData("text/plain")||a.getData("text/uri-list");if(null!=a)if(r.$isRangeSelection(b))for(a=a.split(/(\r?\n|\t)/),
|
|
13732
|
+
""===a[a.length-1]&&a.pop(),c=0;c<a.length;c++)e=a[c],"\n"===e||"\r\n"===e?b.insertParagraph():"\t"===e?b.insertNodes([r.$createTabNode()]):b.insertText(e);else b.insertRawText(a);};LexicalClipboard_prod.$insertGeneratedNodes=y;
|
|
13733
|
+
LexicalClipboard_prod.copyToClipboard=async function(a,b){if(null!==B)return false;if(null!==b)return new Promise(g=>{a.update(()=>{g(C(a,b));});});var c=a.getRootElement();let d=null==a._window?window.document:a._window.document,e=u?(a._window||window).getSelection():null;if(null===c||null===e)return false;let h=d.createElement("span");h.style.cssText="position: fixed; top: -1000px;";h.append(d.createTextNode("#"));c.append(h);c=new Range;c.setStart(h,0);c.setEnd(h,1);e.removeAllRanges();e.addRange(c);return new Promise(g=>
|
|
13734
|
+
{let k=a.registerCommand(r.COPY_COMMAND,n=>{q.objectKlassEquals(n,ClipboardEvent)&&(k(),null!==B&&(window.clearTimeout(B),B=null),g(C(a,n)));return true},r.COMMAND_PRIORITY_CRITICAL);B=window.setTimeout(()=>{k();B=null;g(false);},50);d.execCommand("copy");h.remove();})};
|
|
13735
|
+
return LexicalClipboard_prod;
|
|
13736
|
+
}
|
|
13737
|
+
|
|
13738
|
+
/**
|
|
13739
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13740
|
+
*
|
|
13741
|
+
* This source code is licensed under the MIT license found in the
|
|
13742
|
+
* LICENSE file in the root directory of this source tree.
|
|
13743
|
+
*/
|
|
13744
|
+
|
|
13745
|
+
var LexicalClipboard_1;
|
|
13746
|
+
var hasRequiredLexicalClipboard;
|
|
13747
|
+
|
|
13748
|
+
function requireLexicalClipboard () {
|
|
13749
|
+
if (hasRequiredLexicalClipboard) return LexicalClipboard_1;
|
|
13750
|
+
hasRequiredLexicalClipboard = 1;
|
|
13751
|
+
const LexicalClipboard = process.env.NODE_ENV === 'development' ? requireLexicalClipboard_dev() : requireLexicalClipboard_prod();
|
|
13752
|
+
LexicalClipboard_1 = LexicalClipboard;
|
|
13753
|
+
return LexicalClipboard_1;
|
|
13754
|
+
}
|
|
13755
|
+
|
|
13756
|
+
/**
|
|
13757
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13758
|
+
*
|
|
13759
|
+
* This source code is licensed under the MIT license found in the
|
|
13760
|
+
* LICENSE file in the root directory of this source tree.
|
|
13761
|
+
*/
|
|
13762
|
+
|
|
13763
|
+
var hasRequiredLexicalRichText_dev;
|
|
13764
|
+
|
|
13765
|
+
function requireLexicalRichText_dev () {
|
|
13766
|
+
if (hasRequiredLexicalRichText_dev) return LexicalRichText_dev;
|
|
13767
|
+
hasRequiredLexicalRichText_dev = 1;
|
|
13768
|
+
|
|
13769
|
+
var clipboard = requireLexicalClipboard();
|
|
13770
|
+
var selection = requireLexicalSelection();
|
|
13771
|
+
var utils = requireLexicalUtils();
|
|
13772
|
+
var lexical = require$$3;
|
|
13773
|
+
|
|
13774
|
+
/**
|
|
13775
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13776
|
+
*
|
|
13777
|
+
* This source code is licensed under the MIT license found in the
|
|
13778
|
+
* LICENSE file in the root directory of this source tree.
|
|
13779
|
+
*
|
|
13780
|
+
*/
|
|
13781
|
+
|
|
13782
|
+
function caretFromPoint(x, y) {
|
|
13783
|
+
if (typeof document.caretRangeFromPoint !== 'undefined') {
|
|
13784
|
+
const range = document.caretRangeFromPoint(x, y);
|
|
13785
|
+
if (range === null) {
|
|
13786
|
+
return null;
|
|
13787
|
+
}
|
|
13788
|
+
return {
|
|
13789
|
+
node: range.startContainer,
|
|
13790
|
+
offset: range.startOffset
|
|
13791
|
+
};
|
|
13792
|
+
// @ts-ignore
|
|
13793
|
+
} else if (document.caretPositionFromPoint !== 'undefined') {
|
|
13794
|
+
// @ts-ignore FF - no types
|
|
13795
|
+
const range = document.caretPositionFromPoint(x, y);
|
|
13796
|
+
if (range === null) {
|
|
13797
|
+
return null;
|
|
13798
|
+
}
|
|
13799
|
+
return {
|
|
13800
|
+
node: range.offsetNode,
|
|
13801
|
+
offset: range.offset
|
|
13802
|
+
};
|
|
13803
|
+
} else {
|
|
13804
|
+
// Gracefully handle IE
|
|
13805
|
+
return null;
|
|
13806
|
+
}
|
|
13807
|
+
}
|
|
13808
|
+
|
|
13809
|
+
/**
|
|
13810
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13811
|
+
*
|
|
13812
|
+
* This source code is licensed under the MIT license found in the
|
|
13813
|
+
* LICENSE file in the root directory of this source tree.
|
|
13814
|
+
*
|
|
13815
|
+
*/
|
|
13816
|
+
|
|
13817
|
+
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
13818
|
+
|
|
13819
|
+
/**
|
|
13820
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13821
|
+
*
|
|
13822
|
+
* This source code is licensed under the MIT license found in the
|
|
13823
|
+
* LICENSE file in the root directory of this source tree.
|
|
13824
|
+
*
|
|
13825
|
+
*/
|
|
13826
|
+
const documentMode = CAN_USE_DOM && 'documentMode' in document ? document.documentMode : null;
|
|
13827
|
+
const CAN_USE_BEFORE_INPUT = CAN_USE_DOM && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;
|
|
13828
|
+
const IS_SAFARI = CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
|
|
13829
|
+
const IS_IOS = CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
|
13830
|
+
|
|
13831
|
+
// Keep these in case we need to use them in the future.
|
|
13832
|
+
// export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
|
|
13833
|
+
const IS_CHROME = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
|
|
13834
|
+
// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
|
|
13835
|
+
|
|
13836
|
+
const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.userAgent) && !IS_CHROME;
|
|
13837
|
+
|
|
13838
|
+
/** @module @lexical/rich-text */
|
|
13839
|
+
const DRAG_DROP_PASTE = lexical.createCommand('DRAG_DROP_PASTE_FILE');
|
|
13840
|
+
/** @noInheritDoc */
|
|
13841
|
+
class QuoteNode extends lexical.ElementNode {
|
|
13842
|
+
static getType() {
|
|
13843
|
+
return 'quote';
|
|
13844
|
+
}
|
|
13845
|
+
static clone(node) {
|
|
13846
|
+
return new QuoteNode(node.__key);
|
|
13847
|
+
}
|
|
13848
|
+
constructor(key) {
|
|
13849
|
+
super(key);
|
|
13850
|
+
}
|
|
13851
|
+
|
|
13852
|
+
// View
|
|
13853
|
+
|
|
13854
|
+
createDOM(config) {
|
|
13855
|
+
const element = document.createElement('blockquote');
|
|
13856
|
+
utils.addClassNamesToElement(element, config.theme.quote);
|
|
13857
|
+
return element;
|
|
13858
|
+
}
|
|
13859
|
+
updateDOM(prevNode, dom) {
|
|
13860
|
+
return false;
|
|
13861
|
+
}
|
|
13862
|
+
static importDOM() {
|
|
13863
|
+
return {
|
|
13864
|
+
blockquote: node => ({
|
|
13865
|
+
conversion: convertBlockquoteElement,
|
|
13866
|
+
priority: 0
|
|
13867
|
+
})
|
|
13868
|
+
};
|
|
13869
|
+
}
|
|
13870
|
+
exportDOM(editor) {
|
|
13871
|
+
const {
|
|
13872
|
+
element
|
|
13873
|
+
} = super.exportDOM(editor);
|
|
13874
|
+
if (element && utils.isHTMLElement(element)) {
|
|
13875
|
+
if (this.isEmpty()) element.append(document.createElement('br'));
|
|
13876
|
+
const formatType = this.getFormatType();
|
|
13877
|
+
element.style.textAlign = formatType;
|
|
13878
|
+
const direction = this.getDirection();
|
|
13879
|
+
if (direction) {
|
|
13880
|
+
element.dir = direction;
|
|
13881
|
+
}
|
|
13882
|
+
}
|
|
13883
|
+
return {
|
|
13884
|
+
element
|
|
13885
|
+
};
|
|
13886
|
+
}
|
|
13887
|
+
static importJSON(serializedNode) {
|
|
13888
|
+
const node = $createQuoteNode();
|
|
13889
|
+
node.setFormat(serializedNode.format);
|
|
13890
|
+
node.setIndent(serializedNode.indent);
|
|
13891
|
+
node.setDirection(serializedNode.direction);
|
|
13892
|
+
return node;
|
|
13893
|
+
}
|
|
13894
|
+
exportJSON() {
|
|
13895
|
+
return {
|
|
13896
|
+
...super.exportJSON(),
|
|
13897
|
+
type: 'quote'
|
|
13898
|
+
};
|
|
13899
|
+
}
|
|
13900
|
+
|
|
13901
|
+
// Mutation
|
|
13902
|
+
|
|
13903
|
+
insertNewAfter(_, restoreSelection) {
|
|
13904
|
+
const newBlock = lexical.$createParagraphNode();
|
|
13905
|
+
const direction = this.getDirection();
|
|
13906
|
+
newBlock.setDirection(direction);
|
|
13907
|
+
this.insertAfter(newBlock, restoreSelection);
|
|
13908
|
+
return newBlock;
|
|
13909
|
+
}
|
|
13910
|
+
collapseAtStart() {
|
|
13911
|
+
const paragraph = lexical.$createParagraphNode();
|
|
13912
|
+
const children = this.getChildren();
|
|
13913
|
+
children.forEach(child => paragraph.append(child));
|
|
13914
|
+
this.replace(paragraph);
|
|
13915
|
+
return true;
|
|
13916
|
+
}
|
|
13917
|
+
}
|
|
13918
|
+
function $createQuoteNode() {
|
|
13919
|
+
return lexical.$applyNodeReplacement(new QuoteNode());
|
|
13920
|
+
}
|
|
13921
|
+
function $isQuoteNode(node) {
|
|
13922
|
+
return node instanceof QuoteNode;
|
|
13923
|
+
}
|
|
13924
|
+
/** @noInheritDoc */
|
|
13925
|
+
class HeadingNode extends lexical.ElementNode {
|
|
13926
|
+
/** @internal */
|
|
13927
|
+
|
|
13928
|
+
static getType() {
|
|
13929
|
+
return 'heading';
|
|
13930
|
+
}
|
|
13931
|
+
static clone(node) {
|
|
13932
|
+
return new HeadingNode(node.__tag, node.__key);
|
|
13933
|
+
}
|
|
13934
|
+
constructor(tag, key) {
|
|
13935
|
+
super(key);
|
|
13936
|
+
this.__tag = tag;
|
|
13937
|
+
}
|
|
13938
|
+
getTag() {
|
|
13939
|
+
return this.__tag;
|
|
13940
|
+
}
|
|
13941
|
+
|
|
13942
|
+
// View
|
|
13943
|
+
|
|
13944
|
+
createDOM(config) {
|
|
13945
|
+
const tag = this.__tag;
|
|
13946
|
+
const element = document.createElement(tag);
|
|
13947
|
+
const theme = config.theme;
|
|
13948
|
+
const classNames = theme.heading;
|
|
13949
|
+
if (classNames !== undefined) {
|
|
13950
|
+
const className = classNames[tag];
|
|
13951
|
+
utils.addClassNamesToElement(element, className);
|
|
13952
|
+
}
|
|
13953
|
+
return element;
|
|
13954
|
+
}
|
|
13955
|
+
updateDOM(prevNode, dom) {
|
|
13956
|
+
return false;
|
|
13957
|
+
}
|
|
13958
|
+
static importDOM() {
|
|
13959
|
+
return {
|
|
13960
|
+
h1: node => ({
|
|
13961
|
+
conversion: convertHeadingElement,
|
|
13962
|
+
priority: 0
|
|
13963
|
+
}),
|
|
13964
|
+
h2: node => ({
|
|
13965
|
+
conversion: convertHeadingElement,
|
|
13966
|
+
priority: 0
|
|
13967
|
+
}),
|
|
13968
|
+
h3: node => ({
|
|
13969
|
+
conversion: convertHeadingElement,
|
|
13970
|
+
priority: 0
|
|
13971
|
+
}),
|
|
13972
|
+
h4: node => ({
|
|
13973
|
+
conversion: convertHeadingElement,
|
|
13974
|
+
priority: 0
|
|
13975
|
+
}),
|
|
13976
|
+
h5: node => ({
|
|
13977
|
+
conversion: convertHeadingElement,
|
|
13978
|
+
priority: 0
|
|
13979
|
+
}),
|
|
13980
|
+
h6: node => ({
|
|
13981
|
+
conversion: convertHeadingElement,
|
|
13982
|
+
priority: 0
|
|
13983
|
+
}),
|
|
13984
|
+
p: node => {
|
|
13985
|
+
// domNode is a <p> since we matched it by nodeName
|
|
13986
|
+
const paragraph = node;
|
|
13987
|
+
const firstChild = paragraph.firstChild;
|
|
13988
|
+
if (firstChild !== null && isGoogleDocsTitle(firstChild)) {
|
|
13989
|
+
return {
|
|
13990
|
+
conversion: () => ({
|
|
13991
|
+
node: null
|
|
13992
|
+
}),
|
|
13993
|
+
priority: 3
|
|
13994
|
+
};
|
|
13995
|
+
}
|
|
13996
|
+
return null;
|
|
13997
|
+
},
|
|
13998
|
+
span: node => {
|
|
13999
|
+
if (isGoogleDocsTitle(node)) {
|
|
14000
|
+
return {
|
|
14001
|
+
conversion: domNode => {
|
|
14002
|
+
return {
|
|
14003
|
+
node: $createHeadingNode('h1')
|
|
14004
|
+
};
|
|
14005
|
+
},
|
|
14006
|
+
priority: 3
|
|
14007
|
+
};
|
|
14008
|
+
}
|
|
14009
|
+
return null;
|
|
14010
|
+
}
|
|
14011
|
+
};
|
|
14012
|
+
}
|
|
14013
|
+
exportDOM(editor) {
|
|
14014
|
+
const {
|
|
14015
|
+
element
|
|
14016
|
+
} = super.exportDOM(editor);
|
|
14017
|
+
if (element && utils.isHTMLElement(element)) {
|
|
14018
|
+
if (this.isEmpty()) element.append(document.createElement('br'));
|
|
14019
|
+
const formatType = this.getFormatType();
|
|
14020
|
+
element.style.textAlign = formatType;
|
|
14021
|
+
const direction = this.getDirection();
|
|
14022
|
+
if (direction) {
|
|
14023
|
+
element.dir = direction;
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
return {
|
|
14027
|
+
element
|
|
14028
|
+
};
|
|
14029
|
+
}
|
|
14030
|
+
static importJSON(serializedNode) {
|
|
14031
|
+
const node = $createHeadingNode(serializedNode.tag);
|
|
14032
|
+
node.setFormat(serializedNode.format);
|
|
14033
|
+
node.setIndent(serializedNode.indent);
|
|
14034
|
+
node.setDirection(serializedNode.direction);
|
|
14035
|
+
return node;
|
|
14036
|
+
}
|
|
14037
|
+
exportJSON() {
|
|
14038
|
+
return {
|
|
14039
|
+
...super.exportJSON(),
|
|
14040
|
+
tag: this.getTag(),
|
|
14041
|
+
type: 'heading',
|
|
14042
|
+
version: 1
|
|
14043
|
+
};
|
|
14044
|
+
}
|
|
14045
|
+
|
|
14046
|
+
// Mutation
|
|
14047
|
+
insertNewAfter(selection, restoreSelection = true) {
|
|
14048
|
+
const anchorOffet = selection ? selection.anchor.offset : 0;
|
|
14049
|
+
const newElement = anchorOffet === this.getTextContentSize() || !selection ? lexical.$createParagraphNode() : $createHeadingNode(this.getTag());
|
|
14050
|
+
const direction = this.getDirection();
|
|
14051
|
+
newElement.setDirection(direction);
|
|
14052
|
+
this.insertAfter(newElement, restoreSelection);
|
|
14053
|
+
if (anchorOffet === 0 && !this.isEmpty() && selection) {
|
|
14054
|
+
const paragraph = lexical.$createParagraphNode();
|
|
14055
|
+
paragraph.select();
|
|
14056
|
+
this.replace(paragraph, true);
|
|
14057
|
+
}
|
|
14058
|
+
return newElement;
|
|
14059
|
+
}
|
|
14060
|
+
collapseAtStart() {
|
|
14061
|
+
const newElement = !this.isEmpty() ? $createHeadingNode(this.getTag()) : lexical.$createParagraphNode();
|
|
14062
|
+
const children = this.getChildren();
|
|
14063
|
+
children.forEach(child => newElement.append(child));
|
|
14064
|
+
this.replace(newElement);
|
|
14065
|
+
return true;
|
|
14066
|
+
}
|
|
14067
|
+
extractWithChild() {
|
|
14068
|
+
return true;
|
|
14069
|
+
}
|
|
14070
|
+
}
|
|
14071
|
+
function isGoogleDocsTitle(domNode) {
|
|
14072
|
+
if (domNode.nodeName.toLowerCase() === 'span') {
|
|
14073
|
+
return domNode.style.fontSize === '26pt';
|
|
14074
|
+
}
|
|
14075
|
+
return false;
|
|
14076
|
+
}
|
|
14077
|
+
function convertHeadingElement(element) {
|
|
14078
|
+
const nodeName = element.nodeName.toLowerCase();
|
|
14079
|
+
let node = null;
|
|
14080
|
+
if (nodeName === 'h1' || nodeName === 'h2' || nodeName === 'h3' || nodeName === 'h4' || nodeName === 'h5' || nodeName === 'h6') {
|
|
14081
|
+
node = $createHeadingNode(nodeName);
|
|
14082
|
+
if (element.style !== null) {
|
|
14083
|
+
node.setFormat(element.style.textAlign);
|
|
14084
|
+
}
|
|
14085
|
+
}
|
|
14086
|
+
return {
|
|
14087
|
+
node
|
|
14088
|
+
};
|
|
14089
|
+
}
|
|
14090
|
+
function convertBlockquoteElement(element) {
|
|
14091
|
+
const node = $createQuoteNode();
|
|
14092
|
+
if (element.style !== null) {
|
|
14093
|
+
node.setFormat(element.style.textAlign);
|
|
14094
|
+
}
|
|
14095
|
+
return {
|
|
14096
|
+
node
|
|
14097
|
+
};
|
|
14098
|
+
}
|
|
14099
|
+
function $createHeadingNode(headingTag) {
|
|
14100
|
+
return lexical.$applyNodeReplacement(new HeadingNode(headingTag));
|
|
14101
|
+
}
|
|
14102
|
+
function $isHeadingNode(node) {
|
|
14103
|
+
return node instanceof HeadingNode;
|
|
14104
|
+
}
|
|
14105
|
+
function onPasteForRichText(event, editor) {
|
|
14106
|
+
event.preventDefault();
|
|
14107
|
+
editor.update(() => {
|
|
14108
|
+
const selection = lexical.$getSelection();
|
|
14109
|
+
const clipboardData = event instanceof InputEvent || event instanceof KeyboardEvent ? null : event.clipboardData;
|
|
14110
|
+
if (clipboardData != null && selection !== null) {
|
|
14111
|
+
clipboard.$insertDataTransferForRichText(clipboardData, selection, editor);
|
|
14112
|
+
}
|
|
14113
|
+
}, {
|
|
14114
|
+
tag: 'paste'
|
|
14115
|
+
});
|
|
14116
|
+
}
|
|
14117
|
+
async function onCutForRichText(event, editor) {
|
|
14118
|
+
await clipboard.copyToClipboard(editor, utils.objectKlassEquals(event, ClipboardEvent) ? event : null);
|
|
14119
|
+
editor.update(() => {
|
|
14120
|
+
const selection = lexical.$getSelection();
|
|
14121
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
14122
|
+
selection.removeText();
|
|
14123
|
+
} else if (lexical.$isNodeSelection(selection)) {
|
|
14124
|
+
selection.getNodes().forEach(node => node.remove());
|
|
14125
|
+
}
|
|
14126
|
+
});
|
|
14127
|
+
}
|
|
14128
|
+
|
|
14129
|
+
// Clipboard may contain files that we aren't allowed to read. While the event is arguably useless,
|
|
14130
|
+
// in certain occasions, we want to know whether it was a file transfer, as opposed to text. We
|
|
14131
|
+
// control this with the first boolean flag.
|
|
14132
|
+
function eventFiles(event) {
|
|
14133
|
+
let dataTransfer = null;
|
|
14134
|
+
if (event instanceof DragEvent) {
|
|
14135
|
+
dataTransfer = event.dataTransfer;
|
|
14136
|
+
} else if (event instanceof ClipboardEvent) {
|
|
14137
|
+
dataTransfer = event.clipboardData;
|
|
14138
|
+
}
|
|
14139
|
+
if (dataTransfer === null) {
|
|
14140
|
+
return [false, [], false];
|
|
14141
|
+
}
|
|
14142
|
+
const types = dataTransfer.types;
|
|
14143
|
+
const hasFiles = types.includes('Files');
|
|
14144
|
+
const hasContent = types.includes('text/html') || types.includes('text/plain');
|
|
14145
|
+
return [hasFiles, Array.from(dataTransfer.files), hasContent];
|
|
14146
|
+
}
|
|
14147
|
+
function handleIndentAndOutdent(indentOrOutdent) {
|
|
14148
|
+
const selection = lexical.$getSelection();
|
|
14149
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14150
|
+
return false;
|
|
14151
|
+
}
|
|
14152
|
+
const alreadyHandled = new Set();
|
|
14153
|
+
const nodes = selection.getNodes();
|
|
14154
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
14155
|
+
const node = nodes[i];
|
|
14156
|
+
const key = node.getKey();
|
|
14157
|
+
if (alreadyHandled.has(key)) {
|
|
14158
|
+
continue;
|
|
14159
|
+
}
|
|
14160
|
+
const parentBlock = utils.$getNearestBlockElementAncestorOrThrow(node);
|
|
14161
|
+
const parentKey = parentBlock.getKey();
|
|
14162
|
+
if (parentBlock.canIndent() && !alreadyHandled.has(parentKey)) {
|
|
14163
|
+
alreadyHandled.add(parentKey);
|
|
14164
|
+
indentOrOutdent(parentBlock);
|
|
14165
|
+
}
|
|
14166
|
+
}
|
|
14167
|
+
return alreadyHandled.size > 0;
|
|
14168
|
+
}
|
|
14169
|
+
function $isTargetWithinDecorator(target) {
|
|
14170
|
+
const node = lexical.$getNearestNodeFromDOMNode(target);
|
|
14171
|
+
return lexical.$isDecoratorNode(node);
|
|
14172
|
+
}
|
|
14173
|
+
function $isSelectionAtEndOfRoot(selection) {
|
|
14174
|
+
const focus = selection.focus;
|
|
14175
|
+
return focus.key === 'root' && focus.offset === lexical.$getRoot().getChildrenSize();
|
|
14176
|
+
}
|
|
14177
|
+
function registerRichText(editor) {
|
|
14178
|
+
const removeListener = utils.mergeRegister(editor.registerCommand(lexical.CLICK_COMMAND, payload => {
|
|
14179
|
+
const selection = lexical.$getSelection();
|
|
14180
|
+
if (lexical.$isNodeSelection(selection)) {
|
|
14181
|
+
selection.clear();
|
|
14182
|
+
return true;
|
|
14183
|
+
}
|
|
14184
|
+
return false;
|
|
14185
|
+
}, 0), editor.registerCommand(lexical.DELETE_CHARACTER_COMMAND, isBackward => {
|
|
14186
|
+
const selection = lexical.$getSelection();
|
|
14187
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14188
|
+
return false;
|
|
14189
|
+
}
|
|
14190
|
+
selection.deleteCharacter(isBackward);
|
|
14191
|
+
return true;
|
|
14192
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DELETE_WORD_COMMAND, isBackward => {
|
|
14193
|
+
const selection = lexical.$getSelection();
|
|
14194
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14195
|
+
return false;
|
|
14196
|
+
}
|
|
14197
|
+
selection.deleteWord(isBackward);
|
|
14198
|
+
return true;
|
|
14199
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DELETE_LINE_COMMAND, isBackward => {
|
|
14200
|
+
const selection = lexical.$getSelection();
|
|
14201
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14202
|
+
return false;
|
|
14203
|
+
}
|
|
14204
|
+
selection.deleteLine(isBackward);
|
|
14205
|
+
return true;
|
|
14206
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.CONTROLLED_TEXT_INSERTION_COMMAND, eventOrText => {
|
|
14207
|
+
const selection = lexical.$getSelection();
|
|
14208
|
+
if (typeof eventOrText === 'string') {
|
|
14209
|
+
if (selection !== null) {
|
|
14210
|
+
selection.insertText(eventOrText);
|
|
14211
|
+
}
|
|
14212
|
+
} else {
|
|
14213
|
+
if (selection === null) {
|
|
14214
|
+
return false;
|
|
14215
|
+
}
|
|
14216
|
+
const dataTransfer = eventOrText.dataTransfer;
|
|
14217
|
+
if (dataTransfer != null) {
|
|
14218
|
+
clipboard.$insertDataTransferForRichText(dataTransfer, selection, editor);
|
|
14219
|
+
} else if (lexical.$isRangeSelection(selection)) {
|
|
14220
|
+
const data = eventOrText.data;
|
|
14221
|
+
if (data) {
|
|
14222
|
+
selection.insertText(data);
|
|
14223
|
+
}
|
|
14224
|
+
return true;
|
|
14225
|
+
}
|
|
14226
|
+
}
|
|
14227
|
+
return true;
|
|
14228
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.REMOVE_TEXT_COMMAND, () => {
|
|
14229
|
+
const selection = lexical.$getSelection();
|
|
14230
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14231
|
+
return false;
|
|
14232
|
+
}
|
|
14233
|
+
selection.removeText();
|
|
14234
|
+
return true;
|
|
14235
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.FORMAT_TEXT_COMMAND, format => {
|
|
14236
|
+
const selection = lexical.$getSelection();
|
|
14237
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14238
|
+
return false;
|
|
14239
|
+
}
|
|
14240
|
+
selection.formatText(format);
|
|
14241
|
+
return true;
|
|
14242
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.FORMAT_ELEMENT_COMMAND, format => {
|
|
14243
|
+
const selection = lexical.$getSelection();
|
|
14244
|
+
if (!lexical.$isRangeSelection(selection) && !lexical.$isNodeSelection(selection)) {
|
|
14245
|
+
return false;
|
|
14246
|
+
}
|
|
14247
|
+
const nodes = selection.getNodes();
|
|
14248
|
+
for (const node of nodes) {
|
|
14249
|
+
const element = utils.$findMatchingParent(node, parentNode => lexical.$isElementNode(parentNode) && !parentNode.isInline());
|
|
14250
|
+
if (element !== null) {
|
|
14251
|
+
element.setFormat(format);
|
|
14252
|
+
}
|
|
14253
|
+
}
|
|
14254
|
+
return true;
|
|
14255
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INSERT_LINE_BREAK_COMMAND, selectStart => {
|
|
14256
|
+
const selection = lexical.$getSelection();
|
|
14257
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14258
|
+
return false;
|
|
14259
|
+
}
|
|
14260
|
+
selection.insertLineBreak(selectStart);
|
|
14261
|
+
return true;
|
|
14262
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INSERT_PARAGRAPH_COMMAND, () => {
|
|
14263
|
+
const selection = lexical.$getSelection();
|
|
14264
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14265
|
+
return false;
|
|
14266
|
+
}
|
|
14267
|
+
selection.insertParagraph();
|
|
14268
|
+
return true;
|
|
14269
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INSERT_TAB_COMMAND, () => {
|
|
14270
|
+
lexical.$insertNodes([lexical.$createTabNode()]);
|
|
14271
|
+
return true;
|
|
14272
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, () => {
|
|
14273
|
+
return handleIndentAndOutdent(block => {
|
|
14274
|
+
const indent = block.getIndent();
|
|
14275
|
+
block.setIndent(indent + 1);
|
|
14276
|
+
});
|
|
14277
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.OUTDENT_CONTENT_COMMAND, () => {
|
|
14278
|
+
return handleIndentAndOutdent(block => {
|
|
14279
|
+
const indent = block.getIndent();
|
|
14280
|
+
if (indent > 0) {
|
|
14281
|
+
block.setIndent(indent - 1);
|
|
14282
|
+
}
|
|
14283
|
+
});
|
|
14284
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, event => {
|
|
14285
|
+
const selection = lexical.$getSelection();
|
|
14286
|
+
if (lexical.$isNodeSelection(selection) && !$isTargetWithinDecorator(event.target)) {
|
|
14287
|
+
// If selection is on a node, let's try and move selection
|
|
14288
|
+
// back to being a range selection.
|
|
14289
|
+
const nodes = selection.getNodes();
|
|
14290
|
+
if (nodes.length > 0) {
|
|
14291
|
+
nodes[0].selectPrevious();
|
|
14292
|
+
return true;
|
|
14293
|
+
}
|
|
14294
|
+
} else if (lexical.$isRangeSelection(selection)) {
|
|
14295
|
+
const possibleNode = lexical.$getAdjacentNode(selection.focus, true);
|
|
14296
|
+
if (!event.shiftKey && lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() && !possibleNode.isInline()) {
|
|
14297
|
+
possibleNode.selectPrevious();
|
|
14298
|
+
event.preventDefault();
|
|
14299
|
+
return true;
|
|
14300
|
+
}
|
|
14301
|
+
}
|
|
14302
|
+
return false;
|
|
14303
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, event => {
|
|
14304
|
+
const selection = lexical.$getSelection();
|
|
14305
|
+
if (lexical.$isNodeSelection(selection)) {
|
|
14306
|
+
// If selection is on a node, let's try and move selection
|
|
14307
|
+
// back to being a range selection.
|
|
14308
|
+
const nodes = selection.getNodes();
|
|
14309
|
+
if (nodes.length > 0) {
|
|
14310
|
+
nodes[0].selectNext(0, 0);
|
|
14311
|
+
return true;
|
|
14312
|
+
}
|
|
14313
|
+
} else if (lexical.$isRangeSelection(selection)) {
|
|
14314
|
+
if ($isSelectionAtEndOfRoot(selection)) {
|
|
14315
|
+
event.preventDefault();
|
|
14316
|
+
return true;
|
|
14317
|
+
}
|
|
14318
|
+
const possibleNode = lexical.$getAdjacentNode(selection.focus, false);
|
|
14319
|
+
if (!event.shiftKey && lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() && !possibleNode.isInline()) {
|
|
14320
|
+
possibleNode.selectNext();
|
|
14321
|
+
event.preventDefault();
|
|
14322
|
+
return true;
|
|
14323
|
+
}
|
|
14324
|
+
}
|
|
14325
|
+
return false;
|
|
14326
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_LEFT_COMMAND, event => {
|
|
14327
|
+
const selection$1 = lexical.$getSelection();
|
|
14328
|
+
if (lexical.$isNodeSelection(selection$1)) {
|
|
14329
|
+
// If selection is on a node, let's try and move selection
|
|
14330
|
+
// back to being a range selection.
|
|
14331
|
+
const nodes = selection$1.getNodes();
|
|
14332
|
+
if (nodes.length > 0) {
|
|
14333
|
+
event.preventDefault();
|
|
14334
|
+
nodes[0].selectPrevious();
|
|
14335
|
+
return true;
|
|
14336
|
+
}
|
|
14337
|
+
}
|
|
14338
|
+
if (!lexical.$isRangeSelection(selection$1)) {
|
|
14339
|
+
return false;
|
|
14340
|
+
}
|
|
14341
|
+
if (selection.$shouldOverrideDefaultCharacterSelection(selection$1, true)) {
|
|
14342
|
+
const isHoldingShift = event.shiftKey;
|
|
14343
|
+
event.preventDefault();
|
|
14344
|
+
selection.$moveCharacter(selection$1, isHoldingShift, true);
|
|
14345
|
+
return true;
|
|
14346
|
+
}
|
|
14347
|
+
return false;
|
|
14348
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_RIGHT_COMMAND, event => {
|
|
14349
|
+
const selection$1 = lexical.$getSelection();
|
|
14350
|
+
if (lexical.$isNodeSelection(selection$1) && !$isTargetWithinDecorator(event.target)) {
|
|
14351
|
+
// If selection is on a node, let's try and move selection
|
|
14352
|
+
// back to being a range selection.
|
|
14353
|
+
const nodes = selection$1.getNodes();
|
|
14354
|
+
if (nodes.length > 0) {
|
|
14355
|
+
event.preventDefault();
|
|
14356
|
+
nodes[0].selectNext(0, 0);
|
|
14357
|
+
return true;
|
|
14358
|
+
}
|
|
14359
|
+
}
|
|
14360
|
+
if (!lexical.$isRangeSelection(selection$1)) {
|
|
14361
|
+
return false;
|
|
14362
|
+
}
|
|
14363
|
+
const isHoldingShift = event.shiftKey;
|
|
14364
|
+
if (selection.$shouldOverrideDefaultCharacterSelection(selection$1, false)) {
|
|
14365
|
+
event.preventDefault();
|
|
14366
|
+
selection.$moveCharacter(selection$1, isHoldingShift, false);
|
|
14367
|
+
return true;
|
|
14368
|
+
}
|
|
14369
|
+
return false;
|
|
14370
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_BACKSPACE_COMMAND, event => {
|
|
14371
|
+
if ($isTargetWithinDecorator(event.target)) {
|
|
14372
|
+
return false;
|
|
14373
|
+
}
|
|
14374
|
+
const selection = lexical.$getSelection();
|
|
14375
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14376
|
+
return false;
|
|
14377
|
+
}
|
|
14378
|
+
event.preventDefault();
|
|
14379
|
+
const {
|
|
14380
|
+
anchor
|
|
14381
|
+
} = selection;
|
|
14382
|
+
const anchorNode = anchor.getNode();
|
|
14383
|
+
if (selection.isCollapsed() && anchor.offset === 0 && !lexical.$isRootNode(anchorNode)) {
|
|
14384
|
+
const element = utils.$getNearestBlockElementAncestorOrThrow(anchorNode);
|
|
14385
|
+
if (element.getIndent() > 0) {
|
|
14386
|
+
return editor.dispatchCommand(lexical.OUTDENT_CONTENT_COMMAND, undefined);
|
|
14387
|
+
}
|
|
14388
|
+
}
|
|
14389
|
+
return editor.dispatchCommand(lexical.DELETE_CHARACTER_COMMAND, true);
|
|
14390
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_DELETE_COMMAND, event => {
|
|
14391
|
+
if ($isTargetWithinDecorator(event.target)) {
|
|
14392
|
+
return false;
|
|
14393
|
+
}
|
|
14394
|
+
const selection = lexical.$getSelection();
|
|
14395
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14396
|
+
return false;
|
|
14397
|
+
}
|
|
14398
|
+
event.preventDefault();
|
|
14399
|
+
return editor.dispatchCommand(lexical.DELETE_CHARACTER_COMMAND, false);
|
|
14400
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ENTER_COMMAND, event => {
|
|
14401
|
+
const selection = lexical.$getSelection();
|
|
14402
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14403
|
+
return false;
|
|
14404
|
+
}
|
|
14405
|
+
if (event !== null) {
|
|
14406
|
+
// If we have beforeinput, then we can avoid blocking
|
|
14407
|
+
// the default behavior. This ensures that the iOS can
|
|
14408
|
+
// intercept that we're actually inserting a paragraph,
|
|
14409
|
+
// and autocomplete, autocapitalize etc work as intended.
|
|
14410
|
+
// This can also cause a strange performance issue in
|
|
14411
|
+
// Safari, where there is a noticeable pause due to
|
|
14412
|
+
// preventing the key down of enter.
|
|
14413
|
+
if ((IS_IOS || IS_SAFARI || IS_APPLE_WEBKIT) && CAN_USE_BEFORE_INPUT) {
|
|
14414
|
+
return false;
|
|
14415
|
+
}
|
|
14416
|
+
event.preventDefault();
|
|
14417
|
+
if (event.shiftKey) {
|
|
14418
|
+
return editor.dispatchCommand(lexical.INSERT_LINE_BREAK_COMMAND, false);
|
|
14419
|
+
}
|
|
14420
|
+
}
|
|
14421
|
+
return editor.dispatchCommand(lexical.INSERT_PARAGRAPH_COMMAND, undefined);
|
|
14422
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, () => {
|
|
14423
|
+
const selection = lexical.$getSelection();
|
|
14424
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
14425
|
+
return false;
|
|
14426
|
+
}
|
|
14427
|
+
editor.blur();
|
|
14428
|
+
return true;
|
|
14429
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DROP_COMMAND, event => {
|
|
14430
|
+
const [, files] = eventFiles(event);
|
|
14431
|
+
if (files.length > 0) {
|
|
14432
|
+
const x = event.clientX;
|
|
14433
|
+
const y = event.clientY;
|
|
14434
|
+
const eventRange = caretFromPoint(x, y);
|
|
14435
|
+
if (eventRange !== null) {
|
|
14436
|
+
const {
|
|
14437
|
+
offset: domOffset,
|
|
14438
|
+
node: domNode
|
|
14439
|
+
} = eventRange;
|
|
14440
|
+
const node = lexical.$getNearestNodeFromDOMNode(domNode);
|
|
14441
|
+
if (node !== null) {
|
|
14442
|
+
const selection = lexical.$createRangeSelection();
|
|
14443
|
+
if (lexical.$isTextNode(node)) {
|
|
14444
|
+
selection.anchor.set(node.getKey(), domOffset, 'text');
|
|
14445
|
+
selection.focus.set(node.getKey(), domOffset, 'text');
|
|
14446
|
+
} else {
|
|
14447
|
+
const parentKey = node.getParentOrThrow().getKey();
|
|
14448
|
+
const offset = node.getIndexWithinParent() + 1;
|
|
14449
|
+
selection.anchor.set(parentKey, offset, 'element');
|
|
14450
|
+
selection.focus.set(parentKey, offset, 'element');
|
|
14451
|
+
}
|
|
14452
|
+
const normalizedSelection = lexical.$normalizeSelection__EXPERIMENTAL(selection);
|
|
14453
|
+
lexical.$setSelection(normalizedSelection);
|
|
14454
|
+
}
|
|
14455
|
+
editor.dispatchCommand(DRAG_DROP_PASTE, files);
|
|
14456
|
+
}
|
|
14457
|
+
event.preventDefault();
|
|
14458
|
+
return true;
|
|
14459
|
+
}
|
|
14460
|
+
const selection = lexical.$getSelection();
|
|
14461
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
14462
|
+
return true;
|
|
14463
|
+
}
|
|
14464
|
+
return false;
|
|
14465
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DRAGSTART_COMMAND, event => {
|
|
14466
|
+
const [isFileTransfer] = eventFiles(event);
|
|
14467
|
+
const selection = lexical.$getSelection();
|
|
14468
|
+
if (isFileTransfer && !lexical.$isRangeSelection(selection)) {
|
|
14469
|
+
return false;
|
|
14470
|
+
}
|
|
14471
|
+
return true;
|
|
14472
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DRAGOVER_COMMAND, event => {
|
|
14473
|
+
const [isFileTransfer] = eventFiles(event);
|
|
14474
|
+
const selection = lexical.$getSelection();
|
|
14475
|
+
if (isFileTransfer && !lexical.$isRangeSelection(selection)) {
|
|
14476
|
+
return false;
|
|
14477
|
+
}
|
|
14478
|
+
const x = event.clientX;
|
|
14479
|
+
const y = event.clientY;
|
|
14480
|
+
const eventRange = caretFromPoint(x, y);
|
|
14481
|
+
if (eventRange !== null) {
|
|
14482
|
+
const node = lexical.$getNearestNodeFromDOMNode(eventRange.node);
|
|
14483
|
+
if (lexical.$isDecoratorNode(node)) {
|
|
14484
|
+
// Show browser caret as the user is dragging the media across the screen. Won't work
|
|
14485
|
+
// for DecoratorNode nor it's relevant.
|
|
14486
|
+
event.preventDefault();
|
|
14487
|
+
}
|
|
14488
|
+
}
|
|
14489
|
+
return true;
|
|
14490
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.SELECT_ALL_COMMAND, () => {
|
|
14491
|
+
lexical.$selectAll();
|
|
14492
|
+
return true;
|
|
14493
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.COPY_COMMAND, event => {
|
|
14494
|
+
clipboard.copyToClipboard(editor, utils.objectKlassEquals(event, ClipboardEvent) ? event : null);
|
|
14495
|
+
return true;
|
|
14496
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.CUT_COMMAND, event => {
|
|
14497
|
+
onCutForRichText(event, editor);
|
|
14498
|
+
return true;
|
|
14499
|
+
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.PASTE_COMMAND, event => {
|
|
14500
|
+
const [, files, hasTextContent] = eventFiles(event);
|
|
14501
|
+
if (files.length > 0 && !hasTextContent) {
|
|
14502
|
+
editor.dispatchCommand(DRAG_DROP_PASTE, files);
|
|
14503
|
+
return true;
|
|
14504
|
+
}
|
|
14505
|
+
|
|
14506
|
+
// if inputs then paste within the input ignore creating a new node on paste event
|
|
14507
|
+
if (lexical.isSelectionCapturedInDecoratorInput(event.target)) {
|
|
14508
|
+
return false;
|
|
14509
|
+
}
|
|
14510
|
+
const selection = lexical.$getSelection();
|
|
14511
|
+
if (selection !== null) {
|
|
14512
|
+
onPasteForRichText(event, editor);
|
|
14513
|
+
return true;
|
|
14514
|
+
}
|
|
14515
|
+
return false;
|
|
14516
|
+
}, lexical.COMMAND_PRIORITY_EDITOR));
|
|
14517
|
+
return removeListener;
|
|
14518
|
+
}
|
|
14519
|
+
|
|
14520
|
+
LexicalRichText_dev.$createHeadingNode = $createHeadingNode;
|
|
14521
|
+
LexicalRichText_dev.$createQuoteNode = $createQuoteNode;
|
|
14522
|
+
LexicalRichText_dev.$isHeadingNode = $isHeadingNode;
|
|
14523
|
+
LexicalRichText_dev.$isQuoteNode = $isQuoteNode;
|
|
14524
|
+
LexicalRichText_dev.DRAG_DROP_PASTE = DRAG_DROP_PASTE;
|
|
14525
|
+
LexicalRichText_dev.HeadingNode = HeadingNode;
|
|
14526
|
+
LexicalRichText_dev.QuoteNode = QuoteNode;
|
|
14527
|
+
LexicalRichText_dev.eventFiles = eventFiles;
|
|
14528
|
+
LexicalRichText_dev.registerRichText = registerRichText;
|
|
14529
|
+
return LexicalRichText_dev;
|
|
14530
|
+
}
|
|
14531
|
+
|
|
14532
|
+
var LexicalRichText_prod = {};
|
|
14533
|
+
|
|
14534
|
+
/**
|
|
14535
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14536
|
+
*
|
|
14537
|
+
* This source code is licensed under the MIT license found in the
|
|
14538
|
+
* LICENSE file in the root directory of this source tree.
|
|
14539
|
+
*/
|
|
14540
|
+
|
|
14541
|
+
var hasRequiredLexicalRichText_prod;
|
|
14542
|
+
|
|
14543
|
+
function requireLexicalRichText_prod () {
|
|
14544
|
+
if (hasRequiredLexicalRichText_prod) return LexicalRichText_prod;
|
|
14545
|
+
hasRequiredLexicalRichText_prod = 1;
|
|
14546
|
+
var c=requireLexicalClipboard(),g=requireLexicalSelection(),h=requireLexicalUtils(),k=require$$3;function l(b,a){return "undefined"!==typeof document.caretRangeFromPoint?(b=document.caretRangeFromPoint(b,a),null===b?null:{node:b.startContainer,offset:b.startOffset}):"undefined"!==document.caretPositionFromPoint?(b=document.caretPositionFromPoint(b,a),null===b?null:{node:b.offsetNode,offset:b.offset}):null}
|
|
14547
|
+
let n="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement,p=n&&"documentMode"in document?document.documentMode:null;let q=n&&"InputEvent"in window&&!p?"getTargetRanges"in new window.InputEvent("input"):false,r=n&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent),t=n&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream;
|
|
14548
|
+
let u=n&&/^(?=.*Chrome).*/i.test(navigator.userAgent),v=n&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&!u,w=k.createCommand("DRAG_DROP_PASTE_FILE");
|
|
14549
|
+
class x extends k.ElementNode{static getType(){return "quote"}static clone(b){return new x(b.__key)}constructor(b){super(b);}createDOM(b){let a=document.createElement("blockquote");h.addClassNamesToElement(a,b.theme.quote);return a}updateDOM(){return false}static importDOM(){return {blockquote:()=>({conversion:y,priority:0})}}exportDOM(b){({element:b}=super.exportDOM(b));if(b&&h.isHTMLElement(b)){this.isEmpty()&&b.append(document.createElement("br"));var a=this.getFormatType();b.style.textAlign=a;if(a=this.getDirection())b.dir=
|
|
14550
|
+
a;}return {element:b}}static importJSON(b){let a=z();a.setFormat(b.format);a.setIndent(b.indent);a.setDirection(b.direction);return a}exportJSON(){return {...super.exportJSON(),type:"quote"}}insertNewAfter(b,a){b=k.$createParagraphNode();let d=this.getDirection();b.setDirection(d);this.insertAfter(b,a);return b}collapseAtStart(){let b=k.$createParagraphNode();this.getChildren().forEach(a=>b.append(a));this.replace(b);return true}}function z(){return k.$applyNodeReplacement(new x)}
|
|
14551
|
+
class B extends k.ElementNode{static getType(){return "heading"}static clone(b){return new B(b.__tag,b.__key)}constructor(b,a){super(a);this.__tag=b;}getTag(){return this.__tag}createDOM(b){let a=this.__tag,d=document.createElement(a);b=b.theme.heading;void 0!==b&&h.addClassNamesToElement(d,b[a]);return d}updateDOM(){return false}static importDOM(){return {h1:()=>({conversion:C,priority:0}),h2:()=>({conversion:C,priority:0}),h3:()=>({conversion:C,priority:0}),h4:()=>({conversion:C,priority:0}),h5:()=>({conversion:C,
|
|
14552
|
+
priority:0}),h6:()=>({conversion:C,priority:0}),p:b=>{b=b.firstChild;return null!==b&&D(b)?{conversion:()=>({node:null}),priority:3}:null},span:b=>D(b)?{conversion:()=>({node:E("h1")}),priority:3}:null}}exportDOM(b){({element:b}=super.exportDOM(b));if(b&&h.isHTMLElement(b)){this.isEmpty()&&b.append(document.createElement("br"));var a=this.getFormatType();b.style.textAlign=a;if(a=this.getDirection())b.dir=a;}return {element:b}}static importJSON(b){let a=E(b.tag);a.setFormat(b.format);a.setIndent(b.indent);
|
|
14553
|
+
a.setDirection(b.direction);return a}exportJSON(){return {...super.exportJSON(),tag:this.getTag(),type:"heading",version:1}}insertNewAfter(b,a=true){let d=b?b.anchor.offset:0,e=d!==this.getTextContentSize()&&b?E(this.getTag()):k.$createParagraphNode(),f=this.getDirection();e.setDirection(f);this.insertAfter(e,a);0===d&&!this.isEmpty()&&b&&(b=k.$createParagraphNode(),b.select(),this.replace(b,true));return e}collapseAtStart(){let b=this.isEmpty()?k.$createParagraphNode():E(this.getTag());this.getChildren().forEach(a=>
|
|
14554
|
+
b.append(a));this.replace(b);return true}extractWithChild(){return true}}function D(b){return "span"===b.nodeName.toLowerCase()?"26pt"===b.style.fontSize:false}function C(b){let a=b.nodeName.toLowerCase(),d=null;if("h1"===a||"h2"===a||"h3"===a||"h4"===a||"h5"===a||"h6"===a)d=E(a),null!==b.style&&d.setFormat(b.style.textAlign);return {node:d}}function y(b){let a=z();null!==b.style&&a.setFormat(b.style.textAlign);return {node:a}}function E(b){return k.$applyNodeReplacement(new B(b))}
|
|
14555
|
+
function F(b,a){b.preventDefault();a.update(()=>{let d=k.$getSelection(),e=b instanceof InputEvent||b instanceof KeyboardEvent?null:b.clipboardData;null!=e&&null!==d&&c.$insertDataTransferForRichText(e,d,a);},{tag:"paste"});}async function G(b,a){await c.copyToClipboard(a,h.objectKlassEquals(b,ClipboardEvent)?b:null);a.update(()=>{let d=k.$getSelection();k.$isRangeSelection(d)?d.removeText():k.$isNodeSelection(d)&&d.getNodes().forEach(e=>e.remove());});}
|
|
14556
|
+
function H(b){let a=null;b instanceof DragEvent?a=b.dataTransfer:b instanceof ClipboardEvent&&(a=b.clipboardData);if(null===a)return [false,[],false];var d=a.types;b=d.includes("Files");d=d.includes("text/html")||d.includes("text/plain");return [b,Array.from(a.files),d]}
|
|
14557
|
+
function I(b){var a=k.$getSelection();if(!k.$isRangeSelection(a))return false;let d=new Set;a=a.getNodes();for(let m=0;m<a.length;m++){var e=a[m],f=e.getKey();d.has(f)||(e=h.$getNearestBlockElementAncestorOrThrow(e),f=e.getKey(),e.canIndent()&&!d.has(f)&&(d.add(f),b(e)));}return 0<d.size}function J(b){b=k.$getNearestNodeFromDOMNode(b);return k.$isDecoratorNode(b)}LexicalRichText_prod.$createHeadingNode=E;LexicalRichText_prod.$createQuoteNode=z;LexicalRichText_prod.$isHeadingNode=function(b){return b instanceof B};
|
|
14558
|
+
LexicalRichText_prod.$isQuoteNode=function(b){return b instanceof x};LexicalRichText_prod.DRAG_DROP_PASTE=w;LexicalRichText_prod.HeadingNode=B;LexicalRichText_prod.QuoteNode=x;LexicalRichText_prod.eventFiles=H;
|
|
14559
|
+
LexicalRichText_prod.registerRichText=function(b){return h.mergeRegister(b.registerCommand(k.CLICK_COMMAND,()=>{const a=k.$getSelection();return k.$isNodeSelection(a)?(a.clear(),true):false},0),b.registerCommand(k.DELETE_CHARACTER_COMMAND,a=>{const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;d.deleteCharacter(a);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.DELETE_WORD_COMMAND,a=>{const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;d.deleteWord(a);return true},k.COMMAND_PRIORITY_EDITOR),
|
|
14560
|
+
b.registerCommand(k.DELETE_LINE_COMMAND,a=>{const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;d.deleteLine(a);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.CONTROLLED_TEXT_INSERTION_COMMAND,a=>{const d=k.$getSelection();if("string"===typeof a)null!==d&&d.insertText(a);else {if(null===d)return false;const e=a.dataTransfer;null!=e?c.$insertDataTransferForRichText(e,d,b):k.$isRangeSelection(d)&&(a=a.data)&&d.insertText(a);}return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.REMOVE_TEXT_COMMAND,
|
|
14561
|
+
()=>{const a=k.$getSelection();if(!k.$isRangeSelection(a))return false;a.removeText();return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.FORMAT_TEXT_COMMAND,a=>{const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;d.formatText(a);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.FORMAT_ELEMENT_COMMAND,a=>{var d=k.$getSelection();if(!k.$isRangeSelection(d)&&!k.$isNodeSelection(d))return false;d=d.getNodes();for(const e of d)d=h.$findMatchingParent(e,f=>k.$isElementNode(f)&&!f.isInline()),
|
|
14562
|
+
null!==d&&d.setFormat(a);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.INSERT_LINE_BREAK_COMMAND,a=>{const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;d.insertLineBreak(a);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.INSERT_PARAGRAPH_COMMAND,()=>{const a=k.$getSelection();if(!k.$isRangeSelection(a))return false;a.insertParagraph();return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.INSERT_TAB_COMMAND,()=>{k.$insertNodes([k.$createTabNode()]);return true},k.COMMAND_PRIORITY_EDITOR),
|
|
14563
|
+
b.registerCommand(k.INDENT_CONTENT_COMMAND,()=>I(a=>{const d=a.getIndent();a.setIndent(d+1);}),k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.OUTDENT_CONTENT_COMMAND,()=>I(a=>{const d=a.getIndent();0<d&&a.setIndent(d-1);}),k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ARROW_UP_COMMAND,a=>{var d=k.$getSelection();if(k.$isNodeSelection(d)&&!J(a.target)){if(a=d.getNodes(),0<a.length)return a[0].selectPrevious(),true}else if(k.$isRangeSelection(d)&&(d=k.$getAdjacentNode(d.focus,true),!a.shiftKey&&k.$isDecoratorNode(d)&&
|
|
14564
|
+
!d.isIsolated()&&!d.isInline()))return d.selectPrevious(),a.preventDefault(),true;return false},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ARROW_DOWN_COMMAND,a=>{var d=k.$getSelection();if(k.$isNodeSelection(d)){if(a=d.getNodes(),0<a.length)return a[0].selectNext(0,0),true}else if(k.$isRangeSelection(d)){let e=d.focus;if("root"===e.key&&e.offset===k.$getRoot().getChildrenSize())return a.preventDefault(),true;d=k.$getAdjacentNode(d.focus,false);if(!a.shiftKey&&k.$isDecoratorNode(d)&&!d.isIsolated()&&!d.isInline())return d.selectNext(),
|
|
14565
|
+
a.preventDefault(),true}return false},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ARROW_LEFT_COMMAND,a=>{const d=k.$getSelection();if(k.$isNodeSelection(d)){var e=d.getNodes();if(0<e.length)return a.preventDefault(),e[0].selectPrevious(),true}return k.$isRangeSelection(d)?g.$shouldOverrideDefaultCharacterSelection(d,true)?(e=a.shiftKey,a.preventDefault(),g.$moveCharacter(d,e,true),true):false:false},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ARROW_RIGHT_COMMAND,a=>{const d=k.$getSelection();if(k.$isNodeSelection(d)&&
|
|
14566
|
+
!J(a.target)){var e=d.getNodes();if(0<e.length)return a.preventDefault(),e[0].selectNext(0,0),true}if(!k.$isRangeSelection(d))return false;e=a.shiftKey;return g.$shouldOverrideDefaultCharacterSelection(d,false)?(a.preventDefault(),g.$moveCharacter(d,e,false),true):false},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_BACKSPACE_COMMAND,a=>{if(J(a.target))return false;const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;a.preventDefault();({anchor:a}=d);const e=a.getNode();return d.isCollapsed()&&0===a.offset&&
|
|
14567
|
+
!k.$isRootNode(e)&&0<h.$getNearestBlockElementAncestorOrThrow(e).getIndent()?b.dispatchCommand(k.OUTDENT_CONTENT_COMMAND,void 0):b.dispatchCommand(k.DELETE_CHARACTER_COMMAND,true)},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_DELETE_COMMAND,a=>{if(J(a.target))return false;const d=k.$getSelection();if(!k.$isRangeSelection(d))return false;a.preventDefault();return b.dispatchCommand(k.DELETE_CHARACTER_COMMAND,false)},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ENTER_COMMAND,a=>{const d=k.$getSelection();
|
|
14568
|
+
if(!k.$isRangeSelection(d))return false;if(null!==a){if((t||r||v)&&q)return false;a.preventDefault();if(a.shiftKey)return b.dispatchCommand(k.INSERT_LINE_BREAK_COMMAND,false)}return b.dispatchCommand(k.INSERT_PARAGRAPH_COMMAND,void 0)},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.KEY_ESCAPE_COMMAND,()=>{const a=k.$getSelection();if(!k.$isRangeSelection(a))return false;b.blur();return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.DROP_COMMAND,a=>{const [,d]=H(a);if(0<d.length){var e=l(a.clientX,a.clientY);
|
|
14569
|
+
if(null!==e){const {offset:m,node:K}=e;var f=k.$getNearestNodeFromDOMNode(K);if(null!==f){e=k.$createRangeSelection();if(k.$isTextNode(f))e.anchor.set(f.getKey(),m,"text"),e.focus.set(f.getKey(),m,"text");else {const A=f.getParentOrThrow().getKey();f=f.getIndexWithinParent()+1;e.anchor.set(A,f,"element");e.focus.set(A,f,"element");}e=k.$normalizeSelection__EXPERIMENTAL(e);k.$setSelection(e);}b.dispatchCommand(w,d);}a.preventDefault();return true}a=k.$getSelection();return k.$isRangeSelection(a)?true:false},k.COMMAND_PRIORITY_EDITOR),
|
|
14570
|
+
b.registerCommand(k.DRAGSTART_COMMAND,a=>{[a]=H(a);const d=k.$getSelection();return a&&!k.$isRangeSelection(d)?false:true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.DRAGOVER_COMMAND,a=>{var [d]=H(a);const e=k.$getSelection();if(d&&!k.$isRangeSelection(e))return false;d=l(a.clientX,a.clientY);null!==d&&(d=k.$getNearestNodeFromDOMNode(d.node),k.$isDecoratorNode(d)&&a.preventDefault());return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.SELECT_ALL_COMMAND,()=>{k.$selectAll();return true},k.COMMAND_PRIORITY_EDITOR),
|
|
14571
|
+
b.registerCommand(k.COPY_COMMAND,a=>{c.copyToClipboard(b,h.objectKlassEquals(a,ClipboardEvent)?a:null);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.CUT_COMMAND,a=>{G(a,b);return true},k.COMMAND_PRIORITY_EDITOR),b.registerCommand(k.PASTE_COMMAND,a=>{const [,d,e]=H(a);return 0<d.length&&!e?(b.dispatchCommand(w,d),true):k.isSelectionCapturedInDecoratorInput(a.target)?false:null!==k.$getSelection()?(F(a,b),true):false},k.COMMAND_PRIORITY_EDITOR))};
|
|
14572
|
+
return LexicalRichText_prod;
|
|
14573
|
+
}
|
|
14574
|
+
|
|
14575
|
+
/**
|
|
14576
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14577
|
+
*
|
|
14578
|
+
* This source code is licensed under the MIT license found in the
|
|
14579
|
+
* LICENSE file in the root directory of this source tree.
|
|
14580
|
+
*/
|
|
14581
|
+
|
|
14582
|
+
var LexicalRichText_1;
|
|
14583
|
+
var hasRequiredLexicalRichText;
|
|
14584
|
+
|
|
14585
|
+
function requireLexicalRichText () {
|
|
14586
|
+
if (hasRequiredLexicalRichText) return LexicalRichText_1;
|
|
14587
|
+
hasRequiredLexicalRichText = 1;
|
|
14588
|
+
const LexicalRichText = process.env.NODE_ENV === 'development' ? requireLexicalRichText_dev() : requireLexicalRichText_prod();
|
|
14589
|
+
LexicalRichText_1 = LexicalRichText;
|
|
14590
|
+
return LexicalRichText_1;
|
|
14591
|
+
}
|
|
14592
|
+
|
|
14593
|
+
var LexicalRichTextExports = requireLexicalRichText();
|
|
14594
|
+
|
|
14595
|
+
const useEditorStyles = makeStyles()((theme, { hasFocus, hasContent, readOnly, hasCustomToolbar }) => ({
|
|
14596
|
+
root: {
|
|
14597
|
+
position: 'relative',
|
|
14598
|
+
display: 'inline-flex',
|
|
14599
|
+
flexDirection: hasCustomToolbar ? 'column-reverse' : 'column',
|
|
14600
|
+
minWidth: '100%', // TODO
|
|
14601
|
+
},
|
|
14602
|
+
legend: {
|
|
14603
|
+
position: 'absolute',
|
|
14604
|
+
top: -5,
|
|
14605
|
+
left: 0,
|
|
14606
|
+
right: 0,
|
|
14607
|
+
bottom: 0,
|
|
14608
|
+
lineHeight: '11px',
|
|
14609
|
+
zIndex: hasFocus ? 0 : 1,
|
|
14610
|
+
paddingLeft: 10,
|
|
14611
|
+
borderStyle: 'solid',
|
|
14612
|
+
borderRadius: theme.shape.borderRadius,
|
|
14613
|
+
borderWidth: hasFocus ? 2 : 1,
|
|
14614
|
+
borderColor: hasFocus
|
|
14615
|
+
? theme.palette.primary.main
|
|
14616
|
+
: hex2rgba('#000', 0.23),
|
|
14617
|
+
'&:hover': {
|
|
14618
|
+
borderColor: hasFocus
|
|
14619
|
+
? theme.palette.primary.main
|
|
14620
|
+
: theme.palette.text.primary,
|
|
14621
|
+
},
|
|
14622
|
+
transition: theme.transitions.create(['border-color'], {
|
|
14623
|
+
duration: theme.transitions.duration.shorter,
|
|
14624
|
+
easing: theme.transitions.easing.easeOut,
|
|
14625
|
+
}),
|
|
14626
|
+
},
|
|
14627
|
+
editor: {
|
|
14628
|
+
padding: '.8rem 1rem',
|
|
14629
|
+
position: 'relative',
|
|
14630
|
+
zIndex: hasFocus || readOnly ? 1 : 0,
|
|
14631
|
+
'& .unstyled': {
|
|
14632
|
+
margin: '.5rem 0',
|
|
14633
|
+
},
|
|
14634
|
+
},
|
|
14635
|
+
label: {
|
|
14636
|
+
position: 'absolute',
|
|
14637
|
+
top: 0,
|
|
14638
|
+
left: 0,
|
|
14639
|
+
zIndex: 1,
|
|
14640
|
+
transform: hasFocus || hasContent
|
|
14641
|
+
? 'translate(6px, -14px) scale(0.75)'
|
|
14642
|
+
: 'translate(6px, 12px) scale(1)',
|
|
14643
|
+
transformOrigin: 'top left',
|
|
14644
|
+
transition: theme.transitions.create(['color', 'transform'], {
|
|
14645
|
+
duration: theme.transitions.duration.shorter,
|
|
14646
|
+
easing: theme.transitions.easing.easeOut,
|
|
14647
|
+
}),
|
|
14648
|
+
color: hasFocus
|
|
14649
|
+
? theme.palette.primary[theme.palette.mode === 'light' ? 'dark' : 'light']
|
|
14650
|
+
: theme.palette.text.secondary,
|
|
14651
|
+
fontSize: '1.1428571428571428rem',
|
|
14652
|
+
// hack @todo when time
|
|
14653
|
+
backgroundColor: 'white',
|
|
14654
|
+
padding: '2px 10px',
|
|
14655
|
+
},
|
|
14656
|
+
helpertext: {
|
|
14657
|
+
margin: 0,
|
|
14658
|
+
opacity: hasFocus ? 1 : 0,
|
|
14659
|
+
transition: theme.transitions.create(['opacity'], {
|
|
14660
|
+
duration: theme.transitions.duration.shorter,
|
|
14661
|
+
easing: theme.transitions.easing.easeOut,
|
|
14662
|
+
}),
|
|
14663
|
+
fontSize: 'small',
|
|
14664
|
+
// hack @todo when time
|
|
14665
|
+
backgroundColor: 'white',
|
|
14666
|
+
padding: '2px 10px',
|
|
14667
|
+
},
|
|
14668
|
+
charcount: {
|
|
14669
|
+
margin: 0,
|
|
14670
|
+
transition: theme.transitions.create(['opacity'], {
|
|
14671
|
+
duration: theme.transitions.duration.shorter,
|
|
14672
|
+
easing: theme.transitions.easing.easeOut,
|
|
14673
|
+
}),
|
|
14674
|
+
fontSize: 'small',
|
|
14675
|
+
// hack @todo when time
|
|
14676
|
+
backgroundColor: 'white',
|
|
14677
|
+
padding: '2px 10px',
|
|
14678
|
+
},
|
|
14679
|
+
}));
|
|
14680
|
+
|
|
14681
|
+
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
14682
|
+
|
|
14683
|
+
var LexicalUtilsExports = requireLexicalUtils();
|
|
14684
|
+
|
|
14685
|
+
function StyleWrapperPlugin({ showCharcount, helperText, readOnly, classes, label, children, autoFocus, toolbarAnchor, hasCustomToolbar, }) {
|
|
14686
|
+
const [editor] = useLexicalComposerContext();
|
|
14687
|
+
const [hasFocus, setFocused] = useState(() => {
|
|
14688
|
+
return editor.getRootElement() === document.activeElement;
|
|
14689
|
+
});
|
|
14690
|
+
const [charCount, setCharCount] = useState(0);
|
|
14691
|
+
useEffect(() => {
|
|
14692
|
+
return LexicalUtilsExports.mergeRegister(editor.registerCommand(BLUR_COMMAND, () => {
|
|
14693
|
+
setFocused(editor.getRootElement() === document.activeElement);
|
|
14694
|
+
return false;
|
|
14695
|
+
}, COMMAND_PRIORITY_EDITOR), editor.registerCommand(FOCUS_COMMAND, () => {
|
|
14696
|
+
setFocused(editor.getRootElement() === document.activeElement);
|
|
14697
|
+
return false;
|
|
14698
|
+
}, COMMAND_PRIORITY_EDITOR));
|
|
14699
|
+
}, []);
|
|
14700
|
+
const { classes: styles } = useEditorStyles({
|
|
14701
|
+
hasFocus,
|
|
14702
|
+
hasContent: charCount > 0,
|
|
14703
|
+
readOnly,
|
|
14704
|
+
hasCustomToolbar: hasCustomToolbar,
|
|
14705
|
+
});
|
|
14706
|
+
// Autofocus, makes sure the editor is focused as soon as it it rendered.
|
|
14707
|
+
useEffect(() => {
|
|
14708
|
+
autoFocus &&
|
|
14709
|
+
editor.focus(() => {
|
|
14710
|
+
const activeElement = document.activeElement;
|
|
14711
|
+
const rootElement = editor.getRootElement();
|
|
14712
|
+
if (rootElement !== null &&
|
|
14713
|
+
(activeElement === null || !rootElement.contains(activeElement))) {
|
|
14714
|
+
// Note: preventScroll won't work in Webkit.
|
|
14715
|
+
rootElement.focus({ preventScroll: true });
|
|
14716
|
+
}
|
|
14717
|
+
});
|
|
14718
|
+
}, [autoFocus]);
|
|
14719
|
+
useEffect(() => {
|
|
14720
|
+
editor.registerTextContentListener((content) => {
|
|
14721
|
+
// For some reason a newline "Enter" inserts two \n characters.
|
|
14722
|
+
const newCount = content.replaceAll('\n\n', '\n').length;
|
|
14723
|
+
setCharCount((prevCount) => {
|
|
14724
|
+
return prevCount !== newCount ? newCount : prevCount;
|
|
11374
14725
|
});
|
|
11375
14726
|
});
|
|
11376
14727
|
}, []);
|
|
@@ -11420,7 +14771,7 @@ const htmlExportMap = new Map([
|
|
|
11420
14771
|
},
|
|
11421
14772
|
],
|
|
11422
14773
|
[
|
|
11423
|
-
|
|
14774
|
+
LexicalRichTextExports.HeadingNode,
|
|
11424
14775
|
(editor, node) => {
|
|
11425
14776
|
const headingNode = node;
|
|
11426
14777
|
const element = headingNode.createDOM(editor._config);
|
|
@@ -11484,7 +14835,7 @@ function ModifyPastePlugin({ blockPasting, stripPastedStyles, }) {
|
|
|
11484
14835
|
function PreventNewlinesPlugin({ disableNewlines, }) {
|
|
11485
14836
|
const [editor] = useLexicalComposerContext();
|
|
11486
14837
|
if (disableNewlines) {
|
|
11487
|
-
|
|
14838
|
+
LexicalUtilsExports.mergeRegister(editor.registerNodeTransform(RootNode, (rootNode) => {
|
|
11488
14839
|
if (rootNode.getChildrenSize() <= 1)
|
|
11489
14840
|
return;
|
|
11490
14841
|
rootNode.getLastChild()?.remove();
|
|
@@ -11578,6 +14929,8 @@ function getDOMRangeRect(nativeSelection, rootElement) {
|
|
|
11578
14929
|
return rect;
|
|
11579
14930
|
}
|
|
11580
14931
|
|
|
14932
|
+
var LexicalSelectionExports = requireLexicalSelection();
|
|
14933
|
+
|
|
11581
14934
|
/**
|
|
11582
14935
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11583
14936
|
*
|
|
@@ -11595,10 +14948,10 @@ function getSelectedNode(selection) {
|
|
|
11595
14948
|
}
|
|
11596
14949
|
const isBackward = selection.isBackward();
|
|
11597
14950
|
if (isBackward) {
|
|
11598
|
-
return
|
|
14951
|
+
return LexicalSelectionExports.$isAtNodeEnd(focus) ? anchorNode : focusNode;
|
|
11599
14952
|
}
|
|
11600
14953
|
else {
|
|
11601
|
-
return
|
|
14954
|
+
return LexicalSelectionExports.$isAtNodeEnd(anchor) ? anchorNode : focusNode;
|
|
11602
14955
|
}
|
|
11603
14956
|
}
|
|
11604
14957
|
|
|
@@ -11683,7 +15036,7 @@ function TextFormatFloatingToolbar({ editor, anchorElem, isBold, isItalic, butto
|
|
|
11683
15036
|
editor.getEditorState().read(() => {
|
|
11684
15037
|
updateTextFormatFloatingToolbar();
|
|
11685
15038
|
});
|
|
11686
|
-
return
|
|
15039
|
+
return LexicalUtilsExports.mergeRegister(editor.registerUpdateListener(({ editorState }) => {
|
|
11687
15040
|
editorState.read(() => {
|
|
11688
15041
|
updateTextFormatFloatingToolbar();
|
|
11689
15042
|
});
|
|
@@ -11749,7 +15102,7 @@ function useFloatingTextFormatToolbar(editor, anchorElem, buttons, CustomToolbar
|
|
|
11749
15102
|
};
|
|
11750
15103
|
}, [updatePopup]);
|
|
11751
15104
|
useEffect(() => {
|
|
11752
|
-
return
|
|
15105
|
+
return LexicalUtilsExports.mergeRegister(editor.registerUpdateListener(() => {
|
|
11753
15106
|
updatePopup();
|
|
11754
15107
|
}), editor.registerRootListener(() => {
|
|
11755
15108
|
if (editor.getRootElement() === null) {
|
|
@@ -11776,6 +15129,8 @@ function FloatingTextFormatToolbarPlugin({ anchorElem, buttons, CustomToolbar, }
|
|
|
11776
15129
|
return useFloatingTextFormatToolbar(editor, anchorElem, buttons, CustomToolbar);
|
|
11777
15130
|
}
|
|
11778
15131
|
|
|
15132
|
+
var LexicalHtmlExports = requireLexicalHtml();
|
|
15133
|
+
|
|
11779
15134
|
function InsertDataPlugin({ html }) {
|
|
11780
15135
|
const [editor] = useLexicalComposerContext();
|
|
11781
15136
|
const parser = new DOMParser();
|
|
@@ -11786,7 +15141,7 @@ function InsertDataPlugin({ html }) {
|
|
|
11786
15141
|
}
|
|
11787
15142
|
const dom = parser.parseFromString(html, 'text/html');
|
|
11788
15143
|
editor.update(() => {
|
|
11789
|
-
const nodes =
|
|
15144
|
+
const nodes = LexicalHtmlExports.$generateNodesFromDOM(editor, dom);
|
|
11790
15145
|
$insertNodes(nodes);
|
|
11791
15146
|
});
|
|
11792
15147
|
}, []);
|
|
@@ -11809,12 +15164,12 @@ function HeadingPlugin({ html }) {
|
|
|
11809
15164
|
// Only replace if tag is heading.
|
|
11810
15165
|
if (tag) {
|
|
11811
15166
|
editor.registerNodeTransform(ParagraphNode, (node) => {
|
|
11812
|
-
node.replace(
|
|
15167
|
+
node.replace(LexicalRichTextExports.$createHeadingNode(`${tag}`));
|
|
11813
15168
|
});
|
|
11814
15169
|
}
|
|
11815
15170
|
else {
|
|
11816
15171
|
// Replace a heading with paragraph
|
|
11817
|
-
editor.registerNodeTransform(
|
|
15172
|
+
editor.registerNodeTransform(LexicalRichTextExports.HeadingNode, (node) => {
|
|
11818
15173
|
node.replace($createParagraphNode(), true);
|
|
11819
15174
|
});
|
|
11820
15175
|
}
|
|
@@ -11965,7 +15320,7 @@ function Editor({ html, label, classes, autoFocus, helperText, showCharCount, al
|
|
|
11965
15320
|
theme,
|
|
11966
15321
|
editable: !readOnly,
|
|
11967
15322
|
onError,
|
|
11968
|
-
nodes: [
|
|
15323
|
+
nodes: [LexicalRichTextExports.HeadingNode],
|
|
11969
15324
|
html: {
|
|
11970
15325
|
export: htmlExportMap,
|
|
11971
15326
|
},
|
|
@@ -11976,7 +15331,7 @@ function Editor({ html, label, classes, autoFocus, helperText, showCharCount, al
|
|
|
11976
15331
|
setFloatingAnchorElem(_floatingAnchorElem);
|
|
11977
15332
|
}
|
|
11978
15333
|
};
|
|
11979
|
-
if (
|
|
15334
|
+
if (editorRef === undefined) {
|
|
11980
15335
|
editorRef = useRef(null);
|
|
11981
15336
|
}
|
|
11982
15337
|
const canStyle = allowedStyles === undefined || allowedStyles.length > 0;
|
|
@@ -12003,13 +15358,8 @@ const GrepEditor = ({ ...props }) => {
|
|
|
12003
15358
|
};
|
|
12004
15359
|
|
|
12005
15360
|
const dimensions = {
|
|
12006
|
-
breadcrumbsFontSize: 16,
|
|
12007
|
-
contentWidth: 1028,
|
|
12008
|
-
footerHeight: 50,
|
|
12009
|
-
inputBoxHeight: 61,
|
|
12010
15361
|
toolbarHeight: 80,
|
|
12011
15362
|
toolbarHeightMobile: 40,
|
|
12012
|
-
toolbarWidth: 1260,
|
|
12013
15363
|
toolbarMenuWidth: 1028,
|
|
12014
15364
|
toolbarMenuHeight: 50,
|
|
12015
15365
|
};
|
|
@@ -12387,7 +15737,7 @@ const ConfirmationDialog = ({ open, title, description, warning, onSubmit, onCan
|
|
|
12387
15737
|
React__default.createElement(DialogContent$1, null,
|
|
12388
15738
|
React__default.createElement(DialogContentText$1, null, description)),
|
|
12389
15739
|
React__default.createElement(DialogActions$1, null,
|
|
12390
|
-
React__default.createElement(Button, { color: "
|
|
15740
|
+
React__default.createElement(Button, { color: "inherit", onClick: onCancel }, cancelText),
|
|
12391
15741
|
React__default.createElement(Button, { className: warning ? classes.discard : '', onClick: onSubmit }, confirmText))));
|
|
12392
15742
|
};
|
|
12393
15743
|
|
|
@@ -12395,7 +15745,7 @@ const ConfirmationServiceContext = React__default.createContext(Promise.reject);
|
|
|
12395
15745
|
const ConfirmationServiceProvider = ({ children, }) => {
|
|
12396
15746
|
const [confirmationState, setConfirmationState] = React__default.useState(null);
|
|
12397
15747
|
const [dialogOpen, setDialogOpen] = React__default.useState(false);
|
|
12398
|
-
const awaitingPromiseRef = React__default.useRef(
|
|
15748
|
+
const awaitingPromiseRef = React__default.useRef();
|
|
12399
15749
|
const openDialog = (options) => {
|
|
12400
15750
|
setConfirmationState(options);
|
|
12401
15751
|
setDialogOpen(true);
|