Repository navigation
API structure conventions: mixins #1940
Description
Here we are again talking about mixins :) There isn't actually an issue on mdn/content yet that will formally decide about mixins, so I'm opening this one. Fun fun fun!
Please also read mdn/browser-compat-data#472 for prior discussions.
And if you are concerned about how inheritance structures (as opposed to mixins) are documented, then please read #1006.
So, observing mixins in the wild and deciding how to document them. I recently chatted to Rachel Andrew about this and here's what my take has been:
The idea is to document Aria attributes. A spec for them is here https://www.w3.org/TR/wai-aria-1.2/#AriaAttributes and the idl looks like this:
interface mixin AriaAttributes {
attribute DOMString? ariaActiveDescendant;
attribute DOMString? manymoreattributes;
}
Element includes AriaAttributes;Now, as an MDN writer who uses WebIDL heavily to determine how and where to document things, you are not given a guideline where to document ariaActiveDescendant and friends, and so there are two options basically:
- Create a new API tree called AriaAttributes and put it there:
docs/Web/API/AriaAttributes/ariaActiveDescendant - Create a new page under the Element page tree:
docs/Web/API/Element/ariaActiveDescendant
Option 1. exposes the mixin to the world of web developers and option 2. hides this abstraction.
I recommended option 2. and so why did I do that?
- Mixins are abstractions that aren't exposed or observed directly. They are specification or browser-engine implementation helpers.
- Browsers and specs use mixins to make their life easier and they rename, remove, re-organize them at their discretion. Documentation can't easily follow this. Example in case: In a later spec (https://rawgit.com/w3c/aria/master/#ARIAMixin), there is no
AriaAttributesanymore, it is now calledARIAMixin. Consequently, with option 1. the page would need to move todocs/Web/API/ARIAMixin/ariaActiveDescendantand BCD would need to be updated, etc. But why? It doesn't really matter to web developers because Element.ariaActiveDescendant is going to be there no matter where in the spec or in IDL it has been defined.
On MDN, we can find API docs that do not hide the mixins however. Why is that? Example:
- https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
- Side note for this one: google search suggestion I get here is "windoworworkerglobalscope is not defined", so people are trying to call it, but it doesn't exist!
- See also https://stackoverflow.com/questions/43402321/is-settimeout-located-somewhere-besides-window"
So, I guess the idea here is that mixins add features to multiple interfaces and so having to duplicate docs for every interface they appear on, should be avoided. Does that make sense, though? Mixins can disappear and be renamed still. Even in this case the docs make it quite confusing to the readers.
I'll stop here as it introduces the initial problem space. In a follow-up, I'll try to get to the cases where hiding mixins would mean a lot of (duplicated) content. I want to understand more how these duplications would look like and if it is really duplication or docs in different contexts.
Feedback welcome.
Activity
dontcallmedom commentedon Feb 1, 2021
My own natural inclination is the same as your, option (2) above; I guess the questions of duplication of content will be key to figure out implementability though.
jpmedley commentedon Feb 1, 2021
I have always been an advocate of option 2. (I should note that while Chrome does use mixins in our IDL, we don't always use the ones listed in web specs. Rachel and I bumped into an example of this last week, which I can't seem to find at the moment.)
It seems to me that to do this properly, there should be some kind of inclusion mechanism for both MDN pages and BCD. I don't know what that needs to look like.
Ryuno-Ki commentedon Feb 1, 2021
Hm, I searched Microsoft/TypeScript repo but couldn't find any reference there.
I wonder how they implement it.
Alternatively: Does Facebook's Flow has support for this ootb?
hamishwillee commentedon Feb 1, 2021
So
requestAnimationFrameandcancelAnimationFrameused to beWindowonly methods, but it were recently been added toDedicatedWorkerGlobalScope(well both really) via the mixin:Other cases I've seen document this in the mixin and then refer to it in
Windowsay as "methods documented in other classes". What is it you see happening here - it gets documented in both places?For reference: #1519
jpmedley commentedon Feb 1, 2021
In the short term, yes. (I know. 😞). In the long term we need some kind of inclusion mechanism. This is the only way to keep information out of MDN that has no relevance to writing an actual script.
hamishwillee commentedon Feb 1, 2021
Thanks @jpmedley. We do "kind of" have page inclusion now via a macro - that might be able to pull specific sections for methods from mixin docs into relevant pages? That mechanism feels fragile to me though.
rachelandrew commentedon Feb 2, 2021
It would be lovely for a mixin to also be able to be a mixin in the docs :)
For now it would just be good to have a way forward that works for the majority of cases and that doesn't close the door on being able to address it in a better way in future. At least if we know where all the examples are, and they have been documented in a consistent way that should make it easier to convert them to some kind of inclusion mechanism in future.
I will highlights once I come across as I'm working. My open PRs for
TextEncoderStreamandTextDecoderStreamboth reference properties included via mixin.For example: https://encoding.spec.whatwg.org/#interface-textdecoderstream includes TextDecoderCommon and GenericTransformStream. In this case I have documented these as if they were regular properties which is as option 2.
rachelandrew commentedon Feb 2, 2021
So ... if I am adding ARIAMixin, which was AriaAttributes to Element, for BCD does that mean adding all of these to the 9000+ line long Element BCD file?
Elchi3 commentedon Feb 2, 2021
I've proposed a solution for BCD in mdn/browser-compat-data#8929
Elchi3 commentedon Feb 3, 2021
I've made a proof of concept using
HTMLHyperlinkElementUtils: #2046chrisdavidmills commentedon Feb 9, 2021
I really like this proposal. I think it does what we've needed to do for a long time now. I also agree with the BCD approach outlined in mdn/browser-compat-data#8929. Having a separate file for the stuff defined in a mixin really does help make sense of it all in terms of the compat data.
For quite some time I've thought that we should define mixins in separate page sets, and then have some kind of clever way of slurping them into the actual pages we want readers to see, e.g. have a separate set of https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils pages, but then in the final build render separate https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement and https://developer.mozilla.org/en-US/docs/Web/API/HTMLAreaElement pages based on them.
However, as I think about the implementation of this more, I wonder if that would be worth the effort. You would still need separate descriptions, syntax, examples, BCD, etc. for the two different page sets, if you were doing it properly.
I am going to go and review some of @Elchi3 's proof of concepts now, to see if any issues present themselves. If not, I'd say let's write this up in the MDN meta docs, and move forward with this way of doing things.
foolip commentedon Feb 10, 2021
I'm very happy to see mixins being phased out, but want to quote what I said about
WindowOrWorkerGlobalScopein the BCD issue:Elchi3 commentedon Feb 10, 2021
Thanks @foolip, I agree to leave this out for now and worry about it later. I also assume there will be exceptions to our new mixin documentation convention because the Web is not defined very consistently :)
Elchi3 commentedon Feb 15, 2021
I've sent #2366 to update mixins in the MDN contribution docs according to the discussion here.
To-Do list for existing docs that need updates/refactoring/moving/deletion:
Unfortunately, I run into issues when moving pages around, so it is a bit slow going and hairy on the MDN side of things. We made some progress on the BCD side already, though. See mdn/browser-compat-data#8929
Also, for mixins that exists for workers, it might be a bit more complicated and we're still figuring things out. However, for mixins that don't touch on the worker topic, docs and compat data are vastly improved thanks to this effort.
jpmedley commentedon Feb 16, 2021
That would resolve to a path like /api/fetch. Since I can call fetch() without reference to a global or instantiated object, that would work. But is that generally true of everything with WindowOrWorkerGlobalScope? I don't want to replace one thing that looks like a real code reference but isn't with another thing that looks like a real code reference but isn't.
foolip commentedon Feb 17, 2021
This is the right question to ask! For all of the methods on
WindowOrWorkerGlobalScope, I believe invoking them directly asfetch()rather thanself.fetch()is idiomatic. They are:atob(),btoa(),clearInterval(),clearTimeout(),createImageBitmap(),fetch(),queueMicrotask(),setInterval(),setTimeout().For attributes, while they can be accessed directly, I think for at least these it's more idiomatic to access them via the global object, because it makes it clear they're not local variables:
self.crossOriginIsolated,self.isSecureContext,self.origin.Then there's
cachesandindexedDB, where I suspect there's more variation in style. I'd certainly writeindexedDB.open(...), but the example useswindow.indexedDB.open('toDoList').On the URL, another option would be /api/Global_Objects/fetch, more analogous to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
I think that looking at the members of
WindowandWorkerGlobalScopewill reveal more tricky cases. I think especially a method likewindow.resizeTo(), while it can be invoked as justresizeTo(), would not be great to give the same treatment asfetch().jpmedley commentedon Feb 17, 2021
That sounds like problems with how we need to explain them on actual pages. I've created an issue capture this.
FWIW, I think it would be a good idea to move these under
Global_Obects.sideshowbarker commentedon Jun 8, 2021
I propose we move this to the Discussions tracker.