UNPKG

react-saasify-chrisvxd

Version:

React components for Saasify web clients.

619 lines (527 loc) 14.4 kB
"use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var entities = require('entities'); var defaults = { fg: '#FFF', bg: '#000', newline: false, escapeXML: false, stream: false, colors: getDefaultColors() }; function getDefaultColors() { var colors = { 0: '#000', 1: '#A00', 2: '#0A0', 3: '#A50', 4: '#00A', 5: '#A0A', 6: '#0AA', 7: '#AAA', 8: '#555', 9: '#F55', 10: '#5F5', 11: '#FF5', 12: '#55F', 13: '#F5F', 14: '#5FF', 15: '#FFF' }; range(0, 5).forEach(function (red) { range(0, 5).forEach(function (green) { range(0, 5).forEach(function (blue) { return setStyleColor(red, green, blue, colors); }); }); }); range(0, 23).forEach(function (gray) { var c = gray + 232; var l = toHexString(gray * 10 + 8); colors[c] = '#' + l + l + l; }); return colors; } /** * @param {number} red * @param {number} green * @param {number} blue * @param {object} colors */ function setStyleColor(red, green, blue, colors) { var c = 16 + red * 36 + green * 6 + blue; var r = red > 0 ? red * 40 + 55 : 0; var g = green > 0 ? green * 40 + 55 : 0; var b = blue > 0 ? blue * 40 + 55 : 0; colors[c] = toColorHexString([r, g, b]); } /** * Converts from a number like 15 to a hex string like 'F' * @param {number} num * @returns {string} */ function toHexString(num) { var str = num.toString(16); while (str.length < 2) { str = '0' + str; } return str; } /** * Converts from an array of numbers like [15, 15, 15] to a hex string like 'FFF' * @param {[red, green, blue]} ref * @returns {string} */ function toColorHexString(ref) { var results = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = ref[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var r = _step.value; results.push(toHexString(r)); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return '#' + results.join(''); } /** * @param {Array} stack * @param {string} token * @param {*} data * @param {object} options */ function generateOutput(stack, token, data, options) { var result; if (token === 'text') { result = pushText(data, options); } else if (token === 'display') { result = handleDisplay(stack, data, options); } else if (token === 'xterm256') { result = pushForegroundColor(stack, options.colors[data]); } else if (token === 'rgb') { result = handleRgb(stack, data); } return result; } /** * @param {Array} stack * @param {string} data * @returns {*} */ function handleRgb(stack, data) { data = data.substring(2).slice(0, -1); var operation = +data.substr(0, 2); var color = data.substring(5).split(';'); var rgb = color.map(function (value) { return ('0' + Number(value).toString(16)).substr(-2); }).join(''); return pushStyle(stack, (operation === 38 ? 'color:#' : 'background-color:#') + rgb); } /** * @param {Array} stack * @param {number} code * @param {object} options * @returns {*} */ function handleDisplay(stack, code, options) { code = parseInt(code, 10); var codeMap = { '-1': function _() { return '<br/>'; }, 0: function _() { return stack.length && resetStyles(stack); }, 1: function _() { return pushTag(stack, 'b'); }, 3: function _() { return pushTag(stack, 'i'); }, 4: function _() { return pushTag(stack, 'u'); }, 8: function _() { return pushStyle(stack, 'display:none'); }, 9: function _() { return pushTag(stack, 'strike'); }, 22: function _() { return pushStyle(stack, 'font-weight:normal;text-decoration:none;font-style:normal'); }, 23: function _() { return closeTag(stack, 'i'); }, 24: function _() { return closeTag(stack, 'u'); }, 39: function _() { return pushForegroundColor(stack, options.fg); }, 49: function _() { return pushBackgroundColor(stack, options.bg); }, 53: function _() { return pushStyle(stack, 'text-decoration:overline'); } }; var result; if (codeMap[code]) { result = codeMap[code](); } else if (4 < code && code < 7) { result = pushTag(stack, 'blink'); } else if (29 < code && code < 38) { result = pushForegroundColor(stack, options.colors[code - 30]); } else if (39 < code && code < 48) { result = pushBackgroundColor(stack, options.colors[code - 40]); } else if (89 < code && code < 98) { result = pushForegroundColor(stack, options.colors[8 + (code - 90)]); } else if (99 < code && code < 108) { result = pushBackgroundColor(stack, options.colors[8 + (code - 100)]); } return result; } /** * Clear all the styles * @returns {string} */ function resetStyles(stack) { var stackClone = stack.slice(0); stack.length = 0; return stackClone.reverse().map(function (tag) { return '</' + tag + '>'; }).join(''); } /** * Creates an array of numbers ranging from low to high * @param {number} low * @param {number} high * @returns {Array} * @example range(3, 7); // creates [3, 4, 5, 6, 7] */ function range(low, high) { var results = []; for (var j = low; j <= high; j++) { results.push(j); } return results; } /** * Returns a new function that is true if value is NOT the same category * @param {string} category * @returns {function} */ function notCategory(category) { return function (e) { return (category === null || e.category !== category) && category !== 'all'; }; } /** * Converts a code into an ansi token type * @param {number} code * @returns {string} */ function categoryForCode(code) { code = parseInt(code, 10); var result = null; if (code === 0) { result = 'all'; } else if (code === 1) { result = 'bold'; } else if (2 < code && code < 5) { result = 'underline'; } else if (4 < code && code < 7) { result = 'blink'; } else if (code === 8) { result = 'hide'; } else if (code === 9) { result = 'strike'; } else if (29 < code && code < 38 || code === 39 || 89 < code && code < 98) { result = 'foreground-color'; } else if (39 < code && code < 48 || code === 49 || 99 < code && code < 108) { result = 'background-color'; } return result; } /** * @param {string} text * @param {object} options * @returns {string} */ function pushText(text, options) { if (options.escapeXML) { return entities.encodeXML(text); } return text; } /** * @param {Array} stack * @param {string} tag * @param {string} [style=''] * @returns {string} */ function pushTag(stack, tag, style) { if (!style) { style = ''; } stack.push(tag); return ['<' + tag, style ? ' style="' + style + '"' : void 0, '>'].join(''); } /** * @param {Array} stack * @param {string} style * @returns {string} */ function pushStyle(stack, style) { return pushTag(stack, 'span', style); } function pushForegroundColor(stack, color) { return pushTag(stack, 'span', 'color:' + color); } function pushBackgroundColor(stack, color) { return pushTag(stack, 'span', 'background-color:' + color); } /** * @param {Array} stack * @param {string} style * @returns {string} */ function closeTag(stack, style) { var last; if (stack.slice(-1)[0] === style) { last = stack.pop(); } if (last) { return '</' + style + '>'; } } /** * @param {string} text * @param {object} options * @param {function} callback * @returns {Array} */ function tokenize(text, options, callback) { var ansiMatch = false; var ansiHandler = 3; function remove() { return ''; } function removeXterm256(m, g1) { callback('xterm256', g1); return ''; } function newline(m) { if (options.newline) { callback('display', -1); } else { callback('text', m); } return ''; } function ansiMess(m, g1) { ansiMatch = true; if (g1.trim().length === 0) { g1 = '0'; } g1 = g1.trimRight(';').split(';'); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = g1[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var g = _step2.value; callback('display', g); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) { _iterator2["return"](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return ''; } function realText(m) { callback('text', m); return ''; } function rgb(m) { callback('rgb', m); return ''; } /* eslint no-control-regex:0 */ var tokens = [{ pattern: /^\x08+/, sub: remove }, { pattern: /^\x1b\[[012]?K/, sub: remove }, { pattern: /^\x1b\[\(B/, sub: remove }, { pattern: /^\x1b\[[34]8;2;\d+;\d+;\d+m/, sub: rgb }, { pattern: /^\x1b\[38;5;(\d+)m/, sub: removeXterm256 }, { pattern: /^\n/, sub: newline }, { pattern: /^\x1b\[((?:\d{1,3};?)+|)m/, sub: ansiMess }, { // CSI n J // ED - Erase in Display Clears part of the screen. // If n is 0 (or missing), clear from cursor to end of screen. // If n is 1, clear from cursor to beginning of the screen. // If n is 2, clear entire screen (and moves cursor to upper left on DOS ANSI.SYS). // If n is 3, clear entire screen and delete all lines saved in the scrollback buffer // (this feature was added for xterm and is supported by other terminal applications). pattern: /^\x1b\[\d?J/, sub: remove }, { // CSI n ; m f // HVP - Horizontal Vertical Position Same as CUP pattern: /^\x1b\[\d{0,3};\d{0,3}f/, sub: remove }, { // catch-all for CSI sequences? pattern: /^\x1b\[?[\d;]{0,3}/, sub: remove }, { pattern: /^([^\x1b\x08\n]+)/, sub: realText }]; function process(handler, i) { if (i > ansiHandler && ansiMatch) { return; } ansiMatch = false; text = text.replace(handler.pattern, handler.sub); } var results1 = []; var _text = text, length = _text.length; outer: while (length > 0) { for (var i = 0, o = 0, len = tokens.length; o < len; i = ++o) { var handler = tokens[i]; process(handler, i); if (text.length !== length) { // We matched a token and removed it from the text. We need to // start matching *all* tokens against the new text. length = text.length; continue outer; } } if (text.length === length) { break; } results1.push(0); length = text.length; } return results1; } /** * If streaming, then the stack is "sticky" * * @param {Array} stickyStack * @param {string} token * @param {*} data * @returns {Array} */ function updateStickyStack(stickyStack, token, data) { if (token !== 'text') { stickyStack = stickyStack.filter(notCategory(categoryForCode(data))); stickyStack.push({ token: token, data: data, category: categoryForCode(data) }); } return stickyStack; } var Filter = /*#__PURE__*/ function () { /** * @param {object} options * @param {string=} options.fg The default foreground color used when reset color codes are encountered. * @param {string=} options.bg The default background color used when reset color codes are encountered. * @param {boolean=} options.newline Convert newline characters to `<br/>`. * @param {boolean=} options.escapeXML Generate HTML/XML entities. * @param {boolean=} options.stream Save style state across invocations of `toHtml()`. * @param {(string[] | {[code: number]: string})=} options.colors Can override specific colors or the entire ANSI palette. */ function Filter(options) { _classCallCheck(this, Filter); options = options || {}; if (options.colors) { options.colors = Object.assign({}, defaults.colors, options.colors); } this.options = Object.assign({}, defaults, options); this.stack = []; this.stickyStack = []; } /** * @param {string | string[]} input * @returns {string} */ _createClass(Filter, [{ key: "toHtml", value: function toHtml(input) { var _this = this; input = typeof input === 'string' ? [input] : input; var stack = this.stack, options = this.options; var buf = []; this.stickyStack.forEach(function (element) { var output = generateOutput(stack, element.token, element.data, options); if (output) { buf.push(output); } }); tokenize(input.join(''), options, function (token, data) { var output = generateOutput(stack, token, data, options); if (output) { buf.push(output); } if (options.stream) { _this.stickyStack = updateStickyStack(_this.stickyStack, token, data); } }); if (stack.length) { buf.push(resetStyles(stack)); } return buf.join(''); } }]); return Filter; }(); module.exports = Filter;