@mcpher/gas-fakes 2.5.2 → 2.5.3
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 +8 -1
- package/package.json +1 -1
- package/pngs/srv.jpg +0 -0
- package/src/cli/app.js +1 -0
- package/src/cli/togas.js +23 -14
- package/src/index.js +1 -0
- package/src/services/advslides/fakeadvslides.js +11 -5
- package/src/services/base/app.js +9 -0
- package/src/services/base/fakebase.js +28 -0
- package/src/services/common/fakeadvresource.js +3 -2
- package/src/services/enums/baseenums.js +47 -0
- package/src/services/enums/slidesenums.js +3 -1
- package/src/services/html/serverworker.js +1 -1
- package/src/services/slidesapp/app.js +5 -0
- package/src/services/slidesapp/fakeautofit.js +1 -1
- package/src/services/slidesapp/fakeborder.js +106 -0
- package/src/services/slidesapp/fakecolorscheme.js +1 -1
- package/src/services/slidesapp/fakefill.js +216 -0
- package/src/services/slidesapp/fakegroup.js +35 -0
- package/src/services/slidesapp/fakeimage.js +118 -0
- package/src/services/slidesapp/fakelayout.js +351 -0
- package/src/services/slidesapp/fakeline.js +2 -2
- package/src/services/slidesapp/fakelinefill.js +15 -16
- package/src/services/slidesapp/fakelink.js +20 -3
- package/src/services/slidesapp/fakelist.js +36 -0
- package/src/services/slidesapp/fakeliststyle.js +105 -0
- package/src/services/slidesapp/fakemaster.js +358 -0
- package/src/services/slidesapp/fakenotesmaster.js +125 -0
- package/src/services/slidesapp/fakenotespage.js +102 -2
- package/src/services/slidesapp/fakepagebackground.js +109 -1
- package/src/services/slidesapp/fakepageelement.js +157 -18
- package/src/services/slidesapp/fakepageelementrange.js +28 -0
- package/src/services/slidesapp/fakepagerange.js +28 -0
- package/src/services/slidesapp/fakeparagraphstyle.js +139 -0
- package/src/services/slidesapp/fakepicturefill.js +32 -0
- package/src/services/slidesapp/fakepresentation.js +126 -2
- package/src/services/slidesapp/fakeshape.js +9 -0
- package/src/services/slidesapp/fakeslide.js +216 -24
- package/src/services/slidesapp/fakesolidfill.js +45 -0
- package/src/services/slidesapp/fakespeakerspotlight.js +18 -0
- package/src/services/slidesapp/faketable.js +55 -9
- package/src/services/slidesapp/faketablecell.js +141 -12
- package/src/services/slidesapp/faketablecellrange.js +28 -0
- package/src/services/slidesapp/faketablecolumn.js +72 -0
- package/src/services/slidesapp/faketablerow.js +31 -0
- package/src/services/slidesapp/faketextrange.js +179 -135
- package/src/services/slidesapp/faketextstyle.js +158 -0
- package/src/services/slidesapp/fakevideo.js +35 -0
- package/src/services/slidesapp/fakewordart.js +22 -0
- package/src/services/slidesapp/pageelementfactory.js +24 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Proxies } from '../../support/proxies.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* create a new FakeTableCellRange instance
|
|
5
|
+
* @param {...any} args
|
|
6
|
+
* @returns {FakeTableCellRange}
|
|
7
|
+
*/
|
|
8
|
+
export const newFakeTableCellRange = (...args) => {
|
|
9
|
+
return Proxies.guard(new FakeTableCellRange(...args));
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export class FakeTableCellRange {
|
|
13
|
+
constructor(cells) {
|
|
14
|
+
this.__cells = cells;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns the list of TableCell instances.
|
|
19
|
+
* @returns {FakeTableCell[]} The cells.
|
|
20
|
+
*/
|
|
21
|
+
getTableCells() {
|
|
22
|
+
return this.__cells;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toString() {
|
|
26
|
+
return 'TableCellRange';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Proxies } from '../../support/proxies.js';
|
|
2
|
+
import { newFakeTableCell } from './faketablecell.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* create a new FakeTableColumn instance
|
|
6
|
+
* @param {...any} args
|
|
7
|
+
* @returns {FakeTableColumn}
|
|
8
|
+
*/
|
|
9
|
+
export const newFakeTableColumn = (...args) => {
|
|
10
|
+
return Proxies.guard(new FakeTableColumn(...args));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class FakeTableColumn {
|
|
14
|
+
constructor(table, colIndex) {
|
|
15
|
+
this.__table = table;
|
|
16
|
+
this.__colIndex = colIndex;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Gets a cell by its index.
|
|
21
|
+
* @param {number} index The row index.
|
|
22
|
+
* @returns {FakeTableCell} The cell.
|
|
23
|
+
*/
|
|
24
|
+
getCell(index) {
|
|
25
|
+
return newFakeTableCell(this.__table, index, this.__colIndex);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Gets the 0-based index of the column.
|
|
30
|
+
* @returns {number} The index.
|
|
31
|
+
*/
|
|
32
|
+
getIndex() {
|
|
33
|
+
return this.__colIndex;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets the number of cells in this column.
|
|
38
|
+
* @returns {number} The number of cells.
|
|
39
|
+
*/
|
|
40
|
+
getNumCells() {
|
|
41
|
+
return this.__table.getNumRows();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets the table containing the current column.
|
|
46
|
+
* @returns {FakeTable} The parent table.
|
|
47
|
+
*/
|
|
48
|
+
getParentTable() {
|
|
49
|
+
return this.__table;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gets the width of the column in points.
|
|
54
|
+
* @returns {number} The width.
|
|
55
|
+
*/
|
|
56
|
+
getWidth() {
|
|
57
|
+
const tableResource = this.__table.__resource.table;
|
|
58
|
+
const colProperties = tableResource?.tableColumns?.[this.__colIndex];
|
|
59
|
+
return this.__table.__normalize(colProperties?.columnWidth);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Removes the table column.
|
|
64
|
+
*/
|
|
65
|
+
remove() {
|
|
66
|
+
throw new Error('TableColumn.remove() not yet implemented');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toString() {
|
|
70
|
+
return 'TableColumn';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -38,6 +38,22 @@ export class FakeTableRow {
|
|
|
38
38
|
return cells[index];
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Returns the 0-based index of the row.
|
|
43
|
+
* @returns {number} The index.
|
|
44
|
+
*/
|
|
45
|
+
getIndex() {
|
|
46
|
+
return this.__rowIndex;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Returns the minimum height of the row in points.
|
|
51
|
+
* @returns {number} The minimum height.
|
|
52
|
+
*/
|
|
53
|
+
getMinimumHeight() {
|
|
54
|
+
return this.__table.__normalize(this.__resource?.rowHeight);
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
/**
|
|
42
58
|
* Gets the number of cells in the row.
|
|
43
59
|
* @returns {number} The number of cells.
|
|
@@ -46,6 +62,21 @@ export class FakeTableRow {
|
|
|
46
62
|
return (this.__resource?.tableCells || []).length;
|
|
47
63
|
}
|
|
48
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Returns the table containing the current row.
|
|
67
|
+
* @returns {FakeTable} The parent table.
|
|
68
|
+
*/
|
|
69
|
+
getParentTable() {
|
|
70
|
+
return this.__table;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Removes the table row.
|
|
75
|
+
*/
|
|
76
|
+
remove() {
|
|
77
|
+
throw new Error('TableRow.remove() not yet implemented');
|
|
78
|
+
}
|
|
79
|
+
|
|
49
80
|
toString() {
|
|
50
81
|
return 'TableRow';
|
|
51
82
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Proxies } from '../../support/proxies.js';
|
|
2
2
|
import { newFakeParagraph } from './fakeparagraph.js';
|
|
3
3
|
import { newFakeAutoText } from './fakeautotext.js';
|
|
4
|
+
import { newFakeTextStyle } from './faketextstyle.js';
|
|
5
|
+
import { newFakeParagraphStyle } from './fakeparagraphstyle.js';
|
|
6
|
+
import { newFakeListStyle } from './fakeliststyle.js';
|
|
4
7
|
import { AutofitType } from '../enums/slidesenums.js';
|
|
5
8
|
|
|
6
9
|
export const newFakeTextRange = (...args) => {
|
|
@@ -10,8 +13,6 @@ export const newFakeTextRange = (...args) => {
|
|
|
10
13
|
export class FakeTextRange {
|
|
11
14
|
constructor(shape, startIndex = null, endIndex = null) {
|
|
12
15
|
this.__shape = shape;
|
|
13
|
-
// APIs use 0-based index? Apps Script TextRange uses indices?
|
|
14
|
-
// If null, represents the entire text.
|
|
15
16
|
this.__startIndex = startIndex;
|
|
16
17
|
this.__endIndex = endIndex;
|
|
17
18
|
}
|
|
@@ -21,40 +22,143 @@ export class FakeTextRange {
|
|
|
21
22
|
if (shapeResource && shapeResource.shape && shapeResource.shape.text) {
|
|
22
23
|
return shapeResource.shape.text;
|
|
23
24
|
}
|
|
25
|
+
if (shapeResource && shapeResource.table) {
|
|
26
|
+
return shapeResource.table.tableRows?.[this.__shape.__cellLocation?.rowIndex]?.tableCells?.[this.__shape.__cellLocation?.columnIndex]?.text || {};
|
|
27
|
+
}
|
|
24
28
|
return {};
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
getStartIndex() {
|
|
28
|
-
// If indices are null, it starts at 0?
|
|
29
32
|
return this.__startIndex !== null ? this.__startIndex : 0;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
getEndIndex() {
|
|
33
|
-
// If indices are null, it ends at full length?
|
|
34
|
-
// Caution: If we haven't computed length...
|
|
35
|
-
// But usually FakeTextRange is created with explicit indices by getParagraphs.
|
|
36
|
-
// If created without indices (full range), we need to calculate length.
|
|
37
36
|
if (this.__endIndex !== null) return this.__endIndex;
|
|
38
|
-
return this.
|
|
37
|
+
return this.getLength();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
appendParagraph(text) {
|
|
41
|
+
this.appendText(text + '\n');
|
|
42
|
+
const paragraphs = this.getParagraphs();
|
|
43
|
+
return paragraphs[paragraphs.length - 1];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
appendRange(range) {
|
|
47
|
+
this.appendText(range.asString());
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
appendText(text) {
|
|
52
|
+
// In Google Slides API, if the text ends in a newline, the insertion index
|
|
53
|
+
// should be length - 1 to be inside the text.
|
|
54
|
+
// But actually, for appending, length is correct if we want to add after.
|
|
55
|
+
// The issue is likely that asString() is NOT matching API length.
|
|
56
|
+
return this.insertText(this.asString().length, text);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getLength() {
|
|
60
|
+
const textElements = this.__resource?.textElements || [];
|
|
61
|
+
if (textElements.length === 0) return 0;
|
|
62
|
+
|
|
63
|
+
const lastElement = textElements[textElements.length - 1];
|
|
64
|
+
let totalLength = lastElement.endIndex || 0;
|
|
65
|
+
|
|
66
|
+
if (this.__startIndex !== null && this.__endIndex !== null) {
|
|
67
|
+
return Math.max(0, this.__endIndex - this.__startIndex);
|
|
68
|
+
}
|
|
69
|
+
if (this.__startIndex !== null) {
|
|
70
|
+
return Math.max(0, totalLength - this.__startIndex);
|
|
71
|
+
}
|
|
72
|
+
return totalLength;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getLinks() {
|
|
76
|
+
return this.getTextStyle().hasLink() ? [this] : [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getListParagraphs() {
|
|
80
|
+
return this.getParagraphs().filter(p => p.getRange().getListStyle().isInList());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getListStyle() {
|
|
84
|
+
return newFakeListStyle(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
getParagraphStyle() {
|
|
88
|
+
return newFakeParagraphStyle(this);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getRange(start, end) {
|
|
92
|
+
return newFakeTextRange(this.__shape, this.getStartIndex() + start, this.getStartIndex() + end);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getRuns() {
|
|
96
|
+
return [this];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getTextStyle() {
|
|
100
|
+
return newFakeTextStyle(this);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
insertParagraph(offset, text) {
|
|
104
|
+
this.insertText(offset, text + '\n');
|
|
105
|
+
return this.getParagraphs().find(p => p.getRange().getStartIndex() === this.getStartIndex() + offset);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
insertRange(offset, range) {
|
|
109
|
+
return this.insertText(offset, range.asString());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
replaceAllText(findText, replaceText, matchCase) {
|
|
113
|
+
const presentationId = this.__shape.__presentation.getId();
|
|
114
|
+
const requests = [{
|
|
115
|
+
replaceAllText: {
|
|
116
|
+
replaceText: replaceText,
|
|
117
|
+
containsText: {
|
|
118
|
+
text: findText,
|
|
119
|
+
matchCase: matchCase
|
|
120
|
+
},
|
|
121
|
+
pageObjectIds: [this.__shape.getParentPage().getObjectId()]
|
|
122
|
+
}
|
|
123
|
+
}];
|
|
124
|
+
|
|
125
|
+
const response = Slides.Presentations.batchUpdate({ requests }, presentationId);
|
|
126
|
+
return response.replies[0].replaceAllText.occurrencesChanged || 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
select() {
|
|
130
|
+
return this;
|
|
39
131
|
}
|
|
40
132
|
|
|
41
|
-
/**
|
|
42
|
-
* Gets the rendered string of the text range.
|
|
43
|
-
* @returns {string} The text.
|
|
44
|
-
*/
|
|
45
133
|
asString() {
|
|
46
134
|
const textElements = this.__resource?.textElements || [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
135
|
+
if (textElements.length === 0) return '';
|
|
136
|
+
|
|
137
|
+
// We need the full length of the underlying text resource to use API indices.
|
|
138
|
+
const lastElement = textElements[textElements.length - 1];
|
|
139
|
+
const fullLength = lastElement.endIndex || 0;
|
|
140
|
+
|
|
141
|
+
// Reconstruct the full string based on API indices to ensure parity.
|
|
142
|
+
const chars = new Array(fullLength).fill(null);
|
|
143
|
+
for (const te of textElements) {
|
|
144
|
+
const start = te.startIndex || 0;
|
|
145
|
+
const end = te.endIndex;
|
|
146
|
+
|
|
147
|
+
if (te.textRun) {
|
|
148
|
+
const content = te.textRun.content;
|
|
149
|
+
for (let i = 0; i < content.length; i++) {
|
|
150
|
+
if (start + i < fullLength) chars[start + i] = content[i];
|
|
151
|
+
}
|
|
152
|
+
} else if (te.autoText) {
|
|
153
|
+
if (start < fullLength) chars[start] = te.autoText.content || ' ';
|
|
154
|
+
} else if (te.paragraphMarker) {
|
|
155
|
+
if (end > 0 && end <= fullLength) chars[end - 1] = '\n';
|
|
156
|
+
}
|
|
157
|
+
}
|
|
52
158
|
|
|
53
|
-
|
|
54
|
-
// We assume indices are 0-based relative to the start of the SHAPE text (if referencing shape).
|
|
159
|
+
let fullText = chars.map(c => c === null ? '\n' : c).join('');
|
|
55
160
|
|
|
56
161
|
if (this.__startIndex !== null && this.__endIndex !== null) {
|
|
57
|
-
// Ensure indices are within bounds? Or just slice.
|
|
58
162
|
fullText = fullText.slice(this.__startIndex, this.__endIndex);
|
|
59
163
|
} else if (this.__startIndex !== null) {
|
|
60
164
|
fullText = fullText.slice(this.__startIndex);
|
|
@@ -67,78 +171,68 @@ export class FakeTextRange {
|
|
|
67
171
|
return this.asString();
|
|
68
172
|
}
|
|
69
173
|
|
|
70
|
-
/**
|
|
71
|
-
* Sets the text content.
|
|
72
|
-
* @param {string} newText The new text.
|
|
73
|
-
* @returns {FakeTextRange} This range.
|
|
74
|
-
*/
|
|
75
174
|
setText(newText) {
|
|
76
|
-
|
|
77
|
-
const presentationId = this.__shape.__presentation.getId();
|
|
78
|
-
|
|
79
|
-
const requests = [];
|
|
80
|
-
|
|
81
|
-
const currentText = this.asString();
|
|
82
|
-
|
|
83
|
-
if (currentText.length > 0) {
|
|
84
|
-
requests.push({
|
|
85
|
-
deleteText: {
|
|
86
|
-
objectId: objectId,
|
|
87
|
-
cellLocation: this.__shape.__cellLocation,
|
|
88
|
-
textRange: {
|
|
89
|
-
type: 'FROM_START_INDEX',
|
|
90
|
-
startIndex: 0
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
175
|
+
this.clear();
|
|
96
176
|
if (newText) {
|
|
97
|
-
// Apps Script shapes always end with a newline.
|
|
98
|
-
// If we insert text that ends with a newline, we get double newline (one explicit, one implicit).
|
|
99
|
-
// To match expected behavior where setText("A\n") results in "A" (plus implicit \n),
|
|
100
|
-
// or at least doesn't create "A\n\n", we should strip the trailing newline.
|
|
101
|
-
|
|
102
177
|
if (newText.endsWith('\n')) {
|
|
103
178
|
newText = newText.slice(0, -1);
|
|
104
179
|
}
|
|
105
|
-
|
|
106
|
-
requests.push({
|
|
107
|
-
insertText: {
|
|
108
|
-
objectId: objectId,
|
|
109
|
-
cellLocation: this.__shape.__cellLocation,
|
|
110
|
-
insertionIndex: 0,
|
|
111
|
-
text: newText
|
|
112
|
-
}
|
|
113
|
-
});
|
|
180
|
+
this.appendText(newText);
|
|
114
181
|
}
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
115
184
|
|
|
116
|
-
|
|
117
|
-
|
|
185
|
+
insertText(offset, text) {
|
|
186
|
+
const objectId = this.__shape.getObjectId();
|
|
187
|
+
const presentationId = this.__shape.__presentation.getId();
|
|
188
|
+
|
|
189
|
+
const totalLen = this.getLength();
|
|
190
|
+
let insertionIndex = this.getStartIndex() + offset;
|
|
191
|
+
|
|
192
|
+
// In Slides API, insertionIndex cannot be after the final paragraph marker.
|
|
193
|
+
// If the shape has length 12 (0-11 text, 11-12 marker), max insertionIndex is 11.
|
|
194
|
+
if (insertionIndex >= totalLen && totalLen > 0) {
|
|
195
|
+
insertionIndex = totalLen - 1;
|
|
118
196
|
}
|
|
119
197
|
|
|
198
|
+
Slides.Presentations.batchUpdate({ requests: [{
|
|
199
|
+
insertText: {
|
|
200
|
+
objectId: objectId,
|
|
201
|
+
cellLocation: this.__shape.__cellLocation,
|
|
202
|
+
insertionIndex: insertionIndex,
|
|
203
|
+
text: text
|
|
204
|
+
}
|
|
205
|
+
}] }, presentationId);
|
|
120
206
|
return this;
|
|
121
207
|
}
|
|
122
208
|
|
|
123
209
|
clear() {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
210
|
+
if (this.getLength() === 0) return this;
|
|
211
|
+
const objectId = this.__shape.getObjectId();
|
|
212
|
+
const presentationId = this.__shape.__presentation.getId();
|
|
213
|
+
|
|
214
|
+
const type = (this.__startIndex === null && this.__endIndex === null) ? 'ALL' : 'FIXED_RANGE';
|
|
215
|
+
const deleteRange = { type };
|
|
216
|
+
if (type === 'FIXED_RANGE') {
|
|
217
|
+
deleteRange.startIndex = this.getStartIndex();
|
|
218
|
+
deleteRange.endIndex = this.getEndIndex();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
Slides.Presentations.batchUpdate({ requests: [{
|
|
222
|
+
deleteText: {
|
|
223
|
+
objectId: objectId,
|
|
224
|
+
cellLocation: this.__shape.__cellLocation,
|
|
225
|
+
textRange: deleteRange
|
|
226
|
+
}
|
|
227
|
+
}] }, presentationId);
|
|
228
|
+
return this;
|
|
129
229
|
}
|
|
130
230
|
|
|
131
|
-
/**
|
|
132
|
-
* Gets the paragraphs in the text range.
|
|
133
|
-
* @returns {FakeParagraph[]} The paragraphs.
|
|
134
|
-
*/
|
|
135
231
|
getParagraphs() {
|
|
136
232
|
const fullText = this.asString();
|
|
137
233
|
if (fullText.length === 0) return [];
|
|
138
234
|
|
|
139
235
|
const paragraphs = [];
|
|
140
|
-
let startIndex = 0;
|
|
141
|
-
|
|
142
236
|
let currentIndex = 0;
|
|
143
237
|
let paragraphIndex = 0;
|
|
144
238
|
|
|
@@ -149,15 +243,10 @@ export class FakeTextRange {
|
|
|
149
243
|
if (nextNewline === -1) {
|
|
150
244
|
endIndex = fullText.length;
|
|
151
245
|
} else {
|
|
152
|
-
endIndex = nextNewline + 1;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (startIndex + currentIndex >= startIndex + endIndex) {
|
|
156
|
-
// Empty segment
|
|
157
|
-
if (endIndex === fullText.length) break; // Trailing empty
|
|
246
|
+
endIndex = nextNewline + 1;
|
|
158
247
|
}
|
|
159
248
|
|
|
160
|
-
const range = newFakeTextRange(this.__shape,
|
|
249
|
+
const range = newFakeTextRange(this.__shape, this.getStartIndex() + currentIndex, this.getStartIndex() + endIndex);
|
|
161
250
|
paragraphs.push(newFakeParagraph(range, paragraphIndex++));
|
|
162
251
|
|
|
163
252
|
currentIndex = endIndex;
|
|
@@ -166,76 +255,31 @@ export class FakeTextRange {
|
|
|
166
255
|
return paragraphs;
|
|
167
256
|
}
|
|
168
257
|
|
|
169
|
-
/**
|
|
170
|
-
* Gets the auto texts in the text range.
|
|
171
|
-
* @returns {FakeAutoText[]} The auto texts.
|
|
172
|
-
*/
|
|
173
258
|
getAutoTexts() {
|
|
174
259
|
const textElements = this.__resource?.textElements || [];
|
|
175
260
|
const autoTexts = [];
|
|
176
261
|
let charIndex = 0;
|
|
177
262
|
let autoTextIndex = 0;
|
|
178
263
|
|
|
179
|
-
// We need to iterate text elements to find autoText and calculate their ranges.
|
|
180
|
-
// But FakeTextRange might be a sub-range (startIndex, endIndex).
|
|
181
|
-
// We should only return AutoTexts falling within this range.
|
|
182
|
-
|
|
183
264
|
const rangeStart = this.getStartIndex();
|
|
184
265
|
const rangeEnd = this.getEndIndex();
|
|
185
266
|
|
|
186
267
|
for (const element of textElements) {
|
|
187
268
|
const elementLength = (element.textRun ? element.textRun.content.length : 0) +
|
|
188
|
-
(element.autoText ? 1 : 0)
|
|
189
|
-
|
|
190
|
-
// Actually, paragraph markers ARE elements.
|
|
191
|
-
// Wait, textElements is a flat list.
|
|
192
|
-
// TextRun has content string.
|
|
193
|
-
// AutoText has no content string property directly? It renders as text.
|
|
194
|
-
// In API, AutoText is a separate kind of element.
|
|
195
|
-
// And it usually corresponds to a specific character length (e.g. 1 char for page number).
|
|
196
|
-
|
|
197
|
-
// Let's assume AutoText has length 1 for indexing purposes if it doesn't have explicit content length.
|
|
198
|
-
// But wait, getStartIndex/EndIndex logic in asString() uses textElements.map...
|
|
199
|
-
// asString() uses: te.textRun ? te.textRun.content : ''.
|
|
200
|
-
// So AutoText currently contributes 0 length to `asString()`!
|
|
201
|
-
// If AutoText is not returned by `asString()`, then it doesn't exist in the string view?
|
|
202
|
-
// If so, our `currentIndex` logic in `getParagraphs` works on `asString()`.
|
|
203
|
-
|
|
204
|
-
// If user inserts Page Number, it appears as text.
|
|
205
|
-
// So AutoText MUST contribute to content.
|
|
206
|
-
// We probably need to mock the content of AutoText if it's missing.
|
|
207
|
-
// Or assume `te.autoText` implies some content.
|
|
208
|
-
|
|
209
|
-
// For now, if we encounter an autoText element:
|
|
269
|
+
(element.autoText ? 1 : 0);
|
|
270
|
+
|
|
210
271
|
if (element.autoText) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Check bounds
|
|
221
|
-
// If asString() skips it, its index is not advancing charIndex?
|
|
222
|
-
// This suggests we need to look at how we populate text elements in tests.
|
|
223
|
-
// If we don't allow creating AutoText in tests yet, `getAutoTexts()` will just return empty list.
|
|
224
|
-
// That fulfills the requirement of "Implementing the method".
|
|
225
|
-
// We will implement logic assuming `element.autoText` exists.
|
|
226
|
-
|
|
227
|
-
const autoText = newFakeAutoText(
|
|
228
|
-
newFakeTextRange(this.__shape, charIndex, charIndex + 1), // Assuming length 1
|
|
229
|
-
element.autoText.type,
|
|
230
|
-
autoTextIndex++
|
|
231
|
-
);
|
|
232
|
-
autoTexts.push(autoText);
|
|
272
|
+
if (charIndex >= rangeStart && charIndex < rangeEnd) {
|
|
273
|
+
const autoText = newFakeAutoText(
|
|
274
|
+
newFakeTextRange(this.__shape, charIndex, charIndex + 1),
|
|
275
|
+
element.autoText.type,
|
|
276
|
+
autoTextIndex++
|
|
277
|
+
);
|
|
278
|
+
autoTexts.push(autoText);
|
|
279
|
+
}
|
|
233
280
|
}
|
|
234
281
|
|
|
235
|
-
|
|
236
|
-
charIndex += element.textRun.content.length;
|
|
237
|
-
}
|
|
238
|
-
// Paragraph markers?
|
|
282
|
+
charIndex += elementLength;
|
|
239
283
|
}
|
|
240
284
|
return autoTexts;
|
|
241
285
|
}
|