@mcpher/gas-fakes 2.5.4 → 2.5.6

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 (30) hide show
  1. package/.claspignore +1 -1
  2. package/README.md +27 -1
  3. package/exgcp.sh +63 -0
  4. package/package.json +1 -1
  5. package/src/services/advslides/fakeadvslides.js +20 -1
  6. package/src/services/documentapp/appenderhelpers.js +8 -3
  7. package/src/services/documentapp/elementhelpers.js +148 -7
  8. package/src/services/documentapp/elementoptions.js +40 -0
  9. package/src/services/documentapp/elements.js +7 -0
  10. package/src/services/documentapp/fakebookmark.js +1 -3
  11. package/src/services/documentapp/fakecontainerelement.js +188 -0
  12. package/src/services/documentapp/fakedate.js +92 -0
  13. package/src/services/documentapp/fakedocument.js +51 -0
  14. package/src/services/documentapp/fakedocumenttab.js +9 -25
  15. package/src/services/documentapp/fakeelement.js +453 -90
  16. package/src/services/documentapp/fakeequation.js +28 -0
  17. package/src/services/documentapp/fakeequationfunction.js +37 -0
  18. package/src/services/documentapp/fakeequationfunctionargumentseparator.js +28 -0
  19. package/src/services/documentapp/fakeequationsymbol.js +37 -0
  20. package/src/services/documentapp/fakefootersection.js +64 -1
  21. package/src/services/documentapp/fakeheadersection.js +64 -0
  22. package/src/services/documentapp/fakeperson.js +67 -0
  23. package/src/services/documentapp/fakerangeelement.js +27 -1
  24. package/src/services/documentapp/fakerichlink.js +79 -0
  25. package/src/services/documentapp/fakesectionelement.js +51 -12
  26. package/src/services/documentapp/faketablecell.js +98 -0
  27. package/src/services/documentapp/nrhelpers.js +2 -1
  28. package/src/services/documentapp/shadowdocument.js +19 -2
  29. package/src/services/spreadsheetapp/fakeembeddedchartbuilder.js +2 -7
  30. package/src/support/sxslides.js +5 -4
@@ -7,7 +7,7 @@ import { Utils } from '../../support/utils.js';
7
7
  const { is } = Utils;
8
8
  import { ElementType } from '../enums/docsenums.js';
9
9
  import { getElementFactory } from './elementRegistry.js';
10
- import { findItem } from './elementhelpers.js';
10
+ import { findItem, getAttributes, updateParagraphStyle, updateTextStyle, attributesToStyle } from './elementhelpers.js';
11
11
 
12
12
  /**
13
13
  * @typedef {import('./shadow.js').ShadowStructure} ShadowStructure
@@ -15,37 +15,6 @@ import { findItem } from './elementhelpers.js';
15
15
 
16
16
  const shadowPrefix = "GAS_FAKE_";
17
17
 
18
- /**
19
- * A map of element types to their corresponding 'as' methods (e.g., asParagraph).
20
- * @private
21
- */
22
- const asCasts = {
23
- PARAGRAPH: {
24
- method: 'asParagraph',
25
- },
26
- TABLE: {
27
- method: 'asTable',
28
- },
29
- TABLE_ROW: {
30
- method: 'asTableRow',
31
- },
32
- TABLE_CELL: {
33
- method: 'asTableCell',
34
- },
35
- TEXT: {
36
- method: 'asText',
37
- },
38
- PAGE_BREAK: {
39
- method: 'asPageBreak',
40
- },
41
- HORIZONTAL_RULE: {
42
- method: 'asHorizontalRule',
43
- },
44
- FOOTNOTE_REFERENCE: {
45
- method: 'asFootnoteReference',
46
- },
47
- };
48
-
49
18
  /**
50
19
  * Represents a generic element in a Google Document.
51
20
  * In the Document Service model, almost everything is a type of Element.
@@ -54,47 +23,44 @@ const asCasts = {
54
23
  * @implements {GoogleAppsScript.Document.Element}
55
24
  */
