ラベル JavaScript の投稿を表示しています。 すべての投稿を表示
ラベル JavaScript の投稿を表示しています。 すべての投稿を表示

2016-05-12

gulp-html-extend で共通部分の多い複数のHTMLを生成する

index.html と main.html があって、head 要素や、ナビゲーション部分が、ほとんど共通だったりする。それぞれコピペしていると、モレが出るし、確認もだるい。というわけで、テンプレートエンジンを使って、静的に HTMLを出力したいと思い立った。

これらの HTML のコーディングは、将来的に他の人に任せることを想定している。なので、ソースも HTML で書けるほうがいい。

mustache とか doT とか見てみたんだけど、どうも、私がやりたいことはテンプレート化ではないことに気づいた。ベースのHTMLを継承/拡張したり、共通部分をインクルードしたいのだ。

gulp-html-extend というのが、よさそう。

// base.html
<div>Header</div>
<!-- @@placeholder= content -->
<div>Footer</div>
// index.html
<!-- @@master= base.html-->
<!-- @@block=content-->
<div>my content!!</div>
<!-- @@close-->
// gulpfile.js
// gulpfile.js
var gulp = require('gulp')
var extender = require('gulp-html-extend')
gulp.task('extend', function () {
['index.html', 'main.html'].forEach(function (filename, _, _) {
var path = 'src/' + filename;
gulp.src(path)
.pipe(extender({annotations:false,verbose:false}))
.pipe(gulp.dest('dest'))
});
});
// dest/index.html
<div>Header</div>
<div>my content!!</div>
<div>Footer</div>

いいじゃないか。こういうのでいいんだよ、こういうので。

2015-11-16

カレンダーアプリに JavaScript for Automation でアクセスすると遅い

JavaScript for Automation を使って、OS X の Calendar アプリにアクセスするコードを書いているのだけれど、期待より遅い。

var event = Application("Calendar").calendars[0].events[0];
event.summary();

1行目で、カレンダーの予定を取得している。これは、一瞬で終わる。

2行目では、予定の件名を取得している。.summary は参照だけしていて、値であるところの文字列はまだ分からない。summary() で、Calendar アプリと通信をして取得する。これが30秒くらいかかる。

今回は、カレンダーから、どの仕事に何時間使ったかを抽出しようとしている。カレンダーアプリに直接アクセスせずに、ical フォーマットのファイルを直接読み込んで処理することにした。

2015-11-08

OS X の JavaScript for Automation で、外部ライブラリを読み込む

OS X Yosemite 以降オートメーションのスクリプトをApple Script ではなくてJavaScript でも書けるようになった JavaScript for Automation または JXA と呼ぶらしい

単純な自動化だとシェルスクリプトなり Python なりで書けばいいんだけどアプリケーションと通信するときにはオートメーションを使えると便利だたとえばカレンダーアプリや iTunes の API にアクセスするようなとき

今回、JXA で日付文字列のパースやフォーマットがしたくなった。Node.js なんかだと、moment.js なるライブラリがある。

JXA で外部ライブラリを取り込むには、いくつかやりかたがあるらしいけれど、browserify を使うことにした。

手順


まず、browserify と、取り込むライブラリをインストールする。

npm install -g browserify
npm install moment

moment.js を使うコードを書く

// main.js
var moment = require("moment");
console.log(moment().format('MMMM Do YYYY, h:mm:ss a'));
browserify を使って出力したコードを、JXA 環境で実行する。

$ (echo 'window = this;'; browserify main.js; echo ';ObjC.import("stdlib");$.exit(0)') | osascript -l JavaScript
2015-11-08T16:26:55+09:00

実行コードをファイル保存


エラーが出たりすると、どの行だよ!ってなるので、browserify の出力をファイルにする。Makefile で。cake や gulp じゃなくてすみません。

bundle.js: *.js
    (echo 'window = this;'; browserify main.js; echo ';ObjC.import("stdlib");$$.exit(0)') > bundle.js

