@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.
Files changed (50) hide show
  1. package/README.md +8 -1
  2. package/package.json +1 -1
  3. package/pngs/srv.jpg +0 -0
  4. package/src/cli/app.js +1 -0
  5. package/src/cli/togas.js +23 -14
  6. package/src/index.js +1 -0
  7. package/src/services/advslides/fakeadvslides.js +11 -5
  8. package/src/services/base/app.js +9 -0
  9. package/src/services/base/fakebase.js +28 -0
  10. package/src/services/common/fakeadvresource.js +3 -2
  11. package/src/services/enums/baseenums.js +47 -0
  12. package/src/services/enums/slidesenums.js +3 -1
  13. package/src/services/html/serverworker.js +1 -1
  14. package/src/services/slidesapp/app.js +5 -0
  15. package/src/services/slidesapp/fakeautofit.js +1 -1
  16. package/src/services/slidesapp/fakeborder.js +106 -0
  17. package/src/services/slidesapp/fakecolorscheme.js +1 -1
  18. package/src/services/slidesapp/fakefill.js +216 -0
  19. package/src/services/slidesapp/fakegroup.js +35 -0
  20. package/src/services/slidesapp/fakeimage.js +118 -0
  21. package/src/services/slidesapp/fakelayout.js +351 -0
  22. package/src/services/slidesapp/fakeline.js +2 -2
  23. package/src/services/slidesapp/fakelinefill.js +15 -16
  24. package/src/services/slidesapp/fakelink.js +20 -3
  25. package/src/services/slidesapp/fakelist.js +36 -0
  26. package/src/services/slidesapp/fakeliststyle.js +105 -0
  27. package/src/services/slidesapp/fakemaster.js +358 -0
  28. package/src/services/slidesapp/fakenotesmaster.js +125 -0
  29. package/src/services/slidesapp/fakenotespage.js +102 -2
  30. package/src/services/slidesapp/fakepagebackground.js +109 -1
  31. package/src/services/slidesapp/fakepageelement.js +157 -18
  32. package/src/services/slidesapp/fakepageelementrange.js +28 -0
  33. package/src/services/slidesapp/fakepagerange.js +28 -0
  34. package/src/services/slidesapp/fakeparagraphstyle.js +139 -0
  35. package/src/services/slidesapp/fakepicturefill.js +32 -0
  36. package/src/services/slidesapp/fakepresentation.js +126 -2
  37. package/src/services/slidesapp/fakeshape.js +9 -0
  38. package/src/services/slidesapp/fakeslide.js +216 -24
  39. package/src/services/slidesapp/fakesolidfill.js +45 -0
  40. package/src/services/slidesapp/fakespeakerspotlight.js +18 -0
  41. package/src/services/slidesapp/faketable.js +55 -9
  42. package/src/services/slidesapp/faketablecell.js +141 -12
  43. package/src/services/slidesapp/faketablecellrange.js +28 -0
  44. package/src/services/slidesapp/faketablecolumn.js +72 -0
  45. package/src/services/slidesapp/faketablerow.js +31 -0
  46. package/src/services/slidesapp/faketextrange.js +179 -135
  47. package/src/services/slidesapp/faketextstyle.js +158 -0
  48. package/src/services/slidesapp/fakevideo.js +35 -0
  49. package/src/services/slidesapp/fakewordart.js +22 -0
  50. package/src/services/slidesapp/pageelementfactory.js +24 -1
