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

Generate and publish TypeScript type definitions #57

Open
lieser opened this issue Jul 25, 2021 · 37 comments
Open

Generate and publish TypeScript type definitions #57

lieser opened this issue Jul 25, 2021 · 37 comments

Comments

@lieser
Copy link

lieser commented Jul 25, 2021

For Firefox there exists published TypeScript definitions for WebExtension, that can be easily installed and used via npm.
They seem to be generated by https://github.com/jsmnbom/definitelytyped-firefox-webext-browser (and published to https://github.com/DefinitelyTyped/DefinitelyTyped).

It would be nice to have something similar for Thunderbird.

@lieser
Copy link
Author

lieser commented Jul 25, 2021

See also jsmnbom/definitelytyped-firefox-webext-browser#39

There also exist an attempt to manually create and maintain the definitions: https://github.com/ctrlxc/thunderbird-web-ext-types (more recent fork of https://github.com/kelseasy/web-ext-types).
And some extension have their own definitions of the APIs they use. But I think an automated generation would be much more feasible long term.

@jobisoft
Copy link
Contributor

I have never worked with TypeScript. Our schema files are located at :
https://searchfox.org/comm-central/source/mail/components/extensions/schemas

Could you give it a try and run them through the linked generator?

@lieser
Copy link
Author

lieser commented Jul 27, 2021

Can try to take a closer look in the next weeks, but no promises.

I consider this more a nice to have (as I already created the definitions I currently need manually), and nothing urgent.

@joendres
Copy link
Contributor

joendres commented Aug 3, 2022

Could you give it a try and run them through the linked generator?

I tried, but it doesn't work out of the box. We'd have to understand the inner workings of the generator to adapt it to thunderbird. It seems not to be a problem with the schema format but with parts of the content; some types seem to be too complex for the generator.

@JimDanner
Copy link

I forked that project for the Firefox declarations, and made the (many) changes that were needed to get it to produce Thunderbird declarations. The library @types/thunderbird-webext-browser is now in DefinitelyTyped and npm.

@jobisoft
Copy link
Contributor

Nice! What version of Thunderbird were you using to generate these definitions? Can I include this information on our official API documentation?

@lieser
Copy link
Author

lieser commented Apr 2, 2023

Thanks a lot for creating the generated declarations for Thunderbird. I successfully switched from my (incomplete) manually created ones to it.

One issue I found was with optional return types, e.g. messenger.accounts.get(...). In the schema it is correctly defined as optional (see identities.json), but in the generated types the return type is Promise<MailAccount>.

The Firefox declarations seem to support optional return types, but does it with manual overwrites by setting converterPromiseOptional or converterPromiseOptionalNull in src/overrides.ts.
Don't know why it is not using the optional of the callback parameter (not the optional of the callback itself). Maybe to distinguish between null and undefined, or maybe Firefox was not setting that optional in the past (currently it contains them, see e.g. alarms.json and cookies.json.
See also jsmnbom/definitelytyped-firefox-webext-browser#35, jsmnbom/definitelytyped-firefox-webext-browser#21, jsmnbom/definitelytyped-firefox-webext-browser#6.

Note that the documentation in the schema for optional return types seems to be incomplete. E.g. messenger.accounts.getDefault(...) can also return null, and the description correctly mentions that, but the optional on the parameter of the callback is missing there.
But this is more an issue with Thunderbird's schema files and should be fixed there. See also #56.

@JimDanner
Copy link

@jobisoft

Nice! What version of Thunderbird were you using to generate these definitions?

The current version is based on Thunderbird 109.0, specifically the tag THUNDERBIRD_109_0b4_RELEASE and its associated Gecko version FIREFOX_109_0b9_RELEASE. With the generator any version can be made, but there are a few version-specific 'overrides' correcting quirks and errors in the schemas. The overrides have last been updated for version 109.

Can I include this information on our official API documentation?

Sure. Is there a more systematic way of getting API information? I have used a combination of

  • the Thunderbird namespaces listed in the first table on the documentation page, using schemas in mail/components/extensions/schemas/ in the Thunderbird source code
  • the Gecko namespaces listed in the second table on the documentation page
  • namespaces that turned out to be missing from that documentation page: action, privacy.network, privacy.services, privacy.websites for Thunderbird, and the fundamental namespaces events, experiments, extensionTypes, manifest and types.

