all files / packages/switch-text-type/ SwitchTextTypeCommand.js

0% Statements 0/56
0% Branches 0/38
0% Functions 0/9
0% Lines 0/56
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                                                                                                                                                                                                             
import { isMatch, find, clone } from '../../util'
import { Command } from '../../ui'
 
class SwitchTextTypeCommand extends Command {
  // Available text types on the surface
  getTextTypes(params) {
    let surface = params.surface
    if (surface && surface.isContainerEditor()) {
      return surface.getTextTypes()
    } else {
      return []
    }
  }
 
  getTextType(params) {
    let textTypes = this.getTextTypes(params)
    return find(textTypes, function(t) {
      return t.name === params.textType
    })
  }
 
  // Search which textType matches the current node
  // E.g. {type: 'heading', level: 1} => heading1
  getCurrentTextType(params, node) {
    let textTypes = this.getTextTypes(params)
    let currentTextType
    textTypes.forEach(function(textType) {
      let nodeProps = clone(textType.data)
      delete nodeProps.type
      if (isMatch(node, nodeProps) && node.type === textType.data.type) {
        currentTextType = textType
      }
    })
    return currentTextType
  }
 
  isDisabled({selection, surface}) {
    if (!surface || !surface.isEnabled() || selection.isNull()) {
      return true
    }
    // When command is configured to be disabled for collapsed cursor
    if (selection && this.config.disableCollapsedCursor && selection.isCollapsed()) {
      return true
    }
    return false
  }
 
  getCommandState(params) {
    let doc = params.editorSession.getDocument()
    let sel = params.selection
 
    let node
    let newState = {
      disabled: false,
      textTypes: this.getTextTypes(params)
    }
    // Set disabled when not a property selection
    if (this.isDisabled(params)) {
      newState.disabled = true
    } else if (sel.isContainerSelection()) {
      newState.disabled = true
      newState.currentTextType = {name: 'container-selection'}
    } else if (sel.isPropertySelection()) {
      let path = sel.getPath()
      node = doc.get(path[0])
      // There are cases where path points to an already deleted node,
      // so we need to guard node
      if (node) {
        if (node.isText() && node.isBlock()) {
          newState.currentTextType = this.getCurrentTextType(params, node)
        }
        if (!newState.currentTextType) {
          // We 'abuse' the currentTextType field by providing a property
          // identifier that is translated into a name using an default label set.
          // E.g. this.getLabel('figure.caption') -> Figure Caption
          newState.currentTextType = {name: [node.type, path[1]].join('.')}
          newState.disabled = true
        }
      }
    } else if (sel.isNodeSelection()) {
      node = doc.get(sel.getNodeId())
      newState.currentTextType = {name: node.type}
      newState.disabled = true
    } else if (sel.isCustomSelection()) {
      newState.currentTextType = {name: 'custom'}
      newState.disabled = true
    }
    return newState
  }
 
  /**
    Trigger a switchTextType transaction
   */
  execute(params) {
    let textType = this.getTextType(params)
    let nodeData = textType.data
    let surface = params.surface
    let editorSession = params.editorSession
    if (!surface) {
      console.warn('No focused surface. Stopping command execution.')
      return
    }
    editorSession.transaction(function(tx) {
      return tx.switchTextType(nodeData)
    })
    return nodeData
  }
}
 
export default SwitchTextTypeCommand