JavaScript 最新動向 - Shibuya.JS in Kyoto 資料

JavaScript 最新動向 - Shibuya.JS in Kyoto 資料

プレゼンテーション

JavaScript 最新動向

せっかくきょうとにきたのだ... - いや、そのりくつはおかしい - Hatena Serif

amachang - seijro@gmail.com

またの名を

  • IE8 登場前に絶対に押さえておくべき、 3 つの仕様

自己紹介

今日のメニューは 3 本立て

Access Control for Cross-site Request

XMLHttpRequest level 2

// クライアント側

var xhr = new XMLHttpRequest();

// 外部ドメインにアクセス
xhr.open("GET", "http://example.org", false);

xhr.send(null);

alert(xhr.responseText);

XMLHttpRequest level 2

#!/usr/bin/perl
# サーバー側 (GET)

use strict;

print "Content-Type: text/plain\n";
print "Access-Control: allow <http://example.com>\n\n";

print "Hello world!\n";

XMLHttpRequest level 2

#!/usr/bin/perl
# サーバー側 (GET 以外)

use strict;

if ($ENV{'REQUEST_METHOD'} eq "OPTIONS") {
    print "Content-Type: text/plain\n";
    print "Access-Control: allow <http://example.com>\n\n";
} else {
    print "Content-Type: text/plain\n\n";
    print "Hello, world!\n";
}

XMLHttpRequest level 2

XMLHttpRequest level 2

  • Firefox 3
  • Opera では現状使えない
    • ただ、仕様の提案者が Opera の人なので将来実装されるんじゃないかなあ?

IE は?

orz orz orz

独自仕様  IE 空気嫁 - 悔しい人 - Hatena Serif

XDomainRequest

XDomainRequest

// クライアント側

var xdr = new XDomainRequest();

xdr.open('GET',
         'http://amachang.art-code.org/amachang.cgi');

xdr.send(null);

xdr.onload = function() { alert('load') };

XDomainRequest

#! /usr/bin/perl
# サーバ側

use strict;

print "Content-type: text/plain\n";
print "XDomainRequestAllowed: 1\n\n";
# ↑ ( ゚д゚)

print "hoge\n"

XDomainRequest

  • はいはいわろすわろす
 〃∩ ∧_∧
 ⊂⌒( ・ω・)
  \_っ⌒/⌒c
    ⌒ ⌒

XDomainRequest

  • わろすって言ってんだろ!!
  ∧_∧
