Skip to content

Commit da70c22

Browse files
authored
Merge pull request #523 from scala-js/topic/standards
Document coding standards and conventions
2 parents 385bdfc + cd080dc commit da70c22

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

CONTRIBUTING.md

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
Guide to Contributing
2+
=====================
3+
4+
Thanks for contributing to scala-js-dom!
5+
We primarily accept PRs for:
6+
* Adding facades for APIs documented in the spec
7+
* Enhancing/fixing existing facades to match the spec
8+
* Adding non-facade Scala utilities to complement specific facades
9+
* Any other bug fixes etc.
10+
11+
If you would like to make PR that doesn't fall under those categories,
12+
please raise an issue first for discussion so we can give you the go-ahead!
13+
14+
We look forward to your PRs!
15+
16+
Contents:
17+
18+
* Packages
19+
* Files
20+
* Facades
21+
* Non-Facades
22+
* Binary Compatibility
23+
* Submitting a PR
24+
25+
26+
Packages
27+
========
28+
29+
In v1.x, there used to be sub-packages grouping some parts of the DOM API by major feature.
30+
In v2.x, we've decided to put everything in `org.scalajs.dom` and get rid of sub-packages.
31+
32+
The reason for this change is that the real DOM API isn't namespaced in anyway, and the decision
33+
whether to group in a package or not, was subjective and inconsistent.
34+
35+
36+
Files
37+
=====
38+
39+
* Use `package.scala` for a package object and nothing else.
40+
Also don't include traits/classes/objects.
41+
42+
* Match the filename to the trait/class/object in it; don't add multiple top-level types.
43+
This is effectively Java-style.
44+
45+
46+
Facades
47+
=======
48+
49+
We accept facades for any non-deprecated API documented in the spec, including experimental APIs or APIs not supported on all browsers.
50+
* MDN: https://developer.mozilla.org/en-US/docs/Web/API
51+
* WHATWG: https://spec.whatwg.org/
52+
53+
Please:
54+
* Use `def` for read-only properties unless there is a compelling reason it should be a `val`
55+
(i.e., the spec definitively states it is constant)
56+
* Use `Double` for integer-values that can fall outside the range of `Int`
57+
* Add scaladocs via copy-paste from MDN
58+
59+
60+
Non-Facades
61+
===========
62+
63+
* Implicit conversions should go in companion objects so that they are always in scope without the
64+
need for imports. There's no need to group by feature, the types already specify the feature.
65+
66+
* Add Scala-only utilities that pertain to a specific facade, in the facades companion object
67+
Eg: helper constructors, legal facade values.
68+
69+
* We currently don't see the need for Scala-only utilities that don't pertain to a specific facade,
70+
or shouldn't be universally available (subjective judgement here).
71+
If you believe you've got a compelling use case please raise an issue first to discuss.
72+
73+
Binary Compatibility
74+
====================
75+
76+
Binary compatibility for Scala.js facades is different than standard Scala.
77+
The following are changes that are indeed incompatible in both formats:
78+
79+
Don't:
80+
* Remove a trait / class / object
81+
* Change a class into a trait or vice versa
82+
83+
Here is a non-exhaustive list of changes that would be binary-incompatible for Scala classes, but
84+
are compatible for JS facade types:
85+
86+
You can:
87+
* Remove a member
88+
* Change the type or signature of a member
89+
* Add a field in a trait
90+
* Add an abstract member in a trait
91+
92+
To help us enforce binary compatibility, we use API reports.
93+
They are auto-generated by running `prePR` in sbt and provide a concise summary of the entire API.
94+
Note: We might automate binary compatibility checking in the future (see #503) but for now,
95+
it's just a helpful tool for reviewing PRs.
96+
97+
Here is an example of a binary _compatible_ change in #491 as it appears in the API report diff.
98+
Note that `[JC]` stands for **J**avascript **C**lass, indicating that `HTMLAudioElement` is a facade type and thus this is a compatible change.
99+
```diff
100+
-raw/HTMLAudioElement[JC] def play(): Unit
101+
+raw/HTMLAudioElement[JC] def play(): js.UndefOr[js.Promise[Unit]]
102+
```
103+
104+
Here is an example of a binary _incompatible_ change in #458 as it appears in the API report diff.
105+
Even though the `Fetch` object is a facade (a **J**avascript **O**bject), moving it out of the `experimental` package is not binary compatible.
106+
(In this particular case, the change was accepted along with many binary-breaking changes going into 2.0.0.)
107+
```diff
108+
-experimental/Fetch[JO] def fetch(info: RequestInfo, init: RequestInit = null): js.Promise[Response]
109+
+Fetch[JO] def fetch(info: RequestInfo, init: RequestInit = null): js.Promise[Response]
110+
```
111+
112+
Anything annotated `[SC]`, `[ST]`, or `[SO]` in an API report is an ordinary Scala class/trait/object,
113+
for which standard binary compatibility rules apply.
114+
115+
If the above doesn't make sense to you, don't worry!
116+
The majority of useful changes to scala-js-dom are indeed binary compatible.
117+
118+
119+
Submitting a PR
120+
===============
121+
122+
Once you're done making your changes...
123+
124+
1. Run `sbt prePR`
125+
126+
2. Run `git diff api-reports` and ensure that you aren't breaking backwards-binary-compatibility
127+
(see above).
128+
129+
3. Check in and commit the changes to `api-reports`
130+
131+
4. Submit your PR
132+
133+
5. Know that your contribution is appreciated, thank you!

0 commit comments

Comments
 (0)