ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

Materialize は iOS 13 以降でのバグがあるので注意!

React や Vue を使っていないサイトにおいて、
Materialize というCSSフレームワークは、
コンポーネントが充分に用意されていて、マテリアルデザインなサイトを製作する上でとても有用です。

Google が開発しているのにコンポーネントが不足したまま開発が放置されてしまった material-design-lite よりはよっぽど……。
マテリアルデザインを提唱してる大元なのだからがんばってほしかった・・・)

一方で、Materialize も 2018年9月に v1.0.0 を出して以降はリリースが止まってしまったのでバグがあります。
iOS 13 以降で発生するバグです。

iOS 13 でのバグとその原因

実際に見てもらうのが早いので動画にしました。

www.youtube.com

このように、押した位置と選択結果が一致しないことが多々あります。
動画は iOS 14 を公式 Simulator で動かしたもので、iOS 14 でも引き続きこのバグが起こることを確認できました。

なぜ起こるかと言うと、このフォーラムで書かれているように、どうやら
touchstart, touchend, そこから 0.2〜0.3 秒ほどおいて mousedown, click といった順にイベントが発火しているようです。

これにより、押された瞬間に dropdown.js は touchend イベントで反応するので閉じるアニメーションを開始するのですが、
押された箇所がどの要素か判定する _handleOptionClick メソッドは、
その名の通り click イベントによって発火するので、アニメーションが開始してから遅れて判定が走ります。

結果として、ドロップダウンが少し閉じている状態でのユーザーのタップ位置の li 要素が選ばれるので、
少し下の要素が選ばれてしまうのです。もしくは何も選ばれないのです。

作者の対応

これに対し、作者はこのコミットで、
ドロップダウンが閉じ始めるタイミングを要素が選択されたあとにすることで対応しています。
(_selectOption メソッドの最後で this.dropdown.close(); しているのがポイント)

残念ながらこの2019年9月の修正は v1.0.1 としてリリースされればよかったのですが、今のところリリースされていないので、
自らコンパイルして JS ファイルを作らない限りはこの修正の恩恵を受けられません。

また、ドロップダウンも同様の問題を抱えているのですが、その修正はされていません。
ドロップダウンメニューのリンクを踏んだら別のページに飛ばされるのですから、ユーザー体験はかなり悪いですね……。

どう対処するか

select について

3通り考えられます。
現在の https://github.com/Dogfalo/materialize の r1-dev の最新コミットから grunt を用いて JS を生成し、それを使う方法。
または、こちらの記事で紹介されているように、最新コミットから select.js だけを取ってきて materialize.js の後で読み込む方法です。
後者の方法はメソッドの上書きをすることでギリ動いているのではと思うので、materialize.min.js でなく materialize.js を使わないと上手くいかない気がします。

3つ目の方法は次で説明します。

dropdown について

この記事で書かれている方法がおもしろかったです。
touchend イベントを付与してしまってそちらに処理してしまう方法です。
元々の click イベントと二重に発生する可能性を持っていますがページ移動処理なのでそんなに困らないという、力技の解決方法でけっこう好きです。

他の解決方法としては、dropdown のオプションである closeOnClick を false に設定することで、
ドロップダウンメニュー内を選んだときに閉じるアニメーションが発生しなくなるので、
誤った箇所が選択されることが無くなります。

このオプションは select においても dropdownOptions というオプションから設定できます。select の問題の対処法の3つ目はこれを用いる方法です。
ただ、領域外を押すまでドロップダウンが閉じてくれないので、select で使うのはユーザー体験としては悪いでしょうね……。

最近の Materialize の動き

最近は Materialize に大きな動きがありました。

なかなか動きを見せない作者に業を煮やし、DanielRuf さんが新しいリポジトリを作成しました。

作成した5月からはしばらく動きを見せていませんでしたが、
(作者から「新しいコミュニティを作るのもなんだから、ここのリポジトリを手伝ってくれる人を募集するよ!」って声をかけられたからだと思う。その後 DanielRuf さんが「ぜひ」と返したあとで作者からの返信が無くなるんだけど……)
7月から活発に動くようになり、コミットが少しずつ重ねられています。

まだ最初のリリースも作られていないので自分でコンパイルしない限りは使えませんが、
上手く行けば、select バグなどが解消された v1.0.1 がリリースされる日が来るかも知れません。

