Svyatoslav Kuzmich [JB]
03/04/2019, 2:21 PMfun js(code: String): dynamic
function.
[https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.js/js.html#js]
It allows you to embed JavaScript code to Kotlin. Its one of those features which is super simple to use in most cases but becomes quite complex when specifying what it does in general. It has some problems.
It implicitly links Kotlin declarations with names used inside JavaScript snippet, and can become an effective tool to shoot yourself in a foot. For most interop needs safer constructs like external declarations and dynamic expressions can be used instead.
It is also a tough feature to maintain: it requires a whole JavaScript parser to be included and parser result integrated with compiler data structures. Switching parsers can be hard. Supporting multiple ES versions only adds to complexity.
We are considering various options to redesign it in future releases to make it “less powerful”. We would like to hear your input to make sure we got you covered with a smooth transition:
Do you use js
function a lot? What for?
Are they big? What constructs do you put inside?thana
03/04/2019, 2:26 PMval array = js("[]")
array.push("something")
which feels far more lightweight then trying to to the same in pure kotlin 😄jw
03/04/2019, 2:28 PM{}
so i can create an arbitrary object. there's an YouTrack issue for a map-like facade which would obviate its need.Casey Brooks
03/04/2019, 3:14 PMjs()
function altogether. inline fun obj(block: dynamic.() -> Unit): dynamic {
return object{}.apply<dynamic>(block)
}
// example usage
val options = obj {
url = "<http://api.gdax.com/products/BTC-USD/ticker>"
json = true
headers = obj {
this["User-Agent"] = "request"
}
}
araqnid
03/04/2019, 3:18 PMdelete obj[property]
• passing a js regex
• calling Object.keys and Object.values
• dereferencing the Symbol.iterator property of an object
wouldn’t surprise me if there were ways to do these without using js(), I didn’t necessarily look hard (or since finding one solution months ago)jw
03/04/2019, 3:18 PMobject {}
is there. And I suspect it would cause a class to be created in JS.spand
03/04/2019, 3:19 PMjsObject
for that ?Casey Brooks
03/04/2019, 3:33 PMCasey Brooks
03/04/2019, 3:34 PMjsObject
, it doesn’t seem to be in the stdlib (or maybe I’m just missing it)Casey Brooks
03/04/2019, 3:35 PMobject{}
works to avoid using the js()
functionjw
03/04/2019, 3:35 PMobject{}
with js("{}"}
and your function works exact the same except it's now cheaper and faster in the actual JSspand
03/04/2019, 3:36 PMSvyatoslav Kuzmich [JB]
03/04/2019, 3:43 PMobject{}
currently does create a “class” without any members. It behaves similar to JS object literal (with a bit of overhead) if you add properties to its instance in dynamic
way.Robert Jaros
03/04/2019, 4:35 PMjs("Object").keys
to enumerate properties of dynamic objects.Robert Jaros
03/04/2019, 4:41 PMjs("new Date(2017,2,14,14,50,35).getTime()")
. I have no idea why 😉Robert Jaros
03/04/2019, 4:50 PMjs("....")
function, that just inlines the given text to the resulted javascript code? Without any parser or checking? To just assume a developer knows what he/she is doing?Svyatoslav Kuzmich [JB]
03/04/2019, 4:53 PMjw
03/04/2019, 4:54 PMRobert Jaros
03/04/2019, 5:00 PMSvyatoslav Kuzmich [JB]
03/04/2019, 5:04 PMgalex
03/04/2019, 5:12 PMval themeProps: ThemeOptions = js("({palette: { type: 'placeholder', primary: {main: 'placeholder'}}, typography: {useNextVariants: 'placeholder'}})")
Robert Jaros
03/04/2019, 5:21 PMval variable = ...
val result = js("jsfunction(${variable})")
It would insert the correct variable name (even if it's mangled in resulting code).Robert Jaros
03/04/2019, 5:22 PMaltavir
03/04/2019, 7:17 PMjs
is probably not very inspiring. I do not have a lot of experience with JavaScript. So there are some constructs from examples that I just can't translate into kotlin. In this case I just use js
call for the whole construct.gbaldeck
03/04/2019, 7:45 PM@JsName
annotation so that they are not mangled by the compiler? Then you can use those exact names in the js("...")
call.Svyatoslav Kuzmich [JB]
03/04/2019, 8:29 PMgaetan
03/05/2019, 7:16 AMprivate fun getPixelRatio(): Double{
var pixelRatio = 1.0
js("""
if((typeof window.devicePixelRatio) !== 'undefined') {
pixelRatio = window.devicePixelRatio
}
""")
return pixelRatio
}
internal actual fun delegateNow(): Double = (if (performanceAvailable) js("performance.now()") as Double else Date.now())
val performanceAvailable:Boolean = js("((typeof performance === 'object') && performance.now) ? true : false ") as Boolean
ankushg
03/06/2019, 1:01 AMjs(...)
in a few integration tests to (try to) make sure that things work as expected in JS-land after being DCEd (i.e., method names we rely on aren't mangled if we forget to add a @JsName
annotation, things we need aren't stripped out if we forget to add them to the dceOptions.keep
)