Skip to content

quill.html

html
<!DOCTYPE html>
<html>
<head>
  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

  <style>
    #editor-container {
      height: 375px;
    }
  </style>
</head>
<body>

<h1>Editor</h1>
<div id="editor-container">
</div>

<h1>Result</h1>
<div id="editor-presentor"></div>

<script>
  const container = new Quill('#editor-container', {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        ['image', 'code-block']
      ]
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'  // or 'bubble'
  });

  const presentor = new Quill('#editor-presentor', {
    readOnly: true,
    theme: 'bubble'
  });

  container.on('editor-change', () => {
    presentor.setContents(container.getContents())
  })
</script>

</body>
</html>

quill-advance.html

html
<!DOCTYPE html>
<html>
<head>
  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

  <style>
    #editor-container {
      height: 375px;
    }
  </style>
</head>
<body>

<h1>Editor</h1>
<div id="editor-container"></div>

<input type="button" value="Save and Present" id="save">

<h1>Result</h1>
<div id="editor-presentor"></div>

<script>
  const TOOLBAR_OPTIONS = [
    // toggled buttons
    ['image', 'bold', 'italic', 'underline', 'strike'],
    ['blockquote', 'code-block'],

    // custom button values
    [{ 'header': 1 }, { 'header': 2 }],
    [{ 'list': 'ordered'}, { 'list': 'bullet' }],
    // superscript/subscript
    [{ 'script': 'sub'}, { 'script': 'super' }],
    // outdent/indent
    [{ 'indent': '-1'}, { 'indent': '+1' }],
    // text direction
    [{ 'direction': 'rtl' }],

    // custom dropdown
    [{ 'size': ['small', false, 'large', 'huge'] }],
    [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

    // dropdown with defaults from theme
    [{ 'color': [] }, { 'background': [] }],
    [{ 'font': [] }],
    [{ 'align': [] }],

    // remove formatting button
    ['clean']
  ];

  const container = new Quill('#editor-container', {
    modules: {
      toolbar: TOOLBAR_OPTIONS
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'
  });

  const presentor = new Quill('#editor-presentor', {
    readOnly: true,
    theme: 'bubble'
  });

  window.onload = () => {
    document.querySelector('#save').addEventListener('click', () => {
      const delta = JSON.stringify(container.getContents())
      presentor.setContents(JSON.parse(delta))
    })
  }
</script>

</body>
</html>

quill-adaptor

config.js

js
const TOOLBAR_OPTIONS = [
  // toggled buttons
  ['image', 'bold', 'italic', 'underline', 'strike'],
  ['blockquote', 'code-block'],

  // custom button values
  [{ 'header': 1 }, { 'header': 2 }],
  [{ 'list': 'ordered'}, { 'list': 'bullet' }],
  // superscript/subscript
  [{ 'script': 'sub'}, { 'script': 'super' }],
  // outdent/indent
  [{ 'indent': '-1'}, { 'indent': '+1' }],
  // text direction
  [{ 'direction': 'rtl' }],

  // custom dropdown
  [{ 'size': ['small', false, 'large', 'huge'] }],
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

  // dropdown with defaults from theme
  [{ 'color': [] }, { 'background': [] }],
  [{ 'font': [] }],
  [{ 'align': [] }],

  // remove formatting button
  ['clean']
];

editor-adaptor.js

js
// mountEditor(element: HTMLElement, placeholder: string): QuillContainer
const mountEditor = (element, placeholder = '') => {
  return new Quill(element, {
    modules: {
      toolbar: TOOLBAR_OPTIONS
    },
    placeholder,
    theme: 'snow'
  })
}

// mountViewer(element: HTMLElement): QuillContainer
const mountViewer = (element) => {
  return new Quill(element, {
    readOnly: true,
    theme: 'bubble'
  })
}

// extractContents(editorContainer: QuillContainer): string
const extractContents = (container) => JSON.stringify(container.getContents())

// insertContents(editorContainer: QuillContainer, contents: string): void
const insertContents = (container, contents) => {
  container.setContents(JSON.parse(contents))
}

quill-adaptor.html

html
<!DOCTYPE html>
<html>
<head>
  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  <style>
    #editor-container {
      height: 375px;
    }
  </style>
</head>
<body>

<h1>Editor</h1>
<div id="editor-container"></div>

<input type="button" value="Save and Present" id="save">

<h1>Result</h1>
<div id="editor-presentor"></div>

<input type="button" value="ReEdit" id="re-edit">

<h1>Re-Editor</h1>
<div id="re-editor-container"></div>

<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

<script src="config.js"></script>
<script src="editor-adaptor.js"></script>
<script>
  const getElem = (id) => document.querySelector(id)

  window.onload = () => {
    const container = mountEditor(getElem('#editor-container'))
    const presentor = mountViewer(getElem('#editor-presentor'))
    const reEditContainer = mountEditor(getElem('#re-editor-container'))

    getElem('#save').addEventListener('click', () => {
      const delta = extractContents(container)
      insertContents(presentor, delta)
    })

    getElem('#re-edit').addEventListener('click', () => {
      const delta = extractContents(presentor)
      insertContents(reEditContainer, delta)
    })
  }
</script>

</body>
</html>