mirror of
https://github.com/facebook/lexical.git
synced 2025-05-17 23:26:16 +08:00
Use window of current default view (#2918)
* Use window of current default view * Use window of current default view * Fix codes
This commit is contained in:
@ -24,7 +24,12 @@ import {
|
||||
triggerListeners,
|
||||
updateEditor,
|
||||
} from './LexicalUpdates';
|
||||
import {createUID, dispatchCommand, markAllNodesAsDirty} from './LexicalUtils';
|
||||
import {
|
||||
createUID,
|
||||
dispatchCommand,
|
||||
getDefaultView,
|
||||
markAllNodesAsDirty,
|
||||
} from './LexicalUtils';
|
||||
import {DecoratorNode} from './nodes/LexicalDecoratorNode';
|
||||
import {LineBreakNode} from './nodes/LexicalLineBreakNode';
|
||||
import {ParagraphNode} from './nodes/LexicalParagraphNode';
|
||||
@ -450,6 +455,7 @@ export class LexicalEditor {
|
||||
_onError: ErrorHandler;
|
||||
_htmlConversions: DOMConversionCache;
|
||||
_readOnly: boolean;
|
||||
_window: null | Window;
|
||||
|
||||
constructor(
|
||||
editorState: EditorState,
|
||||
@ -508,6 +514,7 @@ export class LexicalEditor {
|
||||
this._htmlConversions = htmlConversions;
|
||||
this._readOnly = false;
|
||||
this._headless = false;
|
||||
this._window = null;
|
||||
}
|
||||
|
||||
isComposing(): boolean {
|
||||
@ -695,11 +702,13 @@ export class LexicalEditor {
|
||||
}
|
||||
|
||||
if (nextRootElement !== null) {
|
||||
const windowObj = getDefaultView(nextRootElement);
|
||||
const style = nextRootElement.style;
|
||||
style.userSelect = 'text';
|
||||
style.whiteSpace = 'pre-wrap';
|
||||
style.wordBreak = 'break-word';
|
||||
nextRootElement.setAttribute('data-lexical-editor', 'true');
|
||||
this._window = windowObj;
|
||||
this._dirtyType = FULL_RECONCILE;
|
||||
initMutationObserver(this);
|
||||
|
||||
@ -711,6 +720,8 @@ export class LexicalEditor {
|
||||
if (!this._config.disableEvents) {
|
||||
addRootElementEvents(nextRootElement, this);
|
||||
}
|
||||
} else {
|
||||
this._window = null;
|
||||
}
|
||||
|
||||
triggerListeners('root', this, false, nextRootElement, prevRootElement);
|
||||
|
@ -86,6 +86,7 @@ import {
|
||||
getDOMTextNode,
|
||||
getEditorsToPropagate,
|
||||
getNearestEditorFromDOMNode,
|
||||
getWindow,
|
||||
isBackspace,
|
||||
isBold,
|
||||
isCopy,
|
||||
@ -237,7 +238,7 @@ function onSelectionChange(
|
||||
// If we have marked a collapsed selection format, and we're
|
||||
// within the given time range – then attempt to use that format
|
||||
// instead of getting the format from the anchor node.
|
||||
const windowEvent = window.event;
|
||||
const windowEvent = getWindow(editor).event;
|
||||
const currentTimeStamp = windowEvent
|
||||
? windowEvent.timeStamp
|
||||
: performance.now();
|
||||
@ -372,7 +373,7 @@ function onBeforeInput(event: InputEvent, editor: LexicalEditor): void {
|
||||
// user has dom.event.clipboardevents.enabled disabled in
|
||||
// about:config. In that case, we need to process the
|
||||
// pasted content in the DOM mutation phase.
|
||||
(IS_FIREFOX && isFirefoxClipboardEvents())
|
||||
(IS_FIREFOX && isFirefoxClipboardEvents(editor))
|
||||
) {
|
||||
return;
|
||||
} else if (inputType === 'insertCompositionText') {
|
||||
|
@ -31,6 +31,7 @@ import {
|
||||
$getNearestNodeFromDOMNode,
|
||||
$updateTextNodeFromDOMContent,
|
||||
getNodeFromDOMNode,
|
||||
getWindow,
|
||||
internalGetRoot,
|
||||
isFirefoxClipboardEvents,
|
||||
} from './LexicalUtils';
|
||||
@ -48,9 +49,9 @@ function updateTimeStamp(event: Event) {
|
||||
lastTextEntryTimeStamp = event.timeStamp;
|
||||
}
|
||||
|
||||
function initTextEntryListener(): void {
|
||||
function initTextEntryListener(editor: LexicalEditor): void {
|
||||
if (lastTextEntryTimeStamp === 0) {
|
||||
window.addEventListener('textInput', updateTimeStamp, true);
|
||||
getWindow(editor).addEventListener('textInput', updateTimeStamp, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +293,7 @@ export function $flushMutations(
|
||||
$setSelection(selection);
|
||||
}
|
||||
|
||||
if (IS_FIREFOX && isFirefoxClipboardEvents()) {
|
||||
if (IS_FIREFOX && isFirefoxClipboardEvents(editor)) {
|
||||
selection.insertRawText(possibleTextForFirefoxPaste);
|
||||
}
|
||||
}
|
||||
@ -312,7 +313,7 @@ export function flushRootMutations(editor: LexicalEditor): void {
|
||||
}
|
||||
|
||||
export function initMutationObserver(editor: LexicalEditor): void {
|
||||
initTextEntryListener();
|
||||
initTextEntryListener(editor);
|
||||
editor._observer = new MutationObserver(
|
||||
(mutations: Array<MutationRecord>, observer: MutationObserver) => {
|
||||
$flushMutations(editor, mutations, observer);
|
||||
|
@ -2281,6 +2281,10 @@ export function internalCreateRangeSelection(
|
||||
domSelection: Selection | null,
|
||||
editor: LexicalEditor,
|
||||
): null | RangeSelection {
|
||||
const windowObj = editor._window;
|
||||
if (windowObj === null) {
|
||||
return null;
|
||||
}
|
||||
// When we create a selection, we try to use the previous
|
||||
// selection where possible, unless an actual user selection
|
||||
// change has occurred. When we do need to create a new selection
|
||||
@ -2295,7 +2299,7 @@ export function internalCreateRangeSelection(
|
||||
// reconciliation unless there are dirty nodes that need
|
||||
// reconciling.
|
||||
|
||||
const windowEvent = window.event;
|
||||
const windowEvent = windowObj.event;
|
||||
const eventType = windowEvent ? windowEvent.type : undefined;
|
||||
const isSelectionChange = eventType === 'selectionchange';
|
||||
const useDOMSelection =
|
||||
|
@ -1091,8 +1091,8 @@ export function $getDecoratorNode(
|
||||
return null;
|
||||
}
|
||||
|
||||
export function isFirefoxClipboardEvents(): boolean {
|
||||
const event = window.event;
|
||||
export function isFirefoxClipboardEvents(editor: LexicalEditor): boolean {
|
||||
const event = getWindow(editor).event;
|
||||
const inputType = event && (event as InputEvent).inputType;
|
||||
return (
|
||||
inputType === 'insertFromPaste' ||
|
||||
@ -1148,7 +1148,7 @@ export function scrollIntoViewIfNeeded(
|
||||
if (element !== null) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
if (rect.bottom > window.innerHeight) {
|
||||
if (rect.bottom > getWindow(editor).innerHeight) {
|
||||
element.scrollIntoView(false);
|
||||
} else if (rect.top < 0) {
|
||||
element.scrollIntoView();
|
||||
@ -1212,3 +1212,16 @@ function $hasAncestor(child: LexicalNode, targetNode: LexicalNode): boolean {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getDefaultView(domElem: HTMLElement): Window | null {
|
||||
const ownerDoc = domElem.ownerDocument;
|
||||
return (ownerDoc && ownerDoc.defaultView) || null;
|
||||
}
|
||||
|
||||
export function getWindow(editor: LexicalEditor): Window {
|
||||
const windowObj = editor._window;
|
||||
if (windowObj === null) {
|
||||
invariant(false, 'window object not found');
|
||||
}
|
||||
return windowObj;
|
||||
}
|
||||
|
@ -76,5 +76,7 @@
|
||||
"74": "Create node: Type %s in node %s does not match registered node %s with the same type",
|
||||
"75": "Reconciliation: could not find DOM element for node key %s",
|
||||
"76": "append: attempting to append self",
|
||||
"77": "LexicalAutoLinkPlugin: AutoLinkNode not registered on editor"
|
||||
"77": "LexicalAutoLinkPlugin: AutoLinkNode not registered on editor",
|
||||
"78": "window object not found",
|
||||
"79": "MarkdownShortcuts: missing dependency for transformer. Ensure node dependency is included in editor initial config."
|
||||
}
|
||||
|
Reference in New Issue
Block a user