Skip to content

Commit

Permalink
EsModules (#880)
Browse files Browse the repository at this point in the history
Add basic support for ES modules related to #638
  • Loading branch information
Quafadas authored Jul 9, 2024
1 parent bc3f077 commit 87ca141
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 12 deletions.
2 changes: 0 additions & 2 deletions mdoc-js-worker/src/main/scala/ScalaJSWorker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ import org.scalajs.logging.Logger
import org.scalajs.logging.Level
import org.scalajs.linker.standard.MemIRFileImpl
import org.scalajs.linker.interface.Semantics

class ScalaJSWorker(
config: ScalajsConfig,
logger: Logger
) extends ScalajsWorkerApi {
case class IFile(mem: IRFile) extends ScalajsWorkerApi.IRFile

val linker = {
val cfg =
StandardConfig()
Expand Down
17 changes: 17 additions & 0 deletions mdoc-js/src/main/resources/mdoc_esmodule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(function (global) {
function findDivs() {
return Array.from(global.document.querySelectorAll("div[data-mdoc-js]"));
}

function loadAll(scope) {
findDivs().forEach(function (el) {
const id = el.getAttribute("id").replace("-html-", "_js_");
const moduleName = el.getAttribute("data-mdoc-module-name");
import(moduleName).then(function (module) {
module[id](el);
});
});
}

loadAll(global);
})(window);
File renamed without changes.
10 changes: 8 additions & 2 deletions mdoc-js/src/main/scala/mdoc/modifiers/JsConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ case class JsConfig(
relativeLinkPrefix: String = "",
batchMode: Boolean = false
) {
def isCommonJS: Boolean = moduleKind == ModuleType.CommonJSModule
lazy val isCommonJS: Boolean = moduleKind == ModuleType.CommonJSModule
lazy val isEsModule: Boolean = moduleKind == ModuleType.ESModule
def libraryScripts(
outjsfile: AbsolutePath,
ctx: PostProcessContext
Expand All @@ -37,7 +38,12 @@ case class JsConfig(
if (filename.endsWith(".js")) {
lib.copyTo(out)
val src = out.toRelativeLinkFrom(ctx.outputFile, relativeLinkPrefix)
List(s"""<script type="text/javascript" src="$src" defer></script>""")
isEsModule match {
case true =>
List(s"""<script type="module" src="$src"></script>""")
case false =>
List(s"""<script type="text/javascript" src="$src" defer></script>""")
}
} else if (filename.endsWith(".js.map")) {
lib.copyTo(out)
Nil
Expand Down
43 changes: 35 additions & 8 deletions mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import scala.concurrent.Future
import java.nio.file.Paths
import mdoc.js.interfaces._
import java.util.ServiceLoader
import mdoc.js.interfaces.ModuleType.CommonJSModule
import mdoc.js.interfaces.ModuleType.ESModule
import mdoc.js.interfaces.ModuleType.NoModule

class JsModifier extends mdoc.PreModifier {
override val name = "js"
Expand Down Expand Up @@ -173,15 +176,30 @@ class JsModifier extends mdoc.PreModifier {
val outjsfile = resolveOutputJsFile(inputFile)
outjsfile.write(new String(content))
val outmdoc = outjsfile.resolveSibling(_ => "mdoc.js")
outmdoc.write(Resources.readPath("/mdoc.js"))
val selectMocTemplate = config.moduleKind match {
case CommonJSModule => "/mdoc_nomodule.js"
case ESModule => "/mdoc_esmodule.js"
case NoModule => "/mdoc_nomodule.js"
}
outmdoc.write(Resources.readPath(selectMocTemplate))
val relfile = outjsfile.toRelativeLinkFrom(ctx.outputFile, config.relativeLinkPrefix)
val relmdoc = outmdoc.toRelativeLinkFrom(ctx.outputFile, config.relativeLinkPrefix)
new CodeBuilder()
.println(config.htmlHeader)
.lines(config.libraryScripts(outjsfile, ctx))
.println(s"""<script type="text/javascript" src="$relfile" defer></script>""")
.println(s"""<script type="text/javascript" src="$relmdoc" defer></script>""")
.toString
config.moduleKind match {
case NoModule | CommonJSModule =>
new CodeBuilder()
.println(config.htmlHeader)
.lines(config.libraryScripts(outjsfile, ctx))
.println(s"""<script type="text/javascript" src="$relfile" defer></script>""")
.println(s"""<script type="text/javascript" src="$relmdoc" defer></script>""")
.toString
case ESModule =>
new CodeBuilder()
.println(config.htmlHeader)
.lines(config.libraryScripts(outjsfile, ctx))
.println(s"""<script type="module" src="$relfile"></script>""")
.println(s"""<script type="module" src="$relmdoc"></script>""")
.toString
}
}
}
}
Expand Down Expand Up @@ -250,14 +268,23 @@ class JsModifier extends mdoc.PreModifier {
.toString
}

val outModule = ctx.outputFile.toRelative(ctx.outDirectory)

runs += code
new CodeBuilder()
.printIf(!mods.isInvisible, s"```scala")
.printIf(!remainingMods.isEmpty && !mods.isInvisible, remainingMods.mkString(" ", " ", ""))
.printIf(remainingMods.isEmpty && !mods.isInvisible, s"\n")
.printIf(!mods.isInvisible, s"${input.text}\n```")
.printIf(!mods.isInvisible, s"\n")
.printlnIf(mods.isEntrypoint, s"""<div id="$htmlId" data-mdoc-js>$body</div>""")
.printlnIf(
mods.isEntrypoint && !config.isEsModule,
s"""<div id="$htmlId" data-mdoc-js>$body</div>"""
)
.printlnIf(
mods.isEntrypoint && config.isEsModule,
s"""<div id="$htmlId" data-mdoc-js data-mdoc-module-name="./$outModule.js" >$body</div>"""
)
.toString
}
}
21 changes: 21 additions & 0 deletions tests/unit-js/src/test/scala/tests/js/JsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ class JsSuite extends BaseMarkdownSuite {
""".stripMargin
)

check(
"basic_es",
"""
|```scala mdoc:js
|println("hello world!")
|```
|""".stripMargin,
"""|```scala
|println("hello world!")
|```
|<div id="mdoc-html-run0" data-mdoc-js data-mdoc-module-name="./basic_es.md.js" ></div>
|<script type="module" src="basic_es.md.js"></script>
|<script type="module" src="mdoc.js"></script>
""".stripMargin,
settings = {
baseSettings.copy(
site = baseSettings.site.updated("js-module-kind", "ESModule")
)
}
)

check(
"extra_fences",
"""
Expand Down

0 comments on commit 87ca141

Please sign in to comment.