3

I am making something similar to this browser extension that substitutes certain phrases with silly equivalents throughout a webpage. I have read replace words in the body text but one problem that every answer shares is that they also break icon fonts. To see what I mean, go to Google Font's Material Icons demo page and edit the text content inside a <span> with an icon. I found this recommendation by the W3C that font icons be identified with the ARIA role="img" attribute. But this depends on proper implementation by the developer which the demo page seems to lack.

I came up with the following kludge which appears to work for the pages I've tested it on. I would think that the probability of there existing an icon font without "icon" in its name is lower than that of developers setting the role attribute correctly, but clearly both approaches are very fragile and I am wondering if there is something more robust.

window.getComputedStyle(node).getPropertyValue('font-family').toUpperCase().includes('ICON')
Daniel Ting
  • 83
  • 1
  • 7
  • 3
    I mean, the _real_ solution is to only replace text where _you know_ it should be replaced, not just blindly for the whole page. Query-select all the elements that you, as developer, know should be found by a query selector match, and then replace their text, and you never run into the problem of accidentally messing with an icon font. – Mike 'Pomax' Kamermans Aug 02 '21 at 04:27
  • @Mike'Pomax'Kamermans I wish I could, but I'm making something along the lines of [this XKCD substitutions extension](https://chrome.google.com/webstore/detail/xkcd-substitutions/jkgogmboalmaijfgfhfepckdgjeopfhk) whose whole point is to be run on the whole page. – Daniel Ting Aug 02 '21 at 16:42
  • Then you want to [put that detail in your post](/help/how-to-ask). – Mike 'Pomax' Kamermans Aug 02 '21 at 16:56

1 Answers1

0

This isn't 100% infallible, but one would sincerely hope that in any occurrence of an icon font, the element will have a class attribute and somewhere in that class attribute the letters i, c, o and n will be found consecutively and in that order.

In which case, for any textNode you can run the following check:

if ((myTextNode.parentNode.hasAttribute('class') === false) || (myTextNode.parentNode.className.includes('icon') === false)) {

  // REPLACE TEXT
}

But as you've already recognised, this does require the implementor actually using the word icon somewhere in the className of the element containing the textNode.

Rounin
  • 27,134
  • 9
  • 83
  • 108