better regexp, fix offset issue in #4294
This commit is contained in:
@@ -10,8 +10,15 @@ import { ILinkProviderOptions, WebLinkProvider } from './WebLinkProvider';
|
|||||||
// up to first whitespace, `"` or `'` as url
|
// up to first whitespace, `"` or `'` as url
|
||||||
// NOTE: The repeated end clause is needed to not match a dangling `:`
|
// NOTE: The repeated end clause is needed to not match a dangling `:`
|
||||||
// resembling the old (...)*([^:"\'\\s]) final path clause
|
// resembling the old (...)*([^:"\'\\s]) final path clause
|
||||||
// also exclude final interpunction like ,.!?
|
// additionally exclude early + final:
|
||||||
const strictUrlRegex = /https?:[/]{2}[^\s^"^']*[^\s^"^'^:^,^.^!^?]/;
|
// - unsafe from rfc3986: !*'()
|
||||||
|
// - unsafe chars from rfc1738: {}|\^~[]` (minus [] as we need them for ipv6 adresses)
|
||||||
|
// also exclude as finals:
|
||||||
|
// - final interpunction like ,.!?
|
||||||
|
// - any sort of brackets <>()[]{} (not spec conform, but often used to enclose urls)
|
||||||
|
// - unsafe chars from rfc1738: {}|\^~[]`
|
||||||
|
const strictUrlRegex = /https?:[/]{2}[^\s"'!*(){}|\\\^~<>`]*[^\s"':,.!?{}|\\\^~\[\]`()<>]/;
|
||||||
|
|
||||||
|
|
||||||
function handleLink(event: MouseEvent, uri: string): void {
|
function handleLink(event: MouseEvent, uri: string): void {
|
||||||
const newWindow = window.open();
|
const newWindow = window.open();
|
||||||
|
|||||||
+17
-8
@@ -1,25 +1,34 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# all half width - only good case
|
# all half width
|
||||||
echo "aaa http://example.com aaa http://example.com aaa"
|
echo "aaa http://example.com aaa http://example.com aaa"
|
||||||
|
|
||||||
# full width before - wrong offset
|
# full width before
|
||||||
echo "¥¥¥ http://example.com aaa http://example.com aaa"
|
echo "¥¥¥ http://example.com aaa http://example.com aaa"
|
||||||
|
|
||||||
# full width between - wrong offset
|
# full width between
|
||||||
echo "aaa http://example.com ¥¥¥ http://example.com aaa"
|
echo "aaa http://example.com ¥¥¥ http://example.com aaa"
|
||||||
|
|
||||||
# full width before and between - error in offsets adding up
|
# full width before and between
|
||||||
echo "¥¥¥ http://example.com ¥¥¥ http://example.com aaa"
|
echo "¥¥¥ http://example.com ¥¥¥ http://example.com aaa"
|
||||||
|
|
||||||
# full width within url - partial wrong match
|
# full width within url
|
||||||
echo "aaa https://ko.wikipedia.org/wiki/위키백과:대문 aaa https://ko.wikipedia.org/wiki/위키백과:대문 aaa"
|
echo "aaa https://ko.wikipedia.org/wiki/위키백과:대문 aaa https://ko.wikipedia.org/wiki/위키백과:대문 aaa"
|
||||||
|
|
||||||
# full width within and before - partial wrong match + wrong offsets
|
# full width within and before
|
||||||
echo "¥¥¥ https://ko.wikipedia.org/wiki/위키백과:대문 aaa https://ko.wikipedia.org/wiki/위키백과:대문 ¥¥¥"
|
echo "¥¥¥ https://ko.wikipedia.org/wiki/위키백과:대문 aaa https://ko.wikipedia.org/wiki/위키백과:대문 ¥¥¥"
|
||||||
|
|
||||||
# not matching at all
|
# username + password scheme
|
||||||
echo "http://test:password@example.com/some_path aaa"
|
echo "http://test:password@example.com/some_path aaa"
|
||||||
|
|
||||||
# overly long text with urls with final interpunction
|
# overly long text with urls with final interpunction
|
||||||
echo "Lorem ipsum dolor sit amet, consetetur sadipscing elitr https://ko.wikipedia.org/wiki/위키백과:대문, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat: http://test:password@example.com/some_path."
|
echo "Lorem ipsum dolor sit amet, consetetur sadipscing elitr https://ko.wikipedia.org/wiki/위키백과:대문, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat: http://test:password@example.com/some_path."
|
||||||
|
|
||||||
|
# bracket enclosed urls
|
||||||
|
echo "[http://example.de]"
|
||||||
|
echo "(http://example.de)"
|
||||||
|
echo "<http://example.de>"
|
||||||
|
echo "{http://example.de}"
|
||||||
|
|
||||||
|
# ipv6 scheme
|
||||||
|
echo "ipv6 https://[::1]/with/some?vars=and&a#hash"
|
||||||
@@ -38,7 +38,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
private _rowContainer: HTMLElement;
|
private _rowContainer: HTMLElement;
|
||||||
private _rowElements: HTMLElement[] = [];
|
private _rowElements: HTMLElement[] = [];
|
||||||
private _selectionContainer: HTMLElement;
|
private _selectionContainer: HTMLElement;
|
||||||
private _cellToRowElements: Uint16Array[] = [];
|
private _cellToRowElements: Int16Array[] = [];
|
||||||
|
|
||||||
public dimensions: IRenderDimensions;
|
public dimensions: IRenderDimensions;
|
||||||
|
|
||||||
@@ -361,7 +361,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
const lineData = this._bufferService.buffer.lines.get(row);
|
const lineData = this._bufferService.buffer.lines.get(row);
|
||||||
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
||||||
if (!this._cellToRowElements[y] || this._cellToRowElements[y].length !== this._bufferService.cols) {
|
if (!this._cellToRowElements[y] || this._cellToRowElements[y].length !== this._bufferService.cols) {
|
||||||
this._cellToRowElements[y] = new Uint16Array(this._bufferService.cols);
|
this._cellToRowElements[y] = new Int16Array(this._bufferService.cols);
|
||||||
}
|
}
|
||||||
rowElement.replaceChildren(this._rowFactory.createRow(lineData!, row, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.css.cell.width, this._bufferService.cols, this._cellToRowElements[y]));
|
rowElement.replaceChildren(this._rowFactory.createRow(lineData!, row, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.css.cell.width, this._bufferService.cols, this._cellToRowElements[y]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { MockCoreService, MockDecorationService, MockOptionsService } from 'comm
|
|||||||
import { css } from 'common/Color';
|
import { css } from 'common/Color';
|
||||||
import { MockCharacterJoinerService, MockCoreBrowserService, MockThemeService } from 'browser/TestUtils.test';
|
import { MockCharacterJoinerService, MockCoreBrowserService, MockThemeService } from 'browser/TestUtils.test';
|
||||||
|
|
||||||
const EMPTY_ELEM_MAPPING = new Uint16Array(1000);
|
const EMPTY_ELEM_MAPPING = new Int16Array(1000);
|
||||||
|
|
||||||
describe('DomRendererRowFactory', () => {
|
describe('DomRendererRowFactory', () => {
|
||||||
let dom: jsdom.JSDOM;
|
let dom: jsdom.JSDOM;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export class DomRendererRowFactory {
|
|||||||
this._columnSelectMode = columnSelectMode;
|
this._columnSelectMode = columnSelectMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createRow(lineData: IBufferLine, row: number, isCursorRow: boolean, cursorStyle: string | undefined, cursorX: number, cursorBlink: boolean, cellWidth: number, cols: number, cellMap: Uint16Array): DocumentFragment {
|
public createRow(lineData: IBufferLine, row: number, isCursorRow: boolean, cursorStyle: string | undefined, cursorX: number, cursorBlink: boolean, cellWidth: number, cols: number, cellMap: Int16Array): DocumentFragment {
|
||||||
// NOTE: `cellMap` maps cell positions to a span element index in a row.
|
// NOTE: `cellMap` maps cell positions to a span element index in a row.
|
||||||
// All positions should be updated, even skipped ones after wide chars or left overs at the end,
|
// All positions should be updated, even skipped ones after wide chars or left overs at the end,
|
||||||
// otherwise the mouse hover logic might mark the wrong elements as underlined.
|
// otherwise the mouse hover logic might mark the wrong elements as underlined.
|
||||||
@@ -316,7 +316,7 @@ export class DomRendererRowFactory {
|
|||||||
// since the loop above might exit early not handling all cells,
|
// since the loop above might exit early not handling all cells,
|
||||||
// also set remaining cell positions to last element index
|
// also set remaining cell positions to last element index
|
||||||
if (x < cols - 1) {
|
if (x < cols - 1) {
|
||||||
cellMap.subarray(x + 1).fill(elemIndex);
|
cellMap.subarray(x).fill(++elemIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
|
|||||||
Reference in New Issue
Block a user