Moved scripts from .html files to seperate js .files #191
							
								
								
									
										168
									
								
								Frontend/assets/scripts/tools/jsonFormatter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								Frontend/assets/scripts/tools/jsonFormatter.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
const mergeHTMLPlugin = (function () {
 | 
			
		||||
    'use strict';
 | 
			
		||||
 | 
			
		||||
    var originalStream;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} value
 | 
			
		||||
     * @returns {string}
 | 
			
		||||
     */
 | 
			
		||||
    function escapeHTML(value) {
 | 
			
		||||
        return value
 | 
			
		||||
            .replace(/&/g, '&')
 | 
			
		||||
            .replace(/</g, '<')
 | 
			
		||||
            .replace(/>/g, '>')
 | 
			
		||||
            .replace(/"/g, '"')
 | 
			
		||||
            .replace(/'/g, ''');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* plugin itself */
 | 
			
		||||
 | 
			
		||||
    /** @type {HLJSPlugin} */
 | 
			
		||||
    const mergeHTMLPlugin = {
 | 
			
		||||
        // preserve the original HTML token stream
 | 
			
		||||
        "before:highlightElement": ({ el }) => {
 | 
			
		||||
            originalStream = nodeStream(el);
 | 
			
		||||
        },
 | 
			
		||||
        // merge it afterwards with the highlighted token stream
 | 
			
		||||
        "after:highlightElement": ({ el, result, text }) => {
 | 
			
		||||
            if (!originalStream.length) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const resultNode = document.createElement('div');
 | 
			
		||||
            resultNode.innerHTML = result.value;
 | 
			
		||||
            result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
 | 
			
		||||
            el.innerHTML = result.value;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {Node} node
 | 
			
		||||
     */
 | 
			
		||||
    function tag(node) {
 | 
			
		||||
        return node.nodeName.toLowerCase();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {Node} node
 | 
			
		||||
     */
 | 
			
		||||
    function nodeStream(node) {
 | 
			
		||||
        /** @type Event[] */
 | 
			
		||||
        const result = [];
 | 
			
		||||
        (function _nodeStream(node, offset) {
 | 
			
		||||
            for (let child = node.firstChild; child; child = child.nextSibling) {
 | 
			
		||||
                if (child.nodeType === 3) {
 | 
			
		||||
                    offset += child.nodeValue.length;
 | 
			
		||||
                } else if (child.nodeType === 1) {
 | 
			
		||||
                    result.push({
 | 
			
		||||
                        event: 'start',
 | 
			
		||||
                        offset: offset,
 | 
			
		||||
                        node: child
 | 
			
		||||
                    });
 | 
			
		||||
                    offset = _nodeStream(child, offset);
 | 
			
		||||
 | 
			
		||||
                    if (!tag(child).match(/br|hr|img|input/)) {
 | 
			
		||||
                        result.push({
 | 
			
		||||
                            event: 'stop',
 | 
			
		||||
                            offset: offset,
 | 
			
		||||
                            node: child
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return offset;
 | 
			
		||||
        })(node, 0);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {any} original - the original stream
 | 
			
		||||
     * @param {any} highlighted - stream of the highlighted source
 | 
			
		||||
     * @param {string} value - the original source itself
 | 
			
		||||
     */
 | 
			
		||||
    function mergeStreams(original, highlighted, value) {
 | 
			
		||||
        let processed = 0;
 | 
			
		||||
        let result = '';
 | 
			
		||||
        const nodeStack = [];
 | 
			
		||||
 | 
			
		||||
        function selectStream() {
 | 
			
		||||
            if (!original.length || !highlighted.length) {
 | 
			
		||||
                return original.length ? original : highlighted;
 | 
			
		||||
            }
 | 
			
		||||
            if (original[0].offset !== highlighted[0].offset) {
 | 
			
		||||
                return (original[0].offset < highlighted[0].offset) ? original : highlighted;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return highlighted[0].event === 'start' ? original : highlighted;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {Node} node
 | 
			
		||||
         */
 | 
			
		||||
        function open(node) {
 | 
			
		||||
            /** @param {Attr} attr */
 | 
			
		||||
            function attributeString(attr) {
 | 
			
		||||
                return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // @ts-ignore
 | 
			
		||||
            result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('')
 | 
			
		||||
                + '>';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {Node} node
 | 
			
		||||
         */
 | 
			
		||||
        function close(node) {
 | 
			
		||||
            result += '</' + tag(node) + '>';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {Event} event
 | 
			
		||||
         */
 | 
			
		||||
        function render(event) {
 | 
			
		||||
            (event.event === 'start' ? open : close)(event.node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (original.length || highlighted.length) {
 | 
			
		||||
            let stream = selectStream();
 | 
			
		||||
            result += escapeHTML(value.substring(processed, stream[0].offset));
 | 
			
		||||
            processed = stream[0].offset;
 | 
			
		||||
            if (stream === original) {
 | 
			
		||||
                /*
 | 
			
		||||
                On any opening or closing tag of the original markup we first close
 | 
			
		||||
                the entire highlighted node stack, then render the original tag along
 | 
			
		||||
                with all the following original tags at the same offset and then
 | 
			
		||||
                reopen all the tags on the highlighted stack.
 | 
			
		||||
                */
 | 
			
		||||
                nodeStack.reverse().forEach(close);
 | 
			
		||||
                do {
 | 
			
		||||
                    render(stream.splice(0, 1)[0]);
 | 
			
		||||
                    stream = selectStream();
 | 
			
		||||
                } while (stream === original && stream.length && stream[0].offset === processed);
 | 
			
		||||
                nodeStack.reverse().forEach(open);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (stream[0].event === 'start') {
 | 
			
		||||
                    nodeStack.push(stream[0].node);
 | 
			
		||||
                } else {
 | 
			
		||||
                    nodeStack.pop();
 | 
			
		||||
                }
 | 
			
		||||
                render(stream.splice(0, 1)[0]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result + escapeHTML(value.substr(processed));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return mergeHTMLPlugin;
 | 
			
		||||
 | 
			
		||||
}());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
    // Make sure that only plain text is pasted
 | 
			
		||||
    configurePastingInElement("jsonBlock");
 | 
			
		||||
 | 
			
		||||
    hljs.addPlugin(mergeHTMLPlugin);
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,8 @@
 | 
			
		||||
    <link rel="stylesheet" href="../assets/css/tools/r11form.css">
 | 
			
		||||
    <link rel="stylesheet" href="../assets/css/highlight.css">
 | 
			
		||||
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
 | 
			
		||||
    <script src="../assets/scripts/tools/scripts.js"></script>
 | 
			
		||||
    <script src="../assets/scripts/tools/jsonFormatter.js"></script>
 | 
			
		||||
    <!-- <script src="../assets/scripts/tools/scripts.js"></script> -->
 | 
			
		||||
    <script src="../assets/scripts/tools/highlight.js"></script>
 | 
			
		||||
    <script src="../assets/scripts/tools/json.js"></script>
 | 
			
		||||
    <script>hljs.highlightAll();</script>
 | 
			
		||||
@@ -61,175 +62,5 @@
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
      const mergeHTMLPlugin = (function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        var originalStream;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {string} value
 | 
			
		||||
         * @returns {string}
 | 
			
		||||
         */
 | 
			
		||||
        function escapeHTML(value) {
 | 
			
		||||
          return value
 | 
			
		||||
          .replace(/&/g, '&')
 | 
			
		||||
          .replace(/</g, '<')
 | 
			
		||||
          .replace(/>/g, '>')
 | 
			
		||||
          .replace(/"/g, '"')
 | 
			
		||||
          .replace(/'/g, ''');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* plugin itself */
 | 
			
		||||
 | 
			
		||||
        /** @type {HLJSPlugin} */
 | 
			
		||||
        const mergeHTMLPlugin = {
 | 
			
		||||
          // preserve the original HTML token stream
 | 
			
		||||
          "before:highlightElement": ({el}) => {
 | 
			
		||||
            originalStream = nodeStream(el);
 | 
			
		||||
          },
 | 
			
		||||
          // merge it afterwards with the highlighted token stream
 | 
			
		||||
          "after:highlightElement": ({el, result, text}) => {
 | 
			
		||||
            if (!originalStream.length) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const resultNode = document.createElement('div');
 | 
			
		||||
            resultNode.innerHTML = result.value;
 | 
			
		||||
            result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
 | 
			
		||||
            el.innerHTML = result.value;
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {Node} node
 | 
			
		||||
         */
 | 
			
		||||
        function tag(node) {
 | 
			
		||||
          return node.nodeName.toLowerCase();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {Node} node
 | 
			
		||||
         */
 | 
			
		||||
        function nodeStream(node) {
 | 
			
		||||
          /** @type Event[] */
 | 
			
		||||
          const result = [];
 | 
			
		||||
          (function _nodeStream(node, offset) {
 | 
			
		||||
            for (let child = node.firstChild; child; child = child.nextSibling) {
 | 
			
		||||
              if (child.nodeType === 3) {
 | 
			
		||||
                offset += child.nodeValue.length;
 | 
			
		||||
              } else if (child.nodeType === 1) {
 | 
			
		||||
                result.push({
 | 
			
		||||
                  event: 'start',
 | 
			
		||||
                  offset: offset,
 | 
			
		||||
                  node: child
 | 
			
		||||
                });
 | 
			
		||||
                offset = _nodeStream(child, offset);
 | 
			
		||||
 | 
			
		||||
                if (!tag(child).match(/br|hr|img|input/)) {
 | 
			
		||||
                  result.push({
 | 
			
		||||
                    event: 'stop',
 | 
			
		||||
                    offset: offset,
 | 
			
		||||
                    node: child
 | 
			
		||||
                  });
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            return offset;
 | 
			
		||||
          })(node, 0);
 | 
			
		||||
          return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @param {any} original - the original stream
 | 
			
		||||
         * @param {any} highlighted - stream of the highlighted source
 | 
			
		||||
         * @param {string} value - the original source itself
 | 
			
		||||
         */
 | 
			
		||||
        function mergeStreams(original, highlighted, value) {
 | 
			
		||||
          let processed = 0;
 | 
			
		||||
          let result = '';
 | 
			
		||||
          const nodeStack = [];
 | 
			
		||||
 | 
			
		||||
          function selectStream() {
 | 
			
		||||
            if (!original.length || !highlighted.length) {
 | 
			
		||||
              return original.length ? original : highlighted;
 | 
			
		||||
            }
 | 
			
		||||
            if (original[0].offset !== highlighted[0].offset) {
 | 
			
		||||
              return (original[0].offset < highlighted[0].offset) ? original : highlighted;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return highlighted[0].event === 'start' ? original : highlighted;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          /**
 | 
			
		||||
           * @param {Node} node
 | 
			
		||||
           */
 | 
			
		||||
          function open(node) {
 | 
			
		||||
            /** @param {Attr} attr */
 | 
			
		||||
            function attributeString(attr) {
 | 
			
		||||
              return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // @ts-ignore
 | 
			
		||||
            result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('')
 | 
			
		||||
                + '>';
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          /**
 | 
			
		||||
           * @param {Node} node
 | 
			
		||||
           */
 | 
			
		||||
          function close(node) {
 | 
			
		||||
            result += '</' + tag(node) + '>';
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          /**
 | 
			
		||||
           * @param {Event} event
 | 
			
		||||
           */
 | 
			
		||||
          function render(event) {
 | 
			
		||||
            (event.event === 'start' ? open : close)(event.node);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          while (original.length || highlighted.length) {
 | 
			
		||||
            let stream = selectStream();
 | 
			
		||||
            result += escapeHTML(value.substring(processed, stream[0].offset));
 | 
			
		||||
            processed = stream[0].offset;
 | 
			
		||||
            if (stream === original) {
 | 
			
		||||
              /*
 | 
			
		||||
              On any opening or closing tag of the original markup we first close
 | 
			
		||||
              the entire highlighted node stack, then render the original tag along
 | 
			
		||||
              with all the following original tags at the same offset and then
 | 
			
		||||
              reopen all the tags on the highlighted stack.
 | 
			
		||||
              */
 | 
			
		||||
              nodeStack.reverse().forEach(close);
 | 
			
		||||
              do {
 | 
			
		||||
                render(stream.splice(0, 1)[0]);
 | 
			
		||||
                stream = selectStream();
 | 
			
		||||
              } while (stream === original && stream.length && stream[0].offset === processed);
 | 
			
		||||
              nodeStack.reverse().forEach(open);
 | 
			
		||||
            } else {
 | 
			
		||||
              if (stream[0].event === 'start') {
 | 
			
		||||
                nodeStack.push(stream[0].node);
 | 
			
		||||
              } else {
 | 
			
		||||
                nodeStack.pop();
 | 
			
		||||
              }
 | 
			
		||||
              render(stream.splice(0, 1)[0]);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          return result + escapeHTML(value.substr(processed));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mergeHTMLPlugin;
 | 
			
		||||
 | 
			
		||||
      }());
 | 
			
		||||
 | 
			
		||||
      hljs.addPlugin(mergeHTMLPlugin);
 | 
			
		||||
 | 
			
		||||
      function init() {
 | 
			
		||||
        // Make sure that only plain text is pasted
 | 
			
		||||
        configurePastingInElement("jsonBlock");
 | 
			
		||||
        
 | 
			
		||||
      }
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user