diff --git a/lib/ui/console.jsx b/lib/ui/console.jsx index c2535e38..6767a7b0 100644 --- a/lib/ui/console.jsx +++ b/lib/ui/console.jsx @@ -21,6 +21,7 @@ class ConsoleLog { constructor(opts) { this.children = []; this.autoScroll = opts.autoScroll; + this.HighlightText = ''; etch.initialize(this); } @@ -44,6 +45,69 @@ class ConsoleLog { ); } + /** + * Set highlighted text string + * + * @param {String} text Text that will be highlighted + */ + setHighlightText(text) { + this.highlightText = text; + } + + /** + * Highlight text in console from highlightText string + */ + highlightTextInLog() { + let origInnerHtml = this.refs.log.innerHTML; + let cleanInnerHtml = origInnerHtml.replace(/(.*?)<\/span>/gi, '$1'); + if (this.highlightText) { + const escapedText = this.highlightText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(escapedText, 'gi'); + this.refs.log.innerHTML = cleanInnerHtml.replace(regex, match => `${match}`); + } else { + this.refs.log.innerHTML = cleanInnerHtml; + } + } + + /** + * Jump to next highlighted text string + * + * @param {String} direction Direction to jump (up/down) + */ + jumpToHighlightedText(direction) { + const log = this.refs.log; + const textElements = log.querySelectorAll('.highlight'); + const scrollTop = log.scrollTop; + const containerHeight = log.offsetHeight; + const centerLine = scrollTop + containerHeight / 2; + + let bestAbove = null; + let bestBelow = null; + + for (const el of textElements) { + const elTop = el.offsetTop; + const centeredOffset = elTop - containerHeight / 2; + + if (elTop < centerLine) { + bestAbove = centeredOffset; + } else if (elTop > centerLine && bestBelow === null) { + bestBelow = centeredOffset; + } + } + + if (direction === 'down') { + if (bestBelow === null) { + return; + } + log.scrollTop = Math.min(bestBelow, log.scrollHeight - containerHeight); + } else { + if (bestAbove === null) { + return; + } + log.scrollTop = Math.max(bestAbove, 0); + } + } + /** * Update component * @@ -82,6 +146,7 @@ class ConsoleLog { */ clear() { this.children = []; + this.refs.log.innerHTML = ''; this.update(); } } @@ -105,7 +170,8 @@ export default class Console { isHidden: true, logLevel: 'info', autoScroll: true, - showOnBuild: true + showOnBuild: true, + consoleHighlightText: '' }; opts && Object.assign(this.state, opts); @@ -161,6 +227,21 @@ export default class Console {
+
+ +
+
+ +
+
+