@gcorevideo/player 2.30.2 → 2.30.3

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 (47) hide show
  1. package/dist/core.js +1 -1
  2. package/dist/index.css +353 -353
  3. package/dist/index.embed.js +8 -1
  4. package/dist/index.js +9 -2
  5. package/lib/plugins/media-control/MediaControl.d.ts +1 -0
  6. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  7. package/lib/plugins/media-control/MediaControl.js +9 -1
  8. package/package.json +1 -1
  9. package/src/plugins/media-control/MediaControl.ts +10 -1
  10. package/tsconfig.tsbuildinfo +1 -1
  11. package/assets/vast-ads/style.scss +0 -112
  12. package/lib/plugins/vast-ads/VastAds.d.ts +0 -74
  13. package/lib/plugins/vast-ads/VastAds.d.ts.map +0 -1
  14. package/lib/plugins/vast-ads/VastAds.js +0 -693
  15. package/lib/plugins/vast-ads/loaderxml.d.ts +0 -32
  16. package/lib/plugins/vast-ads/loaderxml.d.ts.map +0 -1
  17. package/lib/plugins/vast-ads/loaderxml.js +0 -229
  18. package/lib/plugins/vast-ads/roll.d.ts +0 -60
  19. package/lib/plugins/vast-ads/roll.d.ts.map +0 -1
  20. package/lib/plugins/vast-ads/roll.js +0 -421
  21. package/lib/plugins/vast-ads/rollmanager.d.ts +0 -62
  22. package/lib/plugins/vast-ads/rollmanager.d.ts.map +0 -1
  23. package/lib/plugins/vast-ads/rollmanager.js +0 -357
  24. package/lib/plugins/vast-ads/sctemanager.d.ts +0 -18
  25. package/lib/plugins/vast-ads/sctemanager.d.ts.map +0 -1
  26. package/lib/plugins/vast-ads/sctemanager.js +0 -117
  27. package/lib/plugins/vast-ads/types.d.ts +0 -12
  28. package/lib/plugins/vast-ads/types.d.ts.map +0 -1
  29. package/lib/plugins/vast-ads/types.js +0 -1
  30. package/lib/plugins/vast-ads/urlhandler.d.ts +0 -4
  31. package/lib/plugins/vast-ads/urlhandler.d.ts.map +0 -1
  32. package/lib/plugins/vast-ads/urlhandler.js +0 -30
  33. package/lib/plugins/vast-ads/xmlhttprequest.d.ts +0 -6
  34. package/lib/plugins/vast-ads/xmlhttprequest.d.ts.map +0 -1
  35. package/lib/plugins/vast-ads/xmlhttprequest.js +0 -40
  36. package/lib/plugins/vast-ads/xmlmerge.d.ts +0 -12
  37. package/lib/plugins/vast-ads/xmlmerge.d.ts.map +0 -1
  38. package/lib/plugins/vast-ads/xmlmerge.js +0 -83
  39. package/src/plugins/vast-ads/VastAds.ts +0 -919
  40. package/src/plugins/vast-ads/loaderxml.ts +0 -301
  41. package/src/plugins/vast-ads/roll.ts +0 -590
  42. package/src/plugins/vast-ads/rollmanager.ts +0 -447
  43. package/src/plugins/vast-ads/sctemanager.ts +0 -152
  44. package/src/plugins/vast-ads/types.ts +0 -20
  45. package/src/plugins/vast-ads/urlhandler.ts +0 -42
  46. package/src/plugins/vast-ads/xmlhttprequest.ts +0 -49
  47. package/src/plugins/vast-ads/xmlmerge.ts +0 -106
