forked from EVOgeek/Vmeda.Online
202 lines
6.7 KiB
TypeScript
202 lines
6.7 KiB
TypeScript
// (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.
|
|
|
|
import { CoreSiteInfo, CoreSiteInfoResponse } from '@classes/sites/unauthenticated-site';
|
|
import { CoreSites } from '@services/sites';
|
|
import { CoreUrl } from './url';
|
|
import { CoreConstants } from '../constants';
|
|
import { ScrollDetail } from '@ionic/angular';
|
|
import { CoreDom } from './dom';
|
|
|
|
/**
|
|
* Singleton with helper functions to manage HTML classes.
|
|
*/
|
|
export class CoreHTMLClasses {
|
|
|
|
protected static readonly MOODLE_SITE_URL_PREFIX = 'url-';
|
|
protected static readonly MOODLE_VERSION_PREFIX = 'version-';
|
|
protected static readonly MOODLEAPP_VERSION_PREFIX = 'moodleapp-';
|
|
protected static readonly MOODLE_SITE_THEME_PREFIX = 'theme-site-';
|
|
|
|
/**
|
|
* Initialize HTML classes.
|
|
*/
|
|
static initialize(): void {
|
|
CoreHTMLClasses.toggleModeClass('ionic8', true);
|
|
CoreHTMLClasses.toggleModeClass('development', CoreConstants.BUILD.isDevelopment);
|
|
CoreHTMLClasses.addVersionClass(
|
|
CoreHTMLClasses.MOODLEAPP_VERSION_PREFIX,
|
|
CoreConstants.CONFIG.versionname.replace('-dev', ''),
|
|
);
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const win = <any> window;
|
|
|
|
// Listen to scroll to add style when scroll is not 0.
|
|
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));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convenience function to add version to html classes.
|
|
*
|
|
* @param prefix Prefix to add to the class.
|
|
* @param release Current release number of the site.
|
|
*/
|
|
static addVersionClass(prefix: string, release: string): void {
|
|
const parts = release.split('.', 3);
|
|
|
|
parts[1] = parts[1] || '0';
|
|
parts[2] = parts[2] || '0';
|
|
|
|
CoreHTMLClasses.toggleModeClass(prefix + parts[0], true);
|
|
CoreHTMLClasses.toggleModeClass(prefix + parts[0] + '-' + parts[1], true);
|
|
CoreHTMLClasses.toggleModeClass(prefix + parts[0] + '-' + parts[1] + '-' + parts[2], true);
|
|
}
|
|
|
|
/**
|
|
* Convenience function to remove all mode classes form body.
|
|
*
|
|
* @param prefixes Prefixes of the class mode to be removed.
|
|
*/
|
|
protected static removeModeClasses(prefixes: string[]): void {
|
|
for (const modeClass of CoreHTMLClasses.getModeClasses()) {
|
|
if (!prefixes.some((prefix) => modeClass.startsWith(prefix))) {
|
|
continue;
|
|
}
|
|
|
|
CoreHTMLClasses.toggleModeClass(modeClass, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convenience function to add site classes to html.
|
|
*
|
|
* @param siteInfo Site Info.
|
|
*/
|
|
static addSiteClasses(siteInfo: CoreSiteInfo | CoreSiteInfoResponse): void {
|
|
// Add version classes to html tag.
|
|
this.removeSiteClasses();
|
|
|
|
this.addVersionClass(CoreHTMLClasses.MOODLE_VERSION_PREFIX, CoreSites.getReleaseNumber(siteInfo.release || ''));
|
|
this.addSiteUrlClass(siteInfo.siteurl);
|
|
|
|
if (siteInfo.theme) {
|
|
CoreHTMLClasses.toggleModeClass(CoreHTMLClasses.MOODLE_SITE_THEME_PREFIX + siteInfo.theme, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convenience function to remove all site mode classes form html.
|
|
*/
|
|
static removeSiteClasses(): void {
|
|
// Remove version classes from html tag.
|
|
this.removeModeClasses(
|
|
[
|
|
CoreHTMLClasses.MOODLE_VERSION_PREFIX,
|
|
CoreHTMLClasses.MOODLE_SITE_URL_PREFIX,
|
|
CoreHTMLClasses.MOODLE_SITE_THEME_PREFIX,
|
|
],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Converts the provided URL into a CSS class that be used within the page.
|
|
* This is primarily used to add the siteurl to the body tag as a CSS class.
|
|
* Extracted from LMS url_to_class_name function.
|
|
*
|
|
* @param url Url.
|
|
* @returns Class name
|
|
*/
|
|
protected static urlToClassName(url: string): string {
|
|
const parsedUrl = CoreUrl.parse(url);
|
|
|
|
if (!parsedUrl) {
|
|
return '';
|
|
}
|
|
|
|
let className = parsedUrl.domain?.replace(/\./g, '-') || '';
|
|
|
|
if (parsedUrl.port) {
|
|
className += `--${parsedUrl.port}`;
|
|
}
|
|
if (parsedUrl.path) {
|
|
const leading = new RegExp('^/+');
|
|
const trailing = new RegExp('/+$');
|
|
const path = parsedUrl.path.replace(leading, '').replace(trailing, '');
|
|
if (path) {
|
|
className += '--' + path.replace(/\//g, '-') || '';
|
|
}
|
|
}
|
|
|
|
return className;
|
|
}
|
|
|
|
/**
|
|
* Convenience function to add site url to html classes.
|
|
*/
|
|
static addSiteUrlClass(siteUrl: string): void {
|
|
const className = this.urlToClassName(siteUrl);
|
|
|
|
CoreHTMLClasses.toggleModeClass(CoreHTMLClasses.MOODLE_SITE_URL_PREFIX + className, true);
|
|
}
|
|
|
|
/**
|
|
* Check whether a CSS class indicating an app mode is set.
|
|
*
|
|
* @param className Class name.
|
|
* @returns Whether the CSS class is set.
|
|
*/
|
|
static hasModeClass(className: string): boolean {
|
|
return document.documentElement.classList.contains(className);
|
|
}
|
|
|
|
/**
|
|
* Get active mode CSS classes.
|
|
*
|
|
* @returns Mode classes.
|
|
*/
|
|
static getModeClasses(): string[] {
|
|
return Array.from(document.documentElement.classList);
|
|
}
|
|
|
|
/**
|
|
* Toggle a CSS class in the root element used to indicate app modes.
|
|
*
|
|
* @param className Class name.
|
|
* @param enable Whether to add or remove the class.
|
|
*/
|
|
static toggleModeClass(
|
|
className: string,
|
|
enable = false,
|
|
): void {
|
|
document.documentElement.classList.toggle(className, enable);
|
|
}
|
|
|
|
}
|