Making line numbers uncopyable

后端 未结 4 1038
情书的邮戳
情书的邮戳 2021-01-02 04:20

I\'m working on adding line number support to Rainbow, a syntax highlighter, but I can\'t figure out how to make the line numbers uncopyable.

Disabling selection via

相关标签:
4条回答
  • 2021-01-02 04:35

    I would just add a regular list.

    if (window.Rainbow) window.Rainbow.linecount = (function(Rainbow) {
        Rainbow.onHighlight(function(block) {
            var lines = $(block).text().split('\n');
            var $lines = $('<ul class="lines"/>');
            for (var i = 0, len = lines.length; i < len; i++) {
                $lines.append('<li class="line"'+ i +'>'+ i +'</li>');
            }
            $(block).before($lines);
        });
    })(window.Rainbow);​
    

    And CSS:

    .lines {
        float: left;
        padding-right: 1.5em;
        padding-left: .5em;
    }
    

    So now you can select just the code if you highlight carefully.

    Demo: http://jsfiddle.net/elclanrs/CjJLv/18/

    0 讨论(0)
  • 2021-01-02 04:36

    Okay, the easiest way in compliant browsers, and, sadly, not reliable cross-browser, is to use generated content (I've removed the various parts where index was being added to textual content in the plug-in, and used the following (at the end of the CSS) to implement un-copyable text:

    table.rainbow {
        counter-reset: line;
    }
    
    table.rainbow tbody tr td:first-child {
        counter-increment: line;
    }
    
    table.rainbow tr td:first-child::before {
        content: counter(line);
    }
    

    JS Fiddle demo.

    This does, though, have some rather large flaws (the cross-browser unfriendly approach being the biggest), so I'll try for something better...

    0 讨论(0)
  • 2021-01-02 04:55

    David Thomas's answer is perfect for line numbers. More generally, if you have other text you don't want to be copied, you can have it as generated content:

    <style>#uniqueid::before { content: 'TEXT GOES HERE'; }</style>
    <span id="uniqueid"></span>
    

    But it's ugly to have to embed text in your CSS, so you can refine this using CSS attr() to read the text from an attribute in the HTML (as suggested by pimvdb):

    <style>[data-nocopy]::before { content: attr(data-nocopy); }</style>
    <span data-nocopy="TEXT GOES HERE"></span>
    <span data-nocopy="AND HERE"></span>
    

    Demo: http://jsbin.com/fob/1/edit

    This works in Firefox, Safari, and Chrome due to 21-year-old(!) bugs in selecting generated content:

    • https://bugzilla.mozilla.org/show_bug.cgi?id=12460
    • https://bugs.webkit.org/show_bug.cgi?id=7562
    • https://bugs.chromium.org/p/chromium/issues/detail?id=80466

    But in old IE (< 8) the text will be completely invisible; in newer IE it should be visible but may well be copyable. In general don't use this technique for anything critical, as these bugs might get fixed one day...

    And use sparingly, as this can be very user-hostile.

    0 讨论(0)
  • 2021-01-02 05:01

    You could display each line number as a sequence of <img>s.

    0 讨论(0)
提交回复
热议问题