svg_highlighter.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import * as DomUtil from '../common/dom_util.js';
  2. import { AbstractHighlighter } from './abstract_highlighter.js';
  3. export class SvgHighlighter extends AbstractHighlighter {
  4. constructor() {
  5. super();
  6. this.mactionName = 'mjx-svg-maction';
  7. }
  8. highlightNode(node) {
  9. let info;
  10. if (this.isHighlighted(node)) {
  11. info = {
  12. node: node.previousSibling || node,
  13. background: node.style.backgroundColor,
  14. foreground: node.style.color
  15. };
  16. return info;
  17. }
  18. if (node.tagName === 'svg') {
  19. const info = {
  20. node: node,
  21. background: node.style.backgroundColor,
  22. foreground: node.style.color
  23. };
  24. node.style.backgroundColor = this.colorString().background;
  25. node.style.color = this.colorString().foreground;
  26. return info;
  27. }
  28. const rect = DomUtil.createElementNS('http://www.w3.org/2000/svg', 'rect');
  29. const padding = 40;
  30. let bbox;
  31. if (node.nodeName === 'use') {
  32. const g = DomUtil.createElementNS('http://www.w3.org/2000/svg', 'g');
  33. node.parentNode.insertBefore(g, node);
  34. g.appendChild(node);
  35. bbox = g.getBBox();
  36. g.parentNode.replaceChild(node, g);
  37. }
  38. else {
  39. bbox = node.getBBox();
  40. }
  41. rect.setAttribute('x', (bbox.x - padding).toString());
  42. rect.setAttribute('y', (bbox.y - padding).toString());
  43. rect.setAttribute('width', (bbox.width + 2 * padding).toString());
  44. rect.setAttribute('height', (bbox.height + 2 * padding).toString());
  45. const transform = node.getAttribute('transform');
  46. if (transform) {
  47. rect.setAttribute('transform', transform);
  48. }
  49. rect.setAttribute('fill', this.colorString().background);
  50. rect.setAttribute(this.ATTR, 'true');
  51. node.parentNode.insertBefore(rect, node);
  52. info = { node: rect, foreground: node.getAttribute('fill') };
  53. node.setAttribute('fill', this.colorString().foreground);
  54. return info;
  55. }
  56. setHighlighted(node) {
  57. if (node.tagName === 'svg') {
  58. super.setHighlighted(node);
  59. }
  60. }
  61. unhighlightNode(info) {
  62. if ('background' in info) {
  63. info.node.style.backgroundColor = info.background;
  64. info.node.style.color = info.foreground;
  65. return;
  66. }
  67. info.foreground
  68. ? info.node.nextSibling.setAttribute('fill', info.foreground)
  69. : info.node.nextSibling.removeAttribute('fill');
  70. info.node.parentNode.removeChild(info.node);
  71. }
  72. isMactionNode(node) {
  73. let className = node.className || node.getAttribute('class');
  74. if (!className) {
  75. return false;
  76. }
  77. className =
  78. className.baseVal !== undefined
  79. ? className.baseVal
  80. : className;
  81. return className ? !!className.match(new RegExp(this.mactionName)) : false;
  82. }
  83. }