| 90 | let CSS_PROPS = new Set('color,background,background-color,background-image,background-size,background-position,background-repeat,border,border-radius,border-color,border-width,border-style,border-top,border-right,border-bottom,border-left,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,width,height,min-width,max-width,min-height,max-height,display,position,top,right,bottom,left,float,clear,overflow,overflow-x,overflow-y,z-index,font,font-size,font-weight,font-family,font-style,line-height,text-align,text-decoration,text-transform,text-indent,text-shadow,letter-spacing,word-spacing,white-space,vertical-align,cursor,opacity,visibility,box-shadow,box-sizing,transition,transform,animation,flex,flex-direction,flex-wrap,flex-grow,flex-shrink,flex-basis,justify-content,align-items,align-content,align-self,gap,grid,grid-template,grid-template-columns,grid-template-rows,content,list-style,outline,pointer-events,resize,user-select,fill,stroke'.split(',')); |
| 91 | |
| 92 | let highlightJS = (code) => { |
| 93 | let out = ''; |
| 94 | let i = 0; |
| 95 | let len = code.length; |
| 96 | while (i < len) { |
| 97 | let c = code[i]; |
| 98 | if (c === '/' && code[i + 1] === '/') { |
| 99 | let end = code.indexOf('\n', i); |
| 100 | if (end === -1) end = len; |
| 101 | out += span('comment', code.substring(i, end)); |
| 102 | i = end; |
| 103 | } else if (c === '/' && code[i + 1] === '*') { |
| 104 | let end = code.indexOf('*/', i + 2); |
| 105 | end = end === -1 ? len : end + 2; |
| 106 | out += span('comment', code.substring(i, end)); |
| 107 | i = end; |
| 108 | } else if (c === '"' || c === "'" || c === '`') { |
| 109 | let q = c, j = i + 1; |
| 110 | while (j < len) { |
| 111 | if (code[j] === '\\') { j += 2; continue; } |
| 112 | if (code[j] === q) { j++; break; } |
| 113 | if (q !== '`' && code[j] === '\n') break; |
| 114 | j++; |
| 115 | } |
| 116 | out += span('string', code.substring(i, j)); |
| 117 | i = j; |
| 118 | } else if (c === '/' && /[=(,;:!&|?{}\[\n+\-~^%]/.test(code[i - 1] || '(')) { |
| 119 | let j = i + 1; |
| 120 | while (j < len && code[j] !== '/' && code[j] !== '\n') { |
| 121 | if (code[j] === '\\') j++; |
| 122 | j++; |
| 123 | } |
| 124 | if (j < len && code[j] === '/') { |
| 125 | j++; |
| 126 | while (j < len && /[gimsuy]/.test(code[j])) j++; |
| 127 | out += span('regex', code.substring(i, j)); |
| 128 | i = j; |
| 129 | } else { out += esc(c); i++; } |
| 130 | } else if (/[0-9]/.test(c) || (c === '.' && /[0-9]/.test(code[i + 1]))) { |
| 131 | let j = i; |
| 132 | if (code[j] === '0' && (code[j + 1] === 'x' || code[j + 1] === 'X')) { |
| 133 | j += 2; while (j < len && /[0-9a-fA-F_]/.test(code[j])) j++; |
| 134 | } else if (code[j] === '0' && (code[j + 1] === 'b' || code[j + 1] === 'B')) { |
| 135 | j += 2; while (j < len && /[01_]/.test(code[j])) j++; |
| 136 | } else { |
| 137 | while (j < len && /[0-9_]/.test(code[j])) j++; |
| 138 | if (j < len && code[j] === '.') { j++; while (j < len && /[0-9_]/.test(code[j])) j++; } |
| 139 | if (j < len && (code[j] === 'e' || code[j] === 'E')) { j++; if (code[j] === '+' || code[j] === '-') j++; while (j < len && /[0-9]/.test(code[j])) j++; } |
| 140 | } |
| 141 | if (j < len && code[j] === 'n') j++; |
| 142 | out += span('number', code.substring(i, j)); |
| 143 | i = j; |
| 144 | } else if (/[a-zA-Z_$]/.test(c)) { |
| 145 | let j = i; |
| 146 | while (j < len && /[a-zA-Z0-9_$]/.test(code[j])) j++; |
| 147 | let word = code.substring(i, j); |
| 148 | if (JS_KW.has(word)) out += span('keyword', word); |
| 149 | else if (word === 'true' || word === 'false' || word === 'null' || word === 'undefined' || word === 'NaN' || word === 'Infinity') out += span('literal', word); |