(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.Pell = factory()); }(this, (function () { 'use strict'; const defaultParagraphSeparatorString = 'defaultParagraphSeparator' const formatBlock = 'formatBlock' const addEventListener = (parent, type, listener) => parent.addEventListener(type, listener) const appendChild = (parent, child) => parent.appendChild(child) const createElement = tag => document.createElement(tag) const queryCommandState = command => document.queryCommandState(command) const queryCommandValue = command => document.queryCommandValue(command) const exec = (command, value = null) => document.execCommand(command, false, value) const defaultActions = { bold: { icon: 'B', title: 'Bold', state: () => queryCommandState('bold'), result: () => exec('bold') }, italic: { icon: 'I', title: 'Italic', state: () => queryCommandState('italic'), result: () => exec('italic') }, underline: { icon: 'U', title: 'Underline', state: () => queryCommandState('underline'), result: () => exec('underline') }, strikethrough: { icon: 'S', title: 'Strike-through', state: () => queryCommandState('strikeThrough'), result: () => exec('strikeThrough') }, heading1: { icon: 'H1', title: 'Heading 1', result: () => exec(formatBlock, '

') }, heading2: { icon: 'H2', title: 'Heading 2', result: () => exec(formatBlock, '

') }, paragraph: { icon: '¶', title: 'Paragraph', result: () => exec(formatBlock, '

') }, quote: { icon: '“ ”', title: 'Quote', result: () => exec(formatBlock, '

') }, olist: { icon: '#', title: 'Ordered List', result: () => exec('insertOrderedList') }, ulist: { icon: '•', title: 'Unordered List', result: () => exec('insertUnorderedList') }, code: { icon: '</>', title: 'Code', result: () => exec(formatBlock, '
')
    },
    line: {
      icon: '―',
      title: 'Horizontal Line',
      result: () => exec('insertHorizontalRule')
    },
    link: {
      icon: '🔗',
      title: 'Link',
      result: () => navigator.clipboard.readText().then(url => exec('createLink', url))
    },
    image: {
      icon: '📷',
      title: 'Image',
      result: () => {
        navigator.clipboard.readText().then(url => exec('insertImage', url))
        exec('enableObjectResizing')
      }
    }
  }
  
  const defaultClasses = {
    actionbar: 'pell-actionbar',
    button: 'pell-button',
    content: 'pell-content',
    selected: 'pell-button-selected'
  }
  
  const init = settings => {
    const actions = settings.actions
      ? (
        settings.actions.map(action => {
          if (typeof action === 'string') return defaultActions[action]
          else if (defaultActions[action.name]) return { ...defaultActions[action.name], ...action }
          return action
        })
      )
      : Object.keys(defaultActions).map(action => defaultActions[action])
  
    const classes = { ...defaultClasses, ...settings.classes }
  
    const defaultParagraphSeparator = settings[defaultParagraphSeparatorString] || 'div'
  
    const actionbar = createElement('div')
    actionbar.className = classes.actionbar
    appendChild(settings.element, actionbar)
  
    const content = settings.element.content = createElement('div')
    content.contentEditable = true
    content.className = classes.content
    content.oninput = ({ target: { firstChild } }) => {
      if (firstChild && firstChild.nodeType === 3) exec(formatBlock, `<${defaultParagraphSeparator}>`)
      else if (content.innerHTML === '
') content.innerHTML = '' settings.onChange(content.innerHTML) } content.onkeydown = event => { if (event.key === 'Enter' && queryCommandValue(formatBlock) === 'blockquote') { setTimeout(() => exec(formatBlock, `<${defaultParagraphSeparator}>`), 0) } } appendChild(settings.element, content) actions.forEach(action => { const button = createElement('button') button.className = classes.button button.innerHTML = action.icon button.title = action.title button.setAttribute('type', 'button') button.onclick = () => action.result() && content.focus() if (action.state) { const handler = () => button.classList[action.state() ? 'add' : 'remove'](classes.selected) addEventListener(content, 'keyup', handler) addEventListener(content, 'mouseup', handler) addEventListener(button, 'click', handler) } appendChild(actionbar, button) }) if (settings.styleWithCSS) exec('styleWithCSS') exec(defaultParagraphSeparatorString, defaultParagraphSeparator) return settings.element } return {exec, init} })));