Thunderbird/de-xbl
Here are some notes on the process of converting an XBL binding into a Custom Element. They are basically just a reminder of some of the things you might have to do, and do not attempt to fully document how to do them. Not all of these things will be needed in every case. For examples of conversions, see bug 1484976 (tb-war-on-xbl)
- raw conversion with converter: https://bgrins.github.io/xbl-analysis/converter/
- use `./mach eslint --fix <filename>` to fix linting issues, indentation, etc.
- reindent comments, other things eslint --fix missed
- reformat XUL strings, indentation, etc.
- make sure the custom element has a "-" in the name, which is required for custom elements
- Remove CSS bindings
minimonth { -moz-binding: url("chrome://calendar/content/widgets/minimonth.xml#minimonth"); }
- Edit jar.mn files, remove xml, add js, as needed
- Include js file as a <script> where needed, only once per window/scope/context where needed.
- make change to <element is="custom-element-name"> if needed, where element is used
- use `this.setAttribute("property", "some-value");` in connectedCallback for things like `flex="1"` so they don't have to be added to the tag for each instance.
- add DTD arguments, second argument to parseXULToFragment will be something like this, move exact URLs from XBL file:
[ "chrome://calendar/locale/global.dtd", "chrome://global/locale/global.dtd" ]
- fix DTD entries:
Example: `FROM-DTD-month-1-name` will become `&month.1.name;`
starts with `&` ends with `;` and `.` separate segments
- deal with anonids, convert them to classes (don't use id to prevent duplicate ids on the page issues),
then use querySelector etc.
for example: document.getAnonymousElementByAttribute(this, "id", "months-back-button")
might become: this.querySelector(".months-back-button")
- deal with inherited attributes
remove things like `inherits="value=year"`
static get inheritedAttributes() { return { ".minimonth-header": "readonly,month,year" }; } this.initializeAttributeInheritance();
- fix interfaces: observers, listeners, etc.
this.calICompositeObserver = this.getCustomInterfaceCallback(Ci.calICompositeObserver); MozXULElement.implementCustomInterface(MozMinimonth, [ Ci.calICompositeObserver, Ci.calIOperationListener, Ci.nsIObserver ]);
- fix attributes that were on the top-level element like orient="vertical"
- decide what goes in the constructor vs connectedCallback. Prefer putting code (like adding event listeners) in connectedCallback for later execution If possible add a guard to return early from connectedCallback to prevent it from executing more than once. This basically turns it into a 'constructor' that runs later when the CE is connected.
- Internal event listeners do not need to be removed in disconnectedCallback (the converter will convert destructor into disconnectedCallback).
- refactor code