@a3s-lab/office 0.44.0 → 0.46.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/README.md +24 -0
- package/dist/{0~2330.js → 0~2133.js} +325 -19
- package/dist/{0~5024.js → 0~4042.js} +110 -2
- package/dist/0~document-editor.js +562 -9
- package/dist/0~work-docx-export.js +206 -8
- package/dist/0~work-docx-import.js +22 -7
- package/dist/0~work-office-diagnostics.js +19 -3
- package/dist/4174.js +508 -3
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +15 -1
- package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +4 -1
- package/dist/internal/features/work/editors/document-text-box-ribbon.d.ts +4 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +2 -1
- package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +1 -0
- package/dist/internal/features/work/work-document-image-layout.d.ts +14 -0
- package/dist/internal/features/work/work-document-text-box.d.ts +64 -0
- package/dist/internal/features/work/work-docx-export-image.d.ts +2 -1
- package/dist/internal/features/work/work-docx-image-layout-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-image-transform.d.ts +17 -0
- package/dist/internal/features/work/work-docx-import.d.ts +3 -1
- package/dist/internal/features/work/work-docx-text-box-export.d.ts +25 -0
- package/dist/internal/features/work/work-docx-text-box-import.d.ts +26 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +101 -2
- package/docs/latest/en/browser-editor-architecture.md +7 -3
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -309,6 +309,30 @@ and [CLI reference](./docs/latest/en/cli-reference.md).
|
|
|
309
309
|
|
|
310
310
|
## Current release
|
|
311
311
|
|
|
312
|
+
Version `0.46.0` adds native, bounded Writer text boxes without introducing a
|
|
313
|
+
second document model or a remote service:
|
|
314
|
+
|
|
315
|
+
- The Insert ribbon adds an editable **Text Box** block. Its contextual ribbon
|
|
316
|
+
controls inline/floating placement, millimeter geometry, relative offsets,
|
|
317
|
+
fill, outline, padding, and vertical alignment with one controlled update and
|
|
318
|
+
one Undo record per intent.
|
|
319
|
+
- Isolated WordprocessingML text boxes round-trip through native DOCX geometry,
|
|
320
|
+
body properties, and fill/outline state and share the same live, preview, and
|
|
321
|
+
PDF projection. Mixed or malformed drawings remain an explicit diagnostic
|
|
322
|
+
boundary instead of being silently flattened.
|
|
323
|
+
|
|
324
|
+
Version `0.45.0` adds bounded Writer picture transforms without introducing a
|
|
325
|
+
second document model or a remote service:
|
|
326
|
+
|
|
327
|
+
- The contextual **Picture** ribbon now exposes quarter-turn rotation plus
|
|
328
|
+
horizontal and vertical reflection with accessible Lucide icons. **Picture
|
|
329
|
+
Properties** keeps the same controls in a responsive dialog, and each
|
|
330
|
+
confirmed change is one undoable, controlled update.
|
|
331
|
+
- The transform is projected consistently into editing, preview, PDF capture,
|
|
332
|
+
and the native DOCX `a:xfrm` fields (`rot`, `flipH`, and `flipV`). Imported
|
|
333
|
+
90-degree/reflection values reopen as editable state, while arbitrary-angle
|
|
334
|
+
or malformed values produce a compatibility diagnostic and normalize safely.
|
|
335
|
+
|
|
312
336
|
Version `0.44.0` adds dependent local dropdowns to Spreadsheet Data Validation
|
|
313
337
|
without introducing a remote service:
|
|
314
338
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { documentRunBorderDomAttributes, normalizeDocumentRunBorder, normalizeDocumentParagraphBorder, serializeDocumentRunBorder, serializeDocumentRunShading, documentIndexEntryHtml, attribute as work_ooxml_package_attribute, documentScriptFontFallbackSlots, documentScriptFontsDomAttributes, documentHighlightFromDocxValue, serializeDocxThemeReference, directChildren as work_ooxml_package_directChildren, documentParagraphShadingDomAttributes, documentTableOfContentsHtml, documentParagraphBordersDomAttributes, normalizeDocumentScriptFontHint, normalizeDocumentScriptFonts, DOCUMENT_PARAGRAPH_BORDER_STYLES, normalizeDocumentParagraphBorders as work_document_paragraph_borders_normalizeDocumentParagraphBorders, DOCUMENT_PARAGRAPH_BORDER_EDGES, documentScriptFontFamily, normalizeDocumentThemeFont, normalizeDocumentParagraphId, documentHighlightDomAttributes, descendants, documentIndexHtml, documentHighlightCssColor, xmlNamespacePrefix, normalizeDocumentFontName, documentProofingDomAttributes, work_document_paragraph_shading_DOCUMENT_PARAGRAPH_SHADING_PATTERNS, directChild, documentScriptFontSegments, childPath, parseDocumentTableOfContentsInstruction, documentRunShadingDomAttributes } from "./6968.js";
|
|
2
|
-
import { docxThemeFont, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, parseDocumentIndexEntryInstruction, resolveDocxProofing, parseDocumentIndexInstruction, DOCX_WORD_2010_NAMESPACE, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, STRICT_WORDPROCESSING_NAMESPACE, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxOpenTypeFeatures, docxCharacterScalePercentFromProperties, resolveDocxEmphasisMark, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver as work_docx_theme_resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, parseDocxTwipsMeasure } from "./0~
|
|
3
|
-
import { normalizeDocumentEmphasisMark, normalizeDocumentPageBorders, documentCharacterPositionDomAttributes, DOCUMENT_PAGE_BORDER_EDGES, normalizeDocumentTabStops, documentTextCaseFromWordFlags, documentStrikeDomAttributes, serializeDocumentNumberingChange, numberingTypeFromFormat, normalizeDocumentUnderlineColor, documentAutoLineHeight,
|
|
2
|
+
import { docxThemeFont, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, parseDocumentIndexEntryInstruction, resolveDocxProofing, parseDocumentIndexInstruction, DOCX_WORD_2010_NAMESPACE, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, STRICT_WORDPROCESSING_NAMESPACE, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxOpenTypeFeatures, docxCharacterScalePercentFromProperties, resolveDocxEmphasisMark, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver as work_docx_theme_resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, parseDocxTwipsMeasure } from "./0~4042.js";
|
|
3
|
+
import { normalizeDocumentEmphasisMark, normalizeDocumentPageBorders, textBoxCss, documentCharacterPositionDomAttributes, DOCUMENT_PAGE_BORDER_EDGES, normalizeDocumentTabStops, documentTextCaseFromWordFlags, documentStrikeDomAttributes, serializeDocumentNumberingChange, numberingTypeFromFormat, normalizeDocumentUnderlineColor, documentAutoLineHeight, textBoxDomAttributes, documentCharacterScaleDomAttributes, documentKerningDomAttributes, serializeDocumentParagraphFormatting, normalizeDocumentPaperSource, documentEquationText, documentLegacyTextEffectsDomAttributes, documentLegacyTextEffectsConflict, documentCharacterSpacingDomAttributes, normalizeDocumentParagraphIndent, normalizeDocumentEquation, documentOpenTypeDomAttributes, normalizeDocumentTextBoxProperties, renderDocumentAutoLineHeight, documentUnderlineDomAttributes, MAX_DOCUMENT_NUMBERING_START, normalizeDocumentUnderlineStyle, applyDocumentTextCaseStyle, documentHiddenTextDomAttributes, importedDocumentCharacterFormatting, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, createDocumentEquationElement, normalizeDocumentPageGeometry, serializeDocumentTabStops, documentEmphasisMarkDomAttributes, normalizeDocumentPageMargins, documentWordLineHeightFactor } from "./4174.js";
|
|
4
4
|
function docxCaptionSequenceKind(instruction) {
|
|
5
5
|
const identifier = /^\s*SEQ\s+([^\s\\]+)/i.exec(instruction)?.[1]?.toLowerCase();
|
|
6
6
|
if (!identifier) return null;
|
|
@@ -4074,6 +4074,312 @@ function nextEquationMarker(state) {
|
|
|
4074
4074
|
return marker;
|
|
4075
4075
|
}
|
|
4076
4076
|
const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
4077
|
+
const work_docx_text_box_import_STRICT_WORD_NAMESPACE = 'http://purl.oclc.org/ooxml/wordprocessingml/main';
|
|
4078
|
+
const WORDPROCESSING_DRAWING_NAMESPACES = new Set([
|
|
4079
|
+
'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',
|
|
4080
|
+
'http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing'
|
|
4081
|
+
]);
|
|
4082
|
+
const DRAWING_NAMESPACES = new Set([
|
|
4083
|
+
'http://schemas.openxmlformats.org/drawingml/2006/main',
|
|
4084
|
+
'http://purl.oclc.org/ooxml/drawingml/main'
|
|
4085
|
+
]);
|
|
4086
|
+
const WORDPROCESSING_SHAPE_NAMESPACES = new Set([
|
|
4087
|
+
'http://schemas.microsoft.com/office/word/2010/wordprocessingShape'
|
|
4088
|
+
]);
|
|
4089
|
+
const work_docx_text_box_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
4090
|
+
const WORDPROCESSING_SHAPE_URI = 'http://schemas.microsoft.com/office/word/2010/wordprocessingShape';
|
|
4091
|
+
const EMUS_PER_MILLIMETER = 36000;
|
|
4092
|
+
const MAX_IMPORTED_TEXT_BOXES = 1024;
|
|
4093
|
+
const TEXT_BOX_MARKER_PATTERN = /__A3S_WORK_TEXT_BOX_\d+__/g;
|
|
4094
|
+
const TEXT_BOX_RUN_CONTENT_NAMES = new Set([
|
|
4095
|
+
'br',
|
|
4096
|
+
'cr',
|
|
4097
|
+
'noBreakHyphen',
|
|
4098
|
+
'softHyphen',
|
|
4099
|
+
'sym',
|
|
4100
|
+
'tab',
|
|
4101
|
+
't'
|
|
4102
|
+
]);
|
|
4103
|
+
function markDocxTextBoxes(document) {
|
|
4104
|
+
const textBoxes = [];
|
|
4105
|
+
const drawings = docxDrawings(document);
|
|
4106
|
+
let nextMarker = 1;
|
|
4107
|
+
for (const drawing of drawings){
|
|
4108
|
+
const shape = supportedTextBoxShape(drawing);
|
|
4109
|
+
if (!shape) continue;
|
|
4110
|
+
const paragraph = work_docx_text_box_import_closestAncestor(drawing, 'p');
|
|
4111
|
+
const run = work_docx_text_box_import_closestAncestor(drawing, 'r');
|
|
4112
|
+
if (!paragraph || !run || !isSoleDrawingParagraph(paragraph, run)) continue;
|
|
4113
|
+
if (textBoxes.length >= MAX_IMPORTED_TEXT_BOXES) throw new Error('Imported DOCX exceeds the text-box limit.');
|
|
4114
|
+
const marker = nextTextBoxMarker(document, nextMarker);
|
|
4115
|
+
nextMarker += 1;
|
|
4116
|
+
const properties = textBoxProperties(drawing, shape, textBoxes.length + 1);
|
|
4117
|
+
replaceParagraphWithTextBoxRuns(document, paragraph, shape.content, marker);
|
|
4118
|
+
textBoxes.push({
|
|
4119
|
+
marker,
|
|
4120
|
+
properties
|
|
4121
|
+
});
|
|
4122
|
+
}
|
|
4123
|
+
return {
|
|
4124
|
+
textBoxes
|
|
4125
|
+
};
|
|
4126
|
+
}
|
|
4127
|
+
function inspectDocxTextBoxes(document) {
|
|
4128
|
+
let supported = 0;
|
|
4129
|
+
let unsupported = 0;
|
|
4130
|
+
for (const drawing of docxDrawings(document)){
|
|
4131
|
+
if (!textBoxShapeCandidate(drawing)) continue;
|
|
4132
|
+
const shape = supportedTextBoxShape(drawing);
|
|
4133
|
+
if (!shape) {
|
|
4134
|
+
unsupported += 1;
|
|
4135
|
+
continue;
|
|
4136
|
+
}
|
|
4137
|
+
const paragraph = work_docx_text_box_import_closestAncestor(drawing, 'p');
|
|
4138
|
+
const run = work_docx_text_box_import_closestAncestor(drawing, 'r');
|
|
4139
|
+
if (paragraph && run && isSoleDrawingParagraph(paragraph, run)) supported += 1;
|
|
4140
|
+
else unsupported += 1;
|
|
4141
|
+
}
|
|
4142
|
+
return {
|
|
4143
|
+
supported,
|
|
4144
|
+
unsupported
|
|
4145
|
+
};
|
|
4146
|
+
}
|
|
4147
|
+
function applyImportedDocxTextBoxMarkers(document, markers) {
|
|
4148
|
+
if (!markers.textBoxes.length) return;
|
|
4149
|
+
const byMarker = new Map(markers.textBoxes.map((textBox)=>[
|
|
4150
|
+
textBox.marker,
|
|
4151
|
+
textBox
|
|
4152
|
+
]));
|
|
4153
|
+
const nodes = textNodes(document.body);
|
|
4154
|
+
for (const node of nodes){
|
|
4155
|
+
if (!node.data.includes('__A3S_WORK_TEXT_BOX_')) continue;
|
|
4156
|
+
const match = node.data.match(TEXT_BOX_MARKER_PATTERN)?.find((value)=>byMarker.has(value));
|
|
4157
|
+
if (!match) continue;
|
|
4158
|
+
const textBox = byMarker.get(match);
|
|
4159
|
+
if (!textBox) continue;
|
|
4160
|
+
node.data = node.data.replace(match, '');
|
|
4161
|
+
const block = closestHtmlBlock(node.parentElement);
|
|
4162
|
+
if (!block) continue;
|
|
4163
|
+
const wrapper = document.createElement('div');
|
|
4164
|
+
for (const attribute of Array.from(block.attributes))if (attribute.name.startsWith('data-office-') || attribute.name.startsWith('data-document-')) wrapper.setAttribute(attribute.name, attribute.value);
|
|
4165
|
+
for (const [name, value] of Object.entries(textBoxDomAttributes(textBox.properties)))if (void 0 !== value) wrapper.setAttribute(name, value);
|
|
4166
|
+
wrapper.className = 'work-document-text-box';
|
|
4167
|
+
wrapper.setAttribute('role', 'textbox');
|
|
4168
|
+
wrapper.setAttribute('aria-label', '文本框');
|
|
4169
|
+
wrapper.setAttribute('style', textBoxCss(textBox.properties));
|
|
4170
|
+
while(block.firstChild)wrapper.append(block.firstChild);
|
|
4171
|
+
block.replaceWith(wrapper);
|
|
4172
|
+
}
|
|
4173
|
+
document.body.normalize();
|
|
4174
|
+
}
|
|
4175
|
+
function hasImportedDocxTextBoxMarkers(markers) {
|
|
4176
|
+
return markers.textBoxes.length > 0;
|
|
4177
|
+
}
|
|
4178
|
+
function textBoxShapeCandidate(drawing) {
|
|
4179
|
+
if (!WORDPROCESSING_DRAWING_NAMESPACES.has(drawing.namespaceURI ?? '')) return null;
|
|
4180
|
+
const graphicData = descendants(drawing, 'graphicData').find((element)=>DRAWING_NAMESPACES.has(element.namespaceURI ?? '') && work_ooxml_package_attribute(element, 'uri') === WORDPROCESSING_SHAPE_URI);
|
|
4181
|
+
if (!graphicData) return null;
|
|
4182
|
+
const shape = directChild(graphicData, 'wsp');
|
|
4183
|
+
if (!shape || !WORDPROCESSING_SHAPE_NAMESPACES.has(shape.namespaceURI ?? '')) return null;
|
|
4184
|
+
const nonVisual = directChild(shape, 'cNvSpPr');
|
|
4185
|
+
if (nonVisual && !WORDPROCESSING_SHAPE_NAMESPACES.has(nonVisual.namespaceURI ?? '')) return null;
|
|
4186
|
+
const txBox = work_ooxml_package_attribute(nonVisual ?? shape, 'txBox')?.trim().toLowerCase();
|
|
4187
|
+
if ('1' !== txBox && 'true' !== txBox) return null;
|
|
4188
|
+
return shape;
|
|
4189
|
+
}
|
|
4190
|
+
function supportedTextBoxShape(drawing) {
|
|
4191
|
+
const shape = textBoxShapeCandidate(drawing);
|
|
4192
|
+
if (!shape) return null;
|
|
4193
|
+
const txbx = directChild(shape, 'txbx');
|
|
4194
|
+
if (txbx && !WORDPROCESSING_SHAPE_NAMESPACES.has(txbx.namespaceURI ?? '')) return null;
|
|
4195
|
+
const content = txbx ? directChild(txbx, 'txbxContent') : void 0;
|
|
4196
|
+
return content && isWordElement(content, 'txbxContent') && isSupportedTextBoxContent(content) ? {
|
|
4197
|
+
shape,
|
|
4198
|
+
content
|
|
4199
|
+
} : null;
|
|
4200
|
+
}
|
|
4201
|
+
function isSupportedTextBoxContent(content) {
|
|
4202
|
+
const paragraphs = work_ooxml_package_directChildren(content);
|
|
4203
|
+
if (!paragraphs.length) return false;
|
|
4204
|
+
for (const paragraph of paragraphs){
|
|
4205
|
+
if (!isWordElement(paragraph, 'p')) return false;
|
|
4206
|
+
const children = work_ooxml_package_directChildren(paragraph).filter((element)=>'pPr' !== element.localName);
|
|
4207
|
+
for (const child of children){
|
|
4208
|
+
if (!isWordElement(child, 'r')) return false;
|
|
4209
|
+
const runChildren = work_ooxml_package_directChildren(child).filter((element)=>'rPr' !== element.localName);
|
|
4210
|
+
if (runChildren.some((element)=>!isWordNamespace(element) || !TEXT_BOX_RUN_CONTENT_NAMES.has(element.localName))) return false;
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
return true;
|
|
4214
|
+
}
|
|
4215
|
+
function isWordElement(element, localName) {
|
|
4216
|
+
return element.localName === localName && isWordNamespace(element);
|
|
4217
|
+
}
|
|
4218
|
+
function isWordNamespace(element) {
|
|
4219
|
+
return element.namespaceURI === WORD_NAMESPACE || element.namespaceURI === work_docx_text_box_import_STRICT_WORD_NAMESPACE;
|
|
4220
|
+
}
|
|
4221
|
+
function docxDrawings(document) {
|
|
4222
|
+
return [
|
|
4223
|
+
...descendants(document, 'anchor'),
|
|
4224
|
+
...descendants(document, 'inline')
|
|
4225
|
+
].filter((element)=>WORDPROCESSING_DRAWING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
4226
|
+
}
|
|
4227
|
+
function isSoleDrawingParagraph(paragraph, run) {
|
|
4228
|
+
const meaningful = work_ooxml_package_directChildren(paragraph).filter((element)=>'pPr' !== element.localName);
|
|
4229
|
+
if (1 !== meaningful.length || meaningful[0] !== run) return false;
|
|
4230
|
+
const runContent = work_ooxml_package_directChildren(run).filter((element)=>'rPr' !== element.localName);
|
|
4231
|
+
return 1 === runContent.length && runContent[0]?.localName === 'drawing';
|
|
4232
|
+
}
|
|
4233
|
+
function replaceParagraphWithTextBoxRuns(document, paragraph, content, marker) {
|
|
4234
|
+
const namespace = paragraph.namespaceURI || WORD_NAMESPACE;
|
|
4235
|
+
const prefix = paragraph.prefix ? `${paragraph.prefix}:` : 'w:';
|
|
4236
|
+
const paragraphProperties = directChild(paragraph, 'pPr');
|
|
4237
|
+
const runs = [];
|
|
4238
|
+
const sourceParagraphs = work_ooxml_package_directChildren(content, 'p');
|
|
4239
|
+
for (const [paragraphIndex, sourceParagraph] of sourceParagraphs.entries()){
|
|
4240
|
+
if (paragraphIndex > 0) runs.push(createBreakRun(document, namespace, prefix));
|
|
4241
|
+
const sourceRuns = work_ooxml_package_directChildren(sourceParagraph, 'r');
|
|
4242
|
+
for (const sourceRun of sourceRuns)runs.push(document.importNode(sourceRun, true));
|
|
4243
|
+
}
|
|
4244
|
+
const markerRun = createTextRun(document, namespace, prefix, marker);
|
|
4245
|
+
paragraph.replaceChildren(...paragraphProperties ? [
|
|
4246
|
+
paragraphProperties
|
|
4247
|
+
] : [], markerRun, ...runs);
|
|
4248
|
+
}
|
|
4249
|
+
function createTextRun(document, namespace, prefix, textValue) {
|
|
4250
|
+
const run = document.createElementNS(namespace, `${prefix}r`);
|
|
4251
|
+
const text = document.createElementNS(namespace, `${prefix}t`);
|
|
4252
|
+
text.setAttributeNS(work_docx_text_box_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
4253
|
+
text.textContent = textValue;
|
|
4254
|
+
run.append(text);
|
|
4255
|
+
return run;
|
|
4256
|
+
}
|
|
4257
|
+
function createBreakRun(document, namespace, prefix) {
|
|
4258
|
+
const run = document.createElementNS(namespace, `${prefix}r`);
|
|
4259
|
+
run.append(document.createElementNS(namespace, `${prefix}br`));
|
|
4260
|
+
return run;
|
|
4261
|
+
}
|
|
4262
|
+
function textBoxProperties(drawing, shape, index) {
|
|
4263
|
+
const extent = directChild(drawing, 'extent');
|
|
4264
|
+
const shapeProperties = directChild(shape.shape, 'spPr');
|
|
4265
|
+
const transform = shapeProperties ? directChild(shapeProperties, 'xfrm') : void 0;
|
|
4266
|
+
const extension = directChild(transform ?? shapeProperties ?? shape.shape, 'ext');
|
|
4267
|
+
const width = emuMillimeters(work_ooxml_package_attribute(extent ?? extension ?? shape.shape, 'cx') ?? work_ooxml_package_attribute(extent ?? extension ?? shape.shape, 'x'), 120);
|
|
4268
|
+
const height = emuMillimeters(work_ooxml_package_attribute(extent ?? extension ?? shape.shape, 'cy') ?? work_ooxml_package_attribute(extent ?? extension ?? shape.shape, 'y'), 45);
|
|
4269
|
+
const docProperties = directChild(drawing, 'docPr');
|
|
4270
|
+
const docPropertiesId = integerAttribute(docProperties, 'id');
|
|
4271
|
+
const sourceName = attributeOptional(docProperties, 'name')?.trim() ?? '';
|
|
4272
|
+
const id = sourceName.startsWith('A3S Text Box ') ? sourceName.slice(13).trim() : null === docPropertiesId ? `docx-text-box-${index}` : `docx-text-box-${docPropertiesId}`;
|
|
4273
|
+
const bodyProperties = directChild(shape.shape, 'bodyPr');
|
|
4274
|
+
const horizontal = directChild(drawing, 'positionH');
|
|
4275
|
+
const vertical = directChild(drawing, 'positionV');
|
|
4276
|
+
const layout = 'anchor' === drawing.localName ? 'floating' : 'inline';
|
|
4277
|
+
const fill = shapeFill(shapeProperties);
|
|
4278
|
+
const border = shapeBorder(shapeProperties);
|
|
4279
|
+
return normalizeDocumentTextBoxProperties({
|
|
4280
|
+
id,
|
|
4281
|
+
width,
|
|
4282
|
+
height,
|
|
4283
|
+
layout,
|
|
4284
|
+
horizontalOffset: positionOffset(horizontal),
|
|
4285
|
+
verticalOffset: positionOffset(vertical),
|
|
4286
|
+
horizontalReference: positionReference(horizontal, 'column'),
|
|
4287
|
+
verticalReference: positionReference(vertical, 'paragraph'),
|
|
4288
|
+
fill,
|
|
4289
|
+
borderColor: border.color,
|
|
4290
|
+
borderWidth: border.width,
|
|
4291
|
+
padding: bodyPadding(bodyProperties),
|
|
4292
|
+
verticalAlign: bodyVerticalAlign(bodyProperties),
|
|
4293
|
+
docPropertiesId
|
|
4294
|
+
});
|
|
4295
|
+
}
|
|
4296
|
+
function shapeFill(shapeProperties) {
|
|
4297
|
+
if (!shapeProperties || directChild(shapeProperties, 'noFill')) return 'transparent';
|
|
4298
|
+
const fill = directChild(shapeProperties, 'solidFill');
|
|
4299
|
+
const rgb = fill ? directChild(fill, 'srgbClr') : void 0;
|
|
4300
|
+
const value = attributeOptional(rgb, 'val')?.trim();
|
|
4301
|
+
return value && /^[0-9a-f]{6}$/i.test(value) ? `#${value}` : 'transparent';
|
|
4302
|
+
}
|
|
4303
|
+
function shapeBorder(shapeProperties) {
|
|
4304
|
+
const line = shapeProperties ? directChild(shapeProperties, 'ln') : void 0;
|
|
4305
|
+
if (!line || directChild(line, 'noFill')) return {
|
|
4306
|
+
color: 'none',
|
|
4307
|
+
width: 0
|
|
4308
|
+
};
|
|
4309
|
+
const fill = directChild(line, 'solidFill');
|
|
4310
|
+
const rgb = fill ? directChild(fill, 'srgbClr') : void 0;
|
|
4311
|
+
const value = attributeOptional(rgb, 'val')?.trim();
|
|
4312
|
+
return {
|
|
4313
|
+
color: value && /^[0-9a-f]{6}$/i.test(value) ? `#${value}` : '#4472c4',
|
|
4314
|
+
width: emuMillimeters(work_ooxml_package_attribute(line, 'w'), 0.35)
|
|
4315
|
+
};
|
|
4316
|
+
}
|
|
4317
|
+
function bodyPadding(bodyProperties) {
|
|
4318
|
+
if (!bodyProperties) return 3;
|
|
4319
|
+
const values = [
|
|
4320
|
+
'lIns',
|
|
4321
|
+
'rIns',
|
|
4322
|
+
'tIns',
|
|
4323
|
+
'bIns'
|
|
4324
|
+
].map((name)=>emuMillimeters(attributeOptional(bodyProperties, name), 3));
|
|
4325
|
+
return Math.min(...values);
|
|
4326
|
+
}
|
|
4327
|
+
function bodyVerticalAlign(bodyProperties) {
|
|
4328
|
+
const value = attributeOptional(bodyProperties, 'anchor');
|
|
4329
|
+
if ('ctr' === value) return 'center';
|
|
4330
|
+
if ('b' === value) return 'bottom';
|
|
4331
|
+
return 'top';
|
|
4332
|
+
}
|
|
4333
|
+
function positionOffset(element) {
|
|
4334
|
+
const offset = element ? directChild(element, 'posOffset') : void 0;
|
|
4335
|
+
if (!offset?.textContent?.trim()) return null;
|
|
4336
|
+
const value = Number(offset.textContent);
|
|
4337
|
+
return Number.isFinite(value) ? value / EMUS_PER_MILLIMETER : null;
|
|
4338
|
+
}
|
|
4339
|
+
function positionReference(element, fallback) {
|
|
4340
|
+
const value = attributeOptional(element, 'relativeFrom');
|
|
4341
|
+
if ('margin' === value || 'page' === value || 'column' === value) return value;
|
|
4342
|
+
if ('paragraph' === value) return value;
|
|
4343
|
+
return fallback;
|
|
4344
|
+
}
|
|
4345
|
+
function emuMillimeters(value, fallback) {
|
|
4346
|
+
const number = null === value ? NaN : Number(value);
|
|
4347
|
+
return Number.isFinite(number) && number >= 0 ? number / EMUS_PER_MILLIMETER : fallback;
|
|
4348
|
+
}
|
|
4349
|
+
function integerAttribute(element, name) {
|
|
4350
|
+
if (!element) return null;
|
|
4351
|
+
const value = Number(attributeOptional(element, name));
|
|
4352
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
4353
|
+
}
|
|
4354
|
+
function attributeOptional(element, name) {
|
|
4355
|
+
return element ? work_ooxml_package_attribute(element, name) : null;
|
|
4356
|
+
}
|
|
4357
|
+
function nextTextBoxMarker(document, start) {
|
|
4358
|
+
let index = start;
|
|
4359
|
+
while(document.documentElement.textContent?.includes(`__A3S_WORK_TEXT_BOX_${index}__`))index += 1;
|
|
4360
|
+
return `__A3S_WORK_TEXT_BOX_${index}__`;
|
|
4361
|
+
}
|
|
4362
|
+
function work_docx_text_box_import_closestAncestor(element, localName) {
|
|
4363
|
+
let current = element;
|
|
4364
|
+
while(current){
|
|
4365
|
+
if (current.localName === localName) return current;
|
|
4366
|
+
current = current.parentElement;
|
|
4367
|
+
}
|
|
4368
|
+
return null;
|
|
4369
|
+
}
|
|
4370
|
+
function closestHtmlBlock(element) {
|
|
4371
|
+
if (!element) return null;
|
|
4372
|
+
const block = element.closest('p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th');
|
|
4373
|
+
return block instanceof HTMLElement ? block : null;
|
|
4374
|
+
}
|
|
4375
|
+
function textNodes(root) {
|
|
4376
|
+
const walker = root.ownerDocument?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
4377
|
+
const nodes = [];
|
|
4378
|
+
if (!walker) return nodes;
|
|
4379
|
+
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
4380
|
+
return nodes;
|
|
4381
|
+
}
|
|
4382
|
+
const work_docx_index_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
4077
4383
|
const work_docx_index_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
4078
4384
|
function markDocxIndexes(document) {
|
|
4079
4385
|
const fields = docxFieldOccurrences(document);
|
|
@@ -4128,7 +4434,7 @@ function applyImportedDocxIndexMarkers(document, markers) {
|
|
|
4128
4434
|
}
|
|
4129
4435
|
const importedEntries = Array.from(document.body.querySelectorAll('[data-document-index-entry]'));
|
|
4130
4436
|
for (const index of markers.indexes){
|
|
4131
|
-
const text =
|
|
4437
|
+
const text = work_docx_index_import_textNodes(document.body).find((node)=>node.data.includes(index.marker));
|
|
4132
4438
|
if (!text) continue;
|
|
4133
4439
|
const entries = index.entries.map((entry, entryIndex)=>{
|
|
4134
4440
|
const targets = importedEntries.filter((candidate)=>normalizedTerm(candidate.dataset.indexMainEntry) === normalizedTerm(entry.mainEntry) && normalizedTerm(candidate.dataset.indexSubEntry) === normalizedTerm(entry.subEntry));
|
|
@@ -4153,7 +4459,7 @@ function applyImportedDocxIndexMarkers(document, markers) {
|
|
|
4153
4459
|
options: index.options,
|
|
4154
4460
|
entries
|
|
4155
4461
|
}));
|
|
4156
|
-
|
|
4462
|
+
work_docx_index_import_closestHtmlBlock(text.parentElement)?.replaceWith(fragment);
|
|
4157
4463
|
}
|
|
4158
4464
|
}
|
|
4159
4465
|
function hasImportedDocxIndexMarkers(markers) {
|
|
@@ -4246,27 +4552,27 @@ function insertFieldBoundaryMarkers(document, field, start, end) {
|
|
|
4246
4552
|
field.end.parentNode?.insertBefore(markerText(document, end), field.end.nextSibling);
|
|
4247
4553
|
return;
|
|
4248
4554
|
}
|
|
4249
|
-
field.start.parentNode?.insertBefore(
|
|
4250
|
-
field.end.parentNode?.insertBefore(
|
|
4555
|
+
field.start.parentNode?.insertBefore(work_docx_index_import_markerRun(document, start), field.start);
|
|
4556
|
+
field.end.parentNode?.insertBefore(work_docx_index_import_markerRun(document, end), field.end.nextSibling);
|
|
4251
4557
|
}
|
|
4252
4558
|
function markerParagraph(document, marker) {
|
|
4253
|
-
const paragraph = document.createElementNS(
|
|
4254
|
-
paragraph.append(
|
|
4559
|
+
const paragraph = document.createElementNS(work_docx_index_import_WORD_NAMESPACE, 'w:p');
|
|
4560
|
+
paragraph.append(work_docx_index_import_markerRun(document, marker));
|
|
4255
4561
|
return paragraph;
|
|
4256
4562
|
}
|
|
4257
|
-
function
|
|
4258
|
-
const run = document.createElementNS(
|
|
4563
|
+
function work_docx_index_import_markerRun(document, value) {
|
|
4564
|
+
const run = document.createElementNS(work_docx_index_import_WORD_NAMESPACE, 'w:r');
|
|
4259
4565
|
run.append(markerText(document, value));
|
|
4260
4566
|
return run;
|
|
4261
4567
|
}
|
|
4262
4568
|
function markerText(document, value) {
|
|
4263
|
-
const text = document.createElementNS(
|
|
4569
|
+
const text = document.createElementNS(work_docx_index_import_WORD_NAMESPACE, 'w:t');
|
|
4264
4570
|
text.setAttributeNS(work_docx_index_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
4265
4571
|
text.textContent = value;
|
|
4266
4572
|
return text;
|
|
4267
4573
|
}
|
|
4268
4574
|
function replaceMarkerRange(root, start, end, replacement) {
|
|
4269
|
-
const nodes =
|
|
4575
|
+
const nodes = work_docx_index_import_textNodes(root);
|
|
4270
4576
|
const startNode = nodes.find((node)=>node.data.includes(start));
|
|
4271
4577
|
const endNode = nodes.find((node)=>node.data.includes(end));
|
|
4272
4578
|
if (!startNode || !endNode) return;
|
|
@@ -4276,14 +4582,14 @@ function replaceMarkerRange(root, start, end, replacement) {
|
|
|
4276
4582
|
range.deleteContents();
|
|
4277
4583
|
range.insertNode(replacement);
|
|
4278
4584
|
}
|
|
4279
|
-
function
|
|
4585
|
+
function work_docx_index_import_textNodes(root) {
|
|
4280
4586
|
const walker = root.ownerDocument?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
4281
4587
|
const nodes = [];
|
|
4282
4588
|
if (!walker) return nodes;
|
|
4283
4589
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
4284
4590
|
return nodes;
|
|
4285
4591
|
}
|
|
4286
|
-
function
|
|
4592
|
+
function work_docx_index_import_closestHtmlBlock(element) {
|
|
4287
4593
|
let current = element;
|
|
4288
4594
|
while(current && current.parentElement?.tagName.toLowerCase() !== 'body')current = current.parentElement;
|
|
4289
4595
|
return current;
|
|
@@ -4312,7 +4618,7 @@ function markDocxNumberingChanges(document) {
|
|
|
4312
4618
|
let active;
|
|
4313
4619
|
let markerIndex = 0;
|
|
4314
4620
|
for (const paragraph of descendants(document, 'p')){
|
|
4315
|
-
if (!
|
|
4621
|
+
if (!work_docx_numbering_change_import_isWordElement(paragraph)) {
|
|
4316
4622
|
active = void 0;
|
|
4317
4623
|
continue;
|
|
4318
4624
|
}
|
|
@@ -4381,7 +4687,7 @@ function supportedNumberingChangeInParagraph(paragraph) {
|
|
|
4381
4687
|
return supportedNumberingChange(changes[0]);
|
|
4382
4688
|
}
|
|
4383
4689
|
function supportedNumberingChange(change) {
|
|
4384
|
-
if (!change || 'numberingChange' !== change.localName || !
|
|
4690
|
+
if (!change || 'numberingChange' !== change.localName || !work_docx_numbering_change_import_isWordElement(change)) return null;
|
|
4385
4691
|
const namespace = change.namespaceURI ?? '';
|
|
4386
4692
|
const numbering = change.parentElement;
|
|
4387
4693
|
const properties = numbering?.parentElement;
|
|
@@ -4503,7 +4809,7 @@ function insertParagraphMarker(document, paragraph, properties, marker) {
|
|
|
4503
4809
|
}
|
|
4504
4810
|
function directWordChildren(parent, localName) {
|
|
4505
4811
|
const namespace = parent.namespaceURI;
|
|
4506
|
-
return work_ooxml_package_directChildren(parent, localName).filter((element)=>element.namespaceURI === namespace &&
|
|
4812
|
+
return work_ooxml_package_directChildren(parent, localName).filter((element)=>element.namespaceURI === namespace && work_docx_numbering_change_import_isWordElement(element));
|
|
4507
4813
|
}
|
|
4508
4814
|
function boundedWordInteger(element, name, minimum, maximum) {
|
|
4509
4815
|
if (!element) return null;
|
|
@@ -4544,7 +4850,7 @@ function normalizeRevisionDate(value) {
|
|
|
4544
4850
|
const time = Date.parse(value);
|
|
4545
4851
|
return Number.isFinite(time) ? new Date(time).toISOString() : '';
|
|
4546
4852
|
}
|
|
4547
|
-
function
|
|
4853
|
+
function work_docx_numbering_change_import_isWordElement(element) {
|
|
4548
4854
|
return DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '');
|
|
4549
4855
|
}
|
|
4550
4856
|
function isTextNode(value) {
|
|
@@ -8205,4 +8511,4 @@ function work_docx_table_of_contents_import_closestAncestor(element, localName)
|
|
|
8205
8511
|
function normalizedTitle(value) {
|
|
8206
8512
|
return value.normalize('NFKC').replace(/\s+/g, ' ').trim().toLocaleLowerCase();
|
|
8207
8513
|
}
|
|
8208
|
-
export { applyImportedDocxEquationMarkers, applyImportedDocxIndexMarkers, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphAlignmentMarkers, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphFormattingChangeMarkers, applyImportedDocxParagraphIndentMarkers, applyImportedDocxParagraphPaginationMarkers, applyImportedDocxParagraphShadingMarkers, applyImportedDocxParagraphSpacingMarkers, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxRunFormattingMarkers, applyImportedDocxTableOfContentsMarkers, createDocxParagraphStyleResolver, createDocxTableStyleResolver, createImportedDocxRunFormattingMarkerState, docxCaptionBookmark, docxCaptionReferenceTarget, docxCaptionSequenceKind, docxEquationHtml, docxFieldInstructions, docxFieldOccurrenceIsInlineEditable, docxFieldOccurrences, docxFieldResultText, docxRunPropertySources, docxTableCellStyleLayers, docxTablePropertySources, docxTableRunPropertySources, hasImportedDocxIndexMarkers, hasImportedDocxNumberingChangeMarkers, hasImportedDocxParagraphAlignmentMarkers, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphIndentMarkers, hasImportedDocxParagraphPaginationMarkers, hasImportedDocxParagraphShadingMarkers, hasImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphTabStopMarkers, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, hasInvalidDocxFieldStructure, importedDocxStrike, importedDocxUnderline, inspectDocxEquation, inspectDocxHiddenText, inspectDocxLegacyTextEffects, inspectDocxPageBorders, inspectDocxPageMarginSettings, inspectDocxPageMargins, inspectDocxPageSize, inspectDocxPaperSource, inspectDocxRunBorder, inspectDocxRunFonts, inspectDocxRunShading, isDocxEquationLikeRoot, isSupportedDocxEquationPlacement, isSupportedDocxNumberingChange, isSupportedDocxParagraphFormattingChange, isSupportedDocxRunFormattingChange, markDocxIndexes, markDocxNumberingChanges, markDocxPackageEquations, markDocxParagraphAlignments, markDocxParagraphBorders, markDocxParagraphDirections, markDocxParagraphFormattingChanges, markDocxParagraphIndents, markDocxParagraphPagination, markDocxParagraphShading, markDocxParagraphSpacing, markDocxParagraphTabStops, markDocxRunFormattingIntoState, markDocxTablesOfContents, parseDirectDocxParagraphShading, parseDocxPageBorders, parseDocxPageGeometry, parseDocxPageMargins, parseDocxPaperSource, resolveDocxHiddenText, resolveDocxLegacyTextEffects, resolveDocxParagraphBordersForParagraph, resolveDocxRunBorder, resolveDocxRunShading, resolveDocxTableStyleResolver, supportedDocxIndexEntryField, supportedDocxIndexField, supportedDocxTableOfContentsField };
|
|
8514
|
+
export { applyImportedDocxEquationMarkers, applyImportedDocxIndexMarkers, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphAlignmentMarkers, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphFormattingChangeMarkers, applyImportedDocxParagraphIndentMarkers, applyImportedDocxParagraphPaginationMarkers, applyImportedDocxParagraphShadingMarkers, applyImportedDocxParagraphSpacingMarkers, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxRunFormattingMarkers, applyImportedDocxTableOfContentsMarkers, applyImportedDocxTextBoxMarkers, createDocxParagraphStyleResolver, createDocxTableStyleResolver, createImportedDocxRunFormattingMarkerState, docxCaptionBookmark, docxCaptionReferenceTarget, docxCaptionSequenceKind, docxEquationHtml, docxFieldInstructions, docxFieldOccurrenceIsInlineEditable, docxFieldOccurrences, docxFieldResultText, docxRunPropertySources, docxTableCellStyleLayers, docxTablePropertySources, docxTableRunPropertySources, hasImportedDocxIndexMarkers, hasImportedDocxNumberingChangeMarkers, hasImportedDocxParagraphAlignmentMarkers, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphIndentMarkers, hasImportedDocxParagraphPaginationMarkers, hasImportedDocxParagraphShadingMarkers, hasImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphTabStopMarkers, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, hasImportedDocxTextBoxMarkers, hasInvalidDocxFieldStructure, importedDocxStrike, importedDocxUnderline, inspectDocxEquation, inspectDocxHiddenText, inspectDocxLegacyTextEffects, inspectDocxPageBorders, inspectDocxPageMarginSettings, inspectDocxPageMargins, inspectDocxPageSize, inspectDocxPaperSource, inspectDocxRunBorder, inspectDocxRunFonts, inspectDocxRunShading, inspectDocxTextBoxes, isDocxEquationLikeRoot, isSupportedDocxEquationPlacement, isSupportedDocxNumberingChange, isSupportedDocxParagraphFormattingChange, isSupportedDocxRunFormattingChange, markDocxIndexes, markDocxNumberingChanges, markDocxPackageEquations, markDocxParagraphAlignments, markDocxParagraphBorders, markDocxParagraphDirections, markDocxParagraphFormattingChanges, markDocxParagraphIndents, markDocxParagraphPagination, markDocxParagraphShading, markDocxParagraphSpacing, markDocxParagraphTabStops, markDocxRunFormattingIntoState, markDocxTablesOfContents, markDocxTextBoxes, parseDirectDocxParagraphShading, parseDocxPageBorders, parseDocxPageGeometry, parseDocxPageMargins, parseDocxPaperSource, resolveDocxHiddenText, resolveDocxLegacyTextEffects, resolveDocxParagraphBordersForParagraph, resolveDocxRunBorder, resolveDocxRunShading, resolveDocxTableStyleResolver, supportedDocxIndexEntryField, supportedDocxIndexField, supportedDocxTableOfContentsField };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import jszip from "jszip";
|
|
2
2
|
import { normalizeDocumentIndexEntryDraft, serializeUtf8Xml, directChildren, xmlNamespacePrefix, normalizeDocumentLanguageTag, parseXml, firstDescendant, decodeXmlBytes, directChild, descendants, normalizeDocumentProofingLanguages, attribute as work_ooxml_package_attribute, normalizeDocumentIndexOptions } from "./6968.js";
|
|
3
|
-
import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle,
|
|
3
|
+
import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterSpacingTwips, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentOpenTypeNumberSpacing, createDocumentBibliography, normalizeDocumentImageTransform, normalizeDocumentOpenTypeLigatures, normalizeDocumentOpenTypeNumberForm, normalizeDocumentTabStops, documentCitationStyleDetails, normalizeDocumentOpenTypeStylisticSets } from "./4174.js";
|
|
4
4
|
const BIBLIOGRAPHY_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/bibliography';
|
|
5
5
|
const CUSTOM_XML_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/customXml';
|
|
6
6
|
const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
|
@@ -708,6 +708,114 @@ function isAllowedExtensionNamespace(namespace, context) {
|
|
|
708
708
|
function isNamespacePrefix(value) {
|
|
709
709
|
return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) && 'xml' !== value;
|
|
710
710
|
}
|
|
711
|
+
const DOCX_ROTATION_UNITS_PER_DEGREE = 60000;
|
|
712
|
+
const DOCX_QUADRANT_ROTATION_UNITS = 5400000;
|
|
713
|
+
function readDocxImageTransform(drawing) {
|
|
714
|
+
const target = pictureTransform(drawing);
|
|
715
|
+
if (!target) return {
|
|
716
|
+
transform: null,
|
|
717
|
+
supported: true
|
|
718
|
+
};
|
|
719
|
+
const rawRotation = work_ooxml_package_attribute(target, 'rot');
|
|
720
|
+
const rawFlipHorizontal = work_ooxml_package_attribute(target, 'flipH');
|
|
721
|
+
const rawFlipVertical = work_ooxml_package_attribute(target, 'flipV');
|
|
722
|
+
const rotation = parseRotation(rawRotation);
|
|
723
|
+
const flipHorizontal = parseFlip(rawFlipHorizontal);
|
|
724
|
+
const flipVertical = parseFlip(rawFlipVertical);
|
|
725
|
+
const supported = null !== rotation && null !== flipHorizontal && null !== flipVertical && (0 === rotation || rotation % DOCX_QUADRANT_ROTATION_UNITS === 0);
|
|
726
|
+
const normalized = normalizeDocumentImageTransform({
|
|
727
|
+
rotation: null === rotation ? 0 : rotation / DOCX_ROTATION_UNITS_PER_DEGREE,
|
|
728
|
+
flipHorizontal: flipHorizontal ?? false,
|
|
729
|
+
flipVertical: flipVertical ?? false
|
|
730
|
+
});
|
|
731
|
+
return {
|
|
732
|
+
transform: 0 !== normalized.rotation || normalized.flipHorizontal || normalized.flipVertical ? normalized : null,
|
|
733
|
+
supported
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
class DocxImageTransformPatchCollector {
|
|
737
|
+
patches = [];
|
|
738
|
+
nextMarker = 1;
|
|
739
|
+
marker(transform) {
|
|
740
|
+
if (!transform) return '';
|
|
741
|
+
const normalized = normalizeDocumentImageTransform(transform);
|
|
742
|
+
if (0 === normalized.rotation && !normalized.flipHorizontal && !normalized.flipVertical) return '';
|
|
743
|
+
const marker = `__A3S_IMAGE_TRANSFORM_${this.nextMarker}__`;
|
|
744
|
+
this.nextMarker += 1;
|
|
745
|
+
this.patches.push({
|
|
746
|
+
marker,
|
|
747
|
+
transform: normalized
|
|
748
|
+
});
|
|
749
|
+
return marker;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
async function patchDocxImageTransforms(buffer, patches) {
|
|
753
|
+
if (!patches.length) return buffer;
|
|
754
|
+
const archive = await jszip.loadAsync(buffer);
|
|
755
|
+
const entries = Object.values(archive.files).filter((entry)=>!entry.dir && /^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/.test(entry.name));
|
|
756
|
+
const byMarker = new Map(patches.map((patch)=>[
|
|
757
|
+
patch.marker,
|
|
758
|
+
patch
|
|
759
|
+
]));
|
|
760
|
+
for (const entry of entries){
|
|
761
|
+
const document = parseXml(await entry.async('text'), entry.name);
|
|
762
|
+
let changed = false;
|
|
763
|
+
for (const properties of descendants(document, 'docPr')){
|
|
764
|
+
const patch = imageTransformPatch(properties, byMarker);
|
|
765
|
+
if (!patch) continue;
|
|
766
|
+
removeTransformMarker(properties, patch.marker);
|
|
767
|
+
changed = true;
|
|
768
|
+
const drawing = closestDrawing(properties);
|
|
769
|
+
const transform = drawing ? pictureTransform(drawing) : void 0;
|
|
770
|
+
if (transform) applyImageTransform(transform, patch.transform);
|
|
771
|
+
}
|
|
772
|
+
if (changed) archive.file(entry.name, new XMLSerializer().serializeToString(document));
|
|
773
|
+
}
|
|
774
|
+
return archive.generateAsync({
|
|
775
|
+
type: 'arraybuffer'
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
function imageTransformPatch(properties, patches) {
|
|
779
|
+
for (const attribute of Array.from(properties.attributes))for (const [marker, patch] of patches)if (attribute.value.includes(marker)) return patch;
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
function removeTransformMarker(properties, marker) {
|
|
783
|
+
for (const attribute of Array.from(properties.attributes))if (attribute.value.includes(marker)) attribute.value = attribute.value.replace(marker, '');
|
|
784
|
+
}
|
|
785
|
+
function closestDrawing(element) {
|
|
786
|
+
let current = element;
|
|
787
|
+
while(current){
|
|
788
|
+
if ('anchor' === current.localName || 'inline' === current.localName) return current;
|
|
789
|
+
current = current.parentElement;
|
|
790
|
+
}
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
function pictureTransform(drawing) {
|
|
794
|
+
const picture = descendants(drawing, 'pic')[0];
|
|
795
|
+
const properties = picture ? directChild(picture, 'spPr') : void 0;
|
|
796
|
+
return properties ? directChild(properties, 'xfrm') : descendants(drawing, 'xfrm')[0];
|
|
797
|
+
}
|
|
798
|
+
function parseRotation(value) {
|
|
799
|
+
if (null === value || !value.trim()) return 0;
|
|
800
|
+
const number = Number(value);
|
|
801
|
+
return Number.isInteger(number) && number >= 0 ? number : null;
|
|
802
|
+
}
|
|
803
|
+
function parseFlip(value) {
|
|
804
|
+
if (null === value || !value.trim()) return false;
|
|
805
|
+
const normalized = value.trim().toLowerCase();
|
|
806
|
+
if ('1' === normalized || 'true' === normalized) return true;
|
|
807
|
+
if ('0' === normalized || 'false' === normalized) return false;
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
function applyImageTransform(target, transform) {
|
|
811
|
+
const normalized = normalizeDocumentImageTransform(transform);
|
|
812
|
+
if (0 === normalized.rotation) target.removeAttribute('rot');
|
|
813
|
+
else target.setAttribute('rot', String(normalized.rotation * DOCX_ROTATION_UNITS_PER_DEGREE));
|
|
814
|
+
if (normalized.flipHorizontal) target.setAttribute('flipH', '1');
|
|
815
|
+
else target.removeAttribute('flipH');
|
|
816
|
+
if (normalized.flipVertical) target.setAttribute('flipV', '1');
|
|
817
|
+
else target.removeAttribute('flipV');
|
|
818
|
+
}
|
|
711
819
|
function parseDocumentIndexEntryInstruction(instruction) {
|
|
712
820
|
const command = /^\s*XE\b/i.exec(instruction);
|
|
713
821
|
if (!command) return {
|
|
@@ -2072,4 +2180,4 @@ function isParagraphPartRoot(root, path) {
|
|
|
2072
2180
|
const expected = /^word\/header\d*\.xml$/i.test(path) ? 'hdr' : /^word\/footer\d*\.xml$/i.test(path) ? 'ftr' : /^word\/footnotes\.xml$/i.test(path) ? 'footnotes' : /^word\/endnotes\.xml$/i.test(path) ? 'endnotes' : 'document';
|
|
2073
2181
|
return root.localName === expected && DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '');
|
|
2074
2182
|
}
|
|
2075
|
-
export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxParagraphDefaultCollapsed, readDocxBibliography, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
|
|
2183
|
+
export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxImageTransformPatchCollector, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxImageTransforms, patchDocxParagraphDefaultCollapsed, readDocxBibliography, readDocxImageTransform, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
|