From 5c72224a1ccfb3a71aa14e1f11ca8b1967f06384 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:13:10 -0600 Subject: [PATCH 1/7] fix: move getTextEditorElement to Minimap class --- lib/minimap-element.js | 34 ++++++---------------------------- lib/minimap.js | 19 +++++++++++++++++++ lib/mixins/canvas-drawer.js | 10 +++++----- spec/minimap-element-spec.js | 4 ++-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/lib/minimap-element.js b/lib/minimap-element.js index ee0ecbe8..4edbff16 100644 --- a/lib/minimap-element.js +++ b/lib/minimap-element.js @@ -83,10 +83,7 @@ class MinimapElement { * @access private */ this.minimap = undefined - /** - * @access private - */ - this.editorElement = undefined + /** * @access private */ @@ -379,10 +376,10 @@ class MinimapElement { this.measureHeightAndWidth() this.updateMinimapFlexPosition() this.attached = true - this.attachedToTextEditor = this.queryParentSelector('atom-text-editor') === this.getTextEditorElement() + this.attachedToTextEditor = this.queryParentSelector('atom-text-editor') === this.minimap.getTextEditorElement() if (this.attachedToTextEditor) { - this.getTextEditorElement().setAttribute('with-minimap', '') + this.minimap.getTextEditorElement().setAttribute('with-minimap', '') } this.subscriptions.add( @@ -408,7 +405,7 @@ class MinimapElement { * @access private */ detachedCallback () { - this.getTextEditorElement().removeAttribute('with-minimap') + this.minimap.getTextEditorElement().removeAttribute('with-minimap') this.attached = false } @@ -442,7 +439,7 @@ class MinimapElement { attach (parent) { if (this.attached) { return } - const container = parent || this.getTextEditorElement() + const container = parent || this.minimap.getTextEditorElement() const minimaps = container.querySelectorAll('atom-text-editor-minimap') if (minimaps.length) { Array.prototype.forEach.call(minimaps, (el) => { el.destroy() }) @@ -666,25 +663,6 @@ class MinimapElement { delete this.openQuickSettings } - /** - * Returns the target `TextEditor` of the Minimap. - * - * @return {TextEditor} the minimap's text editor - */ - getTextEditor () { return this.minimap.getTextEditor() } - - /** - * Returns the `TextEditorElement` for the Minimap's `TextEditor`. - * - * @return {TextEditorElement} the minimap's text editor element - */ - getTextEditorElement () { - if (this.editorElement) { return this.editorElement } - - this.editorElement = atom.views.getView(this.getTextEditor()) - return this.editorElement - } - // ## ## ####### ######## ######## ## // ### ### ## ## ## ## ## ## // #### #### ## ## ## ## ## ## @@ -1088,7 +1066,7 @@ class MinimapElement { const row = Math.floor(deltaY / this.minimap.getLineHeight()) + this.minimap.getFirstVisibleScreenRow() const textEditor = this.minimap.getTextEditor() - const textEditorElement = this.getTextEditorElement() + const textEditorElement = this.minimap.getTextEditorElement() const scrollTop = row * textEditor.getLineHeightInPixels() - this.minimap.getTextEditorHeight() / 2 const textEditorScrollTop = textEditorElement.pixelPositionForScreenPosition([row, 0]).top - this.minimap.getTextEditorHeight() / 2 diff --git a/lib/minimap.js b/lib/minimap.js index f227265a..29c613b7 100644 --- a/lib/minimap.js +++ b/lib/minimap.js @@ -46,6 +46,13 @@ export default class Minimap { * @access private */ this.textEditor = options.textEditor + + /** + * The Minimap's text editor element. + * @access private + */ + this.editorElement = undefined + /** * The stand-alone state of the current Minimap. * @@ -525,6 +532,18 @@ export default class Minimap { */ getTextEditor () { return this.textEditor } + /** + * Returns the `TextEditorElement` for the Minimap's `TextEditor`. + * + * @return {TextEditorElement} the minimap's text editor element + */ + getTextEditorElement () { + if (this.editorElement) { return this.editorElement } + + this.editorElement = atom.views.getView(this.getTextEditor()) + return this.editorElement + } + /** * Returns the height of the `TextEditor` at the Minimap scale. * diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index 15218423..f77627f3 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -191,7 +191,7 @@ export default class CanvasDrawer extends Mixin { * @return {string} a CSS color */ getDefaultColor () { - const color = this.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color', this.getTextEditorElement(), true) + const color = this.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color', this.minimap.getTextEditorElement(), true) return transparentize(color, this.getTextOpacity()) } @@ -206,7 +206,7 @@ export default class CanvasDrawer extends Mixin { */ getTokenColor (token) { const scopes = token.scopeDescriptor || token.scopes - const color = this.DOMStylesReader.retrieveStyleFromDom(scopes, 'color', this.getTextEditorElement(), true) + const color = this.DOMStylesReader.retrieveStyleFromDom(scopes, 'color', this.minimap.getTextEditorElement(), true) return transparentize(color, this.getTextOpacity()) } @@ -227,7 +227,7 @@ export default class CanvasDrawer extends Mixin { if (properties.scope) { const scopeString = properties.scope.split(/\s+/) - return this.DOMStylesReader.retrieveStyleFromDom(scopeString, 'background-color', this.getTextEditorElement(), true) + return this.DOMStylesReader.retrieveStyleFromDom(scopeString, 'background-color', this.minimap.getTextEditorElement(), true) } else { return this.getDefaultColor() } @@ -402,7 +402,7 @@ export default class CanvasDrawer extends Mixin { * @access private */ eachTokenForScreenRows (startRow, endRow, callback) { - const editor = this.getTextEditor() + const editor = this.minimap.getTextEditor () const invisibleRegExp = this.getInvisibleRegExp() endRow = Math.min(endRow, editor.getScreenLineCount()) @@ -477,7 +477,7 @@ export default class CanvasDrawer extends Mixin { * @access private */ getInvisibleRegExp () { - const invisibles = this.getTextEditor().getInvisibles() + const invisibles = this.minimap.getTextEditor ().getInvisibles() const regexp = [] if (invisibles.cr != null) { regexp.push(invisibles.cr) } if (invisibles.eol != null) { regexp.push(invisibles.eol) } diff --git a/spec/minimap-element-spec.js b/spec/minimap-element-spec.js index 299aef92..97dcf727 100644 --- a/spec/minimap-element-spec.js +++ b/spec/minimap-element-spec.js @@ -232,7 +232,7 @@ describe('MinimapElement', () => { }) runs(() => { nextAnimationFrame() - expect(minimapElement.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color'), minimapElement.getTextEditorElement()).toEqual(`rgb(0, ${0x6d}, ${0x6d})`) + expect(minimapElement.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color'), minimapElement.minimap.getTextEditorElement()).toEqual(`rgb(0, ${0x6d}, ${0x6d})`) }) }) }) @@ -260,7 +260,7 @@ describe('MinimapElement', () => { }) runs(() => { nextAnimationFrame() - expect(minimapElement.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color'), minimapElement.getTextEditorElement()).toEqual(`rgba(0, ${0x6d}, ${0x6d}, 0)`) + expect(minimapElement.DOMStylesReader.retrieveStyleFromDom(['.editor'], 'color'), minimapElement.minimap.getTextEditorElement()).toEqual(`rgba(0, ${0x6d}, ${0x6d}, 0)`) }) }) }) From d3d5d6eb42cbe54842ae09eb8cf88c933ab300b3 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:15:53 -0600 Subject: [PATCH 2/7] fix: this.minimap.getTextEditor only once in eachTokenForScreenRows --- lib/mixins/canvas-drawer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index f77627f3..b9347794 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -402,8 +402,8 @@ export default class CanvasDrawer extends Mixin { * @access private */ eachTokenForScreenRows (startRow, endRow, callback) { - const editor = this.minimap.getTextEditor () - const invisibleRegExp = this.getInvisibleRegExp() + const editor = this.minimap.getTextEditor() + const invisibleRegExp = this.getInvisibleRegExp(editor) endRow = Math.min(endRow, editor.getScreenLineCount()) for (let row = startRow; row < endRow; row++) { @@ -472,12 +472,12 @@ export default class CanvasDrawer extends Mixin { /** * Returns the regexp to replace invisibles substitution characters * in editor lines. - * + * @param {TextEditor} editor * @return {RegExp} the regular expression to match invisible characters * @access private */ - getInvisibleRegExp () { - const invisibles = this.minimap.getTextEditor ().getInvisibles() + getInvisibleRegExp (editor) { + const invisibles = editor.getInvisibles() const regexp = [] if (invisibles.cr != null) { regexp.push(invisibles.cr) } if (invisibles.eol != null) { regexp.push(invisibles.eol) } From 5e23805005c3754565e51761f255a150ad99c48d Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:17:41 -0600 Subject: [PATCH 3/7] fix: make getInvisibleRegExp a free function --- lib/mixins/canvas-drawer.js | 58 +++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index b9347794..e128b3ec 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -403,7 +403,7 @@ export default class CanvasDrawer extends Mixin { */ eachTokenForScreenRows (startRow, endRow, callback) { const editor = this.minimap.getTextEditor() - const invisibleRegExp = this.getInvisibleRegExp(editor) + const invisibleRegExp = getInvisibleRegExp(editor) endRow = Math.min(endRow, editor.getScreenLineCount()) for (let row = startRow; row < endRow; row++) { @@ -469,30 +469,6 @@ export default class CanvasDrawer extends Mixin { context.fill() } - /** - * Returns the regexp to replace invisibles substitution characters - * in editor lines. - * @param {TextEditor} editor - * @return {RegExp} the regular expression to match invisible characters - * @access private - */ - getInvisibleRegExp (editor) { - const invisibles = editor.getInvisibles() - const regexp = [] - if (invisibles.cr != null) { regexp.push(invisibles.cr) } - if (invisibles.eol != null) { regexp.push(invisibles.eol) } - if (invisibles.space != null) { regexp.push(invisibles.space) } - if (invisibles.tab != null) { regexp.push(invisibles.tab) } - - if (regexp.length !== 0) { - return RegExp(regexp.filter((s) => { - return typeof s === 'string' - }).map(escapeRegExp).join('|'), 'g') - } else { - return null - } - } - /** * Draws a single token on the given context. * @@ -727,6 +703,38 @@ export default class CanvasDrawer extends Mixin { } } +// ######## ######## ### ## ## +// ## ## ## ## ## ## ## ## ## +// ## ## ## ## ## ## ## ## ## +// ## ## ######## ## ## ## ## ## +// ## ## ## ## ######### ## ## ## +// ## ## ## ## ## ## ## ## ## +// ######## ## ## ## ## ### ### + +/** + * Returns the regexp to replace invisibles substitution characters + * in editor lines. + * @param {TextEditor} editor + * @return {RegExp} the regular expression to match invisible characters + * @access private + */ +function getInvisibleRegExp (editor) { + const invisibles = editor.getInvisibles() + const regexp = [] + if (invisibles.cr != null) { regexp.push(invisibles.cr) } + if (invisibles.eol != null) { regexp.push(invisibles.eol) } + if (invisibles.space != null) { regexp.push(invisibles.space) } + if (invisibles.tab != null) { regexp.push(invisibles.tab) } + + if (regexp.length !== 0) { + return RegExp(regexp.filter((s) => { + return typeof s === 'string' + }).map(escapeRegExp).join('|'), 'g') + } else { + return null + } +} + // ###### ####### ## ####### ######## ###### // ## ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## From a296f4880b54dc65abc0ece57a249ec078d1a7ee Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:21:09 -0600 Subject: [PATCH 4/7] fix: make eachTokenForScreenRows a free function --- lib/mixins/canvas-drawer.js | 57 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index e128b3ec..ed01c6ff 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -393,33 +393,6 @@ export default class CanvasDrawer extends Mixin { renderData.context.fill() } - /** - * Returns an array of tokens by line. - * - * @param {number} startRow The start row - * @param {number} endRow The end row - * @return {Array} An array of tokens by line - * @access private - */ - eachTokenForScreenRows (startRow, endRow, callback) { - const editor = this.minimap.getTextEditor() - const invisibleRegExp = getInvisibleRegExp(editor) - endRow = Math.min(endRow, editor.getScreenLineCount()) - - for (let row = startRow; row < endRow; row++) { - const editorTokensForScreenRow = editor.tokensForScreenRow(row) - const numToken = editorTokensForScreenRow.length - const numTokenToRender = Math.min(numToken, this.maxTokensInOneLine) - for (let iToken = 0; iToken < numTokenToRender; iToken++) { - const token = editorTokensForScreenRow[iToken] - callback(row, { - text: token.text.replace(invisibleRegExp, ' '), - scopes: token.scopes - }) - } - } - } - /** * Draws lines on the corresponding layer. * @@ -445,7 +418,7 @@ export default class CanvasDrawer extends Mixin { let lastLine, x let y = (offsetRow * lineHeight) - lineHeight - this.eachTokenForScreenRows(firstRow, lastRow, (line, token) => { + eachTokenForScreenRows(firstRow, lastRow, this.minimap.getTextEditor(), this.maxTokensInOneLine, (line, token) => { if (lastLine !== line) { x = 0 y += lineHeight @@ -711,6 +684,34 @@ export default class CanvasDrawer extends Mixin { // ## ## ## ## ## ## ## ## ## // ######## ## ## ## ## ### ### +/** + * Returns an array of tokens by line. + * + * @param {number} startRow The start row + * @param {number} endRow The end row + * @param {TextEditor} editor + * @param {number} maxTokensInOneLine the maximum number of tokens to render in one line + * @return {Array} An array of tokens by line + * @access private + */ +function eachTokenForScreenRows (startRow, endRow, editor, maxTokensInOneLine, callback) { + const invisibleRegExp = getInvisibleRegExp(editor) + endRow = Math.min(endRow, editor.getScreenLineCount()) + + for (let row = startRow; row < endRow; row++) { + const editorTokensForScreenRow = editor.tokensForScreenRow(row) + const numToken = editorTokensForScreenRow.length + const numTokenToRender = Math.min(numToken, maxTokensInOneLine) + for (let iToken = 0; iToken < numTokenToRender; iToken++) { + const token = editorTokensForScreenRow[iToken] + callback(row, { + text: token.text.replace(invisibleRegExp, ' '), + scopes: token.scopes + }) + } + } +} + /** * Returns the regexp to replace invisibles substitution characters * in editor lines. From ec363ea6fd2de23411299feae8f993c692e9a3f2 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:25:52 -0600 Subject: [PATCH 5/7] fix: make drawToken a free function --- lib/mixins/canvas-drawer.js | 89 +++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index ed01c6ff..524ab079 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -434,56 +434,14 @@ export default class CanvasDrawer extends Mixin { ? this.getTokenColor(token) : this.getDefaultColor() - x = this.drawToken( - context, token.text, color, x, y, charWidth, charHeight + x = drawToken( + context, token.text, color, x, y, charWidth, charHeight, this.ignoreWhitespacesInTokens ) } }) context.fill() } - /** - * Draws a single token on the given context. - * - * @param {CanvasRenderingContext2D} context the target canvas context - * @param {string} text the token's text content - * @param {string} color the token's CSS color - * @param {number} x the x position of the token in the line - * @param {number} y the y position of the line in the minimap - * @param {number} charWidth the width of a character in the minimap - * @param {number} charHeight the height of a character in the minimap - * @return {number} the x position at the end of the token - * @access private - */ - drawToken (context, text, color, x, y, charWidth, charHeight) { - context.fillStyle = color - - if (this.ignoreWhitespacesInTokens) { - const length = text.length * charWidth - context.fillRect(x, y, length, charHeight) - - return x + length - } else { - let chars = 0 - for (let j = 0, len = text.length; j < len; j++) { - const char = text[j] - if (/\s/.test(char)) { - if (chars > 0) { - context.fillRect(x - (chars * charWidth), y, chars * charWidth, charHeight) - } - chars = 0 - } else { - chars++ - } - x += charWidth - } - if (chars > 0) { - context.fillRect(x - (chars * charWidth), y, chars * charWidth, charHeight) - } - return x - } - } - /** * Draws the specified decorations for the current `screenRow`. * @@ -684,6 +642,49 @@ export default class CanvasDrawer extends Mixin { // ## ## ## ## ## ## ## ## ## // ######## ## ## ## ## ### ### +/** + * Draws a single token on the given context. + * + * @param {CanvasRenderingContext2D} context the target canvas context + * @param {string} text the token's text content + * @param {string} color the token's CSS color + * @param {number} x the x position of the token in the line + * @param {number} y the y position of the line in the minimap + * @param {number} charWidth the width of a character in the minimap + * @param {number} charHeight the height of a character in the minimap + * @return {number} the x position at the end of the token + * @return {boolean} the x position at the end of the token + * @access private + */ +function drawToken (context, text, color, x, y, charWidth, charHeight, ignoreWhitespacesInTokens) { + context.fillStyle = color + + if (ignoreWhitespacesInTokens) { + const length = text.length * charWidth + context.fillRect(x, y, length, charHeight) + + return x + length + } else { + let chars = 0 + for (let j = 0, len = text.length; j < len; j++) { + const char = text[j] + if (/\s/.test(char)) { + if (chars > 0) { + context.fillRect(x - (chars * charWidth), y, chars * charWidth, charHeight) + } + chars = 0 + } else { + chars++ + } + x += charWidth + } + if (chars > 0) { + context.fillRect(x - (chars * charWidth), y, chars * charWidth, charHeight) + } + return x + } +} + /** * Returns an array of tokens by line. * From bcee054813345c87b3255d789118c874b21b4545 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:43:48 -0600 Subject: [PATCH 6/7] test: use toBeNear matcher for comparison --- spec/minimap-element-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/minimap-element-spec.js b/spec/minimap-element-spec.js index 97dcf727..641b466f 100644 --- a/spec/minimap-element-spec.js +++ b/spec/minimap-element-spec.js @@ -177,7 +177,7 @@ describe('MinimapElement', () => { it('takes the height of the editor', () => { expect(minimapElement.offsetHeight).toEqual(editorElement.clientHeight) - expect(minimapElement.offsetWidth).toBeCloseTo(editorElement.clientWidth / 10, 0) + expect(minimapElement.offsetWidth).toBeNear(editorElement.clientWidth / 10, 1) }) it('knows when attached to a text editor', () => { From 6999bc54dfa474192273c7993a54cc8968b1e6bf Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 2 Jan 2021 03:44:12 -0600 Subject: [PATCH 7/7] fix: move DOMStylesReader to CanvasDrawer This is where DOMStylesReader is actually used --- lib/minimap-element.js | 6 ------ lib/mixins/canvas-drawer.js | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/minimap-element.js b/lib/minimap-element.js index 4edbff16..4b66cce6 100644 --- a/lib/minimap-element.js +++ b/lib/minimap-element.js @@ -5,7 +5,6 @@ import { EventsDelegation, AncestorsMethods } from 'atom-utils-plus' import elementResizeDetectorImport from 'element-resize-detector' import * as Main from './main' -import DOMStylesReader from './dom-styles-reader' import CanvasDrawer from './mixins/canvas-drawer' import include from './decorators/include' import element from './decorators/element' @@ -178,11 +177,6 @@ class MinimapElement { */ this.quickSettingsElement = undefined - /** - * This MinimapElement's DOMStylesReader - */ - this.DOMStylesReader = new DOMStylesReader() - // States /** diff --git a/lib/mixins/canvas-drawer.js b/lib/mixins/canvas-drawer.js index 524ab079..64ed37ff 100644 --- a/lib/mixins/canvas-drawer.js +++ b/lib/mixins/canvas-drawer.js @@ -5,6 +5,7 @@ import Mixin from 'mixto' import * as Main from '../main' import CanvasLayer from '../canvas-layer' +import DOMStylesReader from '../dom-styles-reader' /** * The `CanvasDrawer` mixin is responsible for the rendering of a `Minimap` @@ -63,6 +64,11 @@ export default class CanvasDrawer extends Mixin { // the maximum number of tokens to render in one line this.maxTokensInOneLine = atom.config.get('minimap.maxTokensInOneLine') + + /** + * This MinimapElement's DOMStylesReader + */ + this.DOMStylesReader = new DOMStylesReader() } /**