It's all a lot of trial-and-error. You'd think that there must be a systematic way to find out which parts of the Gecko API have been implemented in Thunderbird. Is there?

@lieser

One issue I found was with optional return types, e.g. messenger.accounts.get(...). In the schema it is correctly defined as optional (see identities.json), but in the generated types the return type is Promise<MailAccount>.

I see what you mean. I'll put on the Todo-list to put this in src/tb-overrides.ts and to have a look into automatic recognition of optional return values, so the number of overrides can be limited to those where the schemas are incomplete.

@JimDanner
Copy link

One issue I found was with optional return types, e.g. messenger.accounts.get(...). In the schema it is correctly defined as optional (see identities.json), but in the generated types the return type is Promise<MailAccount>.

I have now added this and a few other items to src/tb-overrides.ts so they have the correct return type, like Promise<... | null> or Promise<... | undefined>.

The Firefox declarations seem to support optional return types, but does it with manual overwrites by setting converterPromiseOptional or converterPromiseOptionalNull in src/overrides.ts. Don't know why it is not using the optional of the callback parameter (not the optional of the callback itself).

In an earlier version, the Firefox declaration generator did that: when a schema indicated an optional callback parameter, it added | undefined. But then it was noted that many such indicators in the schemas are incorrect: the documentation often says nothing about promises resolving to null or undefined. So the developer went through all the documentation for such cases and added those where it may actually happen into the overrides script by hand.

I have now also done that for the Thunderbird schemas, which suffer from exactly the same problem. Out of 13 callbacks with an optional parameter in the schemas, 3 are documented as returning null, 2 as undefined, and the rest don't seem to return anything like that in their promises (see my list).

Note that the documentation in the schema for optional return types seems to be incomplete. E.g. messenger.accounts.getDefault(...) can also return null, and the description correctly mentions that, but the optional on the parameter of the callback is missing there.

In version THUNDERBIRD_109_0b4_RELEASE, it is actually correct in the schema (accounts.json). But a big cleanup of this issue would certainly be useful.

@gumulabartosz
Copy link

Guys! By the way, do you have any tutorials/documentation about developing addons for Thunderbird using Typescript? I'm trying but i fails.

@ringods
Copy link

ringods commented Apr 28, 2024

@JimDanner I want to help generate the typings for newer versions of Thunderbird. I tried for v115 but your script errored on me. This is not the place to discuss difficulties I encountered with definitelytyped-thunderbird-webext-browser, but your repo has Github issues disabled. Can you enable Issues so we can discuss it there?

@JimDanner
Copy link

Hi @ringods, thanks for making the effort! I have opened the Issues page on the repository.

I've also run the program myself on the TB 115 API and got an error due to a silly change in Thunderbird's documentation webpage – it now lists the names of the APIs as tabs API etc., whereas it used to be tabs and so on. The program uses those names, so it failed as it was looking for a "tabs API" namespace. I have added code that strips off " API" and now it works again on my system.

Also tried it on the bleeding-edge version TB 127, and there it turns out they added an undocumented function with... a nameless parameter. Really. So that tripped up the program too, and I added some more code to deal with it.

I still need to check if other things in the API have changed (sadly, much has to be adjusted manually), and then create a fully updated output file. Anyway, please pull the new version, see if it works for you, and file an issue if it doesn't.

@jobisoft
Copy link
Contributor

jobisoft commented Apr 28, 2024

I've also run the program myself on the TB 115 API and got an error due to a silly change in Thunderbird's documentation webpage – it now lists the names of the APIs as tabs API etc., whereas it used to be tabs and so on. The program uses those names, so it failed as it was looking for a "tabs API" namespace. I have added code that strips off " API" and now it works again on my system.

I would not call this a silly change, with all due respect.

The page will undergo massive changes in the future. I would propose to work with the schema files directly, and not with the documentation, which I generate from these schema files:

https://searchfox.org/comm-central/source/mail/components/extensions/schemas

@JimDanner
Copy link

