Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace docs with mdoc #766

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open

Replace docs with mdoc #766

wants to merge 14 commits into from

Conversation

zetashift
Copy link
Contributor

Improves and replaces #741

docs/readme.md Outdated Show resolved Hide resolved
@zetashift
Copy link
Contributor Author

Running docs/mdoc gives me the following error (while it didn't in my previous effort):

[error] stack trace is suppressed; run last docs / Compile / managedResources for the full ou
tput
[error] (docs / Compile / managedResources) sbt.internal.util.Init$RuntimeUndefined: References to undefined settings at runtime.
[error] ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,jsdocs)), Select(ConfigKey(compile)), Zero, Zero),fullClasspath) referenced from setting(ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,docs)), Select(ConfigKey(compile)), Zero, Zero),resourceGenerators)) at LinePosition((mdoc.MdocPlugin.projectSettings) MdocPlugin.scala,111)
[error] ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,jsdocs)), Select(ConfigKey(compile)), Zero, Zero),scalacOptions) referenced from setting(ScopedKey(Scope(Select(ProjectRef(file:/home/rishi/dev/scala/new/scala-js-dom/,docs)), Select(ConfigKey(compile)), Zero, Zero),resourceGenerators)) at LinePosition((mdoc.MdocPlugin.projectSettings) MdocPlugin.scala,111)
[error] Total time: 1 s, completed Feb 20, 2023, 12:27:59 AM

project/plugins.sbt Outdated Show resolved Hide resolved
@zetashift
Copy link
Contributor Author

We now have our first runnable demo!

Things to do

  • Is the current way of making a demo good enough?
    • if so change all the other demos as well
  • style the page
  • hook it up to CI/CD things

@zetashift
Copy link
Contributor Author

So the current websocket demo that's commented out, makes mdoc crash with the following:

info: Compiling 1 file to /home/rishi/dev/scala/scala-js-dom/mdocs/target/mdoc
error:
  Could not generate function for JS function: Found a non-private field value input$3 in final <synthetic> class anonfun$echoWebSocket$1$2 extends scala.scalajs.js.Function with scala.scalajs.js.Function1 {
  final def apply(arg1: org.scalajs.dom.Event): Unit = anonfun$echoWebSocket$1$2.this.input$3.onkeyup_=({
    (new <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1>(anonfun$echoWebSocket$1$2.this): scala.scalajs.js.Function1)
  });
  final <bridge> <artifact> def apply(arg1: Object): Object = {
    anonfun$echoWebSocket$1$2.this.apply(arg1.$asInstanceOf[org.scalajs.dom.Event]());
    scala.runtime.BoxedUnit.UNIT
  };
  <synthetic> <paramaccessor> val input$3: org.scalajs.dom.HTMLInputElement = _;
  <synthetic> <paramaccessor> val socket$1: org.scalajs.dom.WebSocket = _;
  def <init>(input$3: org.scalajs.dom.HTMLInputElement, socket$1: org.scalajs.dom.WebSocket): <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> = {
    anonfun$echoWebSocket$1$2.this.input$3 = input$3;
    anonfun$echoWebSocket$1$2.this.socket$1 = socket$1;
    anonfun$echoWebSocket$1$2.super.<init>(scala.collection.immutable.Nil);
    ()
  }
}
     while compiling: readme.md
        during phase: jscode
     library version: version 2.13.6
    compiler version: version 2.13.6
  reconstructed args: -deprecation -feature -unchecked -Wconf:cat=feature:w -Wconf:cat=deprecation:w -Wconf:cat=unchecked:w -Wconf:cat=deprecation:w -Wconf:cat=deprecation:ws -Wconf:cat=feature:ws -Wconf:cat=optimizer:ws -Wunused:imports -Wunused:patvars -Wunused:locals -Wunused:implicits -classpath /home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/classes:/home/rishi/dev/scala/scala-js-dom/dom/target/scala-2.13/classes:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.6/scala-library-2.13.6.jar:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-library_2.13/1.7.1/scalajs-library_2.13-1.7.1.jar -Xmaxerrs -1 -Xmaxwarns -1 -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-compiler_2.13.6/1.7.1/scalajs-compiler_2.13.6-1.7.1.jar -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.6/4.6.0/semanticdb-scalac_2.13.6-4.6.0.jar -Yrangepos -Ydelambdafy:inline -P:semanticdb:targetroot:/home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/meta

  last tree to typer: TypeTree(class Event)
       tree position: line 140 of readme.md
            tree tpe: org.scalajs.dom.Event
              symbol: class Event in package dom
   symbol definition: class Event extends Object (a ClassSymbol)
      symbol package: org.scalajs.dom
       symbol owners: class Event
           call site: <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> in package <empty>

