From 19462916280e51fbe5b1c1253afc4ad5c4651d6f Mon Sep 17 00:00:00 2001 From: MarsLuay <70299537+MarsLuay@users.noreply.github.com> Date: Tue, 25 Aug 2026 09:25:08 +0000 Subject: [PATCH] refactor: extract replaceSlideText helper to flatten replaceText --- src/PresentationEngine.ts | 79 ++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/src/PresentationEngine.ts b/src/PresentationEngine.ts index 7028e65..776e78a 100644 --- a/src/PresentationEngine.ts +++ b/src/PresentationEngine.ts @@ -1312,33 +1312,17 @@ export class PresentationEngine { let total = 0; for (let slideIndex = slideStart; slideIndex < slideEnd; slideIndex++) { - const slidePath = getSlidePath(slideIndex); - const slideXml = zip.textFiles.get(slidePath); - if (!slideXml) continue; - - const slideDoc = parseXml(slideXml, slidePath); - let scope: Element | XMLDocument = slideDoc; - if (scoped) { - try { - scope = getShapeElement(slideDoc, options.shapeIndex as number); - } catch { - continue; - } - } - - const paragraphs = getDescendants(scope, 'p') - .filter((element) => element.namespaceURI === DRAWINGML_NAMESPACE); - let slideChanged = false; - for (const paragraph of paragraphs) { - const count = replaceTextInParagraph(paragraph, query, replacement, matchCase); - if (count > 0) { - total += count; - slideChanged = true; - } - } - - if (slideChanged) { - updatedFiles.set(slidePath, serializeXml(slideDoc)); + const result = this.replaceSlideText( + zip, + slideIndex, + query, + replacement, + matchCase, + scoped ? options.shapeIndex : undefined + ); + if (result) { + total += result.count; + updatedFiles.set(result.slidePath, result.serializedXml); } } @@ -1350,6 +1334,47 @@ export class PresentationEngine { return total; } + private replaceSlideText( + zip: ZipContents, + slideIndex: number, + query: string, + replacement: string, + matchCase: boolean, + shapeIndex?: number + ): { slidePath: string; serializedXml: string; count: number } | null { + const slidePath = getSlidePath(slideIndex); + const slideXml = zip.textFiles.get(slidePath); + if (!slideXml) return null; + + const slideDoc = parseXml(slideXml, slidePath); + let scope: Element | XMLDocument = slideDoc; + if (shapeIndex !== undefined) { + try { + scope = getShapeElement(slideDoc, shapeIndex); + } catch { + return null; + } + } + + const paragraphs = getDescendants(scope, 'p') + .filter((element) => element.namespaceURI === DRAWINGML_NAMESPACE); + let count = 0; + for (const paragraph of paragraphs) { + const replaced = replaceTextInParagraph(paragraph, query, replacement, matchCase); + if (replaced > 0) { + count += replaced; + } + } + + if (count === 0) return null; + + return { + slidePath, + serializedXml: serializeXml(slideDoc), + count, + }; + } + /** * Read the resolved style of a single text run for reflecting toolbar state. * Only directly-authored run/paragraph properties are reported; values