ECMAScript 2016 I18n API

ECMAScript® 2016 Internationalization API Specification がECMAScript 2016と同時にリリースされた。
I18n APIってなんだよってことで、MDN読んでた。Intl – JavaScript | MDN
specは読んでもわからんので…

I18n系のライブラリはいくつもあるし、なんでそんなのあるのって言うの読んでた。
The ECMAScript Internationalization API

ES5にもES2015あたりにも、ちょっとだけ仕組みが入ってるのをおしすすめた。
各ライブラリが個別に再実装するはめになってる。でかい変換テーブルがいる。インターフェースを決める。

そのへんか。なるほど。
まあ例によってユーザーがそのままこのAPI使うわけではなく、ライブラリ作者が楽に高速になるよね、系のアレ。fetchとかみたいな。

ブラウザ実装状況見ると、
chrome 24, firefox 29, ie 11, opera 15, safari 未実装。
chrome for android 26。モバイルはあと未実装。
なので、あーというかんじ。
ただ、safari 10に実装されることが発表されているので、mac os x sierra, ios 10で入る。
将来的にはいい感じになりそう。

ここから下は、仕様の話じゃなくて、もうあるchromeとfirefoxの実装の話。注意。

あとはだいたいMDNからのコピペ。コードを動かしてみるのは主にchrome 51。

Intl

Intlという名前空間があって、その下にオブジェクトがあるのと、あとString, Number, Dateにメソッドが生えてる。

コンストラクタ
Intl.Collator
Intl.DateTimeFormat
Intl.NumberFormat
メソッド
String.prototype.localeCompare()
Number.prototype.toLocaleString()
Date.prototype.toLocaleString()
Date.prototype.toLocaleDateString()
Date.prototype.toLocaleTimeString()

String.prototype.localeCompare()

ウムラウト区別できても関係ないよなーと思ってた。
けど、ふとひらがなカタカナ半角カナで試してみたら、なるほどーとなった。
まあブラウザ実装依存なんだろうけど、おおーってならない? そうでもないか。

'a'.localeCompare('c');
-1
'check'.localeCompare('against');
1
'a'.localeCompare('a');
0
'ä'.localeCompare('z', 'de')
-1
'ä'.localeCompare('z', 'sv')
1

# ドイツとスウェーデンでソート順が違う。ここまでMDNコピペ

'あ'.localeCompare('ア')
-1
'あ'.localeCompare('ア', 'ja')
0
# !?
'あらすか'.localeCompare('アラスカ', 'ja')
0
'あらすか'.localeCompare('アらスカ', 'ja')
0
'あらすか'.localeCompare('アラスカ', 'ja')
0

Number.prototype.toLocaleString()

プリセットでいろいろある。通貨は結構うれしい。デフォルトプリセット気に入らなかったら、設定上書きできる。
数字部分だけ色変えたいとかあるのはまあ自分で文字列切り刻んだり文字列追加したりでやれってことかな。

var number = 123456.789;
undefined
number.toLocaleString()
"123,456.789"
number.toLocaleString('de-DE')
"123.456,789"
number.toLocaleString('ar-EG')
"١٢٣٬٤٥٦٫٧٨٩"
number.toLocaleString('en-IN')
"1,23,456.789"
number.toLocaleString('zh-Hans-CN-u-nu-hanidec')
"一二三,四五六.七八九"
number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
"123.456,79 €"
number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' })
"¥123,457"
number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY', minimumFractionDigits: 2 })
"¥123,456.79"

Date.prototype.toLocaleString()

chromeやるな。 平成って文字列出てきた。でもMDNと違うぞ。でfirefoxで動かしてみたらMDN通りになった。
やっぱりブラウザ間実装差が。

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
undefined
date.toLocaleString('en-US')
"12/20/2012, 12:00:00 PM"
date.toLocaleString('en-GB')
"20/12/2012, 12:00:00"
date.toLocaleString('ja')
"2012/12/20 12:00:00"
date.toLocaleString('ar-EG')
"٢٠‏/١٢‏/٢٠١٢ ١٢:٠٠:٠٠ م"
date.toLocaleString('ko-KR')
"2012. 12. 20. 오후 12:00:00"
date.toLocaleString('ja-JP-u-ca-japanese')
"平成24/12/20 12:00:00"

