Skip to content

Commit bac39d2

Browse files
mihnitamickaelistria
authored andcommitted
Fix #467: Paste as HTML collapses white spaces
1 parent ede9279 commit bac39d2

File tree

3 files changed

+49
-29
lines changed

3 files changed

+49
-29
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/HTMLWriter.java

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public HTMLWriter(StyledText styledText, int start, int length) {
3737
@Override
3838
public void close() {
3939
if (!isClosed()) {
40-
write("</div>\n");
41-
write("</div>\n");
40+
write("</div>");
41+
write("</div>");
4242
super.close();
4343
}
4444
}
@@ -52,29 +52,27 @@ void writeHeader() {
5252
appendStyle(innerDivStyle, "color:", styledText.getForeground(), ";");
5353
appendStyle(innerDivStyle, "background-color:", styledText.getBackground(), ";");
5454

55-
appendStyle(outerDivStyle, "padding-left:", styledText.getLeftMargin(), "px;");
56-
appendStyle(outerDivStyle, "padding-top:", styledText.getTopMargin(), "px;");
57-
appendStyle(outerDivStyle, "padding-right:", styledText.getRightMargin(), "px;");
58-
appendStyle(outerDivStyle, "padding-bottom:", styledText.getBottomMargin(), "px;");
55+
appendStyle(outerDivStyle, "padding:"
56+
+ styledText.getTopMargin() + "px "
57+
+ styledText.getRightMargin() + "px "
58+
+ styledText.getBottomMargin() + "px "
59+
+ styledText.getLeftMargin() + "px;");
5960

6061
String language = appendFont(innerDivStyle, styledText.getFont(), 0);
6162

62-
// Using wrapIndent like this messes up the line background (if set).
63-
// int wrapIndent = styledText.getWrapIndent();
64-
// if (wrapIndent != 0) {
65-
// appendStyle(globalStyle, "padding-left:", wrapIndent, "px;");
66-
// }
67-
// int indent = styledText.getIndent() - wrapIndent;
6863
int indent = styledText.getIndent();
6964
if (indent != 0) {
7065
appendStyle(innerDivStyle, "text-indent:", indent, "px;");
7166
}
7267

73-
// TODO?
74-
// int lineSpacing = styledText.getLineSpacing();
75-
76-
if (!styledText.getWordWrap()) {
77-
appendStyle(innerDivStyle, "white-space:nowrap;");
68+
if (styledText.getWordWrap()) {
69+
// Sequences of white space are preserved.
70+
// Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
71+
appendStyle(innerDivStyle, "white-space:pre-wrap;");
72+
} else {
73+
// Sequences of white space are preserved.
74+
// Lines are only broken at newline characters in the source and at <br> elements.
75+
appendStyle(innerDivStyle, "white-space:pre;");
7876
}
7977

8078
appendAlignAndJustify(innerDivStyle, styledText.getAlignment(), styledText.getJustify());
@@ -83,17 +81,11 @@ void writeHeader() {
8381
appendStyle(innerDivStyle, "direction:rtl;");
8482
}
8583

86-
// Do we have any use for these?
87-
// Color selectionBackground = styledText.getSelectionBackground();
88-
// Color selectionForeground = styledText.getSelectionForeground();
89-
// int tabs = styledText.getTabs();
90-
// boolean blockSelection = styledText.getBlockSelection();
91-
92-
write("<div style='" + outerDivStyle + "'>\n");
84+
write("<div style='" + outerDivStyle + "'>");
9385
if (language == null || language.isEmpty()) {
94-
write("<div style='" + innerDivStyle + "'>\n");
86+
write("<div style='" + innerDivStyle + "'>");
9587
} else {
96-
write("<div lang='" + language + "' style='" + innerDivStyle + "'>\n");
88+
write("<div lang='" + language + "' style='" + innerDivStyle + "'>");
9789
}
9890
}
9991

@@ -102,7 +94,7 @@ public void writeLineDelimiter(String lineDelimiter) {
10294
if (isClosed()) {
10395
SWT.error(SWT.ERROR_IO);
10496
}
105-
write(lineDelimiter);
97+
// We don't write the newline, otherwise it would be rendered because of the `white-space:pre;`.
10698
}
10799

108100
@Override
@@ -117,8 +109,11 @@ String writeLineStart(Color lineBackground, int indent, int verticalIndent, int
117109
appendStyle(paragraphStyle, "text-indent:", indent, "px;");
118110
}
119111

120-
if (verticalIndent != 0) {
121-
appendStyle(paragraphStyle, "margin-top:", verticalIndent, "px;");
112+
if (verticalIndent == 0) {
113+
appendStyle(paragraphStyle, "margin:0;");
114+
} else {
115+
// Set the margin-top to verticalIndent, everything else zero.
116+
appendStyle(paragraphStyle, "margin:", verticalIndent, " 0 0 0;");
122117
}
123118

124119
if (paragraphStyle.length() == 0) {
@@ -131,6 +126,11 @@ String writeLineStart(Color lineBackground, int indent, int verticalIndent, int
131126
return "</p>";
132127
}
133128

129+
@Override
130+
void writeEmptyLine() {
131+
write("<br>");
132+
}
133+
134134
@Override
135135
String writeSpanStart(StyleRange style) {
136136
StringBuilder spanStyle = new StringBuilder();

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/RTFWriter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ String writeLineStart(Color lineBackground, int indent, int verticalIndent, int
135135
return lineBackground == null ? "" : "}";
136136
}
137137

138+
@Override
139+
void writeEmptyLine() {
140+
// Do nothing. RTF does not need special treatment for empty paragraph.
141+
}
142+
138143
@Override
139144
String writeSpanStart(StyleRange style) {
140145
write("{\\cf");

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextWriterBase.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ void writeStyledLine(String line, int lineOffset, int ranges[], StyleRange[] sty
149149
int endOffset = startOffset + super.getCharCount();
150150
int lineEndOffset = Math.min(lineLength, endOffset - lineOffset);
151151

152+
int outTextLen = 0; // collect the length of the text we output (unescaped)
152153
for (int i = 0; i < styles.length; i++) {
153154
StyleRange style = styles[i];
154155
int start, end;
@@ -173,6 +174,7 @@ void writeStyledLine(String line, int lineOffset, int ranges[], StyleRange[] sty
173174
// style starting beyond end of write range or end of line
174175
// is guarded against above.
175176
writeEscaped(line, lineIndex, start);
177+
outTextLen += start - lineIndex;
176178
lineIndex = start;
177179
}
178180
// write styled text
@@ -183,6 +185,7 @@ void writeStyledLine(String line, int lineOffset, int ranges[], StyleRange[] sty
183185
// guard against invalid styles and let style processing continue
184186
copyEnd = Math.max(copyEnd, lineIndex);
185187
writeEscaped(line, lineIndex, copyEnd);
188+
outTextLen += copyEnd - lineIndex;
186189

187190
writeSpanEnd(atSpanEnd);
188191

@@ -192,6 +195,11 @@ void writeStyledLine(String line, int lineOffset, int ranges[], StyleRange[] sty
192195
// write the unstyled text at the end of the line
193196
if (lineIndex < lineEndOffset) {
194197
writeEscaped(line, lineIndex, lineEndOffset);
198+
outTextLen += lineEndOffset - lineIndex;
199+
}
200+
201+
if (outTextLen == 0) {
202+
writeEmptyLine();
195203
}
196204

197205
writeLineEnd(atLineEnd);
@@ -231,6 +239,13 @@ void writeLineEnd(String prepared) {
231239
write(prepared);
232240
}
233241

242+
/**
243+
* Invoked at the end of each line, writeLineEnd, if there was no text output.
244+
*
245+
* <p>This is needed for HTML, which does not render empty paragraphs.</p>
246+
*/
247+
abstract void writeEmptyLine();
248+
234249
/**
235250
* Invoked at the beginning of each styled span fragment in the original widget.
236251
*

0 commit comments

Comments
 (0)