jkomoros / card-web

The web app behind thecompendium.cards
Apache License 2.0
56 stars 8 forks source link

Terms in the body of a card from a concept should show the concept card when they hover #434

Open jkomoros opened 3 years ago

jkomoros commented 3 years ago

Cards that reference a concept by one of its alt titles are sometimes unclear which one they're referring to. There should be some way to see when looking at a card which concepts map to which words somehow.

One way is to make it so card-links in the info panel show the title alternate that matches the card.

Another way is to make the word cloud items that match the concepts show which card they come from.

Another way is to make the text of the body that matches be highlighted in a subtle color and when you hover over it shows a card preview. We'd have a highlightConceptsInHTML method that would be memoized, and take the HTML, and a map of concept normalized string to card ID, and a map of concept cards this card actively references. And then it would do something like originalNgramsForNormalizedString through the whole inner text of the card for the references it knows are in there, and then when it finds one, it would walk through the parsed HTML and replace the strings with a span (using innerHTML). Later, the spans would be simple little custom elements that, when hovered, emit a card-hovered event.

It would need to make sure that the display HTML was never read back and saved. The toContentEditable would have none of this processing done on it, and it would never be visible in HTML to an editor.

Originally tracked in #399 as a bonus item.

jkomoros commented 3 years ago
jkomoros commented 3 years ago

So you have a map of cardIDs that this card explicitly references as concepts. And you can reverse concept map, so you have a list of fully normalized ngrams for each conceptCardID. Then for your text field, you can use extractOriginalNgram to extract the text... minus punctuation. (Dang, that's really really hard to do, and breaks the rest of this). Then once you know the text string, you walk the DOM for the body, looking for innerText that contains that, and then setting innerHTML with the concept text wrapped in the special <span>. BUT, the string might not be in any single run within any single containing element.

So there are two challenges: one to figure out what the literal expanded, non-normalized string to select is, and two to find that string even if it crosses element boundaries. (The second would be OK to just skip)

We could construct a regular expression for a given expandedOriginalNgram that is resilient to extra punctuation or other normalization and then use that to replace those strings with the exact matched string, just wrapped in a <span card='ID>` or whatever.