@mcpher/gas-fakes 2.5.2 → 2.5.4

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 (76) hide show
  1. package/README.md +17 -3
  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/content/contentservice.js +3 -2
  12. package/src/services/enums/baseenums.js +47 -0
  13. package/src/services/enums/contentenums.js +1 -3
  14. package/src/services/enums/scriptenums.js +31 -4
  15. package/src/services/enums/slidesenums.js +3 -1
  16. package/src/services/enums/xmlenums.js +14 -0
  17. package/src/services/html/serverworker.js +1 -1
  18. package/src/services/scriptapp/app.js +14 -7
  19. package/src/services/scriptapp/fakeauthorizationinfo.js +4 -4
  20. package/src/services/slidesapp/app.js +5 -0
  21. package/src/services/slidesapp/fakeautofit.js +1 -1
  22. package/src/services/slidesapp/fakeborder.js +106 -0
  23. package/src/services/slidesapp/fakecolorscheme.js +1 -1
  24. package/src/services/slidesapp/fakefill.js +216 -0
  25. package/src/services/slidesapp/fakegroup.js +35 -0
  26. package/src/services/slidesapp/fakeimage.js +118 -0
  27. package/src/services/slidesapp/fakelayout.js +351 -0
  28. package/src/services/slidesapp/fakeline.js +2 -2
  29. package/src/services/slidesapp/fakelinefill.js +15 -16
  30. package/src/services/slidesapp/fakelink.js +20 -3
  31. package/src/services/slidesapp/fakelist.js +36 -0
  32. package/src/services/slidesapp/fakeliststyle.js +105 -0
  33. package/src/services/slidesapp/fakemaster.js +358 -0
  34. package/src/services/slidesapp/fakenotesmaster.js +125 -0
  35. package/src/services/slidesapp/fakenotespage.js +102 -2
  36. package/src/services/slidesapp/fakepagebackground.js +109 -1
  37. package/src/services/slidesapp/fakepageelement.js +157 -18
  38. package/src/services/slidesapp/fakepageelementrange.js +28 -0
  39. package/src/services/slidesapp/fakepagerange.js +28 -0
  40. package/src/services/slidesapp/fakeparagraphstyle.js +139 -0
  41. package/src/services/slidesapp/fakepicturefill.js +32 -0
  42. package/src/services/slidesapp/fakepresentation.js +126 -2
  43. package/src/services/slidesapp/fakeshape.js +9 -0
  44. package/src/services/slidesapp/fakeslide.js +216 -24
  45. package/src/services/slidesapp/fakesolidfill.js +45 -0
  46. package/src/services/slidesapp/fakespeakerspotlight.js +18 -0
  47. package/src/services/slidesapp/faketable.js +55 -9
  48. package/src/services/slidesapp/faketablecell.js +141 -12
  49. package/src/services/slidesapp/faketablecellrange.js +28 -0
  50. package/src/services/slidesapp/faketablecolumn.js +72 -0
  51. package/src/services/slidesapp/faketablerow.js +31 -0
  52. package/src/services/slidesapp/faketextrange.js +179 -135
  53. package/src/services/slidesapp/faketextstyle.js +158 -0
  54. package/src/services/slidesapp/fakevideo.js +35 -0
  55. package/src/services/slidesapp/fakewordart.js +22 -0
  56. package/src/services/slidesapp/pageelementfactory.js +24 -1
  57. package/src/services/spreadsheetapp/fakeembeddedchartbuilder.js +92 -12
  58. package/src/services/spreadsheetapp/fakespreadsheet.js +360 -62
  59. package/src/services/spreadsheetapp/fakespreadsheettheme.js +53 -0
  60. package/src/services/urlfetchapp/app.js +216 -175
  61. package/src/services/xmlservice/app.js +3 -78
  62. package/src/services/xmlservice/fakeattribute.js +15 -0
  63. package/src/services/xmlservice/fakecdata.js +40 -0
  64. package/src/services/xmlservice/fakecomment.js +34 -0
  65. package/src/services/xmlservice/fakecontent.js +51 -0
  66. package/src/services/xmlservice/fakedoctype.js +68 -0
  67. package/src/services/xmlservice/fakedocument.js +110 -13
  68. package/src/services/xmlservice/fakeelement.js +297 -82
  69. package/src/services/xmlservice/fakeentityref.js +54 -0
  70. package/src/services/xmlservice/fakeformat.js +67 -22
  71. package/src/services/xmlservice/fakeprocessinginstruction.js +44 -0
  72. package/src/services/xmlservice/faketext.js +39 -0
  73. package/src/services/xmlservice/fakexmlservice.js +118 -0
  74. package/src/support/sxfetch.js +60 -0
  75. package/tools/omlx.env.example +6 -0
  76. package/tools/omlx_mcp_server.cjs +157 -0
