This repository has been archived by the owner on Sep 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#10: Provide annotation/macro to inject dependencies
- Replace *Aware traits with @Inject - Package structure cleanup
- Loading branch information
1 parent
0c94a4f
commit 1a093e2
Showing
94 changed files
with
1,071 additions
and
1,472 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,19 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
import scala.language.implicitConversions | ||
import scala.scalajs.js | ||
import scala.scalajs.js.JSConverters.genTravConvertible2JSRichGenTrav | ||
|
||
import org.scalajs.dom.Element | ||
|
||
import com.greencatsoft.angularjs.element.AngularElement | ||
object Angular { | ||
|
||
trait Angular extends js.Object { | ||
import internal.angular | ||
|
||
def module(name: String, require: js.Array[String]): Module = ??? | ||
def apply(name: String): Option[Module] = | ||
angular.module(name).toOption.map(new Module(_)) | ||
|
||
implicit def element(elem: Element): AngularElement | ||
def module(name: String, dependencies: Seq[String] = Nil): Module = | ||
new Module(angular.module(name, dependencies.toJSArray)) | ||
|
||
implicit def element(elem: Element): AngularElement = angular.element(elem) | ||
} |
2 changes: 1 addition & 1 deletion
2
...ft/angularjs/element/AngularElement.scala → ...eencatsoft/angularjs/AngularElement.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
import scala.annotation.StaticAnnotation | ||
|
||
class inject extends StaticAnnotation | ||
|
||
class injectable(name: String) extends StaticAnnotation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
trait Config extends Service with Initializable |
8 changes: 0 additions & 8 deletions
8
src/main/scala/com/greencatsoft/angularjs/ConfigBuilder.scala
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
src/main/scala/com/greencatsoft/angularjs/Controller.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
import scala.scalajs.js | ||
|
||
import com.greencatsoft.angularjs.core.ScopeAware | ||
|
||
trait Controller extends NamedService with Initializable with ScopeAware { | ||
|
||
abstract override def initialize() { | ||
super.initialize() | ||
scope.dynamic.controller = this.asInstanceOf[js.Object] | ||
} | ||
} | ||
|
||
trait PageController extends Controller with Templated | ||
|
||
trait TitledPageController extends PageController with Titled |
233 changes: 233 additions & 0 deletions
233
src/main/scala/com/greencatsoft/angularjs/Directive.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
import scala.language.experimental.macros | ||
import scala.language.implicitConversions | ||
import scala.scalajs.js | ||
import scala.scalajs.js.Any.{ fromBoolean, fromFunction2, fromFunction4, fromString, wrapArray } | ||
import scala.scalajs.js.UndefOr | ||
import scala.scalajs.js.UndefOr.undefOr2ops | ||
import scala.scalajs.js.annotation.JSBracketAccess | ||
|
||
import org.scalajs.dom.Element | ||
|
||
import com.greencatsoft.angularjs.core.Scoped | ||
import com.greencatsoft.angularjs.internal.{ ConfigBuilder, Configuration, ServiceProxy } | ||
|
||
trait Directive extends NamedService with Function0[Configuration] with Scoped with ConfigBuilder { | ||
|
||
import internal.{ Angular => angular } | ||
|
||
override def apply(): Configuration = buildConfig() | ||
|
||
override def buildConfig(config: Configuration): Configuration = { | ||
def bind(scope: ScopeType): ScopeType = { | ||
scope.dynamic.directive = this.asInstanceOf[js.Object] | ||
scope | ||
} | ||
|
||
config("link") = (scope: ScopeType, elems: js.Array[Element], attrs: Attributes, controllers: UndefOr[js.Any]) => { | ||
controllers.toOption match { | ||
case Some(arr) if js.Array.isArray(arr) => | ||
val args = arr.asInstanceOf[js.Array[js.Any]].toSeq.map(ServiceProxy.unbind[Controller](_)).flatten | ||
link(bind(scope), elems, attrs, args: _*) | ||
case Some(c) => | ||
ServiceProxy.unbind[Controller](c) match { | ||
case Some(arg) => link(bind(scope), elems, attrs, arg) | ||
case _ => link(bind(scope), elems, attrs) | ||
} | ||
case None => link(bind(scope), elems, attrs) | ||
} | ||
} | ||
|
||
controller.foreach(config("controller") = _) | ||
|
||
super.buildConfig(config) | ||
} | ||
|
||
def controller(): Option[js.Any] = None | ||
|
||
protected def proxy[A <: Controller](target: A): js.Any = macro ServiceProxy.newInstance[A] | ||
|
||
def link(scope: ScopeType, elems: Seq[Element], attrs: Attributes, controller: Controller*): Unit = Unit | ||
} | ||
|
||
trait Attributes extends js.Object { | ||
|
||
val $attr: js.Dictionary[String] = ??? | ||
|
||
def $addClass(classVal: String): Unit = ??? | ||
|
||
def $removeClass(classVal: String): Unit = ??? | ||
|
||
def $updateClass(newClasses: String, oldClasses: String): Unit = ??? | ||
|
||
@JSBracketAccess | ||
def apply(name: String): UndefOr[String] = ??? | ||
|
||
@JSBracketAccess | ||
def update(name: String, value: String): Unit = ??? | ||
|
||
def $get(name: String): UndefOr[String] = ??? | ||
|
||
def $set(name: String, value: String): Unit = ??? | ||
|
||
def $observe(key: String, fn: js.Function1[String, Unit]): Unit = ??? | ||
} | ||
|
||
trait Requires extends ConfigBuilder { | ||
this: Directive => | ||
|
||
var requirements = Set.empty[Requirement] | ||
|
||
abstract override def buildConfig(config: Configuration): Configuration = { | ||
config("require") = js.Array[String](requirements.toSeq.map(_.toString): _*) | ||
|
||
super.buildConfig(config) | ||
} | ||
|
||
case class Requirement(name: String, lookup: Boolean, optional: Boolean = false) { | ||
|
||
override def toString = (if (lookup) "^" else "") + (if (optional) "?" else "") + name | ||
} | ||
|
||
def ^(requirement: NamedService) = new Requirement(requirement.name, true) | ||
|
||
def ^?(requirement: NamedService) = new Requirement(requirement.name, true, true) | ||
|
||
def ?(requirement: NamedService) = new Requirement(requirement.name, false, true) | ||
|
||
implicit def ~(requirement: NamedService) = new Requirement(requirement.name, false) | ||
} | ||
|
||
trait RestrictedDirective extends Directive with ConfigBuilder { | ||
|
||
def restrict: Set[String] = Set.empty | ||
|
||
abstract override def buildConfig(config: Configuration): Configuration = { | ||
config("restrict") = restrict.mkString | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
||
trait ElementDirective extends RestrictedDirective { | ||
|
||
override def restrict = super.restrict + "E" | ||
|
||
var transclude = false | ||
|
||
var replace = false | ||
|
||
abstract override def buildConfig(config: Configuration): Configuration = { | ||
config("transclude") = transclude | ||
config("replace") = replace | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
||
trait AttributeDirective extends RestrictedDirective { | ||
|
||
override def restrict = super.restrict + "A" | ||
} | ||
|
||
trait ClassDirective extends RestrictedDirective { | ||
|
||
override def restrict = super.restrict + "C" | ||
} | ||
|
||
trait CommentDirective extends RestrictedDirective { | ||
|
||
override def restrict = super.restrict + "M" | ||
} | ||
|
||
trait ScopeStrategy extends ConfigBuilder { | ||
this: Directive => | ||
} | ||
|
||
trait InheritParentScope extends ScopeStrategy { | ||
this: Directive => | ||
|
||
override def buildConfig(config: Configuration): Configuration = { | ||
config("scope") = true | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
||
trait UseParentScope extends ScopeStrategy { | ||
this: Directive => | ||
|
||
override def buildConfig(config: Configuration): Configuration = { | ||
config("scope") = false | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
||
trait IsolatedScope extends ScopeStrategy { | ||
this: Directive => | ||
|
||
var bindings = Seq.empty[ScopeBinding] | ||
|
||
override def buildConfig(config: Configuration): Configuration = { | ||
val dict = js.Dictionary.empty[String] | ||
|
||
bindings foreach { b => | ||
dict(b.name) = s"${b.prefix}${b.attribute}" | ||
} | ||
|
||
config("scope") = dict | ||
|
||
super.buildConfig(config) | ||
} | ||
|
||
abstract class ScopeBinding(val prefix: String) { | ||
|
||
val name: String | ||
|
||
val attribute: String | ||
} | ||
|
||
case class UnidirectionalBinding(name: String, attribute: String = "") extends ScopeBinding("=") | ||
|
||
case class BidirectionalBinding(name: String, attribute: String = "") extends ScopeBinding("@") | ||
|
||
case class BehavioralBinding(name: String, attribute: String = "") extends ScopeBinding("&") | ||
|
||
implicit class BindingBuilder(name: String) { | ||
|
||
def :=(attribute: String = ""): ScopeBinding = UnidirectionalBinding(name, attribute) | ||
|
||
def :@(attribute: String = ""): ScopeBinding = BidirectionalBinding(name, attribute) | ||
|
||
def :&(attribute: String = ""): ScopeBinding = BehavioralBinding(name, attribute) | ||
} | ||
} | ||
|
||
trait TemplatedDirective extends ConfigBuilder with Templated { | ||
this: Directive => | ||
|
||
def getTemplateUrl(elems: Seq[AngularElement], attrs: Attributes): String = templateUrl | ||
|
||
abstract override def buildConfig(config: Configuration): Configuration = { | ||
config("templateUrl") = (elems: js.Array[AngularElement], attrs: Attributes) => getTemplateUrl(elems, attrs) | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
||
trait TemplateSourceDirective extends ConfigBuilder with TemplateSource { | ||
this: Directive => | ||
|
||
val template: String | ||
|
||
def getTemplate(elems: Seq[AngularElement], attrs: Attributes): String = template | ||
|
||
abstract override def buildConfig(config: Configuration): Configuration = { | ||
config("template") = (elems: js.Array[AngularElement], attrs: Attributes) => getTemplate(elems, attrs) | ||
|
||
super.buildConfig(config) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
trait Factory[A] extends NamedTarget with Function0[A] { | ||
|
||
override def initialize(): Unit = Unit | ||
} | ||
trait Factory[A] extends NamedService with Function0[A] |
6 changes: 6 additions & 0 deletions
6
src/main/scala/com/greencatsoft/angularjs/Initializable.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.greencatsoft.angularjs | ||
|
||
trait Initializable { | ||
|
||
def initialize(): Unit = Unit | ||
} |
This file was deleted.
Oops, something went wrong.
12 changes: 0 additions & 12 deletions
12
src/main/scala/com/greencatsoft/angularjs/InjectionTarget.scala
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.