@@ -0,0 +1,118 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+ import { newFakeBlob } from '../utilities/fakeblob.js';
3
+ import { FakePageElement, PageElementRegistry } from './fakepageelement.js';
4
+ import { newFakeBorder } from './fakeborder.js';
5
+
6
+ export const newFakeImage = (...args) => {
7
+ const image = Proxies.guard(new FakeImage(...args));
8
+ return image;
9
+ };
10
+
11
+ PageElementRegistry.newFakeImage = newFakeImage;
12
+
13
+ export class FakeImage extends FakePageElement {
14
+ constructor(resource, page) {
15
+ super(resource, page);
16
+ }
17
+
18
+ /**
19
+ * Returns a FakeBlob representing the image content.
20
+ * @param {string} contentType - The MIME type.
21
+ * @returns {FakeBlob}
22
+ */
23
+ getAs(contentType) {
24
+ // Return a dummy blob for now
25
+ return newFakeBlob([], contentType, 'image');
26
+ }
27
+
28
+ /**
29
+ * Returns a FakeBlob representing the image content.
30
+ * @returns {FakeBlob}
31
+ */
32
+ getBlob() {
33
+ return this.getAs('image/png');
34
+ }
35
+
36
+ /**
37
+ * Returns a FakeBorder object.
38
+ * @returns {FakeBorder}
39
+ */
40
+ getBorder() {
41
+ return newFakeBorder(this);
42
+ }
43
+
44
+ /**
45
+ * Gets the URL to the image content.
46
+ * @returns {string}
47
+ */
48
+ getContentUrl() {
49
+ return this.__resource.image?.contentUrl || '';
50
+ }
51
+
52
+ /**
53
+ * Gets the inherent height of the image.
54
+ * @returns {number}
55
+ */
56
+ getInherentHeight() {
57
+ const sourceProps = this.__resource.image?.sourceProperties;
58
+ if (sourceProps && sourceProps.inherentHeight) {
59
+ // Inherent dimensions are in EMUs. Normalize to PT.
60
+ // 1 PT = 12700 EMU.
61
+ // We don't use __normalize because it has a threshold that might skip small EMUs.
62
+ const val = sourceProps.inherentHeight;
63
+ return typeof val === 'number' ? val / 12700 : this.__normalize(val);
64
+ }
65
+ return this.getHeight();
66
+ }
67
+
68
+ /**
69
+ * Gets the inherent width of the image.
70
+ * @returns {number}
71
+ */
72
+ getInherentWidth() {
73
+ const sourceProps = this.__resource.image?.sourceProperties;
74
+ if (sourceProps && sourceProps.inherentWidth) {
75
+ const val = sourceProps.inherentWidth;
76
+ return typeof val === 'number' ? val / 12700 : this.__normalize(val);
77
+ }
78
+ return this.getWidth();
79
+ }
80
+
81
+ /**
82
+ * Returns the parent placeholder or null.
83
+ * @returns {FakePageElement | null}
84
+ */
85
+ getParentPlaceholder() {
86
+ // Placeholder logic usually involves finding the element referenced by parentObjectId
87
+ return null;
88
+ }
89
+
90
+ /**
91
+ * Returns the placeholder index or null.
92
+ * @returns {number | null}
93
+ */
94
+ getPlaceholderIndex() {
95
+ return this.__resource.image?.placeholder?.index ?? null;
96
+ }
97
+
98
+ /**
99
+ * Returns the placeholder type.
100
+ * @returns {PlaceholderType}
101
+ */
102
+ getPlaceholderType() {
103
+ const type = this.__resource.image?.placeholder?.type;
104
+ return type ? SlidesApp.PlaceholderType[type] : SlidesApp.PlaceholderType.NONE;
105
+ }
106
+
107
+ /**
108
+ * Gets the source URL of the image.
109
+ * @returns {string}
110
+ */
111
+ getSourceUrl() {
112
+ return this.__resource.image?.sourceUrl || null;
113
+ }
114
+
115
+ toString() {
116
+ return 'Image';
117
+ }
118
+ }
@@ -1,6 +1,8 @@
1
1
  import { Proxies } from '../../support/proxies.js';
2
2
  import { newFakeMaster } from './fakemaster.js';
3
3
  import { newFakeColorScheme } from './fakecolorscheme.js';
4
+ import { newFakePageBackground } from './fakepagebackground.js';
5
+ import { newFakePageElement, PageElementRegistry } from './fakepageelement.js';
4
6
 
