Skip to content

Commit 948d344

Browse files
committed
Fix microsoft#35954. Use nbsp when copying html into clipboard
1 parent ac80d49 commit 948d344

2 files changed

Lines changed: 97 additions & 11 deletions

File tree

src/vs/editor/common/modes/textToHtmlTokenizer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export function tokenizeLineToHTML(text: string, viewLineTokens: IViewLineTokens
7777
partContent += '&#8203';
7878
break;
7979

80+
case CharCode.Space:
81+
partContent += '&nbsp';
82+
break;
83+
8084
default:
8185
partContent += String.fromCharCode(charCode);
8286
}

src/vs/editor/test/common/modes/textToHtmlTokenizer.test.ts

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
109109
[
110110
'<div>',
111111
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
112-
'<span style="color: #000000;"> </span>',
112+
'<span style="color: #000000;">&nbsp</span>',
113113
'<span style="color: #00ff00;">hello</span>',
114-
'<span style="color: #000000;"> </span>',
114+
'<span style="color: #000000;">&nbsp</span>',
115115
'<span style="color: #0000ff;text-decoration: underline;">world!</span>',
116116
'</div>'
117117
].join('')
@@ -122,9 +122,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
122122
[
123123
'<div>',
124124
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
125-
'<span style="color: #000000;"> </span>',
125+
'<span style="color: #000000;">&nbsp</span>',
126126
'<span style="color: #00ff00;">hello</span>',
127-
'<span style="color: #000000;"> </span>',
127+
'<span style="color: #000000;">&nbsp</span>',
128128
'<span style="color: #0000ff;text-decoration: underline;">w</span>',
129129
'</div>'
130130
].join('')
@@ -135,9 +135,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
135135
[
136136
'<div>',
137137
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
138-
'<span style="color: #000000;"> </span>',
138+
'<span style="color: #000000;">&nbsp</span>',
139139
'<span style="color: #00ff00;">hello</span>',
140-
'<span style="color: #000000;"> </span>',
140+
'<span style="color: #000000;">&nbsp</span>',
141141
'</div>'
142142
].join('')
143143
);
@@ -147,9 +147,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
147147
[
148148
'<div>',
149149
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">iao</span>',
150-
'<span style="color: #000000;"> </span>',
150+
'<span style="color: #000000;">&nbsp</span>',
151151
'<span style="color: #00ff00;">hello</span>',
152-
'<span style="color: #000000;"> </span>',
152+
'<span style="color: #000000;">&nbsp</span>',
153153
'</div>'
154154
].join('')
155155
);
@@ -158,9 +158,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
158158
tokenizeLineToHTML(text, lineTokens, colorMap, 4, 11, 4),
159159
[
160160
'<div>',
161-
'<span style="color: #000000;"> </span>',
161+
'<span style="color: #000000;">&nbsp</span>',
162162
'<span style="color: #00ff00;">hello</span>',
163-
'<span style="color: #000000;"> </span>',
163+
'<span style="color: #000000;">&nbsp</span>',
164164
'</div>'
165165
].join('')
166166
);
@@ -170,7 +170,7 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
170170
[
171171
'<div>',
172172
'<span style="color: #00ff00;">hello</span>',
173-
'<span style="color: #000000;"> </span>',
173+
'<span style="color: #000000;">&nbsp</span>',
174174
'</div>'
175175
].join('')
176176
);
@@ -193,6 +193,88 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
193193
].join('')
194194
);
195195
});
196+
test('tokenizeLineToHTML handle spaces #35954', () => {
197+
const text = ' Ciao hello world!';
198+
const lineTokens = new ViewLineTokens([
199+
new ViewLineToken(
200+
2,
201+
(
202+
(1 << MetadataConsts.FOREGROUND_OFFSET)
203+
) >>> 0
204+
),
205+
new ViewLineToken(
206+
6,
207+
(
208+
(3 << MetadataConsts.FOREGROUND_OFFSET)
209+
| ((FontStyle.Bold | FontStyle.Italic) << MetadataConsts.FONT_STYLE_OFFSET)
210+
) >>> 0
211+
),
212+
new ViewLineToken(
213+
9,
214+
(
215+
(1 << MetadataConsts.FOREGROUND_OFFSET)
216+
) >>> 0
217+
),
218+
new ViewLineToken(
219+
14,
220+
(
221+
(4 << MetadataConsts.FOREGROUND_OFFSET)
222+
) >>> 0
223+
),
224+
new ViewLineToken(
225+
15,
226+
(
227+
(1 << MetadataConsts.FOREGROUND_OFFSET)
228+
) >>> 0
229+
),
230+
new ViewLineToken(
231+
21,
232+
(
233+
(5 << MetadataConsts.FOREGROUND_OFFSET)
234+
| ((FontStyle.Underline) << MetadataConsts.FONT_STYLE_OFFSET)
235+
) >>> 0
236+
)
237+
]);
238+
const colorMap = [null!, '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff'];
239+
240+
assert.equal(
241+
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 21, 4),
242+
[
243+
'<div>',
244+
'<span style="color: #000000;">&nbsp&nbsp</span>',
245+
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
246+
'<span style="color: #000000;">&nbsp&nbsp&nbsp</span>',
247+
'<span style="color: #00ff00;">hello</span>',
248+
'<span style="color: #000000;">&nbsp</span>',
249+
'<span style="color: #0000ff;text-decoration: underline;">world!</span>',
250+
'</div>'
251+
].join('')
252+
);
253+
254+
assert.equal(
255+
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 17, 4),
256+
[
257+
'<div>',
258+
'<span style="color: #000000;">&nbsp&nbsp</span>',
259+
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
260+
'<span style="color: #000000;">&nbsp&nbsp&nbsp</span>',
261+
'<span style="color: #00ff00;">hello</span>',
262+
'<span style="color: #000000;">&nbsp</span>',
263+
'<span style="color: #0000ff;text-decoration: underline;">wo</span>',
264+
'</div>'
265+
].join('')
266+
);
267+
268+
assert.equal(
269+
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 3, 4),
270+
[
271+
'<div>',
272+
'<span style="color: #000000;">&nbsp&nbsp</span>',
273+
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">C</span>',
274+
'</div>'
275+
].join('')
276+
);
277+
});
196278

197279
});
198280

0 commit comments

Comments
 (0)