firefox 47

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
undefined
date.toLocaleString('en-US')
"12/20/2012, 12:00:00 PM"
date.toLocaleString('ja-JP-u-ca-japanese')
"24/12/20 12:00:00"

エレクトロンならワンちゃんあるかな。

Firefox desktop/android 向けの addon, Build Linkシリーズを作った

tl;dr

  • Firefox desktop/android向けの開いてるページのurlとタイトルをplain, markdown, htmlでコピーするaddonを作った 別々なので3つ
  • 文字列を選択した状態でaddonを動作させると、その文字列を対象にリンクを作る
  • web extensionsではない。web extensionsはまだandroid firefoxで動かないので
  • なおpc firefoxユーザーは Make Link :: Add-ons for Firefox 使えばいいと思う

普段pcではfirefox使っていないので、あしからず。

なぜ作ったか

Create Link – Chrome ウェブストア,
Make Link :: Add-ons for Firefox
的なものはpc/mobileどの環境でも重宝している。が、android firefox上でうまく使えるのがないので、addon作った。

なお、pc ie, ios safari, android chromeではbookmarkletで実現できる。
Bookmarklet of quietmole

android firefoxはbookmarkletで実現できなかったのでaddonにした。

リンク

addonのページ

リポジトリ

使い方

pcでは、ツールバー横のボタンを押すと、クリップボードに入る。
androidでは、メニューに項目が追加されるので、リンクを作りたいページ上でメニューを選ぶと、promptがでるので、そこから自分でコピペする。

dZ7jf6o-2702nq704P-270

作った感想

pc向けはapiもいい感じになっているが、android向けはpcでは廃止されたapiを使って作っていかなければなのでダルい ブラウザのパーツに対して何かする場面はほぼ2個書くことになる かと言って2個に分けるとロジックはそれなりに共通化できるので分けると修正漏れしそう。dom側は同じにしてしまえる。

babel, browserify/webpack なしで作れた。browserifyなしだと、最近npmモジュールでブラウザ向けビルドを提供していないのも多いので、ツライこともある。

ちょっと工夫すると普通のnpm moduleみたいに作りつつビルドも出来るので、楽ちん。そのままだと対象ディレクトリをまるごとパッケージしてしまうから、node_modulesがそのまま使える反面、devDependenciesでパッケージ容量が膨れ上がってしまう。

./dist にgit cloneして、NODE_ENV=production npm install することでdependenciesだけインストールしてパッケージにする感じ。

使った感想

便利に使える。けど、思った以上にLink Bubbleで見てる。
割合的にはfirefox:link bubble = 2:8ぐらい。
インテントで渡すandroidアプリ作るほうがいいのかなーと思う。
ページ遷移していく時や重たくなるページはfirefoxつかう。まえiphone使ってた時に、app内のweb view使うか、べつにブラウザ立ち上げるか、ぐらいの使用感のイメージ。

GitHub Issues/Pull requests を高速に整理する “Triage for GitHub”

TL;DR

GitHub issueとpull requestのやるやらないを、すばやく振り分けていくためのデス
クトップアプリ “Triage for GitHub“を作りました。

triage-for-github

GitHubのIssue, Pull Requestを迅速にさばいていくことが出来ます。

Motivation

Dependency Update as a Service – Tachikoma.io, greenkeeper, deppbot – Automated Dependency Updates を使うことで、ガンガンpull requestを飛ばし、CIやカバレッジなど、GitHubのエコシステムに乗ることが出来るようになりました。

(tachikoma.io 使ってね!)

ただし、数が増えるとpull requestを持て余します。見逃すこともしょっちゅう。

too-many-pull-requests

特に定期ping的に空pull requestでciを起動するような場合、ciが通っていることを
確認したらガンガンpull requestを閉じたい。

Plan A: /pulls

https://github.com/pulls

github-pulls

GitHubには自分のpull request一覧を見るページがあり、これは求めるものに近いものがある。他にも、検索を使ってorganizationのpull request一覧を見る方法もある。しかし、現状どうしてもポチポチクリックしていく必要があり、閉じていくのも面倒くさい。

Plan B: Triage for GitHub

triage-for-github

そこで、ガシガシ閉じていく専用のデスクトップアプリを作りました。
ランチャーみたいなイメージで、気になるのあったら’Jump’してGitHubのUIを開いて確認していく、GitHub Issueのトリアージを実現します。

