Thunderbird 115: CSS Customization


there is something else which either doesn't work or I am not using correctly:
CSS:
/* future: before start date, not due today */
/* doesn't work. Affects all not-started-items, not just those with due date */
.calendar-task-tree > treechildren::-moz-tree-cell-text(future) {color:orange!important}

I think this is supposed to style all tasks with a due-date in the the future.
But in my tests, this styles all "unstarted" tasks with or without due-date.

Looking through the source, I figured out how it works:

There are 5 different possible progress states of a task:
  1. future
  2. inprogress: if either condition is met: (has start date OR % completed > 0 OR status = "in process")
  3. completed: if it has the "completed" checkmark in the checkbox
  4. duetoday: due date = today
  5. overdue: due date = in the past
If none of the states from 2-5 apply, then the state is set to "future".
Unfortunately, this includes tasks with AND without due date. So, I still have to figure out how to style them differently.

JavaScript:
  /**
   * This function return the progress state of a task:
   * completed, overdue, duetoday, inprogress, future
   *
   * @param aTask     The task to check.
   * @returns The progress atom.
   */
  getProgressAtom(aTask) {
    let nowdate = new Date();

    if (aTask.recurrenceInfo) {
      return "repeating";
    }

    if (aTask.isCompleted) {
      return "completed";
    }

    if (aTask.dueDate && aTask.dueDate.isValid) {
      if (cal.dtz.dateTimeToJsDate(aTask.dueDate).getTime() < nowdate.getTime()) {
        return "overdue";
      } else if (
        aTask.dueDate.year == nowdate.getFullYear() &&
        aTask.dueDate.month == nowdate.getMonth() &&
        aTask.dueDate.day == nowdate.getDate()
      ) {
        return "duetoday";
      }
    }

    if (
      aTask.entryDate &&
      aTask.entryDate.isValid &&
      cal.dtz.dateTimeToJsDate(aTask.entryDate).getTime() < nowdate.getTime()
    ) {
      return "inprogress";
    }

    return "future";
  },
};
 

My Computer

System One

  • OS
    Wimdows 10
@das10 : Yes, I am currently on Thunderbird 115. But the DOM selectors rarely change.
Limiting styling to only 1 column instead of entire row:
As far as I can tell, it doesn't appear to be possible using CSS.
Re: "to style tasks with a due date differently from tasks without due-date" - Unfortunately couldn't make this work either.

