Reputation: 67
I need to process selected(highlighted with mouse) text in html page. But if I'm selecting ordered list <ol></ol> elements I'm losing numbering information. Maybe someone can help me with this information extraction, because if I select and copy+paste selection to text editor - I see those numbers. Function used for html fragment selection:
function getSelectionHtml() {
var html = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
}
else if (typeof document.selection != "undefined") {
if (document.selection.type == "Text") {
html = document.selection.createRange().htmlText;
}
}
return html;
}
Complete fiddle example : https://jsfiddle.net/t2mhcbyo/3/
Upvotes: 4
Views: 2598
Reputation: 6220
If you looking the Javascript free solution, that allows user to select and copy text with list numbers or bullets (but not highlight), keep reading.
Your CSS and HTML should look like this:
li {
&::marker {
content: attr(counter);
}
>:first-child {
position: absolute;
left: -99rem;
white-space: pre;
}
}
here is your list with list item you can copy
<ol>
<li counter="1. "><span aria-hidden="true">1. </span>Carefully read the title, abstract, and introduction </li>
<li counter="2. "><span aria-hidden="true">2. </span>Read the section and sub-section headings, but ignore everything else </li>
<li counter="3. "><span aria-hidden="true">3. </span>Read the conclusions </li>
<li counter="4. "><span aria-hidden="true">4. </span>Glance over the references, mentally ticking off the ones you’ve already read </li>
</ol>
You can remove ::marker
CSS preudo-class and counter
attribute on <li>
, they are only needed if you need to replace standard numbers/bullets and you can not do that by the means of list-style-type
. But you will need to find the way to add the space between the number and the list item text.
Now, then user select the text they actually copy the text from the span that is hinged from the view using >:first-child
CSS rule, and by aria-hidden
attribute from screen readers.
So this solution looks, feels and sounds as nothing ever happened but now you can copy the all you see. No penalty of Accessibility and WYSIFYG through and through.
For the context, browsers render bullets and list numbers using ::marker
pseudo-element content
property, and according to MDN:
CSS-generated content is not included in the DOM.
for that reason they can not be selected.
Upvotes: 0
Reputation: 2036
Updated fiddle here. The main problem is that you are not, in fact, actually selecting the numbers. They cannot be selected. (You notice they don't get highlighted).
I suspect that when you are copying the list into a 'text' editor, you are actually copying html (which is an ordered list that has numbers), which the editor displays as an ordered list. When you copy into a plain text editor like notepad, wordpad, or just remove formatting, it will return to just the highlighted test.
To get the number at the start of the list items, you can store the information directly in the <li>
tags.
<li index="3">
Then, when you select the highlighted html, you can use a regex string replace to change the index to a number.
Example regex:
html = html.replace(/<li\ index="([0-9]+)">/g, "<li>$1. ");
<li index="3">
becomes <li>3.
This replaces the start list item tag that contains index information with a tag that has no information, but has a number at the start of the list.
Issue: This method puts a number at the start of every line, regardless of how much of the line is actually highlighted. You might be able to modify the regex to only replace some of the index="#"
's.
Upvotes: 2