Monday, 15 June 2020

JavascriptString Trim By Converting to ByteArray and Using ByteLength


This method of trimming makes sure that non english characters length is properly accounted for when trimming the string.

It converts the string to UF8ByteArray, then checks the byteLength and build the final string.

<!DOCTYPE html>
<html>
<head>
    <title>This Is Where the Title Goes</title>
   
    <!--<meta charset="windows-1252"/>-->
    <meta charset="iso-8859-1"/>
   
</head>
<body>
    <p>Trims the string to provided length</p>
   
    <p><strong>French Original</strong></p>
    <p id="logFrO"></p>

    <p><strong>French Trimmed</strong></p>
    <p id="logFr"></p>

    <p><strong>French Short No Trim</strong></p>
    <p id="logFrSh"></p>

    <p><strong>Concat French Original + Long Trimmed</strong></p>
    <p id="logFrLong"></p>

    <p><strong>English Original</strong></p>
    <div id="logEngO"></div>

    <p><strong>English Trimmed</strong></p>
    <div id="logEng"></div>

    <script>
        var isNullOrUndefined = function(object){
            return object === undefined || object === null;
        }

        var hasValue = function(object){
            if(isNullOrUndefined(object)) return false;
            else if(typeof object === 'number' && isNaN(object)) return false;
            else if(typeof object === 'string' && object.trim() === "") return false;
            else if(!object) return false;
            return true;
        }

        var stringToUtf8ByteArray = function(str) {
            // TODO(user): Use native implementations if/when available
            var out = [], p = 0;
            for (var i = 0; i < str.length; i++) {
                var c = str.charCodeAt(i);
                if (c < 128) {
                    out[p++] = c;
                } else if (c < 2048) {
                    out[p++] = (c >> 6) | 192;
                    out[p++] = (c & 63) | 128;
                } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
                    // Surrogate Pair
                    c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
                    out[p++] = (c >> 18) | 240;
                    out[p++] = ((c >> 12) & 63) | 128;
                    out[p++] = ((c >> 6) & 63) | 128;
                    out[p++] = (c & 63) | 128;
                } else{
                    out[p++] = (c >> 12) | 224;
                    out[p++] = ((c >> 6) & 63) | 128;
                    out[p++] = (c & 63) | 128;
                }
            }
            return out;
        };

        var byteLength = function(str) {
            // returns the byte length of an utf8 string
            var s = str.length;
            for (var i=str.length-1; i>=0; i--) {
                var code = str.charCodeAt(i);
                if (code > 0x7f && code <= 0x7ff) s++;
                else if (code > 0x7ff && code <= 0xffff) s+=2;
                if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
            }
            return s;
        }

        var stringTrim = function(str, maxLength){
            if(!hasValue(str) || !hasValue(maxLength) || maxLength <= 0)
                return str;

            //convert to byte array
            var arr = stringToUtf8ByteArray(str);
            if(arr.length <= maxLength)
                return str;

            //slice upto maxLength
            var arrNew = arr.slice(0, maxLength);
            //check each char to make sure that french chars are properly picked
            var lengthChar = 0;
            var newVal = "";
            for (i=0; i<maxLength; i++){
                var singleChar = String.fromCharCode(arrNew[i]);
                lengthChar += byteLength(singleChar);
                if(lengthChar <= maxLength)
                    newVal += singleChar;
            }
            return newVal;
        }

        var french = "SVP remplacer 3 lumière de néons brûlées. Deux néons sont situés dans le bureau de la cliente et dans le secured desk room. Le dernier est une ampoule neon et c'est située dans le lobby. Le plafond est de hauteur standard. BH: lun-Ve 3";
        var x = '';
        var frenchShort = "Qu'est-ce que Lorem";
        var fenchLong = "Lorem Ipsum est tout simplement un texte factice de l'industrie de l'impression et de la composition. Lorem Ipsum est le texte factice standard de l'industrie depuis les années 1500, lorsqu'une imprimante inconnue a pris une cuisine de type et l'a brouillée pour créer un spécimen de livre. Il a survécu non seulement à cinq siècles, mais aussi au saut dans la composition électronique, demeurant essentiellement inchangé. Il a été popularisé dans les années 1960 avec la sortie de feuilles Letraset contenant des passages de Lorem Ipsum, et plus récemment avec des logiciels de PAO comme Aldus PageMaker incluant des versions de Lorem Ipsum.";
        var english = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
       
        var newFr = stringTrim(french, 200);
        document.getElementById('logFrO').innerHTML = '[' + french.length + '] ' + french;
        document.getElementById('logFr').innerHTML = '[' + newFr.length + '] ' + newFr;

        var newFrSh = stringTrim(frenchShort, 200);
        document.getElementById('logFrSh').innerHTML = '[' + frenchShort.length + '] ' + newFrSh;
       
        var newFrLong = stringTrim(french + '[LongDescription]' + fenchLong, 2000);
        document.getElementById('logFrLong').innerHTML = '[' + newFrLong.length + '] ' + newFrLong;
       
        var newEng = stringTrim(english, 200);
        document.getElementById('logEngO').innerHTML = '[' + english.length + ']' + english;
        document.getElementById('logEng').innerHTML = '[' + newEng.length + ']' + newEng;

    </script>
</body>
</html>