使い方

セットアップ

Latest releaseから自分の環境のzipをダウンロードします。

settings

settingsに、GitHubのpersonal tokenを入れてください。scopeは repo or public_repoで、つまり、private+public repos or public reposのどちらかのトークンを入れます。

トークン未入力の場合、lyrictenor/example-issuesのissues/pull requestsを表示します。issue立てたり、pull requestを送ったり、自由にどうぞ。雰囲気はつかめると思います。

トークン未入力の場合、GitHubのAPIリクエスト回数制限が極端に少ないです。
https://developer.github.com/v3/#rate-limiting

60 requests per hour.

一定時間IP制限かかるので注意です。

トークンを使っていても、人によっては結構な回数APIリクエストをするアプリなので、過剰な巡回・起動には注意してください。

表示

updated atの新しい順に、5日ぶんのissue/pull requestが並びます。日数はひとまず固定です。

実験的機能 自動巡回

autopilotをonにすると、定期的に自動巡回します。
が、コレはまだ動いたり動かなかったりです。

autopiloting flagがonになったままになってしまうバグが有るため、そうなった場合
はdebug paneから force unlockしてください。

issueの詳細

issue, pull requestの詳細は v っぽいアイコンをクリックしてください。

show-details

まとめ

GitHub issues, pull requestsをガンガン振り分けできる “Triage for GitHub”を作ったのでガンガン整理できる。

使ったnpm modules

力作。package.json

  "dependencies": {
    "classnames": "^2.1.3",
    "crossing": "^1.0.1",
    "crypto-js": "^3.1.5",
    "electron-debug": "0.3.0",
    "electron-open-link-in-browser": "^1.0.1",
    "electron-template-menu": "1.0.3",
    "es6-error": "^2.0.0",
    "is-empty-object": "^1.1.0",
    "level-js": "^2.2.2",
    "level-sublevel": "^6.5.2",
    "levelup": "^1.2.1",
    "lodash": "^3.10.1",
    "material-ui": "0.13.1",
    "moment": "^2.10.6",
    "octokat": "^0.4.11",
    "react": "^0.14.2",
    "react-addons-create-fragment": "^0.14.2",
    "react-addons-pure-render-mixin": "^0.14.2",
    "react-addons-transition-group": "^0.14.2",
    "react-addons-update": "^0.14.2",
    "react-dom": "^0.14.2",
    "react-redux": "^4.0.0",
    "react-router": "1.0.0-rc4",
    "react-tap-event-plugin": "0.2.1",
    "redux": "^3.0.0",
    "redux-batched-updates": "^0.1.0",
    "redux-devtools-dock-monitor": "^1.0.0-beta-3",
    "redux-devtools-log-monitor": "^1.0.0-beta-3",
    "redux-form": "^3.0.0-beta-4",
    "redux-thunk": "^1.0.0",
    "reset-storage": "^1.0.1",
    "rndm": "^1.1.0"
  },
  "devDependencies": {
    "archiver": "^0.16.0",
    "babel": "^5.8.23",
    "babel-core": "^5.8.23",
    "babel-eslint": "^4.1.1",
    "babel-loader": "^5.3.2",
    "babel-plugin-react-transform": "^1.0.3",
    "babel-runtime": "^5.8.20",
    "buffered-spawn": "^1.1.2",
    "conventional-changelog": "^0.5.0",
    "cpy": "^3.4.0",
    "css-loader": "^0.21.0",
    "eclint": "^1.1.1",
    "electron-packager": "^5.0.2",
    "electron-prebuilt": "0.34.2",
    "eslint": "^1.3.1",
    "eslint-config-airbnb": "0.1.0",
    "eslint-loader": "^1.0.0",
    "eslint-plugin-babel": "^2.1.1",
    "eslint-plugin-react": "~3.6.3",
    "espower-babel": "^3.3.0",
    "express": "^4.13.3",
    "extract-text-webpack-plugin": "^0.9.0",
    "fixpack": "^2.2.0",
    "globstar": "^1.0.0",
    "html-webpack-plugin": "^1.6.1",
    "is-travis-ci-build-for-tag": "^1.1.1",
    "json-loader": "^0.5.2",
    "mocha": "^2.3.0",
    "npm-check-updates": "^2.2.0",
    "power-assert": "^1.0.0",
    "react-transform-catch-errors": "^1.0.0",
    "react-transform-hmr": "^1.0.1",
    "redbox-react": "^1.0.5",
    "redux-devtools": "^v3.0.0-beta-3",
    "rimraf": "^2.4.3",
    "silence-chromium": "^2.0.0",
    "style-loader": "^0.13.0",
    "touch": "^1.0.0",
    "webfont-dl": "^0.1.2",
    "webpack": "^1.12.0",
    "webpack-dev-middleware": "^1.2.0",
    "webpack-hot-middleware": "^2.1.0",
    "yargs": "^3.23.0"
  },

