Hatena::ブログ(Diary)

babu_babu_babooのごみ箱

2018-05-17

TEXTAREA 要素内で、オートインデントを行う(過去の焼き直し)

| 08:37

<!DOCTYPE html>
<html lang="ja">
<meta charset="UTF-8">

<body>
<h1>textarea 要素の オートインデントを行う</h1>
<p><input id="A"></p>
<textarea id="B" cols="60" rows="10"></textarea>

<script>

//_____autoIndent
{
  const

    NOT_LF = /\r\n|\r/g,
    REG_INDENT_SPACE = /^([\s\u3000]+)/,

    
    //インデント分の空白を挿入
    addEnter = function (e) {
      let start;
      if (! isNaN (start = e.selectionStart)) {
        let
          value = e.value,
          region_byCaret = value.slice (0, start),
          CRLFs = region_byCaret.match (NOT_LF);
    
        if (CRLFs) {
          region_byCaret = region_byCaret.replace (NOT_LF, '\n');
          start -= CRLFs.length;
        }
        
        let
          region = region_byCaret,
          lines = region.split ('\n'),
          n = lines.length - 1,
          spc;
        
        if (0 === lines[n].length) {
          if ((spc = lines[n-1].match (REG_INDENT_SPACE))) {
            let s = spc[1];
            e.value = region_byCaret + s + value.slice (start);
            e.selectionStart = e.selectionEnd = start + s.length;
          }
        }
      }
    };


  //____________________________________
  
  class AutoIndent {
    constructor (target = { }) {
      if (target.nodeName !== 'TEXTAREA')
        throw new Error ('TEXTAREA ではありません');

      this.target = target;
      this.disabled = false;
      
      target.addEventListener ('keyup', this, false);
    }
    
    
    handleEvent ({key}) {
      if (! this.disabled)
        if ('Enter' === key)
          addEnter (this.target);
    }
    
    
    addEnter () {
      if (! this.disabled)
        addEnter (this.target);
    }
  }
  
  this.AutoIndent = AutoIndent;
}

new AutoIndent (document.getElementById('B'));

</script>