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

How to represent 'mixins'? #472

Closed
teoli2003 opened this issue Oct 5, 2017 · 37 comments
Closed

How to represent 'mixins'? #472

teoli2003 opened this issue Oct 5, 2017 · 37 comments
Assignees
Labels
data:api Compat data for Web APIs. https://developer.mozilla.org/docs/Web/API question Issues where a question or problem is stated and a discussion is held to gather opinions.

Comments

@teoli2003
Copy link
Contributor

teoli2003 commented Oct 5, 2017

Mixins are bits of API that are defined once and implemented by several interfaces.
E.g. (fictive)

Mixin.method1
Mixin.method2


Interface1 implements Mixin means:
Interface1.method1 and Interface1.method2 are implemented.

Interface2 implements Mixin means:
Interface2.method2 and Interface2.method2 are implemented.

This is used in spec to describe once methods/properties that are implemented by several interfaces.

Mixins are invisible to the users, and different interfaces can implement these methods at different moment, completely and incompletely, and with different bugs or limitations. Mixins are transparent to the user.

Mixins can go away or be added in the spec, without having an impact on the developer using them.

MDN shows mixins only to avoid duplication (or triplication) of articles [and the nightmare of keeping them coherent]. Mixins are blended in the interface they appear like a regular property or method in the sidebar and in the list in the main text.

How to represent them?

@teoli2003
Copy link
Contributor Author

I propose to hide mixins from the BCD. We put the method and the compat data directly in the interfaces that implements the mixins.

This has 1 drawback, MDN needs to do some magic to show a summary table on a mixin page as it needs to know which interfaces implement the given mixin. It has this information in the {{InterfaceData}} macro (see https://github.com/mdn/kumascript/blob/master/macros/InterfaceData.json ). We likely will need a new macro for these pages.

@teoli2003
Copy link
Contributor Author

This is an important issue for Window and the *GlobalScope interfaces. (As well as a few others like AudioContext and AudioWorklet)

@Elchi3
Copy link
Member

Elchi3 commented Oct 5, 2017

I think I agree to hide mixins.

But what does this mean in practice?

Taking the example of https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob


Not using mixins: This would be two different compat data entries (in different files). This looks closer to what web developers see.

  • api.window.atob
  • api.worker.atob

Using mixins: As there is different compat data for different contexts, you would probably end up with sub features. This has the benefit that all data for "atob" is together in one tree or one file.

  • api.WindowOrWorkerGlobalScope.atob.
    • window_context
    • worker_context

On MDN: The rendered table on https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob should somehow display the compat info for both contexts. We'll need to see how we could do this when not using mixins. (it seems easier with what we can do now if we would use mixins in the compat data, too).

Aside: Imo the MDN page is not very good. It mostly only gives a code example in the window context. I think we need to get better there. Generally "WindowOrWorkerGlobalScope" is invisible to web developers and rather cryptic (on MDN and in BCD). All we want to say somehow is that this is for windows and workers...

@teoli2003
Copy link
Contributor Author

teoli2003 commented Oct 9, 2017

About the aside: yes, I agree with this. This comes from the fact that it wasn't a mixin, then it became one and we did the change without rewriting the page.

Note that we have cases where a method was in a mixin, then outside a mixin (mixin removed); or in a mixin, then in another, then back on the interface while the mixin was kept for this method and used for 2 other interfaces (!).
Mixins come and go very easily as they are a way to make the spec more readable, or less error-prone. It is an editorial technicality for spec writers and is not discussed as feature change.

On MDN: if we use mixin, we likely need to create a specific macro that looks at {{InterfaceData}} to know which interface use the mixin, to find the correct compat info for the compat table.

@teoli2003
Copy link
Contributor Author

teoli2003 commented Oct 9, 2017

Ok, I think the plan could be:
Note: I'm using this to track progress on the issue, as this imply numerous PRs.

  1. Migrate InterfaceData to mdn/data repo
    1. Make mdn/data loaded by kumascript. In progress in mdn/kumascript PR#343 .
    2. Move content of InterfaceData into mdn/data. Details in mdn/data PR#122.
    3. Create tests for macros using {{InterfaceData}}:
      • APIRef
      • FirefoxOSApiRef
      • InheritanceDiagram
      • InterfaceOverview
    4. Update the macros using it to use the one on mdn/data:
      • APIRef
      • FirefoxOSApiRef
      • InheritanceDiagram
      • InterfaceOverview
    5. Remove InterfaceData from mdn/kumascript
  2. Create CompatMix in mdn/kumascript making use of InterfaceData
  3. Update contrib documentation w/ mixin information
  4. Migrate compat data for mixins (will last a long time!)
  5. Update MDN pages for mixin properties and methods not to be specific to a specific interface.

@Elchi3, what do you think?

@Elchi3
Copy link
Member

Elchi3 commented Oct 9, 2017

Sounds good to me, thanks for working on this. Good to see data migrated into the proper repository.
Renaming is needed, because this really is "API inheritance data" or similar.

@a2sheppy
Copy link
Contributor

a2sheppy commented Nov 2, 2017

I wish I'd seen this conversation sooner, since I disagree. I think we need a way to have a unified place for the mixin information in the data store so we don't have to update this stuff in multiple places like we do if we include the implemented mixin methods and properties within each individual interface.

Then a bit of pipe dream thinking: On MDN, we then create the pages for the mixin but we don't show them directly (that is, they're not linked on overview pages, and they might even be noindex). Instead, they get automatically injected or transcluded within the hierarchy of pages under each interface, with the appropriate names subbed in.