正直、今のところは Material Design for Bootstrap を選択するほうが安全策と言えるのですが、
ボタンのデザインなど Materialize の方がデザインはカッコいいと思うので、今後の動きに注目です。

追記:メンバーになりました

「dropdown のバグを直すために少しいじってみるか〜」と、このブログを書いたあとでさわってみたら
いろいろ問題を見つけてしまい、プルリクエストをいくつか出してコントリビュートしていたところ、
翌日メンバーに招待されました。

英語苦手だけどレビューがんばらなくちゃな〜と思いました。

指定ディレクトリ以下の node_modules ディレクトリをすべて消す

node_modules ディレクトリは物によっては数百MBもの大きさになるので、
放ったままにしておくのはディスク領域の無駄となる。

そこで node_modules ディレクトリをすべて削除してしまいたいと考えていたところ、
とてもいい記事を見つけた。

How to Delete ALL node_modules folders on your machine and Free up HD space!

ここで、 node_modules にどれだけの容量を使っているのかを知るコマンド
それらを全て削除するコマンドが説明されていた。ありがたい。

node_modules にどれだけの容量を使っているか

find . -name "node_modules" -type d -prune | xargs du -chs

find コマンドで node_modules ディレクトリを探し、
prune オプションによってそれより下層のディレクトリは結果として出力しない。
で、 xargsdu コマンドに渡してあげて、ディレクトリごとの容量を見ているわけだ。

プログラミングデータをまとめているディレクトリで実行してみたところ、
以下のようになった。

 60M   ./isucon/isucon8/backup/isucon/torb/webapp/nodejs/node_modules
 34M    ./isucon/isucon8/backup/isucon/local/node/lib/node_modules
## (中略)
250M    ./practice/react/my-app/node_modules
101M    ./practice/rails/rails6-practice/node_modules
8.0G   total

なんと驚きの 8.0GB も node_modules に使用していた。

必要になったら再び npm install すればいいので、これらは削除してしまいたい。

すべての node_modules ディレクトリを削除

find . -name "node_modules" -type d -prune -exec rm -rf '{}' +

先ほどの探索コマンドに、exec オプションを付けて実行をしている形である。
つまりは以下のコマンドと同義である。

find . -name "node_modules" -type d -prune | xargs rm -rf

xargs の -p オプションを付けて実行すると、何が削除されるのか表示されるのでより安全。
(表示までやや時間がかかります)

find . -name "node_modules" -type d -prune | xargs -p rm -rf

node_modules ディレクトリごと削除されるので、
node_modules ディレクトリは残してその下層のファイルのみ削除したい場合は別のコマンドを考える必要がある。
自分はいくらか試したが、どうにも上手くいかなかったので、特に困らないし node_modules ディレクトリごと削除する方向に落ち着いた。

プログラマー的 Mac の初期設定 2020年版

はるか昔(2015年)にこんな記事を書いている。

もう5年経って昔と状況が変わってきたので、
今回 TimeMachine を使わずに最初からセットアップしていることを活かし、改めて書いてみる。

1. Chrome のインストール

Safari を開いてまずおこなうのが Chrome のインストール。
Safari は昔の Windows における Internet Explorer と同じく、他のWebブラウザを入れるための踏み台に過ぎないのだ……。

2. Google 日本語入力のインストール

今回はこのブログ記事を書き始める目的があったのですぐにインストール。
そして書きやすいようにセットアップ。(バックスラッシュを使うとか、常に半角スペースを使うとか)

個人の好みだと思うけれど、いちおう貼っておくとこんな感じ。

3. Macの設定(System Preferences)

3-1. 画面解像度の変更

設定画面の Displays から変更

Resolution の Scaled を選択し、解像度を「Default」から「More Space」に変更。

3-2. キーボード設定の変更

設定画面の Keyboard から変更

キーリピート速度を上げたり、タッチバーの表示のデフォルトをファンクションキーにしたり。

また、右下の Modifier Keys... から、 Caps Lock キーが Ctrl キーとして動作するよう変更。

「Text」タブでは smart quotes の設定を必ず切っておく!
Slack とかでコードを説明するとき、これが暴発して困ったことあるプログラマーは絶対にいるはず。

「Shortcuts」タブでは、「Screenshots」以外のショートカットは基本的に切る。
テキストエディタのショートカットと衝突する可能性があるためだ。

