From ae94f3e59ea312e0836ea8ab0c5e74c2a3884566 Mon Sep 17 00:00:00 2001 From: Anton Lavrenov Date: Sat, 30 Jul 2022 21:44:38 -0500 Subject: [PATCH 1/4] Revert "make sure `preventDefault()` is not called on touchend-events per default" --- src/Stage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stage.ts b/src/Stage.ts index 16900efe..c9eb49a6 100644 --- a/src/Stage.ts +++ b/src/Stage.ts @@ -737,7 +737,7 @@ export class Stage extends Container { // always call preventDefault for desktop events because some browsers // try to drag and drop the canvas element - if (evt.cancelable && eventType !== "touch") { + if (evt.cancelable) { evt.preventDefault(); } } From 40267e0d44aa37e2ece8088b3f1f5500c8065108 Mon Sep 17 00:00:00 2001 From: gloryyin Date: Mon, 1 Aug 2022 02:09:00 +0800 Subject: [PATCH 2/4] fix: add ellipsis for last line --- src/shapes/Text.ts | 81 +++++++++++++++++++++++++++++++----------- test/unit/Text-test.ts | 33 +++++++++++++++++ 2 files changed, 94 insertions(+), 20 deletions(-) diff --git a/src/shapes/Text.ts b/src/shapes/Text.ts index e2260ee1..b4781923 100644 --- a/src/shapes/Text.ts +++ b/src/shapes/Text.ts @@ -492,27 +492,10 @@ export class Text extends Shape { this._addTextLine(match); textWidth = Math.max(textWidth, matchWidth); currentHeightPx += lineHeightPx; - if ( - !shouldWrap || - (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) - ) { - var lastLine = this.textArr[this.textArr.length - 1]; - if (lastLine) { - if (shouldAddEllipsis) { - var haveSpace = - this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; - if (!haveSpace) { - lastLine.text = lastLine.text.slice( - 0, - lastLine.text.length - 3 - ); - } - - this.textArr.splice(this.textArr.length - 1, 1); - this._addTextLine(lastLine.text + ELLIPSIS); - } - } + var shouldHandleEllipsis = this._shouldHandleEllipsis(currentHeightPx); + if (shouldHandleEllipsis) { + this._addEllipsisIfNecessary(shouldHandleEllipsis); /* * stop wrapping if wrapping is disabled or if adding * one more line would overflow the fixed height @@ -542,6 +525,8 @@ export class Text extends Shape { this._addTextLine(line); currentHeightPx += lineHeightPx; textWidth = Math.max(textWidth, lineWidth); + + this._addEllipsisIfNecessary(this._shouldHandleEllipsis(currentHeightPx)); } // if element height is fixed, abort if adding one more line would overflow if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) { @@ -559,6 +544,62 @@ export class Text extends Shape { this.textWidth = textWidth; } + /** + * whether to handle ellipsis, there are two cases: + * 1. the current line is the last line + * 2. wrap is NONE + * @param {Number} currentHeightPx + * @returns + */ + _shouldHandleEllipsis(currentHeightPx: number): boolean { + var fontSize = +this.fontSize(), + lineHeightPx = this.lineHeight() * fontSize, + height = this.attrs.height, + fixedHeight = height !== AUTO && height !== undefined, + padding = this.padding(), + maxHeightPx = height - padding * 2, + wrap = this.wrap(), + shouldWrap = wrap !== NONE; + + return (!shouldWrap || (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)); + } + + /** + * add ellipses at the end of the line if necessary + * @param {Boolean} shouldHandleEllipsis + * @returns + */ + _addEllipsisIfNecessary(shouldHandleEllipsis: boolean): void { + var width = this.attrs.width, + fixedWidth = width !== AUTO && width !== undefined, + padding = this.padding(), + maxWidth = width - padding * 2, + shouldAddEllipsis = this.ellipsis(); + + if (!shouldHandleEllipsis) { + return; + } + + var lastLine = this.textArr[this.textArr.length - 1]; + if (!lastLine || !shouldAddEllipsis) { + return; + } + + if (fixedWidth) { + var haveSpace = + this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; + if (!haveSpace) { + lastLine.text = lastLine.text.slice( + 0, + lastLine.text.length - 3 + ); + } + } + + this.textArr.splice(this.textArr.length - 1, 1); + this._addTextLine(lastLine.text + ELLIPSIS); + } + // for text we can't disable stroke scaling // if we do, the result will be unexpected getStrokeScaleEnabled() { diff --git a/test/unit/Text-test.ts b/test/unit/Text-test.ts index 42bb8a87..77c88016 100644 --- a/test/unit/Text-test.ts +++ b/test/unit/Text-test.ts @@ -487,6 +487,39 @@ describe('Text', function () { } }); + // ====================================================== + it('multiline with ellipsis and lineWidth less than maxWidth', function () { + var stage = addStage(); + var layer = new Konva.Layer(); + + var text = new Konva.Text({ + x: 10, + y: 10, + text: "HEADING\nAll the\n world's a stage, merely players. They have theirrrrrrr exits and theirrrrr entrances; And one man in his time plays many parts.", + fontSize: 14, + fontFamily: 'Arial', + fontStyle: 'normal', + width: 100, + padding: 0, + align: 'center', + height: 30, + ellipsis: true, + }); + + layer.add(text); + stage.add(layer); + + assert.equal(text.textArr.length, 2); + assert.equal(text.textArr[1].text.slice(-1), '…'); + + if (isBrowser) { + assert.equal( + layer.getContext().getTrace(false, true), + "clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(All the…,23,21);restore();restore();" + ); + } + }); + // ====================================================== it('make sure we respect false for ellipsis', function () { var stage = addStage(); From 0f8f2f4548ba9becb7b477b44c3a3ab9abf45622 Mon Sep 17 00:00:00 2001 From: Anton Lavrenov Date: Fri, 5 Aug 2022 10:07:22 -0500 Subject: [PATCH 3/4] little refactor --- src/shapes/Text.ts | 43 ++++++++++++++++++------------------------ test/unit/Text-test.ts | 4 ++-- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/shapes/Text.ts b/src/shapes/Text.ts index b4781923..3e370d4b 100644 --- a/src/shapes/Text.ts +++ b/src/shapes/Text.ts @@ -493,9 +493,10 @@ export class Text extends Shape { textWidth = Math.max(textWidth, matchWidth); currentHeightPx += lineHeightPx; - var shouldHandleEllipsis = this._shouldHandleEllipsis(currentHeightPx); + var shouldHandleEllipsis = + this._shouldHandleEllipsis(currentHeightPx); if (shouldHandleEllipsis) { - this._addEllipsisIfNecessary(shouldHandleEllipsis); + this._tryToAddEllipsisToLastLine(); /* * stop wrapping if wrapping is disabled or if adding * one more line would overflow the fixed height @@ -526,7 +527,9 @@ export class Text extends Shape { currentHeightPx += lineHeightPx; textWidth = Math.max(textWidth, lineWidth); - this._addEllipsisIfNecessary(this._shouldHandleEllipsis(currentHeightPx)); + if (this._shouldHandleEllipsis(currentHeightPx)) { + this._tryToAddEllipsisToLastLine(); + } } // if element height is fixed, abort if adding one more line would overflow if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) { @@ -549,9 +552,9 @@ export class Text extends Shape { * 1. the current line is the last line * 2. wrap is NONE * @param {Number} currentHeightPx - * @returns + * @returns */ - _shouldHandleEllipsis(currentHeightPx: number): boolean { + _shouldHandleEllipsis(currentHeightPx: number): boolean { var fontSize = +this.fontSize(), lineHeightPx = this.lineHeight() * fontSize, height = this.attrs.height, @@ -561,38 +564,28 @@ export class Text extends Shape { wrap = this.wrap(), shouldWrap = wrap !== NONE; - return (!shouldWrap || (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)); + return ( + !shouldWrap || + (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) + ); } - /** - * add ellipses at the end of the line if necessary - * @param {Boolean} shouldHandleEllipsis - * @returns - */ - _addEllipsisIfNecessary(shouldHandleEllipsis: boolean): void { + _tryToAddEllipsisToLastLine(): void { var width = this.attrs.width, fixedWidth = width !== AUTO && width !== undefined, padding = this.padding(), maxWidth = width - padding * 2, shouldAddEllipsis = this.ellipsis(); - - if (!shouldHandleEllipsis) { - return; - } - + var lastLine = this.textArr[this.textArr.length - 1]; - if (!lastLine || !shouldAddEllipsis) { + if (!lastLine || !shouldAddEllipsis) { return; } - + if (fixedWidth) { - var haveSpace = - this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; + var haveSpace = this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; if (!haveSpace) { - lastLine.text = lastLine.text.slice( - 0, - lastLine.text.length - 3 - ); + lastLine.text = lastLine.text.slice(0, lastLine.text.length - 3); } } diff --git a/test/unit/Text-test.ts b/test/unit/Text-test.ts index 77c88016..d59c3ace 100644 --- a/test/unit/Text-test.ts +++ b/test/unit/Text-test.ts @@ -12,7 +12,7 @@ import { assertAlmostEqual, } from './test-utils'; -describe('Text', function () { +describe.only('Text', function () { // ====================================================== it('text with empty config is allowed', function () { var stage = addStage(); @@ -515,7 +515,7 @@ describe('Text', function () { if (isBrowser) { assert.equal( layer.getContext().getTrace(false, true), - "clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(All the…,23,21);restore();restore();" + 'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(All the…,23,21);restore();restore();' ); } }); From e2f4710258a7ac9a80bb3b7d18b8ef82fc28788f Mon Sep 17 00:00:00 2001 From: Anton Lavrenov Date: Fri, 5 Aug 2022 10:12:11 -0500 Subject: [PATCH 4/4] enable all tests --- test/unit/Text-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/Text-test.ts b/test/unit/Text-test.ts index d59c3ace..0a70507f 100644 --- a/test/unit/Text-test.ts +++ b/test/unit/Text-test.ts @@ -12,7 +12,7 @@ import { assertAlmostEqual, } from './test-utils'; -describe.only('Text', function () { +describe('Text', function () { // ====================================================== it('text with empty config is allowed', function () { var stage = addStage();