lucid-extension-sdk 0.0.41 → 0.0.44

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucid-extension-sdk",
3
- "version": "0.0.41",
3
+ "version": "0.0.44",
4
4
  "description": "Utility classes for writing Lucid Software editor extensions",
5
5
  "main": "sdk/index.js",
6
6
  "types": "sdk/index.d.ts",
@@ -85,6 +85,7 @@ export declare const enum CommandName {
85
85
  SetProperty = "sp",
86
86
  SetReferenceKey = "srk",
87
87
  SetShapeData = "ssd",
88
+ SetText = "st",
88
89
  ShowModal = "sm",
89
90
  ShowPanel = "spn",
90
91
  SleepForTestCase = "sleep",
@@ -374,6 +375,10 @@ export declare type CommandArgs = {
374
375
  query: SetShapeDataQuery;
375
376
  result: SetShapeDataResult;
376
377
  };
378
+ [CommandName.SetText]: {
379
+ query: SetTextQuery;
380
+ result: SetTextResult;
381
+ };
377
382
  [CommandName.ShowModal]: {
378
383
  query: ShowModalQuery;
379
384
  result: ShowModalResult;
@@ -927,6 +932,17 @@ export declare type SetShapeDataQuery = {
927
932
  'v'?: SerializedFieldType;
928
933
  };
929
934
  export declare type SetShapeDataResult = undefined;
935
+ export declare type SetTextQuery = {
936
+ /** ID of the element to change text on */
937
+ 'id': string;
938
+ /** Name of the text area to update */
939
+ 'n': string;
940
+ /** Plain text to put in the text area*/
941
+ 't': string;
942
+ /** Optional force boolean for extension to update uneditable items*/
943
+ 'f'?: boolean | undefined;
944
+ };
945
+ export declare type SetTextResult = undefined;
930
946
  export declare type ShowModalQuery = {
931
947
  /** Name of the modal's action for receiving events; generated automatically by Modal base class */
932
948
  'n': string;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Aspect ratio 16:9, wider rectangle
3
+ * This will be the default setting if not provided
4
+ *
5
+ * The values are small since we only use width and height value to calculate aspect ratio
6
+ * So in this case, it will be width/height, which will be 16:9
7
+ * It's the same result as 1600 and 900 as default width and height
8
+ */
9
+ export declare const DEFAULT_IFRAME_WIDTH: number;
10
+ export declare const DEFAULT_IFRAME_HEIGHT: number;
11
+ /** @ignore */
12
+ export interface IframeAttributes {
13
+ /**
14
+ * The source url
15
+ */
16
+ src: string;
17
+ /**
18
+ * The list of feature policies allowed
19
+ * for example, "autoplay; fullscreen;"
20
+ */
21
+ allow?: string;
22
+ /**
23
+ * The iFrame height
24
+ */
25
+ height?: number;
26
+ /**
27
+ * The iFrame width
28
+ */
29
+ width?: number;
30
+ /**
31
+ * The iFrame title for accessibility
32
+ */
33
+ title?: string;
34
+ }
35
+ /**
36
+ * Generate iframe HTML from the IFrameAttributes object
37
+ * @returns the generated iframe HTML
38
+ * @ignore
39
+ * */
40
+ export declare function generateIFrameHTML(iframeAttributes: IframeAttributes): string;
41
+ /**
42
+ * Parse the iframe HTML, i.e. <iframe>...</iframe> into the IFrameAttributes object
43
+ * @returns the required attributes to render the target iframe
44
+ * @ignore
45
+ */
46
+ export declare function parseIFrameAttributesFromHTML(iframeHTML: string): IframeAttributes;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseIFrameAttributesFromHTML = exports.generateIFrameHTML = exports.DEFAULT_IFRAME_HEIGHT = exports.DEFAULT_IFRAME_WIDTH = void 0;
4
+ const checks_1 = require("../checks");
5
+ /**
6
+ * Aspect ratio 16:9, wider rectangle
7
+ * This will be the default setting if not provided
8
+ *
9
+ * The values are small since we only use width and height value to calculate aspect ratio
10
+ * So in this case, it will be width/height, which will be 16:9
11
+ * It's the same result as 1600 and 900 as default width and height
12
+ */
13
+ exports.DEFAULT_IFRAME_WIDTH = 16;
14
+ exports.DEFAULT_IFRAME_HEIGHT = 9;
15
+ /**
16
+ * Iframes from external sources are not trustworthy to be embedded directly. They could cause security vulnerability,
17
+ * including XSS attacks. Even if the iframes come from sources with good reputation, it is still a good practice to
18
+ * sanitize their source HTML and restrict their functionality in the sandbox before embedding them to our apps.
19
+ *
20
+ * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe for a list of iframe attributes.
21
+ */
22
+ const iframeRegExps = {
23
+ allow: /allow="(.*?)"/i,
24
+ src: /src="((https:\/\/|\/\/).*?)"/i,
25
+ height: /height="(\d*?)"/i,
26
+ width: /width="(\d*?)"/i,
27
+ title: /title="(.*?)"/i,
28
+ };
29
+ /**
30
+ * Generate iframe HTML from the IFrameAttributes object
31
+ * @returns the generated iframe HTML
32
+ * @ignore
33
+ * */
34
+ function generateIFrameHTML(iframeAttributes) {
35
+ let iframeHTML = `<iframe src="${iframeAttributes.src}"`;
36
+ if (iframeAttributes.width) {
37
+ iframeHTML += ` width="${iframeAttributes.width.toString()}"`;
38
+ }
39
+ if (iframeAttributes.height) {
40
+ iframeHTML += ` height="${iframeAttributes.height.toString()}"`;
41
+ }
42
+ if (iframeAttributes.title) {
43
+ // Escape all the double quotation marks
44
+ const title = iframeAttributes.title.replace(/"/g, '&quot;');
45
+ iframeHTML += ` title="${title}"`;
46
+ }
47
+ if (iframeAttributes.allow) {
48
+ iframeHTML += ` allow="${iframeAttributes.allow}"`;
49
+ }
50
+ iframeHTML += '></iframe>';
51
+ return iframeHTML;
52
+ }
53
+ exports.generateIFrameHTML = generateIFrameHTML;
54
+ /**
55
+ * Parse the iframe HTML, i.e. <iframe>...</iframe> into the IFrameAttributes object
56
+ * @returns the required attributes to render the target iframe
57
+ * @ignore
58
+ */
59
+ function parseIFrameAttributesFromHTML(iframeHTML) {
60
+ var _a, _b, _c, _d, _e, _f, _g, _h;
61
+ const allow = (_b = (_a = iframeHTML.match(iframeRegExps.allow)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '';
62
+ const src = (_d = (_c = iframeHTML.match(iframeRegExps.src)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : '';
63
+ const height = (_e = iframeHTML.match(iframeRegExps.height)) === null || _e === void 0 ? void 0 : _e[1];
64
+ const width = (_f = iframeHTML.match(iframeRegExps.width)) === null || _f === void 0 ? void 0 : _f[1];
65
+ const title = (_h = (_g = iframeHTML.match(iframeRegExps.title)) === null || _g === void 0 ? void 0 : _g[1]) !== null && _h !== void 0 ? _h : '';
66
+ return {
67
+ allow: allow,
68
+ src: src,
69
+ height: !(0, checks_1.isUndefined)(height) ? Number.parseInt(height) : exports.DEFAULT_IFRAME_HEIGHT,
70
+ width: !(0, checks_1.isUndefined)(width) ? Number.parseInt(width) : exports.DEFAULT_IFRAME_WIDTH,
71
+ title: title,
72
+ };
73
+ }
74
+ exports.parseIFrameAttributesFromHTML = parseIFrameAttributesFromHTML;
@@ -35,5 +35,5 @@ export interface UnfurlCallbacks {
35
35
  * @param blockProxy The block proxy of the unfurl block
36
36
  * @ignore
37
37
  */
38
- afterUnfurlCallback?: (blockProxy: ExperimentalLinkUnfurlBlockProxy) => Promise<void>;
38
+ afterUnfurlCallback?: (blockProxy: ExperimentalLinkUnfurlBlockProxy, url: string) => Promise<void>;
39
39
  }
@@ -49,7 +49,8 @@ export declare const isValidUnfurlDetails: (subject: unknown) => subject is impo
49
49
  UnfurlTitle: (x: unknown) => x is string | undefined;
50
50
  Iframe: (x: unknown) => x is import("../guards").DestructureGuardedTypeObj<{
51
51
  IframeUrl: typeof isString;
52
- Size: (x: unknown) => x is import("./unfurliframe").UnfurlIframeSize.Standard | undefined;
52
+ AspectRatio: (x: unknown) => x is import("./unfurliframe").UnfurlIframeAspectRatio | undefined;
53
+ IframeTitle: (x: unknown) => x is string | undefined;
53
54
  }> | undefined;
54
55
  Thumbnails: (x: unknown) => x is import("../guards").DestructureGuardedTypeObj<{
55
56
  url: typeof isString;
@@ -1,12 +1,30 @@
1
1
  import { isString } from '../checks';
2
2
  /**
3
- * An enumeration of of the supported unfurl Iframe sizes.
3
+ * An enumeration of of the supported unfurl Iframe aspect ratio.
4
+ * The iframe will be maximized to fit the screen responsively
4
5
  */
5
- export declare enum UnfurlIframeSize {
6
+ export declare enum UnfurlIframeAspectRatio {
6
7
  /**
7
- * The standard iframe size.
8
+ * Aspect ratio 1:1, square
8
9
  */
9
- Standard = "standard"
10
+ Square = "1:1",
11
+ /**
12
+ * Aspect ratio 16:9, wider rectangle
13
+ * This will be the default setting if not provided
14
+ */
15
+ SixteenToNine = "16:9",
16
+ /**
17
+ * Aspect ratio 9:16, taller rectangle
18
+ */
19
+ NineToSixteen = "9:16",
20
+ /**
21
+ * Aspect ratio 4:3, wider rectangle
22
+ */
23
+ FourToThree = "4:3",
24
+ /**
25
+ * Aspect ratio 3:4, taller rectangle
26
+ */
27
+ ThreeToFour = "3:4"
10
28
  }
11
29
  /**
12
30
  * A definition of the properties needed to expand an iframe for an unfurl
@@ -18,20 +36,31 @@ export interface UnfurlIframe {
18
36
  iframeUrl: string;
19
37
  /**
20
38
  * The size of the iframe requested
39
+ * If not provided, 16:9
40
+ */
41
+ aspectRatio?: UnfurlIframeAspectRatio;
42
+ /**
43
+ * The iframe title for accessibility
21
44
  */
22
- size?: UnfurlIframeSize;
45
+ iframeTitle?: string;
23
46
  }
24
47
  /** @ignore */
25
48
  export interface SerializedUnfurlIframe {
26
49
  'IframeUrl': string;
27
- 'Size'?: UnfurlIframeSize;
50
+ 'AspectRatio'?: UnfurlIframeAspectRatio;
51
+ 'IframeTitle'?: string;
28
52
  }
29
53
  /** @ignore */
30
54
  export declare const isValidUnfurlIframe: (subject: unknown) => subject is import("../guards").DestructureGuardedTypeObj<{
31
55
  IframeUrl: typeof isString;
32
- Size: (x: unknown) => x is UnfurlIframeSize.Standard | undefined;
56
+ AspectRatio: (x: unknown) => x is UnfurlIframeAspectRatio | undefined;
57
+ IframeTitle: (x: unknown) => x is string | undefined;
33
58
  }>;
34
59
  /** @ignore */
35
60
  export declare function deserializeUnfurlIframe(raw: SerializedUnfurlIframe): UnfurlIframe;
36
61
  /** @ignore */
37
62
  export declare function serializeUnfurlIframe(concrete: UnfurlIframe): SerializedUnfurlIframe;
63
+ /** @ignore */
64
+ export declare function getIFrameHeight(unfurlIframeAspectRatio: UnfurlIframeAspectRatio): number;
65
+ /** @ignore */
66
+ export declare function getIFrameWidth(unfurlIframeAspectRatio: UnfurlIframeAspectRatio): number;
@@ -1,28 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serializeUnfurlIframe = exports.deserializeUnfurlIframe = exports.isValidUnfurlIframe = exports.UnfurlIframeSize = void 0;
3
+ exports.getIFrameWidth = exports.getIFrameHeight = exports.serializeUnfurlIframe = exports.deserializeUnfurlIframe = exports.isValidUnfurlIframe = exports.UnfurlIframeAspectRatio = void 0;
4
4
  const checks_1 = require("../checks");
5
5
  const validators_1 = require("../validators/validators");
6
6
  /**
7
- * An enumeration of of the supported unfurl Iframe sizes.
7
+ * An enumeration of of the supported unfurl Iframe aspect ratio.
8
+ * The iframe will be maximized to fit the screen responsively
8
9
  */
9
- var UnfurlIframeSize;
10
- (function (UnfurlIframeSize) {
10
+ var UnfurlIframeAspectRatio;
11
+ (function (UnfurlIframeAspectRatio) {
11
12
  /**
12
- * The standard iframe size.
13
+ * Aspect ratio 1:1, square
13
14
  */
14
- UnfurlIframeSize["Standard"] = "standard";
15
- })(UnfurlIframeSize = exports.UnfurlIframeSize || (exports.UnfurlIframeSize = {}));
15
+ UnfurlIframeAspectRatio["Square"] = "1:1";
16
+ /**
17
+ * Aspect ratio 16:9, wider rectangle
18
+ * This will be the default setting if not provided
19
+ */
20
+ UnfurlIframeAspectRatio["SixteenToNine"] = "16:9";
21
+ /**
22
+ * Aspect ratio 9:16, taller rectangle
23
+ */
24
+ UnfurlIframeAspectRatio["NineToSixteen"] = "9:16";
25
+ /**
26
+ * Aspect ratio 4:3, wider rectangle
27
+ */
28
+ UnfurlIframeAspectRatio["FourToThree"] = "4:3";
29
+ /**
30
+ * Aspect ratio 3:4, taller rectangle
31
+ */
32
+ UnfurlIframeAspectRatio["ThreeToFour"] = "3:4";
33
+ })(UnfurlIframeAspectRatio = exports.UnfurlIframeAspectRatio || (exports.UnfurlIframeAspectRatio = {}));
16
34
  /** @ignore */
17
35
  exports.isValidUnfurlIframe = (0, validators_1.objectValidator)({
18
36
  'IframeUrl': checks_1.isString,
19
- 'Size': (0, validators_1.option)((0, validators_1.stringEnumValidator)(UnfurlIframeSize)),
37
+ 'AspectRatio': (0, validators_1.option)((0, validators_1.stringEnumValidator)(UnfurlIframeAspectRatio)),
38
+ 'IframeTitle': (0, validators_1.option)(checks_1.isString),
20
39
  });
21
40
  /** @ignore */
22
41
  function deserializeUnfurlIframe(raw) {
23
42
  return {
24
43
  iframeUrl: raw['IframeUrl'],
25
- size: raw['Size'],
44
+ aspectRatio: raw['AspectRatio'],
45
+ iframeTitle: raw['IframeTitle'],
26
46
  };
27
47
  }
28
48
  exports.deserializeUnfurlIframe = deserializeUnfurlIframe;
@@ -30,7 +50,44 @@ exports.deserializeUnfurlIframe = deserializeUnfurlIframe;
30
50
  function serializeUnfurlIframe(concrete) {
31
51
  return {
32
52
  'IframeUrl': concrete.iframeUrl,
33
- 'Size': concrete.size,
53
+ 'AspectRatio': concrete.aspectRatio,
54
+ 'IframeTitle': concrete.iframeTitle,
34
55
  };
35
56
  }
36
57
  exports.serializeUnfurlIframe = serializeUnfurlIframe;
58
+ /** @ignore */
59
+ function getIFrameHeight(unfurlIframeAspectRatio) {
60
+ switch (unfurlIframeAspectRatio) {
61
+ case UnfurlIframeAspectRatio.Square:
62
+ return 1;
63
+ case UnfurlIframeAspectRatio.SixteenToNine:
64
+ return 9;
65
+ case UnfurlIframeAspectRatio.NineToSixteen:
66
+ return 16;
67
+ case UnfurlIframeAspectRatio.FourToThree:
68
+ return 3;
69
+ case UnfurlIframeAspectRatio.ThreeToFour:
70
+ return 4;
71
+ default:
72
+ return 9;
73
+ }
74
+ }
75
+ exports.getIFrameHeight = getIFrameHeight;
76
+ /** @ignore */
77
+ function getIFrameWidth(unfurlIframeAspectRatio) {
78
+ switch (unfurlIframeAspectRatio) {
79
+ case UnfurlIframeAspectRatio.Square:
80
+ return 1;
81
+ case UnfurlIframeAspectRatio.SixteenToNine:
82
+ return 16;
83
+ case UnfurlIframeAspectRatio.NineToSixteen:
84
+ return 9;
85
+ case UnfurlIframeAspectRatio.FourToThree:
86
+ return 4;
87
+ case UnfurlIframeAspectRatio.ThreeToFour:
88
+ return 3;
89
+ default:
90
+ return 16;
91
+ }
92
+ }
93
+ exports.getIFrameWidth = getIFrameWidth;
@@ -1,3 +1,4 @@
1
+ import { UnfurlIframe } from '../../core/unfurl/unfurliframe';
1
2
  import { BlockProxy } from '../blockproxy';
2
3
  /**
3
4
  * @ignore
@@ -12,6 +13,12 @@ export declare class ExperimentalLinkUnfurlBlockProxy extends BlockProxy {
12
13
  * @ignore
13
14
  */
14
15
  getTitle(): string;
16
+ /**
17
+ * Sets the title on the block, which is the main text shown on the block.
18
+ *
19
+ * @ignore
20
+ */
21
+ setTitle(title: string): void;
15
22
  /**
16
23
  * Returns the name of the service the link belongs to, such as "Lucid" or "Google", as displayed below the title on
17
24
  * the block.
@@ -24,7 +31,7 @@ export declare class ExperimentalLinkUnfurlBlockProxy extends BlockProxy {
24
31
  *
25
32
  * @ignore
26
33
  */
27
- setIframeUrl(iframeUrl: string): void;
34
+ setIframe(unfurlIframe: UnfurlIframe): void;
28
35
  /**
29
36
  * Sets the main thumbnail on the block
30
37
  *
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExperimentalLinkUnfurlBlockProxy = void 0;
4
+ const iframeutils_1 = require("../../core/iframe/iframeutils");
5
+ const unfurliframe_1 = require("../../core/unfurl/unfurliframe");
4
6
  const blockproxy_1 = require("../blockproxy");
5
7
  /**
6
8
  * @ignore
@@ -16,6 +18,14 @@ class ExperimentalLinkUnfurlBlockProxy extends blockproxy_1.BlockProxy {
16
18
  getTitle() {
17
19
  return this.textAreas.get('t_LinkUnfurlTitle');
18
20
  }
21
+ /**
22
+ * Sets the title on the block, which is the main text shown on the block.
23
+ *
24
+ * @ignore
25
+ */
26
+ setTitle(title) {
27
+ this.textAreas.set('t_LinkUnfurlTitle', title, { force: true });
28
+ }
19
29
  /**
20
30
  * Returns the name of the service the link belongs to, such as "Lucid" or "Google", as displayed below the title on
21
31
  * the block.
@@ -30,8 +40,16 @@ class ExperimentalLinkUnfurlBlockProxy extends blockproxy_1.BlockProxy {
30
40
  *
31
41
  * @ignore
32
42
  */
33
- setIframeUrl(iframeUrl) {
34
- throw new Error('Not yet implemented');
43
+ setIframe(unfurlIframe) {
44
+ const iframeAttributes = {
45
+ src: unfurlIframe.iframeUrl,
46
+ height: unfurlIframe.aspectRatio ? (0, unfurliframe_1.getIFrameHeight)(unfurlIframe.aspectRatio) : iframeutils_1.DEFAULT_IFRAME_HEIGHT,
47
+ width: unfurlIframe.aspectRatio ? (0, unfurliframe_1.getIFrameWidth)(unfurlIframe.aspectRatio) : iframeutils_1.DEFAULT_IFRAME_WIDTH,
48
+ title: unfurlIframe.iframeTitle,
49
+ };
50
+ this.properties.set('LinkUnfurlIframeHtml', (0, iframeutils_1.generateIFrameHTML)(iframeAttributes));
51
+ this.properties.set('LinkUnfurlIframeHeight', iframeAttributes.height);
52
+ this.properties.set('LinkUnfurlIframeWidth', iframeAttributes.width);
35
53
  }
36
54
  /**
37
55
  * Sets the main thumbnail on the block
@@ -21,10 +21,11 @@ class ItemProxy extends elementproxy_1.ElementProxy {
21
21
  this.textAreas = new mapproxy_1.WriteableMapProxy(() => this.client.sendCommand("lta" /* ListTextAreas */, this.id), (name) => this.client.sendCommand("gp" /* GetProperty */, {
22
22
  'id': this.id,
23
23
  'p': name,
24
- }), (name, plainText) => this.client.sendCommand("sp" /* SetProperty */, {
24
+ }), (name, plainText, options) => this.client.sendCommand("st" /* SetText */, {
25
25
  'id': this.id,
26
- 'p': name,
27
- 'v': plainText,
26
+ 'n': name,
27
+ 't': plainText,
28
+ 'f': options === null || options === void 0 ? void 0 : options.force,
28
29
  }));
29
30
  }
30
31
  /**
@@ -17,6 +17,9 @@ export declare class MapProxy<KEY, VALUE> {
17
17
  }
18
18
  export declare class WriteableMapProxy<KEY, VALUE> extends MapProxy<KEY, VALUE> {
19
19
  private readonly setter;
20
- constructor(getKeys: () => KEY[], getItem: (key: KEY) => VALUE, setter: (key: KEY, val: VALUE) => void);
21
- set(key: KEY, value: VALUE): void;
20
+ constructor(getKeys: () => KEY[], getItem: (key: KEY) => VALUE, setter: (key: KEY, val: VALUE, options?: SetterOptions) => void);
21
+ set(key: KEY, value: VALUE, options?: SetterOptions): void;
22
+ }
23
+ export interface SetterOptions {
24
+ force?: boolean;
22
25
  }
@@ -58,8 +58,8 @@ class WriteableMapProxy extends MapProxy {
58
58
  super(getKeys, getItem);
59
59
  this.setter = setter;
60
60
  }
61
- set(key, value) {
62
- this.setter(key, value);
61
+ set(key, value, options = {}) {
62
+ this.setter(key, value, options);
63
63
  }
64
64
  }
65
65
  exports.WriteableMapProxy = WriteableMapProxy;
@@ -220,7 +220,7 @@ class EditorClient {
220
220
  if (msg.blockId) {
221
221
  const proxy = this.getBlockProxy(msg.blockId);
222
222
  if (proxy instanceof linkunfurlblockproxy_1.ExperimentalLinkUnfurlBlockProxy) {
223
- await ((_a = callbacks.afterUnfurlCallback) === null || _a === void 0 ? void 0 : _a.call(callbacks, proxy));
223
+ await ((_a = callbacks.afterUnfurlCallback) === null || _a === void 0 ? void 0 : _a.call(callbacks, proxy, msg.url));
224
224
  }
225
225
  }
226
226
  }