[bug] Adding decorations inside tables no longer works

In earlier versions of Obsidian (eg. v1.4) it was possible to have a plugin that adds decorations inside tables however this is no longer possible.

Reproduction

Clone the sample plugin

git clone https://github.com/obsidianmd/obsidian-sample-plugin.git

Replace main.ts with the following code.

import { syntaxTree } from "@codemirror/language";
import { RangeSetBuilder } from "@codemirror/state";
import {
	Plugin
} from "obsidian"
import {
  Decoration,
  DecorationSet,
  EditorView,
  PluginSpec,
  PluginValue,
  ViewPlugin,
  ViewUpdate,
  WidgetType,
} from "@codemirror/view";
class EmojiWidget extends WidgetType {
  toDOM(view: EditorView): HTMLElement {
    const div = document.createElement("span");

    div.innerText = "👉";

    return div;
  }
}

class EmojiListPlugin implements PluginValue {
  decorations: DecorationSet;

  constructor(view: EditorView) {
    this.decorations = this.buildDecorations(view);
  }

  update(update: ViewUpdate) {
    if (update.docChanged || update.viewportChanged) {
      this.decorations = this.buildDecorations(update.view);
    }
  }

  destroy() {}

  buildDecorations(view: EditorView): DecorationSet {
    const builder = new RangeSetBuilder<Decoration>();
		const { from, to } = view.viewport;
		syntaxTree(view.state).iterate({
			from,
			to,
			enter(node) {
				if (node.type.name.startsWith("list")) {
					// Position of the '-' or the '*'.
					const listCharFrom = node.from - 2;

					builder.add(
						listCharFrom,
						listCharFrom + 1,
						Decoration.replace({
							widget: new EmojiWidget(),
						})
					);
				}
				
				if (node.type.name.startsWith("hmd-table-sep_hmd-table-sep-")) {
					let candidate = view.state.doc.slice(node.from).iterLines().next().value;
					const index = candidate.indexOf("-x")
					if (index != -1) {
						const listCharFrom = node.from + index

						builder.add(
							listCharFrom,
							listCharFrom + 1,
							Decoration.replace({
								widget: new EmojiWidget(),
							})
						);
					}
				}
			},
		});

    return builder.finish();
  }
}

const pluginSpec: PluginSpec<EmojiListPlugin> = {
  decorations: (value: EmojiListPlugin) => value.decorations,
};

export default class EmojiList extends Plugin {
	onload() {
		this.registerEditorExtension([
			ViewPlugin.fromClass(
				EmojiListPlugin,
				{
					decorations: (value: EmojiListPlugin) => value.decorations
				}
			)
		]);
	}
}

This should replace any list items or “-x” inside tables with the :point_right: emoji.

Run the plugin (npm install; npm run dev) and enable the plugin.

Create an Obsidian file like the following:

- this is a list item
- list item 2
- list item 3

|  | col1 | col2 | col3 |
| ---- | ---- | ---- | ---- |
| row1 | -x | -x | -x |
| row2 | -x | -x | -x |

In Live Preview mode (Setting > Editor > Default Editing mode), the decoration doesn’t show up in the table (however the list decoration still works). However in source mode, you are able to see the decoration in both the list and table.

Since this means plugins such as this no longer work[1], it would help a lot to either fix this issue or support the feature request to have checkboxes in tables: Support checkboxes in tables - #62 by Pixionus

This also affect obsidian-markdown-furigana plugin, toDom function is not triggered at all.

This is also causing problems with the progress clocks extension. If I’m understanding correctly, the table view in the editor is itself a decoration and so is getting in the way of decorating the content of cells. I’m not sure codemirror has a good way around this from the plugin developer perspective. It would be really helpful if obsidian itself provided an API for modifying the content of table cells, similar to the API for code blocks.