@@ -1,4 +1,7 @@
1
1
  import { Proxies } from '../../support/proxies.js';
2
+ import { newFakeSolidFill } from './fakesolidfill.js';
3
+ import { newFakePictureFill } from './fakepicturefill.js';
4
+ import { PageBackgroundType } from '../enums/slidesenums.js';
2
5
 
3
6
  export const newFakePageBackground = (...args) => {
4
7
  return Proxies.guard(new FakePageBackground(...args));
@@ -8,9 +11,114 @@ export class FakePageBackground {
8
11
  constructor(page) {
9
12
  this.__page = page;
10
13
  }
14
+
11
15
  get __resource() {
12
- return this.__page.__resource.pageBackgroundFill || null;
16
+ const res = this.__page.__resource;
17
+ if (res && res.pageProperties && res.pageProperties.pageBackgroundFill) {
18
+ return res.pageProperties.pageBackgroundFill;
19
+ }
20
+ return null;
21
+ }
22
+
23
+ getPictureFill() {
24
+ const res = this.__resource;
25
+ return res?.stretchedPictureFill ? newFakePictureFill(res.stretchedPictureFill, this.__page) : null;
26
+ }
27
+
28
+ getSolidFill() {
29
+ return newFakeSolidFill(this.__page);
13
30
  }
31
+
32
+ getType() {
33
+ const res = this.__resource;
34
+ if (!res || res.propertyState === 'NOT_RENDERED') return PageBackgroundType.NONE;
35
+ if (res.stretchedPictureFill) return PageBackgroundType.PICTURE;
36
+ if (res.solidFill) return PageBackgroundType.SOLID;
37
+ return PageBackgroundType.NONE;
38
+ }
39
+
40
+ isVisible() {
41
+ return this.getType().toString() !== 'NONE';
42
+ }
43
+
44
+ setPictureFill(urlOrBlob) {
45
+ const presentationId = this.__page.__presentation.getId();
46
+ let url = typeof urlOrBlob === 'string' ? urlOrBlob : '';
47
+
48
+ const requests = [{
49
+ updatePageProperties: {
50
+ objectId: this.__page.getObjectId(),
51
+ pageProperties: {
52
+ pageBackgroundFill: {
53
+ stretchedPictureFill: {
54
+ contentUrl: url
55
+ }
56
+ }
57
+ },
58
+ fields: 'pageBackgroundFill'
59
+ }
60
+ }];
61
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
62
+
63
+ return this;
64
+ }
65
+
66
+ setSolidFill(color, alpha = 1.0) {
67
+ const presentationId = this.__page.__presentation.getId();
68
+
69
+ let solidFill = {};
70
+ if (typeof color === 'string') {
71
+ const hex = color.replace('#', '');
72
+ solidFill = {
73
+ color: {
74
+ rgbColor: {
75
+ red: parseInt(hex.substring(0, 2), 16) / 255,
76
+ green: parseInt(hex.substring(2, 4), 16) / 255,
77
+ blue: parseInt(hex.substring(4, 6), 16) / 255
78
+ }
79
+ }
80
+ };
81
+ } else if (color && color.toString() === 'Color') {
82
+ solidFill = { color: { themeColor: 'ACCENT1' } };
83
+ }
84
+
85
+ if (alpha !== 1.0) {
86
+ solidFill.alpha = alpha;
87
+ }
88
+
89
+ const requests = [{
90
+ updatePageProperties: {
91
+ objectId: this.__page.getObjectId(),
92
+ pageProperties: {
93
+ pageBackgroundFill: {
94
+ propertyState: 'RENDERED',
95
+ solidFill: solidFill
96
+ }
97
+ },
98
+ fields: 'pageBackgroundFill'
99
+ }
100
+ }];
101
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
102
+ return this;
103
+ }
104
+
105
+ setTransparent() {
106
+ const presentationId = this.__page.__presentation.getId();
107
+ const requests = [{
108
+ updatePageProperties: {
109
+ objectId: this.__page.getObjectId(),
110
+ pageProperties: {
111
+ pageBackgroundFill: {
112
+ propertyState: 'NOT_RENDERED'
113
+ }
114
+ },
115
+ fields: 'pageBackgroundFill'
116
+ }
117
+ }];
118
+ Slides.Presentations.batchUpdate({ requests }, presentationId);
119
+ return this;
120
+ }
121
+
14
122
  toString() {
15
123
  return 'PageBackground';
16
124
  }
@@ -29,9 +29,28 @@ export class FakePageElement {
29
29
 
30
30
  get __resource() {
31
31
  const pageResource = this.__page.__resource;
32
- const element = (pageResource.pageElements || []).find(e => e.objectId === this.__id);
32
+ const allElements = pageResource.pageElements || [];
33
+
34
+ const findElement = (elements, targetId) => {
35
+ for (const element of elements) {
36
+ if (element.objectId === targetId) {
37
+ return element;
38
+ }
39
+ if (element.group && element.group.children) {
40
+ const found = findElement(element.group.children, targetId);
41
+ if (found) return found;
42
+ }
43
+ if (element.elementGroup && element.elementGroup.children) {
44
+ const found = findElement(element.elementGroup.children, targetId);
45
+ if (found) return found;
46
+ }
47
+ }
48
+ return null;
49
+ };
50
+
51
+ const element = findElement(allElements, this.__id);
33
52
  if (!element) {
34
- throw new Error(`PageElement with ID ${this.__id} not found on page`);
53
+ throw new Error(`Exception: Page element (${this.__id}) could not be found.`);
35
54
  }
36
55
  return element;
37
56
  }
@@ -52,6 +71,18 @@ export class FakePageElement {
52
71
  throw new Error('PageElement is not a shape.');
53
72
  }
54
73
 
74
+ /**
75
+ * Returns the page element as an image.
76
+ * @returns {FakeImage} The image.
77
+ */
78
+ asImage() {
79
+ if (this.__resource.image) {
80
+ const { newFakeImage } = PageElementRegistry;
81
+ return newFakeImage(this.__resource, this.__page);
82
+ }
83
+ throw new Error('PageElement is not an image.');
84
+ }
85
+
55
86
  /**
56
87
  * Returns the page element as a line.
57
88
  * @returns {FakeLine} The line.
@@ -76,6 +107,54 @@ export class FakePageElement {
76
107
  throw new Error('PageElement is not a table.');
77
108
  }
78
109
 
110
+ /**
111
+ * Returns the page element as a group.
112
+ * @returns {FakeGroup} The group.
113
+ */
114
+ asGroup() {
115
+ if (this.__resource.elementGroup || this.__resource.group) {
116
+ const { newFakeGroup } = PageElementRegistry;
117
+ return newFakeGroup(this.__resource, this.__page);
118
+ }
119
+ throw new Error('PageElement is not a group.');
120
+ }
121
+
122
+ /**
123
+ * Returns the page element as a video.
124
+ * @returns {FakeVideo} The video.
125
+ */
126
+ asVideo() {
127
+ if (this.__resource.video) {
128
+ const { newFakeVideo } = PageElementRegistry;
129
+ return newFakeVideo(this.__resource, this.__page);
130
+ }
131
+ throw new Error('PageElement is not a video.');
132
+ }
133
+
134
+ /**
135
+ * Returns the page element as a speaker spotlight.
136
+ * @returns {FakeSpeakerSpotlight} The speaker spotlight.
137
+ */
138
+ asSpeakerSpotlight() {
139
+ if (this.__resource.speakerSpotlight) {
140
+ const { newFakeSpeakerSpotlight } = PageElementRegistry;
141
+ return newFakeSpeakerSpotlight(this.__resource, this.__page);
142
+ }
143
+ throw new Error('PageElement is not a speaker spotlight.');
144
+ }
145
+
146
+ /**
147
+ * Returns the page element as word art.
148
+ * @returns {FakeWordArt} The word art.
149
+ */
150
+ asWordArt() {
151
+ if (this.__resource.wordArt) {
152
+ const { newFakeWordArt } = PageElementRegistry;
153
+ return newFakeWordArt(this.__resource, this.__page);
154
+ }
155
+ throw new Error('PageElement is not word art.');
156
+ }
157
+
79
158
  /**
80
159
  * Gets the type of the page element.
81
160
  * @returns {SlidesApp.PageElementType} The type.
@@ -103,12 +182,20 @@ export class FakePageElement {
103
182
  if (this.__resource.sheetsChart) {
104
183
  return types.SHEETS_CHART;
105
184
  }
106
- if (this.__resource.group) {
185
+ if (this.__resource.elementGroup || this.__resource.group) {
107
186
  return types.GROUP;
108
187
  }
109
188
  return types.UNSUPPORTED;
110
189
  }
111
190
 
191
+ getInherentHeight() {
192
+ return this.__normalize(this.__resource.size?.height);
193
+ }
194
+
195
+ getInherentWidth() {
196
+ return this.__normalize(this.__resource.size?.width);
197
+ }
198
+
112
199
  getLeft() {
113
200
  return this.__normalize(this.__resource.transform?.translateX);
114
201
  }
@@ -150,13 +237,21 @@ export class FakePageElement {
150
237
  }
151
238
 
152
239
  getRotation() {
153
- // Rotation can be calculated from scale and shear in affine transform
154
- // But for fakes, we might just return 0 if not easily available.
240
+ if (this._rotation !== undefined) {
241
+ return this._rotation;
242
+ }
243
+ const t = this.__resource.transform;
244
+ if (t && (t.shearY !== undefined || t.scaleX !== undefined)) {
245
+ const shearY = t.shearY || 0;
246
+ const scaleX = t.scaleX || 1;
247
+ const angle = Math.round(Math.atan2(shearY, scaleX) * (180 / Math.PI));
248
+ return (angle + 360) % 360;
249
+ }
155
250
  return 0;
156
251
  }
157
252
 
158
253
  setRotation(angle) {
159
- // In API, we usually setting rotation via updatePageElementTransform with RELATIVE mode or similar
254
+ this._rotation = angle;
160
255
  return this;
161
256
  }
162
257
 
@@ -191,13 +286,13 @@ export class FakePageElement {
191
286
 
192
287
  alignOnPage(alignmentPosition) {
193
288
  const presentationId = this.__page.__presentation?.getId() || this.__page.__slide?.__presentation.getId();
194
- Slides.Presentations.batchUpdate([{
289
+ Slides.Presentations.batchUpdate({ requests: [{
195
290
  updatePageElementProperties: {
196
291
  objectId: this.getObjectId(),
197
292
  pageElementProperties: {}, // API doesn't have direct align?
198
293
  fields: '*'
199
294
  }
200
- }], presentationId);
295
+ }] }, presentationId);
201
296
  return this;
202
297
  }
203
298
 
@@ -231,11 +326,11 @@ export class FakePageElement {
231
326
 
232
327
  remove() {
233
328
  const presentationId = this.__page.__presentation.getId();
234
- Slides.Presentations.batchUpdate([{
329
+ Slides.Presentations.batchUpdate({ requests: [{
235
330
  deleteObject: {
236
331
  objectId: this.getObjectId()
237
332
  }
238
- }], presentationId);
333
+ }] }, presentationId);
239
334
  }
240
335
 
241
336
  bringForward() {
@@ -300,7 +395,7 @@ export class FakePageElement {
300
395
  __updateTransform(transform) {
301
396
  const t = this.getTransform();
302
397
  const presentationId = this.__page.__presentation?.getId() || this.__page.__slide?.__presentation.getId();
303
- Slides.Presentations.batchUpdate([{
398
+ Slides.Presentations.batchUpdate({ requests: [{
304
399
  updatePageElementTransform: {
305
400
  objectId: this.getObjectId(),
306
401
  transform: {
@@ -315,7 +410,7 @@ export class FakePageElement {
315
410
  },
316
411
  applyMode: 'ABSOLUTE'
317
412
  }
318
- }], presentationId);
413
+ }] }, presentationId);
319
414
  }
320
415
 
321
416
  __updateSize(size) {
@@ -338,13 +433,13 @@ export class FakePageElement {
338
433
 
339
434
  __updateAltText(title, description) {
340
435
  const presentationId = this.__page.__presentation.getId();
341
- Slides.Presentations.batchUpdate([{
436
+ Slides.Presentations.batchUpdate({ requests: [{
342
437
  updatePageElementAltText: {
343
438
  objectId: this.getObjectId(),
344
439
  title: title,
345
440
  description: description
346
441
  }
347
- }], presentationId);
442
+ }] }, presentationId);
348
443
  }
349
444
 
350
445
  __updateProperties(props, fields) {
@@ -373,18 +468,18 @@ export class FakePageElement {
373
468
  if (request) {
374
469
  if (request.updateShapeProperties) request.updateShapeProperties.fields = fields || '*';
375
470
  if (request.updateLineProperties) request.updateLineProperties.fields = fields || '*';
376
- Slides.Presentations.batchUpdate([request], presentationId);
471
+ Slides.Presentations.batchUpdate({ requests: [request] }, presentationId);
377
472
  }
378
473
  }
379
474
 
380
475
  __updateZOrder(operation) {
381
476
  const presentationId = this.__page.__presentation.getId();
382
- Slides.Presentations.batchUpdate([{
477
+ Slides.Presentations.batchUpdate({ requests: [{
383
478
  updatePageElementZOrder: {
384
479
  pageElementObjectIds: [this.getObjectId()],
385
480
  zOrderOperation: operation
386
481
  }
387
- }], presentationId);
482
+ }] }, presentationId);
388
483
  }
389
484
 
390
485
  /**
@@ -396,6 +491,43 @@ export class FakePageElement {
396
491
  // For now, let's return a fixed number as a mock.
397
492
  return [0, 1, 2, 3].map(index => newFakeConnectionSite(this, index));
398
493
  }
494
+ scaleHeight(ratio) {
495
+ this.setHeight(this.getHeight() * ratio);
496
+ return this;
497
+ }
498
+
499
+ scaleWidth(ratio) {
500
+ this.setWidth(this.getWidth() * ratio);
501
+ return this;
502
+ }
503
+
504
+ select(replace = true) {
505
+ return this;
506
+ }
507
+
508
+ duplicate() {
509
+ const presentationId = this.__page.__presentation?.getId() || this.__page.__slide?.__presentation.getId();
510
+ const newObjectId = `duplicate_${Math.random().toString(36).substr(2, 9)}`;
511
+
512
+ Slides.Presentations.batchUpdate({ requests: [{
513
+ duplicateObject: {
514
+ objectId: this.getObjectId(),
515
+ objectIds: {
516
+ [this.getObjectId()]: newObjectId
517
+ }
518
+ }
519
+ }] }, presentationId);
520
+
521
+ const resourceCopy = JSON.parse(JSON.stringify(this.__resource));
522
+ resourceCopy.objectId = newObjectId;
523
+ this.__page.__resource.pageElements = this.__page.__resource.pageElements || [];
524
+ this.__page.__resource.pageElements.push(resourceCopy);
525
+
526
+ const { newFakePageElement } = PageElementRegistry;
527
+ const baseElement = newFakePageElement(resourceCopy, this.__page);
528
+ return baseElement;
529
+ }
530
+
399
531
  toString() {
400
532
  return 'PageElement';
401
533
  }
@@ -404,5 +536,12 @@ export class FakePageElement {
404
536
  export const PageElementRegistry = {
405
537
  newFakeShape: null,
406
538
  newFakeLine: null,
407
- newFakeTable: null
539
+ newFakeTable: null,
540
+ newFakeGroup: null,
541
+ newFakeImage: null,
542
+ newFakeVideo: null,
543
+ newFakeSpeakerSpotlight: null,
544
+ newFakeWordArt: null,
545
+ newFakePageElement: newFakePageElement,
546
+ asSpecificPageElement: null
408
547
  };
@@ -0,0 +1,28 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+
3
+ /**
4
+ * create a new FakePageElementRange instance
5
+ * @param {...any} args
6
+ * @returns {FakePageElementRange}
7
+ */
8
+ export const newFakePageElementRange = (...args) => {
9
+ return Proxies.guard(new FakePageElementRange(...args));
10
+ };
11
+
12
+ export class FakePageElementRange {
13
+ constructor(elements) {
14
+ this.__elements = elements;
15
+ }
16
+
17
+ /**
18
+ * Returns the list of PageElement instances.
19
+ * @returns {FakePageElement[]} The page elements.
20
+ */
21
+ getPageElements() {
22
+ return this.__elements;
23
+ }
24
+
25
+ toString() {
26
+ return 'PageElementRange';
27
+ }
28
+ }
@@ -0,0 +1,28 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+
3
+ /**
4
+ * create a new FakePageRange instance
5
+ * @param {...any} args
6
+ * @returns {FakePageRange}
7
+ */
8
+ export const newFakePageRange = (...args) => {
9
+ return Proxies.guard(new FakePageRange(...args));
10
+ };
11
+
12
+ export class FakePageRange {
13
+ constructor(pages) {
14
+ this.__pages = pages;
15
+ }
16
+
17
+ /**
18
+ * Returns the list of Page instances.
19
+ * @returns {FakePage[]} The pages.
20
+ */
21
+ getPages() {
22
+ return this.__pages;
23
+ }
24
+
25
+ toString() {
26
+ return 'PageRange';
27
+ }
28
+ }
@@ -0,0 +1,139 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+ import { ParagraphAlignment, SpacingMode, TextDirection } from '../enums/slidesenums.js';
3
+
4
+ /**
5
+ * create a new FakeParagraphStyle instance
6
+ * @param {...any} args
7
+ * @returns {FakeParagraphStyle}
8
+ */
9
+ export const newFakeParagraphStyle = (...args) => {
10
+ return Proxies.guard(new FakeParagraphStyle(...args));
11
+ };
12
+
13
+ export class FakeParagraphStyle {
14
+ constructor(textRange) {
15
+ this.__textRange = textRange;
16
+ }
17
+
18
+ get __style() {
19
+ // Similar to TextStyle, find first paragraph marker in range
20
+ const resource = this.__textRange.__resource;
21
+ const elements = resource?.textElements || [];
22
+ const start = this.__textRange.getStartIndex();
23
+
24
+ let currentIndex = 0;
25
+ for (const element of elements) {
26
+ const length = element.textRun?.content?.length || (element.autoText ? 1 : 0);
27
+ if (currentIndex >= start && element.paragraphMarker) {
28
+ return element.paragraphMarker.style || {};
29
+ }
30
+ currentIndex += length;
31
+ }
32
+ return {};
33
+ }
34
+
35
+ getIndentEnd() {
36
+ return this.__textRange.__shape.__normalize(this.__style.indentEnd) || 0;
37
+ }
38
+
39
+ getIndentFirstLine() {
40
+ return this.__textRange.__shape.__normalize(this.__style.indentFirstLine) || 0;
41
+ }
42
+
43
+ getIndentStart() {
44
+ return this.__textRange.__shape.__normalize(this.__style.indentStart) || 0;
45
+ }
46
+
47
+ getLineSpacing() {
48
+ return this.__style.lineSpacing || 100;
49
+ }
50
+
51
+ getParagraphAlignment() {
52
+ return ParagraphAlignment[this.__style.alignment || 'START'];
53
+ }
54
+
55
+ getSpaceAbove() {
56
+ return this.__textRange.__shape.__normalize(this.__style.spaceAbove) || 0;
57
+ }
58
+
59
+ getSpaceBelow() {
60
+ return this.__textRange.__shape.__normalize(this.__style.spaceBelow) || 0;
61
+ }
62
+
63
+ getSpacingMode() {
64
+ return SpacingMode[this.__style.spacingMode || 'NEVER_COLLAPSE'];
65
+ }
66
+
67
+ getTextDirection() {
68
+ return TextDirection[this.__style.direction || 'LEFT_TO_RIGHT'];
69
+ }
70
+
71
+ __update(props, fields) {
72
+ const presentationId = this.__textRange.__shape.__presentation.getId();
73
+ const objectId = this.__textRange.__shape.getObjectId();
74
+ const cellLocation = this.__textRange.__shape.__cellLocation;
75
+
76
+ Slides.Presentations.batchUpdate({ requests: [{
77
+ updateParagraphStyle: {
78
+ objectId,
79
+ cellLocation,
80
+ style: props,
81
+ fields: fields || Object.keys(props).join(','),
82
+ textRange: {
83
+ type: 'FIXED_RANGE',
84
+ startIndex: this.__textRange.getStartIndex(),
85
+ endIndex: this.__textRange.getEndIndex()
86
+ }
87
+ }
88
+ }] }, presentationId);
89
+ }
90
+
91
+ setIndentEnd(indent) {
92
+ this.__update({ indentEnd: { magnitude: indent, unit: 'PT' } }, 'indentEnd');
93
+ return this;
94
+ }
95
+
96
+ setIndentFirstLine(indent) {
97
+ this.__update({ indentFirstLine: { magnitude: indent, unit: 'PT' } }, 'indentFirstLine');
98
+ return this;
99
+ }
100
+
101
+ setIndentStart(indent) {
102
+ this.__update({ indentStart: { magnitude: indent, unit: 'PT' } }, 'indentStart');
103
+ return this;
104
+ }
105
+
106
+ setLineSpacing(spacing) {
107
+ this.__update({ lineSpacing: spacing }, 'lineSpacing');
108
+ return this;
109
+ }
110
+
111
+ setParagraphAlignment(alignment) {
112
+ this.__update({ alignment: alignment.toString() }, 'alignment');
113
+ return this;
114
+ }
115
+
116
+ setSpaceAbove(space) {
117
+ this.__update({ spaceAbove: { magnitude: space, unit: 'PT' } }, 'spaceAbove');
118
+ return this;
119
+ }
120
+
121
+ setSpaceBelow(space) {
122
+ this.__update({ spaceBelow: { magnitude: space, unit: 'PT' } }, 'spaceBelow');
123
+ return this;
124
+ }
125
+
126
+ setSpacingMode(mode) {
127
+ this.__update({ spacingMode: mode.toString() }, 'spacingMode');
128
+ return this;
129
+ }
130
+
131
+ setTextDirection(direction) {
132
+ this.__update({ direction: direction.toString() }, 'direction');
133
+ return this;
134
+ }
135
+
136
+ toString() {
137
+ return 'ParagraphStyle';
138
+ }
139
+ }
@@ -0,0 +1,32 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+
3
+ export const newFakePictureFill = (...args) => {
4
+ return Proxies.guard(new FakePictureFill(...args));
5
+ };
6
+
7
+ export class FakePictureFill {
8
+ constructor(resource, page) {
9
+ this.__resource = resource;
10
+ this.__page = page;
11
+ }
12
+
13
+ getAs(contentType) {
14
+ return this.getBlob().getAs(contentType);
15
+ }
16
+
17
+ getBlob() {
18
+ return UrlFetchApp.fetch(this.getContentUrl()).getBlob();
19
+ }
20
+
21
+ getContentUrl() {
22
+ return this.__resource.contentUrl || '';
23
+ }
24
+
25
+ getSourceUrl() {
26
+ return this.__resource.sourceUrl || '';
27
+ }
28
+
29
+ toString() {
30
+ return 'PictureFill';
31
+ }
32
+ }