Skip to content

Commit db2b250

Browse files
committed
Fix copy/paste behavior when using Firefox or Edge (#51)
1 parent 3bd0195 commit db2b250

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

src/highlightjs-line-numbers.js

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
var TABLE_NAME = 'hljs-ln',
77
LINE_NAME = 'hljs-ln-line',
8+
NUMBERS_CONTAINER_NAME = 'hljs-ln-numbers-container',
9+
CODE_CONTAINER_NAME = 'hljs-ln-code-container',
810
CODE_BLOCK_NAME = 'hljs-ln-code',
911
NUMBERS_BLOCK_NAME = 'hljs-ln-numbers',
1012
NUMBER_LINE_NAME = 'hljs-ln-n',
@@ -25,8 +27,8 @@
2527
var css = d.createElement('style');
2628
css.type = 'text/css';
2729
css.innerHTML = format(
28-
'.{0}{border-collapse:collapse}' +
29-
'.{0} td{padding:0}' +
30+
'.{0} table{float:left}' +
31+
'.{0} table td{padding:0}' +
3032
'.{1}:before{content:attr({2})}',
3133
[
3234
TABLE_NAME,
@@ -65,6 +67,11 @@
6567

6668
async(function () {
6769
element.innerHTML = lineNumbersInternal(element, options);
70+
// adjust left margin of code div as line numbers is a float left dom element
71+
var codeMargin = element.querySelector('.' + NUMBERS_CONTAINER_NAME).offsetWidth;
72+
var codeContainerStyle = 'margin-left:' + codeMargin + 'px';
73+
var codeContainer = element.querySelector('.' + CODE_CONTAINER_NAME);
74+
codeContainer.style.cssText = codeContainerStyle;
6875
});
6976
}
7077

@@ -101,30 +108,57 @@
101108
}
102109

103110
if (lines.length > firstLineIndex) {
104-
var html = '';
111+
// Previous implementation was using a single table element
112+
// to render the line numbers and the lines of code.
113+
// But to overcome an annoying copy/paste behavior when using Firefox or Edge
114+
// (see https://github.com/wcoder/highlightjs-line-numbers.js/issues/51)
115+
// the following workaround is used while obtaining the exact same rendering
116+
// as before:
117+
// 1. render the lines number in a table with single column
118+
// 2. render the lines of code in a div
119+
// 3. wrap these in a div and make the table float left
120+
// 4. adjust the left margin of the code div once inserted in the dom
121+
var htmlLinesNumber = '';
122+
var htmlCode = '';
105123

106124
for (var i = 0, l = lines.length; i < l; i++) {
107-
html += format(
108-
'<tr>' +
109-
'<td class="{0}">' +
110-
'<div class="{1} {2}" {3}="{5}"></div>' +
111-
'</td>' +
112-
'<td class="{4}">' +
113-
'<div class="{1}">{6}</div>' +
125+
htmlLinesNumber += format(
126+
'<tr class="{0} {1}" {3}="{4}">' +
127+
'<td>' +
128+
'<div class="{2}" {3}="{4}"></div>' +
114129
'</td>' +
115130
'</tr>',
116131
[
117-
NUMBERS_BLOCK_NAME,
118132
LINE_NAME,
133+
NUMBERS_BLOCK_NAME,
119134
NUMBER_LINE_NAME,
120135
DATA_ATTR_NAME,
136+
i + 1
137+
]);
138+
139+
htmlCode += format(
140+
'<div class="{0} {1}" {2}="{3}">{4}</div>',
141+
[
142+
LINE_NAME,
121143
CODE_BLOCK_NAME,
144+
DATA_ATTR_NAME,
122145
i + 1,
123146
lines[i].length > 0 ? lines[i] : ' '
124147
]);
125148
}
126149

127-
return format('<table class="{0}">{1}</table>', [ TABLE_NAME, html ]);
150+
return format(
151+
'<div class="{0}">' +
152+
'<table class="{1}">{2}</table>' +
153+
'<div class="{3}">{4}</div>' +
154+
'</div>',
155+
[
156+
TABLE_NAME,
157+
NUMBERS_CONTAINER_NAME,
158+
htmlLinesNumber,
159+
CODE_CONTAINER_NAME,
160+
htmlCode
161+
]);
128162
}
129163

130164
return inputHtml;

0 commit comments

Comments
 (0)