@makhmudov.kay/az-editor 0.1.0-beta.12 → 0.1.0-beta.13
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/CHANGELOG.md +5 -0
- package/README.md +2 -2
- package/dist/az-editor.js +137 -129
- package/docs/inline-images.ru.md +2 -0
- package/docs/integration.ru.md +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Изменения
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.13
|
|
4
|
+
|
|
5
|
+
- Исправлен экспорт уже встроенных изображений Word: явные `noFill`, невидимая линия и остаточные `effectExtent` без фактических эффектов больше не вызывают ложную потерю изображения. Байты PNG/JPEG и размеры из `wp:extent` сохраняются при повторном открытии.
|
|
6
|
+
- Для серверного импорта DOCX требуется соответствующая правка Hujjat: размеры каждого изображения читаются из исходного OOXML до обработки PHPWord. Изменений API и схемы БД нет.
|
|
7
|
+
|
|
3
8
|
## 0.1.0-beta.12
|
|
4
9
|
|
|
5
10
|
- Вставка PNG/JPEG из файла в текущую позицию курсора, с уменьшением больших изображений, сохранением прозрачности PNG и поддержкой отмены/повтора.
|
package/README.md
CHANGED
|
@@ -14,10 +14,10 @@ React-библиотека для редактирования DOCX и HTML-до
|
|
|
14
14
|
npm install @makhmudov.kay/az-editor@beta
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Для воспроизводимой установки версии beta.
|
|
17
|
+
Для воспроизводимой установки версии beta.13:
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.
|
|
20
|
+
npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.13
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Требуются React и React DOM 19, Node.js `^24.15.0 || >=26.0.0` для установки/сборки,
|
package/dist/az-editor.js
CHANGED
|
@@ -1061,7 +1061,15 @@ async function He(e) {
|
|
|
1061
1061
|
}
|
|
1062
1062
|
return t;
|
|
1063
1063
|
}
|
|
1064
|
-
function Ue(e
|
|
1064
|
+
function Ue(e) {
|
|
1065
|
+
if (e.namespaceURI !== X) return !1;
|
|
1066
|
+
if (["xfrm", "prstGeom"].includes(e.localName)) return !0;
|
|
1067
|
+
if (["noFill", "effectLst"].includes(e.localName)) return e.children.length === 0;
|
|
1068
|
+
if (e.localName !== "ln" || e.children.length !== 1) return !1;
|
|
1069
|
+
let t = e.children[0];
|
|
1070
|
+
return t.namespaceURI === X && t.localName === "noFill" && t.children.length === 0;
|
|
1071
|
+
}
|
|
1072
|
+
function We(e, t, n, r) {
|
|
1065
1073
|
let i = (t, n) => Array.from(e.getElementsByTagNameNS(t, n)), a = i(ze, "inline"), o = i(Be, "pic");
|
|
1066
1074
|
if (!a.length && !o.length) return r("drawing-removed", "Фигуры и текстовые блоки Word не поддерживаются HTML-блоком Hujjat."), "";
|
|
1067
1075
|
let s = (e) => (r("image-layout-unsupported", e), "");
|
|
@@ -1071,7 +1079,7 @@ function Ue(e, t, n, r) {
|
|
|
1071
1079
|
"r",
|
|
1072
1080
|
"t",
|
|
1073
1081
|
"b"
|
|
1074
|
-
].some((t) => Number(e.getAttribute(t) || 0) !== 0)), l = i(X, "xfrm").some((e) => Number(e.getAttribute("rot") || 0) !== 0 || ["flipH", "flipV"].some((t) => ["1", "true"].includes(e.getAttribute(t) ?? ""))), u = i(X, "effectLst").some((e) => e.children.length) || i(X, "effectDag").length || i(X, "tile").length || i(X, "hlinkClick").length || i(X, "hlinkHover").length, d = i(Be, "spPr").some((e) => Array.from(e.children).some((e) => !
|
|
1082
|
+
].some((t) => Number(e.getAttribute(t) || 0) !== 0)), l = i(X, "xfrm").some((e) => Number(e.getAttribute("rot") || 0) !== 0 || ["flipH", "flipV"].some((t) => ["1", "true"].includes(e.getAttribute(t) ?? ""))), u = i(X, "effectLst").some((e) => e.children.length) || i(X, "effectDag").length || i(X, "tile").length || i(X, "hlinkClick").length || i(X, "hlinkHover").length, d = i(Be, "spPr").some((e) => Array.from(e.children).some((e) => !Ue(e))) || i(X, "prstGeom").some((e) => e.getAttribute("prst") !== "rect") || i(X, "fillRect").some((e) => Array.from(e.attributes).some((e) => Number(e.value) !== 0)), f = i(X, "blip");
|
|
1075
1083
|
if (c || l || u || d || f.some((e) => Array.from(e.children).some((e) => e.localName !== "extLst"))) return s("Обрезка, поворот, эффекты и ссылки изображения не сохраняются в Hujjat. Сначала примените их к самому файлу.");
|
|
1076
1084
|
let p = Array.from(a[0].children).filter((e) => e.namespaceURI === ze && e.localName === "extent"), m = p[0], h = Number(m?.getAttribute("cx")) / 12700, g = Number(m?.getAttribute("cy")) / 12700;
|
|
1077
1085
|
if (p.length !== 1 || !Number.isFinite(h) || !Number.isFinite(g) || h <= 0 || g <= 0 || h > 600 || g > 600) return s("Размер изображения должен быть больше нуля и не превышать 600 pt.");
|
|
@@ -1082,13 +1090,13 @@ function Ue(e, t, n, r) {
|
|
|
1082
1090
|
let x = Array.from(b?.getAttribute("descr") || b?.getAttribute("title") || "").slice(0, 500).join("");
|
|
1083
1091
|
return `<img src="${y.src}" alt="${Se(x)}" style="width:${Number(h.toFixed(4))}pt;height:${Number(g.toFixed(4))}pt">`;
|
|
1084
1092
|
}
|
|
1085
|
-
function
|
|
1093
|
+
function Ge(e, t, n, r, i) {
|
|
1086
1094
|
let a = Math.round(n * 12700), o = Math.round(r * 12700);
|
|
1087
1095
|
return `<w:r><w:drawing><wp:inline xmlns:wp="${ze}" xmlns:a="${X}" xmlns:pic="${Be}" xmlns:r="${Re}" distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${a}" cy="${o}"/><wp:docPr id="${e}" name="Image ${e}" descr="${Se(i)}"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="${Be}"><pic:pic><pic:nvPicPr><pic:cNvPr id="${e}" name="Image ${e}"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${t}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${a}" cy="${o}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
|
|
1088
1096
|
}
|
|
1089
1097
|
//#endregion
|
|
1090
1098
|
//#region src/library/hujjat/docx-to-html.ts
|
|
1091
|
-
async function
|
|
1099
|
+
async function Ke(e, t = {}, n) {
|
|
1092
1100
|
if (e.byteLength > 31457280) throw new z("DOCX превышает 30 МиБ.");
|
|
1093
1101
|
let r;
|
|
1094
1102
|
try {
|
|
@@ -1167,7 +1175,7 @@ async function Ge(e, t = {}, n) {
|
|
|
1167
1175
|
bytes: 0
|
|
1168
1176
|
};
|
|
1169
1177
|
if (t.count >= 32) throw new z("В одном HTML-блоке допускается не более 32 изображений.");
|
|
1170
|
-
let n =
|
|
1178
|
+
let n = We(e, v, d, h);
|
|
1171
1179
|
if (n && (t.count++, t.bytes += new TextEncoder().encode(n).length, y.set(v, t)), t.bytes > (v === "word/document.xml" ? 1048576 : 102400)) throw new z("Встроенные изображения превышают лимит HTML: 1 МБ на тело, 100 КиБ на колонтитул.");
|
|
1172
1180
|
return j = !1, n;
|
|
1173
1181
|
}
|
|
@@ -1380,8 +1388,8 @@ async function Ge(e, t = {}, n) {
|
|
|
1380
1388
|
}
|
|
1381
1389
|
//#endregion
|
|
1382
1390
|
//#region src/library/hujjat/table-grid.ts
|
|
1383
|
-
var
|
|
1384
|
-
function
|
|
1391
|
+
var qe = 1e-7;
|
|
1392
|
+
function Je(e, t, n) {
|
|
1385
1393
|
let r = Array.from({ length: e + 1 }, () => []), i = (e, t, n) => {
|
|
1386
1394
|
r[e].push({
|
|
1387
1395
|
to: t,
|
|
@@ -1401,7 +1409,7 @@ function qe(e, t, n) {
|
|
|
1401
1409
|
for (let n = 0; n < e.length; n++) for (let i of r[e[n]]) {
|
|
1402
1410
|
let r = o[e[n]] + i.distance;
|
|
1403
1411
|
if (a[i.to] !== -1) {
|
|
1404
|
-
if (Math.abs(o[i.to] - r) >
|
|
1412
|
+
if (Math.abs(o[i.to] - r) > qe) return null;
|
|
1405
1413
|
} else a[i.to] = a[t], o[i.to] = r, e.push(i.to);
|
|
1406
1414
|
}
|
|
1407
1415
|
}
|
|
@@ -1427,7 +1435,7 @@ function qe(e, t, n) {
|
|
|
1427
1435
|
high: u
|
|
1428
1436
|
};
|
|
1429
1437
|
}
|
|
1430
|
-
function
|
|
1438
|
+
function Ye(e, t) {
|
|
1431
1439
|
let { groups: n } = e, r = [...e.edges];
|
|
1432
1440
|
if (t !== void 0) for (let i = 0; i < n; i++) r.push({
|
|
1433
1441
|
from: 0,
|
|
@@ -1441,12 +1449,12 @@ function Je(e, t) {
|
|
|
1441
1449
|
let i = Array(n).fill(0);
|
|
1442
1450
|
for (let e = 0; e < n; e++) {
|
|
1443
1451
|
let e = !1;
|
|
1444
|
-
for (let { from: t, to: n, distance: a } of r) i[n] > i[t] + a +
|
|
1452
|
+
for (let { from: t, to: n, distance: a } of r) i[n] > i[t] + a + qe && (i[n] = i[t] + a, e = !0);
|
|
1445
1453
|
if (!e) return i.map((e) => e - i[0]);
|
|
1446
1454
|
}
|
|
1447
1455
|
return null;
|
|
1448
1456
|
}
|
|
1449
|
-
function
|
|
1457
|
+
function Xe(e) {
|
|
1450
1458
|
if (!e) return null;
|
|
1451
1459
|
let t = (t) => ({
|
|
1452
1460
|
...e,
|
|
@@ -1455,45 +1463,45 @@ function Ye(e) {
|
|
|
1455
1463
|
distance: e.distance - t
|
|
1456
1464
|
}))
|
|
1457
1465
|
}), n = t(1);
|
|
1458
|
-
if (
|
|
1459
|
-
if (!
|
|
1466
|
+
if (Ye(n)) return n;
|
|
1467
|
+
if (!Ye(e)) return null;
|
|
1460
1468
|
let r = 0, i = 1, a = e;
|
|
1461
|
-
for (let e = 0; e < 40 && i - r >
|
|
1469
|
+
for (let e = 0; e < 40 && i - r > qe; e++) {
|
|
1462
1470
|
let e = (r + i) / 2, n = t(e);
|
|
1463
|
-
|
|
1471
|
+
Ye(n) ? (r = e, a = n) : i = e;
|
|
1464
1472
|
}
|
|
1465
|
-
return r >
|
|
1473
|
+
return r > qe ? a : null;
|
|
1466
1474
|
}
|
|
1467
|
-
function
|
|
1468
|
-
let t =
|
|
1475
|
+
function Ze(e) {
|
|
1476
|
+
let t = Ye(e), n = Ye(e, 0);
|
|
1469
1477
|
if (n) return n;
|
|
1470
1478
|
let r = 0, i = Math.max(...t.map((t, n) => Math.max(e.low[n] - t, t - e.high[n]))) + 1;
|
|
1471
1479
|
for (let n = 0; n < 60 && i - r > 1e-6; n++) {
|
|
1472
|
-
let n = (r + i) / 2, a =
|
|
1480
|
+
let n = (r + i) / 2, a = Ye(e, n);
|
|
1473
1481
|
a ? (t = a, i = n) : r = n;
|
|
1474
1482
|
}
|
|
1475
1483
|
return t;
|
|
1476
1484
|
}
|
|
1477
|
-
function
|
|
1485
|
+
function Qe(e, t, n, r) {
|
|
1478
1486
|
let i = (e) => Number.isFinite(e) && e > 0 && e < (2 ** 53 - 1) / 4;
|
|
1479
1487
|
if (!Number.isInteger(e) || e < 1 || e > 1e3 || !i(t) || Math.round(t) < e) throw new z("Некорректный размер сетки таблицы.");
|
|
1480
1488
|
for (let t of n) if (!Number.isInteger(t.column) || !Number.isInteger(t.span) || t.column < 0 || t.span < 1 || t.column + t.span > e || !i(t.width)) throw new z("Некорректное ограничение ширины таблицы.");
|
|
1481
|
-
let a = (e) => e.source === "column" ? 0 : e.span === 1 ? 1 : 2, o = (e) => JSON.stringify(Object.entries(e.location ?? {}).sort(([e], [t]) => e < t ? -1 : +(e > t))), s = [...n].sort((e, t) => a(e) - a(t) || e.column - t.column || e.span - t.span || e.width - t.width || o(e).localeCompare(o(t), "en")), c = s.filter((e, t) => !t || a(e) !== a(s[t - 1]) || e.column !== s[t - 1].column || e.span !== s[t - 1].span || e.width !== s[t - 1].width), l =
|
|
1489
|
+
let a = (e) => e.source === "column" ? 0 : e.span === 1 ? 1 : 2, o = (e) => JSON.stringify(Object.entries(e.location ?? {}).sort(([e], [t]) => e < t ? -1 : +(e > t))), s = [...n].sort((e, t) => a(e) - a(t) || e.column - t.column || e.span - t.span || e.width - t.width || o(e).localeCompare(o(t), "en")), c = s.filter((e, t) => !t || a(e) !== a(s[t - 1]) || e.column !== s[t - 1].column || e.span !== s[t - 1].span || e.width !== s[t - 1].width), l = Xe(Je(e, t, c));
|
|
1482
1490
|
if (!l) {
|
|
1483
1491
|
let n = [];
|
|
1484
|
-
l =
|
|
1492
|
+
l = Xe(Je(e, t, []));
|
|
1485
1493
|
for (let r of c) {
|
|
1486
|
-
let i =
|
|
1494
|
+
let i = Xe(Je(e, t, [...n, r]));
|
|
1487
1495
|
i && (i.groups < l.groups && n.push(r), l = i);
|
|
1488
1496
|
}
|
|
1489
1497
|
}
|
|
1490
|
-
let u =
|
|
1498
|
+
let u = Ze(l), d = l.offset.map((e, t) => e + u[l.component[t]]), f = Math.round(t), p = d.map((e) => Math.round(e));
|
|
1491
1499
|
p[0] = 0, p[e] = f;
|
|
1492
|
-
let m = d.map((e) => Math.floor(e + 1 +
|
|
1500
|
+
let m = d.map((e) => Math.floor(e + 1 + qe));
|
|
1493
1501
|
m[e] = f;
|
|
1494
1502
|
for (let t = e - 1; t > 0; t--) m[t] = Math.min(m[t], m[t + 1] - 1);
|
|
1495
1503
|
for (let t = 1; t < e; t++) {
|
|
1496
|
-
let e = Math.max(p[t - 1] + 1, Math.ceil(d[t] - 1 -
|
|
1504
|
+
let e = Math.max(p[t - 1] + 1, Math.ceil(d[t] - 1 - qe));
|
|
1497
1505
|
if (e > m[t]) throw new z("Сетка не представима положительными twips без превышения допуска округления.");
|
|
1498
1506
|
p[t] = Math.max(e, Math.min(m[t], p[t]));
|
|
1499
1507
|
}
|
|
@@ -1512,7 +1520,7 @@ function Ze(e, t, n, r) {
|
|
|
1512
1520
|
}
|
|
1513
1521
|
//#endregion
|
|
1514
1522
|
//#region src/library/hujjat/html-to-docx.ts
|
|
1515
|
-
var
|
|
1523
|
+
var $e = /^(font-|color$|text-align$|text-indent$|text-transform$|line-height$|letter-spacing$|white-space$|text-decoration$|vertical-align$)/, et = new Set("p div h1 h2 h3 h4 h5 h6 ul ol li table hr".split(" ")), tt = {
|
|
1516
1524
|
black: "000000",
|
|
1517
1525
|
white: "FFFFFF",
|
|
1518
1526
|
red: "FF0000",
|
|
@@ -1531,14 +1539,14 @@ var Qe = /^(font-|color$|text-align$|text-indent$|text-transform$|line-height$|l
|
|
|
1531
1539
|
teal: "008080",
|
|
1532
1540
|
aqua: "00FFFF"
|
|
1533
1541
|
};
|
|
1534
|
-
function
|
|
1542
|
+
function nt(e) {
|
|
1535
1543
|
if (!e) return;
|
|
1536
1544
|
if (/^#[\da-f]{6}$/i.test(e)) return e.slice(1);
|
|
1537
1545
|
if (/^#[\da-f]{3}$/i.test(e)) return e.slice(1).split("").map((e) => e + e).join("");
|
|
1538
1546
|
let t = e.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
|
|
1539
|
-
return t ? t.slice(1).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("") :
|
|
1547
|
+
return t ? t.slice(1).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("") : tt[e.toLowerCase()];
|
|
1540
1548
|
}
|
|
1541
|
-
function
|
|
1549
|
+
function rt(e) {
|
|
1542
1550
|
if (e === "0") return 0;
|
|
1543
1551
|
let t = e?.match(/^(-?\d*\.?\d+)(pt|px|in|cm|mm|pc)$/i);
|
|
1544
1552
|
return t ? Number(t[1]) * {
|
|
@@ -1551,9 +1559,9 @@ function nt(e) {
|
|
|
1551
1559
|
}[t[2].toLowerCase()] : void 0;
|
|
1552
1560
|
}
|
|
1553
1561
|
var Z = (e) => {
|
|
1554
|
-
let t =
|
|
1562
|
+
let t = rt(e);
|
|
1555
1563
|
return t === void 0 ? void 0 : Math.round(t * 20);
|
|
1556
|
-
},
|
|
1564
|
+
}, it = (e, t) => (Z(e[`margin-${t}`]) ?? 0) + Math.max(0, Z(e[`padding-${t}`]) ?? 0);
|
|
1557
1565
|
function Q(e, t) {
|
|
1558
1566
|
let n = { ...t }, r = e.style;
|
|
1559
1567
|
for (let e of Array.from(r)) n[e] = r.getPropertyValue(e).trim();
|
|
@@ -1582,8 +1590,8 @@ function Q(e, t) {
|
|
|
1582
1590
|
h3: "12pt"
|
|
1583
1591
|
}[i] ?? "12pt"), r.fontWeight || (n["font-weight"] = "bold")), n;
|
|
1584
1592
|
}
|
|
1585
|
-
var
|
|
1586
|
-
async function
|
|
1593
|
+
var at = (e) => Object.fromEntries(Object.entries(e).filter(([e]) => $e.test(e)));
|
|
1594
|
+
async function ot(e, t, n = R(), r) {
|
|
1587
1595
|
let i = {
|
|
1588
1596
|
width: ne(n.page),
|
|
1589
1597
|
cell: !1
|
|
@@ -1630,7 +1638,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1630
1638
|
h.push(r);
|
|
1631
1639
|
return;
|
|
1632
1640
|
}
|
|
1633
|
-
let i = r && (
|
|
1641
|
+
let i = r && (et.has(r.localName) || [
|
|
1634
1642
|
"br",
|
|
1635
1643
|
"td",
|
|
1636
1644
|
"th",
|
|
@@ -1649,8 +1657,8 @@ async function at(e, t, n = R(), r) {
|
|
|
1649
1657
|
};
|
|
1650
1658
|
r?.line_height !== void 0 && (v["line-height"] = String(r.line_height));
|
|
1651
1659
|
function y(e) {
|
|
1652
|
-
let t = `<w:rFonts w:ascii="${Se(e["font-family"] || "freeserif")}" w:hAnsi="${Se(e["font-family"] || "freeserif")}"/>`, n =
|
|
1653
|
-
return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`),
|
|
1660
|
+
let t = `<w:rFonts w:ascii="${Se(e["font-family"] || "freeserif")}" w:hAnsi="${Se(e["font-family"] || "freeserif")}"/>`, n = rt(e["font-size"]);
|
|
1661
|
+
return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`), nt(e.color) && (t += `<w:color w:val="${nt(e.color)}"/>`), nt(e["background-color"]) && (t += `<w:shd w:fill="${nt(e["background-color"])}"/>`), ["super", "sub"].includes(e["vertical-align"]) && (t += `<w:vertAlign w:val="${e["vertical-align"] === "super" ? "superscript" : "subscript"}"/>`), e["text-transform"] === "uppercase" && (t += "<w:caps/>"), Z(e["letter-spacing"]) !== void 0 && (t += `<w:spacing w:val="${Z(e["letter-spacing"])}"/>`), t;
|
|
1654
1662
|
}
|
|
1655
1663
|
function x(e, t) {
|
|
1656
1664
|
let n = "";
|
|
@@ -1668,7 +1676,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1668
1676
|
}, l.set(e, a);
|
|
1669
1677
|
}
|
|
1670
1678
|
let o = u.get(d) ?? /* @__PURE__ */ new Set();
|
|
1671
|
-
o.add(e), u.set(d, o), n +=
|
|
1679
|
+
o.add(e), u.set(d, o), n += Ge(++f, `rIdImage${a.id}`, i.width, i.height, Array.from(r.getAttribute("alt") ?? "").slice(0, 500).join(""));
|
|
1672
1680
|
} else n += x(r.childNodes, Q(r, t));
|
|
1673
1681
|
}
|
|
1674
1682
|
return n;
|
|
@@ -1690,10 +1698,10 @@ async function at(e, t, n = R(), r) {
|
|
|
1690
1698
|
before: e,
|
|
1691
1699
|
after: r ? e : 1
|
|
1692
1700
|
}), f = ` w:line="${Math.round(Math.max(+!r, e) * 240)}" w:lineRule="auto"`;
|
|
1693
|
-
} else if (
|
|
1701
|
+
} else if (rt(p) !== void 0) {
|
|
1694
1702
|
let e = [], i = (t) => e.push({
|
|
1695
1703
|
...t,
|
|
1696
|
-
"font-size": `${Math.round((
|
|
1704
|
+
"font-size": `${Math.round((rt(t["font-size"]) ?? 12) * 2) / 2}pt`
|
|
1697
1705
|
}), a = (e, t) => {
|
|
1698
1706
|
for (let n of e) if (n.nodeType === 3 && n.textContent) i(t);
|
|
1699
1707
|
else if (n instanceof Element) {
|
|
@@ -1753,11 +1761,11 @@ async function at(e, t, n = R(), r) {
|
|
|
1753
1761
|
dotted: "dotted",
|
|
1754
1762
|
double: "double",
|
|
1755
1763
|
none: "nil"
|
|
1756
|
-
}[r] ?? "single"}" w:sz="${Math.max(0, Math.round((
|
|
1764
|
+
}[r] ?? "single"}" w:sz="${Math.max(0, Math.round((rt(i) ?? .75) * 8))}" w:color="${nt(a) ?? "000000"}"/>`;
|
|
1757
1765
|
}
|
|
1758
1766
|
function w(e, n, r) {
|
|
1759
1767
|
let i = Array.from(e.querySelectorAll("tr")).filter((t) => t.closest("table") === e), a = /* @__PURE__ */ new Map(), o = 1, s = [], c = n.width?.endsWith("%") ? parseFloat(n.width) : void 0, l = (r.left ?? 0) + (Z(n["margin-left"]) ?? 0), u = (r.right ?? 0) + (Z(n["margin-right"]) ?? 0), d = Math.max(1, r.width - l - u), f = Math.max(1, Math.round(Z(n.width) ?? (c === void 0 ? d : d * c / 100))), m = (e) => {
|
|
1760
|
-
let t =
|
|
1768
|
+
let t = rt(e);
|
|
1761
1769
|
return t === void 0 ? e?.endsWith("%") ? parseFloat(e) * f / 100 : void 0 : t * 20;
|
|
1762
1770
|
};
|
|
1763
1771
|
(r.before || r.after || Z(n["margin-top"]) || Z(n["margin-bottom"])) && B(t, "table-margin-approximation", "Вертикальные отступы контейнера вокруг таблицы требуют проверки.");
|
|
@@ -1783,7 +1791,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1783
1791
|
let u = [], d = o.parentElement;
|
|
1784
1792
|
for (; d && d !== e;) u.unshift(d), d = d.parentElement;
|
|
1785
1793
|
let f = (e) => ({
|
|
1786
|
-
...
|
|
1794
|
+
...at(e),
|
|
1787
1795
|
...e["background-color"] ? { "background-color": e["background-color"] } : {}
|
|
1788
1796
|
}), g = Q(o, f(u.reduce((e, t) => Q(t, f(e)), n)));
|
|
1789
1797
|
o.localName === "th" && (g["font-weight"] = "bold");
|
|
@@ -1835,7 +1843,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1835
1843
|
}
|
|
1836
1844
|
}
|
|
1837
1845
|
if (_ > o) throw new z("Число явных колонок превышает логическую сетку ячеек.");
|
|
1838
|
-
let v =
|
|
1846
|
+
let v = Qe(o, f, s, t), y = "<w:p><w:pPr><w:spacing w:before=\"0\" w:after=\"0\"/></w:pPr></w:p>", b = !0, x = g.map((e, n) => {
|
|
1839
1847
|
let r = i[n], a = Q(r, {}), o = Z(a.height), s = o !== void 0 && o >= 0 ? `<w:trHeight w:val="${o}" w:hRule="atLeast"/>` : "";
|
|
1840
1848
|
["avoid", "auto"].includes(a["page-break-inside"]) && (s += `<w:cantSplit w:val="${a["page-break-inside"] === "avoid" ? "1" : "0"}"/>`);
|
|
1841
1849
|
let c = r.parentElement?.localName === "thead";
|
|
@@ -1845,7 +1853,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1845
1853
|
}), c || (b = !1), `<w:tr>${s ? `<w:trPr>${s}</w:trPr>` : ""}${e.map(({ element: e, column: t, span: n, rowSpan: r, css: i }) => {
|
|
1846
1854
|
let a = v.slice(t, t + n).reduce((e, t) => e + t, 0), o = `<w:tcW w:w="${a}" w:type="dxa"/>`;
|
|
1847
1855
|
if (n > 1 && (o += `<w:gridSpan w:val="${n}"/>`), r > 1 && (o += "<w:vMerge w:val=\"restart\"/>"), !e) return `<w:tc><w:tcPr>${o}${r === 0 ? "<w:vMerge/>" : ""}</w:tcPr>${y}</w:tc>`;
|
|
1848
|
-
let s =
|
|
1856
|
+
let s = nt(i["background-color"]);
|
|
1849
1857
|
s && (o += `<w:shd w:fill="${s}"/>`), [
|
|
1850
1858
|
"top",
|
|
1851
1859
|
"middle",
|
|
@@ -1860,7 +1868,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1860
1868
|
l && (o += `<w:tcBorders>${l}</w:tcBorders>`);
|
|
1861
1869
|
let u = c.map((e) => Z(i[`padding-${e}`]) === void 0 ? "" : `<w:${e} w:w="${Math.max(0, Z(i[`padding-${e}`]))}" w:type="dxa"/>`).join("");
|
|
1862
1870
|
u && (o += `<w:tcMar>${u}</w:tcMar>`);
|
|
1863
|
-
let d = Math.max(1, a - Math.max(0, Z(i["padding-left"]) ?? 0) - Math.max(0, Z(i["padding-right"]) ?? 0)), f = O(D(e.childNodes,
|
|
1871
|
+
let d = Math.max(1, a - Math.max(0, Z(i["padding-left"]) ?? 0) - Math.max(0, Z(i["padding-right"]) ?? 0)), f = O(D(e.childNodes, at(i), void 0, {
|
|
1864
1872
|
width: d,
|
|
1865
1873
|
cell: !0
|
|
1866
1874
|
}));
|
|
@@ -1904,12 +1912,12 @@ async function at(e, t, n = R(), r) {
|
|
|
1904
1912
|
u.length && l.push(...T([{ xml: S(u, n, a, m(d, e)) }], n)), u = [];
|
|
1905
1913
|
};
|
|
1906
1914
|
for (let [e, i] of f.entries()) {
|
|
1907
|
-
if (!(i instanceof Element) ||
|
|
1915
|
+
if (!(i instanceof Element) || !et.has(i.localName)) {
|
|
1908
1916
|
u.length || (d = e), u.push(i);
|
|
1909
1917
|
continue;
|
|
1910
1918
|
}
|
|
1911
1919
|
h(e - 1);
|
|
1912
|
-
let f = Q(i,
|
|
1920
|
+
let f = Q(i, at(n)), g = {
|
|
1913
1921
|
...m(e),
|
|
1914
1922
|
htmlPath: p.get(i)
|
|
1915
1923
|
};
|
|
@@ -1928,20 +1936,20 @@ async function at(e, t, n = R(), r) {
|
|
|
1928
1936
|
let a = {
|
|
1929
1937
|
id: e,
|
|
1930
1938
|
pending: !0
|
|
1931
|
-
}, o = Q(i,
|
|
1939
|
+
}, o = Q(i, at(f)), s = {
|
|
1932
1940
|
...g,
|
|
1933
1941
|
before: Math.max(t === 0 ? g.before ?? 0 : 0, Z(o["margin-top"]) ?? 0),
|
|
1934
1942
|
after: Math.max(t === n.length - 1 ? g.after ?? 0 : 0, Z(o["margin-bottom"]) ?? 0),
|
|
1935
|
-
left: (g.left ?? 0) +
|
|
1936
|
-
right: (g.right ?? 0) +
|
|
1943
|
+
left: (g.left ?? 0) + it(f, "left") + it(o, "left"),
|
|
1944
|
+
right: (g.right ?? 0) + it(f, "right") + it(o, "right")
|
|
1937
1945
|
}, c = Object.fromEntries(Object.entries(o).filter(([e]) => !/^(margin|padding)(-|$)/.test(e))), l = D(i.childNodes, c, a, s);
|
|
1938
1946
|
r.push(...T(E(l.length ? l : [{ xml: S([], c, a, s) }], o, p.get(i)), o));
|
|
1939
1947
|
}
|
|
1940
1948
|
l.push(...T(E(r, f, g.htmlPath), f));
|
|
1941
|
-
} else i.localName === "div" && Array.from(i.children).some((e) =>
|
|
1949
|
+
} else i.localName === "div" && Array.from(i.children).some((e) => et.has(e.localName)) ? l.push(...T(E(D(i.childNodes, at(f), a, {
|
|
1942
1950
|
...g,
|
|
1943
|
-
left: (g.left ?? 0) +
|
|
1944
|
-
right: (g.right ?? 0) +
|
|
1951
|
+
left: (g.left ?? 0) + it(f, "left"),
|
|
1952
|
+
right: (g.right ?? 0) + it(f, "right"),
|
|
1945
1953
|
before: Math.max(g.before ?? 0, Z(f["margin-top"]) ?? 0),
|
|
1946
1954
|
after: Math.max(g.after ?? 0, Z(f["margin-bottom"]) ?? 0)
|
|
1947
1955
|
}), f, g.htmlPath), f)) : i.localName === "div" && !i.children.length && !i.textContent && f["page-break-before"] === "always" && Array.from(i.style).every((e) => ["page-break-before", "break-before"].includes(e)) ? l.push({
|
|
@@ -1983,7 +1991,7 @@ async function at(e, t, n = R(), r) {
|
|
|
1983
1991
|
before: r,
|
|
1984
1992
|
after: "baseline"
|
|
1985
1993
|
});
|
|
1986
|
-
let a =
|
|
1994
|
+
let a = et.has(n.localName) && !["table", "hr"].includes(n.localName), o = e.startsWith("padding") && !i && (!a || !["padding-left", "padding-right"].includes(e)) || e.startsWith("border") && !i && n.localName !== "table" || e === "font-size" && rt(r) === void 0 || ["color", "background-color"].includes(e) && nt(r) === void 0, s = (n.localName === "tr" || n.localName === "img") && e === "height" && Z(r) !== void 0 && Z(r) >= 0;
|
|
1987
1995
|
(o || !s && !j.has(e) && !/^border-(top|right|bottom|left)-(width|style|color)$/.test(e)) && B(t, "html-style-approximation", `Стиль ${e} может измениться при открытии HTML в DOCX-редакторе.`, "warning", {
|
|
1988
1996
|
stage: "import",
|
|
1989
1997
|
location: { htmlPath: p.get(n) },
|
|
@@ -2015,18 +2023,18 @@ async function at(e, t, n = R(), r) {
|
|
|
2015
2023
|
}
|
|
2016
2024
|
//#endregion
|
|
2017
2025
|
//#region src/library/hujjat/docx.ts
|
|
2018
|
-
async function
|
|
2026
|
+
async function st(e, t) {
|
|
2019
2027
|
let n = t.page === void 0 ? t.locales?.[t.locale]?.page : t.page;
|
|
2020
2028
|
Fe(n);
|
|
2021
|
-
let r = await
|
|
2029
|
+
let r = await Ke(e, t.layout, n), i = xe(t.locales ?? {}, t.locale, r.html);
|
|
2022
2030
|
return i.warnings.unshift(...r.warnings), i.layout = r.layout, i.page = Ie(r.page, i), i.page !== void 0 && (i.locales[t.locale].page = structuredClone(i.page)), se(i.warnings, t.allowLossy), i;
|
|
2023
2031
|
}
|
|
2024
|
-
async function
|
|
2032
|
+
async function ct(e, t, n = {}) {
|
|
2025
2033
|
let r = ve(be(e, t));
|
|
2026
2034
|
r.page = Ie(e[t]?.page, r);
|
|
2027
2035
|
let i = Le(r.page, n.layout);
|
|
2028
2036
|
re(i.page, Le(r.page).page) || B(r.warnings, "layout-not-carried-by-html", "Геометрия layout отличается от настроек page на сервере. Текущий PDF-контракт поддерживает только ориентацию A4 и фиксированные поля.", "warning", { stage: "import" });
|
|
2029
|
-
let a = await
|
|
2037
|
+
let a = await ot(r.html, r.warnings, i, r.page);
|
|
2030
2038
|
return se(r.warnings, n.allowLossy), {
|
|
2031
2039
|
...r,
|
|
2032
2040
|
document: a,
|
|
@@ -2035,7 +2043,7 @@ async function st(e, t, n = {}) {
|
|
|
2035
2043
|
}
|
|
2036
2044
|
//#endregion
|
|
2037
2045
|
//#region src/library/document-diagnostics.ts
|
|
2038
|
-
async function
|
|
2046
|
+
async function lt(e) {
|
|
2039
2047
|
if (e.byteLength > 31457280) throw new z("DOCX превышает 30 МиБ.");
|
|
2040
2048
|
let t = await b.loadAsync(e);
|
|
2041
2049
|
if (Object.keys(t.files).length > 2e3) throw new z("В DOCX более 2000 частей.");
|
|
@@ -2092,7 +2100,7 @@ async function ct(e) {
|
|
|
2092
2100
|
}
|
|
2093
2101
|
//#endregion
|
|
2094
2102
|
//#region src/library/font-diagnostics.ts
|
|
2095
|
-
function
|
|
2103
|
+
function ut(e) {
|
|
2096
2104
|
let t = 0, n = !1, r = !1, i = 0, a = [], o = /* @__PURE__ */ new Set(), s = {
|
|
2097
2105
|
state: typeof e == "function" ? "loading" : "unknown",
|
|
2098
2106
|
warnings: []
|
|
@@ -2147,17 +2155,17 @@ function lt(e) {
|
|
|
2147
2155
|
}
|
|
2148
2156
|
//#endregion
|
|
2149
2157
|
//#region src/library/EditorMount.tsx
|
|
2150
|
-
var
|
|
2151
|
-
function
|
|
2152
|
-
let t =
|
|
2158
|
+
var dt = /* @__PURE__ */ new WeakMap(), ft = e(() => {});
|
|
2159
|
+
function pt(e) {
|
|
2160
|
+
let t = dt.get(e);
|
|
2153
2161
|
return t || (t = {
|
|
2154
2162
|
count: 0,
|
|
2155
2163
|
overflow: e.body.style.overflow
|
|
2156
|
-
},
|
|
2157
|
-
--t.count === 0 && (e.body.style.overflow = t.overflow,
|
|
2164
|
+
}, dt.set(e, t), e.body.style.overflow = "hidden"), ++t.count, () => {
|
|
2165
|
+
--t.count === 0 && (e.body.style.overflow = t.overflow, dt.delete(e));
|
|
2158
2166
|
};
|
|
2159
2167
|
}
|
|
2160
|
-
function
|
|
2168
|
+
function mt({ expanded: e, onCollapse: t, retainSelection: r, className: i, style: a, children: s }) {
|
|
2161
2169
|
let u = c(null), d = c(t), f = c(r), p = c(null), m = n(() => {
|
|
2162
2170
|
p.current?.(), p.current = null;
|
|
2163
2171
|
}, []);
|
|
@@ -2213,7 +2221,7 @@ function pt({ expanded: e, onCollapse: t, retainSelection: r, className: i, styl
|
|
|
2213
2221
|
]) t.removeEventListener(e, g, !0);
|
|
2214
2222
|
};
|
|
2215
2223
|
if (!e) return _;
|
|
2216
|
-
let v =
|
|
2224
|
+
let v = pt(t), y = (e) => {
|
|
2217
2225
|
e.key !== "Escape" || e.defaultPrevented || t.querySelectorAll("[data-az-fullscreen=\"true\"]").item(t.querySelectorAll("[data-az-fullscreen=\"true\"]").length - 1) === h && (Array.from(t.querySelectorAll("[role=\"dialog\"], [role=\"menu\"], [role=\"listbox\"], [data-az-print-root]")).some((e) => !n.includes(e) && e.getClientRects().length && getComputedStyle(e).visibility !== "hidden") || (e.preventDefault(), e.stopImmediatePropagation(), d.current()));
|
|
2218
2226
|
};
|
|
2219
2227
|
return t.addEventListener("keydown", y, !0), () => {
|
|
@@ -2227,7 +2235,7 @@ function pt({ expanded: e, onCollapse: t, retainSelection: r, className: i, styl
|
|
|
2227
2235
|
ref: u,
|
|
2228
2236
|
className: ["az-document-editor", i].filter(Boolean).join(" "),
|
|
2229
2237
|
style: a,
|
|
2230
|
-
children: h && S(/* @__PURE__ */ w(
|
|
2238
|
+
children: h && S(/* @__PURE__ */ w(ft, {
|
|
2231
2239
|
value: m,
|
|
2232
2240
|
children: s
|
|
2233
2241
|
}), h)
|
|
@@ -2235,20 +2243,20 @@ function pt({ expanded: e, onCollapse: t, retainSelection: r, className: i, styl
|
|
|
2235
2243
|
}
|
|
2236
2244
|
//#endregion
|
|
2237
2245
|
//#region src/library/image-insertion.ts
|
|
2238
|
-
var
|
|
2239
|
-
function
|
|
2246
|
+
var ht = 10485760, gt = 2048;
|
|
2247
|
+
function _t(e, t) {
|
|
2240
2248
|
if (!e || !t || e > 4096 || t > 4096 || e * t > 16777216) throw Error("Слишком большое изображение. Максимум — 4096 пикселей по стороне и 16 мегапикселей.");
|
|
2241
2249
|
}
|
|
2242
|
-
function
|
|
2250
|
+
function vt(e, t) {
|
|
2243
2251
|
return new Promise((n, r) => e.toBlob((e) => e ? n(e) : r(/* @__PURE__ */ Error("Не удалось подготовить изображение.")), t, .86));
|
|
2244
2252
|
}
|
|
2245
|
-
async function
|
|
2246
|
-
if (e.size >
|
|
2253
|
+
async function yt(e, t) {
|
|
2254
|
+
if (e.size > ht) throw Error("Файл слишком большой. Выберите PNG или JPEG размером до 10 МБ.");
|
|
2247
2255
|
t.throwIfAborted();
|
|
2248
2256
|
let n = new Uint8Array(await e.arrayBuffer());
|
|
2249
2257
|
t.throwIfAborted();
|
|
2250
2258
|
let r = P(n);
|
|
2251
|
-
|
|
2259
|
+
_t(r.width, r.height);
|
|
2252
2260
|
let i;
|
|
2253
2261
|
try {
|
|
2254
2262
|
i = await createImageBitmap(new Blob([n], { type: r.mime }), { imageOrientation: "from-image" });
|
|
@@ -2256,14 +2264,14 @@ async function vt(e, t) {
|
|
|
2256
2264
|
throw Error("Не удалось прочитать изображение. Выберите исправный PNG или JPEG.");
|
|
2257
2265
|
}
|
|
2258
2266
|
try {
|
|
2259
|
-
t.throwIfAborted(),
|
|
2260
|
-
let n = document.createElement("canvas"), a = Math.min(1,
|
|
2267
|
+
t.throwIfAborted(), _t(i.width, i.height);
|
|
2268
|
+
let n = document.createElement("canvas"), a = Math.min(1, gt / Math.max(i.width, i.height));
|
|
2261
2269
|
for (let o = 0; o < 18; o++) {
|
|
2262
2270
|
t.throwIfAborted(), n.width = Math.max(1, Math.round(i.width * a)), n.height = Math.max(1, Math.round(i.height * a));
|
|
2263
2271
|
let o = n.getContext("2d");
|
|
2264
2272
|
if (!o) throw Error("Браузер не поддерживает подготовку изображений.");
|
|
2265
2273
|
o.drawImage(i, 0, 0, n.width, n.height);
|
|
2266
|
-
let s = await
|
|
2274
|
+
let s = await vt(n, r.mime);
|
|
2267
2275
|
if (t.throwIfAborted(), s.size <= 262144) {
|
|
2268
2276
|
let n = new Uint8Array(await s.arrayBuffer());
|
|
2269
2277
|
t.throwIfAborted();
|
|
@@ -2285,10 +2293,10 @@ async function vt(e, t) {
|
|
|
2285
2293
|
}
|
|
2286
2294
|
//#endregion
|
|
2287
2295
|
//#region src/library/ImageInsertControl.tsx
|
|
2288
|
-
function
|
|
2296
|
+
function bt(e, t) {
|
|
2289
2297
|
return e.anchor.paragraphId === t.anchor.paragraphId && e.anchor.offset === t.anchor.offset && e.head.paragraphId === t.head.paragraphId && e.head.offset === t.head.offset;
|
|
2290
2298
|
}
|
|
2291
|
-
function
|
|
2299
|
+
function xt({ disabled: e, documentKey: t }) {
|
|
2292
2300
|
let n = h(), r = _((e) => !e.editable || e.isLoading || !!e.isOpening || !!e.parseError), i = e || r, a = c(!1), s = c(null), u = c(null), [d, f] = l(!1), [p, m] = l("");
|
|
2293
2301
|
function v(e) {
|
|
2294
2302
|
e.controller.abort(), e.pin && e.editor.releaseSelection(e.pin), u.current === e && (u.current = null);
|
|
@@ -2307,11 +2315,11 @@ function bt({ disabled: e, documentKey: t }) {
|
|
|
2307
2315
|
e && !e.committing && (v(e), f(!1));
|
|
2308
2316
|
}), g("selectionChange", () => {
|
|
2309
2317
|
let e = u.current;
|
|
2310
|
-
e && e.editor.getDocumentHandle().revision === e.revision && !
|
|
2318
|
+
e && e.editor.getDocumentHandle().revision === e.revision && !bt(e.surface.state().selection, e.selection) && (v(e), f(!1));
|
|
2311
2319
|
});
|
|
2312
2320
|
function y(e) {
|
|
2313
2321
|
let t = e.editor.snapshot();
|
|
2314
|
-
return u.current === e && !e.controller.signal.aborted && a.current && e.editor.surface === e.surface && e.editor.mountGeneration === e.generation && e.editor.getDocumentHandle().revision === e.revision &&
|
|
2322
|
+
return u.current === e && !e.controller.signal.aborted && a.current && e.editor.surface === e.surface && e.editor.mountGeneration === e.generation && e.editor.getDocumentHandle().revision === e.revision && bt(e.surface.state().selection, e.selection) && t.editable && t.selectionCollapsed && !t.isLoading && !t.isOpening && !t.parseError;
|
|
2315
2323
|
}
|
|
2316
2324
|
function b() {
|
|
2317
2325
|
n?.surface && a.current && !d && (u.current && v(u.current), n.snapshot().selectionCollapsed ? (m(""), u.current = {
|
|
@@ -2334,7 +2342,7 @@ function bt({ disabled: e, documentKey: t }) {
|
|
|
2334
2342
|
else {
|
|
2335
2343
|
f(!0);
|
|
2336
2344
|
try {
|
|
2337
|
-
let e = await
|
|
2345
|
+
let e = await yt(t, n.controller.signal);
|
|
2338
2346
|
if (u.current !== n || !a.current) return;
|
|
2339
2347
|
if (!y(n)) throw Error("Документ или позиция курсора изменились. Выберите изображение ещё раз.");
|
|
2340
2348
|
n.editor.focus();
|
|
@@ -2425,8 +2433,8 @@ function bt({ disabled: e, documentKey: t }) {
|
|
|
2425
2433
|
}
|
|
2426
2434
|
//#endregion
|
|
2427
2435
|
//#region src/library/EditorFrame.tsx
|
|
2428
|
-
function
|
|
2429
|
-
let t = h(), n = _((e) => e.zoom), i = r(
|
|
2436
|
+
function St({ forwardedRef: e }) {
|
|
2437
|
+
let t = h(), n = _((e) => e.zoom), i = r(ft);
|
|
2430
2438
|
return o(i, [n, i]), a(e, () => ({
|
|
2431
2439
|
load: (e) => {
|
|
2432
2440
|
t?.load(e);
|
|
@@ -2445,7 +2453,7 @@ function xt({ forwardedRef: e }) {
|
|
|
2445
2453
|
snapshot: (e) => t?.snapshot(e) ?? f
|
|
2446
2454
|
}), [t]), null;
|
|
2447
2455
|
}
|
|
2448
|
-
function
|
|
2456
|
+
function Ct({ forwardedRef: e, ...t }) {
|
|
2449
2457
|
let n = m(), [r, a] = l(() => typeof matchMedia < "u" && matchMedia("(prefers-color-scheme: dark)").matches);
|
|
2450
2458
|
i(() => {
|
|
2451
2459
|
if (t.colorMode !== "system") return;
|
|
@@ -2472,7 +2480,7 @@ function St({ forwardedRef: e, ...t }) {
|
|
|
2472
2480
|
onChange: t.onChange,
|
|
2473
2481
|
onFontError: t.onFontError,
|
|
2474
2482
|
popups: f,
|
|
2475
|
-
children: [/* @__PURE__ */ w(
|
|
2483
|
+
children: [/* @__PURE__ */ w(St, { forwardedRef: e }), /* @__PURE__ */ T("div", {
|
|
2476
2484
|
className: [
|
|
2477
2485
|
"docx-editor",
|
|
2478
2486
|
"az-editor-frame",
|
|
@@ -2501,7 +2509,7 @@ function St({ forwardedRef: e, ...t }) {
|
|
|
2501
2509
|
className: "az-editor-toolbar-row",
|
|
2502
2510
|
children: [
|
|
2503
2511
|
/* @__PURE__ */ w(d.Toolbar, { t: n }),
|
|
2504
|
-
/* @__PURE__ */ w(
|
|
2512
|
+
/* @__PURE__ */ w(xt, {
|
|
2505
2513
|
disabled: t.imagesDisabled || t.mode === "view",
|
|
2506
2514
|
documentKey: t.document
|
|
2507
2515
|
}),
|
|
@@ -2546,16 +2554,16 @@ function St({ forwardedRef: e, ...t }) {
|
|
|
2546
2554
|
})]
|
|
2547
2555
|
});
|
|
2548
2556
|
}
|
|
2549
|
-
var
|
|
2557
|
+
var wt = t(function(e, t) {
|
|
2550
2558
|
return /* @__PURE__ */ w(p, {
|
|
2551
2559
|
i18n: e.i18n,
|
|
2552
|
-
children: /* @__PURE__ */ w(
|
|
2560
|
+
children: /* @__PURE__ */ w(Ct, {
|
|
2553
2561
|
...e,
|
|
2554
2562
|
forwardedRef: t
|
|
2555
2563
|
})
|
|
2556
2564
|
});
|
|
2557
|
-
}),
|
|
2558
|
-
function
|
|
2565
|
+
}), Tt = () => {};
|
|
2566
|
+
function Et({ onStatusChange: e, fonts: t }) {
|
|
2559
2567
|
let n = c(e);
|
|
2560
2568
|
o(() => {
|
|
2561
2569
|
n.current = e;
|
|
@@ -2591,10 +2599,10 @@ function Tt({ onStatusChange: e, fonts: t }) {
|
|
|
2591
2599
|
d
|
|
2592
2600
|
]), null;
|
|
2593
2601
|
}
|
|
2594
|
-
var
|
|
2602
|
+
var Dt = t(function(e, t) {
|
|
2595
2603
|
let n = c(null), r = c(null), f = c(null), [p, m] = l(""), [h, g] = l(!1), _ = e.fullscreen ?? h, b = (t) => {
|
|
2596
2604
|
e.fullscreen === void 0 && g(t), e.onFullscreenChange?.(t);
|
|
2597
|
-
}, x = s(() => y(), []), S = v(x), E = e.fonts ?? S, O = s(() =>
|
|
2605
|
+
}, x = s(() => y(), []), S = v(x), E = e.fonts ?? S, O = s(() => ut(E), [E]), k = u(O.subscribe, O.snapshot, O.snapshot), A = c(e), N = c(0), P = c(!1), ee = c(O);
|
|
2598
2606
|
o(() => {
|
|
2599
2607
|
A.current = e, ee.current = O;
|
|
2600
2608
|
}), o(() => {
|
|
@@ -2604,7 +2612,7 @@ var Et = t(function(e, t) {
|
|
|
2604
2612
|
if (!A.current.onDiagnostics) return;
|
|
2605
2613
|
let n;
|
|
2606
2614
|
try {
|
|
2607
|
-
n = await
|
|
2615
|
+
n = await lt(e);
|
|
2608
2616
|
} catch {
|
|
2609
2617
|
n = [{
|
|
2610
2618
|
code: "diagnostics-unavailable",
|
|
@@ -2675,7 +2683,7 @@ var Et = t(function(e, t) {
|
|
|
2675
2683
|
async exportHujjat(e) {
|
|
2676
2684
|
let t = await n.current?.save();
|
|
2677
2685
|
if (!t) throw new z("Документ ещё не готов к экспорту.");
|
|
2678
|
-
return
|
|
2686
|
+
return st(t, e);
|
|
2679
2687
|
},
|
|
2680
2688
|
insertVariable(e) {
|
|
2681
2689
|
if (!ce(e)) throw new z("Некорректный ключ переменной. Используйте client.name, ASCII, до 100 символов.");
|
|
@@ -2711,7 +2719,7 @@ var Et = t(function(e, t) {
|
|
|
2711
2719
|
n.current?.focus();
|
|
2712
2720
|
},
|
|
2713
2721
|
print: L
|
|
2714
|
-
})), /* @__PURE__ */ w(
|
|
2722
|
+
})), /* @__PURE__ */ w(mt, {
|
|
2715
2723
|
className: e.className,
|
|
2716
2724
|
style: e.style,
|
|
2717
2725
|
expanded: _,
|
|
@@ -2729,7 +2737,7 @@ var Et = t(function(e, t) {
|
|
|
2729
2737
|
role: "alert",
|
|
2730
2738
|
className: "az-print-error",
|
|
2731
2739
|
children: p
|
|
2732
|
-
}), /* @__PURE__ */ w(
|
|
2740
|
+
}), /* @__PURE__ */ w(wt, {
|
|
2733
2741
|
imagesDisabled: e.actionsDisabled || k.state === "loading",
|
|
2734
2742
|
ref: n,
|
|
2735
2743
|
document: e.document ?? "blank",
|
|
@@ -2778,8 +2786,8 @@ var Et = t(function(e, t) {
|
|
|
2778
2786
|
},
|
|
2779
2787
|
menu: F("menu") && {
|
|
2780
2788
|
reportIssue: !1,
|
|
2781
|
-
onOpen:
|
|
2782
|
-
onSave:
|
|
2789
|
+
onOpen: Tt,
|
|
2790
|
+
onSave: Tt,
|
|
2783
2791
|
children: /* @__PURE__ */ T(d.Menu.File, {
|
|
2784
2792
|
preset: !1,
|
|
2785
2793
|
children: [
|
|
@@ -2815,7 +2823,7 @@ var Et = t(function(e, t) {
|
|
|
2815
2823
|
]
|
|
2816
2824
|
})
|
|
2817
2825
|
},
|
|
2818
|
-
children: /* @__PURE__ */ w(
|
|
2826
|
+
children: /* @__PURE__ */ w(Et, {
|
|
2819
2827
|
onStatusChange: e.onStatusChange,
|
|
2820
2828
|
fonts: k
|
|
2821
2829
|
})
|
|
@@ -2825,12 +2833,12 @@ var Et = t(function(e, t) {
|
|
|
2825
2833
|
});
|
|
2826
2834
|
//#endregion
|
|
2827
2835
|
//#region src/library/AzHtmlEditor.tsx
|
|
2828
|
-
function
|
|
2836
|
+
function Ot(...e) {
|
|
2829
2837
|
let t = /* @__PURE__ */ new Map();
|
|
2830
2838
|
for (let n of e.flat()) t.set(JSON.stringify(n), n);
|
|
2831
2839
|
return [...t.values()];
|
|
2832
2840
|
}
|
|
2833
|
-
var
|
|
2841
|
+
var kt = t(function(e, t) {
|
|
2834
2842
|
let { initialHtml: r, layout: s, page: u, onChange: d, onStatusChange: f, renderFallback: p, ...m } = e, [h] = l(r), [g] = l(() => structuredClone(u)), [_] = l(() => s ? {
|
|
2835
2843
|
...s,
|
|
2836
2844
|
page: s.page ? {
|
|
@@ -2859,7 +2867,7 @@ var Ot = t(function(e, t) {
|
|
|
2859
2867
|
error: null
|
|
2860
2868
|
});
|
|
2861
2869
|
try {
|
|
2862
|
-
let n = await
|
|
2870
|
+
let n = await ct({ uz: {
|
|
2863
2871
|
blocks: [{
|
|
2864
2872
|
type: "html",
|
|
2865
2873
|
props: { html: h.trim() ? h : "<p><br></p>" }
|
|
@@ -2927,7 +2935,7 @@ var Ot = t(function(e, t) {
|
|
|
2927
2935
|
page: t.page
|
|
2928
2936
|
});
|
|
2929
2937
|
if (!D.current || r !== O.current || i !== k.current) throw new z("Черновик изменился или закрыт во время экспорта. Повторите экспорт актуального документа.");
|
|
2930
|
-
let a =
|
|
2938
|
+
let a = Ot(t.warnings, n.warnings);
|
|
2931
2939
|
return j({ warnings: a }), se(a, e.allowLossy), {
|
|
2932
2940
|
html: n.html,
|
|
2933
2941
|
variables: n.variables,
|
|
@@ -2962,7 +2970,7 @@ var Ot = t(function(e, t) {
|
|
|
2962
2970
|
M,
|
|
2963
2971
|
j,
|
|
2964
2972
|
ee
|
|
2965
|
-
]), v ? /* @__PURE__ */ w(
|
|
2973
|
+
]), v ? /* @__PURE__ */ w(Dt, {
|
|
2966
2974
|
...m,
|
|
2967
2975
|
ref: C,
|
|
2968
2976
|
document: v,
|
|
@@ -2983,18 +2991,18 @@ var Ot = t(function(e, t) {
|
|
|
2983
2991
|
children: [b.error ?? "Загрузка документа…", b.warnings.length > 0 && /* @__PURE__ */ w("ul", { children: b.warnings.map((e, t) => /* @__PURE__ */ w("li", { children: e.message }, t)) })]
|
|
2984
2992
|
})
|
|
2985
2993
|
});
|
|
2986
|
-
}),
|
|
2987
|
-
function
|
|
2994
|
+
}), At = 31457280, jt = "application/vnd.openxmlformats-officedocument.wordprocessingml.document", Mt = `${jt}.main+xml`, Nt = 8388608, $ = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
2995
|
+
function Pt(e) {
|
|
2988
2996
|
let t = new DOMParser().parseFromString(e, "application/xml");
|
|
2989
2997
|
if (t.getElementsByTagName("parsererror").length || /<!DOCTYPE/i.test(e)) throw Error("XML документа повреждён или содержит неподдерживаемую структуру.");
|
|
2990
2998
|
return t;
|
|
2991
2999
|
}
|
|
2992
|
-
function
|
|
3000
|
+
function Ft(e, t) {
|
|
2993
3001
|
let n = e.file(t);
|
|
2994
3002
|
return n ? new Promise((e, t) => {
|
|
2995
3003
|
let r = n.internalStream("uint8array"), i = [], a = 0;
|
|
2996
3004
|
r.on("data", (e) => {
|
|
2997
|
-
a += e.byteLength, a >
|
|
3005
|
+
a += e.byteLength, a > Nt ? (r.pause(), t(/* @__PURE__ */ Error("Структура документа слишком большая для этого прототипа."))) : i.push(e);
|
|
2998
3006
|
}), r.on("error", t), r.on("end", () => {
|
|
2999
3007
|
let t = new Uint8Array(a), n = 0;
|
|
3000
3008
|
for (let e of i) t.set(e, n), n += e.byteLength;
|
|
@@ -3002,7 +3010,7 @@ function Pt(e, t) {
|
|
|
3002
3010
|
}), r.resume();
|
|
3003
3011
|
}) : Promise.resolve("");
|
|
3004
3012
|
}
|
|
3005
|
-
async function
|
|
3013
|
+
async function It(e) {
|
|
3006
3014
|
if (!/\.docx$/i.test(e.name)) throw Error("Откройте файл DOCX. Форматы DOC, DOCM и PDF здесь не поддерживаются.");
|
|
3007
3015
|
if (!e.size) throw Error("Файл DOCX пуст.");
|
|
3008
3016
|
if (e.size > 31457280) throw Error("Максимальный размер DOCX — 30 МБ.");
|
|
@@ -3015,14 +3023,14 @@ async function Ft(e) {
|
|
|
3015
3023
|
let r = Object.keys(n.files);
|
|
3016
3024
|
if (r.length > 2e3) throw Error("Слишком много вложенных частей в DOCX для этого прототипа.");
|
|
3017
3025
|
if (!n.file("[Content_Types].xml") || !n.file("word/document.xml")) throw Error("Файл не содержит структуру DOCX.");
|
|
3018
|
-
let i =
|
|
3019
|
-
if (Array.from(i.getElementsByTagNameNS("*", "Override")).find((e) => e.getAttribute("PartName") === "/word/document.xml")?.getAttribute("ContentType") !==
|
|
3020
|
-
let a =
|
|
3026
|
+
let i = Pt(await Ft(n, "[Content_Types].xml"));
|
|
3027
|
+
if (Array.from(i.getElementsByTagNameNS("*", "Override")).find((e) => e.getAttribute("PartName") === "/word/document.xml")?.getAttribute("ContentType") !== Mt || r.some((e) => /vbaProject\.bin$/i.test(e))) throw Error("Поддерживается только обычный DOCX без макросов.");
|
|
3028
|
+
let a = Pt(await Ft(n, "word/document.xml"));
|
|
3021
3029
|
if (a.documentElement.localName !== "document" || !a.getElementsByTagNameNS($, "body").length) throw Error("XML документа повреждён или использует неподдерживаемую разновидность DOCX.");
|
|
3022
3030
|
let o = /* @__PURE__ */ new Set(), s = [a];
|
|
3023
3031
|
for (let e of ["word/styles.xml", "word/fontTable.xml"]) {
|
|
3024
|
-
let t = await
|
|
3025
|
-
t && s.push(
|
|
3032
|
+
let t = await Ft(n, e);
|
|
3033
|
+
t && s.push(Pt(t));
|
|
3026
3034
|
}
|
|
3027
3035
|
for (let e of s) {
|
|
3028
3036
|
for (let t of e.getElementsByTagNameNS($, "rFonts")) for (let e of [
|
|
@@ -3039,7 +3047,7 @@ async function Ft(e) {
|
|
|
3039
3047
|
e && o.add(e);
|
|
3040
3048
|
}
|
|
3041
3049
|
}
|
|
3042
|
-
let c = await
|
|
3050
|
+
let c = await Ft(n, "docProps/app.xml"), l = c ? Number(Pt(c).getElementsByTagNameNS("*", "Pages")[0]?.textContent) : 0, { openDocumentForExport: u } = await import("@docx-editor.dev/core/export"), d = u(t.slice());
|
|
3043
3051
|
if (!d.ok) throw Error("Не удалось открыть структуру DOCX. Текущий документ сохранён в редакторе.");
|
|
3044
3052
|
return d.session.dispose(), {
|
|
3045
3053
|
name: e.name,
|
|
@@ -3056,16 +3064,16 @@ async function Ft(e) {
|
|
|
3056
3064
|
}
|
|
3057
3065
|
};
|
|
3058
3066
|
}
|
|
3059
|
-
function
|
|
3067
|
+
function Lt(e) {
|
|
3060
3068
|
return `${(e.replace(/\.docx$/i, "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim() || "Документ").replace(/ — редакция$/, "")} — редакция.docx`;
|
|
3061
3069
|
}
|
|
3062
|
-
function
|
|
3063
|
-
let n = URL.createObjectURL(new Blob([e], { type:
|
|
3070
|
+
function Rt(e, t) {
|
|
3071
|
+
let n = URL.createObjectURL(new Blob([e], { type: jt })), r = document.createElement("a");
|
|
3064
3072
|
r.href = n, r.download = t, document.body.append(r), r.click(), r.remove(), window.setTimeout(() => URL.revokeObjectURL(n), 3e4);
|
|
3065
3073
|
}
|
|
3066
3074
|
//#endregion
|
|
3067
3075
|
//#region src/library/pdf-export.ts
|
|
3068
|
-
async function
|
|
3076
|
+
async function zt(e, t, n, r = {}) {
|
|
3069
3077
|
let i = AbortSignal.any([AbortSignal.timeout(95e3), ...r.signal ? [r.signal] : []]);
|
|
3070
3078
|
i.throwIfAborted();
|
|
3071
3079
|
let a = new FormData();
|
|
@@ -3094,13 +3102,13 @@ async function Rt(e, t, n, r = {}) {
|
|
|
3094
3102
|
warnings: (o.headers.get("x-pdf-warnings") ?? "").split(",").filter(Boolean)
|
|
3095
3103
|
};
|
|
3096
3104
|
}
|
|
3097
|
-
function
|
|
3105
|
+
function Bt(e) {
|
|
3098
3106
|
let t = URL.createObjectURL(e.blob), n = document.createElement("a");
|
|
3099
3107
|
n.href = t, n.download = e.filename, document.body.append(n), n.click(), n.remove(), setTimeout(() => URL.revokeObjectURL(t), 6e4);
|
|
3100
3108
|
}
|
|
3101
3109
|
//#endregion
|
|
3102
3110
|
//#region src/library/pdf-profile.ts
|
|
3103
|
-
var
|
|
3111
|
+
var Vt = {
|
|
3104
3112
|
id: "az-editor-pdf-a0c6eaaeb90716f0",
|
|
3105
3113
|
protocolVersion: 1,
|
|
3106
3114
|
core: "2.27.0",
|
|
@@ -3247,7 +3255,7 @@ var Bt = {
|
|
|
3247
3255
|
};
|
|
3248
3256
|
//#endregion
|
|
3249
3257
|
//#region src/library/hujjat/api.ts
|
|
3250
|
-
function
|
|
3258
|
+
function Ht(e) {
|
|
3251
3259
|
if (!e || !Object.keys(e).length) throw new z("Нет локалей шаблона.");
|
|
3252
3260
|
for (let [t, n] of Object.entries(e)) {
|
|
3253
3261
|
if (ye(t), Fe(n?.page), !n || !Array.isArray(n.blocks) || !n.blocks.length) throw new z(`Нет блоков для ${t}.`);
|
|
@@ -3257,8 +3265,8 @@ function Vt(e) {
|
|
|
3257
3265
|
}
|
|
3258
3266
|
}
|
|
3259
3267
|
}
|
|
3260
|
-
function
|
|
3261
|
-
if (
|
|
3268
|
+
function Ut(e, t) {
|
|
3269
|
+
if (Ht(t), !t.uz) throw new z("Для создания шаблона обязательна локаль uz.");
|
|
3262
3270
|
if (!e.productId || !e.name.trim() || e.name.length > 255) throw new z("Укажите продукт и название шаблона до 255 символов.");
|
|
3263
3271
|
return {
|
|
3264
3272
|
product_id: e.productId,
|
|
@@ -3267,9 +3275,9 @@ function Ht(e, t) {
|
|
|
3267
3275
|
locales: structuredClone(t)
|
|
3268
3276
|
};
|
|
3269
3277
|
}
|
|
3270
|
-
async function
|
|
3278
|
+
async function Wt(e) {
|
|
3271
3279
|
let t = AbortSignal.any([AbortSignal.timeout(95e3), ...e.signal ? [e.signal] : []]);
|
|
3272
|
-
t.throwIfAborted(),
|
|
3280
|
+
t.throwIfAborted(), Ht(e.locales);
|
|
3273
3281
|
let n = e.locale ?? "uz";
|
|
3274
3282
|
ye(n);
|
|
3275
3283
|
let r = new Headers(e.headers);
|
|
@@ -3299,4 +3307,4 @@ async function Ut(e) {
|
|
|
3299
3307
|
};
|
|
3300
3308
|
}
|
|
3301
3309
|
//#endregion
|
|
3302
|
-
export {
|
|
3310
|
+
export { Dt as AzDocumentEditor, kt as AzHtmlEditor, jt as DOCX_MIME, ie as HUJJAT_LOCALES, Pe as HUJJAT_MAX_CHROME_BYTES, ae as HUJJAT_MAX_HTML_BYTES, I as HUJJAT_PAGE, z as HujjatCompatibilityError, At as MAX_DOCX_BYTES, lt as analyzeDocxFormatting, Ut as createHujjatTemplatePayload, Rt as downloadDocx, Bt as downloadPdf, Lt as exportFilename, st as exportHujjatDocx, ct as importHujjatTemplate, Vt as pdfRenderProfile, It as readDocxFile, be as readHujjatHtml, Wt as requestHujjatPreview, zt as requestPdf, R as resolveHtmlLayout, ve as sanitizeHujjatHtml, Fe as validateHujjatPage, ce as validateHujjatVariable, xe as withHujjatLocale };
|
package/docs/inline-images.ru.md
CHANGED
|
@@ -16,4 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
DOCX хранит бинарные media parts и отдельные relationships для тела/колонтитула. Экспорт в HTML переносит те же байты и размеры; импорт восстанавливает inline drawing. Неподдерживаемые объекты дают явную диагностику потери. mPDF читает только проверенный встроенный ресурс этого контракта, без сетевого запроса.
|
|
18
18
|
|
|
19
|
+
Уже встроенное в Word изображение не нужно вставлять заново. Его физический размер берётся из `wp:extent` (12700 EMU = 1 pt), а не из разрешения PNG/JPEG. Явное отсутствие заливки/линии и остаточные `effectExtent` без фактического эффекта допустимы; обрезка, видимая рамка и тень по-прежнему требуют предварительного преобразования изображения. Исправление библиотеки доступно с `0.1.0-beta.13`; для серверного DOCX-импорта также необходимы соответствующие изменения Hujjat.
|
|
20
|
+
|
|
19
21
|
Для включения необходимы новая сборка библиотеки **и** изменения Hujjat: старый sanitizer удаляет `img`. Изменений схемы БД не требуется. Agrodox передаёт HTML существующим сохранением и предпросмотром PDF; опубликованную зависимость нужно обновить после выпуска новой версии библиотеки.
|
package/docs/integration.ru.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Интеграция Az Editor в React-приложение
|
|
2
2
|
|
|
3
|
-
Руководство описывает API `@makhmudov.kay/az-editor` версии `0.1.0-beta.
|
|
3
|
+
Руководство описывает API `@makhmudov.kay/az-editor` версии `0.1.0-beta.13`.
|
|
4
4
|
Поддержка серверного `page`, описанная ниже, добавлена в beta.5.
|
|
5
5
|
Совместимые исправления разрывов и строк таблиц добавлены в beta.6 и описаны ниже.
|
|
6
6
|
Исправление общей сетки таблиц и более строгая диагностика размеров добавлены в beta.7.
|
|
@@ -129,7 +129,7 @@ npm install @makhmudov.kay/az-editor@beta
|
|
|
129
129
|
Для фиксации опубликованной версии:
|
|
130
130
|
|
|
131
131
|
```sh
|
|
132
|
-
npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.
|
|
132
|
+
npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.13
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
Тег `beta` может указывать на более новую версию. Сохраняйте lockfile и проверяйте
|