editor-js / list

Advanced List tool for the Editor.js.
MIT License
48 stars 47 forks source link

fix: Pasting list with inline formats #65

Open bettysteger opened 11 months ago

bettysteger commented 11 months ago

https://github.com/editor-js/nested-list/issues/26

neSpecc commented 11 months ago

Please, describe your change with more details

bettysteger commented 11 months ago

@neSpecc

When pasting the following tags:

<ul>
  <li><b>Bold text</b> non bold</li>
 </ul>

the b-tag is removed in the data:

 { 
   style: 'unordered',
   items: [{ 
     content: 'Bold text non bold', 
     items: [] 
   }]
}

using innerHTML (and removing a nested ul/ol) instead of textContent for content solves this problem!

skovy commented 7 months ago

This also happens with inline links, and confirmed this also fixes those!

skovy commented 7 months ago

I also ran into this same exact issue, but also the issue faced in https://github.com/editor-js/nested-list/pull/63. Here is a monkey patch of this PR and that PR, plus with some additional bug fixes on top.

Would be great to incorporate this in this PR or another to see these fixes made upstream.

Thanks and hopefully this is helpful to others!

import NestedList from "@editorjs/nested-list";

// This is a patched version of the NestedList plugin from EditorJS.
export default class PatchedNestedList extends NestedList {
  pasteHandler(element) {
    const { tagName: tag } = element;
    let style;
    let tagToSearch;

    // Find list style we're working with and tag to search based on the pasted input.
    switch (tag) {
      case "OL":
        style = "ordered";
        tagToSearch = "ol";
        break;
      case "UL":
      case "LI":
        style = "unordered";
        tagToSearch = "ul";
    }

    const getPastedItems = (parent) => {
      let items = [];

      // Get all of the list items (`li`), or nested lists (`ul`/`ol`) that are siblings.
      // Technically, nested lists should be within the list items, but
      // it seems both variants exist in the wild when copy/pasting.
      const children = Array.from(
        parent.querySelectorAll(`:scope > li, :scope > ${tagToSearch}`)
      );

      children.map((childItem) => {
        if (childItem.tagName === tag) {
          // Recursively handle a nested list (`ul`/`ol`). When a sibling nested list is found,
          // it is appended to the previous list item to nest properly.
          const previousListItem = items[items.length - 1];
          previousListItem.items = getPastedItems(childItem);
        } else {
          // Handle a list item (`li`)
          items = items.concat(getListItem(childItem));
        }
      });

      return items;
    };

    const getListItem = (list) => {
      // Also support properly formatted nested lists (`ul`/`ol`) within a list item (`li`).
      const nestedListGroups = Array.from(
        list.querySelectorAll(`:scope > ${tagToSearch}`)
      );

      // Include all of the `innerHTML` of the list instead of only `textContent`.
      // Then allow Editor.js to sanitize the content as needed.
      let content = list?.innerHTML || "";

      // However, we don't want any of the nested list groups to be included,
      // so strip out all of their HTML from the content.
      nestedListGroups.forEach((nestedListGroup) => {
        content = content.replace(nestedListGroup.outerHTML, "");
      });

      return {
        content,
        items: getNestedListGroups(nestedListGroups),
      };
    };

    const getNestedListGroups = (groups) => {
      let lists = [];

      groups.map((nestedListGroup) => {
        lists = lists.concat(getPastedItems(nestedListGroup));
      });

      return lists;
    };

    return {
      style,
      items: getPastedItems(element),
    };
  }
}
bettysteger commented 7 months ago

@skovy i think you linked the wrong PR https://github.com/editor-js/nested-list/pull/25 ?

What are your changes and what are you trying to solve?

skovy commented 7 months ago

d'oh, yes 🤦 i meant https://github.com/editor-js/nested-list/pull/63 (updated)

CodyPChristian commented 7 months ago

@skovy Any updates on this being merged?