56
25
  export class FakeElement {
57
- /**
58
- * The constructor for an element.
59
- * @param {ShadowStructure | null} structure - The document's structure manager, or null for a detached element.
60
- * @param {string | object} nameOrItem - The unique name of the element within the structure, or the raw element resource for a detached element.
61
- * @private
62
- */
26
+ /**
27
+ * The constructor for an element.
28
+ * @param {import('./shadowdocument.js').ShadowDocument | null} shadowDocument - The document's shadow document manager, or null for a detached element.
29
+ * @param {string | object} nameOrItem - The unique name of the element within the structure, or the raw element resource for a detached element.
30
+ * @private
31
+ */
63
32
  constructor(shadowDocument, nameOrItem) {
64
- const { nargs, matchThrow } = signatureArgs(arguments, 'FakeElement');
65
- if (nargs !== 2) matchThrow();
66
-
67
- // An element is either "attached" (with a structure and a name)
68
- // or "detached" (with a structural element but no live structure).
69
- // A detached element is created by copy().
70
- if (is.string(nameOrItem)) { // Attached
71
- if (!is.object(shadowDocument) || !nameOrItem.startsWith(shadowPrefix)) {
72
- throw new Error(`Invalid arguments for attached FakeElement: ${nameOrItem}. Name must start with '${shadowPrefix}'.`);
73
- }
74
- this.__isDetached = false;
75
- this.__shadowDocument = shadowDocument;
76
- // Cache the element's initial position. This is the key to "reviving" the element.
77
- const initialItem = this.__getElementMapItem(nameOrItem);
78
- this.__initialStartIndex = initialItem.startIndex;
79
- this.__initialSegmentId = initialItem.__segmentId;
80
- this.__name = nameOrItem;
81
- this.__detachedItem = null;
82
- } else if (is.object(nameOrItem)) { // Detached
33
+ const {
34
+ nargs,
35
+ matchThrow
36
+ } = signatureArgs(arguments, 'FakeElement');
37
+ if (nargs !== 2) matchThrow();
38
+
39
+ // An element is either "attached" (with a structure and a name)
40
+ // or "detached" (with a structural element but no live structure).
41
+ // A detached element is created by copy().
42
+ if (is.string(nameOrItem)) { // Attached
43
+ if (!is.object(shadowDocument) || (!nameOrItem.startsWith(shadowPrefix) && !nameOrItem.startsWith('kix.'))) {
44
+ throw new Error(`Invalid arguments for attached FakeElement: ${nameOrItem}. Name must start with '${shadowPrefix}' or 'kix.'.`);
45
+ }
46
+ this.__isDetached = false;
47
+ this.__shadowDocument = shadowDocument;
48
+ // Cache the element's initial position. This is the key to "reviving" the element.
49
+ const initialItem = this.__getElementMapItem(nameOrItem);
50
+ this.__initialStartIndex = initialItem.startIndex;
51
+ this.__initialSegmentId = initialItem.__segmentId;
52
+ this.__name = nameOrItem;
53
+ this.__detachedItem = null;
54
+ } else if (is.object(nameOrItem)) { // Detached
83
55
  if (!is.null(shadowDocument)) {
84
56
  throw new Error('shadowDocument must be null for a detached FakeElement');
85
- }
86
- this.__isDetached = true;
87
- this.__shadowDocument = null;
88
- this.__name = null;
89
- this.__detachedItem = nameOrItem;
90
57
  }
91
-
92
- // Dynamically add as...() methods like asParagraph()
93
- Reflect.ownKeys(asCasts).forEach((cast) => {
94
- const ob = asCasts[cast];
95
- this[ob.method] = this.__cast.bind(this, cast);
96
- });
58
+ this.__isDetached = true;
59
+ this.__shadowDocument = null;
60
+ this.__name = null;
61
+ this.__detachedItem = nameOrItem;
97
62
  }
63
+ }
98
64
 
99
65
  /**
100
66
  * Gets the shadow document manager associated with this element's structure.
@@ -157,6 +123,52 @@ export class FakeElement {
157
123
  return this.__elementMapItem.__twig;
158
124
  }
159
125
 
126
+ /**
127
+ * Gets the next sibling element of this element.
128
+ * @returns {GoogleAppsScript.Document.Element | null} The next sibling element, or null if none exists.
129
+ * @see https://developers.google.com/apps-script/reference/document/element#getNextSibling()
130
+ */
131
+ getNextSibling() {
132
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.getNextSibling');
133
+ if (nargs !== 0) matchThrow();
134
+
135
+ if (this.__isDetached || !this.__twig.parent) return null;
136
+
137
+ const parent = this.__twig.parent;
138
+ const children = parent.children;
139
+ const currentIndex = children.indexOf(this.__twig);
140
+
141
+ if (currentIndex === -1 || currentIndex === children.length - 1) {
142
+ return null;
143
+ }
144
+
145
+ const nextTwig = children[currentIndex + 1];
146
+ return newFakeElement(this.__shadowDocument, nextTwig.name).__cast();
147
+ }
148
+
149
+ /**
150
+ * Gets the previous sibling element of this element.
151
+ * @returns {GoogleAppsScript.Document.Element | null} The previous sibling element, or null if none exists.
152
+ * @see https://developers.google.com/apps-script/reference/document/element#getPreviousSibling()
153
+ */
154
+ getPreviousSibling() {
155
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.getPreviousSibling');
156
+ if (nargs !== 0) matchThrow();
157
+
158
+ if (this.__isDetached || !this.__twig.parent) return null;
159
+
160
+ const parent = this.__twig.parent;
161
+ const children = parent.children;
162
+ const currentIndex = children.indexOf(this.__twig);
163
+
164
+ if (currentIndex <= 0) {
165
+ return null;
166
+ }
167
+
168
+ const prevTwig = children[currentIndex - 1];
169
+ return newFakeElement(this.__shadowDocument, prevTwig.name).__cast();
170
+ }
171
+
160
172
  /**
161
173
  * Gets the parent element of this element.
162
174
  * @returns {GoogleAppsScript.Document.ContainerElement | null} The parent element, or null if it has no parent (e.g., it's the Body or is detached).
@@ -192,6 +204,114 @@ export class FakeElement {
192
204
  return enumType;
193
205
  }
194
206
 
207
+ /**
208
+ * Retrieves the element's attributes.
209
+ * @returns {object} The element's attributes.
210
+ * @see https://developers.google.com/apps-script/reference/document/element#getAttributes()
211
+ */
212
+ getAttributes() {
213
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.getAttributes');
214
+ if (nargs !== 0) matchThrow();
215
+
216
+ return getAttributes(this);
217
+ }
218
+
219
+ /**
220
+ * Sets the element's attributes.
221
+ * @param {object} attributes - The attributes to set.
222
+ * @returns {GoogleAppsScript.Document.Element} The current element.
223
+ * @see https://developers.google.com/apps-script/reference/document/element#setAttributes(Object)
224
+ */
225
+ setAttributes(attributes) {
226
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.setAttributes');
227
+ if (nargs !== 1 || !is.object(attributes)) matchThrow();
228
+
229
+ const { paragraphStyle, textStyle, paraFields, textFields } = attributesToStyle(attributes);
230
+ const type = this.getType().toString();
231
+
232
+ if (paraFields && (type === 'PARAGRAPH' || type === 'LIST_ITEM' || type === 'BODY_SECTION')) {
233
+ updateParagraphStyle(this, paragraphStyle, paraFields);
234
+ }
235
+ if (textFields) {
236
+ updateTextStyle(this, textStyle, textFields);
237
+ }
238
+ return this;
239
+ }
240
+
241
+ /**
242
+ * Determines whether the element is at the end of the Document.
243
+ * @returns {boolean} Whether the element is at the end of the tab.
244
+ * @see https://developers.google.com/apps-script/reference/document/element#isAtDocumentEnd()
245
+ */
246
+ isAtDocumentEnd() {
247
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.isAtDocumentEnd');
248
+ if (nargs !== 0) matchThrow();
249
+
250
+ if (this.__isDetached) return false;
251
+
252
+ let current = this;
253
+ while (current && !current.__isDetached) {
254
+ const parent = current.getParent();
255
+ if (!parent) return true; // Body or root is end
256
+
257
+ const children = parent.__twig.children;
258
+ if (children.indexOf(current.__twig) !== children.length - 1) {
259
+ return false;
260
+ }
261
+ current = parent;
262
+ }
263
+ return true;
264
+ }
265
+
266
+ /**
267
+ * Merges the element with the preceding sibling of the same type.
268
+ * @returns {GoogleAppsScript.Document.Element | null} The merged element.
269
+ * @see https://developers.google.com/apps-script/reference/document/element#merge()
270
+ */
271
+ merge() {
272
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.merge');
273
+ if (nargs !== 0) matchThrow();
274
+ // Implementation of merge is complex and requires careful management of child indices.
275
+ // For now, we'll mark it as not implemented.
276
+ throw new Error('merge() is not yet implemented in gas-fakes');
277
+ }
278
+
279
+ /**
280
+ * Removes the element from its parent.
281
+ * @returns {GoogleAppsScript.Document.Element | null} The removed element.
282
+ * @see https://developers.google.com/apps-script/reference/document/element#removeFromParent()
283
+ */
284
+ removeFromParent() {
285
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.removeFromParent');
286
+ if (nargs !== 0) matchThrow();
287
+
288
+ if (this.__isDetached) {
289
+ throw new Error('removeFromParent not supported for detached elements');
290
+ }
291
+
292
+ const parent = this.getParent();
293
+ if (!parent) {
294
+ throw new Error('Cannot remove root element (Body)');
295
+ }
296
+
297
+ const item = this.__elementMapItem;
298
+ const range = {
299
+ startIndex: item.startIndex,
300
+ endIndex: item.endIndex,
301
+ segmentId: item.__segmentId,
302
+ tabId: item.__tabId
303
+ };
304
+
305
+ Docs.Documents.batchUpdate({
306
+ requests: [{
307
+ deleteContentRange: { range }
308
+ }]
309
+ }, this.__shadowDocument.getId());
310
+
311
+ this.__shadowDocument.refresh();
312
+ return this;
313
+ }
314
+
195
315
  /**
196
316
  * Creates a detached copy of the element.
197
317
  * The copied element has no parent and is not part of the document until it is inserted.
@@ -204,32 +324,32 @@ export class FakeElement {
204
324
  // Custom deep clone function to handle the circular reference in __twig.parent.
205
325
  // JSON.stringify cannot handle circular structures.
206
326
  const deepClone = (obj, cache = new WeakMap()) => {
207
- if (obj === null || typeof obj !== 'object') {
208
- return obj;
209
- }
210
- if (cache.has(obj)) {
211
- return cache.get(obj);
212
- }
327
+ if (obj === null || typeof obj !== 'object') {
328
+ return obj;
329
+ }
330
+ if (cache.has(obj)) {
331
+ return cache.get(obj);
332
+ }
213
333
 
214
- const clone = Array.isArray(obj) ? [] : {};
215
- cache.set(obj, clone);
334
+ const clone = Array.isArray(obj) ? [] : {};
335
+ cache.set(obj, clone);
216
336
 
217
- for (const key in obj) {
218
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
337
+ for (const key in obj) {
338
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
219
339
  // The __twig property is the one with the circular reference via its 'parent' property.
220
340
  // We clone it, but explicitly set the parent to null to break the cycle for the detached copy.
221
- if (key === '__twig') {
222
- const twig = obj[key];
223
- clone[key] = {
224
- name: twig.name,
225
- children: deepClone(twig.children, cache), // Recursively clone children twigs
226
- parent: null, // Break the circular reference
227
- };
228
- } else {
229
- clone[key] = deepClone(obj[key], cache);
341
+ if (key === '__twig') {
342
+ const twig = obj[key];
343
+ clone[key] = {
344
+ name: twig.name,
345
+ children: deepClone(twig.children, cache), // Recursively clone children twigs
346
+ parent: null, // Break the circular reference
347
+ };
348
+ } else {
349
+ clone[key] = deepClone(obj[key], cache);
350
+ }
230
351
  }
231
352
  }
232
- }
233
353
  return clone;
234
354
  };
235
355
 
@@ -250,7 +370,9 @@ export class FakeElement {
250
370
  __cast(asType = null) {
251
371
  // We'll return an object that matches the type.
252
372
  const item = this.__elementMapItem;
253
- const { __type: type } = item;
373
+ const {
374
+ __type: type
375
+ } = item;
254
376
  asType = asType || type;
255
377
  if (type !== asType) {
256
378
  throw new Error(`${type} can't be cast as ${asType}`);
@@ -259,12 +381,253 @@ export class FakeElement {
259
381
  return factory(this.__shadowDocument, this.__name);
260
382
  }
261
383
 
384
+ /**
385
+ * Returns the current element as a Body.
386
+ * @returns {GoogleAppsScript.Document.Body} The current element.
387
+ */
388
+ asBody() {
389
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asBody');
390
+ if (nargs !== 0) matchThrow();
391
+ return this.__cast('BODY_SECTION');
392
+ }
393
+
394
+ /**
395
+ * Returns the current element as a Date.
396
+ * @returns {GoogleAppsScript.Document.Date} The current element.
397
+ */
398
+ asDate() {
399
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asDate');
400
+ if (nargs !== 0) matchThrow();
401
+ return this.__cast('DATE');
402
+ }
403
+
404
+ /**
405
+ * Returns the current element as an Equation.
406
+ * @returns {GoogleAppsScript.Document.Equation} The current element.
407
+ */
408
+ asEquation() {
409
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asEquation');
410
+ if (nargs !== 0) matchThrow();
411
+ return this.__cast('EQUATION');
412
+ }
413
+
414
+ /**
415
+ * Returns the current element as an EquationFunction.
416
+ * @returns {GoogleAppsScript.Document.EquationFunction} The current element.
417
+ */
418
+ asEquationFunction() {
419
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asEquationFunction');
420
+ if (nargs !== 0) matchThrow();
421
+ return this.__cast('EQUATION_FUNCTION');
422
+ }
423
+
424
+ /**
425
+ * Returns the current element as an EquationFunctionArgumentSeparator.
426
+ * @returns {GoogleAppsScript.Document.EquationFunctionArgumentSeparator} The current element.
427
+ */
428
+ asEquationFunctionArgumentSeparator() {
429
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asEquationFunctionArgumentSeparator');
430
+ if (nargs !== 0) matchThrow();
431
+ return this.__cast('EQUATION_FUNCTION_ARGUMENT_SEPARATOR');
432
+ }
433
+
434
+ /**
435
+ * Returns the current element as an EquationSymbol.
436
+ * @returns {GoogleAppsScript.Document.EquationSymbol} The current element.
437
+ */
438
+ asEquationSymbol() {
439
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asEquationSymbol');
440
+ if (nargs !== 0) matchThrow();
441
+ return this.__cast('EQUATION_SYMBOL');
442
+ }
443
+
444
+ /**
445
+ * Returns the current element as a FooterSection.
446
+ * @returns {GoogleAppsScript.Document.FooterSection} The current element.
447
+ */
448
+ asFooterSection() {
449
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asFooterSection');
450
+ if (nargs !== 0) matchThrow();
451
+ return this.__cast('FOOTER_SECTION');
452
+ }
453
+
454
+ /**
455
+ * Returns the current element as a Footnote.
456
+ * @returns {GoogleAppsScript.Document.Footnote} The current element.
457
+ */
458
+ asFootnote() {
459
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asFootnote');
460
+ if (nargs !== 0) matchThrow();
461
+ return this.__cast('FOOTNOTE');
462
+ }
463
+
464
+ /**
465
+ * Returns the current element as a FootnoteSection.
466
+ * @returns {GoogleAppsScript.Document.FootnoteSection} The current element.
467
+ */
468
+ asFootnoteSection() {
469
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asFootnoteSection');
470
+ if (nargs !== 0) matchThrow();
471
+ return this.__cast('FOOTNOTE_SECTION');
472
+ }
473
+
474
+ /**
475
+ * Returns the current element as a HeaderSection.
476
+ * @returns {GoogleAppsScript.Document.HeaderSection} The current element.
477
+ */
478
+ asHeaderSection() {
479
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asHeaderSection');
480
+ if (nargs !== 0) matchThrow();
481
+ return this.__cast('HEADER_SECTION');
482
+ }
483
+
484
+ /**
485
+ * Returns the current element as a HorizontalRule.
486
+ * @returns {GoogleAppsScript.Document.HorizontalRule} The current element.
487
+ */
488
+ asHorizontalRule() {
489
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asHorizontalRule');
490
+ if (nargs !== 0) matchThrow();
491
+ return this.__cast('HORIZONTAL_RULE');
492
+ }
493
+
494
+ /**
495
+ * Returns the current element as an InlineDrawing.
496
+ * @returns {GoogleAppsScript.Document.InlineDrawing} The current element.
497
+ */
498
+ asInlineDrawing() {
499
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asInlineDrawing');
500
+ if (nargs !== 0) matchThrow();
501
+ return this.__cast('INLINE_DRAWING');
502
+ }
503
+
504
+ /**
505
+ * Returns the current element as an InlineImage.
506
+ * @returns {GoogleAppsScript.Document.InlineImage} The current element.
507
+ */
508
+ asInlineImage() {
509
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asInlineImage');
510
+ if (nargs !== 0) matchThrow();
511
+ return this.__cast('INLINE_IMAGE');
512
+ }
513
+
514
+ /**
515
+ * Returns the current element as a ListItem.
516
+ * @returns {GoogleAppsScript.Document.ListItem} The current element.
517
+ */
518
+ asListItem() {
519
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asListItem');
520
+ if (nargs !== 0) matchThrow();
521
+ return this.__cast('LIST_ITEM');
522
+ }
523
+
524
+ /**
525
+ * Returns the current element as a PageBreak.
526
+ * @returns {GoogleAppsScript.Document.PageBreak} The current element.
527
+ */
528
+ asPageBreak() {
529
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asPageBreak');
530
+ if (nargs !== 0) matchThrow();
531
+ return this.__cast('PAGE_BREAK');
532
+ }
533
+
534
+ /**
535
+ * Returns the current element as a Paragraph.
536
+ * @returns {GoogleAppsScript.Document.Paragraph} The current element.
537
+ */
538
+ asParagraph() {
539
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asParagraph');
540
+ if (nargs !== 0) matchThrow();
541
+ return this.__cast('PARAGRAPH');
542
+ }
543
+
544
+ /**
545
+ * Returns the current element as a Person.
546
+ * @returns {GoogleAppsScript.Document.Person} The current element.
547
+ */
548
+ asPerson() {
549
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asPerson');
550
+ if (nargs !== 0) matchThrow();
551
+ return this.__cast('PERSON');
552
+ }
553
+
554
+ /**
555
+ * Returns the current element as a RichLink.
556
+ * @returns {GoogleAppsScript.Document.RichLink} The current element.
557
+ */
558
+ asRichLink() {
559
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asRichLink');
560
+ if (nargs !== 0) matchThrow();
561
+ return this.__cast('RICH_LINK');
562
+ }
563
+
564
+ /**
565
+ * Returns the current element as a Table.
566
+ * @returns {GoogleAppsScript.Document.Table} The current element.
567
+ */
568
+ asTable() {
569
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asTable');
570
+ if (nargs !== 0) matchThrow();
571
+ return this.__cast('TABLE');
572
+ }
573
+
574
+ /**
575
+ * Returns the current element as a TableCell.
576
+ * @returns {GoogleAppsScript.Document.TableCell} The current element.
577
+ */
578
+ asTableCell() {
579
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asTableCell');
580
+ if (nargs !== 0) matchThrow();
581
+ return this.__cast('TABLE_CELL');
582
+ }
583
+
584
+ /**
585
+ * Returns the current element as a TableOfContents.
586
+ * @returns {GoogleAppsScript.Document.TableOfContents} The current element.
587
+ */
588
+ asTableOfContents() {
589
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asTableOfContents');
590
+ if (nargs !== 0) matchThrow();
591
+ return this.__cast('TABLE_OF_CONTENTS');
592
+ }
593
+
594
+ /**
595
+ * Returns the current element as a TableRow.
596
+ * @returns {GoogleAppsScript.Document.TableRow} The current element.
597
+ */
598
+ asTableRow() {
599
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asTableRow');
600
+ if (nargs !== 0) matchThrow();
601
+ return this.__cast('TABLE_ROW');
602
+ }
603
+
604
+ /**
605
+ * Returns the current element as a Text.
606
+ * @returns {GoogleAppsScript.Document.Text} The current element.
607
+ */
608
+ asText() {
609
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asText');
610
+ if (nargs !== 0) matchThrow();
611
+ return this.__cast('TEXT');
612
+ }
613
+
614
+ /**
615
+ * Returns the current element as a FootnoteReference.
616
+ * @returns {GoogleAppsScript.Document.FootnoteReference} The current element.
617
+ * @private
618
+ */
619
+ asFootnoteReference() {
620
+ const { nargs, matchThrow } = signatureArgs(arguments, 'Element.asFootnoteReference');
621
+ if (nargs !== 0) matchThrow();
622
+ return this.__cast('FOOTNOTE_REFERENCE');
623
+ }
624
+
262
625
  /**
263
626
  * Returns the string "Element".
264
627
  * @returns {string}
265
628
  */
266
629
  toString() {
267
- return 'Element';
630
+ return this.constructor.name.replace('Fake', '');
268
631
  }
269
632
  }