== Source file context for tree position ==

   137 }
   138 @_root_.scala.scalajs.js.annotation.JSExportTopLevel("mdoc_js_run13")
   139 def run13(node: _root_.org.scalajs.dom.html.Element): Unit = {
   140 document.getElementById("demo7-btn").addEventListener("click", (ev: Event) => {
   141   changeColor(document.getElementById("demo7-text").asInstanceOf[html.Div])
   142 })
   143 }
error: Error while emitting readme.md

  Could not generate function for JS function: Found a non-private field value input$3 in final <synthetic> class anonfun$echoWebSocket$1$2 extends scala.scalajs.js.Function with scala.scalajs.js.Function1 {
  final def apply(arg1: org.scalajs.dom.Event): Unit = anonfun$echoWebSocket$1$2.this.input$3.onkeyup_=({
    (new <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1>(anonfun$echoWebSocket$1$2.this): scala.scalajs.js.Function1)
  });
  final <bridge> <artifact> def apply(arg1: Object): Object = {
    anonfun$echoWebSocket$1$2.this.apply(arg1.$asInstanceOf[org.scalajs.dom.Event]());
    scala.runtime.BoxedUnit.UNIT
  };
  <synthetic> <paramaccessor> val input$3: org.scalajs.dom.HTMLInputElement = _;
  <synthetic> <paramaccessor> val socket$1: org.scalajs.dom.WebSocket = _;
  def <init>(input$3: org.scalajs.dom.HTMLInputElement, socket$1: org.scalajs.dom.WebSocket): <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> = {
    anonfun$echoWebSocket$1$2.this.input$3 = input$3;
    anonfun$echoWebSocket$1$2.this.socket$1 = socket$1;
    anonfun$echoWebSocket$1$2.super.<init>(scala.collection.immutable.Nil);
    ()
  }
}
     while compiling: readme.md
        during phase: jscode
     library version: version 2.13.6
    compiler version: version 2.13.6
  reconstructed args: -deprecation -feature -unchecked -Wconf:cat=feature:w -Wconf:cat=deprecation:w -Wconf:cat=unchecked:w -Wconf:cat=deprecation:w -Wconf:cat=deprecation:ws -Wconf:cat=feature:ws -Wconf:cat=optimizer:ws -Wunused:imports -Wunused:patvars -Wunused:locals -Wunused:implicits -classpath /home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/classes:/home/rishi/dev/scala/scala-js-dom/dom/target/scala-2.13/classes:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.6/scala-library-2.13.6.jar:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-library_2.13/1.7.1/scalajs-library_2.13-1.7.1.jar -Xmaxerrs -1 -Xmaxwarns -1 -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-js/scalajs-compiler_2.13.6/1.7.1/scalajs-compiler_2.13.6-1.7.1.jar -Xplugin:/home/rishi/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.6/4.6.0/semanticdb-scalac_2.13.6-4.6.0.jar -Yrangepos -Ydelambdafy:inline -P:semanticdb:targetroot:/home/rishi/dev/scala/scala-js-dom/mdocs-js/target/scala-2.13/meta

  last tree to typer: TypeTree(class Event)
       tree position: line 140 of readme.md
            tree tpe: org.scalajs.dom.Event
              symbol: class Event in package dom
   symbol definition: class Event extends Object (a ClassSymbol)
      symbol package: org.scalajs.dom
       symbol owners: class Event
           call site: <$anon: scala.scalajs.js.Function with scala.scalajs.js.Function1> in package <empty>