Chrome Extensionにライセンスの明示

Licenseを明示してちょLicense Issue #54 sanemat/do-not-merge-wip-for-githubというissueが立ったので、復習した。

manifest.jsonにlicense書くところがあるかというとなさそうだった。
Manifest File Format – Google Chrome

特にforkではじめてないし考慮するライセンスはなし。GPLにリンクするから問題、とかもなさそう。MITライセンスにしたい。minifyしてない。headerに書いたほうが良さそうだけどまあいいか。

npm packageじゃないけどpackage.jsonはあるから、licenseにMIT追加、LICENSE.txt 追加,READMEに追加、ぐらいでよさそう。

ライセンス変更でパッと思い出したのがRubyのlicense変更だったのでざっと眺める。
Change Ruby’s License to BSDL + Ruby’s dual license – Ruby Forum

たしか、マジメにやろうとすると全contributorから許可取り直して、ダメって言ったら差し替えて、とかやるんよね。それはダルいからcollaboratorにmentionしとけばよかろうぐらいの甘々認識で。やっぱりcontributorにもmentionした。沈黙は黙認とする。

開始年も考えるとわかんなくなる気もするが、さかのぼってinitial commmitの年でいいとしよう。

ひとまず考慮はこのくらいだろうか。

Unexpected gem dependency (at least for me)

Background knowledge

current rspec stable version: 2.14.1
next break backward compatible version beta: 3.0.0.beta1
ready for v3 version beta: 2.99.0.beta1

http://rubygems.org/gems/rspec

I have strange behavior about add_development_dependency (At least for me). Yes, I want to use pre-release version at that time, but v3.0.0 I don’t want yet…

Tachikoma’s gemspec:

spec.add_development_dependency ‘rspec’, ‘>= 2.14.0.rc’

I wrote this before release of 2.14.0.

Then:

Installing rspec-core (3.0.0.beta1)
Installing rspec-support (3.0.0.beta1)
Installing rspec-expectations (3.0.0.beta1)
Installing rspec-mocks (3.0.0.beta1)
Installing rspec (3.0.0.beta1)

I change gemspec:

spec.add_development_dependency ‘rspec’, ‘>= 2.14.0’

Then:

Installing rspec-core (2.14.7)
Installing rspec-expectations (2.14.4)
Using rspec-mocks (2.14.4)
Using rspec (2.14.1)

cms比較部

大筋はwordpress.comかblogger.com使えばいいんじゃないのーと思ってるので、おおまかに。octpressも結局使ってないけど好き。

Rails mountable CMS and or Blog engine – Stack Overflow

content management system – Is it possble include Nesta CMS into Rails3 application? – Stack Overflow

cloneして、テスト走らせてみるところまで

refinerycms,

rails製, エコシステムは一番有りそう ただごつい印象, ruby2.0.0もうtravisのターゲットに入ってる

jipiboily/monologue,

rails製, rails3.2.8なのがちょっと気になる, ruby2.0.0-rc1でテスト全部通った

comfy/comfortable-mexican-sofa,

rails製, コンパクト, rspecですらなくtest-unitなのはちょっとコンパクトにしすぎ感も, ruby2.0.0-rc1でテスト全部通った

gma/nesta,

sinatra製, , ruby2.0.0-rc1でテスト全部通った

rails4にするときどうするんでしょうねーって考えるとgma/nestaに惹かれる気もする。混ぜたほうが楽なのか、混ぜないほうが楽なのか…railsのバージョン上げるときに気にするところ増えるのだるい

考え方これに近い Managing Static Content in a Ruby on Rails Application – Evidence I’m Alive – Bits and Pieces of the Web Curated by Jeff Poulton