JavaScriptでファイルのインポート、エクスポートを実装する

Chrome/Firefoxの拡張機能で、設定をインポート、エクスポートする機能が欲しいといった要望があったので、まずはどんな感じにインポート、エクスポートすれば良いんだっけ、、ってことでJavaScriptで簡単なサンプル書いてみました。

コード

下記のようなHTMLを用意します。インポート、エクスポート用のボタンがあって、インポートしたものを表示するエリアを用意しておきます。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <button type="button" id="inputFile">Import</button>
    <pre><code id="contents"></code></pre>
    <button type="button" id="outputFile">Export</button>
    <script src="file.js"></script>
  </body>
</html>

JavaScriptは下記のような感じで。

let currentContents = '';
const displayElement = document.getElementById('contents');

document.getElementById('inputFile').addEventListener('click', (e) => {
  const fileInput = document.createElement('input');
  fileInput.type = 'file';
  fileInput.setAttribute('hidden', true);

  fileInput.addEventListener('change', (e) => {
    const file = e.target.files[0];
  
    const reader = new FileReader();
    reader.onload = (e) => {
      const fileContents = e.target.result;
      displayElement.textContent = fileContents;
      currentContents = fileContents;
    }
    reader.readAsText(file);
  }, false);
  
  document.body.appendChild(fileInput);
  fileInput.click();
  fileInput.remove();
}, false);


document.getElementById('outputFile').addEventListener('click', (e) => {
  const downloadLink = document.createElement('a');
  downloadLink.download = 'export.txt';
  downloadLink.href = URL.createObjectURL(new Blob([currentContents], { 'type' : 'text/plain' }));
  downloadLink.setAttribute('hidden', true);

  document.body.appendChild(downloadLink);
  downloadLink.click();
  downloadLink.remove();
}, false);

インポートのボタンが押下された際に、ファイル選択用のinput要素を生成してclickを呼び出してファイル選択ダイアログを表示させます。
ファイルが選択されたら、それをFileReaderを使って読みだして表示します。

エクスポートのボタンが押下されたら、BlobからURLを生成し、それをリンクとしてa要素を生成してclickといった流れでダウンロードさせています。

Firefoxだとbody配下に入れないとclickが効かないので、body.appendChildしてremoveといったことをやっています。

動作

とりあえずFirefox、Chrome、Edgeの最新バージョンで動作することを確認済みです。

f:id:onozaty:20191014010546g:plain

Redmine: View customize plugin の v2.5.0 をリリースしました

View customize plugin の v2.5.0 をリリースしました。

今回のリリースでの変更点は下記の2つとなります。

ViewCustomize.context にユーザの最終ログイン日時を追加

Pull requestをいただき、ViewCustomize.context.user.lastLoginOnで最終ログイン日時を参照できるようにしました。
利用するシチュエーションはあまり無いのかもしれませんが、下記の問題を対応するために使いたいとのことだったので、今回対応することとしました。

ISO 8601形式の文字列として取得できます。

f:id:onozaty:20191006234414p:plain

APIアクセスキーの自動生成をオプションとして提供

APIアクセスキーの自動生成をオプションとして指定できるようにしました。

プラグインの設定画面から設定できます。

f:id:onozaty:20191006234921p:plain

APIアクセスキーは、個人設定画面のAPIアクセスキーの「表示」リンクを初めて押下したタイミングで生成されます。そのため、View cutomizeでユーザのAPIアクセスキーを使う場合には、各ユーザに操作してもらう必要があったのですが、このオプションをONにすると、存在しない場合に自動で生成するようになるため、各ユーザでの操作は不要になります。

redmine-issue-loader のバージョン2.1.0をリリースしました

CSVを読み込んでRedmineのチケットを新規作成、更新するツール、redmine-issue-loaderのバージョン2.1.0をリリースしました。

対象のフィールドを増やして欲しいとの要望があったので、今回下記のフィールドを追加しました。これで全部対応できたはず、、

  • 担当者
  • 対象バージョン
  • 開始日
  • 期日
  • 進捗率
  • 予定工数
  • プライベート

詳しい利用方法は下記の日本語READMEをご参照ください。

ShortcutKey2URL for Chrome のバージョン1.2.0をリリースしました

ShortcutKey2URL for Chrome のバージョン1.2.0をリリースしました。

ShortcutKey2URL は、ショートカットキーを使用してURLを開いたり、移動したり、JavaScriptを実行できる拡張機能です。

スタートアップキーであらかじめ設定しておいた動作の一覧を表示し、次のキーでその動作を実行します。

f:id:onozaty:20171018003430p:plain

今回のバージョンより、Script欄にjavascriptスキームのまま書けるようになりました。Firefox版で先に対応しているものですが、ブックマークレットの内容をそのまま書く方が多いようで、嵌る人が多かった箇所になります。

ShortcutKey2URL(Firefox版)の 4.1.0 をリリースしました

バージョン4.1.0 を先ほどリリースしました。

今回の大きな変更点として、Scriptにjavascriptスキームのまま書けるようにしました。

ブックマークレットを登録する際に、javascriptスキームで書かれたものをそのまま登録してしまい、うまく動かないといった問い合わせがあり、javascriptスキーム部分を削除して、デコードしたものを記入してください、、っていうのは、かなり不便だと思ったので、拡張側で同じことを行うようにして対処しました。これでブックマークレットの内容をそのまま記入してもらえばOKとなりました。

あと雑多な変更として、Chrome版のバージョン1.1.0で既に対応していたものをFirefox版に取り込んでいます。

Redmine: View customize plugin の v2.4.0 をリリースしました

View customize plugin の v2.4.0 をリリースしました。

下記の2つに対応しています。

マルチバイトのWikiページにてエラーが発生する問題対処

IE11+Wikiでマルチバイトのページを表示した場合に、エラーが発生する場合がありました。
ローカルで上記組み合わせで再現できていなかったのですが、報告していただいた方にいろいろ試していただいたところ、URLを取り出した際にUTF-8として不正バイトシーケンスが含まれることがあり、そのせいでエラーとなっていることがわかりました。

不正なバイトを置換するようにして回避しています。

全てのカスタマイズに対して無効/有効を切り替え可能に

全てのカスタマイズを一括で無効/有効に出来るようにしました。
全てを無効にしたいといった場合、今まではいちいち各スクリプトの編集画面までいって切り替える必要がありましたが、これが入ったことによって、ワンクリックで切り替えられるようになりました。

f:id:onozaty:20190907222815g:plain