2

The Scala.js documentation has a nice example on how to implement a jQuery facade which also supports chaining:

@js.native
trait JQueryGreenify extends JQuery {
  def greenify(): this.type = ???
}

object JQueryGreenify {
  implicit def jq2greenify(jq: JQuery): JQueryGreenify =
   jq.asInstanceOf[JQueryGreenify]
}

However as far as I understood it, this example assumes that the greenify plugin has been implemented in Javascript already. E.g. like

$.fn.greenify = function() {
  this.css( "color", "green" );
  return this;
}

How would this plugin be implemented in Scala.js?

  • 1
    I honestly don't know if anybody's tried to do so yet. It's certainly possible to do -- as a rule, if it can be done in JavaScript, it should be doable in Scala.js -- but people writing in Scala.js have mostly been writing Scala-centric libraries. So the short answer is, "you'd implement it the same way you would in JavaScript", but I suspect there's some unexplored ground in the details of how best to do that... – Justin du Coeur Mar 18 '16 at 12:07

1 Answers1

3

There two ways to define a "jQuery plugin" in Scala.js. The first one is a safe and idiomatic Scala-esque way, but is only for consumption by other Scala.js code. The second is a bit ugly, but it can be used by JavaScript code.

For Scala.js

In Scala, and in Scala.js, the patch-the-prototype thing that actual jQuery plugins do is discouraged. Instead, we use implicit classes:

implicit class JQueryGreenify(val self: JQuery) extends AnyVal {
  def greenify(): self.type = {
    self.css("color", "green")
    self
  }
}

And then you can simply do

jQuery("#some-element").greenify()

when you have JQueryGreenify in scope (as an import, typically).

This method does not pollute the actual prototype of jQuery objects. It is a pure-Scala abstraction. It is clean and safe, but that means it cannot be used by JavaScript code.

For JavaScript

If you need to call greenify from JavaScript, you actually need to add a function property on the jQuery.fn object. Since the function needs to use the this parameter, we have to explicitly ascribe it to a js.ThisFunction (see also Access the JS this from scala.js):

js.Dynamic.global.jQuery.fn.greenify = { (self: JQuery) =>
  self.css("color", "green")
  self
}: js.ThisFunction

which is basically a transliteration of the original JavaScript code from the question.

Community
  • 1
  • 1
sjrd
  • 21,805
  • 2
  • 61
  • 91