import Revisions from './collection'
import { htmlToDraft } from '../../editor/utils';
import { convertToRaw } from 'draft-js';
import { markdownToHtmlNoLaTeX, dataToMarkdown } from '../../../server/editor/make_editable_callbacks'
import { highlightFromHTML } from '../../editor/ellipsize';
import { addFieldsDict } from '../../modules/utils/schemaUtils'
import { JSDOM } from 'jsdom'
import htmlToText from 'html-to-text'

const PLAINTEXT_DESCRIPTION_LENGTH = 2000

function domBuilder(html) {
  const jsdom = new JSDOM(html)
  const document = jsdom.window.document;
  const bodyEl = document.body; // implicitly created
  return bodyEl
}


export function htmlToDraftServer(...args) {
  // We have to add this type definition to the global object to allow draft-convert to properly work on the server
  global.HTMLElement = new JSDOM().window.HTMLElement
  // And alas, it looks like we have to add this global. This seems quite bad, and I am not fully sure what to do about it.
  global.document = new JSDOM().window.document
  const result = htmlToDraft(...args) 
  // We do however at least remove it right afterwards
  delete global.document
  delete global.HTMLElement
  return result
}

export function dataToDraftJS(data, type) {
  if (data===undefined || data===null) return null;
  
  switch (type) {
    case "draftJS": {
      return data
    }
    case "html": {
      const draftJSContentState = htmlToDraftServer(data, {}, domBuilder)
      return convertToRaw(draftJSContentState)  // On the server have to parse in a JS-DOM implementation to make htmlToDraft work
    }
    case "markdown": {
      const html = markdownToHtmlNoLaTeX(data)
      const draftJSContentState = htmlToDraftServer(html, {}, domBuilder) // On the server have to parse in a JS-DOM implementation to make htmlToDraft work
      return convertToRaw(draftJSContentState) 
    }
    default: {
      throw new Error(`Unrecognized type: ${type}`);
    }
  }
}

addFieldsDict(Revisions, {
  markdown: {
    type: String,
    resolveAs: {
      type: 'String',
      resolver: ({originalContents: {data, type}}) => dataToMarkdown(data, type)
    }
  },
  draftJS: {
    type: Object,
    resolveAs: {
      type: 'JSON',
      resolver: ({originalContents: {data, type}}) => dataToDraftJS(data, type)
    }
  },
  htmlHighlight: {
    type: String,
    resolveAs: {
      type: 'String',
      resolver: ({html}) => highlightFromHTML(html)
    }
  },
  plaintextDescription: {
    type: String,
    resolveAs: {
      type: 'String',
      resolver: ({html}) => htmlToText
        .fromString(html)
        .substring(0, PLAINTEXT_DESCRIPTION_LENGTH)
    }
  }
})
@@ -389,39 +389,179 @@
 ort 
-htmlToText from 'html-to-text'%0A
+%7B Utils %7D from 'meteor/vulcan:core';%0Aimport htmlToText from 'html-to-text'%0Aimport %7B truncate %7D from '../../editor/ellipsize'%0A%0Aconst PLAINTEXT_HTML_TRUNCATION_LENGTH = 4000
 %0Acon
@@ -2682,16 +2682,128 @@
 tml%7D) =%3E
+ %7B%0A        const truncatedHtml = truncate(Utils.sanitize(html), PLAINTEXT_HTML_TRUNCATION_LENGTH)%0A        return
  htmlToT
@@ -2806,16 +2806,18 @@
 lToText%0A
+  
         
@@ -2828,22 +2828,33 @@
 mString(
-h
+truncatedH
 tml)%0A
+  
         
@@ -2893,24 +2893,33 @@
 ION_LENGTH)%0A
+      %7D %0A
     %7D%0A  %7D%0A%7D)

Truncate and sanitize before plaintext translation