Thunderbird is not exposing any more details about the pseudo classes in the task tree than we already know about from various sources, and the usual methods of using pseudo :is :not etc. is not an option either:(

Normally, all of this should be achievable with CSS. The problem seems to be that the task <tree> is "stored in a different way to other elements":

Styling a Tree

The body of the tree must be styled in a somewhat different way than other elements. This is because the tree body is stored in a different way to other elements. The outer <treechildren> is the only real element in the tree body. The inner elements are just placeholders.
I have read the entire help document, but I don't understand it entirely. Do you understand what they say ?

Here is how the <tree> should apparently look like in the DOM Inspector (Browser Toolbox):
treecol
treechildren

But I still don't know how to apply this knowledge to ...
  • ... limit styles to only 1 column (instead of the entire row)
  • ... style tasks with a due date differently from tasks without due-date
It's a pity that this is badly documented and the DOM Inspector apparently can't see the <treechildren> subnodes (otherwise it would be a walk in the park).

calendar-task-tree.js contains information about the task table:

JavaScript:
  class CalendarTaskTree extends customElements.get("tree") {
    connectedCallback() {
      super.connectedCallback();
      if (this.delayConnectedCallback() || this.hasConnected) {
        return;
      }
      this.hasConnected = true;
      this.appendChild(
        MozXULElement.parseXULToFragment(
          `
          <treecols>
            <treecol is="treecol-image" id="calendar-task-tree-col-completed"
                     class="calendar-task-tree-col-completed"
                     style="min-width: 18px"
                     fixed="true"
                     cycler="true"
                     sortKey="completedDate"
                     itemproperty="completed"
                     closemenu="none"
                     src="chrome://messenger/skin/icons/new/compact/checkbox.svg"
                     label="&calendar.unifinder.tree.done.label;"
                     tooltiptext="&calendar.unifinder.tree.done.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol is="treecol-image" id="calendar-task-tree-col-priority"
                     class="calendar-task-tree-col-priority"
                     style="min-width: 17px"
                     fixed="true"
                     itemproperty="priority"
                     closemenu="none"
                     src="chrome://messenger/skin/icons/new/compact/priority.svg"
                     label="&calendar.unifinder.tree.priority.label;"
                     tooltiptext="&calendar.unifinder.tree.priority.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-title"
                     itemproperty="title"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.title.label;"
                     tooltiptext="&calendar.unifinder.tree.title.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-entrydate"
                     itemproperty="entryDate"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.startdate.label;"
                     tooltiptext="&calendar.unifinder.tree.startdate.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-duedate"
                     itemproperty="dueDate"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.duedate.label;"
                     tooltiptext="&calendar.unifinder.tree.duedate.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-duration"
                     itemproperty="duration"
                     sortKey="dueDate"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.duration.label;"
                     tooltiptext="&calendar.unifinder.tree.duration.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-completeddate"
                     itemproperty="completedDate"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.completeddate.label;"
                     tooltiptext="&calendar.unifinder.tree.completeddate.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-percentcomplete"
                     itemproperty="percentComplete"
                     style="flex: 1 auto; min-width: 40px;"
                     closemenu="none"
                     label="&calendar.unifinder.tree.percentcomplete.label;"
                     tooltiptext="&calendar.unifinder.tree.percentcomplete.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-categories"
                     itemproperty="categories"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.categories.label;"
                     tooltiptext="&calendar.unifinder.tree.categories.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-location"
                     itemproperty="location"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.location.label;"
                     tooltiptext="&calendar.unifinder.tree.location.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-status"
                     itemproperty="status"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.status.label;"
                     tooltiptext="&calendar.unifinder.tree.status.tooltip2;"/>
            <splitter class="tree-splitter"/>
            <treecol class="calendar-task-tree-col-calendar"
                     itemproperty="calendar"
                     style="flex: 1 auto"
                     closemenu="none"
                     label="&calendar.unifinder.tree.calendarname.label;"
                     tooltiptext="&calendar.unifinder.tree.calendarname.tooltip2;"/>
          </treecols>
          <treechildren class="calendar-task-treechildren"
                        tooltip="taskTreeTooltip"
                        ondblclick="mTreeView.onDoubleClick(event)"/>
          `,
          ["chrome://calendar/locale/global.dtd", "chrome://calendar/locale/calendar.dtd"]
        )
      );

I tried to build various selectors based on this information, but none worked.

This is as far as I got currently. If I find out more, I'll let you know. Please do the same if you uncover more.
 
Last edited:

My Computer

System One

  • OS
    Wimdows 10
@eleven11
In the js script that you have shown:

Within the <treecols> tag, I note that only the following 2 col identifiers are present. I think these happen to be the only 2 columns where limited sort of customization is possible, and where cells can be co-related to the property of a different column:

treecol is="treecol-image" id="calendar-task-tree-col-completed"
treecol is="treecol-image" id="calendar-task-tree-col-priority"


Those correspond to the Completed checkbox and the Priority Columns.

Within those 2 columns, aside from the priority & completed status you already use, you can, for example customize the background-color for some types of "status" and "categories". However there is no way to customize them with cross-reference to any of the task where the Due Date is blank (even in Sunbird, where a few more styles can be applied to Columnar cells under Category and Status, I personally found it impossible to stylize the Cells with reference to blank Due Dates).

This is just a "rough" concept showing some colorization of those 2 Columns (it looks too busy, but it is just to illustrate the point).

eg: Completed Column cells related to "Category" (Alarms, Anniversary, Birthday, Business) and Status "Cancelled".
Tbird-Completed.webp

eg: Priority Column cells related to some of the "Completed" Status (Cancelled, Completed, In Progress,Overdue).
Tbird-Priority.webp

Basic usage eg: For the Completed Status Column, pair the property "::-calendar-task-tree-col-completed" with say "birthday" Category.
or a Status like this:

Code:
.calendar-task-tree > treechildren::-moz-tree-cell(calendar-task-tree-col-completed   birthday) {
  background-color: lightcyan !important;
}

.calendar-task-tree > treechildren::-moz-tree-cell(calendar-task-tree-col-completed     status-cancelled) {
  background-image: repeating-linear-gradient(135deg, #dededeaa 0px, white 2px, #ffaaaacc 3px) !important;
  outline: 1px solid initial !important;
}

Similarly for the Priority Column, pair "::-calendar-task-tree-col-priority" property with a Category Name or a Status like "status-cancelled" or say "status-overdue" eg:

Code:
.calendar-task-tree > treechildren::-moz-tree-cell(calendar-task-tree-col-priority     status-cancelled) {
  background-image: repeating-linear-gradient(135deg, #dedede88 0px, white 2px, #ffaaaa88 3px) !important;
}

.calendar-task-tree > treechildren::-moz-tree-cell(calendar-task-tree-col-priority     overdue) {
  background-color: yellow !important;
}
 

My Computer

System One

  • OS
    Windows 11 23H2
    Computer type
    PC/Desktop
    Manufacturer/Model
    custom
    CPU
    intel i7-8700 (non-K)
    Motherboard
    Asus Z370 TUF Gaming
    Memory
    32Gb
    Graphics Card(s)
    On-board Intel iGPU
    Sound Card
    On-board Realtek
    Hard Drives
    Samsung_SSD_850_EVO
    PSU
    Corsair Rm850X
    Cooling
    All air

Latest Support Threads

Back
Top Bottom