When using sub-routes like with core-tabs-outlet (e.g. participants), going back to the main menu tab set the main menu route as the current one instead of the sub-route and this caused problems with split view.
121 lines
4.4 KiB
TypeScript
121 lines
4.4 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 { CoreText } from './text';
|
|
|
|
/**
|
|
* Singleton with helper functions for paths.
|
|
*/
|
|
export class CorePath {
|
|
|
|
// Avoid creating singleton instances.
|
|
private constructor() {
|
|
// Nothing to do.
|
|
}
|
|
|
|
/**
|
|
* Calculate a relative path from a folder to another folder.
|
|
*
|
|
* E.g. if initial folder is foo/bar, and final folder is foo/baz/xyz, it will return ../bar/xyz.
|
|
*
|
|
* @param initialFolder The initial folder path.
|
|
* @param finalFolder The final folder. The "root" should be the same as initialFolder.
|
|
* @returns Relative path.
|
|
*/
|
|
static calculateRelativePath(initialFolder: string, finalFolder: string): string {
|
|
initialFolder = CoreText.removeStartingSlash(CoreText.removeEndingSlash(initialFolder));
|
|
finalFolder = CoreText.removeStartingSlash(CoreText.removeEndingSlash(finalFolder));
|
|
|
|
if (initialFolder === finalFolder) {
|
|
return '';
|
|
}
|
|
|
|
const initialFolderSplit = initialFolder === '' ? [] : initialFolder.split('/');
|
|
const finalFolderSplit = finalFolder === '' ? [] : finalFolder.split('/');
|
|
|
|
let firstDiffIndex = initialFolderSplit.length > 0 && finalFolderSplit.length > 0 ?
|
|
initialFolderSplit.findIndex((value, index) => value !== finalFolderSplit[index]) :
|
|
0;
|
|
|
|
if (firstDiffIndex === -1) {
|
|
// All elements in initial folder are equal. The first diff is the first element in the final folder.
|
|
firstDiffIndex = initialFolderSplit.length;
|
|
}
|
|
|
|
const newPathToFinalFolder = finalFolderSplit.slice(firstDiffIndex).join('/');
|
|
|
|
return '../'.repeat(initialFolderSplit.length - firstDiffIndex) + newPathToFinalFolder;
|
|
}
|
|
|
|
/**
|
|
* Convert a relative path (based on a certain folder) to a relative path based on a different folder.
|
|
*
|
|
* E.g. if current folder is foo/bar, relative URL is test.jpg and new folder is foo/baz,
|
|
* it will return ../bar/test.jpg.
|
|
*
|
|
* @param currentFolder The current folder path.
|
|
* @param path The relative path.
|
|
* @param newFolder The folder to use to calculate the new relative path. The "root" should be the same as currentFolder.
|
|
* @returns Relative path.
|
|
*/
|
|
static changeRelativePath(currentFolder: string, path: string, newFolder: string): string {
|
|
return CorePath.concatenatePaths(CorePath.calculateRelativePath(newFolder, currentFolder), path);
|
|
}
|
|
|
|
/**
|
|
* Concatenate two paths, adding a slash between them if needed.
|
|
*
|
|
* @param leftPath Left path.
|
|
* @param rightPath Right path.
|
|
* @returns Concatenated path.
|
|
*/
|
|
static concatenatePaths(leftPath: string, rightPath: string): string {
|
|
if (!leftPath) {
|
|
return rightPath;
|
|
} else if (!rightPath) {
|
|
return leftPath;
|
|
}
|
|
|
|
const lastCharLeft = leftPath.slice(-1);
|
|
const firstCharRight = rightPath.charAt(0);
|
|
|
|
if (lastCharLeft === '/' && firstCharRight === '/') {
|
|
return leftPath + rightPath.substring(1);
|
|
} else if (lastCharLeft !== '/' && firstCharRight !== '/') {
|
|
return leftPath + '/' + rightPath;
|
|
} else {
|
|
return leftPath + rightPath;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a certain path is the ancestor of another path.
|
|
*
|
|
* @param ancestorPath Ancestor path.
|
|
* @param path Path to check.
|
|
* @returns Whether the path is an ancestor of the other path.
|
|
*/
|
|
static pathIsAncestor(ancestorPath: string, path: string): boolean {
|
|
const ancestorSplit = CoreText.removeEndingSlash(ancestorPath).split('/');
|
|
const pathSplit = CoreText.removeEndingSlash(path).split('/');
|
|
|
|
if (ancestorSplit.length >= pathSplit.length) {
|
|
return false;
|
|
}
|
|
|
|
return !ancestorSplit.some((value, index) => value !== pathSplit[index]);
|
|
}
|
|
|
|
}
|