「Input Sources」に関しては Google日本語入力のみに出来ればいいのだが、
やり方を知らないと標準の英字入力が消えなくて戸惑う。

こちらを参照: Macの入力ソースからUSを消す方法 - NISHI3 Output

「日本語」を追加したあと、設定の入力モードの「英字」にチェックを入れると、標準の英字入力が消せるそうだ。
なかなかトリッキーだ。

3-3. 「General」の設定

私はこんな感じにしている。

特に大事なのが 「Close windows when quitting an app」のチェックを外す こと。
小さめの文字で書かれている通り、ここが選択されている場合、
アプリケーションを再起動してもリストア(タブなどが復元)されないことがある。

なぜデフォルトだとここが選択されているのか不思議だ……。

3-4. 「Dock」の設定

個人的な趣味だとこんな感じ。
「Show recent application in Dock」の選択は切るのが好み。

3-5. 「Mission Control」の設定

勝手に順番が変わるのは嫌なので
「Automatically rearrange Spaces based on most recent use」のチェックは切っている。

3-6. マウスポインタのサイズ変更

「Accessibility」>「Display」>「Cursor」から変更可能。
デフォルトのサイズだと個人的には小さく感じるので少し大きめにしている。

3-7. 「Sound」の設定

Macの効果音に関しては以下のようにして切っている。

3-8. 「Trackpad」の設定

ここはかなり好みの出ているところで、
フォースクリックがそんなに好きじゃないのでオフにしていたり、
Windows の習慣に慣れているので右クリックをトラックパッドの右下を押して反応するようにしていたり。

デフォルトは2本指タップなので、他人の Mac を触るときはよく
「そうだ、右クリックは2本指だった」ってなりがち。

3-9. 「Energy Saver」の設定

ディスプレイ消灯までの時間を長く。

また、バッテリー駆動のときに画面が暗くなるのは嫌なので
「Slightly dim the display while on battery power」のチェックは外した。

3-10. アプリケーションごとの言語設定

macOS Catalina から、アプリケーションごとの言語設定が可能になっている

「Language & Region」の「Apps」タブから追加できる。
ここで Music アプリを日本語に設定してあげれば、日本語の曲をダウンロードするときに英題になってしまう問題が解消される。

OSの言語設定を英語にしている場合にもっとも困っていた問題だったので、この設定項目は嬉しい。

4. Finder の設定変更

こんな感じ。

あと、Finder の「Applications」フォルダを Dock にドラッグ&ドロップすると、
Dock 内にアプリケーション一覧が表示されるようになるので、
個人的には Launchpad よりそちらからアプリケーションの立ち上げをすることが多い。

5. Terminal を開く

Applications の Utilities フォルダ内にある「Terminal(ターミナル)」を開く。

設定の「Profiles」から「Pro」をデフォルトに変えたら Command + N で新規ウィンドウ立ち上げ。

6. スクリーンショットを指定ディレクトリに保存

デフォルトではスクリーンショットはデスクトップ上に保存されてしまうが、 以下のコマンドで~/Pictures/Screenshot ディレクトリに「SS 1.png」のような名称で
スクリーンショットが保存されるようになる。

mkdir ~/Pictures/Screenshot
defaults write com.apple.screencapture name "SS"
defaults write com.apple.screencapture include-date -bool false
defaults write com.apple.screencapture location "~/Pictures/Screenshot"
killall SystemUIServer

なお、Macスクリーンショット
Command + Shift + 3 で画面全体撮影、
Command + Shift + 4 で範囲指定撮影、
Command + Shift + 5 で撮影方法を選択ののち撮影(このとき動画撮影も選べる)、
というようなショートカットでおこなえる。

7. 隠しファイルを Finder で表示

ドットファイルなども表示したいので、以下のコマンドでオンにしている。

defaults write com.apple.finder AppleShowAllFiles -boolean true
killall Finder

常時オンにする必要がない人は、 Shift + Command + . で隠しファイルの表示・非表示が切り替えられるので、
そのショートカットを使うと良い。

8. homebrew のインストール

Macのパッケージ管理ソフト homebrew のインストール。
https://brew.sh に従って以下のコマンドを実施。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

9. brewzsh をインストール

homebrew をインストールしたので、 zsh をインストールし直す。
homebrew にあるものの方が、Mac にすでに入っているものよりバージョンが新しいことが多いためだ。

brew install zsh

