@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,246 @@
|
|
|
1
|
+
import AP from 'simple-xdm/combined';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The Events module provides a mechanism for emitting and receiving events.<br>
|
|
5
|
+
*
|
|
6
|
+
* A event emitted by `emit` method will only be received by the modules defined in the same add-on.<br>
|
|
7
|
+
* Public events that emitted by `emitPublic` are used for cross add-on communication.
|
|
8
|
+
* They can be received by any add-on modules that are currently presented on the page.
|
|
9
|
+
*
|
|
10
|
+
* This module is currently not supported on mobile. See
|
|
11
|
+
* <a href='https://jira.atlassian.com/browse/JRACLOUD-79910'>JRACLOUD-79910</a> for more details.
|
|
12
|
+
*
|
|
13
|
+
* <h3>Basic example</h3>
|
|
14
|
+
* Add-on A:
|
|
15
|
+
* ```
|
|
16
|
+
* // The following will create an alert message every time the event `customEvent` is triggered.
|
|
17
|
+
* AP.events.on('customEvent', function(){
|
|
18
|
+
* alert('event fired');
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
*
|
|
22
|
+
* AP.events.emit('customEvent');
|
|
23
|
+
* AP.events.emitPublic('customPublicEvent');
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
* Add-on B:
|
|
28
|
+
* ```
|
|
29
|
+
* // The following will create an alert message every time the event `customPublicEvent` is triggered by add-on A.
|
|
30
|
+
* AP.events.onPublic('customPublicEvent', function(){
|
|
31
|
+
* alert('public event fired');
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @name Events
|
|
36
|
+
* @module
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
class Events {
|
|
40
|
+
constructor(){
|
|
41
|
+
this._events = {};
|
|
42
|
+
this.ANY_PREFIX = '_any';
|
|
43
|
+
this.methods = ['off', 'offAll', 'offAny', 'on', 'onAny', 'once'];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_anyListener(data, callback){
|
|
47
|
+
var eventName = callback._context.eventName;
|
|
48
|
+
var any = this._events[this.ANY_PREFIX] || [];
|
|
49
|
+
var byName = this._events[eventName] || [];
|
|
50
|
+
|
|
51
|
+
if(!Array.isArray(data)){
|
|
52
|
+
data = [data];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
any.forEach((handler) => {
|
|
56
|
+
//clone data before modifying
|
|
57
|
+
var args = data.slice(0);
|
|
58
|
+
args.unshift(eventName);
|
|
59
|
+
args.push({
|
|
60
|
+
args: data,
|
|
61
|
+
name: eventName
|
|
62
|
+
});
|
|
63
|
+
handler.apply(null, args);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
byName.forEach((handler) => {
|
|
67
|
+
handler.apply(null, data);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
off(name, listener){
|
|
72
|
+
if (this._events[name]) {
|
|
73
|
+
var index = this._events[name].indexOf(listener);
|
|
74
|
+
if (index > -1) {
|
|
75
|
+
this._events[name].splice(index, 1);
|
|
76
|
+
}
|
|
77
|
+
if(this._events[name].length === 0) {
|
|
78
|
+
delete this._events[name];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
offAll(name){
|
|
84
|
+
delete this._events[name];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
offAny(listener){
|
|
88
|
+
this.off(this.ANY_PREFIX, listener);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
on(name, listener){
|
|
92
|
+
if(!this._events[name]){
|
|
93
|
+
this._events[name] = [];
|
|
94
|
+
}
|
|
95
|
+
this._events[name].push(listener);
|
|
96
|
+
}
|
|
97
|
+
onAny(listener){
|
|
98
|
+
this.on(this.ANY_PREFIX, listener);
|
|
99
|
+
}
|
|
100
|
+
once(name, listener){
|
|
101
|
+
var _that = this;
|
|
102
|
+
function runOnce() {
|
|
103
|
+
listener.apply(null, arguments);
|
|
104
|
+
_that.off(name, runOnce);
|
|
105
|
+
}
|
|
106
|
+
this.on(name, runOnce);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Adds a listener for all occurrences of an event of a particular name.<br>
|
|
110
|
+
* Listener arguments include any arguments passed to `events.emit`, followed by an object describing the complete event information.
|
|
111
|
+
* @name on
|
|
112
|
+
* @method
|
|
113
|
+
* @memberof module:Events#
|
|
114
|
+
* @param {String} name The event name to subscribe the listener to
|
|
115
|
+
* @param {Function} listener A listener callback to subscribe to the event name
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Adds a listener for all occurrences of a public event of a particular name.<br>
|
|
120
|
+
* Listener arguments include any arguments passed to `events.emitPublic`, followed by an object describing the complete event information.<br>
|
|
121
|
+
* Event emitter's information will be passed to the first argument of the filter function. The listener callback will only be called when filter function returns `true`.
|
|
122
|
+
* @name onPublic
|
|
123
|
+
* @method
|
|
124
|
+
* @memberof module:Events#
|
|
125
|
+
* @param {String} name The event name to subscribe the listener to
|
|
126
|
+
* @param {Function} listener A listener callback to subscribe to the event name
|
|
127
|
+
* @param {Function} [filter] A filter function to filter the events. Callback will always be called when a matching event occurs if the filter is unspecified
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Adds a listener for one occurrence of an event of a particular name.<br>
|
|
132
|
+
* Listener arguments include any argument passed to `events.emit`, followed by an object describing the complete event information.
|
|
133
|
+
* @name once
|
|
134
|
+
* @method
|
|
135
|
+
* @memberof module:Events#
|
|
136
|
+
* @param {String} name The event name to subscribe the listener to
|
|
137
|
+
* @param {Function} listener A listener callback to subscribe to the event name
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Adds a listener for one occurrence of a public event of a particular name.<br>
|
|
142
|
+
* Listener arguments include any argument passed to `events.emit`, followed by an object describing the complete event information.<br>
|
|
143
|
+
* Event emitter's information will be passed to the first argument of the filter function. The listener callback will only be called when filter function returns `true`.
|
|
144
|
+
* @name oncePublic
|
|
145
|
+
* @method
|
|
146
|
+
* @memberof module:Events#
|
|
147
|
+
* @param {String} name The event name to subscribe the listener to
|
|
148
|
+
* @param {Function}listener A listener callback to subscribe to the event name
|
|
149
|
+
* @param {Function} [filter] A filter function to filter the events. Callback will always be called when a matching event occurs if the filter is unspecified
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Adds a listener for all occurrences of any event, regardless of name.<br>
|
|
154
|
+
* Listener arguments begin with the event name, followed by any arguments passed to `events.emit`, followed by an object describing the complete event information.
|
|
155
|
+
* @name onAny
|
|
156
|
+
* @method
|
|
157
|
+
* @memberof module:Events#
|
|
158
|
+
* @param {Function} listener A listener callback to subscribe for any event name
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Adds a listener for all occurrences of any event, regardless of name.<br>
|
|
163
|
+
* Listener arguments begin with the event name, followed by any arguments passed to `events.emit`, followed by an object describing the complete event information.<br>
|
|
164
|
+
* Event emitter's information will be passed to the first argument of the filter function. The listener callback will only be called when filter function returns `true`.
|
|
165
|
+
* @name onAnyPublic
|
|
166
|
+
* @method
|
|
167
|
+
* @memberof module:Events#
|
|
168
|
+
* @param {Function} listener A listener callback to subscribe for any event name
|
|
169
|
+
* @param {Function} [filter] A filter function to filter the events. Callback will always be called when a matching event occurs if the filter is unspecified
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Removes a particular listener for an event.
|
|
174
|
+
* @name off
|
|
175
|
+
* @method
|
|
176
|
+
* @memberof module:Events#
|
|
177
|
+
* @param {String} name The event name to unsubscribe the listener from
|
|
178
|
+
* @param {Function} listener The listener callback to unsubscribe from the event name
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Removes a particular listener for a public event.
|
|
183
|
+
* @name offPublic
|
|
184
|
+
* @method
|
|
185
|
+
* @memberof module:Events#
|
|
186
|
+
* @param {String} name The event name to unsubscribe the listener from
|
|
187
|
+
* @param {Function} listener The listener callback to unsubscribe from the event name
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Removes all listeners from an event name, or unsubscribes all event-name-specific listeners
|
|
192
|
+
* if no name if given.
|
|
193
|
+
* @name offAll
|
|
194
|
+
* @method
|
|
195
|
+
* @memberof module:Events#
|
|
196
|
+
* @param {String} [name] The event name to unsubscribe all listeners from
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Removes all listeners from a public event name, or unsubscribes all event-name-specific listeners for public events
|
|
201
|
+
* if no name if given.
|
|
202
|
+
* @name offAllPublic
|
|
203
|
+
* @method
|
|
204
|
+
* @memberof module:Events#
|
|
205
|
+
* @param {String} [name] The event name to unsubscribe all listeners from
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Removes an `any` event listener.
|
|
210
|
+
* @name offAny
|
|
211
|
+
* @method
|
|
212
|
+
* @memberof module:Events#
|
|
213
|
+
* @param {Function} listener A listener callback to unsubscribe from any event name
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Removes an `anyPublic` event listener.
|
|
218
|
+
* @name offAnyPublic
|
|
219
|
+
* @method
|
|
220
|
+
* @memberof module:Events#
|
|
221
|
+
* @param {Function} listener A listener callback to unsubscribe from any event name
|
|
222
|
+
*/
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Emits an event on this bus, firing listeners by name as well as all 'any' listeners.<br>
|
|
226
|
+
* Arguments following the name parameter are captured and passed to listeners.
|
|
227
|
+
* @name emit
|
|
228
|
+
* @method
|
|
229
|
+
* @memberof module:Events#
|
|
230
|
+
* @param {String} name The name of event to emit
|
|
231
|
+
* @param {String[]} args 0 or more additional data arguments to deliver with the event
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Emits a public event on this bus, firing listeners by name as well as all 'anyPublic' listeners.<br>
|
|
236
|
+
* The event can be received by any add-on modules that are currently presented on the page.<br>
|
|
237
|
+
* Arguments following the name parameter are captured and passed to listeners.
|
|
238
|
+
* @name emitPublic
|
|
239
|
+
* @method
|
|
240
|
+
* @memberof module:Events#
|
|
241
|
+
* @param {String} name The name of event to emit
|
|
242
|
+
* @param {String[]} args 0 or more additional data arguments to deliver with the event
|
|
243
|
+
*/
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export default Events;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// duplicated from ./host/stores/extension_configuration_options_store
|
|
2
|
+
// due to a huge build size difference
|
|
3
|
+
|
|
4
|
+
import util from './util';
|
|
5
|
+
|
|
6
|
+
class ExtensionConfigurationOptionsStore {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.store = {};
|
|
9
|
+
}
|
|
10
|
+
set(obj, val) {
|
|
11
|
+
if(val) {
|
|
12
|
+
var toSet = {};
|
|
13
|
+
toSet[obj] = val;
|
|
14
|
+
} else {
|
|
15
|
+
toSet = obj;
|
|
16
|
+
}
|
|
17
|
+
util.extend(this.store, toSet);
|
|
18
|
+
}
|
|
19
|
+
get(key) {
|
|
20
|
+
if(key) {
|
|
21
|
+
return this.store[key];
|
|
22
|
+
}
|
|
23
|
+
return util.extend({}, this.store); //clone
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default new ExtensionConfigurationOptionsStore();
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import AP from 'simple-xdm/combined';
|
|
2
|
+
import deprecate from './deprecate';
|
|
3
|
+
import $ from './dollar';
|
|
4
|
+
import consumerOptions from 'simple-xdm/src/plugin/consumer-options';
|
|
5
|
+
import EventsInstance from './events-instance';
|
|
6
|
+
import PublicEventsInstance from './public-events';
|
|
7
|
+
import './dialog';
|
|
8
|
+
import AMD from './amd';
|
|
9
|
+
import Meta from './meta';
|
|
10
|
+
import Theming, {loadLegacyTextColorStyles} from './theming';
|
|
11
|
+
import _util from './util';
|
|
12
|
+
import ExtensionConfigurationOptionsStore from './extension_configuration_options_store';
|
|
13
|
+
import analytics from './analytics';
|
|
14
|
+
import { setBooleanFeatureFlagResolver } from '@atlaskit/platform-feature-flags';
|
|
15
|
+
|
|
16
|
+
AP._hostModules._dollar = $;
|
|
17
|
+
AP._hostModules['inline-dialog'] = AP._hostModules.inlineDialog;
|
|
18
|
+
|
|
19
|
+
if (consumerOptions.get('sizeToParent') === true) {
|
|
20
|
+
AP.env && AP.env.sizeToParent(consumerOptions.get('hideFooter') === true);
|
|
21
|
+
} else {
|
|
22
|
+
AP.env && AP.env.hideFooter(consumerOptions.get('hideFooter') === true);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (consumerOptions.get('base') === true) {
|
|
26
|
+
AP.env && AP.env.getLocation(loc => {
|
|
27
|
+
$('head').append({ tag: 'base', href: loc, target: '_parent' });
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
$.each(EventsInstance.methods, (i, method) => {
|
|
32
|
+
if (AP._hostModules && AP._hostModules.events) {
|
|
33
|
+
AP._hostModules.events[method] = AP.events[method] = EventsInstance[method].bind(EventsInstance);
|
|
34
|
+
AP._hostModules.events[method + 'Public'] = AP.events[method + 'Public'] = PublicEventsInstance[method].bind(PublicEventsInstance);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
AP.define = deprecate((...args) => AMD.define(...args), 'AP.define()', null, '5.0');
|
|
39
|
+
|
|
40
|
+
AP.require = deprecate((...args) => AMD.require(...args), 'AP.require()', null, '5.0');
|
|
41
|
+
|
|
42
|
+
var margin = AP._data.options.isDialog ? '10px 10px 0 10px' : '0';
|
|
43
|
+
if (consumerOptions.get('margin') !== false) {
|
|
44
|
+
var setBodyMargin = function() {
|
|
45
|
+
if (document.body) {
|
|
46
|
+
document.body.style.setProperty('margin', margin, 'important');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
setBodyMargin(); // Try to set it straight away
|
|
50
|
+
window.addEventListener('DOMContentLoaded', setBodyMargin); // If it doesn't exist now (likely) we can set it later
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
AP.Meta = {
|
|
54
|
+
get: Meta.getMeta
|
|
55
|
+
};
|
|
56
|
+
AP.meta = Meta.getMeta;
|
|
57
|
+
AP.localUrl = Meta.localUrl;
|
|
58
|
+
|
|
59
|
+
AP._hostModules._util = AP._util = {
|
|
60
|
+
each: _util.each,
|
|
61
|
+
log: _util.log,
|
|
62
|
+
decodeQueryComponent: _util.decodeQueryComponent,
|
|
63
|
+
bind: _util.bind,
|
|
64
|
+
unbind: _util.unbind,
|
|
65
|
+
extend: _util.extend,
|
|
66
|
+
trim: _util.trim,
|
|
67
|
+
debounce: _util.debounce,
|
|
68
|
+
isFunction: _util.isFunction,
|
|
69
|
+
handleError: _util.handleError
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (AP.defineModule) {
|
|
73
|
+
AP.defineModule('env', {
|
|
74
|
+
resize: function(w, h, callback) {
|
|
75
|
+
var iframe = document.getElementById(callback._context.extension_id);
|
|
76
|
+
iframe.style.width = w + (typeof w === 'number' ? 'px' : '');
|
|
77
|
+
iframe.style.height = h + (typeof h === 'number' ? 'px' : '');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (AP._data && AP._data.origin) {
|
|
83
|
+
AP.registerAny(function(data, callback) {
|
|
84
|
+
// dialog.close event doesn't have event data
|
|
85
|
+
if (data && data.event && data.sender) {
|
|
86
|
+
PublicEventsInstance._anyListener(data, callback);
|
|
87
|
+
} else {
|
|
88
|
+
EventsInstance._anyListener(data, callback);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const WEB_VITALS_TIMEOUT = 10000; // 10 seconds
|
|
94
|
+
analytics.setupWebVitals(WEB_VITALS_TIMEOUT);
|
|
95
|
+
|
|
96
|
+
// Sets up theme-related event listeners but DOES NOT react to them.
|
|
97
|
+
// The Connect app has to call AP.theming.initializeTheming() to start reacting to theme changes in the host.
|
|
98
|
+
Theming.initializeThemeListeners();
|
|
99
|
+
// Also load in the confluence macro body stylesheet
|
|
100
|
+
loadLegacyTextColorStyles()
|
|
101
|
+
|
|
102
|
+
// Reads platform feature flags from the parent and sets them as global variables.
|
|
103
|
+
setBooleanFeatureFlagResolver((flagName) => AP._data.options.platformFeatureFlags?.[flagName] || false);
|
|
104
|
+
|
|
105
|
+
// gets the global options from the parent iframe (if present) so they can propagate to future sub-iframes.
|
|
106
|
+
ExtensionConfigurationOptionsStore.set(AP._data.options.globalOptions);
|
|
107
|
+
|
|
108
|
+
if (document.readyState === 'complete') {
|
|
109
|
+
if (typeof window.requestIdleCallback === 'function') {
|
|
110
|
+
window.requestIdleCallback(analytics.sendMetrics, { timeout: 1000 });
|
|
111
|
+
} else {
|
|
112
|
+
analytics.sendMetrics();
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
window.addEventListener('load', analytics.sendMetrics);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export default AP;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import $ from './dollar';
|
|
2
|
+
|
|
3
|
+
function getMeta(name) {
|
|
4
|
+
return $(`meta[name='ap-${name}']`).attr('content');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
getMeta: getMeta,
|
|
9
|
+
|
|
10
|
+
localUrl: function(path) {
|
|
11
|
+
const url = getMeta('local-base-url');
|
|
12
|
+
return typeof url === 'undefined' || typeof path === 'undefined' ? url : `${url}${path}`;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Events from './events';
|
|
2
|
+
import AP from 'simple-xdm/combined';
|
|
3
|
+
|
|
4
|
+
class PublicEvents extends Events {
|
|
5
|
+
constructor(){
|
|
6
|
+
super();
|
|
7
|
+
this.methods = ['offPublic', 'offAllPublic', 'offAnyPublic', 'onPublic', 'onAnyPublic', 'oncePublic'];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
_filterEval(filter, toCompare){
|
|
11
|
+
var value = true;
|
|
12
|
+
if(!filter){
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
switch(typeof filter) {
|
|
16
|
+
case 'function':
|
|
17
|
+
value = Boolean(filter.call(null, toCompare));
|
|
18
|
+
break;
|
|
19
|
+
case 'object':
|
|
20
|
+
value = Object.getOwnPropertyNames(filter).every(function(prop){
|
|
21
|
+
return toCompare[prop] === filter[prop];
|
|
22
|
+
});
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
once(name, listener, filter) {
|
|
29
|
+
var that = this;
|
|
30
|
+
function runOnce(data) {
|
|
31
|
+
listener.apply(null, data);
|
|
32
|
+
that.off(name, runOnce);
|
|
33
|
+
}
|
|
34
|
+
this.on(name, runOnce, filter);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
on(name, listener, filter){
|
|
38
|
+
listener._wrapped = function(data){
|
|
39
|
+
if(this._filterEval(filter, data.sender)) {
|
|
40
|
+
listener.apply(null, data.event);
|
|
41
|
+
}
|
|
42
|
+
}.bind(this);
|
|
43
|
+
super.on(name, listener._wrapped);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
off(name, listener) {
|
|
47
|
+
if(listener._wrapped) {
|
|
48
|
+
super.off(name, listener._wrapped);
|
|
49
|
+
} else {
|
|
50
|
+
super.off(name, listener);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
onAny(listener, filter) {
|
|
55
|
+
listener._wrapped = function(data){
|
|
56
|
+
if(data.sender && this._filterEval(filter, data.sender)) {
|
|
57
|
+
listener.apply(null, data.event);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
super.onAny(listener._wrapped);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
offAny(listener) {
|
|
64
|
+
if(listener._wrapped) {
|
|
65
|
+
super.offAny(name, listener._wrapped);
|
|
66
|
+
} else {
|
|
67
|
+
super.offAny(name, listener);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default new PublicEvents;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import AP from 'simple-xdm/combined';
|
|
2
|
+
import { setGlobalTheme } from '@atlaskit/tokens';
|
|
3
|
+
import { getBooleanFeatureFlagIframe } from './featureFlag';
|
|
4
|
+
|
|
5
|
+
// The CDN URL is now dynamic since we now serve all.js for both commercial and in FedRamp
|
|
6
|
+
// It will be injected during the build process
|
|
7
|
+
// eslint-disable-next-line no-undef
|
|
8
|
+
const CDN_DOMAIN = process.env.CDN_DOMAIN;
|
|
9
|
+
const CDN_URL = `https://${CDN_DOMAIN}`;
|
|
10
|
+
|
|
11
|
+
function appendStyle({ rel, href, as, type, crossOrigin, id, attr }) {
|
|
12
|
+
const link = document.createElement('link');
|
|
13
|
+
|
|
14
|
+
if (rel) {
|
|
15
|
+
link.rel = rel;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (href) {
|
|
19
|
+
link.href = href;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (as) {
|
|
23
|
+
link.as = as;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (type) {
|
|
27
|
+
link.type = type;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (crossOrigin) {
|
|
31
|
+
link.crossOrigin = crossOrigin
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (id && attr) {
|
|
35
|
+
link.dataset[attr] = id
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
document.head.appendChild(link);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function themeLoader(id) {
|
|
42
|
+
const stylesheetUrl = `${CDN_URL}/themes/atlaskit-tokens_${id}.css`;
|
|
43
|
+
|
|
44
|
+
if (document.querySelector(`link[href="${stylesheetUrl}"]`)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
appendStyle({
|
|
49
|
+
rel: 'stylesheet',
|
|
50
|
+
id,
|
|
51
|
+
attr: 'theme',
|
|
52
|
+
href: stylesheetUrl,
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function appendSurface(surface) {
|
|
57
|
+
document.documentElement.dataset.surface = surface;
|
|
58
|
+
|
|
59
|
+
if (document.querySelector('link[data-surface]')) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
appendStyle({
|
|
64
|
+
rel: 'stylesheet',
|
|
65
|
+
id: surface,
|
|
66
|
+
attr: 'surface',
|
|
67
|
+
href: `${CDN_URL}/surfaces.css`
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function removeSurface() {
|
|
72
|
+
delete document.documentElement.dataset.surface;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function loadLegacyTextColorStyles() {
|
|
76
|
+
if (AP._data.options.moduleType !== 'dynamicContentMacros') {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
loadLegacyTextColorStylesCdn(); // Load via Connect CDN stylesheet
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function loadLegacyTextColorStylesCdn() {
|
|
83
|
+
if (document.querySelector('link[data-legacy-text-colors]')) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
appendStyle({
|
|
87
|
+
rel: 'stylesheet',
|
|
88
|
+
id: 'legacy-text-colors',
|
|
89
|
+
attr: 'legacyTextColors',
|
|
90
|
+
href: `${CDN_URL}/legacy-text-colors.css`
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function setTheme(options) {
|
|
95
|
+
await setGlobalTheme(options, themeLoader); // Load via Connect CDN stylesheet
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let hasRegisteredCSPViolationHandler = false;
|
|
99
|
+
function registerCSPViolationHandler() {
|
|
100
|
+
if (hasRegisteredCSPViolationHandler) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
hasRegisteredCSPViolationHandler = true;
|
|
104
|
+
|
|
105
|
+
window.addEventListener('securitypolicyviolation', (event) => {
|
|
106
|
+
if (event.blockedURI.includes(CDN_DOMAIN)) {
|
|
107
|
+
console.warn(`CSP violation detected for ${event.violatedDirective} in app ${event.documentURI}
|
|
108
|
+
Please add ${CDN_URL} to your security policy for script-src and style-src.
|
|
109
|
+
See https://developer.atlassian.com/platform/marketplace/security-requirements/#connect-apps for details.`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function preloadWebFonts(data) {
|
|
116
|
+
try {
|
|
117
|
+
const hasRefreshedTypography = data && data.initialTheme && data.initialTheme.typography === 'typography-refreshed';
|
|
118
|
+
const isInNewFontCohort = await getBooleanFeatureFlagIframe('acjs_new_font')
|
|
119
|
+
if (!isInNewFontCohort || !hasRefreshedTypography) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const fontRoot = 'https://ds-cdn.prod-east.frontend.public.atl-paas.net'
|
|
124
|
+
const woffUrl = `${fontRoot}/assets/fonts/atlassian-sans/v2/AtlassianSans-latin.woff2`
|
|
125
|
+
const cssUrl = `${fontRoot}/assets/font-rules/v4/atlassian-fonts.css`
|
|
126
|
+
|
|
127
|
+
if (!document.querySelector(`link[href="${fontRoot}"]`)) {
|
|
128
|
+
appendStyle({ rel: 'preconnect', href: fontRoot });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!document.querySelector(`link[href="${woffUrl}"]`)) {
|
|
132
|
+
appendStyle({
|
|
133
|
+
rel: 'preload',
|
|
134
|
+
href: woffUrl,
|
|
135
|
+
as: 'font',
|
|
136
|
+
type: 'font/woff2',
|
|
137
|
+
crossOrigin: 'true'
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!document.querySelector(`link[href="${cssUrl}"]`)) {
|
|
142
|
+
appendStyle({
|
|
143
|
+
rel: 'preload stylesheet',
|
|
144
|
+
href: cssUrl,
|
|
145
|
+
as: 'style',
|
|
146
|
+
crossOrigin: 'true'
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
} catch (_err) {
|
|
150
|
+
// do nothing with the error
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const Theming = {
|
|
155
|
+
isThemingEnabled: false,
|
|
156
|
+
forceNoCleanup: false,
|
|
157
|
+
|
|
158
|
+
async onThemeInitialized(data) {
|
|
159
|
+
Theming.isThemingEnabled = true;
|
|
160
|
+
Theming.forceNoCleanup = data.forceNoCleanup || false;
|
|
161
|
+
registerCSPViolationHandler()
|
|
162
|
+
preloadWebFonts(data);
|
|
163
|
+
await Theming.onThemeChanged(data);
|
|
164
|
+
if (window.AP && window.AP.theming && window.AP.theming._finishedInitTheming) {
|
|
165
|
+
window.AP.theming._finishedInitTheming();
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
async onThemeChanged(data) {
|
|
170
|
+
if (!Theming.isThemingEnabled) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const newTheme = data.initialTheme || data.newTheme;
|
|
175
|
+
|
|
176
|
+
if (!newTheme || Object.keys(newTheme).length === 0) {
|
|
177
|
+
if (Theming.forceNoCleanup) {
|
|
178
|
+
await setTheme({ colorMode: 'light' });
|
|
179
|
+
removeSurface();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
removeSurface();
|
|
184
|
+
document.documentElement.removeAttribute('data-theme');
|
|
185
|
+
document.documentElement.removeAttribute('data-color-mode');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await setTheme(newTheme);
|
|
190
|
+
|
|
191
|
+
// Remove existing surface styles.
|
|
192
|
+
removeSurface();
|
|
193
|
+
if (!!data.surface) {
|
|
194
|
+
// Surface styles must be applied after themes for specificity.
|
|
195
|
+
appendSurface(data.surface);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
initializeThemeListeners() {
|
|
200
|
+
if (!AP.theming) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
AP.register({
|
|
205
|
+
theme_initialized: Theming.onThemeInitialized,
|
|
206
|
+
theme_changed: Theming.onThemeChanged,
|
|
207
|
+
});
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export default Theming;
|