読者です 読者をやめる 読者になる 読者になる

べにやまぶろぐ

技術寄りの話を書くつもり

Colored Hashtag for Trello を v1.0.5 に更新しました

Git/GitHub/GitLab JavaScript Trello Yeoman Chrome

どうも Trello のデザインが変わったせいか動作しなくなっていたので Colored Hashtag for Trello を更新しました。

chrome.google.com

Chrome プラグインだと公開するだけで勝手にユーザの環境も更新されるから開発者的には有難いですね。気軽にバグ修正ができます。

この Colored Hashtag for Trello ですが、Plus for Trello というプラグインと一緒に使っても動作するように作っています(チームで導入しているため)。

chrome.google.com

このプラグインを使うと下図のようにハッシュタグが強調表示されるのですが、デザインが変更されるということは DOM の構成、または属性が変更されるということなのでセレクタを使う場合はそこを意識してあげる必要があります。

f:id:beniyama:20150321131156p:plain

実際、Plus for Trello 使用前後を比較してみると

<div class="list-card-details u-clearfix">
  <div class="list-card-labels u-clearfix js-card-labels"></div>
  <a class="list-card-title js-card-name" href="/c/XXXX/1-101">
    <span class="card-short-id hide">#1 </span>#101 プラグインの更新記事を書く
  </a>  
  ...
</div>

という DOM(一部抜粋)が下記のようになっていることがわかります。

<div class="list-card-details u-clearfix">
  <div class="list-card-labels u-clearfix js-card-labels"></div>
  <a class="list-card-title js-card-name agile_hidden" href="/c/XXXX/1-1-story-1">
    <span class="card-short-id hide">#1 </span>#101 プラグインの更新記事を書く
  </a>
  <a class="list-card-title js-card-name agile_clone_title" href="/c/XXXX/1-1-story-1">
    <span class="card-short-id hide">#1 </span> プラグインの更新記事を書く
  </a>
  ...
  <span class="agile_hashtags"><span class="badge agile_badge agile_badge_hashtag_primary">101</span></span>
  ...
</div>

元々一つしか無かった .list-card-title が二つになり、オリジナルは .agile_hidden クラスが付加されて不可視に、ハッシュタグ部分を別 span に分離したクローン(.agile_clone_title が付加されている)がその後ろに差し込まれています。

Colored Hashtag for Trello では(どうせ DOM 操作によるスタイル変更を行うので) Trello API を使わずにタイトル中のテキスト(上図で言うと「#101 プラグインの更新記事を書く」の部分)からハッシュタグを検出しているのですが、ここでオリジナルのものを破壊されてしまうと Plus for Trello の有無で処理を変えないといけません。しかしながら、ちゃんと元の構造のまま残してくれているのでその必要はなく、代わりに .list-card-title で引いたときに最初のもの(オリジナル)だけ取得するようにすれば良いだけです。この辺は、他のプラグインのことも考えて Plus for Trello は作られているなと関心しました。

v1.0.4 までは first-child 疑似クラスで .list-card-title 要素を指定していた(つもりだった)のですが、勘違した疑似クラス first-childの使い方 でも書かれているように .list-card-title:first-child としても「最初の .list-card-title 要素」が選択されるのではなく、「最初の要素が .list-card-title だったときのみマッチする」のでその前に他の要素が同レベルで現れるとひっかかりません。今回はおそらく .list-card-labels の div が差し込まれるようになったために first-child.list-card-title でなくなったことが原因かなと考えています。

結局、今回は代わりに first-of-type 疑似クラスを使う事で解決しました。E:first-of-type−CSS3リファレンス によれば

E:first-childの場合には、種類に関係なく要素を数えるため、 最初に来る要素がE要素であった場合にスタイル適用の対象になります。

一方、E:first-of-typeの場合には、途中で別の種類の要素が入る場合にはそれを数えずに、 指定した種類の要素のみを数えるため、最初に来るE要素がスタイル適用の対象になります。

とのことで、これでめでたく最初の .list-card-title だけ取得することができるようになりました。