@theia/core
Version:
Theia is a cloud & desktop IDE framework implemented in TypeScript.
227 lines • 8.6 kB
JavaScript
// *****************************************************************************
// Copyright (C) 2018 Red Hat, Inc. and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************
// copied from https://github.com/Microsoft/vscode/blob/bf7ac9201e7a7d01741d4e6e64b5dc9f3197d97b/src/vs/base/common/paths.ts
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* eslint-disable no-void */
/* eslint-disable no-null/no-null */
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isEqualOrParent = exports.getRoot = exports.normalize = exports.extname = exports.basename = exports.nativeSep = exports.sep = void 0;
const os_1 = require("./os");
const strings_1 = require("./strings");
/**
* The forward slash path separator.
*/
exports.sep = '/';
/**
* The native path separator depending on the OS.
*/
exports.nativeSep = os_1.isWindows ? '\\' : '/';
const _posixBadPath = /(\/\.\.?\/)|(\/\.\.?)$|^(\.\.?\/)|(\/\/+)|(\\)/;
const _winBadPath = /(\\\.\.?\\)|(\\\.\.?)$|^(\.\.?\\)|(\\\\+)|(\/)/;
function _isNormal(path, win) {
return win
? !_winBadPath.test(path)
: !_posixBadPath.test(path);
}
/**
* @returns the base name of a path.
*/
function basename(path) {
const idx = ~path.lastIndexOf('/') || ~path.lastIndexOf('\\');
if (idx === 0) {
return path;
}
else if (~idx === path.length - 1) {
return basename(path.substring(0, path.length - 1));
}
else {
return path.substr(~idx + 1);
}
}
exports.basename = basename;
/**
* @returns `.far` from `boo.far` or the empty string.
*/
function extname(path) {
path = basename(path);
const idx = ~path.lastIndexOf('.');
return idx ? path.substring(~idx) : '';
}
exports.extname = extname;
function normalize(path, toOSPath) {
if (path === null || path === void 0) {
return path;
}
const len = path.length;
if (len === 0) {
return '.';
}
const wantsBackslash = os_1.isWindows && toOSPath;
if (_isNormal(path, wantsBackslash)) {
return path;
}
// eslint-disable-next-line @typescript-eslint/no-shadow
const sep = wantsBackslash ? '\\' : '/';
const root = getRoot(path, sep);
// skip the root-portion of the path
let start = root.length;
let skip = false;
let res = '';
for (let end = root.length; end <= len; end++) {
// either at the end or at a path-separator character
if (end === len || path.charCodeAt(end) === 47 /* Slash */ || path.charCodeAt(end) === 92 /* Backslash */) {
if (streql(path, start, end, '..')) {
// skip current and remove parent (if there is already something)
const prev_start = res.lastIndexOf(sep);
const prev_part = res.slice(prev_start + 1);
if ((root || prev_part.length > 0) && prev_part !== '..') {
res = prev_start === -1 ? '' : res.slice(0, prev_start);
skip = true;
}
}
else if (streql(path, start, end, '.') && (root || res || end < len - 1)) {
// skip current (if there is already something or if there is more to come)
skip = true;
}
if (!skip) {
const part = path.slice(start, end);
if (res !== '' && res[res.length - 1] !== sep) {
res += sep;
}
res += part;
}
start = end + 1;
skip = false;
}
}
return root + res;
}
exports.normalize = normalize;
function streql(value, start, end, other) {
return start + other.length === end && value.indexOf(other, start) === start;
}
/**
* Computes the _root_ this path, like `getRoot('c:\files') === c:\`,
* `getRoot('files:///files/path') === files:///`,
* or `getRoot('\\server\shares\path') === \\server\shares\`
*/
// eslint-disable-next-line @typescript-eslint/no-shadow
function getRoot(path, sep = '/') {
if (!path) {
return '';
}
const len = path.length;
let code = path.charCodeAt(0);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
code = path.charCodeAt(1);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
// UNC candidate \\localhost\shares\ddd
// ^^^^^^^^^^^^^^^^^^^
code = path.charCodeAt(2);
if (code !== 47 /* Slash */ && code !== 92 /* Backslash */) {
// eslint-disable-next-line @typescript-eslint/no-shadow
let pos = 3;
const start = pos;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
break;
}
}
code = path.charCodeAt(pos + 1);
if (start !== pos && code !== 47 /* Slash */ && code !== 92 /* Backslash */) {
pos += 1;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
return path.slice(0, pos + 1) // consume this separator
.replace(/[\\/]/g, sep);
}
}
}
}
}
// /user/far
// ^
return sep;
}
else if ((code >= 65 /* A */ && code <= 90 /* Z */) || (code >= 97 /* a */ && code <= 122 /* z */)) {
// check for windows drive letter c:\ or c:
if (path.charCodeAt(1) === 58 /* Colon */) {
code = path.charCodeAt(2);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
// C:\fff
// ^^^
return path.slice(0, 2) + sep;
}
else {
// C:
// ^^
return path.slice(0, 2);
}
}
}
// check for URI
// scheme://authority/path
// ^^^^^^^^^^^^^^^^^^^
let pos = path.indexOf('://');
if (pos !== -1) {
pos += 3; // 3 -> "://".length
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === 47 /* Slash */ || code === 92 /* Backslash */) {
return path.slice(0, pos + 1); // consume this separator
}
}
}
return '';
}
exports.getRoot = getRoot;
function isEqualOrParent(path, candidate, ignoreCase) {
if (path === candidate) {
return true;
}
if (!path || !candidate) {
return false;
}
if (candidate.length > path.length) {
return false;
}
if (ignoreCase) {
const beginsWith = (0, strings_1.startsWithIgnoreCase)(path, candidate);
if (!beginsWith) {
return false;
}
if (candidate.length === path.length) {
return true; // same path, different casing
}
let sepOffset = candidate.length;
if (candidate.charAt(candidate.length - 1) === exports.nativeSep) {
sepOffset--; // adjust the expected sep offset in case our candidate already ends in separator character
}
return path.charAt(sepOffset) === exports.nativeSep;
}
if (candidate.charAt(candidate.length - 1) !== exports.nativeSep) {
candidate += exports.nativeSep;
}
return path.indexOf(candidate) === 0;
}
exports.isEqualOrParent = isEqualOrParent;
//# sourceMappingURL=paths.js.map