Need for text formating library

On a website, we have a text field that we need to format. To be able to do this well we employed TinyMCE. This worked out well . Now we can manually create rich text to display our text.
Now the need has come up to have more functionality in this text field. What we would like to be able to do is format content based on a query. This query would include multiple pages that contain the text field. For example, if we wanted to find all words with a specific name in our organization, we would like them bold and purple. Because the field using TinyMCE uses HTML to do this, I thought this would be very simple. I see now that it is more than what I bargained for because of the use of tags. I don’t believe this is a problem. I think the way it is implemented has to be seriously thought about to get what we want.
I think that there must be a library that already does some of what we want. That is to create rich text formatting based on JavaScript to style text to a users desire. This library would have to consider tags that are already in place to not collide with existing formatting. Any ideas are welcome.

Hi @philhagen, so you want to highlight words in the rendered markup, not within the editor? In this case you might use a tree walker to iterate over all text nodes on the page containing the query string (which you can get from the URL search params); then replace the matched nodes with the same text but the query string wrapped in a <mark> like so:

function iterate (walker) {
  // Tree walker iterator for convenience
  return {
    [Symbol.iterator] () {
      return this
    },

    next () {
      const node = walker.nextNode()
      return { value: node, done: node === null }
    }
  }
}

function highlight (text) {
  // Create a walker to iterate over all text
  // nodes that contain the text to highlight
  const walker = document.createTreeWalker(
    document.body,
    NodeFilter.SHOW_TEXT,
    {
      acceptNode (node) {
        return node.textContent.includes(text)
          ? NodeFilter.FILTER_ACCEPT
          : NodeFilter.FILTER_REJECT
      }
    }
  )

  // Get all matched nodes as an array to avoid
  // DOM modifications while walking the tree
  const nodes = [...iterate(walker)]

  // Replace the nodes with the matched text wrapped
  // in a mark element (or whatever you might use)
  for (const node of nodes) {
    const tmp = document.createElement('div')
    tmp.innerHTML = node.textContent.replaceAll(text, `<mark>${text}</mark>`)
    node.replaceWith(...tmp.childNodes)
  }
}

// Highlight text from the URL query parameter
const query = new URLSearchParams(
  window.location.search
).get('query')

if (query) {
  highlight(query)
}

Now if you add e.g. ?query=ipsum to the URL, all words “ipsum” will be highlighted.

1 Like

Hey, with the use of some JavaScript with regex we were able to construct what we need. However, I am excited to learn about this tree walker. I was reading about it on the Mozilla pages and it seems like it has some serious power. Not unlike most stuff I pick up here. Thanks so much for the super help always!

1 Like