From d16ca3305d8457045a1760849058109354f29667 Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Wed, 6 Dec 2023 16:49:55 +0530 Subject: [PATCH] fix: Fixed issues with lists and indents when importing from Evernote --- .../EvernoteConverter/EvernoteConverter.ts | 74 ++++++++++++++----- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/packages/ui-services/src/Import/EvernoteConverter/EvernoteConverter.ts b/packages/ui-services/src/Import/EvernoteConverter/EvernoteConverter.ts index 28fcc1104..092efbfce 100644 --- a/packages/ui-services/src/Import/EvernoteConverter/EvernoteConverter.ts +++ b/packages/ui-services/src/Import/EvernoteConverter/EvernoteConverter.ts @@ -67,29 +67,18 @@ export class EvernoteConverter implements Converter { } const contentXml = this.loadXMLString(contentXmlString, 'html') - const noteElement = contentXml.getElementsByTagName('en-note')[0] + const noteElement = contentXml.getElementsByTagName('en-note')[0] as HTMLElement const unorderedLists = Array.from(noteElement.getElementsByTagName('ul')) + if (canUseSuper) { + this.convertTopLevelDivsToParagraphs(noteElement) this.convertListsToSuperFormatIfApplicable(unorderedLists) + this.convertLeftPaddingToSuperIndent(noteElement) } - // Remove empty lists and orphan list items - Array.from(noteElement.getElementsByTagName('ul')).forEach((ul) => { - if (ul.children.length === 0) { - ul.remove() - } - }) - Array.from(noteElement.getElementsByTagName('ol')).forEach((ol) => { - if (ol.children.length === 0) { - ol.remove() - } - }) - Array.from(noteElement.getElementsByTagName('li')).forEach((li) => { - if (li.children.length === 0 || li.closest('ul, ol') === null) { - li.remove() - } - }) + this.removeEmptyAndOrphanListElements(noteElement) + this.removeUnnecessaryTopLevelBreaks(noteElement) const mediaElements = Array.from(noteElement.getElementsByTagName('en-media')) this.replaceMediaElementsWithResources(mediaElements, resources) @@ -212,6 +201,14 @@ export class EvernoteConverter implements Converter { } as EvernoteResource } + convertTopLevelDivsToParagraphs(noteElement: HTMLElement) { + noteElement.querySelectorAll('div').forEach((div) => { + if (div.parentElement === noteElement) { + changeElementTag(div, 'p') + } + }) + } + convertListsToSuperFormatIfApplicable(unorderedLists: HTMLUListElement[]) { for (const unorderedList of unorderedLists) { if (unorderedList.style.getPropertyValue('--en-todo') !== 'true') { @@ -227,6 +224,42 @@ export class EvernoteConverter implements Converter { } } + convertLeftPaddingToSuperIndent(noteElement: HTMLElement) { + noteElement.querySelectorAll('p').forEach((element) => { + const paddingLeft = element.style.paddingLeft + if (paddingLeft) { + // Lexical uses multiples of 20px for indent while Evernote uses multiples of 40px + const indent = parseInt(paddingLeft) / 2 + element.style.textIndent = `${indent}px` + element.style.paddingLeft = '' + } + }) + } + + removeEmptyAndOrphanListElements(noteElement: HTMLElement) { + Array.from(noteElement.getElementsByTagName('ul, ol')).forEach((list) => { + if (list.children.length === 0) { + list.remove() + } + }) + Array.from(noteElement.getElementsByTagName('li')).forEach((li) => { + const isEmpty = li.textContent === null || li.textContent.trim() === '' + const isOrphan = !li.closest('ul, ol') + if (isEmpty || isOrphan) { + li.remove() + } + }) + } + + removeUnnecessaryTopLevelBreaks(noteElement: HTMLElement) { + Array.from(noteElement.querySelectorAll('* > p > br')).forEach((br) => { + const parent = br.parentElement! + if (parent.children.length === 1) { + parent.remove() + } + }) + } + replaceMediaElementsWithResources(mediaElements: Element[], resources: EvernoteResource[]): number { let replacedElements = 0 for (const mediaElement of mediaElements) { @@ -279,3 +312,10 @@ export class EvernoteConverter implements Converter { return tmp.textContent || tmp.innerText || '' } } + +function changeElementTag(element: HTMLElement, newTag: string) { + const attributes = Array.prototype.slice.call(element.attributes) + element.outerHTML = `<${newTag} ${attributes.map((attr) => attr.name + '="' + attr.value + '"').join(' ')}>${ + element.innerHTML + }` +}