bouzuya.hatenablog.com

ぼうずやのにっき

Atom editor への Panel の追加をためした

週ぶり (shuburi) 2015-W09

bouzuya/atom-btom-mode の 0.3.0 をリリースした。小さなバグを修正した。登録したコマンドが dispose されない問題に対応した。数個のコマンドで増減もほとんどないので、誤差の範囲だとは思うが。

昨日 (2015-02-26) の記事に書いたはてなブックマーク Atom package は今日も開発中。Atom editor の API の使いかたが分からないところがあったので、それを調べるためにコードリーディングをしていたので、コミットは増えていないし、まだ公開できていない。

調べていたのは Atom の Panel を追加する方法。

ゴールは atom/tree-view と同じように左側の panel に独自の要素を追加すること。

開発者ツールで DOM を確認すると atom-workspace > atom-workspace-axis.horizontal > atom-panel-container.left なので、たぶん workspace に API があると予想した。Workspace::addLeftPanel のドキュメントを確認すると、Workspace::addLeftPanel があった。ドキュメントによると引数は 1 つ。item プロパティに ViewRegistry::addViewProvider で指定した model を指定すべきとのこと。

次は ViewRegistry::addViewProvider 。これもドキュメントを確認すると引数 1 つなのだけど、実際には 2 つになっている。このあたりで諦めてソースコードを読むことにした。そんなに難しいはずはないので、呼びたいメソッドを順にたどった。Workspace::addLeftPanelViewRegistryPanelContainerPanelPanelElement あたりを読んだ。

手こずった点としては ViewRegistry::addViewProvider の引数。最初、次のような指定をしていた。

class HatenaBookmarkPanel
  constructor: ->

class HatenaBookmarkPanelElement extends HTMLElement
  constructor: ->

  initialize: (@model) ->
    @

atom.views.addViewProvider HatenaBookmarkPanel, (model) ->
  new HatenaBookmarkPanelElement().initialize(model)

これは PanelPanelElement を真似たつもりだったのだけど、PanelContainerdid-add-panel イベントによって PanelElement を生成するところで落ちる。appendChild ができない、と。

デバッガで動かして分かったのだけど、肝心なところが抜けていた。

HatenaBookmarkPanelElement = document.registerElement 'hatena-bookmark-panel', prototype: HatenaBookmarkPanelElement.prototype

という行が必要になる。ドキュメントだけみると HTMLElement だけ継承していれば良いのかと思っていたのだけど、そうではなくて document.registerElement で DOM 要素として登録して、それを使わないといけない。

まとめると次のようなコードになる。

class HatenaBookmarkPanel
  constructor: ->

class HatenaBookmarkPanelElement extends HTMLElement
  constructor: ->

  initialize: (@model) ->
    @

HatenaBookmarkPanelElement = document.registerElement 'hatena-bookmark-panel', prototype: HatenaBookmarkPanelElement.prototype

atom.views.addViewProvider HatenaBookmarkPanel, (model) ->
  new HatenaBookmarkPanelElement().initialize(model)

panel = new HatenaBookmarkPanel
panelElement = atom.views.getView panel

atom.workspace.addLeftPanel item: panelElement

まとめると、ViewRegistry::addViewProvider には Model のコンストラクタと document.registerElement で登録した要素を指定し、ViewRegistry::getView に Model のインスタンス (panel) を渡して要素を生成 (panelElement) し、Workspace::addLeftPanel にはその要素を渡すことで登録できる。

これが Atom の Panel の追加の基本的な流れだ。

意外とハマった。昔の API から変更されていて、atom/space-pen ではなくて HTML5 の標準的な方法に近づけられていて (この Custom Element のほか Shadow DOM なども使っている) 、いまのエディタ、絶賛開発中という感じはとても良いと思う。

date week day
2015-02-22 O (32 commits) O (+32 commits)
2015-02-23 O (38 commits) O (+6 commits)
2015-02-24 O (40 commits) X (+2 commits)
2015-02-25 O (41 commits) X (+1 commits)
2015-02-26 O (44 commits) X (+3 commits)

よもやまばなし

フロントエンドできない人が、フロントエンドやりすぎだ。あと、Vanilla.jsが便利だ。 - nobkzのブログ

なぜ、いまさら Vanilla.js の話題をぶり返したのか分からない (そして、つまらない) けど、フロントエンドできない人がフロントエンドやりすぎというのは分かる。もちろん、ぼくを含めて。フロントエンドの需要の高まりや変化に人や能力が追いついていないのだと思う。

で、だからこそ、フレームワークが求められていて、こうすれば良いという方針や答えを外に求めているんだとも思う。つまり「設計にあわせてフレームワークを選べ」といったことが書かれているのだけど、ぼくの感覚では「正しい設計をできる気がしないから、フレームワークの設計に頼ろう」という現状があるのだと思う。

事実としてどうなのか、統計も何もないので、どうだか分からないけど。少なくとも、できないけどやらなきゃいけない状況があって、片手間でできない状況がある。

あと関係ないけど Twitter で Service Workder の話題が上がってきていた。

その他

先週発表された webhook が今日やっと来ていた。Hubot スクリプトでポーリングしすぎているので、直しておきたい。