ApplicationManager and better memory management

This commit is contained in:
Mo Bitar
2020-03-23 19:59:55 -05:00
parent 7dc3dab90b
commit ee7cb1fce6
55 changed files with 36786 additions and 3046 deletions

View File

@@ -3,27 +3,38 @@ export function clickOutside($document) {
return {
restrict: 'A',
replace: false,
link: function($scope, $element, attrs) {
var didApplyClickOutside = false;
link: function ($scope, $element, attrs) {
// Causes memory leak as-is:
// let didApplyClickOutside = false;
$element.bind('click', function(e) {
didApplyClickOutside = false;
if (attrs.isOpen) {
e.stopPropagation();
}
});
// $scope.$on('$destroy', () => {
// attrs.clickOutside = null;
// $element.unbind('click', $scope.onElementClick);
// $document.unbind('click', $scope.onDocumentClick);
// $scope.onElementClick = null;
// $scope.onDocumentClick = null;
// });
$document.bind('click', function() {
// Ignore click if on SKAlert
if (event.target.closest(".sk-modal")) {
return;
}
// $scope.onElementClick = (event) => {
// didApplyClickOutside = false;
// if (attrs.isOpen) {
// event.stopPropagation();
// }
// };
// $scope.onDocumentClick = (event) => {
// /* Ignore click if on SKAlert */
// if (event.target.closest('.sk-modal')) {
// return;
// }
// if (!didApplyClickOutside) {
// $scope.$apply(attrs.clickOutside);
// didApplyClickOutside = true;
// }
// };
if (!didApplyClickOutside) {
$scope.$apply(attrs.clickOutside);
didApplyClickOutside = true;
}
});
// $element.bind('click', $scope.onElementClick);
// $document.bind('click', $scope.onDocumentClick);
}
};
}

View File

@@ -1,16 +1,20 @@
/* @ngInject */
export function infiniteScroll($rootScope, $window, $timeout) {
export function infiniteScroll() {
return {
link: function(scope, elem, attrs) {
const offset = parseInt(attrs.threshold) || 0;
const e = elem[0];
elem.on('scroll', function() {
scope.onScroll = () => {
if (
scope.$eval(attrs.canLoad) &&
e.scrollTop + e.offsetHeight >= e.scrollHeight - offset
) {
scope.$apply(attrs.infiniteScroll);
}
};
elem.on('scroll', scope.onScroll);
scope.$on('$destroy', () => {
elem.off('scroll', scope.onScroll);;
});
}
};

View File

@@ -28,32 +28,18 @@ const ELEMENT_NAME_AUTH_PASSWORD_CONF = 'password_conf';
class AccountMenuCtrl extends PureCtrl {
/* @ngInject */
constructor(
$scope,
$rootScope,
$timeout,
appVersion,
application,
appState,
archiveManager,
godService,
lockManager,
) {
super($scope, $timeout, application, appState);
this.$rootScope = $rootScope;
this.appState = appState;
this.application = application;
this.archiveManager = archiveManager;
this.godService = godService;
this.lockManager = lockManager;
super($timeout);
this.appVersion = appVersion;
this.syncStatus = this.application.getSyncStatus();
}
/** @override */
getInitialState() {
return {
appVersion: 'v' + (window.electronAppVersion || this.appVersion),
passcodeAutoLockOptions: this.lockManager.getAutoLockIntervalOptions(),
passcodeAutoLockOptions: this.application.getLockService().getAutoLockIntervalOptions(),
user: this.application.getUser(),
formData: {
mergeLocal: true,
@@ -90,11 +76,12 @@ class AccountMenuCtrl extends PureCtrl {
this.initProps({
closeFunction: this.closeFunction
});
this.syncStatus = this.application.getSyncStatus();
}
close() {
this.$timeout(() => {
this.props.closeFunction()();
this.props.closeFunction();
});
}
@@ -277,19 +264,19 @@ class AccountMenuCtrl extends PureCtrl {
openPasswordWizard() {
this.close();
this.godService.presentPasswordWizard();
this.application.presentPasswordWizard();
}
async openPrivilegesModal() {
this.close();
const run = () => {
this.godService.presentPrivilegesManagementModal();
this.application.presentPrivilegesManagementModal();
};
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege(
ProtectedActions.ManagePrivileges
);
if (needsPrivilege) {
this.godService.presentPrivilegesModal(
this.application.presentPrivilegesModal(
ProtectedActions.ManagePrivileges,
() => {
run();
@@ -366,7 +353,7 @@ class AccountMenuCtrl extends PureCtrl {
ProtectedActions.ManageBackups
);
if (needsPrivilege) {
this.godService.presentPrivilegesModal(
this.application.presentPrivilegesModal(
ProtectedActions.ManageBackups,
run
);
@@ -416,7 +403,7 @@ class AccountMenuCtrl extends PureCtrl {
}
async downloadDataArchive() {
this.archiveManager.downloadBackup(this.state.mutable.backupEncrypted);
this.application.getArchiveService().downloadBackup(this.state.mutable.backupEncrypted);
}
notesAndTagsCount() {
@@ -434,7 +421,7 @@ class AccountMenuCtrl extends PureCtrl {
}
async reloadAutoLockInterval() {
const interval = await this.lockManager.getAutoLockInterval();
const interval = await this.application.getLockService().getAutoLockInterval();
this.setState({
selectedAutoLockInterval: interval
});
@@ -442,14 +429,14 @@ class AccountMenuCtrl extends PureCtrl {
async selectAutoLockInterval(interval) {
const run = async () => {
await this.lockManager.setAutoLockInterval(interval);
await this.application.getLockService().setAutoLockInterval(interval);
this.reloadAutoLockInterval();
};
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege(
ProtectedActions.ManagePasscode
);
if (needsPrivilege) {
this.godService.presentPrivilegesModal(
this.application.presentPrivilegesModal(
ProtectedActions.ManagePasscode,
() => {
run();
@@ -508,7 +495,7 @@ class AccountMenuCtrl extends PureCtrl {
ProtectedActions.ManagePasscode
);
if (needsPrivilege) {
this.godService.presentPrivilegesModal(
this.application.presentPrivilegesModal(
ProtectedActions.ManagePasscode,
run
);
@@ -536,7 +523,7 @@ class AccountMenuCtrl extends PureCtrl {
ProtectedActions.ManagePasscode
);
if (needsPrivilege) {
this.godService.presentPrivilegesModal(
this.application.presentPrivilegesModal(
ProtectedActions.ManagePasscode,
run
);
@@ -558,7 +545,8 @@ export class AccountMenu {
this.controllerAs = 'self';
this.bindToController = true;
this.scope = {
closeFunction: '&'
closeFunction: '&',
application: '='
};
}
}

View File

@@ -4,14 +4,9 @@ import { PureCtrl } from '@Controllers';
class ActionsMenuCtrl extends PureCtrl {
/* @ngInject */
constructor(
$scope,
$timeout,
application,
appState,
godService
$timeout
) {
super($scope, $timeout, application, appState);
this.godService = godService;
super($timeout);
this.state = {
extensions: []
};
@@ -77,7 +72,7 @@ class ActionsMenuCtrl extends PureCtrl {
switch (action.verb) {
case 'render': {
const item = result.item;
this.godService.presentRevisionPreviewModal(
this.application.presentRevisionPreviewModal(
item.uuid,
item.content
);
@@ -111,7 +106,8 @@ export class ActionsMenu {
this.controllerAs = 'self';
this.bindToController = true;
this.scope = {
item: '='
item: '=',
application: '='
};
}
}

View File

@@ -5,13 +5,10 @@ import { PureCtrl } from '@Controllers';
class ChallengeModalCtrl extends PureCtrl {
/* @ngInject */
constructor(
$scope,
$element,
$timeout,
application,
appState
$timeout
) {
super($scope, $timeout, application, appState);
super($timeout);
this.$element = $element;
this.processingTypes = [];
}
@@ -48,6 +45,13 @@ class ChallengeModalCtrl extends PureCtrl {
});
}
deinit() {
this.application = null;
this.orchestrator = null;
this.challenge = null;
super.deinit();
}
reloadProcessingStatus() {
this.setState({
processing: this.processingTypes.length > 0
@@ -106,7 +110,10 @@ class ChallengeModalCtrl extends PureCtrl {
}
dismiss() {
this.$element.remove();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
@@ -116,11 +123,10 @@ export class ChallengeModal {
this.template = template;
this.controller = ChallengeModalCtrl;
this.controllerAs = 'ctrl';
this.bindToController = true;
this.scope = {
onSubmit: '=',
this.bindToController = {
challenge: '=',
orchestrator: '='
orchestrator: '=',
application: '='
};
}
}

View File

@@ -2,18 +2,19 @@ import template from '%/directives/component-modal.pug';
export class ComponentModalCtrl {
/* @ngInject */
constructor($scope, $element) {
constructor($element) {
this.$element = $element;
this.$scope = $scope;
}
dismiss(callback) {
this.$element.remove();
this.$scope.$destroy();
if(this.onDismiss && this.onDismiss()) {
this.onDismiss()(this.component);
if(this.onDismiss) {
this.onDismiss(this.component);
}
callback && callback();
this.callback && this.callback();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}

View File

@@ -14,26 +14,41 @@ class ComponentViewCtrl {
$scope,
$rootScope,
$timeout,
application,
desktopManager,
themeManager
) {
this.$rootScope = $rootScope;
this.$timeout = $timeout;
this.application = application;
this.themeManager = themeManager;
this.desktopManager = desktopManager;
this.componentValid = true;
$scope.$watch('ctrl.component', (component, prevComponent) => {
this.cleanUpWatch = $scope.$watch('ctrl.component', (component, prevComponent) => {
this.componentValueDidSet(component, prevComponent);
});
$scope.$on('ext-reload-complete', () => {
this.cleanUpOn = $scope.$on('ext-reload-complete', () => {
this.reloadStatus(false);
});
$scope.$on('$destroy', () => {
this.destroy();
});
/** To allow for registering events */
this.onVisibilityChange = this.onVisibilityChange.bind(this);
}
$onDestroy() {
this.cleanUpWatch();
this.cleanUpOn();
this.cleanUpWatch = null;
this.cleanUpOn = null;
this.application.componentManager.deregisterHandler(this.themeHandlerIdentifier);
this.application.componentManager.deregisterHandler(this.identifier);
if (this.component && !this.manualDealloc) {
const dontSync = true;
this.application.componentManager.deactivateComponent(this.component, dontSync);
}
this.application.getDesktopService().deregisterUpdateObserver(this.updateObserver);
document.removeEventListener(
VISIBILITY_CHANGE_LISTENER_KEY,
this.onVisibilityChange
);
this.component = null;
this.onLoad = null;
this.application = null;
this.onVisibilityChange = null;
}
$onInit() {
@@ -42,12 +57,12 @@ class ComponentViewCtrl {
};
registerPackageUpdateObserver() {
this.updateObserver = this.desktopManager
.registerUpdateObserver((component) => {
if(component === this.component && component.active) {
this.reloadComponent();
}
});
this.updateObserver = this.application.getDesktopService()
.registerUpdateObserver((component) => {
if (component === this.component && component.active) {
this.reloadComponent();
}
});
}
registerComponentHandlers() {
@@ -65,7 +80,7 @@ class ComponentViewCtrl {
identifier: this.identifier,
areas: [this.component.area],
activationHandler: (component) => {
if(component !== this.component) {
if (component !== this.component) {
return;
}
this.$timeout(() => {
@@ -73,7 +88,7 @@ class ComponentViewCtrl {
});
},
actionHandler: (component, action, data) => {
if(action === 'set-size') {
if (action === 'set-size') {
this.application.componentManager.handleSetSizeEvent(component, data);
}
}
@@ -81,10 +96,10 @@ class ComponentViewCtrl {
}
onVisibilityChange() {
if(document.visibilityState === 'hidden') {
if (document.visibilityState === 'hidden') {
return;
}
if(this.issueLoading) {
if (this.issueLoading) {
this.reloadComponent();
}
}
@@ -100,34 +115,34 @@ class ComponentViewCtrl {
const component = this.component;
const previouslyValid = this.componentValid;
const offlineRestricted = component.offlineOnly && !isDesktopApplication();
const hasUrlError = function(){
if(isDesktopApplication()) {
const hasUrlError = function () {
if (isDesktopApplication()) {
return !component.local_url && !component.hasValidHostedUrl();
} else {
return !component.hasValidHostedUrl();
}
}();
this.expired = component.valid_until && component.valid_until <= new Date();
if(!component.lockReadonly) {
if (!component.lockReadonly) {
component.readonly = this.expired;
}
this.componentValid = !offlineRestricted && !hasUrlError;
if(!this.componentValid) {
if (!this.componentValid) {
this.loading = false;
}
if(offlineRestricted) {
if (offlineRestricted) {
this.error = 'offline-restricted';
} else if(hasUrlError) {
} else if (hasUrlError) {
this.error = 'url-missing';
} else {
this.error = null;
}
if(this.componentValid !== previouslyValid) {
if(this.componentValid) {
if (this.componentValid !== previouslyValid) {
if (this.componentValid) {
this.application.componentManager.reloadComponent(component, true);
}
}
if(this.expired && doManualReload) {
if (this.expired && doManualReload) {
this.$rootScope.$broadcast('reload-ext-dat');
}
@@ -137,17 +152,17 @@ class ComponentViewCtrl {
}
handleActivation() {
if(!this.component.active) {
if (!this.component.active) {
return;
}
const iframe = this.application.componentManager.iframeForComponent(
this.component
);
if(!iframe) {
if (!iframe) {
return;
}
this.loading = true;
if(this.loadTimeout) {
if (this.loadTimeout) {
this.$timeout.cancel(this.loadTimeout);
}
this.loadTimeout = this.$timeout(() => {
@@ -160,16 +175,16 @@ class ComponentViewCtrl {
}
async handleIframeLoadTimeout() {
if(this.loading) {
if (this.loading) {
this.loading = false;
this.issueLoading = true;
if(!this.didAttemptReload) {
if (!this.didAttemptReload) {
this.didAttemptReload = true;
this.reloadComponent();
} else {
document.addEventListener(
VISIBILITY_CHANGE_LISTENER_KEY,
this.onVisibilityChange.bind(this)
this.onVisibilityChange
);
}
}
@@ -177,13 +192,13 @@ class ComponentViewCtrl {
async handleIframeLoad(iframe) {
let desktopError = false;
if(isDesktopApplication()) {
if (isDesktopApplication()) {
try {
/** Accessing iframe.contentWindow.origin only allowed in desktop app. */
if(!iframe.contentWindow.origin || iframe.contentWindow.origin === 'null') {
if (!iframe.contentWindow.origin || iframe.contentWindow.origin === 'null') {
desktopError = true;
}
} catch (e) {}
} catch (e) { }
}
this.$timeout.cancel(this.loadTimeout);
await this.application.componentManager.registerComponentWindow(
@@ -201,13 +216,13 @@ class ComponentViewCtrl {
componentValueDidSet(component, prevComponent) {
const dontSync = true;
if(prevComponent && component !== prevComponent) {
if (prevComponent && component !== prevComponent) {
this.application.componentManager.deactivateComponent(
prevComponent,
dontSync
);
}
if(component) {
if (component) {
this.application.componentManager.activateComponent(
component,
dontSync
@@ -217,7 +232,7 @@ class ComponentViewCtrl {
}
disableActiveTheme() {
this.themeManager.deactivateAllThemes();
this.application.getThemeService().deactivateAllThemes();
}
getUrl() {
@@ -225,21 +240,6 @@ class ComponentViewCtrl {
this.component.runningLocally = (url === this.component.local_url);
return url;
}
destroy() {
this.application.componentManager.deregisterHandler(this.themeHandlerIdentifier);
this.application.componentManager.deregisterHandler(this.identifier);
if(this.component && !this.manualDealloc) {
const dontSync = true;
this.application.componentManager.deactivateComponent(this.component, dontSync);
}
this.desktopManager.deregisterUpdateObserver(this.updateObserver);
document.removeEventListener(
VISIBILITY_CHANGE_LISTENER_KEY,
this.onVisibilityChange.bind(this)
);
}
}
export class ComponentView {
@@ -249,7 +249,8 @@ export class ComponentView {
this.scope = {
component: '=',
onLoad: '=?',
manualDealloc: '=?'
manualDealloc: '=?',
application: '='
};
this.controller = ComponentViewCtrl;
this.controllerAs = 'ctrl';

View File

@@ -2,14 +2,8 @@ import template from '%/directives/conflict-resolution-modal.pug';
class ConflictResolutionCtrl {
/* @ngInject */
constructor(
$element,
archiveManager,
application
) {
constructor($element) {
this.$element = $element;
this.application = application;
this.archiveManager = archiveManager;
}
$onInit() {
@@ -56,7 +50,7 @@ class ConflictResolutionCtrl {
}
export() {
this.archiveManager.downloadBackupOfItems(
this.application.getArchiveService().downloadBackupOfItems(
[this.item1, this.item2],
true
);
@@ -67,7 +61,10 @@ class ConflictResolutionCtrl {
}
dismiss() {
this.$element.remove();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
@@ -81,7 +78,8 @@ export class ConflictResolutionModal {
this.scope = {
item1: '=',
item2: '=',
callback: '='
callback: '=',
application: '='
};
}
}

View File

@@ -5,12 +5,9 @@ import { PureCtrl } from '@Controllers';
class EditorMenuCtrl extends PureCtrl {
/* @ngInject */
constructor(
$scope,
$timeout,
application,
appState
) {
super($scope, $timeout, application, appState);
super($timeout);
this.state = {
isDesktop: isDesktopApplication()
};
@@ -98,7 +95,8 @@ export class EditorMenu {
this.scope = {
callback: '&',
selectedEditor: '=',
currentItem: '='
currentItem: '=',
application: '='
};
}
}

View File

@@ -3,14 +3,16 @@ import template from '%/directives/input-modal.pug';
class InputModalCtrl {
/* @ngInject */
constructor($scope, $element) {
constructor($element) {
this.$element = $element;
this.formData = {};
}
dismiss() {
this.$element.remove();
this.$scope.$destroy();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
submit() {

View File

@@ -26,13 +26,17 @@ class PanelResizerCtrl {
constructor(
$compile,
$element,
$scope,
$timeout,
) {
this.$compile = $compile;
this.$element = $element;
this.$scope = $scope;
this.$timeout = $timeout;
/** To allow for registering events */
this.handleResize = this.handleResize.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
}
$onInit() {
@@ -45,6 +49,19 @@ class PanelResizerCtrl {
this.addMouseUpListener();
}
$onDestroy() {
this.onResizeFinish = null;
this.control = null;
window.removeEventListener(WINDOW_EVENT_RESIZE, this.handleResize);
document.removeEventListener(MouseEvents.Move, this.onMouseMove);
document.removeEventListener(MouseEvents.Up, this.onMouseUp);
this.resizerColumn.removeEventListener(MouseEvents.Down, this.onMouseDown);
this.handleResize = null;
this.onMouseMove = null;
this.onMouseUp = null;
this.onMouseDown = null;
}
configureControl() {
this.control.setWidth = (value) => {
this.setWidth(value, true);
@@ -96,17 +113,17 @@ class PanelResizerCtrl {
}
configureRightPanel() {
const handleResize = debounce(event => {
window.addEventListener(WINDOW_EVENT_RESIZE, this.handleResize);
}
handleResize() {
debounce(() => {
this.reloadDefaultValues();
this.handleWidthEvent();
this.$timeout(() => {
this.finishSettingWidth();
});
}, 250);
window.addEventListener(WINDOW_EVENT_RESIZE, handleResize);
this.$scope.$on('$destroy', () => {
window.removeEventListener(WINDOW_EVENT_RESIZE, handleResize);
});
}
getParentRect() {
@@ -135,7 +152,7 @@ class PanelResizerCtrl {
this.finishSettingWidth();
const newCollapseState = !preClickCollapseState;
this.onResizeFinish()(
this.onResizeFinish(
this.lastWidth,
this.lastLeft,
this.isAtMaxWidth(),
@@ -146,31 +163,35 @@ class PanelResizerCtrl {
}
addMouseDownListener() {
this.resizerColumn.addEventListener(MouseEvents.Down, (event) => {
this.addInvisibleOverlay();
this.pressed = true;
this.lastDownX = event.clientX;
this.startWidth = this.panel.scrollWidth;
this.startLeft = this.panel.offsetLeft;
this.panel.classList.add(CssClasses.NoSelection);
if (this.hoverable) {
this.resizerColumn.classList.add(CssClasses.Dragging);
}
});
this.resizerColumn.addEventListener(MouseEvents.Down, this.onMouseDown);
}
onMouseDown(event) {
this.addInvisibleOverlay();
this.pressed = true;
this.lastDownX = event.clientX;
this.startWidth = this.panel.scrollWidth;
this.startLeft = this.panel.offsetLeft;
this.panel.classList.add(CssClasses.NoSelection);
if (this.hoverable) {
this.resizerColumn.classList.add(CssClasses.Dragging);
}
}
addMouseMoveListener() {
document.addEventListener(MouseEvents.Move, (event) => {
if (!this.pressed) {
return;
}
event.preventDefault();
if (this.property && this.property === PanelSides.Left) {
this.handleLeftEvent(event);
} else {
this.handleWidthEvent(event);
}
});
document.addEventListener(MouseEvents.Move, this.onMouseMove);
}
onMouseMove(event) {
if (!this.pressed) {
return;
}
event.preventDefault();
if (this.property && this.property === PanelSides.Left) {
this.handleLeftEvent(event);
} else {
this.handleWidthEvent(event);
}
}
handleWidthEvent(event) {
@@ -186,9 +207,6 @@ class PanelResizerCtrl {
const deltaX = x - this.lastDownX;
const newWidth = this.startWidth + deltaX;
this.setWidth(newWidth, false);
if (this.onResize()) {
this.onResize()(this.lastWidth, this.panel);
}
}
handleLeftEvent(event) {
@@ -216,24 +234,27 @@ class PanelResizerCtrl {
}
addMouseUpListener() {
document.addEventListener(MouseEvents.Up, event => {
this.removeInvisibleOverlay();
if (this.pressed) {
this.pressed = false;
this.resizerColumn.classList.remove(CssClasses.Dragging);
this.panel.classList.remove(CssClasses.NoSelection);
const isMaxWidth = this.isAtMaxWidth();
if (this.onResizeFinish) {
this.onResizeFinish()(
this.lastWidth,
this.lastLeft,
isMaxWidth,
this.isCollapsed()
);
}
this.finishSettingWidth();
}
});
document.addEventListener(MouseEvents.Up, this.onMouseUp);
}
onMouseUp() {
this.removeInvisibleOverlay();
if (!this.pressed) {
return;
}
this.pressed = false;
this.resizerColumn.classList.remove(CssClasses.Dragging);
this.panel.classList.remove(CssClasses.NoSelection);
const isMaxWidth = this.isAtMaxWidth();
if (this.onResizeFinish) {
this.onResizeFinish(
this.lastWidth,
this.lastLeft,
isMaxWidth,
this.isCollapsed()
);
}
this.finishSettingWidth();
}
isAtMaxWidth() {
@@ -301,7 +322,7 @@ class PanelResizerCtrl {
if (this.overlay) {
return;
}
this.overlay = this.$compile(`<div id='resizer-overlay'></div>`)(this.$scope);
this.overlay = this.$compile(`<div id='resizer-overlay'></div>`)(this);
angular.element(document.body).prepend(this.overlay);
}
@@ -336,7 +357,6 @@ export class PanelResizer {
hoverable: '=',
index: '=',
minWidth: '=',
onResize: '&',
onResizeFinish: '&',
panelId: '=',
property: '='

View File

@@ -11,15 +11,11 @@ class PasswordWizardCtrl extends PureCtrl {
/* @ngInject */
constructor(
$element,
$scope,
$timeout,
application,
appState
) {
super($scope, $timeout, application, appState);
super($timeout);
this.$element = $element;
this.$timeout = $timeout;
this.$scope = $scope;
this.registerWindowUnloadStopper();
}
@@ -38,14 +34,16 @@ class PasswordWizardCtrl extends PureCtrl {
});
}
$onDestroy() {
super.$onDestroy();
window.onbeforeunload = null;
}
/** Confirms with user before closing tab */
registerWindowUnloadStopper() {
window.onbeforeunload = (e) => {
return true;
};
this.$scope.$on("$destroy", () => {
window.onbeforeunload = null;
});
}
resetContinueState() {
@@ -190,8 +188,10 @@ class PasswordWizardCtrl extends PureCtrl {
text: "Cannot close window until pending tasks are complete."
});
} else {
this.$element.remove();
this.$scope.$destroy();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
}
@@ -204,7 +204,8 @@ export class PasswordWizard {
this.controllerAs = 'ctrl';
this.bindToController = true;
this.scope = {
type: '='
type: '=',
application: '='
};
}
}

View File

@@ -7,7 +7,10 @@ class PermissionsModalCtrl {
}
dismiss() {
this.$element.remove();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
accept() {

View File

@@ -4,12 +4,10 @@ class PrivilegesAuthModalCtrl {
/* @ngInject */
constructor(
$element,
$timeout,
application
$timeout
) {
this.$element = $element;
this.$timeout = $timeout;
this.application = application;
}
$onInit() {
@@ -83,7 +81,10 @@ class PrivilegesAuthModalCtrl {
}
dismiss() {
this.$element.remove();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
@@ -97,7 +98,8 @@ export class PrivilegesAuthModal {
this.scope = {
action: '=',
onSuccess: '=',
onCancel: '='
onCancel: '=',
application: '='
};
}
}

View File

@@ -5,15 +5,11 @@ import { PureCtrl } from '@Controllers';
class PrivilegesManagementModalCtrl extends PureCtrl {
/* @ngInject */
constructor(
$scope,
$timeout,
$element,
application,
appState
$element
) {
super($scope, $timeout, application, appState);
super($timeout);
this.$element = $element;
this.application = application;
}
onAppLaunch() {
@@ -78,7 +74,10 @@ class PrivilegesManagementModalCtrl extends PureCtrl {
}
dismiss() {
this.$element.remove();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
@@ -89,6 +88,8 @@ export class PrivilegesManagementModal {
this.controller = PrivilegesManagementModalCtrl;
this.controllerAs = 'ctrl';
this.bindToController = true;
this.scope = {};
this.scope = {
application: '='
};
}
}

View File

@@ -8,24 +8,21 @@ class RevisionPreviewModalCtrl {
/* @ngInject */
constructor(
$element,
$scope,
$timeout,
application
$timeout
) {
this.$element = $element;
this.$scope = $scope;
this.$timeout = $timeout;
this.application = application;
$scope.$on('$destroy', () => {
if (this.identifier) {
this.application.componentManager.deregisterHandler(this.identifier);
}
});
}
$onInit() {
this.configure();
}
$onDestroy() {
if (this.identifier) {
this.application.componentManager.deregisterHandler(this.identifier);
}
}
async configure() {
this.note = await this.application.createTemplateItem({
@@ -110,8 +107,10 @@ class RevisionPreviewModalCtrl {
}
dismiss() {
this.$element.remove();
this.$scope.$destroy();
const elem = this.$element;
const scope = elem.scope();
scope.$destroy();
elem.remove();
}
}
@@ -124,7 +123,8 @@ export class RevisionPreviewModal {
this.bindToController = true;
this.scope = {
uuid: '=',
content: '='
content: '=',
application: '='
};
}
}

View File

@@ -3,19 +3,15 @@ import template from '%/directives/session-history-menu.pug';
class SessionHistoryMenuCtrl {
/* @ngInject */
constructor(
$timeout,
godService,
application,
$timeout
) {
this.$timeout = $timeout;
this.godService = godService;
this.application = application;
this.diskEnabled = this.application.historyManager.isDiskEnabled();
this.autoOptimize = this.application.historyManager.isAutoOptimizeEnabled();
}
$onInit() {
this.reloadHistory();
this.diskEnabled = this.application.historyManager.isDiskEnabled();
this.autoOptimize = this.application.historyManager.isAutoOptimizeEnabled();
}
reloadHistory() {
@@ -27,7 +23,7 @@ class SessionHistoryMenuCtrl {
}
openRevision(revision) {
this.godService.presentRevisionPreviewModal(
this.application.presentRevisionPreviewModal(
revision.item.uuid,
revision.item.content
);
@@ -110,7 +106,8 @@ export class SessionHistoryMenu {
this.controllerAs = 'ctrl';
this.bindToController = true;
this.scope = {
item: '='
item: '=',
application: '='
};
}
}

View File

@@ -3,18 +3,14 @@ import template from '%/directives/sync-resolution-menu.pug';
class SyncResolutionMenuCtrl {
/* @ngInject */
constructor(
$timeout,
archiveManager,
application
$timeout
) {
this.$timeout = $timeout;
this.archiveManager = archiveManager;
this.application = application;
this.status = {};
}
downloadBackup(encrypted) {
this.archiveManager.downloadBackup(encrypted);
this.application.getArchiveService().downloadBackup(encrypted);
this.status.backupFinished = true;
}
@@ -38,7 +34,7 @@ class SyncResolutionMenuCtrl {
close() {
this.$timeout(() => {
this.closeFunction()();
this.closeFunction();
});
}
}
@@ -51,7 +47,8 @@ export class SyncResolutionMenu {
this.controllerAs = 'ctrl';
this.bindToController = true;
this.scope = {
closeFunction: '&'
closeFunction: '&',
application: '='
};
}
}