@atlassian/atlassian-connect-js 5.3.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.
- package/.depcheckrc.json +16 -0
- package/.editorconfig +9 -0
- package/.envrc +5 -0
- package/.eslintignore +12 -0
- package/.eslintrc +31 -0
- package/.husky/pre-commit +11 -0
- package/.lintstagedrc.js +6 -0
- package/.netrc +1 -0
- package/.npmrc-public +4 -0
- package/.nvmrc +1 -0
- package/LICENSE +3 -0
- package/README.md +281 -0
- package/bitbucket-pipelines.yml +33 -0
- package/build/bin/bin-helper.js +29 -0
- package/build/bin/npm-postinstall.js +9 -0
- package/build/configs/append-sourcemapping.js +13 -0
- package/build/configs/availabletasks.js +15 -0
- package/build/configs/clean.js +12 -0
- package/build/configs/concat.js +44 -0
- package/build/configs/copy.js +32 -0
- package/build/configs/index.js +19 -0
- package/build/configs/jshint.js +9 -0
- package/build/configs/karma.js +11 -0
- package/build/configs/replace.js +10 -0
- package/build/configs/requirejs.js +187 -0
- package/build/configs/saucelabs-launchers.js +30 -0
- package/build/configs/shell.js +24 -0
- package/build/configs/uglify.js +15 -0
- package/build/configs/watch.js +45 -0
- package/build/end.frag +13 -0
- package/build/start.frag +18 -0
- package/bundlesize.config.json +14 -0
- package/dist/connect-host.css +225 -0
- package/dist/connect-host.js +13908 -0
- package/dist/connect-host.min.css +1 -0
- package/dist/iframe-fedramp.js +13663 -0
- package/dist/iframe.js +13663 -0
- package/dist/legacy-text-colors.css +245 -0
- package/dist/surfaces.css +11 -0
- package/dist/themes/atlaskit-tokens_dark-future.css +6 -0
- package/dist/themes/atlaskit-tokens_dark.css +394 -0
- package/dist/themes/atlaskit-tokens_legacy-dark.css +394 -0
- package/dist/themes/atlaskit-tokens_legacy-light.css +394 -0
- package/dist/themes/atlaskit-tokens_light-future.css +6 -0
- package/dist/themes/atlaskit-tokens_light.css +394 -0
- package/dist/themes/atlaskit-tokens_shape.css +14 -0
- package/dist/themes/atlaskit-tokens_spacing.css +26 -0
- package/dist/themes/atlaskit-tokens_typography-adg3.css +25 -0
- package/dist/themes/atlaskit-tokens_typography-modernized.css +25 -0
- package/dist/themes/atlaskit-tokens_typography-refreshed.css +25 -0
- package/gulpfile.js +204 -0
- package/memleak-check/app.html +10 -0
- package/memleak-check/index.html +31 -0
- package/memleak-check/index.js +33 -0
- package/package.json +102 -0
- package/renovate.json +11 -0
- package/security-assistant.yml +2 -0
- package/spec/.eslintrc +10 -0
- package/spec/config/karma.base.conf.js +200 -0
- package/spec/config/karma.conf.js +20 -0
- package/spec/fixtures/base_dialog_component_tests.js +180 -0
- package/spec/mocks/mock_feature_flag.js +23 -0
- package/spec/tests/amd_spec.js +122 -0
- package/spec/tests/analytics_dispatcher_spec.js +429 -0
- package/spec/tests/analytics_performance_spec.js +41 -0
- package/spec/tests/button_spec.js +143 -0
- package/spec/tests/dialog_extension_spec.js +59 -0
- package/spec/tests/dialog_module_provider_spec.js +499 -0
- package/spec/tests/dialog_module_spec.js +395 -0
- package/spec/tests/dialog_spec.js +296 -0
- package/spec/tests/dialog_webitem_spec.js +183 -0
- package/spec/tests/dropdown_module_spec.js +77 -0
- package/spec/tests/env_module_spec.js +153 -0
- package/spec/tests/events_spec.js +77 -0
- package/spec/tests/extension_configuration_options_store_spec.js +25 -0
- package/spec/tests/flag_module_provider_spec.js +79 -0
- package/spec/tests/flag_module_spec.js +118 -0
- package/spec/tests/flag_spec.js +243 -0
- package/spec/tests/host-api_spec.js +220 -0
- package/spec/tests/iframe-create_spec.js +43 -0
- package/spec/tests/iframe_container_spec.js +19 -0
- package/spec/tests/iframe_spec.js +265 -0
- package/spec/tests/inline_dialog_spec.js +41 -0
- package/spec/tests/inline_dialog_webitem_spec.js +331 -0
- package/spec/tests/loading_indicator_spec.js +48 -0
- package/spec/tests/messages_module_spec.js +108 -0
- package/spec/tests/meta_spec.js +71 -0
- package/spec/tests/module_args_spec.js +52 -0
- package/spec/tests/observe_spec.js +73 -0
- package/spec/tests/public_events.spec.js +102 -0
- package/spec/tests/scroll_position_spec.js +109 -0
- package/spec/tests/theming_spec.js +594 -0
- package/spec/tests/util_spec.js +55 -0
- package/spec/tests/utils/base64_spec.js +20 -0
- package/spec/tests/utils/button_spec.js +11 -0
- package/spec/tests/utils/cookie_spec.js +19 -0
- package/spec/tests/utils/deprecate_spec.js +22 -0
- package/spec/tests/utils/dialog_spec.js +297 -0
- package/spec/tests/utils/host_util_spec.js +45 -0
- package/spec/tests/utils/iframe_spec.js +41 -0
- package/spec/tests/utils/jwt_spec.js +135 -0
- package/spec/tests/utils/url_spec.js +37 -0
- package/spec/tests/utils/waitUntilReadyNextTick.js +5 -0
- package/spec/tests/utils/webitem.js +219 -0
- package/spec/tests/webitem_spec.js +131 -0
- package/src/css/host/dialog.css +144 -0
- package/src/css/host/flags.css +5 -0
- package/src/css/host/host.css +64 -0
- package/src/css/host/messages.css +12 -0
- package/src/css/plugin/legacy-text-colors.less +55 -0
- package/src/css/plugin/surfaces.css +11 -0
- package/src/host/ACJSFrameworkAdaptor.js +44 -0
- package/src/host/actions/analytics_action.js +35 -0
- package/src/host/actions/button_actions.js +21 -0
- package/src/host/actions/dialog_actions.js +27 -0
- package/src/host/actions/dialog_extension_actions.js +25 -0
- package/src/host/actions/dom_event_actions.js +32 -0
- package/src/host/actions/dropdown_actions.js +12 -0
- package/src/host/actions/env_actions.js +57 -0
- package/src/host/actions/event_actions.js +33 -0
- package/src/host/actions/flag_actions.js +22 -0
- package/src/host/actions/iframe_actions.js +27 -0
- package/src/host/actions/inline_dialog_actions.js +26 -0
- package/src/host/actions/inline_dialog_webitem_actions.js +10 -0
- package/src/host/actions/jwt_actions.js +51 -0
- package/src/host/actions/loading_indicator_actions.js +10 -0
- package/src/host/actions/module_actions.js +14 -0
- package/src/host/actions/webitem_actions.js +29 -0
- package/src/host/components/button.js +112 -0
- package/src/host/components/dialog.js +447 -0
- package/src/host/components/dialog_extension.js +106 -0
- package/src/host/components/dialog_webitem.js +69 -0
- package/src/host/components/flag.js +102 -0
- package/src/host/components/iframe.js +130 -0
- package/src/host/components/iframe_container.js +38 -0
- package/src/host/components/inline_dialog.js +108 -0
- package/src/host/components/inline_dialog_webitem.js +157 -0
- package/src/host/components/loading_indicator.js +110 -0
- package/src/host/components/webitem.js +227 -0
- package/src/host/deprecate.js +20 -0
- package/src/host/dispatchers/analytics_dispatcher.js +512 -0
- package/src/host/dispatchers/event_dispatcher.js +46 -0
- package/src/host/dollar.js +8 -0
- package/src/host/host-api.js +325 -0
- package/src/host/iframe-create.js +7 -0
- package/src/host/index.js +108 -0
- package/src/host/module-providers.js +13 -0
- package/src/host/modules/_featureFlag.js +42 -0
- package/src/host/modules/_performance.js +54 -0
- package/src/host/modules/analytics.js +17 -0
- package/src/host/modules/dialog.js +496 -0
- package/src/host/modules/dropdown.js +255 -0
- package/src/host/modules/env.js +156 -0
- package/src/host/modules/events.js +28 -0
- package/src/host/modules/flag.js +170 -0
- package/src/host/modules/host.js +19 -0
- package/src/host/modules/inline-dialog.js +33 -0
- package/src/host/modules/messages.js +309 -0
- package/src/host/modules/page.js +29 -0
- package/src/host/modules/scroll-position.js +102 -0
- package/src/host/modules/theming.js +114 -0
- package/src/host/stores/extension_configuration_options_store.js +24 -0
- package/src/host/util.js +98 -0
- package/src/host/utils/access-narrowing-context.js +18 -0
- package/src/host/utils/base64.js +22 -0
- package/src/host/utils/button.js +10 -0
- package/src/host/utils/cookie.js +14 -0
- package/src/host/utils/dialog.js +239 -0
- package/src/host/utils/feature-flag.js +27 -0
- package/src/host/utils/iframe.js +23 -0
- package/src/host/utils/jwt.js +60 -0
- package/src/host/utils/observe.js +34 -0
- package/src/host/utils/removal-observer.js +30 -0
- package/src/host/utils/simplexdm.js +58 -0
- package/src/host/utils/url.js +23 -0
- package/src/host/utils/webitem.js +214 -0
- package/src/plugin/amd.js +115 -0
- package/src/plugin/analytics.js +84 -0
- package/src/plugin/deprecate.js +16 -0
- package/src/plugin/dialog.js +197 -0
- package/src/plugin/dollar.js +77 -0
- package/src/plugin/events-instance.js +2 -0
- package/src/plugin/events.js +246 -0
- package/src/plugin/extension_configuration_options_store.js +27 -0
- package/src/plugin/featureFlag.js +8 -0
- package/src/plugin/index.js +118 -0
- package/src/plugin/meta.js +14 -0
- package/src/plugin/public-events.js +73 -0
- package/src/plugin/theming.js +211 -0
- package/src/plugin/util.js +104 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { toByteArray, fromByteArray } from 'base64-js';
|
|
2
|
+
|
|
3
|
+
export function encode(string) {
|
|
4
|
+
return fromByteArray(
|
|
5
|
+
new TextEncoder().encode(string)
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function decode(string) {
|
|
10
|
+
var padding = 4 - string.length % 4;
|
|
11
|
+
if (padding === 1) {
|
|
12
|
+
string += '=';
|
|
13
|
+
} else if (padding === 2) {
|
|
14
|
+
string += '==';
|
|
15
|
+
}
|
|
16
|
+
return new TextDecoder().decode(toByteArray(string));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
encode,
|
|
21
|
+
decode
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function prefixCookie (addonKey, name){
|
|
2
|
+
if (!addonKey || addonKey.length === 0) {
|
|
3
|
+
throw new Error('addon key must be defined on cookies');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (!name || name.length === 0) {
|
|
7
|
+
throw new Error('Name must be defined');
|
|
8
|
+
}
|
|
9
|
+
return addonKey + '$$' + name;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
prefixCookie
|
|
14
|
+
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import util from '../util';
|
|
2
|
+
import buttonUtils from './button';
|
|
3
|
+
import $ from '../dollar';
|
|
4
|
+
import AnalyticsDispatcher from '../dispatchers/analytics_dispatcher';
|
|
5
|
+
|
|
6
|
+
class DialogUtils {
|
|
7
|
+
_maxDimension(val, maxPxVal){
|
|
8
|
+
var parsed = util.stringToDimension(val);
|
|
9
|
+
var parsedInt = parseInt(parsed, 10);
|
|
10
|
+
var parsedMaxPxVal = parseInt(maxPxVal, 10);
|
|
11
|
+
|
|
12
|
+
if ((parsed.indexOf('%') > -1 && parsedInt >= 100) // %
|
|
13
|
+
|| (parsedInt > parsedMaxPxVal)) { // px
|
|
14
|
+
return '100%';
|
|
15
|
+
}
|
|
16
|
+
return parsed;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
_closeOnEscape (options){
|
|
20
|
+
if (options.closeOnEscape === false) {
|
|
21
|
+
return false;
|
|
22
|
+
} else {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_size (options){
|
|
28
|
+
var size = options.size;
|
|
29
|
+
if (options.size === 'x-large') {
|
|
30
|
+
size = 'xlarge';
|
|
31
|
+
}
|
|
32
|
+
if (options.size !== 'maximum' && options.width === '100%' && options.height === '100%') {
|
|
33
|
+
size = 'fullscreen';
|
|
34
|
+
}
|
|
35
|
+
return size;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_header(text){
|
|
39
|
+
var headerText = '';
|
|
40
|
+
switch(typeof text) {
|
|
41
|
+
case 'string':
|
|
42
|
+
headerText = text;
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case 'object':
|
|
46
|
+
headerText = text.value;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return headerText;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_hint(text){
|
|
54
|
+
if(typeof text === 'string'){
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_chrome(options){
|
|
61
|
+
var returnval = false;
|
|
62
|
+
if (typeof options.chrome === 'boolean') {
|
|
63
|
+
returnval = options.chrome;
|
|
64
|
+
}
|
|
65
|
+
if(options.size === 'fullscreen') {
|
|
66
|
+
returnval = true;
|
|
67
|
+
}
|
|
68
|
+
if(options.size === 'maximum') {
|
|
69
|
+
returnval = false;
|
|
70
|
+
}
|
|
71
|
+
return returnval;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_width(options){
|
|
75
|
+
if(options.size) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
if(options.width) {
|
|
79
|
+
return this._maxDimension(options.width, $(window).width());
|
|
80
|
+
}
|
|
81
|
+
return '50%';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
_height(options){
|
|
85
|
+
if(options.size) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
if(options.height) {
|
|
89
|
+
return this._maxDimension(options.height, $(window).height());
|
|
90
|
+
}
|
|
91
|
+
return '50%';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_actions(options){
|
|
95
|
+
var sanitizedActions = [];
|
|
96
|
+
options = options || {};
|
|
97
|
+
if (!options.actions) {
|
|
98
|
+
|
|
99
|
+
sanitizedActions = [
|
|
100
|
+
{
|
|
101
|
+
name: 'submit',
|
|
102
|
+
identifier: 'submit',
|
|
103
|
+
text: options.submitText || 'Submit',
|
|
104
|
+
type: 'primary',
|
|
105
|
+
disabled: true // disable submit button by default (until the dialog has loaded).
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'cancel',
|
|
109
|
+
identifier: 'cancel',
|
|
110
|
+
text: options.cancelText || 'Cancel',
|
|
111
|
+
type: 'link',
|
|
112
|
+
immutable: true
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if(options.buttons) {
|
|
118
|
+
sanitizedActions = sanitizedActions.concat(this._buttons(options));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return sanitizedActions;
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
_id(str){
|
|
126
|
+
if(typeof str !== 'string'){
|
|
127
|
+
str = Math.random().toString(36).substring(2, 8);
|
|
128
|
+
}
|
|
129
|
+
return str;
|
|
130
|
+
}
|
|
131
|
+
// user defined action buttons
|
|
132
|
+
_buttons(options) {
|
|
133
|
+
var buttons = [];
|
|
134
|
+
if(options.buttons && Array.isArray(options.buttons)) {
|
|
135
|
+
options.buttons.forEach((button) => {
|
|
136
|
+
var text;
|
|
137
|
+
var identifier;
|
|
138
|
+
var disabled = false;
|
|
139
|
+
if(button.text && typeof button.text === 'string') {
|
|
140
|
+
text = button.text;
|
|
141
|
+
}
|
|
142
|
+
if(button.identifier && typeof button.identifier === 'string') {
|
|
143
|
+
identifier = button.identifier;
|
|
144
|
+
} else {
|
|
145
|
+
identifier = buttonUtils.randomIdentifier();
|
|
146
|
+
}
|
|
147
|
+
if(button.disabled && button.disabled === true) {
|
|
148
|
+
disabled = true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
buttons.push({
|
|
152
|
+
text: text,
|
|
153
|
+
identifier: identifier,
|
|
154
|
+
type: 'secondary',
|
|
155
|
+
custom: true,
|
|
156
|
+
disabled: disabled
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return buttons;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
_onHide(options) {
|
|
164
|
+
var noop = function () {};
|
|
165
|
+
if (typeof options.onHide === 'function') {
|
|
166
|
+
return options.onHide;
|
|
167
|
+
} else {
|
|
168
|
+
return noop;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
sanitizeOptions(options){
|
|
173
|
+
options = options || {};
|
|
174
|
+
var sanitized = {
|
|
175
|
+
chrome: this._chrome(options),
|
|
176
|
+
header: this._header(options.header),
|
|
177
|
+
hint: this._hint(options.hint),
|
|
178
|
+
width: this._width(options),
|
|
179
|
+
height: this._height(options),
|
|
180
|
+
$content: options.$content,
|
|
181
|
+
extension: options.extension,
|
|
182
|
+
actions: this._actions(options),
|
|
183
|
+
id: this._id(options.id),
|
|
184
|
+
size: options.size,
|
|
185
|
+
closeOnEscape: this._closeOnEscape(options),
|
|
186
|
+
onHide: this._onHide(options),
|
|
187
|
+
};
|
|
188
|
+
sanitized.size = this._size(sanitized);
|
|
189
|
+
|
|
190
|
+
return sanitized;
|
|
191
|
+
}
|
|
192
|
+
// such a bad idea! this entire concept needs rewriting in the p2 plugin.
|
|
193
|
+
moduleOptionsFromGlobal(addon_key, key) {
|
|
194
|
+
var defaultOptions = {
|
|
195
|
+
chrome: true,
|
|
196
|
+
hostFrameOffset: 1
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
if(window._AP
|
|
200
|
+
&& window._AP.dialogModules
|
|
201
|
+
&& window._AP.dialogModules[addon_key]
|
|
202
|
+
&& window._AP.dialogModules[addon_key][key]) {
|
|
203
|
+
return util.extend({}, defaultOptions, window._AP.dialogModules[addon_key][key].options);
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// determines information about dialogs that are about to open and are already open
|
|
209
|
+
trackMultipleDialogOpening(dialogExtension, options) {
|
|
210
|
+
// check for dialogs that are already open
|
|
211
|
+
let trackingDescription;
|
|
212
|
+
let size = this._size(options);
|
|
213
|
+
if($('.ap-aui-dialog2:visible').length) {
|
|
214
|
+
// am i in the confluence editor? first check for macro dialogs opened through macro browser, second is editing an existing macro
|
|
215
|
+
if($('#macro-browser-dialog').length || (AJS.Confluence && AJS.Confluence.Editor && AJS.Confluence.Editor.currentEditMode)) {
|
|
216
|
+
if (size === 'fullscreen') {
|
|
217
|
+
trackingDescription = 'connect-macro-multiple-fullscreen';
|
|
218
|
+
} else {
|
|
219
|
+
trackingDescription = 'connect-macro-multiple';
|
|
220
|
+
}
|
|
221
|
+
} else {
|
|
222
|
+
trackingDescription = 'connect-multiple';
|
|
223
|
+
}
|
|
224
|
+
AnalyticsDispatcher.trackGasV3MultipleDialogOpening(trackingDescription, dialogExtension);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// abstracts and handles a failure to find active dialog
|
|
229
|
+
assertActiveDialogOrThrow(dialogProvider, addon_key) {
|
|
230
|
+
if (!dialogProvider.isActiveDialog(addon_key)) {
|
|
231
|
+
throw new Error('Failed to find an active dialog for: ' + addon_key);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
var dialogUtilsInstance = new DialogUtils();
|
|
238
|
+
|
|
239
|
+
export default dialogUtilsInstance;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
2
|
+
import AnalyticsDispatcher from '../dispatchers/analytics_dispatcher';
|
|
3
|
+
|
|
4
|
+
function getBooleanFeatureFlagStatsig(flagName) {
|
|
5
|
+
if (FeatureGates.initializeCompleted()) {
|
|
6
|
+
return FeatureGates.checkGate(flagName);
|
|
7
|
+
}
|
|
8
|
+
AnalyticsDispatcher.trackGasV3FeatureFlagDefaultFalse(flagName);
|
|
9
|
+
console.error(`[ACJS] Feature flag service is not initialised. Default flag '${flagName}' to false`);
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* For all new feature flags, please create them in Statsig
|
|
16
|
+
* https://hello.atlassian.net/wiki/spaces/ECO/pages/3707522428
|
|
17
|
+
*
|
|
18
|
+
* @param {string} flagName Feature flag name
|
|
19
|
+
* @returns {boolean}
|
|
20
|
+
*/
|
|
21
|
+
export default function getBooleanFeatureFlag(flagName) {
|
|
22
|
+
return getBooleanFeatureFlagStatsig(flagName);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Flags = {
|
|
26
|
+
getBooleanFeatureFlag,
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import util from '../util';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
optionsToAttributes: function(options){
|
|
5
|
+
var sanitized = {};
|
|
6
|
+
if(options && typeof options ==='object'){
|
|
7
|
+
if(options.width){
|
|
8
|
+
sanitized.width = util.stringToDimension(options.width);
|
|
9
|
+
}
|
|
10
|
+
if(options.height){
|
|
11
|
+
sanitized.height = util.stringToDimension(options.height);
|
|
12
|
+
}
|
|
13
|
+
if (typeof options.sandbox === 'string'){
|
|
14
|
+
var domElem = document.createElement('iframe');
|
|
15
|
+
sanitized.sandbox = options.sandbox
|
|
16
|
+
.split(' ')
|
|
17
|
+
.filter(value => util.isSupported(domElem, 'sandbox', value, true))
|
|
18
|
+
.join(' ');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return sanitized;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { decode } from './base64';
|
|
2
|
+
import EventDispatcher from '../dispatchers/event_dispatcher';
|
|
3
|
+
var JWT_SKEW = 60; // in seconds.
|
|
4
|
+
|
|
5
|
+
function parseJwtIssuer(jwt) {
|
|
6
|
+
return parseJwtClaims(jwt)['iss'];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function parseJwtClaims(jwt) {
|
|
10
|
+
|
|
11
|
+
if (null === jwt || '' === jwt) {
|
|
12
|
+
throw('Invalid JWT: must be neither null nor empty-string.');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var firstPeriodIndex = jwt.indexOf('.');
|
|
16
|
+
var secondPeriodIndex = jwt.indexOf('.', firstPeriodIndex + 1);
|
|
17
|
+
|
|
18
|
+
if (firstPeriodIndex < 0 || secondPeriodIndex <= firstPeriodIndex) {
|
|
19
|
+
throw('Invalid JWT: must contain 2 period (".") characters.');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var encodedClaims = jwt.substring(firstPeriodIndex + 1, secondPeriodIndex);
|
|
23
|
+
|
|
24
|
+
if (null === encodedClaims || '' === encodedClaims) {
|
|
25
|
+
throw('Invalid JWT: encoded claims must be neither null nor empty-string.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var claimsString = decode.call(window, encodedClaims);
|
|
29
|
+
return JSON.parse(claimsString);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isJwtExpired(jwtString, skew) {
|
|
33
|
+
if (skew === undefined) {
|
|
34
|
+
skew = JWT_SKEW;
|
|
35
|
+
}
|
|
36
|
+
var claims = parseJwtClaims(jwtString);
|
|
37
|
+
var expires = 0;
|
|
38
|
+
var now = Math.floor(Date.now() / 1000); // UTC timestamp now
|
|
39
|
+
if (claims && claims.exp) {
|
|
40
|
+
expires = claims.exp;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ((expires - skew) < now){
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return false;
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
EventDispatcher.register('jwt-skew-set', function(data){
|
|
52
|
+
JWT_SKEW = data.skew;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
export default {
|
|
57
|
+
parseJwtIssuer,
|
|
58
|
+
parseJwtClaims,
|
|
59
|
+
isJwtExpired
|
|
60
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const threshold = 0.25;
|
|
2
|
+
let targets = [];
|
|
3
|
+
let observe;
|
|
4
|
+
|
|
5
|
+
const observed = target => {
|
|
6
|
+
targets = targets.filter(({ element, callback }) => {
|
|
7
|
+
if (element === target) {
|
|
8
|
+
callback();
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return true;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if ('IntersectionObserver' in window &&
|
|
16
|
+
'IntersectionObserverEntry' in window) {
|
|
17
|
+
const observer = new IntersectionObserver(entries => {
|
|
18
|
+
entries.forEach(({ intersectionRatio, target }) => {
|
|
19
|
+
if (intersectionRatio > 0) {
|
|
20
|
+
observer.unobserve(target);
|
|
21
|
+
observed(target);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}, { threshold });
|
|
25
|
+
observe = observer.observe.bind(observer);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default (element, callback) => {
|
|
29
|
+
if (typeof callback === 'function'
|
|
30
|
+
&& element instanceof Element) {
|
|
31
|
+
targets.push({ element, callback });
|
|
32
|
+
observe(element);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import HostApi from '../host-api';
|
|
2
|
+
|
|
3
|
+
export function observeIframeRemoval() {
|
|
4
|
+
const scopedObserver = new MutationObserver((mutationsList) => {
|
|
5
|
+
mutationsList.forEach((mutation) => {
|
|
6
|
+
if (mutation.type === 'childList') {
|
|
7
|
+
mutation.removedNodes.forEach((node) => {
|
|
8
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const onDisconnect = (node) => {
|
|
12
|
+
HostApi.destroy(node.id);
|
|
13
|
+
};
|
|
14
|
+
// Check if the node itself is an iframe
|
|
15
|
+
if (node.tagName === 'IFRAME' && node.id) {
|
|
16
|
+
onDisconnect(node);
|
|
17
|
+
} else {
|
|
18
|
+
// Check if any iframes exist within the removed node's subtree
|
|
19
|
+
node.querySelectorAll('iframe[id]').forEach((childNode) => {
|
|
20
|
+
onDisconnect(childNode);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
scopedObserver.observe(document.body, { childList: true, subtree: true });
|
|
29
|
+
return scopedObserver;
|
|
30
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import iframeUtils from './iframe';
|
|
2
|
+
import simpleXDM from 'simple-xdm/host';
|
|
3
|
+
import IframeActions from '../actions/iframe_actions';
|
|
4
|
+
import util from '../util';
|
|
5
|
+
import $ from '../dollar';
|
|
6
|
+
import ExtensionConfigurationOptionStore from '../stores/extension_configuration_options_store';
|
|
7
|
+
import getBooleanFeatureFlag from './feature-flag';
|
|
8
|
+
import definePerformanceModule, {ADDON_KEY_CODEBARREL} from '../modules/_performance';
|
|
9
|
+
import defineFeatureFlagModule from '../modules/_featureFlag';
|
|
10
|
+
|
|
11
|
+
// nowhere better to put this. Wires an extension for oldschool and new enviroments
|
|
12
|
+
function createSimpleXdmExtension(extension){
|
|
13
|
+
const extensionConfig = extensionConfigSanitizer(extension);
|
|
14
|
+
const systemExtensionConfigOptions = ExtensionConfigurationOptionStore.get();
|
|
15
|
+
extension.options = extensionConfig.options = util.extend({}, extensionConfig.options);
|
|
16
|
+
extension.options.globalOptions = systemExtensionConfigOptions;
|
|
17
|
+
loadConditionalModules(extension.addon_key);
|
|
18
|
+
const iframeAttributes = simpleXDM.create(extensionConfig, () => {
|
|
19
|
+
if(!extension.options.noDOM){
|
|
20
|
+
extension.$el = $(document.getElementById(extension.id));
|
|
21
|
+
}
|
|
22
|
+
IframeActions.notifyBridgeEstablished(extension.$el, extension);
|
|
23
|
+
}, () => {
|
|
24
|
+
IframeActions.notifyUnloaded(extension.$el, extension);
|
|
25
|
+
});
|
|
26
|
+
// HostApi destroy is relying on previous behaviour of the
|
|
27
|
+
// iframe component wherein it would call simpleXDM.create(extension)
|
|
28
|
+
// and then mutate the extension object with the id returned from the
|
|
29
|
+
// iframeAttributes see changes made in ACJS-760 and ACJS-807
|
|
30
|
+
extensionConfig.id = iframeAttributes.id;
|
|
31
|
+
extension.id = iframeAttributes.id;
|
|
32
|
+
util.extend(iframeAttributes, iframeUtils.optionsToAttributes(extension.options));
|
|
33
|
+
return {
|
|
34
|
+
iframeAttributes,
|
|
35
|
+
extension
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function extensionConfigSanitizer(extension) {
|
|
40
|
+
return {
|
|
41
|
+
addon_key: extension.addon_key,
|
|
42
|
+
key: extension.key,
|
|
43
|
+
url: extension.url,
|
|
44
|
+
options: extension.options,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function loadConditionalModules(addonKey) {
|
|
49
|
+
if (addonKey === ADDON_KEY_CODEBARREL) {
|
|
50
|
+
definePerformanceModule();
|
|
51
|
+
}
|
|
52
|
+
defineFeatureFlagModule();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default {
|
|
56
|
+
createSimpleXdmExtension,
|
|
57
|
+
extensionConfigSanitizer
|
|
58
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import qs from 'query-string';
|
|
2
|
+
import jwtUtil from './jwt';
|
|
3
|
+
|
|
4
|
+
function isJwtExpired(urlStr) {
|
|
5
|
+
var jwtStr = _getJwt(urlStr);
|
|
6
|
+
return jwtUtil.isJwtExpired(jwtStr);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function _getJwt(urlStr) {
|
|
10
|
+
var query = qs.parse(qs.extract(urlStr));
|
|
11
|
+
return query['jwt'];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hasJwt(url) {
|
|
15
|
+
var jwt = _getJwt(url);
|
|
16
|
+
return (jwt && _getJwt(url).length !== 0);
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
hasJwt,
|
|
22
|
+
isJwtExpired
|
|
23
|
+
}
|