Bug 1833284 - Do not wrap text conversion of event descriptions. r=mkmelin
Differential Revision: https://phabricator.services.mozilla.com/D178571 --HG-- extra : amend_source : 7d4291888e540c9f03380fb8f4bf316f8a948809
This commit is contained in:
Родитель
6c196999d2
Коммит
c4c8de57ad
|
@ -1560,8 +1560,9 @@ function saveDialog(item) {
|
|||
|
||||
// The editor gives us output wrapped in a body tag. We don't really want
|
||||
// that, so strip it. (Yes, it's a regex with HTML, but a _very_ specific
|
||||
// one.)
|
||||
item.descriptionHTML = editorOutput.replace(/^<body>(.+)<\/body>$/, "$1");
|
||||
// one.) We use the `s` flag to match across newlines in case there's a
|
||||
// <pre/> tag, in which case <br/> will not be inserted.
|
||||
item.descriptionHTML = editorOutput.replace(/^<body>(.+)<\/body>$/s, "$1");
|
||||
}
|
||||
|
||||
// Event Status
|
||||
|
|
|
@ -421,13 +421,13 @@ calItemBase.prototype = {
|
|||
set descriptionHTML(html) {
|
||||
if (html) {
|
||||
// We need to output a plaintext version of the description, even if we're
|
||||
// using the ALTREP parameter.
|
||||
// using the ALTREP parameter. We use the "preformatted" option in case
|
||||
// the HTML contains a <pre/> tag with newlines.
|
||||
let mode =
|
||||
Ci.nsIDocumentEncoder.OutputDropInvisibleBreak |
|
||||
Ci.nsIDocumentEncoder.OutputWrap |
|
||||
Ci.nsIDocumentEncoder.OutputLFLineBreak |
|
||||
Ci.nsIDocumentEncoder.OutputBodyOnly;
|
||||
let text = gParserUtils.convertToPlainText(html, mode, 80);
|
||||
Ci.nsIDocumentEncoder.OutputPreformatted;
|
||||
let text = gParserUtils.convertToPlainText(html, mode, 0);
|
||||
|
||||
this.setProperty("DESCRIPTION", text);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ support-files = data/**
|
|||
[browser_attendeesDialogRemove.js]
|
||||
[browser_attendeesDialogUpdate.js]
|
||||
[browser_eventDialog.js]
|
||||
[browser_eventDialogDescriptionEditor.js]
|
||||
[browser_eventDialogEditButton.js]
|
||||
[browser_eventDialogModificationPrompt.js]
|
||||
[browser_utf8.js]
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { CalEvent } = ChromeUtils.import("resource:///modules/CalEvent.jsm");
|
||||
const { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
|
||||
|
||||
add_setup(async function() {
|
||||
await CalendarTestUtils.setCalendarView(window, "day");
|
||||
CalendarTestUtils.goToDate(window, 2023, 2, 18);
|
||||
});
|
||||
|
||||
add_task(async function testPastePreformattedWithLinebreak() {
|
||||
const calendar = CalendarTestUtils.createCalendar();
|
||||
|
||||
// Create an event which currently has no description.
|
||||
const event = await calendar.addItem(
|
||||
new CalEvent(CalendarTestUtils.dedent`
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:An event
|
||||
DTSTART:20230218T100000Z
|
||||
DTEND:20230218T110000Z
|
||||
END:VEVENT
|
||||
`)
|
||||
);
|
||||
|
||||
// Remember event details so we can refetch it after editing.
|
||||
const eventId = event.id;
|
||||
const eventModified = event.lastModifiedTime;
|
||||
|
||||
// Sanity check.
|
||||
Assert.equal(event.descriptionHTML, null, "event should not have an HTML description");
|
||||
Assert.equal(event.descriptionText, null, "event should not have a text description");
|
||||
|
||||
// Open our event for editing.
|
||||
const { dialogWindow: eventWindow, iframeDocument } = await CalendarTestUtils.dayView.editEventAt(
|
||||
window,
|
||||
1
|
||||
);
|
||||
|
||||
const editor = iframeDocument.getElementById("item-description");
|
||||
editor.focus();
|
||||
|
||||
const expectedHTML =
|
||||
"<pre><code>This event is one which includes\nan explicit linebreak inside a pre tag.</code></pre>";
|
||||
|
||||
// Create a paste which includes HTML data, which the editor will recognize as
|
||||
// HTML and paste with formatting by default.
|
||||
const stringData = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
stringData.data = expectedHTML;
|
||||
|
||||
const transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
|
||||
transferable.init(null);
|
||||
transferable.addDataFlavor("text/html");
|
||||
transferable.setTransferData("text/html", stringData);
|
||||
Services.clipboard.setData(transferable, null, Ci.nsIClipboard.kGlobalClipboard);
|
||||
|
||||
// Paste.
|
||||
EventUtils.synthesizeKey("v", { accelKey: true }, eventWindow);
|
||||
|
||||
await CalendarTestUtils.items.saveAndCloseItemDialog(eventWindow);
|
||||
|
||||
await TestUtils.waitForCondition(async () => {
|
||||
const item = await calendar.getItem(eventId);
|
||||
return item.lastModifiedTime != eventModified;
|
||||
});
|
||||
|
||||
const editedEvent = await calendar.getItem(eventId);
|
||||
|
||||
// Verify that the description has been set appropriately. There should be no
|
||||
// change to the HTML, which is preformatted, and the text description should
|
||||
// include a linebreak in the same place as the HTML.
|
||||
Assert.equal(editedEvent.descriptionHTML, expectedHTML, "HTML description should match input");
|
||||
Assert.equal(
|
||||
editedEvent.descriptionText,
|
||||
"This event is one which includes\nan explicit linebreak inside a pre tag.",
|
||||
"text description should include linebreak"
|
||||
);
|
||||
|
||||
CalendarTestUtils.removeCalendar(calendar);
|
||||
});
|
||||
|
||||
add_task(async function testTypeLongTextWithLinebreaks() {
|
||||
const calendar = CalendarTestUtils.createCalendar();
|
||||
|
||||
// Create an event which currently has no description.
|
||||
const event = await calendar.addItem(
|
||||
new CalEvent(CalendarTestUtils.dedent`
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:An event
|
||||
DTSTART:20230218T100000Z
|
||||
DTEND:20230218T110000Z
|
||||
END:VEVENT
|
||||
`)
|
||||
);
|
||||
|
||||
// Remember event details so we can refetch it after editing.
|
||||
const eventId = event.id;
|
||||
const eventModified = event.lastModifiedTime;
|
||||
|
||||
// Sanity check.
|
||||
Assert.equal(event.descriptionHTML, null, "event should not have an HTML description");
|
||||
Assert.equal(event.descriptionText, null, "event should not have a text description");
|
||||
|
||||
// Open our event for editing.
|
||||
const {
|
||||
dialogWindow: eventWindow,
|
||||
iframeDocument,
|
||||
iframeWindow,
|
||||
} = await CalendarTestUtils.dayView.editEventAt(window, 1);
|
||||
|
||||
const editor = iframeDocument.getElementById("item-description");
|
||||
editor.focus();
|
||||
|
||||
// Insert text with several long lines and explicit linebreaks.
|
||||
const firstLine =
|
||||
"This event is pretty much just plain text, albeit it has some pretty long lines so that we can ensure that we don't accidentally wrap it during conversion.";
|
||||
EventUtils.sendString(firstLine, iframeWindow);
|
||||
EventUtils.sendKey("RETURN", iframeWindow);
|
||||
|
||||
const secondLine = "This line follows immediately after a linebreak.";
|
||||
EventUtils.sendString(secondLine, iframeWindow);
|
||||
EventUtils.sendKey("RETURN", iframeWindow);
|
||||
EventUtils.sendKey("RETURN", iframeWindow);
|
||||
|
||||
const thirdLine =
|
||||
"And one after a couple more linebreaks, for good measure. It might as well be a fairly long string as well, just so we're certain.";
|
||||
EventUtils.sendString(thirdLine, iframeWindow);
|
||||
|
||||
await CalendarTestUtils.items.saveAndCloseItemDialog(eventWindow);
|
||||
|
||||
await TestUtils.waitForCondition(async () => {
|
||||
const item = await calendar.getItem(eventId);
|
||||
return item.lastModifiedTime != eventModified;
|
||||
});
|
||||
|
||||
const editedEvent = await calendar.getItem(eventId);
|
||||
|
||||
// Verify that the description has been set appropriately. The HTML should
|
||||
// match the input and use <br> as a linebreak, while the text should not be
|
||||
// wrapped and should use \n as a linebreak.
|
||||
Assert.equal(
|
||||
editedEvent.descriptionHTML,
|
||||
`${firstLine}<br>${secondLine}<br><br>${thirdLine}`,
|
||||
"HTML description should match input with <br> for linebreaks"
|
||||
);
|
||||
Assert.equal(
|
||||
editedEvent.descriptionText,
|
||||
`${firstLine}\n${secondLine}\n\n${thirdLine}`,
|
||||
"text description should match input with linebreaks"
|
||||
);
|
||||
|
||||
CalendarTestUtils.removeCalendar(calendar);
|
||||
});
|
Загрузка…
Ссылка в новой задаче