Remove linebreaks / do word wrap + Edit Field During Review (Cloze)

Hello

This post is about my experience with these two add-ons:
1 remove linebreaks / do word wrap
2 Edit Field During Review (Cloze)

I needed an easy, simple way to remove linebreaks while reviewing, and I almost always edit using (Edit Field During Review (Cloze) ), but the problem was that "(remove linebreaks / do word wrap) didn’t work in the reviewer window.

I didn’t find anything online that could help me, so I used ChatGPT to help me create a custom shortcut according to this ( Edit-Field-During-Review-Cloze/FAQ.md at master · BlueGreenMagick/Edit-Field-During-Review-Cloze · GitHub )

This was the final product:
”Paste this at the bottom of both Front & Back templates:

<script>
(function () {
  if (!window.EFDRC || !EFDRC.registerShortcut) return;

  // Turn HTML (with <br>, <p>, etc.) into single-line text
  function flattenHTML(html) {
    const tmp = document.createElement('div');
    tmp.innerHTML = html
      .replace(/<br\s*\/?>/gi, ' ')
      .replace(/<\/(div|p|li|tr|h[1-6])>/gi, ' ')
      .replace(/<li[^>]*>/gi, '')
      .replace(/&nbsp;/gi, ' ');
    let text = (tmp.textContent || '').replace(/\s+/g, ' ');
    return text.replace(/\s+([,.;:!?])/g, '$1').trim();
  }

  function getSelectionRangeIn(root) {
    const sel = document.getSelection();
    if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return null;
    const a = sel.anchorNode, f = sel.focusNode;
    return (root.contains(a) && root.contains(f)) ? sel.getRangeAt(0) : null;
  }

  function replaceSelectionText(range, text) {
    const sel = document.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    // Prefer execCommand for better undo integration
    try {
      if (document.queryCommandSupported && document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, text);
        return;
      }
    } catch (e) {}
    // Fallback DOM replacement
    range.deleteContents();
    const node = document.createTextNode(text);
    range.insertNode(node);
    const r2 = document.createRange();
    r2.setStartAfter(node); r2.setEndAfter(node);
    sel.removeAllRanges(); sel.addRange(r2);
  }

  // Ctrl+Alt+L — SELECTION-ONLY (does nothing if no selection)
  EFDRC.registerShortcut('Ctrl+Alt+L', (ev, elem) => {
    ev.preventDefault(); ev.stopPropagation();
    const range = getSelectionRangeIn(elem);
    if (!range) {
      // tiny visual cue that you need a selection
      try { elem.animate([{outline:'2px solid transparent'},{outline:'2px solid currentColor'}], {duration:120}); } catch(e){}
      return;
    }
    const wrap = document.createElement('div');
    wrap.appendChild(range.cloneContents());
    const flattened = flattenHTML(wrap.innerHTML);
    replaceSelectionText(range, flattened);
  });

  // Ctrl+Alt+Shift+L — WHOLE FIELD (explicit)
  EFDRC.registerShortcut('Ctrl+Alt+Shift+L', (ev, elem) => {
    ev.preventDefault(); ev.stopPropagation();
    const flattenedAll = flattenHTML(elem.innerHTML);
    const sel = document.getSelection();
    const r = document.createRange();
    r.selectNodeContents(elem);
    sel.removeAllRanges(); sel.addRange(r);
    try {
      if (document.queryCommandSupported && document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, flattenedAll);
      } else {
        elem.textContent = flattenedAll; // last-resort fallback
      }
    } catch(e) { elem.textContent = flattenedAll; }
  });
})();
</script>

Now:

  • Ctrl+Alt+L only affects the selected text. If nothing is selected, it does nothing.

  • Ctrl+Alt+Shift+L cleans the entire field when you want that explicitly.”

And it worked!

But then I wanted to use this ( Edit-Field-During-Review-Cloze/FAQ.md at master · BlueGreenMagick/Edit-Field-During-Review-Cloze · GitHub ) to make it more built-in and not edit note type.

And this is the final product:
”

  1. In Anki, go to
    Tools → Add-ons → select “Edit Field During Review (Cloze)” → View Files.

  2. This opens the folder where the add-on’s code lives.

  3. Go into the web folder
    That’s where the add-on loads custom JS/CSS.

  4. Inside web, create a new file named:
    removeLineBreaks.js

  5. Paste your script into it. (the above script-you just need to remove the “ “ from the start and finish )

  6. Now, to make the add-on read the file (script),
    In reviewer.py, find this block (around line ~230):

    js_contents = ["global_card.js", "resize.js"]
    for file_name in js_contents:
        web_content.js.append(url_from_fname(file_name))
    
    

    Change it to:

    js_contents = ["global_card.js", "resize.js", "removeLineBreaks.js"]
    for file_name in js_contents:
        web_content.js.append(url_from_fname(file_name))
    
    

    Save → restart Anki.
    Option 2: More Flexible (Auto-load any JS in web/)

    Replace that block with:

    import os
    for file_name in os.listdir(os.path.join(os.path.dirname(__file__), "web")):
        if file_name.endswith(".js"):
            web_content.js.append(url_from_fname(file_name))
    
    

    That way, any .js You drop into the web/ folder will load automatically — no need to edit reviewer.py again.

    (I used option one)

  7. If you want it to show up in your add-on’s config panel, you can add this to the Advanced Config editor → special_formatting:

    "removeLineBreaks": {
      "command": "removeLineBreaks",
      "enabled": true,
      "shortcut": "Ctrl+Alt+L"
    },
    "removeLineBreaksAll": {
      "command": "removeLineBreaksAll",
      "enabled": true,
      "shortcut": "Ctrl+Alt+Shift+L"
    }
    
    

    These names (removeLineBreaks, removeLineBreaksAll) don’t exist by default, but by keeping them consistent you’ll see them listed and can change the hotkeys later.

And that’s it, it worked for me (I just did it, so I’m not sure if I’m gonna run into any problem with it in the future)

I wanted to share this here to help the community and anyone who may need it.

Disclaimer:
1- I don’t know coding AT ALL, so proceed at your own risk
2- I respect the community and the developers for their efforts. If altering the add-on is wrong in any way, please point that out (I don’t know, but I assumed it’s ok)