-
Notifications
You must be signed in to change notification settings - Fork 57
feat(web): ellipsizeMode and numberOfLines in EnrichedText #687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hejsztynx
wants to merge
30
commits into
main
Choose a base branch
from
@ksienkiewicz/feat-web-enriched-text-ellipsize
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 23 commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
29c9d2a
feat: tail ellipsize
hejsztynx 272b51d
feat: head ellipsize
hejsztynx bc2133f
feat: clip ellipsize
hejsztynx 3ea1138
feat: ellipsizeMode e2e tests
hejsztynx ad4ead3
feat: update docs
hejsztynx de29975
test: ellipsis tests
hejsztynx a18ca7b
fix: update tests and tail and clip logic
hejsztynx f243145
feat: middle ellipsize
hejsztynx bbd4619
refactor: functions cleanup
hejsztynx 4022e5a
test: fix tests to respect native html format
hejsztynx d4d8a7e
test: typos in tests
hejsztynx c85e0b1
fix: sandbox creation cssText overwrite
hejsztynx e6aceb1
docs: ssr ui flash note
hejsztynx 6f547df
fix: preserving original ordered list ordinals
hejsztynx 13ae125
feat: example app action buttons
hejsztynx ca25bbc
fix: zws in empty p tags
hejsztynx 2cc6093
Merge branch 'main' into @ksienkiewicz/feat-web-enriched-text-ellipsize
hejsztynx 9990d7a
fix: acknowledge empty p tags during ellipsize algorithms
hejsztynx 068d9e7
Merge branch 'main' into @ksienkiewicz/feat-web-enriched-text-ellipsize
hejsztynx f2f3c67
Merge branch 'main' into @ksienkiewicz/feat-web-enriched-text-ellipsize
hejsztynx 785b678
refactor: middle ellipsis test suites screenshots rename
hejsztynx 5b553fd
fix: ellipsizeMode refreshes on style and htmlStyle changes
hejsztynx 6e44ac7
refactor: switch to \u2026 character as an ellipsis representation
hejsztynx 6b5623f
fix: safari boundingbox calculation
hejsztynx 73037cf
fix: backward truncation ellipsis removal
hejsztynx ecec3d9
refactor: render optimization when no ellipsize is desired
hejsztynx 8461b46
feat: optimization - eatBackward and eatForward now use binary search
hejsztynx c9124fa
refactor: clean up comments
hejsztynx a0f342b
Merge branch 'main' into @ksienkiewicz/feat-web-enriched-text-ellipsize
hejsztynx a644930
Merge branch 'main' into @ksienkiewicz/feat-web-enriched-text-ellipsize
hejsztynx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+361 Bytes
.playwright/screenshots/ellipsize-between-empty-paragraphs-head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+251 Bytes
.playwright/screenshots/ellipsize-between-multiple-empty-lines-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+361 Bytes
.playwright/screenshots/ellipsize-between-multiple-empty-lines-head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+361 Bytes
.playwright/screenshots/ellipsize-between-multiple-empty-lines-tail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.44 KB
.playwright/screenshots/ellipsize-breaklines-head-fallback-middle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+817 Bytes
.playwright/screenshots/ellipsize-checkbox-list-only-empty-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+887 Bytes
.playwright/screenshots/ellipsize-checkbox-list-only-empty-head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+887 Bytes
.playwright/screenshots/ellipsize-checkbox-list-only-empty-tail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+2.17 KB
.playwright/screenshots/ellipsize-different-blocks-head-fallback-middle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+5.87 KB
.playwright/screenshots/ellipsize-different-paragraph-style-middle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+5.98 KB
...right/screenshots/ellipsize-different-paragraph-style-multiple-lines-middle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+3.48 KB
...wright/screenshots/ellipsize-different-paragraph-style-with-empty-line-clip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+5.7 KB
...wright/screenshots/ellipsize-different-paragraph-style-with-empty-line-head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+3.55 KB
...wright/screenshots/ellipsize-different-paragraph-style-with-empty-line-tail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+8.67 KB
.playwright/screenshots/ellipsize-htmlstyle-blockquote-gapwidth-recompute.png
Oops, something went wrong.
Binary file added
BIN
+7.78 KB
.playwright/screenshots/ellipsize-htmlstyle-heading-fontsize-recompute.png
Oops, something went wrong.
Binary file added
BIN
+7.78 KB
.playwright/screenshots/ellipsize-htmlstyle-ol-marginleft-recompute.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+3.21 KB
...ght/screenshots/ellipsize-multiple-short-paragraphs-with-last-overflow-clip.png
Oops, something went wrong.
Binary file added
BIN
+6.17 KB
...ght/screenshots/ellipsize-multiple-short-paragraphs-with-last-overflow-head.png
Oops, something went wrong.
Binary file added
BIN
+3.28 KB
...ght/screenshots/ellipsize-multiple-short-paragraphs-with-last-overflow-tail.png
Oops, something went wrong.
Binary file added
BIN
+6.63 KB
.playwright/screenshots/ellipsize-one-paragraph-many-inline-images-middle.png
Oops, something went wrong.
Binary file added
BIN
+6.15 KB
.playwright/screenshots/ellipsize-one-paragraph-many-lines-overflowing-middle.png
Oops, something went wrong.
Binary file added
BIN
+6.65 KB
.playwright/screenshots/ellipsize-one-paragraph-one-line-overflowing-middle.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+8.54 KB
...nshots/ellipsize-other-paragraphs-and-break-lines-inside-block-style-middle.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+393 Bytes
.playwright/screenshots/ellipsize-unordered-list-only-empty-clip.png
Oops, something went wrong.
Binary file added
BIN
+534 Bytes
.playwright/screenshots/ellipsize-unordered-list-only-empty-head.png
Oops, something went wrong.
Binary file added
BIN
+534 Bytes
.playwright/screenshots/ellipsize-unordered-list-only-empty-tail.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,383 @@ | ||
| import { test, expect, type Locator, type Page } from '@playwright/test'; | ||
|
|
||
| test.setTimeout(90_000); | ||
|
|
||
| type EllipsizeMode = 'head' | 'middle' | 'tail' | 'clip'; | ||
|
|
||
| const LOREM_IPSUM = `<html><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur porta placerat nulla vitae tincidunt. In tellus neque, volutpat id molestie ut, dapibus sit amet justo. Sed nec lobortis orci. Vestibulum magna est, placerat vitae libero ut, viverra mollis purus. Curabitur lacinia a libero non congue. Vestibulum et velit lacinia, feugiat odio eget, faucibus sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus eu erat commodo, condimentum augue eu, fringilla purus. Morbi at nisi eget felis dignissim fringilla. Pellentesque blandit porttitor libero. Donec accumsan, leo eget ultricies rutrum, lorem purus aliquet quam, sit amet pellentesque lectus nulla non nulla.</p></html>`; | ||
|
|
||
| const sel = { | ||
| root: '[data-testid="test-ellipsize-root"]', | ||
| display: '[data-testid="test-ellipsize-display"]', | ||
| displayInner: '[data-testid="test-ellipsize-display"] .et-view', | ||
| htmlInput: '[data-testid="test-ellipsize-html-input"]', | ||
| setValueButton: '[data-testid="test-ellipsize-set-value-button"]', | ||
| numberOfLinesInput: '[data-testid="test-ellipsize-number-of-lines-input"]', | ||
| numberOfLinesOutput: '[data-testid="test-ellipsize-number-of-lines-output"]', | ||
| modeButton: (mode: EllipsizeMode) => | ||
| `[data-testid="test-ellipsize-mode-${mode}"]`, | ||
| modeOutput: '[data-testid="test-ellipsize-mode-output"]', | ||
| valueOutput: '[data-testid="test-ellipsize-value-output"]', | ||
| toggleButton: (key: OverrideKey) => | ||
| `[data-testid="test-ellipsize-toggle-${key}"]`, | ||
| overrideOutput: (key: OverrideKey) => | ||
| `[data-testid="test-ellipsize-${key}-override-output"]`, | ||
| } as const; | ||
|
|
||
| type OverrideKey = 'style' | 'headings' | 'ol' | 'blockquote'; | ||
|
|
||
| function displayLocator(page: Page): Locator { | ||
| return page.locator(sel.display); | ||
| } | ||
|
|
||
| async function gotoTestEllipsize(page: Page): Promise<void> { | ||
| await page.goto('/test-ellipsize'); | ||
| await page.waitForSelector(sel.displayInner); | ||
| } | ||
|
|
||
| async function setValue(page: Page, html: string): Promise<void> { | ||
| await page.fill(sel.htmlInput, html); | ||
| await page.click(sel.setValueButton); | ||
| await expect | ||
| .poll(async () => (await page.locator(sel.valueOutput).textContent()) ?? '') | ||
| .toBe(html); | ||
| } | ||
|
|
||
| async function setNumberOfLines(page: Page, lines: number): Promise<void> { | ||
| await page.fill(sel.numberOfLinesInput, String(lines)); | ||
| await expect | ||
| .poll( | ||
| async () => | ||
| (await page.locator(sel.numberOfLinesOutput).textContent())?.trim() ?? | ||
| '' | ||
| ) | ||
| .toBe(String(lines)); | ||
| } | ||
|
|
||
| async function setMode(page: Page, mode: EllipsizeMode): Promise<void> { | ||
| await page.click(sel.modeButton(mode)); | ||
| await expect | ||
| .poll( | ||
| async () => | ||
| (await page.locator(sel.modeOutput).textContent())?.trim() ?? '' | ||
| ) | ||
| .toBe(mode); | ||
| } | ||
|
|
||
| async function toggleOverride(page: Page, key: OverrideKey): Promise<void> { | ||
| await page.click(sel.toggleButton(key)); | ||
| await expect | ||
| .poll( | ||
| async () => | ||
| (await page.locator(sel.overrideOutput(key)).textContent())?.trim() ?? | ||
| '' | ||
| ) | ||
| .toContain('true'); | ||
| } | ||
|
|
||
| const SHARED_MODES: EllipsizeMode[] = ['tail', 'head', 'clip']; | ||
|
|
||
| type EllipsizeCase = { | ||
| name: string; | ||
| slug: string; | ||
| html: string; | ||
| numberOfLines: number; | ||
| }; | ||
|
|
||
| const SHARED_CASES: EllipsizeCase[] = [ | ||
| { | ||
| name: 'paragraph that fits', | ||
| slug: 'paragraph-fit', | ||
| html: `<html><p>hello that is a paragraph that should fit and require no ellipsis</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'single word wrapping to multiple lines', | ||
| slug: 'single-word', | ||
| html: | ||
| `<html><p>Verylongpieceoftextfitintoonelinesowecancheckthiscasewherethereis` + | ||
| `averylongpieceoftextanditwrapsaroundsomenumberoflinesandthatwillbetruncated` + | ||
| `accordinglytothesetellipsizemodeintheenrichedtextcomponent</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'a long word that causes line wrapping', | ||
| slug: 'one-word-wrapping', | ||
| html: | ||
| `<html><p>Some paragraph with a long word that will not fit and wrap.` + | ||
| ` The long word: Konstantynopolitanczykowianeczka</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'paragraph with a number of lines much greater than the given limit', | ||
| slug: 'very-long-paragraph', | ||
| html: LOREM_IPSUM, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'a number of paragraphs much greater than the given limit', | ||
| slug: 'multiple-short-paragraphs', | ||
| html: `<html><p>first</p><p>second</p><p>third</p><p>fourth</p><p>fifth</p><p>sixth</p><p>seventh</p></html>`, | ||
| numberOfLines: 4, | ||
| }, | ||
| { | ||
| name: 'a number of paragraphs much greater than the given limit and the last one overflows', | ||
| slug: 'multiple-short-paragraphs-with-last-overflow', | ||
| html: `<html><p>first</p><p>second</p><p>third</p><p>fourth</p><p>fifth</p><p>sixth</p><p>seventh line that will be long enough that it overflows to the next 8th line</p></html>`, | ||
| numberOfLines: 4, | ||
| }, | ||
|
hejsztynx marked this conversation as resolved.
|
||
| { | ||
| name: 'some text between empty paragraphs', | ||
| slug: 'between-empty-paragraphs', | ||
| html: `<html><br><p>between empty paragraphs</p><br></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'some text between multiple empty lines', | ||
| slug: 'between-multiple-empty-lines', | ||
| html: `<html><br><br><p>between empty paragraphs</p><br></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'some empty paragraphs in the middle', | ||
| slug: 'empty-in-the-middle', | ||
| html: `<html><p>first line</p><br><br><br><p>last line</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'unordered list', | ||
| slug: 'unordered-list', | ||
| html: `<html><ul><li>first</li><li>second</li><li>third</li></ul></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'unordered list with empty elements', | ||
| slug: 'unordered-list-with-empty', | ||
| html: `<html><ul><li></li><li>second</li><li></li><li>fourth</li></ul></html>`, | ||
| numberOfLines: 3, | ||
| }, | ||
| { | ||
| name: 'unordered list with only empty elements', | ||
| slug: 'unordered-list-only-empty', | ||
| html: `<html><ul><li></li><li></li><li></li></ul></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'ordered list', | ||
| slug: 'ordered-list', | ||
| html: `<html><ol><li>first</li><li>second</li><li>third</li></ol></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'ordered list with empty elements', | ||
| slug: 'ordered-list-with-empty', | ||
| html: `<html><ol><li></li><li>second</li><li></li><li>fourth</li></ol></html>`, | ||
| numberOfLines: 3, | ||
| }, | ||
| { | ||
| name: 'ordered list with only empty elements', | ||
| slug: 'ordered-list-only-empty', | ||
| html: `<html><ol><li></li><li></li><li></li></ol></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'checkbox list', | ||
| slug: 'checkbox-list', | ||
| html: `<html><ul data-type="checkbox"><li checked>first</li><li>second</li><li>third</li></ul></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'checkbox list with empty elements', | ||
| slug: 'checkbox-list-with-empty', | ||
| html: `<html><ul data-type="checkbox"><li checked></li><li>second</li><li></li><li>fourth</li></ul></html>`, | ||
| numberOfLines: 3, | ||
| }, | ||
| { | ||
| name: 'checkbox list with only empty elements', | ||
| slug: 'checkbox-list-only-empty', | ||
| html: `<html><ul data-type="checkbox"><li checked></li><li></li><li></li></ul></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'different paragraph style', | ||
| slug: 'different-paragraph-style', | ||
| html: `<html><blockquote><p>this is a pretty long blockquote - a different block style paragraph, long enough to overflow in the given number of lines.</p></blockquote></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'different paragraph style with an empty line', | ||
| slug: 'different-paragraph-style-with-empty-line', | ||
| html: `<html><blockquote><p>this is a pretty short blockquote.</p><br><p>This is a line after an empty line.</p></blockquote></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'mixing different paragraph styles', | ||
| slug: 'paragraph-styles-mix', | ||
| html: `<html><p>This is a normal paragraph.</p><codeblock><p>This is a codeblock that will be long enough to overflow.</p></codeblock></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'inline images', | ||
| slug: 'inline-images', | ||
| html: | ||
| `<html><p>This is a line with an inline <img src="asd" width="80" height="80"/>image.` + | ||
| `</p><p>This is a second line and the inline image <img src="asd" width="80" height="80"/> ` + | ||
| `will make it overflow to the next line.</p><p>This is the last line with an <img src="asd" width="80" height="80"/>inline image.</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| ]; | ||
|
|
||
| for (const mode of SHARED_MODES) { | ||
| test.describe(`EnrichedText ellipsize - ${mode}`, () => { | ||
| for (const c of SHARED_CASES) { | ||
| test(c.name, async ({ page }) => { | ||
| await gotoTestEllipsize(page); | ||
| await setValue(page, c.html); | ||
| await setNumberOfLines(page, c.numberOfLines); | ||
| await setMode(page, mode); | ||
|
|
||
| await expect(displayLocator(page)).toHaveScreenshot( | ||
| `ellipsize-${c.slug}-${mode}.png` | ||
| ); | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| test.describe('EnrichedText ellipsize - middle', () => { | ||
| const middleEllipsizeCases: EllipsizeCase[] = [ | ||
| { | ||
| name: 'all text within one paragraph, with one line exceeding the limit', | ||
| slug: 'one-paragraph-one-line-overflowing', | ||
| html: | ||
| `<html><p>This is a fairly long paragraph that should wrap` + | ||
| ` across three lines so the truncation has something to chew on.</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'all text within one paragraph, but with at least two lines exceeding the limit', | ||
| slug: 'one-paragraph-many-lines-overflowing', | ||
| html: | ||
| `<html><p>This is a fairly long paragraph that should wrap across four lines so the` + | ||
| ` truncation has something to chew on. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'all text within one paragraph but with multiple inline images', | ||
| slug: 'one-paragraph-many-inline-images', | ||
| html: | ||
| `<html><p>Some paragraph text overflowing but with so<img src="w" width="20" ` + | ||
| `height="20"/>me inline images <img src="w" width="20" height="20"/><img src="w" ` + | ||
| `width="20" height="20"/><img src="w" width="20" height="20"/>insi<img src="w" width="20" ` + | ||
| `height="20"/>de the eaten text and before, after dummytext the rendered <img src="w" width="20" height="20"/>ellipsis</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'different paragraphs will be truncated with the middle ellipsis if the needed last lines belong to a single paragraph', | ||
| slug: 'different-paragraph-style', | ||
| html: `<html><p>first paragraph.</p><h6>Different paragraph style that will overflow to the next line</h6></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'different paragraph style with many lines', | ||
| slug: 'different-paragraph-style-multiple-lines', | ||
| html: | ||
| `<html><p>first paragraph.</p><codeblock><p>Different paragraph style and the text ` + | ||
| `that will overflow to the next lines of that block verylongwordthatwillnotfitinthelineandwilloverflow</p></codeblock></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'ellipsis on the last paragraph with leading other paragraphs and break lines', | ||
| slug: 'other-paragraphs-and-break-lines-inside-block-style', | ||
| html: | ||
| `<html><p>Normal style.</p><blockquote><p>First line before empty ones.</p><br><br><p>Last ` + | ||
| `paragraph inside a block style that will overflow to three different lines, so we can check this case.</p></blockquote></html>`, | ||
| numberOfLines: 5, | ||
| }, | ||
| { | ||
| name: 'empty lines are preserved', | ||
| slug: 'empty-lines', | ||
| html: `<html><br><p>first line</p><br><p>last line that will overflow and will have an ellipsis</p></html>`, | ||
| numberOfLines: 4, | ||
| }, | ||
| // tests checking a proper fallback to the head ellipsis | ||
| { | ||
| name: 'when the overflowing lines are different blocks, it fallbacks to head ellipsis', | ||
| slug: 'different-blocks-head-fallback', | ||
| html: `<html><p>first line</p><p>second line</p><p>third line</p></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'breaklines inside a block style are considered as different paragraphs', | ||
| slug: 'breaklines-head-fallback', | ||
| html: `<html><blockquote><p>first line</p><br><br></blockquote></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| ]; | ||
|
|
||
| for (const c of middleEllipsizeCases) { | ||
| test(c.name, async ({ page }) => { | ||
| await gotoTestEllipsize(page); | ||
| await setValue(page, c.html); | ||
| await setNumberOfLines(page, c.numberOfLines); | ||
| await setMode(page, 'middle'); | ||
|
|
||
| await expect(displayLocator(page)).toHaveScreenshot( | ||
| `ellipsize-${c.slug}-middle.png` | ||
| ); | ||
| }); | ||
| } | ||
| }); | ||
|
|
||
| test.describe('EnrichedText ellipsize - recomputes on style change', () => { | ||
| type StyleChangeCase = EllipsizeCase & { override: OverrideKey }; | ||
|
|
||
| const styleChangeCases: StyleChangeCase[] = [ | ||
| { | ||
| name: 'recomputes when the text style (fontSize, lineHeight) changes', | ||
| slug: 'style-fontsize', | ||
| override: 'style', | ||
| html: LOREM_IPSUM, | ||
| numberOfLines: 3, | ||
| }, | ||
| { | ||
| name: 'recomputes when the heading font sizes in htmlStyle change', | ||
| slug: 'htmlstyle-heading-fontsize', | ||
| override: 'headings', | ||
| html: `<html><h4>A fairly long level four heading that wraps onto more lines</h4></html>`, | ||
| numberOfLines: 2, | ||
| }, | ||
| { | ||
| name: 'recomputes when the ordered list marginLeft in htmlStyle changes', | ||
| slug: 'htmlstyle-ol-marginleft', | ||
| override: 'ol', | ||
| html: | ||
| `<html><ol><li>first item that is reasonably long and wraps to a new line</li>` + | ||
| `<li>second item also long enough to wrap onto another line</li>` + | ||
| `<li>third item that is long enough to overflow the given lines</li></ol></html>`, | ||
| numberOfLines: 3, | ||
| }, | ||
| { | ||
| name: 'recomputes when the blockquote gapWidth in htmlStyle changes', | ||
| slug: 'htmlstyle-blockquote-gapwidth', | ||
| override: 'blockquote', | ||
| html: `<html><blockquote><p>this is a pretty long blockquote - a different block style paragraph, long enough to overflow in the given number of lines.</p></blockquote></html>`, | ||
| numberOfLines: 3, | ||
| }, | ||
| ]; | ||
|
|
||
| for (const c of styleChangeCases) { | ||
| test(c.name, async ({ page }) => { | ||
| await gotoTestEllipsize(page); | ||
| await setValue(page, c.html); | ||
| await setNumberOfLines(page, c.numberOfLines); | ||
| await setMode(page, 'tail'); | ||
|
|
||
| await toggleOverride(page, c.override); | ||
|
|
||
| await expect(displayLocator(page)).toHaveScreenshot( | ||
| `ellipsize-${c.slug}-recompute.png` | ||
| ); | ||
| }); | ||
| } | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -234,7 +234,8 @@ function App() { | |
| ?.getHTML() | ||
| .then((html) => { | ||
| setEnrichedTextValue(html); | ||
| ref.current?.setValue(''); | ||
| // temporary for making the testing easier | ||
| // ref.current?.setValue(''); | ||
|
hejsztynx marked this conversation as resolved.
Comment on lines
+241
to
+242
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reminder: uncomment it before merging |
||
| }) | ||
| .catch((error: unknown) => { | ||
| setEnrichedTextValue(''); | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.