[ ] check what happens if {{[[table]]}} block ALSO has a {{SmartBlock}} button
Notes
I started looking into this, but didn't get a chance to finish. Here were my findings:
If a SmartBlock button is part of roam {{[[table]]}} the observer doesn't catch it because it's parent blockUid is actually the table block, so the match check fails as there is no SmartBlock button in it's textContent.
It doesn't look like there the original uid that holds the SmartBlock button (VeSLtlz0N) is accessible in the DOM
If !match we could check text (which is parentUid text) for {{[[table]]}}
If true
calculate row/column position based on DOM (el is the button element in the roam
)
get the tree of parentUid
get original uid based on row/column
something like:
// check if parent is roam {{[[table]]}}
const getMatchFromRoamTable = () => {
const parentText = getTextByBlockUid(parentUid);
const roamTablePattern = /\{\{\[\[table\]\]\}\}/;
const isInRoamTable = roamTablePattern.exec(parentText);
if (!isInRoamTable) return null;
const tableEl = el.closest("table");
if (!tableEl) return null;
// Get the row and column of the button
const rows = Array.from(tableEl.querySelectorAll("tr")).filter(
(row) => row.innerHTML.trim() !== "" // first row is blank?
);
let position = { row: 0, column: 0 };
rows.map((row, rowIndex) => {
const cells = Array.from(row.querySelectorAll("td"));
cells.map((cell, colIndex) => {
if (cell.contains(el)) {
position = { row: rowIndex + 1, column: colIndex + 1 };
}
});
});
if (!position.row || !position.column) return null;
// Get UID from tree based position
const tree = getBasicTreeByParentUid(parentUid);
const uid = getUidFromTablePosition() // need to create this
const tableButtonText = getTextByBlockUid(uid);
return regex.exec(tableButtonText);
};
if (!match) match = getMatchFromRoamTable();
but the getUidFromTablePosition() gets a little tricky as there are multiple ways to construct a table
It looks like
node with no children = 1 row
node with 1 child = 1 row
node with 1+n children = 1+n rows
I didn't get a chance to finish writing that, but unless I missed something, it seems quite possible.
Oh, also, should consider if the {{[[table]]}} block ALSO has a {{SmartBlock}} button ... check to make sure it gets the data-roamjs-smartblock-button first.
reported by Mark L via slack.
tl;dr What's left
getUidFromTablePosition()
{{[[table]]}}
block ALSO has a{{SmartBlock}}
buttonNotes
I started looking into this, but didn't get a chance to finish. Here were my findings:
If a SmartBlock button is part of roam
{{[[table]]}}
the observer doesn't catch it because it's parentblockUid
is actually the table block, so thematch
check fails as there is no SmartBlock button in it'stextContent
.It doesn't look like there the original
uid
that holds the SmartBlock button (VeSLtlz0N
) is accessible in the DOMPossible solution: https://github.com/RoamJS/smartblocks/blob/170690d1ba36d416d17545ca39483dd18a0dfd77/src/index.ts#L543-L561
If
!match
we could checktext
(which isparentUid
text) for{{[[table]]}}
If true
el
is the button element in the roamparentUid
uid
based on row/columnsomething like:
but the
getUidFromTablePosition()
gets a little tricky as there are multiple ways to construct a tableIt looks like
I didn't get a chance to finish writing that, but unless I missed something, it seems quite possible.
Oh, also, should consider if the
{{[[table]]}}
block ALSO has a{{SmartBlock}}
button ... check to make sure it gets thedata-roamjs-smartblock-button
first.