Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving a child object into root before it's original parent inside a json array

I have the following JSON array

{"type":"doc","version":1,"content":[{"type":"paragraph","content":[{"type":"image","attrs":{"src":"cid:avatar_de332fbebe0906c451c8859294d1553d"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~malhajj?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4"}}]},{"type":"text","text":" Mohamad AL HAJJ "},{"type":"text","text":"mentioned","marks":[{"type":"strong"}]},{"type":"text","text":" you on a page"}]},{"type":"paragraph","content":[{"type":"text","text":" ","marks":[{"type":"textColor","attrs":{"color":"#ffffff"}}]},{"type":"text","text":" "},{"type":"image","attrs":{"src":"cid:mention-icon","alt":"mention icon","title":"mention icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" "},{"type":"text","text":"Bassem 1-1 2022-07-28","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]}]},{"type":"paragraph","content":[{"type":"text","text":"···"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]}]}]},{"type":"paragraph","content":[{"type":"text","text":"Release 3.0.7 is ready"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[]}]}]},{"type":"paragraph","content":[{"type":"hardBreak"},{"type":"text","text":" Research about supporting React in windows app"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"paragraph","content":[{"type":"hardBreak"},{"type":"text","text":" "},{"type":"hardBreak"},{"type":"text","text":" Test server changes done by Ahmad"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"paragraph","content":[{"type":"hardBreak"}]},{"type":"paragraph","content":[{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-email-resources_view-page-email-adg-footer-item_icon","alt":"View page Icon","title":"View page Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" "},{"type":"text","text":"View page","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" • "},{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-email-resources_add-comment-to-content-email-adg-footer-item_icon","alt":"Add comment Icon","title":"Add comment Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?showComments=true&showCommentArea=true&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=comment#addcomment"}}]},{"type":"text","text":" "},{"type":"text","text":"Add comment","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?showComments=true&showCommentArea=true&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=comment#addcomment"}}]},{"type":"text","text":" • "},{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-like_view-email-adg-content-item_icon","alt":"Like Icon","title":"Like Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/plugins/likes/like.action?contentId=26543947&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=like&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4c3JmOjMwYmFmMWJhN2NjZGRkZDMwMTdmY2ExMzAwN2UwMGM0IiwicXNoIjoiODEwNWNmMmVlZjcwMGQ1MjVmYjUyODkzMjFmYTMzZGQyNDNmNDNmM2M2MWY1YmU5NzU3YjhjMWVmZmIxZTk1MSIsImlzcyI6ImNvbmZsdWVuY2Vfbm90aWZpY2F0aW9uc0JFOFUtTDNMWi1USzFPLVBGM00iLCJleHAiOjE2NTk3NzM1NTYsImlhdCI6MTY1OTE2ODc1Nn0.R4yPR6SKdUg5mc8fwgdGUa7BeWOdN_2LXDZbAKC5A-o"}}]},{"type":"text","text":" "},{"type":"text","text":"Like","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/plugins/likes/like.action?contentId=26543947&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=like&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4c3JmOjMwYmFmMWJhN2NjZGRkZDMwMTdmY2ExMzAwN2UwMGM0IiwicXNoIjoiODEwNWNmMmVlZjcwMGQ1MjVmYjUyODkzMjFmYTMzZGQyNDNmNDNmM2M2MWY1YmU5NzU3YjhjMWVmZmIxZTk1MSIsImlzcyI6ImNvbmZsdWVuY2Vfbm90aWZpY2F0aW9uc0JFOFUtTDNMWi1USzFPLVBGM00iLCJleHAiOjE2NTk3NzM1NTYsImlhdCI6MTY1OTE2ODc1Nn0.R4yPR6SKdUg5mc8fwgdGUa7BeWOdN_2LXDZbAKC5A-o"}}]},{"type":"text","text":" "},{"type":"text","text":" ","marks":[{"type":"textColor","attrs":{"color":"#ffffff"}}]}]},{"type":"paragraph","content":[{"type":"text","text":"Manage notifications","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/users/editmyemailsettings.action?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=manage"}}]},{"type":"text","text":" "},{"type":"image","attrs":{"src":"cid:footer-desktop-logo","alt":"Confluence logo big","title":"Confluence logo big"}},{"type":"text","text":" This message was sent by Atlassian Confluence 7.18.1"},{"type":"hardBreak"},{"type":"image","attrs":{"src":"cid:footer-mobile-logo","alt":"","title":""}}]}]}

what I am trying to do is creating a recursive function that locate all the elements with type image and try to move it from inside it's parent and push it as a root element but I am not able to push it right after or before it's original parent.

This is what I did

static recur = (arr, AttachmentsArr, madfdoc, htmlbody) => {
    if (arr && arr.length > 0) {
        arr.forEach(item => {
            try {
                switch (item.type) {
                    case "image":
                        this.handleImages(arr, madfdoc, item, htmlbody, AttachmentsArr)
                        break;
                    case "paragraph":
                        this.handleParaphs(item, htmlbody, AttachmentsArr)
                        break;
                    default:
                        break;
                }
                if (item.content) {
                    this.recur(item.content, AttachmentsArr, madfdoc, htmlbody);
                }
            }
            catch (ex) {
                console.log(ex)
            }
        });
    }

};

static handleImages(arr, madfdoc, item, htmlbody, AttachmentsArr) {
    var imghtmlobj = htmlbody.querySelector(`img[src*='${item.attrs.src}']`);
    let src = item.attrs.src.replace("cid:", "");
    // find the image bloburl to change it                        
    let fnd = AttachmentsArr && AttachmentsArr.length ? AttachmentsArr.find(obj => {
        return obj.ContentId ? obj.ContentId === src : undefined;
    }) : undefined
    var imgw = undefined;
    var imgh = undefined;
    if (imghtmlobj) {
        let img = new Image();
        img.onload = function () {
            imgw = this.width;
            imgh = this.height;
            delete item["attrs"]
            delete item["marks"]
            item.type = "mediaSingle";
            item.content = [];
            item.content.push({
                type: "media",
                attrs: {
                    type: "external",
                    url: fnd ? fnd.preview : src,
                    width: imgw,
                    height: imgh
                }
            })
            const indexOfObject = arr.findIndex(object => {
                return object.type === "mediaSingle";
            });
            **arr.splice(indexOfObject, 1); // here is where i am deleting it from inside it's parent and push it to the root inside `madfdoc` 
            madfdoc.content.push(item);**
        }
        img.src = fnd ? fnd.preview : src;
    }
}

The expected Json would be something like this

{
 "type": "doc",
 "version": 1,
  "content": [
  {
      "type": "image",
      "attrs": {
        "src": "cid:avatar_de332fbebe0906c451c8859294d1553d"
      },
      "marks": [
        {
          "type": "link",
          "attrs": {
            "href": "https://wiki.infosysta.com/display/~malhajj?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4"
          }
        }
      ]
    },
{
  "type": "paragraph",
  "content": [
    
    {
      "type": "text",
      "text": " test"
    },
    {
      "type": "text",
      "text": "mentioned",
      "marks": [
        {
          "type": "strong"
        }
      ]
    },
    {
      "type": "text",
      "text": " you on a page"
    }
  ]
}

 ]

}

like image 584
Sora Avatar asked Nov 28 '25 12:11

Sora


1 Answers

If I understood your requirement correctly, this should do it:

class ImagePopper {
  #data;
  #collector = [];

  constructor(data) {
    if (typeof data === "object") {
      this.#data = structuredClone(data);
      this.parseObject(this.#data, []);
      this.#collector.reverse().forEach(({ entry, path }) => {
        this.#data[path[0]].splice(path[1], 0, entry);
      });
    }

    return this.#data || data;
  }

  parseArray = (arr, path) => {
    _.set(
      this.#data,
      path,
      arr.reduce((acc, entry, index) => {
        if (typeof entry === "object") {
          this.parseObject(entry, [...path, index]);
        }
        if (entry?.type === "image") {
          this.#collector.push({ entry, path });
        } else {
          acc.push(entry);
        }

        return acc;
      }, [])
    );
  };

  parseObject = (obj, path) =>
    Object.entries(obj).forEach(
      ([key, value]) =>
        Array.isArray(value) && this.parseArray(value, [...path, key])
    );
}

const json = {"type":"doc","version":1,"content":[{"type":"paragraph","content":[{"type":"image","attrs":{"src":"cid:avatar_de332fbebe0906c451c8859294d1553d"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~malhajj?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4"}}]},{"type":"text","text":" Mohamad AL HAJJ "},{"type":"text","text":"mentioned","marks":[{"type":"strong"}]},{"type":"text","text":" you on a page"}]},{"type":"paragraph","content":[{"type":"text","text":" ","marks":[{"type":"textColor","attrs":{"color":"#ffffff"}}]},{"type":"text","text":" "},{"type":"image","attrs":{"src":"cid:mention-icon","alt":"mention icon","title":"mention icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" "},{"type":"text","text":"Bassem 1-1 2022-07-28","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]}]},{"type":"paragraph","content":[{"type":"text","text":"···"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]}]}]},{"type":"paragraph","content":[{"type":"text","text":"Release 3.0.7 is ready"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[]}]}]},{"type":"paragraph","content":[{"type":"hardBreak"},{"type":"text","text":" Research about supporting React in windows app"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"paragraph","content":[{"type":"hardBreak"},{"type":"text","text":" "},{"type":"hardBreak"},{"type":"text","text":" Test server changes done by Ahmad"}]},{"type":"paragraph","content":[{"type":"text","text":"@"},{"type":"text","text":"Bassem Alameddine","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/~balameddine"}}]},{"type":"text","text":" "}]},{"type":"paragraph","content":[{"type":"hardBreak"}]},{"type":"paragraph","content":[{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-email-resources_view-page-email-adg-footer-item_icon","alt":"View page Icon","title":"View page Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" "},{"type":"text","text":"View page","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=view"}}]},{"type":"text","text":" • "},{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-email-resources_add-comment-to-content-email-adg-footer-item_icon","alt":"Add comment Icon","title":"Add comment Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?showComments=true&showCommentArea=true&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=comment#addcomment"}}]},{"type":"text","text":" "},{"type":"text","text":"Add comment","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/display/MDT/Bassem+1-1+2022-07-28?showComments=true&showCommentArea=true&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=comment#addcomment"}}]},{"type":"text","text":" • "},{"type":"image","attrs":{"src":"cid:com.atlassian.confluence.plugins.confluence-like_view-email-adg-content-item_icon","alt":"Like Icon","title":"Like Icon"},"marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/plugins/likes/like.action?contentId=26543947&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=like&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4c3JmOjMwYmFmMWJhN2NjZGRkZDMwMTdmY2ExMzAwN2UwMGM0IiwicXNoIjoiODEwNWNmMmVlZjcwMGQ1MjVmYjUyODkzMjFmYTMzZGQyNDNmNDNmM2M2MWY1YmU5NzU3YjhjMWVmZmIxZTk1MSIsImlzcyI6ImNvbmZsdWVuY2Vfbm90aWZpY2F0aW9uc0JFOFUtTDNMWi1USzFPLVBGM00iLCJleHAiOjE2NTk3NzM1NTYsImlhdCI6MTY1OTE2ODc1Nn0.R4yPR6SKdUg5mc8fwgdGUa7BeWOdN_2LXDZbAKC5A-o"}}]},{"type":"text","text":" "},{"type":"text","text":"Like","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/plugins/likes/like.action?contentId=26543947&src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=like&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4c3JmOjMwYmFmMWJhN2NjZGRkZDMwMTdmY2ExMzAwN2UwMGM0IiwicXNoIjoiODEwNWNmMmVlZjcwMGQ1MjVmYjUyODkzMjFmYTMzZGQyNDNmNDNmM2M2MWY1YmU5NzU3YjhjMWVmZmIxZTk1MSIsImlzcyI6ImNvbmZsdWVuY2Vfbm90aWZpY2F0aW9uc0JFOFUtTDNMWi1USzFPLVBGM00iLCJleHAiOjE2NTk3NzM1NTYsImlhdCI6MTY1OTE2ODc1Nn0.R4yPR6SKdUg5mc8fwgdGUa7BeWOdN_2LXDZbAKC5A-o"}}]},{"type":"text","text":" "},{"type":"text","text":" ","marks":[{"type":"textColor","attrs":{"color":"#ffffff"}}]}]},{"type":"paragraph","content":[{"type":"text","text":"Manage notifications","marks":[{"type":"link","attrs":{"href":"https://wiki.infosysta.com/users/editmyemailsettings.action?src=mail&src.mail.product=confluence-server&src.mail.timestamp=1659168756680&src.mail.notification=com.atlassian.confluence.plugins.confluence-mentions-plugin%3Amention-created-notification&src.mail.recipient=30baf1ba7ccdddd3017fca13007e00c4&src.mail.action=manage"}}]},{"type":"text","text":" "},{"type":"image","attrs":{"src":"cid:footer-desktop-logo","alt":"Confluence logo big","title":"Confluence logo big"}},{"type":"text","text":" This message was sent by Atlassian Confluence 7.18.1"},{"type":"hardBreak"},{"type":"image","attrs":{"src":"cid:footer-mobile-logo","alt":"","title":""}}]}]}

const result = new ImagePopper(json);

// console.log({ before: json, after: result });

before.innerHTML = JSON.stringify(json, null, 2)
after.innerHTML = JSON.stringify(result, null, 2)
@media (min-width: 800px) {
  .side-by-side {
    display: flex;
  }
  .side-by-side > div {
    width: 50%;
  }
  .scroller {
    overflow: auto;
    height: calc(100vh - 84px);
  }
}
pre {
  padding: .5rem;
  background-color: #f5f5f5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

<div class="side-by-side">
  <div>
    <h2>Before</h2>
    <div class="scroller">
      <pre id="before"></pre>
    </div>
  </div>
  <div>
    <h2>After</h2>
    <div class="scroller">
      <pre id="after"></pre>
    </div>
  </div>
</div>

I'm traversing the data recursively and collect all images, storing their current path. At each level, I'm deleting the images from their parent (by omission). I used lodash's set for this (it allows passing the path as array, which was quite handy here). 1, 2

Then I'm injecting each image at top level before its root parent, in reverse order. This way I don't need to always inflate the splice index by the number of previously processed images.

Decided to wrap it as a class to keep it from interacting with the outer scope, for cleanness, readability and reusability.

That's about it.


Notes:

1 - If you don't want to use lodash's set, consider using this implementation.
2 - in your project, you shouldn't import all of lodash, as I'm doing here. Only import set:

import { set } from 'lodash-es'
// replace `_.set(` in the class with just `set(`
like image 67
a.h.g. Avatar answered Nov 30 '25 03:11

a.h.g.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!