浏览代码

Replaced hexToByteArray with fromHex and byteArrayToHex with toHex. Switched displayFilesAsHTML operation to use template strings and introduced markup formatting method.

n1474335 8 年之前
父节点
当前提交
c460c2bf6b
共有 5 个文件被更改,包括 66 次插入103 次删除
  1. 1 1
      src/core/Ingredient.js
  2. 60 98
      src/core/Utils.js
  3. 2 2
      src/core/operations/BitwiseOp.js
  4. 2 2
      src/core/operations/IP.js
  5. 1 0
      src/web/OutputWaiter.js

+ 1 - 1
src/core/Ingredient.js

@@ -73,7 +73,7 @@ Ingredient.prepare = function(data, type) {
         case "byteArray":
             if (typeof data == "string") {
                 data = data.replace(/\s+/g, "");
-                return Utils.hexToByteArray(data);
+                return Utils.fromHex(data);
             } else {
                 return data;
             }

+ 60 - 98
src/core/Utils.js

@@ -340,50 +340,6 @@ const Utils = {
     },
 
 
-    /**
-     * Translates a hex string into an array of bytes.
-     *
-     * @param {string} hexStr
-     * @returns {byteArray}
-     *
-     * @example
-     * // returns [0xfe, 0x09, 0xa7]
-     * Utils.hexToByteArray("fe09a7");
-     */
-    hexToByteArray: function(hexStr) {
-        // TODO: Handle errors i.e. input string is not hex
-        if (!hexStr) return [];
-        hexStr = hexStr.replace(/\s+/g, "");
-        const byteArray = [];
-        for (let i = 0; i < hexStr.length; i += 2) {
-            byteArray.push(parseInt(hexStr.substr(i, 2), 16));
-        }
-        return byteArray;
-    },
-
-
-    /**
-     * Translates an array of bytes to a hex string.
-     *
-     * @param {byteArray} byteArray
-     * @param {string} [delim=" "]
-     * @returns {string}
-     *
-     * @example
-     * // returns "fe09a7"
-     * Utils.byteArrayToHex([0xfe, 0x09, 0xa7], "");
-     */
-    byteArrayToHex: function(byteArray, delim) {
-        if (!byteArray) return "";
-        delim = typeof delim === "undefined" ? " " : delim;
-        let hexStr = "";
-        for (let i = 0; i < byteArray.length; i++) {
-            hexStr += Utils.hex(byteArray[i]) + delim;
-        }
-        return hexStr.slice(0, hexStr.length - delim.length);
-    },
-
-
     /**
      * Converts a string to a byte array.
      * Treats the string as UTF-8 if any values are over 255.
@@ -828,7 +784,7 @@ const Utils = {
         if (removeScriptAndStyle) {
             htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
         }
-        return htmlStr.replace(/<[^>\n]+>/g, "");
+        return htmlStr.replace(/<[^>]+>/g, "");
     },
 
 
@@ -946,16 +902,19 @@ const Utils = {
      * @returns {html}
      */
     displayFilesAsHTML: function(files) {
+        /* <NL> and <SP> used to denote newlines and spaces in HTML markup.
+         * If a non-html operation is used, all markup will be removed but these
+         * whitespace chars will remain for formatting purposes.
+         */
+
         const formatDirectory = function(file) {
-            const html = "<div class='panel panel-default'>" +
-                   "<div class='panel-heading' role='tab'>" +
-                   "<h4 class='panel-title'>" +
-                   Utils.escapeHtml(file.fileName) +
-                   // The following line is for formatting when HTML is stripped
-                   "<span style='display: none'>\n0 bytes\n</span>" +
-                   "</h4>" +
-                   "</div>" +
-                   "</div>";
+            const html = `<div class='panel panel-default' style='white-space: normal;'>
+                    <div class='panel-heading' role='tab'>
+                        <h4 class='panel-title'>
+                            <NL>${Utils.escapeHtml(file.fileName)}
+                        </h4>
+                    </div>
+                </div>`;
             return html;
         };
 
@@ -966,52 +925,52 @@ const Utils = {
             );
             const blobUrl = URL.createObjectURL(blob);
 
-            const downloadAnchorElem = "<a href='" + blobUrl + "' " +
-                "title='Download " + Utils.escapeHtml(file.fileName) + "' " +
-                "download='" + Utils.escapeHtml(file.fileName) + "'>\u21B4</a>";
-
-            const expandFileContentsElem = "<a href='#collapse" + i + "' " +
-                "class='collapsed' " +
-                "data-toggle='collapse' " +
-                "aria-expanded='true' " +
-                "aria-controls='collapse" + i + "' " +
-                "title=\"Show/hide contents of '" + Utils.escapeHtml(file.fileName) + "'\">&#x1F50D</a>";
-
-            const hexFileData = Utils.byteArrayToHex(new Uint8Array(file.bytes));
-
-            const switchFileDataToInput = "<a href='#switchFileToInput" + i + "' " +
-                "class='file-switch' " +
-                "fileValue='" + hexFileData + "'>&#x21E7</a>";
-
-            const html = "<div class='panel panel-default'>" +
-                       "<div class='panel-heading' role='tab' id='heading" + i + "'>" +
-                       "<h4 class='panel-title'>" +
-                       "<div>" +
-                       Utils.escapeHtml(file.fileName) +
-                       " " +  expandFileContentsElem +
-                       " " + downloadAnchorElem +
-                       " " + switchFileDataToInput +
-                       "<span class='pull-right'>" +
-                       // These are for formatting when stripping HTML
-                       "<span style='display: none'>\n</span>" +
-                       file.size.toLocaleString() + " bytes" +
-                       "<span style='display: none'>\n</span>" +
-                       "</span>" +
-                       "</div>" +
-                       "</h4>" +
-                       "</div>" +
-                       "<div id='collapse" + i + "' class='panel-collapse collapse' " +
-                       "role='tabpanel' aria-labelledby='heading" + i + "'>" +
-                       "<div class='panel-body'>" +
-                       "<pre><code>" + Utils.escapeHtml(file.contents) + "</pre></code></div>" +
-                       "</div>" +
-                       "</div>";
+            const viewFileElem = `<a href='#collapse${i}'
+                class='collapsed'
+                data-toggle='collapse'
+                aria-expanded='true'
+                aria-controls='collapse${i}'
+                title="Show/hide contents of '${Utils.escapeHtml(file.fileName)}'">&#x1f441;&#xfe0f;</a>`;
+
+            const downloadFileElem = `<a href='${blobUrl}'
+                title='Download ${Utils.escapeHtml(file.fileName)}'
+                download='${Utils.escapeHtml(file.fileName)}'>&#x1f4be;</a>`;
+
+            const hexFileData = Utils.toHexFast(new Uint8Array(file.bytes));
+
+            const switchToInputElem = `<a href='#switchFileToInput${i}'
+                class='file-switch'
+                title='Move file to input as hex'
+                fileValue='${hexFileData}'>&#x21e7;</a>`;
+
+            const html = `<div class='panel panel-default' style='white-space: normal;'>
+                    <div class='panel-heading' role='tab' id='heading${i}'>
+                        <h4 class='panel-title'>
+                            <div>
+                                ${Utils.escapeHtml(file.fileName)}<NL>
+                                ${viewFileElem}<SP>
+                                ${downloadFileElem}<SP>
+                                ${switchToInputElem}<SP>
+                                <span class='pull-right'>
+                                    <NL>${file.size.toLocaleString()} bytes
+                                </span>
+                            </div>
+                        </h4>
+                    </div>
+                    <div id='collapse${i}' class='panel-collapse collapse'
+                        role='tabpanel' aria-labelledby='heading${i}'>
+                        <div class='panel-body'>
+                            <NL><NL><pre><code>${Utils.escapeHtml(file.contents)}</code></pre>
+                        </div>
+                    </div>
+                </div>`;
             return html;
         };
 
-        let html = "<div style='padding: 5px;'>" +
-                   files.length +
-                   " file(s) found</div>\n";
+        let html = `<div style='padding: 5px; white-space: normal;'>
+                ${files.length} file(s) found<NL>
+            </div>`;
+
         files.forEach(function(file, i) {
             if (typeof file.contents !== "undefined") {
                 html += formatFile(file, i);
@@ -1019,7 +978,10 @@ const Utils = {
                 html += formatDirectory(file);
             }
         });
-        return html;
+
+        return html.replace(/(?:(<pre>(?:\n|.)*<\/pre>)|\s{2,})/g, "$1") // Remove whitespace from markup
+            .replace(/<NL>/g, "\n") // Replace <NP> with newlines
+            .replace(/<SP>/g, " "); // Replace <SP> with spaces
     },
 
 

+ 2 - 2
src/core/operations/BitwiseOp.js

@@ -142,12 +142,12 @@ const BitwiseOp = {
 
 
         for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
-            result = BitwiseOp._bitOp(input, Utils.hexToByteArray(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
+            result = BitwiseOp._bitOp(input, Utils.fromHex(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
             resultUtf8 = Utils.byteArrayToUtf8(result);
             if (crib !== "" && resultUtf8.search(regex) === -1) continue;
             if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
             if (outputHex)
-                output += Utils.byteArrayToHex(result) + "\n";
+                output += Utils.toHex(result) + "\n";
             else
                 output += Utils.printable(resultUtf8, false) + "\n";
             if (printKey) output += "\n";

+ 2 - 2
src/core/operations/IP.js

@@ -283,7 +283,7 @@ const IP = {
                     baIp.push(decimal & 255);
                     break;
                 case "Hex":
-                    baIp = Utils.hexToByteArray(lines[i]);
+                    baIp = Utils.fromHex(lines[i]);
                     break;
                 default:
                     throw "Unsupported input IP format";
@@ -516,7 +516,7 @@ const IP = {
             "<tr><td>Destination IP address</td><td>" + IP._ipv4ToStr(dstIP) + "</td></tr>";
 
         if (ihl > 5) {
-            output += "<tr><td>Options</td><td>" + Utils.byteArrayToHex(options) + "</td></tr>";
+            output += "<tr><td>Options</td><td>" + Utils.toHex(options) + "</td></tr>";
         }
 
         return output + "</table>";

+ 1 - 0
src/web/OutputWaiter.js

@@ -172,6 +172,7 @@ OutputWaiter.prototype.undoSwitchClick = function() {
  * Moves a files data for items created via Utils.displayFilesAsHTML to the input.
  */
 OutputWaiter.prototype.fileSwitch = function(e) {
+    e.preventDefault();
     this.switchOrigData = this.manager.input.get();
     this.app.setInput(e.target.getAttribute("fileValue"));
     document.getElementById("undo-switch").disabled = false;