mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-05 01:25:38 -05:00
Merge from vscode 8df646d3c5477b02737fc10343fa7cf0cc3f606b
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "codicon";
|
||||
src: url("./codicon.ttf?fb4c14f317e1decb0289895ecc9356f0") format("truetype");
|
||||
src: url("./codicon.ttf?3d9ee7d873425ff0bc441f48a1de0c54") format("truetype");
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
@@ -420,4 +420,7 @@
|
||||
.codicon-bell-dot:before { content: "\f102" }
|
||||
.codicon-debug-alt-2:before { content: "\f103" }
|
||||
.codicon-debug-alt:before { content: "\f104" }
|
||||
.codicon-run-all:before { content: "\f105" }
|
||||
.codicon-debug-console:before { content: "\f105" }
|
||||
.codicon-library:before { content: "\f106" }
|
||||
.codicon-output:before { content: "\f107" }
|
||||
.codicon-run-all:before { content: "\f108" }
|
||||
|
||||
Binary file not shown.
@@ -275,6 +275,12 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.layout();
|
||||
}
|
||||
|
||||
updateOptions(options: IListViewOptions<T>) {
|
||||
if (options.additionalScrollHeight !== undefined) {
|
||||
this.additionalScrollHeight = options.additionalScrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
triggerScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent) {
|
||||
this.scrollableElement.triggerScrollFromMouseWheelEvent(browserEvent);
|
||||
}
|
||||
|
||||
@@ -854,6 +854,7 @@ export interface IListOptions<T> {
|
||||
readonly mouseSupport?: boolean;
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly ariaProvider?: IAriaProvider<T>;
|
||||
readonly additionalScrollHeight?: number;
|
||||
}
|
||||
|
||||
export interface IListStyles {
|
||||
@@ -1110,6 +1111,7 @@ class ListViewDragAndDrop<T> implements IListViewDragAndDrop<T> {
|
||||
export interface IListOptionsUpdate {
|
||||
readonly enableKeyboardNavigation?: boolean;
|
||||
readonly automaticKeyboardNavigation?: boolean;
|
||||
readonly additionalScrollHeight?: number;
|
||||
}
|
||||
|
||||
export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
@@ -1289,6 +1291,10 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
if (this.typeLabelController) {
|
||||
this.typeLabelController.updateOptions(this._options);
|
||||
}
|
||||
|
||||
if (optionsUpdate.additionalScrollHeight !== undefined) {
|
||||
this.view.updateOptions(optionsUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
get options(): IListOptions<T> {
|
||||
|
||||
@@ -110,7 +110,7 @@ abstract class ViewItem<TLayoutContext> {
|
||||
get snap(): boolean { return !!this.view.snap; }
|
||||
|
||||
set enabled(enabled: boolean) {
|
||||
this.container.style.pointerEvents = enabled ? null : 'none';
|
||||
this.container.style.pointerEvents = enabled ? '' : 'none';
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -791,7 +791,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
|
||||
this.refreshPromises.set(node, result);
|
||||
|
||||
return result.finally(() => this.refreshPromises.delete(node));
|
||||
return result.finally(() => { this.refreshPromises.delete(node); });
|
||||
}
|
||||
|
||||
private _onDidChangeCollapseState({ node, deep }: ICollapseStateChangeEvent<IAsyncDataTreeNode<TInput, T> | null, any>): void {
|
||||
|
||||
@@ -28,11 +28,17 @@ export class HistoryNavigator<T> implements INavigator<T> {
|
||||
}
|
||||
|
||||
public next(): T | null {
|
||||
return this._navigator.next();
|
||||
if (this._currentPosition() !== this._elements.length - 1) {
|
||||
return this._navigator.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public previous(): T | null {
|
||||
return this._navigator.previous();
|
||||
if (this._currentPosition() !== 0) {
|
||||
return this._navigator.previous();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public current(): T | null {
|
||||
@@ -73,6 +79,15 @@ export class HistoryNavigator<T> implements INavigator<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private _currentPosition(): number {
|
||||
const currentElement = this._navigator.current();
|
||||
if (!currentElement) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this._elements.indexOf(currentElement);
|
||||
}
|
||||
|
||||
private _initialize(history: readonly T[]): void {
|
||||
this._history = new Set();
|
||||
for (const entry of history) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as extpath from 'vs/base/common/extpath';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
import { URI, originalFSPath as uriOriginalFSPath } from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isLinux, isWindows } from 'vs/base/common/platform';
|
||||
@@ -13,7 +13,28 @@ import { CharCode } from 'vs/base/common/charCode';
|
||||
import { ParsedExpression, IExpression, parse } from 'vs/base/common/glob';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
|
||||
export const originalFSPath = uriOriginalFSPath;
|
||||
export function originalFSPath(uri: URI): string {
|
||||
let value: string;
|
||||
const uriPath = uri.path;
|
||||
if (uri.authority && uriPath.length > 1 && uri.scheme === 'file') {
|
||||
// unc path: file://shares/c$/far/boo
|
||||
value = `//${uri.authority}${uriPath}`;
|
||||
} else if (
|
||||
isWindows
|
||||
&& uriPath.charCodeAt(0) === CharCode.Slash
|
||||
&& extpath.isWindowsDriveLetter(uriPath.charCodeAt(1))
|
||||
&& uriPath.charCodeAt(2) === CharCode.Colon
|
||||
) {
|
||||
value = uriPath.substr(1);
|
||||
} else {
|
||||
// other path
|
||||
value = uriPath;
|
||||
}
|
||||
if (isWindows) {
|
||||
value = value.replace(/\//g, '\\');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a key from a resource URI to be used to resource comparison and for resource maps.
|
||||
@@ -24,7 +45,7 @@ export function getComparisonKey(resource: URI, caseInsensitivePath = hasToIgnor
|
||||
if (caseInsensitivePath) {
|
||||
path = path.toLowerCase();
|
||||
}
|
||||
return `${resource.scheme}://${resource.authority.toLowerCase()}/${path}?${resource.query}`;
|
||||
return resource.with({ authority: resource.authority.toLowerCase(), path: path, fragment: null }).toString();
|
||||
}
|
||||
|
||||
export function hasToIgnoreCase(resource: URI | undefined): boolean {
|
||||
@@ -123,7 +144,15 @@ export function dirname(resource: URI): URI {
|
||||
* @returns The resulting URI.
|
||||
*/
|
||||
export function joinPath(resource: URI, ...pathFragment: string[]): URI {
|
||||
return URI.joinPaths(resource, ...pathFragment);
|
||||
let joinedPath: string;
|
||||
if (resource.scheme === 'file') {
|
||||
joinedPath = URI.file(paths.join(originalFSPath(resource), ...pathFragment)).path;
|
||||
} else {
|
||||
joinedPath = paths.posix.join(resource.path || '/', ...pathFragment);
|
||||
}
|
||||
return resource.with({
|
||||
path: joinedPath
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
import * as extpath from 'vs/base/common/extpath';
|
||||
|
||||
const _schemePattern = /^\w[\w\d+.-]*$/;
|
||||
const _singleSlashStart = /^\//;
|
||||
@@ -206,7 +205,7 @@ export class URI implements UriComponents {
|
||||
// if (this.scheme !== 'file') {
|
||||
// console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
|
||||
// }
|
||||
return _makeFsPath(this);
|
||||
return _makeFsPath(this, false);
|
||||
}
|
||||
|
||||
// ---- modify to new -------------------------
|
||||
@@ -340,20 +339,21 @@ export class URI implements UriComponents {
|
||||
/**
|
||||
* Join a URI path with path fragments and normalizes the resulting path.
|
||||
*
|
||||
* @param resource The input URI.
|
||||
* @param uri The input URI.
|
||||
* @param pathFragment The path fragment to add to the URI path.
|
||||
* @returns The resulting URI.
|
||||
*/
|
||||
static joinPaths(resource: URI, ...pathFragment: string[]): URI {
|
||||
let joinedPath: string;
|
||||
if (resource.scheme === 'file') {
|
||||
joinedPath = URI.file(paths.join(originalFSPath(resource), ...pathFragment)).path;
|
||||
} else {
|
||||
joinedPath = paths.posix.join(resource.path || '/', ...pathFragment);
|
||||
static joinPath(uri: URI, ...pathFragment: string[]): URI {
|
||||
if (!uri.path) {
|
||||
throw new Error(`[UriError]: cannot call joinPaths on URI without path`);
|
||||
}
|
||||
return resource.with({
|
||||
path: joinedPath
|
||||
});
|
||||
let newPath: string;
|
||||
if (isWindows && uri.scheme === 'file') {
|
||||
newPath = URI.file(paths.win32.join(_makeFsPath(uri, true), ...pathFragment)).path;
|
||||
} else {
|
||||
newPath = paths.posix.join(uri.path, ...pathFragment);
|
||||
}
|
||||
return uri.with({ path: newPath });
|
||||
}
|
||||
|
||||
// ---- printing/externalize ---------------------------
|
||||
@@ -421,7 +421,7 @@ class _URI extends URI {
|
||||
|
||||
get fsPath(): string {
|
||||
if (!this._fsPath) {
|
||||
this._fsPath = _makeFsPath(this);
|
||||
this._fsPath = _makeFsPath(this, false);
|
||||
}
|
||||
return this._fsPath;
|
||||
}
|
||||
@@ -577,7 +577,7 @@ function encodeURIComponentMinimal(path: string): string {
|
||||
/**
|
||||
* Compute `fsPath` for the given uri
|
||||
*/
|
||||
function _makeFsPath(uri: URI): string {
|
||||
function _makeFsPath(uri: URI, keepDriveLetterCasing: boolean): string {
|
||||
|
||||
let value: string;
|
||||
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
|
||||
@@ -589,7 +589,11 @@ function _makeFsPath(uri: URI): string {
|
||||
&& uri.path.charCodeAt(2) === CharCode.Colon
|
||||
) {
|
||||
// windows drive letter: file:///c:/far/boo
|
||||
value = uri.path[1].toLowerCase() + uri.path.substr(2);
|
||||
if (!keepDriveLetterCasing) {
|
||||
value = uri.path[1].toLowerCase() + uri.path.substr(2);
|
||||
} else {
|
||||
value = uri.path.substr(1, 2);
|
||||
}
|
||||
} else {
|
||||
// other path
|
||||
value = uri.path;
|
||||
@@ -695,29 +699,3 @@ function percentDecode(str: string): string {
|
||||
}
|
||||
return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));
|
||||
}
|
||||
|
||||
|
||||
// --- utils
|
||||
|
||||
export function originalFSPath(uri: URI): string {
|
||||
let value: string;
|
||||
const uriPath = uri.path;
|
||||
if (uri.authority && uriPath.length > 1 && uri.scheme === 'file') {
|
||||
// unc path: file://shares/c$/far/boo
|
||||
value = `//${uri.authority}${uriPath}`;
|
||||
} else if (
|
||||
isWindows
|
||||
&& uriPath.charCodeAt(0) === CharCode.Slash
|
||||
&& extpath.isWindowsDriveLetter(uriPath.charCodeAt(1))
|
||||
&& uriPath.charCodeAt(2) === CharCode.Colon
|
||||
) {
|
||||
value = uriPath.substr(1);
|
||||
} else {
|
||||
// other path
|
||||
value = uriPath;
|
||||
}
|
||||
if (isWindows) {
|
||||
value = value.replace(/\//g, '\\');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@ export class ChannelClient implements IChannelClient, IDisposable {
|
||||
this.activeRequests.add(disposable);
|
||||
});
|
||||
|
||||
return result.finally(() => this.activeRequests.delete(disposable));
|
||||
return result.finally(() => { this.activeRequests.delete(disposable); });
|
||||
}
|
||||
|
||||
private requestEvent(channelName: string, name: string, arg?: any): Event<any> {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/quickInput';
|
||||
import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods, IQuickPickAcceptEvent, NO_KEY_MODS } from 'vs/base/parts/quickinput/common/quickInput';
|
||||
import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods, IQuickPickAcceptEvent, NO_KEY_MODS, ItemActivation } from 'vs/base/parts/quickinput/common/quickInput';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { QuickInputList, QuickInputListFocus } from './quickInputList';
|
||||
@@ -20,11 +20,9 @@ import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { equals } from 'vs/base/common/arrays';
|
||||
import { TimeoutTimer } from 'vs/base/common/async';
|
||||
import { getIconClass } from 'vs/base/parts/quickinput/browser/quickInputUtils';
|
||||
import { registerAndGetAmdImageURL } from 'vs/base/common/amd';
|
||||
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { List, IListOptions, IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IInputBoxStyles } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
@@ -70,10 +68,7 @@ const $ = dom.$;
|
||||
type Writeable<T> = { -readonly [P in keyof T]: T[P] };
|
||||
|
||||
const backButton = {
|
||||
iconPath: {
|
||||
dark: URI.parse(registerAndGetAmdImageURL('vs/base/parts/quickinput/browser/media/arrow-left-dark.svg')),
|
||||
light: URI.parse(registerAndGetAmdImageURL('vs/base/parts/quickinput/browser/media/arrow-left-light.svg'))
|
||||
},
|
||||
iconClass: 'codicon-arrow-left',
|
||||
tooltip: localize('quickInput.back', "Back"),
|
||||
handle: -1 // TODO
|
||||
};
|
||||
@@ -391,7 +386,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
private _matchOnLabel = true;
|
||||
private _sortByLabel = true;
|
||||
private _autoFocusOnList = true;
|
||||
private _autoFocusSecondEntry = false;
|
||||
private _itemActivation = ItemActivation.FIRST;
|
||||
private _activeItems: T[] = [];
|
||||
private activeItemsUpdated = false;
|
||||
private activeItemsToConfirm: T[] | null = [];
|
||||
@@ -527,12 +522,12 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
this.update();
|
||||
}
|
||||
|
||||
get autoFocusSecondEntry() {
|
||||
return this._autoFocusSecondEntry;
|
||||
get itemActivation() {
|
||||
return this._itemActivation;
|
||||
}
|
||||
|
||||
set autoFocusSecondEntry(autoFocusSecondEntry: boolean) {
|
||||
this._autoFocusSecondEntry = autoFocusSecondEntry;
|
||||
set itemActivation(itemActivation: ItemActivation) {
|
||||
this._itemActivation = itemActivation;
|
||||
}
|
||||
|
||||
get activeItems() {
|
||||
@@ -879,11 +874,18 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
this.ui.checkAll.checked = this.ui.list.getAllVisibleChecked();
|
||||
this.ui.visibleCount.setCount(this.ui.list.getVisibleCount());
|
||||
this.ui.count.setCount(this.ui.list.getCheckedCount());
|
||||
if (this._autoFocusSecondEntry) {
|
||||
this.ui.list.focus(QuickInputListFocus.Second);
|
||||
this._autoFocusSecondEntry = false; // only valid once, then unset
|
||||
} else {
|
||||
this.trySelectFirst();
|
||||
switch (this._itemActivation) {
|
||||
case ItemActivation.SECOND:
|
||||
this.ui.list.focus(QuickInputListFocus.Second);
|
||||
this._itemActivation = ItemActivation.FIRST; // only valid once, then unset
|
||||
break;
|
||||
case ItemActivation.LAST:
|
||||
this.ui.list.focus(QuickInputListFocus.Last);
|
||||
this._itemActivation = ItemActivation.FIRST; // only valid once, then unset
|
||||
break;
|
||||
default:
|
||||
this.trySelectFirst();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.ui.container.classList.contains('show-checkboxes') !== !!this.canSelectMany) {
|
||||
|
||||
@@ -496,7 +496,7 @@ export class QuickInputList {
|
||||
}
|
||||
|
||||
set enabled(value: boolean) {
|
||||
this.list.getHTMLElement().style.pointerEvents = value ? null : 'none';
|
||||
this.list.getHTMLElement().style.pointerEvents = value ? '' : 'none';
|
||||
}
|
||||
|
||||
focus(what: QuickInputListFocus): void {
|
||||
|
||||
@@ -182,6 +182,12 @@ export interface IQuickPickAcceptEvent {
|
||||
inBackground: boolean;
|
||||
}
|
||||
|
||||
export enum ItemActivation {
|
||||
FIRST = 1,
|
||||
SECOND,
|
||||
LAST
|
||||
}
|
||||
|
||||
export interface IQuickPick<T extends IQuickPickItem> extends IQuickInput {
|
||||
|
||||
value: string;
|
||||
@@ -237,20 +243,17 @@ export interface IQuickPick<T extends IQuickPickItem> extends IQuickInput {
|
||||
|
||||
autoFocusOnList: boolean;
|
||||
|
||||
/**
|
||||
* If enabled, will try to select the second entry of the picks
|
||||
* once they appear instead of the first one. This is useful
|
||||
* e.g. when `quickNavigate` is enabled to be able to select
|
||||
* a previous entry by just releasing the quick nav keys.
|
||||
*/
|
||||
autoFocusSecondEntry: boolean;
|
||||
|
||||
quickNavigate: IQuickNavigateConfiguration | undefined;
|
||||
|
||||
activeItems: ReadonlyArray<T>;
|
||||
|
||||
readonly onDidChangeActive: Event<T[]>;
|
||||
|
||||
/**
|
||||
* Allows to control which entry should be activated by default.
|
||||
*/
|
||||
itemActivation: ItemActivation;
|
||||
|
||||
selectedItems: ReadonlyArray<T>;
|
||||
|
||||
readonly onDidChangeSelection: Event<T[]>;
|
||||
|
||||
@@ -106,6 +106,40 @@ suite('History Navigator', () => {
|
||||
assert.deepEqual(['2', '3', '1'], toArray(testObject));
|
||||
});
|
||||
|
||||
test('previous returns null if the current position is the first one', () => {
|
||||
const testObject = new HistoryNavigator(['1', '2', '3']);
|
||||
|
||||
testObject.first();
|
||||
|
||||
assert.deepEqual(testObject.previous(), null);
|
||||
});
|
||||
|
||||
test('previous returns object if the current position is not the first one', () => {
|
||||
const testObject = new HistoryNavigator(['1', '2', '3']);
|
||||
|
||||
testObject.first();
|
||||
testObject.next();
|
||||
|
||||
assert.deepEqual(testObject.previous(), '1');
|
||||
});
|
||||
|
||||
test('next returns null if the current position is the last one', () => {
|
||||
const testObject = new HistoryNavigator(['1', '2', '3']);
|
||||
|
||||
testObject.last();
|
||||
|
||||
assert.deepEqual(testObject.next(), null);
|
||||
});
|
||||
|
||||
test('next returns object if the current position is not the last one', () => {
|
||||
const testObject = new HistoryNavigator(['1', '2', '3']);
|
||||
|
||||
testObject.last();
|
||||
testObject.previous();
|
||||
|
||||
assert.deepEqual(testObject.next(), '3');
|
||||
});
|
||||
|
||||
test('clear', () => {
|
||||
const testObject = new HistoryNavigator(['a', 'b', 'c']);
|
||||
assert.equal(testObject.previous(), 'c');
|
||||
|
||||
@@ -503,4 +503,65 @@ suite('URI', () => {
|
||||
// }
|
||||
// console.profileEnd();
|
||||
});
|
||||
function assertJoined(base: string, fragment: string, expected: string, checkWithUrl: boolean = true) {
|
||||
const baseUri = URI.parse(base);
|
||||
const newUri = URI.joinPath(baseUri, fragment);
|
||||
const actual = newUri.toString(true);
|
||||
assert.equal(actual, expected);
|
||||
|
||||
if (checkWithUrl) {
|
||||
const actualUrl = new URL(fragment, base).href;
|
||||
assert.equal(actualUrl, expected, 'DIFFERENT from URL');
|
||||
}
|
||||
}
|
||||
test('URI#joinPath', function () {
|
||||
|
||||
assertJoined(('file:///foo/'), '../../bazz', 'file:///bazz');
|
||||
assertJoined(('file:///foo'), '../../bazz', 'file:///bazz');
|
||||
assertJoined(('file:///foo'), '../../bazz', 'file:///bazz');
|
||||
assertJoined(('file:///foo/bar/'), './bazz', 'file:///foo/bar/bazz');
|
||||
assertJoined(('file:///foo/bar'), './bazz', 'file:///foo/bar/bazz', false);
|
||||
assertJoined(('file:///foo/bar'), 'bazz', 'file:///foo/bar/bazz', false);
|
||||
|
||||
// "auto-path" scheme
|
||||
assertJoined(('file:'), 'bazz', 'file:///bazz');
|
||||
assertJoined(('http://domain'), 'bazz', 'http://domain/bazz');
|
||||
assertJoined(('https://domain'), 'bazz', 'https://domain/bazz');
|
||||
assertJoined(('http:'), 'bazz', 'http:/bazz', false);
|
||||
assertJoined(('https:'), 'bazz', 'https:/bazz', false);
|
||||
|
||||
// no "auto-path" scheme with and w/o paths
|
||||
assertJoined(('foo:/'), 'bazz', 'foo:/bazz');
|
||||
assertJoined(('foo://bar/'), 'bazz', 'foo://bar/bazz');
|
||||
|
||||
// no "auto-path" + no path -> error
|
||||
assert.throws(() => assertJoined(('foo:'), 'bazz', ''));
|
||||
assert.throws(() => new URL('bazz', 'foo:'));
|
||||
assert.throws(() => assertJoined(('foo://bar'), 'bazz', ''));
|
||||
assert.throws(() => new URL('bazz', 'foo://bar'));
|
||||
});
|
||||
|
||||
test('URI#joinPath (posix)', function () {
|
||||
if (isWindows) {
|
||||
this.skip();
|
||||
}
|
||||
assertJoined(('file:///c:/foo/'), '../../bazz', 'file:///bazz', false);
|
||||
assertJoined(('file://server/share/c:/'), '../../bazz', 'file://server/bazz', false);
|
||||
assertJoined(('file://server/share/c:'), '../../bazz', 'file://server/bazz', false);
|
||||
|
||||
assertJoined(('file://ser/foo/'), '../../bazz', 'file://ser/bazz');
|
||||
assertJoined(('file://ser/foo'), '../../bazz', 'file://ser/bazz');
|
||||
});
|
||||
|
||||
test('URI#joinPath (windows)', function () {
|
||||
if (!isWindows) {
|
||||
this.skip();
|
||||
}
|
||||
assertJoined(('file:///c:/foo/'), '../../bazz', 'file:///c:/bazz', false);
|
||||
assertJoined(('file://server/share/c:/'), '../../bazz', 'file://server/share/bazz', false);
|
||||
assertJoined(('file://server/share/c:'), '../../bazz', 'file://server/share/bazz', false);
|
||||
|
||||
assertJoined(('file://ser/foo/'), '../../bazz', 'file://ser/foo/bazz', false);
|
||||
assertJoined(('file://ser/foo'), '../../bazz', 'file://ser/foo/bazz', false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user