-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Beta Part 4: Part of Mega Dynamic Load/Unload support (#1781)
* Beta Part 4: Part of Mega Dynamic Load/Unload support - Fix function typing issues - Update Analytics Extension to start supporting teardown / unload (more tests required) - Adds namespace option to instrumentation hooks (for debugging teardown issues) - Update AITest Class to log and optionally assert events and hooks that have not been removed - Add Update callback when plugins are added / removed (will be extended for config updates) - Some minor minification improvements * Update comments * Add missing enum definition * Update Sender tests
- Loading branch information
Showing
33 changed files
with
1,271 additions
and
610 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,104 @@ | ||
import { getWindow, getDocument, getNavigator, isUndefined, isNullOrUndefined, attachEvent } from "@microsoft/applicationinsights-core-js"; | ||
import dynamicProto from "@microsoft/dynamicproto-js"; | ||
import { getWindow, getDocument, getNavigator, isUndefined, isNullOrUndefined, createUniqueNamespace, mergeEvtNamespace, eventOn, eventOff } from "@microsoft/applicationinsights-core-js"; | ||
|
||
export interface IOfflineListener { | ||
isOnline: () => boolean; | ||
isListening: () => boolean; | ||
unload: () => void; | ||
} | ||
|
||
function _disableEvents(target: any, evtNamespace: string | string[]) { | ||
eventOff(target, null, null, evtNamespace); | ||
} | ||
|
||
/** | ||
* @description Monitors browser for offline events | ||
* @export default - Offline: Static instance of OfflineListener | ||
* @class OfflineListener | ||
* Create a new OfflineListener instance to monitor browser online / offline events | ||
* @param parentEvtNamespace - The parent event namespace to append to any specific events for this instance | ||
*/ | ||
export class OfflineListener { | ||
public static Offline = new OfflineListener; | ||
public isListening: boolean; | ||
|
||
constructor() { | ||
let _window = getWindow(); | ||
let _document = getDocument(); | ||
let isListening = false; | ||
let _onlineStatus: boolean = true; | ||
|
||
dynamicProto(OfflineListener, this, (_self) => { | ||
try { | ||
if (_window) { | ||
if (attachEvent(_window, "online", _setOnline)) { | ||
attachEvent(_window, "offline", _setOffline); | ||
isListening = true; | ||
} | ||
} | ||
|
||
if (_document) { | ||
// Also attach to the document.body or document | ||
let target:any = _document.body || _document; | ||
|
||
if (!isUndefined(target.ononline)) { | ||
target.ononline = _setOnline; | ||
target.onoffline = _setOffline; | ||
isListening = true; | ||
|
||
} | ||
} | ||
export function createOfflineListener(parentEvtNamespace?: string | string[]): IOfflineListener { | ||
let _document = getDocument(); | ||
var _navigator = getNavigator(); // Gets the window.navigator or workerNavigator depending on the global | ||
let _isListening: boolean = false; | ||
let _onlineStatus: boolean = true; | ||
let _evtNamespace = mergeEvtNamespace(createUniqueNamespace("OfflineListener"), parentEvtNamespace); | ||
|
||
if (isListening) { | ||
// We are listening to events so lets set the current status rather than assuming we are online #1538 | ||
var _navigator = getNavigator(); // Gets the window.navigator or workerNavigator depending on the global | ||
if (_navigator && !isNullOrUndefined(_navigator.onLine)) { // navigator.onLine is undefined in react-native | ||
_onlineStatus = _navigator.onLine; | ||
} | ||
try { | ||
if (_enableEvents(getWindow())) { | ||
_isListening = true; | ||
} | ||
|
||
if (_document) { | ||
// Also attach to the document.body or document | ||
let target:any = _document.body || _document; | ||
|
||
if (target.ononline) { | ||
if (_enableEvents(target)) { | ||
_isListening = true; | ||
} | ||
} catch (e) { | ||
|
||
// this makes react-native less angry | ||
isListening = false; | ||
} | ||
|
||
_self.isListening = isListening; | ||
|
||
_self.isOnline = (): boolean => { | ||
let result = true; | ||
var _navigator = getNavigator(); | ||
if (isListening) { | ||
result = _onlineStatus | ||
} else if (_navigator && !isNullOrUndefined(_navigator.onLine)) { // navigator.onLine is undefined in react-native | ||
result = _navigator.onLine; | ||
} | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
_self.isOffline = (): boolean => { | ||
return !_self.isOnline(); | ||
}; | ||
|
||
function _setOnline() { | ||
_onlineStatus = true; | ||
if (_isListening) { | ||
// We are listening to events so lets set the current status rather than assuming we are online #1538 | ||
if (_navigator && !isNullOrUndefined(_navigator.onLine)) { // navigator.onLine is undefined in react-native | ||
_onlineStatus = _navigator.onLine; | ||
} | ||
} | ||
} catch (e) { | ||
// this makes react-native less angry | ||
_isListening = false; | ||
} | ||
|
||
function _setOffline() { | ||
_onlineStatus = false; | ||
function _enableEvents(target: any): boolean { | ||
let enabled = false; | ||
if (target) { | ||
enabled = eventOn(target, "online", _setOnline, _evtNamespace); | ||
if (enabled) { | ||
eventOn(target, "offline", _setOffline, _evtNamespace); | ||
} | ||
}); | ||
} | ||
|
||
return enabled; | ||
} | ||
|
||
public isOnline(): boolean { | ||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging | ||
return false; | ||
function _setOnline() { | ||
_onlineStatus = true; | ||
} | ||
|
||
public isOffline(): boolean { | ||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging | ||
return false; | ||
function _setOffline() { | ||
_onlineStatus = false; | ||
} | ||
} | ||
|
||
export const Offline = OfflineListener.Offline; | ||
function _isOnline(): boolean { | ||
let result = true; | ||
if (_isListening) { | ||
result = _onlineStatus | ||
} else if (_navigator && !isNullOrUndefined(_navigator.onLine)) { // navigator.onLine is undefined in react-native | ||
result = _navigator.onLine; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
function _unload() { | ||
let win = getWindow(); | ||
if (win && _isListening) { | ||
_disableEvents(win, _evtNamespace); | ||
|
||
if (_document) { | ||
// Also attach to the document.body or document | ||
let target:any = _document.body || _document; | ||
if (!isUndefined(target.ononline)) { | ||
_disableEvents(target, _evtNamespace); | ||
} | ||
} | ||
|
||
_isListening = false; | ||
} | ||
} | ||
|
||
return { | ||
isOnline: _isOnline, | ||
isListening: () => _isListening, | ||
unload: _unload | ||
}; | ||
} |
Oops, something went wrong.