This would require some macro and/or platform work, though. But from a user data maintenance standpoint, it would be much better, and from a UX standpoint on MDN, it would be amazing.

@Elchi3 Elchi3 added the question Issues where a question or problem is stated and a discussion is held to gather opinions. label Nov 21, 2017
@teoli2003
Copy link
Contributor Author

In fact, a mixin is not necessarily implemented at the same time in each interface. So it means that we can not have a unique BCD value for a mixin: it needs to be at the interface level.

As a mixin is not user-facing, we also have renaming and removal of mixins happening all the time in the specs. It is an editorial thing at the spec level.

There is no way, and no concrete use, to keep track of these renamings or removals as it has 0 consequences, and is invisible, for web developers. And having dealt (more or less successfully) with the URL interface, it can be a nightmare for writers: lots of work for no actual benefits for the reader. Let's avoid this problem.

So I feel strongly in favour of the rule: no mixin listed separately in BCD.

@a2sheppy
Copy link
Contributor

My only remaining question or concern on this, then, is what if anything we want to do about making sure people can understand why these things are missing if they look at the WebIDL for an interface that's based in part on a mixin.

@caugner
Copy link
Contributor

caugner commented Jul 20, 2018

I would like to point out that it can be confusing not to specify where a sub-feature comes from.

For example, I recently edited the HashChangeEvent article. Before, it had listed target, type, bubbles and cancelable as properties (not compat data though), even though these originate from the parent interface Event – which I found quite confusing.

If we would not mix and list mixin separately, we could add includes <code>FooMixin</code> as a sub-feature.