== Source file context for tree position ==

   137 }
   138 @_root_.scala.scalajs.js.annotation.JSExportTopLevel("mdoc_js_run13")
   139 def run13(node: _root_.org.scalajs.dom.html.Element): Unit = {
   140 document.getElementById("demo7-btn").addEventListener("click", (ev: Event) => {
   141   changeColor(document.getElementById("demo7-text").asInstanceOf[html.Div])
   142 })
   143 }
warning: readme.md:198:1: local method echoWebSocket in method run11 is never used
def echoWebSocket(input: html.Input, pre: html.Pre) = {

@sjrd
Copy link
Member

sjrd commented Feb 27, 2023

Is that reproducible outside of mdoc?

@zetashift
Copy link
Contributor Author

Is that reproducible outside of mdoc?

I don't think so:

I tried the following:

//> using platform "scala-js"
//> using scala "3.2.2"
//> using dep "org.scala-js::scalajs-dom::2.4.0"

import org.scalajs.dom.*

@main def echo() =
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)

  socket.onmessage = (e: MessageEvent) => println(e.data.toString)
  socket.onopen = (e: Event) => println("Connected")

And it compiles fine

@zetashift
Copy link
Contributor Author

zetashift commented Feb 27, 2023

It seems to be an mdoc thing:

This works:

def addInput(input: html.Input, socket: WebSocket) = {
  input.onkeyup = (e: Event) => socket.send(input.value)
}

def echoWebSocket(input: html.Input, pre: html.Pre) = {
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)
  socket.onmessage = {
    (e: MessageEvent) =>
      pre.textContent +=
        e.data.toString
  }

  socket.onopen = (e: Event) => addInput(input, socket)
}

But this doesn't work(notice that everything in onopen is defined in the function body):

def echoWebSocket(input: html.Input, pre: html.Pre) = {
  val echo = "wss://echo.websocket.org"
  val socket = new WebSocket(echo)
  socket.onmessage = {
    (e: MessageEvent) =>
      pre.textContent +=
        e.data.toString
  }

  socket.onopen = { (e: Event) =>
    input.addEventListener("onkeyup", { (e: Event) =>
      socket.send(input.value)
    })
  }
}

EDIT: will try to report this to mdoc with an easier to follow example :P

@zetashift
Copy link
Contributor Author

@armanbilge
The content for the readme is now reviewable, all the examples are "interactive".
I removed the websocket example because the websocket echo server is not working (they shut it down). And it had mdoc troubles anyway. But I did save my progress here in case we find an alternative websocket server. From googling around I couldn't find a replacement.

Things to do:

  • figure out the whole CI/CD deploy thing
  • I have no idea how to style the eventual page that will because the docs

@armanbilge
Copy link
Member

I removed the websocket example because the websocket echo server is not working

there's a new one from postman you can use, see https://http4s.github.io/http4s-dom/websocket.html

I can look into CI deploy and styling :)

Thanks for all your work on this!!

@zetashift
Copy link
Contributor Author

there's a new one from postman you can use, see https://http4s.github.io/http4s-dom/websocket.html

Actually I found that one in my quest for example servers, but it didn't work for me, it gave back a 101 switching protocols.
But this probably means I did something wrong lol, I'll get on it tomorrow again

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look great! Thank you so much for porting them to mdoc :) only a few minor quips about if we need "run" buttons for some of the examples, I wonder if they could be active on page load.


Regarding deployment, here's what I'm thinking.

I think it would be nice if we could adopt the scala-js.org design/theme for the scala-js-dom website. That site is rendered with Jekyll so it will work well with our mdoc.js + GH pages setup. Instead of copying the theming, we can "fork" it as the gh-pages branch on this repo and customize to our needs. Then, if there are updates to the design/theme upstream, we can merge them into our branch.

