2020-10-05 12:56:27 +00:00
|
|
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2022-06-30 11:06:07 +00:00
|
|
|
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
|
2021-02-02 17:41:58 +00:00
|
|
|
import { IonRouterOutlet } from '@ionic/angular';
|
2022-03-09 11:42:25 +00:00
|
|
|
import { BackButtonEvent, ScrollDetail } from '@ionic/core';
|
2020-10-22 11:04:57 +00:00
|
|
|
|
2021-02-02 17:41:58 +00:00
|
|
|
import { CoreLang } from '@services/lang';
|
|
|
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
2021-03-10 11:30:18 +00:00
|
|
|
import { CoreEvents } from '@singletons/events';
|
2022-06-20 16:19:18 +00:00
|
|
|
import { NgZone, SplashScreen, Translate } from '@singletons';
|
2022-06-13 10:45:43 +00:00
|
|
|
import { CoreNetwork } from '@services/network';
|
2022-06-30 11:06:07 +00:00
|
|
|
import { CoreApp } from '@services/app';
|
2020-11-23 11:29:56 +00:00
|
|
|
import { CoreSites } from '@services/sites';
|
2021-01-21 14:24:45 +00:00
|
|
|
import { CoreNavigator } from '@services/navigator';
|
2021-02-02 17:41:58 +00:00
|
|
|
import { CoreSubscriptions } from '@singletons/subscriptions';
|
2021-03-09 08:29:09 +00:00
|
|
|
import { CoreWindow } from '@singletons/window';
|
|
|
|
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
|
|
|
import { CoreUtils } from '@services/utils/utils';
|
|
|
|
import { CoreUrlUtils } from '@services/utils/url';
|
2021-03-10 10:20:10 +00:00
|
|
|
import { CoreConstants } from '@/core/constants';
|
2021-05-19 11:41:11 +00:00
|
|
|
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
2022-01-18 11:51:28 +00:00
|
|
|
import { CoreDomUtils } from '@services/utils/dom';
|
2022-03-24 11:58:55 +00:00
|
|
|
import { CoreDom } from '@singletons/dom';
|
2022-06-20 16:19:18 +00:00
|
|
|
import { CorePlatform } from '@services/platform';
|
2021-03-10 10:20:10 +00:00
|
|
|
|
|
|
|
const MOODLE_VERSION_PREFIX = 'version-';
|
|
|
|
const MOODLEAPP_VERSION_PREFIX = 'moodleapp-';
|
2020-10-05 12:56:27 +00:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-root',
|
|
|
|
templateUrl: 'app.component.html',
|
2020-10-06 10:47:16 +00:00
|
|
|
styleUrls: ['app.component.scss'],
|
2020-10-05 12:56:27 +00:00
|
|
|
})
|
2021-02-02 17:41:58 +00:00
|
|
|
export class AppComponent implements OnInit, AfterViewInit {
|
2020-10-15 09:41:42 +00:00
|
|
|
|
2021-02-02 17:41:58 +00:00
|
|
|
@ViewChild(IonRouterOutlet) outlet?: IonRouterOutlet;
|
2020-10-15 09:41:42 +00:00
|
|
|
|
2021-03-09 08:29:09 +00:00
|
|
|
protected lastUrls: Record<string, number> = {};
|
|
|
|
protected lastInAppUrl?: string;
|
|
|
|
|
2020-10-15 09:41:42 +00:00
|
|
|
/**
|
|
|
|
* Component being initialized.
|
2020-11-23 11:29:56 +00:00
|
|
|
*
|
|
|
|
* @todo Review all old code to see if something is missing:
|
|
|
|
* - IAB events listening.
|
|
|
|
* - Platform pause/resume subscriptions.
|
|
|
|
* - handleOpenURL and openWindowSafely.
|
|
|
|
* - Back button registering to close modal first.
|
|
|
|
* - Note: HideKeyboardFormAccessoryBar has been moved to config.xml.
|
2020-10-15 09:41:42 +00:00
|
|
|
*/
|
|
|
|
ngOnInit(): void {
|
2021-03-09 08:29:09 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
const win = <any> window;
|
2021-03-10 10:20:10 +00:00
|
|
|
document.body.classList.add('ionic5');
|
|
|
|
this.addVersionClass(MOODLEAPP_VERSION_PREFIX, CoreConstants.CONFIG.versionname.replace('-dev', ''));
|
2021-03-09 08:29:09 +00:00
|
|
|
|
2021-05-19 11:41:11 +00:00
|
|
|
CoreEvents.on(CoreEvents.LOGOUT, async () => {
|
2020-10-15 09:41:42 +00:00
|
|
|
// Unload lang custom strings.
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLang.clearCustomStrings();
|
2020-10-15 09:41:42 +00:00
|
|
|
|
|
|
|
// Remove version classes from body.
|
2021-03-10 10:20:10 +00:00
|
|
|
this.removeVersionClass(MOODLE_VERSION_PREFIX);
|
2021-05-19 11:41:11 +00:00
|
|
|
|
|
|
|
// Go to sites page when user is logged out.
|
|
|
|
await CoreNavigator.navigate('/login/sites', { reset: true });
|
|
|
|
|
|
|
|
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
|
|
|
// Temporary fix. Reload the page to unload all plugins.
|
|
|
|
window.location.reload();
|
|
|
|
}
|
2020-10-15 09:41:42 +00:00
|
|
|
});
|
2020-10-30 11:37:00 +00:00
|
|
|
|
2022-03-09 11:42:25 +00:00
|
|
|
// Listen to scroll to add style when scroll is not 0.
|
2022-03-24 11:58:55 +00:00
|
|
|
win.addEventListener('ionScroll', async ({ detail, target }: CustomEvent<ScrollDetail>) => {
|
|
|
|
if ((target as HTMLElement).tagName != 'ION-CONTENT') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const content = (target as HTMLIonContentElement);
|
|
|
|
|
|
|
|
const page = content.closest('.ion-page');
|
|
|
|
if (!page) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
page.querySelector<HTMLIonHeaderElement>('ion-header')?.classList.toggle('core-header-shadow', detail.scrollTop > 0);
|
|
|
|
|
|
|
|
const scrollElement = await content.getScrollElement();
|
|
|
|
content.classList.toggle('core-footer-shadow', !CoreDom.scrollIsBottom(scrollElement));
|
2022-03-09 11:42:25 +00:00
|
|
|
});
|
|
|
|
|
2020-10-30 11:37:00 +00:00
|
|
|
// Listen for session expired events.
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.SESSION_EXPIRED, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLoginHelper.sessionExpired(data);
|
2020-10-30 11:37:00 +00:00
|
|
|
});
|
2020-11-05 13:37:53 +00:00
|
|
|
|
2020-11-23 11:29:56 +00:00
|
|
|
// Listen for passwordchange and usernotfullysetup events to open InAppBrowser.
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.PASSWORD_CHANGE_FORCED, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLoginHelper.passwordChangeForced(data.siteId!);
|
2020-11-23 11:29:56 +00:00
|
|
|
});
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.USER_NOT_FULLY_SETUP, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLoginHelper.openInAppForEdit(data.siteId!, '/user/edit.php', 'core.usernotfullysetup');
|
2020-11-23 11:29:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Listen for sitepolicynotagreed event to accept the site policy.
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.SITE_POLICY_NOT_AGREED, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLoginHelper.sitePolicyNotAgreed(data.siteId);
|
2020-11-23 11:29:56 +00:00
|
|
|
});
|
|
|
|
|
2021-03-09 08:29:09 +00:00
|
|
|
// Check URLs loaded in any InAppBrowser.
|
|
|
|
CoreEvents.on(CoreEvents.IAB_LOAD_START, (event) => {
|
|
|
|
// URLs with a custom scheme can be prefixed with "http://" or "https://", we need to remove this.
|
2021-07-28 08:22:22 +00:00
|
|
|
const protocol = CoreUrlUtils.getUrlProtocol(event.url);
|
2021-03-09 08:29:09 +00:00
|
|
|
const url = event.url.replace(/^https?:\/\//, '');
|
2022-01-18 11:51:28 +00:00
|
|
|
const urlScheme = CoreUrlUtils.getUrlProtocol(url);
|
|
|
|
const isExternalApp = urlScheme && urlScheme !== 'file' && urlScheme !== 'cdvfile';
|
2021-03-09 08:29:09 +00:00
|
|
|
|
|
|
|
if (CoreCustomURLSchemes.isCustomURL(url)) {
|
|
|
|
// Close the browser if it's a valid SSO URL.
|
|
|
|
CoreCustomURLSchemes.handleCustomURL(url).catch((error) => {
|
|
|
|
CoreCustomURLSchemes.treatHandleCustomURLError(error);
|
|
|
|
});
|
|
|
|
CoreUtils.closeInAppBrowser();
|
|
|
|
|
2022-01-18 11:51:28 +00:00
|
|
|
} else if (isExternalApp && url.includes('://token=')) {
|
|
|
|
// It's an SSO token for another app. Close the IAB and show an error.
|
|
|
|
CoreUtils.closeInAppBrowser();
|
2022-01-19 10:53:22 +00:00
|
|
|
CoreDomUtils.showErrorModal(Translate.instant('core.login.contactyouradministratorissue', {
|
|
|
|
$a: '<br><br>' + Translate.instant('core.errorurlschemeinvalidscheme', {
|
|
|
|
$a: urlScheme,
|
|
|
|
}),
|
2022-01-18 11:51:28 +00:00
|
|
|
}));
|
|
|
|
|
2021-10-15 10:10:29 +00:00
|
|
|
} else if (CoreApp.isAndroid()) {
|
2021-03-09 08:29:09 +00:00
|
|
|
// Check if the URL has a custom URL scheme. In Android they need to be opened manually.
|
2022-01-18 11:51:28 +00:00
|
|
|
if (isExternalApp) {
|
2021-03-09 08:29:09 +00:00
|
|
|
// Open in browser should launch the right app if found and do nothing if not found.
|
2021-10-07 06:58:05 +00:00
|
|
|
CoreUtils.openInBrowser(url, { showBrowserWarning: false });
|
2021-03-09 08:29:09 +00:00
|
|
|
|
|
|
|
// At this point the InAppBrowser is showing a "Webpage not available" error message.
|
|
|
|
// Try to navigate to last loaded URL so this error message isn't found.
|
|
|
|
if (this.lastInAppUrl) {
|
|
|
|
CoreUtils.openInApp(this.lastInAppUrl);
|
|
|
|
} else {
|
|
|
|
// No last URL loaded, close the InAppBrowser.
|
|
|
|
CoreUtils.closeInAppBrowser();
|
|
|
|
}
|
|
|
|
} else {
|
2021-07-28 08:22:22 +00:00
|
|
|
this.lastInAppUrl = protocol ? `${protocol}://${url}` : url;
|
2021-03-09 08:29:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Check InAppBrowser closed.
|
|
|
|
CoreEvents.on(CoreEvents.IAB_EXIT, () => {
|
|
|
|
this.lastInAppUrl = '';
|
2021-06-03 13:47:01 +00:00
|
|
|
|
|
|
|
if (CoreLoginHelper.isWaitingForBrowser()) {
|
2022-04-13 13:38:13 +00:00
|
|
|
CoreLoginHelper.stopWaitingForBrowser();
|
2021-06-03 13:47:01 +00:00
|
|
|
CoreLoginHelper.checkLogout();
|
|
|
|
}
|
2021-03-09 08:29:09 +00:00
|
|
|
});
|
|
|
|
|
2022-06-20 16:19:18 +00:00
|
|
|
CorePlatform.resume.subscribe(() => {
|
2021-03-09 08:29:09 +00:00
|
|
|
// Wait a second before setting it to false since in iOS there could be some frozen WS calls.
|
|
|
|
setTimeout(() => {
|
2021-06-03 13:47:01 +00:00
|
|
|
if (CoreLoginHelper.isWaitingForBrowser()) {
|
2022-04-13 13:38:13 +00:00
|
|
|
CoreLoginHelper.stopWaitingForBrowser();
|
2021-06-03 13:47:01 +00:00
|
|
|
CoreLoginHelper.checkLogout();
|
|
|
|
}
|
2021-03-09 08:29:09 +00:00
|
|
|
}, 1000);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Handle app launched with a certain URL (custom URL scheme).
|
|
|
|
win.handleOpenURL = (url: string): void => {
|
|
|
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
|
|
|
NgZone.run(() => {
|
|
|
|
// First check that the URL hasn't been treated a few seconds ago. Sometimes this function is called more than once.
|
|
|
|
if (this.lastUrls[url] && Date.now() - this.lastUrls[url] < 3000) {
|
|
|
|
// Function called more than once, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!CoreCustomURLSchemes.isCustomURL(url)) {
|
|
|
|
// Not a custom URL, ignore.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.lastUrls[url] = Date.now();
|
|
|
|
|
2021-03-10 14:58:10 +00:00
|
|
|
CoreEvents.trigger(CoreEvents.APP_LAUNCHED_URL, { url });
|
2021-03-09 08:29:09 +00:00
|
|
|
CoreCustomURLSchemes.handleCustomURL(url).catch((error) => {
|
|
|
|
CoreCustomURLSchemes.treatHandleCustomURLError(error);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// "Expose" CoreWindow.open.
|
|
|
|
win.openWindowSafely = (url: string, name?: string): void => {
|
|
|
|
CoreWindow.open(url, name);
|
|
|
|
};
|
|
|
|
|
2021-05-19 08:04:01 +00:00
|
|
|
// Treat URLs that try to override the app.
|
|
|
|
win.onOverrideUrlLoading = (url: string) => {
|
|
|
|
CoreWindow.open(url);
|
|
|
|
};
|
|
|
|
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.LOGIN, async (data) => {
|
2020-11-23 11:29:56 +00:00
|
|
|
if (data.siteId) {
|
2021-03-02 10:41:04 +00:00
|
|
|
const site = await CoreSites.getSite(data.siteId);
|
2020-11-23 11:29:56 +00:00
|
|
|
const info = site.getInfo();
|
|
|
|
if (info) {
|
|
|
|
// Add version classes to body.
|
2021-03-10 10:20:10 +00:00
|
|
|
this.removeVersionClass(MOODLE_VERSION_PREFIX);
|
|
|
|
this.addVersionClass(MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(info.release || ''));
|
2020-11-23 11:29:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.loadCustomStrings();
|
|
|
|
});
|
|
|
|
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.SITE_UPDATED, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
if (data.siteId == CoreSites.getCurrentSiteId()) {
|
2020-11-23 11:29:56 +00:00
|
|
|
this.loadCustomStrings();
|
|
|
|
|
|
|
|
// Add version classes to body.
|
2021-03-10 10:20:10 +00:00
|
|
|
this.removeVersionClass(MOODLE_VERSION_PREFIX);
|
|
|
|
this.addVersionClass(MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(data.release || ''));
|
2020-11-23 11:29:56 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-03-10 11:30:18 +00:00
|
|
|
CoreEvents.on(CoreEvents.SITE_ADDED, (data) => {
|
2021-03-02 10:41:04 +00:00
|
|
|
if (data.siteId == CoreSites.getCurrentSiteId()) {
|
2020-11-23 11:29:56 +00:00
|
|
|
this.loadCustomStrings();
|
|
|
|
|
|
|
|
// Add version classes to body.
|
2021-03-10 10:20:10 +00:00
|
|
|
this.removeVersionClass(MOODLE_VERSION_PREFIX);
|
|
|
|
this.addVersionClass(MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(data.release || ''));
|
2020-11-23 11:29:56 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-11-05 13:37:53 +00:00
|
|
|
this.onPlatformReady();
|
2021-02-25 11:16:23 +00:00
|
|
|
|
2021-05-20 09:54:12 +00:00
|
|
|
// Quit app with back button.
|
|
|
|
document.addEventListener('ionBackButton', (event: BackButtonEvent) => {
|
|
|
|
// This callback should have the lowest priority in the app.
|
|
|
|
event.detail.register(-100, async () => {
|
2021-06-04 10:56:13 +00:00
|
|
|
const initialPath = CoreNavigator.getCurrentPath();
|
|
|
|
if (initialPath.startsWith('/main/')) {
|
|
|
|
// Main menu has its own callback to handle back. If this callback is called it means we should exit app.
|
|
|
|
CoreApp.closeApp();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-20 09:54:12 +00:00
|
|
|
// This callback can be called at the same time as Ionic's back navigation callback.
|
|
|
|
// Check if the path changes due to the back navigation handler, to know if we're at root level.
|
|
|
|
// Ionic doc recommends IonRouterOutlet.canGoBack, but there's no easy way to get the current outlet from here.
|
|
|
|
// The path seems to change immediately (0 ms timeout), but use 50ms just in case.
|
|
|
|
await CoreUtils.wait(50);
|
|
|
|
|
|
|
|
if (CoreNavigator.getCurrentPath() != initialPath) {
|
|
|
|
// Ionic has navigated back, nothing else to do.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Quit the app.
|
2021-06-04 10:56:13 +00:00
|
|
|
CoreApp.closeApp();
|
2021-05-20 09:54:12 +00:00
|
|
|
});
|
|
|
|
});
|
2020-11-05 13:37:53 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 17:41:58 +00:00
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
|
|
|
ngAfterViewInit(): void {
|
|
|
|
if (!this.outlet) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreSubscriptions.once(this.outlet.activateEvents, () => SplashScreen.hide());
|
2021-02-02 17:41:58 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 11:29:56 +00:00
|
|
|
/**
|
|
|
|
* Async init function on platform ready.
|
|
|
|
*/
|
2020-11-05 13:37:53 +00:00
|
|
|
protected async onPlatformReady(): Promise<void> {
|
2022-06-20 16:19:18 +00:00
|
|
|
await CorePlatform.ready();
|
2020-11-05 13:37:53 +00:00
|
|
|
|
|
|
|
// Refresh online status when changes.
|
2022-06-13 10:45:43 +00:00
|
|
|
CoreNetwork.onChange().subscribe(() => {
|
2020-11-05 13:37:53 +00:00
|
|
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
2021-03-02 10:41:04 +00:00
|
|
|
NgZone.run(() => {
|
2022-05-11 12:06:42 +00:00
|
|
|
const isOnline = CoreNetwork.isOnline();
|
2020-11-05 13:37:53 +00:00
|
|
|
const hadOfflineMessage = document.body.classList.contains('core-offline');
|
|
|
|
|
|
|
|
document.body.classList.toggle('core-offline', !isOnline);
|
|
|
|
|
|
|
|
if (isOnline && hadOfflineMessage) {
|
|
|
|
document.body.classList.add('core-online');
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
document.body.classList.remove('core-online');
|
|
|
|
}, 3000);
|
|
|
|
} else if (!isOnline) {
|
|
|
|
document.body.classList.remove('core-online');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2020-11-23 11:30:30 +00:00
|
|
|
|
2022-05-11 12:06:42 +00:00
|
|
|
const isOnline = CoreNetwork.isOnline();
|
2021-11-02 07:57:22 +00:00
|
|
|
document.body.classList.toggle('core-offline', !isOnline);
|
|
|
|
|
2020-11-23 11:30:30 +00:00
|
|
|
// Set StatusBar properties.
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreApp.setStatusBarColor();
|
2020-11-05 13:37:53 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 11:29:56 +00:00
|
|
|
/**
|
|
|
|
* Load custom lang strings. This cannot be done inside the lang provider because it causes circular dependencies.
|
|
|
|
*/
|
|
|
|
protected loadCustomStrings(): void {
|
2021-03-02 10:41:04 +00:00
|
|
|
const currentSite = CoreSites.getCurrentSite();
|
2021-02-02 17:41:58 +00:00
|
|
|
|
2020-11-23 11:29:56 +00:00
|
|
|
if (currentSite) {
|
2021-03-02 10:41:04 +00:00
|
|
|
CoreLang.loadCustomStringsFromSite(currentSite);
|
2020-11-23 11:29:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-05 13:37:53 +00:00
|
|
|
/**
|
|
|
|
* Convenience function to add version to body classes.
|
|
|
|
*
|
2021-03-10 10:20:10 +00:00
|
|
|
* @param prefix Prefix to add to the class.
|
2020-11-05 13:37:53 +00:00
|
|
|
* @param release Current release number of the site.
|
|
|
|
*/
|
2021-03-10 10:20:10 +00:00
|
|
|
protected addVersionClass(prefix: string, release: string): void {
|
2020-11-05 13:37:53 +00:00
|
|
|
const parts = release.split('.', 3);
|
|
|
|
|
|
|
|
parts[1] = parts[1] || '0';
|
|
|
|
parts[2] = parts[2] || '0';
|
|
|
|
|
2020-11-06 08:42:45 +00:00
|
|
|
document.body.classList.add(
|
2021-03-10 10:20:10 +00:00
|
|
|
prefix + parts[0],
|
|
|
|
prefix + parts[0] + '-' + parts[1],
|
|
|
|
prefix + parts[0] + '-' + parts[1] + '-' + parts[2],
|
2020-11-06 08:42:45 +00:00
|
|
|
);
|
2020-11-05 13:37:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience function to remove all version classes form body.
|
2021-03-10 10:20:10 +00:00
|
|
|
*
|
|
|
|
* @param prefix Prefix of to the class.
|
2020-11-05 13:37:53 +00:00
|
|
|
*/
|
2021-03-10 10:20:10 +00:00
|
|
|
protected removeVersionClass(prefix: string): void {
|
2020-11-05 13:37:53 +00:00
|
|
|
const remove: string[] = [];
|
|
|
|
|
|
|
|
Array.from(document.body.classList).forEach((tempClass) => {
|
2021-03-10 10:20:10 +00:00
|
|
|
if (tempClass.substring(0, 8) == prefix) {
|
2020-11-05 13:37:53 +00:00
|
|
|
remove.push(tempClass);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
remove.forEach((tempClass) => {
|
|
|
|
document.body.classList.remove(tempClass);
|
|
|
|
});
|
2020-10-15 09:41:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|