⊂(#・д・)
 /   ノ∪
 し—-J |l| |
         人ペシッ!!
       __
       \  \
          ̄ ̄

XDomainRequest

IE 8 Beta 2 くらいで、 Access Control for Cross-site Request に対応するよ!

by IE チームの人

RE: [access-control] Update from Sunava Dutta on 2008-07-09 (public-webapps@w3.org from July to September 2008)

XDomainRequest


( ゚д゚)

XDomainRequest


(つд⊂)ゴシゴシ

XDomainRequest

IE 8 Beta 2 くらいで、 Access Control for Cross-site Request に対応するよ!

by IE チームの人

RE: [access-control] Update from Sunava Dutta on 2008-07-09 (public-webapps@w3.org from July to September 2008)

XDomainRequest


(;゚д゚)

XDomainRequest


(つд⊂)ゴシゴシ

XDomainRequest

IE 8 Beta 2 くらいで、 Access Control for Cross-site Request に対応するよ!

by IE チームの人

RE: [access-control] Update from Sunava Dutta on 2008-07-09 (public-webapps@w3.org from July to September 2008)

XDomainRequest

  _, ._
(;゚ Д゚)!?

Access Control for Cross-site Request

  • キター!
  • というわけでこの仕様をもうちょっと詳しく

Access Control for Cross-site Request

Access-Control: allow <*>

Access-Control: allow <http://example.com>

Access-Control: allow <http://example.com:*>

Access-Control: allow <http://example.com:80>

Access Control for Cross-site Request

Access-Control: allow <example.com:1234> 

Access-Control: allow <*.example.com> <*.example.org>

Access-Control: allow <http://*.example.org> exclude <http://public.example.com>

Access Control for Cross-site Request

<?access-control
    allow="*.example.com"
    exclude="public.example.com" ?>

<hoge>
  <piyo></piyo></hoge>

Access Control for Cross-site Request

  • これって、 XHR2 や XDR のためにある仕様なの?
  • そういう訳ではなく、 Cross-site Server sent events などでも使われる。

Cross-site Server sent events

Cross-site Server sent events

<event-source
    id="source"
    src="http://example.com/hoge.cgi"/>

<script type="text/javascript">

var elm = document.getElementById('source');

elm.addEventLisntener('hoge', function(e) {

    alert(e.data);

});
</script>

Cross-site Server sent events

#!/usr/bin/perl

print "Content-Type: text/plain\n";
print "Access-Control: allow <http://example.org>\n\n";

my $data = 1000;

while ($data--) {
  sleep(10);

  print "Event: hoge\n"
  print "data:  $data\n\n";
}

というわけで

次のメニューは。。。

  • Selectors API
  • 知ってるひとー?(><)ノ

Selectors API

  • CSS セレクタで DOM の要素を抽出する!
  • DOM 3 XPath と同じ用途のもの
  • 機能的には XPath のほうが充実してるが、 CSS セレクタのほうが簡単!

Selectors API

Selectors API

var elm = document.querySelector(
                    "body > div.section > ul > li");

var elms = elm.querySelectorAll("p > strong");

Selectors API の問題点

  • 親要素にさかのぼれない(子要素を条件として親要素を選択することができない)
    • 今のところ、解決策はない
    • つまり、結局親要素に子要素の意味を含ませなければならない><

Selectors API の問題点

<!-- チェックされた要素の親の li を選択できない>< -->

<ul>

  <li><input type="checkbox" /></li>

  <li><input type="checkbox" /></li>

</ul>

Selectors API の問題点

  • CSS セレクタは文法的に Combinator から開始出来ないため、「コンテキストとなる要素の直接の子要素を選択する」などができない。

Selectors API の問題点

var ul = document.getElementsByTagName('ul')[0];

// 直接の子要素だけで調べたいの。。

var list = ul.querySelectorAll('> li.hoge');
// ↑これは出来ない><

var list = ul.querySelectorAll('li.hoge');
// ↑これだと孫要素とかも含まれちゃう><

The Contextual Selector

The Contextual Selector

  • ノリ的には :root と近いのかな。
var lists = ul.querySelectorAll(":scope > li");

The Contextual Selector

  • でも、まだ実装が無い
  • ぜひ IE8 でも対応して欲しい><

というわけで

  • Selectors API

最後のメニューは

Cross-document messaging

  • 2 つの実行コンテキスト間で、文字列のやりとりをする。
  • フレーム間や window.open で開いたウィンドウとのやりとりで使われる

Cross-document messaging

Cross-document messaging

// 送信側
var win = iframeElm.contentWindow;

win.postMessage('Hello!', 'http://example.com');

理想

// 受信側
function handler(e) {

  if (e.origin == 'http://example.org') {

    alert(e.data);

    e.source.postMessage('ok', e.origin);
  }
}

window.addEventListener(
                       'message', handler, false);

現実

// 受信側
function handler(e) {

  if (!e.origin && e.scheme && e.domain) {
    e.origin = e.scheme + '://' + e.domain;
  }
  else if (!e.origin && e.uri) {
    e.origin = e.uri.match(/^(.*?:\/\/.*?)(?:\/|$)/)[1];
  }

  if (e.origin == 'http://example.org') {
    alert(e.data);
    e.source.postMessage('ok', e.origin);
  }
}
window.addEventListener ?
    window.addEventListener('message', handler, false) :
    document.attachEvent('onmessage', function() { handler(window.event) }); 

Cross-document messaging

  • 現実は厳しい・・・orz
  • だが、待って欲しい。
  • いつだってそうだ。
  • 僕たちは、どんなときもライブラリを作って乗り越えてきたじゃないか!
  • どんなときも!

どんなときも!


Cross-document messaging の用途

  • JSONP の代わりに使う
  • window.open したウィンドウを介した Storage の共有
  • ブラウザの実装によると思いますが、マルチスレッドとして?

JSONP の代わり

function handler(e) {
  if (e.origin == 'http://example.org') {

    var xhr = new XMLHttpRequest();

    xhr.open('GET', '/hoge.json'); xhr.send();

    e.source.postMessage(
                       xhr.responseText, e.origin);
  }
}

window.addEventListener(
                       'message', handler, false);

Storage の共有

var win = window.open('http://hoge.com');

win.postMessage(
                'set:hoge=fuga', 'http://hoge.com');

win.postMessage(
                'get:hoge', 'http://hoge.com');

win.addEventListener('message', function(e) {

  alert(e.data);

}, false);

Storage の共有

window.addEventListener('message', function(e) {
  if (e.data.match(/^set:/)) {

    var splited = e.data.split(':')[1].split('=');

    globalStorage[splited[0]] = splited[1];
  }
  else if (e.data.match(/^get:/)) {
    e.source.postMessage(
                      globalStorage[e.data.split(':')[1]],
                      e.origin);
  }
}, false);

Cross-document messaging

  • もっと色々できそう!

というわけで

まとめ

まとめ

  • みなさん IE8 とも仲良くやっていきましょう!