@tiptap/core 3.19.0 → 3.20.1

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/index.cjs CHANGED
@@ -1481,6 +1481,9 @@ function getAttributesFromExtensions(extensions) {
1481
1481
  keepOnSplit: true,
1482
1482
  isRequired: false
1483
1483
  };
1484
+ const nodeExtensionTypes = nodeExtensions.filter((ext) => ext.name !== "text").map((ext) => ext.name);
1485
+ const markExtensionTypes = markExtensions.map((ext) => ext.name);
1486
+ const allExtensionTypes = [...nodeExtensionTypes, ...markExtensionTypes];
1484
1487
  extensions.forEach((extension) => {
1485
1488
  const context = {
1486
1489
  name: extension.name,
@@ -1498,7 +1501,19 @@ function getAttributesFromExtensions(extensions) {
1498
1501
  }
1499
1502
  const globalAttributes = addGlobalAttributes();
1500
1503
  globalAttributes.forEach((globalAttribute) => {
1501
- globalAttribute.types.forEach((type) => {
1504
+ let resolvedTypes;
1505
+ if (Array.isArray(globalAttribute.types)) {
1506
+ resolvedTypes = globalAttribute.types;
1507
+ } else if (globalAttribute.types === "*") {
1508
+ resolvedTypes = allExtensionTypes;
1509
+ } else if (globalAttribute.types === "nodes") {
1510
+ resolvedTypes = nodeExtensionTypes;
1511
+ } else if (globalAttribute.types === "marks") {
1512
+ resolvedTypes = markExtensionTypes;
1513
+ } else {
1514
+ resolvedTypes = [];
1515
+ }
1516
+ resolvedTypes.forEach((type) => {
1502
1517
  Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => {
1503
1518
  extensionAttributes.push({
1504
1519
  type,
@@ -1549,6 +1564,67 @@ function getAttributesFromExtensions(extensions) {
1549
1564
  }
1550
1565
 
1551
1566
  // src/utilities/mergeAttributes.ts
1567
+ function splitStyleDeclarations(styles) {
1568
+ const result = [];
1569
+ let current = "";
1570
+ let inSingleQuote = false;
1571
+ let inDoubleQuote = false;
1572
+ let parenDepth = 0;
1573
+ const length = styles.length;
1574
+ for (let i = 0; i < length; i += 1) {
1575
+ const char = styles[i];
1576
+ if (char === "'" && !inDoubleQuote) {
1577
+ inSingleQuote = !inSingleQuote;
1578
+ current += char;
1579
+ continue;
1580
+ }
1581
+ if (char === '"' && !inSingleQuote) {
1582
+ inDoubleQuote = !inDoubleQuote;
1583
+ current += char;
1584
+ continue;
1585
+ }
1586
+ if (!inSingleQuote && !inDoubleQuote) {
1587
+ if (char === "(") {
1588
+ parenDepth += 1;
1589
+ current += char;
1590
+ continue;
1591
+ }
1592
+ if (char === ")" && parenDepth > 0) {
1593
+ parenDepth -= 1;
1594
+ current += char;
1595
+ continue;
1596
+ }
1597
+ if (char === ";" && parenDepth === 0) {
1598
+ result.push(current);
1599
+ current = "";
1600
+ continue;
1601
+ }
1602
+ }
1603
+ current += char;
1604
+ }
1605
+ if (current) {
1606
+ result.push(current);
1607
+ }
1608
+ return result;
1609
+ }
1610
+ function parseStyleEntries(styles) {
1611
+ const pairs = [];
1612
+ const declarations = splitStyleDeclarations(styles || "");
1613
+ const numDeclarations = declarations.length;
1614
+ for (let i = 0; i < numDeclarations; i += 1) {
1615
+ const declaration = declarations[i];
1616
+ const firstColonIndex = declaration.indexOf(":");
1617
+ if (firstColonIndex === -1) {
1618
+ continue;
1619
+ }
1620
+ const property = declaration.slice(0, firstColonIndex).trim();
1621
+ const value = declaration.slice(firstColonIndex + 1).trim();
1622
+ if (property && value) {
1623
+ pairs.push([property, value]);
1624
+ }
1625
+ }
1626
+ return pairs;
1627
+ }
1552
1628
  function mergeAttributes(...objects) {
1553
1629
  return objects.filter((item) => !!item).reduce((items, item) => {
1554
1630
  const mergedAttributes = { ...items };
@@ -1564,17 +1640,7 @@ function mergeAttributes(...objects) {
1564
1640
  const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
1565
1641
  mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
1566
1642
  } else if (key === "style") {
1567
- const newStyles = value ? value.split(";").map((style2) => style2.trim()).filter(Boolean) : [];
1568
- const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style2) => style2.trim()).filter(Boolean) : [];
1569
- const styleMap = /* @__PURE__ */ new Map();
1570
- existingStyles.forEach((style2) => {
1571
- const [property, val] = style2.split(":").map((part) => part.trim());
1572
- styleMap.set(property, val);
1573
- });
1574
- newStyles.forEach((style2) => {
1575
- const [property, val] = style2.split(":").map((part) => part.trim());
1576
- styleMap.set(property, val);
1577
- });
1643
+ const styleMap = new Map([...parseStyleEntries(mergedAttributes[key]), ...parseStyleEntries(value)]);
1578
1644
  mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
1579
1645
  } else {
1580
1646
  mergedAttributes[key] = value;
@@ -2116,6 +2182,9 @@ function isMarkActive(state, typeOrName, attributes = {}) {
2116
2182
  const from = $from.pos;
2117
2183
  const to = $to.pos;
2118
2184
  state.doc.nodesBetween(from, to, (node, pos) => {
2185
+ if (type && node.inlineContent && !node.type.allowsMarkType(type)) {
2186
+ return false;
2187
+ }
2119
2188
  if (!node.isText && !node.marks.length) {
2120
2189
  return;
2121
2190
  }
@@ -3816,6 +3885,39 @@ var ExtensionManager = class {
3816
3885
  };
3817
3886
  }, baseDispatch);
3818
3887
  }
3888
+ /**
3889
+ * Get the composed transformPastedHTML function from all extensions.
3890
+ * @param baseTransform The base transform function (e.g. from the editor props)
3891
+ * @returns A composed transform function that chains all extension transforms
3892
+ */
3893
+ transformPastedHTML(baseTransform) {
3894
+ const { editor } = this;
3895
+ const extensions = sortExtensions([...this.extensions]);
3896
+ return extensions.reduce(
3897
+ (transform, extension) => {
3898
+ const context = {
3899
+ name: extension.name,
3900
+ options: extension.options,
3901
+ storage: this.editor.extensionStorage[extension.name],
3902
+ editor,
3903
+ type: getSchemaTypeByName(extension.name, this.schema)
3904
+ };
3905
+ const extensionTransform = getExtensionField(
3906
+ extension,
3907
+ "transformPastedHTML",
3908
+ context
3909
+ );
3910
+ if (!extensionTransform) {
3911
+ return transform;
3912
+ }
3913
+ return (html, view) => {
3914
+ const transformedHtml = transform(html, view);
3915
+ return extensionTransform.call(context, transformedHtml);
3916
+ };
3917
+ },
3918
+ baseTransform || ((html) => html)
3919
+ );
3920
+ }
3819
3921
  get markViews() {
3820
3922
  const { editor } = this;
3821
3923
  const { markExtensions } = splitExtensions(this.extensions);
@@ -4838,7 +4940,7 @@ var Editor = class extends EventEmitter {
4838
4940
  return this.options.editable && this.view && this.view.editable;
4839
4941
  }
4840
4942
  /**
4841
- * Returns the editor state.
4943
+ * Returns the editor view.
4842
4944
  */
4843
4945
  get view() {
4844
4946
  if (this.editorView) {
@@ -5007,6 +5109,8 @@ var Editor = class extends EventEmitter {
5007
5109
  const { editorProps, enableExtensionDispatchTransaction } = this.options;
5008
5110
  const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this);
5009
5111
  const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch;
5112
+ const baseTransformPastedHTML = editorProps.transformPastedHTML;
5113
+ const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
5010
5114
  this.editorView = new import_view.EditorView(element, {
5011
5115
  ...editorProps,
5012
5116
  attributes: {
@@ -5015,6 +5119,7 @@ var Editor = class extends EventEmitter {
5015
5119
  ...editorProps == null ? void 0 : editorProps.attributes
5016
5120
  },
5017
5121
  dispatchTransaction: dispatch,
5122
+ transformPastedHTML,
5018
5123
  state: this.editorState,
5019
5124
  markViews: this.extensionManager.markViews,
5020
5125
  nodeViews: this.extensionManager.nodeViews