lexical 0.32.2-nightly.20250627.0 → 0.32.2-nightly.20250701.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/Lexical.dev.js CHANGED
@@ -8402,14 +8402,16 @@ function triggerMutationListeners(editor, mutatedNodes, updateTags, dirtyLeaves,
8402
8402
  const listeners = Array.from(editor._listeners.mutation);
8403
8403
  const listenersLength = listeners.length;
8404
8404
  for (let i = 0; i < listenersLength; i++) {
8405
- const [listener, klass] = listeners[i];
8406
- const mutatedNodesByType = mutatedNodes.get(klass);
8407
- if (mutatedNodesByType !== undefined) {
8408
- listener(mutatedNodesByType, {
8409
- dirtyLeaves,
8410
- prevEditorState,
8411
- updateTags
8412
- });
8405
+ const [listener, klassSet] = listeners[i];
8406
+ for (const klass of klassSet) {
8407
+ const mutatedNodesByType = mutatedNodes.get(klass);
8408
+ if (mutatedNodesByType !== undefined) {
8409
+ listener(mutatedNodesByType, {
8410
+ dirtyLeaves,
8411
+ prevEditorState,
8412
+ updateTags
8413
+ });
8414
+ }
8413
8415
  }
8414
8416
  }
8415
8417
  }
@@ -10000,7 +10002,7 @@ function createEditor(editorConfig) {
10000
10002
  {
10001
10003
  // ArtificialNode__DO_NOT_USE can get renamed, so we use the type
10002
10004
  const name = klass.name;
10003
- const nodeType = hasOwn(klass, 'getType') && klass.getType();
10005
+ const nodeType = hasOwnStaticMethod(klass, 'getType') && klass.getType();
10004
10006
  if (replaceWithKlass) {
10005
10007
  if (!(replaceWithKlass.prototype instanceof klass)) {
10006
10008
  formatDevErrorMessage(`${replaceWithKlass.name} doesn't extend the ${name}`);
@@ -10011,19 +10013,19 @@ function createEditor(editorConfig) {
10011
10013
  if (name !== 'RootNode' && nodeType !== 'root' && nodeType !== 'artificial') {
10012
10014
  const proto = klass.prototype;
10013
10015
  ['getType', 'clone'].forEach(method => {
10014
- if (!hasOwn(klass, method)) {
10016
+ if (!hasOwnStaticMethod(klass, method)) {
10015
10017
  console.warn(`${name} must implement static "${method}" method`);
10016
10018
  }
10017
10019
  });
10018
- if (!hasOwn(klass, 'importDOM') && hasOwn(klass, 'exportDOM')) {
10020
+ if (!hasOwnStaticMethod(klass, 'importDOM') && hasOwnExportDOM(klass)) {
10019
10021
  console.warn(`${name} should implement "importDOM" if using a custom "exportDOM" method to ensure HTML serialization (important for copy & paste) works as expected`);
10020
10022
  }
10021
10023
  if ($isDecoratorNode(proto)) {
10022
- if (!hasOwn(proto, 'decorate')) {
10024
+ if (proto.decorate === DecoratorNode.prototype.decorate) {
10023
10025
  console.warn(`${proto.constructor.name} must implement "decorate" method`);
10024
10026
  }
10025
10027
  }
10026
- if (!hasOwn(klass, 'importJSON')) {
10028
+ if (!hasOwnStaticMethod(klass, 'importJSON')) {
10027
10029
  console.warn(`${name} should implement "importJSON" method to ensure JSON and default HTML serialization works as expected`);
10028
10030
  }
10029
10031
  }
@@ -10333,13 +10335,21 @@ class LexicalEditor {
10333
10335
  registerMutationListener(klass, listener, options) {
10334
10336
  const klassToMutate = this.resolveRegisteredNodeAfterReplacements(this.getRegisteredNode(klass)).klass;
10335
10337
  const mutations = this._listeners.mutation;
10336
- mutations.set(listener, klassToMutate);
10338
+ let klassSet = mutations.get(listener);
10339
+ if (klassSet === undefined) {
10340
+ klassSet = new Set();
10341
+ mutations.set(listener, klassSet);
10342
+ }
10343
+ klassSet.add(klassToMutate);
10337
10344
  const skipInitialization = options && options.skipInitialization;
10338
10345
  if (!(skipInitialization === undefined ? DEFAULT_SKIP_INITIALIZATION : skipInitialization)) {
10339
10346
  this.initializeMutationListener(listener, klassToMutate);
10340
10347
  }
10341
10348
  return () => {
10342
- mutations.delete(listener);
10349
+ klassSet.delete(klassToMutate);
10350
+ if (klassSet.size === 0) {
10351
+ mutations.delete(listener);
10352
+ }
10343
10353
  };
10344
10354
  }
10345
10355
 
@@ -10723,7 +10733,7 @@ class LexicalEditor {
10723
10733
  };
10724
10734
  }
10725
10735
  }
10726
- LexicalEditor.version = "0.32.2-nightly.20250627.0+dev.cjs";
10736
+ LexicalEditor.version = "0.32.2-nightly.20250701.0+dev.cjs";
10727
10737
 
10728
10738
  let pendingNodeToClone = null;
10729
10739
  function setPendingNodeToClone(pendingNode) {
@@ -12180,16 +12190,30 @@ function hasOwn(o, k) {
12180
12190
  return Object.prototype.hasOwnProperty.call(o, k);
12181
12191
  }
12182
12192
 
12193
+ /**
12194
+ * @internal
12195
+ */
12196
+ function hasOwnStaticMethod(klass, k) {
12197
+ return hasOwn(klass, k) && klass[k] !== LexicalNode[k];
12198
+ }
12199
+
12200
+ /**
12201
+ * @internal
12202
+ */
12203
+ function hasOwnExportDOM(klass) {
12204
+ return hasOwn(klass.prototype, 'exportDOM');
12205
+ }
12206
+
12183
12207
  /** @internal */
12184
12208
  function isAbstractNodeClass(klass) {
12185
- return klass === DecoratorNode || klass === ElementNode || klass === Object.getPrototypeOf(ElementNode);
12209
+ return klass === DecoratorNode || klass === ElementNode || klass === LexicalNode;
12186
12210
  }
12187
12211
 
12188
12212
  /** @internal */
12189
12213
  function getStaticNodeConfig(klass) {
12190
12214
  const nodeConfigRecord = PROTOTYPE_CONFIG_METHOD in klass.prototype ? klass.prototype[PROTOTYPE_CONFIG_METHOD]() : undefined;
12191
12215
  const isAbstract = isAbstractNodeClass(klass);
12192
- const nodeType = !isAbstract && hasOwn(klass, 'getType') ? klass.getType() : undefined;
12216
+ const nodeType = !isAbstract && hasOwnStaticMethod(klass, 'getType') ? klass.getType() : undefined;
12193
12217
  let ownNodeConfig;
12194
12218
  let ownNodeType = nodeType;
12195
12219
  if (nodeConfigRecord) {
@@ -12203,11 +12227,14 @@ function getStaticNodeConfig(klass) {
12203
12227
  }
12204
12228
  }
12205
12229
  if (!isAbstract && ownNodeType) {
12206
- if (!hasOwn(klass, 'getType')) {
12230
+ if (!hasOwnStaticMethod(klass, 'getType')) {
12207
12231
  klass.getType = () => ownNodeType;
12208
12232
  }
12209
- if (!hasOwn(klass, 'clone')) {
12210
- {
12233
+ if (!hasOwnStaticMethod(klass, 'clone')) {
12234
+ // TextNode.length > 0 will only be true if the compiler output
12235
+ // is not ES6 compliant, in which case we can not provide this
12236
+ // warning
12237
+ if (TextNode.length === 0) {
12211
12238
  if (!(klass.length === 0)) {
12212
12239
  formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static clone method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
12213
12240
  }
@@ -12217,7 +12244,7 @@ function getStaticNodeConfig(klass) {
12217
12244
  return new klass();
12218
12245
  };
12219
12246
  }
12220
- if (!hasOwn(klass, 'importJSON')) {
12247
+ if (!hasOwnStaticMethod(klass, 'importJSON')) {
12221
12248
  {
12222
12249
  if (!(klass.length === 0)) {
12223
12250
  formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static importJSON method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
@@ -12225,7 +12252,7 @@ function getStaticNodeConfig(klass) {
12225
12252
  }
12226
12253
  klass.importJSON = ownNodeConfig && ownNodeConfig.$importJSON || (serializedNode => new klass().updateFromJSON(serializedNode));
12227
12254
  }
12228
- if (!hasOwn(klass, 'importDOM') && ownNodeConfig) {
12255
+ if (!hasOwnStaticMethod(klass, 'importDOM') && ownNodeConfig) {
12229
12256
  const {
12230
12257
  importDOM
12231
12258
  } = ownNodeConfig;
package/Lexical.dev.mjs CHANGED
@@ -8400,14 +8400,16 @@ function triggerMutationListeners(editor, mutatedNodes, updateTags, dirtyLeaves,
8400
8400
  const listeners = Array.from(editor._listeners.mutation);
8401
8401
  const listenersLength = listeners.length;
8402
8402
  for (let i = 0; i < listenersLength; i++) {
8403
- const [listener, klass] = listeners[i];
8404
- const mutatedNodesByType = mutatedNodes.get(klass);
8405
- if (mutatedNodesByType !== undefined) {
8406
- listener(mutatedNodesByType, {
8407
- dirtyLeaves,
8408
- prevEditorState,
8409
- updateTags
8410
- });
8403
+ const [listener, klassSet] = listeners[i];
8404
+ for (const klass of klassSet) {
8405
+ const mutatedNodesByType = mutatedNodes.get(klass);
8406
+ if (mutatedNodesByType !== undefined) {
8407
+ listener(mutatedNodesByType, {
8408
+ dirtyLeaves,
8409
+ prevEditorState,
8410
+ updateTags
8411
+ });
8412
+ }
8411
8413
  }
8412
8414
  }
8413
8415
  }
@@ -9998,7 +10000,7 @@ function createEditor(editorConfig) {
9998
10000
  {
9999
10001
  // ArtificialNode__DO_NOT_USE can get renamed, so we use the type
10000
10002
  const name = klass.name;
10001
- const nodeType = hasOwn(klass, 'getType') && klass.getType();
10003
+ const nodeType = hasOwnStaticMethod(klass, 'getType') && klass.getType();
10002
10004
  if (replaceWithKlass) {
10003
10005
  if (!(replaceWithKlass.prototype instanceof klass)) {
10004
10006
  formatDevErrorMessage(`${replaceWithKlass.name} doesn't extend the ${name}`);
@@ -10009,19 +10011,19 @@ function createEditor(editorConfig) {
10009
10011
  if (name !== 'RootNode' && nodeType !== 'root' && nodeType !== 'artificial') {
10010
10012
  const proto = klass.prototype;
10011
10013
  ['getType', 'clone'].forEach(method => {
10012
- if (!hasOwn(klass, method)) {
10014
+ if (!hasOwnStaticMethod(klass, method)) {
10013
10015
  console.warn(`${name} must implement static "${method}" method`);
10014
10016
  }
10015
10017
  });
10016
- if (!hasOwn(klass, 'importDOM') && hasOwn(klass, 'exportDOM')) {
10018
+ if (!hasOwnStaticMethod(klass, 'importDOM') && hasOwnExportDOM(klass)) {
10017
10019
  console.warn(`${name} should implement "importDOM" if using a custom "exportDOM" method to ensure HTML serialization (important for copy & paste) works as expected`);
10018
10020
  }
10019
10021
  if ($isDecoratorNode(proto)) {
10020
- if (!hasOwn(proto, 'decorate')) {
10022
+ if (proto.decorate === DecoratorNode.prototype.decorate) {
10021
10023
  console.warn(`${proto.constructor.name} must implement "decorate" method`);
10022
10024
  }
10023
10025
  }
10024
- if (!hasOwn(klass, 'importJSON')) {
10026
+ if (!hasOwnStaticMethod(klass, 'importJSON')) {
10025
10027
  console.warn(`${name} should implement "importJSON" method to ensure JSON and default HTML serialization works as expected`);
10026
10028
  }
10027
10029
  }
@@ -10331,13 +10333,21 @@ class LexicalEditor {
10331
10333
  registerMutationListener(klass, listener, options) {
10332
10334
  const klassToMutate = this.resolveRegisteredNodeAfterReplacements(this.getRegisteredNode(klass)).klass;
10333
10335
  const mutations = this._listeners.mutation;
10334
- mutations.set(listener, klassToMutate);
10336
+ let klassSet = mutations.get(listener);
10337
+ if (klassSet === undefined) {
10338
+ klassSet = new Set();
10339
+ mutations.set(listener, klassSet);
10340
+ }
10341
+ klassSet.add(klassToMutate);
10335
10342
  const skipInitialization = options && options.skipInitialization;
10336
10343
  if (!(skipInitialization === undefined ? DEFAULT_SKIP_INITIALIZATION : skipInitialization)) {
10337
10344
  this.initializeMutationListener(listener, klassToMutate);
10338
10345
  }
10339
10346
  return () => {
10340
- mutations.delete(listener);
10347
+ klassSet.delete(klassToMutate);
10348
+ if (klassSet.size === 0) {
10349
+ mutations.delete(listener);
10350
+ }
10341
10351
  };
10342
10352
  }
10343
10353
 
@@ -10721,7 +10731,7 @@ class LexicalEditor {
10721
10731
  };
10722
10732
  }
10723
10733
  }
10724
- LexicalEditor.version = "0.32.2-nightly.20250627.0+dev.esm";
10734
+ LexicalEditor.version = "0.32.2-nightly.20250701.0+dev.esm";
10725
10735
 
10726
10736
  let pendingNodeToClone = null;
10727
10737
  function setPendingNodeToClone(pendingNode) {
@@ -12178,16 +12188,30 @@ function hasOwn(o, k) {
12178
12188
  return Object.prototype.hasOwnProperty.call(o, k);
12179
12189
  }
12180
12190
 
12191
+ /**
12192
+ * @internal
12193
+ */
12194
+ function hasOwnStaticMethod(klass, k) {
12195
+ return hasOwn(klass, k) && klass[k] !== LexicalNode[k];
12196
+ }
12197
+
12198
+ /**
12199
+ * @internal
12200
+ */
12201
+ function hasOwnExportDOM(klass) {
12202
+ return hasOwn(klass.prototype, 'exportDOM');
12203
+ }
12204
+
12181
12205
  /** @internal */
12182
12206
  function isAbstractNodeClass(klass) {
12183
- return klass === DecoratorNode || klass === ElementNode || klass === Object.getPrototypeOf(ElementNode);
12207
+ return klass === DecoratorNode || klass === ElementNode || klass === LexicalNode;
12184
12208
  }
12185
12209
 
12186
12210
  /** @internal */
12187
12211
  function getStaticNodeConfig(klass) {
12188
12212
  const nodeConfigRecord = PROTOTYPE_CONFIG_METHOD in klass.prototype ? klass.prototype[PROTOTYPE_CONFIG_METHOD]() : undefined;
12189
12213
  const isAbstract = isAbstractNodeClass(klass);
12190
- const nodeType = !isAbstract && hasOwn(klass, 'getType') ? klass.getType() : undefined;
12214
+ const nodeType = !isAbstract && hasOwnStaticMethod(klass, 'getType') ? klass.getType() : undefined;
12191
12215
  let ownNodeConfig;
12192
12216
  let ownNodeType = nodeType;
12193
12217
  if (nodeConfigRecord) {
@@ -12201,11 +12225,14 @@ function getStaticNodeConfig(klass) {
12201
12225
  }
12202
12226
  }
12203
12227
  if (!isAbstract && ownNodeType) {
12204
- if (!hasOwn(klass, 'getType')) {
12228
+ if (!hasOwnStaticMethod(klass, 'getType')) {
12205
12229
  klass.getType = () => ownNodeType;
12206
12230
  }
12207
- if (!hasOwn(klass, 'clone')) {
12208
- {
12231
+ if (!hasOwnStaticMethod(klass, 'clone')) {
12232
+ // TextNode.length > 0 will only be true if the compiler output
12233
+ // is not ES6 compliant, in which case we can not provide this
12234
+ // warning
12235
+ if (TextNode.length === 0) {
12209
12236
  if (!(klass.length === 0)) {
12210
12237
  formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static clone method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
12211
12238
  }
@@ -12215,7 +12242,7 @@ function getStaticNodeConfig(klass) {
12215
12242
  return new klass();
12216
12243
  };
12217
12244
  }
12218
- if (!hasOwn(klass, 'importJSON')) {
12245
+ if (!hasOwnStaticMethod(klass, 'importJSON')) {
12219
12246
  {
12220
12247
  if (!(klass.length === 0)) {
12221
12248
  formatDevErrorMessage(`${klass.name} (type ${ownNodeType}) must implement a static importJSON method since its constructor has ${String(klass.length)} required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey).`);
@@ -12223,7 +12250,7 @@ function getStaticNodeConfig(klass) {
12223
12250
  }
12224
12251
  klass.importJSON = ownNodeConfig && ownNodeConfig.$importJSON || (serializedNode => new klass().updateFromJSON(serializedNode));
12225
12252
  }
12226
- if (!hasOwn(klass, 'importDOM') && ownNodeConfig) {
12253
+ if (!hasOwnStaticMethod(klass, 'importDOM') && ownNodeConfig) {
12227
12254
  const {
12228
12255
  importDOM
12229
12256
  } = ownNodeConfig;