Chat: #scala-js on Discord.
This is the repository for Scala.js, the Scala to JavaScript compiler.
Scala.js is distributed under the Apache License Version 2.0.
Statically typed DOM API for Scala.js
License: Other
Chat: #scala-js on Discord.
This is the repository for Scala.js, the Scala to JavaScript compiler.
Scala.js is distributed under the Apache License Version 2.0.
EventTarget#addEventListener
takes a js.Function1[T, _]
for any T <: Event
but EventTarget#removeEventListener
only accepts a js.Function1[Event, _]
. It should probably also take a js.Function1[T, _]
.
@sjrd Question about efficiency here. We have:
object KeyCode {
val backspace = 8
val tab = 9
// etc
Is there effeciency to be gained by changing to final val
s?
I was thinking @inline def
would be best but then they can be used in pattern matching.
I was trying to use it but I systematically get the following error when I access any of its values: XXXXX is not an instance of java.lang.Integer
in the browser. Taking the js.Dynamic route works fine.
Fails:
val window = dom.document.defaultView
val perf = window.performance.timing
PageLoad(perf.loadEventStart - perf.navigationStart)
Works:
val window = DOMGlobalScope.window
val perf = window.performance.timing
PageLoad(perf.loadEventStart.asInstanceOf[Double] - perf.navigationStart.asInstanceOf[Double])
The Ajax extension is too strict in what it considers failures:
req.onreadystatechange = {(e: dom.Event) =>
if (req.readyState.toInt == 4){
if (200 <= req.status && req.status < 300)
promise.success(req)
else
promise.failure(AjaxException(req))
}
}
304 is a valid response and should not be considered an error.
This would allow people targeting particular platforms to use more experimental features, with the caveat that they require a lot more testing :)
Extensions to core objects like Window would be provided by implicit extensions.
@lihaoyi does org.scalajs.dom.experimental
work as a name, or do you have anything else in mind?
The companion object of MutationObserver
is a plain scala object, so it should not be js.native
here
I thought I create PR that simply changing to
val MutationObserverInit: raw.MutationObserverInit.type = raw.MutationObserverInit
, but produces warning message
Members of traits, classes and objects extending js.Any may only contain members that call js.native. This will be enforced in 1.0.
As per MDN, Text.replaceWholeText()
is deprecated and scheduled for removal. Some browsers already dropped support. I'd suggest to remove this function as well or at least add a deprecation warning. I could send in a PR.
Maybe it's a Firefox only thing? Since it's defined here. If it is, we should probably move it out of the default namespace
Currently scala-js-dom is compiled against scala-js 0.5.
Once we move to 0.5.2+ we can rip out my increasingly silly TypedArray interfaces and change all the signatures.
As revealed by #94.
package object dom
extends js.Any
, and as such it can't export the constructors for various javascript dictionaries.
As it stands, only MutationObserverInit and BlobPropertyBag have constructors, and with BlobPropertyBag only the type is being exported, so it's not being a problem. (though #117 would add a ClipboardEventInit constructor)
Currently my thoughts are either to:
Sadly @sjrd's implicit method trick can only work if dom were a singleton object, not a package.
I bumped the travis build and the build.sbt file; @sjrd would bumping the build to 0.4.0 auto publish it as a non-snapshot, or is that something that needs to be done manually?
I'm just working on bindings for https://www.khronos.org/registry/webgl/specs/1.0/ (it's not up yet, but should be done by the end of the weekend). Would it be worth merging it into scala-js-dom?
WindowTimers.setTimeout()
has the following signature:
def setTimeout(handler: js.Any, timeout: js.Any, args: js.Any*): Int = ???
Some users (including myself) ran into a problem passing a block instead of a lambda. It would be helpful if the compiler could catch this on-the-fly. Therefore, I would advise changing it to:
def setTimeout(handler: () => Unit, timeout: Int): Int = ???
MDN also doesn't specify the additional parameters, which appear to be safe to drop.
In the unlikely event that the user wants to use the untyped version, he can just resort to js.Dynamic.global.setTimeout()
.
as reported by @ochrons via gitter, a trivial issue with an easy fix:
'for some reason in http://www.scala-js.org/api/scalajs-dom/0.8/#org.scalajs.dom.raw.Document the "comment" section is not closed and all the method names look big because of that.
Probably because the comment includes elements such as <body> and <table> making ScalaDoc confused'
Good to catch them all in a single PR (we don't use nested /** */ comments afaik so an easy regex search ought to work). Perhaps put a note in the scala-js
project's CONTRIBUTING.md
?
Something worth looking out for when reviewing PRs for now.
Scalastyle also has an org.scalastyle.scalariform.ScalaDocChecker
plugin, and I'm not sure we're using it in scala-js
, (or how good it is for catching this kind of error, or if it introduces more problems than it would solve...). Eventually maybe we should maintain a duplicate of that task here.
Some docs would be useful
0.6.5 adds |
, which will enable tightening up a lot of the signatures, so I'd vote to move to it if possible.
On the other hand, if we're intentionally staying with 0.6.2 for backwards compatibility, then perhaps we shouldn't just yet. Thoughts?
I have a beginning of a Fetch and Streaming API
https://github.com/read-write-web/rww-scala-js/tree/akka.js/src/main/scala/org/scalajs/dom/experimental
As I use it and make sure it works I'd be happy to add it to the repo here. I have been trying to work on getting as much typesafety as possible out of the Fetch API spec.
I have some initial code demonstrating the working of the Fetch API. I have not yet seriously tested the streaming one yet. As it stabilises I'd be happy to contribute it back. Or else publish it seperately of the library I am building right now.
I would like to invoke dom.requestAnimationFrame. The FrameRequestCallback is a trait that has no provided implicit conversions from a Function1 to an appropriate type.
// Attempt 1
val callback: (js.Number) => Unit = (time: js.Number) => { ... }
dom.requestAnimationFrame(callback) // fails at compile time because (js.Number) => Unit is not a FrameRequestCallback.
// Attempt 2
object callback extends FrameRequestCallback {
override def apply(time: js.Number) { ... }
}
dom.requestAnimationFrame(callback) // fails at runtime because the callback is not a function.
I can't find any code that uses this trait- how is it supposed to be done?
https://github.com/scala-js/scala-js-dom/blob/master/src/main/scala/org/scalajs/dom/lib.scala#L3254
Unfortunately this means we can't actually use a gradient without resorting to silliness!
ctx.asInstanceOf[js.Dynamic].updateDynamic("fillStyle")(gradient)
The spec says:
attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
A possible option would obviously be to just weaken the type to js.Any, but that doesn't seem satisfactory. On the other hand, if it's all we can do, it should probably be done.
strokeStyle
has the same issue.
Does anyone have any better idea how to do this?
Is this an unintentional omission?
Hi,
what's the normal procedure to use addEventListener
with, say, KeyboardEvent
? (maybe the function param type needs to be T forSome { type T <: Event }
)
I'm currently using .onclick
but that seems like a bad idea :).
Hi,
when I (try to) change the value of the scrollTop attribute on a HTMLTextAreaElement, the value is not set.
Mathieu
import scalatags.JsDom.{ tags โ tags }
import scalatags.JsDom.all._
val tARender: HTMLTextAreaElement = tags.textarea(`class` := "form-control", rows := 20).render
tARender.scrollTop = 999.0
println("TOP " + tARender.scrollTop)
Not terribly high priority, but since it seems to be causing confusion: BlobPropertyBag is, if I understand it correctly, basically an options object. As such, the facade isn't actually useful on its own -- there's no good way to use the facade of BlobPropertyBag to create an object to pass into the Blob constructor. It really needs a BlobPropertyBag constructor somewhere to make it functional.
It is currently supported in Firefox, Opera and Chrome. Microsoft have no plans to support it in Trident at this time in favor of adopting their own, competing standard... (Oh, horay, that again). That said, they u-turned on WebGL. The api is technically not browser specific, although I'm not sure what the policy is in this situation.
This actually leads on to a wider question- if a particular browser does not implement a feature, say, WebGL, do we provide a simple method to detect this fact, or is the user of the library forced to drop down to Dynamic hackery to probe the existence themselves? Perhaps this (and general browser version detection) would be a useful addition to org.scalajs.dom.extensions, or would it be better suited as a complementary project that one can optionally link in?
I noticed that you say IE-only, Chrome-only, FF-only, and in general browser-specific attributes will not be present
. Does this mean you would prefer WebRTC to stay out of the scalajs dom for now?
What about things like getUserMedia
. Perhaps that could be added in a similar fashion as Vibrate
in experimental. While leaving things like IceCandidate
, SessionDescription
, ect .. to user code base for now.. thought ?
I am happy to take this on if you like. I will wait to hear what you think is the best approach for this.
Thanks.
Currently, regular expressions used by the Color
class is too strict and it causes an MatchError when it tries to parse such strings:
It would be better if it at least allows arbitary number of spaces/tabs/line breaks between significant numbers.
Trying to do something like this:
val results = Ajax.get("some.json").map { xhr => mapToList(xhr.response) }
results.foreach { x => console.log(x)
This code won't compile because I don't have an ExecutonContext in scope. So I add the recommended global one.
import scala.concurrent.ExecutionContext.Implicits.global
val results = Ajax.get("some.json").map { xhr => mapToList(xhr.response) }
results.foreach { x => console.log(x)
This causes a ton of compilation warnings indicating that I'm referencing scala code that will not be available in the browser. What is the recommended ExecutionContext to use here?
warn] Referring to non-existent class ju_concurrent_Future
[warn] called from s_concurrent_impl_ExecutionContextImpl.execute__jl_Runnable__V
[warn] called from s_concurrent_impl_CallbackRunnable.executeWithValue__s_util_Try__V
[warn] called from s_concurrent_impl_Promise$DefaultPromise.$$anonfun$1__p2__s_concurrent_impl_CallbackRunnable__s_util_Try__V
[warn] called from s_concurrent_impl_Promise$DefaultPromise.tryComplete__s_util_Try__Z
[warn] called from s_concurrent_Promise$class.s_concurrent_Promise$class__complete__s_concurrent_Promise__s_util_Try__s_concurrent_Promise
[warn] called from s_concurrent_impl_Promise$DefaultPromise.complete__s_util_Try__s_concurrent_Promise
[warn] called from s_concurrent_Promise$class.s_concurrent_Promise$class__failure__s_concurrent_Promise__jl_Throwable__s_concurrent_Promise
[warn] called from s_concurrent_impl_Promise$DefaultPromise.failure__jl_Throwable__s_concurrent_Promise
[warn] called from Lorg_scalajs_dom_extensions_Ajax$.apply__T__T__T__I__sci_Map__Z__s_concurrent_Future
[warn] called from Lorg_scalajs_dom_extensions_Ajax$.get__T__T__I__sci_Map__Z__s_concurrent_Future
[warn] called from Ltodo_TaskService$.getAll__s_concurrent_Future
[warn] called from Ltodo_App$.main__V
[warn] called from sjs_js_JSApp$class.sjs_js_JSApp$class__$js$exported$meth$main__sjs_js_JSApp__O
[warn] called from Ltodo_App$.$$js$exported$meth$main__O
[warn] called from Ltodo_App$.<exported>Ltodo_App$
[warn] exported to JavaScript with @JSExport
I am not sure how to get it right but it would be great to have some tests, esp. for DOM extensions, so by adding something I will be sure that I am not breaking anything.
I don't see a reason why DOM elements like HTMLElement
are represented by classes and not traits or abstract classes.
Currently the compiler does not protect us from trying to create HTML elements with plain constructor but it won't work in runtime.
Currently andThen
is defined
def andThen[B](onFulfilled: js.Function1[A,B]): Promise[Any] = js.native
This loss of type in the response (it's of type Promise[Any]
rather than Promise[B]
makes it awkward when writing functions using the Fetch
api where one would like to write things like
def fetchListener(e: FetchEvent) = e.respondWith {
fetch(e.request.url).andThen{
response=> f(response),
err => err
}
}
where respondWith takes a Promise[Response]
. With the current signature one needs to add an extra cast.
Instead the following signature seems more correct and closer to the JS documentation I have read
def andThen[B](onFulfilled: js.Function1[A,B]|js.Function1[A,Promise[B]]): Promise[B] = js.native
Here we use the disjunction type since andThen
can either take a function to a value or a function to something Promisy.
Hello.
The HTMLElement
class in Html.scala
doesn't defines the style
property.
I've added it as
var style: CSSStyleDeclaration = ???
and it seems to be working by now. Is there any reason why it has been left out?
I wonder why
<svg>
</svg>
does not inherit HTMLElement?
shouldn't it be a class since I need to instantiate it?
Wouldn't it be better if we enforced that event handlers return Unit
?
That is change this:
var onmousedown: js.Function1[MouseEvent, _] = js.native
to this:
var onmousedown: js.Function1[MouseEvent, Unit] = js.native
If you agree i can for sure throw up a PR with the necessary changes
Hey, is there any reason why this isn't typed yet?
If not I'll put a patch together.
Noticed that methods for working with ajax in scala-js-dom extensions don't respect any ExecutionContext. Is there any particular reason for that? Or should I make a PR?
Seems there's quite a few msXYZ
properties in css lib. These (and any moz or webkit prefixes) should be removed.
In org.scalajs.dom.raw.HTMLSelectElement the declaration of:
val options: js.Array[HTMLSelectElement] = js.native
Should be:
val options: js.Array[HTMLOptionElement] = js.native
The crypto api mapping is not general enough. The definition I see is:
def generateKey(algorithm: String, extractable: Boolean,
keyUsages: js.Array[String]): Promise[js.Any] = js.native
the algorithm seems to also potentially be an object according to this blog post where the example code is
window.crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: {name: "SHA-256"}
},
true, // Must extract private key to create PEM files later
["sign", "verify"]).
It's actually not that easy to read these JS specs, and WebCrypto API is not exceptions. Still the definition there is
Promise<any> generateKey(AlgorithmIdentifier algorithm,
boolean extractable,
sequence<KeyUsage> keyUsages );
Here:
I am getting runtime errors:
Uncaught scala.scalajs.runtime.UndefinedBehaviorError: An undefined behavior was detected: 67.57 is not an instance of java.lang.Integer
I think these values are measured in seconds that have been buffered.
It appears the WebAudio api accidentally introduced a MediaStream
trait (stubbed) into scala.js.dom.raw
here. This type is also forwarded in dom
.
As you can see though, it's not compatible enough to meet the criteria of being outside of experimental
. But sadly, we've released it in 0.8.1
and 0.8.2
.
There may be others, and I will investigate.
@sjrd @lihaoyi I wonder since the next release will be 0.9.0
if we do some slightly breaking reorganization to fix up anything that slipped out? Hopefully it won't impact too many people.
#179 fleshes out the class (because it's needed for WebRTC), but I've been afraid to move it into experimental without checking with you guys that this breaking change is acceptable.MediaStream
Hi,
the resolver seems to have changed since the 0.5 version.
What resolver is supposed to be used for 0.6 version ?
Thanks for helping !
Mathieu
I'm not sure how difficult this is, but if it's easy then it would be great =) The reduction in bytecode size and support for SAM's is really awesome from a dev-Ex point of view! Same with the JQuery facades.
Is there a reason MouseEvent
does not have pageX
and pageY
? As I can see both are supported by recent browsers. I would prefer not to cast MouseEvent
to my own type just to add these two attributes.
A simple workaround for now is to say img.addEventListener("load", { e: Event => ... })
, but an easy PR for anyone who wants it. If not I'll try to add it before 0.8.2 is released.
In order to be able to find out if a request was redirected to another URL one needs to use the responseURL
method on XMLHTTPRequest
s which I found defined in the whatwg xhr spec.
Currently the code I had to write which works, but is not nice, looks like this:
val redirectURL = xhr.asInstanceOf[js.Dynamic].responseURL.asInstanceOf[String]
You can test it in the browser by compiling and running the html
It may be useful to have a static implementation - though I think it should be done in a way to take account of many browsers returning an undefined value I suppose.
When I attempt to open an XMLHttpRequest using the Ajax utility function, IE11 (correctly) throws an InvalidStateException.
The problem is that withCredentials is being set on the XMLHttpRequest object before it is opened at https://github.com/scala-js/scala-js-dom/blob/master/src/main/scala/org/scalajs/dom/extensions/Extensions.scala#L184.
The issue is explained here:
https://code.google.com/p/v8/issues/detail?id=789
The fix is trivial (just move withCredentials assignment below the open). I can send a PR for it over the weekend if you like.
There should be a HashChangeEvent
. I defined it as follows:
case class HashChangeEvent(newURL: String, oldURL: String)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.