Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/static/css/iframe_editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ html.outer-editor, html.inner-editor {

#innerdocbody a {
color: #2e96f3;
white-space: normal;
word-wrap: break-word;
overflow-wrap: break-word;
}
#innerdocbody.authorColors [class^='author-'] a {
color: inherit;
Expand Down
53 changes: 53 additions & 0 deletions src/tests/frontend-new/specs/url_wrapping.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {expect, test} from "@playwright/test";
import {clearPadContent, getPadBody, goToNewPad, writeToPad} from "../helper/padHelper";

test.beforeEach(async ({page}) => {
await goToNewPad(page);
});

// Regression test for https://github.com/ether/etherpad/issues/7894
test.describe('long URL wrapping in pad editor', function () {
test('long URLs should wrap instead of overflowing the editor', async function ({page}) {
const padBody = await getPadBody(page);
await clearPadContent(page);

// The fix for #7894 ensures #innerdocbody a has white-space: normal,
// word-wrap: break-word, and overflow-wrap: break-word to override
// the global a { white-space: nowrap } from pad.css.
const longUrl =
'https://example.com/this/is/a/very/long/test/url/for/etherpad/regression/' +
'issue/7894/wrapping/behavior/long/urls/should/wrap/instead/of/overflowing/' +
'to/the/right/and/causing/awkward/rendering';

// Write a short word on line 1, then the long URL on line 2
await writeToPad(page, 'hello\n' + longUrl + ' ');

// Verify the URL became a clickable link
const link = padBody.locator('a');
await expect(link).toHaveCount(1);
await expect(link).toHaveAttribute('href', longUrl);

// Verify wrapping CSS properties are applied (the direct fix for #7894)
const cssProps = await link.evaluate((el) => {
const style = window.getComputedStyle(el);
return {
whiteSpace: style.whiteSpace,
wordWrap: style.wordWrap,
overflowWrap: style.overflowWrap,
};
});

expect(cssProps.whiteSpace).toBe('normal');
expect(cssProps.wordWrap).toBe('break-word');
expect(cssProps.overflowWrap).toBe('break-word');

// The short line should be one line tall, the wrapped URL line should
// be much taller — this is the observable behavior that wrapping works.
const lines = padBody.locator('> div');
await expect(lines).toHaveCount(2);

const shortLineHeight = await lines.nth(0).evaluate((el) => el.getBoundingClientRect().height);
const longLineHeight = await lines.nth(1).evaluate((el) => el.getBoundingClientRect().height);
expect(longLineHeight).toBeGreaterThan(shortLineHeight * 1.5);
});
});
Loading