Separated in JSON Formatter
This commit is contained in:
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/tools/r11form.css">
|
||||||
<link rel="stylesheet" href="../assets/css/highlight.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="//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/highlight.js"></script>
|
||||||
<script src="../assets/scripts/tools/json.js"></script>
|
<script src="../assets/scripts/tools/json.js"></script>
|
||||||
<script>hljs.highlightAll();</script>
|
<script>hljs.highlightAll();</script>
|
||||||
@@ -61,175 +62,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user