Skip to content

Commit 94cb5a3

Browse files
author
WebCoder49
committed
Start looking at bitmap font; make JS not replace HTML directly as dangerous
1 parent 120c321 commit 94cb5a3

File tree

17 files changed

+54
-16
lines changed

17 files changed

+54
-16
lines changed

plugins/special-chars.js

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Files: special-chars.js, special-chars.css
44
*/
55

6-
// INCOMPLETE: TODO Optimise regex - compile at start; make so won't change contents of HTML code
6+
// INCOMPLETE: TODO Optimise regex - compile at start; Update CSS for character display; clean up + comment
77

88
codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
99
specialCharRegExp;
@@ -17,7 +17,7 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
1717
* @param {RegExp} specialCharRegExp The regular expression which matches special characters
1818
* @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code
1919
*/
20-
constructor(specialCharRegExp = /(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{FFFF}]/ug, colorInSpecialChars = false) { // By default, covers many non-renderable ASCII characters
20+
constructor(specialCharRegExp = /(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug, colorInSpecialChars = true) { // By default, covers many non-renderable ASCII characters
2121
super();
2222
this.specialCharRegExp = specialCharRegExp;
2323
this.colorInSpecialChars = colorInSpecialChars;
@@ -43,9 +43,45 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
4343
/* Runs after code is highlighted; Params: codeInput element) */
4444
afterHighlight(codeInput) {
4545
let result_element = codeInput.querySelector("pre code");
46-
result_element.innerHTML = result_element.innerHTML.replaceAll(this.specialCharRegExp, this.specialCharReplacer.bind(this));
46+
this.recursivelyReplaceText(result_element);
4747
}
48-
specialCharReplacer(match_char, _match_char, index, whole_string, groups) {
48+
49+
recursivelyReplaceText(element) {
50+
for(let i = 0; i < element.childNodes.length; i++) {
51+
52+
let nextNode = element.childNodes[i];
53+
if(nextNode.nodeName == "#text" && nextNode.nodeValue != "") {
54+
// Replace in here
55+
let oldValue = nextNode.nodeValue;
56+
57+
this.specialCharRegExp.lastIndex = 0;
58+
let searchResult = this.specialCharRegExp.exec(oldValue);
59+
if(searchResult != null) {
60+
let charIndex = searchResult.index; // Start as returns end
61+
62+
nextNode = nextNode.splitText(charIndex+1).previousSibling;
63+
64+
if(charIndex > 0) {
65+
nextNode = nextNode.splitText(charIndex); // Keep those before in difft. span
66+
}
67+
68+
if(nextNode.textContent != "") {
69+
let replacementElement = this.specialCharReplacer(nextNode.textContent);
70+
nextNode.parentNode.insertBefore(replacementElement, nextNode);
71+
nextNode.textContent = "";
72+
}
73+
}
74+
} else if(nextNode.nodeType == 1) {
75+
if(nextNode.className != "code-input_special-char" && nextNode.nodeValue != "") {
76+
// Element - recurse
77+
this.recursivelyReplaceText(nextNode);
78+
}
79+
}
80+
}
81+
}
82+
83+
specialCharReplacer(match_char) {
84+
console.log(2, match_char);
4985
let hex_code = match_char.codePointAt(0);
5086

5187
let colors;
@@ -57,20 +93,22 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
5793

5894
let char_width = this.getCharacterWidth(match_char);
5995

96+
// Create element with hex code
97+
let result = document.createElement("span");
98+
result.classList.add("code-input_special-char");
99+
result.setAttribute("data-hex0", hex_code[0]);
100+
result.setAttribute("data-hex1", hex_code[1]);
101+
result.setAttribute("data-hex2", hex_code[2]);
102+
result.setAttribute("data-hex3", hex_code[3]);
103+
// Handle zero-width chars
104+
if(char_width == 0) result.classList.add("code-input_special-char_zero-width");
105+
else result.style.width = char_width + "px";
106+
60107
if(this.colorInSpecialChars) {
61-
if(char_width == 0) {
62-
return `<span class='code-input_special-char code-input_special-char_zero-width ${hex_code[0] == "0" && hex_code[1] == "0" ? "code-input_special-char_one-byte" : ""}' data-hex0='${hex_code[0]}' data-hex1='${hex_code[1]}' data-hex2='${hex_code[2]}' data-hex3='${hex_code[3]}' style='background-color: #${colors[0]}; color: ${colors[1]};'></span>`;
63-
} else {
64-
return `<span class='code-input_special-char ${hex_code[0] == "0" && hex_code[1] == "0" ? "code-input_special-char_one-byte" : ""}' data-hex0='${hex_code[0]}' data-hex1='${hex_code[1]}' data-hex2='${hex_code[2]}' data-hex3='${hex_code[3]}' style='background-color: #${colors[0]}; color: ${colors[1]}; width: ${char_width}px'></span>`;
65-
}
66-
} else {
67-
if(char_width == 0) {
68-
return `<span class='code-input_special-char code-input_special-char_zero-width ${hex_code[0] == "0" && hex_code[1] == "0" ? "code-input_special-char_one-byte" : ""}' data-hex0='${hex_code[0]}' data-hex1='${hex_code[1]}' data-hex2='${hex_code[2]}' data-hex3='${hex_code[3]}'></span>`;
69-
} else {
70-
return `<span class='code-input_special-char ${hex_code[0] == "0" && hex_code[1] == "0" ? "code-input_special-char_one-byte" : ""}' data-hex0='${hex_code[0]}' data-hex1='${hex_code[1]}' data-hex2='${hex_code[2]}' data-hex3='${hex_code[3]}' style='width: ${char_width}px'></span>`;
71-
}
108+
result.style.backgroundColor = "#" + colors[0];
109+
result.style.color = colors[1];
72110
}
73-
111+
return result;
74112
}
75113

76114
getCharacterColor(ascii_code) {

plugins/special-chars/0.png

99 Bytes
Loading

plugins/special-chars/1.png

92 Bytes
Loading

plugins/special-chars/2.png

101 Bytes
Loading

plugins/special-chars/3.png

94 Bytes
Loading

plugins/special-chars/4.png

100 Bytes
Loading

plugins/special-chars/5.png

104 Bytes
Loading

plugins/special-chars/6.png

102 Bytes
Loading

plugins/special-chars/7.png

92 Bytes
Loading

plugins/special-chars/8.png

95 Bytes
Loading

0 commit comments

Comments
 (0)