If we do mix, we should maybe make it clear in the description where the feature comes from, e.g.: the sub-feature name coming from the mixin CredentialUserData (see #2275) would be described with <code>CredentialUserData.name</code> in FederatedCredential and PasswordCredential (which include the mixin).

@foolip
Copy link
Contributor

foolip commented Feb 12, 2019

When poking around in https://github.com/foolip/mdn-bcd-updater, I've found that the use of mixins in the BCD model results in some strange situation. As @teoli2003 points out things may not be implemented at the same time on the different interfaces that include a mixin and it didn't take long before I stumbled on a real such case:
https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/fullscreenElement

Prefixed variants of this API have existed for a very long time on Document, but the unprefixed ones will be available on Document and ShadowRoot. This can't be easily represented as it is.

The issue of base classes came up in #3368 (comment) and this is information that could be extracted from Web IDL. Similarly, information about mixins could be extracted. I'd be happy to write some scripts for it if that would help move this discussion along.

@jpmedley
Copy link
Contributor

Here's a related issue that @Elchi3 asked me to open. #3441

@foolip
Copy link
Contributor

foolip commented Feb 19, 2019

For reference, usings scrips in https://github.com/foolip/mdn-bcd-updater and comm on the command line, I've produced lists of APIs in BCD but not IDL and IDL but not BCD.

That's with mixins and partial interfaces applied on the IDL side. Much of the lists are explained by BCD using mixins for some things and some things not. With some script tweaking I made IDL with mixins but no BCD and that list is a bit shorter, but it has stuff like NavigatorID.vendor because that particular mixin has been flattened into Navigator in BCD.

One could mostly work around the problems, but I think this will be an impediment to improving the data quality.

I see some similarities to #3463, in that one could try to represent the mixins in the data model and do something in the presentation similar to what one could for members of parent interfaces.

@Elchi3 who has to make a decision on this? Whatever is decided, how would one roll out a change that either deletes a lot of mixins or adds a lot of mixins?

@Elchi3
Copy link
Member

Elchi3 commented Feb 19, 2019

MDN is inconsistent and BCD followed these inconsistencies to not block on data migration. Sometimes we document mixins that specs invented or sometimes people used the mixins the browser vendors invented for convenience. All this changes at different times in specs and browsers as new conveniences are needed.

one could try to represent the mixins in the data model and do something in the presentation similar to what one could for members of parent interfaces.

My understanding is that for web developers they are an implementation detail (almost always I think).
Also, I think it is going to be really hard to have them reliably in a data model for BCD or in good content structures in MDN API docs. We probably want to follow mixins from specs, but even these get often re-arranged for conveniences. So, I'm not sure I buy that they would also bring us conveniences like they bring to spec authors and implementors if we need to move around docs whenever specs move around things as well.

That said, I'm leaning towards not having them exposed to web developers here or on MDN, but I would like to do some research to make a better call. Ideally, we want a tool that accepts WebIDL and spits out MDN URLs and BCD paths to create with rules coded in there. So, if we decide one rule (of many rules likely) is that mixis are bad and we flatten them, the tool takes that into account and presents a structure for MDN and BCD from a given WebIDL snippet. Only this way we create reliable structures and not random structures a contributor to MDN web docs decided to use and BCD then inherits from.

One could mostly work around the problems, but I think this will be an impediment to improving the data quality.

This is on point, so I agree we need to solve this.

@Elchi3 who has to make a decision on this? Whatever is decided, how would one roll out a change that either deletes a lot of mixins or adds a lot of mixins?

The MDN content team lead by @chrisdavidmills as I think I would like to follow what MDN decides. BCD and MDN docs both want to expose useful information about web apis to web developers, so I don't want to make a call for BCD alone.

Making the changes is likely a lot of work, but if we have a reliable ruleset agreed on (this is the hard part), we can see how to address this and audit BCD and MDN against these rules and then piece by piece get things sorted. (BCD is easier as it is in git and as we have tooling to lint etc).

@foolip
Copy link
Contributor

foolip commented Feb 20, 2019

@Elchi3 not representing mixins in the BCD model at all sounds good to me and I'd be happy to work in that direction.

These are the 69 mixins that exist in specs (from reffy-reports) today:

AbstractWorker
AccessibilityRole
Animatable
AnimationFrameProvider
AriaAttributes
BluetoothDeviceEventHandlers
Body
CanvasCompositing
CanvasDrawImage
CanvasDrawPath
CanvasFillStrokeStyles
CanvasFilters
CanvasImageData
CanvasImageSmoothing
CanvasPath
CanvasPathDrawingStyles
CanvasRect
CanvasShadowStyles
CanvasState
CanvasText
CanvasTextDrawingStyles
CanvasTransform
CanvasUserInterface
CharacteristicEventHandlers
ChildNode
CredentialUserData
DocumentAndElementEventHandlers
DocumentOrShadowRoot
ElementContentEditable
ElementCSSInlineStyle
FontFaceSource
GenericTransformStream
GeometryUtils
GetSVGDocument
GlobalEventHandlers
HTMLHyperlinkElementUtils
HTMLOrSVGElement
LinkStyle
NavigatorAutomationInformation
NavigatorConcurrentHardware
NavigatorContentUtils
NavigatorCookies
NavigatorID
NavigatorLanguage
NavigatorNetworkInformation
NavigatorOnLine
NavigatorPlugins
NavigatorStorage
NonDocumentTypeChildNode
NonElementParentNode
ParentNode
Region
ServiceEventHandlers
Slotable
SVGAnimatedPoints
SVGElementInstance
SVGFilterPrimitiveStandardAttributes
SVGFitToViewBox
SVGTests
SVGURIReference
SVGZoomAndPan
TextDecoderCommon
TextEncoderCommon
WebGL2RenderingContextBase
WebGLRenderingContextBase
WindowEventHandlers
WindowLocalStorage
WindowOrWorkerGlobalScope
WindowSessionStorage

Of those it looks like 21 of those are in BCD:

Assuming that pages like NonDocumentTypeChildNode will have to be updated either not include compat tables at all or point to Element + CharacterData, here's a transition plan I think could work:

  1. Flatten the mixins into the interfaces that include them in BCD. When reviewing, careful attention to notes will be needed.
  2. Optionally, add a lint/warning preventing the mixin JSON files from being edited further.
  3. Publish BCD, update the pages pointing to the mixins.
  4. Remove the mixins from BCD.

@foolip
Copy link
Contributor

foolip commented Feb 20, 2019

WindowOrWorkerGlobalScope is a good example where attention to notes will be needed. One note says "fetch() now defined on WindowOrWorkerGlobalScope mixin" which probably means fetch() was exposed to workers then, but that's not clear.

That's also a bit of special case in that it would split window or worker-exposed APIs across Window and the multiple *WorkerGlobalScope interfaces. It probably makes more sense for web developers to visit https://developer.mozilla.org/en-US/docs/Web/API/fetch (now redirects) and see the support in various contexts in a single table.

@foolip
Copy link
Contributor

foolip commented Mar 15, 2019

@Elchi3 any thoughts on how you'd like to deal with the list in #472 (comment)?

@a2sheppy
Copy link
Contributor

So, here are my thoughts on this:

  • I agree that readers don't care about the mixins and want the stuff just listed in the interface they're part of.
  • However, I think it's important organizationally and structurally to have the mixins maintained separately. It will be easier to maintain if they're kept in their own place, so that if they move around, or specs change hands or whatever, you can deal with it more quickly. It also helps keep the size of the base interface file down to a more manageable length.
  • This is especially crucial for mixins that are used by more than one base interface, such as WindowOrWorkerGlobalScope. We should not have to manually update the documentation for a given method or property in two interfaces if there are changes to a mixin. This invites discrepancies and content bugs.
  • I think, therefore, we should keep mixins in their own JSON files for BCD, but that mixins' contents should be displayed on the site within the context of each class that inherits them.
  • Therefore, I believe we need to complete the process of writing code to automatically construct the overview pages, indices, and so forth, so that they get automatically blended into the main class for display on MDN.

The InterfaceData.json file already has the most critical part of the data we need: the list of things implemented by each interface (both mixins and base class). This is contained in the impl field of the records there. For example, consider the record for Navigator:

    "Navigator": {
      "inh": "",
      "impl": [
        "NavigatorID",
        "NavigatorLanguage",
        "NavigatorOnLine",
        "NavigatorContentUtils",
        "NavigatorStorageUtils",
        "NavigatorFeatures",
        "NavigatorGeolocation",
        "NavigatorBattery",
        "NavigatorDataStore",
        "NavigatorMobileId"
      ]
},

I do feel that we should add to mixins listed in the InterfaceData.json file a pointer back to the interfaces that inherit them, too. I don't believe we currently have that.

With this information in hand, we can easily update our compatibility table generator to include the data for the mixins as appropriate, such as by including all of the contents of each of them in the table generated for the Navigator interface itself.

Then we have to look at where we put the documents themselves. For the sake of cohesiveness, I think they should be maintained separately, perhaps just like they are now. Using automatic inclusion of the content into TOCs and indices should do a good job of integrating the content into the inheriting interfaces.

If it's a problem that we the lack the ability to use breadcrumbs to back up into the parent, or the fact that the mixin would not know how to refer to itself based on the parent that the user clicked into it from, there ought to be a technical solution to it. For instance, we could have the macros that build these lists add a parameter to the links that lets the target page know which interface it's being looked at as part of. Then we'd just need a way to have a variable of sorts on the page that would sub in that information when presenting the contents. Something like that.

Not all of this is easy, but it's not tremendously difficult either, and I think we can greatly improve usability for both readers and contributors.

We have made vague attempts at this in the past, and I have my in-progress InterfaceOverview macro that I never get time to work on, whose goal is to do exactly this kind of thing. It doesn't yet deal with mixins, but totally could.

@foolip
Copy link
Contributor

foolip commented Mar 21, 2019

@a2sheppy maintaining a list parent interfaces and mixins should be quite straightforward as it can be derived directly from the Web IDL in reffy-reports. I tweaked a script to generate it here:
https://gist.github.com/foolip/237f1aa6e824620fe7b649613896a8e3

The Navigator section looks a lot like you suggested.

However, as you say, readers probably don't care about mixins. It seems to me there are some challenges in maintaining compat data for mixins and then flattening that into the real interfaces in the support tables that people see/use. How should one deal with the cases where the support status on the real interfaces aren't the same? As I mentioned in #472 (comment) this does happen, most of the members in https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot#Browser_compatibility are like this. It will also be the case for many APIs in https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope#Browser_compatibility which predate worker support in browsers.

@foolip
Copy link
Contributor

foolip commented Sep 22, 2020

@saschanaz what do you think the rule (or lint) for the support statement on M should be? I see two options, with different drawbacks:

  • Supported if on any of the concrete interfaces. This will lead to a lot of support statements for mixins being older than the concept of mixins itself. Harmless?
  • Supported if on all of the concrete interfaces. This will require changing the mixin statement if a new interfaces begins including it, as has just happened with some MathML stuff. This seems harder to maintain over time.

@saschanaz
Copy link
Contributor

saschanaz commented Sep 22, 2020

In TSJS perspective I prefer the first option, as it will use the mixin if there is any real implementation. It could be painful for large mixins like GlobalEventHandlers but I guess it should generally be fine as AFAIK many mixins only have one single concrete implementor interface.

@foolip
Copy link
Contributor

foolip commented Nov 3, 2020

In #7179 (comment) we discovered that there are mismatches between BCD and MDN, where BCD has an api.HTMLElement.style entry which links to https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style, and that page in turn includes the data from api.HTMLElement.style.

Since https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style redirects I gather it was renamed at some point.

This sort of thing is bound to come up more when trying to sort everything out.

@saschanaz
Copy link
Contributor

Now I think I'm more for removing mixins. That way:

  • mdn-bcd-collector doesn't need to care about mixins
  • No complex algorithm needed to create a support table
  • Contributors won't be confused

I still can write code for my use case to track mixin items in BCD, so nothing will be lost.

@foolip
Copy link
Contributor

foolip commented Dec 19, 2020

I just came across something I hadn't seen before and which will also need cleaning up. CharacterData.json has an api.CharacterData.ChildNode entry with the description "Implements the ChildNode interface". It came from wiki migration in #1732 and it looks like it's the only case like this.

foolip added a commit to foolip/browser-compat-data that referenced this issue Dec 19, 2020
ChildNode is a mixin, not an interface as described, and mixins are
completely invisible to web developers; they're a spec author
convenience.

This is a bit of cleanup that makes sense regardless of the outcome of
mdn#472 more broadly.
@queengooborg
Copy link
Contributor

Alright, so there's some interface history with some SVG interfaces that can make this a little bit more complicated. While I was updating data for some mixins, I discovered that a few of the mixins in SVG were initially their own interfaces in SVG 1.1, but then converted to mixins in SVG 2.0. What should we do in this case?

Related PRs: #8235 and #8201

@foolip
Copy link
Contributor

foolip commented Dec 30, 2020

I filed #7752 for the SVG interfaces which were turned into mixins. I think we should treat the ones which are now mixins like all other mixins, however that ends up being. SVGUnitTypes is not a case of this, since it still exists to hold the constants.

@jpmedley
Copy link
Contributor

jpmedley commented Jan 5, 2021

(Sidebar re "Contributors won't be confused": I'm more concerned with whether readers and data consumer are confused. I've always believed it's my job as a documentation person to resolve confusion for myself so that readers, hopefully, never will be.

@saschanaz
Copy link
Contributor

No complex algorithm needed to create a support table

I wonder the support table should ultimately support inheritances, in that case the algorithm is needed anyway.

ddbeck pushed a commit that referenced this issue Jan 13, 2021
ChildNode is a mixin, not an interface as described, and mixins are
completely invisible to web developers; they're a spec author
convenience.

This is a bit of cleanup that makes sense regardless of the outcome of
#472 more broadly.
@Elchi3
Copy link
Member

Elchi3 commented Feb 2, 2021

I've made a concrete proposal of how to proceed in #8929
Please let me know in there if that would work! Thanks :)

@Elchi3
Copy link
Member

Elchi3 commented Feb 14, 2021

I've answered how to represent mixins in #9016

A mixin data guideline was released in BCD 3.1.0. 🎉
See https://github.com/mdn/browser-compat-data/blob/master/docs/data-guidelines.md#mixins and https://github.com/mdn/browser-compat-data/releases/tag/v3.1.0 for details.

I'll fix existing data in #8929.

Closing here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data:api Compat data for Web APIs. https://developer.mozilla.org/docs/Web/API question Issues where a question or problem is stated and a discussion is held to gather opinions.
Projects
None yet
Development

No branches or pull requests

9 participants