All files / src/ui/searchers ByBlock.js

14.29% Statements 4/28
0% Branches 0/15
0% Functions 0/9
15.38% Lines 4/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 751x 1x 1x                   1x                                                                                                                            
import React, {Component} from 'react';
import PropTypes from 'prop-types/prop-types';
import {skipWhile, getNodeContainingBiased} from '../../utils';
 
function getAllNodeTypes(ast) {
  const allNodeTypes = new Set();
  for (const node of ast.nodeIdMap.values()) {
    allNodeTypes.add(node.type);
  }
  return allNodeTypes;
}
 
export default {
  label: 'Search by block',
  setting: {blockType: ''},
  component: class extends Component {
    static propTypes = {
      cmbState: PropTypes.object,
      setting: PropTypes.object.isRequired,
      onChange: PropTypes.func.isRequired,
    }
 
    displayName = 'Search by Block'
 
    handleChange = e => {
      this.props.onChange({
        ...this.props.setting,
        [e.target.name]: e.target.type === 'checkbox' ? e.target.checked : e.target.value,
      });
    }
 
    render() {
      const {setting, cmbState: {ast}} = this.props;
 
      const allNodeTypes = getAllNodeTypes(ast);
      const types = Array.from(allNodeTypes).sort();
      return (
        <select name="blockType" value={setting.blockType} onChange={this.handleChange}>
          {types.map(t => <option key={t} value={t}>{t}</option>)}
        </select>
      );
    }
  },
  search: (cur, settings, cm, {ast, collapsedList}, forward) => {
    let startingNode = getNodeContainingBiased(cur, ast);
    if (!startingNode) {
      startingNode = forward ?
        ast.getNodeAfterCur(cur) :
        ast.getNodeBeforeCur(cur);
    }
 
    // handle the cursor before first / after last block
    if (!startingNode) {
      // TODO(Oak)
    }
 
    const collapsedNodeList = collapsedList.map(ast.getNodeById);
    const next = node => forward ? node.next : node.prev;
 
    // NOTE(Oak): if this is too slow, consider adding a
    // next/prevSibling attribute to short circuit navigation
    const result = skipWhile(
      node => {
        return node && (collapsedNodeList.some(
          collapsed => ast.isAncestor(collapsed.id, node.id)
        ) || node.type !== settings.blockType);
      },
      next(startingNode),
      next
    );
    if (result) return {node: result, cursor: result.from};
    return null;
  }
};