mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 27ada910e121e23a6d95ecca9cae595fb98ab568
This commit is contained in:
@@ -209,7 +209,10 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
'iframe': ['allowfullscreen', 'frameborder', 'src'],
|
||||
'img': ['src', 'title', 'alt', 'width', 'height'],
|
||||
'div': ['class', 'data-code'],
|
||||
'span': ['class']
|
||||
'span': ['class'],
|
||||
// https://github.com/microsoft/vscode/issues/95937
|
||||
'th': ['align'],
|
||||
'td': ['align']
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import 'vs/css!./aria';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
|
||||
// Use a max length since we are inserting the whole msg in the DOM and that can cause browsers to freeze for long messages #94233
|
||||
const MAX_MESSAGE_LENGTH = 20000;
|
||||
let ariaContainer: HTMLElement;
|
||||
let alertContainer: HTMLElement;
|
||||
let statusContainer: HTMLElement;
|
||||
@@ -54,6 +56,9 @@ function insertMessage(target: HTMLElement, msg: string): void {
|
||||
}
|
||||
|
||||
dom.clearNode(target);
|
||||
if (msg.length > MAX_MESSAGE_LENGTH) {
|
||||
msg = msg.substr(0, MAX_MESSAGE_LENGTH);
|
||||
}
|
||||
target.textContent = msg;
|
||||
|
||||
// See https://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
|
||||
.monaco-text-button {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
outline-offset: 2px !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-text-button:hover {
|
||||
@@ -21,3 +23,8 @@
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-button > .codicon {
|
||||
margin: 0 0.2em;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,12 @@ import { mixin } from 'vs/base/common/objects';
|
||||
import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType } from 'vs/base/browser/touch';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
|
||||
export interface IButtonOptions extends IButtonStyles {
|
||||
title?: boolean | string;
|
||||
readonly title?: boolean | string;
|
||||
readonly supportCodicons?: boolean;
|
||||
}
|
||||
|
||||
export interface IButtonStyles {
|
||||
@@ -150,7 +153,11 @@ export class Button extends Disposable {
|
||||
if (!DOM.hasClass(this._element, 'monaco-text-button')) {
|
||||
DOM.addClass(this._element, 'monaco-text-button');
|
||||
}
|
||||
this._element.textContent = value;
|
||||
if (this.options.supportCodicons) {
|
||||
this._element.innerHTML = renderCodicons(escape(value));
|
||||
} else {
|
||||
this._element.textContent = value;
|
||||
}
|
||||
this._element.setAttribute('aria-label', value); // {{SQL CARBON EDIT}}
|
||||
if (typeof this.options.title === 'string') {
|
||||
this._element.title = this.options.title;
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
}
|
||||
|
||||
.codicon-animation-spin {
|
||||
animation: codicon-spin 1.5s linear infinite;
|
||||
/* Use steps to throttle FPS to reduce CPU usage */
|
||||
animation: codicon-spin 1.5s steps(30) infinite;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ export interface IListViewOptions<T> {
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly accessibilityProvider?: IListViewAccessibilityProvider<T>;
|
||||
readonly additionalScrollHeight?: number;
|
||||
readonly transformOptimization?: boolean;
|
||||
}
|
||||
|
||||
const DefaultOptions = {
|
||||
@@ -74,7 +75,8 @@ const DefaultOptions = {
|
||||
onDragOver() { return false; },
|
||||
drop() { }
|
||||
},
|
||||
horizontalScrolling: false
|
||||
horizontalScrolling: false,
|
||||
transformOptimization: true
|
||||
};
|
||||
|
||||
export class ElementsDragAndDropData<T, TContext = void> implements IDragAndDropData {
|
||||
@@ -275,7 +277,11 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
this.rowsContainer = document.createElement('div');
|
||||
this.rowsContainer.className = 'monaco-list-rows';
|
||||
this.rowsContainer.style.transform = 'translate3d(0px, 0px, 0px)';
|
||||
|
||||
if (options.transformOptimization) {
|
||||
this.rowsContainer.style.transform = 'translate3d(0px, 0px, 0px)';
|
||||
}
|
||||
|
||||
this.disposables.add(Gesture.addTarget(this.rowsContainer));
|
||||
|
||||
this.scrollableElement = this.disposables.add(new ScrollableElement(this.rowsContainer, {
|
||||
|
||||
@@ -838,6 +838,7 @@ export interface IListOptions<T> {
|
||||
readonly mouseSupport?: boolean;
|
||||
readonly horizontalScrolling?: boolean;
|
||||
readonly additionalScrollHeight?: number;
|
||||
readonly transformOptimization?: boolean;
|
||||
}
|
||||
|
||||
export interface IListStyles {
|
||||
|
||||
@@ -84,7 +84,7 @@ export class Menu extends ActionBar {
|
||||
context: options.context,
|
||||
actionRunner: options.actionRunner,
|
||||
ariaLabel: options.ariaLabel,
|
||||
triggerKeys: { keys: [KeyCode.Enter, ...(isMacintosh ? [KeyCode.Space] : [])], keyDown: true }
|
||||
triggerKeys: { keys: [KeyCode.Enter, ...(isMacintosh || isLinux ? [KeyCode.Space] : [])], keyDown: true }
|
||||
});
|
||||
|
||||
this.menuElement = menuElement;
|
||||
|
||||
@@ -184,13 +184,18 @@ export abstract class Pane extends Disposable implements IView {
|
||||
}
|
||||
|
||||
this._orientation = orientation;
|
||||
|
||||
if (this.header) {
|
||||
this.updateHeader();
|
||||
}
|
||||
}
|
||||
|
||||
render(): void {
|
||||
this.header = $('.pane-header');
|
||||
append(this.element, this.header);
|
||||
this.header.setAttribute('tabindex', '0');
|
||||
this.header.setAttribute('role', 'toolbar');
|
||||
// Use role button so the aria-expanded state gets read https://github.com/microsoft/vscode/issues/95996
|
||||
this.header.setAttribute('role', 'button');
|
||||
this.header.setAttribute('aria-label', this.ariaHeaderLabel);
|
||||
this.renderHeader(this.header);
|
||||
|
||||
|
||||
@@ -61,5 +61,6 @@
|
||||
}
|
||||
|
||||
.monaco-tl-twistie.codicon-tree-item-loading::before {
|
||||
animation: codicon-spin 1.25s linear infinite;
|
||||
/* Use steps to throttle FPS to reduce CPU usage */
|
||||
animation: codicon-spin 1.25s steps(30) infinite;
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ export function anyScore(pattern: string, lowPattern: string, _patternPos: numbe
|
||||
|
||||
//#region --- fuzzyScore ---
|
||||
|
||||
export function createMatches(score: undefined | FuzzyScore, offset = 0): IMatch[] {
|
||||
export function createMatches(score: undefined | FuzzyScore): IMatch[] {
|
||||
if (typeof score === 'undefined') {
|
||||
return [];
|
||||
}
|
||||
@@ -404,10 +404,10 @@ export function createMatches(score: undefined | FuzzyScore, offset = 0): IMatch
|
||||
for (let pos = wordStart; pos < _maxLen; pos++) {
|
||||
if (matches[matches.length - (pos + 1)] === '1') {
|
||||
const last = res[res.length - 1];
|
||||
if (last && last.end === pos + offset) {
|
||||
last.end = pos + offset + 1;
|
||||
if (last && last.end === pos) {
|
||||
last.end = pos + 1;
|
||||
} else {
|
||||
res.push({ start: pos + offset, end: pos + offset + 1 });
|
||||
res.push({ start: pos, end: pos + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { compareAnything } from 'vs/base/common/comparers';
|
||||
import { matchesPrefix, IMatch, matchesCamelCase, isUpper, fuzzyScore, createMatches as createFuzzyMatches } from 'vs/base/common/filters';
|
||||
import { matchesPrefix, IMatch, matchesCamelCase, isUpper, fuzzyScore, createMatches as createFuzzyMatches, matchesStrictPrefix } from 'vs/base/common/filters';
|
||||
import { sep } from 'vs/base/common/path';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
@@ -281,24 +281,24 @@ export type FuzzyScore2 = [number | undefined /* score */, IMatch[]];
|
||||
|
||||
const NO_SCORE2: FuzzyScore2 = [undefined, []];
|
||||
|
||||
export function scoreFuzzy2(target: string, query: IPreparedQuery | IPreparedQueryPiece, patternStart = 0, matchOffset = 0): FuzzyScore2 {
|
||||
export function scoreFuzzy2(target: string, query: IPreparedQuery | IPreparedQueryPiece, patternStart = 0, wordStart = 0): FuzzyScore2 {
|
||||
|
||||
// Score: multiple inputs
|
||||
const preparedQuery = query as IPreparedQuery;
|
||||
if (preparedQuery.values && preparedQuery.values.length > 1) {
|
||||
return doScoreFuzzy2Multiple(target, preparedQuery.values, patternStart, matchOffset);
|
||||
return doScoreFuzzy2Multiple(target, preparedQuery.values, patternStart, wordStart);
|
||||
}
|
||||
|
||||
// Score: single input
|
||||
return doScoreFuzzy2Single(target, query, patternStart, matchOffset);
|
||||
return doScoreFuzzy2Single(target, query, patternStart, wordStart);
|
||||
}
|
||||
|
||||
function doScoreFuzzy2Multiple(target: string, query: IPreparedQueryPiece[], patternStart: number, matchOffset: number): FuzzyScore2 {
|
||||
function doScoreFuzzy2Multiple(target: string, query: IPreparedQueryPiece[], patternStart: number, wordStart: number): FuzzyScore2 {
|
||||
let totalScore = 0;
|
||||
const totalMatches: IMatch[] = [];
|
||||
|
||||
for (const queryPiece of query) {
|
||||
const [score, matches] = doScoreFuzzy2Single(target, queryPiece, patternStart, matchOffset);
|
||||
const [score, matches] = doScoreFuzzy2Single(target, queryPiece, patternStart, wordStart);
|
||||
if (typeof score !== 'number') {
|
||||
// if a single query value does not match, return with
|
||||
// no score entirely, we require all queries to match
|
||||
@@ -314,13 +314,13 @@ function doScoreFuzzy2Multiple(target: string, query: IPreparedQueryPiece[], pat
|
||||
return [totalScore, normalizeMatches(totalMatches)];
|
||||
}
|
||||
|
||||
function doScoreFuzzy2Single(target: string, query: IPreparedQueryPiece, patternStart: number, matchOffset: number): FuzzyScore2 {
|
||||
const score = fuzzyScore(query.original, query.originalLowercase, patternStart, target, target.toLowerCase(), 0, true);
|
||||
function doScoreFuzzy2Single(target: string, query: IPreparedQueryPiece, patternStart: number, wordStart: number): FuzzyScore2 {
|
||||
const score = fuzzyScore(query.original, query.originalLowercase, patternStart, target, target.toLowerCase(), wordStart, true);
|
||||
if (!score) {
|
||||
return NO_SCORE2;
|
||||
}
|
||||
|
||||
return [score[0], createFuzzyMatches(score, matchOffset)];
|
||||
return [score[0], createFuzzyMatches(score)];
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -370,9 +370,10 @@ export interface IItemAccessor<T> {
|
||||
}
|
||||
|
||||
const PATH_IDENTITY_SCORE = 1 << 18;
|
||||
const LABEL_PREFIX_SCORE = 1 << 17;
|
||||
const LABEL_CAMELCASE_SCORE = 1 << 16;
|
||||
const LABEL_SCORE_THRESHOLD = 1 << 15;
|
||||
const LABEL_PREFIX_SCORE_MATCHCASE = 1 << 17;
|
||||
const LABEL_PREFIX_SCORE_IGNORECASE = 1 << 16;
|
||||
const LABEL_CAMELCASE_SCORE = 1 << 15;
|
||||
const LABEL_SCORE_THRESHOLD = 1 << 14;
|
||||
|
||||
export function scoreItemFuzzy<T>(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor<T>, cache: FuzzyScorerCache): IItemScore {
|
||||
if (!item || !query.normalized) {
|
||||
@@ -458,13 +459,14 @@ function doScoreItemFuzzySingle(label: string, description: string | undefined,
|
||||
// Prefer label matches if told so
|
||||
if (preferLabelMatches) {
|
||||
|
||||
// Treat prefix matches on the label second highest
|
||||
const prefixLabelMatch = matchesPrefix(query.normalized, label);
|
||||
if (prefixLabelMatch) {
|
||||
return { score: LABEL_PREFIX_SCORE, labelMatch: prefixLabelMatch };
|
||||
// Treat prefix matches on the label highest
|
||||
const prefixLabelMatchIgnoreCase = matchesPrefix(query.normalized, label);
|
||||
if (prefixLabelMatchIgnoreCase) {
|
||||
const prefixLabelMatchStrictCase = matchesStrictPrefix(query.normalized, label);
|
||||
return { score: prefixLabelMatchStrictCase ? LABEL_PREFIX_SCORE_MATCHCASE : LABEL_PREFIX_SCORE_IGNORECASE, labelMatch: prefixLabelMatchStrictCase || prefixLabelMatchIgnoreCase };
|
||||
}
|
||||
|
||||
// Treat camelcase matches on the label third highest
|
||||
// Treat camelcase matches on the label second highest
|
||||
const camelcaseLabelMatch = matchesCamelCase(query.normalized, label);
|
||||
if (camelcaseLabelMatch) {
|
||||
return { score: LABEL_CAMELCASE_SCORE, labelMatch: camelcaseLabelMatch };
|
||||
@@ -600,10 +602,10 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 2.) prefer label prefix matches
|
||||
if (scoreA === LABEL_PREFIX_SCORE || scoreB === LABEL_PREFIX_SCORE) {
|
||||
// 2.) prefer label prefix matches (match case)
|
||||
if (scoreA === LABEL_PREFIX_SCORE_MATCHCASE || scoreB === LABEL_PREFIX_SCORE_MATCHCASE) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA === LABEL_PREFIX_SCORE ? -1 : 1;
|
||||
return scoreA === LABEL_PREFIX_SCORE_MATCHCASE ? -1 : 1;
|
||||
}
|
||||
|
||||
const labelA = accessor.getItemLabel(itemA) || '';
|
||||
@@ -615,7 +617,22 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 3.) prefer camelcase matches
|
||||
// 3.) prefer label prefix matches (ignore case)
|
||||
if (scoreA === LABEL_PREFIX_SCORE_IGNORECASE || scoreB === LABEL_PREFIX_SCORE_IGNORECASE) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA === LABEL_PREFIX_SCORE_IGNORECASE ? -1 : 1;
|
||||
}
|
||||
|
||||
const labelA = accessor.getItemLabel(itemA) || '';
|
||||
const labelB = accessor.getItemLabel(itemB) || '';
|
||||
|
||||
// prefer shorter names when both match on label prefix
|
||||
if (labelA.length !== labelB.length) {
|
||||
return labelA.length - labelB.length;
|
||||
}
|
||||
}
|
||||
|
||||
// 4.) prefer camelcase matches
|
||||
if (scoreA === LABEL_CAMELCASE_SCORE || scoreB === LABEL_CAMELCASE_SCORE) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA === LABEL_CAMELCASE_SCORE ? -1 : 1;
|
||||
@@ -636,7 +653,7 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 4.) prefer label scores
|
||||
// 5.) prefer label scores
|
||||
if (scoreA > LABEL_SCORE_THRESHOLD || scoreB > LABEL_SCORE_THRESHOLD) {
|
||||
if (scoreB < LABEL_SCORE_THRESHOLD) {
|
||||
return -1;
|
||||
@@ -647,12 +664,12 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 5.) compare by score
|
||||
// 6.) compare by score
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA > scoreB ? -1 : 1;
|
||||
}
|
||||
|
||||
// 6.) prefer matches in label over non-label matches
|
||||
// 7.) prefer matches in label over non-label matches
|
||||
const itemAHasLabelMatches = Array.isArray(itemScoreA.labelMatch) && itemScoreA.labelMatch.length > 0;
|
||||
const itemBHasLabelMatches = Array.isArray(itemScoreB.labelMatch) && itemScoreB.labelMatch.length > 0;
|
||||
if (itemAHasLabelMatches && !itemBHasLabelMatches) {
|
||||
@@ -661,14 +678,14 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 7.) scores are identical, prefer more compact matches (label and description)
|
||||
// 8.) scores are identical, prefer more compact matches (label and description)
|
||||
const itemAMatchDistance = computeLabelAndDescriptionMatchDistance(itemA, itemScoreA, accessor);
|
||||
const itemBMatchDistance = computeLabelAndDescriptionMatchDistance(itemB, itemScoreB, accessor);
|
||||
if (itemAMatchDistance && itemBMatchDistance && itemAMatchDistance !== itemBMatchDistance) {
|
||||
return itemBMatchDistance > itemAMatchDistance ? -1 : 1;
|
||||
}
|
||||
|
||||
// 7.) at this point, scores are identical and match compactness as well
|
||||
// 9.) at this point, scores are identical and match compactness as well
|
||||
// for both items so we start to use the fallback compare
|
||||
return fallbackCompare(itemA, itemB, query, accessor);
|
||||
}
|
||||
|
||||
@@ -53,17 +53,18 @@ export interface IJSONSchema {
|
||||
then?: IJSONSchema;
|
||||
else?: IJSONSchema;
|
||||
|
||||
// VSCode extensions
|
||||
defaultSnippets?: IJSONSchemaSnippet[]; // VSCode extension
|
||||
errorMessage?: string; // VSCode extension
|
||||
patternErrorMessage?: string; // VSCode extension
|
||||
deprecationMessage?: string; // VSCode extension
|
||||
enumDescriptions?: string[]; // VSCode extension
|
||||
markdownEnumDescriptions?: string[]; // VSCode extension
|
||||
markdownDescription?: string; // VSCode extension
|
||||
doNotSuggest?: boolean; // VSCode extension
|
||||
allowComments?: boolean; // VSCode extension
|
||||
allowTrailingCommas?: boolean; // VSCode extension
|
||||
// VS Code extensions
|
||||
defaultSnippets?: IJSONSchemaSnippet[];
|
||||
errorMessage?: string;
|
||||
patternErrorMessage?: string;
|
||||
deprecationMessage?: string;
|
||||
markdownDeprecationMessage?: string;
|
||||
enumDescriptions?: string[];
|
||||
markdownEnumDescriptions?: string[];
|
||||
markdownDescription?: string;
|
||||
doNotSuggest?: boolean;
|
||||
allowComments?: boolean;
|
||||
allowTrailingCommas?: boolean;
|
||||
}
|
||||
|
||||
export interface IJSONSchemaMap {
|
||||
|
||||
@@ -853,7 +853,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
}
|
||||
dom.toggleClass(this.ui.container, 'hidden-input', hideInput);
|
||||
const visibilities: Visibilities = {
|
||||
title: !!this.title || !!this.step,
|
||||
title: !!this.title || !!this.step || !!this.buttons.length,
|
||||
description: !!this.description,
|
||||
checkAll: this.canSelectMany,
|
||||
inputBox: !hideInput,
|
||||
@@ -1048,7 +1048,12 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
this.ui.setVisibilities({ title: !!this.title || !!this.step, description: !!this.description || !!this.step, inputBox: true, message: true });
|
||||
const visibilities: Visibilities = {
|
||||
title: !!this.title || !!this.step || !!this.buttons.length,
|
||||
description: !!this.description || !!this.step,
|
||||
inputBox: true, message: true
|
||||
};
|
||||
this.ui.setVisibilities(visibilities);
|
||||
super.update();
|
||||
if (this.ui.inputBox.value !== this.value) {
|
||||
this.ui.inputBox.value = this.value;
|
||||
|
||||
@@ -912,6 +912,19 @@ suite('Fuzzy Scorer', () => {
|
||||
assert.equal(res[0], resourceB);
|
||||
});
|
||||
|
||||
test('compareFilesByScore - prefer case match (bug #96122)', function () {
|
||||
const resourceA = URI.file('lists.php');
|
||||
const resourceB = URI.file('lib/Lists.php');
|
||||
|
||||
let query = 'Lists.php';
|
||||
|
||||
let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
|
||||
assert.equal(res[0], resourceB);
|
||||
|
||||
res = [resourceB, resourceA].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
|
||||
assert.equal(res[0], resourceB);
|
||||
});
|
||||
|
||||
test('prepareQuery', () => {
|
||||
assert.equal(scorer.prepareQuery(' f*a ').normalized, 'fa');
|
||||
assert.equal(scorer.prepareQuery('model Tester.ts').original, 'model Tester.ts');
|
||||
@@ -977,14 +990,14 @@ suite('Fuzzy Scorer', () => {
|
||||
const target = 'HeLlo-World';
|
||||
|
||||
for (const offset of [0, 3]) {
|
||||
let [score, matches] = _doScore2(target, 'HeLlo-World', offset);
|
||||
let [score, matches] = _doScore2(offset === 0 ? target : `123${target}`, 'HeLlo-World', offset);
|
||||
|
||||
assert.ok(score);
|
||||
assert.equal(matches.length, 1);
|
||||
assert.equal(matches[0].start, 0 + offset);
|
||||
assert.equal(matches[0].end, target.length + offset);
|
||||
|
||||
[score, matches] = _doScore2(target, 'HW', offset);
|
||||
[score, matches] = _doScore2(offset === 0 ? target : `123${target}`, 'HW', offset);
|
||||
|
||||
assert.ok(score);
|
||||
assert.equal(matches.length, 2);
|
||||
|
||||
Reference in New Issue
Block a user