run: bundle.js
    osascript -l JavaScript bundle.js

JXA 環境特有の調整


Node.js と JXA との環境の違いを吸収するため、 browserify の出力前後に、数行追加してある。

JXA には window がない。ただし、this でグローバルなオブジェクトにアクセスできる。window = this することで、window オブジェクトが使える風にする。今回のスクリプトでは不要。

browserify で生成した関数を実行すると最後に評価された式の値がプリントされる結果を標準出力に出してパイプでつなぐような用途だと困る

ObjC.import("stdlib");
で、なんかライブラリを読み込む。らしい。ObjC.foo または $.foo で、読み込んだ関数にアクセスできる。というわけで、
$.exit(0);
して、何も表示させずに終了している。

2014-02-22

Angular JS のチュートリアルを写経

Python 旅館 2014.02 なる寄り合いに参加した。会議室を借りて、だべったりコード書いたりする。今回は Angular JS のチュートリアルを写経した。

このチュートリアルは、各ステップで、すべてのソースコードが文書に書かれていない。git checkout step-8 を実行すると、ステップ8でのすべてのファイルの変更が分かる。この方式だと、私はステップをきちんと入力せずに、なんとなく解説を読んで分かったような気になる。もちろん分かっていない。

というわけで、写経してチュートリアルを読み進めていった。結果として有効だったと思う。モジュールの基本的な考え方がなんとなく見えたし、コントローラ、フィルタ、サービスを追加するイディオムらしきものも分かった。「写経」は定義のゆれが大きい言葉なので、具体的にやったことを書いておく。


  • チュートリアルのリポジトリを git clone する。
  • git checkout step-1 とかしながら、ステップを進めていく。
  • 別のディレクトリに、チュートリアルのコードを写していく。
    • npm install は使わない。
    • index.html から写経し、必要なファイルを追加していく。
  • これは何が起こっているのだ?という箇所があったら、チュートリアルのドキュメントを読む。
  • 次のステップへ。

を、繰り返した。スマホのカタログサイトを作るというチュートリアルで、スマホのスペックが書かれたJSON ファイルは、1ファイルをちょっとだけ写経したあとは、ファイル郡を丸ごとコピーした。CSS や HTMLテンプレートで、似たような繰り返しはコピペで済ませた。

2012-05-30

HTTP Access Control のヘッダ

Basic 認証のかかったウェブ API に対して、別のドメインから jQuery.ajax() でアクセスしようとして、えらく時間がかかりました。

サーバに
  • Access-Control-Allow-Origin: http://example.com
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • Access-Control-Allow-Headers: Origin, Authorization, Accept
  • Access-Control-Allow-Credentials: true
をヘッダで返してもらうようにしたら、うまくいきました。が、これはただのコピペ。

それぞれ、何の意味を持つヘッダなのかが、 HTTP access control による、Cross-Origin Resource Sharing の解説に書かれています。

Access-Control-Allow-Origin

HTTP サーバに対して、 JavaScript からアクセスしてもよいドメインを指定する。Ajax で same origin 問題で検索すると、たいてい、このヘッダについて言及がある。ここまではよろしい。

ブラウザは、実際に GET や POST する前に、プリフライトリクエストというリクエストを発行します。通常これは OPTIONS メソッドです。で、このときのレスポンスヘッダをみて、ブラウザは呼び出す/呼び出さないを決定します。以下、同じく概要。

Access-Control-Allow-Methods

発行してもよいメソッドのリスト。OPTIONS と GET しか許さない場合には、OPTIONS, GET など。

Access-Control-Allow-Headers

サーバに送信してもいいヘッダのリスト。認証情報は Authorization ヘッダに書かれるので、このヘッダに Authorization が記載されている必要がある。

Access-Control-Allow-Credentials

名前だけみると上の Authorization と冗長な気がするんだけれど、こっちは cookie を送っていいかどうかのフラグ。

ブラウザによって、できたり/できなかったりして、いまだに確信が持てない。