Skip to content

Commit e5b46a1

Browse files
committed
Move all documentation into doc/
1 parent c3cca64 commit e5b46a1

File tree

9 files changed

+322
-314
lines changed

9 files changed

+322
-314
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ Includes a router, testing utils, performance utils, more.
1818
- [Type Summary](doc/TYPES.md).
1919
- [Functional Programming](doc/FP.md).
2020
- Scala-only Utilities.
21-
- [Router](extra/ROUTER.md).
22-
- [Performance Management](extra/PERF.md).
23-
- [Smaller stuff](extra/README.md).
24-
- [Testing](test/README.md).
21+
- [Router](doc/ROUTER.md).
22+
- [Performance Management](doc/PERFORMANCE.md).
23+
- [Smaller stuff](doc/EXTRA.md).
24+
- [Testing](doc/TESTING.md).
2525
- [Changelogs](doc/)[Latest](doc/CHANGELOG-0.10.md).
2626

2727

doc/CHANGELOG-0.7.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ https://gist.github.com/japgolly/c68482dbadb0077f550c
3838
#### Router
3939
New in this release is a router, type-safe and written entirely in Scala.js, for Single-Page Applications.
4040

41-
See [extra/ROUTER.md](https://github.com/japgolly/scalajs-react/blob/master/extra/ROUTER.md) for details.
41+
See [ROUTER.md](https://github.com/japgolly/scalajs-react/blob/v0.7.0/extra/ROUTER.md) for details.
4242

4343
#### Refs
4444
* Refs can now be applied to components from the outside, prior to mounting. ([#44](https://github.com/japgolly/scalajs-react/issues/44))

doc/CHANGELOG-0.9.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ find . -name '*.scala' -type f -exec perl -pi -e 's/focusState/zoom/g' {} +
4949
* nice `.toString` methods to `Px` classes.
5050
* `ReusableFn.renderComponent` which recreates a `Props ~=> ReactElement`.
5151
* `ReactComponentB.configureSpec` - useful for JS interop.
52-
* [`ReusableVal2`](../extra/PERF.md#reusableval2): A lazy value whose reusability is determined by another value.
52+
* [`ReusableVal2`](PERFORMANCE.md#reusableval2): A lazy value whose reusability is determined by another value.
5353
* Upgrade:
5454
* [scala-js-dom](https://github.com/scala-js/scala-js-dom) to 0.8.1.
5555
* Scalaz to 7.1.3.
@@ -85,7 +85,7 @@ find . -name '*.scala' -type f -exec perl -pi -e 's/focusState/zoom/g' {} +
8585
## Performance Management
8686
A number of new tools and utilities have been introduced for you to manage the performance of your React app.
8787

88-
Detail with examples are here: [extra/PERF.md](../extra/PERF.md).
88+
Detail with examples are here: [PERFORMANCE.md](PERFORMANCE.md).
8989

9090
* Scala facade for `React.addons.Perf`. See https://facebook.github.io/react/docs/perf.html.
9191
* `Reusability` for fast, easy & safe `shouldComponentUpdate` management.
@@ -99,7 +99,7 @@ Detail with examples are here: [extra/PERF.md](../extra/PERF.md).
9999

100100
This release comes with a new and improved router.
101101

102-
The design of [the v1 Router](../extra/ROUTER.md)
102+
The design of [the v1 Router](https://github.com/japgolly/scalajs-react/blob/v0.8.4/extra/ROUTER.md)
103103
made certain features very hard to accommodate:
104104
[#96](https://github.com/japgolly/scalajs-react/issues/96),
105105
[#103](https://github.com/japgolly/scalajs-react/issues/103),
@@ -108,7 +108,7 @@ made certain features very hard to accommodate:
108108
[#94](https://github.com/japgolly/scalajs-react/issues/94),
109109
[#69](https://github.com/japgolly/scalajs-react/issues/69).
110110

111-
In contrast, [the v2 Router](../extra/ROUTER2.md) has a different design that:
111+
In contrast, [the v2 Router](https://github.com/japgolly/scalajs-react/blob/v0.9.0/extra/ROUTER2.md) has a different design that:
112112

113113
* Uses a user-provided data representation of your pages to identify routes and their parameters.
114114
* Similarly the Router can now indicate the current page with precision, faciliating dynamic menus and breadcrumbs even in the presence of complex, dynamic routes.
@@ -117,4 +117,4 @@ In contrast, [the v2 Router](../extra/ROUTER2.md) has a different design that:
117117
* Routes can be manipulated in bulk.
118118
* Has a better API such that usage previously recommended against, is now impossible. Noteworthy is that `Router` is now just a `ReactComponent`, and `RouterCtl` is the client API.
119119

120-
Detail with examples are here: [extra/ROUTER2.md](../extra/ROUTER2.md).
120+
Detail with examples are here: [ROUTER2.md](https://github.com/japgolly/scalajs-react/blob/v0.9.0/extra/ROUTER2.md).

doc/EXTRA.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
`extra` Utility Module
2+
======================
3+
4+
```scala
5+
libraryDependencies += "com.github.japgolly.scalajs-react" %%% "extra" % "0.10.0"
6+
```
7+
8+
**Big Stuff**
9+
- [Router](ROUTER.md)
10+
- [Performance Management](PERFORMANCE.md)
11+
12+
**Small Stuff**
13+
- [ExternalVar](#externalvar)
14+
- Component Mixins:
15+
- [Broadcaster and Listenable](#broadcaster-and-listenable)
16+
- [EventListener](#eventlistener)
17+
- [LogLifecycle](#loglifecycle)
18+
- [OnUnmount](#onunmount)
19+
- [SetInterval](#setinterval)
20+
21+
22+
Broadcaster and Listenable
23+
==========================
24+
These help your components listen and react to external events or data changes.
25+
26+
##### Usage
27+
```scala
28+
// A listening component
29+
val component = ReactComponentB[...]
30+
...
31+
.backend(_ => new OnUnmount.Backend)
32+
...
33+
.configure(Listenable.install(...))
34+
...
35+
36+
// A simple broadcaster
37+
object HelloBroadcaster extends Broadcaster[String] {
38+
def sayHello(): Unit = broadcast("Hello!")
39+
}
40+
```
41+
42+
##### Features
43+
* `Listenable`: When component mounts, it registers itself as a listener.
44+
* `Listenable`: When component unmounts, it unregisters itself as a listener.
45+
* `Broadcaster`: Manages listener registration and unregistration.
46+
* `Broadcaster`: Provides a `protected def broadcast(a: A): Unit` for easy message broadcasting.
47+
48+
EventListener
49+
=============
50+
* Installs event listeners when component is mounted.
51+
* Uninstalls event listeners when component is unmounted.
52+
* By default, listens to the component node's events. Can specify other event targets (eg. `window`, `document`)
53+
54+
A live demo with accompanying code is available here:
55+
56+
https://japgolly.github.io/scalajs-react/#examples/event-listener
57+
58+
59+
ExternalVar
60+
===========
61+
Provides a component with safe R/W access to an external variable.
62+
63+
A live demo with accompanying code is available here:
64+
65+
https://japgolly.github.io/scalajs-react/#examples/external-var
66+
67+
68+
LogLifecycle
69+
============
70+
This will cause logging to occur at React component lifecycle stages.
71+
72+
##### Usage
73+
```scala
74+
val component = ReactComponentB[...]
75+
...
76+
.configure(LogLifecycle.short) // Logs the component name and stage
77+
.configure(LogLifecycle.verbose) // Logs component props and state as well
78+
...
79+
```
80+
81+
##### Example output
82+
```
83+
[DragAndDrop Demo] componentWillMount
84+
Constructor {props: Object, _owner: Constructor, _lifeCycleState: "MOUNTED", _pendingCallbacks: null, _currentElement: ReactElement…}
85+
86+
[DragAndDrop Demo] componentDidMount
87+
Constructor {props: Object, _owner: Constructor, _lifeCycleState: "MOUNTED", _pendingCallbacks: null, _currentElement: ReactElement…}
88+
89+
[DragAndDrop Demo] componentWillUpdate
90+
Constructor {props: Object, _owner: Constructor, _lifeCycleState: "MOUNTED", _pendingCallbacks: null, _currentElement: ReactElement…}
91+
Props: List(Item(10,Ten), Item(20,Two Zero), Item(30,Firty), Item(40,Thorty), Item(50,Fipty))
92+
State: ParentState(List(Item(10,Ten), Item(20,Two Zero), Item(30,Firty), Item(40,Thorty), Item(50,Fipty)),Started(Item(50,Fipty)),0)
93+
94+
[DragAndDrop Demo] componentDidUpdate
95+
Constructor {props: Object, _owner: Constructor, _lifeCycleState: "MOUNTED", _pendingCallbacks: null, _currentElement: ReactElement…}
96+
Props: List(Item(10,Ten), Item(20,Two Zero), Item(30,Firty), Item(40,Thorty), Item(50,Fipty))
97+
State: ParentState(List(Item(10,Ten), Item(20,Two Zero), Item(30,Firty), Item(40,Thorty), Item(50,Fipty)),Inactive,0)
98+
```
99+
100+
101+
OnUnmount
102+
=========
103+
Accrues procedures to be run automatically when its component unmounts.
104+
105+
##### Example
106+
```scala
107+
class MyBackend extends OnUnmount {
108+
def init(): Unit = {
109+
console.log("Initialising now...")
110+
onUnmount { console.log("Component unmounting...") }
111+
}
112+
}
113+
114+
val eg = ReactComponentB[Unit]("Example")
115+
.stateless
116+
.backend(_ => new MyBackend)
117+
.render(_ => ???)
118+
.componentWillMount(_.backend.init())
119+
.configure(OnUnmount.install)
120+
.buildU
121+
```
122+
123+
SetInterval
124+
===========
125+
Alternative to `window.setInterval` that automatically unregisters installed callbacks when its component unmounts.
126+
127+
##### Example
128+
```scala
129+
class MyBackend extends SetInterval
130+
131+
val Timer = ReactComponentB[Unit]("Timer")
132+
.initialState(0L)
133+
.backend(_ => new MyBackend)
134+
.render((_,s,_) => div("Seconds elapsed: ", s))
135+
.componentDidMount(c => c.backend.setInterval(c.modState(_ + 1), 1.second))
136+
.configure(SetInterval.install)
137+
.buildU
138+
```
File renamed without changes.
File renamed without changes.

doc/TESTING.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
Testing
2+
=======
3+
4+
##### Contents
5+
- [Setup](#setup)
6+
- [`React.addons.TestUtils`](#reactaddonstestutils)
7+
- [`Simulate` and `Simulation`](#simulate-and-simulation)
8+
- [`Sel`](#sel)
9+
- [`DebugJs`](#debugjs)
10+
11+
Setup
12+
=====
13+
14+
1. Install PhantomJS.
15+
16+
2. Add the following to SBT:
17+
18+
```scala
19+
// scalajs-react test module
20+
libraryDependencies += "com.github.japgolly.scalajs-react" %%% "test" % "0.10.0" % "test"
21+
22+
// React JS itself.
23+
// NOTE: Requires react-with-addons.js instead of just react.js
24+
jsDependencies +=
25+
"org.webjars" % "react" % "0.12.2" % "test" / "react-with-addons.js" commonJSName "React"
26+
27+
// Indicate that unit tests will access the DOM
28+
requiresDOM := true
29+
30+
// Compile tests to JS using fast-optimisation
31+
scalaJSStage in Test := FastOptStage
32+
```
33+
34+
3. To [workaround](https://github.com/scala-js/scala-js/issues/1555) a [PhantomJS bug](https://github.com/ariya/phantomjs/issues/13112) that causes tests to crash if they write to stderr, copy [`PhantomJS2Env.scala`](../project/PhantomJS2Env.scala) to your `project` directory and add this to SBT:
35+
36+
```scala
37+
jsEnv in Test := new PhantomJS2Env(scalaJSPhantomJSClassLoader.value)
38+
```
39+
40+
41+
`React.addons.TestUtils`
42+
========================
43+
[React.addons.TestUtils](https://facebook.github.io/react/docs/test-utils.html) is wrapped in Scala and available as `ReactTestUtils`. Usage is unchanged from JS.
44+
45+
46+
`Simulate` and `Simulation`
47+
===========================
48+
To make event simulation easier, certain event types have dedicated, strongly-typed case classes to wrap event data. For example, JS like
49+
```js
50+
// JavaScript
51+
React.addons.TestUtils.Simulate.change(t, {target: {value: "Hi"}})
52+
```
53+
becomes
54+
```scala
55+
// Scala
56+
ReactTestUtils.Simulate.change(t, ChangeEventData(value = "Hi"))
57+
58+
// Or shorter
59+
ChangeEventData("Hi") simulate t
60+
```
61+
62+
Simulations can also be created and composed without a target, using `Simulation`. Example:
63+
```scala
64+
val a = Simulation.focus
65+
val b = Simulation.change(ChangeEventData(value = "hi"))
66+
val c = Simulation.blur
67+
val s = a andThen b andThen c
68+
69+
// Or shorter
70+
val s = Simulation.focus >> ChangeEventData("hi").simulation >> Simulation.blur
71+
72+
// Or even shorter again, using a convenience method
73+
val s = Simulation.focusChangeBlur("hi")
74+
75+
// Then run it later
76+
s run component
77+
```
78+
79+
`Sel`
80+
=====
81+
DOM lookup is much easier than using `ReactTestUtils` directly by instead using `Sel`.
82+
`Sel` allows you to use a jQuery/CSS-like selector to lookup a DOM element or subset.
83+
Full examples can be [seen here](src/test/scala/japgolly/scalajs/react/test/SelTest.scala); this is a sample:
84+
```scala
85+
val dom = Sel(".inner a.active.new") findIn myComponent
86+
```
87+
88+
Note: The syntax is quite limited. It supports tags and classes. It does **not** support Ids.
89+
jQuery or Sizzle will do a better job. I don't think I thought of that when I wrote `Sel` :)
90+
91+
`DebugJs`
92+
=========
93+
[DebugJs](src/main/scala/japgolly/scalajs/react/test/DebugJs.scala) is a dumping ground for functionality useful when testing raw JS.
94+
95+
It doesn't have much but `inspectObject` can be tremendously useful.
96+
97+
Example:
98+
```scala
99+
.componentDidMount { $ =>
100+
val dom = $.getDOMNode()
101+
println(DebugJs inspectObject dom)
102+
}
103+
```
104+
105+
Output (truncated):
106+
```
107+
[object HTMLCanvasElement]
108+
[ 1/137] ALLOW_KEYBOARD_INPUT : number = 1
109+
[ 2/137] ATTRIBUTE_NODE : number = 2
110+
[ 3/137] CDATA_SECTION_NODE : number = 4
111+
[ 4/137] COMMENT_NODE : number = 8
112+
[ 5/137] DOCUMENT_FRAGMENT_NODE : number = 11
113+
[ 6/137] DOCUMENT_NODE : number = 9
114+
[ 7/137] DOCUMENT_POSITION_CONTAINED_BY : number = 16
115+
[ 8/137] DOCUMENT_POSITION_CONTAINS : number = 8
116+
[ 9/137] DOCUMENT_POSITION_DISCONNECTED : number = 1
117+
[ 10/137] DOCUMENT_POSITION_FOLLOWING : number = 4
118+
[ 11/137] DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : number = 32
119+
[ 12/137] DOCUMENT_POSITION_PRECEDING : number = 2
120+
[ 13/137] DOCUMENT_TYPE_NODE : number = 10
121+
[ 14/137] ELEMENT_NODE : number = 1
122+
[ 15/137] ENTITY_NODE : number = 6
123+
[ 16/137] ENTITY_REFERENCE_NODE : number = 5
124+
[ 17/137] NOTATION_NODE : number = 12
125+
[ 18/137] PROCESSING_INSTRUCTION_NODE : number = 7
126+
[ 19/137] TEXT_NODE : number = 3
127+
[ 20/137] accessKey : string =
128+
[ 21/137] addEventListener : function = function addEventListener() {
129+
[ 22/137] appendChild : function = function appendChild() {
130+
[ 23/137] attributes : object = [object NamedNodeMap]
131+
[ 24/137] baseURI : object = null
132+
[ 25/137] blur : function = function blur() {
133+
[ 26/137] childElementCount : number = 0
134+
[ 27/137] childNodes : object = [object NodeList]
135+
[ 28/137] children : object = [object HTMLCollection]
136+
[ 29/137] classList : object =
137+
[ 30/137] className : string =
138+
[ 31/137] click : function = function click() {
139+
[ 32/137] clientHeight : number = 0
140+
[ 33/137] clientLeft : number = 0
141+
[ 34/137] clientTop : number = 0
142+
[ 35/137] clientWidth : number = 0
143+
[ 36/137] cloneNode : function = function cloneNode() {
144+
[ 37/137] compareDocumentPosition : function = function compareDocumentPosition() {
145+
[ 38/137] contains : function = function contains() {
146+
[ 39/137] contentEditable : string = inherit
147+
[ 40/137] dataset : object = [object DOMStringMap]
148+
[ 41/137] dir : string =
149+
[ 42/137] dispatchEvent : function = function dispatchEvent() {
150+
[ 43/137] draggable : boolean = false
151+
[ 44/137] firstChild : object = null
152+
[ 45/137] firstElementChild : object = null
153+
[ 46/137] focus : function = function focus() {
154+
[ 47/137] getAttribute : function = function getAttribute() {
155+
[ 48/137] getAttributeNS : function = function getAttributeNS() {
156+
[ 49/137] getAttributeNode : function = function getAttributeNode() {
157+
[ 50/137] getAttributeNodeNS : function = function getAttributeNodeNS() {
158+
[ 51/137] getBoundingClientRect : function = function getBoundingClientRect() {
159+
[ 52/137] getClientRects : function = function getClientRects() {
160+
[ 53/137] getContext : function = function getContext() {
161+
[ 54/137] getElementsByClassName : function = function getElementsByClassName() {
162+
[ 55/137] getElementsByTagName : function = function getElementsByTagName() {
163+
[ 56/137] getElementsByTagNameNS : function = function getElementsByTagNameNS() {
164+
[ 57/137] hasAttribute : function = function hasAttribute() {
165+
[ 58/137] hasAttributeNS : function = function hasAttributeNS() {
166+
[ 59/137] hasAttributes : function = function hasAttributes() {
167+
[ 60/137] hasChildNodes : function = function hasChildNodes() {
168+
[ 61/137] height : number = 150
169+
[ 62/137] hidden : boolean = false
170+
[ 63/137] id : string =
171+
...
172+
```

0 commit comments

Comments
 (0)