expensify-common 2.0.188 → 2.0.190

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 (78) hide show
  1. package/dist/Logger.js +11 -1
  2. package/dist/esm/API.d.ts +11 -0
  3. package/dist/esm/API.js +786 -0
  4. package/dist/esm/APIDeferred.d.ts +7 -0
  5. package/dist/esm/APIDeferred.js +216 -0
  6. package/dist/esm/BrowserDetect.d.ts +19 -0
  7. package/dist/esm/BrowserDetect.js +105 -0
  8. package/dist/esm/CLI.js +37 -29
  9. package/dist/esm/CONST.d.ts +1727 -0
  10. package/dist/esm/CONST.js +1847 -0
  11. package/dist/esm/Cookie.d.ts +68 -0
  12. package/dist/esm/Cookie.js +159 -0
  13. package/dist/esm/CredentialsWrapper.d.ts +32 -0
  14. package/dist/esm/CredentialsWrapper.js +46 -0
  15. package/dist/esm/Device.d.ts +8 -0
  16. package/dist/esm/Device.js +24 -0
  17. package/dist/esm/ExpenseRule.d.ts +39 -0
  18. package/dist/esm/ExpenseRule.js +77 -0
  19. package/dist/esm/ExpensiMark.d.ts +197 -0
  20. package/dist/esm/ExpensiMark.js +1374 -0
  21. package/dist/esm/Func.d.ts +40 -0
  22. package/dist/esm/Func.js +69 -0
  23. package/dist/esm/Log.d.ts +3 -0
  24. package/dist/esm/Log.js +35 -0
  25. package/dist/esm/Logger.d.ts +82 -0
  26. package/dist/esm/Logger.js +148 -0
  27. package/dist/esm/Network.d.ts +6 -0
  28. package/dist/esm/Network.js +168 -0
  29. package/dist/esm/Num.d.ts +95 -0
  30. package/dist/esm/Num.js +190 -0
  31. package/dist/esm/PageEvent.d.ts +25 -0
  32. package/dist/esm/PageEvent.js +22 -0
  33. package/dist/esm/PubSub.d.ts +2 -0
  34. package/dist/esm/PubSub.js +111 -0
  35. package/dist/esm/ReportHistoryStore.d.ts +8 -0
  36. package/dist/esm/ReportHistoryStore.js +199 -0
  37. package/dist/esm/SafeString.js +2 -2
  38. package/dist/esm/Templates.d.ts +58 -0
  39. package/dist/esm/Templates.js +196 -0
  40. package/dist/esm/Url.d.ts +10 -0
  41. package/dist/esm/Url.js +15 -0
  42. package/dist/esm/components/CopyText.d.ts +45 -0
  43. package/dist/esm/components/CopyText.js +56 -0
  44. package/dist/esm/components/StepProgressBar.d.ts +26 -0
  45. package/dist/esm/components/StepProgressBar.js +40 -0
  46. package/dist/esm/components/form/element/combobox.d.ts +231 -0
  47. package/dist/esm/components/form/element/combobox.js +812 -0
  48. package/dist/esm/components/form/element/dropdown.d.ts +35 -0
  49. package/dist/esm/components/form/element/dropdown.js +61 -0
  50. package/dist/esm/components/form/element/dropdownItem.d.ts +55 -0
  51. package/dist/esm/components/form/element/dropdownItem.js +113 -0
  52. package/dist/esm/components/form/element/onOffSwitch.d.ts +94 -0
  53. package/dist/esm/components/form/element/onOffSwitch.js +167 -0
  54. package/dist/esm/components/form/element/switch.d.ts +58 -0
  55. package/dist/esm/components/form/element/switch.js +98 -0
  56. package/dist/esm/fastMerge.d.ts +9 -0
  57. package/dist/esm/fastMerge.js +58 -0
  58. package/dist/esm/index.d.ts +22 -0
  59. package/dist/esm/index.js +22 -0
  60. package/dist/esm/jquery.expensifyIframify.d.ts +9 -0
  61. package/dist/esm/jquery.expensifyIframify.js +397 -0
  62. package/dist/esm/md5.d.ts +2 -0
  63. package/dist/esm/md5.js +170 -0
  64. package/dist/esm/mixins/PubSub.d.ts +20 -0
  65. package/dist/esm/mixins/PubSub.js +47 -0
  66. package/dist/esm/mixins/extraClasses.d.ts +8 -0
  67. package/dist/esm/mixins/extraClasses.js +37 -0
  68. package/dist/esm/mixins/validationClasses.d.ts +12 -0
  69. package/dist/esm/mixins/validationClasses.js +30 -0
  70. package/dist/esm/str.d.ts +604 -0
  71. package/dist/esm/str.js +1036 -0
  72. package/dist/esm/tlds.d.ts +2 -0
  73. package/dist/esm/tlds.js +2 -0
  74. package/dist/esm/utils.d.ts +30 -0
  75. package/dist/esm/utils.js +65 -0
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.js +8 -1
  78. package/package.json +221 -4
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Merges two objects and removes null values if "shouldRemoveNullObjectValues" is set to true
3
+ *
4
+ * We generally want to remove null values from objects written to disk and cache, because it decreases the amount of data stored in memory and on disk.
5
+ * On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
6
+ * To be consistent with the behaviour for merge, we'll also want to remove null values for "set" operations.
7
+ */
8
+ declare function fastMerge<TObject>(target: TObject, source: TObject, shouldRemoveNullObjectValues?: boolean): TObject;
9
+ export default fastMerge;
@@ -0,0 +1,58 @@
1
+ 'worklet';
2
+ // Mostly copied from https://medium.com/@lubaka.a/how-to-remove-lodash-performance-improvement-b306669ad0e1
3
+ /**
4
+ * Checks whether the given value can be merged. It has to be an object, but not an array, RegExp or Date.
5
+ */
6
+ function isMergeableObject(value) {
7
+ const nonNullObject = value != null ? typeof value === 'object' : false;
8
+ return nonNullObject && Object.prototype.toString.call(value) !== '[object RegExp]' && Object.prototype.toString.call(value) !== '[object Date]' && !Array.isArray(value);
9
+ }
10
+ function fastMerge(target, source, shouldRemoveNullObjectValues = true) {
11
+ // We have to ignore arrays and nullish values here,
12
+ // otherwise "mergeObject" will throw an error,
13
+ // because it expects an object as "source"
14
+ if (Array.isArray(source) || source === null || source === undefined) {
15
+ return source;
16
+ }
17
+ // Merges the source object into the target object.
18
+ const destination = {};
19
+ if (isMergeableObject(target)) {
20
+ // lodash adds a small overhead so we don't use it here
21
+ const targetKeys = Object.keys(target);
22
+ for (let i = 0; i < targetKeys.length; ++i) {
23
+ const key = targetKeys[i];
24
+ const sourceValue = source === null || source === void 0 ? void 0 : source[key];
25
+ const targetValue = target === null || target === void 0 ? void 0 : target[key];
26
+ // If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
27
+ const isSourceOrTargetNull = targetValue === null || sourceValue === null;
28
+ const shouldOmitSourceKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
29
+ if (!shouldOmitSourceKey) {
30
+ destination[key] = targetValue;
31
+ }
32
+ }
33
+ }
34
+ // lodash adds a small overhead so we don't use it here
35
+ const sourceKeys = Object.keys(source);
36
+ for (let i = 0; i < sourceKeys.length; ++i) {
37
+ const key = sourceKeys[i];
38
+ const sourceValue = source === null || source === void 0 ? void 0 : source[key];
39
+ const targetValue = target === null || target === void 0 ? void 0 : target[key];
40
+ // If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
41
+ const shouldOmitSourceKey = shouldRemoveNullObjectValues && sourceValue === null;
42
+ // If we pass undefined as the updated value for a key, we want to generally ignore it
43
+ const isSourceKeyUndefined = sourceValue === undefined;
44
+ if (!isSourceKeyUndefined && !shouldOmitSourceKey) {
45
+ const isSourceKeyMergable = isMergeableObject(sourceValue);
46
+ if (isSourceKeyMergable && targetValue) {
47
+ if (!shouldRemoveNullObjectValues || isSourceKeyMergable) {
48
+ destination[key] = fastMerge(targetValue, sourceValue, shouldRemoveNullObjectValues);
49
+ }
50
+ }
51
+ else if (!shouldRemoveNullObjectValues || sourceValue !== null) {
52
+ destination[key] = sourceValue;
53
+ }
54
+ }
55
+ }
56
+ return destination;
57
+ }
58
+ export default fastMerge;
@@ -0,0 +1,22 @@
1
+ export { default as API } from './API';
2
+ export { default as APIDeferred } from './APIDeferred';
3
+ export { default as BrowserDetect } from './BrowserDetect';
4
+ export { g_cloudFront, g_cloudFrontImg, CONST, UI, PUBLIC_DOMAINS_SET } from './CONST';
5
+ export { default as Cookie } from './Cookie';
6
+ export { default as CredentialsWrapper, LOGIN_PARTNER_DETAILS } from './CredentialsWrapper';
7
+ export * as Device from './Device';
8
+ export { default as ExpensiMark } from './ExpensiMark';
9
+ export { default as Logger } from './Logger';
10
+ export { default as Network } from './Network';
11
+ export { default as Num } from './Num';
12
+ export { default as PageEvent } from './PageEvent';
13
+ export { default as PubSub } from './PubSub';
14
+ export { default as ReportHistoryStore } from './ReportHistoryStore';
15
+ export { default as Templates } from './Templates';
16
+ export * as Url from './Url';
17
+ export { default as fastMerge } from './fastMerge';
18
+ export { default as Str } from './str';
19
+ export { default as TLD_REGEX } from './tlds';
20
+ export { default as md5 } from './md5';
21
+ export { default as SafeString } from './SafeString';
22
+ export { escapeText, isFunction, isNavigatorAvailable, isObject, isWindowAvailable, unescapeText } from './utils';
@@ -0,0 +1,22 @@
1
+ export { default as API } from './API';
2
+ export { default as APIDeferred } from './APIDeferred';
3
+ export { default as BrowserDetect } from './BrowserDetect';
4
+ export { g_cloudFront, g_cloudFrontImg, CONST, UI, PUBLIC_DOMAINS_SET } from './CONST';
5
+ export { default as Cookie } from './Cookie';
6
+ export { default as CredentialsWrapper, LOGIN_PARTNER_DETAILS } from './CredentialsWrapper';
7
+ export * as Device from './Device';
8
+ export { default as ExpensiMark } from './ExpensiMark';
9
+ export { default as Logger } from './Logger';
10
+ export { default as Network } from './Network';
11
+ export { default as Num } from './Num';
12
+ export { default as PageEvent } from './PageEvent';
13
+ export { default as PubSub } from './PubSub';
14
+ export { default as ReportHistoryStore } from './ReportHistoryStore';
15
+ export { default as Templates } from './Templates';
16
+ export * as Url from './Url';
17
+ export { default as fastMerge } from './fastMerge';
18
+ export { default as Str } from './str';
19
+ export { default as TLD_REGEX } from './tlds';
20
+ export { default as md5 } from './md5';
21
+ export { default as SafeString } from './SafeString';
22
+ export { escapeText, isFunction, isNavigatorAvailable, isObject, isWindowAvailable, unescapeText } from './utils';
@@ -0,0 +1,9 @@
1
+ declare namespace _default {
2
+ /**
3
+ * Loads the widget into jQuery
4
+ *
5
+ * @param {jQuery} $ jQuery instance
6
+ */
7
+ function load($: JQueryStatic): void;
8
+ }
9
+ export default _default;
@@ -0,0 +1,397 @@
1
+ /**
2
+ * This is a jQuery plugin that provides some iFrame functionality like
3
+ * posting messages to the parent window.
4
+ *
5
+ * Usage:
6
+ *
7
+ * From inside the iFrame:
8
+ * $.fn.expensifyIframeify( 'resize', { height: 100, width: 400 } );
9
+ * $.fn.expensifyIframeify( 'tellParent', { name: 'say', data: { msg: 'Hello world!' } } );
10
+ *
11
+ * From inside the parent:
12
+ * $( '#myIframe' ).expensifyIframeify( 'on', 'resize', function( data ) { ... } );
13
+ * $( '#myIframe' ).expensifyIframeify( 'on', 'say', function( data ) {
14
+ * // alerts "Hello world!"
15
+ * alert( data.msg );
16
+ * });
17
+ */
18
+ export default {
19
+ /**
20
+ * Loads the widget into jQuery
21
+ *
22
+ * @param {jQuery} $ jQuery instance
23
+ */
24
+ load($) {
25
+ /**
26
+ * Holds the value normally stored in window.location.origin but it's calculated
27
+ * according to the suggested solutions
28
+ * Issue:
29
+ * - https://github.com/Expensify/Expensify/issues/13192#issuecomment-100322844
30
+ * Solution suggested in the following sites:
31
+ * - http://stackoverflow.com/questions/22564167/window-location-origin-gives-wrong-path-when-using-ie
32
+ * - http://tosbourn.com/a-fix-for-window-location-origin-in-internet-explorer/
33
+ *
34
+ * Believe it or not before this change this was causing a syntax error in IE10 that disappears with this change
35
+ *
36
+ * @type {String} jQuery Element
37
+ */
38
+ const defaultOrigin = `${window.location.protocol}//${window.location.hostname}`;
39
+ /**
40
+ * This indicates from and to which domains we need to send the messages.
41
+ * @type {object}
42
+ */
43
+ const allowedCommunications = {
44
+ 'https://www.expensify.com': ['https://secure.expensify.com', 'https://www.expensify.com'],
45
+ 'https://secure.expensify.com': ['https://www.expensify.com', 'https://secure.expensify.com', 'https://salesforce.expensify.com'],
46
+ 'https://staging.expensify.com': ['https://staging.expensify.com', 'https://staging-secure.expensify.com'],
47
+ 'https://staging-secure.expensify.com': ['https://staging.expensify.com', 'https://staging-secure.expensify.com'],
48
+ 'https://www.expensify.com.dev': ['https://secure.expensify.com.dev', 'https://www.expensify.com.dev'],
49
+ 'https://secure.expensify.com.dev': ['https://www.expensify.com.dev', 'https://secure.expensify.com.dev'],
50
+ 'https://salesforce.expensify.com': ['https://secure.expensify.com'],
51
+ 'https://www.google.com': ['https://secure.expensify.com.dev', 'https://secure.expensify.com'],
52
+ 'https://cdn.plaid.com': ['https://secure.expensify.com'],
53
+ };
54
+ /**
55
+ * Holds a reference to the jQuery iFrame object
56
+ *
57
+ * @type {object} jQuery Element
58
+ */
59
+ let iframeElement = null;
60
+ /**
61
+ * Whether or not the parent window is listening to the message event
62
+ *
63
+ * @type {Boolean}
64
+ */
65
+ let parentIsListening = false;
66
+ /**
67
+ * Whether or not the plugin has been initialized
68
+ * @type {Boolean}
69
+ */
70
+ let wasInitalized = false;
71
+ /**
72
+ * Whether or not the iframe is listening to the message event
73
+ *
74
+ * @type {Boolean}
75
+ */
76
+ let iframeIsListening = false;
77
+ /**
78
+ * Keeps a record of if this script is running from the "parent" or the "iframe"
79
+ * so that we only have to do this logic once.
80
+ */
81
+ let whatIAm;
82
+ /**
83
+ * Default settings for our plugin
84
+ *
85
+ * @type {object}
86
+ */
87
+ let settings = {
88
+ origin: defaultOrigin,
89
+ debug: false,
90
+ };
91
+ /**
92
+ * Holds all of our registered event handlers
93
+ *
94
+ * @type {object}
95
+ */
96
+ let eventHandlers = {};
97
+ /**
98
+ * A method for logging things to the console for debugging
99
+ * @param {...any} args
100
+ */
101
+ function log(...args) {
102
+ if (!settings.debug) {
103
+ return;
104
+ }
105
+ // Make an array out of our arguments
106
+ const mainArguments = Array.prototype.slice.call(args);
107
+ const source = whatIAm === 'parent' ? 'Parent' : 'Iframe';
108
+ mainArguments.unshift(`${source}:`);
109
+ mainArguments.unshift('[EXPENSIFYIFRAMEIFY]');
110
+ console.log(...mainArguments); // eslint-disable-line no-console
111
+ }
112
+ /**
113
+ * Forms the message to send to our parent. The message structure is like:
114
+ *
115
+ * Full example:
116
+ * iframeify:<iframeId>:<name>☢<data>
117
+ *
118
+ * Lite example:
119
+ * iframeify:<name>
120
+ *
121
+ * Where:
122
+ * - <iframeId> (optional) is the "id" attribute of the iframe
123
+ * - <name> (required) is the name of the event
124
+ * - <data> (optional) is a stringified glob of data
125
+ *
126
+ * @param {string} name the name of the message to send
127
+ * @param {object} data to send in the message
128
+ * @param {boolean|undefined} postToIframe if true, then we post the message
129
+ * to the iFrame or else we post
130
+ * the message to the parent
131
+ */
132
+ function postMessage(name, data, postToIframe) {
133
+ let msg = 'iframeify';
134
+ if (iframeElement.iframeId) {
135
+ msg += `:${iframeElement.iframeId}`;
136
+ }
137
+ msg += `:${name}`;
138
+ if (data) {
139
+ msg += '☢';
140
+ msg += JSON.stringify(data);
141
+ }
142
+ const isCommunicationAllowed = allowedCommunications[settings.origin];
143
+ if (!isCommunicationAllowed) {
144
+ log('not posting message, communication from this domain is not allowed', settings.origin, name, data);
145
+ }
146
+ let targetOrigin;
147
+ // Sending message from the iFrame to the parent
148
+ // Only post a message if this is in an iFrame
149
+ if (!postToIframe && window.parent !== window) {
150
+ targetOrigin = `${window.parent.location.protocol}//${window.parent.location.hostname}`;
151
+ log('posting message to parent', targetOrigin, msg);
152
+ window.parent.postMessage(msg, targetOrigin);
153
+ }
154
+ // Sending message from the parent to the iFrame
155
+ if (postToIframe && iframeElement[0].contentWindow) {
156
+ targetOrigin = `${iframeElement[0].contentWindow.location.protocol}//${iframeElement[0].contentWindow.location.hostname}`;
157
+ log('posting message to iframe', targetOrigin, msg);
158
+ iframeElement[0].contentWindow.postMessage(msg, targetOrigin);
159
+ }
160
+ }
161
+ /**
162
+ * Calls all the methods associated with the event name
163
+ * and passes it the given data
164
+ *
165
+ * @param {string} name of the event
166
+ * @param {mixed} data passed to the event handler
167
+ * @param {string} [iframeId]
168
+ */
169
+ function trigger(name, data, iframeId) {
170
+ log(`heard event "${name}"`, data);
171
+ const id = iframeId || iframeElement.iframeId;
172
+ if (eventHandlers[id] && eventHandlers[id][name] && eventHandlers[id][name].length) {
173
+ const listeners = eventHandlers[id][name];
174
+ for (let i = 0; i < listeners.length; i += 1) {
175
+ listeners[i](data);
176
+ }
177
+ }
178
+ }
179
+ /**
180
+ * Handles the window message by parsing the data
181
+ * and relaying it to our event listeners
182
+ *
183
+ * @param {Event} e jQuery event
184
+ */
185
+ function handleWindowMessage(e) {
186
+ // Use the original event to get our data properly
187
+ const event = e.originalEvent;
188
+ if (!event.origin || !event.target) {
189
+ return;
190
+ }
191
+ if (allowedCommunications[event.origin] &&
192
+ allowedCommunications[event.origin].indexOf('*') === -1 &&
193
+ allowedCommunications[event.origin].indexOf(`${event.target.location.protocol}//${event.target.location.hostname}`) === -1) {
194
+ log('not handling message, communication from this domain is not allowed', settings.origin);
195
+ return;
196
+ }
197
+ if (!event.data || (typeof event.data !== 'string' && !(event.data instanceof String))) {
198
+ return;
199
+ }
200
+ // Get the pieces of our message (should be two)
201
+ const msgParts = event.data.split('☢');
202
+ if (!msgParts.length) {
203
+ return;
204
+ }
205
+ // Get the pieces of our name (should be two or three)
206
+ // and extract the event name and the iframe ID
207
+ const nameParts = msgParts[0].split(':');
208
+ if (!nameParts.length || nameParts.length > 3) {
209
+ return;
210
+ }
211
+ let iframeId = null;
212
+ let eventName = null;
213
+ let data = null;
214
+ if (nameParts.length === 3) {
215
+ iframeId = nameParts[1];
216
+ eventName = nameParts[2];
217
+ }
218
+ else if (nameParts.length === 2) {
219
+ eventName = nameParts[1];
220
+ }
221
+ // Get the data
222
+ if (msgParts.length > 1) {
223
+ try {
224
+ data = JSON.parse(msgParts[1]);
225
+ }
226
+ catch (_a) {
227
+ // This should only happen if someone didn't code something right
228
+ console.error('Could not parse JSON response for some reason', event.data);
229
+ }
230
+ }
231
+ // Trigger any listeners for this event
232
+ trigger(eventName, data, iframeId);
233
+ }
234
+ const actions = {
235
+ // Add actions here
236
+ /**
237
+ * Tells the parent to dynamically resize the iFrame
238
+ *
239
+ * @param {object} args
240
+ * @param {string} args.id the ID of the iFrame to resize
241
+ * @param {integer} args.height (optional) the height to set the iFrame to
242
+ * @param {integer} args.width (optional) the width to set the iFrame to
243
+ */
244
+ resize(args) {
245
+ const size = {};
246
+ if (args.height !== undefined) {
247
+ size.height = args.height;
248
+ }
249
+ if (args.width !== undefined) {
250
+ size.width = args.width;
251
+ }
252
+ postMessage('resize', size);
253
+ },
254
+ /**
255
+ * Tell our parent a generic message
256
+ *
257
+ * @param {object} args
258
+ * @param {string} args.name the name of the message to post
259
+ * @param {object} args.data (optional) to send with the message
260
+ */
261
+ tellParent(args) {
262
+ postMessage(args.name, args.data);
263
+ },
264
+ /**
265
+ * Tell our iFrame a generic message
266
+ *
267
+ * @param {object} args
268
+ * @param {string} args.name the name of the message to post
269
+ * @param {object} args.data (optional) to send with the message
270
+ */
271
+ tellIframe(args) {
272
+ postMessage(args.name, args.data, true);
273
+ },
274
+ /**
275
+ * Register an event handler. The callback will be stored
276
+ * for the particular iFrame ID so that you can listen to
277
+ * multiple iFrames if you want
278
+ *
279
+ * @param {string} name of the event
280
+ * @param {Function} callback
281
+ */
282
+ on(name, callback) {
283
+ log(`listening to event "${name}"`);
284
+ if (!eventHandlers[iframeElement.iframeId]) {
285
+ eventHandlers[iframeElement.iframeId] = {};
286
+ }
287
+ if (!eventHandlers[iframeElement.iframeId][name]) {
288
+ eventHandlers[iframeElement.iframeId][name] = [];
289
+ }
290
+ eventHandlers[iframeElement.iframeId][name].push(callback);
291
+ },
292
+ /**
293
+ * Unregister all handlers for an event. If name is null
294
+ * then all handlers will be removed
295
+ *
296
+ * @param {string} name (optional) of the event
297
+ */
298
+ off(name) {
299
+ log(`stop listening to event "${name}"`);
300
+ if (iframeElement.iframeId) {
301
+ if (eventHandlers[iframeElement.iframeId]) {
302
+ if (!name) {
303
+ eventHandlers[iframeElement.iframeId] = {};
304
+ }
305
+ else {
306
+ delete eventHandlers[iframeElement.iframeId][name];
307
+ }
308
+ }
309
+ }
310
+ else if (!name) {
311
+ eventHandlers = {};
312
+ }
313
+ else {
314
+ for (const handlerMap of Object.values(eventHandlers)) {
315
+ delete handlerMap[name];
316
+ }
317
+ }
318
+ },
319
+ /**
320
+ * Tears down the plugin by
321
+ * - removing all event handlers
322
+ * - stop listening to the 'message' window event
323
+ */
324
+ destroy() {
325
+ $(window).off('message', handleWindowMessage);
326
+ parentIsListening = false;
327
+ iframeIsListening = false;
328
+ iframeElement = null;
329
+ },
330
+ };
331
+ /* eslint-disable no-param-reassign */
332
+ /**
333
+ * The method that we expose to jQuery. Is used to set options
334
+ * or perform actions
335
+ *
336
+ * @param {mixed} actionOrOptions string of an action to perform
337
+ * object of options to set
338
+ * @param {object} args to pass to an action method
339
+ * @param {function} callback (optional) for event handlers
340
+ *
341
+ * @returns {[type]}
342
+ */
343
+ $.fn.expensifyIframeify = function (actionOrOptions, args, callback) {
344
+ /* eslint-enable no-param-reassign */
345
+ const urlArray = defaultOrigin.split('://');
346
+ const domainArray = urlArray[1].split('.');
347
+ const subdomain = domainArray.shift();
348
+ const domainWithoutSubdomain = domainArray.join('.');
349
+ // There are some browsers that don't support document.domain so we have to manually create it
350
+ document.domain = domainWithoutSubdomain;
351
+ iframeElement = this;
352
+ if (!wasInitalized) {
353
+ // Determine if this is the parent, or the iframe
354
+ // Because our site runs inside of an iframe in salesforce, the parent
355
+ // will actually think it's an iframe too. So here, we detect that we're on
356
+ // the salesforce subdomain and we know that we should be the parent
357
+ whatIAm = window.parent === window || subdomain === 'salesforce' ? 'parent' : 'iframe';
358
+ log('I am the:', whatIAm);
359
+ wasInitalized = true;
360
+ }
361
+ // The iframeId is pulled from the frameElement (if this is inside an iFrame)
362
+ // or it's pulled from the element that this plugin was called from.
363
+ //
364
+ // Example:
365
+ // $( '#myIframe' ).expensifyIframeify();
366
+ //
367
+ // 'myIframe' would be the frameId
368
+ iframeElement.iframeId = whatIAm === 'iframe' ? $(window.frameElement).attr('id') : iframeElement.attr('id');
369
+ // Figure out if we are doing an action or setting options
370
+ if (typeof actionOrOptions === 'string') {
371
+ if (typeof actions[actionOrOptions] !== 'undefined') {
372
+ actions[actionOrOptions](args, callback);
373
+ }
374
+ }
375
+ else {
376
+ // Extend our default settings
377
+ settings = $.extend(settings, actionOrOptions);
378
+ }
379
+ // If this is the parent page, then we can start listening to messages
380
+ // from the iFrame
381
+ if (whatIAm === 'parent' && !parentIsListening) {
382
+ $(window).on('message', handleWindowMessage);
383
+ parentIsListening = true;
384
+ log('parent is listening for messages');
385
+ }
386
+ // If this is the iFrame, then we can start listening to messages
387
+ // from the iFrame
388
+ if (whatIAm === 'iframe' && !iframeIsListening) {
389
+ $(window).on('message', handleWindowMessage);
390
+ iframeIsListening = true;
391
+ log('iframe is listening for messages');
392
+ }
393
+ // make this plugin chainable
394
+ return this;
395
+ };
396
+ },
397
+ };
@@ -0,0 +1,2 @@
1
+ declare function md5(s: string): string;
2
+ export default md5;