@@ -1,447 +0,0 @@
1
- import {
2
- $,
3
- Browser,
4
- Container,
5
- ContainerPlugin,
6
- Core,
7
- Events,
8
- HTML5Video,
9
- Log,
10
- Playback,
11
- UIContainerPlugin,
12
- Utils,
13
- } from '@clappr/core'
14
- import { reportError } from '@gcorevideo/utils'
15
- import assert from 'assert'
16
-
17
- import LoaderXML from './loaderxml.js'
18
- import Roll from './roll.js'
19
- import { ZeptoResult } from '../../types.js'
20
- import { AdRollDesc, AdRollItem, AdRollType, VastAdsOptions } from './types.js'
21
-
22
- type CoreOptions = Record<string, unknown>
23
-
24
- type ExtensionData = Record<string, unknown>
25
-
26
- export default class RollManager extends Events {
27
- private _allURLRequest = false
28
-
29
- private _container: Container
30
- private container: Container
31
-
32
- private _options: CoreOptions
33
-
34
- private vastAdsOptions: VastAdsOptions
35
-
36
- private _playback: Playback
37
-
38
- private _contentElement: HTMLMediaElement
39
-
40
- private _posterPlugin: UIContainerPlugin
41
-
42
- private _clickToPausePlugin: ContainerPlugin
43
-
44
- private adTemplates: AdRollItem[] | null = null
45
-
46
- // private _adDisplayContainer: HTMLElement | null = null;
47
-
48
- private extension: ExtensionData | null = null
49
-
50
- private firstRemaininTime = 0
51
-
52
- private _imaContainer: HTMLElement | null = null
53
-
54
- private isPlaying = false
55
-
56
- private loadXML: LoaderXML | null = null
57
-
58
- private _pr: number
59
-
60
- private roll: Roll | null = null
61
-
62
- constructor(
63
- private core: Core,
64
- private options: CoreOptions,
65
- private $skipAd: ZeptoResult,
66
- private $muteIcon: ZeptoResult,
67
- private $areaClick: ZeptoResult,
68
- private _adContainer: HTMLElement,
69
- private type: AdRollType,
70
- private countRoll: number,
71
- private volume: number,
72
- private prevVolume: number,
73
- ) {
74
- super()
75
- this._options = options
76
- this.vastAdsOptions = this._options.vastAds as any
77
- this.container = this.core.activeContainer
78
- this._container = this.container
79
- // this.countRoll = countRoll || 0;
80
- this.$skipAd = $skipAd
81
- this.type = type
82
- this.$muteIcon = $muteIcon
83
- this.$areaClick = $areaClick
84
- this._playback = this.core.activePlayback
85
- this._contentElement = this._playback.el as HTMLMediaElement
86
- this._posterPlugin = this._container.getPlugin('poster')
87
- this._clickToPausePlugin = this._container.getPlugin('click_to_pause')
88
- this._adContainer = _adContainer
89
- this._events = {}
90
- this._pr = Math.floor(Math.random() * 1000000)
91
- }
92
-
93
- private initializeRoll({
94
- xml,
95
- url,
96
- extension,
97
- }: {
98
- xml: any
99
- url: string
100
- extension: any
101
- }) {
102
- try {
103
- this.roll = new Roll({
104
- core: this.core,
105
- $skipAd: this.$skipAd,
106
- $muteIcon: this.$muteIcon,
107
- $areaClick: this.$areaClick,
108
- mute: !!this.options.mute,
109
- volume: this.volume,
110
- prevVolume: this.prevVolume,
111
- })
112
- // @ts-ignore
113
- this.roll.on('volume', this.changeVolume.bind(this))
114
- // @ts-ignore
115
- this.roll.on('advertisement_started', this.onAdStarted.bind(this))
116
- // @ts-ignore
117
- this.roll.on('advertisement_played', this.onAdPlayed.bind(this))
118
- // @ts-ignore
119
- this.roll.on('continue_ad', this._cleverContinueAd.bind(this))
120
- // @ts-ignore
121
- this.roll.on('advertisement_finish', this._playVideoContent.bind(this))
122
-
123
- this.roll._requestAd({ xml, url, extension })
124
- } catch (error) {
125
- // LogManager.exception(error);
126
- reportError(error)
127
- }
128
- }
129
-
130
- playerResize(_: { width: number; height: number }) {
131
- if (this.roll) {
132
- this.roll.playerResize()
133
- }
134
- }
135
-
136
- private onAdStarted(_: { url: string }) {
137
- this.removeContainer()
138
- }
139
-
140
- onAdPlayed() {
141
- this.isPlaying = true
142
- }
143
-
144
- private removeContainer() {
145
- this.trigger('advertisement_started')
146
- }
147
-
148
- private changeVolume(obj: { volume: number; mute: boolean }) {
149
- this.trigger('volume', obj)
150
- }
151
-
152
- // private _createAdDisplayContainer() {
153
- // this._createImaContainer();
154
- // assert('google' in window, 'google not found');
155
- // this._adDisplayContainer = new (window.google as any).ima.AdDisplayContainer(this._imaContainer, this._contentElement);
156
- // }
157
-
158
- _createImaContainer() {
159
- this._destroyImaContainer()
160
- // IMA does not clean ad container when finished
161
- // For the sake of simplicity, wrap into a <div> element
162
- if (this._adContainer) {
163
- this._imaContainer = document.createElement('div')
164
- this._adContainer.appendChild(this._imaContainer)
165
- }
166
- }
167
-
168
- _destroyImaContainer() {
169
- if (this._imaContainer && this._adContainer) {
170
- this._adContainer.removeChild(this._imaContainer)
171
- this._imaContainer = null
172
- }
173
- }
174
-
175
- async setupRoll() {
176
- // TODO: check if this is correct
177
- const dataAd = this.vastAdsOptions[this.type] || { data: [] }
178
- const { oneByOne = false } = dataAd
179
- let rollList = dataAd.data
180
-
181
- if (this.type === 'middleroll') {
182
- const currentStartTime = dataAd.data[this.countRoll].startTimePercent
183
-
184
- rollList = dataAd.data.filter((el) => {
185
- if (el.startTimePercent === currentStartTime) {
186
- return true
187
- }
188
- })
189
- }
190
- if (this.type === 'repeatableroll') {
191
- const currentStartTime = dataAd.data[this.countRoll].startTime
192
-
193
- rollList = dataAd.data.filter((el) => {
194
- if (el.startTime === currentStartTime) {
195
- return true
196
- }
197
- })
198
- }
199
-
200
- if (this.type === 'middleroll' || this.type === 'repeatableroll') {
201
- this.trigger('change_counter', {
202
- type: this.type,
203
- value: this.countRoll + rollList.length,
204
- })
205
- }
206
- await this.startAd(this.type, { data: rollList, oneByOne })
207
- }
208
-
209
- async startAd(type: AdRollType, roll: AdRollDesc) {
210
- // TODO
211
- // Player.player.trigger('advertisementWasStarted');
212
- this.core.trigger('core:advertisement:start')
213
- this.container.trigger('container:advertisement:start')
214
- ;(this.container as any).advertisement = { type: type }
215
- if (type !== 'middleroll' && type !== 'repeatableroll') {
216
- console.warn('disableControls')
217
- setTimeout(() => this._disableControls(), 0)
218
- }
219
-
220
- if (!this.adTemplates && roll) {
221
- this.adTemplates = this.parseAdUrl(roll.data)
222
- if (!this.adTemplates) {
223
- this.trigger('disable_plugin', { type: this.type })
224
-
225
- return
226
- }
227
- }
228
- if (type === 'preroll') {
229
- if (Browser.isMobile) {
230
- this._playback.consent(() => {})
231
- }
232
- }
233
- //чтобы реклама шла одна за другой
234
- this._allURLRequest = !!roll.oneByOne
235
- try {
236
- const customPosterPlugin = this.container.getPlugin('poster')
237
-
238
- customPosterPlugin.hidePlayButton()
239
- } catch (error) {
240
- // LogManager.exception(error);
241
- reportError(error)
242
- }
243
-
244
- if (!this.adTemplates?.length) {
245
- this.trigger('advertisement_dont_play', { type: this.type })
246
-
247
- return
248
- }
249
- Log.debug('Advertisement', 'advertisement will start')
250
- try {
251
- const adTemplate = this.adTemplates.shift()
252
- // @ts-ignore
253
- await this.loadAd(adTemplate.url)
254
- } catch (error) {
255
- // LogManager.exception(error);
256
- reportError(error)
257
- }
258
- }
259
-
260
- _disableControls() {
261
- this.container.disableMediaControl()
262
- this._clickToPausePlugin?.disable()
263
- // @ts-ignore
264
- this._posterPlugin?.$playWrapper.hide()
265
- }
266
-
267
- private parseAdUrl(arr: any): AdRollItem[] | null {
268
- if (!Array.isArray(arr)) {
269
- return null
270
- }
271
-
272
- return arr.filter((el) => el.url)
273
- }
274
-
275
- paramsUrl(url: string): string {
276
- try {
277
- url = url.replace(/\{width\}/g, this.container.$el.width())
278
- url = url.replace(/\{height\}/g, this.container.$el.height())
279
- url = url.replace(/\{pr\}/g, String(this._pr))
280
- url = url.replace(
281
- /\{random\}/g,
282
- String(Math.floor(Math.random() * 1000000)),
283
- )
284
- url = url.replace(/\{session_id\}/g, Utils.uniqueId(''))
285
- url = url.replace(/\{start_delay\}/g, '0')
286
-
287
- if (this.options.referer) {
288
- url = url.replace(
289
- new RegExp(/\{referer\}/g, 'g'),
290
- String(this.options.referer ?? ''),
291
- )
292
- }
293
-
294
- let playback = 1
295
-
296
- if (this.options.autoPlay && this.options.mute) {
297
- playback = 2
298
- }
299
-
300
- if (!this.options.autoPlay) {
301
- playback = 3
302
- }
303
-
304
- url = url.replace(/\{playback\}/g, String(playback))
305
- } catch (error) {
306
- // LogManager.exception(error);
307
- reportError(error)
308
- }
309
-
310
- return url
311
- }
312
-
313
- async loadAd(url: string) {
314
- if (!url) {
315
- return
316
- }
317
- try {
318
- if (
319
- !['middleroll', 'repeatableroll'].includes(
320
- (this.container as any).advertisement.type,
321
- )
322
- ) {
323
- const spinnerPlugin = this.container.getPlugin('spinner')
324
-
325
- spinnerPlugin?.show()
326
- }
327
- } catch (error) {
328
- // LogManager.exception(error);
329
- reportError(error)
330
- }
331
- url = this.paramsUrl(url)
332
-
333
- Roll._adContainer = this._adContainer
334
- Roll._contentElement = this._contentElement
335
- Roll.createAdDisplayContainer()
336
- this.loadXML = new LoaderXML(url)
337
- let data: ExtensionData
338
-
339
- try {
340
- data = await this.loadXML.startLoad()
341
- } catch (error) {
342
- // LogManager.exception(error);
343
- reportError(error)
344
- if (this.adTemplates && this.adTemplates.length > 0) {
345
- const adTemplate = this.adTemplates.shift()
346
- // @ts-ignore
347
- await this.loadAd(adTemplate.url)
348
- } else {
349
- const spinnerPlugin = this.container.getPlugin('spinner')
350
-
351
- spinnerPlugin?.hide()
352
- this.trigger('advertisement_dont_play', { type: this.type })
353
- }
354
-
355
- return
356
- }
357
- try {
358
- this.firstRemaininTime = 0
359
- this.$muteIcon.hide()
360
- this.$skipAd.hide()
361
-
362
- // this.volume = this._playback.volume;
363
- assert(this._playback instanceof HTML5Video)
364
- this.volume = (this._playback.el as HTMLMediaElement).volume
365
- } catch (error) {
366
- // LogManager.exception(error);
367
- reportError(error)
368
- }
369
- this.extension = data
370
- this.initializeRoll({
371
- xml: data.config,
372
- url: String(data.url || url),
373
- extension: data,
374
- })
375
- }
376
-
377
- _onAdError(adErrorEvent: any) {
378
- try {
379
- const googleError = adErrorEvent.getError()
380
- const error = new Error(
381
- googleError.getMessage() + ' ' + googleError.getErrorCode(),
382
- )
383
-
384
- error.name = googleError.getType()
385
- // LogManager.exception(error);
386
- reportError(error)
387
- } catch (error) {
388
- // LogManager.exception(error);
389
- reportError(error)
390
- }
391
- Log.debug('Advertisement', 'advertisement error')
392
-
393
- this._cleverContinueAd(true)
394
- }
395
-
396
- _imaEvent(eventName: string, e: any) {
397
- $.isFunction((this._events as any)[eventName]) &&
398
- (this._events as any)[eventName](e)
399
- }
400
-
401
- /**
402
- * определяет, что дальше будет запускаться реклама или контент
403
- *
404
- */
405
- async _cleverContinueAd(data: any) {
406
- this.destroyRoll()
407
- const error = data.error
408
-
409
- if (
410
- (this._allURLRequest || error) &&
411
- this.adTemplates &&
412
- this.adTemplates.length > 0
413
- ) {
414
- const adTemplate = this.adTemplates.shift()
415
- // @ts-ignore
416
- await this.loadAd(adTemplate.url)
417
-
418
- return
419
- }
420
- this._playVideoContent()
421
- }
422
-
423
- _playVideoContent() {
424
- this.destroyRoll()
425
- Roll.destroyImaContainer()
426
-
427
- const spinnerPlugin = this.container.getPlugin('spinner')
428
-
429
- spinnerPlugin?.hide()
430
-
431
- if (this.isPlaying) {
432
- this.trigger('advertisement_finish', { type: this.type })
433
- } else {
434
- this.trigger('advertisement_dont_play', { type: this.type })
435
- }
436
- }
437
-
438
- destroyRoll() {
439
- if (!this.roll) {
440
- return
441
- }
442
- // @ts-ignore
443
- this.roll.off()
444
- this.roll.destroy()
445
- this.roll = null
446
- }
447
- }
@@ -1,152 +0,0 @@
1
- import { Events, Playback } from '@clappr/core'
2
- import { Events as HlsEvents, FragChangedData } from 'hls.js'
3
-
4
- const OUT = 'out',
5
- IN = 'in',
6
- OUT_CONT = 'out_cont'
7
-
8
- type CueResult = { kind?: 'in' | 'out' | 'out_cont'; duration?: number }
9
-
10
- export default class SCTEManager extends Events {
11
- private _playback: Playback | null = null
12
-
13
- private _scteIsStarted = false
14
-
15
- set playback(value: Playback) {
16
- if (this._playback) {
17
- //удалить все подписанные евенты
18
- // @ts-ignore
19
- if (this._playback._hls) {
20
- // @ts-ignore
21
- this._playback._hls.off(
22
- HlsEvents.FRAG_CHANGED,
23
- this._onHlsFragChanged.bind(this),
24
- )
25
- }
26
-
27
- this._playback.off(
28
- Events.PLAYBACK_PLAY_INTENT,
29
- this._subscribedHlsEvents,
30
- this,
31
- )
32
- }
33
- this._playback = value
34
- // @ts-ignore
35
- if (!this._playback._hls) {
36
- this._playback.once(
37
- Events.PLAYBACK_PLAY_INTENT,
38
- this._subscribedHlsEvents,
39
- this,
40
- )
41
- } else {
42
- this._subscribedHlsEvents()
43
- }
44
- }
45
-
46
- get playback(): Playback | null {
47
- return this._playback
48
- }
49
-
50
- _subscribedHlsEvents() {
51
- // @ts-ignore
52
- if (this._playback._hls) {
53
- // @ts-ignore
54
- this._playback._hls.off(
55
- HlsEvents.FRAG_CHANGED,
56
- this._onHlsFragChanged.bind(this),
57
- )
58
- // @ts-ignore
59
- this._playback._hls.on(
60
- HlsEvents.FRAG_CHANGED,
61
- this._onHlsFragChanged.bind(this),
62
- )
63
- }
64
- }
65
-
66
- _onHlsFragChanged(_: HlsEvents.FRAG_CHANGED, data: FragChangedData) {
67
- const { tagList } = data.frag
68
-
69
- if (tagList) {
70
- const cue = this._getCue(tagList)
71
-
72
- if (Object.keys(cue).length > 0) {
73
- if (!this._scteIsStarted) {
74
- if (cue.kind === OUT || cue.kind === OUT_CONT) {
75
- this._scteIsStarted = true
76
- console.warn('scteroll will be started')
77
- this.trigger('startSCTERoll', {
78
- duration: cue.duration,
79
- })
80
- }
81
- } else {
82
- if (cue.kind === IN) {
83
- console.warn('scteroll will be stopped')
84
- this._stopScte()
85
- }
86
- }
87
- } else {
88
- this._stopScte()
89
- }
90
- }
91
- }
92
-
93
- _stopScte() {
94
- if (this._scteIsStarted) {
95
- this.trigger('stopSCTERoll')
96
- this._scteIsStarted = false
97
- }
98
- }
99
-
100
- _getCue(tagList: string[][]): CueResult {
101
- let cueResult: CueResult = {
102
- kind: undefined,
103
- duration: undefined,
104
- }
105
-
106
- for (let i = 0; i < tagList.length; i++) {
107
- const infoSegment = tagList[i]
108
- let kind: 'in' | 'out' | 'out_cont' | undefined
109
- let duration: number | undefined
110
-
111
- infoSegment.forEach((info) => {
112
- if (kind) {
113
- if (kind === OUT) {
114
- const dur = parseInt(info)
115
-
116
- !isNaN(dur) && (duration = dur)
117
- }
118
- if (kind === OUT_CONT) {
119
- const durString = info.match(/Duration=\d+/g)
120
-
121
- if (durString) {
122
- const durNumb = durString[0].match(/\d+/g)
123
-
124
- if (durNumb) {
125
- duration = parseInt(durNumb[0])
126
- }
127
- }
128
- }
129
- } else {
130
- switch (info) {
131
- case 'EXT-X-CUE-OUT':
132
- kind = OUT
133
- break
134
- case 'EXT-X-CUE-OUT-CONT':
135
- kind = OUT_CONT
136
- break
137
- case 'EXT-X-CUE-IN':
138
- kind = IN
139
- break
140
- }
141
- }
142
- })
143
- kind &&
144
- (cueResult = {
145
- kind,
146
- duration,
147
- })
148
- }
149
-
150
- return cueResult
151
- }
152
- }
@@ -1,20 +0,0 @@
1
- export type AdRollType =
2
- | 'preroll'
3
- | 'middleroll'
4
- | 'repeatableroll'
5
- | 'pauseroll'
6
- | 'postroll'
7
- | 'scteroll'
8
-
9
- export type AdRollItem = {
10
- startTime: number
11
- startTimePercent: number
12
- tag: string
13
- }
14
-
15
- export type AdRollDesc = {
16
- data: AdRollItem[]
17
- oneByOne?: boolean
18
- }
19
-
20
- export type VastAdsOptions = Partial<Record<AdRollType, AdRollDesc>>
@@ -1,42 +0,0 @@
1
- import assert from 'assert'
2
- import XHRURLHandler from './xmlhttprequest.js'
3
-
4
- // eslint-disable-next-line max-len
5
- const ERROR_MESSAGE =
6
- 'Current context is not supported by any of the default URLHandlers. Please provide a custom URLHandler'
7
-
8
- export default class URLHandler {
9
- static get(
10
- url: string,
11
- options: any,
12
- cb?: (err: any | null, response?: any) => void,
13
- ) {
14
- // Allow skip of the options param
15
- if (!cb) {
16
- if (typeof options === 'function') {
17
- cb = options
18
- }
19
- options = {}
20
- }
21
-
22
- assert(cb, 'URLHandler.get: callback is required')
23
- if (options.response) {
24
- // Trick: the VAST response XML document is passed as an option
25
- const { response } = options
26
-
27
- delete options.response
28
-
29
- return cb(null, response)
30
- }
31
-
32
- if (options.urlhandler?.supported()) {
33
- // explicitly supply your own URLHandler object
34
- return options.urlhandler.get(url, options, cb)
35
- }
36
- if (XHRURLHandler.supported()) {
37
- return XHRURLHandler.get(url, options, cb)
38
- }
39
-
40
- return cb(new Error(ERROR_MESSAGE))
41
- }
42
- }
@@ -1,49 +0,0 @@
1
- import { reportError } from '@gcorevideo/utils'
2
- import assert from 'assert'
3
-
4
- export default class XHRURLHandler {
5
- static xhrCreate(): XMLHttpRequest | false {
6
- const xhr = new window.XMLHttpRequest()
7
-
8
- if ('withCredentials' in xhr) {
9
- // check CORS support
10
- return xhr
11
- }
12
-
13
- return false
14
- }
15
-
16
- static supported() {
17
- return !!this.xhrCreate()
18
- }
19
-
20
- static get(
21
- url: string,
22
- options: any,
23
- cb: (err: Error | null, response?: any) => void,
24
- ) {
25
- try {
26
- const xhr = this.xhrCreate()
27
- assert(xhr, 'XHRURLHandler: XMLHttpRequest is not supported')
28
-
29
- xhr.open('GET', url)
30
- xhr.timeout = options.timeout || 0
31
- xhr.withCredentials = options.withCredentials || false
32
- xhr.onreadystatechange = function () {
33
- if (xhr.readyState === 4) {
34
- if (xhr.status === 200) {
35
- return cb(null, xhr.response)
36
- } else {
37
- return cb(new Error(`XHRURLHandler: ${xhr.statusText}`))
38
- }
39
- }
40
- }
41
-
42
- return xhr.send()
43
- } catch (error) {
44
- // LogManager.exception(error);
45
- reportError(error)
46
- return cb(new Error('XHRURLHandler: Unexpected error'))
47
- }
48
- }
49
- }