Skip to content

Commit e73cd60

Browse files
committed
Redesign DOMList and review its implementations.
DOMList is now no more than an interface for things that have a `length` and index properties. We add a Seq view of all DOMLists in its companion object. We make it read-only and covariant, as its implementations are actually not mutable in the DOM standard. We review all its subclasses and subtraits: * Make them classes iff they are exposed and can be used with `instanceof`. Their constructors are always private. Otherwise, make them traits. * Explicitly declare `item()` iff it is supported in the given class/trait (it used to be in `DOMList`, but not all implementations support `item()`). We make `NodeList` parameterized and covariant in the type of node. We deprecate `NodeListOf` in favor of `NodeList`.
1 parent a6e10f8 commit e73cd60

File tree

10 files changed

+670
-750
lines changed

10 files changed

+670
-750
lines changed

api-reports/2_12.txt

Lines changed: 301 additions & 341 deletions
Large diffs are not rendered by default.

api-reports/2_13.txt

Lines changed: 301 additions & 341 deletions
Large diffs are not rendered by default.

src/main/scala/org/scalajs/dom/CSSTypes.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ class CSSPageRule extends CSSRule {
501501
*/
502502
@js.native
503503
@JSGlobal
504-
class CSSRuleList extends DOMList[CSSRule]
504+
class CSSRuleList private[this] () extends DOMList[CSSRule] {
505+
def item(index: Int): CSSRule = js.native
506+
}
505507

506508
/**
507509
* The CSSKeyframesRule interface describes an object representing a complete set

src/main/scala/org/scalajs/dom/HTMLTypes.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,8 @@ abstract class HTMLMenuElement extends HTMLElement {
11611161
*/
11621162
@js.native
11631163
@JSGlobal
1164-
abstract class HTMLCollection extends DOMList[Element] {
1164+
class HTMLCollection private[this] () extends DOMList[Element] {
1165+
def item(index: Int): Element = js.native
11651166

11661167
/**
11671168
* Returns the specific node whose ID or, as a fallback, name matches the string

src/main/scala/org/scalajs/dom/SVGTypes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ abstract class SVGSVGElement
12441244
* MDN
12451245
*/
12461246
def getIntersectionList(rect: SVGRect,
1247-
referenceElement: SVGElement): NodeList = js.native
1247+
referenceElement: SVGElement): NodeList[Node] = js.native
12481248

12491249
/**
12501250
* Unsuspends (i.e., unpauses) currently running animations that are defined
@@ -1327,7 +1327,7 @@ abstract class SVGSVGElement
13271327
def createSVGAngle(): SVGAngle = js.native
13281328

13291329
def getEnclosureList(rect: SVGRect,
1330-
referenceElement: SVGElement): NodeList = js.native
1330+
referenceElement: SVGElement): NodeList[Node] = js.native
13311331

13321332
/**
13331333
* Creates an SVGTransform object outside of any document trees. The object is

src/main/scala/org/scalajs/dom/ext/Extensions.scala

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,6 @@ import scala.scalajs.js
99
import scala.scalajs.js.typedarray.ArrayBufferView
1010
import scala.scalajs.js.typedarray.TypedArrayBufferOps._
1111

12-
/**
13-
* Used to extend out javascript *Collections to make them usable as normal
14-
* Scala Seq[*]s
15-
*/
16-
class EasySeq[T](jsLength: Int, jsApply: Int => T)
17-
extends scala.collection.Seq[T] {
18-
19-
def length = jsLength
20-
21-
def apply(x: Int) = jsApply(x)
22-
23-
def iterator = new Iterator[T] {
24-
var index = 0
25-
26-
def hasNext: scala.Boolean = index < jsLength
27-
28-
def next() = {
29-
val res = jsApply(index)
30-
index += 1
31-
res
32-
}
33-
}
34-
}
35-
3612
/**
3713
* A list of the codes returned by KeyEvents.
3814
*/

src/main/scala/org/scalajs/dom/ext/package.scala

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/scala/org/scalajs/dom/lib.scala

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ trait NodeSelector extends js.Object {
517517
*
518518
* MDN
519519
*/
520-
def querySelectorAll(selectors: String): NodeList = js.native
520+
def querySelectorAll(selectors: String): NodeList[Node] = js.native
521521

522522
/**
523523
* Returns the first element within the document (using depth-first pre-order
@@ -1158,7 +1158,7 @@ abstract class Node extends EventTarget {
11581158
*
11591159
* MDN
11601160
*/
1161-
def childNodes: NodeList = js.native
1161+
def childNodes: NodeList[Node] = js.native
11621162

11631163
/**
11641164
* Returns a DOMString containing the name of the Node. The structure of the name will
@@ -3050,8 +3050,9 @@ class TouchEvent(typeArg: String, init: js.UndefOr[TouchEventInit])
30503050
* MDN
30513051
*/
30523052
@js.native
3053-
@JSGlobal
3054-
class TouchList extends DOMList[Touch]
3053+
trait TouchList extends DOMList[Touch] {
3054+
def item(index: Int): Touch = js.native
3055+
}
30553056

30563057
/**
30573058
* A Touch object represents a single point of contact between the user and a touch-sensitive
@@ -3410,7 +3411,7 @@ abstract class Document
34103411
*
34113412
* MDN
34123413
*/
3413-
def getElementsByName(elementName: String): NodeList = js.native
3414+
def getElementsByName(elementName: String): NodeList[Node] = js.native
34143415

34153416
/**
34163417
* Returns a HTMLCollection of elements with the given tag name. The complete
@@ -5098,14 +5099,14 @@ trait MutationRecord extends js.Object {
50985099
*
50995100
* MDN
51005101
*/
5101-
def addedNodes: NodeList = js.native
5102+
def addedNodes: NodeList[Node] = js.native
51025103

51035104
/**
51045105
* Return the nodes removed. Will be an empty NodeList if no nodes were removed.
51055106
*
51065107
* MDN
51075108
*/
5108-
def removedNodes: NodeList = js.native
5109+
def removedNodes: NodeList[Node] = js.native
51095110

51105111
/**
51115112
* Return the previous sibling of the added or removed nodes, or null.
@@ -6383,14 +6384,40 @@ class StyleSheet extends js.Object {
63836384
}
63846385

63856386
@js.native
6386-
trait DOMList[T] extends js.Object {
6387+
trait DOMList[+T] extends js.Object {
63876388
def length: Int = js.native
6388-
def item(index: Int): T = js.native
6389-
@scala.scalajs.js.annotation.JSBracketAccess
6389+
6390+
@JSBracketAccess
63906391
def apply(index: Int): T = js.native
6392+
}
63916393

6392-
@scala.scalajs.js.annotation.JSBracketAccess
6393-
def update(index: Int, v: T): Unit = js.native
6394+
object DOMList {
6395+
implicit def domListAsSeq[T](domList: DOMList[T]): scala.collection.Seq[T] =
6396+
new DOMListSeq(domList)
6397+
6398+
private final class DOMListSeq[+T](domList: DOMList[T])
6399+
extends scala.collection.Seq[T] {
6400+
6401+
def length: Int = domList.length
6402+
6403+
def apply(x: Int): T = domList(x)
6404+
6405+
def iterator: Iterator[T] = new DOMListIterator(domList)
6406+
}
6407+
6408+
private final class DOMListIterator[+T](domList: DOMList[T])
6409+
extends Iterator[T] {
6410+
6411+
private[this] var index = 0
6412+
6413+
def hasNext: Boolean = index < domList.length
6414+
6415+
def next(): T = {
6416+
val res = domList(index)
6417+
index += 1
6418+
res
6419+
}
6420+
}
63946421
}
63956422

63966423
/**
@@ -6401,10 +6428,9 @@ trait DOMList[T] extends js.Object {
64016428
*/
64026429
@js.native
64036430
@JSGlobal
6404-
class NodeList extends DOMList[Node]
6405-
6406-
@js.native
6407-
trait NodeListOf[TNode <: Node] extends DOMList[TNode]
6431+
class NodeList[+T <: Node] private[this] () extends DOMList[T] {
6432+
def item(index: Int): T = js.native
6433+
}
64086434

64096435
@js.native
64106436
@JSGlobal
@@ -6925,7 +6951,9 @@ trait TextTrackCue extends EventTarget {
69256951
* MDN
69266952
*/
69276953
@js.native
6928-
trait DOMTokenList extends DOMList[String] {
6954+
@JSGlobal
6955+
class DOMTokenList private[this] extends DOMList[String] {
6956+
def item(index: Int): String = js.native
69296957

69306958
def contains(token: String): Boolean = js.native
69316959

@@ -7298,7 +7326,10 @@ trait ProgressEvent extends Event {
72987326
* MDN
72997327
*/
73007328
@js.native
7301-
trait FileList extends DOMList[File]
7329+
@JSGlobal
7330+
class FileList private[this] () extends DOMList[File] {
7331+
def item(index: Int): File = js.native
7332+
}
73027333

73037334
/**
73047335
* The File interface provides information about -- and access to the contents of --
@@ -7473,7 +7504,8 @@ trait AudioTrack extends js.Object {
74737504
}
74747505

74757506
@js.native
7476-
trait TextTrackCueList extends DOMList[TextTrackCue] {
7507+
@JSGlobal
7508+
class TextTrackCueList private[this] () extends DOMList[TextTrackCue] {
74777509
def getCueById(id: String): TextTrackCue = js.native
74787510
}
74797511

@@ -7665,7 +7697,10 @@ trait WindowBase64 extends js.Object {
76657697
* MDN
76667698
*/
76677699
@js.native
7668-
trait DOMStringList extends DOMList[String] {
7700+
@JSGlobal
7701+
class DOMStringList private[this] () extends DOMList[String] {
7702+
def item(index: Int): String = js.native
7703+
76697704
def contains(str: String): Boolean = js.native
76707705
}
76717706

src/main/scala/org/scalajs/dom/package.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ package object dom {
4141

4242
@deprecated("use DOMRectList instead", "2.0.0")
4343
type ClientRectList = DOMRectList
44+
45+
@deprecated("use NodeList[T] instead", "2.0.0")
46+
type NodeListOf[+T <: Node] = NodeList[T]
4447
}

src/main/scala/org/scalajs/dom/raw.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ object rawold {
8282
type DOMException = dom.DOMException
8383
type DOMImplementation = dom.DOMImplementation
8484
lazy val DOMException: dom.DOMException.type = dom.DOMException
85-
type DOMList[T] = dom.DOMList[T]
85+
type DOMList[+T] = dom.DOMList[T]
8686
type DOMParser = dom.DOMParser
8787
type DOMRect = dom.DOMRect
8888
type DOMRectList = dom.DOMRectList
@@ -240,8 +240,8 @@ object rawold {
240240
type NodeFilter = dom.NodeFilter
241241
lazy val NodeFilter: dom.NodeFilter.type = dom.NodeFilter
242242
type NodeIterator = dom.NodeIterator
243-
type NodeList = dom.NodeList
244-
type NodeListOf[TNode <: Node] = dom.NodeListOf[TNode]
243+
type NodeList[+T <: Node] = dom.NodeList[T]
244+
type NodeListOf[+T <: Node] = NodeList[T]
245245

246246
type OfflineAudioContext = dom.OfflineAudioContext
247247
type OffscreenCanvas = dom.OffscreenCanvas

0 commit comments

Comments
 (0)