One other idea I had along these lines, is that we can deploy the rendered markdown and JS to a branch on this repo. Then the scala-js-website repo could include that as git submodule, so it's deployed as part of the scala-js.org site. We can setup dependabot to automatically open PRs on scala-js-website when there are changes to the site here. Depends what @sjrd thinks of this, of course :)

Thoughts?

docs/readme.md Outdated Show resolved Hide resolved
docs/readme.md Outdated Show resolved Hide resolved
docs/readme.md Outdated Show resolved Hide resolved
docs/readme.md Outdated Show resolved Hide resolved
docs/readme.md Outdated Show resolved Hide resolved
@sjrd
Copy link
Member

sjrd commented Mar 17, 2023

One other idea I had along these lines, is that we can deploy the rendered markdown and JS to a branch on this repo. Then the scala-js-website repo could include that as git submodule, so it's deployed as part of the scala-js.org site. We can setup dependabot to automatically open PRs on scala-js-website when there are changes to the site here. Depends what @sjrd thinks of this, of course :)

What is supposed to be the benefit of publishing inside scala-js.org as opposed to the GH Pages of this repo? It seems like a lot of infrastructure for a questionable benefit.

@armanbilge
Copy link
Member

It seems like a lot of infrastructure

Well, depends who you ask :)

The only "infrastructure" I'm proposing is (1) a git submodule and (2) ~ 3 lines of dependabot YAML.

The alternative is that we maintain all the "infrastructure" to configure and deploy a fully-styled site from this repository. In comparison it seems like a lot more work, at least to me!

@zetashift
Copy link
Contributor Author

Yea I was also unsure about the run buttons, but since the current docs has them, I didn't even think about just removing them lol.

As for the infrastructure, at first the git submodule sounded like a lot of things as well, because well, weaving in a git submodule into another repo sounds like a lot of work. But reading your explanation it does sound like less work? Handling all the infra here does seem like starting from scratch.

@armanbilge
Copy link
Member

weaving in a git submodule into another repo sounds like a lot of work

git submodule add https://github.com/scala-js/scala-js-dom

Then we add a dependabot config like this:
https://github.com/typelevel/cats-effect/blob/fb35b3f85d03cb5d33eb5e12ceb4d3f179346783/.github/dependabot.yml#L3-L8

All this would be doing is placing the index.md with our docs as a page in the scala-js.org website. It would basically be the same if we just manually copied that page in.

@armanbilge
Copy link
Member

I opened a PR against scala-js-website showing how my proposal would work.

@zetashift
Copy link
Contributor Author

I opened a PR against scala-js-website showing how my proposal would work.

* [Add scala-js-dom docs as submodule scala-js-website#609](https://github.com/scala-js/scala-js-website/pull/609)

That does look quite simple, nice! Let's see if sjrd agrees :P

@armanbilge
Copy link
Member

@sjrd polite bump? :)

docs/index.md Outdated Show resolved Hide resolved
docs/index.md Outdated
- dom.css: CSS APIs
- dom: Miscellanious, unclassified APIs

Most names have been shortened from names of the raw browser APIs, since the namespacing avoids collisions. By convention these types are imported qualified: e.g. as `html.Canvas` instead of directly as `Canvas`. There is also the `dom.raw` namespace which contains everything with their full, un-shortened name.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is outdated now. We put everything back into dom and dom.raw was deprecated.

docs/index.md Outdated Show resolved Hide resolved
@@ -41,7 +41,8 @@ ThisBuild / prePR_nonCross := Def.sequential(

Def.taskDyn {
if (scalaVersion.value.startsWith("2.12."))
Def.task[Unit]((readme / Compile / compile).value)
// TODO should this really be docs / Compile?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't know if the current docs / Compile / compile is the right command to run during prePR.
@armanbilge does:

      Def.task[Unit]((docs / Compile / compile).value)

work fine here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to take another look at this. I was hoping we could decide how we are deploying the site so we can figure out what to do with the build :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants