2

I am building an app that allows users to use image maps (which they create on a different website). Currently, after the user makes the image map on the other site, they need to come back to my site and one by one enter the different areas manually (shape and coords).

I would like to automate the process, so the user just copy pastes the whole code snippet and I will automatically extract the individuals areas.

For example, I want a user to enter for example this code:

<img src="Screenshot (473).png" alt="" usemap="#map" />
<map name="map">
    <area shape="rect" coords="866, 213, 1024, 357" />
    <area shape="rect" coords="965, 451, 1048, 512" />
    <area shape="circle" coords="1167, 200, 77" />
    <area shape="poly" coords="1357, 298, 1279, 376, 1394, 501, 1651, 386, 1511, 286" />
    <area shape="poly" coords="802, 250, 856, 499, 551, 536, 610, 262, 758, 181" />
</map>

And then when they submit, I will automatically extract the following:

[
  {
    shape: "rect",
    coords: [866, 213, 1024, 357]
  },
  {
    shape: "rect",
    coords: [965, 451, 1048, 512]
  },
  {
    shape: "circle",
    coords: [1167, 200, 77]
  },
  {
    shape: "poly",
    coords: [1357, 298, 1279, 376, 1394, 501, 1651, 386, 1511, 286]
  },
  {
    shape: "poly",
    coords: [802, 250, 856, 499, 551, 536, 610, 262, 758, 181]
  }
]

I'm trying to figure out the best way to approach this, but haven't figured out anything elegant yet. Just a deeply nested trim operations. What would be the "cleanest" way to approach this?

FZs
  • 16,581
  • 13
  • 41
  • 50
Tsabary
  • 3,119
  • 2
  • 24
  • 66
  • Depends on the complexity, you can create a parser or you can use a pre-built xml-to-json parser – Christian Vincenzo Traina May 21 '20 at 07:43
  • In the second case, you'd need some intervention on the generated JS object, but it won't be hard. A map/reduce approach is everything you need – Christian Vincenzo Traina May 21 '20 at 07:43
  • Not sure if I understand how to use a map in this case. So far (junior dev here) I've been using maps to iterate over arrays. In my case here, I want to finish with an array, but I start with a raw string. How would a map come to action here? – Tsabary May 21 '20 at 07:46
  • One way is to just have the browser parse the HTML, then use basic DOM methods to grab the data: https://jsfiddle.net/khrismuc/nwockb7h/ –  May 21 '20 at 07:48
  • Does this answer your question? [XML parsing of a variable string in JavaScript](https://stackoverflow.com/questions/649614/xml-parsing-of-a-variable-string-in-javascript) –  May 21 '20 at 07:51

1 Answers1

6

This is a fun one! A not-so-often used API. You're looking for DOMParser.

This would need a bit of "defend against bad input" defense and cleanup, but with proper input as you've given, we can do this:

const sampleString = `
  <img src="Screenshot (473).png" alt="" usemap="#map" />
  <map name="map">
      <area shape="rect" coords="866, 213, 1024, 357" />
      <area shape="rect" coords="965, 451, 1048, 512" />
      <area shape="circle" coords="1167, 200, 77" />
      <area shape="poly" coords="1357, 298, 1279, 376, 1394, 501, 1651, 386, 1511, 286" />
      <area shape="poly" coords="802, 250, 856, 499, 551, 536, 610, 262, 758, 181" />
  </map>
`;

const domparser = new DOMParser();
const doc = domparser.parseFromString(sampleString, 'text/html');

const output = [...doc.querySelectorAll('area')].map(a => ({shape: a.shape, coords: a.coords.split(/,\s*/)}));

console.log(output);
Chase
  • 3,028
  • 14
  • 15