Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve HTMLCollection, add HTMLOptionsCollection and HTMLFormControlsCollection #593

Merged
merged 7 commits into from
Oct 17, 2021

Conversation

ghostbuster91
Copy link
Contributor

Hi,

Following suggestion from @raquo here is a PR which fixes incorrect type of options property in HTMLSelectElement.

Cheers!

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing!! At a first glance this is looking good.

Looking at MDN:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionsCollection
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

I wonder if we should define HTMLCollection with the item and namedItem methods, and then HTMLOptionsCollection can extend that. What do you think?

@ghostbuster91
Copy link
Contributor Author

That was my first thought but than I noticed private constructor and got confused by all of these js annotations. I don't really know much about scala-js.

Let me know if I did it right :)

@armanbilge armanbilge mentioned this pull request Oct 13, 2021
@armanbilge
Copy link
Member

Moving the conversation from #593 (comment) back to the main thread...

It seems that typescript does use Element as an upper bound for HTMLCollection.

/** A generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list. */
interface HTMLCollectionBase {
    /**
     * Sets or retrieves the number of objects in a collection.
     */
    readonly length: number;
    /**
     * Retrieves an object from various collections.
     */
    item(index: number): Element | null;
    [index: number]: Element;
}

interface HTMLCollection extends HTMLCollectionBase {
    /**
     * Retrieves a select object or an object from an options collection.
     */
    namedItem(name: string): Element | null;
}

declare var HTMLCollection: {
    prototype: HTMLCollection;
    new(): HTMLCollection;
};

@armanbilge
Copy link
Member

Then they have:

interface HTMLFormControlsCollection extends HTMLCollectionBase {
    /**
     * Returns the item with ID or name name from the collection.
     *
     * If there are multiple matching items, then a RadioNodeList object containing all those elements is returned.
     */
    namedItem(name: string): RadioNodeList | Element | null;
}

I think they are doing really tricky typescripty things we can't replicate in Scala actually 🤔

Given the MDN docs, I think it's okay to remove the upper bound.

@armanbilge
Copy link
Member

armanbilge commented Oct 14, 2021

Ah, the "trick" is that they are extending HTMLCollectionBase (with the Element upper-bound) instead of HTMLCollection, and then manually defining namedItem with non-Element return type (rather than overriding). Which actually we could do too I guess.

I'd still rather remove the upper bound. It's cleaner and supported by the docs.

@armanbilge armanbilge changed the title Create HTMLOptionsCollection to improve ux when dealing with <select>… Define HTMLCollection and friends Oct 14, 2021
@armanbilge armanbilge changed the title Define HTMLCollection and friends Improve HTMLCollection, add HTMLOptionsCollection and HTMLFormControlsCollection Oct 14, 2021
@armanbilge armanbilge added this to the v2.0.0 milestone Oct 14, 2021
Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple tiny things...

Otherwise, looks great!! Thank you so much for taking this on and sticking with it, much appreciated. This is a significant improvement to this API, and just in time for 2.0.0 😁

src/main/scala/org/scalajs/dom/raw.scala Outdated Show resolved Hide resolved
src/main/scala/org/scalajs/dom/html.scala Outdated Show resolved Hide resolved
@ghostbuster91
Copy link
Contributor Author

Otherwise, looks great!! Thank you so much for taking this on and sticking with it, much appreciated. This is a significant improvement to this API, and just in time for 2.0.0 grin

No problem at all. I learned some new things and I am always happy to contribute back to scala ecosystem :)
Thanks for the guidance 👍

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again!

@armanbilge
Copy link
Member

@japgolly do you want to have a look at this?

Copy link
Contributor

@japgolly japgolly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic changes! Just one question about variance...

@@ -14,12 +14,12 @@ import scala.scalajs.js.annotation._
*/
@js.native
@JSGlobal
class HTMLCollection private[this] () extends DOMList[Element] {
def item(index: Int): Element = js.native
abstract class HTMLCollection[E] extends DOMList[E] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be HTMLCollection[+E <: Node] extends DOMList[E]?

Note: If yes, don't forget to add a + to the type alias too :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interpreting the spec as any object? Not just a Node?
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

The HTMLCollection interface represents a generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The + makes sense though 👍

@japgolly japgolly merged commit 60a6b59 into scala-js:master Oct 17, 2021
@armanbilge armanbilge mentioned this pull request Oct 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants