using instead two attributes per dom node

This commit is contained in:
Aiday Marlen Kyzy
2023-09-05 13:55:47 +02:00
parent 4409d5b2da
commit 79773c8b1f
2 changed files with 54 additions and 54 deletions
@@ -257,26 +257,30 @@ export class StickyScrollController extends Disposable implements IEditorContrib
}
if (mouseEvent.shiftKey) {
// shift click
const lineIndex = this._stickyScrollWidget.getInfoFromLineDomNode(mouseEvent.target)?.index;
if (lineIndex === undefined) {
const lineIndex = this._stickyScrollWidget.getLineNumberFromChildDomNode(mouseEvent.target);
if (lineIndex === null) {
return;
}
const position = new Position(this._endLineNumbers[lineIndex], 1);
this._revealLineInCenterIfOutsideViewport(position);
return;
}
// click on folding icon
const isInFoldingIconDomNode = this._stickyScrollWidget.isInFoldingIconDomNode(mouseEvent.target);
if (isInFoldingIconDomNode) {
const lineNumber = this._stickyScrollWidget.getInfoFromLineNumberDomNode(mouseEvent.target)?.line;
// clicked on folding icon
const lineNumber = this._stickyScrollWidget.getLineNumberFromChildDomNode(mouseEvent.target);
this._toggleFoldingRegionForLine(lineNumber);
return;
}
const isInStickyLine = this._stickyScrollWidget.isInStickyLine(mouseEvent.target);
if (!isInStickyLine) {
return;
}
// normal click
let position = this._stickyScrollWidget.getEditorPositionFromNode(mouseEvent.target);
if (!position) {
const lineNumber = this._stickyScrollWidget.getInfoFromLineDomNode(mouseEvent.target)?.line;
if (lineNumber === undefined) {
const lineNumber = this._stickyScrollWidget.getLineNumberFromChildDomNode(mouseEvent.target);
if (lineNumber === null) {
// not hovering a sticky scroll line
return;
}
@@ -286,8 +290,8 @@ export class StickyScrollController extends Disposable implements IEditorContrib
}));
this._register(dom.addStandardDisposableListener(stickyScrollWidgetDomNode, dom.EventType.MOUSE_MOVE, (mouseEvent: IMouseEvent) => {
if (mouseEvent.shiftKey) {
const currentEndForLineIndex = this._stickyScrollWidget.getInfoFromLineDomNode(mouseEvent.target)?.index;
if (currentEndForLineIndex === undefined || this._showEndForLine !== null && this._showEndForLine === currentEndForLineIndex) {
const currentEndForLineIndex = this._stickyScrollWidget.getLineIndexFromChildDomNode(mouseEvent.target);
if (currentEndForLineIndex === null || this._showEndForLine !== null && this._showEndForLine === currentEndForLineIndex) {
return;
}
this._showEndForLine = currentEndForLineIndex;
@@ -382,8 +386,8 @@ export class StickyScrollController extends Disposable implements IEditorContrib
});
}
private _toggleFoldingRegionForLine(line: number | undefined) {
if (!this._foldingModel || line === undefined) {
private _toggleFoldingRegionForLine(line: number | null) {
if (!this._foldingModel || line === null) {
return;
}
const stickyLine = this._stickyScrollWidget.getStickyLineForLine(line);
@@ -401,9 +405,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib
this._editor.setScrollTop(scrollTop);
}
private _renderStickyScrollUpdateFields() {
private async _renderStickyScrollUpdateFields() {
this._showEndForLine = null;
this._renderStickyScroll(this._forceRebuildFromLine);
await this._renderStickyScroll(this._forceRebuildFromLine);
this._forceRebuildFromLine = Infinity;
}
@@ -38,10 +38,10 @@ export class StickyScrollWidgetState {
}
const _ttPolicy = createTrustedTypesPolicy('stickyScrollViewLayer', { createHTML: value => value });
const STICKY_LINE_INDEX_ATTR = 'data-sticky-line-index';
const STICKY_LINE_NUMBER_INDEX_ATTR = 'data-sticky-line-number-index';
const STICKY_INDEX_ATTR = 'data-sticky-line-index';
const STICKY_IS_LINE_ATTR = 'data-sticky-is-line';
const STICKY_IS_LINE_NUMBER_ATTR = 'data-sticky-is-line-number';
const STICKY_IS_FOLDING_ICON_ATTR = 'data-sticky-is-folding-icon';
type STICKY_INDEX_TYPE = typeof STICKY_LINE_INDEX_ATTR | typeof STICKY_LINE_NUMBER_INDEX_ATTR;
export class StickyScrollWidget extends Disposable implements IOverlayWidget {
@@ -51,7 +51,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
private readonly _linesDomNodeScrollable: HTMLElement = document.createElement('div');
private readonly _linesDomNode: HTMLElement = document.createElement('div');
private _state: StickyScrollWidgetState | undefined;
private _previousState: StickyScrollWidgetState | undefined;
private _lineHeight: number = this._editor.getOption(EditorOption.lineHeight);
private _stickyLines: RenderedStickyLine[] = [];
private _lineNumbers: number[] = [];
@@ -128,12 +128,12 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
setState(state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | null, forceRebuildFromLine: number = Infinity): void {
if (
((!this._state && !state) || (this._state && this._state.equals(state)))
((!this._previousState && !state) || (this._previousState && this._previousState.equals(state)))
&& forceRebuildFromLine === Infinity
) {
return;
}
this._state = state;
this._previousState = state;
const previousStickyLines = this._stickyLines;
this._clearStickyWidget();
if (!state || !this._editor._getViewModel()) {
@@ -273,12 +273,18 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
}
const lineHTMLNode = document.createElement('span');
lineHTMLNode.setAttribute(STICKY_INDEX_ATTR, String(index));
lineHTMLNode.setAttribute(STICKY_IS_LINE_ATTR, '');
lineHTMLNode.setAttribute('role', 'listitem');
lineHTMLNode.tabIndex = 0;
lineHTMLNode.className = 'sticky-line-content';
lineHTMLNode.classList.add(`stickyLine${line}`);
lineHTMLNode.style.lineHeight = `${this._lineHeight}px`;
lineHTMLNode.innerHTML = newLine as string;
const lineNumberHTMLNode = document.createElement('span');
lineNumberHTMLNode.setAttribute(STICKY_INDEX_ATTR, String(index));
lineNumberHTMLNode.setAttribute(STICKY_IS_LINE_NUMBER_ATTR, '');
lineNumberHTMLNode.className = 'sticky-line-number';
lineNumberHTMLNode.style.lineHeight = `${this._lineHeight}px`;
const lineNumbersWidth = minimapSide === 'left' ? layoutInfo.contentLeft - layoutInfo.minimap.minimapCanvasOuterWidth : layoutInfo.contentLeft;
@@ -308,10 +314,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
this._editor.applyFontInfo(lineHTMLNode);
this._editor.applyFontInfo(innerLineNumberHTML);
lineNumberHTMLNode.setAttribute(STICKY_LINE_NUMBER_INDEX_ATTR, String(index));
lineHTMLNode.setAttribute(STICKY_LINE_INDEX_ATTR, String(index));
lineHTMLNode.setAttribute('role', 'listitem');
lineHTMLNode.tabIndex = 0;
lineNumberHTMLNode.style.lineHeight = `${this._lineHeight}px`;
lineHTMLNode.style.lineHeight = `${this._lineHeight}px`;
@@ -394,14 +396,14 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
}
/**
* Given a sticky line (not line number) leaf dom node, tries to find the editor position.
* Given a leaf dom node, tries to find the editor position.
*/
getEditorPositionFromNode(spanDomNode: HTMLElement | null): Position | null {
if (!spanDomNode || spanDomNode.children.length > 0) {
// This is not a leaf node
return null;
}
const renderedStickyLine = this._getRenderedStickyLineFromDomNode(spanDomNode, STICKY_LINE_INDEX_ATTR);
const renderedStickyLine = this._getRenderedStickyLineFromChildDomNode(spanDomNode);
if (!renderedStickyLine) {
return null;
}
@@ -409,36 +411,12 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
return new Position(renderedStickyLine.lineNumber, column);
}
/**
* Retrieves the line number and index from the input dom node.
* Returns non null, only if the dom node is in the sticky lines dom node (as opposed to sticky line numbers dom node).
* @param domNode input dom node
* @returns info containing the line number and index
*/
getInfoFromLineDomNode(domNode: HTMLElement | null): { index: number; line: number } | null {
return this._getInfoFromDomNode(domNode, STICKY_LINE_INDEX_ATTR);
getLineNumberFromChildDomNode(domNode: HTMLElement | null): number | null {
return this._getRenderedStickyLineFromChildDomNode(domNode)?.lineNumber ?? null;
}
/**
* Retrieves the line number and index from the input dom node.
* Returns non null, only if the dom node is in the sticky line numbers dom node (as opposed to sticky lines dom node)
* @param domNode input dom node
* @returns info containing the line number and index
*/
getInfoFromLineNumberDomNode(domNode: HTMLElement | null): { index: number; line: number } | null {
return this._getInfoFromDomNode(domNode, STICKY_LINE_NUMBER_INDEX_ATTR);
}
private _getInfoFromDomNode(domNode: HTMLElement | null, attribute: STICKY_INDEX_TYPE): { index: number; line: number } | null {
const renderedStickyLine = this._getRenderedStickyLineFromDomNode(domNode, attribute);
if (!renderedStickyLine) {
return null;
}
return { index: renderedStickyLine.index, line: renderedStickyLine.lineNumber };
}
private _getRenderedStickyLineFromDomNode(domNode: HTMLElement | null, attribute: STICKY_INDEX_TYPE): RenderedStickyLine | null {
const index = this._getLineIndexFromDomNode(domNode, attribute);
private _getRenderedStickyLineFromChildDomNode(domNode: HTMLElement | null): RenderedStickyLine | null {
const index = this.getLineIndexFromChildDomNode(domNode);
if (index === null || index < 0 || index >= this._stickyLines.length) {
return null;
}
@@ -449,11 +427,29 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
* Given a child dom node, tries to find the sticky line index or sticky line number index atttribute.
* Returns null if none is found.
*/
private _getLineIndexFromDomNode(domNode: HTMLElement | null, attribute: STICKY_INDEX_TYPE): number | null {
const lineIndex = this._getAttributeValue(domNode, attribute);
getLineIndexFromChildDomNode(domNode: HTMLElement | null): number | null {
const lineIndex = this._getAttributeValue(domNode, STICKY_INDEX_ATTR);
return lineIndex ? parseInt(lineIndex, 10) : null;
}
/**
* Given a child dom node, tries to find if this dom node
* is (contained in) a sticky line. Returns a boolean.
*/
isInStickyLine(domNode: HTMLElement | null): boolean {
const isInLine = this._getAttributeValue(domNode, STICKY_IS_LINE_ATTR);
return isInLine !== undefined;
}
/**
* Given a child dom node, tries to find if this dom node
* is (contained in) a sticky line number. Returns a boolean.
*/
isInStickyLineNumber(domNode: HTMLElement | null): boolean {
const isInLineNumber = this._getAttributeValue(domNode, STICKY_IS_LINE_NUMBER_ATTR);
return isInLineNumber !== undefined;
}
/**
* Given a child dom node, tries to find if this dom node
* is (contained in) a sticky folding icon. Returns a boolean.