Replace letters in text when copying untranslated text

In CSS, .someclass { text-transform: uppercase }

converts all text with a class someclass

to uppercase, but when I select the text, copy and paste it into a text editor or email, the letters keep the original code. But CSS does not support transformations other than alphabetic as defined in Unicode. Comments and answers to my previous question Showing one letter as another on the page when copying untransformed text is recommended to suck it and use JavaScript because it cannot be done with CSS alone. (This will require some discernible notification that scripts are not being applied, such as the CSS that is hidden when the script is run.)

In JavaScript without Flash, how can I replace characters in all text nodes, but the clipboard and search do not reflect the transformation? For example, I may need to change r

to w

, so what is ruby wings

displayed as wuby wings

, but by selecting text, copying and pasting into notepad, you get ruby wings

and Ctrl + F ruby

finds that.

I would save the original text somewhere, copy the copy events, count the characters in the selected text, and copy the same range from the original text. But it doesn't help with Ctrl + F. And the answers to How to copy to clipboard in JavaScript? recommend using Zero Clipboard which relies on Adobe Flash Player not installed in mobile browsers or libre browsers. Also, oncopy is non-standard at the time of this writing. Or should I also suck it and use Flash and then copy and find the wrong thing to work without Flash?

+3


source to share


2 answers


Perhaps not the solution you were looking for, but have you considered creating a custom font? A quick Google search and you'll come up with quite a few options for this ...



0


source


script needs to look for text nodes for matching letters, but skip text nodes on elements that don't appear as text, like <style>

and <script>

. Then make the original letter invisible but copyable and generate a replacement letter with CSS generated content.

To keep an invisible element copied in Firefox, you cannot use visibility: hidden

or display: none

. Use instead opacity: 0

. Then use pointer-events: none

to make it invisible and position: absolute

to suppress the space it took.

In fact, it takes three elements to get all the behaviors span

:

  • fuddinner

    hides the original letter
  • fudduc

    / fuddlc

    generates a new email
  • fuddouter

    suppresses the word break before a new letter


Work performed:

function classcontains(hayel, needle) {
    "use strict";
    needle = " " + needle + " ";
    var hayclass = " " + hayel.className + " ";
    return hayclass.replace(/[\n\t\r]/g, " ").indexOf(needle) > -1;
}

function fuddize(root) {
    "use strict";
    var textNodes = [];
    var contains = {}.hasOwnProperty;

    var blacklist = {
        br:1, hr:1,
        script:1, style:1, img:1, video:1, audio:1, canvas:1, svg:1, map:1, object:1,
        input:1, textarea:1, select:1, option:1, optgroup: 1, button:1
    };
    var replacements = [
        ["R","fudduc"], ["r","fuddlc"], ["L","fudduc"], ["l","fuddlc"]
    ];
    var outerclassname = "fuddouter";
    var innerclassname = "fuddinner";

    function addTextNodesInEl(el) {
        var tag = el.nodeName.toLowerCase();
        if (contains.call(blacklist, tag)
            || classcontains(el, innerclassname)) {
            console.log("Skipping "+tag);
            return;
        }
        for (var i = 0; i < el.childNodes.length; i++) {
            var n = el.childNodes[i];
            if (n.nodeType == Node.TEXT_NODE) {
                textNodes.push(n);
            }
        }
    }
    
    function fuddize_node(n) {
        var i = 0;
        while (i < replacements.length) {
            var needle = replacements[i][0];
            var txt = n.nodeValue;
            var idx = txt.indexOf(needle);
            if (idx < 0) {
                i = i + 1;
                continue;
            }
            var lpart = txt.substring(0, idx);
            var rpart = txt.substring(idx + needle.length);
            var papa = n.parentNode;
            if (lpart !== "") {
                var lnode = document.createTextNode(lpart);
                papa.insertBefore(lnode, n);
                fuddize_node(lnode);
            }
            var outerel = document.createElement("span");
            outerel.className = outerclassname;
            var midel = document.createElement("span");
            midel.className = replacements[i][1];
            var innerel = document.createElement("span");
            innerel.className = innerclassname;
            innerel.appendChild(document.createTextNode(needle));
            midel.appendChild(innerel);
            outerel.appendChild(midel);
            papa.insertBefore(outerel, n);
            n.nodeValue = rpart;
        }
    }

    if (!document.querySelectorAll) return false;
    var els = root.querySelectorAll('*');
    [].forEach.call(els, addTextNodesInEl);
    [].forEach.call(textNodes, fuddize_node);
}

function fuddize_body() {
    fuddize(document.body);
}

document.addEventListener('DOMContentLoaded', fuddize_body);
      

body { max-width: 32em; padding: 1em; line-height: 1.6; margin: 0 auto }
h1,h2,h3 { line-height: 1.2 }
h1 { margin-top: 0 }

.fuddinner { position: absolute; opacity: 0; pointer-events: none }
.fudduc:after { content: "W"; }
.fuddlc:after { content: "w"; }
.fuddouter { white-space: nowrap; }
      

<h1>Lorem Ipsum</h1>
<p>
Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure.
</p>
      

Run code


0


source







All Articles