270
633
 
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @file Provides a fake implementation of the Equation class.
3
+ */
4
+
5
+ import { Proxies } from '../../support/proxies.js';
6
+ import { FakeContainerElement } from './fakecontainerelement.js';
7
+ import { registerElement } from './elementRegistry.js';
8
+
9
+ /**
10
+ * A fake implementation of the Equation class.
11
+ * @class
12
+ * @extends {FakeContainerElement}
13
+ * @implements {GoogleAppsScript.Document.Equation}
14
+ * @see https://developers.google.com/apps-script/reference/document/equation
15
+ */
16
+ export class FakeEquation extends FakeContainerElement {
17
+ constructor(shadowDocument, nameOrItem) {
18
+ super(shadowDocument, nameOrItem);
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Creates a new fake Equation.
24
+ * @param {...any} args The arguments for the FakeEquation constructor.
25
+ * @returns {FakeEquation} A new proxied FakeEquation instance.
26
+ */
27
+ export const newFakeEquation = (...args) => Proxies.guard(new FakeEquation(...args));
28
+ registerElement('EQUATION', newFakeEquation);
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @file Provides a fake implementation of the EquationFunction class.
3
+ */
4
+
5
+ import { Proxies } from '../../support/proxies.js';
6
+ import { FakeContainerElement } from './fakecontainerelement.js';
7
+ import { registerElement } from './elementRegistry.js';
8
+
9
+ /**
10
+ * A fake implementation of the EquationFunction class.
11
+ * @class
12
+ * @extends {FakeContainerElement}
13
+ * @implements {GoogleAppsScript.Document.EquationFunction}
14
+ * @see https://developers.google.com/apps-script/reference/document/equation-function
15
+ */
16
+ export class FakeEquationFunction extends FakeContainerElement {
17
+ constructor(shadowDocument, nameOrItem) {
18
+ super(shadowDocument, nameOrItem);
19
+ }
20
+
21
+ /**
22
+ * Retrieves the code corresponding to the equation function.
23
+ * @returns {string} the function code
24
+ * @see https://developers.google.com/apps-script/reference/document/equation-function#getCode()
25
+ */
26
+ getCode() {
27
+ return this.__elementMapItem.equationFunctionStyle?.code || "";
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Creates a new fake EquationFunction.
33
+ * @param {...any} args The arguments for the FakeEquationFunction constructor.
34
+ * @returns {FakeEquationFunction} A new proxied FakeEquationFunction instance.
35
+ */
36
+ export const newFakeEquationFunction = (...args) => Proxies.guard(new FakeEquationFunction(...args));
37
+ registerElement('EQUATION_FUNCTION', newFakeEquationFunction);