Skip to content

Commit

Permalink
Fixes to bugs in BrowserConsoleWriter and RichBrowserOutputFormat (Re…
Browse files Browse the repository at this point in the history
…solves #327)
  • Loading branch information
darkfrog26 committed Aug 21, 2022
1 parent 037826e commit ccc15ac
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 82 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ val scalaNativeVersions = scalaNot211Versions

name := "scribe"
ThisBuild / organization := "com.outr"
ThisBuild / version := "3.10.2"
ThisBuild / version := "3.10.3-SNAPSHOT"
ThisBuild / scalaVersion := scala213
ThisBuild / scalacOptions ++= Seq("-unchecked", "-deprecation")
ThisBuild / javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
ThisBuild / resolvers += Resolver.sonatypeRepo("releases")
ThisBuild / resolvers ++= Resolver.sonatypeOssRepos("releases")
ThisBuild / resolvers += Resolver.JCenterRepository
//javaOptions in run += "-agentpath:/opt/YourKit-JavaProfiler-2020.9/bin/linux-x86-64/libyjpagent.so=delay=10000,listen=all"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,92 +3,39 @@ package scribe.output.format
import scribe.output._
import scribe.writer.BrowserConsoleWriter

import scala.collection.mutable.ListBuffer

/**
* Supports rich output to JavaScript console in the browser
*/
object RichBrowserOutputFormat extends OutputFormat {
override def apply(output: LogOutput, stream: String => Unit): Unit = recurse(
stream = stream,
args = BrowserConsoleWriter.args,
fg = None,
bg = None,
bold = false,
italic = false,
underline = false,
strikethrough = false,
output = output
)
import BrowserConsoleWriter.args

private def recurse(stream: String => Unit,
args: ListBuffer[String],
fg: Option[String],
bg: Option[String],
bold: Boolean,
italic: Boolean,
underline: Boolean,
strikethrough: Boolean,
output: LogOutput): Unit = output match {
case o: TextOutput => stream(o.plainText)
case o: CompositeOutput => o.entries.foreach(recurse(stream, args, fg, bg, bold, italic, underline, strikethrough, _))
case o: ColoredOutput => {
val color = color2CSS(o.color)
stream("%c")
val css = s"color: $color"
args += css
recurse(stream, args, Some(css), bg, bold, italic, underline, strikethrough, o.output)
stream("%c")
args += fg.getOrElse(s"color: ${color2CSS(Color.Black)}")
}
case o: BackgroundColoredOutput => {
val color = color2CSS(o.color)
stream("%c")
val css = s"background-color: $color"
args += css
recurse(stream, args, fg, Some(css), bold, italic, underline, strikethrough, o.output)
stream("%c")
args += bg.getOrElse(s"background-color: ${color2CSS(Color.White)}")
}
case o: URLOutput => {
stream("%o (")
args += o.url
recurse(stream, args, fg, bg, bold, italic, underline, strikethrough, o.output)
stream(")")
}
case o: BoldOutput => if (!bold) {
stream("%c")
val css = "font-weight: bold"
args += css
recurse(stream, args, fg, bg, true, italic, underline, strikethrough, o.output)
stream("%c")
args += "font-weight: normal"
}
case o: ItalicOutput => if (!italic) {
stream("%c")
val css = "font-style: italic"
args += css
recurse(stream, args, fg, bg, bold, true, underline, strikethrough, o.output)
stream("%c")
args += "font-style: normal"
}
case o: UnderlineOutput => if (!underline) {
override def apply(output: LogOutput, stream: String => Unit): Unit = recurse(output, stream)

private def recurse(output: LogOutput, stream: String => Unit): Unit = {
def withArg(key: String, value: String, output: LogOutput): Unit = {
stream("%c")
val css = "text-decoration: underline"
args += css
recurse(stream, args, fg, bg, bold, italic, true, strikethrough, o.output)
args.around(key -> value) {
recurse(output, stream)
}
stream("%c")
args += "text-decoration: none"
}
case o: StrikethroughOutput => if (!strikethrough) {
stream("%c")
val css = "text-decoration: line-through"
args += css
recurse(stream, args, fg, bg, bold, italic, underline, true, o.output)
stream("%c")
args += "text-decoration: none"
output match {
case o: TextOutput => stream(o.plainText)
case o: CompositeOutput => o.entries.foreach(recurse(_, stream))
case o: ColoredOutput => withArg("color", color2CSS(o.color), o.output)
case o: BackgroundColoredOutput => withArg("background-color", color2CSS(o.color), o.output)
case o: URLOutput =>
stream("%o (")
args.around("::URL" -> o.url) {
recurse(o.output, stream)
}
stream(")")
case o: BoldOutput => withArg("font-weight", "bold", o.output)
case o: ItalicOutput => withArg("font-style", "italic", o.output)
case o: UnderlineOutput => withArg("text-decoration", "underline", o.output)
case o: StrikethroughOutput => withArg("text-decoration", "line-through", o.output)
case _ => stream(output.plainText)
}
case _ => stream(output.plainText)
}

private def color2CSS(color: Color): String = color match {
Expand Down
31 changes: 28 additions & 3 deletions core/js/src/main/scala/scribe/writer/BrowserConsoleWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,41 @@ import scala.scalajs.js
* Writer specifically to target the JavaScript console in the browser
*/
object BrowserConsoleWriter extends Writer {
val args: ListBuffer[String] = ListBuffer.empty
private var map = Map.empty[String, String]
private var argsList = List.empty[String]

object args {
def around[Return](t: (String, String))(f: => Return): Return = {
this += t
try {
f
} finally {
this -= t._1
}
}
private def append(): Unit = argsList = map.map {
case (key, value) if key.startsWith("::") => value
case (key, value) => s"$key: $value"
}.mkString("; ") :: argsList
def +=(t: (String, String)): Unit = {
map += t
append()
}
def -=(key: String): Unit = {
map -= key
append()
}
}

override def write(record: LogRecord, output: LogOutput, outputFormat: OutputFormat): Unit = {
val b = new mutable.StringBuilder
args.clear()
map = Map.empty
argsList = Nil
outputFormat.begin(b.append(_))
outputFormat(output, b.append(_))
outputFormat.end(b.append(_))

val jsArgs = args.map(js.Any.fromString).toList
val jsArgs = argsList.map(js.Any.fromString).reverse
if (record.level >= Level.Error) {
console.error(b.toString(), jsArgs: _*)
} else if (record.level >= Level.Warn) {
Expand Down

0 comments on commit ccc15ac

Please sign in to comment.