So far, using the documentation webpage has been unavoidable. It is the only place I know where the program can see

  1. which Firefox (Gecko) APIs are implemented in Thunderbird's extension system
  2. what the URL is of the documentation page for each individual API (the program puts that URL in the type-definition JSdoc comments, so extension programmers get to see it in their IDE and can click it for further information on a namespace).

If there's a place where that information is available – preferably in a systematic and stable form – I would prefer to use that.

Regarding the addition of "API" after the names of Thunderbird's APIs, perhaps it isn't silly, but it's not very useful either and I don't understand why it was done in the table for Thunderbird and not in the table right below it for Gecko.

@jobisoft
Copy link
Contributor

The list of APIs supported by Thunderbird is generated from the title of the individual API pages. "API" was added to the title because other feedback I got indicated that this helps readability. The list of supported Firefox APIs is curated and not generated and was not modified. Thanks for pointing it out.

The list of supported Firefox APIs can be taken from here:
https://searchfox.org/mozilla-central/source/toolkit/components/extensions/schemas

My curated list only includes useful and manually tested Firefox APIs.

I will think about a solution for the link to the documentation. How is Firefox solving this?

@JimDanner
Copy link

The list of APIs supported by Thunderbird is generated from the title of the individual API pages. "API" was added to the title because other feedback I got indicated that this helps readability. The list of supported Firefox APIs is curated and not generated and was not modified. Thanks for pointing it out.

The list of supported Firefox APIs can be taken from here: https://searchfox.org/mozilla-central/source/toolkit/components/extensions/schemas

My curated list only includes useful and manually tested Firefox APIs.

I've often wondered how the integration of Gecko is done by the Thunderbird developers: they must make an explicit choice somewhere which parts of the browser and its WebExtensions API they compile into Thunderbird. For example, the alarms namespace from the file alarms.json is not on the list on the webpage; the developers must have decided to leave it out. Couldn't find anything about this in the Thunderbird source code, and apparently you have to test this manually – is the WebExtensions API an 'emergent phenomenon'?

By the way, the toolkit/components/extensions/schemas directory you point to is not exhaustive; Thunderbird also uses some APIs whose JSON files are in browser/components/extensions/schemas, like pkcs11.json.

Also, I have added various APIs to the list manually, as you can see in my code. It works, it just seems a bit arbitrary and not very rigorous. I discovered these things 'the hard way', by seeing errors in the results. If things change, it will depend on coincidence how long it takes to find out.

I will think about a solution for the link to the documentation. How is Firefox solving this?

If I recall correctly, the Firefox typedef generator doesn't include links to the documentation pages. It also has a much easier time, as it can simply download all the JSON files from the two folders in the Firefox source code, without having to figure out which ones are implemented.

@tdulcet
Copy link

tdulcet commented Apr 29, 2024

I will bring this up at the next Thunderbird Council meeting as part of my WECG motion, but it think it would be much better for the Thunderbird developers to take over maintenance of the TS type definitions, as they could much more easily resolve the many issues @JimDanner described above, as well as produce more regular updates of the definitions when they update the MailExtension documentation, which will become more important as Thunderbird moves towards monthly releases. Having official Thunderbird TS type definitions, as well as documentation on how to use them would be extremely helpful for WebExtension developers by allowing them to easily perform type checking on their extensions.

Another issue currently is for extensions supporting both Thunderbird and Firefox, and using APIs exclusive to both. In that case, developers cannot use the existing Thunderbird or Firefox type definitions, as they do not cover all APIs. It would be great if Thunderbird could collaborate with Mozilla to publish separate TS type definitions that cover the superset of extension APIs supported by both clients, which I believe could be accomplished by joining the WECG.

