input[type="date"]の入力補完

FireFox とか Chorome の日付入力のUIが便利になったのだが、俺には余計だ。その機能を止めたいのだが止められない。
仕方無くShiftキーとの併用で入力補完を行うことにした。
本日の日付けの入力とカーソルキーでの日付けの変化を可能にしてみた。
う〜〜〜ん、邪道なのだけれど。

[Shift]+[Ins]ってペースト機能があったのね。忘れてた!

<!DOCTYPE hrml>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>input[type="date"]要素の入力補完スクリプト</title>


<body>
<h1>input[type="date"]要素の入力補完</h1>
<form>
  <ol>
    <li>
      日付けを入力します。
      <input type="date" name="hoge" value="">
    <li>
      日付けを入力します。
      <input type="date" name="fuga" value=""><em>(入力できる範囲は今月日だけ)</em>
  </ol>
</form>

<h2>使用方法</h2>
<table>
  <tr>
    <th>[Shift] + [Ins]
    <td>今日の日付けの入力
    <td>未入力状態の時だけ入力できる。ダブルクリックでも可能
  
  <tr>
    <th>[Shift] + []
    <td>日付けを未来方向へ
    <td>max値が指定されていればその値が適用される
  
  <tr>
    <th>[Shift] + []
    <td>日付けを過去方向へ
    <td>min値が指定されていればその値が適用される
</table>

<script>
/* fuga の最小値と最大値を設定する */
let
  fuga = document.querySelector ('input[name="fuga"]'),
  now  = new Date,
  y = now.getFullYear (),
  m = now.getMonth () + 1,
  d = now.getDate ();
  D = new Date (y, m, 0);
  
fuga.min = [y,m,1].join ('-');
fuga.max = [D.getFullYear(), D.getMonth()+1, D.getDate()].join('-');
fuga.value = [y,m,d].join ('-');




{
  const
    ymd_reg = /^\s*([0-9]{1,4})(?:[-/ ]?0?([1-9]|1[0-2]))(?:[-/ ]?0?([1-9]|[1-2][0-9]|3[0-1]))\s*$/,
    
    padding =
      function (num, n = 2) {
        return ('00' + num).slice (-n);
      },
    
    strToDate =
      function (str) {
        let ymd = ymd_reg.exec (str);
        if (ymd) {
          let [, y, m, d] = ymd;
          return new Date (parseInt (y, 10), parseInt (m, 10) - 1, parseInt (d, 10));
        }
        return null;
      },
    
    getOffsetDate =
      function (e, direction = 1) {
        let
          { min, max, step, value } = e,
          dt = strToDate (value), cmp;

        if (dt) {
          step = parseInt (step) || 1;
          dt.setDate (dt.getDate () + direction * step);

          if ('' !== min) {
            if (cmp = strToDate (min)) {
              if (+dt < +cmp) {
                dt = cmp;
              }
            }
          }
          
          if ('' !== max) {
            if (cmp = strToDate (max)) { 
              if (+cmp < +dt) {
                dt = cmp;
              }
            }
          }
          
          return dt;
        }
      },

    dateToString =
      function (dt = new Date) {
        return [
          dt.getFullYear (),
          padding (dt.getMonth () + 1),
          padding (dt.getDate ())
        ].join ('-');
      },
    
  //________________________________________

    dblClickHandler =
      function ({target}) {
        if ('date' === target.getAttribute ('type'))
          target.value = dateToString ();
      },
      
    keyDownHandler =
      function (event) {
        let e = event.target;

        if (e.disabled || e.readOnly || 'date' !== e.getAttribute ('type'))
          return;

        if (event.getModifierState ('Shift')) {
          let dt = null;

          switch (event.keyCode || event.which) {
          case 38 : dt = getOffsetDate (e); break;     // up
          case 40 : dt = getOffsetDate (e, -1); break; // down
          case 45 :
            if ('' !== e.value) return;
            dt = new Date;
            break; // ins
          default : return;
          }

          e.value = dateToString (dt);
          event.preventDefault ();
        }
      };
  
  //________________________________________
  
  document.addEventListener ('dblclick', dblClickHandler, false);
  document.addEventListener ('keydown', keyDownHandler, true);

}
    

</script>