@harbour-enterprises/superdoc 1.4.0-next.1 → 1.4.0-next.2

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.
@@ -1,6 +1,6 @@
1
1
  import { d as defineComponent, h, T as Transition, p as process$1, w as watchEffect, c as computed, r as ref, f as onMounted, X as onUnmounted, E as createElementBlock, G as openBlock, K as createBaseVNode, M as createCommentVNode, I as createVNode, v as unref } from "./vue-BnBKJwCW.es.js";
2
- import { N as NBaseLoading, u as useSuperdocStore, s as storeToRefs, a as useSelection } from "./index-BP9aFfwI.es.js";
3
- import { C as derived, r as c, q as cB, aF as fadeInTransition, y as cM, I as warnOnce, J as useConfig, N as useTheme, aG as pxfy, P as createKey, Q as useThemeClass, aH as useCompitable, ai as _export_sfc } from "./index-CEcYlysg.es.js";
2
+ import { N as NBaseLoading, u as useSuperdocStore, s as storeToRefs, a as useSelection } from "./index-D246eEeJ.es.js";
3
+ import { C as derived, r as c, q as cB, aF as fadeInTransition, y as cM, I as warnOnce, J as useConfig, N as useTheme, aG as pxfy, P as createKey, Q as useThemeClass, aH as useCompitable, ai as _export_sfc } from "./index-dnQEKI-e.es.js";
4
4
  function self(vars) {
5
5
  const {
6
6
  opacityDisabled,
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("./vue-De9wkgLl.cjs");
4
- const superdoc = require("./index-BdaseaBw.cjs");
5
- const index = require("./index-C3KRKogJ.cjs");
4
+ const superdoc = require("./index-DpgrTjYC.cjs");
5
+ const index = require("./index-DJuBZura.cjs");
6
6
  function self(vars) {
7
7
  const {
8
8
  opacityDisabled,
@@ -19026,7 +19026,7 @@ function isMetafileExtension(extension) {
19026
19026
  const DRAWING_XML_TAG = "w:drawing";
19027
19027
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
19028
19028
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
19029
- const normalizeTargetPath = (targetPath = "") => {
19029
+ const normalizeTargetPath$1 = (targetPath = "") => {
19030
19030
  if (!targetPath) return targetPath;
19031
19031
  const trimmed = targetPath.replace(/^\/+/, "");
19032
19032
  if (trimmed.startsWith("word/")) return trimmed;
@@ -19185,7 +19185,14 @@ function handleImageNode(node, params, isAnchor) {
19185
19185
  }
19186
19186
  const stretch = blipFill?.elements.find((el) => el.name === "a:stretch");
19187
19187
  const fillRect = stretch?.elements.find((el) => el.name === "a:fillRect");
19188
+ const srcRect = blipFill?.elements.find((el) => el.name === "a:srcRect");
19189
+ const srcRectAttrs = srcRect?.attributes || {};
19190
+ const srcRectHasNegativeValues = ["l", "t", "r", "b"].some((attr) => {
19191
+ const val = srcRectAttrs[attr];
19192
+ return val != null && parseFloat(val) < 0;
19193
+ });
19188
19194
  const shouldStretch = Boolean(stretch && fillRect);
19195
+ const shouldCover = shouldStretch && !srcRectHasNegativeValues;
19189
19196
  const spPr = picture.elements.find((el) => el.name === "pic:spPr");
19190
19197
  if (spPr) {
19191
19198
  const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
@@ -19214,7 +19221,7 @@ function handleImageNode(node, params, isAnchor) {
19214
19221
  }
19215
19222
  const { attributes: relAttributes } = rel;
19216
19223
  const targetPath = relAttributes["Target"];
19217
- const path = normalizeTargetPath(targetPath);
19224
+ const path = normalizeTargetPath$1(targetPath);
19218
19225
  const extension = path.substring(path.lastIndexOf(".") + 1);
19219
19226
  let finalSrc = path;
19220
19227
  let finalExtension = extension;
@@ -19262,7 +19269,7 @@ function handleImageNode(node, params, isAnchor) {
19262
19269
  wrapText: wrap2.attrs.wrapText
19263
19270
  } : {},
19264
19271
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
19265
- shouldStretch,
19272
+ shouldCover,
19266
19273
  originalPadding: {
19267
19274
  distT: attributes["distT"],
19268
19275
  distB: attributes["distB"],
@@ -19455,7 +19462,7 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
19455
19462
  const { elements } = relationships || [];
19456
19463
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
19457
19464
  if (!rel) return null;
19458
- const targetPath = normalizeTargetPath(rel.attributes?.["Target"]);
19465
+ const targetPath = normalizeTargetPath$1(rel.attributes?.["Target"]);
19459
19466
  const path = targetPath;
19460
19467
  const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
19461
19468
  const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
@@ -29559,6 +29566,10 @@ function filterOutRootInlineNodes(content = []) {
29559
29566
  if (!node || typeof node.type !== "string") return;
29560
29567
  const type = node.type;
29561
29568
  const preservableNodeName = PRESERVABLE_INLINE_XML_NAMES[type];
29569
+ if (type === "image" && node.attrs?.isAnchor) {
29570
+ result.push(node);
29571
+ return;
29572
+ }
29562
29573
  if (!INLINE_TYPES.has(type)) {
29563
29574
  result.push(node);
29564
29575
  } else if (preservableNodeName) {
@@ -29752,6 +29763,137 @@ function buildStyles(styleObject) {
29752
29763
  }
29753
29764
  return style;
29754
29765
  }
29766
+ function handleShapeImageImport({ params, pict }) {
29767
+ const shape = pict.elements?.find((el) => el.name === "v:shape");
29768
+ if (!shape) return null;
29769
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
29770
+ if (!imagedata) return null;
29771
+ const { docx, filename } = params;
29772
+ const shapeAttrs = shape.attributes || {};
29773
+ const imagedataAttrs = imagedata.attributes || {};
29774
+ const rId = imagedataAttrs["r:id"];
29775
+ if (!rId) {
29776
+ console.warn("v:imagedata missing r:id attribute");
29777
+ return null;
29778
+ }
29779
+ const currentFile = filename || "document.xml";
29780
+ let rels = docx[`word/_rels/${currentFile}.rels`];
29781
+ if (!rels) rels = docx[`word/_rels/document.xml.rels`];
29782
+ const relationships = rels?.elements?.find((el) => el.name === "Relationships");
29783
+ const { elements } = relationships || [];
29784
+ const rel = elements?.find((el) => el.attributes["Id"] === rId);
29785
+ if (!rel) {
29786
+ console.warn(`Relationship not found for r:id="${rId}"`);
29787
+ return null;
29788
+ }
29789
+ const targetPath = rel.attributes["Target"];
29790
+ const normalizedPath = normalizeTargetPath(targetPath);
29791
+ const style = shapeAttrs.style || "";
29792
+ const styleObj = parseVmlStyle(style);
29793
+ const width = styleObj.width || "100px";
29794
+ const height = styleObj.height || "100px";
29795
+ const position = {
29796
+ type: styleObj.position || "absolute",
29797
+ marginLeft: styleObj["margin-left"] || "0",
29798
+ marginTop: styleObj["margin-top"] || "0"
29799
+ };
29800
+ const zIndex = styleObj["z-index"] ? parseInt(styleObj["z-index"], 10) : void 0;
29801
+ const hPosition = styleObj["mso-position-horizontal"] || "center";
29802
+ const vPosition = styleObj["mso-position-vertical"] || "center";
29803
+ const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
29804
+ const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
29805
+ const gain = imagedataAttrs["gain"];
29806
+ const blacklevel = imagedataAttrs["blacklevel"];
29807
+ const title = imagedataAttrs["o:title"] || "Watermark";
29808
+ const imageNode = {
29809
+ type: "image",
29810
+ attrs: {
29811
+ src: normalizedPath,
29812
+ alt: title,
29813
+ extension: normalizedPath.substring(normalizedPath.lastIndexOf(".") + 1),
29814
+ title,
29815
+ rId,
29816
+ // Store VML-specific attributes for round-trip
29817
+ vmlWatermark: true,
29818
+ vmlStyle: style,
29819
+ vmlAttributes: shapeAttrs,
29820
+ vmlImagedata: imagedataAttrs,
29821
+ // Positioning
29822
+ isAnchor: true,
29823
+ inline: false,
29824
+ wrap: {
29825
+ type: "None",
29826
+ attrs: {
29827
+ behindDoc: Number.isFinite(zIndex) ? zIndex < 0 : true
29828
+ }
29829
+ },
29830
+ anchorData: {
29831
+ hRelativeFrom: hRelativeTo,
29832
+ vRelativeFrom: vRelativeTo,
29833
+ alignH: hPosition,
29834
+ alignV: vPosition
29835
+ },
29836
+ // Size
29837
+ size: {
29838
+ width: convertToPixels(width),
29839
+ height: convertToPixels(height)
29840
+ },
29841
+ marginOffset: {
29842
+ horizontal: convertToPixels(position.marginLeft),
29843
+ top: convertToPixels(position.marginTop)
29844
+ },
29845
+ // Image adjustments
29846
+ ...gain && { gain },
29847
+ ...blacklevel && { blacklevel }
29848
+ }
29849
+ };
29850
+ return imageNode;
29851
+ }
29852
+ function normalizeTargetPath(targetPath = "") {
29853
+ if (!targetPath) return targetPath;
29854
+ const trimmed = targetPath.replace(/^\/+/, "");
29855
+ if (trimmed.startsWith("word/")) return trimmed;
29856
+ if (trimmed.startsWith("media/")) return `word/${trimmed}`;
29857
+ return `word/${trimmed}`;
29858
+ }
29859
+ function parseVmlStyle(style) {
29860
+ const result = {};
29861
+ if (!style) return result;
29862
+ const declarations = style.split(";").filter((s) => s.trim());
29863
+ for (const decl of declarations) {
29864
+ const [prop, value] = decl.split(":").map((s) => s.trim());
29865
+ if (prop && value) {
29866
+ result[prop] = value;
29867
+ }
29868
+ }
29869
+ return result;
29870
+ }
29871
+ function convertToPixels(value) {
29872
+ if (typeof value === "number") return value;
29873
+ if (!value || typeof value !== "string") return 0;
29874
+ const match = value.match(/^([\d.]+)([a-z%]+)?$/i);
29875
+ if (!match) return 0;
29876
+ const num = parseFloat(match[1]);
29877
+ const unit = match[2] || "px";
29878
+ switch (unit.toLowerCase()) {
29879
+ case "px":
29880
+ return num;
29881
+ case "pt":
29882
+ return num * (96 / 72);
29883
+ // 1pt = 1/72 inch, 96 DPI
29884
+ case "in":
29885
+ return num * 96;
29886
+ case "cm":
29887
+ return num * (96 / 2.54);
29888
+ case "mm":
29889
+ return num * (96 / 25.4);
29890
+ case "pc":
29891
+ return num * 16;
29892
+ // 1pc = 12pt
29893
+ default:
29894
+ return num;
29895
+ }
29896
+ }
29755
29897
  function pictNodeTypeStrategy(node) {
29756
29898
  const shape = node.elements?.find((el) => el.name === "v:shape");
29757
29899
  const group = node.elements?.find((el) => el.name === "v:group");
@@ -29770,6 +29912,10 @@ function pictNodeTypeStrategy(node) {
29770
29912
  if (textbox) {
29771
29913
  return { type: "shapeContainer", handler: handleShapeTextboxImport };
29772
29914
  }
29915
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
29916
+ if (imagedata) {
29917
+ return { type: "image", handler: handleShapeImageImport };
29918
+ }
29773
29919
  }
29774
29920
  return { type: "unknown", handler: null };
29775
29921
  }
@@ -29868,8 +30014,116 @@ function translateVRectContentBlock(params) {
29868
30014
  };
29869
30015
  return wrapTextInRun(pict);
29870
30016
  }
30017
+ function translateVmlWatermark(params) {
30018
+ const { node } = params;
30019
+ const { attrs } = node;
30020
+ if (attrs.vmlAttributes && attrs.vmlImagedata) {
30021
+ const shape2 = {
30022
+ name: "v:shape",
30023
+ attributes: attrs.vmlAttributes,
30024
+ elements: [
30025
+ {
30026
+ name: "v:imagedata",
30027
+ attributes: {
30028
+ ...attrs.vmlImagedata,
30029
+ "r:id": attrs.rId
30030
+ }
30031
+ }
30032
+ ]
30033
+ };
30034
+ const pict2 = {
30035
+ name: "w:pict",
30036
+ attributes: {
30037
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
30038
+ },
30039
+ elements: [shape2]
30040
+ };
30041
+ const par2 = {
30042
+ name: "w:p",
30043
+ elements: [wrapTextInRun(pict2)]
30044
+ };
30045
+ return par2;
30046
+ }
30047
+ const style = buildVmlStyle(attrs);
30048
+ const shape = {
30049
+ name: "v:shape",
30050
+ attributes: {
30051
+ id: `WordPictureWatermark${generateRandomSigned32BitIntStrId().replace("-", "")}`,
30052
+ "o:spid": `_x0000_s${Math.floor(Math.random() * 1e4)}`,
30053
+ type: "#_x0000_t75",
30054
+ style,
30055
+ "o:allowincell": "f"
30056
+ },
30057
+ elements: [
30058
+ {
30059
+ name: "v:imagedata",
30060
+ attributes: {
30061
+ "r:id": attrs.rId,
30062
+ "o:title": attrs.title || attrs.alt || "Watermark",
30063
+ ...attrs.gain && { gain: attrs.gain },
30064
+ ...attrs.blacklevel && { blacklevel: attrs.blacklevel }
30065
+ }
30066
+ }
30067
+ ]
30068
+ };
30069
+ const pict = {
30070
+ name: "w:pict",
30071
+ attributes: {
30072
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
30073
+ },
30074
+ elements: [shape]
30075
+ };
30076
+ const par = {
30077
+ name: "w:p",
30078
+ elements: [wrapTextInRun(pict)]
30079
+ };
30080
+ return par;
30081
+ }
30082
+ function buildVmlStyle(attrs) {
30083
+ const styles = [];
30084
+ styles.push("position:absolute");
30085
+ if (attrs.size) {
30086
+ if (attrs.size.width) {
30087
+ styles.push(`width:${convertToPt(attrs.size.width)}pt`);
30088
+ }
30089
+ if (attrs.size.height) {
30090
+ styles.push(`height:${convertToPt(attrs.size.height)}pt`);
30091
+ }
30092
+ }
30093
+ if (attrs.marginOffset) {
30094
+ if (attrs.marginOffset.horizontal !== void 0) {
30095
+ styles.push(`margin-left:${convertToPt(attrs.marginOffset.horizontal)}pt`);
30096
+ }
30097
+ if (attrs.marginOffset.top !== void 0) {
30098
+ styles.push(`margin-top:${convertToPt(attrs.marginOffset.top)}pt`);
30099
+ }
30100
+ }
30101
+ if (attrs.wrap?.attrs?.behindDoc) {
30102
+ styles.push("z-index:-251653120");
30103
+ }
30104
+ if (attrs.anchorData) {
30105
+ if (attrs.anchorData.alignH) {
30106
+ styles.push(`mso-position-horizontal:${attrs.anchorData.alignH}`);
30107
+ }
30108
+ if (attrs.anchorData.alignV) {
30109
+ styles.push(`mso-position-vertical:${attrs.anchorData.alignV}`);
30110
+ }
30111
+ if (attrs.anchorData.hRelativeFrom) {
30112
+ styles.push(`mso-position-horizontal-relative:${attrs.anchorData.hRelativeFrom}`);
30113
+ }
30114
+ if (attrs.anchorData.vRelativeFrom) {
30115
+ styles.push(`mso-position-vertical-relative:${attrs.anchorData.vRelativeFrom}`);
30116
+ }
30117
+ }
30118
+ styles.push("mso-width-percent:0");
30119
+ styles.push("mso-height-percent:0");
30120
+ return styles.join(";");
30121
+ }
30122
+ function convertToPt(pixels) {
30123
+ return pixels * 72 / 96;
30124
+ }
29871
30125
  const XML_NODE_NAME = "w:pict";
29872
- const SD_NODE_NAME = ["shapeContainer", "contentBlock"];
30126
+ const SD_NODE_NAME = ["shapeContainer", "contentBlock", "image"];
29873
30127
  const validXmlAttributes = [];
29874
30128
  function encode(params) {
29875
30129
  const { node, pNode } = params.extraParams;
@@ -29893,6 +30147,12 @@ function decode(params) {
29893
30147
  shapeContainer: () => translateShapeContainer(params),
29894
30148
  shapeTextbox: () => translateShapeTextbox(params),
29895
30149
  contentBlock: () => translateContentBlock(params),
30150
+ image: () => {
30151
+ if (node.attrs?.vmlWatermark) {
30152
+ return translateVmlWatermark(params);
30153
+ }
30154
+ return null;
30155
+ },
29896
30156
  default: () => null
29897
30157
  };
29898
30158
  const decoder = types[node.type] ?? types.default;
@@ -31008,7 +31268,7 @@ class SuperConverter {
31008
31268
  static getStoredSuperdocVersion(docx) {
31009
31269
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
31010
31270
  }
31011
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.4.0-next.1") {
31271
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.4.0-next.2") {
31012
31272
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
31013
31273
  }
31014
31274
  /**