(I should note that I am not advocating for developers to write their extensions in TS. Using TS results in obfuscated code, which is unnecessary for extensions that generally do not need to support older browsers and causes a performance degradation, as well as being the antithesis of open source. However, the TS type definitions can also be used to perform type checking on regular JS code by adding JSDoc comments, which is what Thunderbird should document and encourage add-on developers to do. See TinyWebEx/AddonTemplate#5 for more information.)

@jobisoft
Copy link
Contributor

jobisoft commented Apr 29, 2024

browser/components/extensions/schemas

You are right, forgot about those as that is considered bad practice, but we have no choice. The missing link is here:
https://searchfox.org/comm-central/source/mail/components/extensions/jar.mn#60

alarms is in the folder I mentioned:
https://searchfox.org/comm-central/search?q=ext-alarms&path=&case=false&regexp=false

I did not add it to our documentation, because I missed it. Will add it.

Edit: I added the list of supported Firefox APIs to our docs to make it easier for developers to see, which of the Firefox APIs work for Thunderbird as well. That is a manual process. If this is what you refer to as an 'emergent phenomenon', then yes. Help on that matter is always appreciated.

@JimDanner
Copy link

@jobisoft

The missing link is here: https://searchfox.org/comm-central/source/mail/components/extensions/jar.mn#60

OK, the list in jar.mn seems to be the same one that's in the first table on the documentation website.

alarms is in the folder I mentioned: https://searchfox.org/comm-central/search?q=ext-alarms&path=&case=false&regexp=false

I did not add it to our documentation, because I missed it. Will add it.

To be clear, alarms is just a random example. Other Gecko namespaces that aren't in the second table on the documentation website (probably for good reasons) are activityLog, browserSettings.colorManagement, browsingData, captivePortal, contextualIdentities, declarativeNetRequest, geckoProfiler, networkStatus, pageAction, scripting, telemetry, and test.

I think this is another illustration of why the Thunderbird developers might want to be a bit more explicit about the choices they make in the integration of Gecko.

@tdulcet I agree that the application developers are in the best position to publish API documentation, including the sort that's published at DefinitelyTyped in the form of index.d.ts files. (Those files are probably used for extension development in JavaScript at least as much as TypeScript; the JSdoc comments and function signatures are just really useful in a good IDE.) If a developer in the Thunderbird team wants to take over this task, that would be very welcome.

They could take a look at some of my code, in particular the parts download.ts, tb-overrides.ts and perhaps desc-to-docs.ts; and a few documentation files I have written: Reserved words and Typefiles, to appreciate the types of complications that the generator deals with, e.g.:

  • converting description fields written in reStructuredText to JSdoc comments in Markdown or HTML format
  • nesting the namespaces in the output file, or not doing so
  • dealing with function names that are also reserved words in JavaScript, e.g. messenger.messages.delete()
  • dealing with optional function arguments, where the WebExtension standard conflicts with the TypeScript standard (as solved here)
  • dealing with promises that may return null or undefined, as well as those that have an 'optional' callback argument in their JSON file but don't actually return undefined – see issue Document if null can possibly be returned #56.

@jobisoft
Copy link
Contributor

From your experience with parsing of schema files, do you happen to know a nodeJS project, which can generate a pure manifest V2 or manifest V3 schema file from our mixed schema files?

@JimDanner
Copy link

From your experience with parsing of schema files, do you happen to know a nodeJS project, which can generate a pure manifest V2 or manifest V3 schema file from our mixed schema files?

Don't know of any, unfortunately.

@ringods
Copy link

ringods commented Apr 30, 2024

@jobisoft I'm not sure if I understand your request correctly.

If your request is about reading a JSON file into a JS datatype and validating it for correctness and completeness against a schema, then I propose to have a look at Zod.

@jobisoft
Copy link
Contributor

Our schema files have min_manifest_version and max_manifest_versions properties to suppress entries, based on the Manifest version used. In order to generate documentation or type definitions from them, the first step should be to extract clean schemas for the required version. I would like to replace my home-brewed Python script.

@jobisoft
Copy link
Contributor

jobisoft commented May 5, 2024

@JimDanner : How is your generator (or the upstream project at https://github.com/jsmnbom/definitelytyped-firefox-webext-browser) dealing with Manifest V3? Since there are differences to Manifest V2, I assume your generated type definition can only be for Manifest V2 or Manifest V3, right?

Reason I am asking: Would you benefit from a clean set of schema files for Manifest V2 and another clean set of schema files for Manifest V3?

Also: Are there any discussions in the upstream project you may be aware of, to not use the raw schema files as source, but the output from the addons-linter project? The JSON from the linter looks a bit different, but already does some of the heavy lifting (for example untangle the mess regarding the browserAction API / action API schema files, which use an $import statement). The output can be found here:

https://github.com/mozilla/addons-linter/tree/master/src/schema/imported

We are in the process of making the linter work with Thunderbird extensions.

@jobisoft
Copy link
Contributor

jobisoft commented May 6, 2024

Ok, this is what is gonna happen:

Once this issue is fixed, we will most probably drop our own out-of-date fork of the addons-linter and instead use the Firefox version directly with some added build instructions to use our set of schema files. This one: thunderbird_beta_schema_files.zip.

Note: This file does not yet include the schema fixes regarding missing/wrong return values. That will hopefully be ready with the next Beta. The zip file has a browser/ folder, because that is where the linter is looking for that data. That does not matter, those are our supported APIs.

In the end, I hope this set of schema files will be the base for:

(I am still unsure if we should instead use the output from the linter as base for the typescript definition file and our documentation, as it has some of the heavy lifting done already, but a slightly different format, see my last comment.)

We will officially provide that schema zip-file somewhere once this process has been implemented, probably in our own (reworked) addons-linter repo.

The next step is to convert our current meta-data into browser-compat-data used by MDN and the linter.

After that, there should be no need to manually parse our documentation page. All information are either in the browser-compat-data or the provided schema zip-file.

@JimDanner
Copy link

JimDanner commented May 6, 2024

@JimDanner : How is your generator (or the upstream project at https://github.com/jsmnbom/definitelytyped-firefox-webext-browser) dealing with Manifest V3? Since there are differences to Manifest V2, I assume your generated type definition can only be for Manifest V2 or Manifest V3, right?

Reason I am asking: Would you benefit from a clean set of schema files for Manifest V2 and another clean set of schema files for Manifest V3?

The generator is manifest-version-unaware: it just uses the JSON files it's told to download, without looking at the version. So it would benefit from separate sets of schemas for the two versions.

Also: Are there any discussions in the upstream project you may be aware of, to not use the raw schema files as source, but the output from the addons-linter project?

Probably not, the upstream project isn't very active. Addons-linter looks interesting (though converting its output into a .d.ts TypeScript declaration file seems like a project in itself).

In the end, I hope this set of schema files will be the base for:

I think these are good developments; there's no use in doing double work. However, the idea that there are "no further quirks" may be a bit optimistic. As it is, the Firefox generator has a long list of manual fixes for issues with the schemas; it remains to be seen whether addons-linter solves all of them.

Further, if the definitelytyped-firefox-webext-browser definition-file generator will be used, I'm not sure it will be able to handle all of the Thunderbird-specific issues I discovered while adjusting it for Thunderbird:

  • converting description fields written in reStructuredText to JSdoc comments in Markdown or HTML format. The Firefox schemas don't have this. Some have to be done manually.
  • dealing with function names that are also reserved words in JavaScript, e.g. messenger.messages.delete(). Again, only happens in the Thunderbird API.
  • dealing with promises that may return null or undefined, as well as those that have an 'optional' callback argument in their JSON file but don't actually return undefined: this is still done manually based on your latest list
  • explicitly adding some required APIs not listed on the documentation page, such as events and privacy.network. The Firefox generator doesn't have to think about this as it simply uses all of Firefox' schema files. How would the output of addons-linter deal with this?
  • duplication of all of the declarations: some extension programmers use the browser root namespace, others use messenger; both should be documented and auto-completed by the IDE, so the .d.ts file must duplicate the whole block.

Also, my fork addresses a few issues the Firefox generator ignores or gets wrong, such as

@jobisoft
Copy link
Contributor

jobisoft commented May 6, 2024

converting description fields written in reStructuredText to JSdoc comments in Markdown or HTML format. The Firefox schemas don't have this. Some have to be done manually.

I see. The descriptions are piped into Sphinx to build our documentation. It will be difficult to remove them. But why do you need to manually change some? We should try to eliminate the need for that.

dealing with function names that are also reserved words in JavaScript, e.g. messenger.messages.delete(). Again, only happens in the Thunderbird API.

That is unexpexted. Even Javascript Map has a delete function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete?retiredLocale=de

Hm.

dealing with promises that may return null or undefined, as well as those that have an 'optional' callback argument in their JSON file but don't actually return undefined: this is still done manually based on your latest list

See #56 (comment)

Functions can either return null or undefined and our APIs did both
without explicitly specifying which. We now use optional: true to
indicate undefined. If a function returns null, it is explicity
stated as a possible return value.

Isn't this fixed with the pending schema updates?

explicitly adding some required APIs not listed on the documentation page, such as events and privacy.network. The Firefox generator doesn't have to think about this as it simply uses all of Firefox' schema files. How would the output of addons-linter deal with this?

  • privacy.* are in the zip file I provided.
  • the action.json file is created by the linter, same issue in Firefox, done by the $import statement. The linter output has a file for each API.
  • event is also created by the linter

Here is the output from the linter. It is mostly the same, but does not use choices but some other mechanism. Maybe switching the input data format is the better approach?
thunderbird_beta_linter_files.zip

duplication of all of the declarations: some extension programmers use the browser root namespace, others use messenger; both should be documented and auto-completed by the IDE, so the .d.ts file must duplicate the whole block.

Ok, I do not see how we can fix this in the schema files, as these root namespaces are not defined in the schema, IIRC.

So after all, it looks like we will still need a special fork of the generator project, for Thunderbird. This will be even more true, if the linter output is considered as input format. But I cannot do that. Your knowledge regarding typescript is superior to mine (which is basically non-exiting). It would be a huge waste of time if I had to start maintaining the project. I stand by what I said earlier:

  • Just because there is now MZLA to do work on Thunderbird, it should not mean that all work has to be done by them (or us, as I am a paid MZLA employee)
  • Thunderbird is a community project and always has been, we depend on community contributions and are grateful for them

I will try my best to generate the input data you need, to minimize your aditional / manual work.

@JimDanner
Copy link

I see. The descriptions are piped into Sphinx to build our documentation. It will be difficult to remove them. But why do you need to manually change some? We should try to eliminate the need for that.

Yes, it would be good to eliminate those cases. For example, the function windows.create has this description:

Creates (opens) a new window with any optional sizing, position or default URL provided.
When loading a page into a popup window, same-site links are opened within the same
window, all other links are opened in the user's default browser. To override this behavior,
add-ons have to register a
`content script <https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3>`__ ,
capture click events and handle them manually. Same-site links with targets other than
<value>_self</value> are opened in a new tab in the most recent ``normal`` Thunderbird 
window.

This includes (if I understand reStructuredText correctly) a link with link text content script <https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3> to a URL that should be specified somewhere else in the text (but seems to have been omitted). It's probably intended as a link with text content script to URL https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3. Anyway, the parser I inherited from the Firefox project gets this wrong, so I have entered a correct text by hand.

There are similar problems with the function tabs.create and the types _manifest.ThemeExperiment, menus.MenuIconDictionary, and menus.MenuIconPath.

That is unexpexted. Even Javascript Map has a delete function. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete?retiredLocale=de

The problem in the TypeScript declaration file may be that delete is not introduced as a property of some object, it's declared inside the context of a namespace – where it's not tacked onto some object but standing on its own. See my notes on the issue.

Isn't this fixed with the pending schema updates?

Let's assume it is.

  • privacy.* are in the zip file I provided.

  • the action.json file is created by the linter, same issue in Firefox, done by the $import statement. The linter output has a file for each API.

  • event is also created by the linter

That suggests that the linter can be an improvement over the current situation.

  • Just because there is now MZLA to do work on Thunderbird, it should not mean that all work has to be done by them (or us, as I am a paid MZLA employee)

  • Thunderbird is a community project and always has been, we depend on community contributions and are grateful for them

I will try my best to generate the input data you need, to minimize your aditional / manual work.

That sounds like a reasonable way forward.

@jobisoft
Copy link
Contributor

jobisoft commented May 6, 2024

I see. The descriptions are piped into Sphinx to build our documentation. It will be difficult to remove them. But why do you need to manually change some? We should try to eliminate the need for that.

Yes, it would be good to eliminate those cases. For example, the function windows.create has this description:

Creates (opens) a new window with any optional sizing, position or default URL provided.
When loading a page into a popup window, same-site links are opened within the same
window, all other links are opened in the user's default browser. To override this behavior,
add-ons have to register a
`content script <https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3>`__ ,
capture click events and handle them manually. Same-site links with targets other than
<value>_self</value> are opened in a new tab in the most recent ``normal`` Thunderbird 
window.

This includes (if I understand reStructuredText correctly) a link with link text content script <https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3> to a URL that should be specified somewhere else in the text (but seems to have been omitted). It's probably intended as a link with text content script to URL https://bugzilla.mozilla.org/show_bug.cgi?id=1618828#c3.

That is exactly what that reStructuredText notation for inline links does. Nothing has been left out. There is a different notation, which uses placeholders, which has a single underscore at the end. I try not to use it, except for the index.

Anyway, the parser I inherited from the Firefox project gets this wrong, so I have entered a correct text by hand.

Could you replace that specific reStructuredText notation using regular expressions, something like this?

description.replace(/`(.*) <(.*)>`__/g, '[$1]($2]')

This way you do not have to deal with individual descriptions, but just replace the correct reStructuredText notation for inline links with whatever you need? You could also just leave out the link by not using $2 in the replacement string.

That is unexpexted. Even Javascript Map has a delete function. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete?retiredLocale=de

The problem in the TypeScript declaration file may be that delete is not introduced as a property of some object, it's declared inside the context of a namespace – where it's not tacked onto some object but standing on its own. See my notes on the issue.

I will keep this in mind when creating new APIs.

@JimDanner
Copy link

JimDanner commented May 6, 2024

That is exactly what that reStructuredText notation for inline links does. Nothing has been left out. There is a different notation, which uses placeholders, which has a single underscore at the end. I try not to use it, except for the index.

Ah, I see, the quick ref omits that syntax (only mentions the single-underscore variant) but it's mentioned in the full specification. I'll test your regex and see if the conversion of descripotions can be fully automated.

@jobisoft
Copy link
Contributor

I have two follow-up question regarding @tdulcet request for a universal typescript definition, which should support all vendors.

  1. Universal type definition

Since @JimDanner 's project provides a specific type definition for Thunderbird, developers know that if something is proposed from the typescript definition file in the IDE, it should work in the most recent version of Thunderbird - but it may still have false positives, because a feature may only work for 115 but not for 102. That will only be caught by the addons-linter, using compat data.

If the developer is using a universal typescript definition file, including supported features from Firefox or even other vendors, this will become more difficult, right? Is this at all desired?

  1. Thunderbird modifications

In the early days of me working on the APIs, I added Thunderbird functions to namespaces, which are also used by Firefox. Specifically windows.openDefaultBrowser() and browserAction.setLabel(). I also added a tab parameter to the commands.oncommand event, because I did not want to wait for Firefox, but they followed in the meantime.

I guess this makes creating add-ons in Firefox and Thunderbird difficult as well, does it? Would it help to clearly separate these additions by moving them into a sub namespace, something like browserAction.tb.setLabel()?

@tdulcet
Copy link

tdulcet commented May 13, 2024

Thank you @jobisoft for your all your work and for taking the initiative to resolve those issues described by @JimDanner. Once this is finished, it should be a huge improvement for TB add-on developers.

To answer your questions:

  1. Yes, this would be very much desired. As with the issue you described about the new APIs not working with older TB ESR releases, this should be caught by the add-ons linter once it understands the specific APIs supported by TB (Thunderbird WebExtension APIs unsupported by linter addons-server#73).

    However, the Universal type definitions I requested should be in addition to the existing TB and FF specific type definitions. If developers know they are only supporting TB (and not FF or any browsers), then they should use of course the TB specific type definitions. The advantage of the Universal type definitions is that it would make it much easier to develop universal extensions that support multiple clients. Considering that both Firefox and Chrome have orders of magnitude more extensions than Thunderbird, this (along with other needed changes) could lead to more add-ons supporting TB, so I think it would be in TB's interest to encourage all extension developers to use the Universal type definitions if/when they are available.
  2. No, I do not believe this is an issue for anyone. The only part that is confusing is that these modifications are not documented on MDN with the rest of the functions in the namespace. I suspect most developers using the windows or browserAction APIs for example would go straight to MDN for the documentation and thus would be unaware of the TB modifications. The TB specific documentation also does not always make it clear which parts are the modifications.

@jobisoft
Copy link
Contributor

... the Universal type definitions I requested should be in addition to the existing TB and FF specific type definitions. If developers know they are only supporting TB (and not FF or any browsers), then they should use of course the TB specific type definitions. The advantage of the Universal type definitions is that it would make it much easier to develop universal extensions that support multiple clients. Considering that both Firefox and Chrome have orders of magnitude more extensions than Thunderbird, this (along with other needed changes) could lead to more add-ons supporting TB ...

Would that not require the universal type definition to only include the overlap of all vendors? A set of shared APIs, which would reduce the available APIs to a minimum?

How could that lead to more add-ons supporting TB ?

@Juraj-Masiar
Copy link

If I may, I would like to share my experience with TypeScript addons development in Thunderbird / Safari / Firefox / Chrome / Edge.
For me, it's most useful that the API definitions are simply there.
The fact that they came in a specific version (or environment) is something I handle myself if needed, but it's rare. Modern Thunderbird 115 has great API support, so many things works without any change (compared to Firefox version). And with the upcoming Thunderbird 128 it's gonna be even better.

I'm using browser namespace in all of my addons, also in Chrome by using the webextension-polyfill (until they implement it), so this also greatly simplifies cross-development.

Note that if the API definitions are missing, then one have to use // @ts-ignore, which is super ugly and type-unsafe (often also on the following lines, due to any type).

@tdulcet
Copy link

tdulcet commented May 13, 2024

Would that not require the universal type definition to only include the overlap of all vendors? A set of shared APIs, which would reduce the available APIs to a minimum?

No, that would not be helpful. What is needed instead is Universal type definitions that cover the superset of APIs supported across all WebExtention clients. Then add-ons could for example use both TB and FF exclusive APIs in the same add-on, while still having type checking and other advanced IDE features, such as function signatures and autocompletion.

Note that this was not something I was proposing MZLA do themselves, but instead collaborate with Mozilla, Google and Apple to create as part of the WECG. However, if MZLA wants to do it alone, it would likely benefit TB much more than it would the browsers considering the disparate set of APIs supported by TB.

How could that lead to more add-ons supporting TB ?

While there are obviously no guarantees, I believe any changes that make it easier for add-on developers to support TB or otherwise inform them of the available MailExtension APIs in TB would result in more TB add-ons. Of course, documenting the MailExtension APIs on MDN and making some of the other changes I proposed to the Council would help significantly as well.

@jobisoft
Copy link
Contributor

@JimDanner : I found this:

https://searchfox.org/comm-central/search?q=%24%28ref%3Awindows.update%29%29.&path=&case=false&regexp=false

So Firefox does use a reference system in their descriptions. Will look at it and see if we can use the same.

@jobisoft
Copy link
Contributor

jobisoft commented Jun 18, 2024

I have published the first version of
https://github.com/thunderbird/webext-schemas

The repository contains a script, which pulls all the relevant schema files for Thunderbird and does some post-processing (like manifest version split). The official documentation is based on these files now as well (only the "latest" branch so far):
https://webextension-api.thunderbird.net/en/latest-mv3/

During the next week I will check, if really all Firefox APIs which are baked into Thunderbird work. The documentation lists all of them now, but I do not think all of them are meaningful. For example:

  • activityLog
  • browserSettings
  • browsingData
  • captivePortal
  • geckoProfiler
  • privacy.*
  • proxy
  • webNavigation
  • webRequest

If I conclude that they are not working, I will probably remove them from the generated schema files (and therefore from the documentation). Have you worked with any of them and know if they are in any way helpful and working in Thunderbird?

These scheme files include some additional data, for example links to the documentation. I hope this is now everything you need. The schema files have been re-worked massively to get rid of all reStructuredText notation in favour of inline <a> tags and Firefox reference notation. Bug 1903248 still needs to land.

Once the dust has settled, we could also add the processed schema files for the latest beta and/or esr directly to the repository, if that is desired.

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

No branches or pull requests

8 participants