Node.js based smart shopping cart app
Information
In this page, there is English description followed by Japanese one.
本ページは英語の説明の後に日本語の説明が続きます。
Getting Started
Installing Node.js and npm
You need to have Node.js and npm installed.
To check if you have them installed, open a terminal or command prompt and run the following commands:
node --version npm --version
If you see an number output similar to x.x.x for each command, then they are both installed and you can continue to the next section.
To install on Windows or mac, you can download the installer from https://nodejs.org/en/download.
To install on Linux, you can use a package manager. Instructions for installing Node.js on your distribution can be found in the following link:
https://nodejs.org/en/download/package-manager
Prerequisite
This example assumes that you've already run the following program that can communicate the decoded result of barcode data with mbed Device Connector:
Import programGR-PEACH_mbed-os-client-ZXingSample
Fork of https://developer.mbed.org/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/
Configuring the Applition
In order to run this app, you need to set up the options shown below via .env file stored in the folder GR-PEACH_mbed-os-QRCode-ShoppingCart-node which should be automatically created when cloning this program.
- ACCESS_KEY
Set this variable to your Access Key that you can create on mbed Device Connector. if you don't have an Access Key yet, please create it in accordance with the following procedure.
1. Access https://connector.mbed.com/#accesskeys.
2. Click CREATE NEW ACCESS KEY.
3. When prompted, enter a name for the access key (e.g. "demo") and click ADD.
After an access key is successfully created, please copy the access key you just created and use it in .env file as follows:
.env
ACCESS_KEY=...
- PORT
Set this variable as follows to override the default port for this example if needed. The default port is 8080.
.env
PORT=...
Also, user need to prepare for the comma-delimited list which includes "Item Name" and "Price" which is added to shopping cart, and save it by the name klist.txt as follows:
The list should be stored in GR-Peach_mbed-os_QRCode_ShoppingCart_node\public\list.
Application Execution
This application consists of 2 tabs. One is Shopping Cart and the other is QR Code Login. In this section, it is described that how those work.
As mentioned above, GR-PEACH_mbed-os-client-ZXingSample should be executed beforehand. For details on how to set up and execute GR-PEACH_mbed-os-client-ZXingSample, please refer to https://developer.mbed.org/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/. If the program works properly, you can see the following message in your terminal:
After it is confirmed that the program works properly, please follow the procedure below in order to execute this Web Application.
- How to invoke this Web Application
You can now run the application by invoking the following:
Then, you should see the following message if the configuration is successfully done, :
Please note that 8080 might be changed. It should depends on your PORT setting mentioned above. If you access the above URL using Web browser, you can see the following Smart Shopping Cart tab by default:
- How Shopping Cart tab works
When you decode QR code stored in GR-Peach_mbed-os_QRCode_ShoppingCart_node\qrcode by GR-PEACH successfully, the item should be added to shopping cart as follows:
- How QR Code Login tab works
When you choose QR Code Login tab, you can see the following screen indicating it's Locked status.
Then, if you decode the Unlock qrcode described in GR-Peach_mbed-os_QRCode_ShoppingCart_node\qrcode\qr.pdf, screen should transit to the following one indicating it's Unlocked status.
After that if you you decode the Lock qrcode described in the above qr.pdf, screen should re-transit to Locked status. In this way, the screen transits to Locked and Unlocked status in accordance with the decoded result of QR code.
How to Deploy this app on HEROKU
HEROKU ( https://id.heroku.com ) is PaaS (Platform as a Service) on which Node.js application can deploy free-of charge. By utilizing it, you can access mbed Shopping Cart and QR Code Login from mobile terminal.
Here is the procedure to deploy this application on HEROKU:
- Create your HEROKU account at https://signup.heroku.com/login if you haven't created it yet.
- Install Heroku Toolbelt
32-bit: https://cli-assets.heroku.com/heroku-cli/channels/stable/heroku-cli-x86.exe
64-bit: https://cli-assets.heroku.com/heroku-cli/channels/stable/heroku-cli-x64.exe ) - Launch command prompt (e.g. Windows PowerShell) and move to the project root directory. Then, invoke the command heroku login. At the first time, Email and Password is thought to be required. At that time, please type Email address and password registered at the step 1.
- Invoke the command git init
- Invoke the command git add . to prepare all the files staged for the next commit
- Invoke the command git commit -m "[commit message]" to commit the files staged at the step 5
- Invoke the command heroku create. If the command is successfully terminated, the remote repository heroku should be created and associated with the local repository
- Invoke the command git push heroku master If the command is successfully terminated, this application should be deployed to HEROKU and its URL should be shown as follows:
remote: -----> Launching... remote: Released v3 remote: https://hogeoge.herokuapp.com/ deployed to Heroku
After all the steps are completed without error, please access the URL http:hogehoge.herokuapp.com/ (i.e URL where https in the URL shown in the step 7 is replaced with http) with Web browser. You should be able to show mbed Shopping Cart on Web browser.
-------------------------------------------------------------------------------------------------------------------------------------------------
Node.jsとnpmのインストール
本アプリケーションを実行するにあたっては、Node.jsとnpmのインストールが必要です。
お使いの開発環境(PC)にNode.js、npmがインストールされているかどうかは、下記コマンドで確認する事ができます。
node --version npm --version
上記コマンド実行後、x.x.x というバージョン・リビジョン番号が表示されれば、Node.js、npmは既にインストールされていますので、次節以降の手順にしたがってアプリケーションのセットアップを行ってください。未インストールの場合は以降の手順にしたがってNode.js、npmをインストールしてください。
開発環境のホストOSがWindowsまたはmacの場合はhttps://nodejs.org/en/download から入手可能なインストーラを使用してインストールします。
開発環境のホストOSがLinuxの場合は、お使いのディストリビーションに応じたパッケージ管理システムを用いたインストールが可能です。詳細はhttps://nodejs.org/en/download/package-manager を参照ください。
前提条件
本アプリケーションを実行するにあたっては、GR-PEACH上のバーコードデータのデコード結果にmbed Device Connectorからアクセスする下記プログラムを事前にセットアップしておく必要があります。
Import programGR-PEACH_mbed-os-client-ZXingSample
Fork of https://developer.mbed.org/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/
アプリケーションの設定
本アプリケーションの実行するためには、.envファイルを介して以下に示すオプションを設定する必要があります。なお、.envファイルはGR-PEACH_mbed-os-QRCode-ShoppingCart-nodeフォルダに格納されています。
- ACCESS_KEY
本変数にはmbed Device Connector上で生成可能なAccess Keyを設定します。Access Keyが未生成の場合は下記に従って作成してください。
1. https://connector.mbed.com/#accesskeys にアクセスします。
2. CREATE NEW ACCESS KEYをクリックします。
3. access keyの名称を入力するように促されたら、任意の名称(例えばdemo等)を入力し、ADDをクリックします。
access keyが正常に生成できたら、コピーして下記のように.envファイルでACCESS_KEYに設定します。
.env
ACCESS_KEY=...
- PORT
本変数にはWebアプリへのアクセスに使用するポート番号を下記のように設定します。デフォルトのポート番号は 8080 です。8080から変更の必要がなければ、設定は省略可能です。
.env
PORT=...
また、ショッピングカートに追加する品目と値段をカンマ区切りで下記のように記載したリストを準備し、klist.txtという名称でGR-Peach_mbed-os_QRCode_ShoppingCart_node\public\listフォルダに格納してください。
アプリケーションの実行
本アプリケーションでは、Shopping CartとQR Code Loginという2つのタブが実装されています。以下、それぞれの動作方法について記載します。
なお上述の通り、本アプリケーションの実行に際しては、事前にGR-PEACH_mbed-os-client-ZXingSampleを実行しておく必要があります。GR-PEACH_mbed-os-client-ZXingSampleのセットアップ方法、および実行方法に関しては、https://developer.mbed.org/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/ を参照ください。プログラムが正常に動作している場合、下記のメッセージがターミナルに表示されます。
プログラムの正常動作が確認できたら、以降の手順に従ってWebアプリケーションを実行します。
- Webアプリケーションの起動
下記コマンドでWebアプリケーションを起動可能です。
上述のアプリケーション設定が正常に行われていれば、下記メッセージが表示されます。
なお、8080はPORT設定に応じた値となります。
続いて、上述のURLにWebブラウザでアクセスすると、下記のSmart Shopping Cartの画面が表示されます。
- Shopping Cartタブ
GR-Peach_mbed-os_QRCode_ShoppingCart_node\qrcode\qrcode.pdf に記載されている Birthday Cake、Party Cups、Beer Kegs、Pound of beef、Buflle-proof vest のQRコードをデコードすると、下記のようにデコードしたアイテムが都度ショッピングカートに追加されます。
- QR Code Loginタブ
このタブを選択すると、下記のLock状態を示す画面が表示されます。
ここで、GR-Peach_mbed-os_QRCode_ShoppingCart_node\qrcode\qrcode.pdf に記載のUnlock QRコードをデコードすると、Unlock状態を示す下記の画面に遷移します。
この後、Lock QRコードをデコードすると画面はLock状態に再度遷移します。
このようにQR Code Loginタブでは、LockとUnlockのQRコードをデコードする都度、対応する画面に遷移するアプリケーションです。
HEROKUへのデプロイ
HEROKU ( https://id.heroku.com) はNode.jsアプリが無償でデプロイ可能なPaaS (Platform as a Service)と呼ばれるサービスです。HEROKUを活用する事で、mbed Shopping CartとQR Code Loginにモバイル端末等からアクセスする事が可能となります。
以下、HEROKUへ本アプリをデプロイする手順を説明します。
- HEROKUのアカウントを所有していない場合は https://signup.heroku.com/login でアカウントを作成してください
- Heroku Toolbeltをインストールします
32-bit版: https://cli-assets.heroku.com/heroku-cli/channels/stable/heroku-cli-x86.exe
64-bit版: https://cli-assets.heroku.com/heroku-cli/channels/stable/heroku-cli-x64.exe ) - ターミナルソフトウェア(例えばWindows PowerShell)を立上げます。そして本アプリのルートディレクトリへ移動し、heroku loginコマンドを実行します。Emailアドレスとパスワードの入力を求められた場合は、アカウント生成時に入力したアドレスとパスワードを入力してください。
- git initコマンドを実行します
- git add .コマンドを実行し、全ファイルをコミット対象に設定します
- git commit -m "[commit message]" で、全ファイルをコミットします
- heroku createを実行します。本コマンドが正常終了すると、リモートリポジトリ herokuが設定されます
- git push heroku master本コマンドが正常終了すると、HEROKUへのデプロイが完了し、下記のように本WebアプリのURLが表示されます
remote: -----> Launching... remote: Released v3 remote: https://hogeoge.herokuapp.com/ deployed to Heroku
上記の全ての手順が完了したら、http:hogehoge.herokuapp.com/ ( 8. で表示されたURL中のhttpsをhttpに置換えたもの)へブラウザ等でアクセスします。途中でエラーが発生していなければ、mbed Shopping CartがWebブラウザ上に表示されます。
public/js/socket.io.js@0:a40b9a259b52, 2018-01-12 (annotated)
- Committer:
- Osamu Nakamura
- Date:
- Fri Jan 12 19:05:14 2018 +0900
- Revision:
- 0:a40b9a259b52
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Osamu Nakamura |
0:a40b9a259b52 | 1 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 2 | |
Osamu Nakamura |
0:a40b9a259b52 | 3 | module.exports = _dereq_('./lib/'); |
Osamu Nakamura |
0:a40b9a259b52 | 4 | |
Osamu Nakamura |
0:a40b9a259b52 | 5 | },{"./lib/":2}],2:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 6 | |
Osamu Nakamura |
0:a40b9a259b52 | 7 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 8 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 9 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 10 | |
Osamu Nakamura |
0:a40b9a259b52 | 11 | var url = _dereq_('./url'); |
Osamu Nakamura |
0:a40b9a259b52 | 12 | var parser = _dereq_('socket.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 13 | var Manager = _dereq_('./manager'); |
Osamu Nakamura |
0:a40b9a259b52 | 14 | var debug = _dereq_('debug')('socket.io-client'); |
Osamu Nakamura |
0:a40b9a259b52 | 15 | |
Osamu Nakamura |
0:a40b9a259b52 | 16 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 17 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 18 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 19 | |
Osamu Nakamura |
0:a40b9a259b52 | 20 | module.exports = exports = lookup; |
Osamu Nakamura |
0:a40b9a259b52 | 21 | |
Osamu Nakamura |
0:a40b9a259b52 | 22 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 23 | * Managers cache. |
Osamu Nakamura |
0:a40b9a259b52 | 24 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 25 | |
Osamu Nakamura |
0:a40b9a259b52 | 26 | var cache = exports.managers = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 27 | |
Osamu Nakamura |
0:a40b9a259b52 | 28 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 29 | * Looks up an existing `Manager` for multiplexing. |
Osamu Nakamura |
0:a40b9a259b52 | 30 | * If the user summons: |
Osamu Nakamura |
0:a40b9a259b52 | 31 | * |
Osamu Nakamura |
0:a40b9a259b52 | 32 | * `io('http://localhost/a');` |
Osamu Nakamura |
0:a40b9a259b52 | 33 | * `io('http://localhost/b');` |
Osamu Nakamura |
0:a40b9a259b52 | 34 | * |
Osamu Nakamura |
0:a40b9a259b52 | 35 | * We reuse the existing instance based on same scheme/port/host, |
Osamu Nakamura |
0:a40b9a259b52 | 36 | * and we initialize sockets for each namespace. |
Osamu Nakamura |
0:a40b9a259b52 | 37 | * |
Osamu Nakamura |
0:a40b9a259b52 | 38 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 39 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 40 | |
Osamu Nakamura |
0:a40b9a259b52 | 41 | function lookup(uri, opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 42 | if (typeof uri == 'object') { |
Osamu Nakamura |
0:a40b9a259b52 | 43 | opts = uri; |
Osamu Nakamura |
0:a40b9a259b52 | 44 | uri = undefined; |
Osamu Nakamura |
0:a40b9a259b52 | 45 | } |
Osamu Nakamura |
0:a40b9a259b52 | 46 | |
Osamu Nakamura |
0:a40b9a259b52 | 47 | opts = opts || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 48 | |
Osamu Nakamura |
0:a40b9a259b52 | 49 | var parsed = url(uri); |
Osamu Nakamura |
0:a40b9a259b52 | 50 | var source = parsed.source; |
Osamu Nakamura |
0:a40b9a259b52 | 51 | var id = parsed.id; |
Osamu Nakamura |
0:a40b9a259b52 | 52 | var path = parsed.path; |
Osamu Nakamura |
0:a40b9a259b52 | 53 | var sameNamespace = (cache[id] && cache[id].nsps[path] && |
Osamu Nakamura |
0:a40b9a259b52 | 54 | path == cache[id].nsps[path].nsp); |
Osamu Nakamura |
0:a40b9a259b52 | 55 | var newConnection = opts.forceNew || opts['force new connection'] || |
Osamu Nakamura |
0:a40b9a259b52 | 56 | false === opts.multiplex || sameNamespace; |
Osamu Nakamura |
0:a40b9a259b52 | 57 | |
Osamu Nakamura |
0:a40b9a259b52 | 58 | var io; |
Osamu Nakamura |
0:a40b9a259b52 | 59 | |
Osamu Nakamura |
0:a40b9a259b52 | 60 | if (newConnection) { |
Osamu Nakamura |
0:a40b9a259b52 | 61 | debug('ignoring socket cache for %s', source); |
Osamu Nakamura |
0:a40b9a259b52 | 62 | io = Manager(source, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 63 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 64 | if (!cache[id]) { |
Osamu Nakamura |
0:a40b9a259b52 | 65 | debug('new io instance for %s', source); |
Osamu Nakamura |
0:a40b9a259b52 | 66 | cache[id] = Manager(source, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 67 | } |
Osamu Nakamura |
0:a40b9a259b52 | 68 | io = cache[id]; |
Osamu Nakamura |
0:a40b9a259b52 | 69 | } |
Osamu Nakamura |
0:a40b9a259b52 | 70 | |
Osamu Nakamura |
0:a40b9a259b52 | 71 | return io.socket(parsed.path); |
Osamu Nakamura |
0:a40b9a259b52 | 72 | } |
Osamu Nakamura |
0:a40b9a259b52 | 73 | |
Osamu Nakamura |
0:a40b9a259b52 | 74 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 75 | * Protocol version. |
Osamu Nakamura |
0:a40b9a259b52 | 76 | * |
Osamu Nakamura |
0:a40b9a259b52 | 77 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 78 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 79 | |
Osamu Nakamura |
0:a40b9a259b52 | 80 | exports.protocol = parser.protocol; |
Osamu Nakamura |
0:a40b9a259b52 | 81 | |
Osamu Nakamura |
0:a40b9a259b52 | 82 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 83 | * `connect`. |
Osamu Nakamura |
0:a40b9a259b52 | 84 | * |
Osamu Nakamura |
0:a40b9a259b52 | 85 | * @param {String} uri |
Osamu Nakamura |
0:a40b9a259b52 | 86 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 87 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 88 | |
Osamu Nakamura |
0:a40b9a259b52 | 89 | exports.connect = lookup; |
Osamu Nakamura |
0:a40b9a259b52 | 90 | |
Osamu Nakamura |
0:a40b9a259b52 | 91 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 92 | * Expose constructors for standalone build. |
Osamu Nakamura |
0:a40b9a259b52 | 93 | * |
Osamu Nakamura |
0:a40b9a259b52 | 94 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 95 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 96 | |
Osamu Nakamura |
0:a40b9a259b52 | 97 | exports.Manager = _dereq_('./manager'); |
Osamu Nakamura |
0:a40b9a259b52 | 98 | exports.Socket = _dereq_('./socket'); |
Osamu Nakamura |
0:a40b9a259b52 | 99 | |
Osamu Nakamura |
0:a40b9a259b52 | 100 | },{"./manager":3,"./socket":5,"./url":6,"debug":10,"socket.io-parser":46}],3:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 101 | |
Osamu Nakamura |
0:a40b9a259b52 | 102 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 103 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 104 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 105 | |
Osamu Nakamura |
0:a40b9a259b52 | 106 | var url = _dereq_('./url'); |
Osamu Nakamura |
0:a40b9a259b52 | 107 | var eio = _dereq_('engine.io-client'); |
Osamu Nakamura |
0:a40b9a259b52 | 108 | var Socket = _dereq_('./socket'); |
Osamu Nakamura |
0:a40b9a259b52 | 109 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 110 | var parser = _dereq_('socket.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 111 | var on = _dereq_('./on'); |
Osamu Nakamura |
0:a40b9a259b52 | 112 | var bind = _dereq_('component-bind'); |
Osamu Nakamura |
0:a40b9a259b52 | 113 | var object = _dereq_('object-component'); |
Osamu Nakamura |
0:a40b9a259b52 | 114 | var debug = _dereq_('debug')('socket.io-client:manager'); |
Osamu Nakamura |
0:a40b9a259b52 | 115 | var indexOf = _dereq_('indexof'); |
Osamu Nakamura |
0:a40b9a259b52 | 116 | var Backoff = _dereq_('backo2'); |
Osamu Nakamura |
0:a40b9a259b52 | 117 | |
Osamu Nakamura |
0:a40b9a259b52 | 118 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 119 | * Module exports |
Osamu Nakamura |
0:a40b9a259b52 | 120 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 121 | |
Osamu Nakamura |
0:a40b9a259b52 | 122 | module.exports = Manager; |
Osamu Nakamura |
0:a40b9a259b52 | 123 | |
Osamu Nakamura |
0:a40b9a259b52 | 124 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 125 | * `Manager` constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 126 | * |
Osamu Nakamura |
0:a40b9a259b52 | 127 | * @param {String} engine instance or engine uri/opts |
Osamu Nakamura |
0:a40b9a259b52 | 128 | * @param {Object} options |
Osamu Nakamura |
0:a40b9a259b52 | 129 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 130 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 131 | |
Osamu Nakamura |
0:a40b9a259b52 | 132 | function Manager(uri, opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 133 | if (!(this instanceof Manager)) return new Manager(uri, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 134 | if (uri && ('object' == typeof uri)) { |
Osamu Nakamura |
0:a40b9a259b52 | 135 | opts = uri; |
Osamu Nakamura |
0:a40b9a259b52 | 136 | uri = undefined; |
Osamu Nakamura |
0:a40b9a259b52 | 137 | } |
Osamu Nakamura |
0:a40b9a259b52 | 138 | opts = opts || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 139 | |
Osamu Nakamura |
0:a40b9a259b52 | 140 | opts.path = opts.path || '/socket.io'; |
Osamu Nakamura |
0:a40b9a259b52 | 141 | this.nsps = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 142 | this.subs = []; |
Osamu Nakamura |
0:a40b9a259b52 | 143 | this.opts = opts; |
Osamu Nakamura |
0:a40b9a259b52 | 144 | this.reconnection(opts.reconnection !== false); |
Osamu Nakamura |
0:a40b9a259b52 | 145 | this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); |
Osamu Nakamura |
0:a40b9a259b52 | 146 | this.reconnectionDelay(opts.reconnectionDelay || 1000); |
Osamu Nakamura |
0:a40b9a259b52 | 147 | this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); |
Osamu Nakamura |
0:a40b9a259b52 | 148 | this.randomizationFactor(opts.randomizationFactor || 0.5); |
Osamu Nakamura |
0:a40b9a259b52 | 149 | this.backoff = new Backoff({ |
Osamu Nakamura |
0:a40b9a259b52 | 150 | min: this.reconnectionDelay(), |
Osamu Nakamura |
0:a40b9a259b52 | 151 | max: this.reconnectionDelayMax(), |
Osamu Nakamura |
0:a40b9a259b52 | 152 | jitter: this.randomizationFactor() |
Osamu Nakamura |
0:a40b9a259b52 | 153 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 154 | this.timeout(null == opts.timeout ? 20000 : opts.timeout); |
Osamu Nakamura |
0:a40b9a259b52 | 155 | this.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 156 | this.uri = uri; |
Osamu Nakamura |
0:a40b9a259b52 | 157 | this.connected = []; |
Osamu Nakamura |
0:a40b9a259b52 | 158 | this.encoding = false; |
Osamu Nakamura |
0:a40b9a259b52 | 159 | this.packetBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 160 | this.encoder = new parser.Encoder(); |
Osamu Nakamura |
0:a40b9a259b52 | 161 | this.decoder = new parser.Decoder(); |
Osamu Nakamura |
0:a40b9a259b52 | 162 | this.autoConnect = opts.autoConnect !== false; |
Osamu Nakamura |
0:a40b9a259b52 | 163 | if (this.autoConnect) this.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 164 | } |
Osamu Nakamura |
0:a40b9a259b52 | 165 | |
Osamu Nakamura |
0:a40b9a259b52 | 166 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 167 | * Propagate given event to sockets and emit on `this` |
Osamu Nakamura |
0:a40b9a259b52 | 168 | * |
Osamu Nakamura |
0:a40b9a259b52 | 169 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 170 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 171 | |
Osamu Nakamura |
0:a40b9a259b52 | 172 | Manager.prototype.emitAll = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 173 | this.emit.apply(this, arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 174 | for (var nsp in this.nsps) { |
Osamu Nakamura |
0:a40b9a259b52 | 175 | this.nsps[nsp].emit.apply(this.nsps[nsp], arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 176 | } |
Osamu Nakamura |
0:a40b9a259b52 | 177 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 178 | |
Osamu Nakamura |
0:a40b9a259b52 | 179 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 180 | * Update `socket.id` of all sockets |
Osamu Nakamura |
0:a40b9a259b52 | 181 | * |
Osamu Nakamura |
0:a40b9a259b52 | 182 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 183 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 184 | |
Osamu Nakamura |
0:a40b9a259b52 | 185 | Manager.prototype.updateSocketIds = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 186 | for (var nsp in this.nsps) { |
Osamu Nakamura |
0:a40b9a259b52 | 187 | this.nsps[nsp].id = this.engine.id; |
Osamu Nakamura |
0:a40b9a259b52 | 188 | } |
Osamu Nakamura |
0:a40b9a259b52 | 189 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 190 | |
Osamu Nakamura |
0:a40b9a259b52 | 191 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 192 | * Mix in `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 193 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 194 | |
Osamu Nakamura |
0:a40b9a259b52 | 195 | Emitter(Manager.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 196 | |
Osamu Nakamura |
0:a40b9a259b52 | 197 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 198 | * Sets the `reconnection` config. |
Osamu Nakamura |
0:a40b9a259b52 | 199 | * |
Osamu Nakamura |
0:a40b9a259b52 | 200 | * @param {Boolean} true/false if it should automatically reconnect |
Osamu Nakamura |
0:a40b9a259b52 | 201 | * @return {Manager} self or value |
Osamu Nakamura |
0:a40b9a259b52 | 202 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 203 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 204 | |
Osamu Nakamura |
0:a40b9a259b52 | 205 | Manager.prototype.reconnection = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 206 | if (!arguments.length) return this._reconnection; |
Osamu Nakamura |
0:a40b9a259b52 | 207 | this._reconnection = !!v; |
Osamu Nakamura |
0:a40b9a259b52 | 208 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 209 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 210 | |
Osamu Nakamura |
0:a40b9a259b52 | 211 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 212 | * Sets the reconnection attempts config. |
Osamu Nakamura |
0:a40b9a259b52 | 213 | * |
Osamu Nakamura |
0:a40b9a259b52 | 214 | * @param {Number} max reconnection attempts before giving up |
Osamu Nakamura |
0:a40b9a259b52 | 215 | * @return {Manager} self or value |
Osamu Nakamura |
0:a40b9a259b52 | 216 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 217 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 218 | |
Osamu Nakamura |
0:a40b9a259b52 | 219 | Manager.prototype.reconnectionAttempts = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 220 | if (!arguments.length) return this._reconnectionAttempts; |
Osamu Nakamura |
0:a40b9a259b52 | 221 | this._reconnectionAttempts = v; |
Osamu Nakamura |
0:a40b9a259b52 | 222 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 223 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 224 | |
Osamu Nakamura |
0:a40b9a259b52 | 225 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 226 | * Sets the delay between reconnections. |
Osamu Nakamura |
0:a40b9a259b52 | 227 | * |
Osamu Nakamura |
0:a40b9a259b52 | 228 | * @param {Number} delay |
Osamu Nakamura |
0:a40b9a259b52 | 229 | * @return {Manager} self or value |
Osamu Nakamura |
0:a40b9a259b52 | 230 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 231 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 232 | |
Osamu Nakamura |
0:a40b9a259b52 | 233 | Manager.prototype.reconnectionDelay = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 234 | if (!arguments.length) return this._reconnectionDelay; |
Osamu Nakamura |
0:a40b9a259b52 | 235 | this._reconnectionDelay = v; |
Osamu Nakamura |
0:a40b9a259b52 | 236 | this.backoff && this.backoff.setMin(v); |
Osamu Nakamura |
0:a40b9a259b52 | 237 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 238 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 239 | |
Osamu Nakamura |
0:a40b9a259b52 | 240 | Manager.prototype.randomizationFactor = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 241 | if (!arguments.length) return this._randomizationFactor; |
Osamu Nakamura |
0:a40b9a259b52 | 242 | this._randomizationFactor = v; |
Osamu Nakamura |
0:a40b9a259b52 | 243 | this.backoff && this.backoff.setJitter(v); |
Osamu Nakamura |
0:a40b9a259b52 | 244 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 245 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 246 | |
Osamu Nakamura |
0:a40b9a259b52 | 247 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 248 | * Sets the maximum delay between reconnections. |
Osamu Nakamura |
0:a40b9a259b52 | 249 | * |
Osamu Nakamura |
0:a40b9a259b52 | 250 | * @param {Number} delay |
Osamu Nakamura |
0:a40b9a259b52 | 251 | * @return {Manager} self or value |
Osamu Nakamura |
0:a40b9a259b52 | 252 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 253 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 254 | |
Osamu Nakamura |
0:a40b9a259b52 | 255 | Manager.prototype.reconnectionDelayMax = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 256 | if (!arguments.length) return this._reconnectionDelayMax; |
Osamu Nakamura |
0:a40b9a259b52 | 257 | this._reconnectionDelayMax = v; |
Osamu Nakamura |
0:a40b9a259b52 | 258 | this.backoff && this.backoff.setMax(v); |
Osamu Nakamura |
0:a40b9a259b52 | 259 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 260 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 261 | |
Osamu Nakamura |
0:a40b9a259b52 | 262 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 263 | * Sets the connection timeout. `false` to disable |
Osamu Nakamura |
0:a40b9a259b52 | 264 | * |
Osamu Nakamura |
0:a40b9a259b52 | 265 | * @return {Manager} self or value |
Osamu Nakamura |
0:a40b9a259b52 | 266 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 267 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 268 | |
Osamu Nakamura |
0:a40b9a259b52 | 269 | Manager.prototype.timeout = function(v){ |
Osamu Nakamura |
0:a40b9a259b52 | 270 | if (!arguments.length) return this._timeout; |
Osamu Nakamura |
0:a40b9a259b52 | 271 | this._timeout = v; |
Osamu Nakamura |
0:a40b9a259b52 | 272 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 273 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 274 | |
Osamu Nakamura |
0:a40b9a259b52 | 275 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 276 | * Starts trying to reconnect if reconnection is enabled and we have not |
Osamu Nakamura |
0:a40b9a259b52 | 277 | * started reconnecting yet |
Osamu Nakamura |
0:a40b9a259b52 | 278 | * |
Osamu Nakamura |
0:a40b9a259b52 | 279 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 280 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 281 | |
Osamu Nakamura |
0:a40b9a259b52 | 282 | Manager.prototype.maybeReconnectOnOpen = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 283 | // Only try to reconnect if it's the first time we're connecting |
Osamu Nakamura |
0:a40b9a259b52 | 284 | if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 285 | // keeps reconnection from firing twice for the same reconnection loop |
Osamu Nakamura |
0:a40b9a259b52 | 286 | this.reconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 287 | } |
Osamu Nakamura |
0:a40b9a259b52 | 288 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 289 | |
Osamu Nakamura |
0:a40b9a259b52 | 290 | |
Osamu Nakamura |
0:a40b9a259b52 | 291 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 292 | * Sets the current transport `socket`. |
Osamu Nakamura |
0:a40b9a259b52 | 293 | * |
Osamu Nakamura |
0:a40b9a259b52 | 294 | * @param {Function} optional, callback |
Osamu Nakamura |
0:a40b9a259b52 | 295 | * @return {Manager} self |
Osamu Nakamura |
0:a40b9a259b52 | 296 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 297 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 298 | |
Osamu Nakamura |
0:a40b9a259b52 | 299 | Manager.prototype.open = |
Osamu Nakamura |
0:a40b9a259b52 | 300 | Manager.prototype.connect = function(fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 301 | debug('readyState %s', this.readyState); |
Osamu Nakamura |
0:a40b9a259b52 | 302 | if (~this.readyState.indexOf('open')) return this; |
Osamu Nakamura |
0:a40b9a259b52 | 303 | |
Osamu Nakamura |
0:a40b9a259b52 | 304 | debug('opening %s', this.uri); |
Osamu Nakamura |
0:a40b9a259b52 | 305 | this.engine = eio(this.uri, this.opts); |
Osamu Nakamura |
0:a40b9a259b52 | 306 | var socket = this.engine; |
Osamu Nakamura |
0:a40b9a259b52 | 307 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 308 | this.readyState = 'opening'; |
Osamu Nakamura |
0:a40b9a259b52 | 309 | this.skipReconnect = false; |
Osamu Nakamura |
0:a40b9a259b52 | 310 | |
Osamu Nakamura |
0:a40b9a259b52 | 311 | // emit `open` |
Osamu Nakamura |
0:a40b9a259b52 | 312 | var openSub = on(socket, 'open', function() { |
Osamu Nakamura |
0:a40b9a259b52 | 313 | self.onopen(); |
Osamu Nakamura |
0:a40b9a259b52 | 314 | fn && fn(); |
Osamu Nakamura |
0:a40b9a259b52 | 315 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 316 | |
Osamu Nakamura |
0:a40b9a259b52 | 317 | // emit `connect_error` |
Osamu Nakamura |
0:a40b9a259b52 | 318 | var errorSub = on(socket, 'error', function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 319 | debug('connect_error'); |
Osamu Nakamura |
0:a40b9a259b52 | 320 | self.cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 321 | self.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 322 | self.emitAll('connect_error', data); |
Osamu Nakamura |
0:a40b9a259b52 | 323 | if (fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 324 | var err = new Error('Connection error'); |
Osamu Nakamura |
0:a40b9a259b52 | 325 | err.data = data; |
Osamu Nakamura |
0:a40b9a259b52 | 326 | fn(err); |
Osamu Nakamura |
0:a40b9a259b52 | 327 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 328 | // Only do this if there is no fn to handle the error |
Osamu Nakamura |
0:a40b9a259b52 | 329 | self.maybeReconnectOnOpen(); |
Osamu Nakamura |
0:a40b9a259b52 | 330 | } |
Osamu Nakamura |
0:a40b9a259b52 | 331 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 332 | |
Osamu Nakamura |
0:a40b9a259b52 | 333 | // emit `connect_timeout` |
Osamu Nakamura |
0:a40b9a259b52 | 334 | if (false !== this._timeout) { |
Osamu Nakamura |
0:a40b9a259b52 | 335 | var timeout = this._timeout; |
Osamu Nakamura |
0:a40b9a259b52 | 336 | debug('connect attempt will timeout after %d', timeout); |
Osamu Nakamura |
0:a40b9a259b52 | 337 | |
Osamu Nakamura |
0:a40b9a259b52 | 338 | // set timer |
Osamu Nakamura |
0:a40b9a259b52 | 339 | var timer = setTimeout(function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 340 | debug('connect attempt timed out after %d', timeout); |
Osamu Nakamura |
0:a40b9a259b52 | 341 | openSub.destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 342 | socket.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 343 | socket.emit('error', 'timeout'); |
Osamu Nakamura |
0:a40b9a259b52 | 344 | self.emitAll('connect_timeout', timeout); |
Osamu Nakamura |
0:a40b9a259b52 | 345 | }, timeout); |
Osamu Nakamura |
0:a40b9a259b52 | 346 | |
Osamu Nakamura |
0:a40b9a259b52 | 347 | this.subs.push({ |
Osamu Nakamura |
0:a40b9a259b52 | 348 | destroy: function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 349 | clearTimeout(timer); |
Osamu Nakamura |
0:a40b9a259b52 | 350 | } |
Osamu Nakamura |
0:a40b9a259b52 | 351 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 352 | } |
Osamu Nakamura |
0:a40b9a259b52 | 353 | |
Osamu Nakamura |
0:a40b9a259b52 | 354 | this.subs.push(openSub); |
Osamu Nakamura |
0:a40b9a259b52 | 355 | this.subs.push(errorSub); |
Osamu Nakamura |
0:a40b9a259b52 | 356 | |
Osamu Nakamura |
0:a40b9a259b52 | 357 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 358 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 359 | |
Osamu Nakamura |
0:a40b9a259b52 | 360 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 361 | * Called upon transport open. |
Osamu Nakamura |
0:a40b9a259b52 | 362 | * |
Osamu Nakamura |
0:a40b9a259b52 | 363 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 364 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 365 | |
Osamu Nakamura |
0:a40b9a259b52 | 366 | Manager.prototype.onopen = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 367 | debug('open'); |
Osamu Nakamura |
0:a40b9a259b52 | 368 | |
Osamu Nakamura |
0:a40b9a259b52 | 369 | // clear old subs |
Osamu Nakamura |
0:a40b9a259b52 | 370 | this.cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 371 | |
Osamu Nakamura |
0:a40b9a259b52 | 372 | // mark as open |
Osamu Nakamura |
0:a40b9a259b52 | 373 | this.readyState = 'open'; |
Osamu Nakamura |
0:a40b9a259b52 | 374 | this.emit('open'); |
Osamu Nakamura |
0:a40b9a259b52 | 375 | |
Osamu Nakamura |
0:a40b9a259b52 | 376 | // add new subs |
Osamu Nakamura |
0:a40b9a259b52 | 377 | var socket = this.engine; |
Osamu Nakamura |
0:a40b9a259b52 | 378 | this.subs.push(on(socket, 'data', bind(this, 'ondata'))); |
Osamu Nakamura |
0:a40b9a259b52 | 379 | this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded'))); |
Osamu Nakamura |
0:a40b9a259b52 | 380 | this.subs.push(on(socket, 'error', bind(this, 'onerror'))); |
Osamu Nakamura |
0:a40b9a259b52 | 381 | this.subs.push(on(socket, 'close', bind(this, 'onclose'))); |
Osamu Nakamura |
0:a40b9a259b52 | 382 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 383 | |
Osamu Nakamura |
0:a40b9a259b52 | 384 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 385 | * Called with data. |
Osamu Nakamura |
0:a40b9a259b52 | 386 | * |
Osamu Nakamura |
0:a40b9a259b52 | 387 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 388 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 389 | |
Osamu Nakamura |
0:a40b9a259b52 | 390 | Manager.prototype.ondata = function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 391 | this.decoder.add(data); |
Osamu Nakamura |
0:a40b9a259b52 | 392 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 393 | |
Osamu Nakamura |
0:a40b9a259b52 | 394 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 395 | * Called when parser fully decodes a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 396 | * |
Osamu Nakamura |
0:a40b9a259b52 | 397 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 398 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 399 | |
Osamu Nakamura |
0:a40b9a259b52 | 400 | Manager.prototype.ondecoded = function(packet) { |
Osamu Nakamura |
0:a40b9a259b52 | 401 | this.emit('packet', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 402 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 403 | |
Osamu Nakamura |
0:a40b9a259b52 | 404 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 405 | * Called upon socket error. |
Osamu Nakamura |
0:a40b9a259b52 | 406 | * |
Osamu Nakamura |
0:a40b9a259b52 | 407 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 408 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 409 | |
Osamu Nakamura |
0:a40b9a259b52 | 410 | Manager.prototype.onerror = function(err){ |
Osamu Nakamura |
0:a40b9a259b52 | 411 | debug('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 412 | this.emitAll('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 413 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 414 | |
Osamu Nakamura |
0:a40b9a259b52 | 415 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 416 | * Creates a new socket for the given `nsp`. |
Osamu Nakamura |
0:a40b9a259b52 | 417 | * |
Osamu Nakamura |
0:a40b9a259b52 | 418 | * @return {Socket} |
Osamu Nakamura |
0:a40b9a259b52 | 419 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 420 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 421 | |
Osamu Nakamura |
0:a40b9a259b52 | 422 | Manager.prototype.socket = function(nsp){ |
Osamu Nakamura |
0:a40b9a259b52 | 423 | var socket = this.nsps[nsp]; |
Osamu Nakamura |
0:a40b9a259b52 | 424 | if (!socket) { |
Osamu Nakamura |
0:a40b9a259b52 | 425 | socket = new Socket(this, nsp); |
Osamu Nakamura |
0:a40b9a259b52 | 426 | this.nsps[nsp] = socket; |
Osamu Nakamura |
0:a40b9a259b52 | 427 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 428 | socket.on('connect', function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 429 | socket.id = self.engine.id; |
Osamu Nakamura |
0:a40b9a259b52 | 430 | if (!~indexOf(self.connected, socket)) { |
Osamu Nakamura |
0:a40b9a259b52 | 431 | self.connected.push(socket); |
Osamu Nakamura |
0:a40b9a259b52 | 432 | } |
Osamu Nakamura |
0:a40b9a259b52 | 433 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 434 | } |
Osamu Nakamura |
0:a40b9a259b52 | 435 | return socket; |
Osamu Nakamura |
0:a40b9a259b52 | 436 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 437 | |
Osamu Nakamura |
0:a40b9a259b52 | 438 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 439 | * Called upon a socket close. |
Osamu Nakamura |
0:a40b9a259b52 | 440 | * |
Osamu Nakamura |
0:a40b9a259b52 | 441 | * @param {Socket} socket |
Osamu Nakamura |
0:a40b9a259b52 | 442 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 443 | |
Osamu Nakamura |
0:a40b9a259b52 | 444 | Manager.prototype.destroy = function(socket){ |
Osamu Nakamura |
0:a40b9a259b52 | 445 | var index = indexOf(this.connected, socket); |
Osamu Nakamura |
0:a40b9a259b52 | 446 | if (~index) this.connected.splice(index, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 447 | if (this.connected.length) return; |
Osamu Nakamura |
0:a40b9a259b52 | 448 | |
Osamu Nakamura |
0:a40b9a259b52 | 449 | this.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 450 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 451 | |
Osamu Nakamura |
0:a40b9a259b52 | 452 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 453 | * Writes a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 454 | * |
Osamu Nakamura |
0:a40b9a259b52 | 455 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 456 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 457 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 458 | |
Osamu Nakamura |
0:a40b9a259b52 | 459 | Manager.prototype.packet = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 460 | debug('writing packet %j', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 461 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 462 | |
Osamu Nakamura |
0:a40b9a259b52 | 463 | if (!self.encoding) { |
Osamu Nakamura |
0:a40b9a259b52 | 464 | // encode, then write to engine with result |
Osamu Nakamura |
0:a40b9a259b52 | 465 | self.encoding = true; |
Osamu Nakamura |
0:a40b9a259b52 | 466 | this.encoder.encode(packet, function(encodedPackets) { |
Osamu Nakamura |
0:a40b9a259b52 | 467 | for (var i = 0; i < encodedPackets.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 468 | self.engine.write(encodedPackets[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 469 | } |
Osamu Nakamura |
0:a40b9a259b52 | 470 | self.encoding = false; |
Osamu Nakamura |
0:a40b9a259b52 | 471 | self.processPacketQueue(); |
Osamu Nakamura |
0:a40b9a259b52 | 472 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 473 | } else { // add packet to the queue |
Osamu Nakamura |
0:a40b9a259b52 | 474 | self.packetBuffer.push(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 475 | } |
Osamu Nakamura |
0:a40b9a259b52 | 476 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 477 | |
Osamu Nakamura |
0:a40b9a259b52 | 478 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 479 | * If packet buffer is non-empty, begins encoding the |
Osamu Nakamura |
0:a40b9a259b52 | 480 | * next packet in line. |
Osamu Nakamura |
0:a40b9a259b52 | 481 | * |
Osamu Nakamura |
0:a40b9a259b52 | 482 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 483 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 484 | |
Osamu Nakamura |
0:a40b9a259b52 | 485 | Manager.prototype.processPacketQueue = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 486 | if (this.packetBuffer.length > 0 && !this.encoding) { |
Osamu Nakamura |
0:a40b9a259b52 | 487 | var pack = this.packetBuffer.shift(); |
Osamu Nakamura |
0:a40b9a259b52 | 488 | this.packet(pack); |
Osamu Nakamura |
0:a40b9a259b52 | 489 | } |
Osamu Nakamura |
0:a40b9a259b52 | 490 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 491 | |
Osamu Nakamura |
0:a40b9a259b52 | 492 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 493 | * Clean up transport subscriptions and packet buffer. |
Osamu Nakamura |
0:a40b9a259b52 | 494 | * |
Osamu Nakamura |
0:a40b9a259b52 | 495 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 496 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 497 | |
Osamu Nakamura |
0:a40b9a259b52 | 498 | Manager.prototype.cleanup = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 499 | var sub; |
Osamu Nakamura |
0:a40b9a259b52 | 500 | while (sub = this.subs.shift()) sub.destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 501 | |
Osamu Nakamura |
0:a40b9a259b52 | 502 | this.packetBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 503 | this.encoding = false; |
Osamu Nakamura |
0:a40b9a259b52 | 504 | |
Osamu Nakamura |
0:a40b9a259b52 | 505 | this.decoder.destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 506 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 507 | |
Osamu Nakamura |
0:a40b9a259b52 | 508 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 509 | * Close the current socket. |
Osamu Nakamura |
0:a40b9a259b52 | 510 | * |
Osamu Nakamura |
0:a40b9a259b52 | 511 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 512 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 513 | |
Osamu Nakamura |
0:a40b9a259b52 | 514 | Manager.prototype.close = |
Osamu Nakamura |
0:a40b9a259b52 | 515 | Manager.prototype.disconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 516 | this.skipReconnect = true; |
Osamu Nakamura |
0:a40b9a259b52 | 517 | this.backoff.reset(); |
Osamu Nakamura |
0:a40b9a259b52 | 518 | this.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 519 | this.engine && this.engine.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 520 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 521 | |
Osamu Nakamura |
0:a40b9a259b52 | 522 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 523 | * Called upon engine close. |
Osamu Nakamura |
0:a40b9a259b52 | 524 | * |
Osamu Nakamura |
0:a40b9a259b52 | 525 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 526 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 527 | |
Osamu Nakamura |
0:a40b9a259b52 | 528 | Manager.prototype.onclose = function(reason){ |
Osamu Nakamura |
0:a40b9a259b52 | 529 | debug('close'); |
Osamu Nakamura |
0:a40b9a259b52 | 530 | this.cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 531 | this.backoff.reset(); |
Osamu Nakamura |
0:a40b9a259b52 | 532 | this.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 533 | this.emit('close', reason); |
Osamu Nakamura |
0:a40b9a259b52 | 534 | if (this._reconnection && !this.skipReconnect) { |
Osamu Nakamura |
0:a40b9a259b52 | 535 | this.reconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 536 | } |
Osamu Nakamura |
0:a40b9a259b52 | 537 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 538 | |
Osamu Nakamura |
0:a40b9a259b52 | 539 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 540 | * Attempt a reconnection. |
Osamu Nakamura |
0:a40b9a259b52 | 541 | * |
Osamu Nakamura |
0:a40b9a259b52 | 542 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 543 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 544 | |
Osamu Nakamura |
0:a40b9a259b52 | 545 | Manager.prototype.reconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 546 | if (this.reconnecting || this.skipReconnect) return this; |
Osamu Nakamura |
0:a40b9a259b52 | 547 | |
Osamu Nakamura |
0:a40b9a259b52 | 548 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 549 | |
Osamu Nakamura |
0:a40b9a259b52 | 550 | if (this.backoff.attempts >= this._reconnectionAttempts) { |
Osamu Nakamura |
0:a40b9a259b52 | 551 | debug('reconnect failed'); |
Osamu Nakamura |
0:a40b9a259b52 | 552 | this.backoff.reset(); |
Osamu Nakamura |
0:a40b9a259b52 | 553 | this.emitAll('reconnect_failed'); |
Osamu Nakamura |
0:a40b9a259b52 | 554 | this.reconnecting = false; |
Osamu Nakamura |
0:a40b9a259b52 | 555 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 556 | var delay = this.backoff.duration(); |
Osamu Nakamura |
0:a40b9a259b52 | 557 | debug('will wait %dms before reconnect attempt', delay); |
Osamu Nakamura |
0:a40b9a259b52 | 558 | |
Osamu Nakamura |
0:a40b9a259b52 | 559 | this.reconnecting = true; |
Osamu Nakamura |
0:a40b9a259b52 | 560 | var timer = setTimeout(function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 561 | if (self.skipReconnect) return; |
Osamu Nakamura |
0:a40b9a259b52 | 562 | |
Osamu Nakamura |
0:a40b9a259b52 | 563 | debug('attempting reconnect'); |
Osamu Nakamura |
0:a40b9a259b52 | 564 | self.emitAll('reconnect_attempt', self.backoff.attempts); |
Osamu Nakamura |
0:a40b9a259b52 | 565 | self.emitAll('reconnecting', self.backoff.attempts); |
Osamu Nakamura |
0:a40b9a259b52 | 566 | |
Osamu Nakamura |
0:a40b9a259b52 | 567 | // check again for the case socket closed in above events |
Osamu Nakamura |
0:a40b9a259b52 | 568 | if (self.skipReconnect) return; |
Osamu Nakamura |
0:a40b9a259b52 | 569 | |
Osamu Nakamura |
0:a40b9a259b52 | 570 | self.open(function(err){ |
Osamu Nakamura |
0:a40b9a259b52 | 571 | if (err) { |
Osamu Nakamura |
0:a40b9a259b52 | 572 | debug('reconnect attempt error'); |
Osamu Nakamura |
0:a40b9a259b52 | 573 | self.reconnecting = false; |
Osamu Nakamura |
0:a40b9a259b52 | 574 | self.reconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 575 | self.emitAll('reconnect_error', err.data); |
Osamu Nakamura |
0:a40b9a259b52 | 576 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 577 | debug('reconnect success'); |
Osamu Nakamura |
0:a40b9a259b52 | 578 | self.onreconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 579 | } |
Osamu Nakamura |
0:a40b9a259b52 | 580 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 581 | }, delay); |
Osamu Nakamura |
0:a40b9a259b52 | 582 | |
Osamu Nakamura |
0:a40b9a259b52 | 583 | this.subs.push({ |
Osamu Nakamura |
0:a40b9a259b52 | 584 | destroy: function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 585 | clearTimeout(timer); |
Osamu Nakamura |
0:a40b9a259b52 | 586 | } |
Osamu Nakamura |
0:a40b9a259b52 | 587 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 588 | } |
Osamu Nakamura |
0:a40b9a259b52 | 589 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 590 | |
Osamu Nakamura |
0:a40b9a259b52 | 591 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 592 | * Called upon successful reconnect. |
Osamu Nakamura |
0:a40b9a259b52 | 593 | * |
Osamu Nakamura |
0:a40b9a259b52 | 594 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 595 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 596 | |
Osamu Nakamura |
0:a40b9a259b52 | 597 | Manager.prototype.onreconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 598 | var attempt = this.backoff.attempts; |
Osamu Nakamura |
0:a40b9a259b52 | 599 | this.reconnecting = false; |
Osamu Nakamura |
0:a40b9a259b52 | 600 | this.backoff.reset(); |
Osamu Nakamura |
0:a40b9a259b52 | 601 | this.updateSocketIds(); |
Osamu Nakamura |
0:a40b9a259b52 | 602 | this.emitAll('reconnect', attempt); |
Osamu Nakamura |
0:a40b9a259b52 | 603 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 604 | |
Osamu Nakamura |
0:a40b9a259b52 | 605 | },{"./on":4,"./socket":5,"./url":6,"backo2":7,"component-bind":8,"component-emitter":9,"debug":10,"engine.io-client":11,"indexof":42,"object-component":43,"socket.io-parser":46}],4:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 606 | |
Osamu Nakamura |
0:a40b9a259b52 | 607 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 608 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 609 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 610 | |
Osamu Nakamura |
0:a40b9a259b52 | 611 | module.exports = on; |
Osamu Nakamura |
0:a40b9a259b52 | 612 | |
Osamu Nakamura |
0:a40b9a259b52 | 613 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 614 | * Helper for subscriptions. |
Osamu Nakamura |
0:a40b9a259b52 | 615 | * |
Osamu Nakamura |
0:a40b9a259b52 | 616 | * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter` |
Osamu Nakamura |
0:a40b9a259b52 | 617 | * @param {String} event name |
Osamu Nakamura |
0:a40b9a259b52 | 618 | * @param {Function} callback |
Osamu Nakamura |
0:a40b9a259b52 | 619 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 620 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 621 | |
Osamu Nakamura |
0:a40b9a259b52 | 622 | function on(obj, ev, fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 623 | obj.on(ev, fn); |
Osamu Nakamura |
0:a40b9a259b52 | 624 | return { |
Osamu Nakamura |
0:a40b9a259b52 | 625 | destroy: function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 626 | obj.removeListener(ev, fn); |
Osamu Nakamura |
0:a40b9a259b52 | 627 | } |
Osamu Nakamura |
0:a40b9a259b52 | 628 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 629 | } |
Osamu Nakamura |
0:a40b9a259b52 | 630 | |
Osamu Nakamura |
0:a40b9a259b52 | 631 | },{}],5:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 632 | |
Osamu Nakamura |
0:a40b9a259b52 | 633 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 634 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 635 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 636 | |
Osamu Nakamura |
0:a40b9a259b52 | 637 | var parser = _dereq_('socket.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 638 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 639 | var toArray = _dereq_('to-array'); |
Osamu Nakamura |
0:a40b9a259b52 | 640 | var on = _dereq_('./on'); |
Osamu Nakamura |
0:a40b9a259b52 | 641 | var bind = _dereq_('component-bind'); |
Osamu Nakamura |
0:a40b9a259b52 | 642 | var debug = _dereq_('debug')('socket.io-client:socket'); |
Osamu Nakamura |
0:a40b9a259b52 | 643 | var hasBin = _dereq_('has-binary'); |
Osamu Nakamura |
0:a40b9a259b52 | 644 | |
Osamu Nakamura |
0:a40b9a259b52 | 645 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 646 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 647 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 648 | |
Osamu Nakamura |
0:a40b9a259b52 | 649 | module.exports = exports = Socket; |
Osamu Nakamura |
0:a40b9a259b52 | 650 | |
Osamu Nakamura |
0:a40b9a259b52 | 651 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 652 | * Internal events (blacklisted). |
Osamu Nakamura |
0:a40b9a259b52 | 653 | * These events can't be emitted by the user. |
Osamu Nakamura |
0:a40b9a259b52 | 654 | * |
Osamu Nakamura |
0:a40b9a259b52 | 655 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 656 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 657 | |
Osamu Nakamura |
0:a40b9a259b52 | 658 | var events = { |
Osamu Nakamura |
0:a40b9a259b52 | 659 | connect: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 660 | connect_error: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 661 | connect_timeout: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 662 | disconnect: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 663 | error: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 664 | reconnect: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 665 | reconnect_attempt: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 666 | reconnect_failed: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 667 | reconnect_error: 1, |
Osamu Nakamura |
0:a40b9a259b52 | 668 | reconnecting: 1 |
Osamu Nakamura |
0:a40b9a259b52 | 669 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 670 | |
Osamu Nakamura |
0:a40b9a259b52 | 671 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 672 | * Shortcut to `Emitter#emit`. |
Osamu Nakamura |
0:a40b9a259b52 | 673 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 674 | |
Osamu Nakamura |
0:a40b9a259b52 | 675 | var emit = Emitter.prototype.emit; |
Osamu Nakamura |
0:a40b9a259b52 | 676 | |
Osamu Nakamura |
0:a40b9a259b52 | 677 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 678 | * `Socket` constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 679 | * |
Osamu Nakamura |
0:a40b9a259b52 | 680 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 681 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 682 | |
Osamu Nakamura |
0:a40b9a259b52 | 683 | function Socket(io, nsp){ |
Osamu Nakamura |
0:a40b9a259b52 | 684 | this.io = io; |
Osamu Nakamura |
0:a40b9a259b52 | 685 | this.nsp = nsp; |
Osamu Nakamura |
0:a40b9a259b52 | 686 | this.json = this; // compat |
Osamu Nakamura |
0:a40b9a259b52 | 687 | this.ids = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 688 | this.acks = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 689 | if (this.io.autoConnect) this.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 690 | this.receiveBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 691 | this.sendBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 692 | this.connected = false; |
Osamu Nakamura |
0:a40b9a259b52 | 693 | this.disconnected = true; |
Osamu Nakamura |
0:a40b9a259b52 | 694 | } |
Osamu Nakamura |
0:a40b9a259b52 | 695 | |
Osamu Nakamura |
0:a40b9a259b52 | 696 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 697 | * Mix in `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 698 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 699 | |
Osamu Nakamura |
0:a40b9a259b52 | 700 | Emitter(Socket.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 701 | |
Osamu Nakamura |
0:a40b9a259b52 | 702 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 703 | * Subscribe to open, close and packet events |
Osamu Nakamura |
0:a40b9a259b52 | 704 | * |
Osamu Nakamura |
0:a40b9a259b52 | 705 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 706 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 707 | |
Osamu Nakamura |
0:a40b9a259b52 | 708 | Socket.prototype.subEvents = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 709 | if (this.subs) return; |
Osamu Nakamura |
0:a40b9a259b52 | 710 | |
Osamu Nakamura |
0:a40b9a259b52 | 711 | var io = this.io; |
Osamu Nakamura |
0:a40b9a259b52 | 712 | this.subs = [ |
Osamu Nakamura |
0:a40b9a259b52 | 713 | on(io, 'open', bind(this, 'onopen')), |
Osamu Nakamura |
0:a40b9a259b52 | 714 | on(io, 'packet', bind(this, 'onpacket')), |
Osamu Nakamura |
0:a40b9a259b52 | 715 | on(io, 'close', bind(this, 'onclose')) |
Osamu Nakamura |
0:a40b9a259b52 | 716 | ]; |
Osamu Nakamura |
0:a40b9a259b52 | 717 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 718 | |
Osamu Nakamura |
0:a40b9a259b52 | 719 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 720 | * "Opens" the socket. |
Osamu Nakamura |
0:a40b9a259b52 | 721 | * |
Osamu Nakamura |
0:a40b9a259b52 | 722 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 723 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 724 | |
Osamu Nakamura |
0:a40b9a259b52 | 725 | Socket.prototype.open = |
Osamu Nakamura |
0:a40b9a259b52 | 726 | Socket.prototype.connect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 727 | if (this.connected) return this; |
Osamu Nakamura |
0:a40b9a259b52 | 728 | |
Osamu Nakamura |
0:a40b9a259b52 | 729 | this.subEvents(); |
Osamu Nakamura |
0:a40b9a259b52 | 730 | this.io.open(); // ensure open |
Osamu Nakamura |
0:a40b9a259b52 | 731 | if ('open' == this.io.readyState) this.onopen(); |
Osamu Nakamura |
0:a40b9a259b52 | 732 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 733 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 734 | |
Osamu Nakamura |
0:a40b9a259b52 | 735 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 736 | * Sends a `message` event. |
Osamu Nakamura |
0:a40b9a259b52 | 737 | * |
Osamu Nakamura |
0:a40b9a259b52 | 738 | * @return {Socket} self |
Osamu Nakamura |
0:a40b9a259b52 | 739 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 740 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 741 | |
Osamu Nakamura |
0:a40b9a259b52 | 742 | Socket.prototype.send = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 743 | var args = toArray(arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 744 | args.unshift('message'); |
Osamu Nakamura |
0:a40b9a259b52 | 745 | this.emit.apply(this, args); |
Osamu Nakamura |
0:a40b9a259b52 | 746 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 747 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 748 | |
Osamu Nakamura |
0:a40b9a259b52 | 749 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 750 | * Override `emit`. |
Osamu Nakamura |
0:a40b9a259b52 | 751 | * If the event is in `events`, it's emitted normally. |
Osamu Nakamura |
0:a40b9a259b52 | 752 | * |
Osamu Nakamura |
0:a40b9a259b52 | 753 | * @param {String} event name |
Osamu Nakamura |
0:a40b9a259b52 | 754 | * @return {Socket} self |
Osamu Nakamura |
0:a40b9a259b52 | 755 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 756 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 757 | |
Osamu Nakamura |
0:a40b9a259b52 | 758 | Socket.prototype.emit = function(ev){ |
Osamu Nakamura |
0:a40b9a259b52 | 759 | if (events.hasOwnProperty(ev)) { |
Osamu Nakamura |
0:a40b9a259b52 | 760 | emit.apply(this, arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 761 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 762 | } |
Osamu Nakamura |
0:a40b9a259b52 | 763 | |
Osamu Nakamura |
0:a40b9a259b52 | 764 | var args = toArray(arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 765 | var parserType = parser.EVENT; // default |
Osamu Nakamura |
0:a40b9a259b52 | 766 | if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary |
Osamu Nakamura |
0:a40b9a259b52 | 767 | var packet = { type: parserType, data: args }; |
Osamu Nakamura |
0:a40b9a259b52 | 768 | |
Osamu Nakamura |
0:a40b9a259b52 | 769 | // event ack callback |
Osamu Nakamura |
0:a40b9a259b52 | 770 | if ('function' == typeof args[args.length - 1]) { |
Osamu Nakamura |
0:a40b9a259b52 | 771 | debug('emitting packet with ack id %d', this.ids); |
Osamu Nakamura |
0:a40b9a259b52 | 772 | this.acks[this.ids] = args.pop(); |
Osamu Nakamura |
0:a40b9a259b52 | 773 | packet.id = this.ids++; |
Osamu Nakamura |
0:a40b9a259b52 | 774 | } |
Osamu Nakamura |
0:a40b9a259b52 | 775 | |
Osamu Nakamura |
0:a40b9a259b52 | 776 | if (this.connected) { |
Osamu Nakamura |
0:a40b9a259b52 | 777 | this.packet(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 778 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 779 | this.sendBuffer.push(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 780 | } |
Osamu Nakamura |
0:a40b9a259b52 | 781 | |
Osamu Nakamura |
0:a40b9a259b52 | 782 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 783 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 784 | |
Osamu Nakamura |
0:a40b9a259b52 | 785 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 786 | * Sends a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 787 | * |
Osamu Nakamura |
0:a40b9a259b52 | 788 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 789 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 790 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 791 | |
Osamu Nakamura |
0:a40b9a259b52 | 792 | Socket.prototype.packet = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 793 | packet.nsp = this.nsp; |
Osamu Nakamura |
0:a40b9a259b52 | 794 | this.io.packet(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 795 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 796 | |
Osamu Nakamura |
0:a40b9a259b52 | 797 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 798 | * Called upon engine `open`. |
Osamu Nakamura |
0:a40b9a259b52 | 799 | * |
Osamu Nakamura |
0:a40b9a259b52 | 800 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 801 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 802 | |
Osamu Nakamura |
0:a40b9a259b52 | 803 | Socket.prototype.onopen = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 804 | debug('transport is open - connecting'); |
Osamu Nakamura |
0:a40b9a259b52 | 805 | |
Osamu Nakamura |
0:a40b9a259b52 | 806 | // write connect packet if necessary |
Osamu Nakamura |
0:a40b9a259b52 | 807 | if ('/' != this.nsp) { |
Osamu Nakamura |
0:a40b9a259b52 | 808 | this.packet({ type: parser.CONNECT }); |
Osamu Nakamura |
0:a40b9a259b52 | 809 | } |
Osamu Nakamura |
0:a40b9a259b52 | 810 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 811 | |
Osamu Nakamura |
0:a40b9a259b52 | 812 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 813 | * Called upon engine `close`. |
Osamu Nakamura |
0:a40b9a259b52 | 814 | * |
Osamu Nakamura |
0:a40b9a259b52 | 815 | * @param {String} reason |
Osamu Nakamura |
0:a40b9a259b52 | 816 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 817 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 818 | |
Osamu Nakamura |
0:a40b9a259b52 | 819 | Socket.prototype.onclose = function(reason){ |
Osamu Nakamura |
0:a40b9a259b52 | 820 | debug('close (%s)', reason); |
Osamu Nakamura |
0:a40b9a259b52 | 821 | this.connected = false; |
Osamu Nakamura |
0:a40b9a259b52 | 822 | this.disconnected = true; |
Osamu Nakamura |
0:a40b9a259b52 | 823 | delete this.id; |
Osamu Nakamura |
0:a40b9a259b52 | 824 | this.emit('disconnect', reason); |
Osamu Nakamura |
0:a40b9a259b52 | 825 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 826 | |
Osamu Nakamura |
0:a40b9a259b52 | 827 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 828 | * Called with socket packet. |
Osamu Nakamura |
0:a40b9a259b52 | 829 | * |
Osamu Nakamura |
0:a40b9a259b52 | 830 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 831 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 832 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 833 | |
Osamu Nakamura |
0:a40b9a259b52 | 834 | Socket.prototype.onpacket = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 835 | if (packet.nsp != this.nsp) return; |
Osamu Nakamura |
0:a40b9a259b52 | 836 | |
Osamu Nakamura |
0:a40b9a259b52 | 837 | switch (packet.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 838 | case parser.CONNECT: |
Osamu Nakamura |
0:a40b9a259b52 | 839 | this.onconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 840 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 841 | |
Osamu Nakamura |
0:a40b9a259b52 | 842 | case parser.EVENT: |
Osamu Nakamura |
0:a40b9a259b52 | 843 | this.onevent(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 844 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 845 | |
Osamu Nakamura |
0:a40b9a259b52 | 846 | case parser.BINARY_EVENT: |
Osamu Nakamura |
0:a40b9a259b52 | 847 | this.onevent(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 848 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 849 | |
Osamu Nakamura |
0:a40b9a259b52 | 850 | case parser.ACK: |
Osamu Nakamura |
0:a40b9a259b52 | 851 | this.onack(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 852 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 853 | |
Osamu Nakamura |
0:a40b9a259b52 | 854 | case parser.BINARY_ACK: |
Osamu Nakamura |
0:a40b9a259b52 | 855 | this.onack(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 856 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 857 | |
Osamu Nakamura |
0:a40b9a259b52 | 858 | case parser.DISCONNECT: |
Osamu Nakamura |
0:a40b9a259b52 | 859 | this.ondisconnect(); |
Osamu Nakamura |
0:a40b9a259b52 | 860 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 861 | |
Osamu Nakamura |
0:a40b9a259b52 | 862 | case parser.ERROR: |
Osamu Nakamura |
0:a40b9a259b52 | 863 | this.emit('error', packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 864 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 865 | } |
Osamu Nakamura |
0:a40b9a259b52 | 866 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 867 | |
Osamu Nakamura |
0:a40b9a259b52 | 868 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 869 | * Called upon a server event. |
Osamu Nakamura |
0:a40b9a259b52 | 870 | * |
Osamu Nakamura |
0:a40b9a259b52 | 871 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 872 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 873 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 874 | |
Osamu Nakamura |
0:a40b9a259b52 | 875 | Socket.prototype.onevent = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 876 | var args = packet.data || []; |
Osamu Nakamura |
0:a40b9a259b52 | 877 | debug('emitting event %j', args); |
Osamu Nakamura |
0:a40b9a259b52 | 878 | |
Osamu Nakamura |
0:a40b9a259b52 | 879 | if (null != packet.id) { |
Osamu Nakamura |
0:a40b9a259b52 | 880 | debug('attaching ack callback to event'); |
Osamu Nakamura |
0:a40b9a259b52 | 881 | args.push(this.ack(packet.id)); |
Osamu Nakamura |
0:a40b9a259b52 | 882 | } |
Osamu Nakamura |
0:a40b9a259b52 | 883 | |
Osamu Nakamura |
0:a40b9a259b52 | 884 | if (this.connected) { |
Osamu Nakamura |
0:a40b9a259b52 | 885 | emit.apply(this, args); |
Osamu Nakamura |
0:a40b9a259b52 | 886 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 887 | this.receiveBuffer.push(args); |
Osamu Nakamura |
0:a40b9a259b52 | 888 | } |
Osamu Nakamura |
0:a40b9a259b52 | 889 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 890 | |
Osamu Nakamura |
0:a40b9a259b52 | 891 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 892 | * Produces an ack callback to emit with an event. |
Osamu Nakamura |
0:a40b9a259b52 | 893 | * |
Osamu Nakamura |
0:a40b9a259b52 | 894 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 895 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 896 | |
Osamu Nakamura |
0:a40b9a259b52 | 897 | Socket.prototype.ack = function(id){ |
Osamu Nakamura |
0:a40b9a259b52 | 898 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 899 | var sent = false; |
Osamu Nakamura |
0:a40b9a259b52 | 900 | return function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 901 | // prevent double callbacks |
Osamu Nakamura |
0:a40b9a259b52 | 902 | if (sent) return; |
Osamu Nakamura |
0:a40b9a259b52 | 903 | sent = true; |
Osamu Nakamura |
0:a40b9a259b52 | 904 | var args = toArray(arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 905 | debug('sending ack %j', args); |
Osamu Nakamura |
0:a40b9a259b52 | 906 | |
Osamu Nakamura |
0:a40b9a259b52 | 907 | var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK; |
Osamu Nakamura |
0:a40b9a259b52 | 908 | self.packet({ |
Osamu Nakamura |
0:a40b9a259b52 | 909 | type: type, |
Osamu Nakamura |
0:a40b9a259b52 | 910 | id: id, |
Osamu Nakamura |
0:a40b9a259b52 | 911 | data: args |
Osamu Nakamura |
0:a40b9a259b52 | 912 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 913 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 914 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 915 | |
Osamu Nakamura |
0:a40b9a259b52 | 916 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 917 | * Called upon a server acknowlegement. |
Osamu Nakamura |
0:a40b9a259b52 | 918 | * |
Osamu Nakamura |
0:a40b9a259b52 | 919 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 920 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 921 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 922 | |
Osamu Nakamura |
0:a40b9a259b52 | 923 | Socket.prototype.onack = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 924 | debug('calling ack %s with %j', packet.id, packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 925 | var fn = this.acks[packet.id]; |
Osamu Nakamura |
0:a40b9a259b52 | 926 | fn.apply(this, packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 927 | delete this.acks[packet.id]; |
Osamu Nakamura |
0:a40b9a259b52 | 928 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 929 | |
Osamu Nakamura |
0:a40b9a259b52 | 930 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 931 | * Called upon server connect. |
Osamu Nakamura |
0:a40b9a259b52 | 932 | * |
Osamu Nakamura |
0:a40b9a259b52 | 933 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 934 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 935 | |
Osamu Nakamura |
0:a40b9a259b52 | 936 | Socket.prototype.onconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 937 | this.connected = true; |
Osamu Nakamura |
0:a40b9a259b52 | 938 | this.disconnected = false; |
Osamu Nakamura |
0:a40b9a259b52 | 939 | this.emit('connect'); |
Osamu Nakamura |
0:a40b9a259b52 | 940 | this.emitBuffered(); |
Osamu Nakamura |
0:a40b9a259b52 | 941 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 942 | |
Osamu Nakamura |
0:a40b9a259b52 | 943 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 944 | * Emit buffered events (received and emitted). |
Osamu Nakamura |
0:a40b9a259b52 | 945 | * |
Osamu Nakamura |
0:a40b9a259b52 | 946 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 947 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 948 | |
Osamu Nakamura |
0:a40b9a259b52 | 949 | Socket.prototype.emitBuffered = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 950 | var i; |
Osamu Nakamura |
0:a40b9a259b52 | 951 | for (i = 0; i < this.receiveBuffer.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 952 | emit.apply(this, this.receiveBuffer[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 953 | } |
Osamu Nakamura |
0:a40b9a259b52 | 954 | this.receiveBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 955 | |
Osamu Nakamura |
0:a40b9a259b52 | 956 | for (i = 0; i < this.sendBuffer.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 957 | this.packet(this.sendBuffer[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 958 | } |
Osamu Nakamura |
0:a40b9a259b52 | 959 | this.sendBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 960 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 961 | |
Osamu Nakamura |
0:a40b9a259b52 | 962 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 963 | * Called upon server disconnect. |
Osamu Nakamura |
0:a40b9a259b52 | 964 | * |
Osamu Nakamura |
0:a40b9a259b52 | 965 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 966 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 967 | |
Osamu Nakamura |
0:a40b9a259b52 | 968 | Socket.prototype.ondisconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 969 | debug('server disconnect (%s)', this.nsp); |
Osamu Nakamura |
0:a40b9a259b52 | 970 | this.destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 971 | this.onclose('io server disconnect'); |
Osamu Nakamura |
0:a40b9a259b52 | 972 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 973 | |
Osamu Nakamura |
0:a40b9a259b52 | 974 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 975 | * Called upon forced client/server side disconnections, |
Osamu Nakamura |
0:a40b9a259b52 | 976 | * this method ensures the manager stops tracking us and |
Osamu Nakamura |
0:a40b9a259b52 | 977 | * that reconnections don't get triggered for this. |
Osamu Nakamura |
0:a40b9a259b52 | 978 | * |
Osamu Nakamura |
0:a40b9a259b52 | 979 | * @api private. |
Osamu Nakamura |
0:a40b9a259b52 | 980 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 981 | |
Osamu Nakamura |
0:a40b9a259b52 | 982 | Socket.prototype.destroy = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 983 | if (this.subs) { |
Osamu Nakamura |
0:a40b9a259b52 | 984 | // clean subscriptions to avoid reconnections |
Osamu Nakamura |
0:a40b9a259b52 | 985 | for (var i = 0; i < this.subs.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 986 | this.subs[i].destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 987 | } |
Osamu Nakamura |
0:a40b9a259b52 | 988 | this.subs = null; |
Osamu Nakamura |
0:a40b9a259b52 | 989 | } |
Osamu Nakamura |
0:a40b9a259b52 | 990 | |
Osamu Nakamura |
0:a40b9a259b52 | 991 | this.io.destroy(this); |
Osamu Nakamura |
0:a40b9a259b52 | 992 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 993 | |
Osamu Nakamura |
0:a40b9a259b52 | 994 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 995 | * Disconnects the socket manually. |
Osamu Nakamura |
0:a40b9a259b52 | 996 | * |
Osamu Nakamura |
0:a40b9a259b52 | 997 | * @return {Socket} self |
Osamu Nakamura |
0:a40b9a259b52 | 998 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 999 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1000 | |
Osamu Nakamura |
0:a40b9a259b52 | 1001 | Socket.prototype.close = |
Osamu Nakamura |
0:a40b9a259b52 | 1002 | Socket.prototype.disconnect = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1003 | if (this.connected) { |
Osamu Nakamura |
0:a40b9a259b52 | 1004 | debug('performing disconnect (%s)', this.nsp); |
Osamu Nakamura |
0:a40b9a259b52 | 1005 | this.packet({ type: parser.DISCONNECT }); |
Osamu Nakamura |
0:a40b9a259b52 | 1006 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1007 | |
Osamu Nakamura |
0:a40b9a259b52 | 1008 | // remove socket from pool |
Osamu Nakamura |
0:a40b9a259b52 | 1009 | this.destroy(); |
Osamu Nakamura |
0:a40b9a259b52 | 1010 | |
Osamu Nakamura |
0:a40b9a259b52 | 1011 | if (this.connected) { |
Osamu Nakamura |
0:a40b9a259b52 | 1012 | // fire events |
Osamu Nakamura |
0:a40b9a259b52 | 1013 | this.onclose('io client disconnect'); |
Osamu Nakamura |
0:a40b9a259b52 | 1014 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1015 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1016 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1017 | |
Osamu Nakamura |
0:a40b9a259b52 | 1018 | },{"./on":4,"component-bind":8,"component-emitter":9,"debug":10,"has-binary":38,"socket.io-parser":46,"to-array":50}],6:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1019 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 1020 | |
Osamu Nakamura |
0:a40b9a259b52 | 1021 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1022 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 1023 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1024 | |
Osamu Nakamura |
0:a40b9a259b52 | 1025 | var parseuri = _dereq_('parseuri'); |
Osamu Nakamura |
0:a40b9a259b52 | 1026 | var debug = _dereq_('debug')('socket.io-client:url'); |
Osamu Nakamura |
0:a40b9a259b52 | 1027 | |
Osamu Nakamura |
0:a40b9a259b52 | 1028 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1029 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 1030 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1031 | |
Osamu Nakamura |
0:a40b9a259b52 | 1032 | module.exports = url; |
Osamu Nakamura |
0:a40b9a259b52 | 1033 | |
Osamu Nakamura |
0:a40b9a259b52 | 1034 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1035 | * URL parser. |
Osamu Nakamura |
0:a40b9a259b52 | 1036 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1037 | * @param {String} url |
Osamu Nakamura |
0:a40b9a259b52 | 1038 | * @param {Object} An object meant to mimic window.location. |
Osamu Nakamura |
0:a40b9a259b52 | 1039 | * Defaults to window.location. |
Osamu Nakamura |
0:a40b9a259b52 | 1040 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1041 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1042 | |
Osamu Nakamura |
0:a40b9a259b52 | 1043 | function url(uri, loc){ |
Osamu Nakamura |
0:a40b9a259b52 | 1044 | var obj = uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1045 | |
Osamu Nakamura |
0:a40b9a259b52 | 1046 | // default to window.location |
Osamu Nakamura |
0:a40b9a259b52 | 1047 | var loc = loc || global.location; |
Osamu Nakamura |
0:a40b9a259b52 | 1048 | if (null == uri) uri = loc.protocol + '//' + loc.host; |
Osamu Nakamura |
0:a40b9a259b52 | 1049 | |
Osamu Nakamura |
0:a40b9a259b52 | 1050 | // relative path support |
Osamu Nakamura |
0:a40b9a259b52 | 1051 | if ('string' == typeof uri) { |
Osamu Nakamura |
0:a40b9a259b52 | 1052 | if ('/' == uri.charAt(0)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1053 | if ('/' == uri.charAt(1)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1054 | uri = loc.protocol + uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1055 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 1056 | uri = loc.hostname + uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1057 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1058 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1059 | |
Osamu Nakamura |
0:a40b9a259b52 | 1060 | if (!/^(https?|wss?):\/\//.test(uri)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1061 | debug('protocol-less url %s', uri); |
Osamu Nakamura |
0:a40b9a259b52 | 1062 | if ('undefined' != typeof loc) { |
Osamu Nakamura |
0:a40b9a259b52 | 1063 | uri = loc.protocol + '//' + uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1064 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 1065 | uri = 'https://' + uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1066 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1067 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1068 | |
Osamu Nakamura |
0:a40b9a259b52 | 1069 | // parse |
Osamu Nakamura |
0:a40b9a259b52 | 1070 | debug('parse %s', uri); |
Osamu Nakamura |
0:a40b9a259b52 | 1071 | obj = parseuri(uri); |
Osamu Nakamura |
0:a40b9a259b52 | 1072 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1073 | |
Osamu Nakamura |
0:a40b9a259b52 | 1074 | // make sure we treat `localhost:80` and `localhost` equally |
Osamu Nakamura |
0:a40b9a259b52 | 1075 | if (!obj.port) { |
Osamu Nakamura |
0:a40b9a259b52 | 1076 | if (/^(http|ws)$/.test(obj.protocol)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1077 | obj.port = '80'; |
Osamu Nakamura |
0:a40b9a259b52 | 1078 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1079 | else if (/^(http|ws)s$/.test(obj.protocol)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1080 | obj.port = '443'; |
Osamu Nakamura |
0:a40b9a259b52 | 1081 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1082 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1083 | |
Osamu Nakamura |
0:a40b9a259b52 | 1084 | obj.path = obj.path || '/'; |
Osamu Nakamura |
0:a40b9a259b52 | 1085 | |
Osamu Nakamura |
0:a40b9a259b52 | 1086 | // define unique id |
Osamu Nakamura |
0:a40b9a259b52 | 1087 | obj.id = obj.protocol + '://' + obj.host + ':' + obj.port; |
Osamu Nakamura |
0:a40b9a259b52 | 1088 | // define href |
Osamu Nakamura |
0:a40b9a259b52 | 1089 | obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port)); |
Osamu Nakamura |
0:a40b9a259b52 | 1090 | |
Osamu Nakamura |
0:a40b9a259b52 | 1091 | return obj; |
Osamu Nakamura |
0:a40b9a259b52 | 1092 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1093 | |
Osamu Nakamura |
0:a40b9a259b52 | 1094 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 1095 | },{"debug":10,"parseuri":44}],7:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1096 | |
Osamu Nakamura |
0:a40b9a259b52 | 1097 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1098 | * Expose `Backoff`. |
Osamu Nakamura |
0:a40b9a259b52 | 1099 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1100 | |
Osamu Nakamura |
0:a40b9a259b52 | 1101 | module.exports = Backoff; |
Osamu Nakamura |
0:a40b9a259b52 | 1102 | |
Osamu Nakamura |
0:a40b9a259b52 | 1103 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1104 | * Initialize backoff timer with `opts`. |
Osamu Nakamura |
0:a40b9a259b52 | 1105 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1106 | * - `min` initial timeout in milliseconds [100] |
Osamu Nakamura |
0:a40b9a259b52 | 1107 | * - `max` max timeout [10000] |
Osamu Nakamura |
0:a40b9a259b52 | 1108 | * - `jitter` [0] |
Osamu Nakamura |
0:a40b9a259b52 | 1109 | * - `factor` [2] |
Osamu Nakamura |
0:a40b9a259b52 | 1110 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1111 | * @param {Object} opts |
Osamu Nakamura |
0:a40b9a259b52 | 1112 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1113 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1114 | |
Osamu Nakamura |
0:a40b9a259b52 | 1115 | function Backoff(opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 1116 | opts = opts || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1117 | this.ms = opts.min || 100; |
Osamu Nakamura |
0:a40b9a259b52 | 1118 | this.max = opts.max || 10000; |
Osamu Nakamura |
0:a40b9a259b52 | 1119 | this.factor = opts.factor || 2; |
Osamu Nakamura |
0:a40b9a259b52 | 1120 | this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; |
Osamu Nakamura |
0:a40b9a259b52 | 1121 | this.attempts = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 1122 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1123 | |
Osamu Nakamura |
0:a40b9a259b52 | 1124 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1125 | * Return the backoff duration. |
Osamu Nakamura |
0:a40b9a259b52 | 1126 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1127 | * @return {Number} |
Osamu Nakamura |
0:a40b9a259b52 | 1128 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1129 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1130 | |
Osamu Nakamura |
0:a40b9a259b52 | 1131 | Backoff.prototype.duration = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1132 | var ms = this.ms * Math.pow(this.factor, this.attempts++); |
Osamu Nakamura |
0:a40b9a259b52 | 1133 | if (this.jitter) { |
Osamu Nakamura |
0:a40b9a259b52 | 1134 | var rand = Math.random(); |
Osamu Nakamura |
0:a40b9a259b52 | 1135 | var deviation = Math.floor(rand * this.jitter * ms); |
Osamu Nakamura |
0:a40b9a259b52 | 1136 | ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; |
Osamu Nakamura |
0:a40b9a259b52 | 1137 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1138 | return Math.min(ms, this.max) | 0; |
Osamu Nakamura |
0:a40b9a259b52 | 1139 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1140 | |
Osamu Nakamura |
0:a40b9a259b52 | 1141 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1142 | * Reset the number of attempts. |
Osamu Nakamura |
0:a40b9a259b52 | 1143 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1144 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1145 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1146 | |
Osamu Nakamura |
0:a40b9a259b52 | 1147 | Backoff.prototype.reset = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1148 | this.attempts = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 1149 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1150 | |
Osamu Nakamura |
0:a40b9a259b52 | 1151 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1152 | * Set the minimum duration |
Osamu Nakamura |
0:a40b9a259b52 | 1153 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1154 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1155 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1156 | |
Osamu Nakamura |
0:a40b9a259b52 | 1157 | Backoff.prototype.setMin = function(min){ |
Osamu Nakamura |
0:a40b9a259b52 | 1158 | this.ms = min; |
Osamu Nakamura |
0:a40b9a259b52 | 1159 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1160 | |
Osamu Nakamura |
0:a40b9a259b52 | 1161 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1162 | * Set the maximum duration |
Osamu Nakamura |
0:a40b9a259b52 | 1163 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1164 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1165 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1166 | |
Osamu Nakamura |
0:a40b9a259b52 | 1167 | Backoff.prototype.setMax = function(max){ |
Osamu Nakamura |
0:a40b9a259b52 | 1168 | this.max = max; |
Osamu Nakamura |
0:a40b9a259b52 | 1169 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1170 | |
Osamu Nakamura |
0:a40b9a259b52 | 1171 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1172 | * Set the jitter |
Osamu Nakamura |
0:a40b9a259b52 | 1173 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1174 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1175 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1176 | |
Osamu Nakamura |
0:a40b9a259b52 | 1177 | Backoff.prototype.setJitter = function(jitter){ |
Osamu Nakamura |
0:a40b9a259b52 | 1178 | this.jitter = jitter; |
Osamu Nakamura |
0:a40b9a259b52 | 1179 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1180 | |
Osamu Nakamura |
0:a40b9a259b52 | 1181 | |
Osamu Nakamura |
0:a40b9a259b52 | 1182 | },{}],8:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1183 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1184 | * Slice reference. |
Osamu Nakamura |
0:a40b9a259b52 | 1185 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1186 | |
Osamu Nakamura |
0:a40b9a259b52 | 1187 | var slice = [].slice; |
Osamu Nakamura |
0:a40b9a259b52 | 1188 | |
Osamu Nakamura |
0:a40b9a259b52 | 1189 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1190 | * Bind `obj` to `fn`. |
Osamu Nakamura |
0:a40b9a259b52 | 1191 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1192 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 1193 | * @param {Function|String} fn or string |
Osamu Nakamura |
0:a40b9a259b52 | 1194 | * @return {Function} |
Osamu Nakamura |
0:a40b9a259b52 | 1195 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1196 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1197 | |
Osamu Nakamura |
0:a40b9a259b52 | 1198 | module.exports = function(obj, fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 1199 | if ('string' == typeof fn) fn = obj[fn]; |
Osamu Nakamura |
0:a40b9a259b52 | 1200 | if ('function' != typeof fn) throw new Error('bind() requires a function'); |
Osamu Nakamura |
0:a40b9a259b52 | 1201 | var args = slice.call(arguments, 2); |
Osamu Nakamura |
0:a40b9a259b52 | 1202 | return function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1203 | return fn.apply(obj, args.concat(slice.call(arguments))); |
Osamu Nakamura |
0:a40b9a259b52 | 1204 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1205 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1206 | |
Osamu Nakamura |
0:a40b9a259b52 | 1207 | },{}],9:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1208 | |
Osamu Nakamura |
0:a40b9a259b52 | 1209 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1210 | * Expose `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 1211 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1212 | |
Osamu Nakamura |
0:a40b9a259b52 | 1213 | module.exports = Emitter; |
Osamu Nakamura |
0:a40b9a259b52 | 1214 | |
Osamu Nakamura |
0:a40b9a259b52 | 1215 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1216 | * Initialize a new `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 1217 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1218 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1219 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1220 | |
Osamu Nakamura |
0:a40b9a259b52 | 1221 | function Emitter(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 1222 | if (obj) return mixin(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 1223 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1224 | |
Osamu Nakamura |
0:a40b9a259b52 | 1225 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1226 | * Mixin the emitter properties. |
Osamu Nakamura |
0:a40b9a259b52 | 1227 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1228 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 1229 | * @return {Object} |
Osamu Nakamura |
0:a40b9a259b52 | 1230 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1231 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1232 | |
Osamu Nakamura |
0:a40b9a259b52 | 1233 | function mixin(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 1234 | for (var key in Emitter.prototype) { |
Osamu Nakamura |
0:a40b9a259b52 | 1235 | obj[key] = Emitter.prototype[key]; |
Osamu Nakamura |
0:a40b9a259b52 | 1236 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1237 | return obj; |
Osamu Nakamura |
0:a40b9a259b52 | 1238 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1239 | |
Osamu Nakamura |
0:a40b9a259b52 | 1240 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1241 | * Listen on the given `event` with `fn`. |
Osamu Nakamura |
0:a40b9a259b52 | 1242 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1243 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1244 | * @param {Function} fn |
Osamu Nakamura |
0:a40b9a259b52 | 1245 | * @return {Emitter} |
Osamu Nakamura |
0:a40b9a259b52 | 1246 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1247 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1248 | |
Osamu Nakamura |
0:a40b9a259b52 | 1249 | Emitter.prototype.on = |
Osamu Nakamura |
0:a40b9a259b52 | 1250 | Emitter.prototype.addEventListener = function(event, fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 1251 | this._callbacks = this._callbacks || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1252 | (this._callbacks[event] = this._callbacks[event] || []) |
Osamu Nakamura |
0:a40b9a259b52 | 1253 | .push(fn); |
Osamu Nakamura |
0:a40b9a259b52 | 1254 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1255 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1256 | |
Osamu Nakamura |
0:a40b9a259b52 | 1257 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1258 | * Adds an `event` listener that will be invoked a single |
Osamu Nakamura |
0:a40b9a259b52 | 1259 | * time then automatically removed. |
Osamu Nakamura |
0:a40b9a259b52 | 1260 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1261 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1262 | * @param {Function} fn |
Osamu Nakamura |
0:a40b9a259b52 | 1263 | * @return {Emitter} |
Osamu Nakamura |
0:a40b9a259b52 | 1264 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1265 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1266 | |
Osamu Nakamura |
0:a40b9a259b52 | 1267 | Emitter.prototype.once = function(event, fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 1268 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 1269 | this._callbacks = this._callbacks || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1270 | |
Osamu Nakamura |
0:a40b9a259b52 | 1271 | function on() { |
Osamu Nakamura |
0:a40b9a259b52 | 1272 | self.off(event, on); |
Osamu Nakamura |
0:a40b9a259b52 | 1273 | fn.apply(this, arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 1274 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1275 | |
Osamu Nakamura |
0:a40b9a259b52 | 1276 | on.fn = fn; |
Osamu Nakamura |
0:a40b9a259b52 | 1277 | this.on(event, on); |
Osamu Nakamura |
0:a40b9a259b52 | 1278 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1279 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1280 | |
Osamu Nakamura |
0:a40b9a259b52 | 1281 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1282 | * Remove the given callback for `event` or all |
Osamu Nakamura |
0:a40b9a259b52 | 1283 | * registered callbacks. |
Osamu Nakamura |
0:a40b9a259b52 | 1284 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1285 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1286 | * @param {Function} fn |
Osamu Nakamura |
0:a40b9a259b52 | 1287 | * @return {Emitter} |
Osamu Nakamura |
0:a40b9a259b52 | 1288 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1289 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1290 | |
Osamu Nakamura |
0:a40b9a259b52 | 1291 | Emitter.prototype.off = |
Osamu Nakamura |
0:a40b9a259b52 | 1292 | Emitter.prototype.removeListener = |
Osamu Nakamura |
0:a40b9a259b52 | 1293 | Emitter.prototype.removeAllListeners = |
Osamu Nakamura |
0:a40b9a259b52 | 1294 | Emitter.prototype.removeEventListener = function(event, fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 1295 | this._callbacks = this._callbacks || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1296 | |
Osamu Nakamura |
0:a40b9a259b52 | 1297 | // all |
Osamu Nakamura |
0:a40b9a259b52 | 1298 | if (0 == arguments.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 1299 | this._callbacks = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1300 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1301 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1302 | |
Osamu Nakamura |
0:a40b9a259b52 | 1303 | // specific event |
Osamu Nakamura |
0:a40b9a259b52 | 1304 | var callbacks = this._callbacks[event]; |
Osamu Nakamura |
0:a40b9a259b52 | 1305 | if (!callbacks) return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1306 | |
Osamu Nakamura |
0:a40b9a259b52 | 1307 | // remove all handlers |
Osamu Nakamura |
0:a40b9a259b52 | 1308 | if (1 == arguments.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 1309 | delete this._callbacks[event]; |
Osamu Nakamura |
0:a40b9a259b52 | 1310 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1311 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1312 | |
Osamu Nakamura |
0:a40b9a259b52 | 1313 | // remove specific handler |
Osamu Nakamura |
0:a40b9a259b52 | 1314 | var cb; |
Osamu Nakamura |
0:a40b9a259b52 | 1315 | for (var i = 0; i < callbacks.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 1316 | cb = callbacks[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 1317 | if (cb === fn || cb.fn === fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 1318 | callbacks.splice(i, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 1319 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 1320 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1321 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1322 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1323 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1324 | |
Osamu Nakamura |
0:a40b9a259b52 | 1325 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1326 | * Emit `event` with the given args. |
Osamu Nakamura |
0:a40b9a259b52 | 1327 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1328 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1329 | * @param {Mixed} ... |
Osamu Nakamura |
0:a40b9a259b52 | 1330 | * @return {Emitter} |
Osamu Nakamura |
0:a40b9a259b52 | 1331 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1332 | |
Osamu Nakamura |
0:a40b9a259b52 | 1333 | Emitter.prototype.emit = function(event){ |
Osamu Nakamura |
0:a40b9a259b52 | 1334 | this._callbacks = this._callbacks || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1335 | var args = [].slice.call(arguments, 1) |
Osamu Nakamura |
0:a40b9a259b52 | 1336 | , callbacks = this._callbacks[event]; |
Osamu Nakamura |
0:a40b9a259b52 | 1337 | |
Osamu Nakamura |
0:a40b9a259b52 | 1338 | if (callbacks) { |
Osamu Nakamura |
0:a40b9a259b52 | 1339 | callbacks = callbacks.slice(0); |
Osamu Nakamura |
0:a40b9a259b52 | 1340 | for (var i = 0, len = callbacks.length; i < len; ++i) { |
Osamu Nakamura |
0:a40b9a259b52 | 1341 | callbacks[i].apply(this, args); |
Osamu Nakamura |
0:a40b9a259b52 | 1342 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1343 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1344 | |
Osamu Nakamura |
0:a40b9a259b52 | 1345 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 1346 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1347 | |
Osamu Nakamura |
0:a40b9a259b52 | 1348 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1349 | * Return array of callbacks for `event`. |
Osamu Nakamura |
0:a40b9a259b52 | 1350 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1351 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1352 | * @return {Array} |
Osamu Nakamura |
0:a40b9a259b52 | 1353 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1354 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1355 | |
Osamu Nakamura |
0:a40b9a259b52 | 1356 | Emitter.prototype.listeners = function(event){ |
Osamu Nakamura |
0:a40b9a259b52 | 1357 | this._callbacks = this._callbacks || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1358 | return this._callbacks[event] || []; |
Osamu Nakamura |
0:a40b9a259b52 | 1359 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1360 | |
Osamu Nakamura |
0:a40b9a259b52 | 1361 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1362 | * Check if this emitter has `event` handlers. |
Osamu Nakamura |
0:a40b9a259b52 | 1363 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1364 | * @param {String} event |
Osamu Nakamura |
0:a40b9a259b52 | 1365 | * @return {Boolean} |
Osamu Nakamura |
0:a40b9a259b52 | 1366 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1367 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1368 | |
Osamu Nakamura |
0:a40b9a259b52 | 1369 | Emitter.prototype.hasListeners = function(event){ |
Osamu Nakamura |
0:a40b9a259b52 | 1370 | return !! this.listeners(event).length; |
Osamu Nakamura |
0:a40b9a259b52 | 1371 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1372 | |
Osamu Nakamura |
0:a40b9a259b52 | 1373 | },{}],10:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1374 | |
Osamu Nakamura |
0:a40b9a259b52 | 1375 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1376 | * Expose `debug()` as the module. |
Osamu Nakamura |
0:a40b9a259b52 | 1377 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1378 | |
Osamu Nakamura |
0:a40b9a259b52 | 1379 | module.exports = debug; |
Osamu Nakamura |
0:a40b9a259b52 | 1380 | |
Osamu Nakamura |
0:a40b9a259b52 | 1381 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1382 | * Create a debugger with the given `name`. |
Osamu Nakamura |
0:a40b9a259b52 | 1383 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1384 | * @param {String} name |
Osamu Nakamura |
0:a40b9a259b52 | 1385 | * @return {Type} |
Osamu Nakamura |
0:a40b9a259b52 | 1386 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1387 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1388 | |
Osamu Nakamura |
0:a40b9a259b52 | 1389 | function debug(name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1390 | if (!debug.enabled(name)) return function(){}; |
Osamu Nakamura |
0:a40b9a259b52 | 1391 | |
Osamu Nakamura |
0:a40b9a259b52 | 1392 | return function(fmt){ |
Osamu Nakamura |
0:a40b9a259b52 | 1393 | fmt = coerce(fmt); |
Osamu Nakamura |
0:a40b9a259b52 | 1394 | |
Osamu Nakamura |
0:a40b9a259b52 | 1395 | var curr = new Date; |
Osamu Nakamura |
0:a40b9a259b52 | 1396 | var ms = curr - (debug[name] || curr); |
Osamu Nakamura |
0:a40b9a259b52 | 1397 | debug[name] = curr; |
Osamu Nakamura |
0:a40b9a259b52 | 1398 | |
Osamu Nakamura |
0:a40b9a259b52 | 1399 | fmt = name |
Osamu Nakamura |
0:a40b9a259b52 | 1400 | + ' ' |
Osamu Nakamura |
0:a40b9a259b52 | 1401 | + fmt |
Osamu Nakamura |
0:a40b9a259b52 | 1402 | + ' +' + debug.humanize(ms); |
Osamu Nakamura |
0:a40b9a259b52 | 1403 | |
Osamu Nakamura |
0:a40b9a259b52 | 1404 | // This hackery is required for IE8 |
Osamu Nakamura |
0:a40b9a259b52 | 1405 | // where `console.log` doesn't have 'apply' |
Osamu Nakamura |
0:a40b9a259b52 | 1406 | window.console |
Osamu Nakamura |
0:a40b9a259b52 | 1407 | && console.log |
Osamu Nakamura |
0:a40b9a259b52 | 1408 | && Function.prototype.apply.call(console.log, console, arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 1409 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1410 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1411 | |
Osamu Nakamura |
0:a40b9a259b52 | 1412 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1413 | * The currently active debug mode names. |
Osamu Nakamura |
0:a40b9a259b52 | 1414 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1415 | |
Osamu Nakamura |
0:a40b9a259b52 | 1416 | debug.names = []; |
Osamu Nakamura |
0:a40b9a259b52 | 1417 | debug.skips = []; |
Osamu Nakamura |
0:a40b9a259b52 | 1418 | |
Osamu Nakamura |
0:a40b9a259b52 | 1419 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1420 | * Enables a debug mode by name. This can include modes |
Osamu Nakamura |
0:a40b9a259b52 | 1421 | * separated by a colon and wildcards. |
Osamu Nakamura |
0:a40b9a259b52 | 1422 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1423 | * @param {String} name |
Osamu Nakamura |
0:a40b9a259b52 | 1424 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1425 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1426 | |
Osamu Nakamura |
0:a40b9a259b52 | 1427 | debug.enable = function(name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1428 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 1429 | localStorage.debug = name; |
Osamu Nakamura |
0:a40b9a259b52 | 1430 | } catch(e){} |
Osamu Nakamura |
0:a40b9a259b52 | 1431 | |
Osamu Nakamura |
0:a40b9a259b52 | 1432 | var split = (name || '').split(/[\s,]+/) |
Osamu Nakamura |
0:a40b9a259b52 | 1433 | , len = split.length; |
Osamu Nakamura |
0:a40b9a259b52 | 1434 | |
Osamu Nakamura |
0:a40b9a259b52 | 1435 | for (var i = 0; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 1436 | name = split[i].replace('*', '.*?'); |
Osamu Nakamura |
0:a40b9a259b52 | 1437 | if (name[0] === '-') { |
Osamu Nakamura |
0:a40b9a259b52 | 1438 | debug.skips.push(new RegExp('^' + name.substr(1) + '$')); |
Osamu Nakamura |
0:a40b9a259b52 | 1439 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1440 | else { |
Osamu Nakamura |
0:a40b9a259b52 | 1441 | debug.names.push(new RegExp('^' + name + '$')); |
Osamu Nakamura |
0:a40b9a259b52 | 1442 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1443 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1444 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1445 | |
Osamu Nakamura |
0:a40b9a259b52 | 1446 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1447 | * Disable debug output. |
Osamu Nakamura |
0:a40b9a259b52 | 1448 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1449 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1450 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1451 | |
Osamu Nakamura |
0:a40b9a259b52 | 1452 | debug.disable = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1453 | debug.enable(''); |
Osamu Nakamura |
0:a40b9a259b52 | 1454 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1455 | |
Osamu Nakamura |
0:a40b9a259b52 | 1456 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1457 | * Humanize the given `ms`. |
Osamu Nakamura |
0:a40b9a259b52 | 1458 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1459 | * @param {Number} m |
Osamu Nakamura |
0:a40b9a259b52 | 1460 | * @return {String} |
Osamu Nakamura |
0:a40b9a259b52 | 1461 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1462 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1463 | |
Osamu Nakamura |
0:a40b9a259b52 | 1464 | debug.humanize = function(ms) { |
Osamu Nakamura |
0:a40b9a259b52 | 1465 | var sec = 1000 |
Osamu Nakamura |
0:a40b9a259b52 | 1466 | , min = 60 * 1000 |
Osamu Nakamura |
0:a40b9a259b52 | 1467 | , hour = 60 * min; |
Osamu Nakamura |
0:a40b9a259b52 | 1468 | |
Osamu Nakamura |
0:a40b9a259b52 | 1469 | if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; |
Osamu Nakamura |
0:a40b9a259b52 | 1470 | if (ms >= min) return (ms / min).toFixed(1) + 'm'; |
Osamu Nakamura |
0:a40b9a259b52 | 1471 | if (ms >= sec) return (ms / sec | 0) + 's'; |
Osamu Nakamura |
0:a40b9a259b52 | 1472 | return ms + 'ms'; |
Osamu Nakamura |
0:a40b9a259b52 | 1473 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1474 | |
Osamu Nakamura |
0:a40b9a259b52 | 1475 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1476 | * Returns true if the given mode name is enabled, false otherwise. |
Osamu Nakamura |
0:a40b9a259b52 | 1477 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1478 | * @param {String} name |
Osamu Nakamura |
0:a40b9a259b52 | 1479 | * @return {Boolean} |
Osamu Nakamura |
0:a40b9a259b52 | 1480 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1481 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1482 | |
Osamu Nakamura |
0:a40b9a259b52 | 1483 | debug.enabled = function(name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1484 | for (var i = 0, len = debug.skips.length; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 1485 | if (debug.skips[i].test(name)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1486 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 1487 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1488 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1489 | for (var i = 0, len = debug.names.length; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 1490 | if (debug.names[i].test(name)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1491 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 1492 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1493 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1494 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 1495 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1496 | |
Osamu Nakamura |
0:a40b9a259b52 | 1497 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1498 | * Coerce `val`. |
Osamu Nakamura |
0:a40b9a259b52 | 1499 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1500 | |
Osamu Nakamura |
0:a40b9a259b52 | 1501 | function coerce(val) { |
Osamu Nakamura |
0:a40b9a259b52 | 1502 | if (val instanceof Error) return val.stack || val.message; |
Osamu Nakamura |
0:a40b9a259b52 | 1503 | return val; |
Osamu Nakamura |
0:a40b9a259b52 | 1504 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1505 | |
Osamu Nakamura |
0:a40b9a259b52 | 1506 | // persist |
Osamu Nakamura |
0:a40b9a259b52 | 1507 | |
Osamu Nakamura |
0:a40b9a259b52 | 1508 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 1509 | if (window.localStorage) debug.enable(localStorage.debug); |
Osamu Nakamura |
0:a40b9a259b52 | 1510 | } catch(e){} |
Osamu Nakamura |
0:a40b9a259b52 | 1511 | |
Osamu Nakamura |
0:a40b9a259b52 | 1512 | },{}],11:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1513 | |
Osamu Nakamura |
0:a40b9a259b52 | 1514 | module.exports = _dereq_('./lib/'); |
Osamu Nakamura |
0:a40b9a259b52 | 1515 | |
Osamu Nakamura |
0:a40b9a259b52 | 1516 | },{"./lib/":12}],12:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1517 | |
Osamu Nakamura |
0:a40b9a259b52 | 1518 | module.exports = _dereq_('./socket'); |
Osamu Nakamura |
0:a40b9a259b52 | 1519 | |
Osamu Nakamura |
0:a40b9a259b52 | 1520 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1521 | * Exports parser |
Osamu Nakamura |
0:a40b9a259b52 | 1522 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1523 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1524 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1525 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1526 | module.exports.parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 1527 | |
Osamu Nakamura |
0:a40b9a259b52 | 1528 | },{"./socket":13,"engine.io-parser":25}],13:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 1529 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 1530 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1531 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 1532 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1533 | |
Osamu Nakamura |
0:a40b9a259b52 | 1534 | var transports = _dereq_('./transports'); |
Osamu Nakamura |
0:a40b9a259b52 | 1535 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 1536 | var debug = _dereq_('debug')('engine.io-client:socket'); |
Osamu Nakamura |
0:a40b9a259b52 | 1537 | var index = _dereq_('indexof'); |
Osamu Nakamura |
0:a40b9a259b52 | 1538 | var parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 1539 | var parseuri = _dereq_('parseuri'); |
Osamu Nakamura |
0:a40b9a259b52 | 1540 | var parsejson = _dereq_('parsejson'); |
Osamu Nakamura |
0:a40b9a259b52 | 1541 | var parseqs = _dereq_('parseqs'); |
Osamu Nakamura |
0:a40b9a259b52 | 1542 | |
Osamu Nakamura |
0:a40b9a259b52 | 1543 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1544 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 1545 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1546 | |
Osamu Nakamura |
0:a40b9a259b52 | 1547 | module.exports = Socket; |
Osamu Nakamura |
0:a40b9a259b52 | 1548 | |
Osamu Nakamura |
0:a40b9a259b52 | 1549 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1550 | * Noop function. |
Osamu Nakamura |
0:a40b9a259b52 | 1551 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1552 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1553 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1554 | |
Osamu Nakamura |
0:a40b9a259b52 | 1555 | function noop(){} |
Osamu Nakamura |
0:a40b9a259b52 | 1556 | |
Osamu Nakamura |
0:a40b9a259b52 | 1557 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1558 | * Socket constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 1559 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1560 | * @param {String|Object} uri or options |
Osamu Nakamura |
0:a40b9a259b52 | 1561 | * @param {Object} options |
Osamu Nakamura |
0:a40b9a259b52 | 1562 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1563 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1564 | |
Osamu Nakamura |
0:a40b9a259b52 | 1565 | function Socket(uri, opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 1566 | if (!(this instanceof Socket)) return new Socket(uri, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 1567 | |
Osamu Nakamura |
0:a40b9a259b52 | 1568 | opts = opts || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1569 | |
Osamu Nakamura |
0:a40b9a259b52 | 1570 | if (uri && 'object' == typeof uri) { |
Osamu Nakamura |
0:a40b9a259b52 | 1571 | opts = uri; |
Osamu Nakamura |
0:a40b9a259b52 | 1572 | uri = null; |
Osamu Nakamura |
0:a40b9a259b52 | 1573 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1574 | |
Osamu Nakamura |
0:a40b9a259b52 | 1575 | if (uri) { |
Osamu Nakamura |
0:a40b9a259b52 | 1576 | uri = parseuri(uri); |
Osamu Nakamura |
0:a40b9a259b52 | 1577 | opts.host = uri.host; |
Osamu Nakamura |
0:a40b9a259b52 | 1578 | opts.secure = uri.protocol == 'https' || uri.protocol == 'wss'; |
Osamu Nakamura |
0:a40b9a259b52 | 1579 | opts.port = uri.port; |
Osamu Nakamura |
0:a40b9a259b52 | 1580 | if (uri.query) opts.query = uri.query; |
Osamu Nakamura |
0:a40b9a259b52 | 1581 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1582 | |
Osamu Nakamura |
0:a40b9a259b52 | 1583 | this.secure = null != opts.secure ? opts.secure : |
Osamu Nakamura |
0:a40b9a259b52 | 1584 | (global.location && 'https:' == location.protocol); |
Osamu Nakamura |
0:a40b9a259b52 | 1585 | |
Osamu Nakamura |
0:a40b9a259b52 | 1586 | if (opts.host) { |
Osamu Nakamura |
0:a40b9a259b52 | 1587 | var pieces = opts.host.split(':'); |
Osamu Nakamura |
0:a40b9a259b52 | 1588 | opts.hostname = pieces.shift(); |
Osamu Nakamura |
0:a40b9a259b52 | 1589 | if (pieces.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 1590 | opts.port = pieces.pop(); |
Osamu Nakamura |
0:a40b9a259b52 | 1591 | } else if (!opts.port) { |
Osamu Nakamura |
0:a40b9a259b52 | 1592 | // if no port is specified manually, use the protocol default |
Osamu Nakamura |
0:a40b9a259b52 | 1593 | opts.port = this.secure ? '443' : '80'; |
Osamu Nakamura |
0:a40b9a259b52 | 1594 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1595 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1596 | |
Osamu Nakamura |
0:a40b9a259b52 | 1597 | this.agent = opts.agent || false; |
Osamu Nakamura |
0:a40b9a259b52 | 1598 | this.hostname = opts.hostname || |
Osamu Nakamura |
0:a40b9a259b52 | 1599 | (global.location ? location.hostname : 'localhost'); |
Osamu Nakamura |
0:a40b9a259b52 | 1600 | this.port = opts.port || (global.location && location.port ? |
Osamu Nakamura |
0:a40b9a259b52 | 1601 | location.port : |
Osamu Nakamura |
0:a40b9a259b52 | 1602 | (this.secure ? 443 : 80)); |
Osamu Nakamura |
0:a40b9a259b52 | 1603 | this.query = opts.query || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1604 | if ('string' == typeof this.query) this.query = parseqs.decode(this.query); |
Osamu Nakamura |
0:a40b9a259b52 | 1605 | this.upgrade = false !== opts.upgrade; |
Osamu Nakamura |
0:a40b9a259b52 | 1606 | this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; |
Osamu Nakamura |
0:a40b9a259b52 | 1607 | this.forceJSONP = !!opts.forceJSONP; |
Osamu Nakamura |
0:a40b9a259b52 | 1608 | this.jsonp = false !== opts.jsonp; |
Osamu Nakamura |
0:a40b9a259b52 | 1609 | this.forceBase64 = !!opts.forceBase64; |
Osamu Nakamura |
0:a40b9a259b52 | 1610 | this.enablesXDR = !!opts.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 1611 | this.timestampParam = opts.timestampParam || 't'; |
Osamu Nakamura |
0:a40b9a259b52 | 1612 | this.timestampRequests = opts.timestampRequests; |
Osamu Nakamura |
0:a40b9a259b52 | 1613 | this.transports = opts.transports || ['polling', 'websocket']; |
Osamu Nakamura |
0:a40b9a259b52 | 1614 | this.readyState = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 1615 | this.writeBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 1616 | this.callbackBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 1617 | this.policyPort = opts.policyPort || 843; |
Osamu Nakamura |
0:a40b9a259b52 | 1618 | this.rememberUpgrade = opts.rememberUpgrade || false; |
Osamu Nakamura |
0:a40b9a259b52 | 1619 | this.binaryType = null; |
Osamu Nakamura |
0:a40b9a259b52 | 1620 | this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; |
Osamu Nakamura |
0:a40b9a259b52 | 1621 | |
Osamu Nakamura |
0:a40b9a259b52 | 1622 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 1623 | this.pfx = opts.pfx || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1624 | this.key = opts.key || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1625 | this.passphrase = opts.passphrase || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1626 | this.cert = opts.cert || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1627 | this.ca = opts.ca || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1628 | this.ciphers = opts.ciphers || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1629 | this.rejectUnauthorized = opts.rejectUnauthorized || null; |
Osamu Nakamura |
0:a40b9a259b52 | 1630 | |
Osamu Nakamura |
0:a40b9a259b52 | 1631 | this.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 1632 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1633 | |
Osamu Nakamura |
0:a40b9a259b52 | 1634 | Socket.priorWebsocketSuccess = false; |
Osamu Nakamura |
0:a40b9a259b52 | 1635 | |
Osamu Nakamura |
0:a40b9a259b52 | 1636 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1637 | * Mix in `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 1638 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1639 | |
Osamu Nakamura |
0:a40b9a259b52 | 1640 | Emitter(Socket.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 1641 | |
Osamu Nakamura |
0:a40b9a259b52 | 1642 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1643 | * Protocol version. |
Osamu Nakamura |
0:a40b9a259b52 | 1644 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1645 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1646 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1647 | |
Osamu Nakamura |
0:a40b9a259b52 | 1648 | Socket.protocol = parser.protocol; // this is an int |
Osamu Nakamura |
0:a40b9a259b52 | 1649 | |
Osamu Nakamura |
0:a40b9a259b52 | 1650 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1651 | * Expose deps for legacy compatibility |
Osamu Nakamura |
0:a40b9a259b52 | 1652 | * and standalone browser access. |
Osamu Nakamura |
0:a40b9a259b52 | 1653 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1654 | |
Osamu Nakamura |
0:a40b9a259b52 | 1655 | Socket.Socket = Socket; |
Osamu Nakamura |
0:a40b9a259b52 | 1656 | Socket.Transport = _dereq_('./transport'); |
Osamu Nakamura |
0:a40b9a259b52 | 1657 | Socket.transports = _dereq_('./transports'); |
Osamu Nakamura |
0:a40b9a259b52 | 1658 | Socket.parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 1659 | |
Osamu Nakamura |
0:a40b9a259b52 | 1660 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1661 | * Creates transport of the given type. |
Osamu Nakamura |
0:a40b9a259b52 | 1662 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1663 | * @param {String} transport name |
Osamu Nakamura |
0:a40b9a259b52 | 1664 | * @return {Transport} |
Osamu Nakamura |
0:a40b9a259b52 | 1665 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1666 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1667 | |
Osamu Nakamura |
0:a40b9a259b52 | 1668 | Socket.prototype.createTransport = function (name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1669 | debug('creating transport "%s"', name); |
Osamu Nakamura |
0:a40b9a259b52 | 1670 | var query = clone(this.query); |
Osamu Nakamura |
0:a40b9a259b52 | 1671 | |
Osamu Nakamura |
0:a40b9a259b52 | 1672 | // append engine.io protocol identifier |
Osamu Nakamura |
0:a40b9a259b52 | 1673 | query.EIO = parser.protocol; |
Osamu Nakamura |
0:a40b9a259b52 | 1674 | |
Osamu Nakamura |
0:a40b9a259b52 | 1675 | // transport name |
Osamu Nakamura |
0:a40b9a259b52 | 1676 | query.transport = name; |
Osamu Nakamura |
0:a40b9a259b52 | 1677 | |
Osamu Nakamura |
0:a40b9a259b52 | 1678 | // session id if we already have one |
Osamu Nakamura |
0:a40b9a259b52 | 1679 | if (this.id) query.sid = this.id; |
Osamu Nakamura |
0:a40b9a259b52 | 1680 | |
Osamu Nakamura |
0:a40b9a259b52 | 1681 | var transport = new transports[name]({ |
Osamu Nakamura |
0:a40b9a259b52 | 1682 | agent: this.agent, |
Osamu Nakamura |
0:a40b9a259b52 | 1683 | hostname: this.hostname, |
Osamu Nakamura |
0:a40b9a259b52 | 1684 | port: this.port, |
Osamu Nakamura |
0:a40b9a259b52 | 1685 | secure: this.secure, |
Osamu Nakamura |
0:a40b9a259b52 | 1686 | path: this.path, |
Osamu Nakamura |
0:a40b9a259b52 | 1687 | query: query, |
Osamu Nakamura |
0:a40b9a259b52 | 1688 | forceJSONP: this.forceJSONP, |
Osamu Nakamura |
0:a40b9a259b52 | 1689 | jsonp: this.jsonp, |
Osamu Nakamura |
0:a40b9a259b52 | 1690 | forceBase64: this.forceBase64, |
Osamu Nakamura |
0:a40b9a259b52 | 1691 | enablesXDR: this.enablesXDR, |
Osamu Nakamura |
0:a40b9a259b52 | 1692 | timestampRequests: this.timestampRequests, |
Osamu Nakamura |
0:a40b9a259b52 | 1693 | timestampParam: this.timestampParam, |
Osamu Nakamura |
0:a40b9a259b52 | 1694 | policyPort: this.policyPort, |
Osamu Nakamura |
0:a40b9a259b52 | 1695 | socket: this, |
Osamu Nakamura |
0:a40b9a259b52 | 1696 | pfx: this.pfx, |
Osamu Nakamura |
0:a40b9a259b52 | 1697 | key: this.key, |
Osamu Nakamura |
0:a40b9a259b52 | 1698 | passphrase: this.passphrase, |
Osamu Nakamura |
0:a40b9a259b52 | 1699 | cert: this.cert, |
Osamu Nakamura |
0:a40b9a259b52 | 1700 | ca: this.ca, |
Osamu Nakamura |
0:a40b9a259b52 | 1701 | ciphers: this.ciphers, |
Osamu Nakamura |
0:a40b9a259b52 | 1702 | rejectUnauthorized: this.rejectUnauthorized |
Osamu Nakamura |
0:a40b9a259b52 | 1703 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 1704 | |
Osamu Nakamura |
0:a40b9a259b52 | 1705 | return transport; |
Osamu Nakamura |
0:a40b9a259b52 | 1706 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1707 | |
Osamu Nakamura |
0:a40b9a259b52 | 1708 | function clone (obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 1709 | var o = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 1710 | for (var i in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 1711 | if (obj.hasOwnProperty(i)) { |
Osamu Nakamura |
0:a40b9a259b52 | 1712 | o[i] = obj[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 1713 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1714 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1715 | return o; |
Osamu Nakamura |
0:a40b9a259b52 | 1716 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1717 | |
Osamu Nakamura |
0:a40b9a259b52 | 1718 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1719 | * Initializes transport to use and starts probe. |
Osamu Nakamura |
0:a40b9a259b52 | 1720 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1721 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1722 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1723 | Socket.prototype.open = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 1724 | var transport; |
Osamu Nakamura |
0:a40b9a259b52 | 1725 | if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) { |
Osamu Nakamura |
0:a40b9a259b52 | 1726 | transport = 'websocket'; |
Osamu Nakamura |
0:a40b9a259b52 | 1727 | } else if (0 == this.transports.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 1728 | // Emit error on next tick so it can be listened to |
Osamu Nakamura |
0:a40b9a259b52 | 1729 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 1730 | setTimeout(function() { |
Osamu Nakamura |
0:a40b9a259b52 | 1731 | self.emit('error', 'No transports available'); |
Osamu Nakamura |
0:a40b9a259b52 | 1732 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 1733 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 1734 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 1735 | transport = this.transports[0]; |
Osamu Nakamura |
0:a40b9a259b52 | 1736 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1737 | this.readyState = 'opening'; |
Osamu Nakamura |
0:a40b9a259b52 | 1738 | |
Osamu Nakamura |
0:a40b9a259b52 | 1739 | // Retry with the next transport if the transport is disabled (jsonp: false) |
Osamu Nakamura |
0:a40b9a259b52 | 1740 | var transport; |
Osamu Nakamura |
0:a40b9a259b52 | 1741 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 1742 | transport = this.createTransport(transport); |
Osamu Nakamura |
0:a40b9a259b52 | 1743 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 1744 | this.transports.shift(); |
Osamu Nakamura |
0:a40b9a259b52 | 1745 | this.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 1746 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 1747 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1748 | |
Osamu Nakamura |
0:a40b9a259b52 | 1749 | transport.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 1750 | this.setTransport(transport); |
Osamu Nakamura |
0:a40b9a259b52 | 1751 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1752 | |
Osamu Nakamura |
0:a40b9a259b52 | 1753 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1754 | * Sets the current transport. Disables the existing one (if any). |
Osamu Nakamura |
0:a40b9a259b52 | 1755 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1756 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1757 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1758 | |
Osamu Nakamura |
0:a40b9a259b52 | 1759 | Socket.prototype.setTransport = function(transport){ |
Osamu Nakamura |
0:a40b9a259b52 | 1760 | debug('setting transport %s', transport.name); |
Osamu Nakamura |
0:a40b9a259b52 | 1761 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 1762 | |
Osamu Nakamura |
0:a40b9a259b52 | 1763 | if (this.transport) { |
Osamu Nakamura |
0:a40b9a259b52 | 1764 | debug('clearing existing transport %s', this.transport.name); |
Osamu Nakamura |
0:a40b9a259b52 | 1765 | this.transport.removeAllListeners(); |
Osamu Nakamura |
0:a40b9a259b52 | 1766 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1767 | |
Osamu Nakamura |
0:a40b9a259b52 | 1768 | // set up transport |
Osamu Nakamura |
0:a40b9a259b52 | 1769 | this.transport = transport; |
Osamu Nakamura |
0:a40b9a259b52 | 1770 | |
Osamu Nakamura |
0:a40b9a259b52 | 1771 | // set up transport listeners |
Osamu Nakamura |
0:a40b9a259b52 | 1772 | transport |
Osamu Nakamura |
0:a40b9a259b52 | 1773 | .on('drain', function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1774 | self.onDrain(); |
Osamu Nakamura |
0:a40b9a259b52 | 1775 | }) |
Osamu Nakamura |
0:a40b9a259b52 | 1776 | .on('packet', function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 1777 | self.onPacket(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 1778 | }) |
Osamu Nakamura |
0:a40b9a259b52 | 1779 | .on('error', function(e){ |
Osamu Nakamura |
0:a40b9a259b52 | 1780 | self.onError(e); |
Osamu Nakamura |
0:a40b9a259b52 | 1781 | }) |
Osamu Nakamura |
0:a40b9a259b52 | 1782 | .on('close', function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1783 | self.onClose('transport close'); |
Osamu Nakamura |
0:a40b9a259b52 | 1784 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 1785 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1786 | |
Osamu Nakamura |
0:a40b9a259b52 | 1787 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1788 | * Probes a transport. |
Osamu Nakamura |
0:a40b9a259b52 | 1789 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1790 | * @param {String} transport name |
Osamu Nakamura |
0:a40b9a259b52 | 1791 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1792 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1793 | |
Osamu Nakamura |
0:a40b9a259b52 | 1794 | Socket.prototype.probe = function (name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1795 | debug('probing transport "%s"', name); |
Osamu Nakamura |
0:a40b9a259b52 | 1796 | var transport = this.createTransport(name, { probe: 1 }) |
Osamu Nakamura |
0:a40b9a259b52 | 1797 | , failed = false |
Osamu Nakamura |
0:a40b9a259b52 | 1798 | , self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 1799 | |
Osamu Nakamura |
0:a40b9a259b52 | 1800 | Socket.priorWebsocketSuccess = false; |
Osamu Nakamura |
0:a40b9a259b52 | 1801 | |
Osamu Nakamura |
0:a40b9a259b52 | 1802 | function onTransportOpen(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1803 | if (self.onlyBinaryUpgrades) { |
Osamu Nakamura |
0:a40b9a259b52 | 1804 | var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 1805 | failed = failed || upgradeLosesBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 1806 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1807 | if (failed) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1808 | |
Osamu Nakamura |
0:a40b9a259b52 | 1809 | debug('probe transport "%s" opened', name); |
Osamu Nakamura |
0:a40b9a259b52 | 1810 | transport.send([{ type: 'ping', data: 'probe' }]); |
Osamu Nakamura |
0:a40b9a259b52 | 1811 | transport.once('packet', function (msg) { |
Osamu Nakamura |
0:a40b9a259b52 | 1812 | if (failed) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1813 | if ('pong' == msg.type && 'probe' == msg.data) { |
Osamu Nakamura |
0:a40b9a259b52 | 1814 | debug('probe transport "%s" pong', name); |
Osamu Nakamura |
0:a40b9a259b52 | 1815 | self.upgrading = true; |
Osamu Nakamura |
0:a40b9a259b52 | 1816 | self.emit('upgrading', transport); |
Osamu Nakamura |
0:a40b9a259b52 | 1817 | if (!transport) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1818 | Socket.priorWebsocketSuccess = 'websocket' == transport.name; |
Osamu Nakamura |
0:a40b9a259b52 | 1819 | |
Osamu Nakamura |
0:a40b9a259b52 | 1820 | debug('pausing current transport "%s"', self.transport.name); |
Osamu Nakamura |
0:a40b9a259b52 | 1821 | self.transport.pause(function () { |
Osamu Nakamura |
0:a40b9a259b52 | 1822 | if (failed) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1823 | if ('closed' == self.readyState) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1824 | debug('changing transport and sending upgrade packet'); |
Osamu Nakamura |
0:a40b9a259b52 | 1825 | |
Osamu Nakamura |
0:a40b9a259b52 | 1826 | cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 1827 | |
Osamu Nakamura |
0:a40b9a259b52 | 1828 | self.setTransport(transport); |
Osamu Nakamura |
0:a40b9a259b52 | 1829 | transport.send([{ type: 'upgrade' }]); |
Osamu Nakamura |
0:a40b9a259b52 | 1830 | self.emit('upgrade', transport); |
Osamu Nakamura |
0:a40b9a259b52 | 1831 | transport = null; |
Osamu Nakamura |
0:a40b9a259b52 | 1832 | self.upgrading = false; |
Osamu Nakamura |
0:a40b9a259b52 | 1833 | self.flush(); |
Osamu Nakamura |
0:a40b9a259b52 | 1834 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 1835 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 1836 | debug('probe transport "%s" failed', name); |
Osamu Nakamura |
0:a40b9a259b52 | 1837 | var err = new Error('probe error'); |
Osamu Nakamura |
0:a40b9a259b52 | 1838 | err.transport = transport.name; |
Osamu Nakamura |
0:a40b9a259b52 | 1839 | self.emit('upgradeError', err); |
Osamu Nakamura |
0:a40b9a259b52 | 1840 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1841 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 1842 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1843 | |
Osamu Nakamura |
0:a40b9a259b52 | 1844 | function freezeTransport() { |
Osamu Nakamura |
0:a40b9a259b52 | 1845 | if (failed) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1846 | |
Osamu Nakamura |
0:a40b9a259b52 | 1847 | // Any callback called by transport should be ignored since now |
Osamu Nakamura |
0:a40b9a259b52 | 1848 | failed = true; |
Osamu Nakamura |
0:a40b9a259b52 | 1849 | |
Osamu Nakamura |
0:a40b9a259b52 | 1850 | cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 1851 | |
Osamu Nakamura |
0:a40b9a259b52 | 1852 | transport.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 1853 | transport = null; |
Osamu Nakamura |
0:a40b9a259b52 | 1854 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1855 | |
Osamu Nakamura |
0:a40b9a259b52 | 1856 | //Handle any error that happens while probing |
Osamu Nakamura |
0:a40b9a259b52 | 1857 | function onerror(err) { |
Osamu Nakamura |
0:a40b9a259b52 | 1858 | var error = new Error('probe error: ' + err); |
Osamu Nakamura |
0:a40b9a259b52 | 1859 | error.transport = transport.name; |
Osamu Nakamura |
0:a40b9a259b52 | 1860 | |
Osamu Nakamura |
0:a40b9a259b52 | 1861 | freezeTransport(); |
Osamu Nakamura |
0:a40b9a259b52 | 1862 | |
Osamu Nakamura |
0:a40b9a259b52 | 1863 | debug('probe transport "%s" failed because of error: %s', name, err); |
Osamu Nakamura |
0:a40b9a259b52 | 1864 | |
Osamu Nakamura |
0:a40b9a259b52 | 1865 | self.emit('upgradeError', error); |
Osamu Nakamura |
0:a40b9a259b52 | 1866 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1867 | |
Osamu Nakamura |
0:a40b9a259b52 | 1868 | function onTransportClose(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1869 | onerror("transport closed"); |
Osamu Nakamura |
0:a40b9a259b52 | 1870 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1871 | |
Osamu Nakamura |
0:a40b9a259b52 | 1872 | //When the socket is closed while we're probing |
Osamu Nakamura |
0:a40b9a259b52 | 1873 | function onclose(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1874 | onerror("socket closed"); |
Osamu Nakamura |
0:a40b9a259b52 | 1875 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1876 | |
Osamu Nakamura |
0:a40b9a259b52 | 1877 | //When the socket is upgraded while we're probing |
Osamu Nakamura |
0:a40b9a259b52 | 1878 | function onupgrade(to){ |
Osamu Nakamura |
0:a40b9a259b52 | 1879 | if (transport && to.name != transport.name) { |
Osamu Nakamura |
0:a40b9a259b52 | 1880 | debug('"%s" works - aborting "%s"', to.name, transport.name); |
Osamu Nakamura |
0:a40b9a259b52 | 1881 | freezeTransport(); |
Osamu Nakamura |
0:a40b9a259b52 | 1882 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1883 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1884 | |
Osamu Nakamura |
0:a40b9a259b52 | 1885 | //Remove all listeners on the transport and on self |
Osamu Nakamura |
0:a40b9a259b52 | 1886 | function cleanup(){ |
Osamu Nakamura |
0:a40b9a259b52 | 1887 | transport.removeListener('open', onTransportOpen); |
Osamu Nakamura |
0:a40b9a259b52 | 1888 | transport.removeListener('error', onerror); |
Osamu Nakamura |
0:a40b9a259b52 | 1889 | transport.removeListener('close', onTransportClose); |
Osamu Nakamura |
0:a40b9a259b52 | 1890 | self.removeListener('close', onclose); |
Osamu Nakamura |
0:a40b9a259b52 | 1891 | self.removeListener('upgrading', onupgrade); |
Osamu Nakamura |
0:a40b9a259b52 | 1892 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1893 | |
Osamu Nakamura |
0:a40b9a259b52 | 1894 | transport.once('open', onTransportOpen); |
Osamu Nakamura |
0:a40b9a259b52 | 1895 | transport.once('error', onerror); |
Osamu Nakamura |
0:a40b9a259b52 | 1896 | transport.once('close', onTransportClose); |
Osamu Nakamura |
0:a40b9a259b52 | 1897 | |
Osamu Nakamura |
0:a40b9a259b52 | 1898 | this.once('close', onclose); |
Osamu Nakamura |
0:a40b9a259b52 | 1899 | this.once('upgrading', onupgrade); |
Osamu Nakamura |
0:a40b9a259b52 | 1900 | |
Osamu Nakamura |
0:a40b9a259b52 | 1901 | transport.open(); |
Osamu Nakamura |
0:a40b9a259b52 | 1902 | |
Osamu Nakamura |
0:a40b9a259b52 | 1903 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1904 | |
Osamu Nakamura |
0:a40b9a259b52 | 1905 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1906 | * Called when connection is deemed open. |
Osamu Nakamura |
0:a40b9a259b52 | 1907 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1908 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 1909 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1910 | |
Osamu Nakamura |
0:a40b9a259b52 | 1911 | Socket.prototype.onOpen = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 1912 | debug('socket open'); |
Osamu Nakamura |
0:a40b9a259b52 | 1913 | this.readyState = 'open'; |
Osamu Nakamura |
0:a40b9a259b52 | 1914 | Socket.priorWebsocketSuccess = 'websocket' == this.transport.name; |
Osamu Nakamura |
0:a40b9a259b52 | 1915 | this.emit('open'); |
Osamu Nakamura |
0:a40b9a259b52 | 1916 | this.flush(); |
Osamu Nakamura |
0:a40b9a259b52 | 1917 | |
Osamu Nakamura |
0:a40b9a259b52 | 1918 | // we check for `readyState` in case an `open` |
Osamu Nakamura |
0:a40b9a259b52 | 1919 | // listener already closed the socket |
Osamu Nakamura |
0:a40b9a259b52 | 1920 | if ('open' == this.readyState && this.upgrade && this.transport.pause) { |
Osamu Nakamura |
0:a40b9a259b52 | 1921 | debug('starting upgrade probes'); |
Osamu Nakamura |
0:a40b9a259b52 | 1922 | for (var i = 0, l = this.upgrades.length; i < l; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 1923 | this.probe(this.upgrades[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 1924 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1925 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1926 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1927 | |
Osamu Nakamura |
0:a40b9a259b52 | 1928 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1929 | * Handles a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 1930 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1931 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1932 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1933 | |
Osamu Nakamura |
0:a40b9a259b52 | 1934 | Socket.prototype.onPacket = function (packet) { |
Osamu Nakamura |
0:a40b9a259b52 | 1935 | if ('opening' == this.readyState || 'open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 1936 | debug('socket receive: type "%s", data "%s"', packet.type, packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 1937 | |
Osamu Nakamura |
0:a40b9a259b52 | 1938 | this.emit('packet', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 1939 | |
Osamu Nakamura |
0:a40b9a259b52 | 1940 | // Socket is live - any packet counts |
Osamu Nakamura |
0:a40b9a259b52 | 1941 | this.emit('heartbeat'); |
Osamu Nakamura |
0:a40b9a259b52 | 1942 | |
Osamu Nakamura |
0:a40b9a259b52 | 1943 | switch (packet.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 1944 | case 'open': |
Osamu Nakamura |
0:a40b9a259b52 | 1945 | this.onHandshake(parsejson(packet.data)); |
Osamu Nakamura |
0:a40b9a259b52 | 1946 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 1947 | |
Osamu Nakamura |
0:a40b9a259b52 | 1948 | case 'pong': |
Osamu Nakamura |
0:a40b9a259b52 | 1949 | this.setPing(); |
Osamu Nakamura |
0:a40b9a259b52 | 1950 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 1951 | |
Osamu Nakamura |
0:a40b9a259b52 | 1952 | case 'error': |
Osamu Nakamura |
0:a40b9a259b52 | 1953 | var err = new Error('server error'); |
Osamu Nakamura |
0:a40b9a259b52 | 1954 | err.code = packet.data; |
Osamu Nakamura |
0:a40b9a259b52 | 1955 | this.emit('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 1956 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 1957 | |
Osamu Nakamura |
0:a40b9a259b52 | 1958 | case 'message': |
Osamu Nakamura |
0:a40b9a259b52 | 1959 | this.emit('data', packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 1960 | this.emit('message', packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 1961 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 1962 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1963 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 1964 | debug('packet received with socket readyState "%s"', this.readyState); |
Osamu Nakamura |
0:a40b9a259b52 | 1965 | } |
Osamu Nakamura |
0:a40b9a259b52 | 1966 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1967 | |
Osamu Nakamura |
0:a40b9a259b52 | 1968 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1969 | * Called upon handshake completion. |
Osamu Nakamura |
0:a40b9a259b52 | 1970 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1971 | * @param {Object} handshake obj |
Osamu Nakamura |
0:a40b9a259b52 | 1972 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1973 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1974 | |
Osamu Nakamura |
0:a40b9a259b52 | 1975 | Socket.prototype.onHandshake = function (data) { |
Osamu Nakamura |
0:a40b9a259b52 | 1976 | this.emit('handshake', data); |
Osamu Nakamura |
0:a40b9a259b52 | 1977 | this.id = data.sid; |
Osamu Nakamura |
0:a40b9a259b52 | 1978 | this.transport.query.sid = data.sid; |
Osamu Nakamura |
0:a40b9a259b52 | 1979 | this.upgrades = this.filterUpgrades(data.upgrades); |
Osamu Nakamura |
0:a40b9a259b52 | 1980 | this.pingInterval = data.pingInterval; |
Osamu Nakamura |
0:a40b9a259b52 | 1981 | this.pingTimeout = data.pingTimeout; |
Osamu Nakamura |
0:a40b9a259b52 | 1982 | this.onOpen(); |
Osamu Nakamura |
0:a40b9a259b52 | 1983 | // In case open handler closes socket |
Osamu Nakamura |
0:a40b9a259b52 | 1984 | if ('closed' == this.readyState) return; |
Osamu Nakamura |
0:a40b9a259b52 | 1985 | this.setPing(); |
Osamu Nakamura |
0:a40b9a259b52 | 1986 | |
Osamu Nakamura |
0:a40b9a259b52 | 1987 | // Prolong liveness of socket on heartbeat |
Osamu Nakamura |
0:a40b9a259b52 | 1988 | this.removeListener('heartbeat', this.onHeartbeat); |
Osamu Nakamura |
0:a40b9a259b52 | 1989 | this.on('heartbeat', this.onHeartbeat); |
Osamu Nakamura |
0:a40b9a259b52 | 1990 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 1991 | |
Osamu Nakamura |
0:a40b9a259b52 | 1992 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 1993 | * Resets ping timeout. |
Osamu Nakamura |
0:a40b9a259b52 | 1994 | * |
Osamu Nakamura |
0:a40b9a259b52 | 1995 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 1996 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 1997 | |
Osamu Nakamura |
0:a40b9a259b52 | 1998 | Socket.prototype.onHeartbeat = function (timeout) { |
Osamu Nakamura |
0:a40b9a259b52 | 1999 | clearTimeout(this.pingTimeoutTimer); |
Osamu Nakamura |
0:a40b9a259b52 | 2000 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2001 | self.pingTimeoutTimer = setTimeout(function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2002 | if ('closed' == self.readyState) return; |
Osamu Nakamura |
0:a40b9a259b52 | 2003 | self.onClose('ping timeout'); |
Osamu Nakamura |
0:a40b9a259b52 | 2004 | }, timeout || (self.pingInterval + self.pingTimeout)); |
Osamu Nakamura |
0:a40b9a259b52 | 2005 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2006 | |
Osamu Nakamura |
0:a40b9a259b52 | 2007 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2008 | * Pings server every `this.pingInterval` and expects response |
Osamu Nakamura |
0:a40b9a259b52 | 2009 | * within `this.pingTimeout` or closes connection. |
Osamu Nakamura |
0:a40b9a259b52 | 2010 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2011 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2012 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2013 | |
Osamu Nakamura |
0:a40b9a259b52 | 2014 | Socket.prototype.setPing = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2015 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2016 | clearTimeout(self.pingIntervalTimer); |
Osamu Nakamura |
0:a40b9a259b52 | 2017 | self.pingIntervalTimer = setTimeout(function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2018 | debug('writing ping packet - expecting pong within %sms', self.pingTimeout); |
Osamu Nakamura |
0:a40b9a259b52 | 2019 | self.ping(); |
Osamu Nakamura |
0:a40b9a259b52 | 2020 | self.onHeartbeat(self.pingTimeout); |
Osamu Nakamura |
0:a40b9a259b52 | 2021 | }, self.pingInterval); |
Osamu Nakamura |
0:a40b9a259b52 | 2022 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2023 | |
Osamu Nakamura |
0:a40b9a259b52 | 2024 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2025 | * Sends a ping packet. |
Osamu Nakamura |
0:a40b9a259b52 | 2026 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2027 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2028 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2029 | |
Osamu Nakamura |
0:a40b9a259b52 | 2030 | Socket.prototype.ping = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2031 | this.sendPacket('ping'); |
Osamu Nakamura |
0:a40b9a259b52 | 2032 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2033 | |
Osamu Nakamura |
0:a40b9a259b52 | 2034 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2035 | * Called on `drain` event |
Osamu Nakamura |
0:a40b9a259b52 | 2036 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2037 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2038 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2039 | |
Osamu Nakamura |
0:a40b9a259b52 | 2040 | Socket.prototype.onDrain = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 2041 | for (var i = 0; i < this.prevBufferLen; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 2042 | if (this.callbackBuffer[i]) { |
Osamu Nakamura |
0:a40b9a259b52 | 2043 | this.callbackBuffer[i](); |
Osamu Nakamura |
0:a40b9a259b52 | 2044 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2045 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2046 | |
Osamu Nakamura |
0:a40b9a259b52 | 2047 | this.writeBuffer.splice(0, this.prevBufferLen); |
Osamu Nakamura |
0:a40b9a259b52 | 2048 | this.callbackBuffer.splice(0, this.prevBufferLen); |
Osamu Nakamura |
0:a40b9a259b52 | 2049 | |
Osamu Nakamura |
0:a40b9a259b52 | 2050 | // setting prevBufferLen = 0 is very important |
Osamu Nakamura |
0:a40b9a259b52 | 2051 | // for example, when upgrading, upgrade packet is sent over, |
Osamu Nakamura |
0:a40b9a259b52 | 2052 | // and a nonzero prevBufferLen could cause problems on `drain` |
Osamu Nakamura |
0:a40b9a259b52 | 2053 | this.prevBufferLen = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 2054 | |
Osamu Nakamura |
0:a40b9a259b52 | 2055 | if (this.writeBuffer.length == 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 2056 | this.emit('drain'); |
Osamu Nakamura |
0:a40b9a259b52 | 2057 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2058 | this.flush(); |
Osamu Nakamura |
0:a40b9a259b52 | 2059 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2060 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2061 | |
Osamu Nakamura |
0:a40b9a259b52 | 2062 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2063 | * Flush write buffers. |
Osamu Nakamura |
0:a40b9a259b52 | 2064 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2065 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2066 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2067 | |
Osamu Nakamura |
0:a40b9a259b52 | 2068 | Socket.prototype.flush = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2069 | if ('closed' != this.readyState && this.transport.writable && |
Osamu Nakamura |
0:a40b9a259b52 | 2070 | !this.upgrading && this.writeBuffer.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 2071 | debug('flushing %d packets in socket', this.writeBuffer.length); |
Osamu Nakamura |
0:a40b9a259b52 | 2072 | this.transport.send(this.writeBuffer); |
Osamu Nakamura |
0:a40b9a259b52 | 2073 | // keep track of current length of writeBuffer |
Osamu Nakamura |
0:a40b9a259b52 | 2074 | // splice writeBuffer and callbackBuffer on `drain` |
Osamu Nakamura |
0:a40b9a259b52 | 2075 | this.prevBufferLen = this.writeBuffer.length; |
Osamu Nakamura |
0:a40b9a259b52 | 2076 | this.emit('flush'); |
Osamu Nakamura |
0:a40b9a259b52 | 2077 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2078 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2079 | |
Osamu Nakamura |
0:a40b9a259b52 | 2080 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2081 | * Sends a message. |
Osamu Nakamura |
0:a40b9a259b52 | 2082 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2083 | * @param {String} message. |
Osamu Nakamura |
0:a40b9a259b52 | 2084 | * @param {Function} callback function. |
Osamu Nakamura |
0:a40b9a259b52 | 2085 | * @return {Socket} for chaining. |
Osamu Nakamura |
0:a40b9a259b52 | 2086 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2087 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2088 | |
Osamu Nakamura |
0:a40b9a259b52 | 2089 | Socket.prototype.write = |
Osamu Nakamura |
0:a40b9a259b52 | 2090 | Socket.prototype.send = function (msg, fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 2091 | this.sendPacket('message', msg, fn); |
Osamu Nakamura |
0:a40b9a259b52 | 2092 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 2093 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2094 | |
Osamu Nakamura |
0:a40b9a259b52 | 2095 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2096 | * Sends a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 2097 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2098 | * @param {String} packet type. |
Osamu Nakamura |
0:a40b9a259b52 | 2099 | * @param {String} data. |
Osamu Nakamura |
0:a40b9a259b52 | 2100 | * @param {Function} callback function. |
Osamu Nakamura |
0:a40b9a259b52 | 2101 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2102 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2103 | |
Osamu Nakamura |
0:a40b9a259b52 | 2104 | Socket.prototype.sendPacket = function (type, data, fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 2105 | if ('closing' == this.readyState || 'closed' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2106 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 2107 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2108 | |
Osamu Nakamura |
0:a40b9a259b52 | 2109 | var packet = { type: type, data: data }; |
Osamu Nakamura |
0:a40b9a259b52 | 2110 | this.emit('packetCreate', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 2111 | this.writeBuffer.push(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 2112 | this.callbackBuffer.push(fn); |
Osamu Nakamura |
0:a40b9a259b52 | 2113 | this.flush(); |
Osamu Nakamura |
0:a40b9a259b52 | 2114 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2115 | |
Osamu Nakamura |
0:a40b9a259b52 | 2116 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2117 | * Closes the connection. |
Osamu Nakamura |
0:a40b9a259b52 | 2118 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2119 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2120 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2121 | |
Osamu Nakamura |
0:a40b9a259b52 | 2122 | Socket.prototype.close = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2123 | if ('opening' == this.readyState || 'open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2124 | this.readyState = 'closing'; |
Osamu Nakamura |
0:a40b9a259b52 | 2125 | |
Osamu Nakamura |
0:a40b9a259b52 | 2126 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2127 | |
Osamu Nakamura |
0:a40b9a259b52 | 2128 | function close() { |
Osamu Nakamura |
0:a40b9a259b52 | 2129 | self.onClose('forced close'); |
Osamu Nakamura |
0:a40b9a259b52 | 2130 | debug('socket closing - telling transport to close'); |
Osamu Nakamura |
0:a40b9a259b52 | 2131 | self.transport.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 2132 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2133 | |
Osamu Nakamura |
0:a40b9a259b52 | 2134 | function cleanupAndClose() { |
Osamu Nakamura |
0:a40b9a259b52 | 2135 | self.removeListener('upgrade', cleanupAndClose); |
Osamu Nakamura |
0:a40b9a259b52 | 2136 | self.removeListener('upgradeError', cleanupAndClose); |
Osamu Nakamura |
0:a40b9a259b52 | 2137 | close(); |
Osamu Nakamura |
0:a40b9a259b52 | 2138 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2139 | |
Osamu Nakamura |
0:a40b9a259b52 | 2140 | function waitForUpgrade() { |
Osamu Nakamura |
0:a40b9a259b52 | 2141 | // wait for upgrade to finish since we can't send packets while pausing a transport |
Osamu Nakamura |
0:a40b9a259b52 | 2142 | self.once('upgrade', cleanupAndClose); |
Osamu Nakamura |
0:a40b9a259b52 | 2143 | self.once('upgradeError', cleanupAndClose); |
Osamu Nakamura |
0:a40b9a259b52 | 2144 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2145 | |
Osamu Nakamura |
0:a40b9a259b52 | 2146 | if (this.writeBuffer.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 2147 | this.once('drain', function() { |
Osamu Nakamura |
0:a40b9a259b52 | 2148 | if (this.upgrading) { |
Osamu Nakamura |
0:a40b9a259b52 | 2149 | waitForUpgrade(); |
Osamu Nakamura |
0:a40b9a259b52 | 2150 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2151 | close(); |
Osamu Nakamura |
0:a40b9a259b52 | 2152 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2153 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 2154 | } else if (this.upgrading) { |
Osamu Nakamura |
0:a40b9a259b52 | 2155 | waitForUpgrade(); |
Osamu Nakamura |
0:a40b9a259b52 | 2156 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2157 | close(); |
Osamu Nakamura |
0:a40b9a259b52 | 2158 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2159 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2160 | |
Osamu Nakamura |
0:a40b9a259b52 | 2161 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 2162 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2163 | |
Osamu Nakamura |
0:a40b9a259b52 | 2164 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2165 | * Called upon transport error |
Osamu Nakamura |
0:a40b9a259b52 | 2166 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2167 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2168 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2169 | |
Osamu Nakamura |
0:a40b9a259b52 | 2170 | Socket.prototype.onError = function (err) { |
Osamu Nakamura |
0:a40b9a259b52 | 2171 | debug('socket error %j', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2172 | Socket.priorWebsocketSuccess = false; |
Osamu Nakamura |
0:a40b9a259b52 | 2173 | this.emit('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2174 | this.onClose('transport error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2175 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2176 | |
Osamu Nakamura |
0:a40b9a259b52 | 2177 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2178 | * Called upon transport close. |
Osamu Nakamura |
0:a40b9a259b52 | 2179 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2180 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2181 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2182 | |
Osamu Nakamura |
0:a40b9a259b52 | 2183 | Socket.prototype.onClose = function (reason, desc) { |
Osamu Nakamura |
0:a40b9a259b52 | 2184 | if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2185 | debug('socket close with reason: "%s"', reason); |
Osamu Nakamura |
0:a40b9a259b52 | 2186 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2187 | |
Osamu Nakamura |
0:a40b9a259b52 | 2188 | // clear timers |
Osamu Nakamura |
0:a40b9a259b52 | 2189 | clearTimeout(this.pingIntervalTimer); |
Osamu Nakamura |
0:a40b9a259b52 | 2190 | clearTimeout(this.pingTimeoutTimer); |
Osamu Nakamura |
0:a40b9a259b52 | 2191 | |
Osamu Nakamura |
0:a40b9a259b52 | 2192 | // clean buffers in next tick, so developers can still |
Osamu Nakamura |
0:a40b9a259b52 | 2193 | // grab the buffers on `close` event |
Osamu Nakamura |
0:a40b9a259b52 | 2194 | setTimeout(function() { |
Osamu Nakamura |
0:a40b9a259b52 | 2195 | self.writeBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 2196 | self.callbackBuffer = []; |
Osamu Nakamura |
0:a40b9a259b52 | 2197 | self.prevBufferLen = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 2198 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 2199 | |
Osamu Nakamura |
0:a40b9a259b52 | 2200 | // stop event from firing again for transport |
Osamu Nakamura |
0:a40b9a259b52 | 2201 | this.transport.removeAllListeners('close'); |
Osamu Nakamura |
0:a40b9a259b52 | 2202 | |
Osamu Nakamura |
0:a40b9a259b52 | 2203 | // ensure transport won't stay open |
Osamu Nakamura |
0:a40b9a259b52 | 2204 | this.transport.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 2205 | |
Osamu Nakamura |
0:a40b9a259b52 | 2206 | // ignore further transport communication |
Osamu Nakamura |
0:a40b9a259b52 | 2207 | this.transport.removeAllListeners(); |
Osamu Nakamura |
0:a40b9a259b52 | 2208 | |
Osamu Nakamura |
0:a40b9a259b52 | 2209 | // set ready state |
Osamu Nakamura |
0:a40b9a259b52 | 2210 | this.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 2211 | |
Osamu Nakamura |
0:a40b9a259b52 | 2212 | // clear session id |
Osamu Nakamura |
0:a40b9a259b52 | 2213 | this.id = null; |
Osamu Nakamura |
0:a40b9a259b52 | 2214 | |
Osamu Nakamura |
0:a40b9a259b52 | 2215 | // emit close event |
Osamu Nakamura |
0:a40b9a259b52 | 2216 | this.emit('close', reason, desc); |
Osamu Nakamura |
0:a40b9a259b52 | 2217 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2218 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2219 | |
Osamu Nakamura |
0:a40b9a259b52 | 2220 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2221 | * Filters upgrades, returning only those matching client transports. |
Osamu Nakamura |
0:a40b9a259b52 | 2222 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2223 | * @param {Array} server upgrades |
Osamu Nakamura |
0:a40b9a259b52 | 2224 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2225 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2226 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2227 | |
Osamu Nakamura |
0:a40b9a259b52 | 2228 | Socket.prototype.filterUpgrades = function (upgrades) { |
Osamu Nakamura |
0:a40b9a259b52 | 2229 | var filteredUpgrades = []; |
Osamu Nakamura |
0:a40b9a259b52 | 2230 | for (var i = 0, j = upgrades.length; i<j; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 2231 | if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 2232 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2233 | return filteredUpgrades; |
Osamu Nakamura |
0:a40b9a259b52 | 2234 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2235 | |
Osamu Nakamura |
0:a40b9a259b52 | 2236 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 2237 | },{"./transport":14,"./transports":15,"component-emitter":9,"debug":22,"engine.io-parser":25,"indexof":42,"parsejson":34,"parseqs":35,"parseuri":36}],14:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 2238 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2239 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 2240 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2241 | |
Osamu Nakamura |
0:a40b9a259b52 | 2242 | var parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 2243 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 2244 | |
Osamu Nakamura |
0:a40b9a259b52 | 2245 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2246 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 2247 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2248 | |
Osamu Nakamura |
0:a40b9a259b52 | 2249 | module.exports = Transport; |
Osamu Nakamura |
0:a40b9a259b52 | 2250 | |
Osamu Nakamura |
0:a40b9a259b52 | 2251 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2252 | * Transport abstract constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 2253 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2254 | * @param {Object} options. |
Osamu Nakamura |
0:a40b9a259b52 | 2255 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2256 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2257 | |
Osamu Nakamura |
0:a40b9a259b52 | 2258 | function Transport (opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 2259 | this.path = opts.path; |
Osamu Nakamura |
0:a40b9a259b52 | 2260 | this.hostname = opts.hostname; |
Osamu Nakamura |
0:a40b9a259b52 | 2261 | this.port = opts.port; |
Osamu Nakamura |
0:a40b9a259b52 | 2262 | this.secure = opts.secure; |
Osamu Nakamura |
0:a40b9a259b52 | 2263 | this.query = opts.query; |
Osamu Nakamura |
0:a40b9a259b52 | 2264 | this.timestampParam = opts.timestampParam; |
Osamu Nakamura |
0:a40b9a259b52 | 2265 | this.timestampRequests = opts.timestampRequests; |
Osamu Nakamura |
0:a40b9a259b52 | 2266 | this.readyState = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 2267 | this.agent = opts.agent || false; |
Osamu Nakamura |
0:a40b9a259b52 | 2268 | this.socket = opts.socket; |
Osamu Nakamura |
0:a40b9a259b52 | 2269 | this.enablesXDR = opts.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 2270 | |
Osamu Nakamura |
0:a40b9a259b52 | 2271 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 2272 | this.pfx = opts.pfx; |
Osamu Nakamura |
0:a40b9a259b52 | 2273 | this.key = opts.key; |
Osamu Nakamura |
0:a40b9a259b52 | 2274 | this.passphrase = opts.passphrase; |
Osamu Nakamura |
0:a40b9a259b52 | 2275 | this.cert = opts.cert; |
Osamu Nakamura |
0:a40b9a259b52 | 2276 | this.ca = opts.ca; |
Osamu Nakamura |
0:a40b9a259b52 | 2277 | this.ciphers = opts.ciphers; |
Osamu Nakamura |
0:a40b9a259b52 | 2278 | this.rejectUnauthorized = opts.rejectUnauthorized; |
Osamu Nakamura |
0:a40b9a259b52 | 2279 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2280 | |
Osamu Nakamura |
0:a40b9a259b52 | 2281 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2282 | * Mix in `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 2283 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2284 | |
Osamu Nakamura |
0:a40b9a259b52 | 2285 | Emitter(Transport.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 2286 | |
Osamu Nakamura |
0:a40b9a259b52 | 2287 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2288 | * A counter used to prevent collisions in the timestamps used |
Osamu Nakamura |
0:a40b9a259b52 | 2289 | * for cache busting. |
Osamu Nakamura |
0:a40b9a259b52 | 2290 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2291 | |
Osamu Nakamura |
0:a40b9a259b52 | 2292 | Transport.timestamps = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 2293 | |
Osamu Nakamura |
0:a40b9a259b52 | 2294 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2295 | * Emits an error. |
Osamu Nakamura |
0:a40b9a259b52 | 2296 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2297 | * @param {String} str |
Osamu Nakamura |
0:a40b9a259b52 | 2298 | * @return {Transport} for chaining |
Osamu Nakamura |
0:a40b9a259b52 | 2299 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2300 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2301 | |
Osamu Nakamura |
0:a40b9a259b52 | 2302 | Transport.prototype.onError = function (msg, desc) { |
Osamu Nakamura |
0:a40b9a259b52 | 2303 | var err = new Error(msg); |
Osamu Nakamura |
0:a40b9a259b52 | 2304 | err.type = 'TransportError'; |
Osamu Nakamura |
0:a40b9a259b52 | 2305 | err.description = desc; |
Osamu Nakamura |
0:a40b9a259b52 | 2306 | this.emit('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2307 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 2308 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2309 | |
Osamu Nakamura |
0:a40b9a259b52 | 2310 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2311 | * Opens the transport. |
Osamu Nakamura |
0:a40b9a259b52 | 2312 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2313 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2314 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2315 | |
Osamu Nakamura |
0:a40b9a259b52 | 2316 | Transport.prototype.open = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2317 | if ('closed' == this.readyState || '' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2318 | this.readyState = 'opening'; |
Osamu Nakamura |
0:a40b9a259b52 | 2319 | this.doOpen(); |
Osamu Nakamura |
0:a40b9a259b52 | 2320 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2321 | |
Osamu Nakamura |
0:a40b9a259b52 | 2322 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 2323 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2324 | |
Osamu Nakamura |
0:a40b9a259b52 | 2325 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2326 | * Closes the transport. |
Osamu Nakamura |
0:a40b9a259b52 | 2327 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2328 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2329 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2330 | |
Osamu Nakamura |
0:a40b9a259b52 | 2331 | Transport.prototype.close = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2332 | if ('opening' == this.readyState || 'open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2333 | this.doClose(); |
Osamu Nakamura |
0:a40b9a259b52 | 2334 | this.onClose(); |
Osamu Nakamura |
0:a40b9a259b52 | 2335 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2336 | |
Osamu Nakamura |
0:a40b9a259b52 | 2337 | return this; |
Osamu Nakamura |
0:a40b9a259b52 | 2338 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2339 | |
Osamu Nakamura |
0:a40b9a259b52 | 2340 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2341 | * Sends multiple packets. |
Osamu Nakamura |
0:a40b9a259b52 | 2342 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2343 | * @param {Array} packets |
Osamu Nakamura |
0:a40b9a259b52 | 2344 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2345 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2346 | |
Osamu Nakamura |
0:a40b9a259b52 | 2347 | Transport.prototype.send = function(packets){ |
Osamu Nakamura |
0:a40b9a259b52 | 2348 | if ('open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 2349 | this.write(packets); |
Osamu Nakamura |
0:a40b9a259b52 | 2350 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2351 | throw new Error('Transport not open'); |
Osamu Nakamura |
0:a40b9a259b52 | 2352 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2353 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2354 | |
Osamu Nakamura |
0:a40b9a259b52 | 2355 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2356 | * Called upon open |
Osamu Nakamura |
0:a40b9a259b52 | 2357 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2358 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2359 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2360 | |
Osamu Nakamura |
0:a40b9a259b52 | 2361 | Transport.prototype.onOpen = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2362 | this.readyState = 'open'; |
Osamu Nakamura |
0:a40b9a259b52 | 2363 | this.writable = true; |
Osamu Nakamura |
0:a40b9a259b52 | 2364 | this.emit('open'); |
Osamu Nakamura |
0:a40b9a259b52 | 2365 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2366 | |
Osamu Nakamura |
0:a40b9a259b52 | 2367 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2368 | * Called with data. |
Osamu Nakamura |
0:a40b9a259b52 | 2369 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2370 | * @param {String} data |
Osamu Nakamura |
0:a40b9a259b52 | 2371 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2372 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2373 | |
Osamu Nakamura |
0:a40b9a259b52 | 2374 | Transport.prototype.onData = function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 2375 | var packet = parser.decodePacket(data, this.socket.binaryType); |
Osamu Nakamura |
0:a40b9a259b52 | 2376 | this.onPacket(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 2377 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2378 | |
Osamu Nakamura |
0:a40b9a259b52 | 2379 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2380 | * Called with a decoded packet. |
Osamu Nakamura |
0:a40b9a259b52 | 2381 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2382 | |
Osamu Nakamura |
0:a40b9a259b52 | 2383 | Transport.prototype.onPacket = function (packet) { |
Osamu Nakamura |
0:a40b9a259b52 | 2384 | this.emit('packet', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 2385 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2386 | |
Osamu Nakamura |
0:a40b9a259b52 | 2387 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2388 | * Called upon close. |
Osamu Nakamura |
0:a40b9a259b52 | 2389 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2390 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2391 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2392 | |
Osamu Nakamura |
0:a40b9a259b52 | 2393 | Transport.prototype.onClose = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2394 | this.readyState = 'closed'; |
Osamu Nakamura |
0:a40b9a259b52 | 2395 | this.emit('close'); |
Osamu Nakamura |
0:a40b9a259b52 | 2396 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2397 | |
Osamu Nakamura |
0:a40b9a259b52 | 2398 | },{"component-emitter":9,"engine.io-parser":25}],15:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 2399 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 2400 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2401 | * Module dependencies |
Osamu Nakamura |
0:a40b9a259b52 | 2402 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2403 | |
Osamu Nakamura |
0:a40b9a259b52 | 2404 | var XMLHttpRequest = _dereq_('xmlhttprequest'); |
Osamu Nakamura |
0:a40b9a259b52 | 2405 | var XHR = _dereq_('./polling-xhr'); |
Osamu Nakamura |
0:a40b9a259b52 | 2406 | var JSONP = _dereq_('./polling-jsonp'); |
Osamu Nakamura |
0:a40b9a259b52 | 2407 | var websocket = _dereq_('./websocket'); |
Osamu Nakamura |
0:a40b9a259b52 | 2408 | |
Osamu Nakamura |
0:a40b9a259b52 | 2409 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2410 | * Export transports. |
Osamu Nakamura |
0:a40b9a259b52 | 2411 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2412 | |
Osamu Nakamura |
0:a40b9a259b52 | 2413 | exports.polling = polling; |
Osamu Nakamura |
0:a40b9a259b52 | 2414 | exports.websocket = websocket; |
Osamu Nakamura |
0:a40b9a259b52 | 2415 | |
Osamu Nakamura |
0:a40b9a259b52 | 2416 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2417 | * Polling transport polymorphic constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 2418 | * Decides on xhr vs jsonp based on feature detection. |
Osamu Nakamura |
0:a40b9a259b52 | 2419 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2420 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2421 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2422 | |
Osamu Nakamura |
0:a40b9a259b52 | 2423 | function polling(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 2424 | var xhr; |
Osamu Nakamura |
0:a40b9a259b52 | 2425 | var xd = false; |
Osamu Nakamura |
0:a40b9a259b52 | 2426 | var xs = false; |
Osamu Nakamura |
0:a40b9a259b52 | 2427 | var jsonp = false !== opts.jsonp; |
Osamu Nakamura |
0:a40b9a259b52 | 2428 | |
Osamu Nakamura |
0:a40b9a259b52 | 2429 | if (global.location) { |
Osamu Nakamura |
0:a40b9a259b52 | 2430 | var isSSL = 'https:' == location.protocol; |
Osamu Nakamura |
0:a40b9a259b52 | 2431 | var port = location.port; |
Osamu Nakamura |
0:a40b9a259b52 | 2432 | |
Osamu Nakamura |
0:a40b9a259b52 | 2433 | // some user agents have empty `location.port` |
Osamu Nakamura |
0:a40b9a259b52 | 2434 | if (!port) { |
Osamu Nakamura |
0:a40b9a259b52 | 2435 | port = isSSL ? 443 : 80; |
Osamu Nakamura |
0:a40b9a259b52 | 2436 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2437 | |
Osamu Nakamura |
0:a40b9a259b52 | 2438 | xd = opts.hostname != location.hostname || port != opts.port; |
Osamu Nakamura |
0:a40b9a259b52 | 2439 | xs = opts.secure != isSSL; |
Osamu Nakamura |
0:a40b9a259b52 | 2440 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2441 | |
Osamu Nakamura |
0:a40b9a259b52 | 2442 | opts.xdomain = xd; |
Osamu Nakamura |
0:a40b9a259b52 | 2443 | opts.xscheme = xs; |
Osamu Nakamura |
0:a40b9a259b52 | 2444 | xhr = new XMLHttpRequest(opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2445 | |
Osamu Nakamura |
0:a40b9a259b52 | 2446 | if ('open' in xhr && !opts.forceJSONP) { |
Osamu Nakamura |
0:a40b9a259b52 | 2447 | return new XHR(opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2448 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2449 | if (!jsonp) throw new Error('JSONP disabled'); |
Osamu Nakamura |
0:a40b9a259b52 | 2450 | return new JSONP(opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2451 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2452 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2453 | |
Osamu Nakamura |
0:a40b9a259b52 | 2454 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 2455 | },{"./polling-jsonp":16,"./polling-xhr":17,"./websocket":19,"xmlhttprequest":20}],16:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 2456 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 2457 | |
Osamu Nakamura |
0:a40b9a259b52 | 2458 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2459 | * Module requirements. |
Osamu Nakamura |
0:a40b9a259b52 | 2460 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2461 | |
Osamu Nakamura |
0:a40b9a259b52 | 2462 | var Polling = _dereq_('./polling'); |
Osamu Nakamura |
0:a40b9a259b52 | 2463 | var inherit = _dereq_('component-inherit'); |
Osamu Nakamura |
0:a40b9a259b52 | 2464 | |
Osamu Nakamura |
0:a40b9a259b52 | 2465 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2466 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 2467 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2468 | |
Osamu Nakamura |
0:a40b9a259b52 | 2469 | module.exports = JSONPPolling; |
Osamu Nakamura |
0:a40b9a259b52 | 2470 | |
Osamu Nakamura |
0:a40b9a259b52 | 2471 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2472 | * Cached regular expressions. |
Osamu Nakamura |
0:a40b9a259b52 | 2473 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2474 | |
Osamu Nakamura |
0:a40b9a259b52 | 2475 | var rNewline = /\n/g; |
Osamu Nakamura |
0:a40b9a259b52 | 2476 | var rEscapedNewline = /\\n/g; |
Osamu Nakamura |
0:a40b9a259b52 | 2477 | |
Osamu Nakamura |
0:a40b9a259b52 | 2478 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2479 | * Global JSONP callbacks. |
Osamu Nakamura |
0:a40b9a259b52 | 2480 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2481 | |
Osamu Nakamura |
0:a40b9a259b52 | 2482 | var callbacks; |
Osamu Nakamura |
0:a40b9a259b52 | 2483 | |
Osamu Nakamura |
0:a40b9a259b52 | 2484 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2485 | * Callbacks count. |
Osamu Nakamura |
0:a40b9a259b52 | 2486 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2487 | |
Osamu Nakamura |
0:a40b9a259b52 | 2488 | var index = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 2489 | |
Osamu Nakamura |
0:a40b9a259b52 | 2490 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2491 | * Noop. |
Osamu Nakamura |
0:a40b9a259b52 | 2492 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2493 | |
Osamu Nakamura |
0:a40b9a259b52 | 2494 | function empty () { } |
Osamu Nakamura |
0:a40b9a259b52 | 2495 | |
Osamu Nakamura |
0:a40b9a259b52 | 2496 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2497 | * JSONP Polling constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 2498 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2499 | * @param {Object} opts. |
Osamu Nakamura |
0:a40b9a259b52 | 2500 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2501 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2502 | |
Osamu Nakamura |
0:a40b9a259b52 | 2503 | function JSONPPolling (opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 2504 | Polling.call(this, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2505 | |
Osamu Nakamura |
0:a40b9a259b52 | 2506 | this.query = this.query || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 2507 | |
Osamu Nakamura |
0:a40b9a259b52 | 2508 | // define global callbacks array if not present |
Osamu Nakamura |
0:a40b9a259b52 | 2509 | // we do this here (lazily) to avoid unneeded global pollution |
Osamu Nakamura |
0:a40b9a259b52 | 2510 | if (!callbacks) { |
Osamu Nakamura |
0:a40b9a259b52 | 2511 | // we need to consider multiple engines in the same page |
Osamu Nakamura |
0:a40b9a259b52 | 2512 | if (!global.___eio) global.___eio = []; |
Osamu Nakamura |
0:a40b9a259b52 | 2513 | callbacks = global.___eio; |
Osamu Nakamura |
0:a40b9a259b52 | 2514 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2515 | |
Osamu Nakamura |
0:a40b9a259b52 | 2516 | // callback identifier |
Osamu Nakamura |
0:a40b9a259b52 | 2517 | this.index = callbacks.length; |
Osamu Nakamura |
0:a40b9a259b52 | 2518 | |
Osamu Nakamura |
0:a40b9a259b52 | 2519 | // add callback to jsonp global |
Osamu Nakamura |
0:a40b9a259b52 | 2520 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2521 | callbacks.push(function (msg) { |
Osamu Nakamura |
0:a40b9a259b52 | 2522 | self.onData(msg); |
Osamu Nakamura |
0:a40b9a259b52 | 2523 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 2524 | |
Osamu Nakamura |
0:a40b9a259b52 | 2525 | // append to query string |
Osamu Nakamura |
0:a40b9a259b52 | 2526 | this.query.j = this.index; |
Osamu Nakamura |
0:a40b9a259b52 | 2527 | |
Osamu Nakamura |
0:a40b9a259b52 | 2528 | // prevent spurious errors from being emitted when the window is unloaded |
Osamu Nakamura |
0:a40b9a259b52 | 2529 | if (global.document && global.addEventListener) { |
Osamu Nakamura |
0:a40b9a259b52 | 2530 | global.addEventListener('beforeunload', function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2531 | if (self.script) self.script.onerror = empty; |
Osamu Nakamura |
0:a40b9a259b52 | 2532 | }, false); |
Osamu Nakamura |
0:a40b9a259b52 | 2533 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2534 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2535 | |
Osamu Nakamura |
0:a40b9a259b52 | 2536 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2537 | * Inherits from Polling. |
Osamu Nakamura |
0:a40b9a259b52 | 2538 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2539 | |
Osamu Nakamura |
0:a40b9a259b52 | 2540 | inherit(JSONPPolling, Polling); |
Osamu Nakamura |
0:a40b9a259b52 | 2541 | |
Osamu Nakamura |
0:a40b9a259b52 | 2542 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 2543 | * JSONP only supports binary as base64 encoded strings |
Osamu Nakamura |
0:a40b9a259b52 | 2544 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2545 | |
Osamu Nakamura |
0:a40b9a259b52 | 2546 | JSONPPolling.prototype.supportsBinary = false; |
Osamu Nakamura |
0:a40b9a259b52 | 2547 | |
Osamu Nakamura |
0:a40b9a259b52 | 2548 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2549 | * Closes the socket. |
Osamu Nakamura |
0:a40b9a259b52 | 2550 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2551 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2552 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2553 | |
Osamu Nakamura |
0:a40b9a259b52 | 2554 | JSONPPolling.prototype.doClose = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2555 | if (this.script) { |
Osamu Nakamura |
0:a40b9a259b52 | 2556 | this.script.parentNode.removeChild(this.script); |
Osamu Nakamura |
0:a40b9a259b52 | 2557 | this.script = null; |
Osamu Nakamura |
0:a40b9a259b52 | 2558 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2559 | |
Osamu Nakamura |
0:a40b9a259b52 | 2560 | if (this.form) { |
Osamu Nakamura |
0:a40b9a259b52 | 2561 | this.form.parentNode.removeChild(this.form); |
Osamu Nakamura |
0:a40b9a259b52 | 2562 | this.form = null; |
Osamu Nakamura |
0:a40b9a259b52 | 2563 | this.iframe = null; |
Osamu Nakamura |
0:a40b9a259b52 | 2564 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2565 | |
Osamu Nakamura |
0:a40b9a259b52 | 2566 | Polling.prototype.doClose.call(this); |
Osamu Nakamura |
0:a40b9a259b52 | 2567 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2568 | |
Osamu Nakamura |
0:a40b9a259b52 | 2569 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2570 | * Starts a poll cycle. |
Osamu Nakamura |
0:a40b9a259b52 | 2571 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2572 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2573 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2574 | |
Osamu Nakamura |
0:a40b9a259b52 | 2575 | JSONPPolling.prototype.doPoll = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2576 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2577 | var script = document.createElement('script'); |
Osamu Nakamura |
0:a40b9a259b52 | 2578 | |
Osamu Nakamura |
0:a40b9a259b52 | 2579 | if (this.script) { |
Osamu Nakamura |
0:a40b9a259b52 | 2580 | this.script.parentNode.removeChild(this.script); |
Osamu Nakamura |
0:a40b9a259b52 | 2581 | this.script = null; |
Osamu Nakamura |
0:a40b9a259b52 | 2582 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2583 | |
Osamu Nakamura |
0:a40b9a259b52 | 2584 | script.async = true; |
Osamu Nakamura |
0:a40b9a259b52 | 2585 | script.src = this.uri(); |
Osamu Nakamura |
0:a40b9a259b52 | 2586 | script.onerror = function(e){ |
Osamu Nakamura |
0:a40b9a259b52 | 2587 | self.onError('jsonp poll error',e); |
Osamu Nakamura |
0:a40b9a259b52 | 2588 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2589 | |
Osamu Nakamura |
0:a40b9a259b52 | 2590 | var insertAt = document.getElementsByTagName('script')[0]; |
Osamu Nakamura |
0:a40b9a259b52 | 2591 | insertAt.parentNode.insertBefore(script, insertAt); |
Osamu Nakamura |
0:a40b9a259b52 | 2592 | this.script = script; |
Osamu Nakamura |
0:a40b9a259b52 | 2593 | |
Osamu Nakamura |
0:a40b9a259b52 | 2594 | var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent); |
Osamu Nakamura |
0:a40b9a259b52 | 2595 | |
Osamu Nakamura |
0:a40b9a259b52 | 2596 | if (isUAgecko) { |
Osamu Nakamura |
0:a40b9a259b52 | 2597 | setTimeout(function () { |
Osamu Nakamura |
0:a40b9a259b52 | 2598 | var iframe = document.createElement('iframe'); |
Osamu Nakamura |
0:a40b9a259b52 | 2599 | document.body.appendChild(iframe); |
Osamu Nakamura |
0:a40b9a259b52 | 2600 | document.body.removeChild(iframe); |
Osamu Nakamura |
0:a40b9a259b52 | 2601 | }, 100); |
Osamu Nakamura |
0:a40b9a259b52 | 2602 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2603 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2604 | |
Osamu Nakamura |
0:a40b9a259b52 | 2605 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2606 | * Writes with a hidden iframe. |
Osamu Nakamura |
0:a40b9a259b52 | 2607 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2608 | * @param {String} data to send |
Osamu Nakamura |
0:a40b9a259b52 | 2609 | * @param {Function} called upon flush. |
Osamu Nakamura |
0:a40b9a259b52 | 2610 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2611 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2612 | |
Osamu Nakamura |
0:a40b9a259b52 | 2613 | JSONPPolling.prototype.doWrite = function (data, fn) { |
Osamu Nakamura |
0:a40b9a259b52 | 2614 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2615 | |
Osamu Nakamura |
0:a40b9a259b52 | 2616 | if (!this.form) { |
Osamu Nakamura |
0:a40b9a259b52 | 2617 | var form = document.createElement('form'); |
Osamu Nakamura |
0:a40b9a259b52 | 2618 | var area = document.createElement('textarea'); |
Osamu Nakamura |
0:a40b9a259b52 | 2619 | var id = this.iframeId = 'eio_iframe_' + this.index; |
Osamu Nakamura |
0:a40b9a259b52 | 2620 | var iframe; |
Osamu Nakamura |
0:a40b9a259b52 | 2621 | |
Osamu Nakamura |
0:a40b9a259b52 | 2622 | form.className = 'socketio'; |
Osamu Nakamura |
0:a40b9a259b52 | 2623 | form.style.position = 'absolute'; |
Osamu Nakamura |
0:a40b9a259b52 | 2624 | form.style.top = '-1000px'; |
Osamu Nakamura |
0:a40b9a259b52 | 2625 | form.style.left = '-1000px'; |
Osamu Nakamura |
0:a40b9a259b52 | 2626 | form.target = id; |
Osamu Nakamura |
0:a40b9a259b52 | 2627 | form.method = 'POST'; |
Osamu Nakamura |
0:a40b9a259b52 | 2628 | form.setAttribute('accept-charset', 'utf-8'); |
Osamu Nakamura |
0:a40b9a259b52 | 2629 | area.name = 'd'; |
Osamu Nakamura |
0:a40b9a259b52 | 2630 | form.appendChild(area); |
Osamu Nakamura |
0:a40b9a259b52 | 2631 | document.body.appendChild(form); |
Osamu Nakamura |
0:a40b9a259b52 | 2632 | |
Osamu Nakamura |
0:a40b9a259b52 | 2633 | this.form = form; |
Osamu Nakamura |
0:a40b9a259b52 | 2634 | this.area = area; |
Osamu Nakamura |
0:a40b9a259b52 | 2635 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2636 | |
Osamu Nakamura |
0:a40b9a259b52 | 2637 | this.form.action = this.uri(); |
Osamu Nakamura |
0:a40b9a259b52 | 2638 | |
Osamu Nakamura |
0:a40b9a259b52 | 2639 | function complete () { |
Osamu Nakamura |
0:a40b9a259b52 | 2640 | initIframe(); |
Osamu Nakamura |
0:a40b9a259b52 | 2641 | fn(); |
Osamu Nakamura |
0:a40b9a259b52 | 2642 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2643 | |
Osamu Nakamura |
0:a40b9a259b52 | 2644 | function initIframe () { |
Osamu Nakamura |
0:a40b9a259b52 | 2645 | if (self.iframe) { |
Osamu Nakamura |
0:a40b9a259b52 | 2646 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2647 | self.form.removeChild(self.iframe); |
Osamu Nakamura |
0:a40b9a259b52 | 2648 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 2649 | self.onError('jsonp polling iframe removal error', e); |
Osamu Nakamura |
0:a40b9a259b52 | 2650 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2651 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2652 | |
Osamu Nakamura |
0:a40b9a259b52 | 2653 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2654 | // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) |
Osamu Nakamura |
0:a40b9a259b52 | 2655 | var html = '<iframe src="javascript:0" name="'+ self.iframeId +'">'; |
Osamu Nakamura |
0:a40b9a259b52 | 2656 | iframe = document.createElement(html); |
Osamu Nakamura |
0:a40b9a259b52 | 2657 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 2658 | iframe = document.createElement('iframe'); |
Osamu Nakamura |
0:a40b9a259b52 | 2659 | iframe.name = self.iframeId; |
Osamu Nakamura |
0:a40b9a259b52 | 2660 | iframe.src = 'javascript:0'; |
Osamu Nakamura |
0:a40b9a259b52 | 2661 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2662 | |
Osamu Nakamura |
0:a40b9a259b52 | 2663 | iframe.id = self.iframeId; |
Osamu Nakamura |
0:a40b9a259b52 | 2664 | |
Osamu Nakamura |
0:a40b9a259b52 | 2665 | self.form.appendChild(iframe); |
Osamu Nakamura |
0:a40b9a259b52 | 2666 | self.iframe = iframe; |
Osamu Nakamura |
0:a40b9a259b52 | 2667 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2668 | |
Osamu Nakamura |
0:a40b9a259b52 | 2669 | initIframe(); |
Osamu Nakamura |
0:a40b9a259b52 | 2670 | |
Osamu Nakamura |
0:a40b9a259b52 | 2671 | // escape \n to prevent it from being converted into \r\n by some UAs |
Osamu Nakamura |
0:a40b9a259b52 | 2672 | // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side |
Osamu Nakamura |
0:a40b9a259b52 | 2673 | data = data.replace(rEscapedNewline, '\\\n'); |
Osamu Nakamura |
0:a40b9a259b52 | 2674 | this.area.value = data.replace(rNewline, '\\n'); |
Osamu Nakamura |
0:a40b9a259b52 | 2675 | |
Osamu Nakamura |
0:a40b9a259b52 | 2676 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2677 | this.form.submit(); |
Osamu Nakamura |
0:a40b9a259b52 | 2678 | } catch(e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 2679 | |
Osamu Nakamura |
0:a40b9a259b52 | 2680 | if (this.iframe.attachEvent) { |
Osamu Nakamura |
0:a40b9a259b52 | 2681 | this.iframe.onreadystatechange = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2682 | if (self.iframe.readyState == 'complete') { |
Osamu Nakamura |
0:a40b9a259b52 | 2683 | complete(); |
Osamu Nakamura |
0:a40b9a259b52 | 2684 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2685 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2686 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2687 | this.iframe.onload = complete; |
Osamu Nakamura |
0:a40b9a259b52 | 2688 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2689 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2690 | |
Osamu Nakamura |
0:a40b9a259b52 | 2691 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 2692 | },{"./polling":18,"component-inherit":21}],17:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 2693 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 2694 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2695 | * Module requirements. |
Osamu Nakamura |
0:a40b9a259b52 | 2696 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2697 | |
Osamu Nakamura |
0:a40b9a259b52 | 2698 | var XMLHttpRequest = _dereq_('xmlhttprequest'); |
Osamu Nakamura |
0:a40b9a259b52 | 2699 | var Polling = _dereq_('./polling'); |
Osamu Nakamura |
0:a40b9a259b52 | 2700 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 2701 | var inherit = _dereq_('component-inherit'); |
Osamu Nakamura |
0:a40b9a259b52 | 2702 | var debug = _dereq_('debug')('engine.io-client:polling-xhr'); |
Osamu Nakamura |
0:a40b9a259b52 | 2703 | |
Osamu Nakamura |
0:a40b9a259b52 | 2704 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2705 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 2706 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2707 | |
Osamu Nakamura |
0:a40b9a259b52 | 2708 | module.exports = XHR; |
Osamu Nakamura |
0:a40b9a259b52 | 2709 | module.exports.Request = Request; |
Osamu Nakamura |
0:a40b9a259b52 | 2710 | |
Osamu Nakamura |
0:a40b9a259b52 | 2711 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2712 | * Empty function |
Osamu Nakamura |
0:a40b9a259b52 | 2713 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2714 | |
Osamu Nakamura |
0:a40b9a259b52 | 2715 | function empty(){} |
Osamu Nakamura |
0:a40b9a259b52 | 2716 | |
Osamu Nakamura |
0:a40b9a259b52 | 2717 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2718 | * XHR Polling constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 2719 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2720 | * @param {Object} opts |
Osamu Nakamura |
0:a40b9a259b52 | 2721 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2722 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2723 | |
Osamu Nakamura |
0:a40b9a259b52 | 2724 | function XHR(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 2725 | Polling.call(this, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2726 | |
Osamu Nakamura |
0:a40b9a259b52 | 2727 | if (global.location) { |
Osamu Nakamura |
0:a40b9a259b52 | 2728 | var isSSL = 'https:' == location.protocol; |
Osamu Nakamura |
0:a40b9a259b52 | 2729 | var port = location.port; |
Osamu Nakamura |
0:a40b9a259b52 | 2730 | |
Osamu Nakamura |
0:a40b9a259b52 | 2731 | // some user agents have empty `location.port` |
Osamu Nakamura |
0:a40b9a259b52 | 2732 | if (!port) { |
Osamu Nakamura |
0:a40b9a259b52 | 2733 | port = isSSL ? 443 : 80; |
Osamu Nakamura |
0:a40b9a259b52 | 2734 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2735 | |
Osamu Nakamura |
0:a40b9a259b52 | 2736 | this.xd = opts.hostname != global.location.hostname || |
Osamu Nakamura |
0:a40b9a259b52 | 2737 | port != opts.port; |
Osamu Nakamura |
0:a40b9a259b52 | 2738 | this.xs = opts.secure != isSSL; |
Osamu Nakamura |
0:a40b9a259b52 | 2739 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2740 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2741 | |
Osamu Nakamura |
0:a40b9a259b52 | 2742 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2743 | * Inherits from Polling. |
Osamu Nakamura |
0:a40b9a259b52 | 2744 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2745 | |
Osamu Nakamura |
0:a40b9a259b52 | 2746 | inherit(XHR, Polling); |
Osamu Nakamura |
0:a40b9a259b52 | 2747 | |
Osamu Nakamura |
0:a40b9a259b52 | 2748 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2749 | * XHR supports binary |
Osamu Nakamura |
0:a40b9a259b52 | 2750 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2751 | |
Osamu Nakamura |
0:a40b9a259b52 | 2752 | XHR.prototype.supportsBinary = true; |
Osamu Nakamura |
0:a40b9a259b52 | 2753 | |
Osamu Nakamura |
0:a40b9a259b52 | 2754 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2755 | * Creates a request. |
Osamu Nakamura |
0:a40b9a259b52 | 2756 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2757 | * @param {String} method |
Osamu Nakamura |
0:a40b9a259b52 | 2758 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2759 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2760 | |
Osamu Nakamura |
0:a40b9a259b52 | 2761 | XHR.prototype.request = function(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 2762 | opts = opts || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 2763 | opts.uri = this.uri(); |
Osamu Nakamura |
0:a40b9a259b52 | 2764 | opts.xd = this.xd; |
Osamu Nakamura |
0:a40b9a259b52 | 2765 | opts.xs = this.xs; |
Osamu Nakamura |
0:a40b9a259b52 | 2766 | opts.agent = this.agent || false; |
Osamu Nakamura |
0:a40b9a259b52 | 2767 | opts.supportsBinary = this.supportsBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 2768 | opts.enablesXDR = this.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 2769 | |
Osamu Nakamura |
0:a40b9a259b52 | 2770 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 2771 | opts.pfx = this.pfx; |
Osamu Nakamura |
0:a40b9a259b52 | 2772 | opts.key = this.key; |
Osamu Nakamura |
0:a40b9a259b52 | 2773 | opts.passphrase = this.passphrase; |
Osamu Nakamura |
0:a40b9a259b52 | 2774 | opts.cert = this.cert; |
Osamu Nakamura |
0:a40b9a259b52 | 2775 | opts.ca = this.ca; |
Osamu Nakamura |
0:a40b9a259b52 | 2776 | opts.ciphers = this.ciphers; |
Osamu Nakamura |
0:a40b9a259b52 | 2777 | opts.rejectUnauthorized = this.rejectUnauthorized; |
Osamu Nakamura |
0:a40b9a259b52 | 2778 | |
Osamu Nakamura |
0:a40b9a259b52 | 2779 | return new Request(opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2780 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2781 | |
Osamu Nakamura |
0:a40b9a259b52 | 2782 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2783 | * Sends data. |
Osamu Nakamura |
0:a40b9a259b52 | 2784 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2785 | * @param {String} data to send. |
Osamu Nakamura |
0:a40b9a259b52 | 2786 | * @param {Function} called upon flush. |
Osamu Nakamura |
0:a40b9a259b52 | 2787 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2788 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2789 | |
Osamu Nakamura |
0:a40b9a259b52 | 2790 | XHR.prototype.doWrite = function(data, fn){ |
Osamu Nakamura |
0:a40b9a259b52 | 2791 | var isBinary = typeof data !== 'string' && data !== undefined; |
Osamu Nakamura |
0:a40b9a259b52 | 2792 | var req = this.request({ method: 'POST', data: data, isBinary: isBinary }); |
Osamu Nakamura |
0:a40b9a259b52 | 2793 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2794 | req.on('success', fn); |
Osamu Nakamura |
0:a40b9a259b52 | 2795 | req.on('error', function(err){ |
Osamu Nakamura |
0:a40b9a259b52 | 2796 | self.onError('xhr post error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2797 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 2798 | this.sendXhr = req; |
Osamu Nakamura |
0:a40b9a259b52 | 2799 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2800 | |
Osamu Nakamura |
0:a40b9a259b52 | 2801 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2802 | * Starts a poll cycle. |
Osamu Nakamura |
0:a40b9a259b52 | 2803 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2804 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2805 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2806 | |
Osamu Nakamura |
0:a40b9a259b52 | 2807 | XHR.prototype.doPoll = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2808 | debug('xhr poll'); |
Osamu Nakamura |
0:a40b9a259b52 | 2809 | var req = this.request(); |
Osamu Nakamura |
0:a40b9a259b52 | 2810 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2811 | req.on('data', function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 2812 | self.onData(data); |
Osamu Nakamura |
0:a40b9a259b52 | 2813 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 2814 | req.on('error', function(err){ |
Osamu Nakamura |
0:a40b9a259b52 | 2815 | self.onError('xhr poll error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2816 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 2817 | this.pollXhr = req; |
Osamu Nakamura |
0:a40b9a259b52 | 2818 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2819 | |
Osamu Nakamura |
0:a40b9a259b52 | 2820 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2821 | * Request constructor |
Osamu Nakamura |
0:a40b9a259b52 | 2822 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2823 | * @param {Object} options |
Osamu Nakamura |
0:a40b9a259b52 | 2824 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 2825 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2826 | |
Osamu Nakamura |
0:a40b9a259b52 | 2827 | function Request(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 2828 | this.method = opts.method || 'GET'; |
Osamu Nakamura |
0:a40b9a259b52 | 2829 | this.uri = opts.uri; |
Osamu Nakamura |
0:a40b9a259b52 | 2830 | this.xd = !!opts.xd; |
Osamu Nakamura |
0:a40b9a259b52 | 2831 | this.xs = !!opts.xs; |
Osamu Nakamura |
0:a40b9a259b52 | 2832 | this.async = false !== opts.async; |
Osamu Nakamura |
0:a40b9a259b52 | 2833 | this.data = undefined != opts.data ? opts.data : null; |
Osamu Nakamura |
0:a40b9a259b52 | 2834 | this.agent = opts.agent; |
Osamu Nakamura |
0:a40b9a259b52 | 2835 | this.isBinary = opts.isBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 2836 | this.supportsBinary = opts.supportsBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 2837 | this.enablesXDR = opts.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 2838 | |
Osamu Nakamura |
0:a40b9a259b52 | 2839 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 2840 | this.pfx = opts.pfx; |
Osamu Nakamura |
0:a40b9a259b52 | 2841 | this.key = opts.key; |
Osamu Nakamura |
0:a40b9a259b52 | 2842 | this.passphrase = opts.passphrase; |
Osamu Nakamura |
0:a40b9a259b52 | 2843 | this.cert = opts.cert; |
Osamu Nakamura |
0:a40b9a259b52 | 2844 | this.ca = opts.ca; |
Osamu Nakamura |
0:a40b9a259b52 | 2845 | this.ciphers = opts.ciphers; |
Osamu Nakamura |
0:a40b9a259b52 | 2846 | this.rejectUnauthorized = opts.rejectUnauthorized; |
Osamu Nakamura |
0:a40b9a259b52 | 2847 | |
Osamu Nakamura |
0:a40b9a259b52 | 2848 | this.create(); |
Osamu Nakamura |
0:a40b9a259b52 | 2849 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2850 | |
Osamu Nakamura |
0:a40b9a259b52 | 2851 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2852 | * Mix in `Emitter`. |
Osamu Nakamura |
0:a40b9a259b52 | 2853 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2854 | |
Osamu Nakamura |
0:a40b9a259b52 | 2855 | Emitter(Request.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 2856 | |
Osamu Nakamura |
0:a40b9a259b52 | 2857 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2858 | * Creates the XHR object and sends the request. |
Osamu Nakamura |
0:a40b9a259b52 | 2859 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2860 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2861 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2862 | |
Osamu Nakamura |
0:a40b9a259b52 | 2863 | Request.prototype.create = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2864 | var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR }; |
Osamu Nakamura |
0:a40b9a259b52 | 2865 | |
Osamu Nakamura |
0:a40b9a259b52 | 2866 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 2867 | opts.pfx = this.pfx; |
Osamu Nakamura |
0:a40b9a259b52 | 2868 | opts.key = this.key; |
Osamu Nakamura |
0:a40b9a259b52 | 2869 | opts.passphrase = this.passphrase; |
Osamu Nakamura |
0:a40b9a259b52 | 2870 | opts.cert = this.cert; |
Osamu Nakamura |
0:a40b9a259b52 | 2871 | opts.ca = this.ca; |
Osamu Nakamura |
0:a40b9a259b52 | 2872 | opts.ciphers = this.ciphers; |
Osamu Nakamura |
0:a40b9a259b52 | 2873 | opts.rejectUnauthorized = this.rejectUnauthorized; |
Osamu Nakamura |
0:a40b9a259b52 | 2874 | |
Osamu Nakamura |
0:a40b9a259b52 | 2875 | var xhr = this.xhr = new XMLHttpRequest(opts); |
Osamu Nakamura |
0:a40b9a259b52 | 2876 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2877 | |
Osamu Nakamura |
0:a40b9a259b52 | 2878 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2879 | debug('xhr open %s: %s', this.method, this.uri); |
Osamu Nakamura |
0:a40b9a259b52 | 2880 | xhr.open(this.method, this.uri, this.async); |
Osamu Nakamura |
0:a40b9a259b52 | 2881 | if (this.supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 2882 | // This has to be done after open because Firefox is stupid |
Osamu Nakamura |
0:a40b9a259b52 | 2883 | // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension |
Osamu Nakamura |
0:a40b9a259b52 | 2884 | xhr.responseType = 'arraybuffer'; |
Osamu Nakamura |
0:a40b9a259b52 | 2885 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2886 | |
Osamu Nakamura |
0:a40b9a259b52 | 2887 | if ('POST' == this.method) { |
Osamu Nakamura |
0:a40b9a259b52 | 2888 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2889 | if (this.isBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 2890 | xhr.setRequestHeader('Content-type', 'application/octet-stream'); |
Osamu Nakamura |
0:a40b9a259b52 | 2891 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2892 | xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); |
Osamu Nakamura |
0:a40b9a259b52 | 2893 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2894 | } catch (e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 2895 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2896 | |
Osamu Nakamura |
0:a40b9a259b52 | 2897 | // ie6 check |
Osamu Nakamura |
0:a40b9a259b52 | 2898 | if ('withCredentials' in xhr) { |
Osamu Nakamura |
0:a40b9a259b52 | 2899 | xhr.withCredentials = true; |
Osamu Nakamura |
0:a40b9a259b52 | 2900 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2901 | |
Osamu Nakamura |
0:a40b9a259b52 | 2902 | if (this.hasXDR()) { |
Osamu Nakamura |
0:a40b9a259b52 | 2903 | xhr.onload = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2904 | self.onLoad(); |
Osamu Nakamura |
0:a40b9a259b52 | 2905 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2906 | xhr.onerror = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2907 | self.onError(xhr.responseText); |
Osamu Nakamura |
0:a40b9a259b52 | 2908 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2909 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2910 | xhr.onreadystatechange = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2911 | if (4 != xhr.readyState) return; |
Osamu Nakamura |
0:a40b9a259b52 | 2912 | if (200 == xhr.status || 1223 == xhr.status) { |
Osamu Nakamura |
0:a40b9a259b52 | 2913 | self.onLoad(); |
Osamu Nakamura |
0:a40b9a259b52 | 2914 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2915 | // make sure the `error` event handler that's user-set |
Osamu Nakamura |
0:a40b9a259b52 | 2916 | // does not throw in the same tick and gets caught here |
Osamu Nakamura |
0:a40b9a259b52 | 2917 | setTimeout(function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2918 | self.onError(xhr.status); |
Osamu Nakamura |
0:a40b9a259b52 | 2919 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 2920 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2921 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2922 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2923 | |
Osamu Nakamura |
0:a40b9a259b52 | 2924 | debug('xhr data %s', this.data); |
Osamu Nakamura |
0:a40b9a259b52 | 2925 | xhr.send(this.data); |
Osamu Nakamura |
0:a40b9a259b52 | 2926 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 2927 | // Need to defer since .create() is called directly fhrom the constructor |
Osamu Nakamura |
0:a40b9a259b52 | 2928 | // and thus the 'error' event can only be only bound *after* this exception |
Osamu Nakamura |
0:a40b9a259b52 | 2929 | // occurs. Therefore, also, we cannot throw here at all. |
Osamu Nakamura |
0:a40b9a259b52 | 2930 | setTimeout(function() { |
Osamu Nakamura |
0:a40b9a259b52 | 2931 | self.onError(e); |
Osamu Nakamura |
0:a40b9a259b52 | 2932 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 2933 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 2934 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2935 | |
Osamu Nakamura |
0:a40b9a259b52 | 2936 | if (global.document) { |
Osamu Nakamura |
0:a40b9a259b52 | 2937 | this.index = Request.requestsCount++; |
Osamu Nakamura |
0:a40b9a259b52 | 2938 | Request.requests[this.index] = this; |
Osamu Nakamura |
0:a40b9a259b52 | 2939 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2940 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2941 | |
Osamu Nakamura |
0:a40b9a259b52 | 2942 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2943 | * Called upon successful response. |
Osamu Nakamura |
0:a40b9a259b52 | 2944 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2945 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2946 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2947 | |
Osamu Nakamura |
0:a40b9a259b52 | 2948 | Request.prototype.onSuccess = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 2949 | this.emit('success'); |
Osamu Nakamura |
0:a40b9a259b52 | 2950 | this.cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 2951 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2952 | |
Osamu Nakamura |
0:a40b9a259b52 | 2953 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2954 | * Called if we have data. |
Osamu Nakamura |
0:a40b9a259b52 | 2955 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2956 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2957 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2958 | |
Osamu Nakamura |
0:a40b9a259b52 | 2959 | Request.prototype.onData = function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 2960 | this.emit('data', data); |
Osamu Nakamura |
0:a40b9a259b52 | 2961 | this.onSuccess(); |
Osamu Nakamura |
0:a40b9a259b52 | 2962 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2963 | |
Osamu Nakamura |
0:a40b9a259b52 | 2964 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2965 | * Called upon error. |
Osamu Nakamura |
0:a40b9a259b52 | 2966 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2967 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2968 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2969 | |
Osamu Nakamura |
0:a40b9a259b52 | 2970 | Request.prototype.onError = function(err){ |
Osamu Nakamura |
0:a40b9a259b52 | 2971 | this.emit('error', err); |
Osamu Nakamura |
0:a40b9a259b52 | 2972 | this.cleanup(true); |
Osamu Nakamura |
0:a40b9a259b52 | 2973 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 2974 | |
Osamu Nakamura |
0:a40b9a259b52 | 2975 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 2976 | * Cleans up house. |
Osamu Nakamura |
0:a40b9a259b52 | 2977 | * |
Osamu Nakamura |
0:a40b9a259b52 | 2978 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 2979 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 2980 | |
Osamu Nakamura |
0:a40b9a259b52 | 2981 | Request.prototype.cleanup = function(fromError){ |
Osamu Nakamura |
0:a40b9a259b52 | 2982 | if ('undefined' == typeof this.xhr || null === this.xhr) { |
Osamu Nakamura |
0:a40b9a259b52 | 2983 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 2984 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2985 | // xmlhttprequest |
Osamu Nakamura |
0:a40b9a259b52 | 2986 | if (this.hasXDR()) { |
Osamu Nakamura |
0:a40b9a259b52 | 2987 | this.xhr.onload = this.xhr.onerror = empty; |
Osamu Nakamura |
0:a40b9a259b52 | 2988 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 2989 | this.xhr.onreadystatechange = empty; |
Osamu Nakamura |
0:a40b9a259b52 | 2990 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2991 | |
Osamu Nakamura |
0:a40b9a259b52 | 2992 | if (fromError) { |
Osamu Nakamura |
0:a40b9a259b52 | 2993 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 2994 | this.xhr.abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 2995 | } catch(e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 2996 | } |
Osamu Nakamura |
0:a40b9a259b52 | 2997 | |
Osamu Nakamura |
0:a40b9a259b52 | 2998 | if (global.document) { |
Osamu Nakamura |
0:a40b9a259b52 | 2999 | delete Request.requests[this.index]; |
Osamu Nakamura |
0:a40b9a259b52 | 3000 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3001 | |
Osamu Nakamura |
0:a40b9a259b52 | 3002 | this.xhr = null; |
Osamu Nakamura |
0:a40b9a259b52 | 3003 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3004 | |
Osamu Nakamura |
0:a40b9a259b52 | 3005 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3006 | * Called upon load. |
Osamu Nakamura |
0:a40b9a259b52 | 3007 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3008 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3009 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3010 | |
Osamu Nakamura |
0:a40b9a259b52 | 3011 | Request.prototype.onLoad = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3012 | var data; |
Osamu Nakamura |
0:a40b9a259b52 | 3013 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3014 | var contentType; |
Osamu Nakamura |
0:a40b9a259b52 | 3015 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3016 | contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0]; |
Osamu Nakamura |
0:a40b9a259b52 | 3017 | } catch (e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 3018 | if (contentType === 'application/octet-stream') { |
Osamu Nakamura |
0:a40b9a259b52 | 3019 | data = this.xhr.response; |
Osamu Nakamura |
0:a40b9a259b52 | 3020 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3021 | if (!this.supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 3022 | data = this.xhr.responseText; |
Osamu Nakamura |
0:a40b9a259b52 | 3023 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3024 | data = 'ok'; |
Osamu Nakamura |
0:a40b9a259b52 | 3025 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3026 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3027 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 3028 | this.onError(e); |
Osamu Nakamura |
0:a40b9a259b52 | 3029 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3030 | if (null != data) { |
Osamu Nakamura |
0:a40b9a259b52 | 3031 | this.onData(data); |
Osamu Nakamura |
0:a40b9a259b52 | 3032 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3033 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3034 | |
Osamu Nakamura |
0:a40b9a259b52 | 3035 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3036 | * Check if it has XDomainRequest. |
Osamu Nakamura |
0:a40b9a259b52 | 3037 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3038 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3039 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3040 | |
Osamu Nakamura |
0:a40b9a259b52 | 3041 | Request.prototype.hasXDR = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3042 | return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 3043 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3044 | |
Osamu Nakamura |
0:a40b9a259b52 | 3045 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3046 | * Aborts the request. |
Osamu Nakamura |
0:a40b9a259b52 | 3047 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3048 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3049 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3050 | |
Osamu Nakamura |
0:a40b9a259b52 | 3051 | Request.prototype.abort = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3052 | this.cleanup(); |
Osamu Nakamura |
0:a40b9a259b52 | 3053 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3054 | |
Osamu Nakamura |
0:a40b9a259b52 | 3055 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3056 | * Aborts pending requests when unloading the window. This is needed to prevent |
Osamu Nakamura |
0:a40b9a259b52 | 3057 | * memory leaks (e.g. when using IE) and to ensure that no spurious error is |
Osamu Nakamura |
0:a40b9a259b52 | 3058 | * emitted. |
Osamu Nakamura |
0:a40b9a259b52 | 3059 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3060 | |
Osamu Nakamura |
0:a40b9a259b52 | 3061 | if (global.document) { |
Osamu Nakamura |
0:a40b9a259b52 | 3062 | Request.requestsCount = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3063 | Request.requests = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 3064 | if (global.attachEvent) { |
Osamu Nakamura |
0:a40b9a259b52 | 3065 | global.attachEvent('onunload', unloadHandler); |
Osamu Nakamura |
0:a40b9a259b52 | 3066 | } else if (global.addEventListener) { |
Osamu Nakamura |
0:a40b9a259b52 | 3067 | global.addEventListener('beforeunload', unloadHandler, false); |
Osamu Nakamura |
0:a40b9a259b52 | 3068 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3069 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3070 | |
Osamu Nakamura |
0:a40b9a259b52 | 3071 | function unloadHandler() { |
Osamu Nakamura |
0:a40b9a259b52 | 3072 | for (var i in Request.requests) { |
Osamu Nakamura |
0:a40b9a259b52 | 3073 | if (Request.requests.hasOwnProperty(i)) { |
Osamu Nakamura |
0:a40b9a259b52 | 3074 | Request.requests[i].abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 3075 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3076 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3077 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3078 | |
Osamu Nakamura |
0:a40b9a259b52 | 3079 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 3080 | },{"./polling":18,"component-emitter":9,"component-inherit":21,"debug":22,"xmlhttprequest":20}],18:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3081 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3082 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 3083 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3084 | |
Osamu Nakamura |
0:a40b9a259b52 | 3085 | var Transport = _dereq_('../transport'); |
Osamu Nakamura |
0:a40b9a259b52 | 3086 | var parseqs = _dereq_('parseqs'); |
Osamu Nakamura |
0:a40b9a259b52 | 3087 | var parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 3088 | var inherit = _dereq_('component-inherit'); |
Osamu Nakamura |
0:a40b9a259b52 | 3089 | var debug = _dereq_('debug')('engine.io-client:polling'); |
Osamu Nakamura |
0:a40b9a259b52 | 3090 | |
Osamu Nakamura |
0:a40b9a259b52 | 3091 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3092 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 3093 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3094 | |
Osamu Nakamura |
0:a40b9a259b52 | 3095 | module.exports = Polling; |
Osamu Nakamura |
0:a40b9a259b52 | 3096 | |
Osamu Nakamura |
0:a40b9a259b52 | 3097 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3098 | * Is XHR2 supported? |
Osamu Nakamura |
0:a40b9a259b52 | 3099 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3100 | |
Osamu Nakamura |
0:a40b9a259b52 | 3101 | var hasXHR2 = (function() { |
Osamu Nakamura |
0:a40b9a259b52 | 3102 | var XMLHttpRequest = _dereq_('xmlhttprequest'); |
Osamu Nakamura |
0:a40b9a259b52 | 3103 | var xhr = new XMLHttpRequest({ xdomain: false }); |
Osamu Nakamura |
0:a40b9a259b52 | 3104 | return null != xhr.responseType; |
Osamu Nakamura |
0:a40b9a259b52 | 3105 | })(); |
Osamu Nakamura |
0:a40b9a259b52 | 3106 | |
Osamu Nakamura |
0:a40b9a259b52 | 3107 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3108 | * Polling interface. |
Osamu Nakamura |
0:a40b9a259b52 | 3109 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3110 | * @param {Object} opts |
Osamu Nakamura |
0:a40b9a259b52 | 3111 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3112 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3113 | |
Osamu Nakamura |
0:a40b9a259b52 | 3114 | function Polling(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 3115 | var forceBase64 = (opts && opts.forceBase64); |
Osamu Nakamura |
0:a40b9a259b52 | 3116 | if (!hasXHR2 || forceBase64) { |
Osamu Nakamura |
0:a40b9a259b52 | 3117 | this.supportsBinary = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3118 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3119 | Transport.call(this, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 3120 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3121 | |
Osamu Nakamura |
0:a40b9a259b52 | 3122 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3123 | * Inherits from Transport. |
Osamu Nakamura |
0:a40b9a259b52 | 3124 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3125 | |
Osamu Nakamura |
0:a40b9a259b52 | 3126 | inherit(Polling, Transport); |
Osamu Nakamura |
0:a40b9a259b52 | 3127 | |
Osamu Nakamura |
0:a40b9a259b52 | 3128 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3129 | * Transport name. |
Osamu Nakamura |
0:a40b9a259b52 | 3130 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3131 | |
Osamu Nakamura |
0:a40b9a259b52 | 3132 | Polling.prototype.name = 'polling'; |
Osamu Nakamura |
0:a40b9a259b52 | 3133 | |
Osamu Nakamura |
0:a40b9a259b52 | 3134 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3135 | * Opens the socket (triggers polling). We write a PING message to determine |
Osamu Nakamura |
0:a40b9a259b52 | 3136 | * when the transport is open. |
Osamu Nakamura |
0:a40b9a259b52 | 3137 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3138 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3139 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3140 | |
Osamu Nakamura |
0:a40b9a259b52 | 3141 | Polling.prototype.doOpen = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3142 | this.poll(); |
Osamu Nakamura |
0:a40b9a259b52 | 3143 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3144 | |
Osamu Nakamura |
0:a40b9a259b52 | 3145 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3146 | * Pauses polling. |
Osamu Nakamura |
0:a40b9a259b52 | 3147 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3148 | * @param {Function} callback upon buffers are flushed and transport is paused |
Osamu Nakamura |
0:a40b9a259b52 | 3149 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3150 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3151 | |
Osamu Nakamura |
0:a40b9a259b52 | 3152 | Polling.prototype.pause = function(onPause){ |
Osamu Nakamura |
0:a40b9a259b52 | 3153 | var pending = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3154 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3155 | |
Osamu Nakamura |
0:a40b9a259b52 | 3156 | this.readyState = 'pausing'; |
Osamu Nakamura |
0:a40b9a259b52 | 3157 | |
Osamu Nakamura |
0:a40b9a259b52 | 3158 | function pause(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3159 | debug('paused'); |
Osamu Nakamura |
0:a40b9a259b52 | 3160 | self.readyState = 'paused'; |
Osamu Nakamura |
0:a40b9a259b52 | 3161 | onPause(); |
Osamu Nakamura |
0:a40b9a259b52 | 3162 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3163 | |
Osamu Nakamura |
0:a40b9a259b52 | 3164 | if (this.polling || !this.writable) { |
Osamu Nakamura |
0:a40b9a259b52 | 3165 | var total = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3166 | |
Osamu Nakamura |
0:a40b9a259b52 | 3167 | if (this.polling) { |
Osamu Nakamura |
0:a40b9a259b52 | 3168 | debug('we are currently polling - waiting to pause'); |
Osamu Nakamura |
0:a40b9a259b52 | 3169 | total++; |
Osamu Nakamura |
0:a40b9a259b52 | 3170 | this.once('pollComplete', function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3171 | debug('pre-pause polling complete'); |
Osamu Nakamura |
0:a40b9a259b52 | 3172 | --total || pause(); |
Osamu Nakamura |
0:a40b9a259b52 | 3173 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3174 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3175 | |
Osamu Nakamura |
0:a40b9a259b52 | 3176 | if (!this.writable) { |
Osamu Nakamura |
0:a40b9a259b52 | 3177 | debug('we are currently writing - waiting to pause'); |
Osamu Nakamura |
0:a40b9a259b52 | 3178 | total++; |
Osamu Nakamura |
0:a40b9a259b52 | 3179 | this.once('drain', function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3180 | debug('pre-pause writing complete'); |
Osamu Nakamura |
0:a40b9a259b52 | 3181 | --total || pause(); |
Osamu Nakamura |
0:a40b9a259b52 | 3182 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3183 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3184 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3185 | pause(); |
Osamu Nakamura |
0:a40b9a259b52 | 3186 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3187 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3188 | |
Osamu Nakamura |
0:a40b9a259b52 | 3189 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3190 | * Starts polling cycle. |
Osamu Nakamura |
0:a40b9a259b52 | 3191 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3192 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3193 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3194 | |
Osamu Nakamura |
0:a40b9a259b52 | 3195 | Polling.prototype.poll = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3196 | debug('polling'); |
Osamu Nakamura |
0:a40b9a259b52 | 3197 | this.polling = true; |
Osamu Nakamura |
0:a40b9a259b52 | 3198 | this.doPoll(); |
Osamu Nakamura |
0:a40b9a259b52 | 3199 | this.emit('poll'); |
Osamu Nakamura |
0:a40b9a259b52 | 3200 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3201 | |
Osamu Nakamura |
0:a40b9a259b52 | 3202 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3203 | * Overloads onData to detect payloads. |
Osamu Nakamura |
0:a40b9a259b52 | 3204 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3205 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3206 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3207 | |
Osamu Nakamura |
0:a40b9a259b52 | 3208 | Polling.prototype.onData = function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 3209 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3210 | debug('polling got data %s', data); |
Osamu Nakamura |
0:a40b9a259b52 | 3211 | var callback = function(packet, index, total) { |
Osamu Nakamura |
0:a40b9a259b52 | 3212 | // if its the first message we consider the transport open |
Osamu Nakamura |
0:a40b9a259b52 | 3213 | if ('opening' == self.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 3214 | self.onOpen(); |
Osamu Nakamura |
0:a40b9a259b52 | 3215 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3216 | |
Osamu Nakamura |
0:a40b9a259b52 | 3217 | // if its a close packet, we close the ongoing requests |
Osamu Nakamura |
0:a40b9a259b52 | 3218 | if ('close' == packet.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 3219 | self.onClose(); |
Osamu Nakamura |
0:a40b9a259b52 | 3220 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 3221 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3222 | |
Osamu Nakamura |
0:a40b9a259b52 | 3223 | // otherwise bypass onData and handle the message |
Osamu Nakamura |
0:a40b9a259b52 | 3224 | self.onPacket(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 3225 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3226 | |
Osamu Nakamura |
0:a40b9a259b52 | 3227 | // decode payload |
Osamu Nakamura |
0:a40b9a259b52 | 3228 | parser.decodePayload(data, this.socket.binaryType, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 3229 | |
Osamu Nakamura |
0:a40b9a259b52 | 3230 | // if an event did not trigger closing |
Osamu Nakamura |
0:a40b9a259b52 | 3231 | if ('closed' != this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 3232 | // if we got data we're not polling |
Osamu Nakamura |
0:a40b9a259b52 | 3233 | this.polling = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3234 | this.emit('pollComplete'); |
Osamu Nakamura |
0:a40b9a259b52 | 3235 | |
Osamu Nakamura |
0:a40b9a259b52 | 3236 | if ('open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 3237 | this.poll(); |
Osamu Nakamura |
0:a40b9a259b52 | 3238 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3239 | debug('ignoring poll - transport state "%s"', this.readyState); |
Osamu Nakamura |
0:a40b9a259b52 | 3240 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3241 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3242 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3243 | |
Osamu Nakamura |
0:a40b9a259b52 | 3244 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3245 | * For polling, send a close packet. |
Osamu Nakamura |
0:a40b9a259b52 | 3246 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3247 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3248 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3249 | |
Osamu Nakamura |
0:a40b9a259b52 | 3250 | Polling.prototype.doClose = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3251 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3252 | |
Osamu Nakamura |
0:a40b9a259b52 | 3253 | function close(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3254 | debug('writing close packet'); |
Osamu Nakamura |
0:a40b9a259b52 | 3255 | self.write([{ type: 'close' }]); |
Osamu Nakamura |
0:a40b9a259b52 | 3256 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3257 | |
Osamu Nakamura |
0:a40b9a259b52 | 3258 | if ('open' == this.readyState) { |
Osamu Nakamura |
0:a40b9a259b52 | 3259 | debug('transport open - closing'); |
Osamu Nakamura |
0:a40b9a259b52 | 3260 | close(); |
Osamu Nakamura |
0:a40b9a259b52 | 3261 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3262 | // in case we're trying to close while |
Osamu Nakamura |
0:a40b9a259b52 | 3263 | // handshaking is in progress (GH-164) |
Osamu Nakamura |
0:a40b9a259b52 | 3264 | debug('transport not open - deferring close'); |
Osamu Nakamura |
0:a40b9a259b52 | 3265 | this.once('open', close); |
Osamu Nakamura |
0:a40b9a259b52 | 3266 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3267 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3268 | |
Osamu Nakamura |
0:a40b9a259b52 | 3269 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3270 | * Writes a packets payload. |
Osamu Nakamura |
0:a40b9a259b52 | 3271 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3272 | * @param {Array} data packets |
Osamu Nakamura |
0:a40b9a259b52 | 3273 | * @param {Function} drain callback |
Osamu Nakamura |
0:a40b9a259b52 | 3274 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3275 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3276 | |
Osamu Nakamura |
0:a40b9a259b52 | 3277 | Polling.prototype.write = function(packets){ |
Osamu Nakamura |
0:a40b9a259b52 | 3278 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3279 | this.writable = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3280 | var callbackfn = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 3281 | self.writable = true; |
Osamu Nakamura |
0:a40b9a259b52 | 3282 | self.emit('drain'); |
Osamu Nakamura |
0:a40b9a259b52 | 3283 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3284 | |
Osamu Nakamura |
0:a40b9a259b52 | 3285 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3286 | parser.encodePayload(packets, this.supportsBinary, function(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 3287 | self.doWrite(data, callbackfn); |
Osamu Nakamura |
0:a40b9a259b52 | 3288 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3289 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3290 | |
Osamu Nakamura |
0:a40b9a259b52 | 3291 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3292 | * Generates uri for connection. |
Osamu Nakamura |
0:a40b9a259b52 | 3293 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3294 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3295 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3296 | |
Osamu Nakamura |
0:a40b9a259b52 | 3297 | Polling.prototype.uri = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3298 | var query = this.query || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 3299 | var schema = this.secure ? 'https' : 'http'; |
Osamu Nakamura |
0:a40b9a259b52 | 3300 | var port = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 3301 | |
Osamu Nakamura |
0:a40b9a259b52 | 3302 | // cache busting is forced |
Osamu Nakamura |
0:a40b9a259b52 | 3303 | if (false !== this.timestampRequests) { |
Osamu Nakamura |
0:a40b9a259b52 | 3304 | query[this.timestampParam] = +new Date + '-' + Transport.timestamps++; |
Osamu Nakamura |
0:a40b9a259b52 | 3305 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3306 | |
Osamu Nakamura |
0:a40b9a259b52 | 3307 | if (!this.supportsBinary && !query.sid) { |
Osamu Nakamura |
0:a40b9a259b52 | 3308 | query.b64 = 1; |
Osamu Nakamura |
0:a40b9a259b52 | 3309 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3310 | |
Osamu Nakamura |
0:a40b9a259b52 | 3311 | query = parseqs.encode(query); |
Osamu Nakamura |
0:a40b9a259b52 | 3312 | |
Osamu Nakamura |
0:a40b9a259b52 | 3313 | // avoid port if default for schema |
Osamu Nakamura |
0:a40b9a259b52 | 3314 | if (this.port && (('https' == schema && this.port != 443) || |
Osamu Nakamura |
0:a40b9a259b52 | 3315 | ('http' == schema && this.port != 80))) { |
Osamu Nakamura |
0:a40b9a259b52 | 3316 | port = ':' + this.port; |
Osamu Nakamura |
0:a40b9a259b52 | 3317 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3318 | |
Osamu Nakamura |
0:a40b9a259b52 | 3319 | // prepend ? to query |
Osamu Nakamura |
0:a40b9a259b52 | 3320 | if (query.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 3321 | query = '?' + query; |
Osamu Nakamura |
0:a40b9a259b52 | 3322 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3323 | |
Osamu Nakamura |
0:a40b9a259b52 | 3324 | return schema + '://' + this.hostname + port + this.path + query; |
Osamu Nakamura |
0:a40b9a259b52 | 3325 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3326 | |
Osamu Nakamura |
0:a40b9a259b52 | 3327 | },{"../transport":14,"component-inherit":21,"debug":22,"engine.io-parser":25,"parseqs":35,"xmlhttprequest":20}],19:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3328 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3329 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 3330 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3331 | |
Osamu Nakamura |
0:a40b9a259b52 | 3332 | var Transport = _dereq_('../transport'); |
Osamu Nakamura |
0:a40b9a259b52 | 3333 | var parser = _dereq_('engine.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 3334 | var parseqs = _dereq_('parseqs'); |
Osamu Nakamura |
0:a40b9a259b52 | 3335 | var inherit = _dereq_('component-inherit'); |
Osamu Nakamura |
0:a40b9a259b52 | 3336 | var debug = _dereq_('debug')('engine.io-client:websocket'); |
Osamu Nakamura |
0:a40b9a259b52 | 3337 | |
Osamu Nakamura |
0:a40b9a259b52 | 3338 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3339 | * `ws` exposes a WebSocket-compatible interface in |
Osamu Nakamura |
0:a40b9a259b52 | 3340 | * Node, or the `WebSocket` or `MozWebSocket` globals |
Osamu Nakamura |
0:a40b9a259b52 | 3341 | * in the browser. |
Osamu Nakamura |
0:a40b9a259b52 | 3342 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3343 | |
Osamu Nakamura |
0:a40b9a259b52 | 3344 | var WebSocket = _dereq_('ws'); |
Osamu Nakamura |
0:a40b9a259b52 | 3345 | |
Osamu Nakamura |
0:a40b9a259b52 | 3346 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3347 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 3348 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3349 | |
Osamu Nakamura |
0:a40b9a259b52 | 3350 | module.exports = WS; |
Osamu Nakamura |
0:a40b9a259b52 | 3351 | |
Osamu Nakamura |
0:a40b9a259b52 | 3352 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3353 | * WebSocket transport constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 3354 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3355 | * @api {Object} connection options |
Osamu Nakamura |
0:a40b9a259b52 | 3356 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3357 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3358 | |
Osamu Nakamura |
0:a40b9a259b52 | 3359 | function WS(opts){ |
Osamu Nakamura |
0:a40b9a259b52 | 3360 | var forceBase64 = (opts && opts.forceBase64); |
Osamu Nakamura |
0:a40b9a259b52 | 3361 | if (forceBase64) { |
Osamu Nakamura |
0:a40b9a259b52 | 3362 | this.supportsBinary = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3363 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3364 | Transport.call(this, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 3365 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3366 | |
Osamu Nakamura |
0:a40b9a259b52 | 3367 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3368 | * Inherits from Transport. |
Osamu Nakamura |
0:a40b9a259b52 | 3369 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3370 | |
Osamu Nakamura |
0:a40b9a259b52 | 3371 | inherit(WS, Transport); |
Osamu Nakamura |
0:a40b9a259b52 | 3372 | |
Osamu Nakamura |
0:a40b9a259b52 | 3373 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3374 | * Transport name. |
Osamu Nakamura |
0:a40b9a259b52 | 3375 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3376 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3377 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3378 | |
Osamu Nakamura |
0:a40b9a259b52 | 3379 | WS.prototype.name = 'websocket'; |
Osamu Nakamura |
0:a40b9a259b52 | 3380 | |
Osamu Nakamura |
0:a40b9a259b52 | 3381 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 3382 | * WebSockets support binary |
Osamu Nakamura |
0:a40b9a259b52 | 3383 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3384 | |
Osamu Nakamura |
0:a40b9a259b52 | 3385 | WS.prototype.supportsBinary = true; |
Osamu Nakamura |
0:a40b9a259b52 | 3386 | |
Osamu Nakamura |
0:a40b9a259b52 | 3387 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3388 | * Opens socket. |
Osamu Nakamura |
0:a40b9a259b52 | 3389 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3390 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3391 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3392 | |
Osamu Nakamura |
0:a40b9a259b52 | 3393 | WS.prototype.doOpen = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3394 | if (!this.check()) { |
Osamu Nakamura |
0:a40b9a259b52 | 3395 | // let probe timeout |
Osamu Nakamura |
0:a40b9a259b52 | 3396 | return; |
Osamu Nakamura |
0:a40b9a259b52 | 3397 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3398 | |
Osamu Nakamura |
0:a40b9a259b52 | 3399 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3400 | var uri = this.uri(); |
Osamu Nakamura |
0:a40b9a259b52 | 3401 | var protocols = void(0); |
Osamu Nakamura |
0:a40b9a259b52 | 3402 | var opts = { agent: this.agent }; |
Osamu Nakamura |
0:a40b9a259b52 | 3403 | |
Osamu Nakamura |
0:a40b9a259b52 | 3404 | // SSL options for Node.js client |
Osamu Nakamura |
0:a40b9a259b52 | 3405 | opts.pfx = this.pfx; |
Osamu Nakamura |
0:a40b9a259b52 | 3406 | opts.key = this.key; |
Osamu Nakamura |
0:a40b9a259b52 | 3407 | opts.passphrase = this.passphrase; |
Osamu Nakamura |
0:a40b9a259b52 | 3408 | opts.cert = this.cert; |
Osamu Nakamura |
0:a40b9a259b52 | 3409 | opts.ca = this.ca; |
Osamu Nakamura |
0:a40b9a259b52 | 3410 | opts.ciphers = this.ciphers; |
Osamu Nakamura |
0:a40b9a259b52 | 3411 | opts.rejectUnauthorized = this.rejectUnauthorized; |
Osamu Nakamura |
0:a40b9a259b52 | 3412 | |
Osamu Nakamura |
0:a40b9a259b52 | 3413 | this.ws = new WebSocket(uri, protocols, opts); |
Osamu Nakamura |
0:a40b9a259b52 | 3414 | |
Osamu Nakamura |
0:a40b9a259b52 | 3415 | if (this.ws.binaryType === undefined) { |
Osamu Nakamura |
0:a40b9a259b52 | 3416 | this.supportsBinary = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3417 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3418 | |
Osamu Nakamura |
0:a40b9a259b52 | 3419 | this.ws.binaryType = 'arraybuffer'; |
Osamu Nakamura |
0:a40b9a259b52 | 3420 | this.addEventListeners(); |
Osamu Nakamura |
0:a40b9a259b52 | 3421 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3422 | |
Osamu Nakamura |
0:a40b9a259b52 | 3423 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3424 | * Adds event listeners to the socket |
Osamu Nakamura |
0:a40b9a259b52 | 3425 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3426 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3427 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3428 | |
Osamu Nakamura |
0:a40b9a259b52 | 3429 | WS.prototype.addEventListeners = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3430 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3431 | |
Osamu Nakamura |
0:a40b9a259b52 | 3432 | this.ws.onopen = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3433 | self.onOpen(); |
Osamu Nakamura |
0:a40b9a259b52 | 3434 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3435 | this.ws.onclose = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3436 | self.onClose(); |
Osamu Nakamura |
0:a40b9a259b52 | 3437 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3438 | this.ws.onmessage = function(ev){ |
Osamu Nakamura |
0:a40b9a259b52 | 3439 | self.onData(ev.data); |
Osamu Nakamura |
0:a40b9a259b52 | 3440 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3441 | this.ws.onerror = function(e){ |
Osamu Nakamura |
0:a40b9a259b52 | 3442 | self.onError('websocket error', e); |
Osamu Nakamura |
0:a40b9a259b52 | 3443 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3444 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3445 | |
Osamu Nakamura |
0:a40b9a259b52 | 3446 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3447 | * Override `onData` to use a timer on iOS. |
Osamu Nakamura |
0:a40b9a259b52 | 3448 | * See: https://gist.github.com/mloughran/2052006 |
Osamu Nakamura |
0:a40b9a259b52 | 3449 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3450 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3451 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3452 | |
Osamu Nakamura |
0:a40b9a259b52 | 3453 | if ('undefined' != typeof navigator |
Osamu Nakamura |
0:a40b9a259b52 | 3454 | && /iPad|iPhone|iPod/i.test(navigator.userAgent)) { |
Osamu Nakamura |
0:a40b9a259b52 | 3455 | WS.prototype.onData = function(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 3456 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3457 | setTimeout(function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3458 | Transport.prototype.onData.call(self, data); |
Osamu Nakamura |
0:a40b9a259b52 | 3459 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 3460 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3461 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3462 | |
Osamu Nakamura |
0:a40b9a259b52 | 3463 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3464 | * Writes data to socket. |
Osamu Nakamura |
0:a40b9a259b52 | 3465 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3466 | * @param {Array} array of packets. |
Osamu Nakamura |
0:a40b9a259b52 | 3467 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3468 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3469 | |
Osamu Nakamura |
0:a40b9a259b52 | 3470 | WS.prototype.write = function(packets){ |
Osamu Nakamura |
0:a40b9a259b52 | 3471 | var self = this; |
Osamu Nakamura |
0:a40b9a259b52 | 3472 | this.writable = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3473 | // encodePacket efficient as it uses WS framing |
Osamu Nakamura |
0:a40b9a259b52 | 3474 | // no need for encodePayload |
Osamu Nakamura |
0:a40b9a259b52 | 3475 | for (var i = 0, l = packets.length; i < l; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 3476 | parser.encodePacket(packets[i], this.supportsBinary, function(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 3477 | //Sometimes the websocket has already been closed but the browser didn't |
Osamu Nakamura |
0:a40b9a259b52 | 3478 | //have a chance of informing us about it yet, in that case send will |
Osamu Nakamura |
0:a40b9a259b52 | 3479 | //throw an error |
Osamu Nakamura |
0:a40b9a259b52 | 3480 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3481 | self.ws.send(data); |
Osamu Nakamura |
0:a40b9a259b52 | 3482 | } catch (e){ |
Osamu Nakamura |
0:a40b9a259b52 | 3483 | debug('websocket closed before onclose event'); |
Osamu Nakamura |
0:a40b9a259b52 | 3484 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3485 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3486 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3487 | |
Osamu Nakamura |
0:a40b9a259b52 | 3488 | function ondrain() { |
Osamu Nakamura |
0:a40b9a259b52 | 3489 | self.writable = true; |
Osamu Nakamura |
0:a40b9a259b52 | 3490 | self.emit('drain'); |
Osamu Nakamura |
0:a40b9a259b52 | 3491 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3492 | // fake drain |
Osamu Nakamura |
0:a40b9a259b52 | 3493 | // defer to next tick to allow Socket to clear writeBuffer |
Osamu Nakamura |
0:a40b9a259b52 | 3494 | setTimeout(ondrain, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 3495 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3496 | |
Osamu Nakamura |
0:a40b9a259b52 | 3497 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3498 | * Called upon close |
Osamu Nakamura |
0:a40b9a259b52 | 3499 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3500 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3501 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3502 | |
Osamu Nakamura |
0:a40b9a259b52 | 3503 | WS.prototype.onClose = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3504 | Transport.prototype.onClose.call(this); |
Osamu Nakamura |
0:a40b9a259b52 | 3505 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3506 | |
Osamu Nakamura |
0:a40b9a259b52 | 3507 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3508 | * Closes socket. |
Osamu Nakamura |
0:a40b9a259b52 | 3509 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3510 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3511 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3512 | |
Osamu Nakamura |
0:a40b9a259b52 | 3513 | WS.prototype.doClose = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3514 | if (typeof this.ws !== 'undefined') { |
Osamu Nakamura |
0:a40b9a259b52 | 3515 | this.ws.close(); |
Osamu Nakamura |
0:a40b9a259b52 | 3516 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3517 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3518 | |
Osamu Nakamura |
0:a40b9a259b52 | 3519 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3520 | * Generates uri for connection. |
Osamu Nakamura |
0:a40b9a259b52 | 3521 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3522 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3523 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3524 | |
Osamu Nakamura |
0:a40b9a259b52 | 3525 | WS.prototype.uri = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3526 | var query = this.query || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 3527 | var schema = this.secure ? 'wss' : 'ws'; |
Osamu Nakamura |
0:a40b9a259b52 | 3528 | var port = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 3529 | |
Osamu Nakamura |
0:a40b9a259b52 | 3530 | // avoid port if default for schema |
Osamu Nakamura |
0:a40b9a259b52 | 3531 | if (this.port && (('wss' == schema && this.port != 443) |
Osamu Nakamura |
0:a40b9a259b52 | 3532 | || ('ws' == schema && this.port != 80))) { |
Osamu Nakamura |
0:a40b9a259b52 | 3533 | port = ':' + this.port; |
Osamu Nakamura |
0:a40b9a259b52 | 3534 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3535 | |
Osamu Nakamura |
0:a40b9a259b52 | 3536 | // append timestamp to URI |
Osamu Nakamura |
0:a40b9a259b52 | 3537 | if (this.timestampRequests) { |
Osamu Nakamura |
0:a40b9a259b52 | 3538 | query[this.timestampParam] = +new Date; |
Osamu Nakamura |
0:a40b9a259b52 | 3539 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3540 | |
Osamu Nakamura |
0:a40b9a259b52 | 3541 | // communicate binary support capabilities |
Osamu Nakamura |
0:a40b9a259b52 | 3542 | if (!this.supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 3543 | query.b64 = 1; |
Osamu Nakamura |
0:a40b9a259b52 | 3544 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3545 | |
Osamu Nakamura |
0:a40b9a259b52 | 3546 | query = parseqs.encode(query); |
Osamu Nakamura |
0:a40b9a259b52 | 3547 | |
Osamu Nakamura |
0:a40b9a259b52 | 3548 | // prepend ? to query |
Osamu Nakamura |
0:a40b9a259b52 | 3549 | if (query.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 3550 | query = '?' + query; |
Osamu Nakamura |
0:a40b9a259b52 | 3551 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3552 | |
Osamu Nakamura |
0:a40b9a259b52 | 3553 | return schema + '://' + this.hostname + port + this.path + query; |
Osamu Nakamura |
0:a40b9a259b52 | 3554 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3555 | |
Osamu Nakamura |
0:a40b9a259b52 | 3556 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3557 | * Feature detection for WebSocket. |
Osamu Nakamura |
0:a40b9a259b52 | 3558 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3559 | * @return {Boolean} whether this transport is available. |
Osamu Nakamura |
0:a40b9a259b52 | 3560 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3561 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3562 | |
Osamu Nakamura |
0:a40b9a259b52 | 3563 | WS.prototype.check = function(){ |
Osamu Nakamura |
0:a40b9a259b52 | 3564 | return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name); |
Osamu Nakamura |
0:a40b9a259b52 | 3565 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3566 | |
Osamu Nakamura |
0:a40b9a259b52 | 3567 | },{"../transport":14,"component-inherit":21,"debug":22,"engine.io-parser":25,"parseqs":35,"ws":37}],20:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3568 | // browser shim for xmlhttprequest module |
Osamu Nakamura |
0:a40b9a259b52 | 3569 | var hasCORS = _dereq_('has-cors'); |
Osamu Nakamura |
0:a40b9a259b52 | 3570 | |
Osamu Nakamura |
0:a40b9a259b52 | 3571 | module.exports = function(opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 3572 | var xdomain = opts.xdomain; |
Osamu Nakamura |
0:a40b9a259b52 | 3573 | |
Osamu Nakamura |
0:a40b9a259b52 | 3574 | // scheme must be same when usign XDomainRequest |
Osamu Nakamura |
0:a40b9a259b52 | 3575 | // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx |
Osamu Nakamura |
0:a40b9a259b52 | 3576 | var xscheme = opts.xscheme; |
Osamu Nakamura |
0:a40b9a259b52 | 3577 | |
Osamu Nakamura |
0:a40b9a259b52 | 3578 | // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default. |
Osamu Nakamura |
0:a40b9a259b52 | 3579 | // https://github.com/Automattic/engine.io-client/pull/217 |
Osamu Nakamura |
0:a40b9a259b52 | 3580 | var enablesXDR = opts.enablesXDR; |
Osamu Nakamura |
0:a40b9a259b52 | 3581 | |
Osamu Nakamura |
0:a40b9a259b52 | 3582 | // XMLHttpRequest can be disabled on IE |
Osamu Nakamura |
0:a40b9a259b52 | 3583 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3584 | if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) { |
Osamu Nakamura |
0:a40b9a259b52 | 3585 | return new XMLHttpRequest(); |
Osamu Nakamura |
0:a40b9a259b52 | 3586 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3587 | } catch (e) { } |
Osamu Nakamura |
0:a40b9a259b52 | 3588 | |
Osamu Nakamura |
0:a40b9a259b52 | 3589 | // Use XDomainRequest for IE8 if enablesXDR is true |
Osamu Nakamura |
0:a40b9a259b52 | 3590 | // because loading bar keeps flashing when using jsonp-polling |
Osamu Nakamura |
0:a40b9a259b52 | 3591 | // https://github.com/yujiosaka/socke.io-ie8-loading-example |
Osamu Nakamura |
0:a40b9a259b52 | 3592 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3593 | if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) { |
Osamu Nakamura |
0:a40b9a259b52 | 3594 | return new XDomainRequest(); |
Osamu Nakamura |
0:a40b9a259b52 | 3595 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3596 | } catch (e) { } |
Osamu Nakamura |
0:a40b9a259b52 | 3597 | |
Osamu Nakamura |
0:a40b9a259b52 | 3598 | if (!xdomain) { |
Osamu Nakamura |
0:a40b9a259b52 | 3599 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3600 | return new ActiveXObject('Microsoft.XMLHTTP'); |
Osamu Nakamura |
0:a40b9a259b52 | 3601 | } catch(e) { } |
Osamu Nakamura |
0:a40b9a259b52 | 3602 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3603 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3604 | |
Osamu Nakamura |
0:a40b9a259b52 | 3605 | },{"has-cors":40}],21:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3606 | |
Osamu Nakamura |
0:a40b9a259b52 | 3607 | module.exports = function(a, b){ |
Osamu Nakamura |
0:a40b9a259b52 | 3608 | var fn = function(){}; |
Osamu Nakamura |
0:a40b9a259b52 | 3609 | fn.prototype = b.prototype; |
Osamu Nakamura |
0:a40b9a259b52 | 3610 | a.prototype = new fn; |
Osamu Nakamura |
0:a40b9a259b52 | 3611 | a.prototype.constructor = a; |
Osamu Nakamura |
0:a40b9a259b52 | 3612 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3613 | },{}],22:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3614 | |
Osamu Nakamura |
0:a40b9a259b52 | 3615 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3616 | * This is the web browser implementation of `debug()`. |
Osamu Nakamura |
0:a40b9a259b52 | 3617 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3618 | * Expose `debug()` as the module. |
Osamu Nakamura |
0:a40b9a259b52 | 3619 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3620 | |
Osamu Nakamura |
0:a40b9a259b52 | 3621 | exports = module.exports = _dereq_('./debug'); |
Osamu Nakamura |
0:a40b9a259b52 | 3622 | exports.log = log; |
Osamu Nakamura |
0:a40b9a259b52 | 3623 | exports.formatArgs = formatArgs; |
Osamu Nakamura |
0:a40b9a259b52 | 3624 | exports.save = save; |
Osamu Nakamura |
0:a40b9a259b52 | 3625 | exports.load = load; |
Osamu Nakamura |
0:a40b9a259b52 | 3626 | exports.useColors = useColors; |
Osamu Nakamura |
0:a40b9a259b52 | 3627 | |
Osamu Nakamura |
0:a40b9a259b52 | 3628 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3629 | * Colors. |
Osamu Nakamura |
0:a40b9a259b52 | 3630 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3631 | |
Osamu Nakamura |
0:a40b9a259b52 | 3632 | exports.colors = [ |
Osamu Nakamura |
0:a40b9a259b52 | 3633 | 'lightseagreen', |
Osamu Nakamura |
0:a40b9a259b52 | 3634 | 'forestgreen', |
Osamu Nakamura |
0:a40b9a259b52 | 3635 | 'goldenrod', |
Osamu Nakamura |
0:a40b9a259b52 | 3636 | 'dodgerblue', |
Osamu Nakamura |
0:a40b9a259b52 | 3637 | 'darkorchid', |
Osamu Nakamura |
0:a40b9a259b52 | 3638 | 'crimson' |
Osamu Nakamura |
0:a40b9a259b52 | 3639 | ]; |
Osamu Nakamura |
0:a40b9a259b52 | 3640 | |
Osamu Nakamura |
0:a40b9a259b52 | 3641 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3642 | * Currently only WebKit-based Web Inspectors, Firefox >= v31, |
Osamu Nakamura |
0:a40b9a259b52 | 3643 | * and the Firebug extension (any Firefox version) are known |
Osamu Nakamura |
0:a40b9a259b52 | 3644 | * to support "%c" CSS customizations. |
Osamu Nakamura |
0:a40b9a259b52 | 3645 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3646 | * TODO: add a `localStorage` variable to explicitly enable/disable colors |
Osamu Nakamura |
0:a40b9a259b52 | 3647 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3648 | |
Osamu Nakamura |
0:a40b9a259b52 | 3649 | function useColors() { |
Osamu Nakamura |
0:a40b9a259b52 | 3650 | // is webkit? http://stackoverflow.com/a/16459606/376773 |
Osamu Nakamura |
0:a40b9a259b52 | 3651 | return ('WebkitAppearance' in document.documentElement.style) || |
Osamu Nakamura |
0:a40b9a259b52 | 3652 | // is firebug? http://stackoverflow.com/a/398120/376773 |
Osamu Nakamura |
0:a40b9a259b52 | 3653 | (window.console && (console.firebug || (console.exception && console.table))) || |
Osamu Nakamura |
0:a40b9a259b52 | 3654 | // is firefox >= v31? |
Osamu Nakamura |
0:a40b9a259b52 | 3655 | // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages |
Osamu Nakamura |
0:a40b9a259b52 | 3656 | (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); |
Osamu Nakamura |
0:a40b9a259b52 | 3657 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3658 | |
Osamu Nakamura |
0:a40b9a259b52 | 3659 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3660 | * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. |
Osamu Nakamura |
0:a40b9a259b52 | 3661 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3662 | |
Osamu Nakamura |
0:a40b9a259b52 | 3663 | exports.formatters.j = function(v) { |
Osamu Nakamura |
0:a40b9a259b52 | 3664 | return JSON.stringify(v); |
Osamu Nakamura |
0:a40b9a259b52 | 3665 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3666 | |
Osamu Nakamura |
0:a40b9a259b52 | 3667 | |
Osamu Nakamura |
0:a40b9a259b52 | 3668 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3669 | * Colorize log arguments if enabled. |
Osamu Nakamura |
0:a40b9a259b52 | 3670 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3671 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3672 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3673 | |
Osamu Nakamura |
0:a40b9a259b52 | 3674 | function formatArgs() { |
Osamu Nakamura |
0:a40b9a259b52 | 3675 | var args = arguments; |
Osamu Nakamura |
0:a40b9a259b52 | 3676 | var useColors = this.useColors; |
Osamu Nakamura |
0:a40b9a259b52 | 3677 | |
Osamu Nakamura |
0:a40b9a259b52 | 3678 | args[0] = (useColors ? '%c' : '') |
Osamu Nakamura |
0:a40b9a259b52 | 3679 | + this.namespace |
Osamu Nakamura |
0:a40b9a259b52 | 3680 | + (useColors ? ' %c' : ' ') |
Osamu Nakamura |
0:a40b9a259b52 | 3681 | + args[0] |
Osamu Nakamura |
0:a40b9a259b52 | 3682 | + (useColors ? '%c ' : ' ') |
Osamu Nakamura |
0:a40b9a259b52 | 3683 | + '+' + exports.humanize(this.diff); |
Osamu Nakamura |
0:a40b9a259b52 | 3684 | |
Osamu Nakamura |
0:a40b9a259b52 | 3685 | if (!useColors) return args; |
Osamu Nakamura |
0:a40b9a259b52 | 3686 | |
Osamu Nakamura |
0:a40b9a259b52 | 3687 | var c = 'color: ' + this.color; |
Osamu Nakamura |
0:a40b9a259b52 | 3688 | args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); |
Osamu Nakamura |
0:a40b9a259b52 | 3689 | |
Osamu Nakamura |
0:a40b9a259b52 | 3690 | // the final "%c" is somewhat tricky, because there could be other |
Osamu Nakamura |
0:a40b9a259b52 | 3691 | // arguments passed either before or after the %c, so we need to |
Osamu Nakamura |
0:a40b9a259b52 | 3692 | // figure out the correct index to insert the CSS into |
Osamu Nakamura |
0:a40b9a259b52 | 3693 | var index = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3694 | var lastC = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3695 | args[0].replace(/%[a-z%]/g, function(match) { |
Osamu Nakamura |
0:a40b9a259b52 | 3696 | if ('%' === match) return; |
Osamu Nakamura |
0:a40b9a259b52 | 3697 | index++; |
Osamu Nakamura |
0:a40b9a259b52 | 3698 | if ('%c' === match) { |
Osamu Nakamura |
0:a40b9a259b52 | 3699 | // we only are interested in the *last* %c |
Osamu Nakamura |
0:a40b9a259b52 | 3700 | // (the user may have provided their own) |
Osamu Nakamura |
0:a40b9a259b52 | 3701 | lastC = index; |
Osamu Nakamura |
0:a40b9a259b52 | 3702 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3703 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3704 | |
Osamu Nakamura |
0:a40b9a259b52 | 3705 | args.splice(lastC, 0, c); |
Osamu Nakamura |
0:a40b9a259b52 | 3706 | return args; |
Osamu Nakamura |
0:a40b9a259b52 | 3707 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3708 | |
Osamu Nakamura |
0:a40b9a259b52 | 3709 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3710 | * Invokes `console.log()` when available. |
Osamu Nakamura |
0:a40b9a259b52 | 3711 | * No-op when `console.log` is not a "function". |
Osamu Nakamura |
0:a40b9a259b52 | 3712 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3713 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3714 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3715 | |
Osamu Nakamura |
0:a40b9a259b52 | 3716 | function log() { |
Osamu Nakamura |
0:a40b9a259b52 | 3717 | // This hackery is required for IE8, |
Osamu Nakamura |
0:a40b9a259b52 | 3718 | // where the `console.log` function doesn't have 'apply' |
Osamu Nakamura |
0:a40b9a259b52 | 3719 | return 'object' == typeof console |
Osamu Nakamura |
0:a40b9a259b52 | 3720 | && 'function' == typeof console.log |
Osamu Nakamura |
0:a40b9a259b52 | 3721 | && Function.prototype.apply.call(console.log, console, arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 3722 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3723 | |
Osamu Nakamura |
0:a40b9a259b52 | 3724 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3725 | * Save `namespaces`. |
Osamu Nakamura |
0:a40b9a259b52 | 3726 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3727 | * @param {String} namespaces |
Osamu Nakamura |
0:a40b9a259b52 | 3728 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3729 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3730 | |
Osamu Nakamura |
0:a40b9a259b52 | 3731 | function save(namespaces) { |
Osamu Nakamura |
0:a40b9a259b52 | 3732 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3733 | if (null == namespaces) { |
Osamu Nakamura |
0:a40b9a259b52 | 3734 | localStorage.removeItem('debug'); |
Osamu Nakamura |
0:a40b9a259b52 | 3735 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3736 | localStorage.debug = namespaces; |
Osamu Nakamura |
0:a40b9a259b52 | 3737 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3738 | } catch(e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 3739 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3740 | |
Osamu Nakamura |
0:a40b9a259b52 | 3741 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3742 | * Load `namespaces`. |
Osamu Nakamura |
0:a40b9a259b52 | 3743 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3744 | * @return {String} returns the previously persisted debug modes |
Osamu Nakamura |
0:a40b9a259b52 | 3745 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3746 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3747 | |
Osamu Nakamura |
0:a40b9a259b52 | 3748 | function load() { |
Osamu Nakamura |
0:a40b9a259b52 | 3749 | var r; |
Osamu Nakamura |
0:a40b9a259b52 | 3750 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 3751 | r = localStorage.debug; |
Osamu Nakamura |
0:a40b9a259b52 | 3752 | } catch(e) {} |
Osamu Nakamura |
0:a40b9a259b52 | 3753 | return r; |
Osamu Nakamura |
0:a40b9a259b52 | 3754 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3755 | |
Osamu Nakamura |
0:a40b9a259b52 | 3756 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3757 | * Enable namespaces listed in `localStorage.debug` initially. |
Osamu Nakamura |
0:a40b9a259b52 | 3758 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3759 | |
Osamu Nakamura |
0:a40b9a259b52 | 3760 | exports.enable(load()); |
Osamu Nakamura |
0:a40b9a259b52 | 3761 | |
Osamu Nakamura |
0:a40b9a259b52 | 3762 | },{"./debug":23}],23:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3763 | |
Osamu Nakamura |
0:a40b9a259b52 | 3764 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3765 | * This is the common logic for both the Node.js and web browser |
Osamu Nakamura |
0:a40b9a259b52 | 3766 | * implementations of `debug()`. |
Osamu Nakamura |
0:a40b9a259b52 | 3767 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3768 | * Expose `debug()` as the module. |
Osamu Nakamura |
0:a40b9a259b52 | 3769 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3770 | |
Osamu Nakamura |
0:a40b9a259b52 | 3771 | exports = module.exports = debug; |
Osamu Nakamura |
0:a40b9a259b52 | 3772 | exports.coerce = coerce; |
Osamu Nakamura |
0:a40b9a259b52 | 3773 | exports.disable = disable; |
Osamu Nakamura |
0:a40b9a259b52 | 3774 | exports.enable = enable; |
Osamu Nakamura |
0:a40b9a259b52 | 3775 | exports.enabled = enabled; |
Osamu Nakamura |
0:a40b9a259b52 | 3776 | exports.humanize = _dereq_('ms'); |
Osamu Nakamura |
0:a40b9a259b52 | 3777 | |
Osamu Nakamura |
0:a40b9a259b52 | 3778 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3779 | * The currently active debug mode names, and names to skip. |
Osamu Nakamura |
0:a40b9a259b52 | 3780 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3781 | |
Osamu Nakamura |
0:a40b9a259b52 | 3782 | exports.names = []; |
Osamu Nakamura |
0:a40b9a259b52 | 3783 | exports.skips = []; |
Osamu Nakamura |
0:a40b9a259b52 | 3784 | |
Osamu Nakamura |
0:a40b9a259b52 | 3785 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3786 | * Map of special "%n" handling functions, for the debug "format" argument. |
Osamu Nakamura |
0:a40b9a259b52 | 3787 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3788 | * Valid key names are a single, lowercased letter, i.e. "n". |
Osamu Nakamura |
0:a40b9a259b52 | 3789 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3790 | |
Osamu Nakamura |
0:a40b9a259b52 | 3791 | exports.formatters = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 3792 | |
Osamu Nakamura |
0:a40b9a259b52 | 3793 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3794 | * Previously assigned color. |
Osamu Nakamura |
0:a40b9a259b52 | 3795 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3796 | |
Osamu Nakamura |
0:a40b9a259b52 | 3797 | var prevColor = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3798 | |
Osamu Nakamura |
0:a40b9a259b52 | 3799 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3800 | * Previous log timestamp. |
Osamu Nakamura |
0:a40b9a259b52 | 3801 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3802 | |
Osamu Nakamura |
0:a40b9a259b52 | 3803 | var prevTime; |
Osamu Nakamura |
0:a40b9a259b52 | 3804 | |
Osamu Nakamura |
0:a40b9a259b52 | 3805 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3806 | * Select a color. |
Osamu Nakamura |
0:a40b9a259b52 | 3807 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3808 | * @return {Number} |
Osamu Nakamura |
0:a40b9a259b52 | 3809 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3810 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3811 | |
Osamu Nakamura |
0:a40b9a259b52 | 3812 | function selectColor() { |
Osamu Nakamura |
0:a40b9a259b52 | 3813 | return exports.colors[prevColor++ % exports.colors.length]; |
Osamu Nakamura |
0:a40b9a259b52 | 3814 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3815 | |
Osamu Nakamura |
0:a40b9a259b52 | 3816 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3817 | * Create a debugger with the given `namespace`. |
Osamu Nakamura |
0:a40b9a259b52 | 3818 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3819 | * @param {String} namespace |
Osamu Nakamura |
0:a40b9a259b52 | 3820 | * @return {Function} |
Osamu Nakamura |
0:a40b9a259b52 | 3821 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3822 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3823 | |
Osamu Nakamura |
0:a40b9a259b52 | 3824 | function debug(namespace) { |
Osamu Nakamura |
0:a40b9a259b52 | 3825 | |
Osamu Nakamura |
0:a40b9a259b52 | 3826 | // define the `disabled` version |
Osamu Nakamura |
0:a40b9a259b52 | 3827 | function disabled() { |
Osamu Nakamura |
0:a40b9a259b52 | 3828 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3829 | disabled.enabled = false; |
Osamu Nakamura |
0:a40b9a259b52 | 3830 | |
Osamu Nakamura |
0:a40b9a259b52 | 3831 | // define the `enabled` version |
Osamu Nakamura |
0:a40b9a259b52 | 3832 | function enabled() { |
Osamu Nakamura |
0:a40b9a259b52 | 3833 | |
Osamu Nakamura |
0:a40b9a259b52 | 3834 | var self = enabled; |
Osamu Nakamura |
0:a40b9a259b52 | 3835 | |
Osamu Nakamura |
0:a40b9a259b52 | 3836 | // set `diff` timestamp |
Osamu Nakamura |
0:a40b9a259b52 | 3837 | var curr = +new Date(); |
Osamu Nakamura |
0:a40b9a259b52 | 3838 | var ms = curr - (prevTime || curr); |
Osamu Nakamura |
0:a40b9a259b52 | 3839 | self.diff = ms; |
Osamu Nakamura |
0:a40b9a259b52 | 3840 | self.prev = prevTime; |
Osamu Nakamura |
0:a40b9a259b52 | 3841 | self.curr = curr; |
Osamu Nakamura |
0:a40b9a259b52 | 3842 | prevTime = curr; |
Osamu Nakamura |
0:a40b9a259b52 | 3843 | |
Osamu Nakamura |
0:a40b9a259b52 | 3844 | // add the `color` if not set |
Osamu Nakamura |
0:a40b9a259b52 | 3845 | if (null == self.useColors) self.useColors = exports.useColors(); |
Osamu Nakamura |
0:a40b9a259b52 | 3846 | if (null == self.color && self.useColors) self.color = selectColor(); |
Osamu Nakamura |
0:a40b9a259b52 | 3847 | |
Osamu Nakamura |
0:a40b9a259b52 | 3848 | var args = Array.prototype.slice.call(arguments); |
Osamu Nakamura |
0:a40b9a259b52 | 3849 | |
Osamu Nakamura |
0:a40b9a259b52 | 3850 | args[0] = exports.coerce(args[0]); |
Osamu Nakamura |
0:a40b9a259b52 | 3851 | |
Osamu Nakamura |
0:a40b9a259b52 | 3852 | if ('string' !== typeof args[0]) { |
Osamu Nakamura |
0:a40b9a259b52 | 3853 | // anything else let's inspect with %o |
Osamu Nakamura |
0:a40b9a259b52 | 3854 | args = ['%o'].concat(args); |
Osamu Nakamura |
0:a40b9a259b52 | 3855 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3856 | |
Osamu Nakamura |
0:a40b9a259b52 | 3857 | // apply any `formatters` transformations |
Osamu Nakamura |
0:a40b9a259b52 | 3858 | var index = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 3859 | args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { |
Osamu Nakamura |
0:a40b9a259b52 | 3860 | // if we encounter an escaped % then don't increase the array index |
Osamu Nakamura |
0:a40b9a259b52 | 3861 | if (match === '%') return match; |
Osamu Nakamura |
0:a40b9a259b52 | 3862 | index++; |
Osamu Nakamura |
0:a40b9a259b52 | 3863 | var formatter = exports.formatters[format]; |
Osamu Nakamura |
0:a40b9a259b52 | 3864 | if ('function' === typeof formatter) { |
Osamu Nakamura |
0:a40b9a259b52 | 3865 | var val = args[index]; |
Osamu Nakamura |
0:a40b9a259b52 | 3866 | match = formatter.call(self, val); |
Osamu Nakamura |
0:a40b9a259b52 | 3867 | |
Osamu Nakamura |
0:a40b9a259b52 | 3868 | // now we need to remove `args[index]` since it's inlined in the `format` |
Osamu Nakamura |
0:a40b9a259b52 | 3869 | args.splice(index, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 3870 | index--; |
Osamu Nakamura |
0:a40b9a259b52 | 3871 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3872 | return match; |
Osamu Nakamura |
0:a40b9a259b52 | 3873 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 3874 | |
Osamu Nakamura |
0:a40b9a259b52 | 3875 | if ('function' === typeof exports.formatArgs) { |
Osamu Nakamura |
0:a40b9a259b52 | 3876 | args = exports.formatArgs.apply(self, args); |
Osamu Nakamura |
0:a40b9a259b52 | 3877 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3878 | var logFn = enabled.log || exports.log || console.log.bind(console); |
Osamu Nakamura |
0:a40b9a259b52 | 3879 | logFn.apply(self, args); |
Osamu Nakamura |
0:a40b9a259b52 | 3880 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3881 | enabled.enabled = true; |
Osamu Nakamura |
0:a40b9a259b52 | 3882 | |
Osamu Nakamura |
0:a40b9a259b52 | 3883 | var fn = exports.enabled(namespace) ? enabled : disabled; |
Osamu Nakamura |
0:a40b9a259b52 | 3884 | |
Osamu Nakamura |
0:a40b9a259b52 | 3885 | fn.namespace = namespace; |
Osamu Nakamura |
0:a40b9a259b52 | 3886 | |
Osamu Nakamura |
0:a40b9a259b52 | 3887 | return fn; |
Osamu Nakamura |
0:a40b9a259b52 | 3888 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3889 | |
Osamu Nakamura |
0:a40b9a259b52 | 3890 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3891 | * Enables a debug mode by namespaces. This can include modes |
Osamu Nakamura |
0:a40b9a259b52 | 3892 | * separated by a colon and wildcards. |
Osamu Nakamura |
0:a40b9a259b52 | 3893 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3894 | * @param {String} namespaces |
Osamu Nakamura |
0:a40b9a259b52 | 3895 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3896 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3897 | |
Osamu Nakamura |
0:a40b9a259b52 | 3898 | function enable(namespaces) { |
Osamu Nakamura |
0:a40b9a259b52 | 3899 | exports.save(namespaces); |
Osamu Nakamura |
0:a40b9a259b52 | 3900 | |
Osamu Nakamura |
0:a40b9a259b52 | 3901 | var split = (namespaces || '').split(/[\s,]+/); |
Osamu Nakamura |
0:a40b9a259b52 | 3902 | var len = split.length; |
Osamu Nakamura |
0:a40b9a259b52 | 3903 | |
Osamu Nakamura |
0:a40b9a259b52 | 3904 | for (var i = 0; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 3905 | if (!split[i]) continue; // ignore empty strings |
Osamu Nakamura |
0:a40b9a259b52 | 3906 | namespaces = split[i].replace(/\*/g, '.*?'); |
Osamu Nakamura |
0:a40b9a259b52 | 3907 | if (namespaces[0] === '-') { |
Osamu Nakamura |
0:a40b9a259b52 | 3908 | exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); |
Osamu Nakamura |
0:a40b9a259b52 | 3909 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 3910 | exports.names.push(new RegExp('^' + namespaces + '$')); |
Osamu Nakamura |
0:a40b9a259b52 | 3911 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3912 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3913 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3914 | |
Osamu Nakamura |
0:a40b9a259b52 | 3915 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3916 | * Disable debug output. |
Osamu Nakamura |
0:a40b9a259b52 | 3917 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3918 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3919 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3920 | |
Osamu Nakamura |
0:a40b9a259b52 | 3921 | function disable() { |
Osamu Nakamura |
0:a40b9a259b52 | 3922 | exports.enable(''); |
Osamu Nakamura |
0:a40b9a259b52 | 3923 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3924 | |
Osamu Nakamura |
0:a40b9a259b52 | 3925 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3926 | * Returns true if the given mode name is enabled, false otherwise. |
Osamu Nakamura |
0:a40b9a259b52 | 3927 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3928 | * @param {String} name |
Osamu Nakamura |
0:a40b9a259b52 | 3929 | * @return {Boolean} |
Osamu Nakamura |
0:a40b9a259b52 | 3930 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3931 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3932 | |
Osamu Nakamura |
0:a40b9a259b52 | 3933 | function enabled(name) { |
Osamu Nakamura |
0:a40b9a259b52 | 3934 | var i, len; |
Osamu Nakamura |
0:a40b9a259b52 | 3935 | for (i = 0, len = exports.skips.length; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 3936 | if (exports.skips[i].test(name)) { |
Osamu Nakamura |
0:a40b9a259b52 | 3937 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 3938 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3939 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3940 | for (i = 0, len = exports.names.length; i < len; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 3941 | if (exports.names[i].test(name)) { |
Osamu Nakamura |
0:a40b9a259b52 | 3942 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 3943 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3944 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3945 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 3946 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3947 | |
Osamu Nakamura |
0:a40b9a259b52 | 3948 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3949 | * Coerce `val`. |
Osamu Nakamura |
0:a40b9a259b52 | 3950 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3951 | * @param {Mixed} val |
Osamu Nakamura |
0:a40b9a259b52 | 3952 | * @return {Mixed} |
Osamu Nakamura |
0:a40b9a259b52 | 3953 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3954 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3955 | |
Osamu Nakamura |
0:a40b9a259b52 | 3956 | function coerce(val) { |
Osamu Nakamura |
0:a40b9a259b52 | 3957 | if (val instanceof Error) return val.stack || val.message; |
Osamu Nakamura |
0:a40b9a259b52 | 3958 | return val; |
Osamu Nakamura |
0:a40b9a259b52 | 3959 | } |
Osamu Nakamura |
0:a40b9a259b52 | 3960 | |
Osamu Nakamura |
0:a40b9a259b52 | 3961 | },{"ms":24}],24:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 3962 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3963 | * Helpers. |
Osamu Nakamura |
0:a40b9a259b52 | 3964 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3965 | |
Osamu Nakamura |
0:a40b9a259b52 | 3966 | var s = 1000; |
Osamu Nakamura |
0:a40b9a259b52 | 3967 | var m = s * 60; |
Osamu Nakamura |
0:a40b9a259b52 | 3968 | var h = m * 60; |
Osamu Nakamura |
0:a40b9a259b52 | 3969 | var d = h * 24; |
Osamu Nakamura |
0:a40b9a259b52 | 3970 | var y = d * 365.25; |
Osamu Nakamura |
0:a40b9a259b52 | 3971 | |
Osamu Nakamura |
0:a40b9a259b52 | 3972 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3973 | * Parse or format the given `val`. |
Osamu Nakamura |
0:a40b9a259b52 | 3974 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3975 | * Options: |
Osamu Nakamura |
0:a40b9a259b52 | 3976 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3977 | * - `long` verbose formatting [false] |
Osamu Nakamura |
0:a40b9a259b52 | 3978 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3979 | * @param {String|Number} val |
Osamu Nakamura |
0:a40b9a259b52 | 3980 | * @param {Object} options |
Osamu Nakamura |
0:a40b9a259b52 | 3981 | * @return {String|Number} |
Osamu Nakamura |
0:a40b9a259b52 | 3982 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 3983 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 3984 | |
Osamu Nakamura |
0:a40b9a259b52 | 3985 | module.exports = function(val, options){ |
Osamu Nakamura |
0:a40b9a259b52 | 3986 | options = options || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 3987 | if ('string' == typeof val) return parse(val); |
Osamu Nakamura |
0:a40b9a259b52 | 3988 | return options.long |
Osamu Nakamura |
0:a40b9a259b52 | 3989 | ? long(val) |
Osamu Nakamura |
0:a40b9a259b52 | 3990 | : short(val); |
Osamu Nakamura |
0:a40b9a259b52 | 3991 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 3992 | |
Osamu Nakamura |
0:a40b9a259b52 | 3993 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 3994 | * Parse the given `str` and return milliseconds. |
Osamu Nakamura |
0:a40b9a259b52 | 3995 | * |
Osamu Nakamura |
0:a40b9a259b52 | 3996 | * @param {String} str |
Osamu Nakamura |
0:a40b9a259b52 | 3997 | * @return {Number} |
Osamu Nakamura |
0:a40b9a259b52 | 3998 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 3999 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4000 | |
Osamu Nakamura |
0:a40b9a259b52 | 4001 | function parse(str) { |
Osamu Nakamura |
0:a40b9a259b52 | 4002 | var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str); |
Osamu Nakamura |
0:a40b9a259b52 | 4003 | if (!match) return; |
Osamu Nakamura |
0:a40b9a259b52 | 4004 | var n = parseFloat(match[1]); |
Osamu Nakamura |
0:a40b9a259b52 | 4005 | var type = (match[2] || 'ms').toLowerCase(); |
Osamu Nakamura |
0:a40b9a259b52 | 4006 | switch (type) { |
Osamu Nakamura |
0:a40b9a259b52 | 4007 | case 'years': |
Osamu Nakamura |
0:a40b9a259b52 | 4008 | case 'year': |
Osamu Nakamura |
0:a40b9a259b52 | 4009 | case 'y': |
Osamu Nakamura |
0:a40b9a259b52 | 4010 | return n * y; |
Osamu Nakamura |
0:a40b9a259b52 | 4011 | case 'days': |
Osamu Nakamura |
0:a40b9a259b52 | 4012 | case 'day': |
Osamu Nakamura |
0:a40b9a259b52 | 4013 | case 'd': |
Osamu Nakamura |
0:a40b9a259b52 | 4014 | return n * d; |
Osamu Nakamura |
0:a40b9a259b52 | 4015 | case 'hours': |
Osamu Nakamura |
0:a40b9a259b52 | 4016 | case 'hour': |
Osamu Nakamura |
0:a40b9a259b52 | 4017 | case 'h': |
Osamu Nakamura |
0:a40b9a259b52 | 4018 | return n * h; |
Osamu Nakamura |
0:a40b9a259b52 | 4019 | case 'minutes': |
Osamu Nakamura |
0:a40b9a259b52 | 4020 | case 'minute': |
Osamu Nakamura |
0:a40b9a259b52 | 4021 | case 'm': |
Osamu Nakamura |
0:a40b9a259b52 | 4022 | return n * m; |
Osamu Nakamura |
0:a40b9a259b52 | 4023 | case 'seconds': |
Osamu Nakamura |
0:a40b9a259b52 | 4024 | case 'second': |
Osamu Nakamura |
0:a40b9a259b52 | 4025 | case 's': |
Osamu Nakamura |
0:a40b9a259b52 | 4026 | return n * s; |
Osamu Nakamura |
0:a40b9a259b52 | 4027 | case 'ms': |
Osamu Nakamura |
0:a40b9a259b52 | 4028 | return n; |
Osamu Nakamura |
0:a40b9a259b52 | 4029 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4030 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4031 | |
Osamu Nakamura |
0:a40b9a259b52 | 4032 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4033 | * Short format for `ms`. |
Osamu Nakamura |
0:a40b9a259b52 | 4034 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4035 | * @param {Number} ms |
Osamu Nakamura |
0:a40b9a259b52 | 4036 | * @return {String} |
Osamu Nakamura |
0:a40b9a259b52 | 4037 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4038 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4039 | |
Osamu Nakamura |
0:a40b9a259b52 | 4040 | function short(ms) { |
Osamu Nakamura |
0:a40b9a259b52 | 4041 | if (ms >= d) return Math.round(ms / d) + 'd'; |
Osamu Nakamura |
0:a40b9a259b52 | 4042 | if (ms >= h) return Math.round(ms / h) + 'h'; |
Osamu Nakamura |
0:a40b9a259b52 | 4043 | if (ms >= m) return Math.round(ms / m) + 'm'; |
Osamu Nakamura |
0:a40b9a259b52 | 4044 | if (ms >= s) return Math.round(ms / s) + 's'; |
Osamu Nakamura |
0:a40b9a259b52 | 4045 | return ms + 'ms'; |
Osamu Nakamura |
0:a40b9a259b52 | 4046 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4047 | |
Osamu Nakamura |
0:a40b9a259b52 | 4048 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4049 | * Long format for `ms`. |
Osamu Nakamura |
0:a40b9a259b52 | 4050 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4051 | * @param {Number} ms |
Osamu Nakamura |
0:a40b9a259b52 | 4052 | * @return {String} |
Osamu Nakamura |
0:a40b9a259b52 | 4053 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4054 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4055 | |
Osamu Nakamura |
0:a40b9a259b52 | 4056 | function long(ms) { |
Osamu Nakamura |
0:a40b9a259b52 | 4057 | return plural(ms, d, 'day') |
Osamu Nakamura |
0:a40b9a259b52 | 4058 | || plural(ms, h, 'hour') |
Osamu Nakamura |
0:a40b9a259b52 | 4059 | || plural(ms, m, 'minute') |
Osamu Nakamura |
0:a40b9a259b52 | 4060 | || plural(ms, s, 'second') |
Osamu Nakamura |
0:a40b9a259b52 | 4061 | || ms + ' ms'; |
Osamu Nakamura |
0:a40b9a259b52 | 4062 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4063 | |
Osamu Nakamura |
0:a40b9a259b52 | 4064 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4065 | * Pluralization helper. |
Osamu Nakamura |
0:a40b9a259b52 | 4066 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4067 | |
Osamu Nakamura |
0:a40b9a259b52 | 4068 | function plural(ms, n, name) { |
Osamu Nakamura |
0:a40b9a259b52 | 4069 | if (ms < n) return; |
Osamu Nakamura |
0:a40b9a259b52 | 4070 | if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; |
Osamu Nakamura |
0:a40b9a259b52 | 4071 | return Math.ceil(ms / n) + ' ' + name + 's'; |
Osamu Nakamura |
0:a40b9a259b52 | 4072 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4073 | |
Osamu Nakamura |
0:a40b9a259b52 | 4074 | },{}],25:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4075 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 4076 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4077 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 4078 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4079 | |
Osamu Nakamura |
0:a40b9a259b52 | 4080 | var keys = _dereq_('./keys'); |
Osamu Nakamura |
0:a40b9a259b52 | 4081 | var hasBinary = _dereq_('has-binary'); |
Osamu Nakamura |
0:a40b9a259b52 | 4082 | var sliceBuffer = _dereq_('arraybuffer.slice'); |
Osamu Nakamura |
0:a40b9a259b52 | 4083 | var base64encoder = _dereq_('base64-arraybuffer'); |
Osamu Nakamura |
0:a40b9a259b52 | 4084 | var after = _dereq_('after'); |
Osamu Nakamura |
0:a40b9a259b52 | 4085 | var utf8 = _dereq_('utf8'); |
Osamu Nakamura |
0:a40b9a259b52 | 4086 | |
Osamu Nakamura |
0:a40b9a259b52 | 4087 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4088 | * Check if we are running an android browser. That requires us to use |
Osamu Nakamura |
0:a40b9a259b52 | 4089 | * ArrayBuffer with polling transports... |
Osamu Nakamura |
0:a40b9a259b52 | 4090 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4091 | * http://ghinda.net/jpeg-blob-ajax-android/ |
Osamu Nakamura |
0:a40b9a259b52 | 4092 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4093 | |
Osamu Nakamura |
0:a40b9a259b52 | 4094 | var isAndroid = navigator.userAgent.match(/Android/i); |
Osamu Nakamura |
0:a40b9a259b52 | 4095 | |
Osamu Nakamura |
0:a40b9a259b52 | 4096 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4097 | * Check if we are running in PhantomJS. |
Osamu Nakamura |
0:a40b9a259b52 | 4098 | * Uploading a Blob with PhantomJS does not work correctly, as reported here: |
Osamu Nakamura |
0:a40b9a259b52 | 4099 | * https://github.com/ariya/phantomjs/issues/11395 |
Osamu Nakamura |
0:a40b9a259b52 | 4100 | * @type boolean |
Osamu Nakamura |
0:a40b9a259b52 | 4101 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4102 | var isPhantomJS = /PhantomJS/i.test(navigator.userAgent); |
Osamu Nakamura |
0:a40b9a259b52 | 4103 | |
Osamu Nakamura |
0:a40b9a259b52 | 4104 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4105 | * When true, avoids using Blobs to encode payloads. |
Osamu Nakamura |
0:a40b9a259b52 | 4106 | * @type boolean |
Osamu Nakamura |
0:a40b9a259b52 | 4107 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4108 | var dontSendBlobs = isAndroid || isPhantomJS; |
Osamu Nakamura |
0:a40b9a259b52 | 4109 | |
Osamu Nakamura |
0:a40b9a259b52 | 4110 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4111 | * Current protocol version. |
Osamu Nakamura |
0:a40b9a259b52 | 4112 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4113 | |
Osamu Nakamura |
0:a40b9a259b52 | 4114 | exports.protocol = 3; |
Osamu Nakamura |
0:a40b9a259b52 | 4115 | |
Osamu Nakamura |
0:a40b9a259b52 | 4116 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4117 | * Packet types. |
Osamu Nakamura |
0:a40b9a259b52 | 4118 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4119 | |
Osamu Nakamura |
0:a40b9a259b52 | 4120 | var packets = exports.packets = { |
Osamu Nakamura |
0:a40b9a259b52 | 4121 | open: 0 // non-ws |
Osamu Nakamura |
0:a40b9a259b52 | 4122 | , close: 1 // non-ws |
Osamu Nakamura |
0:a40b9a259b52 | 4123 | , ping: 2 |
Osamu Nakamura |
0:a40b9a259b52 | 4124 | , pong: 3 |
Osamu Nakamura |
0:a40b9a259b52 | 4125 | , message: 4 |
Osamu Nakamura |
0:a40b9a259b52 | 4126 | , upgrade: 5 |
Osamu Nakamura |
0:a40b9a259b52 | 4127 | , noop: 6 |
Osamu Nakamura |
0:a40b9a259b52 | 4128 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4129 | |
Osamu Nakamura |
0:a40b9a259b52 | 4130 | var packetslist = keys(packets); |
Osamu Nakamura |
0:a40b9a259b52 | 4131 | |
Osamu Nakamura |
0:a40b9a259b52 | 4132 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4133 | * Premade error packet. |
Osamu Nakamura |
0:a40b9a259b52 | 4134 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4135 | |
Osamu Nakamura |
0:a40b9a259b52 | 4136 | var err = { type: 'error', data: 'parser error' }; |
Osamu Nakamura |
0:a40b9a259b52 | 4137 | |
Osamu Nakamura |
0:a40b9a259b52 | 4138 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4139 | * Create a blob api even for blob builder when vendor prefixes exist |
Osamu Nakamura |
0:a40b9a259b52 | 4140 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4141 | |
Osamu Nakamura |
0:a40b9a259b52 | 4142 | var Blob = _dereq_('blob'); |
Osamu Nakamura |
0:a40b9a259b52 | 4143 | |
Osamu Nakamura |
0:a40b9a259b52 | 4144 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4145 | * Encodes a packet. |
Osamu Nakamura |
0:a40b9a259b52 | 4146 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4147 | * <packet type id> [ <data> ] |
Osamu Nakamura |
0:a40b9a259b52 | 4148 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4149 | * Example: |
Osamu Nakamura |
0:a40b9a259b52 | 4150 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4151 | * 5hello world |
Osamu Nakamura |
0:a40b9a259b52 | 4152 | * 3 |
Osamu Nakamura |
0:a40b9a259b52 | 4153 | * 4 |
Osamu Nakamura |
0:a40b9a259b52 | 4154 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4155 | * Binary is encoded in an identical principle |
Osamu Nakamura |
0:a40b9a259b52 | 4156 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4157 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4158 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4159 | |
Osamu Nakamura |
0:a40b9a259b52 | 4160 | exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4161 | if ('function' == typeof supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 4162 | callback = supportsBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 4163 | supportsBinary = false; |
Osamu Nakamura |
0:a40b9a259b52 | 4164 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4165 | |
Osamu Nakamura |
0:a40b9a259b52 | 4166 | if ('function' == typeof utf8encode) { |
Osamu Nakamura |
0:a40b9a259b52 | 4167 | callback = utf8encode; |
Osamu Nakamura |
0:a40b9a259b52 | 4168 | utf8encode = null; |
Osamu Nakamura |
0:a40b9a259b52 | 4169 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4170 | |
Osamu Nakamura |
0:a40b9a259b52 | 4171 | var data = (packet.data === undefined) |
Osamu Nakamura |
0:a40b9a259b52 | 4172 | ? undefined |
Osamu Nakamura |
0:a40b9a259b52 | 4173 | : packet.data.buffer || packet.data; |
Osamu Nakamura |
0:a40b9a259b52 | 4174 | |
Osamu Nakamura |
0:a40b9a259b52 | 4175 | if (global.ArrayBuffer && data instanceof ArrayBuffer) { |
Osamu Nakamura |
0:a40b9a259b52 | 4176 | return encodeArrayBuffer(packet, supportsBinary, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4177 | } else if (Blob && data instanceof global.Blob) { |
Osamu Nakamura |
0:a40b9a259b52 | 4178 | return encodeBlob(packet, supportsBinary, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4179 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4180 | |
Osamu Nakamura |
0:a40b9a259b52 | 4181 | // might be an object with { base64: true, data: dataAsBase64String } |
Osamu Nakamura |
0:a40b9a259b52 | 4182 | if (data && data.base64) { |
Osamu Nakamura |
0:a40b9a259b52 | 4183 | return encodeBase64Object(packet, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4184 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4185 | |
Osamu Nakamura |
0:a40b9a259b52 | 4186 | // Sending data as a utf-8 string |
Osamu Nakamura |
0:a40b9a259b52 | 4187 | var encoded = packets[packet.type]; |
Osamu Nakamura |
0:a40b9a259b52 | 4188 | |
Osamu Nakamura |
0:a40b9a259b52 | 4189 | // data fragment is optional |
Osamu Nakamura |
0:a40b9a259b52 | 4190 | if (undefined !== packet.data) { |
Osamu Nakamura |
0:a40b9a259b52 | 4191 | encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 4192 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4193 | |
Osamu Nakamura |
0:a40b9a259b52 | 4194 | return callback('' + encoded); |
Osamu Nakamura |
0:a40b9a259b52 | 4195 | |
Osamu Nakamura |
0:a40b9a259b52 | 4196 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4197 | |
Osamu Nakamura |
0:a40b9a259b52 | 4198 | function encodeBase64Object(packet, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4199 | // packet data is an object { base64: true, data: dataAsBase64String } |
Osamu Nakamura |
0:a40b9a259b52 | 4200 | var message = 'b' + exports.packets[packet.type] + packet.data.data; |
Osamu Nakamura |
0:a40b9a259b52 | 4201 | return callback(message); |
Osamu Nakamura |
0:a40b9a259b52 | 4202 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4203 | |
Osamu Nakamura |
0:a40b9a259b52 | 4204 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4205 | * Encode packet helpers for binary types |
Osamu Nakamura |
0:a40b9a259b52 | 4206 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4207 | |
Osamu Nakamura |
0:a40b9a259b52 | 4208 | function encodeArrayBuffer(packet, supportsBinary, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4209 | if (!supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 4210 | return exports.encodeBase64Packet(packet, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4211 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4212 | |
Osamu Nakamura |
0:a40b9a259b52 | 4213 | var data = packet.data; |
Osamu Nakamura |
0:a40b9a259b52 | 4214 | var contentArray = new Uint8Array(data); |
Osamu Nakamura |
0:a40b9a259b52 | 4215 | var resultBuffer = new Uint8Array(1 + data.byteLength); |
Osamu Nakamura |
0:a40b9a259b52 | 4216 | |
Osamu Nakamura |
0:a40b9a259b52 | 4217 | resultBuffer[0] = packets[packet.type]; |
Osamu Nakamura |
0:a40b9a259b52 | 4218 | for (var i = 0; i < contentArray.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4219 | resultBuffer[i+1] = contentArray[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 4220 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4221 | |
Osamu Nakamura |
0:a40b9a259b52 | 4222 | return callback(resultBuffer.buffer); |
Osamu Nakamura |
0:a40b9a259b52 | 4223 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4224 | |
Osamu Nakamura |
0:a40b9a259b52 | 4225 | function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4226 | if (!supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 4227 | return exports.encodeBase64Packet(packet, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4228 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4229 | |
Osamu Nakamura |
0:a40b9a259b52 | 4230 | var fr = new FileReader(); |
Osamu Nakamura |
0:a40b9a259b52 | 4231 | fr.onload = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 4232 | packet.data = fr.result; |
Osamu Nakamura |
0:a40b9a259b52 | 4233 | exports.encodePacket(packet, supportsBinary, true, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4234 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4235 | return fr.readAsArrayBuffer(packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 4236 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4237 | |
Osamu Nakamura |
0:a40b9a259b52 | 4238 | function encodeBlob(packet, supportsBinary, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4239 | if (!supportsBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 4240 | return exports.encodeBase64Packet(packet, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4241 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4242 | |
Osamu Nakamura |
0:a40b9a259b52 | 4243 | if (dontSendBlobs) { |
Osamu Nakamura |
0:a40b9a259b52 | 4244 | return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4245 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4246 | |
Osamu Nakamura |
0:a40b9a259b52 | 4247 | var length = new Uint8Array(1); |
Osamu Nakamura |
0:a40b9a259b52 | 4248 | length[0] = packets[packet.type]; |
Osamu Nakamura |
0:a40b9a259b52 | 4249 | var blob = new Blob([length.buffer, packet.data]); |
Osamu Nakamura |
0:a40b9a259b52 | 4250 | |
Osamu Nakamura |
0:a40b9a259b52 | 4251 | return callback(blob); |
Osamu Nakamura |
0:a40b9a259b52 | 4252 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4253 | |
Osamu Nakamura |
0:a40b9a259b52 | 4254 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4255 | * Encodes a packet with binary data in a base64 string |
Osamu Nakamura |
0:a40b9a259b52 | 4256 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4257 | * @param {Object} packet, has `type` and `data` |
Osamu Nakamura |
0:a40b9a259b52 | 4258 | * @return {String} base64 encoded message |
Osamu Nakamura |
0:a40b9a259b52 | 4259 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4260 | |
Osamu Nakamura |
0:a40b9a259b52 | 4261 | exports.encodeBase64Packet = function(packet, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4262 | var message = 'b' + exports.packets[packet.type]; |
Osamu Nakamura |
0:a40b9a259b52 | 4263 | if (Blob && packet.data instanceof Blob) { |
Osamu Nakamura |
0:a40b9a259b52 | 4264 | var fr = new FileReader(); |
Osamu Nakamura |
0:a40b9a259b52 | 4265 | fr.onload = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 4266 | var b64 = fr.result.split(',')[1]; |
Osamu Nakamura |
0:a40b9a259b52 | 4267 | callback(message + b64); |
Osamu Nakamura |
0:a40b9a259b52 | 4268 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4269 | return fr.readAsDataURL(packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 4270 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4271 | |
Osamu Nakamura |
0:a40b9a259b52 | 4272 | var b64data; |
Osamu Nakamura |
0:a40b9a259b52 | 4273 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 4274 | b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); |
Osamu Nakamura |
0:a40b9a259b52 | 4275 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 4276 | // iPhone Safari doesn't let you apply with typed arrays |
Osamu Nakamura |
0:a40b9a259b52 | 4277 | var typed = new Uint8Array(packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 4278 | var basic = new Array(typed.length); |
Osamu Nakamura |
0:a40b9a259b52 | 4279 | for (var i = 0; i < typed.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4280 | basic[i] = typed[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 4281 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4282 | b64data = String.fromCharCode.apply(null, basic); |
Osamu Nakamura |
0:a40b9a259b52 | 4283 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4284 | message += global.btoa(b64data); |
Osamu Nakamura |
0:a40b9a259b52 | 4285 | return callback(message); |
Osamu Nakamura |
0:a40b9a259b52 | 4286 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4287 | |
Osamu Nakamura |
0:a40b9a259b52 | 4288 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4289 | * Decodes a packet. Changes format to Blob if requested. |
Osamu Nakamura |
0:a40b9a259b52 | 4290 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4291 | * @return {Object} with `type` and `data` (if any) |
Osamu Nakamura |
0:a40b9a259b52 | 4292 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4293 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4294 | |
Osamu Nakamura |
0:a40b9a259b52 | 4295 | exports.decodePacket = function (data, binaryType, utf8decode) { |
Osamu Nakamura |
0:a40b9a259b52 | 4296 | // String data |
Osamu Nakamura |
0:a40b9a259b52 | 4297 | if (typeof data == 'string' || data === undefined) { |
Osamu Nakamura |
0:a40b9a259b52 | 4298 | if (data.charAt(0) == 'b') { |
Osamu Nakamura |
0:a40b9a259b52 | 4299 | return exports.decodeBase64Packet(data.substr(1), binaryType); |
Osamu Nakamura |
0:a40b9a259b52 | 4300 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4301 | |
Osamu Nakamura |
0:a40b9a259b52 | 4302 | if (utf8decode) { |
Osamu Nakamura |
0:a40b9a259b52 | 4303 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 4304 | data = utf8.decode(data); |
Osamu Nakamura |
0:a40b9a259b52 | 4305 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 4306 | return err; |
Osamu Nakamura |
0:a40b9a259b52 | 4307 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4308 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4309 | var type = data.charAt(0); |
Osamu Nakamura |
0:a40b9a259b52 | 4310 | |
Osamu Nakamura |
0:a40b9a259b52 | 4311 | if (Number(type) != type || !packetslist[type]) { |
Osamu Nakamura |
0:a40b9a259b52 | 4312 | return err; |
Osamu Nakamura |
0:a40b9a259b52 | 4313 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4314 | |
Osamu Nakamura |
0:a40b9a259b52 | 4315 | if (data.length > 1) { |
Osamu Nakamura |
0:a40b9a259b52 | 4316 | return { type: packetslist[type], data: data.substring(1) }; |
Osamu Nakamura |
0:a40b9a259b52 | 4317 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4318 | return { type: packetslist[type] }; |
Osamu Nakamura |
0:a40b9a259b52 | 4319 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4320 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4321 | |
Osamu Nakamura |
0:a40b9a259b52 | 4322 | var asArray = new Uint8Array(data); |
Osamu Nakamura |
0:a40b9a259b52 | 4323 | var type = asArray[0]; |
Osamu Nakamura |
0:a40b9a259b52 | 4324 | var rest = sliceBuffer(data, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4325 | if (Blob && binaryType === 'blob') { |
Osamu Nakamura |
0:a40b9a259b52 | 4326 | rest = new Blob([rest]); |
Osamu Nakamura |
0:a40b9a259b52 | 4327 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4328 | return { type: packetslist[type], data: rest }; |
Osamu Nakamura |
0:a40b9a259b52 | 4329 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4330 | |
Osamu Nakamura |
0:a40b9a259b52 | 4331 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4332 | * Decodes a packet encoded in a base64 string |
Osamu Nakamura |
0:a40b9a259b52 | 4333 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4334 | * @param {String} base64 encoded message |
Osamu Nakamura |
0:a40b9a259b52 | 4335 | * @return {Object} with `type` and `data` (if any) |
Osamu Nakamura |
0:a40b9a259b52 | 4336 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4337 | |
Osamu Nakamura |
0:a40b9a259b52 | 4338 | exports.decodeBase64Packet = function(msg, binaryType) { |
Osamu Nakamura |
0:a40b9a259b52 | 4339 | var type = packetslist[msg.charAt(0)]; |
Osamu Nakamura |
0:a40b9a259b52 | 4340 | if (!global.ArrayBuffer) { |
Osamu Nakamura |
0:a40b9a259b52 | 4341 | return { type: type, data: { base64: true, data: msg.substr(1) } }; |
Osamu Nakamura |
0:a40b9a259b52 | 4342 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4343 | |
Osamu Nakamura |
0:a40b9a259b52 | 4344 | var data = base64encoder.decode(msg.substr(1)); |
Osamu Nakamura |
0:a40b9a259b52 | 4345 | |
Osamu Nakamura |
0:a40b9a259b52 | 4346 | if (binaryType === 'blob' && Blob) { |
Osamu Nakamura |
0:a40b9a259b52 | 4347 | data = new Blob([data]); |
Osamu Nakamura |
0:a40b9a259b52 | 4348 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4349 | |
Osamu Nakamura |
0:a40b9a259b52 | 4350 | return { type: type, data: data }; |
Osamu Nakamura |
0:a40b9a259b52 | 4351 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4352 | |
Osamu Nakamura |
0:a40b9a259b52 | 4353 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4354 | * Encodes multiple messages (payload). |
Osamu Nakamura |
0:a40b9a259b52 | 4355 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4356 | * <length>:data |
Osamu Nakamura |
0:a40b9a259b52 | 4357 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4358 | * Example: |
Osamu Nakamura |
0:a40b9a259b52 | 4359 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4360 | * 11:hello world2:hi |
Osamu Nakamura |
0:a40b9a259b52 | 4361 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4362 | * If any contents are binary, they will be encoded as base64 strings. Base64 |
Osamu Nakamura |
0:a40b9a259b52 | 4363 | * encoded strings are marked with a b before the length specifier |
Osamu Nakamura |
0:a40b9a259b52 | 4364 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4365 | * @param {Array} packets |
Osamu Nakamura |
0:a40b9a259b52 | 4366 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4367 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4368 | |
Osamu Nakamura |
0:a40b9a259b52 | 4369 | exports.encodePayload = function (packets, supportsBinary, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4370 | if (typeof supportsBinary == 'function') { |
Osamu Nakamura |
0:a40b9a259b52 | 4371 | callback = supportsBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 4372 | supportsBinary = null; |
Osamu Nakamura |
0:a40b9a259b52 | 4373 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4374 | |
Osamu Nakamura |
0:a40b9a259b52 | 4375 | var isBinary = hasBinary(packets); |
Osamu Nakamura |
0:a40b9a259b52 | 4376 | |
Osamu Nakamura |
0:a40b9a259b52 | 4377 | if (supportsBinary && isBinary) { |
Osamu Nakamura |
0:a40b9a259b52 | 4378 | if (Blob && !dontSendBlobs) { |
Osamu Nakamura |
0:a40b9a259b52 | 4379 | return exports.encodePayloadAsBlob(packets, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4380 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4381 | |
Osamu Nakamura |
0:a40b9a259b52 | 4382 | return exports.encodePayloadAsArrayBuffer(packets, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4383 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4384 | |
Osamu Nakamura |
0:a40b9a259b52 | 4385 | if (!packets.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4386 | return callback('0:'); |
Osamu Nakamura |
0:a40b9a259b52 | 4387 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4388 | |
Osamu Nakamura |
0:a40b9a259b52 | 4389 | function setLengthHeader(message) { |
Osamu Nakamura |
0:a40b9a259b52 | 4390 | return message.length + ':' + message; |
Osamu Nakamura |
0:a40b9a259b52 | 4391 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4392 | |
Osamu Nakamura |
0:a40b9a259b52 | 4393 | function encodeOne(packet, doneCallback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4394 | exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) { |
Osamu Nakamura |
0:a40b9a259b52 | 4395 | doneCallback(null, setLengthHeader(message)); |
Osamu Nakamura |
0:a40b9a259b52 | 4396 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4397 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4398 | |
Osamu Nakamura |
0:a40b9a259b52 | 4399 | map(packets, encodeOne, function(err, results) { |
Osamu Nakamura |
0:a40b9a259b52 | 4400 | return callback(results.join('')); |
Osamu Nakamura |
0:a40b9a259b52 | 4401 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4402 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4403 | |
Osamu Nakamura |
0:a40b9a259b52 | 4404 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4405 | * Async array map using after |
Osamu Nakamura |
0:a40b9a259b52 | 4406 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4407 | |
Osamu Nakamura |
0:a40b9a259b52 | 4408 | function map(ary, each, done) { |
Osamu Nakamura |
0:a40b9a259b52 | 4409 | var result = new Array(ary.length); |
Osamu Nakamura |
0:a40b9a259b52 | 4410 | var next = after(ary.length, done); |
Osamu Nakamura |
0:a40b9a259b52 | 4411 | |
Osamu Nakamura |
0:a40b9a259b52 | 4412 | var eachWithIndex = function(i, el, cb) { |
Osamu Nakamura |
0:a40b9a259b52 | 4413 | each(el, function(error, msg) { |
Osamu Nakamura |
0:a40b9a259b52 | 4414 | result[i] = msg; |
Osamu Nakamura |
0:a40b9a259b52 | 4415 | cb(error, result); |
Osamu Nakamura |
0:a40b9a259b52 | 4416 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4417 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4418 | |
Osamu Nakamura |
0:a40b9a259b52 | 4419 | for (var i = 0; i < ary.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4420 | eachWithIndex(i, ary[i], next); |
Osamu Nakamura |
0:a40b9a259b52 | 4421 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4422 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4423 | |
Osamu Nakamura |
0:a40b9a259b52 | 4424 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 4425 | * Decodes data when a payload is maybe expected. Possible binary contents are |
Osamu Nakamura |
0:a40b9a259b52 | 4426 | * decoded from their base64 representation |
Osamu Nakamura |
0:a40b9a259b52 | 4427 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4428 | * @param {String} data, callback method |
Osamu Nakamura |
0:a40b9a259b52 | 4429 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 4430 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4431 | |
Osamu Nakamura |
0:a40b9a259b52 | 4432 | exports.decodePayload = function (data, binaryType, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4433 | if (typeof data != 'string') { |
Osamu Nakamura |
0:a40b9a259b52 | 4434 | return exports.decodePayloadAsBinary(data, binaryType, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 4435 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4436 | |
Osamu Nakamura |
0:a40b9a259b52 | 4437 | if (typeof binaryType === 'function') { |
Osamu Nakamura |
0:a40b9a259b52 | 4438 | callback = binaryType; |
Osamu Nakamura |
0:a40b9a259b52 | 4439 | binaryType = null; |
Osamu Nakamura |
0:a40b9a259b52 | 4440 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4441 | |
Osamu Nakamura |
0:a40b9a259b52 | 4442 | var packet; |
Osamu Nakamura |
0:a40b9a259b52 | 4443 | if (data == '') { |
Osamu Nakamura |
0:a40b9a259b52 | 4444 | // parser error - ignoring payload |
Osamu Nakamura |
0:a40b9a259b52 | 4445 | return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4446 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4447 | |
Osamu Nakamura |
0:a40b9a259b52 | 4448 | var length = '' |
Osamu Nakamura |
0:a40b9a259b52 | 4449 | , n, msg; |
Osamu Nakamura |
0:a40b9a259b52 | 4450 | |
Osamu Nakamura |
0:a40b9a259b52 | 4451 | for (var i = 0, l = data.length; i < l; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4452 | var chr = data.charAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 4453 | |
Osamu Nakamura |
0:a40b9a259b52 | 4454 | if (':' != chr) { |
Osamu Nakamura |
0:a40b9a259b52 | 4455 | length += chr; |
Osamu Nakamura |
0:a40b9a259b52 | 4456 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4457 | if ('' == length || (length != (n = Number(length)))) { |
Osamu Nakamura |
0:a40b9a259b52 | 4458 | // parser error - ignoring payload |
Osamu Nakamura |
0:a40b9a259b52 | 4459 | return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4460 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4461 | |
Osamu Nakamura |
0:a40b9a259b52 | 4462 | msg = data.substr(i + 1, n); |
Osamu Nakamura |
0:a40b9a259b52 | 4463 | |
Osamu Nakamura |
0:a40b9a259b52 | 4464 | if (length != msg.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4465 | // parser error - ignoring payload |
Osamu Nakamura |
0:a40b9a259b52 | 4466 | return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4467 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4468 | |
Osamu Nakamura |
0:a40b9a259b52 | 4469 | if (msg.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4470 | packet = exports.decodePacket(msg, binaryType, true); |
Osamu Nakamura |
0:a40b9a259b52 | 4471 | |
Osamu Nakamura |
0:a40b9a259b52 | 4472 | if (err.type == packet.type && err.data == packet.data) { |
Osamu Nakamura |
0:a40b9a259b52 | 4473 | // parser error in individual packet - ignoring payload |
Osamu Nakamura |
0:a40b9a259b52 | 4474 | return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4475 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4476 | |
Osamu Nakamura |
0:a40b9a259b52 | 4477 | var ret = callback(packet, i + n, l); |
Osamu Nakamura |
0:a40b9a259b52 | 4478 | if (false === ret) return; |
Osamu Nakamura |
0:a40b9a259b52 | 4479 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4480 | |
Osamu Nakamura |
0:a40b9a259b52 | 4481 | // advance cursor |
Osamu Nakamura |
0:a40b9a259b52 | 4482 | i += n; |
Osamu Nakamura |
0:a40b9a259b52 | 4483 | length = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 4484 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4485 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4486 | |
Osamu Nakamura |
0:a40b9a259b52 | 4487 | if (length != '') { |
Osamu Nakamura |
0:a40b9a259b52 | 4488 | // parser error - ignoring payload |
Osamu Nakamura |
0:a40b9a259b52 | 4489 | return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4490 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4491 | |
Osamu Nakamura |
0:a40b9a259b52 | 4492 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4493 | |
Osamu Nakamura |
0:a40b9a259b52 | 4494 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4495 | * Encodes multiple messages (payload) as binary. |
Osamu Nakamura |
0:a40b9a259b52 | 4496 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4497 | * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number |
Osamu Nakamura |
0:a40b9a259b52 | 4498 | * 255><data> |
Osamu Nakamura |
0:a40b9a259b52 | 4499 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4500 | * Example: |
Osamu Nakamura |
0:a40b9a259b52 | 4501 | * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers |
Osamu Nakamura |
0:a40b9a259b52 | 4502 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4503 | * @param {Array} packets |
Osamu Nakamura |
0:a40b9a259b52 | 4504 | * @return {ArrayBuffer} encoded payload |
Osamu Nakamura |
0:a40b9a259b52 | 4505 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4506 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4507 | |
Osamu Nakamura |
0:a40b9a259b52 | 4508 | exports.encodePayloadAsArrayBuffer = function(packets, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4509 | if (!packets.length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4510 | return callback(new ArrayBuffer(0)); |
Osamu Nakamura |
0:a40b9a259b52 | 4511 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4512 | |
Osamu Nakamura |
0:a40b9a259b52 | 4513 | function encodeOne(packet, doneCallback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4514 | exports.encodePacket(packet, true, true, function(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 4515 | return doneCallback(null, data); |
Osamu Nakamura |
0:a40b9a259b52 | 4516 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4517 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4518 | |
Osamu Nakamura |
0:a40b9a259b52 | 4519 | map(packets, encodeOne, function(err, encodedPackets) { |
Osamu Nakamura |
0:a40b9a259b52 | 4520 | var totalLength = encodedPackets.reduce(function(acc, p) { |
Osamu Nakamura |
0:a40b9a259b52 | 4521 | var len; |
Osamu Nakamura |
0:a40b9a259b52 | 4522 | if (typeof p === 'string'){ |
Osamu Nakamura |
0:a40b9a259b52 | 4523 | len = p.length; |
Osamu Nakamura |
0:a40b9a259b52 | 4524 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4525 | len = p.byteLength; |
Osamu Nakamura |
0:a40b9a259b52 | 4526 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4527 | return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2 |
Osamu Nakamura |
0:a40b9a259b52 | 4528 | }, 0); |
Osamu Nakamura |
0:a40b9a259b52 | 4529 | |
Osamu Nakamura |
0:a40b9a259b52 | 4530 | var resultArray = new Uint8Array(totalLength); |
Osamu Nakamura |
0:a40b9a259b52 | 4531 | |
Osamu Nakamura |
0:a40b9a259b52 | 4532 | var bufferIndex = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4533 | encodedPackets.forEach(function(p) { |
Osamu Nakamura |
0:a40b9a259b52 | 4534 | var isString = typeof p === 'string'; |
Osamu Nakamura |
0:a40b9a259b52 | 4535 | var ab = p; |
Osamu Nakamura |
0:a40b9a259b52 | 4536 | if (isString) { |
Osamu Nakamura |
0:a40b9a259b52 | 4537 | var view = new Uint8Array(p.length); |
Osamu Nakamura |
0:a40b9a259b52 | 4538 | for (var i = 0; i < p.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4539 | view[i] = p.charCodeAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 4540 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4541 | ab = view.buffer; |
Osamu Nakamura |
0:a40b9a259b52 | 4542 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4543 | |
Osamu Nakamura |
0:a40b9a259b52 | 4544 | if (isString) { // not true binary |
Osamu Nakamura |
0:a40b9a259b52 | 4545 | resultArray[bufferIndex++] = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4546 | } else { // true binary |
Osamu Nakamura |
0:a40b9a259b52 | 4547 | resultArray[bufferIndex++] = 1; |
Osamu Nakamura |
0:a40b9a259b52 | 4548 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4549 | |
Osamu Nakamura |
0:a40b9a259b52 | 4550 | var lenStr = ab.byteLength.toString(); |
Osamu Nakamura |
0:a40b9a259b52 | 4551 | for (var i = 0; i < lenStr.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4552 | resultArray[bufferIndex++] = parseInt(lenStr[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 4553 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4554 | resultArray[bufferIndex++] = 255; |
Osamu Nakamura |
0:a40b9a259b52 | 4555 | |
Osamu Nakamura |
0:a40b9a259b52 | 4556 | var view = new Uint8Array(ab); |
Osamu Nakamura |
0:a40b9a259b52 | 4557 | for (var i = 0; i < view.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4558 | resultArray[bufferIndex++] = view[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 4559 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4560 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4561 | |
Osamu Nakamura |
0:a40b9a259b52 | 4562 | return callback(resultArray.buffer); |
Osamu Nakamura |
0:a40b9a259b52 | 4563 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4564 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4565 | |
Osamu Nakamura |
0:a40b9a259b52 | 4566 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4567 | * Encode as Blob |
Osamu Nakamura |
0:a40b9a259b52 | 4568 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4569 | |
Osamu Nakamura |
0:a40b9a259b52 | 4570 | exports.encodePayloadAsBlob = function(packets, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4571 | function encodeOne(packet, doneCallback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4572 | exports.encodePacket(packet, true, true, function(encoded) { |
Osamu Nakamura |
0:a40b9a259b52 | 4573 | var binaryIdentifier = new Uint8Array(1); |
Osamu Nakamura |
0:a40b9a259b52 | 4574 | binaryIdentifier[0] = 1; |
Osamu Nakamura |
0:a40b9a259b52 | 4575 | if (typeof encoded === 'string') { |
Osamu Nakamura |
0:a40b9a259b52 | 4576 | var view = new Uint8Array(encoded.length); |
Osamu Nakamura |
0:a40b9a259b52 | 4577 | for (var i = 0; i < encoded.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4578 | view[i] = encoded.charCodeAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 4579 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4580 | encoded = view.buffer; |
Osamu Nakamura |
0:a40b9a259b52 | 4581 | binaryIdentifier[0] = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4582 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4583 | |
Osamu Nakamura |
0:a40b9a259b52 | 4584 | var len = (encoded instanceof ArrayBuffer) |
Osamu Nakamura |
0:a40b9a259b52 | 4585 | ? encoded.byteLength |
Osamu Nakamura |
0:a40b9a259b52 | 4586 | : encoded.size; |
Osamu Nakamura |
0:a40b9a259b52 | 4587 | |
Osamu Nakamura |
0:a40b9a259b52 | 4588 | var lenStr = len.toString(); |
Osamu Nakamura |
0:a40b9a259b52 | 4589 | var lengthAry = new Uint8Array(lenStr.length + 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4590 | for (var i = 0; i < lenStr.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4591 | lengthAry[i] = parseInt(lenStr[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 4592 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4593 | lengthAry[lenStr.length] = 255; |
Osamu Nakamura |
0:a40b9a259b52 | 4594 | |
Osamu Nakamura |
0:a40b9a259b52 | 4595 | if (Blob) { |
Osamu Nakamura |
0:a40b9a259b52 | 4596 | var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]); |
Osamu Nakamura |
0:a40b9a259b52 | 4597 | doneCallback(null, blob); |
Osamu Nakamura |
0:a40b9a259b52 | 4598 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4599 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4600 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4601 | |
Osamu Nakamura |
0:a40b9a259b52 | 4602 | map(packets, encodeOne, function(err, results) { |
Osamu Nakamura |
0:a40b9a259b52 | 4603 | return callback(new Blob(results)); |
Osamu Nakamura |
0:a40b9a259b52 | 4604 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4605 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4606 | |
Osamu Nakamura |
0:a40b9a259b52 | 4607 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 4608 | * Decodes data when a payload is maybe expected. Strings are decoded by |
Osamu Nakamura |
0:a40b9a259b52 | 4609 | * interpreting each byte as a key code for entries marked to start with 0. See |
Osamu Nakamura |
0:a40b9a259b52 | 4610 | * description of encodePayloadAsBinary |
Osamu Nakamura |
0:a40b9a259b52 | 4611 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4612 | * @param {ArrayBuffer} data, callback method |
Osamu Nakamura |
0:a40b9a259b52 | 4613 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 4614 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4615 | |
Osamu Nakamura |
0:a40b9a259b52 | 4616 | exports.decodePayloadAsBinary = function (data, binaryType, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 4617 | if (typeof binaryType === 'function') { |
Osamu Nakamura |
0:a40b9a259b52 | 4618 | callback = binaryType; |
Osamu Nakamura |
0:a40b9a259b52 | 4619 | binaryType = null; |
Osamu Nakamura |
0:a40b9a259b52 | 4620 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4621 | |
Osamu Nakamura |
0:a40b9a259b52 | 4622 | var bufferTail = data; |
Osamu Nakamura |
0:a40b9a259b52 | 4623 | var buffers = []; |
Osamu Nakamura |
0:a40b9a259b52 | 4624 | |
Osamu Nakamura |
0:a40b9a259b52 | 4625 | var numberTooLong = false; |
Osamu Nakamura |
0:a40b9a259b52 | 4626 | while (bufferTail.byteLength > 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 4627 | var tailArray = new Uint8Array(bufferTail); |
Osamu Nakamura |
0:a40b9a259b52 | 4628 | var isString = tailArray[0] === 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4629 | var msgLength = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 4630 | |
Osamu Nakamura |
0:a40b9a259b52 | 4631 | for (var i = 1; ; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4632 | if (tailArray[i] == 255) break; |
Osamu Nakamura |
0:a40b9a259b52 | 4633 | |
Osamu Nakamura |
0:a40b9a259b52 | 4634 | if (msgLength.length > 310) { |
Osamu Nakamura |
0:a40b9a259b52 | 4635 | numberTooLong = true; |
Osamu Nakamura |
0:a40b9a259b52 | 4636 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 4637 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4638 | |
Osamu Nakamura |
0:a40b9a259b52 | 4639 | msgLength += tailArray[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 4640 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4641 | |
Osamu Nakamura |
0:a40b9a259b52 | 4642 | if(numberTooLong) return callback(err, 0, 1); |
Osamu Nakamura |
0:a40b9a259b52 | 4643 | |
Osamu Nakamura |
0:a40b9a259b52 | 4644 | bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); |
Osamu Nakamura |
0:a40b9a259b52 | 4645 | msgLength = parseInt(msgLength); |
Osamu Nakamura |
0:a40b9a259b52 | 4646 | |
Osamu Nakamura |
0:a40b9a259b52 | 4647 | var msg = sliceBuffer(bufferTail, 0, msgLength); |
Osamu Nakamura |
0:a40b9a259b52 | 4648 | if (isString) { |
Osamu Nakamura |
0:a40b9a259b52 | 4649 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 4650 | msg = String.fromCharCode.apply(null, new Uint8Array(msg)); |
Osamu Nakamura |
0:a40b9a259b52 | 4651 | } catch (e) { |
Osamu Nakamura |
0:a40b9a259b52 | 4652 | // iPhone Safari doesn't let you apply to typed arrays |
Osamu Nakamura |
0:a40b9a259b52 | 4653 | var typed = new Uint8Array(msg); |
Osamu Nakamura |
0:a40b9a259b52 | 4654 | msg = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 4655 | for (var i = 0; i < typed.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4656 | msg += String.fromCharCode(typed[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 4657 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4658 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4659 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4660 | |
Osamu Nakamura |
0:a40b9a259b52 | 4661 | buffers.push(msg); |
Osamu Nakamura |
0:a40b9a259b52 | 4662 | bufferTail = sliceBuffer(bufferTail, msgLength); |
Osamu Nakamura |
0:a40b9a259b52 | 4663 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4664 | |
Osamu Nakamura |
0:a40b9a259b52 | 4665 | var total = buffers.length; |
Osamu Nakamura |
0:a40b9a259b52 | 4666 | buffers.forEach(function(buffer, i) { |
Osamu Nakamura |
0:a40b9a259b52 | 4667 | callback(exports.decodePacket(buffer, binaryType, true), i, total); |
Osamu Nakamura |
0:a40b9a259b52 | 4668 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 4669 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4670 | |
Osamu Nakamura |
0:a40b9a259b52 | 4671 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 4672 | },{"./keys":26,"after":27,"arraybuffer.slice":28,"base64-arraybuffer":29,"blob":30,"has-binary":31,"utf8":33}],26:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4673 | |
Osamu Nakamura |
0:a40b9a259b52 | 4674 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4675 | * Gets the keys for an object. |
Osamu Nakamura |
0:a40b9a259b52 | 4676 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4677 | * @return {Array} keys |
Osamu Nakamura |
0:a40b9a259b52 | 4678 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 4679 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4680 | |
Osamu Nakamura |
0:a40b9a259b52 | 4681 | module.exports = Object.keys || function keys (obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 4682 | var arr = []; |
Osamu Nakamura |
0:a40b9a259b52 | 4683 | var has = Object.prototype.hasOwnProperty; |
Osamu Nakamura |
0:a40b9a259b52 | 4684 | |
Osamu Nakamura |
0:a40b9a259b52 | 4685 | for (var i in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 4686 | if (has.call(obj, i)) { |
Osamu Nakamura |
0:a40b9a259b52 | 4687 | arr.push(i); |
Osamu Nakamura |
0:a40b9a259b52 | 4688 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4689 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4690 | return arr; |
Osamu Nakamura |
0:a40b9a259b52 | 4691 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4692 | |
Osamu Nakamura |
0:a40b9a259b52 | 4693 | },{}],27:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4694 | module.exports = after |
Osamu Nakamura |
0:a40b9a259b52 | 4695 | |
Osamu Nakamura |
0:a40b9a259b52 | 4696 | function after(count, callback, err_cb) { |
Osamu Nakamura |
0:a40b9a259b52 | 4697 | var bail = false |
Osamu Nakamura |
0:a40b9a259b52 | 4698 | err_cb = err_cb || noop |
Osamu Nakamura |
0:a40b9a259b52 | 4699 | proxy.count = count |
Osamu Nakamura |
0:a40b9a259b52 | 4700 | |
Osamu Nakamura |
0:a40b9a259b52 | 4701 | return (count === 0) ? callback() : proxy |
Osamu Nakamura |
0:a40b9a259b52 | 4702 | |
Osamu Nakamura |
0:a40b9a259b52 | 4703 | function proxy(err, result) { |
Osamu Nakamura |
0:a40b9a259b52 | 4704 | if (proxy.count <= 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 4705 | throw new Error('after called too many times') |
Osamu Nakamura |
0:a40b9a259b52 | 4706 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4707 | --proxy.count |
Osamu Nakamura |
0:a40b9a259b52 | 4708 | |
Osamu Nakamura |
0:a40b9a259b52 | 4709 | // after first error, rest are passed to err_cb |
Osamu Nakamura |
0:a40b9a259b52 | 4710 | if (err) { |
Osamu Nakamura |
0:a40b9a259b52 | 4711 | bail = true |
Osamu Nakamura |
0:a40b9a259b52 | 4712 | callback(err) |
Osamu Nakamura |
0:a40b9a259b52 | 4713 | // future error callbacks will go to error handler |
Osamu Nakamura |
0:a40b9a259b52 | 4714 | callback = err_cb |
Osamu Nakamura |
0:a40b9a259b52 | 4715 | } else if (proxy.count === 0 && !bail) { |
Osamu Nakamura |
0:a40b9a259b52 | 4716 | callback(null, result) |
Osamu Nakamura |
0:a40b9a259b52 | 4717 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4718 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4719 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4720 | |
Osamu Nakamura |
0:a40b9a259b52 | 4721 | function noop() {} |
Osamu Nakamura |
0:a40b9a259b52 | 4722 | |
Osamu Nakamura |
0:a40b9a259b52 | 4723 | },{}],28:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4724 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4725 | * An abstraction for slicing an arraybuffer even when |
Osamu Nakamura |
0:a40b9a259b52 | 4726 | * ArrayBuffer.prototype.slice is not supported |
Osamu Nakamura |
0:a40b9a259b52 | 4727 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4728 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 4729 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4730 | |
Osamu Nakamura |
0:a40b9a259b52 | 4731 | module.exports = function(arraybuffer, start, end) { |
Osamu Nakamura |
0:a40b9a259b52 | 4732 | var bytes = arraybuffer.byteLength; |
Osamu Nakamura |
0:a40b9a259b52 | 4733 | start = start || 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4734 | end = end || bytes; |
Osamu Nakamura |
0:a40b9a259b52 | 4735 | |
Osamu Nakamura |
0:a40b9a259b52 | 4736 | if (arraybuffer.slice) { return arraybuffer.slice(start, end); } |
Osamu Nakamura |
0:a40b9a259b52 | 4737 | |
Osamu Nakamura |
0:a40b9a259b52 | 4738 | if (start < 0) { start += bytes; } |
Osamu Nakamura |
0:a40b9a259b52 | 4739 | if (end < 0) { end += bytes; } |
Osamu Nakamura |
0:a40b9a259b52 | 4740 | if (end > bytes) { end = bytes; } |
Osamu Nakamura |
0:a40b9a259b52 | 4741 | |
Osamu Nakamura |
0:a40b9a259b52 | 4742 | if (start >= bytes || start >= end || bytes === 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 4743 | return new ArrayBuffer(0); |
Osamu Nakamura |
0:a40b9a259b52 | 4744 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4745 | |
Osamu Nakamura |
0:a40b9a259b52 | 4746 | var abv = new Uint8Array(arraybuffer); |
Osamu Nakamura |
0:a40b9a259b52 | 4747 | var result = new Uint8Array(end - start); |
Osamu Nakamura |
0:a40b9a259b52 | 4748 | for (var i = start, ii = 0; i < end; i++, ii++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4749 | result[ii] = abv[i]; |
Osamu Nakamura |
0:a40b9a259b52 | 4750 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4751 | return result.buffer; |
Osamu Nakamura |
0:a40b9a259b52 | 4752 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4753 | |
Osamu Nakamura |
0:a40b9a259b52 | 4754 | },{}],29:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4755 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 4756 | * base64-arraybuffer |
Osamu Nakamura |
0:a40b9a259b52 | 4757 | * https://github.com/niklasvh/base64-arraybuffer |
Osamu Nakamura |
0:a40b9a259b52 | 4758 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4759 | * Copyright (c) 2012 Niklas von Hertzen |
Osamu Nakamura |
0:a40b9a259b52 | 4760 | * Licensed under the MIT license. |
Osamu Nakamura |
0:a40b9a259b52 | 4761 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4762 | (function(chars){ |
Osamu Nakamura |
0:a40b9a259b52 | 4763 | "use strict"; |
Osamu Nakamura |
0:a40b9a259b52 | 4764 | |
Osamu Nakamura |
0:a40b9a259b52 | 4765 | exports.encode = function(arraybuffer) { |
Osamu Nakamura |
0:a40b9a259b52 | 4766 | var bytes = new Uint8Array(arraybuffer), |
Osamu Nakamura |
0:a40b9a259b52 | 4767 | i, len = bytes.length, base64 = ""; |
Osamu Nakamura |
0:a40b9a259b52 | 4768 | |
Osamu Nakamura |
0:a40b9a259b52 | 4769 | for (i = 0; i < len; i+=3) { |
Osamu Nakamura |
0:a40b9a259b52 | 4770 | base64 += chars[bytes[i] >> 2]; |
Osamu Nakamura |
0:a40b9a259b52 | 4771 | base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; |
Osamu Nakamura |
0:a40b9a259b52 | 4772 | base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; |
Osamu Nakamura |
0:a40b9a259b52 | 4773 | base64 += chars[bytes[i + 2] & 63]; |
Osamu Nakamura |
0:a40b9a259b52 | 4774 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4775 | |
Osamu Nakamura |
0:a40b9a259b52 | 4776 | if ((len % 3) === 2) { |
Osamu Nakamura |
0:a40b9a259b52 | 4777 | base64 = base64.substring(0, base64.length - 1) + "="; |
Osamu Nakamura |
0:a40b9a259b52 | 4778 | } else if (len % 3 === 1) { |
Osamu Nakamura |
0:a40b9a259b52 | 4779 | base64 = base64.substring(0, base64.length - 2) + "=="; |
Osamu Nakamura |
0:a40b9a259b52 | 4780 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4781 | |
Osamu Nakamura |
0:a40b9a259b52 | 4782 | return base64; |
Osamu Nakamura |
0:a40b9a259b52 | 4783 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4784 | |
Osamu Nakamura |
0:a40b9a259b52 | 4785 | exports.decode = function(base64) { |
Osamu Nakamura |
0:a40b9a259b52 | 4786 | var bufferLength = base64.length * 0.75, |
Osamu Nakamura |
0:a40b9a259b52 | 4787 | len = base64.length, i, p = 0, |
Osamu Nakamura |
0:a40b9a259b52 | 4788 | encoded1, encoded2, encoded3, encoded4; |
Osamu Nakamura |
0:a40b9a259b52 | 4789 | |
Osamu Nakamura |
0:a40b9a259b52 | 4790 | if (base64[base64.length - 1] === "=") { |
Osamu Nakamura |
0:a40b9a259b52 | 4791 | bufferLength--; |
Osamu Nakamura |
0:a40b9a259b52 | 4792 | if (base64[base64.length - 2] === "=") { |
Osamu Nakamura |
0:a40b9a259b52 | 4793 | bufferLength--; |
Osamu Nakamura |
0:a40b9a259b52 | 4794 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4795 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4796 | |
Osamu Nakamura |
0:a40b9a259b52 | 4797 | var arraybuffer = new ArrayBuffer(bufferLength), |
Osamu Nakamura |
0:a40b9a259b52 | 4798 | bytes = new Uint8Array(arraybuffer); |
Osamu Nakamura |
0:a40b9a259b52 | 4799 | |
Osamu Nakamura |
0:a40b9a259b52 | 4800 | for (i = 0; i < len; i+=4) { |
Osamu Nakamura |
0:a40b9a259b52 | 4801 | encoded1 = chars.indexOf(base64[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 4802 | encoded2 = chars.indexOf(base64[i+1]); |
Osamu Nakamura |
0:a40b9a259b52 | 4803 | encoded3 = chars.indexOf(base64[i+2]); |
Osamu Nakamura |
0:a40b9a259b52 | 4804 | encoded4 = chars.indexOf(base64[i+3]); |
Osamu Nakamura |
0:a40b9a259b52 | 4805 | |
Osamu Nakamura |
0:a40b9a259b52 | 4806 | bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); |
Osamu Nakamura |
0:a40b9a259b52 | 4807 | bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); |
Osamu Nakamura |
0:a40b9a259b52 | 4808 | bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); |
Osamu Nakamura |
0:a40b9a259b52 | 4809 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4810 | |
Osamu Nakamura |
0:a40b9a259b52 | 4811 | return arraybuffer; |
Osamu Nakamura |
0:a40b9a259b52 | 4812 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4813 | })("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); |
Osamu Nakamura |
0:a40b9a259b52 | 4814 | |
Osamu Nakamura |
0:a40b9a259b52 | 4815 | },{}],30:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4816 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 4817 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4818 | * Create a blob builder even when vendor prefixes exist |
Osamu Nakamura |
0:a40b9a259b52 | 4819 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4820 | |
Osamu Nakamura |
0:a40b9a259b52 | 4821 | var BlobBuilder = global.BlobBuilder |
Osamu Nakamura |
0:a40b9a259b52 | 4822 | || global.WebKitBlobBuilder |
Osamu Nakamura |
0:a40b9a259b52 | 4823 | || global.MSBlobBuilder |
Osamu Nakamura |
0:a40b9a259b52 | 4824 | || global.MozBlobBuilder; |
Osamu Nakamura |
0:a40b9a259b52 | 4825 | |
Osamu Nakamura |
0:a40b9a259b52 | 4826 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4827 | * Check if Blob constructor is supported |
Osamu Nakamura |
0:a40b9a259b52 | 4828 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4829 | |
Osamu Nakamura |
0:a40b9a259b52 | 4830 | var blobSupported = (function() { |
Osamu Nakamura |
0:a40b9a259b52 | 4831 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 4832 | var b = new Blob(['hi']); |
Osamu Nakamura |
0:a40b9a259b52 | 4833 | return b.size == 2; |
Osamu Nakamura |
0:a40b9a259b52 | 4834 | } catch(e) { |
Osamu Nakamura |
0:a40b9a259b52 | 4835 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 4836 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4837 | })(); |
Osamu Nakamura |
0:a40b9a259b52 | 4838 | |
Osamu Nakamura |
0:a40b9a259b52 | 4839 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4840 | * Check if BlobBuilder is supported |
Osamu Nakamura |
0:a40b9a259b52 | 4841 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4842 | |
Osamu Nakamura |
0:a40b9a259b52 | 4843 | var blobBuilderSupported = BlobBuilder |
Osamu Nakamura |
0:a40b9a259b52 | 4844 | && BlobBuilder.prototype.append |
Osamu Nakamura |
0:a40b9a259b52 | 4845 | && BlobBuilder.prototype.getBlob; |
Osamu Nakamura |
0:a40b9a259b52 | 4846 | |
Osamu Nakamura |
0:a40b9a259b52 | 4847 | function BlobBuilderConstructor(ary, options) { |
Osamu Nakamura |
0:a40b9a259b52 | 4848 | options = options || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 4849 | |
Osamu Nakamura |
0:a40b9a259b52 | 4850 | var bb = new BlobBuilder(); |
Osamu Nakamura |
0:a40b9a259b52 | 4851 | for (var i = 0; i < ary.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4852 | bb.append(ary[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 4853 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4854 | return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); |
Osamu Nakamura |
0:a40b9a259b52 | 4855 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4856 | |
Osamu Nakamura |
0:a40b9a259b52 | 4857 | module.exports = (function() { |
Osamu Nakamura |
0:a40b9a259b52 | 4858 | if (blobSupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 4859 | return global.Blob; |
Osamu Nakamura |
0:a40b9a259b52 | 4860 | } else if (blobBuilderSupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 4861 | return BlobBuilderConstructor; |
Osamu Nakamura |
0:a40b9a259b52 | 4862 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4863 | return undefined; |
Osamu Nakamura |
0:a40b9a259b52 | 4864 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4865 | })(); |
Osamu Nakamura |
0:a40b9a259b52 | 4866 | |
Osamu Nakamura |
0:a40b9a259b52 | 4867 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 4868 | },{}],31:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4869 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 4870 | |
Osamu Nakamura |
0:a40b9a259b52 | 4871 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 4872 | * Module requirements. |
Osamu Nakamura |
0:a40b9a259b52 | 4873 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4874 | |
Osamu Nakamura |
0:a40b9a259b52 | 4875 | var isArray = _dereq_('isarray'); |
Osamu Nakamura |
0:a40b9a259b52 | 4876 | |
Osamu Nakamura |
0:a40b9a259b52 | 4877 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4878 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 4879 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4880 | |
Osamu Nakamura |
0:a40b9a259b52 | 4881 | module.exports = hasBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 4882 | |
Osamu Nakamura |
0:a40b9a259b52 | 4883 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 4884 | * Checks for binary data. |
Osamu Nakamura |
0:a40b9a259b52 | 4885 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4886 | * Right now only Buffer and ArrayBuffer are supported.. |
Osamu Nakamura |
0:a40b9a259b52 | 4887 | * |
Osamu Nakamura |
0:a40b9a259b52 | 4888 | * @param {Object} anything |
Osamu Nakamura |
0:a40b9a259b52 | 4889 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 4890 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 4891 | |
Osamu Nakamura |
0:a40b9a259b52 | 4892 | function hasBinary(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 4893 | |
Osamu Nakamura |
0:a40b9a259b52 | 4894 | function _hasBinary(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 4895 | if (!obj) return false; |
Osamu Nakamura |
0:a40b9a259b52 | 4896 | |
Osamu Nakamura |
0:a40b9a259b52 | 4897 | if ( (global.Buffer && global.Buffer.isBuffer(obj)) || |
Osamu Nakamura |
0:a40b9a259b52 | 4898 | (global.ArrayBuffer && obj instanceof ArrayBuffer) || |
Osamu Nakamura |
0:a40b9a259b52 | 4899 | (global.Blob && obj instanceof Blob) || |
Osamu Nakamura |
0:a40b9a259b52 | 4900 | (global.File && obj instanceof File) |
Osamu Nakamura |
0:a40b9a259b52 | 4901 | ) { |
Osamu Nakamura |
0:a40b9a259b52 | 4902 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 4903 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4904 | |
Osamu Nakamura |
0:a40b9a259b52 | 4905 | if (isArray(obj)) { |
Osamu Nakamura |
0:a40b9a259b52 | 4906 | for (var i = 0; i < obj.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 4907 | if (_hasBinary(obj[i])) { |
Osamu Nakamura |
0:a40b9a259b52 | 4908 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 4909 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4910 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4911 | } else if (obj && 'object' == typeof obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 4912 | if (obj.toJSON) { |
Osamu Nakamura |
0:a40b9a259b52 | 4913 | obj = obj.toJSON(); |
Osamu Nakamura |
0:a40b9a259b52 | 4914 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4915 | |
Osamu Nakamura |
0:a40b9a259b52 | 4916 | for (var key in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 4917 | if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) { |
Osamu Nakamura |
0:a40b9a259b52 | 4918 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 4919 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4920 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4921 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4922 | |
Osamu Nakamura |
0:a40b9a259b52 | 4923 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 4924 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4925 | |
Osamu Nakamura |
0:a40b9a259b52 | 4926 | return _hasBinary(data); |
Osamu Nakamura |
0:a40b9a259b52 | 4927 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4928 | |
Osamu Nakamura |
0:a40b9a259b52 | 4929 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 4930 | },{"isarray":32}],32:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4931 | module.exports = Array.isArray || function (arr) { |
Osamu Nakamura |
0:a40b9a259b52 | 4932 | return Object.prototype.toString.call(arr) == '[object Array]'; |
Osamu Nakamura |
0:a40b9a259b52 | 4933 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 4934 | |
Osamu Nakamura |
0:a40b9a259b52 | 4935 | },{}],33:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 4936 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 4937 | /*! http://mths.be/utf8js v2.0.0 by @mathias */ |
Osamu Nakamura |
0:a40b9a259b52 | 4938 | ;(function(root) { |
Osamu Nakamura |
0:a40b9a259b52 | 4939 | |
Osamu Nakamura |
0:a40b9a259b52 | 4940 | // Detect free variables `exports` |
Osamu Nakamura |
0:a40b9a259b52 | 4941 | var freeExports = typeof exports == 'object' && exports; |
Osamu Nakamura |
0:a40b9a259b52 | 4942 | |
Osamu Nakamura |
0:a40b9a259b52 | 4943 | // Detect free variable `module` |
Osamu Nakamura |
0:a40b9a259b52 | 4944 | var freeModule = typeof module == 'object' && module && |
Osamu Nakamura |
0:a40b9a259b52 | 4945 | module.exports == freeExports && module; |
Osamu Nakamura |
0:a40b9a259b52 | 4946 | |
Osamu Nakamura |
0:a40b9a259b52 | 4947 | // Detect free variable `global`, from Node.js or Browserified code, |
Osamu Nakamura |
0:a40b9a259b52 | 4948 | // and use it as `root` |
Osamu Nakamura |
0:a40b9a259b52 | 4949 | var freeGlobal = typeof global == 'object' && global; |
Osamu Nakamura |
0:a40b9a259b52 | 4950 | if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { |
Osamu Nakamura |
0:a40b9a259b52 | 4951 | root = freeGlobal; |
Osamu Nakamura |
0:a40b9a259b52 | 4952 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4953 | |
Osamu Nakamura |
0:a40b9a259b52 | 4954 | /*--------------------------------------------------------------------------*/ |
Osamu Nakamura |
0:a40b9a259b52 | 4955 | |
Osamu Nakamura |
0:a40b9a259b52 | 4956 | var stringFromCharCode = String.fromCharCode; |
Osamu Nakamura |
0:a40b9a259b52 | 4957 | |
Osamu Nakamura |
0:a40b9a259b52 | 4958 | // Taken from http://mths.be/punycode |
Osamu Nakamura |
0:a40b9a259b52 | 4959 | function ucs2decode(string) { |
Osamu Nakamura |
0:a40b9a259b52 | 4960 | var output = []; |
Osamu Nakamura |
0:a40b9a259b52 | 4961 | var counter = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 4962 | var length = string.length; |
Osamu Nakamura |
0:a40b9a259b52 | 4963 | var value; |
Osamu Nakamura |
0:a40b9a259b52 | 4964 | var extra; |
Osamu Nakamura |
0:a40b9a259b52 | 4965 | while (counter < length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4966 | value = string.charCodeAt(counter++); |
Osamu Nakamura |
0:a40b9a259b52 | 4967 | if (value >= 0xD800 && value <= 0xDBFF && counter < length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4968 | // high surrogate, and there is a next character |
Osamu Nakamura |
0:a40b9a259b52 | 4969 | extra = string.charCodeAt(counter++); |
Osamu Nakamura |
0:a40b9a259b52 | 4970 | if ((extra & 0xFC00) == 0xDC00) { // low surrogate |
Osamu Nakamura |
0:a40b9a259b52 | 4971 | output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); |
Osamu Nakamura |
0:a40b9a259b52 | 4972 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4973 | // unmatched surrogate; only append this code unit, in case the next |
Osamu Nakamura |
0:a40b9a259b52 | 4974 | // code unit is the high surrogate of a surrogate pair |
Osamu Nakamura |
0:a40b9a259b52 | 4975 | output.push(value); |
Osamu Nakamura |
0:a40b9a259b52 | 4976 | counter--; |
Osamu Nakamura |
0:a40b9a259b52 | 4977 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4978 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 4979 | output.push(value); |
Osamu Nakamura |
0:a40b9a259b52 | 4980 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4981 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4982 | return output; |
Osamu Nakamura |
0:a40b9a259b52 | 4983 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4984 | |
Osamu Nakamura |
0:a40b9a259b52 | 4985 | // Taken from http://mths.be/punycode |
Osamu Nakamura |
0:a40b9a259b52 | 4986 | function ucs2encode(array) { |
Osamu Nakamura |
0:a40b9a259b52 | 4987 | var length = array.length; |
Osamu Nakamura |
0:a40b9a259b52 | 4988 | var index = -1; |
Osamu Nakamura |
0:a40b9a259b52 | 4989 | var value; |
Osamu Nakamura |
0:a40b9a259b52 | 4990 | var output = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 4991 | while (++index < length) { |
Osamu Nakamura |
0:a40b9a259b52 | 4992 | value = array[index]; |
Osamu Nakamura |
0:a40b9a259b52 | 4993 | if (value > 0xFFFF) { |
Osamu Nakamura |
0:a40b9a259b52 | 4994 | value -= 0x10000; |
Osamu Nakamura |
0:a40b9a259b52 | 4995 | output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); |
Osamu Nakamura |
0:a40b9a259b52 | 4996 | value = 0xDC00 | value & 0x3FF; |
Osamu Nakamura |
0:a40b9a259b52 | 4997 | } |
Osamu Nakamura |
0:a40b9a259b52 | 4998 | output += stringFromCharCode(value); |
Osamu Nakamura |
0:a40b9a259b52 | 4999 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5000 | return output; |
Osamu Nakamura |
0:a40b9a259b52 | 5001 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5002 | |
Osamu Nakamura |
0:a40b9a259b52 | 5003 | /*--------------------------------------------------------------------------*/ |
Osamu Nakamura |
0:a40b9a259b52 | 5004 | |
Osamu Nakamura |
0:a40b9a259b52 | 5005 | function createByte(codePoint, shift) { |
Osamu Nakamura |
0:a40b9a259b52 | 5006 | return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); |
Osamu Nakamura |
0:a40b9a259b52 | 5007 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5008 | |
Osamu Nakamura |
0:a40b9a259b52 | 5009 | function encodeCodePoint(codePoint) { |
Osamu Nakamura |
0:a40b9a259b52 | 5010 | if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5011 | return stringFromCharCode(codePoint); |
Osamu Nakamura |
0:a40b9a259b52 | 5012 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5013 | var symbol = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5014 | if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5015 | symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); |
Osamu Nakamura |
0:a40b9a259b52 | 5016 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5017 | else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5018 | symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); |
Osamu Nakamura |
0:a40b9a259b52 | 5019 | symbol += createByte(codePoint, 6); |
Osamu Nakamura |
0:a40b9a259b52 | 5020 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5021 | else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5022 | symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); |
Osamu Nakamura |
0:a40b9a259b52 | 5023 | symbol += createByte(codePoint, 12); |
Osamu Nakamura |
0:a40b9a259b52 | 5024 | symbol += createByte(codePoint, 6); |
Osamu Nakamura |
0:a40b9a259b52 | 5025 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5026 | symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); |
Osamu Nakamura |
0:a40b9a259b52 | 5027 | return symbol; |
Osamu Nakamura |
0:a40b9a259b52 | 5028 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5029 | |
Osamu Nakamura |
0:a40b9a259b52 | 5030 | function utf8encode(string) { |
Osamu Nakamura |
0:a40b9a259b52 | 5031 | var codePoints = ucs2decode(string); |
Osamu Nakamura |
0:a40b9a259b52 | 5032 | |
Osamu Nakamura |
0:a40b9a259b52 | 5033 | // console.log(JSON.stringify(codePoints.map(function(x) { |
Osamu Nakamura |
0:a40b9a259b52 | 5034 | // return 'U+' + x.toString(16).toUpperCase(); |
Osamu Nakamura |
0:a40b9a259b52 | 5035 | // }))); |
Osamu Nakamura |
0:a40b9a259b52 | 5036 | |
Osamu Nakamura |
0:a40b9a259b52 | 5037 | var length = codePoints.length; |
Osamu Nakamura |
0:a40b9a259b52 | 5038 | var index = -1; |
Osamu Nakamura |
0:a40b9a259b52 | 5039 | var codePoint; |
Osamu Nakamura |
0:a40b9a259b52 | 5040 | var byteString = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5041 | while (++index < length) { |
Osamu Nakamura |
0:a40b9a259b52 | 5042 | codePoint = codePoints[index]; |
Osamu Nakamura |
0:a40b9a259b52 | 5043 | byteString += encodeCodePoint(codePoint); |
Osamu Nakamura |
0:a40b9a259b52 | 5044 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5045 | return byteString; |
Osamu Nakamura |
0:a40b9a259b52 | 5046 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5047 | |
Osamu Nakamura |
0:a40b9a259b52 | 5048 | /*--------------------------------------------------------------------------*/ |
Osamu Nakamura |
0:a40b9a259b52 | 5049 | |
Osamu Nakamura |
0:a40b9a259b52 | 5050 | function readContinuationByte() { |
Osamu Nakamura |
0:a40b9a259b52 | 5051 | if (byteIndex >= byteCount) { |
Osamu Nakamura |
0:a40b9a259b52 | 5052 | throw Error('Invalid byte index'); |
Osamu Nakamura |
0:a40b9a259b52 | 5053 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5054 | |
Osamu Nakamura |
0:a40b9a259b52 | 5055 | var continuationByte = byteArray[byteIndex] & 0xFF; |
Osamu Nakamura |
0:a40b9a259b52 | 5056 | byteIndex++; |
Osamu Nakamura |
0:a40b9a259b52 | 5057 | |
Osamu Nakamura |
0:a40b9a259b52 | 5058 | if ((continuationByte & 0xC0) == 0x80) { |
Osamu Nakamura |
0:a40b9a259b52 | 5059 | return continuationByte & 0x3F; |
Osamu Nakamura |
0:a40b9a259b52 | 5060 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5061 | |
Osamu Nakamura |
0:a40b9a259b52 | 5062 | // If we end up here, it’s not a continuation byte |
Osamu Nakamura |
0:a40b9a259b52 | 5063 | throw Error('Invalid continuation byte'); |
Osamu Nakamura |
0:a40b9a259b52 | 5064 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5065 | |
Osamu Nakamura |
0:a40b9a259b52 | 5066 | function decodeSymbol() { |
Osamu Nakamura |
0:a40b9a259b52 | 5067 | var byte1; |
Osamu Nakamura |
0:a40b9a259b52 | 5068 | var byte2; |
Osamu Nakamura |
0:a40b9a259b52 | 5069 | var byte3; |
Osamu Nakamura |
0:a40b9a259b52 | 5070 | var byte4; |
Osamu Nakamura |
0:a40b9a259b52 | 5071 | var codePoint; |
Osamu Nakamura |
0:a40b9a259b52 | 5072 | |
Osamu Nakamura |
0:a40b9a259b52 | 5073 | if (byteIndex > byteCount) { |
Osamu Nakamura |
0:a40b9a259b52 | 5074 | throw Error('Invalid byte index'); |
Osamu Nakamura |
0:a40b9a259b52 | 5075 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5076 | |
Osamu Nakamura |
0:a40b9a259b52 | 5077 | if (byteIndex == byteCount) { |
Osamu Nakamura |
0:a40b9a259b52 | 5078 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 5079 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5080 | |
Osamu Nakamura |
0:a40b9a259b52 | 5081 | // Read first byte |
Osamu Nakamura |
0:a40b9a259b52 | 5082 | byte1 = byteArray[byteIndex] & 0xFF; |
Osamu Nakamura |
0:a40b9a259b52 | 5083 | byteIndex++; |
Osamu Nakamura |
0:a40b9a259b52 | 5084 | |
Osamu Nakamura |
0:a40b9a259b52 | 5085 | // 1-byte sequence (no continuation bytes) |
Osamu Nakamura |
0:a40b9a259b52 | 5086 | if ((byte1 & 0x80) == 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 5087 | return byte1; |
Osamu Nakamura |
0:a40b9a259b52 | 5088 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5089 | |
Osamu Nakamura |
0:a40b9a259b52 | 5090 | // 2-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5091 | if ((byte1 & 0xE0) == 0xC0) { |
Osamu Nakamura |
0:a40b9a259b52 | 5092 | var byte2 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5093 | codePoint = ((byte1 & 0x1F) << 6) | byte2; |
Osamu Nakamura |
0:a40b9a259b52 | 5094 | if (codePoint >= 0x80) { |
Osamu Nakamura |
0:a40b9a259b52 | 5095 | return codePoint; |
Osamu Nakamura |
0:a40b9a259b52 | 5096 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 5097 | throw Error('Invalid continuation byte'); |
Osamu Nakamura |
0:a40b9a259b52 | 5098 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5099 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5100 | |
Osamu Nakamura |
0:a40b9a259b52 | 5101 | // 3-byte sequence (may include unpaired surrogates) |
Osamu Nakamura |
0:a40b9a259b52 | 5102 | if ((byte1 & 0xF0) == 0xE0) { |
Osamu Nakamura |
0:a40b9a259b52 | 5103 | byte2 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5104 | byte3 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5105 | codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; |
Osamu Nakamura |
0:a40b9a259b52 | 5106 | if (codePoint >= 0x0800) { |
Osamu Nakamura |
0:a40b9a259b52 | 5107 | return codePoint; |
Osamu Nakamura |
0:a40b9a259b52 | 5108 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 5109 | throw Error('Invalid continuation byte'); |
Osamu Nakamura |
0:a40b9a259b52 | 5110 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5111 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5112 | |
Osamu Nakamura |
0:a40b9a259b52 | 5113 | // 4-byte sequence |
Osamu Nakamura |
0:a40b9a259b52 | 5114 | if ((byte1 & 0xF8) == 0xF0) { |
Osamu Nakamura |
0:a40b9a259b52 | 5115 | byte2 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5116 | byte3 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5117 | byte4 = readContinuationByte(); |
Osamu Nakamura |
0:a40b9a259b52 | 5118 | codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | |
Osamu Nakamura |
0:a40b9a259b52 | 5119 | (byte3 << 0x06) | byte4; |
Osamu Nakamura |
0:a40b9a259b52 | 5120 | if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { |
Osamu Nakamura |
0:a40b9a259b52 | 5121 | return codePoint; |
Osamu Nakamura |
0:a40b9a259b52 | 5122 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5123 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5124 | |
Osamu Nakamura |
0:a40b9a259b52 | 5125 | throw Error('Invalid UTF-8 detected'); |
Osamu Nakamura |
0:a40b9a259b52 | 5126 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5127 | |
Osamu Nakamura |
0:a40b9a259b52 | 5128 | var byteArray; |
Osamu Nakamura |
0:a40b9a259b52 | 5129 | var byteCount; |
Osamu Nakamura |
0:a40b9a259b52 | 5130 | var byteIndex; |
Osamu Nakamura |
0:a40b9a259b52 | 5131 | function utf8decode(byteString) { |
Osamu Nakamura |
0:a40b9a259b52 | 5132 | byteArray = ucs2decode(byteString); |
Osamu Nakamura |
0:a40b9a259b52 | 5133 | byteCount = byteArray.length; |
Osamu Nakamura |
0:a40b9a259b52 | 5134 | byteIndex = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 5135 | var codePoints = []; |
Osamu Nakamura |
0:a40b9a259b52 | 5136 | var tmp; |
Osamu Nakamura |
0:a40b9a259b52 | 5137 | while ((tmp = decodeSymbol()) !== false) { |
Osamu Nakamura |
0:a40b9a259b52 | 5138 | codePoints.push(tmp); |
Osamu Nakamura |
0:a40b9a259b52 | 5139 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5140 | return ucs2encode(codePoints); |
Osamu Nakamura |
0:a40b9a259b52 | 5141 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5142 | |
Osamu Nakamura |
0:a40b9a259b52 | 5143 | /*--------------------------------------------------------------------------*/ |
Osamu Nakamura |
0:a40b9a259b52 | 5144 | |
Osamu Nakamura |
0:a40b9a259b52 | 5145 | var utf8 = { |
Osamu Nakamura |
0:a40b9a259b52 | 5146 | 'version': '2.0.0', |
Osamu Nakamura |
0:a40b9a259b52 | 5147 | 'encode': utf8encode, |
Osamu Nakamura |
0:a40b9a259b52 | 5148 | 'decode': utf8decode |
Osamu Nakamura |
0:a40b9a259b52 | 5149 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5150 | |
Osamu Nakamura |
0:a40b9a259b52 | 5151 | // Some AMD build optimizers, like r.js, check for specific condition patterns |
Osamu Nakamura |
0:a40b9a259b52 | 5152 | // like the following: |
Osamu Nakamura |
0:a40b9a259b52 | 5153 | if ( |
Osamu Nakamura |
0:a40b9a259b52 | 5154 | typeof define == 'function' && |
Osamu Nakamura |
0:a40b9a259b52 | 5155 | typeof define.amd == 'object' && |
Osamu Nakamura |
0:a40b9a259b52 | 5156 | define.amd |
Osamu Nakamura |
0:a40b9a259b52 | 5157 | ) { |
Osamu Nakamura |
0:a40b9a259b52 | 5158 | define(function() { |
Osamu Nakamura |
0:a40b9a259b52 | 5159 | return utf8; |
Osamu Nakamura |
0:a40b9a259b52 | 5160 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 5161 | } else if (freeExports && !freeExports.nodeType) { |
Osamu Nakamura |
0:a40b9a259b52 | 5162 | if (freeModule) { // in Node.js or RingoJS v0.8.0+ |
Osamu Nakamura |
0:a40b9a259b52 | 5163 | freeModule.exports = utf8; |
Osamu Nakamura |
0:a40b9a259b52 | 5164 | } else { // in Narwhal or RingoJS v0.7.0- |
Osamu Nakamura |
0:a40b9a259b52 | 5165 | var object = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 5166 | var hasOwnProperty = object.hasOwnProperty; |
Osamu Nakamura |
0:a40b9a259b52 | 5167 | for (var key in utf8) { |
Osamu Nakamura |
0:a40b9a259b52 | 5168 | hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); |
Osamu Nakamura |
0:a40b9a259b52 | 5169 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5170 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5171 | } else { // in Rhino or a web browser |
Osamu Nakamura |
0:a40b9a259b52 | 5172 | root.utf8 = utf8; |
Osamu Nakamura |
0:a40b9a259b52 | 5173 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5174 | |
Osamu Nakamura |
0:a40b9a259b52 | 5175 | }(this)); |
Osamu Nakamura |
0:a40b9a259b52 | 5176 | |
Osamu Nakamura |
0:a40b9a259b52 | 5177 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 5178 | },{}],34:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5179 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 5180 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5181 | * JSON parse. |
Osamu Nakamura |
0:a40b9a259b52 | 5182 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5183 | * @see Based on jQuery#parseJSON (MIT) and JSON2 |
Osamu Nakamura |
0:a40b9a259b52 | 5184 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5185 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5186 | |
Osamu Nakamura |
0:a40b9a259b52 | 5187 | var rvalidchars = /^[\],:{}\s]*$/; |
Osamu Nakamura |
0:a40b9a259b52 | 5188 | var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; |
Osamu Nakamura |
0:a40b9a259b52 | 5189 | var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; |
Osamu Nakamura |
0:a40b9a259b52 | 5190 | var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; |
Osamu Nakamura |
0:a40b9a259b52 | 5191 | var rtrimLeft = /^\s+/; |
Osamu Nakamura |
0:a40b9a259b52 | 5192 | var rtrimRight = /\s+$/; |
Osamu Nakamura |
0:a40b9a259b52 | 5193 | |
Osamu Nakamura |
0:a40b9a259b52 | 5194 | module.exports = function parsejson(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5195 | if ('string' != typeof data || !data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5196 | return null; |
Osamu Nakamura |
0:a40b9a259b52 | 5197 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5198 | |
Osamu Nakamura |
0:a40b9a259b52 | 5199 | data = data.replace(rtrimLeft, '').replace(rtrimRight, ''); |
Osamu Nakamura |
0:a40b9a259b52 | 5200 | |
Osamu Nakamura |
0:a40b9a259b52 | 5201 | // Attempt to parse using the native JSON parser first |
Osamu Nakamura |
0:a40b9a259b52 | 5202 | if (global.JSON && JSON.parse) { |
Osamu Nakamura |
0:a40b9a259b52 | 5203 | return JSON.parse(data); |
Osamu Nakamura |
0:a40b9a259b52 | 5204 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5205 | |
Osamu Nakamura |
0:a40b9a259b52 | 5206 | if (rvalidchars.test(data.replace(rvalidescape, '@') |
Osamu Nakamura |
0:a40b9a259b52 | 5207 | .replace(rvalidtokens, ']') |
Osamu Nakamura |
0:a40b9a259b52 | 5208 | .replace(rvalidbraces, ''))) { |
Osamu Nakamura |
0:a40b9a259b52 | 5209 | return (new Function('return ' + data))(); |
Osamu Nakamura |
0:a40b9a259b52 | 5210 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5211 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5212 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 5213 | },{}],35:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5214 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5215 | * Compiles a querystring |
Osamu Nakamura |
0:a40b9a259b52 | 5216 | * Returns string representation of the object |
Osamu Nakamura |
0:a40b9a259b52 | 5217 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5218 | * @param {Object} |
Osamu Nakamura |
0:a40b9a259b52 | 5219 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5220 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5221 | |
Osamu Nakamura |
0:a40b9a259b52 | 5222 | exports.encode = function (obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5223 | var str = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5224 | |
Osamu Nakamura |
0:a40b9a259b52 | 5225 | for (var i in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5226 | if (obj.hasOwnProperty(i)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5227 | if (str.length) str += '&'; |
Osamu Nakamura |
0:a40b9a259b52 | 5228 | str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 5229 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5230 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5231 | |
Osamu Nakamura |
0:a40b9a259b52 | 5232 | return str; |
Osamu Nakamura |
0:a40b9a259b52 | 5233 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5234 | |
Osamu Nakamura |
0:a40b9a259b52 | 5235 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5236 | * Parses a simple querystring into an object |
Osamu Nakamura |
0:a40b9a259b52 | 5237 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5238 | * @param {String} qs |
Osamu Nakamura |
0:a40b9a259b52 | 5239 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5240 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5241 | |
Osamu Nakamura |
0:a40b9a259b52 | 5242 | exports.decode = function(qs){ |
Osamu Nakamura |
0:a40b9a259b52 | 5243 | var qry = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 5244 | var pairs = qs.split('&'); |
Osamu Nakamura |
0:a40b9a259b52 | 5245 | for (var i = 0, l = pairs.length; i < l; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 5246 | var pair = pairs[i].split('='); |
Osamu Nakamura |
0:a40b9a259b52 | 5247 | qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); |
Osamu Nakamura |
0:a40b9a259b52 | 5248 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5249 | return qry; |
Osamu Nakamura |
0:a40b9a259b52 | 5250 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5251 | |
Osamu Nakamura |
0:a40b9a259b52 | 5252 | },{}],36:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5253 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5254 | * Parses an URI |
Osamu Nakamura |
0:a40b9a259b52 | 5255 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5256 | * @author Steven Levithan <stevenlevithan.com> (MIT license) |
Osamu Nakamura |
0:a40b9a259b52 | 5257 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5258 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5259 | |
Osamu Nakamura |
0:a40b9a259b52 | 5260 | var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; |
Osamu Nakamura |
0:a40b9a259b52 | 5261 | |
Osamu Nakamura |
0:a40b9a259b52 | 5262 | var parts = [ |
Osamu Nakamura |
0:a40b9a259b52 | 5263 | 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor' |
Osamu Nakamura |
0:a40b9a259b52 | 5264 | ]; |
Osamu Nakamura |
0:a40b9a259b52 | 5265 | |
Osamu Nakamura |
0:a40b9a259b52 | 5266 | module.exports = function parseuri(str) { |
Osamu Nakamura |
0:a40b9a259b52 | 5267 | var src = str, |
Osamu Nakamura |
0:a40b9a259b52 | 5268 | b = str.indexOf('['), |
Osamu Nakamura |
0:a40b9a259b52 | 5269 | e = str.indexOf(']'); |
Osamu Nakamura |
0:a40b9a259b52 | 5270 | |
Osamu Nakamura |
0:a40b9a259b52 | 5271 | if (b != -1 && e != -1) { |
Osamu Nakamura |
0:a40b9a259b52 | 5272 | str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); |
Osamu Nakamura |
0:a40b9a259b52 | 5273 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5274 | |
Osamu Nakamura |
0:a40b9a259b52 | 5275 | var m = re.exec(str || ''), |
Osamu Nakamura |
0:a40b9a259b52 | 5276 | uri = {}, |
Osamu Nakamura |
0:a40b9a259b52 | 5277 | i = 14; |
Osamu Nakamura |
0:a40b9a259b52 | 5278 | |
Osamu Nakamura |
0:a40b9a259b52 | 5279 | while (i--) { |
Osamu Nakamura |
0:a40b9a259b52 | 5280 | uri[parts[i]] = m[i] || ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5281 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5282 | |
Osamu Nakamura |
0:a40b9a259b52 | 5283 | if (b != -1 && e != -1) { |
Osamu Nakamura |
0:a40b9a259b52 | 5284 | uri.source = src; |
Osamu Nakamura |
0:a40b9a259b52 | 5285 | uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); |
Osamu Nakamura |
0:a40b9a259b52 | 5286 | uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); |
Osamu Nakamura |
0:a40b9a259b52 | 5287 | uri.ipv6uri = true; |
Osamu Nakamura |
0:a40b9a259b52 | 5288 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5289 | |
Osamu Nakamura |
0:a40b9a259b52 | 5290 | return uri; |
Osamu Nakamura |
0:a40b9a259b52 | 5291 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5292 | |
Osamu Nakamura |
0:a40b9a259b52 | 5293 | },{}],37:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5294 | |
Osamu Nakamura |
0:a40b9a259b52 | 5295 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5296 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 5297 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5298 | |
Osamu Nakamura |
0:a40b9a259b52 | 5299 | var global = (function() { return this; })(); |
Osamu Nakamura |
0:a40b9a259b52 | 5300 | |
Osamu Nakamura |
0:a40b9a259b52 | 5301 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5302 | * WebSocket constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 5303 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5304 | |
Osamu Nakamura |
0:a40b9a259b52 | 5305 | var WebSocket = global.WebSocket || global.MozWebSocket; |
Osamu Nakamura |
0:a40b9a259b52 | 5306 | |
Osamu Nakamura |
0:a40b9a259b52 | 5307 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5308 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 5309 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5310 | |
Osamu Nakamura |
0:a40b9a259b52 | 5311 | module.exports = WebSocket ? ws : null; |
Osamu Nakamura |
0:a40b9a259b52 | 5312 | |
Osamu Nakamura |
0:a40b9a259b52 | 5313 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5314 | * WebSocket constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 5315 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5316 | * The third `opts` options object gets ignored in web browsers, since it's |
Osamu Nakamura |
0:a40b9a259b52 | 5317 | * non-standard, and throws a TypeError if passed to the constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 5318 | * See: https://github.com/einaros/ws/issues/227 |
Osamu Nakamura |
0:a40b9a259b52 | 5319 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5320 | * @param {String} uri |
Osamu Nakamura |
0:a40b9a259b52 | 5321 | * @param {Array} protocols (optional) |
Osamu Nakamura |
0:a40b9a259b52 | 5322 | * @param {Object) opts (optional) |
Osamu Nakamura |
0:a40b9a259b52 | 5323 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5324 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5325 | |
Osamu Nakamura |
0:a40b9a259b52 | 5326 | function ws(uri, protocols, opts) { |
Osamu Nakamura |
0:a40b9a259b52 | 5327 | var instance; |
Osamu Nakamura |
0:a40b9a259b52 | 5328 | if (protocols) { |
Osamu Nakamura |
0:a40b9a259b52 | 5329 | instance = new WebSocket(uri, protocols); |
Osamu Nakamura |
0:a40b9a259b52 | 5330 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 5331 | instance = new WebSocket(uri); |
Osamu Nakamura |
0:a40b9a259b52 | 5332 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5333 | return instance; |
Osamu Nakamura |
0:a40b9a259b52 | 5334 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5335 | |
Osamu Nakamura |
0:a40b9a259b52 | 5336 | if (WebSocket) ws.prototype = WebSocket.prototype; |
Osamu Nakamura |
0:a40b9a259b52 | 5337 | |
Osamu Nakamura |
0:a40b9a259b52 | 5338 | },{}],38:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5339 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 5340 | |
Osamu Nakamura |
0:a40b9a259b52 | 5341 | /* |
Osamu Nakamura |
0:a40b9a259b52 | 5342 | * Module requirements. |
Osamu Nakamura |
0:a40b9a259b52 | 5343 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5344 | |
Osamu Nakamura |
0:a40b9a259b52 | 5345 | var isArray = _dereq_('isarray'); |
Osamu Nakamura |
0:a40b9a259b52 | 5346 | |
Osamu Nakamura |
0:a40b9a259b52 | 5347 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5348 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 5349 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5350 | |
Osamu Nakamura |
0:a40b9a259b52 | 5351 | module.exports = hasBinary; |
Osamu Nakamura |
0:a40b9a259b52 | 5352 | |
Osamu Nakamura |
0:a40b9a259b52 | 5353 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5354 | * Checks for binary data. |
Osamu Nakamura |
0:a40b9a259b52 | 5355 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5356 | * Right now only Buffer and ArrayBuffer are supported.. |
Osamu Nakamura |
0:a40b9a259b52 | 5357 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5358 | * @param {Object} anything |
Osamu Nakamura |
0:a40b9a259b52 | 5359 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5360 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5361 | |
Osamu Nakamura |
0:a40b9a259b52 | 5362 | function hasBinary(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5363 | |
Osamu Nakamura |
0:a40b9a259b52 | 5364 | function _hasBinary(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5365 | if (!obj) return false; |
Osamu Nakamura |
0:a40b9a259b52 | 5366 | |
Osamu Nakamura |
0:a40b9a259b52 | 5367 | if ( (global.Buffer && global.Buffer.isBuffer(obj)) || |
Osamu Nakamura |
0:a40b9a259b52 | 5368 | (global.ArrayBuffer && obj instanceof ArrayBuffer) || |
Osamu Nakamura |
0:a40b9a259b52 | 5369 | (global.Blob && obj instanceof Blob) || |
Osamu Nakamura |
0:a40b9a259b52 | 5370 | (global.File && obj instanceof File) |
Osamu Nakamura |
0:a40b9a259b52 | 5371 | ) { |
Osamu Nakamura |
0:a40b9a259b52 | 5372 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 5373 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5374 | |
Osamu Nakamura |
0:a40b9a259b52 | 5375 | if (isArray(obj)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5376 | for (var i = 0; i < obj.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 5377 | if (_hasBinary(obj[i])) { |
Osamu Nakamura |
0:a40b9a259b52 | 5378 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 5379 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5380 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5381 | } else if (obj && 'object' == typeof obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5382 | if (obj.toJSON) { |
Osamu Nakamura |
0:a40b9a259b52 | 5383 | obj = obj.toJSON(); |
Osamu Nakamura |
0:a40b9a259b52 | 5384 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5385 | |
Osamu Nakamura |
0:a40b9a259b52 | 5386 | for (var key in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5387 | if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) { |
Osamu Nakamura |
0:a40b9a259b52 | 5388 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 5389 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5390 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5391 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5392 | |
Osamu Nakamura |
0:a40b9a259b52 | 5393 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 5394 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5395 | |
Osamu Nakamura |
0:a40b9a259b52 | 5396 | return _hasBinary(data); |
Osamu Nakamura |
0:a40b9a259b52 | 5397 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5398 | |
Osamu Nakamura |
0:a40b9a259b52 | 5399 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 5400 | },{"isarray":39}],39:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5401 | module.exports=_dereq_(32) |
Osamu Nakamura |
0:a40b9a259b52 | 5402 | },{}],40:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5403 | |
Osamu Nakamura |
0:a40b9a259b52 | 5404 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5405 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 5406 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5407 | |
Osamu Nakamura |
0:a40b9a259b52 | 5408 | var global = _dereq_('global'); |
Osamu Nakamura |
0:a40b9a259b52 | 5409 | |
Osamu Nakamura |
0:a40b9a259b52 | 5410 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5411 | * Module exports. |
Osamu Nakamura |
0:a40b9a259b52 | 5412 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5413 | * Logic borrowed from Modernizr: |
Osamu Nakamura |
0:a40b9a259b52 | 5414 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5415 | * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js |
Osamu Nakamura |
0:a40b9a259b52 | 5416 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5417 | |
Osamu Nakamura |
0:a40b9a259b52 | 5418 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 5419 | module.exports = 'XMLHttpRequest' in global && |
Osamu Nakamura |
0:a40b9a259b52 | 5420 | 'withCredentials' in new global.XMLHttpRequest(); |
Osamu Nakamura |
0:a40b9a259b52 | 5421 | } catch (err) { |
Osamu Nakamura |
0:a40b9a259b52 | 5422 | // if XMLHttp support is disabled in IE then it will throw |
Osamu Nakamura |
0:a40b9a259b52 | 5423 | // when trying to create |
Osamu Nakamura |
0:a40b9a259b52 | 5424 | module.exports = false; |
Osamu Nakamura |
0:a40b9a259b52 | 5425 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5426 | |
Osamu Nakamura |
0:a40b9a259b52 | 5427 | },{"global":41}],41:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5428 | |
Osamu Nakamura |
0:a40b9a259b52 | 5429 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5430 | * Returns `this`. Execute this without a "context" (i.e. without it being |
Osamu Nakamura |
0:a40b9a259b52 | 5431 | * attached to an object of the left-hand side), and `this` points to the |
Osamu Nakamura |
0:a40b9a259b52 | 5432 | * "global" scope of the current JS execution. |
Osamu Nakamura |
0:a40b9a259b52 | 5433 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5434 | |
Osamu Nakamura |
0:a40b9a259b52 | 5435 | module.exports = (function () { return this; })(); |
Osamu Nakamura |
0:a40b9a259b52 | 5436 | |
Osamu Nakamura |
0:a40b9a259b52 | 5437 | },{}],42:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5438 | |
Osamu Nakamura |
0:a40b9a259b52 | 5439 | var indexOf = [].indexOf; |
Osamu Nakamura |
0:a40b9a259b52 | 5440 | |
Osamu Nakamura |
0:a40b9a259b52 | 5441 | module.exports = function(arr, obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 5442 | if (indexOf) return arr.indexOf(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5443 | for (var i = 0; i < arr.length; ++i) { |
Osamu Nakamura |
0:a40b9a259b52 | 5444 | if (arr[i] === obj) return i; |
Osamu Nakamura |
0:a40b9a259b52 | 5445 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5446 | return -1; |
Osamu Nakamura |
0:a40b9a259b52 | 5447 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5448 | },{}],43:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5449 | |
Osamu Nakamura |
0:a40b9a259b52 | 5450 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5451 | * HOP ref. |
Osamu Nakamura |
0:a40b9a259b52 | 5452 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5453 | |
Osamu Nakamura |
0:a40b9a259b52 | 5454 | var has = Object.prototype.hasOwnProperty; |
Osamu Nakamura |
0:a40b9a259b52 | 5455 | |
Osamu Nakamura |
0:a40b9a259b52 | 5456 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5457 | * Return own keys in `obj`. |
Osamu Nakamura |
0:a40b9a259b52 | 5458 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5459 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 5460 | * @return {Array} |
Osamu Nakamura |
0:a40b9a259b52 | 5461 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5462 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5463 | |
Osamu Nakamura |
0:a40b9a259b52 | 5464 | exports.keys = Object.keys || function(obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 5465 | var keys = []; |
Osamu Nakamura |
0:a40b9a259b52 | 5466 | for (var key in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5467 | if (has.call(obj, key)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5468 | keys.push(key); |
Osamu Nakamura |
0:a40b9a259b52 | 5469 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5470 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5471 | return keys; |
Osamu Nakamura |
0:a40b9a259b52 | 5472 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5473 | |
Osamu Nakamura |
0:a40b9a259b52 | 5474 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5475 | * Return own values in `obj`. |
Osamu Nakamura |
0:a40b9a259b52 | 5476 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5477 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 5478 | * @return {Array} |
Osamu Nakamura |
0:a40b9a259b52 | 5479 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5480 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5481 | |
Osamu Nakamura |
0:a40b9a259b52 | 5482 | exports.values = function(obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 5483 | var vals = []; |
Osamu Nakamura |
0:a40b9a259b52 | 5484 | for (var key in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5485 | if (has.call(obj, key)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5486 | vals.push(obj[key]); |
Osamu Nakamura |
0:a40b9a259b52 | 5487 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5488 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5489 | return vals; |
Osamu Nakamura |
0:a40b9a259b52 | 5490 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5491 | |
Osamu Nakamura |
0:a40b9a259b52 | 5492 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5493 | * Merge `b` into `a`. |
Osamu Nakamura |
0:a40b9a259b52 | 5494 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5495 | * @param {Object} a |
Osamu Nakamura |
0:a40b9a259b52 | 5496 | * @param {Object} b |
Osamu Nakamura |
0:a40b9a259b52 | 5497 | * @return {Object} a |
Osamu Nakamura |
0:a40b9a259b52 | 5498 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5499 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5500 | |
Osamu Nakamura |
0:a40b9a259b52 | 5501 | exports.merge = function(a, b){ |
Osamu Nakamura |
0:a40b9a259b52 | 5502 | for (var key in b) { |
Osamu Nakamura |
0:a40b9a259b52 | 5503 | if (has.call(b, key)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5504 | a[key] = b[key]; |
Osamu Nakamura |
0:a40b9a259b52 | 5505 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5506 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5507 | return a; |
Osamu Nakamura |
0:a40b9a259b52 | 5508 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5509 | |
Osamu Nakamura |
0:a40b9a259b52 | 5510 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5511 | * Return length of `obj`. |
Osamu Nakamura |
0:a40b9a259b52 | 5512 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5513 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 5514 | * @return {Number} |
Osamu Nakamura |
0:a40b9a259b52 | 5515 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5516 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5517 | |
Osamu Nakamura |
0:a40b9a259b52 | 5518 | exports.length = function(obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 5519 | return exports.keys(obj).length; |
Osamu Nakamura |
0:a40b9a259b52 | 5520 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5521 | |
Osamu Nakamura |
0:a40b9a259b52 | 5522 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5523 | * Check if `obj` is empty. |
Osamu Nakamura |
0:a40b9a259b52 | 5524 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5525 | * @param {Object} obj |
Osamu Nakamura |
0:a40b9a259b52 | 5526 | * @return {Boolean} |
Osamu Nakamura |
0:a40b9a259b52 | 5527 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5528 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5529 | |
Osamu Nakamura |
0:a40b9a259b52 | 5530 | exports.isEmpty = function(obj){ |
Osamu Nakamura |
0:a40b9a259b52 | 5531 | return 0 == exports.length(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5532 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5533 | },{}],44:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5534 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5535 | * Parses an URI |
Osamu Nakamura |
0:a40b9a259b52 | 5536 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5537 | * @author Steven Levithan <stevenlevithan.com> (MIT license) |
Osamu Nakamura |
0:a40b9a259b52 | 5538 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5539 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5540 | |
Osamu Nakamura |
0:a40b9a259b52 | 5541 | var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; |
Osamu Nakamura |
0:a40b9a259b52 | 5542 | |
Osamu Nakamura |
0:a40b9a259b52 | 5543 | var parts = [ |
Osamu Nakamura |
0:a40b9a259b52 | 5544 | 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host' |
Osamu Nakamura |
0:a40b9a259b52 | 5545 | , 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor' |
Osamu Nakamura |
0:a40b9a259b52 | 5546 | ]; |
Osamu Nakamura |
0:a40b9a259b52 | 5547 | |
Osamu Nakamura |
0:a40b9a259b52 | 5548 | module.exports = function parseuri(str) { |
Osamu Nakamura |
0:a40b9a259b52 | 5549 | var m = re.exec(str || '') |
Osamu Nakamura |
0:a40b9a259b52 | 5550 | , uri = {} |
Osamu Nakamura |
0:a40b9a259b52 | 5551 | , i = 14; |
Osamu Nakamura |
0:a40b9a259b52 | 5552 | |
Osamu Nakamura |
0:a40b9a259b52 | 5553 | while (i--) { |
Osamu Nakamura |
0:a40b9a259b52 | 5554 | uri[parts[i]] = m[i] || ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5555 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5556 | |
Osamu Nakamura |
0:a40b9a259b52 | 5557 | return uri; |
Osamu Nakamura |
0:a40b9a259b52 | 5558 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5559 | |
Osamu Nakamura |
0:a40b9a259b52 | 5560 | },{}],45:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5561 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 5562 | /*global Blob,File*/ |
Osamu Nakamura |
0:a40b9a259b52 | 5563 | |
Osamu Nakamura |
0:a40b9a259b52 | 5564 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5565 | * Module requirements |
Osamu Nakamura |
0:a40b9a259b52 | 5566 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5567 | |
Osamu Nakamura |
0:a40b9a259b52 | 5568 | var isArray = _dereq_('isarray'); |
Osamu Nakamura |
0:a40b9a259b52 | 5569 | var isBuf = _dereq_('./is-buffer'); |
Osamu Nakamura |
0:a40b9a259b52 | 5570 | |
Osamu Nakamura |
0:a40b9a259b52 | 5571 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5572 | * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder. |
Osamu Nakamura |
0:a40b9a259b52 | 5573 | * Anything with blobs or files should be fed through removeBlobs before coming |
Osamu Nakamura |
0:a40b9a259b52 | 5574 | * here. |
Osamu Nakamura |
0:a40b9a259b52 | 5575 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5576 | * @param {Object} packet - socket.io event packet |
Osamu Nakamura |
0:a40b9a259b52 | 5577 | * @return {Object} with deconstructed packet and list of buffers |
Osamu Nakamura |
0:a40b9a259b52 | 5578 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5579 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5580 | |
Osamu Nakamura |
0:a40b9a259b52 | 5581 | exports.deconstructPacket = function(packet){ |
Osamu Nakamura |
0:a40b9a259b52 | 5582 | var buffers = []; |
Osamu Nakamura |
0:a40b9a259b52 | 5583 | var packetData = packet.data; |
Osamu Nakamura |
0:a40b9a259b52 | 5584 | |
Osamu Nakamura |
0:a40b9a259b52 | 5585 | function _deconstructPacket(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5586 | if (!data) return data; |
Osamu Nakamura |
0:a40b9a259b52 | 5587 | |
Osamu Nakamura |
0:a40b9a259b52 | 5588 | if (isBuf(data)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5589 | var placeholder = { _placeholder: true, num: buffers.length }; |
Osamu Nakamura |
0:a40b9a259b52 | 5590 | buffers.push(data); |
Osamu Nakamura |
0:a40b9a259b52 | 5591 | return placeholder; |
Osamu Nakamura |
0:a40b9a259b52 | 5592 | } else if (isArray(data)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5593 | var newData = new Array(data.length); |
Osamu Nakamura |
0:a40b9a259b52 | 5594 | for (var i = 0; i < data.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 5595 | newData[i] = _deconstructPacket(data[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 5596 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5597 | return newData; |
Osamu Nakamura |
0:a40b9a259b52 | 5598 | } else if ('object' == typeof data && !(data instanceof Date)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5599 | var newData = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 5600 | for (var key in data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5601 | newData[key] = _deconstructPacket(data[key]); |
Osamu Nakamura |
0:a40b9a259b52 | 5602 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5603 | return newData; |
Osamu Nakamura |
0:a40b9a259b52 | 5604 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5605 | return data; |
Osamu Nakamura |
0:a40b9a259b52 | 5606 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5607 | |
Osamu Nakamura |
0:a40b9a259b52 | 5608 | var pack = packet; |
Osamu Nakamura |
0:a40b9a259b52 | 5609 | pack.data = _deconstructPacket(packetData); |
Osamu Nakamura |
0:a40b9a259b52 | 5610 | pack.attachments = buffers.length; // number of binary 'attachments' |
Osamu Nakamura |
0:a40b9a259b52 | 5611 | return {packet: pack, buffers: buffers}; |
Osamu Nakamura |
0:a40b9a259b52 | 5612 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5613 | |
Osamu Nakamura |
0:a40b9a259b52 | 5614 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5615 | * Reconstructs a binary packet from its placeholder packet and buffers |
Osamu Nakamura |
0:a40b9a259b52 | 5616 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5617 | * @param {Object} packet - event packet with placeholders |
Osamu Nakamura |
0:a40b9a259b52 | 5618 | * @param {Array} buffers - binary buffers to put in placeholder positions |
Osamu Nakamura |
0:a40b9a259b52 | 5619 | * @return {Object} reconstructed packet |
Osamu Nakamura |
0:a40b9a259b52 | 5620 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5621 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5622 | |
Osamu Nakamura |
0:a40b9a259b52 | 5623 | exports.reconstructPacket = function(packet, buffers) { |
Osamu Nakamura |
0:a40b9a259b52 | 5624 | var curPlaceHolder = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 5625 | |
Osamu Nakamura |
0:a40b9a259b52 | 5626 | function _reconstructPacket(data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5627 | if (data && data._placeholder) { |
Osamu Nakamura |
0:a40b9a259b52 | 5628 | var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway) |
Osamu Nakamura |
0:a40b9a259b52 | 5629 | return buf; |
Osamu Nakamura |
0:a40b9a259b52 | 5630 | } else if (isArray(data)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5631 | for (var i = 0; i < data.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 5632 | data[i] = _reconstructPacket(data[i]); |
Osamu Nakamura |
0:a40b9a259b52 | 5633 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5634 | return data; |
Osamu Nakamura |
0:a40b9a259b52 | 5635 | } else if (data && 'object' == typeof data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5636 | for (var key in data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5637 | data[key] = _reconstructPacket(data[key]); |
Osamu Nakamura |
0:a40b9a259b52 | 5638 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5639 | return data; |
Osamu Nakamura |
0:a40b9a259b52 | 5640 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5641 | return data; |
Osamu Nakamura |
0:a40b9a259b52 | 5642 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5643 | |
Osamu Nakamura |
0:a40b9a259b52 | 5644 | packet.data = _reconstructPacket(packet.data); |
Osamu Nakamura |
0:a40b9a259b52 | 5645 | packet.attachments = undefined; // no longer useful |
Osamu Nakamura |
0:a40b9a259b52 | 5646 | return packet; |
Osamu Nakamura |
0:a40b9a259b52 | 5647 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5648 | |
Osamu Nakamura |
0:a40b9a259b52 | 5649 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5650 | * Asynchronously removes Blobs or Files from data via |
Osamu Nakamura |
0:a40b9a259b52 | 5651 | * FileReader's readAsArrayBuffer method. Used before encoding |
Osamu Nakamura |
0:a40b9a259b52 | 5652 | * data as msgpack. Calls callback with the blobless data. |
Osamu Nakamura |
0:a40b9a259b52 | 5653 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5654 | * @param {Object} data |
Osamu Nakamura |
0:a40b9a259b52 | 5655 | * @param {Function} callback |
Osamu Nakamura |
0:a40b9a259b52 | 5656 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5657 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5658 | |
Osamu Nakamura |
0:a40b9a259b52 | 5659 | exports.removeBlobs = function(data, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 5660 | function _removeBlobs(obj, curKey, containingObject) { |
Osamu Nakamura |
0:a40b9a259b52 | 5661 | if (!obj) return obj; |
Osamu Nakamura |
0:a40b9a259b52 | 5662 | |
Osamu Nakamura |
0:a40b9a259b52 | 5663 | // convert any blob |
Osamu Nakamura |
0:a40b9a259b52 | 5664 | if ((global.Blob && obj instanceof Blob) || |
Osamu Nakamura |
0:a40b9a259b52 | 5665 | (global.File && obj instanceof File)) { |
Osamu Nakamura |
0:a40b9a259b52 | 5666 | pendingBlobs++; |
Osamu Nakamura |
0:a40b9a259b52 | 5667 | |
Osamu Nakamura |
0:a40b9a259b52 | 5668 | // async filereader |
Osamu Nakamura |
0:a40b9a259b52 | 5669 | var fileReader = new FileReader(); |
Osamu Nakamura |
0:a40b9a259b52 | 5670 | fileReader.onload = function() { // this.result == arraybuffer |
Osamu Nakamura |
0:a40b9a259b52 | 5671 | if (containingObject) { |
Osamu Nakamura |
0:a40b9a259b52 | 5672 | containingObject[curKey] = this.result; |
Osamu Nakamura |
0:a40b9a259b52 | 5673 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5674 | else { |
Osamu Nakamura |
0:a40b9a259b52 | 5675 | bloblessData = this.result; |
Osamu Nakamura |
0:a40b9a259b52 | 5676 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5677 | |
Osamu Nakamura |
0:a40b9a259b52 | 5678 | // if nothing pending its callback time |
Osamu Nakamura |
0:a40b9a259b52 | 5679 | if(! --pendingBlobs) { |
Osamu Nakamura |
0:a40b9a259b52 | 5680 | callback(bloblessData); |
Osamu Nakamura |
0:a40b9a259b52 | 5681 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5682 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5683 | |
Osamu Nakamura |
0:a40b9a259b52 | 5684 | fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer |
Osamu Nakamura |
0:a40b9a259b52 | 5685 | } else if (isArray(obj)) { // handle array |
Osamu Nakamura |
0:a40b9a259b52 | 5686 | for (var i = 0; i < obj.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 5687 | _removeBlobs(obj[i], i, obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5688 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5689 | } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object |
Osamu Nakamura |
0:a40b9a259b52 | 5690 | for (var key in obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5691 | _removeBlobs(obj[key], key, obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5692 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5693 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5694 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5695 | |
Osamu Nakamura |
0:a40b9a259b52 | 5696 | var pendingBlobs = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 5697 | var bloblessData = data; |
Osamu Nakamura |
0:a40b9a259b52 | 5698 | _removeBlobs(bloblessData); |
Osamu Nakamura |
0:a40b9a259b52 | 5699 | if (!pendingBlobs) { |
Osamu Nakamura |
0:a40b9a259b52 | 5700 | callback(bloblessData); |
Osamu Nakamura |
0:a40b9a259b52 | 5701 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5702 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5703 | |
Osamu Nakamura |
0:a40b9a259b52 | 5704 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 5705 | },{"./is-buffer":47,"isarray":48}],46:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 5706 | |
Osamu Nakamura |
0:a40b9a259b52 | 5707 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5708 | * Module dependencies. |
Osamu Nakamura |
0:a40b9a259b52 | 5709 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5710 | |
Osamu Nakamura |
0:a40b9a259b52 | 5711 | var debug = _dereq_('debug')('socket.io-parser'); |
Osamu Nakamura |
0:a40b9a259b52 | 5712 | var json = _dereq_('json3'); |
Osamu Nakamura |
0:a40b9a259b52 | 5713 | var isArray = _dereq_('isarray'); |
Osamu Nakamura |
0:a40b9a259b52 | 5714 | var Emitter = _dereq_('component-emitter'); |
Osamu Nakamura |
0:a40b9a259b52 | 5715 | var binary = _dereq_('./binary'); |
Osamu Nakamura |
0:a40b9a259b52 | 5716 | var isBuf = _dereq_('./is-buffer'); |
Osamu Nakamura |
0:a40b9a259b52 | 5717 | |
Osamu Nakamura |
0:a40b9a259b52 | 5718 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5719 | * Protocol version. |
Osamu Nakamura |
0:a40b9a259b52 | 5720 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5721 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5722 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5723 | |
Osamu Nakamura |
0:a40b9a259b52 | 5724 | exports.protocol = 4; |
Osamu Nakamura |
0:a40b9a259b52 | 5725 | |
Osamu Nakamura |
0:a40b9a259b52 | 5726 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5727 | * Packet types. |
Osamu Nakamura |
0:a40b9a259b52 | 5728 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5729 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5730 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5731 | |
Osamu Nakamura |
0:a40b9a259b52 | 5732 | exports.types = [ |
Osamu Nakamura |
0:a40b9a259b52 | 5733 | 'CONNECT', |
Osamu Nakamura |
0:a40b9a259b52 | 5734 | 'DISCONNECT', |
Osamu Nakamura |
0:a40b9a259b52 | 5735 | 'EVENT', |
Osamu Nakamura |
0:a40b9a259b52 | 5736 | 'BINARY_EVENT', |
Osamu Nakamura |
0:a40b9a259b52 | 5737 | 'ACK', |
Osamu Nakamura |
0:a40b9a259b52 | 5738 | 'BINARY_ACK', |
Osamu Nakamura |
0:a40b9a259b52 | 5739 | 'ERROR' |
Osamu Nakamura |
0:a40b9a259b52 | 5740 | ]; |
Osamu Nakamura |
0:a40b9a259b52 | 5741 | |
Osamu Nakamura |
0:a40b9a259b52 | 5742 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5743 | * Packet type `connect`. |
Osamu Nakamura |
0:a40b9a259b52 | 5744 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5745 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5746 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5747 | |
Osamu Nakamura |
0:a40b9a259b52 | 5748 | exports.CONNECT = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 5749 | |
Osamu Nakamura |
0:a40b9a259b52 | 5750 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5751 | * Packet type `disconnect`. |
Osamu Nakamura |
0:a40b9a259b52 | 5752 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5753 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5754 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5755 | |
Osamu Nakamura |
0:a40b9a259b52 | 5756 | exports.DISCONNECT = 1; |
Osamu Nakamura |
0:a40b9a259b52 | 5757 | |
Osamu Nakamura |
0:a40b9a259b52 | 5758 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5759 | * Packet type `event`. |
Osamu Nakamura |
0:a40b9a259b52 | 5760 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5761 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5762 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5763 | |
Osamu Nakamura |
0:a40b9a259b52 | 5764 | exports.EVENT = 2; |
Osamu Nakamura |
0:a40b9a259b52 | 5765 | |
Osamu Nakamura |
0:a40b9a259b52 | 5766 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5767 | * Packet type `ack`. |
Osamu Nakamura |
0:a40b9a259b52 | 5768 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5769 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5770 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5771 | |
Osamu Nakamura |
0:a40b9a259b52 | 5772 | exports.ACK = 3; |
Osamu Nakamura |
0:a40b9a259b52 | 5773 | |
Osamu Nakamura |
0:a40b9a259b52 | 5774 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5775 | * Packet type `error`. |
Osamu Nakamura |
0:a40b9a259b52 | 5776 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5777 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5778 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5779 | |
Osamu Nakamura |
0:a40b9a259b52 | 5780 | exports.ERROR = 4; |
Osamu Nakamura |
0:a40b9a259b52 | 5781 | |
Osamu Nakamura |
0:a40b9a259b52 | 5782 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5783 | * Packet type 'binary event' |
Osamu Nakamura |
0:a40b9a259b52 | 5784 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5785 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5786 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5787 | |
Osamu Nakamura |
0:a40b9a259b52 | 5788 | exports.BINARY_EVENT = 5; |
Osamu Nakamura |
0:a40b9a259b52 | 5789 | |
Osamu Nakamura |
0:a40b9a259b52 | 5790 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5791 | * Packet type `binary ack`. For acks with binary arguments. |
Osamu Nakamura |
0:a40b9a259b52 | 5792 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5793 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5794 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5795 | |
Osamu Nakamura |
0:a40b9a259b52 | 5796 | exports.BINARY_ACK = 6; |
Osamu Nakamura |
0:a40b9a259b52 | 5797 | |
Osamu Nakamura |
0:a40b9a259b52 | 5798 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5799 | * Encoder constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 5800 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5801 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5802 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5803 | |
Osamu Nakamura |
0:a40b9a259b52 | 5804 | exports.Encoder = Encoder; |
Osamu Nakamura |
0:a40b9a259b52 | 5805 | |
Osamu Nakamura |
0:a40b9a259b52 | 5806 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5807 | * Decoder constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 5808 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5809 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5810 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5811 | |
Osamu Nakamura |
0:a40b9a259b52 | 5812 | exports.Decoder = Decoder; |
Osamu Nakamura |
0:a40b9a259b52 | 5813 | |
Osamu Nakamura |
0:a40b9a259b52 | 5814 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5815 | * A socket.io Encoder instance |
Osamu Nakamura |
0:a40b9a259b52 | 5816 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5817 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5818 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5819 | |
Osamu Nakamura |
0:a40b9a259b52 | 5820 | function Encoder() {} |
Osamu Nakamura |
0:a40b9a259b52 | 5821 | |
Osamu Nakamura |
0:a40b9a259b52 | 5822 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5823 | * Encode a packet as a single string if non-binary, or as a |
Osamu Nakamura |
0:a40b9a259b52 | 5824 | * buffer sequence, depending on packet type. |
Osamu Nakamura |
0:a40b9a259b52 | 5825 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5826 | * @param {Object} obj - packet object |
Osamu Nakamura |
0:a40b9a259b52 | 5827 | * @param {Function} callback - function to handle encodings (likely engine.write) |
Osamu Nakamura |
0:a40b9a259b52 | 5828 | * @return Calls callback with Array of encodings |
Osamu Nakamura |
0:a40b9a259b52 | 5829 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5830 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5831 | |
Osamu Nakamura |
0:a40b9a259b52 | 5832 | Encoder.prototype.encode = function(obj, callback){ |
Osamu Nakamura |
0:a40b9a259b52 | 5833 | debug('encoding packet %j', obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5834 | |
Osamu Nakamura |
0:a40b9a259b52 | 5835 | if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 5836 | encodeAsBinary(obj, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 5837 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5838 | else { |
Osamu Nakamura |
0:a40b9a259b52 | 5839 | var encoding = encodeAsString(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5840 | callback([encoding]); |
Osamu Nakamura |
0:a40b9a259b52 | 5841 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5842 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5843 | |
Osamu Nakamura |
0:a40b9a259b52 | 5844 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5845 | * Encode packet as string. |
Osamu Nakamura |
0:a40b9a259b52 | 5846 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5847 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 5848 | * @return {String} encoded |
Osamu Nakamura |
0:a40b9a259b52 | 5849 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5850 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5851 | |
Osamu Nakamura |
0:a40b9a259b52 | 5852 | function encodeAsString(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5853 | var str = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5854 | var nsp = false; |
Osamu Nakamura |
0:a40b9a259b52 | 5855 | |
Osamu Nakamura |
0:a40b9a259b52 | 5856 | // first is type |
Osamu Nakamura |
0:a40b9a259b52 | 5857 | str += obj.type; |
Osamu Nakamura |
0:a40b9a259b52 | 5858 | |
Osamu Nakamura |
0:a40b9a259b52 | 5859 | // attachments if we have them |
Osamu Nakamura |
0:a40b9a259b52 | 5860 | if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 5861 | str += obj.attachments; |
Osamu Nakamura |
0:a40b9a259b52 | 5862 | str += '-'; |
Osamu Nakamura |
0:a40b9a259b52 | 5863 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5864 | |
Osamu Nakamura |
0:a40b9a259b52 | 5865 | // if we have a namespace other than `/` |
Osamu Nakamura |
0:a40b9a259b52 | 5866 | // we append it followed by a comma `,` |
Osamu Nakamura |
0:a40b9a259b52 | 5867 | if (obj.nsp && '/' != obj.nsp) { |
Osamu Nakamura |
0:a40b9a259b52 | 5868 | nsp = true; |
Osamu Nakamura |
0:a40b9a259b52 | 5869 | str += obj.nsp; |
Osamu Nakamura |
0:a40b9a259b52 | 5870 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5871 | |
Osamu Nakamura |
0:a40b9a259b52 | 5872 | // immediately followed by the id |
Osamu Nakamura |
0:a40b9a259b52 | 5873 | if (null != obj.id) { |
Osamu Nakamura |
0:a40b9a259b52 | 5874 | if (nsp) { |
Osamu Nakamura |
0:a40b9a259b52 | 5875 | str += ','; |
Osamu Nakamura |
0:a40b9a259b52 | 5876 | nsp = false; |
Osamu Nakamura |
0:a40b9a259b52 | 5877 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5878 | str += obj.id; |
Osamu Nakamura |
0:a40b9a259b52 | 5879 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5880 | |
Osamu Nakamura |
0:a40b9a259b52 | 5881 | // json data |
Osamu Nakamura |
0:a40b9a259b52 | 5882 | if (null != obj.data) { |
Osamu Nakamura |
0:a40b9a259b52 | 5883 | if (nsp) str += ','; |
Osamu Nakamura |
0:a40b9a259b52 | 5884 | str += json.stringify(obj.data); |
Osamu Nakamura |
0:a40b9a259b52 | 5885 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5886 | |
Osamu Nakamura |
0:a40b9a259b52 | 5887 | debug('encoded %j as %s', obj, str); |
Osamu Nakamura |
0:a40b9a259b52 | 5888 | return str; |
Osamu Nakamura |
0:a40b9a259b52 | 5889 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5890 | |
Osamu Nakamura |
0:a40b9a259b52 | 5891 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5892 | * Encode packet as 'buffer sequence' by removing blobs, and |
Osamu Nakamura |
0:a40b9a259b52 | 5893 | * deconstructing packet into object with placeholders and |
Osamu Nakamura |
0:a40b9a259b52 | 5894 | * a list of buffers. |
Osamu Nakamura |
0:a40b9a259b52 | 5895 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5896 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 5897 | * @return {Buffer} encoded |
Osamu Nakamura |
0:a40b9a259b52 | 5898 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5899 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5900 | |
Osamu Nakamura |
0:a40b9a259b52 | 5901 | function encodeAsBinary(obj, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 5902 | |
Osamu Nakamura |
0:a40b9a259b52 | 5903 | function writeEncoding(bloblessData) { |
Osamu Nakamura |
0:a40b9a259b52 | 5904 | var deconstruction = binary.deconstructPacket(bloblessData); |
Osamu Nakamura |
0:a40b9a259b52 | 5905 | var pack = encodeAsString(deconstruction.packet); |
Osamu Nakamura |
0:a40b9a259b52 | 5906 | var buffers = deconstruction.buffers; |
Osamu Nakamura |
0:a40b9a259b52 | 5907 | |
Osamu Nakamura |
0:a40b9a259b52 | 5908 | buffers.unshift(pack); // add packet info to beginning of data list |
Osamu Nakamura |
0:a40b9a259b52 | 5909 | callback(buffers); // write all the buffers |
Osamu Nakamura |
0:a40b9a259b52 | 5910 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5911 | |
Osamu Nakamura |
0:a40b9a259b52 | 5912 | binary.removeBlobs(obj, writeEncoding); |
Osamu Nakamura |
0:a40b9a259b52 | 5913 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5914 | |
Osamu Nakamura |
0:a40b9a259b52 | 5915 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5916 | * A socket.io Decoder instance |
Osamu Nakamura |
0:a40b9a259b52 | 5917 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5918 | * @return {Object} decoder |
Osamu Nakamura |
0:a40b9a259b52 | 5919 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5920 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5921 | |
Osamu Nakamura |
0:a40b9a259b52 | 5922 | function Decoder() { |
Osamu Nakamura |
0:a40b9a259b52 | 5923 | this.reconstructor = null; |
Osamu Nakamura |
0:a40b9a259b52 | 5924 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5925 | |
Osamu Nakamura |
0:a40b9a259b52 | 5926 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5927 | * Mix in `Emitter` with Decoder. |
Osamu Nakamura |
0:a40b9a259b52 | 5928 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5929 | |
Osamu Nakamura |
0:a40b9a259b52 | 5930 | Emitter(Decoder.prototype); |
Osamu Nakamura |
0:a40b9a259b52 | 5931 | |
Osamu Nakamura |
0:a40b9a259b52 | 5932 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5933 | * Decodes an ecoded packet string into packet JSON. |
Osamu Nakamura |
0:a40b9a259b52 | 5934 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5935 | * @param {String} obj - encoded packet |
Osamu Nakamura |
0:a40b9a259b52 | 5936 | * @return {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 5937 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 5938 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5939 | |
Osamu Nakamura |
0:a40b9a259b52 | 5940 | Decoder.prototype.add = function(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5941 | var packet; |
Osamu Nakamura |
0:a40b9a259b52 | 5942 | if ('string' == typeof obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 5943 | packet = decodeString(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5944 | if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json |
Osamu Nakamura |
0:a40b9a259b52 | 5945 | this.reconstructor = new BinaryReconstructor(packet); |
Osamu Nakamura |
0:a40b9a259b52 | 5946 | |
Osamu Nakamura |
0:a40b9a259b52 | 5947 | // no attachments, labeled binary but no binary data to follow |
Osamu Nakamura |
0:a40b9a259b52 | 5948 | if (this.reconstructor.reconPack.attachments === 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 5949 | this.emit('decoded', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 5950 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5951 | } else { // non-binary full packet |
Osamu Nakamura |
0:a40b9a259b52 | 5952 | this.emit('decoded', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 5953 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5954 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5955 | else if (isBuf(obj) || obj.base64) { // raw binary data |
Osamu Nakamura |
0:a40b9a259b52 | 5956 | if (!this.reconstructor) { |
Osamu Nakamura |
0:a40b9a259b52 | 5957 | throw new Error('got binary data when not reconstructing a packet'); |
Osamu Nakamura |
0:a40b9a259b52 | 5958 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 5959 | packet = this.reconstructor.takeBinaryData(obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5960 | if (packet) { // received final buffer |
Osamu Nakamura |
0:a40b9a259b52 | 5961 | this.reconstructor = null; |
Osamu Nakamura |
0:a40b9a259b52 | 5962 | this.emit('decoded', packet); |
Osamu Nakamura |
0:a40b9a259b52 | 5963 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5964 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5965 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5966 | else { |
Osamu Nakamura |
0:a40b9a259b52 | 5967 | throw new Error('Unknown type: ' + obj); |
Osamu Nakamura |
0:a40b9a259b52 | 5968 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5969 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 5970 | |
Osamu Nakamura |
0:a40b9a259b52 | 5971 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 5972 | * Decode a packet String (JSON data) |
Osamu Nakamura |
0:a40b9a259b52 | 5973 | * |
Osamu Nakamura |
0:a40b9a259b52 | 5974 | * @param {String} str |
Osamu Nakamura |
0:a40b9a259b52 | 5975 | * @return {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 5976 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 5977 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 5978 | |
Osamu Nakamura |
0:a40b9a259b52 | 5979 | function decodeString(str) { |
Osamu Nakamura |
0:a40b9a259b52 | 5980 | var p = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 5981 | var i = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 5982 | |
Osamu Nakamura |
0:a40b9a259b52 | 5983 | // look up type |
Osamu Nakamura |
0:a40b9a259b52 | 5984 | p.type = Number(str.charAt(0)); |
Osamu Nakamura |
0:a40b9a259b52 | 5985 | if (null == exports.types[p.type]) return error(); |
Osamu Nakamura |
0:a40b9a259b52 | 5986 | |
Osamu Nakamura |
0:a40b9a259b52 | 5987 | // look up attachments if type binary |
Osamu Nakamura |
0:a40b9a259b52 | 5988 | if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) { |
Osamu Nakamura |
0:a40b9a259b52 | 5989 | var buf = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 5990 | while (str.charAt(++i) != '-') { |
Osamu Nakamura |
0:a40b9a259b52 | 5991 | buf += str.charAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 5992 | if (i == str.length) break; |
Osamu Nakamura |
0:a40b9a259b52 | 5993 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5994 | if (buf != Number(buf) || str.charAt(i) != '-') { |
Osamu Nakamura |
0:a40b9a259b52 | 5995 | throw new Error('Illegal attachments'); |
Osamu Nakamura |
0:a40b9a259b52 | 5996 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5997 | p.attachments = Number(buf); |
Osamu Nakamura |
0:a40b9a259b52 | 5998 | } |
Osamu Nakamura |
0:a40b9a259b52 | 5999 | |
Osamu Nakamura |
0:a40b9a259b52 | 6000 | // look up namespace (if any) |
Osamu Nakamura |
0:a40b9a259b52 | 6001 | if ('/' == str.charAt(i + 1)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6002 | p.nsp = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 6003 | while (++i) { |
Osamu Nakamura |
0:a40b9a259b52 | 6004 | var c = str.charAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 6005 | if (',' == c) break; |
Osamu Nakamura |
0:a40b9a259b52 | 6006 | p.nsp += c; |
Osamu Nakamura |
0:a40b9a259b52 | 6007 | if (i == str.length) break; |
Osamu Nakamura |
0:a40b9a259b52 | 6008 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6009 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6010 | p.nsp = '/'; |
Osamu Nakamura |
0:a40b9a259b52 | 6011 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6012 | |
Osamu Nakamura |
0:a40b9a259b52 | 6013 | // look up id |
Osamu Nakamura |
0:a40b9a259b52 | 6014 | var next = str.charAt(i + 1); |
Osamu Nakamura |
0:a40b9a259b52 | 6015 | if ('' !== next && Number(next) == next) { |
Osamu Nakamura |
0:a40b9a259b52 | 6016 | p.id = ''; |
Osamu Nakamura |
0:a40b9a259b52 | 6017 | while (++i) { |
Osamu Nakamura |
0:a40b9a259b52 | 6018 | var c = str.charAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 6019 | if (null == c || Number(c) != c) { |
Osamu Nakamura |
0:a40b9a259b52 | 6020 | --i; |
Osamu Nakamura |
0:a40b9a259b52 | 6021 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6022 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6023 | p.id += str.charAt(i); |
Osamu Nakamura |
0:a40b9a259b52 | 6024 | if (i == str.length) break; |
Osamu Nakamura |
0:a40b9a259b52 | 6025 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6026 | p.id = Number(p.id); |
Osamu Nakamura |
0:a40b9a259b52 | 6027 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6028 | |
Osamu Nakamura |
0:a40b9a259b52 | 6029 | // look up json data |
Osamu Nakamura |
0:a40b9a259b52 | 6030 | if (str.charAt(++i)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6031 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6032 | p.data = json.parse(str.substr(i)); |
Osamu Nakamura |
0:a40b9a259b52 | 6033 | } catch(e){ |
Osamu Nakamura |
0:a40b9a259b52 | 6034 | return error(); |
Osamu Nakamura |
0:a40b9a259b52 | 6035 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6036 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6037 | |
Osamu Nakamura |
0:a40b9a259b52 | 6038 | debug('decoded %s as %j', str, p); |
Osamu Nakamura |
0:a40b9a259b52 | 6039 | return p; |
Osamu Nakamura |
0:a40b9a259b52 | 6040 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6041 | |
Osamu Nakamura |
0:a40b9a259b52 | 6042 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 6043 | * Deallocates a parser's resources |
Osamu Nakamura |
0:a40b9a259b52 | 6044 | * |
Osamu Nakamura |
0:a40b9a259b52 | 6045 | * @api public |
Osamu Nakamura |
0:a40b9a259b52 | 6046 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 6047 | |
Osamu Nakamura |
0:a40b9a259b52 | 6048 | Decoder.prototype.destroy = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 6049 | if (this.reconstructor) { |
Osamu Nakamura |
0:a40b9a259b52 | 6050 | this.reconstructor.finishedReconstruction(); |
Osamu Nakamura |
0:a40b9a259b52 | 6051 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6052 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6053 | |
Osamu Nakamura |
0:a40b9a259b52 | 6054 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 6055 | * A manager of a binary event's 'buffer sequence'. Should |
Osamu Nakamura |
0:a40b9a259b52 | 6056 | * be constructed whenever a packet of type BINARY_EVENT is |
Osamu Nakamura |
0:a40b9a259b52 | 6057 | * decoded. |
Osamu Nakamura |
0:a40b9a259b52 | 6058 | * |
Osamu Nakamura |
0:a40b9a259b52 | 6059 | * @param {Object} packet |
Osamu Nakamura |
0:a40b9a259b52 | 6060 | * @return {BinaryReconstructor} initialized reconstructor |
Osamu Nakamura |
0:a40b9a259b52 | 6061 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 6062 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 6063 | |
Osamu Nakamura |
0:a40b9a259b52 | 6064 | function BinaryReconstructor(packet) { |
Osamu Nakamura |
0:a40b9a259b52 | 6065 | this.reconPack = packet; |
Osamu Nakamura |
0:a40b9a259b52 | 6066 | this.buffers = []; |
Osamu Nakamura |
0:a40b9a259b52 | 6067 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6068 | |
Osamu Nakamura |
0:a40b9a259b52 | 6069 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 6070 | * Method to be called when binary data received from connection |
Osamu Nakamura |
0:a40b9a259b52 | 6071 | * after a BINARY_EVENT packet. |
Osamu Nakamura |
0:a40b9a259b52 | 6072 | * |
Osamu Nakamura |
0:a40b9a259b52 | 6073 | * @param {Buffer | ArrayBuffer} binData - the raw binary data received |
Osamu Nakamura |
0:a40b9a259b52 | 6074 | * @return {null | Object} returns null if more binary data is expected or |
Osamu Nakamura |
0:a40b9a259b52 | 6075 | * a reconstructed packet object if all buffers have been received. |
Osamu Nakamura |
0:a40b9a259b52 | 6076 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 6077 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 6078 | |
Osamu Nakamura |
0:a40b9a259b52 | 6079 | BinaryReconstructor.prototype.takeBinaryData = function(binData) { |
Osamu Nakamura |
0:a40b9a259b52 | 6080 | this.buffers.push(binData); |
Osamu Nakamura |
0:a40b9a259b52 | 6081 | if (this.buffers.length == this.reconPack.attachments) { // done with buffer list |
Osamu Nakamura |
0:a40b9a259b52 | 6082 | var packet = binary.reconstructPacket(this.reconPack, this.buffers); |
Osamu Nakamura |
0:a40b9a259b52 | 6083 | this.finishedReconstruction(); |
Osamu Nakamura |
0:a40b9a259b52 | 6084 | return packet; |
Osamu Nakamura |
0:a40b9a259b52 | 6085 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6086 | return null; |
Osamu Nakamura |
0:a40b9a259b52 | 6087 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6088 | |
Osamu Nakamura |
0:a40b9a259b52 | 6089 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 6090 | * Cleans up binary packet reconstruction variables. |
Osamu Nakamura |
0:a40b9a259b52 | 6091 | * |
Osamu Nakamura |
0:a40b9a259b52 | 6092 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 6093 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 6094 | |
Osamu Nakamura |
0:a40b9a259b52 | 6095 | BinaryReconstructor.prototype.finishedReconstruction = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 6096 | this.reconPack = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6097 | this.buffers = []; |
Osamu Nakamura |
0:a40b9a259b52 | 6098 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6099 | |
Osamu Nakamura |
0:a40b9a259b52 | 6100 | function error(data){ |
Osamu Nakamura |
0:a40b9a259b52 | 6101 | return { |
Osamu Nakamura |
0:a40b9a259b52 | 6102 | type: exports.ERROR, |
Osamu Nakamura |
0:a40b9a259b52 | 6103 | data: 'parser error' |
Osamu Nakamura |
0:a40b9a259b52 | 6104 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6105 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6106 | |
Osamu Nakamura |
0:a40b9a259b52 | 6107 | },{"./binary":45,"./is-buffer":47,"component-emitter":9,"debug":10,"isarray":48,"json3":49}],47:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 6108 | (function (global){ |
Osamu Nakamura |
0:a40b9a259b52 | 6109 | |
Osamu Nakamura |
0:a40b9a259b52 | 6110 | module.exports = isBuf; |
Osamu Nakamura |
0:a40b9a259b52 | 6111 | |
Osamu Nakamura |
0:a40b9a259b52 | 6112 | /** |
Osamu Nakamura |
0:a40b9a259b52 | 6113 | * Returns true if obj is a buffer or an arraybuffer. |
Osamu Nakamura |
0:a40b9a259b52 | 6114 | * |
Osamu Nakamura |
0:a40b9a259b52 | 6115 | * @api private |
Osamu Nakamura |
0:a40b9a259b52 | 6116 | */ |
Osamu Nakamura |
0:a40b9a259b52 | 6117 | |
Osamu Nakamura |
0:a40b9a259b52 | 6118 | function isBuf(obj) { |
Osamu Nakamura |
0:a40b9a259b52 | 6119 | return (global.Buffer && global.Buffer.isBuffer(obj)) || |
Osamu Nakamura |
0:a40b9a259b52 | 6120 | (global.ArrayBuffer && obj instanceof ArrayBuffer); |
Osamu Nakamura |
0:a40b9a259b52 | 6121 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6122 | |
Osamu Nakamura |
0:a40b9a259b52 | 6123 | }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Osamu Nakamura |
0:a40b9a259b52 | 6124 | },{}],48:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 6125 | module.exports=_dereq_(32) |
Osamu Nakamura |
0:a40b9a259b52 | 6126 | },{}],49:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 6127 | /*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */ |
Osamu Nakamura |
0:a40b9a259b52 | 6128 | ;(function (window) { |
Osamu Nakamura |
0:a40b9a259b52 | 6129 | // Convenience aliases. |
Osamu Nakamura |
0:a40b9a259b52 | 6130 | var getClass = {}.toString, isProperty, forEach, undef; |
Osamu Nakamura |
0:a40b9a259b52 | 6131 | |
Osamu Nakamura |
0:a40b9a259b52 | 6132 | // Detect the `define` function exposed by asynchronous module loaders. The |
Osamu Nakamura |
0:a40b9a259b52 | 6133 | // strict `define` check is necessary for compatibility with `r.js`. |
Osamu Nakamura |
0:a40b9a259b52 | 6134 | var isLoader = typeof define === "function" && define.amd; |
Osamu Nakamura |
0:a40b9a259b52 | 6135 | |
Osamu Nakamura |
0:a40b9a259b52 | 6136 | // Detect native implementations. |
Osamu Nakamura |
0:a40b9a259b52 | 6137 | var nativeJSON = typeof JSON == "object" && JSON; |
Osamu Nakamura |
0:a40b9a259b52 | 6138 | |
Osamu Nakamura |
0:a40b9a259b52 | 6139 | // Set up the JSON 3 namespace, preferring the CommonJS `exports` object if |
Osamu Nakamura |
0:a40b9a259b52 | 6140 | // available. |
Osamu Nakamura |
0:a40b9a259b52 | 6141 | var JSON3 = typeof exports == "object" && exports && !exports.nodeType && exports; |
Osamu Nakamura |
0:a40b9a259b52 | 6142 | |
Osamu Nakamura |
0:a40b9a259b52 | 6143 | if (JSON3 && nativeJSON) { |
Osamu Nakamura |
0:a40b9a259b52 | 6144 | // Explicitly delegate to the native `stringify` and `parse` |
Osamu Nakamura |
0:a40b9a259b52 | 6145 | // implementations in CommonJS environments. |
Osamu Nakamura |
0:a40b9a259b52 | 6146 | JSON3.stringify = nativeJSON.stringify; |
Osamu Nakamura |
0:a40b9a259b52 | 6147 | JSON3.parse = nativeJSON.parse; |
Osamu Nakamura |
0:a40b9a259b52 | 6148 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6149 | // Export for web browsers, JavaScript engines, and asynchronous module |
Osamu Nakamura |
0:a40b9a259b52 | 6150 | // loaders, using the global `JSON` object if available. |
Osamu Nakamura |
0:a40b9a259b52 | 6151 | JSON3 = window.JSON = nativeJSON || {}; |
Osamu Nakamura |
0:a40b9a259b52 | 6152 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6153 | |
Osamu Nakamura |
0:a40b9a259b52 | 6154 | // Test the `Date#getUTC*` methods. Based on work by @Yaffle. |
Osamu Nakamura |
0:a40b9a259b52 | 6155 | var isExtended = new Date(-3509827334573292); |
Osamu Nakamura |
0:a40b9a259b52 | 6156 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6157 | // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical |
Osamu Nakamura |
0:a40b9a259b52 | 6158 | // results for certain dates in Opera >= 10.53. |
Osamu Nakamura |
0:a40b9a259b52 | 6159 | isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && |
Osamu Nakamura |
0:a40b9a259b52 | 6160 | // Safari < 2.0.2 stores the internal millisecond time value correctly, |
Osamu Nakamura |
0:a40b9a259b52 | 6161 | // but clips the values returned by the date methods to the range of |
Osamu Nakamura |
0:a40b9a259b52 | 6162 | // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). |
Osamu Nakamura |
0:a40b9a259b52 | 6163 | isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; |
Osamu Nakamura |
0:a40b9a259b52 | 6164 | } catch (exception) {} |
Osamu Nakamura |
0:a40b9a259b52 | 6165 | |
Osamu Nakamura |
0:a40b9a259b52 | 6166 | // Internal: Determines whether the native `JSON.stringify` and `parse` |
Osamu Nakamura |
0:a40b9a259b52 | 6167 | // implementations are spec-compliant. Based on work by Ken Snyder. |
Osamu Nakamura |
0:a40b9a259b52 | 6168 | function has(name) { |
Osamu Nakamura |
0:a40b9a259b52 | 6169 | if (has[name] !== undef) { |
Osamu Nakamura |
0:a40b9a259b52 | 6170 | // Return cached feature test result. |
Osamu Nakamura |
0:a40b9a259b52 | 6171 | return has[name]; |
Osamu Nakamura |
0:a40b9a259b52 | 6172 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6173 | |
Osamu Nakamura |
0:a40b9a259b52 | 6174 | var isSupported; |
Osamu Nakamura |
0:a40b9a259b52 | 6175 | if (name == "bug-string-char-index") { |
Osamu Nakamura |
0:a40b9a259b52 | 6176 | // IE <= 7 doesn't support accessing string characters using square |
Osamu Nakamura |
0:a40b9a259b52 | 6177 | // bracket notation. IE 8 only supports this for primitives. |
Osamu Nakamura |
0:a40b9a259b52 | 6178 | isSupported = "a"[0] != "a"; |
Osamu Nakamura |
0:a40b9a259b52 | 6179 | } else if (name == "json") { |
Osamu Nakamura |
0:a40b9a259b52 | 6180 | // Indicates whether both `JSON.stringify` and `JSON.parse` are |
Osamu Nakamura |
0:a40b9a259b52 | 6181 | // supported. |
Osamu Nakamura |
0:a40b9a259b52 | 6182 | isSupported = has("json-stringify") && has("json-parse"); |
Osamu Nakamura |
0:a40b9a259b52 | 6183 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6184 | var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; |
Osamu Nakamura |
0:a40b9a259b52 | 6185 | // Test `JSON.stringify`. |
Osamu Nakamura |
0:a40b9a259b52 | 6186 | if (name == "json-stringify") { |
Osamu Nakamura |
0:a40b9a259b52 | 6187 | var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended; |
Osamu Nakamura |
0:a40b9a259b52 | 6188 | if (stringifySupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 6189 | // A test function object with a custom `toJSON` method. |
Osamu Nakamura |
0:a40b9a259b52 | 6190 | (value = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 6191 | return 1; |
Osamu Nakamura |
0:a40b9a259b52 | 6192 | }).toJSON = value; |
Osamu Nakamura |
0:a40b9a259b52 | 6193 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6194 | stringifySupported = |
Osamu Nakamura |
0:a40b9a259b52 | 6195 | // Firefox 3.1b1 and b2 serialize string, number, and boolean |
Osamu Nakamura |
0:a40b9a259b52 | 6196 | // primitives as object literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6197 | stringify(0) === "0" && |
Osamu Nakamura |
0:a40b9a259b52 | 6198 | // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object |
Osamu Nakamura |
0:a40b9a259b52 | 6199 | // literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6200 | stringify(new Number()) === "0" && |
Osamu Nakamura |
0:a40b9a259b52 | 6201 | stringify(new String()) == '""' && |
Osamu Nakamura |
0:a40b9a259b52 | 6202 | // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or |
Osamu Nakamura |
0:a40b9a259b52 | 6203 | // does not define a canonical JSON representation (this applies to |
Osamu Nakamura |
0:a40b9a259b52 | 6204 | // objects with `toJSON` properties as well, *unless* they are nested |
Osamu Nakamura |
0:a40b9a259b52 | 6205 | // within an object or array). |
Osamu Nakamura |
0:a40b9a259b52 | 6206 | stringify(getClass) === undef && |
Osamu Nakamura |
0:a40b9a259b52 | 6207 | // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and |
Osamu Nakamura |
0:a40b9a259b52 | 6208 | // FF 3.1b3 pass this test. |
Osamu Nakamura |
0:a40b9a259b52 | 6209 | stringify(undef) === undef && |
Osamu Nakamura |
0:a40b9a259b52 | 6210 | // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, |
Osamu Nakamura |
0:a40b9a259b52 | 6211 | // respectively, if the value is omitted entirely. |
Osamu Nakamura |
0:a40b9a259b52 | 6212 | stringify() === undef && |
Osamu Nakamura |
0:a40b9a259b52 | 6213 | // FF 3.1b1, 2 throw an error if the given value is not a number, |
Osamu Nakamura |
0:a40b9a259b52 | 6214 | // string, array, object, Boolean, or `null` literal. This applies to |
Osamu Nakamura |
0:a40b9a259b52 | 6215 | // objects with custom `toJSON` methods as well, unless they are nested |
Osamu Nakamura |
0:a40b9a259b52 | 6216 | // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` |
Osamu Nakamura |
0:a40b9a259b52 | 6217 | // methods entirely. |
Osamu Nakamura |
0:a40b9a259b52 | 6218 | stringify(value) === "1" && |
Osamu Nakamura |
0:a40b9a259b52 | 6219 | stringify([value]) == "[1]" && |
Osamu Nakamura |
0:a40b9a259b52 | 6220 | // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of |
Osamu Nakamura |
0:a40b9a259b52 | 6221 | // `"[null]"`. |
Osamu Nakamura |
0:a40b9a259b52 | 6222 | stringify([undef]) == "[null]" && |
Osamu Nakamura |
0:a40b9a259b52 | 6223 | // YUI 3.0.0b1 fails to serialize `null` literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6224 | stringify(null) == "null" && |
Osamu Nakamura |
0:a40b9a259b52 | 6225 | // FF 3.1b1, 2 halts serialization if an array contains a function: |
Osamu Nakamura |
0:a40b9a259b52 | 6226 | // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 |
Osamu Nakamura |
0:a40b9a259b52 | 6227 | // elides non-JSON values from objects and arrays, unless they |
Osamu Nakamura |
0:a40b9a259b52 | 6228 | // define custom `toJSON` methods. |
Osamu Nakamura |
0:a40b9a259b52 | 6229 | stringify([undef, getClass, null]) == "[null,null,null]" && |
Osamu Nakamura |
0:a40b9a259b52 | 6230 | // Simple serialization test. FF 3.1b1 uses Unicode escape sequences |
Osamu Nakamura |
0:a40b9a259b52 | 6231 | // where character escape codes are expected (e.g., `\b` => `\u0008`). |
Osamu Nakamura |
0:a40b9a259b52 | 6232 | stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && |
Osamu Nakamura |
0:a40b9a259b52 | 6233 | // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. |
Osamu Nakamura |
0:a40b9a259b52 | 6234 | stringify(null, value) === "1" && |
Osamu Nakamura |
0:a40b9a259b52 | 6235 | stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && |
Osamu Nakamura |
0:a40b9a259b52 | 6236 | // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly |
Osamu Nakamura |
0:a40b9a259b52 | 6237 | // serialize extended years. |
Osamu Nakamura |
0:a40b9a259b52 | 6238 | stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && |
Osamu Nakamura |
0:a40b9a259b52 | 6239 | // The milliseconds are optional in ES 5, but required in 5.1. |
Osamu Nakamura |
0:a40b9a259b52 | 6240 | stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && |
Osamu Nakamura |
0:a40b9a259b52 | 6241 | // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative |
Osamu Nakamura |
0:a40b9a259b52 | 6242 | // four-digit years instead of six-digit years. Credits: @Yaffle. |
Osamu Nakamura |
0:a40b9a259b52 | 6243 | stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && |
Osamu Nakamura |
0:a40b9a259b52 | 6244 | // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond |
Osamu Nakamura |
0:a40b9a259b52 | 6245 | // values less than 1000. Credits: @Yaffle. |
Osamu Nakamura |
0:a40b9a259b52 | 6246 | stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; |
Osamu Nakamura |
0:a40b9a259b52 | 6247 | } catch (exception) { |
Osamu Nakamura |
0:a40b9a259b52 | 6248 | stringifySupported = false; |
Osamu Nakamura |
0:a40b9a259b52 | 6249 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6250 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6251 | isSupported = stringifySupported; |
Osamu Nakamura |
0:a40b9a259b52 | 6252 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6253 | // Test `JSON.parse`. |
Osamu Nakamura |
0:a40b9a259b52 | 6254 | if (name == "json-parse") { |
Osamu Nakamura |
0:a40b9a259b52 | 6255 | var parse = JSON3.parse; |
Osamu Nakamura |
0:a40b9a259b52 | 6256 | if (typeof parse == "function") { |
Osamu Nakamura |
0:a40b9a259b52 | 6257 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6258 | // FF 3.1b1, b2 will throw an exception if a bare literal is provided. |
Osamu Nakamura |
0:a40b9a259b52 | 6259 | // Conforming implementations should also coerce the initial argument to |
Osamu Nakamura |
0:a40b9a259b52 | 6260 | // a string prior to parsing. |
Osamu Nakamura |
0:a40b9a259b52 | 6261 | if (parse("0") === 0 && !parse(false)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6262 | // Simple parsing test. |
Osamu Nakamura |
0:a40b9a259b52 | 6263 | value = parse(serialized); |
Osamu Nakamura |
0:a40b9a259b52 | 6264 | var parseSupported = value["a"].length == 5 && value["a"][0] === 1; |
Osamu Nakamura |
0:a40b9a259b52 | 6265 | if (parseSupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 6266 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6267 | // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. |
Osamu Nakamura |
0:a40b9a259b52 | 6268 | parseSupported = !parse('"\t"'); |
Osamu Nakamura |
0:a40b9a259b52 | 6269 | } catch (exception) {} |
Osamu Nakamura |
0:a40b9a259b52 | 6270 | if (parseSupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 6271 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6272 | // FF 4.0 and 4.0.1 allow leading `+` signs and leading |
Osamu Nakamura |
0:a40b9a259b52 | 6273 | // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow |
Osamu Nakamura |
0:a40b9a259b52 | 6274 | // certain octal literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6275 | parseSupported = parse("01") !== 1; |
Osamu Nakamura |
0:a40b9a259b52 | 6276 | } catch (exception) {} |
Osamu Nakamura |
0:a40b9a259b52 | 6277 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6278 | if (parseSupported) { |
Osamu Nakamura |
0:a40b9a259b52 | 6279 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6280 | // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal |
Osamu Nakamura |
0:a40b9a259b52 | 6281 | // points. These environments, along with FF 3.1b1 and 2, |
Osamu Nakamura |
0:a40b9a259b52 | 6282 | // also allow trailing commas in JSON objects and arrays. |
Osamu Nakamura |
0:a40b9a259b52 | 6283 | parseSupported = parse("1.") !== 1; |
Osamu Nakamura |
0:a40b9a259b52 | 6284 | } catch (exception) {} |
Osamu Nakamura |
0:a40b9a259b52 | 6285 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6286 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6287 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6288 | } catch (exception) { |
Osamu Nakamura |
0:a40b9a259b52 | 6289 | parseSupported = false; |
Osamu Nakamura |
0:a40b9a259b52 | 6290 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6291 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6292 | isSupported = parseSupported; |
Osamu Nakamura |
0:a40b9a259b52 | 6293 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6294 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6295 | return has[name] = !!isSupported; |
Osamu Nakamura |
0:a40b9a259b52 | 6296 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6297 | |
Osamu Nakamura |
0:a40b9a259b52 | 6298 | if (!has("json")) { |
Osamu Nakamura |
0:a40b9a259b52 | 6299 | // Common `[[Class]]` name aliases. |
Osamu Nakamura |
0:a40b9a259b52 | 6300 | var functionClass = "[object Function]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6301 | var dateClass = "[object Date]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6302 | var numberClass = "[object Number]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6303 | var stringClass = "[object String]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6304 | var arrayClass = "[object Array]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6305 | var booleanClass = "[object Boolean]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6306 | |
Osamu Nakamura |
0:a40b9a259b52 | 6307 | // Detect incomplete support for accessing string characters by index. |
Osamu Nakamura |
0:a40b9a259b52 | 6308 | var charIndexBuggy = has("bug-string-char-index"); |
Osamu Nakamura |
0:a40b9a259b52 | 6309 | |
Osamu Nakamura |
0:a40b9a259b52 | 6310 | // Define additional utility methods if the `Date` methods are buggy. |
Osamu Nakamura |
0:a40b9a259b52 | 6311 | if (!isExtended) { |
Osamu Nakamura |
0:a40b9a259b52 | 6312 | var floor = Math.floor; |
Osamu Nakamura |
0:a40b9a259b52 | 6313 | // A mapping between the months of the year and the number of days between |
Osamu Nakamura |
0:a40b9a259b52 | 6314 | // January 1st and the first of the respective month. |
Osamu Nakamura |
0:a40b9a259b52 | 6315 | var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; |
Osamu Nakamura |
0:a40b9a259b52 | 6316 | // Internal: Calculates the number of days between the Unix epoch and the |
Osamu Nakamura |
0:a40b9a259b52 | 6317 | // first day of the given month. |
Osamu Nakamura |
0:a40b9a259b52 | 6318 | var getDay = function (year, month) { |
Osamu Nakamura |
0:a40b9a259b52 | 6319 | return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); |
Osamu Nakamura |
0:a40b9a259b52 | 6320 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6321 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6322 | |
Osamu Nakamura |
0:a40b9a259b52 | 6323 | // Internal: Determines if a property is a direct property of the given |
Osamu Nakamura |
0:a40b9a259b52 | 6324 | // object. Delegates to the native `Object#hasOwnProperty` method. |
Osamu Nakamura |
0:a40b9a259b52 | 6325 | if (!(isProperty = {}.hasOwnProperty)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6326 | isProperty = function (property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6327 | var members = {}, constructor; |
Osamu Nakamura |
0:a40b9a259b52 | 6328 | if ((members.__proto__ = null, members.__proto__ = { |
Osamu Nakamura |
0:a40b9a259b52 | 6329 | // The *proto* property cannot be set multiple times in recent |
Osamu Nakamura |
0:a40b9a259b52 | 6330 | // versions of Firefox and SeaMonkey. |
Osamu Nakamura |
0:a40b9a259b52 | 6331 | "toString": 1 |
Osamu Nakamura |
0:a40b9a259b52 | 6332 | }, members).toString != getClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6333 | // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but |
Osamu Nakamura |
0:a40b9a259b52 | 6334 | // supports the mutable *proto* property. |
Osamu Nakamura |
0:a40b9a259b52 | 6335 | isProperty = function (property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6336 | // Capture and break the object's prototype chain (see section 8.6.2 |
Osamu Nakamura |
0:a40b9a259b52 | 6337 | // of the ES 5.1 spec). The parenthesized expression prevents an |
Osamu Nakamura |
0:a40b9a259b52 | 6338 | // unsafe transformation by the Closure Compiler. |
Osamu Nakamura |
0:a40b9a259b52 | 6339 | var original = this.__proto__, result = property in (this.__proto__ = null, this); |
Osamu Nakamura |
0:a40b9a259b52 | 6340 | // Restore the original prototype chain. |
Osamu Nakamura |
0:a40b9a259b52 | 6341 | this.__proto__ = original; |
Osamu Nakamura |
0:a40b9a259b52 | 6342 | return result; |
Osamu Nakamura |
0:a40b9a259b52 | 6343 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6344 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6345 | // Capture a reference to the top-level `Object` constructor. |
Osamu Nakamura |
0:a40b9a259b52 | 6346 | constructor = members.constructor; |
Osamu Nakamura |
0:a40b9a259b52 | 6347 | // Use the `constructor` property to simulate `Object#hasOwnProperty` in |
Osamu Nakamura |
0:a40b9a259b52 | 6348 | // other environments. |
Osamu Nakamura |
0:a40b9a259b52 | 6349 | isProperty = function (property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6350 | var parent = (this.constructor || constructor).prototype; |
Osamu Nakamura |
0:a40b9a259b52 | 6351 | return property in this && !(property in parent && this[property] === parent[property]); |
Osamu Nakamura |
0:a40b9a259b52 | 6352 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6353 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6354 | members = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6355 | return isProperty.call(this, property); |
Osamu Nakamura |
0:a40b9a259b52 | 6356 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6357 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6358 | |
Osamu Nakamura |
0:a40b9a259b52 | 6359 | // Internal: A set of primitive types used by `isHostType`. |
Osamu Nakamura |
0:a40b9a259b52 | 6360 | var PrimitiveTypes = { |
Osamu Nakamura |
0:a40b9a259b52 | 6361 | 'boolean': 1, |
Osamu Nakamura |
0:a40b9a259b52 | 6362 | 'number': 1, |
Osamu Nakamura |
0:a40b9a259b52 | 6363 | 'string': 1, |
Osamu Nakamura |
0:a40b9a259b52 | 6364 | 'undefined': 1 |
Osamu Nakamura |
0:a40b9a259b52 | 6365 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6366 | |
Osamu Nakamura |
0:a40b9a259b52 | 6367 | // Internal: Determines if the given object `property` value is a |
Osamu Nakamura |
0:a40b9a259b52 | 6368 | // non-primitive. |
Osamu Nakamura |
0:a40b9a259b52 | 6369 | var isHostType = function (object, property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6370 | var type = typeof object[property]; |
Osamu Nakamura |
0:a40b9a259b52 | 6371 | return type == 'object' ? !!object[property] : !PrimitiveTypes[type]; |
Osamu Nakamura |
0:a40b9a259b52 | 6372 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6373 | |
Osamu Nakamura |
0:a40b9a259b52 | 6374 | // Internal: Normalizes the `for...in` iteration algorithm across |
Osamu Nakamura |
0:a40b9a259b52 | 6375 | // environments. Each enumerated key is yielded to a `callback` function. |
Osamu Nakamura |
0:a40b9a259b52 | 6376 | forEach = function (object, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6377 | var size = 0, Properties, members, property; |
Osamu Nakamura |
0:a40b9a259b52 | 6378 | |
Osamu Nakamura |
0:a40b9a259b52 | 6379 | // Tests for bugs in the current environment's `for...in` algorithm. The |
Osamu Nakamura |
0:a40b9a259b52 | 6380 | // `valueOf` property inherits the non-enumerable flag from |
Osamu Nakamura |
0:a40b9a259b52 | 6381 | // `Object.prototype` in older versions of IE, Netscape, and Mozilla. |
Osamu Nakamura |
0:a40b9a259b52 | 6382 | (Properties = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 6383 | this.valueOf = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 6384 | }).prototype.valueOf = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 6385 | |
Osamu Nakamura |
0:a40b9a259b52 | 6386 | // Iterate over a new instance of the `Properties` class. |
Osamu Nakamura |
0:a40b9a259b52 | 6387 | members = new Properties(); |
Osamu Nakamura |
0:a40b9a259b52 | 6388 | for (property in members) { |
Osamu Nakamura |
0:a40b9a259b52 | 6389 | // Ignore all properties inherited from `Object.prototype`. |
Osamu Nakamura |
0:a40b9a259b52 | 6390 | if (isProperty.call(members, property)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6391 | size++; |
Osamu Nakamura |
0:a40b9a259b52 | 6392 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6393 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6394 | Properties = members = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6395 | |
Osamu Nakamura |
0:a40b9a259b52 | 6396 | // Normalize the iteration algorithm. |
Osamu Nakamura |
0:a40b9a259b52 | 6397 | if (!size) { |
Osamu Nakamura |
0:a40b9a259b52 | 6398 | // A list of non-enumerable properties inherited from `Object.prototype`. |
Osamu Nakamura |
0:a40b9a259b52 | 6399 | members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; |
Osamu Nakamura |
0:a40b9a259b52 | 6400 | // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable |
Osamu Nakamura |
0:a40b9a259b52 | 6401 | // properties. |
Osamu Nakamura |
0:a40b9a259b52 | 6402 | forEach = function (object, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6403 | var isFunction = getClass.call(object) == functionClass, property, length; |
Osamu Nakamura |
0:a40b9a259b52 | 6404 | var hasProperty = !isFunction && typeof object.constructor != 'function' && isHostType(object, 'hasOwnProperty') ? object.hasOwnProperty : isProperty; |
Osamu Nakamura |
0:a40b9a259b52 | 6405 | for (property in object) { |
Osamu Nakamura |
0:a40b9a259b52 | 6406 | // Gecko <= 1.0 enumerates the `prototype` property of functions under |
Osamu Nakamura |
0:a40b9a259b52 | 6407 | // certain conditions; IE does not. |
Osamu Nakamura |
0:a40b9a259b52 | 6408 | if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6409 | callback(property); |
Osamu Nakamura |
0:a40b9a259b52 | 6410 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6411 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6412 | // Manually invoke the callback for each non-enumerable property. |
Osamu Nakamura |
0:a40b9a259b52 | 6413 | for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); |
Osamu Nakamura |
0:a40b9a259b52 | 6414 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6415 | } else if (size == 2) { |
Osamu Nakamura |
0:a40b9a259b52 | 6416 | // Safari <= 2.0.4 enumerates shadowed properties twice. |
Osamu Nakamura |
0:a40b9a259b52 | 6417 | forEach = function (object, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6418 | // Create a set of iterated properties. |
Osamu Nakamura |
0:a40b9a259b52 | 6419 | var members = {}, isFunction = getClass.call(object) == functionClass, property; |
Osamu Nakamura |
0:a40b9a259b52 | 6420 | for (property in object) { |
Osamu Nakamura |
0:a40b9a259b52 | 6421 | // Store each property name to prevent double enumeration. The |
Osamu Nakamura |
0:a40b9a259b52 | 6422 | // `prototype` property of functions is not enumerated due to cross- |
Osamu Nakamura |
0:a40b9a259b52 | 6423 | // environment inconsistencies. |
Osamu Nakamura |
0:a40b9a259b52 | 6424 | if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6425 | callback(property); |
Osamu Nakamura |
0:a40b9a259b52 | 6426 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6427 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6428 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6429 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6430 | // No bugs detected; use the standard `for...in` algorithm. |
Osamu Nakamura |
0:a40b9a259b52 | 6431 | forEach = function (object, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6432 | var isFunction = getClass.call(object) == functionClass, property, isConstructor; |
Osamu Nakamura |
0:a40b9a259b52 | 6433 | for (property in object) { |
Osamu Nakamura |
0:a40b9a259b52 | 6434 | if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { |
Osamu Nakamura |
0:a40b9a259b52 | 6435 | callback(property); |
Osamu Nakamura |
0:a40b9a259b52 | 6436 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6437 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6438 | // Manually invoke the callback for the `constructor` property due to |
Osamu Nakamura |
0:a40b9a259b52 | 6439 | // cross-environment inconsistencies. |
Osamu Nakamura |
0:a40b9a259b52 | 6440 | if (isConstructor || isProperty.call(object, (property = "constructor"))) { |
Osamu Nakamura |
0:a40b9a259b52 | 6441 | callback(property); |
Osamu Nakamura |
0:a40b9a259b52 | 6442 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6443 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6444 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6445 | return forEach(object, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 6446 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6447 | |
Osamu Nakamura |
0:a40b9a259b52 | 6448 | // Public: Serializes a JavaScript `value` as a JSON string. The optional |
Osamu Nakamura |
0:a40b9a259b52 | 6449 | // `filter` argument may specify either a function that alters how object and |
Osamu Nakamura |
0:a40b9a259b52 | 6450 | // array members are serialized, or an array of strings and numbers that |
Osamu Nakamura |
0:a40b9a259b52 | 6451 | // indicates which properties should be serialized. The optional `width` |
Osamu Nakamura |
0:a40b9a259b52 | 6452 | // argument may be either a string or number that specifies the indentation |
Osamu Nakamura |
0:a40b9a259b52 | 6453 | // level of the output. |
Osamu Nakamura |
0:a40b9a259b52 | 6454 | if (!has("json-stringify")) { |
Osamu Nakamura |
0:a40b9a259b52 | 6455 | // Internal: A map of control characters and their escaped equivalents. |
Osamu Nakamura |
0:a40b9a259b52 | 6456 | var Escapes = { |
Osamu Nakamura |
0:a40b9a259b52 | 6457 | 92: "\\\\", |
Osamu Nakamura |
0:a40b9a259b52 | 6458 | 34: '\\"', |
Osamu Nakamura |
0:a40b9a259b52 | 6459 | 8: "\\b", |
Osamu Nakamura |
0:a40b9a259b52 | 6460 | 12: "\\f", |
Osamu Nakamura |
0:a40b9a259b52 | 6461 | 10: "\\n", |
Osamu Nakamura |
0:a40b9a259b52 | 6462 | 13: "\\r", |
Osamu Nakamura |
0:a40b9a259b52 | 6463 | 9: "\\t" |
Osamu Nakamura |
0:a40b9a259b52 | 6464 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6465 | |
Osamu Nakamura |
0:a40b9a259b52 | 6466 | // Internal: Converts `value` into a zero-padded string such that its |
Osamu Nakamura |
0:a40b9a259b52 | 6467 | // length is at least equal to `width`. The `width` must be <= 6. |
Osamu Nakamura |
0:a40b9a259b52 | 6468 | var leadingZeroes = "000000"; |
Osamu Nakamura |
0:a40b9a259b52 | 6469 | var toPaddedString = function (width, value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6470 | // The `|| 0` expression is necessary to work around a bug in |
Osamu Nakamura |
0:a40b9a259b52 | 6471 | // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. |
Osamu Nakamura |
0:a40b9a259b52 | 6472 | return (leadingZeroes + (value || 0)).slice(-width); |
Osamu Nakamura |
0:a40b9a259b52 | 6473 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6474 | |
Osamu Nakamura |
0:a40b9a259b52 | 6475 | // Internal: Double-quotes a string `value`, replacing all ASCII control |
Osamu Nakamura |
0:a40b9a259b52 | 6476 | // characters (characters with code unit values between 0 and 31) with |
Osamu Nakamura |
0:a40b9a259b52 | 6477 | // their escaped equivalents. This is an implementation of the |
Osamu Nakamura |
0:a40b9a259b52 | 6478 | // `Quote(value)` operation defined in ES 5.1 section 15.12.3. |
Osamu Nakamura |
0:a40b9a259b52 | 6479 | var unicodePrefix = "\\u00"; |
Osamu Nakamura |
0:a40b9a259b52 | 6480 | var quote = function (value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6481 | var result = '"', index = 0, length = value.length, isLarge = length > 10 && charIndexBuggy, symbols; |
Osamu Nakamura |
0:a40b9a259b52 | 6482 | if (isLarge) { |
Osamu Nakamura |
0:a40b9a259b52 | 6483 | symbols = value.split(""); |
Osamu Nakamura |
0:a40b9a259b52 | 6484 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6485 | for (; index < length; index++) { |
Osamu Nakamura |
0:a40b9a259b52 | 6486 | var charCode = value.charCodeAt(index); |
Osamu Nakamura |
0:a40b9a259b52 | 6487 | // If the character is a control character, append its Unicode or |
Osamu Nakamura |
0:a40b9a259b52 | 6488 | // shorthand escape sequence; otherwise, append the character as-is. |
Osamu Nakamura |
0:a40b9a259b52 | 6489 | switch (charCode) { |
Osamu Nakamura |
0:a40b9a259b52 | 6490 | case 8: case 9: case 10: case 12: case 13: case 34: case 92: |
Osamu Nakamura |
0:a40b9a259b52 | 6491 | result += Escapes[charCode]; |
Osamu Nakamura |
0:a40b9a259b52 | 6492 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6493 | default: |
Osamu Nakamura |
0:a40b9a259b52 | 6494 | if (charCode < 32) { |
Osamu Nakamura |
0:a40b9a259b52 | 6495 | result += unicodePrefix + toPaddedString(2, charCode.toString(16)); |
Osamu Nakamura |
0:a40b9a259b52 | 6496 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6497 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6498 | result += isLarge ? symbols[index] : charIndexBuggy ? value.charAt(index) : value[index]; |
Osamu Nakamura |
0:a40b9a259b52 | 6499 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6500 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6501 | return result + '"'; |
Osamu Nakamura |
0:a40b9a259b52 | 6502 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6503 | |
Osamu Nakamura |
0:a40b9a259b52 | 6504 | // Internal: Recursively serializes an object. Implements the |
Osamu Nakamura |
0:a40b9a259b52 | 6505 | // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. |
Osamu Nakamura |
0:a40b9a259b52 | 6506 | var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { |
Osamu Nakamura |
0:a40b9a259b52 | 6507 | var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; |
Osamu Nakamura |
0:a40b9a259b52 | 6508 | try { |
Osamu Nakamura |
0:a40b9a259b52 | 6509 | // Necessary for host object support. |
Osamu Nakamura |
0:a40b9a259b52 | 6510 | value = object[property]; |
Osamu Nakamura |
0:a40b9a259b52 | 6511 | } catch (exception) {} |
Osamu Nakamura |
0:a40b9a259b52 | 6512 | if (typeof value == "object" && value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6513 | className = getClass.call(value); |
Osamu Nakamura |
0:a40b9a259b52 | 6514 | if (className == dateClass && !isProperty.call(value, "toJSON")) { |
Osamu Nakamura |
0:a40b9a259b52 | 6515 | if (value > -1 / 0 && value < 1 / 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 6516 | // Dates are serialized according to the `Date#toJSON` method |
Osamu Nakamura |
0:a40b9a259b52 | 6517 | // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 |
Osamu Nakamura |
0:a40b9a259b52 | 6518 | // for the ISO 8601 date time string format. |
Osamu Nakamura |
0:a40b9a259b52 | 6519 | if (getDay) { |
Osamu Nakamura |
0:a40b9a259b52 | 6520 | // Manually compute the year, month, date, hours, minutes, |
Osamu Nakamura |
0:a40b9a259b52 | 6521 | // seconds, and milliseconds if the `getUTC*` methods are |
Osamu Nakamura |
0:a40b9a259b52 | 6522 | // buggy. Adapted from @Yaffle's `date-shim` project. |
Osamu Nakamura |
0:a40b9a259b52 | 6523 | date = floor(value / 864e5); |
Osamu Nakamura |
0:a40b9a259b52 | 6524 | for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); |
Osamu Nakamura |
0:a40b9a259b52 | 6525 | for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); |
Osamu Nakamura |
0:a40b9a259b52 | 6526 | date = 1 + date - getDay(year, month); |
Osamu Nakamura |
0:a40b9a259b52 | 6527 | // The `time` value specifies the time within the day (see ES |
Osamu Nakamura |
0:a40b9a259b52 | 6528 | // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used |
Osamu Nakamura |
0:a40b9a259b52 | 6529 | // to compute `A modulo B`, as the `%` operator does not |
Osamu Nakamura |
0:a40b9a259b52 | 6530 | // correspond to the `modulo` operation for negative numbers. |
Osamu Nakamura |
0:a40b9a259b52 | 6531 | time = (value % 864e5 + 864e5) % 864e5; |
Osamu Nakamura |
0:a40b9a259b52 | 6532 | // The hours, minutes, seconds, and milliseconds are obtained by |
Osamu Nakamura |
0:a40b9a259b52 | 6533 | // decomposing the time within the day. See section 15.9.1.10. |
Osamu Nakamura |
0:a40b9a259b52 | 6534 | hours = floor(time / 36e5) % 24; |
Osamu Nakamura |
0:a40b9a259b52 | 6535 | minutes = floor(time / 6e4) % 60; |
Osamu Nakamura |
0:a40b9a259b52 | 6536 | seconds = floor(time / 1e3) % 60; |
Osamu Nakamura |
0:a40b9a259b52 | 6537 | milliseconds = time % 1e3; |
Osamu Nakamura |
0:a40b9a259b52 | 6538 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6539 | year = value.getUTCFullYear(); |
Osamu Nakamura |
0:a40b9a259b52 | 6540 | month = value.getUTCMonth(); |
Osamu Nakamura |
0:a40b9a259b52 | 6541 | date = value.getUTCDate(); |
Osamu Nakamura |
0:a40b9a259b52 | 6542 | hours = value.getUTCHours(); |
Osamu Nakamura |
0:a40b9a259b52 | 6543 | minutes = value.getUTCMinutes(); |
Osamu Nakamura |
0:a40b9a259b52 | 6544 | seconds = value.getUTCSeconds(); |
Osamu Nakamura |
0:a40b9a259b52 | 6545 | milliseconds = value.getUTCMilliseconds(); |
Osamu Nakamura |
0:a40b9a259b52 | 6546 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6547 | // Serialize extended years correctly. |
Osamu Nakamura |
0:a40b9a259b52 | 6548 | value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + |
Osamu Nakamura |
0:a40b9a259b52 | 6549 | "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + |
Osamu Nakamura |
0:a40b9a259b52 | 6550 | // Months, dates, hours, minutes, and seconds should have two |
Osamu Nakamura |
0:a40b9a259b52 | 6551 | // digits; milliseconds should have three. |
Osamu Nakamura |
0:a40b9a259b52 | 6552 | "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + |
Osamu Nakamura |
0:a40b9a259b52 | 6553 | // Milliseconds are optional in ES 5.0, but required in 5.1. |
Osamu Nakamura |
0:a40b9a259b52 | 6554 | "." + toPaddedString(3, milliseconds) + "Z"; |
Osamu Nakamura |
0:a40b9a259b52 | 6555 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6556 | value = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6557 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6558 | } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { |
Osamu Nakamura |
0:a40b9a259b52 | 6559 | // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the |
Osamu Nakamura |
0:a40b9a259b52 | 6560 | // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 |
Osamu Nakamura |
0:a40b9a259b52 | 6561 | // ignores all `toJSON` methods on these objects unless they are |
Osamu Nakamura |
0:a40b9a259b52 | 6562 | // defined directly on an instance. |
Osamu Nakamura |
0:a40b9a259b52 | 6563 | value = value.toJSON(property); |
Osamu Nakamura |
0:a40b9a259b52 | 6564 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6565 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6566 | if (callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6567 | // If a replacement function was provided, call it to obtain the value |
Osamu Nakamura |
0:a40b9a259b52 | 6568 | // for serialization. |
Osamu Nakamura |
0:a40b9a259b52 | 6569 | value = callback.call(object, property, value); |
Osamu Nakamura |
0:a40b9a259b52 | 6570 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6571 | if (value === null) { |
Osamu Nakamura |
0:a40b9a259b52 | 6572 | return "null"; |
Osamu Nakamura |
0:a40b9a259b52 | 6573 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6574 | className = getClass.call(value); |
Osamu Nakamura |
0:a40b9a259b52 | 6575 | if (className == booleanClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6576 | // Booleans are represented literally. |
Osamu Nakamura |
0:a40b9a259b52 | 6577 | return "" + value; |
Osamu Nakamura |
0:a40b9a259b52 | 6578 | } else if (className == numberClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6579 | // JSON numbers must be finite. `Infinity` and `NaN` are serialized as |
Osamu Nakamura |
0:a40b9a259b52 | 6580 | // `"null"`. |
Osamu Nakamura |
0:a40b9a259b52 | 6581 | return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; |
Osamu Nakamura |
0:a40b9a259b52 | 6582 | } else if (className == stringClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6583 | // Strings are double-quoted and escaped. |
Osamu Nakamura |
0:a40b9a259b52 | 6584 | return quote("" + value); |
Osamu Nakamura |
0:a40b9a259b52 | 6585 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6586 | // Recursively serialize objects and arrays. |
Osamu Nakamura |
0:a40b9a259b52 | 6587 | if (typeof value == "object") { |
Osamu Nakamura |
0:a40b9a259b52 | 6588 | // Check for cyclic structures. This is a linear search; performance |
Osamu Nakamura |
0:a40b9a259b52 | 6589 | // is inversely proportional to the number of unique nested objects. |
Osamu Nakamura |
0:a40b9a259b52 | 6590 | for (length = stack.length; length--;) { |
Osamu Nakamura |
0:a40b9a259b52 | 6591 | if (stack[length] === value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6592 | // Cyclic structures cannot be serialized by `JSON.stringify`. |
Osamu Nakamura |
0:a40b9a259b52 | 6593 | throw TypeError(); |
Osamu Nakamura |
0:a40b9a259b52 | 6594 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6595 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6596 | // Add the object to the stack of traversed objects. |
Osamu Nakamura |
0:a40b9a259b52 | 6597 | stack.push(value); |
Osamu Nakamura |
0:a40b9a259b52 | 6598 | results = []; |
Osamu Nakamura |
0:a40b9a259b52 | 6599 | // Save the current indentation level and indent one additional level. |
Osamu Nakamura |
0:a40b9a259b52 | 6600 | prefix = indentation; |
Osamu Nakamura |
0:a40b9a259b52 | 6601 | indentation += whitespace; |
Osamu Nakamura |
0:a40b9a259b52 | 6602 | if (className == arrayClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6603 | // Recursively serialize array elements. |
Osamu Nakamura |
0:a40b9a259b52 | 6604 | for (index = 0, length = value.length; index < length; index++) { |
Osamu Nakamura |
0:a40b9a259b52 | 6605 | element = serialize(index, value, callback, properties, whitespace, indentation, stack); |
Osamu Nakamura |
0:a40b9a259b52 | 6606 | results.push(element === undef ? "null" : element); |
Osamu Nakamura |
0:a40b9a259b52 | 6607 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6608 | result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; |
Osamu Nakamura |
0:a40b9a259b52 | 6609 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6610 | // Recursively serialize object members. Members are selected from |
Osamu Nakamura |
0:a40b9a259b52 | 6611 | // either a user-specified list of property names, or the object |
Osamu Nakamura |
0:a40b9a259b52 | 6612 | // itself. |
Osamu Nakamura |
0:a40b9a259b52 | 6613 | forEach(properties || value, function (property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6614 | var element = serialize(property, value, callback, properties, whitespace, indentation, stack); |
Osamu Nakamura |
0:a40b9a259b52 | 6615 | if (element !== undef) { |
Osamu Nakamura |
0:a40b9a259b52 | 6616 | // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} |
Osamu Nakamura |
0:a40b9a259b52 | 6617 | // is not the empty string, let `member` {quote(property) + ":"} |
Osamu Nakamura |
0:a40b9a259b52 | 6618 | // be the concatenation of `member` and the `space` character." |
Osamu Nakamura |
0:a40b9a259b52 | 6619 | // The "`space` character" refers to the literal space |
Osamu Nakamura |
0:a40b9a259b52 | 6620 | // character, not the `space` {width} argument provided to |
Osamu Nakamura |
0:a40b9a259b52 | 6621 | // `JSON.stringify`. |
Osamu Nakamura |
0:a40b9a259b52 | 6622 | results.push(quote(property) + ":" + (whitespace ? " " : "") + element); |
Osamu Nakamura |
0:a40b9a259b52 | 6623 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6624 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 6625 | result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; |
Osamu Nakamura |
0:a40b9a259b52 | 6626 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6627 | // Remove the object from the traversed object stack. |
Osamu Nakamura |
0:a40b9a259b52 | 6628 | stack.pop(); |
Osamu Nakamura |
0:a40b9a259b52 | 6629 | return result; |
Osamu Nakamura |
0:a40b9a259b52 | 6630 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6631 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6632 | |
Osamu Nakamura |
0:a40b9a259b52 | 6633 | // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. |
Osamu Nakamura |
0:a40b9a259b52 | 6634 | JSON3.stringify = function (source, filter, width) { |
Osamu Nakamura |
0:a40b9a259b52 | 6635 | var whitespace, callback, properties, className; |
Osamu Nakamura |
0:a40b9a259b52 | 6636 | if (typeof filter == "function" || typeof filter == "object" && filter) { |
Osamu Nakamura |
0:a40b9a259b52 | 6637 | if ((className = getClass.call(filter)) == functionClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6638 | callback = filter; |
Osamu Nakamura |
0:a40b9a259b52 | 6639 | } else if (className == arrayClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6640 | // Convert the property names array into a makeshift set. |
Osamu Nakamura |
0:a40b9a259b52 | 6641 | properties = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 6642 | for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); |
Osamu Nakamura |
0:a40b9a259b52 | 6643 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6644 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6645 | if (width) { |
Osamu Nakamura |
0:a40b9a259b52 | 6646 | if ((className = getClass.call(width)) == numberClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6647 | // Convert the `width` to an integer and create a string containing |
Osamu Nakamura |
0:a40b9a259b52 | 6648 | // `width` number of space characters. |
Osamu Nakamura |
0:a40b9a259b52 | 6649 | if ((width -= width % 1) > 0) { |
Osamu Nakamura |
0:a40b9a259b52 | 6650 | for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); |
Osamu Nakamura |
0:a40b9a259b52 | 6651 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6652 | } else if (className == stringClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6653 | whitespace = width.length <= 10 ? width : width.slice(0, 10); |
Osamu Nakamura |
0:a40b9a259b52 | 6654 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6655 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6656 | // Opera <= 7.54u2 discards the values associated with empty string keys |
Osamu Nakamura |
0:a40b9a259b52 | 6657 | // (`""`) only if they are used directly within an object member list |
Osamu Nakamura |
0:a40b9a259b52 | 6658 | // (e.g., `!("" in { "": 1})`). |
Osamu Nakamura |
0:a40b9a259b52 | 6659 | return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); |
Osamu Nakamura |
0:a40b9a259b52 | 6660 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6661 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6662 | |
Osamu Nakamura |
0:a40b9a259b52 | 6663 | // Public: Parses a JSON source string. |
Osamu Nakamura |
0:a40b9a259b52 | 6664 | if (!has("json-parse")) { |
Osamu Nakamura |
0:a40b9a259b52 | 6665 | var fromCharCode = String.fromCharCode; |
Osamu Nakamura |
0:a40b9a259b52 | 6666 | |
Osamu Nakamura |
0:a40b9a259b52 | 6667 | // Internal: A map of escaped control characters and their unescaped |
Osamu Nakamura |
0:a40b9a259b52 | 6668 | // equivalents. |
Osamu Nakamura |
0:a40b9a259b52 | 6669 | var Unescapes = { |
Osamu Nakamura |
0:a40b9a259b52 | 6670 | 92: "\\", |
Osamu Nakamura |
0:a40b9a259b52 | 6671 | 34: '"', |
Osamu Nakamura |
0:a40b9a259b52 | 6672 | 47: "/", |
Osamu Nakamura |
0:a40b9a259b52 | 6673 | 98: "\b", |
Osamu Nakamura |
0:a40b9a259b52 | 6674 | 116: "\t", |
Osamu Nakamura |
0:a40b9a259b52 | 6675 | 110: "\n", |
Osamu Nakamura |
0:a40b9a259b52 | 6676 | 102: "\f", |
Osamu Nakamura |
0:a40b9a259b52 | 6677 | 114: "\r" |
Osamu Nakamura |
0:a40b9a259b52 | 6678 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6679 | |
Osamu Nakamura |
0:a40b9a259b52 | 6680 | // Internal: Stores the parser state. |
Osamu Nakamura |
0:a40b9a259b52 | 6681 | var Index, Source; |
Osamu Nakamura |
0:a40b9a259b52 | 6682 | |
Osamu Nakamura |
0:a40b9a259b52 | 6683 | // Internal: Resets the parser state and throws a `SyntaxError`. |
Osamu Nakamura |
0:a40b9a259b52 | 6684 | var abort = function() { |
Osamu Nakamura |
0:a40b9a259b52 | 6685 | Index = Source = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6686 | throw SyntaxError(); |
Osamu Nakamura |
0:a40b9a259b52 | 6687 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6688 | |
Osamu Nakamura |
0:a40b9a259b52 | 6689 | // Internal: Returns the next token, or `"$"` if the parser has reached |
Osamu Nakamura |
0:a40b9a259b52 | 6690 | // the end of the source string. A token may be a string, number, `null` |
Osamu Nakamura |
0:a40b9a259b52 | 6691 | // literal, or Boolean literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6692 | var lex = function () { |
Osamu Nakamura |
0:a40b9a259b52 | 6693 | var source = Source, length = source.length, value, begin, position, isSigned, charCode; |
Osamu Nakamura |
0:a40b9a259b52 | 6694 | while (Index < length) { |
Osamu Nakamura |
0:a40b9a259b52 | 6695 | charCode = source.charCodeAt(Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6696 | switch (charCode) { |
Osamu Nakamura |
0:a40b9a259b52 | 6697 | case 9: case 10: case 13: case 32: |
Osamu Nakamura |
0:a40b9a259b52 | 6698 | // Skip whitespace tokens, including tabs, carriage returns, line |
Osamu Nakamura |
0:a40b9a259b52 | 6699 | // feeds, and space characters. |
Osamu Nakamura |
0:a40b9a259b52 | 6700 | Index++; |
Osamu Nakamura |
0:a40b9a259b52 | 6701 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6702 | case 123: case 125: case 91: case 93: case 58: case 44: |
Osamu Nakamura |
0:a40b9a259b52 | 6703 | // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at |
Osamu Nakamura |
0:a40b9a259b52 | 6704 | // the current position. |
Osamu Nakamura |
0:a40b9a259b52 | 6705 | value = charIndexBuggy ? source.charAt(Index) : source[Index]; |
Osamu Nakamura |
0:a40b9a259b52 | 6706 | Index++; |
Osamu Nakamura |
0:a40b9a259b52 | 6707 | return value; |
Osamu Nakamura |
0:a40b9a259b52 | 6708 | case 34: |
Osamu Nakamura |
0:a40b9a259b52 | 6709 | // `"` delimits a JSON string; advance to the next character and |
Osamu Nakamura |
0:a40b9a259b52 | 6710 | // begin parsing the string. String tokens are prefixed with the |
Osamu Nakamura |
0:a40b9a259b52 | 6711 | // sentinel `@` character to distinguish them from punctuators and |
Osamu Nakamura |
0:a40b9a259b52 | 6712 | // end-of-string tokens. |
Osamu Nakamura |
0:a40b9a259b52 | 6713 | for (value = "@", Index++; Index < length;) { |
Osamu Nakamura |
0:a40b9a259b52 | 6714 | charCode = source.charCodeAt(Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6715 | if (charCode < 32) { |
Osamu Nakamura |
0:a40b9a259b52 | 6716 | // Unescaped ASCII control characters (those with a code unit |
Osamu Nakamura |
0:a40b9a259b52 | 6717 | // less than the space character) are not permitted. |
Osamu Nakamura |
0:a40b9a259b52 | 6718 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6719 | } else if (charCode == 92) { |
Osamu Nakamura |
0:a40b9a259b52 | 6720 | // A reverse solidus (`\`) marks the beginning of an escaped |
Osamu Nakamura |
0:a40b9a259b52 | 6721 | // control character (including `"`, `\`, and `/`) or Unicode |
Osamu Nakamura |
0:a40b9a259b52 | 6722 | // escape sequence. |
Osamu Nakamura |
0:a40b9a259b52 | 6723 | charCode = source.charCodeAt(++Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6724 | switch (charCode) { |
Osamu Nakamura |
0:a40b9a259b52 | 6725 | case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: |
Osamu Nakamura |
0:a40b9a259b52 | 6726 | // Revive escaped control characters. |
Osamu Nakamura |
0:a40b9a259b52 | 6727 | value += Unescapes[charCode]; |
Osamu Nakamura |
0:a40b9a259b52 | 6728 | Index++; |
Osamu Nakamura |
0:a40b9a259b52 | 6729 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6730 | case 117: |
Osamu Nakamura |
0:a40b9a259b52 | 6731 | // `\u` marks the beginning of a Unicode escape sequence. |
Osamu Nakamura |
0:a40b9a259b52 | 6732 | // Advance to the first character and validate the |
Osamu Nakamura |
0:a40b9a259b52 | 6733 | // four-digit code point. |
Osamu Nakamura |
0:a40b9a259b52 | 6734 | begin = ++Index; |
Osamu Nakamura |
0:a40b9a259b52 | 6735 | for (position = Index + 4; Index < position; Index++) { |
Osamu Nakamura |
0:a40b9a259b52 | 6736 | charCode = source.charCodeAt(Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6737 | // A valid sequence comprises four hexdigits (case- |
Osamu Nakamura |
0:a40b9a259b52 | 6738 | // insensitive) that form a single hexadecimal value. |
Osamu Nakamura |
0:a40b9a259b52 | 6739 | if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6740 | // Invalid Unicode escape sequence. |
Osamu Nakamura |
0:a40b9a259b52 | 6741 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6742 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6743 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6744 | // Revive the escaped character. |
Osamu Nakamura |
0:a40b9a259b52 | 6745 | value += fromCharCode("0x" + source.slice(begin, Index)); |
Osamu Nakamura |
0:a40b9a259b52 | 6746 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6747 | default: |
Osamu Nakamura |
0:a40b9a259b52 | 6748 | // Invalid escape sequence. |
Osamu Nakamura |
0:a40b9a259b52 | 6749 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6750 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6751 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6752 | if (charCode == 34) { |
Osamu Nakamura |
0:a40b9a259b52 | 6753 | // An unescaped double-quote character marks the end of the |
Osamu Nakamura |
0:a40b9a259b52 | 6754 | // string. |
Osamu Nakamura |
0:a40b9a259b52 | 6755 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6756 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6757 | charCode = source.charCodeAt(Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6758 | begin = Index; |
Osamu Nakamura |
0:a40b9a259b52 | 6759 | // Optimize for the common case where a string is valid. |
Osamu Nakamura |
0:a40b9a259b52 | 6760 | while (charCode >= 32 && charCode != 92 && charCode != 34) { |
Osamu Nakamura |
0:a40b9a259b52 | 6761 | charCode = source.charCodeAt(++Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6762 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6763 | // Append the string as-is. |
Osamu Nakamura |
0:a40b9a259b52 | 6764 | value += source.slice(begin, Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6765 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6766 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6767 | if (source.charCodeAt(Index) == 34) { |
Osamu Nakamura |
0:a40b9a259b52 | 6768 | // Advance to the next character and return the revived string. |
Osamu Nakamura |
0:a40b9a259b52 | 6769 | Index++; |
Osamu Nakamura |
0:a40b9a259b52 | 6770 | return value; |
Osamu Nakamura |
0:a40b9a259b52 | 6771 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6772 | // Unterminated string. |
Osamu Nakamura |
0:a40b9a259b52 | 6773 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6774 | default: |
Osamu Nakamura |
0:a40b9a259b52 | 6775 | // Parse numbers and literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6776 | begin = Index; |
Osamu Nakamura |
0:a40b9a259b52 | 6777 | // Advance past the negative sign, if one is specified. |
Osamu Nakamura |
0:a40b9a259b52 | 6778 | if (charCode == 45) { |
Osamu Nakamura |
0:a40b9a259b52 | 6779 | isSigned = true; |
Osamu Nakamura |
0:a40b9a259b52 | 6780 | charCode = source.charCodeAt(++Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6781 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6782 | // Parse an integer or floating-point value. |
Osamu Nakamura |
0:a40b9a259b52 | 6783 | if (charCode >= 48 && charCode <= 57) { |
Osamu Nakamura |
0:a40b9a259b52 | 6784 | // Leading zeroes are interpreted as octal literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6785 | if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6786 | // Illegal octal literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6787 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6788 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6789 | isSigned = false; |
Osamu Nakamura |
0:a40b9a259b52 | 6790 | // Parse the integer component. |
Osamu Nakamura |
0:a40b9a259b52 | 6791 | for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); |
Osamu Nakamura |
0:a40b9a259b52 | 6792 | // Floats cannot contain a leading decimal point; however, this |
Osamu Nakamura |
0:a40b9a259b52 | 6793 | // case is already accounted for by the parser. |
Osamu Nakamura |
0:a40b9a259b52 | 6794 | if (source.charCodeAt(Index) == 46) { |
Osamu Nakamura |
0:a40b9a259b52 | 6795 | position = ++Index; |
Osamu Nakamura |
0:a40b9a259b52 | 6796 | // Parse the decimal component. |
Osamu Nakamura |
0:a40b9a259b52 | 6797 | for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); |
Osamu Nakamura |
0:a40b9a259b52 | 6798 | if (position == Index) { |
Osamu Nakamura |
0:a40b9a259b52 | 6799 | // Illegal trailing decimal. |
Osamu Nakamura |
0:a40b9a259b52 | 6800 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6801 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6802 | Index = position; |
Osamu Nakamura |
0:a40b9a259b52 | 6803 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6804 | // Parse exponents. The `e` denoting the exponent is |
Osamu Nakamura |
0:a40b9a259b52 | 6805 | // case-insensitive. |
Osamu Nakamura |
0:a40b9a259b52 | 6806 | charCode = source.charCodeAt(Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6807 | if (charCode == 101 || charCode == 69) { |
Osamu Nakamura |
0:a40b9a259b52 | 6808 | charCode = source.charCodeAt(++Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6809 | // Skip past the sign following the exponent, if one is |
Osamu Nakamura |
0:a40b9a259b52 | 6810 | // specified. |
Osamu Nakamura |
0:a40b9a259b52 | 6811 | if (charCode == 43 || charCode == 45) { |
Osamu Nakamura |
0:a40b9a259b52 | 6812 | Index++; |
Osamu Nakamura |
0:a40b9a259b52 | 6813 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6814 | // Parse the exponential component. |
Osamu Nakamura |
0:a40b9a259b52 | 6815 | for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); |
Osamu Nakamura |
0:a40b9a259b52 | 6816 | if (position == Index) { |
Osamu Nakamura |
0:a40b9a259b52 | 6817 | // Illegal empty exponent. |
Osamu Nakamura |
0:a40b9a259b52 | 6818 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6819 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6820 | Index = position; |
Osamu Nakamura |
0:a40b9a259b52 | 6821 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6822 | // Coerce the parsed value to a JavaScript number. |
Osamu Nakamura |
0:a40b9a259b52 | 6823 | return +source.slice(begin, Index); |
Osamu Nakamura |
0:a40b9a259b52 | 6824 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6825 | // A negative sign may only precede numbers. |
Osamu Nakamura |
0:a40b9a259b52 | 6826 | if (isSigned) { |
Osamu Nakamura |
0:a40b9a259b52 | 6827 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6828 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6829 | // `true`, `false`, and `null` literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6830 | if (source.slice(Index, Index + 4) == "true") { |
Osamu Nakamura |
0:a40b9a259b52 | 6831 | Index += 4; |
Osamu Nakamura |
0:a40b9a259b52 | 6832 | return true; |
Osamu Nakamura |
0:a40b9a259b52 | 6833 | } else if (source.slice(Index, Index + 5) == "false") { |
Osamu Nakamura |
0:a40b9a259b52 | 6834 | Index += 5; |
Osamu Nakamura |
0:a40b9a259b52 | 6835 | return false; |
Osamu Nakamura |
0:a40b9a259b52 | 6836 | } else if (source.slice(Index, Index + 4) == "null") { |
Osamu Nakamura |
0:a40b9a259b52 | 6837 | Index += 4; |
Osamu Nakamura |
0:a40b9a259b52 | 6838 | return null; |
Osamu Nakamura |
0:a40b9a259b52 | 6839 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6840 | // Unrecognized token. |
Osamu Nakamura |
0:a40b9a259b52 | 6841 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6842 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6843 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6844 | // Return the sentinel `$` character if the parser has reached the end |
Osamu Nakamura |
0:a40b9a259b52 | 6845 | // of the source string. |
Osamu Nakamura |
0:a40b9a259b52 | 6846 | return "$"; |
Osamu Nakamura |
0:a40b9a259b52 | 6847 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6848 | |
Osamu Nakamura |
0:a40b9a259b52 | 6849 | // Internal: Parses a JSON `value` token. |
Osamu Nakamura |
0:a40b9a259b52 | 6850 | var get = function (value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6851 | var results, hasMembers; |
Osamu Nakamura |
0:a40b9a259b52 | 6852 | if (value == "$") { |
Osamu Nakamura |
0:a40b9a259b52 | 6853 | // Unexpected end of input. |
Osamu Nakamura |
0:a40b9a259b52 | 6854 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6855 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6856 | if (typeof value == "string") { |
Osamu Nakamura |
0:a40b9a259b52 | 6857 | if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { |
Osamu Nakamura |
0:a40b9a259b52 | 6858 | // Remove the sentinel `@` character. |
Osamu Nakamura |
0:a40b9a259b52 | 6859 | return value.slice(1); |
Osamu Nakamura |
0:a40b9a259b52 | 6860 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6861 | // Parse object and array literals. |
Osamu Nakamura |
0:a40b9a259b52 | 6862 | if (value == "[") { |
Osamu Nakamura |
0:a40b9a259b52 | 6863 | // Parses a JSON array, returning a new JavaScript array. |
Osamu Nakamura |
0:a40b9a259b52 | 6864 | results = []; |
Osamu Nakamura |
0:a40b9a259b52 | 6865 | for (;; hasMembers || (hasMembers = true)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6866 | value = lex(); |
Osamu Nakamura |
0:a40b9a259b52 | 6867 | // A closing square bracket marks the end of the array literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6868 | if (value == "]") { |
Osamu Nakamura |
0:a40b9a259b52 | 6869 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6870 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6871 | // If the array literal contains elements, the current token |
Osamu Nakamura |
0:a40b9a259b52 | 6872 | // should be a comma separating the previous element from the |
Osamu Nakamura |
0:a40b9a259b52 | 6873 | // next. |
Osamu Nakamura |
0:a40b9a259b52 | 6874 | if (hasMembers) { |
Osamu Nakamura |
0:a40b9a259b52 | 6875 | if (value == ",") { |
Osamu Nakamura |
0:a40b9a259b52 | 6876 | value = lex(); |
Osamu Nakamura |
0:a40b9a259b52 | 6877 | if (value == "]") { |
Osamu Nakamura |
0:a40b9a259b52 | 6878 | // Unexpected trailing `,` in array literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6879 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6880 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6881 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6882 | // A `,` must separate each array element. |
Osamu Nakamura |
0:a40b9a259b52 | 6883 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6884 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6885 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6886 | // Elisions and leading commas are not permitted. |
Osamu Nakamura |
0:a40b9a259b52 | 6887 | if (value == ",") { |
Osamu Nakamura |
0:a40b9a259b52 | 6888 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6889 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6890 | results.push(get(value)); |
Osamu Nakamura |
0:a40b9a259b52 | 6891 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6892 | return results; |
Osamu Nakamura |
0:a40b9a259b52 | 6893 | } else if (value == "{") { |
Osamu Nakamura |
0:a40b9a259b52 | 6894 | // Parses a JSON object, returning a new JavaScript object. |
Osamu Nakamura |
0:a40b9a259b52 | 6895 | results = {}; |
Osamu Nakamura |
0:a40b9a259b52 | 6896 | for (;; hasMembers || (hasMembers = true)) { |
Osamu Nakamura |
0:a40b9a259b52 | 6897 | value = lex(); |
Osamu Nakamura |
0:a40b9a259b52 | 6898 | // A closing curly brace marks the end of the object literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6899 | if (value == "}") { |
Osamu Nakamura |
0:a40b9a259b52 | 6900 | break; |
Osamu Nakamura |
0:a40b9a259b52 | 6901 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6902 | // If the object literal contains members, the current token |
Osamu Nakamura |
0:a40b9a259b52 | 6903 | // should be a comma separator. |
Osamu Nakamura |
0:a40b9a259b52 | 6904 | if (hasMembers) { |
Osamu Nakamura |
0:a40b9a259b52 | 6905 | if (value == ",") { |
Osamu Nakamura |
0:a40b9a259b52 | 6906 | value = lex(); |
Osamu Nakamura |
0:a40b9a259b52 | 6907 | if (value == "}") { |
Osamu Nakamura |
0:a40b9a259b52 | 6908 | // Unexpected trailing `,` in object literal. |
Osamu Nakamura |
0:a40b9a259b52 | 6909 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6910 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6911 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6912 | // A `,` must separate each object member. |
Osamu Nakamura |
0:a40b9a259b52 | 6913 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6914 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6915 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6916 | // Leading commas are not permitted, object property names must be |
Osamu Nakamura |
0:a40b9a259b52 | 6917 | // double-quoted strings, and a `:` must separate each property |
Osamu Nakamura |
0:a40b9a259b52 | 6918 | // name and value. |
Osamu Nakamura |
0:a40b9a259b52 | 6919 | if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { |
Osamu Nakamura |
0:a40b9a259b52 | 6920 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6921 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6922 | results[value.slice(1)] = get(lex()); |
Osamu Nakamura |
0:a40b9a259b52 | 6923 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6924 | return results; |
Osamu Nakamura |
0:a40b9a259b52 | 6925 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6926 | // Unexpected token encountered. |
Osamu Nakamura |
0:a40b9a259b52 | 6927 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6928 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6929 | return value; |
Osamu Nakamura |
0:a40b9a259b52 | 6930 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6931 | |
Osamu Nakamura |
0:a40b9a259b52 | 6932 | // Internal: Updates a traversed object member. |
Osamu Nakamura |
0:a40b9a259b52 | 6933 | var update = function(source, property, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6934 | var element = walk(source, property, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 6935 | if (element === undef) { |
Osamu Nakamura |
0:a40b9a259b52 | 6936 | delete source[property]; |
Osamu Nakamura |
0:a40b9a259b52 | 6937 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6938 | source[property] = element; |
Osamu Nakamura |
0:a40b9a259b52 | 6939 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6940 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6941 | |
Osamu Nakamura |
0:a40b9a259b52 | 6942 | // Internal: Recursively traverses a parsed JSON object, invoking the |
Osamu Nakamura |
0:a40b9a259b52 | 6943 | // `callback` function for each value. This is an implementation of the |
Osamu Nakamura |
0:a40b9a259b52 | 6944 | // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. |
Osamu Nakamura |
0:a40b9a259b52 | 6945 | var walk = function (source, property, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6946 | var value = source[property], length; |
Osamu Nakamura |
0:a40b9a259b52 | 6947 | if (typeof value == "object" && value) { |
Osamu Nakamura |
0:a40b9a259b52 | 6948 | // `forEach` can't be used to traverse an array in Opera <= 8.54 |
Osamu Nakamura |
0:a40b9a259b52 | 6949 | // because its `Object#hasOwnProperty` implementation returns `false` |
Osamu Nakamura |
0:a40b9a259b52 | 6950 | // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). |
Osamu Nakamura |
0:a40b9a259b52 | 6951 | if (getClass.call(value) == arrayClass) { |
Osamu Nakamura |
0:a40b9a259b52 | 6952 | for (length = value.length; length--;) { |
Osamu Nakamura |
0:a40b9a259b52 | 6953 | update(value, length, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 6954 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6955 | } else { |
Osamu Nakamura |
0:a40b9a259b52 | 6956 | forEach(value, function (property) { |
Osamu Nakamura |
0:a40b9a259b52 | 6957 | update(value, property, callback); |
Osamu Nakamura |
0:a40b9a259b52 | 6958 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 6959 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6960 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6961 | return callback.call(source, property, value); |
Osamu Nakamura |
0:a40b9a259b52 | 6962 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6963 | |
Osamu Nakamura |
0:a40b9a259b52 | 6964 | // Public: `JSON.parse`. See ES 5.1 section 15.12.2. |
Osamu Nakamura |
0:a40b9a259b52 | 6965 | JSON3.parse = function (source, callback) { |
Osamu Nakamura |
0:a40b9a259b52 | 6966 | var result, value; |
Osamu Nakamura |
0:a40b9a259b52 | 6967 | Index = 0; |
Osamu Nakamura |
0:a40b9a259b52 | 6968 | Source = "" + source; |
Osamu Nakamura |
0:a40b9a259b52 | 6969 | result = get(lex()); |
Osamu Nakamura |
0:a40b9a259b52 | 6970 | // If a JSON string contains multiple tokens, it is invalid. |
Osamu Nakamura |
0:a40b9a259b52 | 6971 | if (lex() != "$") { |
Osamu Nakamura |
0:a40b9a259b52 | 6972 | abort(); |
Osamu Nakamura |
0:a40b9a259b52 | 6973 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6974 | // Reset the parser state. |
Osamu Nakamura |
0:a40b9a259b52 | 6975 | Index = Source = null; |
Osamu Nakamura |
0:a40b9a259b52 | 6976 | return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; |
Osamu Nakamura |
0:a40b9a259b52 | 6977 | }; |
Osamu Nakamura |
0:a40b9a259b52 | 6978 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6979 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6980 | |
Osamu Nakamura |
0:a40b9a259b52 | 6981 | // Export for asynchronous module loaders. |
Osamu Nakamura |
0:a40b9a259b52 | 6982 | if (isLoader) { |
Osamu Nakamura |
0:a40b9a259b52 | 6983 | define(function () { |
Osamu Nakamura |
0:a40b9a259b52 | 6984 | return JSON3; |
Osamu Nakamura |
0:a40b9a259b52 | 6985 | }); |
Osamu Nakamura |
0:a40b9a259b52 | 6986 | } |
Osamu Nakamura |
0:a40b9a259b52 | 6987 | }(this)); |
Osamu Nakamura |
0:a40b9a259b52 | 6988 | |
Osamu Nakamura |
0:a40b9a259b52 | 6989 | },{}],50:[function(_dereq_,module,exports){ |
Osamu Nakamura |
0:a40b9a259b52 | 6990 | module.exports = toArray |
Osamu Nakamura |
0:a40b9a259b52 | 6991 | |
Osamu Nakamura |
0:a40b9a259b52 | 6992 | function toArray(list, index) { |
Osamu Nakamura |
0:a40b9a259b52 | 6993 | var array = [] |
Osamu Nakamura |
0:a40b9a259b52 | 6994 | |
Osamu Nakamura |
0:a40b9a259b52 | 6995 | index = index || 0 |
Osamu Nakamura |
0:a40b9a259b52 | 6996 | |
Osamu Nakamura |
0:a40b9a259b52 | 6997 | for (var i = index || 0; i < list.length; i++) { |
Osamu Nakamura |
0:a40b9a259b52 | 6998 | array[i - index] = list[i] |
Osamu Nakamura |
0:a40b9a259b52 | 6999 | } |
Osamu Nakamura |
0:a40b9a259b52 | 7000 | |
Osamu Nakamura |
0:a40b9a259b52 | 7001 | return array |
Osamu Nakamura |
0:a40b9a259b52 | 7002 | } |
Osamu Nakamura |
0:a40b9a259b52 | 7003 | |
Osamu Nakamura |
0:a40b9a259b52 | 7004 | },{}]},{},[1]) |
Osamu Nakamura |
0:a40b9a259b52 | 7005 | (1) |
Osamu Nakamura |
0:a40b9a259b52 | 7006 | }); |