pptx-viewer-mcp 2.3.0 → 2.4.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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +240 -202
- package/dist/index.mjs +240 -202
- package/dist/mcp/index.js +253 -204
- package/dist/mcp/index.mjs +253 -204
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +13 -2
- package/dist/schemas/index.mjs +13 -2
- package/package.json +2 -2
package/dist/mcp/index.js
CHANGED
|
@@ -154,7 +154,13 @@ var UpdateElementSchema = zod.z.object({
|
|
|
154
154
|
opacity: zod.z.number().min(0).max(1).optional(),
|
|
155
155
|
hidden: zod.z.boolean().optional(),
|
|
156
156
|
flipH: zod.z.boolean().optional(),
|
|
157
|
-
flipV: zod.z.boolean().optional()
|
|
157
|
+
flipV: zod.z.boolean().optional(),
|
|
158
|
+
altText: zod.z.string().optional().describe(
|
|
159
|
+
"Accessibility description (p:cNvPr/@descr) for image, picture, table, chart, smartArt, ole, media, text, shape and connector elements"
|
|
160
|
+
),
|
|
161
|
+
title: zod.z.string().optional().describe(
|
|
162
|
+
"Accessibility title (p:cNvPr/@title) for table, chart, smartArt, ole, media, text, shape and connector elements (not pictures)"
|
|
163
|
+
)
|
|
158
164
|
});
|
|
159
165
|
var RenameElementSchema = zod.z.object({
|
|
160
166
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
@@ -309,7 +315,12 @@ var UpdateElementStyleSchema = zod.z.object({
|
|
|
309
315
|
brightness: zod.z.number().optional(),
|
|
310
316
|
contrast: zod.z.number().optional(),
|
|
311
317
|
grayscale: zod.z.boolean().optional(),
|
|
312
|
-
altText: zod.z.string().optional()
|
|
318
|
+
altText: zod.z.string().optional().describe(
|
|
319
|
+
"Accessibility description (p:cNvPr/@descr) for image, picture, table, chart, smartArt, ole, media, text, shape and connector elements"
|
|
320
|
+
),
|
|
321
|
+
title: zod.z.string().optional().describe(
|
|
322
|
+
"Accessibility title (p:cNvPr/@title) for table, chart, smartArt, ole, media, text, shape and connector elements (not pictures)"
|
|
323
|
+
)
|
|
313
324
|
});
|
|
314
325
|
var FindTextSchema = zod.z.object({
|
|
315
326
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
@@ -1631,6 +1642,240 @@ async function convertToMarkdown(ctx, params) {
|
|
|
1631
1642
|
}
|
|
1632
1643
|
};
|
|
1633
1644
|
}
|
|
1645
|
+
var ALT_TEXT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["image", "picture", "table", "chart", "smartArt", "ole", "media", "text", "shape", "connector"]);
|
|
1646
|
+
var TITLE_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
1647
|
+
"table",
|
|
1648
|
+
"chart",
|
|
1649
|
+
"smartArt",
|
|
1650
|
+
"ole",
|
|
1651
|
+
"media",
|
|
1652
|
+
"text",
|
|
1653
|
+
"shape",
|
|
1654
|
+
"connector"
|
|
1655
|
+
]);
|
|
1656
|
+
function applyElementAltText(el, altText) {
|
|
1657
|
+
if (!ALT_TEXT_ELEMENT_TYPES.has(el.type)) {
|
|
1658
|
+
throw new Error(
|
|
1659
|
+
`Element '${el.id}' (${el.type}) does not support altText; only ${[...ALT_TEXT_ELEMENT_TYPES].join(", ")} elements do.`
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
el.altText = altText;
|
|
1663
|
+
}
|
|
1664
|
+
function applyElementTitle(el, title) {
|
|
1665
|
+
if (!TITLE_ELEMENT_TYPES.has(el.type)) {
|
|
1666
|
+
throw new Error(
|
|
1667
|
+
`Element '${el.id}' (${el.type}) does not support title; only ${[...TITLE_ELEMENT_TYPES].join(", ")} elements do.`
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
el.title = title;
|
|
1671
|
+
}
|
|
1672
|
+
function updateElementStyle(ctx, params) {
|
|
1673
|
+
const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
|
|
1674
|
+
if (err) {
|
|
1675
|
+
throw new Error(err);
|
|
1676
|
+
}
|
|
1677
|
+
const slide = ctx.pptxData.slides[params.slideIndex];
|
|
1678
|
+
const el = slide.elements.find((e) => e.id === params.elementId);
|
|
1679
|
+
if (!el) {
|
|
1680
|
+
throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
|
|
1681
|
+
}
|
|
1682
|
+
if ("shapeStyle" in el) {
|
|
1683
|
+
if (!el.shapeStyle) {
|
|
1684
|
+
el.shapeStyle = {};
|
|
1685
|
+
}
|
|
1686
|
+
const ss = el.shapeStyle;
|
|
1687
|
+
if (params.fillThemeColor !== void 0) {
|
|
1688
|
+
ss.fillColorRef = params.fillThemeColor;
|
|
1689
|
+
const resolved = pptxViewerCore.resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
|
|
1690
|
+
if (params.fillColor !== void 0) {
|
|
1691
|
+
ss.fillColor = params.fillColor;
|
|
1692
|
+
} else if (resolved) {
|
|
1693
|
+
ss.fillColor = resolved;
|
|
1694
|
+
}
|
|
1695
|
+
} else if (params.fillColor !== void 0) {
|
|
1696
|
+
ss.fillColor = params.fillColor;
|
|
1697
|
+
ss.fillColorRef = void 0;
|
|
1698
|
+
}
|
|
1699
|
+
if (params.fillMode !== void 0) {
|
|
1700
|
+
ss.fillMode = params.fillMode;
|
|
1701
|
+
}
|
|
1702
|
+
if (params.fillGradientStops !== void 0) {
|
|
1703
|
+
ss.fillGradientStops = params.fillGradientStops;
|
|
1704
|
+
}
|
|
1705
|
+
if (params.fillGradientAngle !== void 0) {
|
|
1706
|
+
ss.fillGradientAngle = params.fillGradientAngle;
|
|
1707
|
+
}
|
|
1708
|
+
if (params.fillGradientType !== void 0) {
|
|
1709
|
+
ss.fillGradientType = params.fillGradientType;
|
|
1710
|
+
}
|
|
1711
|
+
if (params.fillOpacity !== void 0) {
|
|
1712
|
+
ss.fillOpacity = params.fillOpacity;
|
|
1713
|
+
}
|
|
1714
|
+
if (params.strokeThemeColor !== void 0) {
|
|
1715
|
+
ss.strokeColorRef = params.strokeThemeColor;
|
|
1716
|
+
const resolved = pptxViewerCore.resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
|
|
1717
|
+
if (params.strokeColor !== void 0) {
|
|
1718
|
+
ss.strokeColor = params.strokeColor;
|
|
1719
|
+
} else if (resolved) {
|
|
1720
|
+
ss.strokeColor = resolved;
|
|
1721
|
+
}
|
|
1722
|
+
} else if (params.strokeColor !== void 0) {
|
|
1723
|
+
ss.strokeColor = params.strokeColor;
|
|
1724
|
+
ss.strokeColorRef = void 0;
|
|
1725
|
+
}
|
|
1726
|
+
if (params.strokeWidth !== void 0) {
|
|
1727
|
+
ss.strokeWidth = params.strokeWidth;
|
|
1728
|
+
}
|
|
1729
|
+
if (params.strokeDash !== void 0) {
|
|
1730
|
+
ss.strokeDash = params.strokeDash;
|
|
1731
|
+
}
|
|
1732
|
+
if (params.strokeOpacity !== void 0) {
|
|
1733
|
+
ss.strokeOpacity = params.strokeOpacity;
|
|
1734
|
+
}
|
|
1735
|
+
if (params.shadowColor !== void 0) {
|
|
1736
|
+
ss.shadowColor = params.shadowColor;
|
|
1737
|
+
}
|
|
1738
|
+
if (params.shadowBlur !== void 0) {
|
|
1739
|
+
ss.shadowBlur = params.shadowBlur;
|
|
1740
|
+
}
|
|
1741
|
+
if (params.shadowOffsetX !== void 0) {
|
|
1742
|
+
ss.shadowOffsetX = params.shadowOffsetX;
|
|
1743
|
+
}
|
|
1744
|
+
if (params.shadowOffsetY !== void 0) {
|
|
1745
|
+
ss.shadowOffsetY = params.shadowOffsetY;
|
|
1746
|
+
}
|
|
1747
|
+
if (params.shadowOpacity !== void 0) {
|
|
1748
|
+
ss.shadowOpacity = params.shadowOpacity;
|
|
1749
|
+
}
|
|
1750
|
+
if (params.glowColor !== void 0) {
|
|
1751
|
+
ss.glowColor = params.glowColor;
|
|
1752
|
+
}
|
|
1753
|
+
if (params.glowRadius !== void 0) {
|
|
1754
|
+
ss.glowRadius = params.glowRadius;
|
|
1755
|
+
}
|
|
1756
|
+
if (params.glowOpacity !== void 0) {
|
|
1757
|
+
ss.glowOpacity = params.glowOpacity;
|
|
1758
|
+
}
|
|
1759
|
+
if (params.softEdgeRadius !== void 0) {
|
|
1760
|
+
ss.softEdgeRadius = params.softEdgeRadius;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
if (params.altText !== void 0) {
|
|
1764
|
+
applyElementAltText(el, params.altText);
|
|
1765
|
+
}
|
|
1766
|
+
if (params.title !== void 0) {
|
|
1767
|
+
applyElementTitle(el, params.title);
|
|
1768
|
+
}
|
|
1769
|
+
if (el.type === "image" || el.type === "picture") {
|
|
1770
|
+
const img = el;
|
|
1771
|
+
if (params.cropLeft !== void 0) {
|
|
1772
|
+
img.cropLeft = params.cropLeft;
|
|
1773
|
+
}
|
|
1774
|
+
if (params.cropTop !== void 0) {
|
|
1775
|
+
img.cropTop = params.cropTop;
|
|
1776
|
+
}
|
|
1777
|
+
if (params.cropRight !== void 0) {
|
|
1778
|
+
img.cropRight = params.cropRight;
|
|
1779
|
+
}
|
|
1780
|
+
if (params.cropBottom !== void 0) {
|
|
1781
|
+
img.cropBottom = params.cropBottom;
|
|
1782
|
+
}
|
|
1783
|
+
if (params.brightness !== void 0 || params.contrast !== void 0 || params.grayscale !== void 0) {
|
|
1784
|
+
if (!img.imageEffects) {
|
|
1785
|
+
img.imageEffects = {};
|
|
1786
|
+
}
|
|
1787
|
+
if (params.brightness !== void 0) {
|
|
1788
|
+
img.imageEffects.brightness = params.brightness;
|
|
1789
|
+
}
|
|
1790
|
+
if (params.contrast !== void 0) {
|
|
1791
|
+
img.imageEffects.contrast = params.contrast;
|
|
1792
|
+
}
|
|
1793
|
+
if (params.grayscale !== void 0) {
|
|
1794
|
+
img.imageEffects.grayscale = params.grayscale;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
return {
|
|
1799
|
+
pptxData: ctx.pptxData,
|
|
1800
|
+
dirty: true,
|
|
1801
|
+
result: { elementId: params.elementId }
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
function runAccessibilityCheck(ctx) {
|
|
1805
|
+
const issues = [];
|
|
1806
|
+
for (let si = 0; si < ctx.pptxData.slides.length; si++) {
|
|
1807
|
+
const slide = ctx.pptxData.slides[si];
|
|
1808
|
+
let slideHasText = false;
|
|
1809
|
+
for (const el of slide.elements) {
|
|
1810
|
+
if (el.type === "image" || el.type === "picture") {
|
|
1811
|
+
const img = el;
|
|
1812
|
+
if (!img.altText) {
|
|
1813
|
+
issues.push({
|
|
1814
|
+
slideIndex: si,
|
|
1815
|
+
elementId: el.id,
|
|
1816
|
+
severity: "error",
|
|
1817
|
+
message: `Image element '${el.id}' has no alt text.`
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
if (pptxViewerCore.hasTextProperties(el)) {
|
|
1822
|
+
const textEl = el;
|
|
1823
|
+
slideHasText = true;
|
|
1824
|
+
if (!textEl.text || textEl.text.trim() === "") {
|
|
1825
|
+
issues.push({
|
|
1826
|
+
slideIndex: si,
|
|
1827
|
+
elementId: el.id,
|
|
1828
|
+
severity: "info",
|
|
1829
|
+
message: `Text element '${el.id}' is empty.`
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
const fs = textEl.textStyle?.fontSize;
|
|
1833
|
+
if (fs !== void 0 && fs < 10) {
|
|
1834
|
+
issues.push({
|
|
1835
|
+
slideIndex: si,
|
|
1836
|
+
elementId: el.id,
|
|
1837
|
+
severity: "warning",
|
|
1838
|
+
message: `Text element '${el.id}' has very small font size (${fs}pt < 10pt).`
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
const textColor = textEl.textStyle?.color?.toLowerCase();
|
|
1842
|
+
const bgColor = slide.backgroundColor?.toLowerCase();
|
|
1843
|
+
if (textColor && bgColor && textColor === bgColor) {
|
|
1844
|
+
issues.push({
|
|
1845
|
+
slideIndex: si,
|
|
1846
|
+
elementId: el.id,
|
|
1847
|
+
severity: "error",
|
|
1848
|
+
message: `Text element '${el.id}' has same color as slide background (${textColor}).`
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
if (!slideHasText) {
|
|
1854
|
+
issues.push({
|
|
1855
|
+
slideIndex: si,
|
|
1856
|
+
severity: "warning",
|
|
1857
|
+
message: `Slide ${si + 1} contains no text elements.`
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
const errorCount = issues.filter((i) => i.severity === "error").length;
|
|
1862
|
+
const warningCount = issues.filter((i) => i.severity === "warning").length;
|
|
1863
|
+
const infoCount = issues.filter((i) => i.severity === "info").length;
|
|
1864
|
+
return {
|
|
1865
|
+
pptxData: ctx.pptxData,
|
|
1866
|
+
dirty: false,
|
|
1867
|
+
result: {
|
|
1868
|
+
slideCount: ctx.pptxData.slides.length,
|
|
1869
|
+
totalIssues: issues.length,
|
|
1870
|
+
errorCount,
|
|
1871
|
+
warningCount,
|
|
1872
|
+
infoCount,
|
|
1873
|
+
issues
|
|
1874
|
+
}
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
// src/tools/element-tools.ts
|
|
1634
1879
|
function addElement(ctx, params) {
|
|
1635
1880
|
const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
|
|
1636
1881
|
if (err) {
|
|
@@ -1810,6 +2055,12 @@ function updateElement(ctx, params) {
|
|
|
1810
2055
|
if (params.flipV !== void 0) {
|
|
1811
2056
|
el.flipVertical = params.flipV;
|
|
1812
2057
|
}
|
|
2058
|
+
if (params.altText !== void 0) {
|
|
2059
|
+
applyElementAltText(el, params.altText);
|
|
2060
|
+
}
|
|
2061
|
+
if (params.title !== void 0) {
|
|
2062
|
+
applyElementTitle(el, params.title);
|
|
2063
|
+
}
|
|
1813
2064
|
if (pptxViewerCore.hasTextProperties(el)) {
|
|
1814
2065
|
const textEl = el;
|
|
1815
2066
|
if (params.text !== void 0) {
|
|
@@ -3064,208 +3315,6 @@ function manageSmartArt(ctx, params) {
|
|
|
3064
3315
|
throw new Error(`Unknown SmartArt action: ${String(params.action)}`);
|
|
3065
3316
|
}
|
|
3066
3317
|
}
|
|
3067
|
-
function updateElementStyle(ctx, params) {
|
|
3068
|
-
const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
|
|
3069
|
-
if (err) {
|
|
3070
|
-
throw new Error(err);
|
|
3071
|
-
}
|
|
3072
|
-
const slide = ctx.pptxData.slides[params.slideIndex];
|
|
3073
|
-
const el = slide.elements.find((e) => e.id === params.elementId);
|
|
3074
|
-
if (!el) {
|
|
3075
|
-
throw new Error(`Element '${params.elementId}' not found on slide ${params.slideIndex}.`);
|
|
3076
|
-
}
|
|
3077
|
-
if ("shapeStyle" in el) {
|
|
3078
|
-
if (!el.shapeStyle) {
|
|
3079
|
-
el.shapeStyle = {};
|
|
3080
|
-
}
|
|
3081
|
-
const ss = el.shapeStyle;
|
|
3082
|
-
if (params.fillThemeColor !== void 0) {
|
|
3083
|
-
ss.fillColorRef = params.fillThemeColor;
|
|
3084
|
-
const resolved = pptxViewerCore.resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
|
|
3085
|
-
if (params.fillColor !== void 0) {
|
|
3086
|
-
ss.fillColor = params.fillColor;
|
|
3087
|
-
} else if (resolved) {
|
|
3088
|
-
ss.fillColor = resolved;
|
|
3089
|
-
}
|
|
3090
|
-
} else if (params.fillColor !== void 0) {
|
|
3091
|
-
ss.fillColor = params.fillColor;
|
|
3092
|
-
ss.fillColorRef = void 0;
|
|
3093
|
-
}
|
|
3094
|
-
if (params.fillMode !== void 0) {
|
|
3095
|
-
ss.fillMode = params.fillMode;
|
|
3096
|
-
}
|
|
3097
|
-
if (params.fillGradientStops !== void 0) {
|
|
3098
|
-
ss.fillGradientStops = params.fillGradientStops;
|
|
3099
|
-
}
|
|
3100
|
-
if (params.fillGradientAngle !== void 0) {
|
|
3101
|
-
ss.fillGradientAngle = params.fillGradientAngle;
|
|
3102
|
-
}
|
|
3103
|
-
if (params.fillGradientType !== void 0) {
|
|
3104
|
-
ss.fillGradientType = params.fillGradientType;
|
|
3105
|
-
}
|
|
3106
|
-
if (params.fillOpacity !== void 0) {
|
|
3107
|
-
ss.fillOpacity = params.fillOpacity;
|
|
3108
|
-
}
|
|
3109
|
-
if (params.strokeThemeColor !== void 0) {
|
|
3110
|
-
ss.strokeColorRef = params.strokeThemeColor;
|
|
3111
|
-
const resolved = pptxViewerCore.resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
|
|
3112
|
-
if (params.strokeColor !== void 0) {
|
|
3113
|
-
ss.strokeColor = params.strokeColor;
|
|
3114
|
-
} else if (resolved) {
|
|
3115
|
-
ss.strokeColor = resolved;
|
|
3116
|
-
}
|
|
3117
|
-
} else if (params.strokeColor !== void 0) {
|
|
3118
|
-
ss.strokeColor = params.strokeColor;
|
|
3119
|
-
ss.strokeColorRef = void 0;
|
|
3120
|
-
}
|
|
3121
|
-
if (params.strokeWidth !== void 0) {
|
|
3122
|
-
ss.strokeWidth = params.strokeWidth;
|
|
3123
|
-
}
|
|
3124
|
-
if (params.strokeDash !== void 0) {
|
|
3125
|
-
ss.strokeDash = params.strokeDash;
|
|
3126
|
-
}
|
|
3127
|
-
if (params.strokeOpacity !== void 0) {
|
|
3128
|
-
ss.strokeOpacity = params.strokeOpacity;
|
|
3129
|
-
}
|
|
3130
|
-
if (params.shadowColor !== void 0) {
|
|
3131
|
-
ss.shadowColor = params.shadowColor;
|
|
3132
|
-
}
|
|
3133
|
-
if (params.shadowBlur !== void 0) {
|
|
3134
|
-
ss.shadowBlur = params.shadowBlur;
|
|
3135
|
-
}
|
|
3136
|
-
if (params.shadowOffsetX !== void 0) {
|
|
3137
|
-
ss.shadowOffsetX = params.shadowOffsetX;
|
|
3138
|
-
}
|
|
3139
|
-
if (params.shadowOffsetY !== void 0) {
|
|
3140
|
-
ss.shadowOffsetY = params.shadowOffsetY;
|
|
3141
|
-
}
|
|
3142
|
-
if (params.shadowOpacity !== void 0) {
|
|
3143
|
-
ss.shadowOpacity = params.shadowOpacity;
|
|
3144
|
-
}
|
|
3145
|
-
if (params.glowColor !== void 0) {
|
|
3146
|
-
ss.glowColor = params.glowColor;
|
|
3147
|
-
}
|
|
3148
|
-
if (params.glowRadius !== void 0) {
|
|
3149
|
-
ss.glowRadius = params.glowRadius;
|
|
3150
|
-
}
|
|
3151
|
-
if (params.glowOpacity !== void 0) {
|
|
3152
|
-
ss.glowOpacity = params.glowOpacity;
|
|
3153
|
-
}
|
|
3154
|
-
if (params.softEdgeRadius !== void 0) {
|
|
3155
|
-
ss.softEdgeRadius = params.softEdgeRadius;
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
|
-
if (el.type === "image" || el.type === "picture") {
|
|
3159
|
-
const img = el;
|
|
3160
|
-
if (params.altText !== void 0) {
|
|
3161
|
-
img.altText = params.altText;
|
|
3162
|
-
}
|
|
3163
|
-
if (params.cropLeft !== void 0) {
|
|
3164
|
-
img.cropLeft = params.cropLeft;
|
|
3165
|
-
}
|
|
3166
|
-
if (params.cropTop !== void 0) {
|
|
3167
|
-
img.cropTop = params.cropTop;
|
|
3168
|
-
}
|
|
3169
|
-
if (params.cropRight !== void 0) {
|
|
3170
|
-
img.cropRight = params.cropRight;
|
|
3171
|
-
}
|
|
3172
|
-
if (params.cropBottom !== void 0) {
|
|
3173
|
-
img.cropBottom = params.cropBottom;
|
|
3174
|
-
}
|
|
3175
|
-
if (params.brightness !== void 0 || params.contrast !== void 0 || params.grayscale !== void 0) {
|
|
3176
|
-
if (!img.imageEffects) {
|
|
3177
|
-
img.imageEffects = {};
|
|
3178
|
-
}
|
|
3179
|
-
if (params.brightness !== void 0) {
|
|
3180
|
-
img.imageEffects.brightness = params.brightness;
|
|
3181
|
-
}
|
|
3182
|
-
if (params.contrast !== void 0) {
|
|
3183
|
-
img.imageEffects.contrast = params.contrast;
|
|
3184
|
-
}
|
|
3185
|
-
if (params.grayscale !== void 0) {
|
|
3186
|
-
img.imageEffects.grayscale = params.grayscale;
|
|
3187
|
-
}
|
|
3188
|
-
}
|
|
3189
|
-
}
|
|
3190
|
-
return {
|
|
3191
|
-
pptxData: ctx.pptxData,
|
|
3192
|
-
dirty: true,
|
|
3193
|
-
result: { elementId: params.elementId }
|
|
3194
|
-
};
|
|
3195
|
-
}
|
|
3196
|
-
function runAccessibilityCheck(ctx) {
|
|
3197
|
-
const issues = [];
|
|
3198
|
-
for (let si = 0; si < ctx.pptxData.slides.length; si++) {
|
|
3199
|
-
const slide = ctx.pptxData.slides[si];
|
|
3200
|
-
let slideHasText = false;
|
|
3201
|
-
for (const el of slide.elements) {
|
|
3202
|
-
if (el.type === "image" || el.type === "picture") {
|
|
3203
|
-
const img = el;
|
|
3204
|
-
if (!img.altText) {
|
|
3205
|
-
issues.push({
|
|
3206
|
-
slideIndex: si,
|
|
3207
|
-
elementId: el.id,
|
|
3208
|
-
severity: "error",
|
|
3209
|
-
message: `Image element '${el.id}' has no alt text.`
|
|
3210
|
-
});
|
|
3211
|
-
}
|
|
3212
|
-
}
|
|
3213
|
-
if (pptxViewerCore.hasTextProperties(el)) {
|
|
3214
|
-
const textEl = el;
|
|
3215
|
-
slideHasText = true;
|
|
3216
|
-
if (!textEl.text || textEl.text.trim() === "") {
|
|
3217
|
-
issues.push({
|
|
3218
|
-
slideIndex: si,
|
|
3219
|
-
elementId: el.id,
|
|
3220
|
-
severity: "info",
|
|
3221
|
-
message: `Text element '${el.id}' is empty.`
|
|
3222
|
-
});
|
|
3223
|
-
}
|
|
3224
|
-
const fs = textEl.textStyle?.fontSize;
|
|
3225
|
-
if (fs !== void 0 && fs < 10) {
|
|
3226
|
-
issues.push({
|
|
3227
|
-
slideIndex: si,
|
|
3228
|
-
elementId: el.id,
|
|
3229
|
-
severity: "warning",
|
|
3230
|
-
message: `Text element '${el.id}' has very small font size (${fs}pt < 10pt).`
|
|
3231
|
-
});
|
|
3232
|
-
}
|
|
3233
|
-
const textColor = textEl.textStyle?.color?.toLowerCase();
|
|
3234
|
-
const bgColor = slide.backgroundColor?.toLowerCase();
|
|
3235
|
-
if (textColor && bgColor && textColor === bgColor) {
|
|
3236
|
-
issues.push({
|
|
3237
|
-
slideIndex: si,
|
|
3238
|
-
elementId: el.id,
|
|
3239
|
-
severity: "error",
|
|
3240
|
-
message: `Text element '${el.id}' has same color as slide background (${textColor}).`
|
|
3241
|
-
});
|
|
3242
|
-
}
|
|
3243
|
-
}
|
|
3244
|
-
}
|
|
3245
|
-
if (!slideHasText) {
|
|
3246
|
-
issues.push({
|
|
3247
|
-
slideIndex: si,
|
|
3248
|
-
severity: "warning",
|
|
3249
|
-
message: `Slide ${si + 1} contains no text elements.`
|
|
3250
|
-
});
|
|
3251
|
-
}
|
|
3252
|
-
}
|
|
3253
|
-
const errorCount = issues.filter((i) => i.severity === "error").length;
|
|
3254
|
-
const warningCount = issues.filter((i) => i.severity === "warning").length;
|
|
3255
|
-
const infoCount = issues.filter((i) => i.severity === "info").length;
|
|
3256
|
-
return {
|
|
3257
|
-
pptxData: ctx.pptxData,
|
|
3258
|
-
dirty: false,
|
|
3259
|
-
result: {
|
|
3260
|
-
slideCount: ctx.pptxData.slides.length,
|
|
3261
|
-
totalIssues: issues.length,
|
|
3262
|
-
errorCount,
|
|
3263
|
-
warningCount,
|
|
3264
|
-
infoCount,
|
|
3265
|
-
issues
|
|
3266
|
-
}
|
|
3267
|
-
};
|
|
3268
|
-
}
|
|
3269
3318
|
function findTableElement(ctx, slideIndex, elementId) {
|
|
3270
3319
|
const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
|
|
3271
3320
|
if (err) {
|