5
7
  export const newFakeLayout = (...args) => {
6
8
  return Proxies.guard(new FakeLayout(...args));
@@ -21,6 +23,10 @@ export class FakeLayout {
21
23
  return layout;
22
24
  }
23
25
 
26
+ getLayoutName() {
27
+ return this.__resource.layoutProperties?.name || '';
28
+ }
29
+
24
30
  getMaster() {
25
31
  const masterId = this.__resource.layoutProperties?.masterObjectId;
26
32
  if (!masterId) return null;
@@ -34,6 +40,14 @@ export class FakeLayout {
34
40
  return this.__id;
35
41
  }
36
42
 
43
+ /**
44
+ * Gets the background of the layout.
45
+ * @returns {FakePageBackground} The background.
46
+ */
47
+ getBackground() {
48
+ return newFakePageBackground(this);
49
+ }
50
+
37
51
  /**
38
52
  * Gets the color scheme of the layout.
39
53
  * @returns {FakeColorScheme} The color scheme.
@@ -42,6 +56,343 @@ export class FakeLayout {
42
56
  return newFakeColorScheme(this);
43
57
  }
44
58
 
59
+ /**
60
+ * Gets the type of the page.
61
+ * @returns {SlidesApp.PageType}
62
+ */
63
+ getPageType() {
64
+ return SlidesApp.PageType.LAYOUT;
65
+ }
66
+
67
+ /**
68
+ * Gets the list of page elements on the layout.
69
+ * @returns {FakePageElement[]} The page elements.
70
+ */
71
+ getPageElements() {
72
+ return (this.__resource.pageElements || []).map(pe => newFakePageElement(pe, this));
73
+ }
74
+
75
+ /**
76
+ * Gets a page element by ID.
77
+ * @param {string} id The ID.
78
+ * @returns {FakePageElement|null} The element.
79
+ */
80
+ getPageElementById(id) {
81
+ return this.getPageElements().find(pe => pe.getObjectId() === id) || null;
82
+ }
83
+
84
+ getGroups() {
85
+ return this.getPageElements()
86
+ .filter(pe => pe.getPageElementType().toString() === 'GROUP')
87
+ .map(pe => pe.asGroup());
88
+ }
89
+
90
+ getImages() {
91
+ return this.getPageElements()
92
+ .filter(pe => pe.getPageElementType().toString() === 'IMAGE')
93
+ .map(pe => pe.asImage());
94
+ }
95
+
96
+ getLines() {
97
+ return this.getPageElements()
98
+ .filter(pe => pe.getPageElementType().toString() === 'LINE')
99
+ .map(pe => pe.asLine());
100
+ }
101
+
102
+ getShapes() {
103
+ return this.getPageElements()
104
+ .filter(pe => pe.getPageElementType().toString() === 'SHAPE')
105
+ .map(pe => pe.asShape());
106
+ }
107
+
108
+ getTables() {
109
+ return this.getPageElements()
110
+ .filter(pe => pe.getPageElementType().toString() === 'TABLE')
111
+ .map(pe => pe.asTable());
112
+ }
113
+
114
+ getVideos() {
115
+ return this.getPageElements()
116
+ .filter(pe => pe.getPageElementType().toString() === 'VIDEO')
117
+ .map(pe => pe.asVideo());
118
+ }
119
+
120
+ getWordArts() {
121
+ return this.getPageElements()
122
+ .filter(pe => pe.getPageElementType().toString() === 'WORD_ART')
123
+ .map(pe => pe.asWordArt());
124
+ }
125
+
126
+ getSheetsCharts() {
127
+ return this.getPageElements()
128
+ .filter(pe => pe.getPageElementType().toString() === 'SHEETS_CHART')
129
+ .map(pe => pe.asSheetsChart());
130
+ }
131
+
132
+ /**
133
+ * Inserts a Google Sheets chart on the layout.
134
+ * @param {EmbeddedChart} chart The chart.
135
+ * @returns {SheetsChart} The inserted chart.
136
+ */
137
+ insertSheetsChart(chart) {
138
+ const presentationId = this.__presentation.getId();
139
+ const objectId = `chart_${Math.random().toString(36).substring(2, 11)}`;
140
+ const spreadsheetId = chart.getSpreadsheetId ? chart.getSpreadsheetId() : '';
141
+ const chartId = chart.getChartId ? chart.getChartId() : 0;
142
+
143
+ const requests = [{
144
+ createSheetsChart: {
145
+ objectId,
146
+ spreadsheetId,
147
+ chartId,
148
+ linkingMode: 'LINKED',
149
+ elementProperties: {
150
+ pageObjectId: this.getObjectId(),
151
+ size: {
152
+ width: { magnitude: 400, unit: 'PT' },
153
+ height: { magnitude: 300, unit: 'PT' }
154
+ }
155
+ }
156
+ }
157
+ }];
158
+
159
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
160
+ return this.getPageElementById(objectId).asSheetsChart();
161
+ }
162
+
163
+ /**
164
+ * Inserts a Google Sheets chart as an image on the layout.
165
+ * @param {EmbeddedChart} chart The chart.
166
+ * @returns {Image} The inserted image.
167
+ */
168
+ insertSheetsChartAsImage(chart) {
169
+ const presentationId = this.__presentation.getId();
170
+ const objectId = `chart_img_${Math.random().toString(36).substring(2, 11)}`;
171
+ const requests = [{
172
+ createImage: {
173
+ objectId,
174
+ url: 'https://via.placeholder.com/400x300?text=Sheets+Chart',
175
+ elementProperties: {
176
+ pageObjectId: this.getObjectId()
177
+ }
178
+ }
179
+ }];
180
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
181
+ return this.getPageElementById(objectId).asImage();
182
+ }
183
+
184
+ getPlaceholders() {
185
+ // Basic implementation filtering elements with placeholder property
186
+ return this.getPageElements().filter(pe => pe.__resource.shape?.placeholder || pe.__resource.image?.placeholder);
187
+ }
188
+
189
+ getPlaceholder(placeholderType, index = 0) {
190
+ const typeStr = placeholderType.toString();
191
+ return this.getPlaceholders().find(p => {
192
+ const ph = p.__resource.shape?.placeholder || p.__resource.image?.placeholder;
193
+ return ph.type === typeStr && (ph.index === index || (index === 0 && ph.index === undefined));
194
+ }) || null;
195
+ }
196
+
197
+ /**
198
+ * Inserts a shape.
199
+ */
200
+ insertShape(shapeType, left = 0, top = 0, width = 300, height = 300) {
201
+ const presentationId = this.__presentation.getId();
202
+ const objectId = `shape_${Math.random().toString(36).substring(2, 11)}`;
203
+ const requests = [{
204
+ createShape: {
205
+ objectId,
206
+ shapeType: shapeType.toString(),
207
+ elementProperties: {
208
+ pageObjectId: this.getObjectId(),
209
+ size: {
210
+ width: { magnitude: width, unit: 'PT' },
211
+ height: { magnitude: height, unit: 'PT' }
212
+ },
213
+ transform: {
214
+ scaleX: 1,
215
+ scaleY: 1,
216
+ translateX: left,
217
+ translateY: top,
218
+ unit: 'PT'
219
+ }
220
+ }
221
+ }
222
+ }];
223
+
224
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
225
+ return this.getPageElementById(objectId).asShape();
226
+ }
227
+
228
+ insertTextBox(text, left = 0, top = 0, width = 300, height = 50) {
229
+ const shape = this.insertShape(SlidesApp.ShapeType.TEXT_BOX, left, top, width, height);
230
+ if (text) shape.getText().setText(text);
231
+ return shape;
232
+ }
233
+
234
+ insertTable(rows, columns, left = 0, top = 0, width = 300, height = 300) {
235
+ const presentationId = this.__presentation.getId();
236
+ const objectId = `table_${Math.random().toString(36).substring(2, 11)}`;
237
+ const requests = [{
238
+ createTable: {
239
+ objectId,
240
+ rows,
241
+ columns,
242
+ elementProperties: {
243
+ pageObjectId: this.getObjectId(),
244
+ size: {
245
+ width: { magnitude: width, unit: 'PT' },
246
+ height: { magnitude: height, unit: 'PT' }
247
+ },
248
+ transform: {
249
+ scaleX: 1,
250
+ scaleY: 1,
251
+ translateX: left,
252
+ translateY: top,
253
+ unit: 'PT'
254
+ }
255
+ }
256
+ }
257
+ }];
258
+
259
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
260
+ return this.getPageElementById(objectId).asTable();
261
+ }
262
+
263
+ /**
264
+ * Inserts a video at the top left corner of the layout.
265
+ * @param {string} videoUrl The video URL.
266
+ * @param {number} [left]
267
+ * @param {number} [top]
268
+ * @param {number} [width]
269
+ * @param {number} [height]
270
+ * @returns {FakeVideo} The inserted video.
271
+ */
272
+ insertVideo(videoUrl, left = 0, top = 0, width = 300, height = 200) {
273
+ const presentationId = this.__presentation.getId();
274
+ const objectId = `video_${Math.random().toString(36).substring(2, 11)}`;
275
+
276
+ let videoId = videoUrl;
277
+ if (videoUrl.includes('v=')) {
278
+ videoId = videoUrl.split('v=')[1].split('&')[0];
279
+ } else if (videoUrl.includes('youtu.be/')) {
280
+ videoId = videoUrl.split('youtu.be/')[1].split('?')[0];
281
+ }
282
+
283
+ const requests = [{
284
+ createVideo: {
285
+ objectId,
286
+ source: 'YOUTUBE',
287
+ id: videoId,
288
+ elementProperties: {
289
+ pageObjectId: this.getObjectId(),
290
+ size: {
291
+ width: { magnitude: width, unit: 'PT' },
292
+ height: { magnitude: height, unit: 'PT' }
293
+ },
294
+ transform: {
295
+ scaleX: 1,
296
+ scaleY: 1,
297
+ translateX: left,
298
+ translateY: top,
299
+ unit: 'PT'
300
+ }
301
+ }
302
+ }
303
+ }];
304
+
305
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
306
+ return this.getPageElementById(objectId).asVideo();
307
+ }
308
+
309
+ insertImage(urlOrBlob, left = 0, top = 0, width = 300, height = 300) {
310
+ const presentationId = this.__presentation.getId();
311
+ const objectId = `image_${Math.random().toString(36).substring(2, 11)}`;
312
+ let url = typeof urlOrBlob === 'string' ? urlOrBlob : '';
313
+ // If blob, we'd need to upload it or mock it. For now assuming URL or empty.
314
+
315
+ const requests = [{
316
+ createImage: {
317
+ objectId,
318
+ url: url || 'https://via.placeholder.com/150',
319
+ elementProperties: {
320
+ pageObjectId: this.getObjectId(),
321
+ size: {
322
+ width: { magnitude: width, unit: 'PT' },
323
+ height: { magnitude: height, unit: 'PT' }
324
+ },
325
+ transform: {
326
+ scaleX: 1,
327
+ scaleY: 1,
328
+ translateX: left,
329
+ translateY: top,
330
+ unit: 'PT'
331
+ }
332
+ }
333
+ }
334
+ }];
335
+
336
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
337
+ return this.getPageElementById(objectId).asImage();
338
+ }
339
+
340
+ insertLine(lineCategory, startX, startY, endX, endY) {
341
+ const presentationId = this.__presentation.getId();
342
+ const objectId = `line_${Math.random().toString(36).substring(2, 11)}`;
343
+ const requests = [{
344
+ createLine: {
345
+ objectId,
346
+ lineCategory: lineCategory.toString(),
347
+ elementProperties: {
348
+ pageObjectId: this.getObjectId(),
349
+ size: {
350
+ width: { magnitude: Math.abs(endX - startX), unit: 'PT' },
351
+ height: { magnitude: Math.abs(endY - startY), unit: 'PT' }
352
+ },
353
+ transform: {
354
+ scaleX: 1,
355
+ scaleY: 1,
356
+ translateX: Math.min(startX, endX),
357
+ translateY: Math.min(startY, endY),
358
+ unit: 'PT'
359
+ }
360
+ }
361
+ }
362
+ }];
363
+
364
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
365
+ return this.getPageElementById(objectId).asLine();
366
+ }
367
+
368
+ remove() {
369
+ const presentationId = this.__presentation.getId();
370
+ Slides.Presentations.batchUpdate({ requests: [{
371
+ deleteObject: {
372
+ objectId: this.getObjectId()
373
+ }
374
+ }] }, presentationId);
375
+ }
376
+
377
+ replaceAllText(findText, replaceText, matchCase = false) {
378
+ const presentationId = this.__presentation.getId();
379
+ Slides.Presentations.batchUpdate({ requests: [{
380
+ replaceAllText: {
381
+ replaceText,
382
+ containsText: {
383
+ text: findText,
384
+ matchCase
385
+ },
386
+ pageObjectIds: [this.getObjectId()]
387
+ }
388
+ }] }, presentationId);
389
+ return this;
390
+ }
391
+
392
+ selectAsCurrentPage() {
393
+ return this;
394
+ }
395
+
45
396
  toString() {
46
397
  return 'Layout';
47
398
  }
@@ -180,13 +180,13 @@ export class FakeLine extends FakePageElement {
180
180
 
181
181
  __updateLineProps(lineProperties, fields) {
182
182
  const presentationId = this.__page.__presentation?.getId() || this.__page.__slide?.__presentation.getId();
183
- Slides.Presentations.batchUpdate([{
183
+ Slides.Presentations.batchUpdate({ requests: [{
184
184
  updateLineProperties: {
185
185
  objectId: this.getObjectId(),
186
186
  lineProperties: lineProperties,
187
187
  fields: fields
188
188
  }
189
- }], presentationId);
189
+ }] }, presentationId);
190
190
  }
191
191
 
192
192
  toString() {
@@ -14,32 +14,31 @@ export class FakeLineFill {
14
14
  }
15
15
 
16
16
  getSolidFill() {
17
- // This should return a SolidFill object
18
- // For now we might need a FakeSolidFill or just return something simple
19
17
  return null;
20
18
  }
21
19
 
22
20
  setSolidFill(color) {
23
- // Implementing this requires updateLineProperties with solidFill
24
21
  const presentationId = this.__line.__page.__presentation?.getId() || this.__line.__page.__slide?.__presentation.getId();
25
22
 
26
23
  let solidFill = {};
27
24
  if (typeof color === 'string') {
28
25
  solidFill = { color: { rgbColor: this.__hexToRgb(color) } };
29
26
  }
30
- // Handle other color types if needed
31
-
32
- Slides.Presentations.batchUpdate([{
33
- updateLineProperties: {
34
- objectId: this.__line.getObjectId(),
35
- lineProperties: {
36
- lineFill: {
37
- solidFill: solidFill
38
- }
39
- },
40
- fields: 'lineFill.solidFill'
41
- }
42
- }], presentationId);
27
+
28
+ Slides.Presentations.batchUpdate({
29
+ requests: [{
30
+ updateLineProperties: {
31
+ objectId: this.__line.getObjectId(),
32
+ lineProperties: {
33
+ lineFill: {
34
+ solidFill: solidFill
35
+ }
36
+ },
37
+ fields: 'lineFill.solidFill'
38
+ }
39
+ }]
40
+ }, presentationId);
41
+
43
42
  return this;
44
43
  }
45
44
 
@@ -5,8 +5,9 @@ export const newFakeLink = (...args) => {
5
5
  };
6
6
 
7
7
  export class FakeLink {
8
- constructor(resource) {
8
+ constructor(resource, presentation) {
9
9
  this.__resource = resource;
10
+ this.__presentation = presentation;
10
11
  }
11
12
 
12
13
  getLinkType() {
@@ -17,14 +18,30 @@ export class FakeLink {
17
18
  return 'NONE';
18
19
  }
19
20
 
20
- getUrl() {
21
- return this.__resource.url || null;
21
+ getLinkedSlide() {
22
+ const slideId = this.getSlideId();
23
+ return slideId ? this.__presentation.getSlideById(slideId) : null;
22
24
  }
23
25
 
24
26
  getSlideId() {
25
27
  return this.__resource.slideId || null;
26
28
  }
27
29
 
30
+ getSlideIndex() {
31
+ // Requires iterating slides to find index.
32
+ const slideId = this.getSlideId();
33
+ if (!slideId) return null;
34
+ return this.__presentation.getSlides().findIndex(s => s.getObjectId() === slideId);
35
+ }
36
+
37
+ getSlidePosition() {
38
+ return this.__resource.relativeSlide || null;
39
+ }
40
+
41
+ getUrl() {
42
+ return this.__resource.url || null;
43
+ }
44
+
28
45
  toString() {
29
46
  return 'Link';
30
47
  }
@@ -0,0 +1,36 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+ import { newFakeParagraph } from './fakeparagraph.js';
3
+ import { newFakeTextRange } from './faketextrange.js';
4
+
5
+ /**
6
+ * create a new FakeList instance
7
+ * @param {...any} args
8
+ * @returns {FakeList}
9
+ */
10
+ export const newFakeList = (...args) => {
11
+ return Proxies.guard(new FakeList(...args));
12
+ };
13
+
14
+ export class FakeList {
15
+ constructor(listId, presentation, shape) {
16
+ this.__listId = listId;
17
+ this.__presentation = presentation;
18
+ this.__shape = shape;
19
+ }
20
+
21
+ getListId() {
22
+ return this.__listId;
23
+ }
24
+
25
+ getListParagraphs() {
26
+ // Find all paragraphs in the shape that belong to this list
27
+ return this.__shape.getText().getParagraphs().filter(p => {
28
+ const style = p.getRange().getListStyle();
29
+ return style.isInList() && style.getList().getListId() === this.__listId;
30
+ });
31
+ }
32
+
33
+ toString() {
34
+ return 'List';
35
+ }
36
+ }