インストール後、昔は単純に chsh コマンドでログインシェルの変更ができたが、
/etc/shells に記載されていないと non-standard shell と言われて変更できないようになっていたので、あらかじめ

sudo vi /etc/shells

/usr/local/bin/zsh を最終行に書き足しておく。

それが終わったら、

chsh -s /usr/local/bin/zsh

で、 ログインシェルの変更をおこなう。

10. prezto の導入

素の zsh だと便利さが足りないので prezto の導入。
https://github.com/sorin-ionescu/prezto に従って適用。

git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"

したあとに

setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done

これで終わりだけど、git module を使いたいので

vi ~/.zpreztorc

で開いて

zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'prompt'

ってなってるところに git を足して以下のようにしてあげる。

zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'prompt' \
  'git'

終わったらターミナルを再起動。

11. 必要なアプリケーションをどんどん入れていく

App Store や homebrew などでどんどん入れていく。

Xcode が一番時間かかるので、Xcode が必要な場合はそれから始める。
(昔と違って、Xcode のインストールをしなくても macOS に git や ruby などが最初からインストールされているので、iOS 開発者でないのなら Xcode をインストールする必要性は薄くなった)

brew cask は昔は問題あったが(参考: https://queryok.ikuwow.com/entry/stop-brew-cask )、
現在だとデメリットが少ないので必要なアプリケーションのインストールのためにどんどん使っていく。

App Store にアプリケーションがある場合は、
アップデート通知機能を持たないアプリケーションだったら、
brew cask で入れるよりも App Store からインストールしたほうが、更新するのを忘れないので良い。

11-1. App Store で入れたもの

  • Xcode
  • The Unarchiver
  • Amphetamine
touch aaa.zip aaa.tar aaa.xz aaa.gz aaa.7z aaa.tgz

で仮ファイル作って Get Info から Open With を The Unarchiver に Change All... して切り替える作業がやや面倒。
(詳しくは前回の記事の 17. の項を)

11-2. brew でインストール

個人的にはこんな感じ。
たぶん全然足りていないが、必要なときに追々足していく。

brew install awscli curl gibo git go imagemagick jq kotlin mysql node openjdk perl postgresql python ruby sqlite wget yarn

Heroku CLI

brew tap heroku/brew && brew install heroku

11-3. brew cask でインストール

以下で1コマンドで書いているが、
ターミナルを複数タブ開いていくつかに分けておこなうほうが速い。

brew install --cask visual-studio-code android-studio iterm2 docker tweeten discord skype slack teamviewer firefox opera vivaldi

## お仕事の場合
brew install --cask visual-studio-code iterm2 docker virtualbox slack firefox opera

ZoomVirtualBox はインストール時にパスワードを要求される関係で、
インストールやアップデートが気付いたら途中で止まっていることが起こるので、brew cask を使わずにインストールしています。

12. フォントを微妙に太くする

視認性が高いものが好みのため、フォントのアンチエイリアスの設定を変更。
参考: https://colinstodd.com/posts/tech/fix-macos-catalina-fonts-after-upgrade.html

defaults write -g CGFontRenderingFontSmoothingDisabled -bool FALSE
defaults -currentHost write -globalDomain AppleFontSmoothing -int 3

本当に微妙な差だけれど、文字が少しだけ太くなる。

元の太さ

設定後

元に戻す場合のコマンドは以下。

defaults -currentHost delete -globalDomain AppleFontSmoothing
defaults write -g CGFontRenderingFontSmoothingDisabled -bool True

おわり

以前に書いた記事とはだいぶ中身が変わった。
当時が El Capitan で、その後 Sierra, High Sierra, Mojave, Catalina と OS が4つも変わってきたのだから当然の結果なのかもしれない。

この秋には Big Sur が出る予定で、macOS のバージョンとしてついに 11 へとメジャーバージョンアップされるので、
この記事もすぐ古くなってしまいそうだ。(メジャーバージョンアップの理由は Apple製の新CPUに対応するためだと思うので、ユーザー的にはそんなに変わらないかもしれないが)

さて、Mac周りの設定は終わったので、あとはアプリケーションごとの設定だ。
5年間で積み上がった不要ファイルとの決別のため TimeMachine を使わなかったが、
アプリケーションごとの設定もやり直しになるのでなかなか大変だ。

快適な環境に戻るための道のりは長い……!