aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/net
diff options
context:
space:
mode:
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/net')
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/all-wcprops377
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/entries2142
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browsertestchannel.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloaderhelper.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channeldebug.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.gif.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test_response.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/errorcode.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/eventtype.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/httpstatus.js.svn-base9
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test_response.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_different_base_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame2.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame3.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg1.gif.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg2.gif.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg3.gif.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockiframeio.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/tmpnetwork.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/wrapperxmlhttpfactory.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhriopool.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlitepool.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrmanager.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttp.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttpfactory.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel.js.svn-base2470
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel_test.html.svn-base1200
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browsertestchannel.js.svn-base541
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader.js.svn-base172
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader_test.html.svn-base232
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloaderhelper.js.svn-base127
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channeldebug.js.svn-base287
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest.js.svn-base1139
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest_test.html.svn-base187
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies.js.svn-base402
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies_test.html.svn-base255
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc.js.svn-base849
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.gif.svn-base0
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.html.svn-base120
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test_response.html.svn-base59
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/errorcode.js.svn-base130
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/eventtype.js.svn-base37
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader.js.svn-base741
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader_test.html.svn-base372
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/httpstatus.js.svn-base109
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test.html.svn-base147
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test_response.html.svn-base17
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio.js.svn-base1300
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.data.svn-base2
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.html.svn-base44
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_test.html.svn-base374
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor.js.svn-base200
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test.html.svn-base113
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame.html.svn-base12
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame2.html.svn-base12
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame3.html.svn-base12
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader.js.svn-base237
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_test.html.svn-base200
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg1.gif.svn-basebin453 -> 0 bytes
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg2.gif.svn-basebin460 -> 0 bytes
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg3.gif.svn-basebin13446 -> 0 bytes
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress.js.svn-base510
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress_test.html.svn-base227
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader.js.svn-base362
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader_test.html.svn-base134
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp.js.svn-base341
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp_test.html.svn-base327
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockiframeio.js.svn-base318
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite.js.svn-base34
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite_test.html.svn-base109
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor.js.svn-base116
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor_test.html.svn-base172
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester.js.svn-base383
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester_test.html.svn-base227
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/tmpnetwork.js.svn-base153
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket.js.svn-base504
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket_test.html.svn-base367
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/wrapperxmlhttpfactory.js.svn-base68
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio.js.svn-base1082
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio_test.html.svn-base639
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhriopool.js.svn-base87
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite.js.svn-base119
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite_test.html.svn-base157
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlitepool.js.svn-base37
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrmanager.js.svn-base757
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttp.js.svn-base217
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttpfactory.js.svn-base64
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/browserchannel.js330
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/browserchannel_test.html163
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/browsertestchannel.js45
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/bulkloader.js11
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/bulkloader_test.html1
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/channeldebug.js9
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/channelrequest.js188
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/channelrequest_test.html197
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/cookies.js39
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/cookies_test.html33
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/crossdomainrpc_test.css7
-rwxr-xr-xcontexts/data/lib/closure-library/closure/goog/net/httpstatus.js4
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/imageloader.js175
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/imageloader_test.html402
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/ipaddress.js1
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/jsloader.js61
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/jsonp.js2
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/all-wcprops29
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/entries164
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test1.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test2.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test3.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test4.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test1.js.svn-base23
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test2.js.svn-base23
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test3.js.svn-base23
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test4.js.svn-base23
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xhrio.js54
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xhrio_test.html53
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xhriopool.js17
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xhrmanager.js73
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xhrmanager_test.html123
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xmlhttp.js15
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/all-wcprops77
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/entries439
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannelrole.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/frameelementmethodtransport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframepollingtransport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframerelaytransport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport_test.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nixtransport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/relay.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/transport.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/xpc.js.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel.js.svn-base673
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel_test.html.svn-base420
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannelrole.js.svn-base30
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/frameelementmethodtransport.js.svn-base250
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframepollingtransport.js.svn-base829
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframerelaytransport.js.svn-base388
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport.js.svn-base287
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport_test.html.svn-base165
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nixtransport.js.svn-base473
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/relay.js.svn-base72
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/transport.js.svn-base105
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/xpc.js.svn-base238
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel.js276
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel_test.html828
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/frameelementmethodtransport.js16
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport.js156
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport_test.html295
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/iframerelaytransport.js21
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport.js414
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport_test.html175
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/nixtransport.js210
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/all-wcprops11
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/entries62
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/prop-base/inner_peer.html.svn-base5
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/text-base/inner_peer.html.svn-base106
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/access_checker.html29
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/inner_peer.html56
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/transport.js4
-rw-r--r--contexts/data/lib/closure-library/closure/goog/net/xpc/xpc.js68
201 files changed, 3614 insertions, 28370 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/net/.svn/all-wcprops
deleted file mode 100644
index 1c7eccb..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/all-wcprops
+++ /dev/null
@@ -1,377 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 41
-/svn/!svn/ver/1477/trunk/closure/goog/net
-END
-ipaddress_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 61
-/svn/!svn/ver/1274/trunk/closure/goog/net/ipaddress_test.html
-END
-iframeio_different_base_test.data
-K 25
-svn:wc:ra_dav:version-url
-V 74
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeio_different_base_test.data
-END
-networktester_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 64
-/svn/!svn/ver/850/trunk/closure/goog/net/networktester_test.html
-END
-imageloader.js
-K 25
-svn:wc:ra_dav:version-url
-V 56
-/svn/!svn/ver/1472/trunk/closure/goog/net/imageloader.js
-END
-tmpnetwork.js
-K 25
-svn:wc:ra_dav:version-url
-V 54
-/svn/!svn/ver/850/trunk/closure/goog/net/tmpnetwork.js
-END
-bulkloader_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 61
-/svn/!svn/ver/850/trunk/closure/goog/net/bulkloader_test.html
-END
-browsertestchannel.js
-K 25
-svn:wc:ra_dav:version-url
-V 63
-/svn/!svn/ver/1388/trunk/closure/goog/net/browsertestchannel.js
-END
-ipaddress.js
-K 25
-svn:wc:ra_dav:version-url
-V 54
-/svn/!svn/ver/1302/trunk/closure/goog/net/ipaddress.js
-END
-xhrlite.js
-K 25
-svn:wc:ra_dav:version-url
-V 52
-/svn/!svn/ver/1336/trunk/closure/goog/net/xhrlite.js
-END
-networktester.js
-K 25
-svn:wc:ra_dav:version-url
-V 57
-/svn/!svn/ver/850/trunk/closure/goog/net/networktester.js
-END
-mockxhrlite_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 62
-/svn/!svn/ver/850/trunk/closure/goog/net/mockxhrlite_test.html
-END
-channelrequest.js
-K 25
-svn:wc:ra_dav:version-url
-V 59
-/svn/!svn/ver/1397/trunk/closure/goog/net/channelrequest.js
-END
-iframeio_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 60
-/svn/!svn/ver/1153/trunk/closure/goog/net/iframeio_test.html
-END
-httpstatus.js
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/svn/!svn/ver/1439/trunk/closure/goog/net/httpstatus.js
-END
-bulkloader.js
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/svn/!svn/ver/1302/trunk/closure/goog/net/bulkloader.js
-END
-filedownloader_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 66
-/svn/!svn/ver/1434/trunk/closure/goog/net/filedownloader_test.html
-END
-xmlhttpfactory.js
-K 25
-svn:wc:ra_dav:version-url
-V 58
-/svn/!svn/ver/850/trunk/closure/goog/net/xmlhttpfactory.js
-END
-wrapperxmlhttpfactory.js
-K 25
-svn:wc:ra_dav:version-url
-V 66
-/svn/!svn/ver/1302/trunk/closure/goog/net/wrapperxmlhttpfactory.js
-END
-iframe_xhr_test_response.html
-K 25
-svn:wc:ra_dav:version-url
-V 70
-/svn/!svn/ver/850/trunk/closure/goog/net/iframe_xhr_test_response.html
-END
-xhrio.js
-K 25
-svn:wc:ra_dav:version-url
-V 50
-/svn/!svn/ver/1453/trunk/closure/goog/net/xhrio.js
-END
-jsonp.js
-K 25
-svn:wc:ra_dav:version-url
-V 50
-/svn/!svn/ver/1452/trunk/closure/goog/net/jsonp.js
-END
-crossdomainrpc_test_response.html
-K 25
-svn:wc:ra_dav:version-url
-V 74
-/svn/!svn/ver/850/trunk/closure/goog/net/crossdomainrpc_test_response.html
-END
-filedownloader.js
-K 25
-svn:wc:ra_dav:version-url
-V 59
-/svn/!svn/ver/1302/trunk/closure/goog/net/filedownloader.js
-END
-iframeloadmonitor_test_frame3.html
-K 25
-svn:wc:ra_dav:version-url
-V 75
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeloadmonitor_test_frame3.html
-END
-imageloader_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 62
-/svn/!svn/ver/850/trunk/closure/goog/net/imageloader_test.html
-END
-xmlhttp.js
-K 25
-svn:wc:ra_dav:version-url
-V 52
-/svn/!svn/ver/1472/trunk/closure/goog/net/xmlhttp.js
-END
-browserchannel_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 66
-/svn/!svn/ver/1243/trunk/closure/goog/net/browserchannel_test.html
-END
-jsloader.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/1452/trunk/closure/goog/net/jsloader.js
-END
-mockiframeio.js
-K 25
-svn:wc:ra_dav:version-url
-V 56
-/svn/!svn/ver/850/trunk/closure/goog/net/mockiframeio.js
-END
-xhrlite_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 59
-/svn/!svn/ver/1472/trunk/closure/goog/net/xhrlite_test.html
-END
-channelrequest_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 66
-/svn/!svn/ver/1383/trunk/closure/goog/net/channelrequest_test.html
-END
-xhrlitepool.js
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/svn/!svn/ver/850/trunk/closure/goog/net/xhrlitepool.js
-END
-iframeloadmonitor.js
-K 25
-svn:wc:ra_dav:version-url
-V 62
-/svn/!svn/ver/1302/trunk/closure/goog/net/iframeloadmonitor.js
-END
-iframe_xhr_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 62
-/svn/!svn/ver/1395/trunk/closure/goog/net/iframe_xhr_test.html
-END
-iframeloadmonitor_test_frame.html
-K 25
-svn:wc:ra_dav:version-url
-V 74
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeloadmonitor_test_frame.html
-END
-browserchannel.js
-K 25
-svn:wc:ra_dav:version-url
-V 59
-/svn/!svn/ver/1399/trunk/closure/goog/net/browserchannel.js
-END
-crossdomainrpc_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/svn/!svn/ver/850/trunk/closure/goog/net/crossdomainrpc_test.html
-END
-multiiframeloadmonitor_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 73
-/svn/!svn/ver/850/trunk/closure/goog/net/multiiframeloadmonitor_test.html
-END
-websocket_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 60
-/svn/!svn/ver/973/trunk/closure/goog/net/websocket_test.html
-END
-crossdomainrpc_test.gif
-K 25
-svn:wc:ra_dav:version-url
-V 64
-/svn/!svn/ver/850/trunk/closure/goog/net/crossdomainrpc_test.gif
-END
-imageloader_testimg1.gif
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/svn/!svn/ver/850/trunk/closure/goog/net/imageloader_testimg1.gif
-END
-channeldebug.js
-K 25
-svn:wc:ra_dav:version-url
-V 57
-/svn/!svn/ver/1248/trunk/closure/goog/net/channeldebug.js
-END
-imageloader_testimg2.gif
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/svn/!svn/ver/850/trunk/closure/goog/net/imageloader_testimg2.gif
-END
-xhrio_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 57
-/svn/!svn/ver/1472/trunk/closure/goog/net/xhrio_test.html
-END
-jsonp_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 57
-/svn/!svn/ver/1452/trunk/closure/goog/net/jsonp_test.html
-END
-imageloader_testimg3.gif
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/svn/!svn/ver/850/trunk/closure/goog/net/imageloader_testimg3.gif
-END
-eventtype.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/850/trunk/closure/goog/net/eventtype.js
-END
-xhriopool.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/850/trunk/closure/goog/net/xhriopool.js
-END
-cookies_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 58
-/svn/!svn/ver/850/trunk/closure/goog/net/cookies_test.html
-END
-bulkloaderhelper.js
-K 25
-svn:wc:ra_dav:version-url
-V 61
-/svn/!svn/ver/1302/trunk/closure/goog/net/bulkloaderhelper.js
-END
-errorcode.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/850/trunk/closure/goog/net/errorcode.js
-END
-crossdomainrpc.js
-K 25
-svn:wc:ra_dav:version-url
-V 58
-/svn/!svn/ver/850/trunk/closure/goog/net/crossdomainrpc.js
-END
-multiiframeloadmonitor.js
-K 25
-svn:wc:ra_dav:version-url
-V 66
-/svn/!svn/ver/850/trunk/closure/goog/net/multiiframeloadmonitor.js
-END
-websocket.js
-K 25
-svn:wc:ra_dav:version-url
-V 54
-/svn/!svn/ver/1302/trunk/closure/goog/net/websocket.js
-END
-mockxhrlite.js
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/svn/!svn/ver/850/trunk/closure/goog/net/mockxhrlite.js
-END
-jsloader_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 60
-/svn/!svn/ver/1452/trunk/closure/goog/net/jsloader_test.html
-END
-iframeio.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/1395/trunk/closure/goog/net/iframeio.js
-END
-xhrmanager.js
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/svn/!svn/ver/1302/trunk/closure/goog/net/xhrmanager.js
-END
-cookies.js
-K 25
-svn:wc:ra_dav:version-url
-V 52
-/svn/!svn/ver/1472/trunk/closure/goog/net/cookies.js
-END
-iframeloadmonitor_test_frame2.html
-K 25
-svn:wc:ra_dav:version-url
-V 75
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeloadmonitor_test_frame2.html
-END
-iframeio_different_base_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 74
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeio_different_base_test.html
-END
-iframeloadmonitor_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 68
-/svn/!svn/ver/850/trunk/closure/goog/net/iframeloadmonitor_test.html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/entries b/contexts/data/lib/closure-library/closure/goog/net/.svn/entries
deleted file mode 100644
index 0ab3b50..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/entries
+++ /dev/null
@@ -1,2142 +0,0 @@
-10
-
-dir
-1494
-http://closure-library.googlecode.com/svn/trunk/closure/goog/net
-http://closure-library.googlecode.com/svn
-
-
-
-2011-12-14T19:06:32.000000Z
-1477
-dpb@google.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0b95b8e8-c90f-11de-9d4f-f947ee5921c8
-
-networktester_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.456355Z
-4ecefadd766d973571160a3c29c2388e
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6339
-
-tmpnetwork.js
-file
-
-
-
-
-2011-12-23T22:42:30.456355Z
-542171368a78a90f6f9062ff7784fa68
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4437
-
-bulkloader_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.456355Z
-8a3b0fb36fc0c41e25a9c43510aeda56
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6818
-
-xhrlite.js
-file
-
-
-
-
-2011-12-23T22:42:30.457355Z
-4760395c844d0649641c2808c3517c1a
-2011-10-13T12:17:51.000000Z
-1336
-johnmaguire@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4025
-
-channelrequest.js
-file
-
-
-
-
-2011-12-23T22:42:30.457355Z
-ed8732e66369b4a2e33377bfd660a8cb
-2011-11-16T19:24:51.000000Z
-1397
-nicksantos@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-32535
-
-httpstatus.js
-file
-
-
-
-
-2011-12-23T22:42:30.457355Z
-cb2cc9f29d2c7c1421f1f1518e98e4c7
-2011-12-01T01:21:24.000000Z
-1439
-pupius@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2948
-
-wrapperxmlhttpfactory.js
-file
-
-
-
-
-2011-12-23T22:42:30.458355Z
-795053f68d1d3fbc0163841db0b1822d
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2106
-
-jsloader.js
-file
-
-
-
-
-2011-12-23T22:42:30.458355Z
-e338acf3ed58a29d4229c7c3c087aaed
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11979
-
-browserchannel_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.458355Z
-e979f20ee082710309d0f1a0d89da2cf
-2011-08-23T18:48:07.000000Z
-1243
-simonmorris@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-34344
-
-channelrequest_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.458355Z
-e9bd16c117f91c9bb6926360be6a4a2d
-2011-11-10T21:29:44.000000Z
-1383
-nicksantos@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4759
-
-xhrlitepool.js
-file
-
-
-
-
-2011-12-23T22:42:30.459355Z
-263edc15ca614d02034fd244e166b2ca
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1270
-
-iframeloadmonitor_test_frame.html
-file
-
-
-
-
-2011-12-23T22:42:30.459355Z
-f84f71085657c4d7599d457ae11285fd
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-291
-
-crossdomainrpc_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.459355Z
-c400f40c7380acf2b91db0eff69b4c9e
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3614
-
-imageloader_testimg1.gif
-file
-
-
-
-
-2011-12-23T22:42:30.459355Z
-6119f80160fe51207a3d1a834dae1521
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-453
-
-imageloader_testimg2.gif
-file
-
-
-
-
-2011-12-23T22:42:30.460355Z
-8fbb2a44c7a791c7f0c75f7a62304794
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-460
-
-imageloader_testimg3.gif
-file
-
-
-
-
-2011-12-23T22:42:30.460355Z
-9da7bb8b5861dd6201a3731dbf8a0a81
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-13446
-
-eventtype.js
-file
-
-
-
-
-2011-12-23T22:42:30.460355Z
-3f6a7fb6e31a966bc436d1473086bac0
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1044
-
-bulkloaderhelper.js
-file
-
-
-
-
-2011-12-23T22:42:30.460355Z
-8775a73d7fd8d446fc0b6b3fdc43aed4
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3086
-
-crossdomainrpc.js
-file
-
-
-
-
-2011-12-23T22:42:30.461355Z
-e435e51bdc94da0f18b059c5995f66a7
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-28252
-
-mockxhrlite.js
-file
-
-
-
-
-2011-12-23T22:42:30.461355Z
-ca57ee5fc3df8104b8355e7ef344d2ed
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1132
-
-cookies.js
-file
-
-
-
-
-2011-12-23T22:42:30.461355Z
-d987e75fc6e7e38d2ad4a79e39d09bf2
-2011-12-13T22:20:28.000000Z
-1472
-ccalabro@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11764
-
-xhrmanager.js
-file
-
-
-
-
-2011-12-23T22:42:30.462355Z
-d79ad2a0b2b2abe8e0d9da05dc0096d0
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-22053
-
-testdata
-dir
-
-iframeloadmonitor_test_frame2.html
-file
-
-
-
-
-2011-12-23T22:42:30.462355Z
-3eba82bc5a6ccd7f5e87d1bdc3bb1c53
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-291
-
-iframeloadmonitor_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.462355Z
-d55b1ca2bc1046b3ed13bbb2ac108aa9
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3527
-
-iframeio_different_base_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.462355Z
-927b7f4b542f75ca474528aa0de969d6
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1279
-
-ipaddress_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.463355Z
-d731702f1635a28fccb4e0c6acc9014c
-2011-09-08T20:28:27.000000Z
-1274
-stephenamar@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11044
-
-iframeio_different_base_test.data
-file
-
-
-
-
-2011-12-23T22:42:30.463355Z
-45b1968f90df42f6624e643e5a6ac9a3
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-86
-
-imageloader.js
-file
-
-
-
-
-2011-12-23T22:42:30.463355Z
-65a78d12cbcd32c8e46e0517f1ba5952
-2011-12-13T22:20:28.000000Z
-1472
-ccalabro@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7765
-
-browsertestchannel.js
-file
-
-
-
-
-2011-12-23T22:42:30.463355Z
-2960ef9da9220b04d280ab9c08ea54ba
-2011-11-14T23:15:47.000000Z
-1388
-nicksantos@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-17028
-
-ipaddress.js
-file
-
-
-
-
-2011-12-23T22:42:30.464355Z
-c4abaf630c126ffbea802cf852853e2d
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-13512
-
-xpc
-dir
-
-networktester.js
-file
-
-
-
-
-2011-12-23T22:42:30.464355Z
-17002db90240d3778a3bbc6cfdc2b03a
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-9202
-
-mockxhrlite_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.464355Z
-680360477f2de6cdf86795c25b45c9a6
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3043
-
-iframeio_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.465355Z
-8e09e00c7973e6004313a2a6a9126c3e
-2011-07-25T16:50:22.000000Z
-1153
-lascap@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-10090
-
-bulkloader.js
-file
-
-
-
-
-2011-12-23T22:42:30.465355Z
-04d889a068ab9e8d7b2ceffbbda4f7b3
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4640
-
-filedownloader_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.466355Z
-75bed46174a9b474fb370218b73e97a7
-2011-11-30T22:16:21.000000Z
-1434
-chrishenry@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-12389
-
-xmlhttpfactory.js
-file
-
-
-
-
-2011-12-23T22:42:30.466355Z
-9fcf54b3e17afe0b1c392e37b329f130
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1842
-
-jsonp.js
-file
-
-
-
-
-2011-12-23T22:42:30.467355Z
-5cea1d3600a09558415feab3802549a1
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11742
-
-xhrio.js
-file
-
-
-
-
-2011-12-23T22:42:30.466355Z
-7bd0dbd7d39211f7dd6d1d18a83dbcbd
-2011-12-07T18:41:01.000000Z
-1453
-pupius@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-33881
-
-iframe_xhr_test_response.html
-file
-
-
-
-
-2011-12-23T22:42:30.466355Z
-14aee16432a233f82344ea9740fe16ea
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-563
-
-crossdomainrpc_test_response.html
-file
-
-
-
-
-2011-12-23T22:42:30.467355Z
-563f2a5d32dca8e707c25df1f9501022
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1653
-
-filedownloader.js
-file
-
-
-
-
-2011-12-23T22:42:30.467355Z
-2537e091e219598f22b5503a7982222b
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-24465
-
-iframeloadmonitor_test_frame3.html
-file
-
-
-
-
-2011-12-23T22:42:30.467355Z
-c5514b0bcd134b1c241da3e66f813810
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-291
-
-xmlhttp.js
-file
-
-
-
-
-2011-12-23T22:42:30.468355Z
-e2011c59dc81f5e1ce06586ea64aad79
-2011-12-13T22:20:28.000000Z
-1472
-ccalabro@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6393
-
-imageloader_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.468355Z
-1d7c8649ed23babc8fcc9445505198ea
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6070
-
-mockiframeio.js
-file
-
-
-
-
-2011-12-23T22:42:30.468355Z
-db53b4b779ecd5c69c990ec1b43421a7
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-8164
-
-xhrlite_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.469355Z
-5b9f3be7ce15a166e6cc2a37e7a86356
-2011-12-13T22:20:28.000000Z
-1472
-ccalabro@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3536
-
-iframe_xhr_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.469355Z
-f983379fa75cf6d8ff35d1abecd6cc23
-2011-11-16T01:24:53.000000Z
-1395
-pupius@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4904
-
-iframeloadmonitor.js
-file
-
-
-
-
-2011-12-23T22:42:30.469355Z
-d7e3b4e11030fb98977b2fb8ddf9bb29
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6257
-
-browserchannel.js
-file
-
-
-
-
-2011-12-23T22:42:30.469355Z
-44969868e3ac1fe2739fe7f3672d8fc7
-2011-11-16T20:03:43.000000Z
-1399
-nicksantos@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-73966
-
-websocket_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.470355Z
-f6af5c79039cdab3b4d15350ffcdcb44
-2011-05-26T22:24:22.000000Z
-973
-jdeyerle@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11142
-
-multiiframeloadmonitor_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.470355Z
-bbf798350c87097f6cb8f627ebbe2cb2
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5666
-
-crossdomainrpc_test.gif
-file
-
-
-
-
-2011-12-23T22:42:30.470355Z
-d41d8cd98f00b204e9800998ecf8427e
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0
-
-channeldebug.js
-file
-
-
-
-
-2011-12-23T22:42:30.470355Z
-135fa037c095ab8bb1d8a3a714c5c127
-2011-08-25T15:58:34.000000Z
-1248
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7941
-
-jsonp_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.471355Z
-c68f8cb1703093bf09d737cab9d7b5d3
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-9876
-
-xhrio_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.471355Z
-491d1d3dffa7ab2df1b87496cc90f676
-2011-12-13T22:20:28.000000Z
-1472
-ccalabro@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-16693
-
-cookies_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.471355Z
-5c14dff27acfd7018aad825dfced6ee4
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6881
-
-xhriopool.js
-file
-
-
-
-
-2011-12-23T22:42:30.471355Z
-4c9ed5b346ea732e2594b86854fbac9a
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2735
-
-errorcode.js
-file
-
-
-
-
-2011-12-23T22:42:30.472355Z
-121b2f4c92930d792f997276d8cd5487
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3287
-
-websocket.js
-file
-
-
-
-
-2011-12-23T22:42:30.472355Z
-2845b3f2dfb94bb51689fdc4ad79b99c
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-15360
-
-multiiframeloadmonitor.js
-file
-
-
-
-
-2011-12-23T22:42:30.472355Z
-9b8d3191cd9bbc2c1a419c1c7c552654
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4093
-
-jsloader_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.473355Z
-61f32714d8b3735fc1c71fdeca6c8827
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3658
-
-iframeio.js
-file
-
-
-
-
-2011-12-23T22:42:30.473355Z
-b6fbb54a967bc5224eaca896068db1f7
-2011-11-16T01:24:53.000000Z
-1395
-pupius@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-39041
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browserchannel_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browsertestchannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browsertestchannel.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/browsertestchannel.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloader_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloaderhelper.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloaderhelper.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/bulkloaderhelper.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channeldebug.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channeldebug.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channeldebug.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/channelrequest_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/cookies_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.gif.svn-base
deleted file mode 100644
index 1c48e39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.gif.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-image/gif
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test_response.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test_response.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/crossdomainrpc_test_response.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/errorcode.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/errorcode.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/errorcode.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/eventtype.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/eventtype.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/eventtype.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/filedownloader_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/httpstatus.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/httpstatus.js.svn-base
deleted file mode 100644
index 931becf..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/httpstatus.js.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-K 14
-svn:executable
-V 1
-*
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test_response.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test_response.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframe_xhr_test_response.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_different_base_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_different_base_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_different_base_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeio_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame2.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame2.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame2.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame3.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame3.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/iframeloadmonitor_test_frame3.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg1.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg1.gif.svn-base
deleted file mode 100644
index 1c48e39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg1.gif.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-image/gif
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg2.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg2.gif.svn-base
deleted file mode 100644
index 1c48e39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg2.gif.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-image/gif
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg3.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg3.gif.svn-base
deleted file mode 100644
index 1c48e39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/imageloader_testimg3.gif.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-image/gif
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/ipaddress_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsloader_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/jsonp_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockiframeio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockiframeio.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockiframeio.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/mockxhrlite_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/multiiframeloadmonitor_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/networktester_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/tmpnetwork.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/tmpnetwork.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/tmpnetwork.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/websocket_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/wrapperxmlhttpfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/wrapperxmlhttpfactory.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/wrapperxmlhttpfactory.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrio_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhriopool.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhriopool.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhriopool.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlite_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlitepool.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlitepool.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrlitepool.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrmanager.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrmanager.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xhrmanager.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttp.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttp.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttp.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttpfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttpfactory.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/prop-base/xmlhttpfactory.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel.js.svn-base
deleted file mode 100644
index fbfef88..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel.js.svn-base
+++ /dev/null
@@ -1,2470 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of the BrowserChannel class. A BrowserChannel
- * simulates a bidirectional socket over HTTP. It is the basis of the
- * Gmail Chat IM connections to the server.
- *
- * See http://wiki/Main/BrowserChannel
- * This doesn't yet completely comform to the design document as we've done
- * some renaming and cleanup in the design document that hasn't yet been
- * implemented in the protocol.
- *
- * Typical usage will look like
- * var handler = [handler object];
- * var channel = new BrowserChannel(clientVersion);
- * channel.setHandler(handler);
- * channel.connect('channel/test', 'channel/bind');
- *
- * See goog.net.BrowserChannel.Handler for the handler interface.
- *
- */
-
-
-goog.provide('goog.net.BrowserChannel');
-goog.provide('goog.net.BrowserChannel.Error');
-goog.provide('goog.net.BrowserChannel.Event');
-goog.provide('goog.net.BrowserChannel.Handler');
-goog.provide('goog.net.BrowserChannel.LogSaver');
-goog.provide('goog.net.BrowserChannel.QueuedMap');
-goog.provide('goog.net.BrowserChannel.Stat');
-goog.provide('goog.net.BrowserChannel.StatEvent');
-goog.provide('goog.net.BrowserChannel.State');
-goog.provide('goog.net.BrowserChannel.TimingEvent');
-
-goog.require('goog.Uri');
-goog.require('goog.array');
-goog.require('goog.debug.Logger');
-goog.require('goog.debug.TextFormatter');
-goog.require('goog.events.Event');
-goog.require('goog.events.EventTarget');
-goog.require('goog.json');
-goog.require('goog.net.BrowserTestChannel');
-goog.require('goog.net.ChannelDebug');
-goog.require('goog.net.ChannelRequest');
-goog.require('goog.net.ChannelRequest.Error');
-goog.require('goog.net.XhrIo');
-goog.require('goog.net.tmpnetwork');
-goog.require('goog.string');
-goog.require('goog.structs');
-goog.require('goog.structs.CircularBuffer');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Encapsulates the logic for a single BrowserChannel.
- *
- * @param {string} clientVersion An application-specific version number that
- * is sent to the server when connected.
- * @constructor
- */
-goog.net.BrowserChannel = function(clientVersion) {
- /**
- * The application specific version that is passed to the server.
- * @type {string}
- * @private
- */
- this.clientVersion_ = clientVersion;
-
- /**
- * The current state of the BrowserChannel. It should be one of the
- * goog.net.BrowserChannel.State constants.
- * @type {goog.net.BrowserChannel.State}
- * @private
- */
- this.state_ = goog.net.BrowserChannel.State.INIT;
-
- /**
- * An array of queued maps that need to be sent to the server.
- * @type {Array.<goog.net.BrowserChannel.QueuedMap>}
- * @private
- */
- this.outgoingMaps_ = [];
-
- /**
- * An array of dequeued maps that we have either received a non-successful
- * response for, or no response at all, and which therefore may or may not
- * have been received by the server.
- * @type {Array.<goog.net.BrowserChannel.QueuedMap>}
- * @private
- */
- this.pendingMaps_ = [];
-
- /**
- * The channel debug used for browserchannel logging
- * @type {goog.net.ChannelDebug}
- * @private
- */
- this.channelDebug_ = new goog.net.ChannelDebug();
-};
-
-
-
-/**
- * Simple container class for a (mapId, map) pair.
- * @param {number} mapId The id for this map.
- * @param {Object|goog.structs.Map} map The map itself.
- * @constructor
- */
-goog.net.BrowserChannel.QueuedMap = function(mapId, map) {
- /**
- * The id for this map.
- * @type {number}
- */
- this.mapId = mapId;
-
- /**
- * The map itself.
- * @type {Object|goog.structs.Map}
- */
- this.map = map;
-};
-
-
-/**
- * Extra HTTP headers to add to all the requests sent to the server.
- * @type {Object}
- * @private
- */
-goog.net.BrowserChannel.prototype.extraHeaders_ = null;
-
-
-/**
- * Extra parameters to add to all the requests sent to the server.
- * @type {Object}
- * @private
- */
-goog.net.BrowserChannel.prototype.extraParams_ = null;
-
-
-/**
- * The current ChannelRequest object for the forwardchannel.
- * @type {goog.net.ChannelRequest?}
- * @private
- */
-goog.net.BrowserChannel.prototype.forwardChannelRequest_ = null;
-
-
-/**
- * The ChannelRequest object for the backchannel.
- * @type {goog.net.ChannelRequest?}
- * @private
- */
-goog.net.BrowserChannel.prototype.backChannelRequest_ = null;
-
-
-/**
- * The relative path (in the context of the the page hosting the browser
- * channel) for making requests to the server.
- * @type {?string}
- * @private
- */
-goog.net.BrowserChannel.prototype.path_ = null;
-
-
-/**
- * The absolute URI for the forwardchannel request.
- * @type {goog.Uri}
- * @private
- */
-goog.net.BrowserChannel.prototype.forwardChannelUri_ = null;
-
-
-/**
- * The absolute URI for the backchannel request.
- * @type {goog.Uri}
- * @private
- */
-goog.net.BrowserChannel.prototype.backChannelUri_ = null;
-
-
-/**
- * A subdomain prefix for using a subdomain in IE for the backchannel
- * requests.
- * @type {?string}
- * @private
- */
-goog.net.BrowserChannel.prototype.hostPrefix_ = null;
-
-
-/**
- * Whether we allow the use of a subdomain in IE for the backchannel requests.
- * @private
- */
-goog.net.BrowserChannel.prototype.allowHostPrefix_ = true;
-
-
-/**
- * The next id to use for the RID (request identifier) parameter. This
- * identifier uniquely identifies the forward channel request.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.nextRid_ = 0;
-
-
-/**
- * The id to use for the next outgoing map. This identifier uniquely
- * identifies a sent map.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.nextMapId_ = 0;
-
-
-/**
- * Whether to fail forward-channel requests after one try, or after a few tries.
- * @type {boolean}
- * @private
- */
-goog.net.BrowserChannel.prototype.failFast_ = false;
-
-
-/**
- * The handler that receive callbacks for state changes and data.
- * @type {goog.net.BrowserChannel.Handler}
- * @private
- */
-goog.net.BrowserChannel.prototype.handler_ = null;
-
-
-/**
- * Timer identifier for asynchronously making a forward channel request.
- * @type {?number}
- * @private
- */
-goog.net.BrowserChannel.prototype.forwardChannelTimerId_ = null;
-
-
-/**
- * Timer identifier for asynchronously making a back channel request.
- * @type {?number}
- * @private
- */
-goog.net.BrowserChannel.prototype.backChannelTimerId_ = null;
-
-
-/**
- * Timer identifier for the timer that waits for us to retry the backchannel in
- * the case where it is dead and no longer receiving data.
- * @type {?number}
- * @private
- */
-goog.net.BrowserChannel.prototype.deadBackChannelTimerId_ = null;
-
-
-/**
- * The BrowserTestChannel object which encapsulates the logic for determining
- * interesting network conditions about the client.
- * @type {goog.net.BrowserTestChannel?}
- * @private
- */
-goog.net.BrowserChannel.prototype.connectionTest_ = null;
-
-
-/**
- * Whether the client's network conditions can support chunked responses.
- * @type {?boolean}
- * @private
- */
-goog.net.BrowserChannel.prototype.useChunked_ = null;
-
-
-/**
- * Whether chunked mode is allowed. In certain debugging situations, it's
- * useful to disable this.
- * @private
- */
-goog.net.BrowserChannel.prototype.allowChunkedMode_ = true;
-
-
-/**
- * The array identifier of the last array received from the server for the
- * backchannel request.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.lastArrayId_ = -1;
-
-
-/**
- * The array identifier of the last array sent by the server that we know about.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.lastPostResponseArrayId_ = -1;
-
-
-/**
- * The last status code received.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.lastStatusCode_ = -1;
-
-
-/**
- * Number of times we have retried the current forward channel request.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.forwardChannelRetryCount_ = 0;
-
-
-/**
- * Number of times it a row that we have retried the current back channel
- * request and received no data.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.backChannelRetryCount_ = 0;
-
-
-/**
- * The attempt id for the current back channel request. Starts at 1 and
- * increments for each reconnect. The server uses this to log if our connection
- * is flaky or not.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.backChannelAttemptId_;
-
-
-/**
- * The latest protocol version that this class supports. We request this version
- * from the server when opening the connection. Should match
- * com.google.net.browserchannel.BrowserChannel.LATEST_CHANNEL_VERSION.
- * @type {number}
- */
-goog.net.BrowserChannel.LATEST_CHANNEL_VERSION = 8;
-
-
-/**
- * The channel version that we negotiated with the server for this session.
- * Starts out as the version we request, and then is changed to the negotiated
- * version after the initial open.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.prototype.channelVersion_ =
- goog.net.BrowserChannel.LATEST_CHANNEL_VERSION;
-
-
-/**
- * Enum type for the browser channel state machine.
- * @enum {number}
- */
-goog.net.BrowserChannel.State = {
- /** The channel is closed. */
- CLOSED: 0,
-
- /** The channel has been initialized but hasn't yet initiated a connection. */
- INIT: 1,
-
- /** The channel is in the process of opening a connection to the server. */
- OPENING: 2,
-
- /** The channel is open. */
- OPENED: 3
-};
-
-
-/**
- * Maximum number of attempts to connect to the server for forward channel
- * requests.
- * @type {number}
- */
-goog.net.BrowserChannel.FORWARD_CHANNEL_MAX_RETRIES = 2;
-
-
-/**
- * The timeout in milliseconds for a forward channel request.
- * @type {number}
- */
-goog.net.BrowserChannel.FORWARD_CHANNEL_RETRY_TIMEOUT = 20 * 1000;
-
-
-/**
- * Maximum number of attempts to connect to the server for back channel
- * requests.
- * @type {number}
- */
-goog.net.BrowserChannel.BACK_CHANNEL_MAX_RETRIES = 3;
-
-
-/**
- * Default timeout in MS before the initial retry. Subsequent retries will be
- * slower.
- * @type {number}
- */
-goog.net.BrowserChannel.RETRY_DELAY_MS = 5 * 1000;
-
-
-/**
- * We will add a random time between 0 and this number of MS to retries to
- * the retry time for this request.
- * @type {number}
- */
-goog.net.BrowserChannel.RETRY_DELAY_SEED = 10 * 1000;
-
-
-/**
- * A number in MS of how long we guess the maxmium amount of time a round trip
- * to the server should take. In the future this could be substituted with a
- * real measurement of the RTT.
- * @type {number}
- */
-goog.net.BrowserChannel.RTT_ESTIMATE = 3 * 1000;
-
-
-/**
- * When retrying for an inactive channel, we will multiply the total delay by
- * this number.
- * @type {number}
- */
-goog.net.BrowserChannel.INACTIVE_CHANNEL_RETRY_FACTOR = 2;
-
-
-/**
- * Enum type for identifying a BrowserChannel error.
- * @enum {number}
- */
-goog.net.BrowserChannel.Error = {
- /** Value that indicates no error has occurred. */
- OK: 0,
-
- /** An error due to a request failing. */
- REQUEST_FAILED: 2,
-
- /** An error due to the user being logged out. */
- LOGGED_OUT: 4,
-
- /** An error due to server response which contains no data. */
- NO_DATA: 5,
-
- /** An error due to a server response indicating an unknown session id */
- UNKNOWN_SESSION_ID: 6,
-
- /** An error due to a server response requesting to stop the channel. */
- STOP: 7,
-
- /** A general network error. */
- NETWORK: 8,
-
- /** An error due to the channel being blocked by a network administrator. */
- BLOCKED: 9,
-
- /** An error due to bad data being returned from the server. */
- BAD_DATA: 10,
-
- /** An error due to a response that doesn't start with the magic cookie. */
- BAD_RESPONSE: 11
-};
-
-
-/**
- * Internal enum type for the two browser channel channel types.
- * @enum {number}
- * @private
- */
-goog.net.BrowserChannel.ChannelType_ = {
- FORWARD_CHANNEL: 1,
-
- BACK_CHANNEL: 2
-};
-
-
-/**
- * The maximum number of maps that can be sent in one POST. Should match
- * com.google.net.browserchannel.BrowserChannel.MAX_MAPS_PER_REQUEST.
- * @type {number}
- * @private
- */
-goog.net.BrowserChannel.MAX_MAPS_PER_REQUEST_ = 1000;
-
-
-/**
- * Singleton event target for firing stat events
- * @type {goog.events.EventTarget}
- * @private
- */
-goog.net.BrowserChannel.statEventTarget_ = new goog.events.EventTarget();
-
-
-/**
- * Events fired by BrowserChannel and associated objects
- * @type {Object}
- */
-goog.net.BrowserChannel.Event = {};
-
-
-/**
- * Stat Event that fires when things of interest happen that may be useful for
- * applications to know about for stats or debugging purposes. This event fires
- * on the EventTarget returned by getStatEventTarget.
- */
-goog.net.BrowserChannel.Event.STAT_EVENT = 'statevent';
-
-
-
-/**
- * Event class for goog.net.BrowserChannel.Event.STAT_EVENT
- *
- * @param {goog.events.EventTarget} eventTarget The stat event target for
- the browser channel.
- * @param {goog.net.BrowserChannel.Stat} stat The stat.
- * @constructor
- * @extends {goog.events.Event}
- */
-goog.net.BrowserChannel.StatEvent = function(eventTarget, stat) {
- goog.events.Event.call(this, goog.net.BrowserChannel.Event.STAT_EVENT,
- eventTarget);
-
- /**
- * The stat
- * @type {goog.net.BrowserChannel.Stat}
- */
- this.stat = stat;
-
-};
-goog.inherits(goog.net.BrowserChannel.StatEvent, goog.events.Event);
-
-
-/**
- * An event that fires when POST requests complete successfully, indicating
- * the size of the POST and the round trip time.
- * This event fires on the EventTarget returned by getStatEventTarget.
- */
-goog.net.BrowserChannel.Event.TIMING_EVENT = 'timingevent';
-
-
-
-/**
- * Event class for goog.net.BrowserChannel.Event.TIMING_EVENT
- *
- * @param {goog.events.EventTarget} target The stat event target for
- the browser channel.
- * @param {number} size The number of characters in the POST data.
- * @param {number} rtt The total round trip time from POST to response in MS.
- * @param {number} retries The number of times the POST had to be retried.
- * @constructor
- * @extends {goog.events.Event}
- */
-goog.net.BrowserChannel.TimingEvent = function(target, size, rtt, retries) {
- goog.events.Event.call(this, goog.net.BrowserChannel.Event.TIMING_EVENT,
- target);
-
- /**
- * @type {number}
- */
- this.size = size;
-
- /**
- * @type {number}
- */
- this.rtt = rtt;
-
- /**
- * @type {number}
- */
- this.retries = retries;
-
-};
-goog.inherits(goog.net.BrowserChannel.TimingEvent, goog.events.Event);
-
-
-/**
- * Enum that identifies events for statistics that are interesting to track.
- * TODO(user) - Change name not to use Event or use EventTarget
- * @enum {number}
- */
-goog.net.BrowserChannel.Stat = {
- /** Event indicating a new connection attempt. */
- CONNECT_ATTEMPT: 0,
-
- /** Event indicating a connection error due to a general network problem. */
- ERROR_NETWORK: 1,
-
- /**
- * Event indicating a connection error that isn't due to a general network
- * problem.
- */
- ERROR_OTHER: 2,
-
- /** Event indicating the start of test stage one. */
- TEST_STAGE_ONE_START: 3,
-
-
- /** Event indicating the channel is blocked by a network administrator. */
- CHANNEL_BLOCKED: 4,
-
- /** Event indicating the start of test stage two. */
- TEST_STAGE_TWO_START: 5,
-
- /** Event indicating the first piece of test data was received. */
- TEST_STAGE_TWO_DATA_ONE: 6,
-
- /**
- * Event indicating that the second piece of test data was received and it was
- * recieved separately from the first.
- */
- TEST_STAGE_TWO_DATA_TWO: 7,
-
- /** Event indicating both pieces of test data were received simultaneously. */
- TEST_STAGE_TWO_DATA_BOTH: 8,
-
- /** Event indicating stage one of the test request failed. */
- TEST_STAGE_ONE_FAILED: 9,
-
- /** Event indicating stage two of the test request failed. */
- TEST_STAGE_TWO_FAILED: 10,
-
- /**
- * Event indicating that a buffering proxy is likely between the client and
- * the server.
- */
- PROXY: 11,
-
- /**
- * Event indicating that no buffering proxy is likely between the client and
- * the server.
- */
- NOPROXY: 12,
-
- /** Event indicating an unknown SID error. */
- REQUEST_UNKNOWN_SESSION_ID: 13,
-
- /** Event indicating a bad status code was received. */
- REQUEST_BAD_STATUS: 14,
-
- /** Event indicating incomplete data was received */
- REQUEST_INCOMPLETE_DATA: 15,
-
- /** Event indicating bad data was received */
- REQUEST_BAD_DATA: 16,
-
- /** Event indicating no data was received when data was expected. */
- REQUEST_NO_DATA: 17,
-
- /** Event indicating a request timeout. */
- REQUEST_TIMEOUT: 18,
-
- /**
- * Event indicating that the server never received our hanging GET and so it
- * is being retried.
- */
- BACKCHANNEL_MISSING: 19,
-
- /**
- * Event indicating that we have determined that our hanging GET is not
- * receiving data when it should be. Thus it is dead dead and will be retried.
- */
- BACKCHANNEL_DEAD: 20
-};
-
-
-/**
- * The normal response for forward channel requests.
- * Used only before version 8 of the protocol.
- * @type {string}
- */
-goog.net.BrowserChannel.MAGIC_RESPONSE_COOKIE = 'y2f%';
-
-
-/**
- * A guess at a cutoff at which to no longer assume the backchannel is dead
- * when we are slow to receive data. Number in bytes.
- *
- * Assumption: The worst bandwidth we work on is 50 kilobits/sec
- * 50kbits/sec * (1 byte / 8 bits) * 6 sec dead backchannel timeout
- * @type {number}
- */
-goog.net.BrowserChannel.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF = 37500;
-
-
-/**
- * Returns the browserchannel logger.
- *
- * @return {goog.net.ChannelDebug} The channel debug object.
- */
-goog.net.BrowserChannel.prototype.getChannelDebug = function() {
- return this.channelDebug_;
-};
-
-
-/**
- * Set the browserchannel logger.
- * TODO(user): Add interface for channel loggers or remove this function.
- *
- * @param {goog.net.ChannelDebug} channelDebug The channel debug object.
- */
-goog.net.BrowserChannel.prototype.setChannelDebug = function(
- channelDebug) {
- this.channelDebug_ = channelDebug;
-};
-
-
-/**
- * Allows the application to set an execution hooks for when BrowserChannel
- * starts processing requests. This is useful to track timing or logging
- * special information. The function takes no parameters and return void.
- * @param {Function} startHook The function for the start hook.
- */
-goog.net.BrowserChannel.setStartThreadExecutionHook = function(startHook) {
- goog.net.BrowserChannel.startExecutionHook_ = startHook;
-};
-
-
-/**
- * Allows the application to set an execution hooks for when BrowserChannel
- * stops processing requests. This is useful to track timing or logging
- * special information. The function takes no parameters and return void.
- * @param {Function} endHook The function for the end hook.
- */
-goog.net.BrowserChannel.setEndThreadExecutionHook = function(endHook) {
- goog.net.BrowserChannel.endExecutionHook_ = endHook;
-};
-
-
-/**
- * Application provided execution hook for the start hook.
- *
- * @type {Function}
- * @private
- */
-goog.net.BrowserChannel.startExecutionHook_ = function() { };
-
-
-/**
- * Application provided execution hook for the end hook.
- *
- * @type {Function}
- * @private
- */
-goog.net.BrowserChannel.endExecutionHook_ = function() { };
-
-
-/**
- * Instantiates a ChannelRequest with the given parameters. Overidden in tests.
- *
- * @param {goog.net.BrowserChannel|goog.net.BrowserTestChannel} channel
- * The BrowserChannel that owns this request.
- * @param {goog.net.ChannelDebug} channelDebug A ChannelDebug to use for
- * logging.
- * @param {string=} opt_sessionId The session id for the channel.
- * @param {string|number=} opt_requestId The request id for this request.
- * @param {number=} opt_retryId The retry id for this request.
- * @return {goog.net.ChannelRequest} The created channel request.
- */
-goog.net.BrowserChannel.createChannelRequest = function(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {
- return new goog.net.ChannelRequest(
- channel,
- channelDebug,
- opt_sessionId,
- opt_requestId,
- opt_retryId);
-};
-
-
-/**
- * Starts the channel. This initiates connections to the server.
- *
- * @param {string} testPath The path for the test connection.
- * @param {string} channelPath The path for the channel connection.
- * @param {Object} extraParams Extra parameter keys and values to add to the
- * requests.
- * @param {string=} opt_oldSessionId Session ID from a previous session.
- * @param {number=} opt_oldArrayId The last array ID from a previous session.
- */
-goog.net.BrowserChannel.prototype.connect = function(testPath, channelPath,
- extraParams, opt_oldSessionId, opt_oldArrayId) {
- this.channelDebug_.debug('connect()');
-
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.CONNECT_ATTEMPT);
-
- this.path_ = channelPath;
- this.extraParams_ = extraParams || {};
-
- // Attach parameters about the previous session if reconnecting.
- if (opt_oldSessionId && goog.isDef(opt_oldArrayId)) {
- this.extraParams_['OSID'] = opt_oldSessionId;
- this.extraParams_['OAID'] = opt_oldArrayId;
- }
-
- this.connectTest_(testPath);
-};
-
-
-/**
- * Disconnects and closes the channel.
- */
-goog.net.BrowserChannel.prototype.disconnect = function() {
- this.channelDebug_.debug('disconnect()');
-
- this.cancelRequests_();
-
- if (this.state_ == goog.net.BrowserChannel.State.OPENED) {
- var rid = this.nextRid_++;
- var uri = this.forwardChannelUri_.clone();
- uri.setParameterValue('SID', this.sid_);
- uri.setParameterValue('RID', rid);
- uri.setParameterValue('TYPE', 'terminate');
-
- // Add the reconnect parameters.
- this.addAdditionalParams_(uri);
-
- var request = goog.net.BrowserChannel.createChannelRequest(
- this, this.channelDebug_, this.sid_, rid);
- request.sendUsingImgTag(uri);
- this.onClose_();
- }
-};
-
-
-/**
- * Returns the session id of the channel. Only available after the
- * channel has been opened.
- * @return {string} Session ID.
- */
-goog.net.BrowserChannel.prototype.getSessionId = function() {
- return this.sid_;
-};
-
-
-/**
- * Starts the test channel to determine network conditions.
- *
- * @param {string} testPath The relative PATH for the test connection.
- * @private
- */
-goog.net.BrowserChannel.prototype.connectTest_ = function(testPath) {
- this.channelDebug_.debug('connectTest_()');
- if (!this.okToMakeRequest_()) {
- return; // channel is cancelled
- }
- this.connectionTest_ = new goog.net.BrowserTestChannel(
- this, this.channelDebug_);
- this.connectionTest_.setExtraHeaders(this.extraHeaders_);
- this.connectionTest_.connect(testPath);
-};
-
-
-/**
- * Starts the regular channel which is run after the test channel is complete.
- * @private
- */
-goog.net.BrowserChannel.prototype.connectChannel_ = function() {
- this.channelDebug_.debug('connectChannel_()');
- this.ensureInState_(goog.net.BrowserChannel.State.INIT,
- goog.net.BrowserChannel.State.CLOSED);
- this.forwardChannelUri_ =
- this.getForwardChannelUri(/** @type {string} */ (this.path_));
- this.ensureForwardChannel_();
-};
-
-
-/**
- * Cancels all outstanding requests.
- * @private
- */
-goog.net.BrowserChannel.prototype.cancelRequests_ = function() {
- if (this.connectionTest_) {
- this.connectionTest_.abort();
- this.connectionTest_ = null;
- }
-
- if (this.backChannelRequest_) {
- this.backChannelRequest_.cancel();
- this.backChannelRequest_ = null;
- }
-
- if (this.backChannelTimerId_) {
- goog.global.clearTimeout(this.backChannelTimerId_);
- this.backChannelTimerId_ = null;
- }
-
- this.clearDeadBackchannelTimer_();
-
- if (this.forwardChannelRequest_) {
- this.forwardChannelRequest_.cancel();
- this.forwardChannelRequest_ = null;
- }
-
- if (this.forwardChannelTimerId_) {
- goog.global.clearTimeout(this.forwardChannelTimerId_);
- this.forwardChannelTimerId_ = null;
- }
-};
-
-
-/**
- * Returns the extra HTTP headers to add to all the requests sent to the server.
- *
- * @return {Object} The HTTP headers, or null.
- */
-goog.net.BrowserChannel.prototype.getExtraHeaders = function() {
- return this.extraHeaders_;
-};
-
-
-/**
- * Sets extra HTTP headers to add to all the requests sent to the server.
- *
- * @param {Object} extraHeaders The HTTP headers, or null.
- */
-goog.net.BrowserChannel.prototype.setExtraHeaders = function(extraHeaders) {
- this.extraHeaders_ = extraHeaders;
-};
-
-
-/**
- * Returns the handler used for channel callback events.
- *
- * @return {goog.net.BrowserChannel.Handler} The handler.
- */
-goog.net.BrowserChannel.prototype.getHandler = function() {
- return this.handler_;
-};
-
-
-/**
- * Sets the handler used for channel callback events.
- * @param {goog.net.BrowserChannel.Handler} handler The handler to set.
- */
-goog.net.BrowserChannel.prototype.setHandler = function(handler) {
- this.handler_ = handler;
-};
-
-
-/**
- * Returns whether the channel allows the use of a subdomain. There may be
- * cases where this isn't allowed.
- * @return {boolean} Whether a host prefix is allowed.
- */
-goog.net.BrowserChannel.prototype.getAllowHostPrefix = function() {
- return this.allowHostPrefix_;
-};
-
-
-/**
- * Sets whether the channel allows the use of a subdomain. There may be cases
- * where this isn't allowed, for example, logging in with troutboard where
- * using a subdomain causes Apache to force the user to authenticate twice.
- * @param {boolean} allowHostPrefix Whether a host prefix is allowed.
- */
-goog.net.BrowserChannel.prototype.setAllowHostPrefix =
- function(allowHostPrefix) {
- this.allowHostPrefix_ = allowHostPrefix;
-};
-
-
-/**
- * Returns whether the channel is buffered or not. This state is valid for
- * querying only after the test connection has completed. This may be
- * queried in the goog.net.BrowserChannel.okToMakeRequest() callback.
- * A channel may be buffered if the test connection determines that
- * a chunked response could not be sent down within a suitable time.
- * @return {boolean} Whether the channel is buffered.
- */
-goog.net.BrowserChannel.prototype.isBuffered = function() {
- return !this.useChunked_;
-};
-
-
-/**
- * Returns whether chunked mode is allowed. In certain debugging situations,
- * it's useful for the application to have a way to disable chunked mode for a
- * user.
-
- * @return {boolean} Whether chunked mode is allowed.
- */
-goog.net.BrowserChannel.prototype.getAllowChunkedMode =
- function() {
- return this.allowChunkedMode_;
-};
-
-
-/**
- * Sets whether chunked mode is allowed. In certain debugging situations, it's
- * useful for the application to have a way to disable chunked mode for a user.
- * @param {boolean} allowChunkedMode Whether chunked mode is allowed.
- */
-goog.net.BrowserChannel.prototype.setAllowChunkedMode =
- function(allowChunkedMode) {
- this.allowChunkedMode_ = allowChunkedMode;
-};
-
-
-/**
- * Sends a request to the server. The format of the request is a Map data
- * structure of key/value pairs. These maps are then encoded in a format
- * suitable for the wire and then reconstituted as a Map data structure that
- * the server can process.
- * @param {Object|goog.structs.Map} map The map to send.
- */
-goog.net.BrowserChannel.prototype.sendMap = function(map) {
- if (this.state_ == goog.net.BrowserChannel.State.CLOSED) {
- throw Error('Invalid operation: sending map when state is closed');
- }
-
- // We can only send 1000 maps per POST, but typically we should never have
- // that much to send, so warn if we exceed that (we still send all the maps).
- if (this.outgoingMaps_.length ==
- goog.net.BrowserChannel.MAX_MAPS_PER_REQUEST_) {
- // severe() is temporary so that we get these uploaded and can figure out
- // what's causing them. Afterwards can change to warning().
- this.channelDebug_.severe(
- 'Already have ' + goog.net.BrowserChannel.MAX_MAPS_PER_REQUEST_ +
- ' queued maps upon queueing ' + goog.json.serialize(map));
- }
-
- this.outgoingMaps_.push(
- new goog.net.BrowserChannel.QueuedMap(this.nextMapId_++, map));
- if (this.state_ == goog.net.BrowserChannel.State.OPENING ||
- this.state_ == goog.net.BrowserChannel.State.OPENED) {
- this.ensureForwardChannel_();
- }
-};
-
-
-/**
- * When set to true, this changes the behavior of the forward channel so it
- * will not retry requests; it will fail after one network failure, and if
- * there was already one network failure, the request will fail immediately.
- * @param {boolean} failFast Whether or not to fail fast.
- */
-goog.net.BrowserChannel.prototype.setFailFast = function(failFast) {
- this.failFast_ = failFast;
- this.channelDebug_.info('setFailFast: ' + failFast);
- if ((this.forwardChannelRequest_ || this.forwardChannelTimerId_) &&
- this.forwardChannelRetryCount_ > this.getForwardChannelMaxRetries()) {
- this.channelDebug_.info(
- 'Retry count ' + this.forwardChannelRetryCount_ +
- ' > new maxRetries ' + this.getForwardChannelMaxRetries() +
- '. Fail immediately!');
- if (this.forwardChannelRequest_) {
- this.forwardChannelRequest_.cancel();
- // Go through the standard onRequestComplete logic to expose the max-retry
- // failure in the standard way.
- this.onRequestComplete(this.forwardChannelRequest_);
- } else { // i.e., this.forwardChannelTimerId_
- goog.global.clearTimeout(this.forwardChannelTimerId_);
- this.forwardChannelTimerId_ = null;
- // The error code from the last failed request is gone, so just use a
- // generic one.
- this.signalError_(goog.net.BrowserChannel.Error.REQUEST_FAILED);
- }
- }
-};
-
-
-/**
- * @return {number} The max number of forward-channel retries, which will be 0
- * in fail-fast mode.
- */
-goog.net.BrowserChannel.prototype.getForwardChannelMaxRetries = function() {
- return this.failFast_ ?
- 0 : goog.net.BrowserChannel.FORWARD_CHANNEL_MAX_RETRIES;
-};
-
-
-/**
- * @return {number} The max number of back-channel retries, which is a constant.
- */
-goog.net.BrowserChannel.prototype.getBackChannelMaxRetries = function() {
- // Back-channel retries is a constant.
- return goog.net.BrowserChannel.BACK_CHANNEL_MAX_RETRIES;
-};
-
-
-/**
- * Returns whether the channel is closed
- * @return {boolean} true if the channel is closed.
- */
-goog.net.BrowserChannel.prototype.isClosed = function() {
- return this.state_ == goog.net.BrowserChannel.State.CLOSED;
-};
-
-
-/**
- * Returns the browser channel state.
- * @return {goog.net.BrowserChannel.State} The current state of the browser
- * channel.
- */
-goog.net.BrowserChannel.prototype.getState = function() {
- return this.state_;
-};
-
-
-/**
- * Return the last status code received for a request.
- * @return {number} The last status code received for a request.
- */
-goog.net.BrowserChannel.prototype.getLastStatusCode = function() {
- return this.lastStatusCode_;
-};
-
-
-/**
- * @return {number} The last array id received.
- */
-goog.net.BrowserChannel.prototype.getLastArrayId = function() {
- return this.lastArrayId_;
-};
-
-
-/**
- * Returns whether there are outstanding requests servicing the channel.
- * @return {boolean} true if there are outstanding requests.
- */
-goog.net.BrowserChannel.prototype.hasOutstandingRequests = function() {
- return this.outstandingRequests_() != 0;
-};
-
-
-/**
- * Returns the number of outstanding requests.
- * @return {number} The number of outstanding requests to the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.outstandingRequests_ = function() {
- var count = 0;
- if (this.backChannelRequest_) {
- count++;
- }
- if (this.forwardChannelRequest_) {
- count++;
- }
- return count;
-};
-
-
-/**
- * Ensures that a forward channel request is scheduled.
- * @private
- */
-goog.net.BrowserChannel.prototype.ensureForwardChannel_ = function() {
- if (this.forwardChannelRequest_) {
- // connection in process - no need to start a new request
- return;
- }
-
- if (this.forwardChannelTimerId_) {
- // no need to start a new request - one is already scheduled
- return;
- }
-
- this.forwardChannelTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onStartForwardChannelTimer_, this), 0);
- this.forwardChannelRetryCount_ = 0;
-};
-
-
-/**
- * Schedules a forward-channel retry for the specified request, unless the max
- * retries has been reached.
- * @param {goog.net.ChannelRequest} request The failed request to retry.
- * @return {boolean} true iff a retry was scheduled.
- * @private
- */
-goog.net.BrowserChannel.prototype.maybeRetryForwardChannel_ =
- function(request) {
- if (this.forwardChannelRequest_ || this.forwardChannelTimerId_) {
- // Should be impossible to be called in this state.
- this.channelDebug_.severe('Request already in progress');
- return false;
- }
-
- if (this.state_ == goog.net.BrowserChannel.State.INIT || // no retry open_()
- (this.forwardChannelRetryCount_ >= this.getForwardChannelMaxRetries())) {
- return false;
- }
-
- this.channelDebug_.debug('Going to retry POST');
-
- this.forwardChannelTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onStartForwardChannelTimer_, this, request),
- this.getRetryTime_(this.forwardChannelRetryCount_));
- this.forwardChannelRetryCount_++;
- return true;
-};
-
-
-/**
- * Timer callback for ensureForwardChannel
- * @param {goog.net.ChannelRequest=} opt_retryRequest A failed request to retry.
- * @private
- */
-goog.net.BrowserChannel.prototype.onStartForwardChannelTimer_ = function(
- opt_retryRequest) {
- this.forwardChannelTimerId_ = null;
- this.startForwardChannel_(opt_retryRequest);
-};
-
-
-/**
- * Begins a new forward channel operation to the server.
- * @param {goog.net.ChannelRequest=} opt_retryRequest A failed request to retry.
- * @private
- */
-goog.net.BrowserChannel.prototype.startForwardChannel_ = function(
- opt_retryRequest) {
- this.channelDebug_.debug('startForwardChannel_');
- if (!this.okToMakeRequest_()) {
- return; // channel is cancelled
- } else if (this.state_ == goog.net.BrowserChannel.State.INIT) {
- if (opt_retryRequest) {
- this.channelDebug_.severe('Not supposed to retry the open');
- return;
- }
- this.open_();
- this.state_ = goog.net.BrowserChannel.State.OPENING;
- } else if (this.state_ == goog.net.BrowserChannel.State.OPENED) {
- if (opt_retryRequest) {
- this.makeForwardChannelRequest_(opt_retryRequest);
- return;
- }
-
- if (this.outgoingMaps_.length == 0) {
- this.channelDebug_.debug('startForwardChannel_ returned: ' +
- 'nothing to send');
- // no need to start a new forward channel request
- return;
- }
-
- if (this.forwardChannelRequest_) {
- // Should be impossible to be called in this state.
- this.channelDebug_.severe('startForwardChannel_ returned: ' +
- 'connection already in progress');
- return;
- }
-
- this.makeForwardChannelRequest_();
- this.channelDebug_.debug('startForwardChannel_ finished, sent request');
- }
-};
-
-
-/**
- * Establishes a new channel session with the the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.open_ = function() {
- this.channelDebug_.debug('open_()');
- this.nextRid_ = Math.floor(Math.random() * 100000);
-
- var rid = this.nextRid_++;
- var request = goog.net.BrowserChannel.createChannelRequest(
- this, this.channelDebug_, '', rid);
- request.setExtraHeaders(this.extraHeaders_);
- var requestText = this.dequeueOutgoingMaps_();
- var uri = this.forwardChannelUri_.clone();
- uri.setParameterValue('RID', rid);
- if (this.clientVersion_) {
- uri.setParameterValue('CVER', this.clientVersion_);
- }
-
- // Add the reconnect parameters.
- this.addAdditionalParams_(uri);
-
- request.xmlHttpPost(uri, requestText, true);
- this.forwardChannelRequest_ = request;
-};
-
-
-/**
- * Makes a forward channel request using XMLHTTP.
- * @param {goog.net.ChannelRequest=} opt_retryRequest A failed request to retry.
- * @private
- */
-goog.net.BrowserChannel.prototype.makeForwardChannelRequest_ =
- function(opt_retryRequest) {
- var rid;
- var requestText;
- if (opt_retryRequest) {
- if (this.channelVersion_ > 6) {
- // In version 7 and up we can tack on new arrays to a retry.
- this.requeuePendingMaps_();
- rid = this.nextRid_ - 1; // Must use last RID
- requestText = this.dequeueOutgoingMaps_();
- } else {
- // TODO(user): Remove this code and the opt_retryRequest passing
- // once server-side support for ver 7 is ubiquitous.
- rid = opt_retryRequest.getRequestId();
- requestText = /** @type {string} */ (opt_retryRequest.getPostData());
- }
- } else {
- rid = this.nextRid_++;
- requestText = this.dequeueOutgoingMaps_();
- }
-
- var uri = this.forwardChannelUri_.clone();
- uri.setParameterValue('SID', this.sid_);
- uri.setParameterValue('RID', rid);
- uri.setParameterValue('AID', this.lastArrayId_);
- // Add the additional reconnect parameters.
- this.addAdditionalParams_(uri);
-
- var request = goog.net.BrowserChannel.createChannelRequest(
- this,
- this.channelDebug_,
- this.sid_,
- rid,
- this.forwardChannelRetryCount_ + 1);
- request.setExtraHeaders(this.extraHeaders_);
-
- // randomize from 50%-100% of the forward channel timeout to avoid
- // a big hit if servers happen to die at once.
- request.setTimeout(
- Math.round(goog.net.BrowserChannel.FORWARD_CHANNEL_RETRY_TIMEOUT * 0.50) +
- Math.round(goog.net.BrowserChannel.FORWARD_CHANNEL_RETRY_TIMEOUT * 0.50 *
- Math.random()));
- this.forwardChannelRequest_ = request;
- request.xmlHttpPost(uri, requestText, true);
-};
-
-
-/**
- * Adds the additional parameters from the handler to the given URI.
- * @param {goog.Uri} uri The URI to add the parameters to.
- * @private
- */
-goog.net.BrowserChannel.prototype.addAdditionalParams_ = function(uri) {
- // Add the additional reconnect parameters as needed.
- if (this.handler_) {
- var params = this.handler_.getAdditionalParams(this);
- if (params) {
- goog.structs.forEach(params, function(value, key, coll) {
- uri.setParameterValue(key, value);
- });
- }
- }
-};
-
-
-/**
- * Returns the request text from the outgoing maps and resets it.
- * @return {string} The encoded request text created from all the currently
- * queued outgoing maps.
- * @private
- */
-goog.net.BrowserChannel.prototype.dequeueOutgoingMaps_ = function() {
- var count = Math.min(this.outgoingMaps_.length,
- goog.net.BrowserChannel.MAX_MAPS_PER_REQUEST_);
- var sb = ['count=' + count];
- var offset;
- if (this.channelVersion_ > 6 && count > 0) {
- // To save a bit of bandwidth, specify the base mapId and the rest as
- // offsets from it.
- offset = this.outgoingMaps_[0].mapId;
- sb.push('ofs=' + offset);
- } else {
- offset = 0;
- }
- for (var i = 0; i < count; i++) {
- var mapId = this.outgoingMaps_[i].mapId;
- var map = this.outgoingMaps_[i].map;
- if (this.channelVersion_ <= 6) {
- // Map IDs were not used in ver 6 and before, just indexes in the request.
- mapId = i;
- } else {
- mapId -= offset;
- }
- try {
- goog.structs.forEach(map, function(value, key, coll) {
- sb.push('req' + mapId + '_' + key + '=' + encodeURIComponent(value));
- });
- } catch (ex) {
- // We send a map here because lots of the retry logic relies on map IDs,
- // so we have to send something.
- sb.push('req' + mapId + '_' + 'type' + '=' +
- encodeURIComponent('_badmap'));
- if (this.handler_) {
- this.handler_.badMapError(this, map);
- }
- }
- }
- this.pendingMaps_ = this.pendingMaps_.concat(
- this.outgoingMaps_.splice(0, count));
- return sb.join('&');
-};
-
-
-/**
- * Requeues unacknowledged sent arrays for retransmission in the next forward
- * channel request.
- * @private
- */
-goog.net.BrowserChannel.prototype.requeuePendingMaps_ = function() {
- this.outgoingMaps_ = this.pendingMaps_.concat(this.outgoingMaps_);
- this.pendingMaps_.length = 0;
-};
-
-
-/**
- * Ensures there is a backchannel request for receiving data from the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.ensureBackChannel_ = function() {
- if (this.backChannelRequest_) {
- // already have one
- return;
- }
-
- if (this.backChannelTimerId_) {
- // no need to start a new request - one is already scheduled
- return;
- }
-
- this.backChannelAttemptId_ = 1;
- this.backChannelTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onStartBackChannelTimer_, this), 0);
- this.backChannelRetryCount_ = 0;
-};
-
-
-/**
- * Schedules a back-channel retry, unless the max retries has been reached.
- * @return {boolean} true iff a retry was scheduled.
- * @private
- */
-goog.net.BrowserChannel.prototype.maybeRetryBackChannel_ = function() {
- if (this.backChannelRequest_ || this.backChannelTimerId_) {
- // Should be impossible to be called in this state.
- this.channelDebug_.severe('Request already in progress');
- return false;
- }
-
- if (this.backChannelRetryCount_ >= this.getBackChannelMaxRetries()) {
- return false;
- }
-
- this.channelDebug_.debug('Going to retry GET');
-
- this.backChannelAttemptId_++;
- this.backChannelTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onStartBackChannelTimer_, this),
- this.getRetryTime_(this.backChannelRetryCount_));
- this.backChannelRetryCount_++;
- return true;
-};
-
-
-/**
- * Timer callback for ensureBackChannel_.
- * @private
- */
-goog.net.BrowserChannel.prototype.onStartBackChannelTimer_ = function() {
- this.backChannelTimerId_ = null;
- this.startBackChannel_();
-};
-
-
-/**
- * Begins a new back channel operation to the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.startBackChannel_ = function() {
- if (!this.okToMakeRequest_()) {
- // channel is cancelled
- return;
- }
-
- this.channelDebug_.debug('Creating new HttpRequest');
- this.backChannelRequest_ = goog.net.BrowserChannel.createChannelRequest(
- this,
- this.channelDebug_,
- this.sid_,
- 'rpc',
- this.backChannelAttemptId_);
- this.backChannelRequest_.setExtraHeaders(this.extraHeaders_);
- var uri = this.backChannelUri_.clone();
- uri.setParameterValue('RID', 'rpc');
- uri.setParameterValue('SID', this.sid_);
- uri.setParameterValue('CI', this.useChunked_ ? '0' : '1');
- uri.setParameterValue('AID', this.lastArrayId_);
-
- // Add the reconnect parameters.
- this.addAdditionalParams_(uri);
-
- if (!goog.net.ChannelRequest.supportsXhrStreaming()) {
- uri.setParameterValue('TYPE', 'html');
- this.backChannelRequest_.tridentGet(uri, Boolean(this.hostPrefix_));
- } else {
- uri.setParameterValue('TYPE', 'xmlhttp');
- this.backChannelRequest_.xmlHttpGet(uri, true /* decodeChunks */,
- this.hostPrefix_, false /* opt_noClose */);
- }
- this.channelDebug_.debug('New Request created');
-};
-
-
-/**
- * Gives the handler a chance to return an error code and stop channel
- * execution. A handler might want to do this to check that the user is still
- * logged in, for example.
- * @private
- * @return {boolean} If it's OK to make a request.
- */
-goog.net.BrowserChannel.prototype.okToMakeRequest_ = function() {
- if (this.handler_) {
- var result = this.handler_.okToMakeRequest(this);
- if (result != goog.net.BrowserChannel.Error.OK) {
- this.channelDebug_.debug('Handler returned error code from ' +
- 'okToMakeRequest');
- this.signalError_(result);
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Callback from BrowserTestChannel for when the channel is finished.
- * @param {goog.net.BrowserTestChannel} testChannel The BrowserTestChannel.
- * @param {boolean} useChunked Whether we can chunk responses.
- */
-goog.net.BrowserChannel.prototype.testConnectionFinished =
- function(testChannel, useChunked) {
- this.channelDebug_.debug('Test Connection Finished');
-
- this.useChunked_ = this.allowChunkedMode_ && useChunked;
- this.lastStatusCode_ = testChannel.getLastStatusCode();
- this.connectChannel_();
-};
-
-
-/**
- * Callback from BrowserTestChannel for when the channel has an error.
- * @param {goog.net.BrowserTestChannel} testChannel The BrowserTestChannel.
- * @param {goog.net.ChannelRequest.Error} errorCode The error code of the
- failure.
- */
-goog.net.BrowserChannel.prototype.testConnectionFailure =
- function(testChannel, errorCode) {
- this.channelDebug_.debug('Test Connection Failed');
- this.lastStatusCode_ = testChannel.getLastStatusCode();
- this.signalError_(goog.net.BrowserChannel.Error.REQUEST_FAILED);
-};
-
-
-/**
- * Callback from BrowserTestChannel for when the channel is blocked.
- * @param {goog.net.BrowserTestChannel} testChannel The BrowserTestChannel.
- */
-goog.net.BrowserChannel.prototype.testConnectionBlocked =
- function(testChannel) {
- this.channelDebug_.debug('Test Connection Blocked');
- this.lastStatusCode_ = this.connectionTest_.getLastStatusCode();
- this.signalError_(goog.net.BrowserChannel.Error.BLOCKED);
-};
-
-
-/**
- * Callback from ChannelRequest for when new data is received
- * @param {goog.net.ChannelRequest} request The request object.
- * @param {string} responseText The text of the response.
- */
-goog.net.BrowserChannel.prototype.onRequestData =
- function(request, responseText) {
- if (this.state_ == goog.net.BrowserChannel.State.CLOSED ||
- (this.backChannelRequest_ != request &&
- this.forwardChannelRequest_ != request)) {
- // either CLOSED or a request we don't know about (perhaps an old request)
- return;
- }
- this.lastStatusCode_ = request.getLastStatusCode();
-
- if (this.forwardChannelRequest_ == request &&
- this.state_ == goog.net.BrowserChannel.State.OPENED) {
- if (this.channelVersion_ > 7) {
- var response;
- try {
- response = (/** @type {Array} */ goog.json.unsafeParse(responseText));
- } catch (ex) {
- response = null;
- }
- if (goog.isArray(response) && response.length == 3) {
- this.handlePostResponse_(response);
- } else {
- this.channelDebug_.debug('Bad POST response data returned');
- this.signalError_(goog.net.BrowserChannel.Error.BAD_RESPONSE);
- }
- } else if (responseText != goog.net.BrowserChannel.MAGIC_RESPONSE_COOKIE) {
- this.channelDebug_.debug('Bad data returned - missing/invald ' +
- 'magic cookie');
- this.signalError_(goog.net.BrowserChannel.Error.BAD_RESPONSE);
- }
- } else {
- if (this.backChannelRequest_ == request) {
- this.clearDeadBackchannelTimer_();
- }
- if (!goog.string.isEmpty(responseText)) {
- this.onInput_(/** @type {Array} */ (goog.json.unsafeParse(responseText)));
- }
- }
-};
-
-
-/**
- * Handles a POST response from the server.
- * @param {Array} responseValues The key value pairs in the POST response.
- * @private
- */
-goog.net.BrowserChannel.prototype.handlePostResponse_ = function(
- responseValues) {
- // The first response value is set to 0 if server is missing backchannel.
- if (responseValues[0] == 0) {
- this.handleBackchannelMissing_();
- return;
- }
- this.lastPostResponseArrayId_ = responseValues[1];
- var outstandingArrays = this.lastPostResponseArrayId_ - this.lastArrayId_;
- if (0 < outstandingArrays) {
- var numOutstandingBackchannelBytes = responseValues[2];
- this.channelDebug_.debug(numOutstandingBackchannelBytes + ' bytes (in ' +
- outstandingArrays + ' arrays) are outstanding on the BackChannel');
- if (!this.shouldRetryBackChannel_(numOutstandingBackchannelBytes)) {
- return;
- }
- if (!this.deadBackChannelTimerId_) {
- // We expect to receive data within 2 RTTs or we retry the backchannel.
- this.deadBackChannelTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onBackChannelDead_, this),
- 2 * goog.net.BrowserChannel.RTT_ESTIMATE);
- }
- }
-};
-
-
-/**
- * Handles a POST response from the server telling us that it has detected that
- * we have no hanging GET connection.
- * @private
- */
-goog.net.BrowserChannel.prototype.handleBackchannelMissing_ = function() {
- // As long as the back channel was started before the POST was sent,
- // we should retry the backchannel. We give a slight buffer of RTT_ESTIMATE
- // so as not to excessively retry the backchannel
- this.channelDebug_.debug('Server claims our backchannel is missing.');
- if (this.backChannelTimerId_) {
- this.channelDebug_.debug('But we are currently starting the request.');
- return;
- } else if (!this.backChannelRequest_) {
- this.channelDebug_.warning(
- 'We do not have a BackChannel established');
- } else if (this.backChannelRequest_.getRequestStartTime() +
- goog.net.BrowserChannel.RTT_ESTIMATE <
- this.forwardChannelRequest_.getRequestStartTime()) {
- this.clearDeadBackchannelTimer_();
- this.backChannelRequest_.cancel();
- this.backChannelRequest_ = null;
- } else {
- return;
- }
- this.maybeRetryBackChannel_();
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.BACKCHANNEL_MISSING);
-};
-
-
-/**
- * Determines whether we should start the process of retrying a possibly
- * dead backchannel.
- * @param {number} outstandingBytes The number of bytes for which the server has
- * not yet received acknowledgement.
- * @return {boolean} Whether to start the backchannel retry timer.
- * @private
- */
-goog.net.BrowserChannel.prototype.shouldRetryBackChannel_ = function(
- outstandingBytes) {
- // Not too many outstanding bytes, not buffered and not after a retry.
- return outstandingBytes <
- goog.net.BrowserChannel.OUTSTANDING_DATA_BACKCHANNEL_RETRY_CUTOFF &&
- !this.isBuffered() &&
- this.backChannelRetryCount_ == 0;
-};
-
-
-/**
- * Decides which host prefix should be used, if any. If there is a handler,
- * allows the handler to validate a host prefix provided by the server, and
- * optionally override it.
- * @param {?string} serverHostPrefix The host prefix provided by the server.
- * @return {?string} The host prefix to actually use, if any. Will return null
- * if the use of host prefixes was disabled via setAllowHostPrefix().
- */
-goog.net.BrowserChannel.prototype.correctHostPrefix = function(
- serverHostPrefix) {
- if (this.allowHostPrefix_) {
- if (this.handler_) {
- return this.handler_.correctHostPrefix(serverHostPrefix);
- }
- return serverHostPrefix;
- }
- return null;
-};
-
-
-/**
- * Handles the timer that indicates that our backchannel is no longer able to
- * successfully receive data from the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.onBackChannelDead_ = function() {
- if (goog.isDefAndNotNull(this.deadBackChannelTimerId_)) {
- this.deadBackChannelTimerId_ = null;
- this.backChannelRequest_.cancel();
- this.backChannelRequest_ = null;
- this.maybeRetryBackChannel_();
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD);
- }
-};
-
-
-/**
- * Clears the timer that indicates that our backchannel is no longer able to
- * successfully receive data from the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.clearDeadBackchannelTimer_ = function() {
- if (goog.isDefAndNotNull(this.deadBackChannelTimerId_)) {
- goog.global.clearTimeout(this.deadBackChannelTimerId_);
- this.deadBackChannelTimerId_ = null;
- }
-};
-
-
-/**
- * Returns whether or not the given error/status combination is fatal or not.
- * On fatal errors we immediately close the session rather than retrying the
- * failed request.
- * @param {goog.net.ChannelRequest.Error?} error The error code for the failed
- * request.
- * @param {number} statusCode The last HTTP status code.
- * @return {boolean} Whether or not the error is fatal.
- * @private
- */
-goog.net.BrowserChannel.isFatalError_ =
- function(error, statusCode) {
- return error == goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID ||
- (error == goog.net.ChannelRequest.Error.STATUS &&
- statusCode > 0);
-};
-
-
-/**
- * Callback from ChannelRequest that indicates a request has completed.
- * @param {goog.net.ChannelRequest} request The request object.
- */
-goog.net.BrowserChannel.prototype.onRequestComplete =
- function(request) {
- this.channelDebug_.debug('Request complete');
- var type;
- if (this.backChannelRequest_ == request) {
- this.clearDeadBackchannelTimer_();
- this.backChannelRequest_ = null;
- type = goog.net.BrowserChannel.ChannelType_.BACK_CHANNEL;
- } else if (this.forwardChannelRequest_ == request) {
- this.forwardChannelRequest_ = null;
- type = goog.net.BrowserChannel.ChannelType_.FORWARD_CHANNEL;
- } else {
- // return if it was an old request from a previous session
- return;
- }
-
- this.lastStatusCode_ = request.getLastStatusCode();
-
- if (this.state_ == goog.net.BrowserChannel.State.CLOSED) {
- return;
- }
-
- if (request.getSuccess()) {
- // Yay!
- if (type == goog.net.BrowserChannel.ChannelType_.FORWARD_CHANNEL) {
- var size = request.getPostData() ? request.getPostData().length : 0;
- goog.net.BrowserChannel.notifyTimingEvent(size,
- goog.now() - request.getRequestStartTime(),
- this.forwardChannelRetryCount_);
- this.ensureForwardChannel_();
- this.pendingMaps_.length = 0;
- } else { // i.e., back-channel
- this.ensureBackChannel_();
- }
- return;
- }
- // Else unsuccessful. Fall through.
-
- var lastError = request.getLastError();
- if (!goog.net.BrowserChannel.isFatalError_(lastError,
- this.lastStatusCode_)) {
- // Maybe retry.
- this.channelDebug_.debug('Maybe retrying, last error: ' +
- goog.net.ChannelRequest.errorStringFromCode(
- /** @type {goog.net.ChannelRequest.Error} */ (lastError),
- this.lastStatusCode_));
- if (type == goog.net.BrowserChannel.ChannelType_.FORWARD_CHANNEL) {
- if (this.maybeRetryForwardChannel_(request)) {
- return;
- }
- }
- if (type == goog.net.BrowserChannel.ChannelType_.BACK_CHANNEL) {
- if (this.maybeRetryBackChannel_()) {
- return;
- }
- }
- // Else exceeded max retries. Fall through.
- this.channelDebug_.debug('Exceeded max number of retries');
- } else {
- // Else fatal error. Fall through and mark the pending maps as failed.
- this.channelDebug_.debug('Not retrying due to error type');
- }
-
-
- // Can't save this session. :(
- this.channelDebug_.debug('Error: HTTP request failed');
- switch (lastError) {
- case goog.net.ChannelRequest.Error.NO_DATA:
- this.signalError_(goog.net.BrowserChannel.Error.NO_DATA);
- break;
- case goog.net.ChannelRequest.Error.BAD_DATA:
- this.signalError_(goog.net.BrowserChannel.Error.BAD_DATA);
- break;
- case goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID:
- this.signalError_(goog.net.BrowserChannel.Error.UNKNOWN_SESSION_ID);
- break;
- default:
- this.signalError_(goog.net.BrowserChannel.Error.REQUEST_FAILED);
- break;
- }
-};
-
-
-/**
- * @param {number} retryCount Number of retries so far.
- * @return {number} Time in ms before firing next retry request.
- * @private
- */
-goog.net.BrowserChannel.prototype.getRetryTime_ = function(retryCount) {
- var retryTime = goog.net.BrowserChannel.RETRY_DELAY_MS +
- Math.floor(Math.random() * goog.net.BrowserChannel.RETRY_DELAY_SEED);
- if (!this.isActive()) {
- this.channelDebug_.debug('Inactive channel');
- retryTime =
- retryTime * goog.net.BrowserChannel.INACTIVE_CHANNEL_RETRY_FACTOR;
- }
- // Backoff for subsequent retries
- retryTime = retryTime * retryCount;
- return retryTime;
-};
-
-
-/**
- * Processes the data returned by the server.
- * @param {Array} respArray The response array returned by the server.
- * @private
- */
-goog.net.BrowserChannel.prototype.onInput_ = function(respArray) {
- // respArray is an array of arrays
- var batch = this.handler_ && this.handler_.channelHandleMultipleArrays ?
- [] : null;
- for (var i = 0; i < respArray.length; i++) {
- var nextArray = respArray[i];
- this.lastArrayId_ = nextArray[0];
- nextArray = nextArray[1];
- if (this.state_ == goog.net.BrowserChannel.State.OPENING) {
- if (nextArray[0] == 'c') {
- this.sid_ = nextArray[1];
- this.hostPrefix_ = this.correctHostPrefix(nextArray[2]);
- var negotiatedVersion = nextArray[3];
- if (goog.isDefAndNotNull(negotiatedVersion)) {
- this.channelVersion_ = negotiatedVersion;
- } else {
- // Servers prior to version 7 did not send this, so assume version 6.
- this.channelVersion_ = 6;
- }
- this.state_ = goog.net.BrowserChannel.State.OPENED;
- if (this.handler_) {
- this.handler_.channelOpened(this);
- }
- this.backChannelUri_ = this.getBackChannelUri(
- this.hostPrefix_, /** @type {string} */ (this.path_));
- // Open connection to receive data
- this.ensureBackChannel_();
- } else if (nextArray[0] == 'stop') {
- this.signalError_(goog.net.BrowserChannel.Error.STOP);
- }
- } else if (this.state_ == goog.net.BrowserChannel.State.OPENED) {
- if (nextArray[0] == 'stop') {
- if (batch && batch.length) {
- this.handler_.channelHandleMultipleArrays(this, batch);
- batch.length = 0;
- }
- this.signalError_(goog.net.BrowserChannel.Error.STOP);
- } else if (nextArray[0] == 'noop') {
- // ignore - noop to keep connection happy
- } else {
- if (batch) {
- batch.push(nextArray);
- } else if (this.handler_) {
- this.handler_.channelHandleArray(this, nextArray);
- }
- }
- // We have received useful data on the back-channel, so clear its retry
- // count. We do this because back-channels by design do not complete
- // quickly, so on a flaky connection we could have many fail to complete
- // fully but still deliver a lot of data before they fail. We don't want
- // to count such failures towards the retry limit, because we don't want
- // to give up on a session if we can still receive data.
- this.backChannelRetryCount_ = 0;
- }
- }
- if (batch && batch.length) {
- this.handler_.channelHandleMultipleArrays(this, batch);
- }
-};
-
-
-/**
- * Helper to ensure the BrowserChannel is in the expected state.
- * @param {...number} var_args The channel must be in one of the indicated
- * states.
- * @private
- */
-goog.net.BrowserChannel.prototype.ensureInState_ = function(var_args) {
- if (!goog.array.contains(arguments, this.state_)) {
- throw Error('Unexpected channel state: ' + this.state_);
- }
-};
-
-
-/**
- * Signals an error has occurred.
- * @param {goog.net.BrowserChannel.Error} error The error code for the failure.
- * @private
- */
-goog.net.BrowserChannel.prototype.signalError_ = function(error) {
- this.channelDebug_.info('Error code ' + error);
- if (error == goog.net.BrowserChannel.Error.REQUEST_FAILED ||
- error == goog.net.BrowserChannel.Error.BLOCKED) {
- // Ping google to check if it's a server error or user's network error.
- var imageUri = null;
- if (this.handler_) {
- imageUri = this.handler_.getNetworkTestImageUri(this);
- }
- goog.net.tmpnetwork.testGoogleCom(
- goog.bind(this.testGoogleComCallback_, this), imageUri);
- } else {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.ERROR_OTHER);
- }
- this.onError_(error);
-};
-
-
-/**
- * Callback for testGoogleCom during error handling.
- * @param {boolean} networkUp Whether the network is up.
- * @private
- */
-goog.net.BrowserChannel.prototype.testGoogleComCallback_ = function(networkUp) {
- if (networkUp) {
- this.channelDebug_.info('Successfully pinged google.com');
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.ERROR_OTHER);
- } else {
- this.channelDebug_.info('Failed to ping google.com');
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.ERROR_NETWORK);
- // We cann onError_ here instead of signalError_ because the latter just
- // calls notifyStatEvent, and we don't want to have another stat event.
- this.onError_(goog.net.BrowserChannel.Error.NETWORK);
- }
-};
-
-
-/**
- * Called when we've determined the final error for a channel. It closes the
- * notifiers the handler of the error and closes the channel.
- * @param {goog.net.BrowserChannel.Error} error The error code for the failure.
- * @private
- */
-goog.net.BrowserChannel.prototype.onError_ = function(error) {
- this.channelDebug_.debug('HttpChannel: error - ' + error);
- this.state_ = goog.net.BrowserChannel.State.CLOSED;
- if (this.handler_) {
- this.handler_.channelError(this, error);
- }
- this.onClose_();
- this.cancelRequests_();
-};
-
-
-/**
- * Called when the channel has been closed. It notifiers the handler of the
- * event, and reports any pending or undelivered maps.
- * @private
- */
-goog.net.BrowserChannel.prototype.onClose_ = function() {
- this.state_ = goog.net.BrowserChannel.State.CLOSED;
- this.lastStatusCode_ = -1;
- if (this.handler_) {
- if (this.pendingMaps_.length == 0 && this.outgoingMaps_.length == 0) {
- this.handler_.channelClosed(this);
- } else {
- this.channelDebug_.debug('Number of undelivered maps' +
- ', pending: ' + this.pendingMaps_.length +
- ', outgoing: ' + this.outgoingMaps_.length);
-
- var copyOfPendingMaps = goog.array.clone(this.pendingMaps_);
- var copyOfUndeliveredMaps = goog.array.clone(this.outgoingMaps_);
- this.pendingMaps_.length = 0;
- this.outgoingMaps_.length = 0;
-
- this.handler_.channelClosed(this,
- copyOfPendingMaps,
- copyOfUndeliveredMaps);
- }
- }
-};
-
-
-/**
- * Gets the Uri used for the connection that sends data to the server.
- * @param {string} path The path on the host.
- * @return {goog.Uri} The forward channel URI.
- */
-goog.net.BrowserChannel.prototype.getForwardChannelUri =
- function(path) {
- var uri = this.createDataUri(null, path);
- this.channelDebug_.debug('GetForwardChannelUri: ' + uri);
- return uri;
-};
-
-
-/**
- * Gets the Uri used for the connection that receives data from the server.
- * @param {?string} hostPrefix The host prefix.
- * @param {string} path The path on the host.
- * @return {goog.Uri} The back channel URI.
- */
-goog.net.BrowserChannel.prototype.getBackChannelUri =
- function(hostPrefix, path) {
- var uri = this.createDataUri(this.shouldUseSecondaryDomains() ?
- hostPrefix : null, path);
- this.channelDebug_.debug('GetBackChannelUri: ' + uri);
- return uri;
-};
-
-
-/**
- * Creates a data Uri applying logic for secondary hostprefix, port
- * overrides, and versioning.
- * @param {?string} hostPrefix The host prefix.
- * @param {string} path The path on the host (may be absolute or relative).
- * @param {number=} opt_overridePort Optional override port.
- * @return {goog.Uri} The data URI.
- */
-goog.net.BrowserChannel.prototype.createDataUri =
- function(hostPrefix, path, opt_overridePort) {
- var uri = goog.Uri.parse(path);
- var uriAbsolute = (uri.getDomain() != '');
- if (uriAbsolute) {
- if (hostPrefix) {
- uri.setDomain(hostPrefix + '.' + uri.getDomain());
- }
-
- uri.setPort(opt_overridePort || uri.getPort());
- } else {
- var locationPage = window.location;
- var hostName;
- if (hostPrefix) {
- hostName = hostPrefix + '.' + locationPage.hostname;
- } else {
- hostName = locationPage.hostname;
- }
-
- var port = opt_overridePort || locationPage.port;
-
- uri = goog.Uri.create(locationPage.protocol, null, hostName, port, path);
- }
-
- if (this.extraParams_) {
- goog.structs.forEach(this.extraParams_, function(value, key, coll) {
- uri.setParameterValue(key, value);
- });
- }
-
- // Add the protocol version to the URI.
- uri.setParameterValue('VER', this.channelVersion_);
-
- // Add the reconnect parameters.
- this.addAdditionalParams_(uri);
-
- return uri;
-};
-
-
-/**
- * Called when BC needs to create an XhrIo object. Override in a subclass if
- * you need to customize the behavior, for example to enable the creation of
- * XHR's capable of calling a secondary domain.
- * @param {?string} hostPrefix The host prefix, if we need an XhrIo object
- * capable of calling a secondary domain.
- * @return {!goog.net.XhrIo} A new XhrIo object.
- */
-goog.net.BrowserChannel.prototype.createXhrIo = function(hostPrefix) {
- if (hostPrefix) {
- throw new Error('Can\'t create secondary domain capable XhrIo object.');
- } else {
- return new goog.net.XhrIo();
- }
-};
-
-
-/**
- * Gets whether this channel is currently active. This is used to determine the
- * length of time to wait before retrying. This call delegates to the handler.
- * @return {boolean} Whether the channel is currently active.
- */
-goog.net.BrowserChannel.prototype.isActive = function() {
- return !!this.handler_ && this.handler_.isActive(this);
-};
-
-
-/**
- * Wrapper around SafeTimeout which calls the start and end execution hooks
- * with a try...finally block.
- * @param {Function} fn The callback function.
- * @param {number} ms The time in MS for the timer.
- * @return {number} The ID of the timer.
- */
-goog.net.BrowserChannel.setTimeout = function(fn, ms) {
- if (!goog.isFunction(fn)) {
- throw Error('Fn must not be null and must be a function');
- }
- return goog.global.setTimeout(function() {
- goog.net.BrowserChannel.onStartExecution();
- try {
- fn();
- } finally {
- goog.net.BrowserChannel.onEndExecution();
- }
- }, ms);
-};
-
-
-/**
- * Helper function to call the start hook
- */
-goog.net.BrowserChannel.onStartExecution = function() {
- goog.net.BrowserChannel.startExecutionHook_();
-};
-
-
-/**
- * Helper function to call the end hook
- */
-goog.net.BrowserChannel.onEndExecution = function() {
- goog.net.BrowserChannel.endExecutionHook_();
-};
-
-
-/**
- * Returns the singleton event target for stat events.
- * @return {goog.events.EventTarget} The event target for stat events.
- */
-goog.net.BrowserChannel.getStatEventTarget = function() {
- return goog.net.BrowserChannel.statEventTarget_;
-};
-
-
-/**
- * Helper function to call the stat event callback.
- * @param {goog.net.BrowserChannel.Stat} stat The stat.
- */
-goog.net.BrowserChannel.notifyStatEvent = function(stat) {
- var target = goog.net.BrowserChannel.statEventTarget_;
- target.dispatchEvent(
- new goog.net.BrowserChannel.StatEvent(target, stat));
-};
-
-
-/**
- * Helper function to notify listeners about POST request performance.
- *
- * @param {number} size Number of characters in the POST data.
- * @param {number} rtt The amount of time from POST start to response.
- * @param {number} retries The number of times the POST had to be retried.
- */
-goog.net.BrowserChannel.notifyTimingEvent = function(size, rtt, retries) {
- var target = goog.net.BrowserChannel.statEventTarget_;
- target.dispatchEvent(
- new goog.net.BrowserChannel.TimingEvent(target, size, rtt, retries));
-};
-
-
-/**
- * Determines whether to use a secondary domain when the server gives us
- * a host prefix. This allows us to work around browser per-domain
- * connection limits.
- *
- * Currently, we only use secondary domains when using Trident's ActiveXObject,
- * because it supports cross-domain requests out of the box. Even if we wanted
- * to use secondary domains on Gecko/Webkit, they wouldn't work due to
- * security restrictions on cross-origin XHRs.
- *
- * If you need to use secondary domains on other browsers, you'll need
- * to override this method in a subclass, and make sure that those browsers
- * use some messaging mechanism that works cross-domain.
- *
- * @return {boolean} Whether to use secondary domains.
- * @see http://code.google.com/p/closure-library/issues/detail?id=339
- */
-goog.net.BrowserChannel.prototype.shouldUseSecondaryDomains = function() {
- return goog.userAgent.IE;
-};
-
-
-/**
- * A LogSaver that can be used to accumulate all the debug logs for
- * BrowserChannels so they can be sent to the server when a problem is
- * detected.
- */
-goog.net.BrowserChannel.LogSaver = {};
-
-
-/**
- * Buffer for accumulating the debug log
- * @type {goog.structs.CircularBuffer}
- * @private
- */
-goog.net.BrowserChannel.LogSaver.buffer_ =
- new goog.structs.CircularBuffer(1000);
-
-
-/**
- * Whether we're currently accumulating the debug log.
- * @type {boolean}
- * @private
- */
-goog.net.BrowserChannel.LogSaver.enabled_ = false;
-
-
-/**
- * Formatter for saving logs.
- * @type {goog.debug.Formatter}
- * @private
- */
-goog.net.BrowserChannel.LogSaver.formatter_ = new goog.debug.TextFormatter();
-
-
-/**
- * Returns whether the LogSaver is enabled.
- * @return {boolean} Whether saving is enabled or disabled.
- */
-goog.net.BrowserChannel.LogSaver.isEnabled = function() {
- return goog.net.BrowserChannel.LogSaver.enabled_;
-};
-
-
-/**
- * Enables of disables the LogSaver.
- * @param {boolean} enable Whether to enable or disable saving.
- */
-goog.net.BrowserChannel.LogSaver.setEnabled = function(enable) {
- if (enable == goog.net.BrowserChannel.LogSaver.enabled_) {
- return;
- }
-
- var fn = goog.net.BrowserChannel.LogSaver.addLogRecord;
- var logger = goog.debug.Logger.getLogger('goog.net');
- if (enable) {
- logger.addHandler(fn);
- } else {
- logger.removeHandler(fn);
- }
-};
-
-
-/**
- * Adds a log record.
- * @param {goog.debug.LogRecord} logRecord the LogRecord.
- */
-goog.net.BrowserChannel.LogSaver.addLogRecord = function(logRecord) {
- goog.net.BrowserChannel.LogSaver.buffer_.add(
- goog.net.BrowserChannel.LogSaver.formatter_.formatRecord(logRecord));
-};
-
-
-/**
- * Returns the log as a single string.
- * @return {string} The log as a single string.
- */
-goog.net.BrowserChannel.LogSaver.getBuffer = function() {
- return goog.net.BrowserChannel.LogSaver.buffer_.getValues().join('');
-};
-
-
-/**
- * Clears the buffer
- */
-goog.net.BrowserChannel.LogSaver.clearBuffer = function() {
- goog.net.BrowserChannel.LogSaver.buffer_.clear();
-};
-
-
-
-/**
- * Interface for the browser channel handler
- * @constructor
- */
-goog.net.BrowserChannel.Handler = function() {
-};
-
-
-/**
- * Callback handler for when a batch of response arrays is received from the
- * server.
- * @type {Function}
- */
-goog.net.BrowserChannel.Handler.prototype.channelHandleMultipleArrays = null;
-
-
-/**
- * Whether it's okay to make a request to the server. A handler can return
- * false if the channel should fail. For example, if the user has logged out,
- * the handler may want all requests to fail immediately.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @return {goog.net.BrowserChannel.Error} An error code. The code should
- * return goog.net.BrowserChannel.Error.OK to indicate it's okay. Any other
- * error code will cause a failure.
- */
-goog.net.BrowserChannel.Handler.prototype.okToMakeRequest =
- function(browserChannel) {
- return goog.net.BrowserChannel.Error.OK;
-};
-
-
-/**
- * Indicates the BrowserChannel has successfully negotiated with the server
- * and can now send and receive data.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- */
-goog.net.BrowserChannel.Handler.prototype.channelOpened =
- function(browserChannel) {
-};
-
-
-/**
- * New input is available for the application to process.
- *
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @param {Array} array The data array.
- */
-goog.net.BrowserChannel.Handler.prototype.channelHandleArray =
- function(browserChannel, array) {
-};
-
-
-/**
- * Indicates an error occurred on the BrowserChannel.
- *
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @param {goog.net.BrowserChannel.Error} error The error code.
- */
-goog.net.BrowserChannel.Handler.prototype.channelError =
- function(browserChannel, error) {
-};
-
-
-/**
- * Indicates the BrowserChannel is closed. Also notifies about which maps,
- * if any, that may not have been delivered to the server.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @param {Array.<goog.net.BrowserChannel.QueuedMap>=} opt_pendingMaps The
- * array of pending maps, which may or may not have been delivered to the
- * server.
- * @param {Array.<goog.net.BrowserChannel.QueuedMap>=} opt_undeliveredMaps
- * The array of undelivered maps, which have definitely not been delivered
- * to the server.
- */
-goog.net.BrowserChannel.Handler.prototype.channelClosed =
- function(browserChannel, opt_pendingMaps, opt_undeliveredMaps) {
-};
-
-
-/**
- * Gets any parameters that should be added at the time another connection is
- * made to the server.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @return {Object} Extra parameter keys and values to add to the
- * requests.
- */
-goog.net.BrowserChannel.Handler.prototype.getAdditionalParams =
- function(browserChannel) {
- return {};
-};
-
-
-/**
- * Gets the URI of an image that can be used to test network connectivity.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @return {goog.Uri?} A custom URI to load for the network test.
- */
-goog.net.BrowserChannel.Handler.prototype.getNetworkTestImageUri =
- function(browserChannel) {
- return null;
-};
-
-
-/**
- * Gets whether this channel is currently active. This is used to determine the
- * length of time to wait before retrying.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @return {boolean} Whether the channel is currently active.
- */
-goog.net.BrowserChannel.Handler.prototype.isActive = function(browserChannel) {
- return true;
-};
-
-
-/**
- * Called by the channel if enumeration of the map throws an exception.
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @param {Object} map The map that can't be enumerated.
- */
-goog.net.BrowserChannel.Handler.prototype.badMapError =
- function(browserChannel, map) {
- return;
-};
-
-
-/**
- * Allows the handler to override a host prefix provided by the server. Will
- * be called whenever the channel has received such a prefix and is considering
- * its use.
- * @param {?string} serverHostPrefix The host prefix provided by the server.
- * @return {?string} The host prefix the client should use.
- */
-goog.net.BrowserChannel.Handler.prototype.correctHostPrefix =
- function(serverHostPrefix) {
- return serverHostPrefix;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel_test.html.svn-base
deleted file mode 100644
index 89bce9e..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browserchannel_test.html.svn-base
+++ /dev/null
@@ -1,1200 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2009 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.BrowserChannel</title>
-<script type="text/javascript" src="../base.js"></script>
-<script type="text/javascript">
- goog.require('goog.Timer');
- goog.require('goog.dom');
- goog.require('goog.functions');
- goog.require('goog.json');
- goog.require('goog.net.BrowserChannel');
- goog.require('goog.net.ChannelRequest');
- goog.require('goog.net.tmpnetwork');
- goog.require('goog.string.StringBuffer');
- goog.require('goog.structs.Map');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.asserts');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-
-<!-- Define unit tests. -->
-<script type="text/javascript" >
-
-/**
- * Delay between a network failure and the next network request.
- */
-var RETRY_TIME = 1000;
-
-/**
- * A really long time - used to make sure no more timeouts will fire.
- */
-var ALL_DAY_MS = 1000 * 60 * 60 * 24;
-
-var browserChannel;
-var handler;
-var mockClock;
-var sb;
-var gotError;
-var numStatEvents;
-var lastStatEvent;
-var numTimingEvents;
-var lastPostSize;
-var lastPostRtt;
-var lastPostRetryCount;
-
-// Set to true to see the channel debug output in the browser window.
-var debug = false;
-
-function debugToWindow(message) {
- if (debug) {
- sb.append(message + '<br>');
- goog.dom.getElement('debug').innerHTML = sb.toString();
- }
-}
-
-
-/**
- * Mock ChannelRequest.
- */
-function MockChannelRequest() {}
-MockChannelRequest = function(channel, channelDebug, opt_sessionId,
- opt_requestId, opt_retryId) {
- this.channel_ = channel;
- this.channelDebug_ = channelDebug;
- this.sessionId_ = opt_sessionId;
- this.requestId_ = opt_requestId;
- this.successful_ = true;
- this.lastError_ = null;
- this.lastStatusCode_ = 200;
-
- // For debugging, keep track of whether this is a back or forward channel.
- this.isBack = !!(opt_requestId == 'rpc');
- this.isForward = !this.isBack;
-};
-
-MockChannelRequest.prototype.postData_ = null;
-
-MockChannelRequest.prototype.requestStartTime_ = null;
-
-MockChannelRequest.prototype.setExtraHeaders = function(extraHeaders) {};
-
-MockChannelRequest.prototype.setTimeout = function(timeout) {};
-
-MockChannelRequest.prototype.xmlHttpPost = function(uri, postData,
- decodeChunks) {
- this.channelDebug_.debug('---> POST: ' + uri + ', ' + postData + ', ' +
- decodeChunks);
- this.postData_ = postData;
- this.requestStartTime_ = goog.now()
-};
-
-MockChannelRequest.prototype.xmlHttpGet = function(uri, decodeChunks,
- opt_noClose) {
- this.channelDebug_.debug('<--- GET: ' + uri + ', ' + decodeChunks + ', ' +
- opt_noClose);
- this.requestStartTime_ = goog.now()
-};
-
-MockChannelRequest.prototype.tridentGet = function(uri, usingSecondaryDomain) {
- this.channelDebug_.debug('<---GET (T): ' + uri);
- this.requestStartTime_ = goog.now()
-};
-
-MockChannelRequest.prototype.sendUsingImgTag = function(uri) {
- this.requestStartTime_ = goog.now()
-};
-
-MockChannelRequest.prototype.cancel = function() {
- this.successful_ = false;
-};
-
-MockChannelRequest.prototype.getSuccess = function() {
- return this.successful_;
-};
-
-MockChannelRequest.prototype.getLastError = function() {
- return this.lastError_;
-};
-
-MockChannelRequest.prototype.getLastStatusCode = function() {
- return this.lastStatusCode_;
-};
-
-MockChannelRequest.prototype.getSessionId = function() {
- return this.sessionId_;
-};
-
-MockChannelRequest.prototype.getRequestId = function() {
- return this.requestId_;
-};
-
-MockChannelRequest.prototype.getPostData = function() {
- return this.postData_;
-};
-
-MockChannelRequest.prototype.getRequestStartTime = function() {
- return this.requestStartTime_;
-};
-
-
-function setUpPage() {
- // Use our MockChannelRequests instead of the real ones.
- goog.net.BrowserChannel.createChannelRequest = function(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {
- return new MockChannelRequest(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId);
- };
- sb = new goog.string.StringBuffer();
-
- // Mock out the stat notification code.
- goog.net.BrowserChannel.notifyStatEvent = function(stat) {
- numStatEvents++;
- lastStatEvent = stat;
- };
-
- goog.net.BrowserChannel.notifyTimingEvent = function(size, rtt, retries) {
- numTimingEvents++;
- lastPostSize = size;
- lastPostRtt = rtt;
- lastPostRetryCount = retries;
- };
-}
-
-
-function setUp() {
- numTimingEvents = 0;
- lastPostSize = null;
- lastPostRtt = null;
- lastPostRetryCount = null;
-
- mockClock = new goog.testing.MockClock(true);
- browserChannel = new goog.net.BrowserChannel('1');
- gotError = false;
-
- handler = new goog.net.BrowserChannel.Handler();
- handler.channelOpened = function() {};
- handler.channelError = function(channel, error) {
- gotError = true;
- };
- handler.channelClosed = function(
- channel, opt_pendingMaps, opt_undeliveredMaps) {
- // Mock out the handler, and let it set a formatted user readable string
- // of the undelivered maps which we can use when verifying our assertions.
- if (opt_pendingMaps) {
- this.pendingMapsString = formatArrayOfMaps(opt_pendingMaps);
- }
- if (opt_undeliveredMaps) {
- this.undeliveredMapsString = formatArrayOfMaps(opt_undeliveredMaps);
- }
- };
- handler.channelHandleMultipleArrays = function() {};
- handler.channelHandleArray = function() {};
-
- browserChannel.setHandler(handler);
-
- // Provide a predictable retry time for testing.
- browserChannel.getRetryTime_ = function(retryCount) {
- return RETRY_TIME;
- };
-
- var channelDebug = new goog.net.ChannelDebug();
- channelDebug.debug = function(message) {
- debugToWindow(message);
- };
- browserChannel.setChannelDebug(channelDebug);
-
- numStatEvents = 0;
- lastStatEvent = null;
-}
-
-
-function tearDown() {
- mockClock.dispose();
- debugToWindow('<hr>');
-}
-
-
-/**
- * Helper function to return a formatted string representing an array of maps.
- */
-function formatArrayOfMaps(arrayOfMaps) {
- var result = [];
- for (var i = 0; i < arrayOfMaps.length; i++) {
- var map = arrayOfMaps[i];
- var keys = map.map.getKeys();
- for (var j = 0; j < keys.length; j++) {
- result.push(keys[j] + ':' + map.map.get(keys[j]));
- }
- }
- return result.join(', ');
-}
-
-
-function testFormatArrayOfMaps() {
- // This function is used in a non-trivial test, so let's verify that it works.
- var map1 = new goog.structs.Map();
- map1.set('k1', 'v1');
- map1.set('k2', 'v2');
- var map2 = new goog.structs.Map();
- map2.set('k3', 'v3');
- var map3 = new goog.structs.Map();
- map3.set('k4', 'v4');
- map3.set('k5', 'v5');
- map3.set('k6', 'v6');
-
- // One map.
- var a = [];
- a.push(new goog.net.BrowserChannel.QueuedMap(0, map1));
- assertEquals('k1:v1, k2:v2',
- formatArrayOfMaps(a));
-
- // Many maps.
- var b = [];
- b.push(new goog.net.BrowserChannel.QueuedMap(0, map1));
- b.push(new goog.net.BrowserChannel.QueuedMap(0, map2));
- b.push(new goog.net.BrowserChannel.QueuedMap(0, map3));
- assertEquals('k1:v1, k2:v2, k3:v3, k4:v4, k5:v5, k6:v6',
- formatArrayOfMaps(b));
-}
-
-
-function connect(opt_serverVersion, opt_hostPrefix, opt_uriPrefix) {
- var uriPrefix = opt_uriPrefix || '';
- browserChannel.connect(uriPrefix + '/test', uriPrefix + '/bind', null);
- mockClock.tick(0);
- completeTestConnection();
- completeForwardChannel(opt_serverVersion, opt_hostPrefix);
- completeBackChannel();
-}
-
-
-function disconnect() {
- browserChannel.disconnect();
- mockClock.tick(0);
-}
-
-
-function completeTestConnection() {
- completeForwardTestConnection();
- completeBackTestConnection();
- assertEquals(goog.net.BrowserChannel.State.OPENING,
- browserChannel.getState());
-}
-
-
-function completeForwardTestConnection() {
- browserChannel.connectionTest_.onRequestData(
- browserChannel.connectionTest_,
- '["b"]');
- browserChannel.connectionTest_.onRequestComplete(
- browserChannel.connectionTest_);
- mockClock.tick(0);
-}
-
-
-function completeBackTestConnection() {
- browserChannel.connectionTest_.onRequestData(
- browserChannel.connectionTest_,
- '11111');
- mockClock.tick(0);
-}
-
-
-function completeForwardChannel(opt_serverVersion, opt_hostPrefix) {
- var responseData = '[[0,["c","1234567890ABCDEF",' +
- (opt_hostPrefix ? '"' + opt_hostPrefix + '"' : 'null') +
- (opt_serverVersion ? ',' + opt_serverVersion : '') +
- ']]]';
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- responseData);
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function completeBackChannel() {
- browserChannel.onRequestData(
- browserChannel.backChannelRequest_,
- '[[1,["foo"]]]');
- browserChannel.onRequestComplete(
- browserChannel.backChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function responseVersion7() {
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- goog.net.BrowserChannel.MAGIC_RESPONSE_COOKIE);
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-function responseNoBackchannel(lastArrayIdSentFromServer, outstandingDataSize) {
- responseData = goog.json.serialize(
- [0, lastArrayIdSentFromServer, outstandingDataSize]);
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- responseData);
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-function response(lastArrayIdSentFromServer, outstandingDataSize) {
- responseData = goog.json.serialize(
- [1, lastArrayIdSentFromServer, outstandingDataSize]);
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- responseData
- );
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function receive(data) {
- browserChannel.onRequestData(
- browserChannel.backChannelRequest_,
- '[[1,' + data + ']]');
- browserChannel.onRequestComplete(
- browserChannel.backChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function responseTimeout() {
- browserChannel.forwardChannelRequest_lastError_ =
- goog.net.ChannelRequest.Error.TIMEOUT;
- browserChannel.forwardChannelRequest_.successful_ = false;
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function responseRequestFailed(opt_statusCode) {
- browserChannel.forwardChannelRequest_.lastError_ =
- goog.net.ChannelRequest.Error.STATUS;
- browserChannel.forwardChannelRequest_.lastStatusCode_ =
- opt_statusCode || 503;
- browserChannel.forwardChannelRequest_.successful_ = false;
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function responseUnknownSessionId() {
- browserChannel.forwardChannelRequest_.lastError_ =
- goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID;
- browserChannel.forwardChannelRequest_.successful_ = false;
- browserChannel.onRequestComplete(
- browserChannel.forwardChannelRequest_);
- mockClock.tick(0);
-}
-
-
-function sendMap(key, value) {
- var map = new goog.structs.Map();
- map.set(key, value);
- browserChannel.sendMap(map);
- mockClock.tick(0);
-}
-
-
-function hasForwardChannel() {
- return !!browserChannel.forwardChannelRequest_;
-}
-
-
-function hasBackChannel() {
- return !!browserChannel.backChannelRequest_;
-}
-
-
-function hasDeadBackChannelTimer() {
- return goog.isDefAndNotNull(browserChannel.deadBackChannelTimerId_);
-};
-
-
-function assertHasForwardChannel() {
- assertTrue('Forward channel missing.', hasForwardChannel());
-}
-
-
-function assertHasBackChannel() {
- assertTrue('Back channel missing.', hasBackChannel());
-}
-
-
-function testConnect() {
- connect();
- assertEquals(goog.net.BrowserChannel.State.OPENED,
- browserChannel.getState());
- // If the server specifies no version, the client assumes 6
- assertEquals(6, browserChannel.channelVersion_);
- assertFalse(browserChannel.isBuffered());
-}
-
-function testConnect_backChannelEstablished() {
- connect();
- assertHasBackChannel();
-}
-
-function testConnect_withServerHostPrefix() {
- connect(undefined, 'serverHostPrefix');
- assertEquals('serverHostPrefix', browserChannel.hostPrefix_);
-}
-
-function testConnect_withClientHostPrefix() {
- handler.correctHostPrefix = function(hostPrefix) {
- return 'clientHostPrefix';
- }
- connect();
- assertEquals('clientHostPrefix', browserChannel.hostPrefix_);
-}
-
-function testConnect_overrideServerHostPrefix() {
- handler.correctHostPrefix = function(hostPrefix) {
- return 'clientHostPrefix';
- }
- connect(undefined, 'serverHostPrefix');
- assertEquals('clientHostPrefix', browserChannel.hostPrefix_);
-}
-
-function testConnect_withServerVersion() {
- connect(8);
- assertEquals(8, browserChannel.channelVersion_);
-}
-
-function testConnect_notOkToMakeRequestForTest() {
- handler.okToMakeRequest =
- goog.functions.constant(goog.net.BrowserChannel.Error.NETWORK);
- browserChannel.connect('/test', '/bind', null);
- mockClock.tick(0);
- assertEquals(goog.net.BrowserChannel.State.CLOSED, browserChannel.getState());
-}
-
-function testConnect_notOkToMakeRequestForBind() {
- browserChannel.connect('/test', '/bind', null);
- mockClock.tick(0);
- completeTestConnection();
- handler.okToMakeRequest =
- goog.functions.constant(goog.net.BrowserChannel.Error.NETWORK);
- completeForwardChannel();
- assertEquals(goog.net.BrowserChannel.State.CLOSED, browserChannel.getState());
-}
-
-
-function testSendMap() {
- connect();
- assertEquals(1, numTimingEvents);
- sendMap('foo', 'bar');
- responseVersion7();
- assertEquals(2, numTimingEvents);
-}
-
-
-function testSendMap_twice() {
- connect();
- sendMap('foo1', 'bar1');
- responseVersion7();
- sendMap('foo2', 'bar2');
- responseVersion7();
-}
-
-
-function testSendMap_andReceive() {
- connect();
- sendMap('foo', 'bar');
- responseVersion7();
- receive('["the server reply"]');
-}
-
-
-function testReceive() {
- connect();
- receive('["message from server"]');
- assertHasBackChannel();
-}
-
-
-function testReceive_twice() {
- connect();
- receive('["message one from server"]');
- receive('["message two from server"]');
- assertHasBackChannel();
-}
-
-
-function testReceive_andSendMap() {
- connect();
- receive('["the server reply"]');
- sendMap('foo', 'bar');
- responseVersion7();
- assertHasBackChannel();
-}
-
-
-function testBackChannelRemainsEstablished_afterSingleSendMap() {
- connect();
-
- sendMap('foo', 'bar');
- responseVersion7();
- receive('["ack"]');
-
- assertHasBackChannel();
-}
-
-
-function testBackChannelRemainsEstablished_afterDoubleSendMap() {
- connect();
-
- sendMap('foo1', 'bar1');
- sendMap('foo2', 'bar2');
- responseVersion7();
- receive('["ack"]');
-
- // This assertion would fail prior to CL 13302660.
- assertHasBackChannel();
-}
-
-
-function testTimingEvent(){
- connect();
- assertEquals(1, numTimingEvents);
- sendMap('', '');
- assertEquals(1, numTimingEvents);
- mockClock.tick(20);
- var expSize = browserChannel.forwardChannelRequest_.getPostData().length;
- responseVersion7();
-
- assertEquals(2, numTimingEvents);
- assertEquals(expSize, lastPostSize);
- assertEquals(20, lastPostRtt);
- assertEquals(0, lastPostRetryCount);
-
- sendMap('abcdefg', '123456');
- expSize = browserChannel.forwardChannelRequest_.getPostData().length;
- responseTimeout();
- assertEquals(2, numTimingEvents);
- mockClock.tick(RETRY_TIME + 1);
- responseVersion7();
- assertEquals(3, numTimingEvents);
- assertEquals(expSize, lastPostSize);
- assertEquals(1, lastPostRetryCount);
- assertEquals(1, lastPostRtt);
-
-}
-
-
-/**
- * Make sure that dropping the forward channel retry limit below the retry count
- * reports an error, and prevents another request from firing.
- */
-function testSetFailFastWhileWaitingForRetry() {
- connect();
- assertEquals(1, numTimingEvents);
-
- sendMap('foo', 'bar');
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
-
- // Watchdog timeout.
- responseTimeout();
- assertNotNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
-
- // Almost finish the between-retry timeout.
- mockClock.tick(RETRY_TIME - 1);
- assertNotNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
-
- // Setting max retries to 0 should cancel the timer and raise an error.
- browserChannel.setFailFast(true);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
-
- assertTrue(gotError);
- // We get the error immediately before starting to ping google.com.
- // Simulate that timing out. We should get a network error in addition to the
- // initial failure.
- gotError = false;
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
-
- // Make sure no more retry timers are firing.
- mockClock.tick(ALL_DAY_MS);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
- assertEquals(1, numTimingEvents);
-}
-
-
-/**
- * Make sure that dropping the forward channel retry limit below the retry count
- * reports an error, and prevents another request from firing.
- */
-function testSetFailFastWhileRetryXhrIsInFlight() {
- connect();
- assertEquals(1, numTimingEvents);
-
- sendMap('foo', 'bar');
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
-
- // Watchdog timeout.
- responseTimeout();
- assertNotNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
-
- // Wait for the between-retry timeout.
- mockClock.tick(RETRY_TIME);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(1, browserChannel.forwardChannelRetryCount_);
-
- // Simulate a second watchdog timeout.
- responseTimeout();
- assertNotNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(2, browserChannel.forwardChannelRetryCount_);
-
- // Wait for another between-retry timeout.
- mockClock.tick(RETRY_TIME);
- // Now the third req is in flight.
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(2, browserChannel.forwardChannelRetryCount_);
-
- // Set fail fast, killing the request
- browserChannel.setFailFast(true);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(2, browserChannel.forwardChannelRetryCount_);
-
- assertTrue(gotError);
- // We get the error immediately before starting to ping google.com.
- // Simulate that timing out. We should get a network error in addition to the
- gotError = false;
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
-
- // Make sure no more retry timers are firing.
- mockClock.tick(ALL_DAY_MS);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(2, browserChannel.forwardChannelRetryCount_);
- assertEquals(1, numTimingEvents);
-}
-
-
-/**
- * Makes sure that setting fail fast while not retrying doesn't cause a failure.
- */
-function testSetFailFastAtRetryCount() {
- connect();
- assertEquals(1, numTimingEvents);
-
- sendMap('foo', 'bar');
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
-
- // Set fail fast.
- browserChannel.setFailFast(true);
- // Request should still be alive.
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNotNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
-
- // Watchdog timeout. Now we should get an error.
- responseTimeout();
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
-
- assertTrue(gotError);
- // We get the error immediately before starting to ping google.com.
- // Simulate that timing out. We should get a network error in addition to the
- // initial failure.
- gotError = false;
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
-
- // Make sure no more retry timers are firing.
- mockClock.tick(ALL_DAY_MS);
- assertNull(browserChannel.forwardChannelTimerId_);
- assertNull(browserChannel.forwardChannelRequest_);
- assertEquals(0, browserChannel.forwardChannelRetryCount_);
- assertEquals(1, numTimingEvents);
-}
-
-
-function testRequestFailedClosesChannel() {
- connect();
- assertEquals(1, numTimingEvents);
-
- sendMap('foo', 'bar');
- responseRequestFailed();
-
- assertEquals('Should be closed immediately after request failed.',
- goog.net.BrowserChannel.State.CLOSED, browserChannel.getState());
-
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
-
- assertEquals('Should remain closed after the ping timeout.',
- goog.net.BrowserChannel.State.CLOSED, browserChannel.getState());
- assertEquals(1, numTimingEvents);
-}
-
-
-function testStatEventReportedOnlyOnce() {
- connect();
- sendMap('foo', 'bar');
- numStatEvents = 0;
- lastStatEvent = null;
- responseUnknownSessionId();
-
- assertEquals(1, numStatEvents);
- assertEquals(goog.net.BrowserChannel.Stat.ERROR_OTHER, lastStatEvent);
-
- numStatEvents = 0;
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertEquals('No new stat events should be reported.', 0, numStatEvents);
-}
-
-
-function testStatEventReportedOnlyOnce_onNetworkUp() {
- connect();
- sendMap('foo', 'bar');
- numStatEvents = 0;
- lastStatEvent = null;
- responseRequestFailed();
-
- assertEquals('No stat event should be reported before we know the reason.',
- 0, numStatEvents);
-
- // Let the ping time out.
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
-
- // Assert we report the correct stat event.
- assertEquals(1, numStatEvents);
- assertEquals(goog.net.BrowserChannel.Stat.ERROR_NETWORK, lastStatEvent);
-}
-
-
-function testStatEventReportedOnlyOnce_onNetworkDown() {
- connect();
- sendMap('foo', 'bar');
- numStatEvents = 0;
- lastStatEvent = null;
- responseRequestFailed();
-
- assertEquals('No stat event should be reported before we know the reason.',
- 0, numStatEvents);
-
- // Wait half the ping timeout period, and then fake the network being up.
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT / 2);
- browserChannel.testGoogleComCallback_(true);
-
- // Assert we report the correct stat event.
- assertEquals(1, numStatEvents);
- assertEquals(goog.net.BrowserChannel.Stat.ERROR_OTHER, lastStatEvent);
-}
-
-
-function testOutgoingMapsAwaitsResponse() {
- connect();
- assertEquals(0, browserChannel.outgoingMaps_.length);
-
- sendMap('foo1', 'bar');
- assertEquals(0, browserChannel.outgoingMaps_.length);
- sendMap('foo2', 'bar');
- assertEquals(1, browserChannel.outgoingMaps_.length);
- sendMap('foo3', 'bar');
- assertEquals(2, browserChannel.outgoingMaps_.length);
- sendMap('foo4', 'bar');
- assertEquals(3, browserChannel.outgoingMaps_.length);
-
- responseVersion7();
- // Now the forward channel request is completed and a new started, so all maps
- // are dequeued from the array of outgoing maps into this new forward request.
- assertEquals(0, browserChannel.outgoingMaps_.length);
-}
-
-
-function testUndeliveredMaps_doesNotNotifyWhenSuccessful() {
- handler.channelClosed = function(
- channel, opt_pendingMaps, opt_undeliveredMaps) {
- if (opt_pendingMaps || opt_undeliveredMaps) {
- fail('No pending or undelivered maps should be reported.');
- }
- };
-
- connect();
- sendMap('foo1', 'bar1');
- responseVersion7();
- sendMap('foo2', 'bar2');
- responseVersion7();
- disconnect();
-}
-
-
-function testUndeliveredMaps_doesNotNotifyIfNothingWasSent() {
- handler.channelClosed = function(
- channel, opt_pendingMaps, opt_undeliveredMaps) {
- if (opt_pendingMaps || opt_undeliveredMaps) {
- fail('No pending or undelivered maps should be reported.');
- }
- };
-
- connect();
- mockClock.tick(ALL_DAY_MS);
- disconnect();
-}
-
-
-function testUndeliveredMaps_clearsPendingMapsAfterNotifying() {
- connect();
- sendMap('foo1', 'bar1');
- sendMap('foo2', 'bar2');
- sendMap('foo3', 'bar3');
-
- assertEquals(1, browserChannel.pendingMaps_.length);
- assertEquals(2, browserChannel.outgoingMaps_.length);
-
- disconnect();
-
- assertEquals(0, browserChannel.pendingMaps_.length);
- assertEquals(0, browserChannel.outgoingMaps_.length);
-}
-
-
-function testUndeliveredMaps_notifiesWhenNoResponseReceived() {
- connect();
-
- // First send two messages that succeed.
- sendMap('foo1', 'bar1');
- responseVersion7();
- sendMap('foo2', 'bar2');
- responseVersion7();
-
- // Pretend the server hangs and no longer responds.
- sendMap('foo3', 'bar3');
- sendMap('foo4', 'bar4');
- sendMap('foo5', 'bar5');
-
- // Give up.
- disconnect();
-
- // Assert that we are informed of any undelivered messages; both about
- // #3 that was sent but which we don't know if the server received, and
- // #4 and #5 which remain in the outgoing maps and have not yet been sent.
- assertEquals('foo3:bar3', handler.pendingMapsString);
- assertEquals('foo4:bar4, foo5:bar5', handler.undeliveredMapsString);
-}
-
-
-function testUndeliveredMaps_serviceUnavailable() {
- // Send a few maps, and let one fail.
- connect();
- sendMap('foo1', 'bar1');
- responseVersion7();
- sendMap('foo2', 'bar2');
- responseRequestFailed();
-
- // After a failure, the channel should be closed.
- disconnect();
-
- assertEquals('foo2:bar2', handler.pendingMapsString);
- assertEquals('', handler.undeliveredMapsString);
-}
-
-
-function testUndeliveredMaps_onPingTimeout() {
- connect();
-
- // Send a message.
- sendMap('foo1', 'bar1');
-
- // Fake REQUEST_FAILED, triggering a ping to check the network.
- responseRequestFailed();
-
- // Let the ping time out, unsuccessfully.
- mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
-
- // Assert channel is closed.
- assertEquals(goog.net.BrowserChannel.State.CLOSED,
- browserChannel.getState());
-
- // Assert that the handler is notified about the undelivered messages.
- assertEquals('foo1:bar1', handler.pendingMapsString);
- assertEquals('', handler.undeliveredMapsString);
-}
-
-
-function testResponseNoBackchannelPostNotBeforeBackchannel() {
- connect(8);
- sendMap('foo1', 'bar1');
-
- mockClock.tick(10);
- assertFalse(browserChannel.backChannelRequest_.getRequestStartTime() <
- browserChannel.forwardChannelRequest_.getRequestStartTime());
- responseNoBackchannel();
- assertNotEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_MISSING,
- lastStatEvent);
-}
-
-
-function testResponseNoBackchannel() {
- connect(8);
- sendMap('foo1', 'bar1');
- response(-1, 0);
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE + 1);
- sendMap('foo2', 'bar2');
- assertTrue(browserChannel.backChannelRequest_.getRequestStartTime() +
- goog.net.BrowserChannel.RTT_ESTIMATE <
- browserChannel.forwardChannelRequest_.getRequestStartTime());
- responseNoBackchannel();
- assertEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_MISSING, lastStatEvent);
-}
-
-
-function testResponseNoBackchannelWithNoBackchannel() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertNull(browserChannel.backChannelTimerId_);
- browserChannel.backChannelRequest_.cancel();
- browserChannel.backChannelRequest_ = null;
- responseNoBackchannel();
- assertEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_MISSING, lastStatEvent);
-}
-
-
-function testResponseNoBackchannelWithStartTimer() {
- connect(8);
- sendMap('foo1', 'bar1');
-
- browserChannel.backChannelRequest_.cancel();
- browserChannel.backChannelRequest_ = null;
- browserChannel.backChannelTimerId_ = 123;
- responseNoBackchannel();
- assertNotEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_MISSING,
- lastStatEvent);
-}
-
-
-function testResponseWithNoArraySent() {
- connect(8);
- sendMap('foo1', 'bar1');
-
- // Send a response as if the server hasn't sent down an array.
- response(-1, 0);
-
- // POST response with an array ID lower than our last received is OK.
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-}
-
-
-function testResponseWithArraysMissing() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-
- // Send a response as if the server has sent down seven arrays.
- response(7, 111);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE * 2);
- assertEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD, lastStatEvent);
-}
-
-
-function testMultipleResponsesWithArraysMissing() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-
- // Send a response as if the server has sent down seven arrays.
- response(7, 111);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- sendMap('foo2', 'bar2');
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE);
- response(8, 119);
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE);
- // The original timer should still fire.
- assertEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD, lastStatEvent);
-}
-
-
-function testOnlyRetryOnceBasedOnResponse() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-
- // Send a response as if the server has sent down seven arrays.
- response(7, 111);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- assertTrue(hasDeadBackChannelTimer());
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE * 2);
- assertEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD, lastStatEvent);
- assertEquals(1, browserChannel.backChannelRetryCount_);
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE);
- sendMap('foo2', 'bar2');
- assertFalse(hasDeadBackChannelTimer());
- response(8, 119);
- assertFalse(hasDeadBackChannelTimer());
-}
-
-
-function testResponseWithArraysMissingAndLiveChannel() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-
- // Send a response as if the server has sent down seven arrays.
- response(7, 111);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE);
- assertTrue(hasDeadBackChannelTimer());
- receive('["ack"]');
- assertFalse(hasDeadBackChannelTimer());
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE);
- assertNotEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD, lastStatEvent);
-}
-
-
-function testResponseWithBigOutstandingData() {
- connect(8);
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
-
- // Send a response as if the server has sent down seven arrays and 50kbytes.
- response(7, 50000);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- assertFalse(hasDeadBackChannelTimer());
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE * 2);
- assertNotEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD,
- lastStatEvent);
-}
-
-
-function testResponseInBufferedMode() {
- connect(8);
- browserChannel.useChunked_ = false;
- sendMap('foo1', 'bar1');
- assertEquals(-1, browserChannel.lastPostResponseArrayId_);
- response(7, 111);
-
- assertEquals(1, browserChannel.lastArrayId_);
- assertEquals(7, browserChannel.lastPostResponseArrayId_);
- assertFalse(hasDeadBackChannelTimer());
- mockClock.tick(goog.net.BrowserChannel.RTT_ESTIMATE * 2);
- assertNotEquals(goog.net.BrowserChannel.Stat.BACKCHANNEL_DEAD,
- lastStatEvent);
-}
-
-
-function testResponseWithGarbage() {
- connect(8);
- sendMap('foo1', 'bar1');
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- 'garbage'
- );
- assertEquals(goog.net.BrowserChannel.State.CLOSED,
- browserChannel.getState());
-}
-
-
-function testResponseWithGarbageInArray() {
- connect(8);
- sendMap('foo1', 'bar1');
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- '["garbage"]'
- );
- assertEquals(goog.net.BrowserChannel.State.CLOSED,
- browserChannel.getState());
-}
-
-
-function testResponseWithEvilData() {
- connect(8);
- sendMap('foo1', 'bar1');
- browserChannel.onRequestData(
- browserChannel.forwardChannelRequest_,
- goog.net.BrowserChannel.LAST_ARRAY_ID_RESPONSE_PREFIX +
- '=<script>evil()\<\/script>&' +
- goog.net.BrowserChannel.OUTSTANDING_DATA_RESPONSE_PREFIX +
- '=<script>moreEvil()\<\/script>');
- assertEquals(goog.net.BrowserChannel.State.CLOSED,
- browserChannel.getState());
-}
-
-
-function testPathAbsolute() {
- connect(8, undefined, '/talkgadget');
- assertEquals(browserChannel.backChannelUri_.getDomain(),
- window.location.hostname);
- assertEquals(browserChannel.forwardChannelUri_.getDomain(),
- window.location.hostname);
-}
-
-
-function testPathRelative() {
- connect(8, undefined, 'talkgadget');
- assertEquals(browserChannel.backChannelUri_.getDomain(),
- window.location.hostname);
- assertEquals(browserChannel.forwardChannelUri_.getDomain(),
- window.location.hostname);
-}
-
-
-function testPathWithHost() {
- connect(8, undefined, 'https://example.com');
- assertEquals(browserChannel.backChannelUri_.getScheme(), 'https');
- assertEquals(browserChannel.backChannelUri_.getDomain(), 'example.com');
- assertEquals(browserChannel.forwardChannelUri_.getScheme(), 'https');
- assertEquals(browserChannel.forwardChannelUri_.getDomain(), 'example.com');
-}
-
-</script>
-<div id="debug" style="font-size: small"></div>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browsertestchannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browsertestchannel.js.svn-base
deleted file mode 100644
index 6a66de7..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/browsertestchannel.js.svn-base
+++ /dev/null
@@ -1,541 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of the BrowserTestChannel class. A
- * BrowserTestChannel is used during the first part of channel negotiation
- * with the server to create the channel. It helps us determine whether we're
- * behind a buffering proxy. It also runs the logic to see if the channel
- * has been blocked by a network administrator. This class is part of the
- * BrowserChannel implementation and is not for use by normal application code.
- *
- */
-
-
-goog.provide('goog.net.BrowserTestChannel');
-
-goog.require('goog.json');
-goog.require('goog.net.ChannelRequest');
-goog.require('goog.net.ChannelRequest.Error');
-goog.require('goog.net.tmpnetwork');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Encapsulates the logic for a single BrowserTestChannel.
- *
- * @constructor
- * @param {goog.net.BrowserChannel} channel The BrowserChannel that owns this
- * test channel.
- * @param {goog.net.ChannelDebug} channelDebug A ChannelDebug to use for
- * logging.
- */
-goog.net.BrowserTestChannel = function(channel, channelDebug) {
- /**
- * The BrowserChannel that owns this test channel
- * @type {goog.net.BrowserChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The channel debug to use for logging
- * @type {goog.net.ChannelDebug}
- * @private
- */
- this.channelDebug_ = channelDebug;
-};
-
-
-/**
- * Extra HTTP headers to add to all the requests sent to the server.
- * @type {Object}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.extraHeaders_ = null;
-
-
-/**
- * The test request.
- * @type {goog.net.ChannelRequest}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.request_ = null;
-
-
-/**
- * Whether we have received the first result as an intermediate result. This
- * helps us determine whether we're behind a buffering proxy.
- * @type {boolean}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.receivedIntermediateResult_ = false;
-
-
-/**
- * The time when the test request was started. We use timing in IE as
- * a heuristic for whether we're behind a buffering proxy.
- * @type {?number}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.startTime_ = null;
-
-
-/**
- * The time for of the first result part. We use timing in IE as a
- * heuristic for whether we're behind a buffering proxy.
- * @type {?number}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.firstTime_ = null;
-
-
-/**
- * The time for of the last result part. We use timing in IE as a
- * heuristic for whether we're behind a buffering proxy.
- * @type {?number}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.lastTime_ = null;
-
-
-/**
- * The relative path for test requests.
- * @type {?string}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.path_ = null;
-
-
-/**
- * The state of the state machine for this object.
- *
- * @type {?number}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.state_ = null;
-
-
-/**
- * The last status code received.
- * @type {number}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.lastStatusCode_ = -1;
-
-
-/**
- * A subdomain prefix for using a subdomain in IE for the backchannel
- * requests.
- * @type {?string}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.hostPrefix_ = null;
-
-
-/**
- * A subdomain prefix for testing whether the channel was disabled by
- * a network administrator;
- * @type {?string}
- * @private
- */
-goog.net.BrowserTestChannel.prototype.blockedPrefix_ = null;
-
-
-/**
- * Enum type for the browser test channel state machine
- * @enum {number}
- * @private
- */
-goog.net.BrowserTestChannel.State_ = {
- /**
- * The state for the BrowserTestChannel state machine where we making the
- * initial call to get the server configured parameters.
- */
- INIT: 0,
-
- /**
- * The state for the BrowserTestChannel state machine where we're checking to
- * see if the channel has been blocked.
- */
- CHECKING_BLOCKED: 1,
-
- /**
- * The state for the BrowserTestChannel state machine where we're checking to
- * se if we're behind a buffering proxy.
- */
- CONNECTION_TESTING: 2
-};
-
-
-/**
- * Time in MS for waiting for the request to see if the channel is blocked.
- * If the response takes longer than this many ms, we assume the request has
- * failed.
- * @type {number}
- * @private
- */
-goog.net.BrowserTestChannel.BLOCKED_TIMEOUT_ = 5000;
-
-
-/**
- * Number of attempts to try to see if the check to see if we're blocked
- * succeeds. Sometimes the request can fail because of flaky network conditions
- * and checking multiple times reduces false positives.
- * @type {number}
- * @private
- */
-goog.net.BrowserTestChannel.BLOCKED_RETRIES_ = 3;
-
-
-/**
- * Time in ms between retries of the blocked request
- * @type {number}
- * @private
- */
-goog.net.BrowserTestChannel.BLOCKED_PAUSE_BETWEEN_RETRIES_ = 2000;
-
-
-/**
- * Time between chunks in the test connection that indicates that we
- * are not behind a buffering proxy. This value should be less than or
- * equals to the time between chunks sent from the server.
- * @type {number}
- * @private
- */
-goog.net.BrowserTestChannel.MIN_TIME_EXPECTED_BETWEEN_DATA_ = 500;
-
-
-/**
- * Sets extra HTTP headers to add to all the requests sent to the server.
- *
- * @param {Object} extraHeaders The HTTP headers.
- */
-goog.net.BrowserTestChannel.prototype.setExtraHeaders = function(extraHeaders) {
- this.extraHeaders_ = extraHeaders;
-};
-
-
-/**
- * Starts the test channel. This initiates connections to the server.
- *
- * @param {string} path The relative uri for the test connection.
- */
-goog.net.BrowserTestChannel.prototype.connect = function(path) {
- this.path_ = path;
- var sendDataUri = this.channel_.getForwardChannelUri(this.path_);
-
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_ONE_START);
-
- // the first request returns server specific parameters
- sendDataUri.setParameterValues('MODE', 'init');
- this.request_ = goog.net.BrowserChannel.createChannelRequest(
- this, this.channelDebug_);
- this.request_.setExtraHeaders(this.extraHeaders_);
- this.request_.xmlHttpGet(sendDataUri, false /* decodeChunks */,
- null /* hostPrefix */, true /* opt_noClose */);
- this.state_ = goog.net.BrowserTestChannel.State_.INIT;
- this.startTime_ = goog.now();
-};
-
-
-/**
- * Checks to see whether the channel is blocked. This is for implementing the
- * feature that allows network administrators to block Gmail Chat. The
- * strategy to determine if we're blocked is to try to load an image off a
- * special subdomain that network administrators will block access to if they
- * are trying to block chat. For Gmail Chat, the subdomain is
- * chatenabled.mail.google.com.
- * @private
- */
-goog.net.BrowserTestChannel.prototype.checkBlocked_ = function() {
- var uri = this.channel_.createDataUri(this.blockedPrefix_,
- '/mail/images/cleardot.gif');
- uri.makeUnique();
- goog.net.tmpnetwork.testLoadImageWithRetries(uri.toString(),
- goog.net.BrowserTestChannel.BLOCKED_TIMEOUT_,
- goog.bind(this.checkBlockedCallback_, this),
- goog.net.BrowserTestChannel.BLOCKED_RETRIES_,
- goog.net.BrowserTestChannel.BLOCKED_PAUSE_BETWEEN_RETRIES_);
-};
-
-
-/**
- * Callback for testLoadImageWithRetries to check if browser channel is
- * blocked.
- * @param {boolean} succeeded Whether the request succeeded.
- * @private
- */
-goog.net.BrowserTestChannel.prototype.checkBlockedCallback_ = function(
- succeeded) {
- if (succeeded) {
- this.state_ = goog.net.BrowserTestChannel.State_.CONNECTION_TESTING;
- this.connectStage2_();
- } else {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.CHANNEL_BLOCKED);
- this.channel_.testConnectionBlocked(this);
- }
-};
-
-
-/**
- * Begins the second stage of the test channel where we test to see if we're
- * behind a buffering proxy. The server sends back a multi-chunked response
- * with the first chunk containing the content '1' and then two seconds later
- * sending the second chunk containing the content '2'. Depending on how we
- * receive the content, we can tell if we're behind a buffering proxy.
- * @private
- */
-goog.net.BrowserTestChannel.prototype.connectStage2_ = function() {
- this.channelDebug_.debug('TestConnection: starting stage 2');
- this.request_ = goog.net.BrowserChannel.createChannelRequest(
- this, this.channelDebug_);
- this.request_.setExtraHeaders(this.extraHeaders_);
- var recvDataUri = this.channel_.getBackChannelUri(this.hostPrefix_,
- /** @type {string} */ (this.path_));
-
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_TWO_START);
- if (!goog.net.ChannelRequest.supportsXhrStreaming()) {
- recvDataUri.setParameterValues('TYPE', 'html');
- this.request_.tridentGet(recvDataUri, Boolean(this.hostPrefix_));
- } else {
- recvDataUri.setParameterValues('TYPE', 'xmlhttp');
- this.request_.xmlHttpGet(recvDataUri, false /** decodeChunks */,
- this.hostPrefix_, false /** opt_noClose */);
- }
-};
-
-
-/**
- * Factory method for XhrIo objects.
- * @param {?string} hostPrefix The host prefix, if we need an XhrIo object
- * capable of calling a secondary domain.
- * @return {!goog.net.XhrIo} New XhrIo object.
- */
-goog.net.BrowserTestChannel.prototype.createXhrIo = function(hostPrefix) {
- return this.channel_.createXhrIo(hostPrefix);
-};
-
-
-/**
- * Aborts the test channel.
- */
-goog.net.BrowserTestChannel.prototype.abort = function() {
- if (this.request_) {
- this.request_.cancel();
- this.request_ = null;
- }
- this.lastStatusCode_ = -1;
-};
-
-
-/**
- * Returns whether the test channel is closed. The ChannelRequest object expects
- * this method to be implemented on its handler.
- *
- * @return {boolean} Whether the channel is closed.
- */
-goog.net.BrowserTestChannel.prototype.isClosed = function() {
- return false;
-};
-
-
-/**
- * Callback from ChannelRequest for when new data is received
- *
- * @param {goog.net.ChannelRequest} req The request object.
- * @param {string} responseText The text of the response.
- */
-goog.net.BrowserTestChannel.prototype.onRequestData =
- function(req, responseText) {
- this.lastStatusCode_ = req.getLastStatusCode();
- if (this.state_ == goog.net.BrowserTestChannel.State_.INIT) {
- this.channelDebug_.debug('TestConnection: Got data for stage 1');
- if (!responseText) {
- this.channelDebug_.debug('TestConnection: Null responseText');
- // The server should always send text; something is wrong here
- this.channel_.testConnectionFailure(this,
- goog.net.ChannelRequest.Error.BAD_DATA);
- return;
- }
- /** @preserveTry */
- try {
- var respArray = goog.json.unsafeParse(responseText);
- } catch (e) {
- this.channelDebug_.dumpException(e);
- this.channel_.testConnectionFailure(this,
- goog.net.ChannelRequest.Error.BAD_DATA);
- return;
- }
- this.hostPrefix_ = this.channel_.correctHostPrefix(respArray[0]);
- this.blockedPrefix_ = respArray[1];
- } else if (this.state_ ==
- goog.net.BrowserTestChannel.State_.CONNECTION_TESTING) {
- if (this.receivedIntermediateResult_) {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_TWO_DATA_TWO);
- this.lastTime_ = goog.now();
- } else {
- // '11111' is used instead of '1' to prevent a small amount of buffering
- // by Safari.
- if (responseText == '11111') {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_TWO_DATA_ONE);
- this.receivedIntermediateResult_ = true;
- this.firstTime_ = goog.now();
- if (this.checkForEarlyNonBuffered_()) {
- // If early chunk detection is on, and we passed the tests,
- // assume HTTP_OK, cancel the test and turn on noproxy mode.
- this.lastStatusCode_ = 200;
- this.request_.cancel();
- this.channelDebug_.debug(
- 'Test connection succeeded; using streaming connection');
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.NOPROXY);
- this.channel_.testConnectionFinished(this, true);
- }
- } else {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_TWO_DATA_BOTH);
- this.firstTime_ = this.lastTime_ = goog.now();
- this.receivedIntermediateResult_ = false;
- }
- }
- }
-};
-
-
-/**
- * Callback from ChannelRequest that indicates a request has completed.
- *
- * @param {goog.net.ChannelRequest} req The request object.
- */
-goog.net.BrowserTestChannel.prototype.onRequestComplete =
- function(req) {
- this.lastStatusCode_ = this.request_.getLastStatusCode();
- if (!this.request_.getSuccess()) {
- this.channelDebug_.debug(
- 'TestConnection: request failed, in state ' + this.state_);
- if (this.state_ == goog.net.BrowserTestChannel.State_.INIT) {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_ONE_FAILED);
- } else if (this.state_ ==
- goog.net.BrowserTestChannel.State_.CONNECTION_TESTING) {
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.TEST_STAGE_TWO_FAILED);
- }
- this.channel_.testConnectionFailure(this,
- /** @type {goog.net.ChannelRequest.Error} */
- (this.request_.getLastError()));
- return;
- }
-
- if (this.state_ == goog.net.BrowserTestChannel.State_.INIT) {
- this.channelDebug_.debug(
- 'TestConnection: request complete for initial check');
- if (this.blockedPrefix_) {
- this.state_ = goog.net.BrowserTestChannel.State_.CHECKING_BLOCKED;
- this.checkBlocked_();
- } else {
- this.state_ = goog.net.BrowserTestChannel.State_.CONNECTION_TESTING;
- this.connectStage2_();
- }
- } else if (this.state_ ==
- goog.net.BrowserTestChannel.State_.CONNECTION_TESTING) {
- this.channelDebug_.debug('TestConnection: request complete for stage 2');
- var goodConn = false;
-
- if (!goog.net.ChannelRequest.supportsXhrStreaming()) {
- // we always get Trident responses in separate calls to
- // onRequestData, so we have to check the time they came
- var ms = this.lastTime_ - this.firstTime_;
- if (ms < 200) {
- // TODO: need to empirically verify that this number is OK
- // for slow computers
- goodConn = false;
- } else {
- goodConn = true;
- }
- } else {
- goodConn = this.receivedIntermediateResult_;
- }
-
- if (goodConn) {
- this.channelDebug_.debug(
- 'Test connection succeeded; using streaming connection');
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.NOPROXY);
- this.channel_.testConnectionFinished(this, true);
- } else {
- this.channelDebug_.debug(
- 'Test connection failed; not using streaming');
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.PROXY);
- this.channel_.testConnectionFinished(this, false);
- }
- }
-};
-
-
-/**
- * Returns the last status code received for a request.
- * @return {number} The last status code received for a request.
- */
-goog.net.BrowserTestChannel.prototype.getLastStatusCode = function() {
- return this.lastStatusCode_;
-};
-
-
-/**
- * @return {boolean} Whether we should be using secondary domains when the
- * server instructs us to do so.
- */
-goog.net.BrowserTestChannel.prototype.shouldUseSecondaryDomains = function() {
- return this.channel_.shouldUseSecondaryDomains();
-};
-
-
-/**
- * Gets whether this channel is currently active. This is used to determine the
- * length of time to wait before retrying.
- *
- * @param {goog.net.BrowserChannel} browserChannel The browser channel.
- * @return {boolean} Whether the channel is currently active.
- */
-goog.net.BrowserTestChannel.prototype.isActive =
- function(browserChannel) {
- return this.channel_.isActive();
-};
-
-
-/**
- * @return {boolean} True if test stage 2 detected a non-buffered
- * channel early and early no buffering detection is enabled.
- * @private
- */
-goog.net.BrowserTestChannel.prototype.checkForEarlyNonBuffered_ =
- function() {
- var ms = this.firstTime_ - this.startTime_;
-
- // we always get Trident responses in separate calls to
- // onRequestData, so we have to check the time that the first came in
- // and verify that the data arrived before the second portion could
- // have been sent. For all other browser's we skip the timing test.
- return goog.net.ChannelRequest.supportsXhrStreaming() ||
- ms < goog.net.BrowserTestChannel.MIN_TIME_EXPECTED_BETWEEN_DATA_;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader.js.svn-base
deleted file mode 100644
index 70afa6f..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader.js.svn-base
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Loads a list of URIs in bulk. All requests must be a success
- * in order for the load to be considered a success.
- *
- */
-
-goog.provide('goog.net.BulkLoader');
-
-goog.require('goog.debug.Logger');
-goog.require('goog.events.Event');
-goog.require('goog.events.EventHandler');
-goog.require('goog.events.EventTarget');
-goog.require('goog.net.BulkLoaderHelper');
-goog.require('goog.net.EventType');
-goog.require('goog.net.XhrIo');
-
-
-
-/**
- * Class used to load multiple URIs.
- * @param {Array.<string|goog.Uri>} uris The URIs to load.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.BulkLoader = function(uris) {
- goog.events.EventTarget.call(this);
-
- /**
- * The bulk loader helper.
- * @type {goog.net.BulkLoaderHelper}
- * @private
- */
- this.helper_ = new goog.net.BulkLoaderHelper(uris);
-
- /**
- * The handler for managing events.
- * @type {goog.events.EventHandler}
- * @private
- */
- this.eventHandler_ = new goog.events.EventHandler(this);
-};
-goog.inherits(goog.net.BulkLoader, goog.events.EventTarget);
-
-
-/**
- * A logger.
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.BulkLoader.prototype.logger_ =
- goog.debug.Logger.getLogger('goog.net.BulkLoader');
-
-
-/**
- * Gets the response texts.
- * @return {Array.<string>} The response texts.
- */
-goog.net.BulkLoader.prototype.getResponseTexts = function() {
- return this.helper_.getResponseTexts();
-};
-
-
-/**
- * Starts the process of loading the URIs.
- */
-goog.net.BulkLoader.prototype.load = function() {
- var eventHandler = this.eventHandler_;
- var uris = this.helper_.getUris();
- this.logger_.info('Starting load of code with ' + uris.length + ' uris.');
-
- for (var i = 0; i < uris.length; i++) {
- var xhrIo = new goog.net.XhrIo();
- eventHandler.listen(xhrIo,
- goog.net.EventType.COMPLETE,
- goog.bind(this.handleEvent_, this, i));
-
- xhrIo.send(uris[i]);
- }
-};
-
-
-/**
- * Handles all events fired by the XhrManager.
- * @param {number} id The id of the request.
- * @param {goog.events.Event} e The event.
- * @private
- */
-goog.net.BulkLoader.prototype.handleEvent_ = function(id, e) {
- this.logger_.info('Received event "' + e.type + '" for id ' + id +
- ' with uri ' + this.helper_.getUri(id));
- var xhrIo = /** @type {goog.net.XhrIo} */ (e.target);
- if (xhrIo.isSuccess()) {
- this.handleSuccess_(id, xhrIo);
- } else {
- this.handleError_(id, xhrIo);
- }
-};
-
-
-/**
- * Handles when a request is successful (i.e., completed and response received).
- * Stores thhe responseText and checks if loading is complete.
- * @param {number} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo objects that was used.
- * @private
- */
-goog.net.BulkLoader.prototype.handleSuccess_ = function(
- id, xhrIo) {
- // Save the response text.
- this.helper_.setResponseText(id, xhrIo.getResponseText());
-
- // Check if all response texts have been received.
- if (this.helper_.isLoadComplete()) {
- this.finishLoad_();
- }
- xhrIo.dispose();
-};
-
-
-/**
- * Handles when a request has ended in error (i.e., all retries completed and
- * none were successful). Cancels loading of the URI's.
- * @param {number|string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo objects that was used.
- * @private
- */
-goog.net.BulkLoader.prototype.handleError_ = function(
- id, xhrIo) {
- // TODO(user): Abort all pending requests.
-
- // Dispatch the ERROR event.
- this.dispatchEvent(goog.net.EventType.ERROR);
- xhrIo.dispose();
-};
-
-
-/**
- * Finishes the load of the URI's. Dispatches the SUCCESS event.
- * @private
- */
-goog.net.BulkLoader.prototype.finishLoad_ = function() {
- this.logger_.info('All uris loaded.');
-
- // Dispatch the SUCCESS event.
- this.dispatchEvent(goog.net.EventType.SUCCESS);
-};
-
-
-/** @override */
-goog.net.BulkLoader.prototype.disposeInternal = function() {
- goog.net.BulkLoader.superClass_.disposeInternal.call(this);
-
- this.eventHandler_.dispose();
- this.eventHandler_ = null;
-
- this.helper_.dispose();
- this.helper_ = null;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader_test.html.svn-base
deleted file mode 100644
index 7b904fd..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloader_test.html.svn-base
+++ /dev/null
@@ -1,232 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.BulkLoader</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.events.EventHandler');
- goog.require('goog.net.BulkLoader');
- goog.require('goog.net.EventType');
- goog.require('goog.testing.jsunit');
- goog.require('goog.testing.MockClock');
-</script>
-</head>
-<body>
-<script type="text/javascript">
-
- /**
- * Test interval between sending uri requests to the server.
- */
- var DELAY_INTERVAL_BETWEEN_URI_REQUESTS = 5;
-
- /**
- * Test interval before a response is received for a URI request.
- */
- var DELAY_INTERVAL_FOR_URI_LOAD = 15;
-
- var clock;
- var loadSuccess, loadError;
- var successResponseTexts;
-
- function setUpPage() {
- clock = new goog.testing.MockClock(true);
- }
-
- function tearDownPage() {
- clock.dispose();
- }
-
- function setUp() {
- loadSuccess = false;
- loadError = false;
- successResponseTexts = [];
- }
-
- /**
- * Gets the successful bulkloader for the specified uris with some
- * modifications for testability.
- * <ul>
- * <li> Added onSuccess methods to simulate success while loading uris.
- * <li> The send function of the XhrManager used by the bulkloader
- * calls the onSuccess function after a specified time interval.
- * </ul>
- * @param {Array.<string>} uris The URIs.
- */
- function getSuccessfulBulkLoader(uris) {
- var bulkLoader = new goog.net.BulkLoader(uris);
- bulkLoader.load = function() {
- var uris = this.helper_.getUris();
- for (var i = 0; i < uris.length; i++) {
- // This clock tick simulates a delay for processing every URI.
- clock.tick(DELAY_INTERVAL_BETWEEN_URI_REQUESTS);
- // This timeout determines how many ticks after the send request
- // all the URIs will complete loading. This delays the load of
- // the first uri and every subsequent uri by 15 ticks.
- setTimeout(goog.bind(this.onSuccess, this, i, uris[i]),
- DELAY_INTERVAL_FOR_URI_LOAD);
- }
- };
-
- bulkLoader.onSuccess = function(id, uri) {
- var xhrIo = {
- getResponseText: function() {return uri;},
- isSuccess: function() {return true;},
- dispose: function() {}
- };
- this.handleEvent_(id, new goog.events.Event(
- goog.net.EventType.COMPLETE, xhrIo));
- };
-
- var eventHandler = new goog.events.EventHandler();
- eventHandler.listen(bulkLoader,
- goog.net.EventType.SUCCESS,
- handleSuccess);
- eventHandler.listen(bulkLoader,
- goog.net.EventType.ERROR,
- handleError);
-
- return bulkLoader;
- };
-
- /**
- * Gets the non-successful bulkloader for the specified uris with some
- * modifications for testability.
- * <ul>
- * <li> Added onSuccess and onError methods to simulate success and error
- * while loading uris.
- * <li> The send function of the XhrManager used by the bulkloader
- * calls the onSuccess or onError function after a specified time
- * interval.
- * </ul>
- * @param {Array.<string>} uris The URIs.
- */
- function getNonSuccessfulBulkLoader(uris) {
- var bulkLoader = new goog.net.BulkLoader(uris);
- bulkLoader.load = function() {
- var uris = this.helper_.getUris();
- for (var i = 0; i < uris.length; i++) {
- // This clock tick simulates a delay for processing every URI.
- clock.tick(DELAY_INTERVAL_BETWEEN_URI_REQUESTS);
-
- // This timeout determines how many ticks after the send request
- // all the URIs will complete loading in error. This delays the load
- // of the first uri and every subsequent uri by 15 ticks. The URI
- // with id == 2 is in error.
- if (i != 2) {
- setTimeout(goog.bind(this.onSuccess, this, i, uris[i]),
- DELAY_INTERVAL_FOR_URI_LOAD);
- } else {
- setTimeout(goog.bind(this.onError, this, i, uris[i]),
- DELAY_INTERVAL_FOR_URI_LOAD);
- }
- }
- };
-
- bulkLoader.onSuccess = function(id, uri) {
- var xhrIo = {
- getResponseText: function() {return uri;},
- isSuccess: function() {return true;},
- dispose: function() {}
- };
- this.handleEvent_(id, new goog.events.Event(
- goog.net.EventType.COMPLETE, xhrIo));
- };
-
- bulkLoader.onError = function(id) {
- var xhrIo = {
- getResponseText: function() {return null;},
- isSuccess: function() {return false;},
- dispose: function() {}
- };
- this.handleEvent_(id, new goog.events.Event(
- goog.net.EventType.ERROR, xhrIo));
- };
-
- var eventHandler = new goog.events.EventHandler();
- eventHandler.listen(bulkLoader,
- goog.net.EventType.SUCCESS,
- handleSuccess);
- eventHandler.listen(bulkLoader,
- goog.net.EventType.ERROR,
- handleError);
-
- return bulkLoader;
- };
-
- function handleSuccess(e) {
- loadSuccess = true;
- successResponseTexts = e.target.getResponseTexts();
- }
-
- function handleError(e) {
- loadError = true;
- }
-
- /**
- * Test successful loading of URIs using the bulkloader.
- */
- function testBulkLoaderLoadSuccess() {
- var uris = ['a', 'b', 'c'];
- var bulkLoader = getSuccessfulBulkLoader(uris);
-
- bulkLoader.load();
-
- clock.tick(2);
- assertFalse(
- 'The bulk loader is not yet loaded (after 2 ticks)', loadSuccess);
-
- clock.tick(3);
- assertFalse(
- 'The bulk loader is not yet loaded (after 5 ticks)', loadSuccess);
-
- clock.tick(5);
- assertFalse(
- 'The bulk loader is not yet loaded (after 10 ticks)', loadSuccess);
-
- clock.tick(5);
- assertTrue('The bulk loader is loaded (after 15 ticks)', loadSuccess);
-
- assertArrayEquals('Ensure that the response texts are present',
- successResponseTexts, uris);
- }
-
- /**
- * Test error loading URIs using the bulkloader.
- */
- function testBulkLoaderLoadError() {
- var uris = ['a', 'b', 'c'];
- var bulkLoader = getNonSuccessfulBulkLoader(uris);
-
- bulkLoader.load();
-
- clock.tick(2);
- assertFalse(
- 'The bulk loader is not yet loaded (after 2 ticks)', loadError);
-
- clock.tick(3);
- assertFalse(
- 'The bulk loader is not yet loaded (after 5 ticks)', loadError);
-
- clock.tick(5);
- assertFalse(
- 'The bulk loader is not yet loaded (after 10 ticks)', loadError);
-
- clock.tick(5);
- assertFalse(
- 'The bulk loader is not loaded successfully (after 15 ticks)',
- loadSuccess);
- assertTrue(
- 'The bulk loader is loaded in error (after 15 ticks)', loadError);
- }
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloaderhelper.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloaderhelper.js.svn-base
deleted file mode 100644
index 08d7fa0..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/bulkloaderhelper.js.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Helper class to load a list of URIs in bulk. All URIs
- * must be a successfully loaded in order for the entire load to be considered
- * a success.
- *
- */
-
-goog.provide('goog.net.BulkLoaderHelper');
-
-goog.require('goog.Disposable');
-goog.require('goog.debug.Logger');
-
-
-
-/**
- * Helper class used to load multiple URIs.
- * @param {Array.<string|goog.Uri>} uris The URIs to load.
- * @constructor
- * @extends {goog.Disposable}
- */
-goog.net.BulkLoaderHelper = function(uris) {
- goog.Disposable.call(this);
-
- /**
- * The URIs to load.
- * @type {Array.<string|goog.Uri>}
- * @private
- */
- this.uris_ = uris;
-
- /**
- * The response from the XHR's.
- * @type {Array.<string>}
- * @private
- */
- this.responseTexts_ = [];
-};
-goog.inherits(goog.net.BulkLoaderHelper, goog.Disposable);
-
-
-/**
- * A logger.
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.BulkLoaderHelper.prototype.logger_ =
- goog.debug.Logger.getLogger('goog.net.BulkLoaderHelper');
-
-
-/**
- * Gets the URI by id.
- * @param {number} id The id.
- * @return {string|goog.Uri} The URI specified by the id.
- */
-goog.net.BulkLoaderHelper.prototype.getUri = function(id) {
- return this.uris_[id];
-};
-
-
-/**
- * Gets the URIs.
- * @return {Array.<string|goog.Uri>} The URIs.
- */
-goog.net.BulkLoaderHelper.prototype.getUris = function() {
- return this.uris_;
-};
-
-
-/**
- * Gets the response texts.
- * @return {Array.<string>} The response texts.
- */
-goog.net.BulkLoaderHelper.prototype.getResponseTexts = function() {
- return this.responseTexts_;
-};
-
-
-/**
- * Sets the response text by id.
- * @param {number} id The id.
- * @param {string} responseText The response texts.
- */
-goog.net.BulkLoaderHelper.prototype.setResponseText = function(
- id, responseText) {
- this.responseTexts_[id] = responseText;
-};
-
-
-/**
- * Determines if the load of the URIs is complete.
- * @return {boolean} TRUE iff the load is complete.
- */
-goog.net.BulkLoaderHelper.prototype.isLoadComplete = function() {
- var responseTexts = this.responseTexts_;
- if (responseTexts.length == this.uris_.length) {
- for (var i = 0; i < responseTexts.length; i++) {
- if (!goog.isDefAndNotNull(responseTexts[i])) {
- return false;
- }
- }
- return true;
- }
- return false;
-};
-
-
-/** @override */
-goog.net.BulkLoaderHelper.prototype.disposeInternal = function() {
- goog.net.BulkLoaderHelper.superClass_.disposeInternal.call(this);
-
- this.uris_ = null;
- this.responseTexts_ = null;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channeldebug.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channeldebug.js.svn-base
deleted file mode 100644
index b31f089..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channeldebug.js.svn-base
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of the ChannelDebug class. ChannelDebug provides
- * a utility for tracing and debugging the BrowserChannel requests.
- *
- * TODO(user) - allow client to specify a custom redaction policy
- */
-
-
-/**
- * Namespace for BrowserChannel
- */
-goog.provide('goog.net.ChannelDebug');
-goog.require('goog.debug.Logger');
-goog.require('goog.json');
-
-
-
-/**
- * Logs and keeps a buffer of debugging info for the Channel.
- *
- * @constructor
- */
-goog.net.ChannelDebug = function() {
- /**
- * The logger instance.
- * @type {goog.debug.Logger}
- * @private
- */
- this.logger_ = goog.debug.Logger.getLogger('goog.net.BrowserChannel');
-};
-
-
-/**
- * Gets the logger used by this ChannelDebug.
- * @return {goog.debug.Logger} The logger used by this ChannelDebug.
- */
-goog.net.ChannelDebug.prototype.getLogger = function() {
- return this.logger_;
-};
-
-
-/**
- * Logs an XmlHttp request..
- * @param {string} verb The request type (GET/POST).
- * @param {goog.Uri} uri The request destination.
- * @param {string|number|undefined} id The request id.
- * @param {number} attempt Which attempt # the request was.
- * @param {?string} postData The data posted in the request.
- */
-goog.net.ChannelDebug.prototype.xmlHttpChannelRequest =
- function(verb, uri, id, attempt, postData) {
- this.info(
- 'XMLHTTP REQ (' + id + ') [attempt ' + attempt + ']: ' +
- verb + '\n' + uri + '\n' +
- this.maybeRedactPostData_(postData));
-};
-
-
-/**
- * Logs the meta data received from an XmlHttp request.
- * @param {string} verb The request type (GET/POST).
- * @param {goog.Uri} uri The request destination.
- * @param {string|number|undefined} id The request id.
- * @param {number} attempt Which attempt # the request was.
- * @param {goog.net.XmlHttp.ReadyState} readyState The ready state.
- * @param {number} statusCode The HTTP status code.
- */
-goog.net.ChannelDebug.prototype.xmlHttpChannelResponseMetaData =
- function(verb, uri, id, attempt, readyState, statusCode) {
- this.info(
- 'XMLHTTP RESP (' + id + ') [ attempt ' + attempt + ']: ' +
- verb + '\n' + uri + '\n' + readyState + ' ' + statusCode);
-};
-
-
-/**
- * Logs the response data received from an XmlHttp request.
- * @param {string|number|undefined} id The request id.
- * @param {?string} responseText The response text.
- * @param {?string=} opt_desc Optional request description.
- */
-goog.net.ChannelDebug.prototype.xmlHttpChannelResponseText =
- function(id, responseText, opt_desc) {
- this.info(
- 'XMLHTTP TEXT (' + id + '): ' +
- this.redactResponse_(responseText) +
- (opt_desc ? ' ' + opt_desc : ''));
-};
-
-
-/**
- * Logs a Trident ActiveX request.
- * @param {string} verb The request type (GET/POST).
- * @param {goog.Uri} uri The request destination.
- * @param {string|number|undefined} id The request id.
- * @param {number} attempt Which attempt # the request was.
- */
-goog.net.ChannelDebug.prototype.tridentChannelRequest =
- function(verb, uri, id, attempt) {
- this.info(
- 'TRIDENT REQ (' + id + ') [ attempt ' + attempt + ']: ' +
- verb + '\n' + uri);
-};
-
-
-/**
- * Logs the response text received from a Trident ActiveX request.
- * @param {string|number|undefined} id The request id.
- * @param {string} responseText The response text.
- */
-goog.net.ChannelDebug.prototype.tridentChannelResponseText =
- function(id, responseText) {
- this.info(
- 'TRIDENT TEXT (' + id + '): ' +
- this.redactResponse_(responseText));
-};
-
-
-/**
- * Logs the done response received from a Trident ActiveX request.
- * @param {string|number|undefined} id The request id.
- * @param {boolean} successful Whether the request was successful.
- */
-goog.net.ChannelDebug.prototype.tridentChannelResponseDone =
- function(id, successful) {
- this.info(
- 'TRIDENT TEXT (' + id + '): ' + successful ? 'success' : 'failure');
-};
-
-
-/**
- * Logs a request timeout.
- * @param {goog.Uri} uri The uri that timed out.
- */
-goog.net.ChannelDebug.prototype.timeoutResponse = function(uri) {
- this.info('TIMEOUT: ' + uri);
-};
-
-
-/**
- * Logs a debug message.
- * @param {string} text The message.
- */
-goog.net.ChannelDebug.prototype.debug = function(text) {
- this.info(text);
-};
-
-
-/**
- * Logs an exception
- * @param {Error} e The error or error event.
- * @param {string=} opt_msg The optional message, defaults to 'Exception'.
- */
-goog.net.ChannelDebug.prototype.dumpException = function(e, opt_msg) {
- this.severe((opt_msg || 'Exception') + e);
-};
-
-
-/**
- * Logs an info message.
- * @param {string} text The message.
- */
-goog.net.ChannelDebug.prototype.info = function(text) {
- this.logger_.info(text);
-};
-
-
-/**
- * Logs a warning message.
- * @param {string} text The message.
- */
-goog.net.ChannelDebug.prototype.warning = function(text) {
- this.logger_.warning(text);
-};
-
-
-/**
- * Logs a severe message.
- * @param {string} text The message.
- */
-goog.net.ChannelDebug.prototype.severe = function(text) {
- this.logger_.severe(text);
-};
-
-
-/**
- * Removes potentially private data from a response so that we don't
- * accidentally save private and personal data to the server logs.
- * @param {?string} responseText A JSON response to clean.
- * @return {?string} The cleaned response.
- * @private
- */
-goog.net.ChannelDebug.prototype.redactResponse_ = function(responseText) {
- // first check if it's not JS - the only non-JS should be the magic cookie
- if (!responseText ||
- responseText == goog.net.BrowserChannel.MAGIC_RESPONSE_COOKIE) {
- return responseText;
- }
- /** @preserveTry */
- try {
- var responseArray = goog.json.unsafeParse(responseText);
-
- for (var i = 0; i < responseArray.length; i++) {
- if (goog.isArray(responseArray[i])) {
- this.maybeRedactArray_(responseArray[i]);
- }
- }
-
- return goog.json.serialize(responseArray);
- } catch (e) {
- this.debug('Exception parsing expected JS array - probably was not JS');
- return responseText;
- }
-};
-
-
-/**
- * Removes data from a response array that may be sensitive.
- * @param {Array} array The array to clean.
- * @private
- */
-goog.net.ChannelDebug.prototype.maybeRedactArray_ = function(array) {
- if (array.length < 2) {
- return;
- }
- var dataPart = array[1];
- if (!goog.isArray(dataPart)) {
- return;
- }
- if (dataPart.length < 1) {
- return;
- }
-
- var type = dataPart[0];
- if (type != 'noop' && type != 'stop') {
- // redact all fields in the array
- for (var i = 1; i < dataPart.length; i++) {
- dataPart[i] = '';
- }
- }
-};
-
-
-/**
- * Removes potentially private data from a request POST body so that we don't
- * accidentally save private and personal data to the server logs.
- * @param {?string} data The data string to clean.
- * @return {?string} The data string with sensitive data replaced by 'redacted'.
- * @private
- */
-goog.net.ChannelDebug.prototype.maybeRedactPostData_ = function(data) {
- if (!data) {
- return null;
- }
- var out = '';
- var params = data.split('&');
- for (var i = 0; i < params.length; i++) {
- var param = params[i];
- var keyValue = param.split('=');
- if (keyValue.length > 1) {
- var key = keyValue[0];
- var value = keyValue[1];
-
- var keyParts = key.split('_');
- if (keyParts.length >= 2 && keyParts[1] == 'type') {
- out += key + '=' + value + '&';
- } else {
- out += key + '=' + 'redacted' + '&';
- }
- }
- }
- return out;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest.js.svn-base
deleted file mode 100644
index 919962d..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest.js.svn-base
+++ /dev/null
@@ -1,1139 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of the ChannelRequest class. The ChannelRequest
- * object encapsulates the logic for making a single request, either for the
- * forward channel, back channel, or test channel, to the server. It contains
- * the logic for the three types of transports we use in the BrowserChannel:
- * XMLHTTP, Trident ActiveX (ie only), and Image request. It provides timeout
- * detection. This class is part of the BrowserChannel implementation and is not
- * for use by normal application code.
- *
- */
-
-
-goog.provide('goog.net.ChannelRequest');
-goog.provide('goog.net.ChannelRequest.Error');
-
-goog.require('goog.Timer');
-goog.require('goog.events');
-goog.require('goog.events.EventHandler');
-goog.require('goog.net.EventType');
-goog.require('goog.net.XmlHttp.ReadyState');
-goog.require('goog.object');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Creates a ChannelRequest object which encapsulates a request to the server.
- * A new ChannelRequest is created for each request to the server.
- *
- * @param {goog.net.BrowserChannel|goog.net.BrowserTestChannel} channel
- * The BrowserChannel that owns this request.
- * @param {goog.net.ChannelDebug} channelDebug A ChannelDebug to use for
- * logging.
- * @param {string=} opt_sessionId The session id for the channel.
- * @param {string|number=} opt_requestId The request id for this request.
- * @param {number=} opt_retryId The retry id for this request.
- * @constructor
- */
-goog.net.ChannelRequest = function(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {
- /**
- * The BrowserChannel object that owns the request.
- * @type {goog.net.BrowserChannel|goog.net.BrowserTestChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The channel debug to use for logging
- * @type {goog.net.ChannelDebug}
- * @private
- */
- this.channelDebug_ = channelDebug;
-
- /**
- * The Session ID for the channel.
- * @type {string|undefined}
- * @private
- */
- this.sid_ = opt_sessionId;
-
- /**
- * The RID (request ID) for the request.
- * @type {string|number|undefined}
- * @private
- */
- this.rid_ = opt_requestId;
-
-
- /**
- * The attempt number of the current request.
- * @type {number}
- * @private
- */
- this.retryId_ = opt_retryId || 1;
-
-
- /**
- * The timeout in ms before failing the request.
- * @type {number}
- * @private
- */
- this.timeout_ = goog.net.ChannelRequest.TIMEOUT_MS;
-
- /**
- * An object to keep track of the channel request event listeners.
- * @type {!goog.events.EventHandler}
- * @private
- */
- this.eventHandler_ = new goog.events.EventHandler(this);
-
- /**
- * A timer for polling responseText in browsers that don't fire
- * onreadystatechange during incremental loading of responseText.
- * @type {goog.Timer}
- * @private
- */
- this.pollingTimer_ = new goog.Timer();
-
- this.pollingTimer_.setInterval(goog.net.ChannelRequest.POLLING_INTERVAL_MS);
-};
-
-
-/**
- * Extra HTTP headers to add to all the requests sent to the server.
- * @type {Object}
- * @private
- */
-goog.net.ChannelRequest.prototype.extraHeaders_ = null;
-
-
-/**
- * Whether the request was successful. This is only set to true after the
- * request successfuly completes.
- * @type {boolean}
- * @private
- */
-goog.net.ChannelRequest.prototype.successful_ = false;
-
-
-/**
- * The TimerID of the timer used to detect if the request has timed-out.
- * @type {?number}
- * @private
- */
-goog.net.ChannelRequest.prototype.watchDogTimerId_ = null;
-
-
-/**
- * The time in the future when the request will timeout.
- * @type {?number}
- * @private
- */
-goog.net.ChannelRequest.prototype.watchDogTimeoutTime_ = null;
-
-
-/**
- * The time the request started.
- * @type {?number}
- * @private
- */
-goog.net.ChannelRequest.prototype.requestStartTime_ = null;
-
-
-/**
- * The type of request (XMLHTTP, IMG, Trident)
- * @type {?number}
- * @private
- */
-goog.net.ChannelRequest.prototype.type_ = null;
-
-
-/**
- * The base Uri for the request. The includes all the parameters except the
- * one that indicates the retry number.
- * @type {goog.Uri?}
- * @private
- */
-goog.net.ChannelRequest.prototype.baseUri_ = null;
-
-
-/**
- * The request Uri that was actually used for the most recent request attempt.
- * @type {goog.Uri?}
- * @private
- */
-goog.net.ChannelRequest.prototype.requestUri_ = null;
-
-
-/**
- * The post data, if the request is a post.
- * @type {?string}
- * @private
- */
-goog.net.ChannelRequest.prototype.postData_ = null;
-
-
-/**
- * The XhrLte request if the request is using XMLHTTP
- * @type {goog.net.XhrIo}
- * @private
- */
-goog.net.ChannelRequest.prototype.xmlHttp_ = null;
-
-
-/**
- * The position of where the next unprocessed chunk starts in the response
- * text.
- * @type {number}
- * @private
- */
-goog.net.ChannelRequest.prototype.xmlHttpChunkStart_ = 0;
-
-
-/**
- * The Trident instance if the request is using Trident.
- * @type {ActiveXObject}
- * @private
- */
-goog.net.ChannelRequest.prototype.trident_ = null;
-
-
-/**
- * The verb (Get or Post) for the request.
- * @type {?string}
- * @private
- */
-goog.net.ChannelRequest.prototype.verb_ = null;
-
-
-/**
- * The last error if the request failed.
- * @type {?goog.net.ChannelRequest.Error}
- * @private
- */
-goog.net.ChannelRequest.prototype.lastError_ = null;
-
-
-/**
- * The last status code received.
- * @type {number}
- * @private
- */
-goog.net.ChannelRequest.prototype.lastStatusCode_ = -1;
-
-
-/**
- * Whether to send the Connection:close header as part of the request.
- * @type {boolean}
- * @private
- */
-goog.net.ChannelRequest.prototype.sendClose_ = true;
-
-
-/**
- * Whether the request has been cancelled due to a call to cancel.
- * @type {boolean}
- * @private
- */
-goog.net.ChannelRequest.prototype.cancelled_ = false;
-
-
-/**
- * Default timeout in MS for a request. The server must return data within this
- * time limit for the request to not timeout.
- * @type {number}
- */
-goog.net.ChannelRequest.TIMEOUT_MS = 45 * 1000;
-
-
-/**
- * How often to poll (in MS) for changes to responseText in browsers that don't
- * fire onreadystatechange during incremental loading of responseText.
- * @type {number}
- */
-goog.net.ChannelRequest.POLLING_INTERVAL_MS = 250;
-
-
-/**
- * Minimum version of Safari that receives a non-null responseText in ready
- * state interactive.
- * @type {string}
- * @private
- */
-goog.net.ChannelRequest.MIN_WEBKIT_FOR_INTERACTIVE_ = '420+';
-
-
-/**
- * Enum for channel requests type
- * @enum {number}
- * @private
- */
-goog.net.ChannelRequest.Type_ = {
- /**
- * XMLHTTP requests.
- */
- XML_HTTP: 1,
-
- /**
- * IMG requests.
- */
- IMG: 2,
-
- /**
- * Requests that use the MSHTML ActiveX control.
- */
- TRIDENT: 3
-};
-
-
-/**
- * Enum type for identifying a ChannelRequest error.
- * @enum {number}
- */
-goog.net.ChannelRequest.Error = {
- /**
- * Errors due to a non-200 status code.
- */
- STATUS: 0,
-
- /**
- * Errors due to no data being returned.
- */
- NO_DATA: 1,
-
- /**
- * Errors due to a timeout.
- */
- TIMEOUT: 2,
-
- /**
- * Errors due to the server returning an unknown.
- */
- UNKNOWN_SESSION_ID: 3,
-
- /**
- * Errors due to bad data being received.
- */
- BAD_DATA: 4,
-
- /**
- * Errors due to the handler throwing an exception.
- */
- HANDLER_EXCEPTION: 5
-};
-
-
-/**
- * Returns a useful error string for debugging based on the specified error
- * code.
- * @param {goog.net.ChannelRequest.Error} errorCode The error code.
- * @param {number} statusCode The HTTP status code.
- * @return {string} The error string for the given code combination.
- */
-goog.net.ChannelRequest.errorStringFromCode = function(errorCode, statusCode) {
- switch (errorCode) {
- case goog.net.ChannelRequest.Error.STATUS:
- return 'Non-200 return code (' + statusCode + ')';
- case goog.net.ChannelRequest.Error.NO_DATA:
- return 'XMLHTTP failure (no data)';
- case goog.net.ChannelRequest.Error.TIMEOUT:
- return 'HttpConnection timeout';
- default:
- return 'Unknown error';
- }
-};
-
-
-/**
- * Sentinel value used to indicate an invalid chunk in a multi-chunk response.
- * @type {Object}
- * @private
- */
-goog.net.ChannelRequest.INVALID_CHUNK_ = {};
-
-
-/**
- * Sentinel value used to indicate an incomplete chunk in a multi-chunk
- * response.
- * @type {Object}
- * @private
- */
-goog.net.ChannelRequest.INCOMPLETE_CHUNK_ = {};
-
-
-/**
- * Returns whether XHR streaming is supported on this browser.
- *
- * If XHR streaming is not supported, we will try to use an ActiveXObject
- * to create a Forever IFrame.
- *
- * @return {boolean} Whether XHR streaming is supported.
- * @see http://code.google.com/p/closure-library/issues/detail?id=346
- */
-goog.net.ChannelRequest.supportsXhrStreaming = function() {
- return !goog.userAgent.IE;
-};
-
-
-/**
- * Sets extra HTTP headers to add to all the requests sent to the server.
- *
- * @param {Object} extraHeaders The HTTP headers.
- */
-goog.net.ChannelRequest.prototype.setExtraHeaders = function(extraHeaders) {
- this.extraHeaders_ = extraHeaders;
-};
-
-
-/**
- * Sets the timeout for a request
- *
- * @param {number} timeout The timeout in MS for when we fail the request.
- */
-goog.net.ChannelRequest.prototype.setTimeout = function(timeout) {
- this.timeout_ = timeout;
-};
-
-
-/**
- * Uses XMLHTTP to send an HTTP POST to the server.
- *
- * @param {goog.Uri} uri The uri of the request.
- * @param {string} postData The data for the post body.
- * @param {boolean} decodeChunks Whether to the result is expected to be
- * encoded for chunking and thus requires decoding.
- */
-goog.net.ChannelRequest.prototype.xmlHttpPost = function(uri, postData,
- decodeChunks) {
- this.type_ = goog.net.ChannelRequest.Type_.XML_HTTP;
- this.baseUri_ = uri.clone().makeUnique();
- this.postData_ = postData;
- this.decodeChunks_ = decodeChunks;
- this.sendXmlHttp_(null /* hostPrefix */);
-};
-
-
-/**
- * Uses XMLHTTP to send an HTTP GET to the server.
- *
- * @param {goog.Uri} uri The uri of the request.
- * @param {boolean} decodeChunks Whether to the result is expected to be
- * encoded for chunking and thus requires decoding.
- * @param {?string} hostPrefix The host prefix, if we might be using a
- * secondary domain. Note that it should also be in the URL, adding this
- * won't cause it to be added to the URL.
- * @param {boolean=} opt_noClose Whether to request that the tcp/ip connection
- * should be closed.
- */
-goog.net.ChannelRequest.prototype.xmlHttpGet = function(uri, decodeChunks,
- hostPrefix, opt_noClose) {
- this.type_ = goog.net.ChannelRequest.Type_.XML_HTTP;
- this.baseUri_ = uri.clone().makeUnique();
- this.postData_ = null;
- this.decodeChunks_ = decodeChunks;
- if (opt_noClose) {
- this.sendClose_ = false;
- }
- this.sendXmlHttp_(hostPrefix);
-};
-
-
-/**
- * Sends a request via XMLHTTP according to the current state of the
- * ChannelRequest object.
- *
- * @param {?string} hostPrefix The host prefix, if we might be using a secondary
- * domain.
- * @private
- */
-goog.net.ChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {
- this.requestStartTime_ = goog.now();
- this.ensureWatchDogTimer_();
-
- // clone the base URI to create the request URI. The request uri has the
- // attempt number as a parameter which helps in debugging.
- this.requestUri_ = this.baseUri_.clone();
- this.requestUri_.setParameterValues('t', this.retryId_);
-
- // send the request either as a POST or GET
- this.xmlHttpChunkStart_ = 0;
- var useSecondaryDomains = this.channel_.shouldUseSecondaryDomains();
- this.xmlHttp_ = this.channel_.createXhrIo(useSecondaryDomains ?
- hostPrefix : null);
- goog.events.listen(this.xmlHttp_, goog.net.EventType.READY_STATE_CHANGE,
- this.xmlHttpHandler_, false, this);
-
- var headers = this.extraHeaders_ ? goog.object.clone(this.extraHeaders_) : {};
- if (this.postData_) {
- // todo (jonp) - use POST constant when Dan defines it
- this.verb_ = 'POST';
- headers['Content-Type'] = 'application/x-www-form-urlencoded';
- this.xmlHttp_.send(this.requestUri_, this.verb_, this.postData_, headers);
- } else {
- // todo (jonp) - use GET constant when Dan defines it
- this.verb_ = 'GET';
-
- // If the user agent is webkit, we cannot send the close header since it is
- // disallowed by the browser. If we attempt to set the "Connection: close"
- // header in WEBKIT browser, it will actually causes an error message.
- if (this.sendClose_ && !goog.userAgent.WEBKIT) {
- headers['Connection'] = 'close';
- }
- this.xmlHttp_.send(this.requestUri_, this.verb_, null, headers);
- }
- this.channelDebug_.xmlHttpChannelRequest(this.verb_,
- this.requestUri_, this.rid_, this.retryId_,
- this.postData_);
-};
-
-
-/**
- * XmlHttp handler
- * @param {goog.events.Event} e Event object, target is a XhrIo object.
- * @private
- */
-goog.net.ChannelRequest.prototype.xmlHttpHandler_ = function(e) {
- var xmlhttp = e.target;
- goog.net.BrowserChannel.onStartExecution();
- /** @preserveTry */
- try {
- if (xmlhttp == this.xmlHttp_) {
- this.onXmlHttpReadyStateChanged_();
- } else {
- this.channelDebug_.warning('Called back with an ' +
- 'unexpected xmlhttp');
- }
- } catch (ex) {
- this.channelDebug_.debug('Failed call to OnXmlHttpReadyStateChanged_');
- if (this.xmlHttp_ && this.xmlHttp_.getResponseText()) {
- this.channelDebug_.dumpException(ex,
- 'ResponseText: ' + this.xmlHttp_.getResponseText());
- } else {
- this.channelDebug_.dumpException(ex, 'No response text');
- }
- } finally {
- goog.net.BrowserChannel.onEndExecution();
- }
-};
-
-
-/**
- * Called by the readystate handler for XMLHTTP requests.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.onXmlHttpReadyStateChanged_ = function() {
- var readyState = this.xmlHttp_.getReadyState();
- // If it is Safari less than 420+, there is a bug that causes null to be
- // in the responseText on ready state interactive so we must wait for
- // ready state complete.
- if (!goog.net.ChannelRequest.supportsXhrStreaming() ||
- (goog.userAgent.WEBKIT &&
- !goog.userAgent.isVersion(
- goog.net.ChannelRequest.MIN_WEBKIT_FOR_INTERACTIVE_))) {
- if (readyState < goog.net.XmlHttp.ReadyState.COMPLETE) {
- // not yet ready
- return;
- }
- } else {
- // we get partial results in browsers that support ready state interactive.
- // We also make sure that getResponseText is not null in interactive mode
- // before we continue. However, we don't do it in Opera because it only
- // fire readyState == INTERACTIVE once. We need the following code to poll
- if (readyState < goog.net.XmlHttp.ReadyState.INTERACTIVE ||
- readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE &&
- !goog.userAgent.OPERA && !this.xmlHttp_.getResponseText()) {
- // not yet ready
- return;
- }
- }
-
- // got some data so cancel the watchdog timer
- this.cancelWatchDogTimer_();
-
- var status = this.xmlHttp_.getStatus();
- this.lastStatusCode_ = status;
- var responseText = this.xmlHttp_.getResponseText();
- if (!responseText) {
- this.channelDebug_.debug('No response text for uri ' +
- this.requestUri_ + ' status ' + status);
- }
- this.successful_ = (status == 200);
-
- this.channelDebug_.xmlHttpChannelResponseMetaData(
- /** @type {string} */ (this.verb_),
- this.requestUri_, this.rid_, this.retryId_, readyState,
- status);
-
- if (!this.successful_) {
- if (status == 400 &&
- responseText.indexOf('Unknown SID') > 0) {
- // the server error string will include 'Unknown SID' which indicates the
- // server doesn't know about the session (maybe it got restarted, maybe
- // the user got moved to another server, etc.,). Handlers can special
- // case this error
- this.lastError_ = goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_UNKNOWN_SESSION_ID);
- } else {
- this.lastError_ = goog.net.ChannelRequest.Error.STATUS;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_BAD_STATUS);
- }
- this.channelDebug_.xmlHttpChannelResponseText(this.rid_, responseText);
- this.cleanup_();
- this.dispatchFailure_();
- return;
- }
-
- if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {
- this.cleanup_();
- }
-
- if (this.decodeChunks_) {
- this.decodeNextChunks_(readyState, responseText);
- if (goog.userAgent.OPERA &&
- readyState == goog.net.XmlHttp.ReadyState.INTERACTIVE) {
- this.startPolling_();
- }
- } else {
- this.channelDebug_.xmlHttpChannelResponseText(
- this.rid_, responseText, null);
- this.safeOnRequestData_(responseText);
- }
-
- if (!this.successful_) {
- return;
- }
-
- if (!this.cancelled_) {
- if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {
- this.channel_.onRequestComplete(this);
- } else {
- // The default is false, the result from this callback shouldn't carry
- // over to the next callback, otherwise the request looks successful if
- // the watchdog timer gets called
- this.successful_ = false;
- this.ensureWatchDogTimer_();
- }
- }
-};
-
-
-/**
- * Decodes the next set of available chunks in the response.
- * @param {number} readyState The value of readyState.
- * @param {string} responseText The value of responseText.
- * @private
- */
-goog.net.ChannelRequest.prototype.decodeNextChunks_ = function(readyState,
- responseText) {
- var decodeNextChunksSuccessful = true;
- while (!this.cancelled_ &&
- this.xmlHttpChunkStart_ < responseText.length) {
- var chunkText = this.getNextChunk_(responseText);
- if (chunkText == goog.net.ChannelRequest.INCOMPLETE_CHUNK_) {
- if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE) {
- // should have consumed entire response when the request is done
- this.lastError_ = goog.net.ChannelRequest.Error.BAD_DATA;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_INCOMPLETE_DATA);
- decodeNextChunksSuccessful = false;
- }
- this.channelDebug_.xmlHttpChannelResponseText(
- this.rid_, null, '[Incomplete Response]');
- break;
- } else if (chunkText == goog.net.ChannelRequest.INVALID_CHUNK_) {
- this.lastError_ = goog.net.ChannelRequest.Error.BAD_DATA;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_BAD_DATA);
- this.channelDebug_.xmlHttpChannelResponseText(
- this.rid_, responseText, '[Invalid Chunk]');
- decodeNextChunksSuccessful = false;
- break;
- } else {
- this.channelDebug_.xmlHttpChannelResponseText(
- this.rid_, /** @type {string} */ (chunkText), null);
- this.safeOnRequestData_(/** @type {string} */ (chunkText));
- }
- }
- if (readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&
- responseText.length == 0) {
- // also an error if we didn't get any response
- this.lastError_ = goog.net.ChannelRequest.Error.NO_DATA;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_NO_DATA);
- decodeNextChunksSuccessful = false;
- }
- this.successful_ = this.successful_ && decodeNextChunksSuccessful;
- if (!decodeNextChunksSuccessful) {
- // malformed response - we make this trigger retry logic
- this.channelDebug_.xmlHttpChannelResponseText(
- this.rid_, responseText, '[Invalid Chunked Response]');
- this.cleanup_();
- this.dispatchFailure_();
- }
-};
-
-
-/**
- * Polls the response for new data.
- * @private
- */
-goog.net.ChannelRequest.prototype.pollResponse_ = function() {
- var readyState = this.xmlHttp_.getReadyState();
- var responseText = this.xmlHttp_.getResponseText();
- if (this.xmlHttpChunkStart_ < responseText.length) {
- this.cancelWatchDogTimer_();
- this.decodeNextChunks_(readyState, responseText);
- if (this.successful_ &&
- readyState != goog.net.XmlHttp.ReadyState.COMPLETE) {
- this.ensureWatchDogTimer_();
- }
- }
-};
-
-
-/**
- * Starts a polling interval for changes to responseText of the
- * XMLHttpRequest, for browsers that don't fire onreadystatechange
- * as data comes in incrementally.
- * @private
- */
-goog.net.ChannelRequest.prototype.startPolling_ = function() {
- this.eventHandler_.listen(this.pollingTimer_, goog.Timer.TICK,
- this.pollResponse_);
- this.pollingTimer_.start();
-};
-
-
-/**
- * Stops the polling interval for changes to responseText.
- * @private
- */
-goog.net.ChannelRequest.prototype.stopPolling_ = function() {
- this.pollingTimer_.stop();
- this.eventHandler_.removeAll();
-};
-
-
-/**
- * Returns the next chunk of a chunk-encoded response. This is not standard
- * HTTP chunked encoding because browsers don't expose the chunk boundaries to
- * the application through XMLHTTP. So we have an additional chunk encoding at
- * the application level that lets us tell where the beginning and end of
- * individual responses are so that we can only try to eval a complete JS array.
- *
- * The encoding is the size of the chunk encoded as a decimal string followed
- * by a newline followed by the data.
- *
- * @param {string} responseText The response text from the XMLHTTP response.
- * @return {string|Object} The next chunk string or a sentinel object
- * indicating a special condition.
- * @private
- */
-goog.net.ChannelRequest.prototype.getNextChunk_ = function(responseText) {
- var sizeStartIndex = this.xmlHttpChunkStart_;
- var sizeEndIndex = responseText.indexOf('\n', sizeStartIndex);
- if (sizeEndIndex == -1) {
- return goog.net.ChannelRequest.INCOMPLETE_CHUNK_;
- }
-
- var sizeAsString = responseText.substring(sizeStartIndex, sizeEndIndex);
- var size = Number(sizeAsString);
- if (isNaN(size)) {
- return goog.net.ChannelRequest.INVALID_CHUNK_;
- }
-
- var chunkStartIndex = sizeEndIndex + 1;
- if (chunkStartIndex + size > responseText.length) {
- return goog.net.ChannelRequest.INCOMPLETE_CHUNK_;
- }
-
- var chunkText = responseText.substr(chunkStartIndex, size);
- this.xmlHttpChunkStart_ = chunkStartIndex + size;
- return chunkText;
-};
-
-
-/**
- * Uses the Trident htmlfile ActiveX control to send a GET request in IE. This
- * is the innovation discovered that lets us get intermediate results in
- * Internet Explorer. Thanks to http://go/kev
- * @param {goog.Uri} uri The uri to request from.
- * @param {boolean} usingSecondaryDomain Whether to use a secondary domain.
- */
-goog.net.ChannelRequest.prototype.tridentGet = function(uri,
- usingSecondaryDomain) {
- this.type_ = goog.net.ChannelRequest.Type_.TRIDENT;
- this.baseUri_ = uri.clone().makeUnique();
- this.tridentGet_(usingSecondaryDomain);
-};
-
-
-/**
- * Starts the Trident request.
- * @param {boolean} usingSecondaryDomain Whether to use a secondary domain.
- * @private
- */
-goog.net.ChannelRequest.prototype.tridentGet_ = function(usingSecondaryDomain) {
- this.requestStartTime_ = goog.now();
- this.ensureWatchDogTimer_();
-
- this.trident_ = new ActiveXObject('htmlfile');
-
- var hostname = '';
- var body = '<html><body>';
- if (usingSecondaryDomain) {
- hostname = window.location.hostname;
- body += '<script>document.domain="' + hostname + '"</scr' + 'ipt>';
- }
- body += '</body></html>';
-
- this.trident_.open();
- this.trident_.write(body);
- this.trident_.close();
-
- this.trident_.parentWindow['m'] = goog.bind(this.onTridentRpcMessage_, this);
- this.trident_.parentWindow['d'] = goog.bind(this.onTridentDone_, this, true);
- this.trident_.parentWindow['rpcClose'] =
- goog.bind(this.onTridentDone_, this, false);
-
- var div = this.trident_.createElement('div');
- this.trident_.parentWindow.document.body.appendChild(div);
- this.requestUri_ = this.baseUri_.clone();
- this.requestUri_.setParameterValue('DOMAIN', hostname);
- this.requestUri_.setParameterValue('t', this.retryId_);
- div.innerHTML = '<iframe src="' + this.requestUri_ + '"></iframe>';
- this.channelDebug_.tridentChannelRequest('GET',
- this.requestUri_, this.rid_, this.retryId_);
-};
-
-
-/**
- * Callback from the Trident htmlfile ActiveX control for when a new message
- * is received.
- *
- * @param {string} msg The data payload.
- * @private
- */
-goog.net.ChannelRequest.prototype.onTridentRpcMessage_ = function(msg) {
- // need to do async b/c this gets called off of the context of the ActiveX
- goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onTridentRpcMessageAsync_, this, msg), 0);
-};
-
-
-/**
- * Callback from the Trident htmlfile ActiveX control for when a new message
- * is received.
- *
- * @param {string} msg The data payload.
- * @private
- */
-goog.net.ChannelRequest.prototype.onTridentRpcMessageAsync_ = function(msg) {
- if (this.cancelled_) {
- return;
- }
- this.channelDebug_.tridentChannelResponseText(this.rid_, msg);
- this.cancelWatchDogTimer_();
- this.safeOnRequestData_(msg);
- this.ensureWatchDogTimer_();
-};
-
-
-/**
- * Callback from the Trident htmlfile ActiveX control for when the request
- * is complete
- *
- * @param {boolean} successful Whether the request successfully completed.
- * @private
- */
-goog.net.ChannelRequest.prototype.onTridentDone_ = function(successful) {
- // need to do async b/c this gets called off of the context of the ActiveX
- goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onTridentDoneAsync_, this, successful), 0);
-};
-
-
-/**
- * Callback from the Trident htmlfile ActiveX control for when the request
- * is complete
- *
- * @param {boolean} successful Whether the request successfully completed.
- * @private
- */
-goog.net.ChannelRequest.prototype.onTridentDoneAsync_ = function(successful) {
- if (this.cancelled_) {
- return;
- }
- this.channelDebug_.tridentChannelResponseDone(
- this.rid_, successful);
- this.cancelWatchDogTimer_();
- this.cleanup_();
- this.successful_ = successful;
- this.channel_.onRequestComplete(this);
-};
-
-
-/**
- * Uses an IMG tag to send an HTTP get to the server. This is only currently
- * used to terminate the connection, as an IMG tag is the most reliable way to
- * send something to the server while the page is getting torn down.
- * @param {goog.Uri} uri The uri to send a request to.
- */
-goog.net.ChannelRequest.prototype.sendUsingImgTag = function(uri) {
- this.type_ = goog.net.ChannelRequest.Type_.IMG;
- this.baseUri_ = uri.clone().makeUnique();
- this.imgTagGet_();
-};
-
-
-/**
- * Starts the IMG request.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.imgTagGet_ = function() {
- var eltImg = new Image();
- eltImg.src = this.baseUri_;
- this.requestStartTime_ = goog.now();
- this.ensureWatchDogTimer_();
-};
-
-
-/**
- * Cancels the request no matter what the underlying transport is.
- */
-goog.net.ChannelRequest.prototype.cancel = function() {
- this.cancelled_ = true;
- this.cancelWatchDogTimer_();
- this.cleanup_();
-};
-
-
-/**
- * Ensures that there is watchdog timeout which is used to ensure that
- * the connection completes in time.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.ensureWatchDogTimer_ = function() {
- this.watchDogTimeoutTime_ = goog.now() + this.timeout_;
- this.startWatchDogTimer_(this.timeout_);
-};
-
-
-/**
- * Starts the watchdog timer which is used to ensure that the connection
- * completes in time.
- * @param {number} time The number of milliseconds to wait.
- * @private
- */
-goog.net.ChannelRequest.prototype.startWatchDogTimer_ = function(time) {
- if (this.watchDogTimerId_ != null) {
- // assertion
- throw Error('WatchDog timer not null');
- }
- this.watchDogTimerId_ = goog.net.BrowserChannel.setTimeout(
- goog.bind(this.onWatchDogTimeout_, this), time);
-};
-
-
-/**
- * Cancels the watchdog timer if it has been started.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.cancelWatchDogTimer_ = function() {
- if (this.watchDogTimerId_) {
- goog.global.clearTimeout(this.watchDogTimerId_);
- this.watchDogTimerId_ = null;
- }
-};
-
-
-/**
- * Called when the watchdog timer is triggered. It also handles a case where it
- * is called too early which we suspect may be happening sometimes
- * (not sure why)
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.onWatchDogTimeout_ = function() {
- this.watchDogTimerId_ = null;
- var now = goog.now();
- if (now - this.watchDogTimeoutTime_ >= 0) {
- this.handleTimeout_();
- } else {
- // got called too early for some reason
- this.channelDebug_.warning('WatchDog timer called too early');
- this.startWatchDogTimer_(this.watchDogTimeoutTime_ - now);
- }
-};
-
-
-/**
- * Called when the request has actually timed out. Will cleanup and notify the
- * channel of the failure.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.handleTimeout_ = function() {
- if (this.successful_) {
- // Should never happen.
- this.channelDebug_.severe(
- 'Received watchdog timeout even though request loaded successfully');
- }
-
- this.channelDebug_.timeoutResponse(this.requestUri_);
- this.cleanup_();
-
- // set error and dispatch failure
- this.lastError_ = goog.net.ChannelRequest.Error.TIMEOUT;
- goog.net.BrowserChannel.notifyStatEvent(
- goog.net.BrowserChannel.Stat.REQUEST_TIMEOUT);
- this.dispatchFailure_();
-};
-
-
-/**
- * Notifies the channel that this request failed.
- * @private
- */
-goog.net.ChannelRequest.prototype.dispatchFailure_ = function() {
- if (this.channel_.isClosed() || this.cancelled_) {
- return;
- }
-
- this.channel_.onRequestComplete(this);
-};
-
-
-/**
- * Cleans up the objects used to make the request. This function is
- * idempotent.
- *
- * @private
- */
-goog.net.ChannelRequest.prototype.cleanup_ = function() {
- this.stopPolling_();
- if (this.xmlHttp_) {
- // clear out this.xmlHttp_ before aborting so we handle getting reentered
- // inside abort
- var xmlhttp = this.xmlHttp_;
- this.xmlHttp_ = null;
- goog.events.unlisten(xmlhttp, goog.net.EventType.READY_STATE_CHANGE,
- this.xmlHttpHandler_, false, this);
- xmlhttp.abort();
- }
-
- if (this.trident_) {
- this.trident_ = null;
- }
-};
-
-
-/**
- * Indicates whether the request was successful. Only valid after the handler
- * is called to indicate completion of the request.
- *
- * @return {boolean} True if the request succeeded.
- */
-goog.net.ChannelRequest.prototype.getSuccess = function() {
- return this.successful_;
-};
-
-
-/**
- * If the request was not successful, returns the reason.
- *
- * @return {?goog.net.ChannelRequest.Error} The last error.
- */
-goog.net.ChannelRequest.prototype.getLastError = function() {
- return this.lastError_;
-};
-
-
-/**
- * Returns the status code of the last request.
- * @return {number} The status code of the last request.
- */
-goog.net.ChannelRequest.prototype.getLastStatusCode = function() {
- return this.lastStatusCode_;
-};
-
-
-/**
- * Returns the session id for this channel.
- *
- * @return {string|undefined} The session ID.
- */
-goog.net.ChannelRequest.prototype.getSessionId = function() {
- return this.sid_;
-};
-
-
-/**
- * Returns the request id for this request. Each request has a unique request
- * id and the request IDs are a sequential increasing count.
- *
- * @return {string|number|undefined} The request ID.
- */
-goog.net.ChannelRequest.prototype.getRequestId = function() {
- return this.rid_;
-};
-
-
-/**
- * Returns the data for a post, if this request is a post.
- *
- * @return {?string} The POST data provided by the request initiator.
- */
-goog.net.ChannelRequest.prototype.getPostData = function() {
- return this.postData_;
-};
-
-
-/**
- * Returns the time that the request started, if it has started.
- *
- * @return {?number} The time the request started, as returned by goog.now().
- */
-goog.net.ChannelRequest.prototype.getRequestStartTime = function() {
- return this.requestStartTime_;
-};
-
-
-/**
- * Helper to call the callback's onRequestData, which catches any
- * exception and cleans up the request.
- * @param {string} data The request data.
- * @private
- */
-goog.net.ChannelRequest.prototype.safeOnRequestData_ = function(data) {
- /** @preserveTry */
- try {
- this.channel_.onRequestData(this, data);
- } catch (e) {
- // Dump debug info, but keep going without closing the channel.
- this.channelDebug_.dumpException(
- e, 'Error in httprequest callback');
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest_test.html.svn-base
deleted file mode 100644
index 1bca491..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/channelrequest_test.html.svn-base
+++ /dev/null
@@ -1,187 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.ChannelRequest</title>
-<script src="../base.js"></script>
-<script>
-goog.require('goog.functions');
-goog.require('goog.net.BrowserChannel');
-goog.require('goog.net.ChannelDebug');
-goog.require('goog.net.ChannelRequest');
-goog.require('goog.testing.MockClock');
-goog.require('goog.testing.jsunit');
-goog.require('goog.testing.net.XhrIo');
-</script>
-</head>
-<body>
-<script>
-
-var mockClock;
-
-/**
- * Time to wait for a network request to time out, before aborting.
- */
-var WATCHDOG_TIME = 2000;
-
-/**
- * A really long time - used to make sure no more timeouts will fire.
- */
-var ALL_DAY_MS = 1000 * 60 * 60 * 24;
-
-
-function setUp() {
- mockClock = new goog.testing.MockClock();
- mockClock.install();
-}
-
-
-function tearDown() {
- mockClock.uninstall();
-}
-
-
-/**
- * Constructs a duck-type BrowserChannel that tracks the completed requests.
- * @constructor
- */
-function MockBrowserChannel() {
- this.createXhrIo = function(domainPrefix) {
- assertNull(domainPrefix);
- var xhrIo = new goog.testing.net.XhrIo();
- xhrIo.abort = xhrIo.abort || function() {
- this.active_ = false;
- };
- return xhrIo;
- }
- this.isClosed = function() {
- return false;
- };
- this.isActive = function() {
- return true;
- };
- this.shouldUseSecondaryDomains = function() {
- return false;
- }
- this.completedRequests = [];
- this.onRequestComplete = function(request) {
- this.completedRequests.push(request);
- };
- this.onRequestData = function(request, data) {};
-}
-
-
-/**
- * Creates a real ChannelRequest object, with some modifications for
- * testability:
- * <ul>
- * <li>The BrowserChannel is a MockBrowserChannel.
- * <li>createXhrIo_() returns the xhrIo that is passed in.
- * <li>The new watchdogTimeoutCallCount property tracks onWatchDogTimeout_()
- * calls.
- * <li>The timeout is set to WATCHDOG_TIME.
- * </ul>
- * @param {goog.testing.net.XhrIo} xhrIo A test XhrIo.
- * @return {goog.net.ChannelRequest} A slightly modified ChannelRequest
- */
-function createChannelRequest(xhrIo) {
- // Install mock browser channel and no-op debug logger.
- var req = new goog.net.ChannelRequest(
- new MockBrowserChannel(),
- new goog.net.ChannelDebug());
-
- // Install test XhrIo.
- req.createXhrIo_ = function() {
- return xhrIo;
- };
-
- // Install watchdogTimeoutCallCount.
- req.watchdogTimeoutCallCount = 0;
- req.originalOnWatchDogTimeout = req.onWatchDogTimeout_;
- req.onWatchDogTimeout_ = function() {
- this.watchdogTimeoutCallCount++;
- return this.originalOnWatchDogTimeout();
- };
-
- req.setTimeout(WATCHDOG_TIME);
-
- return req;
-}
-
-
-/**
- * Creates a test XhrIo, with the abort() method defined.
- * @return {goog.testing.net.XhrIo} A test XhrIo.
- */
-function createXhrIo() {
- var xhrIo = new goog.testing.net.XhrIo();
- xhrIo.abort = xhrIo.abort || function() {
- this.active_ = false;
- };
- return xhrIo;
-}
-
-
-/**
- * Make sure that the request "completes" with an error when the timeout
- * expires.
- */
-function testRequestTimeout() {
- var xhrIo = createXhrIo();
- var req = createChannelRequest(xhrIo);
-
- req.xmlHttpPost(new goog.Uri('some_uri'), 'some_postdata', true);
- assertEquals(0, req.watchdogTimeoutCallCount);
- assertEquals(0, req.channel_.completedRequests.length);
-
- // Watchdog timeout.
- mockClock.tick(WATCHDOG_TIME);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
- assertFalse(req.getSuccess());
-
- // Make sure no more timers are firing.
- mockClock.tick(ALL_DAY_MS);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
-}
-
-function testRequestTimeoutWithUnexpectedException() {
- var xhrIo = createXhrIo();
- var req = createChannelRequest(xhrIo);
- req.channel_.createXhrIo = goog.functions.error('Weird error');
-
- try {
- req.xmlHttpGet(new goog.Uri('some_uri'), true, null);
- fail('Expected error');
- } catch (e) {
- assertEquals('Weird error', e.message);
- }
-
-
- assertEquals(0, req.watchdogTimeoutCallCount);
- assertEquals(0, req.channel_.completedRequests.length);
-
- // Watchdog timeout.
- mockClock.tick(WATCHDOG_TIME);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
- assertFalse(req.getSuccess());
-
- // Make sure no more timers are firing.
- mockClock.tick(ALL_DAY_MS);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies.js.svn-base
deleted file mode 100644
index 9978f27..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies.js.svn-base
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Functions for setting, getting and deleting cookies.
- *
- * @author arv@google.com (Erik Arvidsson)
- */
-
-
-goog.provide('goog.net.Cookies');
-goog.provide('goog.net.cookies');
-
-goog.require('goog.userAgent');
-
-
-
-/**
- * A class for handling browser cookies.
- * @param {Document} context The context document to get/set cookies on.
- * @constructor
- */
-goog.net.Cookies = function(context) {
- /**
- * The context document to get/set cookies on
- * @type {Document}
- * @private
- */
- this.document_ = context;
-};
-
-
-/**
- * Static constant for the size of cookies. Per the spec, there's a 4K limit
- * to the size of a cookie. To make sure users can't break this limit, we
- * should truncate long cookies at 3950 bytes, to be extra careful with dumb
- * browsers/proxies that interpret 4K as 4000 rather than 4096.
- * @type {number}
- */
-goog.net.Cookies.MAX_COOKIE_LENGTH = 3950;
-
-
-/**
- * RegExp used to split the cookies string.
- * @type {RegExp}
- * @private
- */
-goog.net.Cookies.SPLIT_RE_ = /\s*;\s*/;
-
-
-/**
- * Test cookie name. Used for a temp cookie when testing if cookies are
- * enabled.
- * @type {string}
- * @private
- */
-goog.net.Cookies.TEST_COOKIE_NAME_ = 'COOKIES_TEST_';
-
-
-/**
- * Returns true if cookies are enabled.
- * @return {boolean} True if cookies are enabled.
- */
-goog.net.Cookies.prototype.isEnabled = function() {
- var isEnabled = this.isNavigatorCookieEnabled_();
-
- if (isEnabled && goog.userAgent.WEBKIT) {
- // Chrome has a bug where it will report cookies as enabled even if they
- // are not, see http://code.google.com/p/chromium/issues/detail?id=1850 .
- // To work around, we set a unique cookie, then check for it.
- var cookieName = goog.net.Cookies.TEST_COOKIE_NAME_ + goog.now();
- goog.net.cookies.set(cookieName, '1');
- if (!this.get(cookieName)) {
- return false;
- }
- // Remove temp cookie.
- this.remove(cookieName);
- }
-
- return isEnabled;
-};
-
-
-/**
- * We do not allow '=', ';', or white space in the name.
- *
- * NOTE: The following are allowed by this method, but should be avoided for
- * cookies handled by the server.
- * - any name starting with '$'
- * - 'Comment'
- * - 'Domain'
- * - 'Expires'
- * - 'Max-Age'
- * - 'Path'
- * - 'Secure'
- * - 'Version'
- *
- * @param {string} name Cookie name.
- * @return {boolean} Whether name is valid.
- *
- * @see <a href="http://tools.ietf.org/html/rfc2109">RFC 2109</a>
- * @see <a href="http://tools.ietf.org/html/rfc2965">RFC 2965</a>
- */
-goog.net.Cookies.prototype.isValidName = function(name) {
- return !(/[;=\s]/.test(name));
-};
-
-
-/**
- * We do not allow ';' or line break in the value.
- *
- * Spec does not mention any illegal characters, but in practice semi-colons
- * break parsing and line breaks truncate the name.
- *
- * @param {string} value Cookie value.
- * @return {boolean} Whether value is valid.
- *
- * @see <a href="http://tools.ietf.org/html/rfc2109">RFC 2109</a>
- * @see <a href="http://tools.ietf.org/html/rfc2965">RFC 2965</a>
- */
-goog.net.Cookies.prototype.isValidValue = function(value) {
- return !(/[;\r\n]/.test(value));
-};
-
-
-/**
- * Sets a cookie. The max_age can be -1 to set a session cookie. To remove and
- * expire cookies, use remove() instead.
- *
- * Neither the {@code name} nor the {@code value} are encoded in any way. It is
- * up to the callers of {@code get} and {@code set} (as well as all the other
- * methods) to handle any possible encoding and decoding.
- *
- * @throws {!Error} If the {@code name} fails #goog.net.cookies.isValidName.
- * @throws {!Error} If the {@code value} fails #goog.net.cookies.isValidValue.
- *
- * @param {string} name The cookie name.
- * @param {string} value The cookie value.
- * @param {number=} opt_maxAge The max age in seconds (from now). Use -1 to
- * set a session cookie. If not provided, the default is -1
- * (i.e. set a session cookie).
- * @param {?string=} opt_path The path of the cookie. If not present then this
- * uses the full request path.
- * @param {?string=} opt_domain The domain of the cookie, or null to not
- * specify a domain attribute (browser will use the full request host name).
- * If not provided, the default is null (i.e. let browser use full request
- * host name).
- * @param {boolean=} opt_secure Whether the cookie should only be sent over
- * a secure channel.
- */
-goog.net.Cookies.prototype.set = function(
- name, value, opt_maxAge, opt_path, opt_domain, opt_secure) {
- if (!this.isValidName(name)) {
- throw Error('Invalid cookie name "' + name + '"');
- }
- if (!this.isValidValue(value)) {
- throw Error('Invalid cookie value "' + value + '"');
- }
-
- if (!goog.isDef(opt_maxAge)) {
- opt_maxAge = -1;
- }
-
- var domainStr = opt_domain ? ';domain=' + opt_domain : '';
- var pathStr = opt_path ? ';path=' + opt_path : '';
- var secureStr = opt_secure ? ';secure' : '';
-
- var expiresStr;
-
- // Case 1: Set a session cookie.
- if (opt_maxAge < 0) {
- expiresStr = '';
-
- // Case 2: Expire the cookie.
- // Note: We don't tell people about this option in the function doc because
- // we prefer people to use ExpireCookie() to expire cookies.
- } else if (opt_maxAge == 0) {
- // Note: Don't use Jan 1, 1970 for date because NS 4.76 will try to convert
- // it to local time, and if the local time is before Jan 1, 1970, then the
- // browser will ignore the Expires attribute altogether.
- var pastDate = new Date(1970, 1 /*Feb*/, 1); // Feb 1, 1970
- expiresStr = ';expires=' + pastDate.toUTCString();
-
- // Case 3: Set a persistent cookie.
- } else {
- var futureDate = new Date(goog.now() + opt_maxAge * 1000);
- expiresStr = ';expires=' + futureDate.toUTCString();
- }
-
- this.setCookie_(name + '=' + value + domainStr + pathStr +
- expiresStr + secureStr);
-};
-
-
-/**
- * Returns the value for the first cookie with the given name.
- * @param {string} name The name of the cookie to get.
- * @param {string=} opt_default If not found this is returned instead.
- * @return {string|undefined} The value of the cookie. If no cookie is set this
- * returns opt_default or undefined if opt_default is not provided.
- */
-goog.net.Cookies.prototype.get = function(name, opt_default) {
- var nameEq = name + '=';
- var parts = this.getParts_();
- for (var i = 0, part; part = parts[i]; i++) {
- if (part.indexOf(nameEq) == 0) {
- return part.substr(nameEq.length);
- }
- }
- return opt_default;
-};
-
-
-/**
- * Removes and expires a cookie.
- * @param {string} name The cookie name.
- * @param {string=} opt_path The path of the cookie, or null to expire a cookie
- * set at the full request path. If not provided, the default is '/'
- * (i.e. path=/).
- * @param {string=} opt_domain The domain of the cookie, or null to expire a
- * cookie set at the full request host name. If not provided, the default is
- * null (i.e. cookie at full request host name).
- * @return {boolean} Whether the cookie existed before it was removed.
- */
-goog.net.Cookies.prototype.remove = function(name, opt_path, opt_domain) {
- var rv = this.containsKey(name);
- this.set(name, '', 0, opt_path, opt_domain);
- return rv;
-};
-
-
-/**
- * Gets the names for all the cookies.
- * @return {Array.<string>} An array with the names of the cookies.
- */
-goog.net.Cookies.prototype.getKeys = function() {
- return this.getKeyValues_().keys;
-};
-
-
-/**
- * Gets the values for all the cookies.
- * @return {Array.<string>} An array with the values of the cookies.
- */
-goog.net.Cookies.prototype.getValues = function() {
- return this.getKeyValues_().values;
-};
-
-
-/**
- * @return {boolean} Whether there are any cookies for this document.
- */
-goog.net.Cookies.prototype.isEmpty = function() {
- return !this.getCookie_();
-};
-
-
-/**
- * @return {number} The number of cookies for this document.
- */
-goog.net.Cookies.prototype.getCount = function() {
- var cookie = this.getCookie_();
- if (!cookie) {
- return 0;
- }
- return this.getParts_().length;
-};
-
-
-/**
- * Returns whether there is a cookie with the given name.
- * @param {string} key The name of the cookie to test for.
- * @return {boolean} Whether there is a cookie by that name.
- */
-goog.net.Cookies.prototype.containsKey = function(key) {
- // substring will return empty string if the key is not found, so the get
- // function will only return undefined
- return goog.isDef(this.get(key));
-};
-
-
-/**
- * Returns whether there is a cookie with the given value. (This is an O(n)
- * operation.)
- * @param {string} value The value to check for.
- * @return {boolean} Whether there is a cookie with that value.
- */
-goog.net.Cookies.prototype.containsValue = function(value) {
- // this O(n) in any case so lets do the trivial thing.
- var values = this.getKeyValues_().values;
- for (var i = 0; i < values.length; i++) {
- if (values[i] == value) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Removes all cookies for this document. Note that this will only remove
- * cookies from the current path and domain. If there are cookies set using a
- * subpath and/or another domain these will still be there.
- */
-goog.net.Cookies.prototype.clear = function() {
- var keys = this.getKeyValues_().keys;
- for (var i = keys.length - 1; i >= 0; i--) {
- this.remove(keys[i]);
- }
-};
-
-
-/**
- * Private helper function to allow testing cookies without depending on the
- * browser.
- * @param {string} s The cookie string to set.
- * @private
- */
-goog.net.Cookies.prototype.setCookie_ = function(s) {
- this.document_.cookie = s;
-};
-
-
-/**
- * Private helper function to allow testing cookies without depending on the
- * browser. IE6 can return null here.
- * @return {?string} Returns the {@code document.cookie}.
- * @private
- */
-goog.net.Cookies.prototype.getCookie_ = function() {
- return this.document_.cookie;
-};
-
-
-/**
- * @return {!Array.<string>} The cookie split on semi colons.
- * @private
- */
-goog.net.Cookies.prototype.getParts_ = function() {
- return (this.getCookie_() || '').
- split(goog.net.Cookies.SPLIT_RE_);
-};
-
-
-/**
- * Returns navigator.cookieEnabled. Overridden in unit tests.
- * @return {boolean} The value of navigator.cookieEnabled.
- * @private
- */
-goog.net.Cookies.prototype.isNavigatorCookieEnabled_ = function() {
- return navigator.cookieEnabled;
-};
-
-
-/**
- * Gets the names and values for all the cookies.
- * @return {Object} An object with keys and values.
- * @private
- */
-goog.net.Cookies.prototype.getKeyValues_ = function() {
- var parts = this.getParts_();
- var keys = [], values = [], index, part;
- for (var i = 0; part = parts[i]; i++) {
- index = part.indexOf('=');
-
- if (index == -1) { // empty name
- keys.push('');
- values.push(part);
- } else {
- keys.push(part.substring(0, index));
- values.push(part.substring(index + 1));
- }
- }
- return {keys: keys, values: values};
-};
-
-
-/**
- * A static default instance.
- * @type {goog.net.Cookies}
- */
-goog.net.cookies = new goog.net.Cookies(document);
-
-
-/**
- * Define the constant on the instance in order not to break many references to
- * it.
- * @type {number}
- * @deprecated Use goog.net.Cookies.MAX_COOKIE_LENGTH instead.
- */
-goog.net.cookies.MAX_COOKIE_LENGTH = goog.net.Cookies.MAX_COOKIE_LENGTH;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies_test.html.svn-base
deleted file mode 100644
index 10ec66c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/cookies_test.html.svn-base
+++ /dev/null
@@ -1,255 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2006 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.cookies</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.array');
- goog.require('goog.net.cookies');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-<script>
-
-var cookies = goog.net.cookies;
-var baseCount = 0;
-
-function checkForCookies() {
- if (!cookies.isEnabled()) {
- var message = 'Cookies must be enabled to run this test.';
- if (location.protocol == 'file:') {
- message += '\nNote that cookies for local files are disabled in some ' +
- 'browsers.\nThey can be enabled in Chrome with the ' +
- '--enable-file-cookies flag.';
- }
-
- fail(message);
- }
-}
-
-function setUp() {
- checkForCookies();
-
- // Make sure there are no cookies set by previous, bad tests.
- cookies.clear();
- baseCount = cookies.getCount();
-}
-
-function tearDown() {
- // Clear up after ourselves.
- cookies.clear();
-}
-
-function testIsEnabled() {
- // Save static function prior to mocking.
- var isNavigatorCookieEnabled = cookies.isNavigatorCookieEnabled_;
- try {
- cookies.isNavigatorCookieEnabled_ = function() { return true; };
- assertTrue(cookies.isEnabled());
- cookies.isNavigatorCookieEnabled_ = function() { return false; };
- assertFalse(cookies.isEnabled());
- } finally {
- // Restore static function.
- cookies.isNavigatorCookieEnabled_ = isNavigatorCookieEnabled;
- }
-}
-
-function testCount() {
- // setUp empties the cookies
-
- cookies.set('testa', 'A');
- assertEquals(baseCount + 1, cookies.getCount());
- cookies.set('testb', 'B');
- cookies.set('testc', 'C');
- assertEquals(baseCount + 3, cookies.getCount());
- cookies.remove('testa');
- cookies.remove('testb');
- assertEquals(baseCount + 1, cookies.getCount());
- cookies.remove('testc');
- assertEquals(baseCount + 0, cookies.getCount());
-}
-
-function testSet() {
- cookies.set('testa', 'testb');
- assertEquals('testb', cookies.get('testa'));
- cookies.remove('testa');
- assertEquals(undefined, cookies.get('testa'));
- // check for invalid characters in name and value
-}
-
-function testGetKeys() {
- cookies.set('testa', 'A');
- cookies.set('testb', 'B');
- cookies.set('testc', 'C');
- var keys = cookies.getKeys();
- assertTrue(goog.array.contains(keys, 'testa'));
- assertTrue(goog.array.contains(keys, 'testb'));
- assertTrue(goog.array.contains(keys, 'testc'));
-}
-
-
-function testGetValues() {
- cookies.set('testa', 'A');
- cookies.set('testb', 'B');
- cookies.set('testc', 'C');
- var values = cookies.getValues();
- assertTrue(goog.array.contains(values, 'A'));
- assertTrue(goog.array.contains(values, 'B'));
- assertTrue(goog.array.contains(values, 'C'));
-}
-
-
-function testContainsKey() {
- assertFalse(cookies.containsKey('testa'));
- cookies.set('testa', 'A');
- assertTrue(cookies.containsKey('testa'));
- cookies.set('testb', 'B');
- assertTrue(cookies.containsKey('testb'));
- cookies.remove('testb');
- assertFalse(cookies.containsKey('testb'));
- cookies.remove('testa');
- assertFalse(cookies.containsKey('testa'));
-}
-
-
-function testContainsValue() {
- assertFalse(cookies.containsValue('A'));
- cookies.set('testa', 'A');
- assertTrue(cookies.containsValue('A'));
- cookies.set('testb', 'B');
- assertTrue(cookies.containsValue('B'));
- cookies.remove('testb');
- assertFalse(cookies.containsValue('B'));
- cookies.remove('testa');
- assertFalse(cookies.containsValue('A'));
-}
-
-
-function testIsEmpty() {
- // we cannot guarantee that we have no cookies so testing for the true
- // case cannot be done without a mock document.cookie
- cookies.set('testa', 'A');
- assertFalse(cookies.isEmpty());
- cookies.set('testb', 'B');
- assertFalse(cookies.isEmpty());
- cookies.remove('testb');
- assertFalse(cookies.isEmpty());
- cookies.remove('testa');
-}
-
-
-function testRemove() {
- assertFalse('1. Cookie should not contain "testa"', cookies.containsKey('testa'));
- cookies.set('testa', 'A', undefined, '/');
- assertTrue('2. Cookie should contain "testa"', cookies.containsKey('testa'));
- cookies.remove('testa', '/');
- assertFalse('3. Cookie should not contain "testa"', cookies.containsKey('testa'));
-
- cookies.set('testa', 'A');
- assertTrue('4. Cookie should contain "testa"', cookies.containsKey('testa'));
- cookies.remove('testa');
- assertFalse('5. Cookie should not contain "testa"', cookies.containsKey('testa'));
-}
-
-function testStrangeValue() {
- // This ensures that the pattern key2=value in the value does not match
- // the key2 cookie.
- var value = 'testb=bbb';
- var value2 = 'ccc';
-
- cookies.set('testa', value);
- cookies.set('testb', value2);
-
- assertEquals(value, cookies.get('testa'));
- assertEquals(value2, cookies.get('testb'));
-}
-
-function testSetCookiePath() {
- assertEquals('foo=bar;path=/xyz',
- mockSetCookie('foo', 'bar', -1, '/xyz'));
-}
-
-function testSetCookieDomain() {
- assertEquals('foo=bar;domain=google.com',
- mockSetCookie('foo', 'bar', -1, null, 'google.com'));
-}
-
-function testSetCookieSecure() {
- assertEquals('foo=bar;secure',
- mockSetCookie('foo', 'bar', -1, null, null, true));
-}
-
-function testSetCookieMaxAgeZero() {
- var result = mockSetCookie('foo', 'bar', 0);
- var pattern = new RegExp(
- 'foo=bar;expires=' + new Date(1970, 1, 1).toUTCString());
- if (!result.match(pattern)) {
- fail('expected match against ' + pattern + ' got ' + result);
- }
-}
-
-// TODO(chrisn): Testing max age > 0 requires a mock clock.
-
-function mockSetCookie(var_args) {
- var setCookie = cookies.setCookie_;
- try {
- var result;
- cookies.setCookie_ = function(arg) {
- result = arg;
- };
- cookies.set.apply(cookies, arguments);
- return result;
- } finally {
- cookies.setCookie_ = setCookie;
- }
-}
-
-function assertValidName(name) {
- assertTrue(name + ' should be valid', cookies.isValidName(name));
-}
-
-function assertInvalidName(name) {
- assertFalse(name + ' should be invalid', cookies.isValidName(name));
- assertThrows(function() {
- cookies.set(name, 'value');
- });
-}
-
-function assertValidValue(val) {
- assertTrue(val + ' should be valid', cookies.isValidValue(val));
-}
-
-function assertInvalidValue(val) {
- assertFalse(val + ' should be invalid', cookies.isValidValue(val));
- assertThrows(function() {
- cookies.set('name', val);
- });
-}
-
-function testValidName() {
- assertValidName('foo');
- assertInvalidName('foo bar');
- assertInvalidName('foo=bar');
- assertInvalidName('foo;bar');
- assertInvalidName('foo\nbar');
-}
-
-function testValidValue() {
- assertValidValue('foo');
- assertValidValue('foo bar');
- assertValidValue('foo=bar');
- assertInvalidValue('foo;bar');
- assertInvalidValue('foo\nbar');
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc.js.svn-base
deleted file mode 100644
index 7952011..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc.js.svn-base
+++ /dev/null
@@ -1,849 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Cross domain RPC library using the <a
- * href="http://go/xd2_design" target="_top">XD2 approach</a>.
- *
- * <h5>Protocol</h5>
- * Client sends a request across domain via a form submission. Server
- * receives these parameters: "xdpe:request-id", "xdpe:dummy-uri" ("xdpe" for
- * "cross domain parameter to echo back") and other user parameters prefixed
- * with "xdp" (for "cross domain parameter"). Headers are passed as parameters
- * prefixed with "xdh" (for "cross domain header"). Only strings are supported
- * for parameters and headers. A GET method is mapped to a form GET. All
- * other methods are mapped to a POST. Server is expected to produce a
- * HTML response such as the following:
- * <pre>
- * &lt;body&gt;
- * &lt;script type="text/javascript"
- * src="path-to-crossdomainrpc.js"&gt;&lt;/script&gt;
- * var currentDirectory = location.href.substring(
- * 0, location.href.lastIndexOf('/')
- * );
- *
- * // echo all parameters prefixed with "xdpe:"
- * var echo = {};
- * echo[goog.net.CrossDomainRpc.PARAM_ECHO_REQUEST_ID] =
- * &lt;value of parameter "xdpe:request-id"&gt;;
- * echo[goog.net.CrossDomainRpc.PARAM_ECHO_DUMMY_URI] =
- * &lt;value of parameter "xdpe:dummy-uri"&gt;;
- *
- * goog.net.CrossDomainRpc.sendResponse(
- * '({"result":"&lt;responseInJSON"})',
- * true, // is JSON
- * echo, // parameters to echo back
- * status, // response status code
- * headers // response headers
- * );
- * &lt;/script&gt;
- * &lt;/body&gt;
- * </pre>
- *
- * <h5>Server Side</h5>
- * For an example of the server side, refer to the following files:
- * <ul>
- * <li>http://go/xdservletfilter.java</li>
- * <li>http://go/xdservletrequest.java</li>
- * <li>http://go/xdservletresponse.java</li>
- * </ul>
- *
- * <h5>System Requirements</h5>
- * Tested on IE6, IE7, Firefox 2.0 and Safari nightly r23841.
- *
- */
-
-goog.provide('goog.net.CrossDomainRpc');
-
-goog.require('goog.Uri.QueryData');
-goog.require('goog.debug.Logger');
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.events.EventTarget');
-goog.require('goog.events.EventType');
-goog.require('goog.json');
-goog.require('goog.net.EventType');
-goog.require('goog.net.HttpStatus');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Creates a new instance of cross domain RPC
- * @extends {goog.events.EventTarget}
- * @constructor
- */
-goog.net.CrossDomainRpc = function() {
- goog.events.EventTarget.call(this);
-};
-goog.inherits(goog.net.CrossDomainRpc, goog.events.EventTarget);
-
-
-/**
- * Cross-domain response iframe marker.
- * @type {string}
- * @private
- */
-goog.net.CrossDomainRpc.RESPONSE_MARKER_ = 'xdrp';
-
-
-/**
- * Use a fallback dummy resource if none specified or detected.
- * @type {boolean}
- * @private
- */
-goog.net.CrossDomainRpc.useFallBackDummyResource_ = true;
-
-
-/**
- * Checks to see if we are executing inside a response iframe. This is the
- * case when this page is used as a dummy resource to gain caller's domain.
- * @return {*} True if we are executing inside a response iframe; false
- * otherwise.
- * @private
- */
-goog.net.CrossDomainRpc.isInResponseIframe_ = function() {
- return window.location && (window.location.hash.indexOf(
- goog.net.CrossDomainRpc.RESPONSE_MARKER_) == 1 ||
- window.location.search.indexOf(
- goog.net.CrossDomainRpc.RESPONSE_MARKER_) == 1);
-};
-
-
-/**
- * Stops execution of the rest of the page if this page is loaded inside a
- * response iframe.
- */
-if (goog.net.CrossDomainRpc.isInResponseIframe_()) {
- if (goog.userAgent.IE) {
- document.execCommand('Stop');
- } else if (goog.userAgent.GECKO) {
- window.stop();
- } else {
- throw Error('stopped');
- }
-}
-
-
-/**
- * Sets the URI for a dummy resource on caller's domain. This function is
- * used for specifying a particular resource to use rather than relying on
- * auto detection.
- * @param {string} dummyResourceUri URI to dummy resource on the same domain
- * of caller's page.
- */
-goog.net.CrossDomainRpc.setDummyResourceUri = function(dummyResourceUri) {
- goog.net.CrossDomainRpc.dummyResourceUri_ = dummyResourceUri;
-};
-
-
-/**
- * Sets whether a fallback dummy resource ("/robots.txt" on Firefox and Safari
- * and current page on IE) should be used when a suitable dummy resource is
- * not available.
- * @param {boolean} useFallBack Whether to use fallback or not.
- */
-goog.net.CrossDomainRpc.setUseFallBackDummyResource = function(useFallBack) {
- goog.net.CrossDomainRpc.useFallBackDummyResource_ = useFallBack;
-};
-
-
-/**
- * Sends a request across domain.
- * @param {string} uri Uri to make request to.
- * @param {Function=} opt_continuation Continuation function to be called
- * when request is completed. Takes one argument of an event object
- * whose target has the following properties: "status" is the HTTP
- * response status code, "responseText" is the response text,
- * and "headers" is an object with all response headers. The event
- * target's getResponseJson() method returns a JavaScript object evaluated
- * from the JSON response or undefined if response is not JSON.
- * @param {string=} opt_method Method of request. Default is POST.
- * @param {Object=} opt_params Parameters. Each property is turned into a
- * request parameter.
- * @param {Object=} opt_headers Map of headers of the request.
- */
-goog.net.CrossDomainRpc.send =
- function(uri, opt_continuation, opt_method, opt_params, opt_headers) {
- var xdrpc = new goog.net.CrossDomainRpc();
- if (opt_continuation) {
- goog.events.listen(xdrpc, goog.net.EventType.COMPLETE, opt_continuation);
- }
- goog.events.listen(xdrpc, goog.net.EventType.READY, xdrpc.reset);
- xdrpc.sendRequest(uri, opt_method, opt_params, opt_headers);
-};
-
-
-/**
- * Sets debug mode to true or false. When debug mode is on, response iframes
- * are visible and left behind after their use is finished.
- * @param {boolean} flag Flag to indicate intention to turn debug model on
- * (true) or off (false).
- */
-goog.net.CrossDomainRpc.setDebugMode = function(flag) {
- goog.net.CrossDomainRpc.debugMode_ = flag;
-};
-
-
-/**
- * Logger for goog.net.CrossDomainRpc
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.CrossDomainRpc.logger_ =
- goog.debug.Logger.getLogger('goog.net.CrossDomainRpc');
-
-
-/**
- * Creates the HTML of an input element
- * @param {string} name Name of input element.
- * @param {*} value Value of input element.
- * @return {string} HTML of input element with that name and value.
- * @private
- */
-goog.net.CrossDomainRpc.createInputHtml_ = function(name, value) {
- return '<textarea name="' + name + '">' +
- goog.net.CrossDomainRpc.escapeAmpersand_(value) + '</textarea>';
-};
-
-
-/**
- * Escapes ampersand so that XML/HTML entities are submitted as is because
- * browser unescapes them when they are put into a text area.
- * @param {*} value Value to escape.
- * @return {*} Value with ampersand escaped, if value is a string;
- * otherwise the value itself is returned.
- * @private
- */
-goog.net.CrossDomainRpc.escapeAmpersand_ = function(value) {
- return value && (goog.isString(value) || value.constructor == String) ?
- value.replace(/&/g, '&amp;') : value;
-};
-
-
-/**
- * Finds a dummy resource that can be used by response to gain domain of
- * requester's page.
- * @return {string} URI of the resource to use.
- * @private
- */
-goog.net.CrossDomainRpc.getDummyResourceUri_ = function() {
- if (goog.net.CrossDomainRpc.dummyResourceUri_) {
- return goog.net.CrossDomainRpc.dummyResourceUri_;
- }
-
- // find a style sheet if not on IE, which will attempt to save style sheet
- if (goog.userAgent.GECKO) {
- var links = document.getElementsByTagName('link');
- for (var i = 0; i < links.length; i++) {
- var link = links[i];
- // find a link which is on the same domain as this page
- // cannot use one with '?' or '#' in its URL as it will confuse
- // goog.net.CrossDomainRpc.getFramePayload_()
- if (link.rel == 'stylesheet' &&
- goog.Uri.haveSameDomain(link.href, window.location.href) &&
- link.href.indexOf('?') < 0) {
- return goog.net.CrossDomainRpc.removeHash_(link.href);
- }
- }
- }
-
- var images = document.getElementsByTagName('img');
- for (var i = 0; i < images.length; i++) {
- var image = images[i];
- // find a link which is on the same domain as this page
- // cannot use one with '?' or '#' in its URL as it will confuse
- // goog.net.CrossDomainRpc.getFramePayload_()
- if (goog.Uri.haveSameDomain(image.src, window.location.href) &&
- image.src.indexOf('?') < 0) {
- return goog.net.CrossDomainRpc.removeHash_(image.src);
- }
- }
-
- if (!goog.net.CrossDomainRpc.useFallBackDummyResource_) {
- throw Error(
- 'No suitable dummy resource specified or detected for this page');
- }
-
- if (goog.userAgent.IE) {
- // use this page as the dummy resource; remove hash from URL if any
- return goog.net.CrossDomainRpc.removeHash_(window.location.href);
- } else {
- /**
- * Try to use "http://<this-domain>/robots.txt" which may exist. Even if
- * it does not, an error page is returned and is a good dummy resource to
- * use on Firefox and Safari. An existing resource is faster because it
- * is cached.
- */
- var locationHref = window.location.href;
- var rootSlash = locationHref.indexOf('/', locationHref.indexOf('//') + 2);
- var rootHref = locationHref.substring(0, rootSlash);
- return rootHref + '/robots.txt';
- }
-};
-
-
-/**
- * Removes everything at and after hash from URI
- * @param {string} uri Uri to to remove hash.
- * @return {string} Uri with its hash and all characters after removed.
- * @private
- */
-goog.net.CrossDomainRpc.removeHash_ = function(uri) {
- return uri.split('#')[0];
-};
-
-
-// ------------
-// request side
-
-
-/**
- * next request id used to support multiple XD requests at the same time
- * @type {number}
- * @private
- */
-goog.net.CrossDomainRpc.nextRequestId_ = 0;
-
-
-/**
- * Header prefix.
- * @type {string}
- */
-goog.net.CrossDomainRpc.HEADER = 'xdh:';
-
-
-/**
- * Parameter prefix.
- * @type {string}
- */
-goog.net.CrossDomainRpc.PARAM = 'xdp:';
-
-
-/**
- * Parameter to echo prefix.
- * @type {string}
- */
-goog.net.CrossDomainRpc.PARAM_ECHO = 'xdpe:';
-
-
-/**
- * Parameter to echo: request id
- * @type {string}
- */
-goog.net.CrossDomainRpc.PARAM_ECHO_REQUEST_ID =
- goog.net.CrossDomainRpc.PARAM_ECHO + 'request-id';
-
-
-/**
- * Parameter to echo: dummy resource URI
- * @type {string}
- */
-goog.net.CrossDomainRpc.PARAM_ECHO_DUMMY_URI =
- goog.net.CrossDomainRpc.PARAM_ECHO + 'dummy-uri';
-
-
-/**
- * Cross-domain request marker.
- * @type {string}
- * @private
- */
-goog.net.CrossDomainRpc.REQUEST_MARKER_ = 'xdrq';
-
-
-/**
- * Sends a request across domain.
- * @param {string} uri Uri to make request to.
- * @param {string=} opt_method Method of request. Default is POST.
- * @param {Object=} opt_params Parameters. Each property is turned into a
- * request parameter.
- * @param {Object=} opt_headers Map of headers of the request.
- */
-goog.net.CrossDomainRpc.prototype.sendRequest =
- function(uri, opt_method, opt_params, opt_headers) {
- // create request frame
- var requestFrame = this.requestFrame_ = document.createElement('iframe');
- var requestId = goog.net.CrossDomainRpc.nextRequestId_++;
- requestFrame.id = goog.net.CrossDomainRpc.REQUEST_MARKER_ + '-' + requestId;
- if (!goog.net.CrossDomainRpc.debugMode_) {
- requestFrame.style.position = 'absolute';
- requestFrame.style.top = '-5000px';
- requestFrame.style.left = '-5000px';
- }
- document.body.appendChild(requestFrame);
-
- // build inputs
- var inputs = [];
-
- // add request id
- inputs.push(goog.net.CrossDomainRpc.createInputHtml_(
- goog.net.CrossDomainRpc.PARAM_ECHO_REQUEST_ID, requestId));
-
- // add dummy resource uri
- var dummyUri = goog.net.CrossDomainRpc.getDummyResourceUri_();
- goog.net.CrossDomainRpc.logger_.log(
- goog.debug.Logger.Level.FINE, 'dummyUri: ' + dummyUri);
- inputs.push(goog.net.CrossDomainRpc.createInputHtml_(
- goog.net.CrossDomainRpc.PARAM_ECHO_DUMMY_URI, dummyUri));
-
- // add parameters
- if (opt_params) {
- for (var name in opt_params) {
- var value = opt_params[name];
- inputs.push(goog.net.CrossDomainRpc.createInputHtml_(
- goog.net.CrossDomainRpc.PARAM + name, value));
- }
- }
-
- // add headers
- if (opt_headers) {
- for (var name in opt_headers) {
- var value = opt_headers[name];
- inputs.push(goog.net.CrossDomainRpc.createInputHtml_(
- goog.net.CrossDomainRpc.HEADER + name, value));
- }
- }
-
- var requestFrameContent = '<body><form method="' +
- (opt_method == 'GET' ? 'GET' : 'POST') + '" action="' +
- uri + '">' + inputs.join('') + '</form></body>';
- var requestFrameDoc = goog.dom.getFrameContentDocument(requestFrame);
- requestFrameDoc.open();
- requestFrameDoc.write(requestFrameContent);
- requestFrameDoc.close();
-
- requestFrameDoc.forms[0].submit();
- requestFrameDoc = null;
-
- this.loadListenerKey_ = goog.events.listen(
- requestFrame, goog.events.EventType.LOAD, function() {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'response ready');
- this.responseReady_ = true;
- }, false, this);
-
- this.receiveResponse_();
-};
-
-
-/**
- * period of response polling (ms)
- * @type {number}
- * @private
- */
-goog.net.CrossDomainRpc.RESPONSE_POLLING_PERIOD_ = 50;
-
-
-/**
- * timeout from response comes back to sendResponse is called (ms)
- * @type {number}
- * @private
- */
-goog.net.CrossDomainRpc.SEND_RESPONSE_TIME_OUT_ = 500;
-
-
-/**
- * Receives response by polling to check readiness of response and then
- * reads response frames and assembles response data
- * @private
- */
-goog.net.CrossDomainRpc.prototype.receiveResponse_ = function() {
- this.timeWaitedAfterResponseReady_ = 0;
- var responseDetectorHandle = window.setInterval(goog.bind(function() {
- this.detectResponse_(responseDetectorHandle);
- }, this), goog.net.CrossDomainRpc.RESPONSE_POLLING_PERIOD_);
-};
-
-
-/**
- * Detects response inside request frame
- * @param {number} responseDetectorHandle Handle of detector.
- * @private
- */
-goog.net.CrossDomainRpc.prototype.detectResponse_ =
- function(responseDetectorHandle) {
- var requestFrameWindow = this.requestFrame_.contentWindow;
- var grandChildrenLength = requestFrameWindow.frames.length;
- var responseInfoFrame = null;
- if (grandChildrenLength > 0 &&
- goog.net.CrossDomainRpc.isResponseInfoFrame_(responseInfoFrame =
- requestFrameWindow.frames[grandChildrenLength - 1])) {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'xd response ready');
-
- var responseInfoPayload = goog.net.CrossDomainRpc.getFramePayload_(
- responseInfoFrame).substring(1);
- var params = new goog.Uri.QueryData(responseInfoPayload);
-
- var chunks = [];
- var numChunks = Number(params.get('n'));
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'xd response number of chunks: ' + numChunks);
- for (var i = 0; i < numChunks; i++) {
- var responseFrame = requestFrameWindow.frames[i];
- if (!responseFrame || !responseFrame.location ||
- !responseFrame.location.href) {
- // On Safari 3.0, it is sometimes the case that the
- // iframe exists but doesn't have a same domain href yet.
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'xd response iframe not ready');
- return;
- }
- var responseChunkPayload =
- goog.net.CrossDomainRpc.getFramePayload_(responseFrame);
- // go past "chunk="
- var chunkIndex = responseChunkPayload.indexOf(
- goog.net.CrossDomainRpc.PARAM_CHUNK_) +
- goog.net.CrossDomainRpc.PARAM_CHUNK_.length + 1;
- var chunk = responseChunkPayload.substring(chunkIndex);
- chunks.push(chunk);
- }
-
- window.clearInterval(responseDetectorHandle);
-
- var responseData = chunks.join('');
- // Payload is not encoded to begin with on IE. Decode in other cases only.
- if (!goog.userAgent.IE) {
- responseData = decodeURIComponent(responseData);
- }
-
- this.status = Number(params.get('status'));
- this.responseText = responseData;
- this.responseTextIsJson_ = params.get('isDataJson') == 'true';
- this.responseHeaders = goog.json.unsafeParse(
- /** @type {string} */ (params.get('headers')));
-
- this.dispatchEvent(goog.net.EventType.READY);
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- } else {
- if (this.responseReady_) {
- /* The response has come back. But the first response iframe has not
- * been created yet. If this lasts long enough, it is an error.
- */
- this.timeWaitedAfterResponseReady_ +=
- goog.net.CrossDomainRpc.RESPONSE_POLLING_PERIOD_;
- if (this.timeWaitedAfterResponseReady_ >
- goog.net.CrossDomainRpc.SEND_RESPONSE_TIME_OUT_) {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'xd response timed out');
- window.clearInterval(responseDetectorHandle);
-
- this.status = goog.net.HttpStatus.INTERNAL_SERVER_ERROR;
- this.responseText = 'response timed out';
-
- this.dispatchEvent(goog.net.EventType.READY);
- this.dispatchEvent(goog.net.EventType.ERROR);
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- }
- }
- }
-};
-
-
-/**
- * Checks whether a frame is response info frame.
- * @param {Object} frame Frame to check.
- * @return {boolean} True if frame is a response info frame; false otherwise.
- * @private
- */
-goog.net.CrossDomainRpc.isResponseInfoFrame_ = function(frame) {
- /** @preserveTry */
- try {
- return goog.net.CrossDomainRpc.getFramePayload_(frame).indexOf(
- goog.net.CrossDomainRpc.RESPONSE_INFO_MARKER_) == 1;
- } catch (e) {
- // frame not ready for same-domain access yet
- return false;
- }
-};
-
-
-/**
- * Returns the payload of a frame (value after # or ? on the URL). This value
- * is URL encoded except IE, where the value is not encoded to begin with.
- * @param {Object} frame Frame.
- * @return {string} Payload of that frame.
- * @private
- */
-goog.net.CrossDomainRpc.getFramePayload_ = function(frame) {
- var href = frame.location.href;
- var question = href.indexOf('?');
- var hash = href.indexOf('#');
- // On IE, beucase the URL is not encoded, we can have a case where ?
- // is the delimiter before payload and # in payload or # as the delimiter
- // and ? in payload. So here we treat whoever is the first as the delimiter.
- var delimiter = question < 0 ? hash :
- hash < 0 ? question : Math.min(question, hash);
- return href.substring(delimiter);
-};
-
-
-/**
- * If response is JSON, evaluates it to a JavaScript object and
- * returns it; otherwise returns undefined.
- * @return {Object|undefined} JavaScript object if response is in JSON
- * or undefined.
- */
-goog.net.CrossDomainRpc.prototype.getResponseJson = function() {
- return this.responseTextIsJson_ ?
- goog.json.unsafeParse(this.responseText) : undefined;
-};
-
-
-/**
- * @return {boolean} Whether the request completed with a success.
- */
-goog.net.CrossDomainRpc.prototype.isSuccess = function() {
- // Definition similar to goog.net.XhrIo.prototype.isSuccess.
- switch (this.status) {
- case goog.net.HttpStatus.OK:
- case goog.net.HttpStatus.NOT_MODIFIED:
- return true;
-
- default:
- return false;
- }
-};
-
-
-/**
- * Removes request iframe used.
- */
-goog.net.CrossDomainRpc.prototype.reset = function() {
- if (!goog.net.CrossDomainRpc.debugMode_) {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'request frame removed: ' + this.requestFrame_.id);
- goog.events.unlistenByKey(this.loadListenerKey_);
- this.requestFrame_.parentNode.removeChild(this.requestFrame_);
- }
- delete this.requestFrame_;
-};
-
-
-// -------------
-// response side
-
-
-/**
- * Name of response info iframe.
- * @type {string}
- * @private
- */
-goog.net.CrossDomainRpc.RESPONSE_INFO_MARKER_ =
- goog.net.CrossDomainRpc.RESPONSE_MARKER_ + '-info';
-
-
-/**
- * Maximal chunk size. IE can only handle 4095 bytes on its URL.
- * 16MB has been tested on Firefox. But 1MB is a practical size.
- * @type {number}
- * @private
- */
-goog.net.CrossDomainRpc.MAX_CHUNK_SIZE_ =
- goog.userAgent.IE ? 4095 : 1024 * 1024;
-
-
-/**
- * Query parameter 'chunk'.
- * @type {string}
- * @private
- */
-goog.net.CrossDomainRpc.PARAM_CHUNK_ = 'chunk';
-
-
-/**
- * Prefix before data chunk for passing other parameters.
- * type String
- * @private
- */
-goog.net.CrossDomainRpc.CHUNK_PREFIX_ =
- goog.net.CrossDomainRpc.RESPONSE_MARKER_ + '=1&' +
- goog.net.CrossDomainRpc.PARAM_CHUNK_ + '=';
-
-
-/**
- * Makes response available for grandparent (requester)'s receiveResponse
- * call to pick up by creating a series of iframes pointed to the dummy URI
- * with a payload (value after either ? or #) carrying a chunk of response
- * data and a response info iframe that tells the grandparent (requester) the
- * readiness of response.
- * @param {string} data Response data (string or JSON string).
- * @param {boolean} isDataJson true if data is a JSON string; false if just a
- * string.
- * @param {Object} echo Parameters to echo back
- * "xdpe:request-id": Server that produces the response needs to
- * copy it here to support multiple current XD requests on the same page.
- * "xdpe:dummy-uri": URI to a dummy resource that response
- * iframes point to to gain the domain of the client. This can be an
- * image (IE) or a CSS file (FF) found on the requester's page.
- * Server should copy value from request parameter "xdpe:dummy-uri".
- * @param {number} status HTTP response status code.
- * @param {string} headers Response headers in JSON format.
- */
-goog.net.CrossDomainRpc.sendResponse =
- function(data, isDataJson, echo, status, headers) {
- var dummyUri = echo[goog.net.CrossDomainRpc.PARAM_ECHO_DUMMY_URI];
-
- // since the dummy-uri can be specified by the user, verify that it doesn't
- // use any other protocols. (Specifically we don't want users to use a
- // dummy-uri beginning with "javascript:").
- if (!goog.string.caseInsensitiveStartsWith(dummyUri, 'http://') &&
- !goog.string.caseInsensitiveStartsWith(dummyUri, 'https://')) {
- dummyUri = 'http://' + dummyUri;
- }
-
- // usable chunk size is max less dummy URI less chunk prefix length
- // TODO(user): Figure out why we need to do "- 1" below
- var chunkSize = goog.net.CrossDomainRpc.MAX_CHUNK_SIZE_ - dummyUri.length -
- 1 - // payload delimiter ('#' or '?')
- goog.net.CrossDomainRpc.CHUNK_PREFIX_.length - 1;
-
- /*
- * Here we used to do URI encoding of data before we divide it into chunks
- * and decode on the receiving end. We don't do this any more on IE for the
- * following reasons.
- *
- * 1) On IE, calling decodeURIComponent on a relatively large string is
- * extremely slow (~22s for 160KB). So even a moderate amount of data
- * makes this library pretty much useless. Fortunately, we can actually
- * put unencoded data on IE's URL and get it back reliably. So we are
- * completely skipping encoding and decoding on IE. When we call
- * getFrameHash_ to get it back, the value is still intact(*) and unencoded.
- * 2) On Firefox, we have to call decodeURIComponent because location.hash
- * does decoding by itself. Fortunately, decodeURIComponent is not slow
- * on Firefox.
- * 3) Safari automatically encodes everything you put on URL and it does not
- * automatically decode when you access it via location.hash or
- * location.href. So we encode it here and decode it in detectResponse_().
- *
- * Note(*): IE actually does encode only space to %20 and decodes that
- * automatically when you do location.href or location.hash.
- */
- if (!goog.userAgent.IE) {
- data = encodeURIComponent(data);
- }
-
- var numChunksToSend = Math.ceil(data.length / chunkSize);
- if (numChunksToSend == 0) {
- goog.net.CrossDomainRpc.createResponseInfo_(
- dummyUri, numChunksToSend, isDataJson, status, headers);
- } else {
- var numChunksSent = 0;
- function checkToCreateResponseInfo_() {
- if (++numChunksSent == numChunksToSend) {
- goog.net.CrossDomainRpc.createResponseInfo_(
- dummyUri, numChunksToSend, isDataJson, status, headers);
- }
- }
-
- for (var i = 0; i < numChunksToSend; i++) {
- var chunkStart = i * chunkSize;
- var chunkEnd = chunkStart + chunkSize;
- var chunk = chunkEnd > data.length ?
- data.substring(chunkStart) :
- data.substring(chunkStart, chunkEnd);
-
- var responseFrame = document.createElement('iframe');
- responseFrame.src = dummyUri +
- goog.net.CrossDomainRpc.getPayloadDelimiter_(dummyUri) +
- goog.net.CrossDomainRpc.CHUNK_PREFIX_ + chunk;
- document.body.appendChild(responseFrame);
-
- // We used to call the function below when handling load event of
- // responseFrame. But that event does not fire on IE when current
- // page is used as the dummy resource (because its loading is stopped?).
- // It also does not fire sometimes on Firefox. So now we call it
- // directly.
- checkToCreateResponseInfo_();
- }
- }
-};
-
-
-/**
- * Creates a response info iframe to indicate completion of sendResponse
- * @param {string} dummyUri URI to a dummy resource.
- * @param {number} numChunks Total number of chunks.
- * @param {boolean} isDataJson Whether response is a JSON string or just string.
- * @param {number} status HTTP response status code.
- * @param {string} headers Response headers in JSON format.
- * @private
- */
-goog.net.CrossDomainRpc.createResponseInfo_ =
- function(dummyUri, numChunks, isDataJson, status, headers) {
- var responseInfoFrame = document.createElement('iframe');
- document.body.appendChild(responseInfoFrame);
- responseInfoFrame.src = dummyUri +
- goog.net.CrossDomainRpc.getPayloadDelimiter_(dummyUri) +
- goog.net.CrossDomainRpc.RESPONSE_INFO_MARKER_ +
- '=1&n=' + numChunks + '&isDataJson=' + isDataJson + '&status=' + status +
- '&headers=' + encodeURIComponent(headers);
-};
-
-
-/**
- * Returns payload delimiter, either "#" when caller's page is not used as
- * the dummy resource or "?" when it is, in which case caching issues prevent
- * response frames to gain the caller's domain.
- * @param {string} dummyUri URI to resource being used as dummy resource.
- * @return {string} Either "?" when caller's page is used as dummy resource or
- * "#" if it is not.
- * @private
- */
-goog.net.CrossDomainRpc.getPayloadDelimiter_ = function(dummyUri) {
- return goog.net.CrossDomainRpc.REFERRER_ == dummyUri ? '?' : '#';
-};
-
-
-/**
- * Removes all parameters (after ? or #) from URI.
- * @param {string} uri URI to remove parameters from.
- * @return {string} URI with all parameters removed.
- * @private
- */
-goog.net.CrossDomainRpc.removeUriParams_ = function(uri) {
- // remove everything after question mark
- var question = uri.indexOf('?');
- if (question > 0) {
- uri = uri.substring(0, question);
- }
-
- // remove everything after hash mark
- var hash = uri.indexOf('#');
- if (hash > 0) {
- uri = uri.substring(0, hash);
- }
-
- return uri;
-};
-
-
-/**
- * Gets a response header.
- * @param {string} name Name of response header.
- * @return {string|undefined} Value of response header; undefined if not found.
- */
-goog.net.CrossDomainRpc.prototype.getResponseHeader = function(name) {
- return goog.isObject(this.responseHeaders) ?
- this.responseHeaders[name] : undefined;
-};
-
-
-/**
- * Referrer of current document with all parameters after "?" and "#" stripped.
- * @type {string}
- * @private
- */
-goog.net.CrossDomainRpc.REFERRER_ =
- goog.net.CrossDomainRpc.removeUriParams_(document.referrer);
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.gif.svn-base
deleted file mode 100644
index e69de29..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.gif.svn-base
+++ /dev/null
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.html.svn-base
deleted file mode 100644
index fbb077f..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test.html.svn-base
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.CrossDomainRpc</title>
-<link href="CrossDomainRpc_test.css?123" rel="stylesheet" type="text/css">
-<link href="CrossDomainRpc_test.css#123" rel="stylesheet" type="text/css">
-<link href="CrossDomainRpc_test.css" rel="stylesheet" type="text/css">
-<script src="../base.js"></script>
-<script>
- goog.require('goog.debug.Logger');
- goog.require('goog.net.CrossDomainRpc');
- goog.require('goog.testing.jsunit');
-</script>
-
-<script>
-
-// TODO(user): These tests are in fact async since the send command makes a
-// request for a file, the reason they do not fail is that the JsUnit test
-// runner reports completion after the testFoo functions are finished, and
-// does not catch any errors after this point. These tests need updating so
-// that they either mock out the async part of the test, or they should be
-// written as an async test case.
-
-function print(o) {
- if (Object.prototype.toSource) {
- return o.toSource();
- } else {
- var fragments = [];
- fragments.push('{');
- var first = true;
- for (var p in o) {
- if (!first) fragments.push(',');
- fragments.push(p);
- fragments.push(':"');
- fragments.push(o[p]);
- fragments.push('"');
- first = false;
- }
- return fragments.join('');
- }
-};
-
-
-function testNormalRequest() {
- var start = new Date();
- goog.net.CrossDomainRpc.send(
- 'crossdomainrpc_test_response.html',
- function(e) {
- if (e.target.status < 300) {
- var elapsed = new Date() - start;
- var responseData = eval(e.target.responseText);
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- elapsed + 'ms: [' + responseData.result.length + '] '
- + print(responseData)
- );
- assertEquals(16 * 1024, responseData.result.length);
- assertEquals(e.target.status, 123);
- assertEquals(e.target.responseHeaders.a, 1);
- assertEquals(e.target.responseHeaders.b, '2');
- } else {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- print(e));
- fail();
- }
- },
- 'POST',
- {xyz: '01234567891123456789'}
- );
-};
-
-
-function testErrorRequest() {
- goog.net.CrossDomainRpc.send(
- 'http://hoodjimcwaadji.google.com/index.html',
- function(e) {
- if (e.target.status < 300) {
- fail('should have failed requesting a non-existent URI');
- } else {
- goog.net.CrossDomainRpc.logger_.log(goog.debug.Logger.Level.FINE,
- 'expected error seen; event=' + print(e));
- }
- },
- 'POST',
- {xyz: '01234567891123456789'}
- );
-};
-
-
-function testGetDummyResourceUri() {
- var url = goog.net.CrossDomainRpc.getDummyResourceUri_();
- assertTrue(
- 'dummy resource URL should not contain "?"', url.indexOf('?') < 0);
- assertTrue(
- 'dummy resource URL should not contain "#"', url.indexOf('#') < 0);
-};
-
-
-function testRemoveHash() {
- assertEquals('abc', goog.net.CrossDomainRpc.removeHash_('abc#123'));
- assertEquals('abc', goog.net.CrossDomainRpc.removeHash_('abc#12#3'));
-};
-</script>
-</head>
-
-<body>
-<img src="crossdomainrpc_test.gif?123" alt="dummy resource">
-<img src="crossdomainrpc_test.gif#123" alt="dummy resource">
-<img src="crossdomainrpc_test.gif" alt="dummy resource">
-</body>
-
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test_response.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test_response.html.svn-base
deleted file mode 100644
index b44a01b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/crossdomainrpc_test_response.html.svn-base
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
-
-
- In reality, this response comes from a different domain. For simplicity of
- testing, this response is one the same domain, while exercising the same
- functionality.
--->
-<title>crossdomainrpc test response</title>
-<body>
-<script type="text/javascript" src="../base.js"></script>
-<script type="text/javascript">
-goog.require('goog.debug.Logger');
-goog.require('goog.dom');
-goog.require('goog.events.EventTarget');
-goog.require('goog.json');
-goog.require('goog.net.EventType');
-goog.require('goog.Uri.QueryData');
-goog.require('goog.userAgent');
-</script>
-<script type="text/javascript" src="crossdomainrpc.js"></script>
-<script type="text/javascript">
-function createPayload(size) {
- var chars = [];
- for (var i = 0; i < size; i++) {
- chars.push('0');
- }
- return chars.join('');
-};
-
-var payload = createPayload(16 * 1024);
-
-var currentDirectory = location.href.substring(
- 0, location.href.lastIndexOf('/')
-);
-
-var echo = {};
-echo[goog.net.CrossDomainRpc.PARAM_ECHO_REQUEST_ID] = 0;
-echo[goog.net.CrossDomainRpc.PARAM_ECHO_DUMMY_URI] = goog.userAgent.IE ?
- currentDirectory + '/crossdomainrpc_test.gif' :
- currentDirectory + '/crossdomainrpc_test.css';
-
-goog.net.CrossDomainRpc.sendResponse(
- '({"result":"' + payload + '"})',
- true, // is JSON
- echo, // parameters to echo back
- 123, // response code
- '{"a":1,"b":"2"}' // response headers
-);
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/errorcode.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/errorcode.js.svn-base
deleted file mode 100644
index 4d6d834..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/errorcode.js.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Error codes shared between goog.net.IframeIo and
- * goog.net.XhrIo.
- */
-
-goog.provide('goog.net.ErrorCode');
-
-
-/**
- * Error codes
- * @enum {number}
- */
-goog.net.ErrorCode = {
-
- /**
- * There is no error condition.
- */
- NO_ERROR: 0,
-
- /**
- * The most common error from iframeio, unfortunately, is that the browser
- * responded with an error page that is classed as a different domain. The
- * situations, are when a browser error page is shown -- 404, access denied,
- * DNS failure, connection reset etc.)
- *
- */
- ACCESS_DENIED: 1,
-
- /**
- * Currently the only case where file not found will be caused is when the
- * code is running on the local file system and a non-IE browser makes a
- * request to a file that doesn't exist.
- */
- FILE_NOT_FOUND: 2,
-
- /**
- * If Firefox shows a browser error page, such as a connection reset by
- * server or access denied, then it will fail silently without the error or
- * load handlers firing.
- */
- FF_SILENT_ERROR: 3,
-
- /**
- * Custom error provided by the client through the error check hook.
- */
- CUSTOM_ERROR: 4,
-
- /**
- * Exception was thrown while processing the request.
- */
- EXCEPTION: 5,
-
- /**
- * The Http response returned a non-successful http status code.
- */
- HTTP_ERROR: 6,
-
- /**
- * The request was aborted.
- */
- ABORT: 7,
-
- /**
- * The request timed out.
- */
- TIMEOUT: 8,
-
- /**
- * The resource is not available offline.
- */
- OFFLINE: 9
-};
-
-
-/**
- * Returns a friendly error message for an error code. These messages are for
- * debugging and are not localized.
- * @param {goog.net.ErrorCode} errorCode An error code.
- * @return {string} A message for debugging.
- */
-goog.net.ErrorCode.getDebugMessage = function(errorCode) {
- switch (errorCode) {
- case goog.net.ErrorCode.NO_ERROR:
- return 'No Error';
-
- case goog.net.ErrorCode.ACCESS_DENIED:
- return 'Access denied to content document';
-
- case goog.net.ErrorCode.FILE_NOT_FOUND:
- return 'File not found';
-
- case goog.net.ErrorCode.FF_SILENT_ERROR:
- return 'Firefox silently errored';
-
- case goog.net.ErrorCode.CUSTOM_ERROR:
- return 'Application custom error';
-
- case goog.net.ErrorCode.EXCEPTION:
- return 'An exception occurred';
-
- case goog.net.ErrorCode.HTTP_ERROR:
- return 'Http response at 400 or 500 level';
-
- case goog.net.ErrorCode.ABORT:
- return 'Request was aborted';
-
- case goog.net.ErrorCode.TIMEOUT:
- return 'Request timed out';
-
- case goog.net.ErrorCode.OFFLINE:
- return 'The resource is not available offline';
-
- default:
- return 'Unrecognized error code';
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/eventtype.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/eventtype.js.svn-base
deleted file mode 100644
index ac86979..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/eventtype.js.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Common events for the network classes.
- */
-
-
-goog.provide('goog.net.EventType');
-
-
-/**
- * Event names for network events
- * @enum {string}
- */
-goog.net.EventType = {
- COMPLETE: 'complete',
- SUCCESS: 'success',
- ERROR: 'error',
- ABORT: 'abort',
- READY: 'ready',
- READY_STATE_CHANGE: 'readystatechange',
- TIMEOUT: 'timeout',
- INCREMENTAL_DATA: 'incrementaldata',
- PROGRESS: 'progress'
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader.js.svn-base
deleted file mode 100644
index da551a1..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader.js.svn-base
+++ /dev/null
@@ -1,741 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview A class for downloading remote files and storing them
- * locally using the HTML5 FileSystem API.
- *
- * The directory structure is of the form /HASH/URL/BASENAME:
- *
- * The HASH portion is a three-character slice of the hash of the URL. Since the
- * filesystem has a limit of about 5000 files per directory, this should divide
- * the downloads roughly evenly among about 5000 directories, thus allowing for
- * at most 5000^2 downloads.
- *
- * The URL portion is the (sanitized) full URL used for downloading the file.
- * This is used to ensure that each file ends up in a different location, even
- * if the HASH and BASENAME are the same.
- *
- * The BASENAME portion is the basename of the URL. It's used for the filename
- * proper so that the local filesystem: URL will be downloaded to a file with a
- * recognizable name.
- *
- */
-
-goog.provide('goog.net.FileDownloader');
-goog.provide('goog.net.FileDownloader.Error');
-
-goog.require('goog.Disposable');
-goog.require('goog.asserts');
-goog.require('goog.async.Deferred');
-goog.require('goog.crypt.hash32');
-goog.require('goog.debug.Error');
-goog.require('goog.events.EventHandler');
-goog.require('goog.fs');
-goog.require('goog.fs.DirectoryEntry.Behavior');
-goog.require('goog.fs.Error.ErrorCode');
-goog.require('goog.fs.FileSaver.EventType');
-goog.require('goog.net.EventType');
-goog.require('goog.net.XhrIo.ResponseType');
-goog.require('goog.net.XhrIoPool');
-
-
-
-/**
- * A class for downloading remote files and storing them locally using the
- * HTML5 filesystem API.
- *
- * @param {!goog.fs.DirectoryEntry} dir The directory in which the downloaded
- * files are stored. This directory should be solely managed by
- * FileDownloader.
- * @param {goog.net.XhrIoPool=} opt_pool The pool of XhrIo objects to use for
- * downloading files.
- * @constructor
- * @extends {goog.Disposable}
- */
-goog.net.FileDownloader = function(dir, opt_pool) {
- goog.base(this);
-
- /**
- * The directory in which the downloaded files are stored.
- * @type {!goog.fs.DirectoryEntry}
- * @private
- */
- this.dir_ = dir;
-
- /**
- * The pool of XHRs to use for capturing.
- * @type {!goog.net.XhrIoPool}
- * @private
- */
- this.pool_ = opt_pool || new goog.net.XhrIoPool();
-
- /**
- * A map from URLs to active downloads running for those URLs.
- * @type {!Object.<!goog.net.FileDownloader.Download_>}
- * @private
- */
- this.downloads_ = {};
-
- /**
- * The handler for URL capturing events.
- * @type {!goog.events.EventHandler}
- * @private
- */
- this.eventHandler_ = new goog.events.EventHandler(this);
-};
-goog.inherits(goog.net.FileDownloader, goog.Disposable);
-
-
-/**
- * Download a remote file and save its contents to the filesystem. A given file
- * is uniquely identified by its URL string; this means that the relative and
- * absolute URLs for a single file are considered different for the purposes of
- * the FileDownloader.
- *
- * Returns a Deferred that will contain the downloaded blob. If there's an error
- * while downloading the URL, this Deferred will be passed the
- * {@link goog.net.FileDownloader.Error} object as an errback.
- *
- * If a download is already in progress for the given URL, this will return the
- * deferred blob for that download. If the URL has already been downloaded, this
- * will fail once it tries to save the downloaded blob.
- *
- * When a download is in progress, all Deferreds returned for that download will
- * be branches of a single parent. If all such branches are cancelled, or if one
- * is cancelled with opt_deepCancel set, then the download will be cancelled as
- * well.
- *
- * @param {string} url The URL of the file to download.
- * @return {!goog.async.Deferred} The deferred result blob.
- */
-goog.net.FileDownloader.prototype.download = function(url) {
- if (this.isDownloading(url)) {
- return this.downloads_[url].deferred.branch(true /* opt_propagateCancel */);
- }
-
- var download = new goog.net.FileDownloader.Download_(url, this);
- this.downloads_[url] = download;
- this.pool_.getObject(goog.bind(this.gotXhr_, this, download));
- return download.deferred.branch(true /* opt_propagateCancel */);
-};
-
-
-/**
- * Return a Deferred that will fire once no download is active for a given URL.
- * If there's no download active for that URL when this is called, the deferred
- * will fire immediately; otherwise, it will fire once the download is complete,
- * whether or not it succeeds.
- *
- * @param {string} url The URL of the download to wait for.
- * @return {!goog.async.Deferred} The Deferred that will fire when the download
- * is complete.
- */
-goog.net.FileDownloader.prototype.waitForDownload = function(url) {
- var deferred = new goog.async.Deferred();
- if (this.isDownloading(url)) {
- this.downloads_[url].deferred.addBoth(function() {
- deferred.callback(null);
- }, this);
- } else {
- deferred.callback(null);
- }
- return deferred;
-};
-
-
-/**
- * Returns whether or not there is an active download for a given URL.
- *
- * @param {string} url The URL of the download to check.
- * @return {boolean} Whether or not there is an active download for the URL.
- */
-goog.net.FileDownloader.prototype.isDownloading = function(url) {
- return url in this.downloads_;
-};
-
-
-/**
- * Load a downloaded blob from the filesystem. Will fire a deferred error if the
- * given URL has not yet been downloaded.
- *
- * @param {string} url The URL of the blob to load.
- * @return {!goog.async.Deferred} The deferred Blob object. The callback will be
- * passed the blob. If a file API error occurs while loading the blob, that
- * error will be passed to the errback.
- */
-goog.net.FileDownloader.prototype.getDownloadedBlob = function(url) {
- return this.getFile_(url).
- addCallback(function(fileEntry) { return fileEntry.file(); });
-};
-
-
-/**
- * Get the local filesystem: URL for a downloaded file. This is different from
- * the blob: URL that's available from getDownloadedBlob(). If the end user
- * accesses the filesystem: URL, the resulting file's name will be determined by
- * the download filename as opposed to an arbitrary GUID. In addition, the
- * filesystem: URL is connected to a filesystem location, so if the download is
- * removed then that URL will become invalid.
- *
- * Warning: in Chrome 12, some filesystem: URLs are opened inline. This means
- * that e.g. HTML pages given to the user via filesystem: URLs will be opened
- * and processed by the browser.
- *
- * @param {string} url The URL of the file to get the URL of.
- * @return {!goog.async.Deferred} The deferred filesystem: URL. The callback
- * will be passed the URL. If a file API error occurs while loading the
- * blob, that error will be passed to the errback.
- */
-goog.net.FileDownloader.prototype.getLocalUrl = function(url) {
- return this.getFile_(url).
- addCallback(function(fileEntry) { return fileEntry.toUrl(); });
-};
-
-
-/**
- * Return (deferred) whether or not a URL has been downloaded. Will fire a
- * deferred error if something goes wrong when determining this.
- *
- * @param {string} url The URL to check.
- * @return {!goog.async.Deferred} The deferred boolean. The callback will be
- * passed the boolean. If a file API error occurs while checking the
- * existence of the downloaded URL, that error will be passed to the
- * errback.
- */
-goog.net.FileDownloader.prototype.isDownloaded = function(url) {
- var deferred = new goog.async.Deferred();
- var blobDeferred = this.getDownloadedBlob(url);
- blobDeferred.addCallback(function() {
- deferred.callback(true);
- });
- blobDeferred.addErrback(function(err) {
- if (err.code == goog.fs.Error.ErrorCode.NOT_FOUND) {
- deferred.callback(false);
- } else {
- deferred.errback(err);
- }
- });
- return deferred;
-};
-
-
-/**
- * Remove a URL from the FileDownloader.
- *
- * This returns a Deferred. If the removal is completed successfully, its
- * callback will be called without any value. If the removal fails, its errback
- * will be called with the {@link goog.fs.Error}.
- *
- * @param {string} url The URL to remove.
- * @return {!goog.async.Deferred} The deferred used for registering callbacks on
- * success or on error.
- */
-goog.net.FileDownloader.prototype.remove = function(url) {
- return this.getDir_(url, goog.fs.DirectoryEntry.Behavior.DEFAULT).
- addCallback(function(dir) { return dir.removeRecursively(); });
-};
-
-
-/**
- * Save a blob for a given URL. This works just as through the blob were
- * downloaded form that URL, except you specify the blob and no HTTP request is
- * made.
- *
- * If the URL is currently being downloaded, it's indeterminate whether the blob
- * being set or the blob being downloaded will end up in the filesystem.
- * Whichever one doesn't get saved will have an error. To ensure that one or the
- * other takes precedence, use {@link #waitForDownload} to allow the download to
- * complete before setting the blob.
- *
- * @param {string} url The URL at which to set the blob.
- * @param {!Blob} blob The blob to set.
- * @param {string=} opt_name The name of the file. If this isn't given, it's
- * determined from the URL.
- * @return {!goog.async.Deferred} The deferred used for registering callbacks on
- * success or on error. This can be cancelled just like a {@link #download}
- * Deferred. The objects passed to the errback will be
- * {@link goog.net.FileDownloader.Error}s.
- */
-goog.net.FileDownloader.prototype.setBlob = function(url, blob, opt_name) {
- var name = this.sanitize_(opt_name || this.urlToName_(url));
- var download = new goog.net.FileDownloader.Download_(url, this);
- this.downloads_[url] = download;
- download.blob = blob;
- this.getDir_(download.url, goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE).
- addCallback(function(dir) {
- return dir.getFile(
- name, goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE);
- }).
- addCallback(goog.bind(this.fileSuccess_, this, download)).
- addErrback(goog.bind(this.error_, this, download));
- return download.deferred.branch(true /* opt_propagateCancel */);
-};
-
-
-/**
- * The callback called when an XHR becomes available from the XHR pool.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @param {!goog.net.XhrIo} xhr The XhrIo object for downloading the page.
- * @private
- */
-goog.net.FileDownloader.prototype.gotXhr_ = function(download, xhr) {
- if (download.cancelled) {
- this.freeXhr_(xhr);
- return;
- }
-
- this.eventHandler_.listen(
- xhr, goog.net.EventType.SUCCESS,
- goog.bind(this.xhrSuccess_, this, download));
- this.eventHandler_.listen(
- xhr, [goog.net.EventType.ERROR, goog.net.EventType.ABORT],
- goog.bind(this.error_, this, download));
- this.eventHandler_.listen(
- xhr, goog.net.EventType.READY,
- goog.bind(this.freeXhr_, this, xhr));
-
- download.xhr = xhr;
- xhr.setResponseType(goog.net.XhrIo.ResponseType.ARRAY_BUFFER);
- xhr.send(download.url);
-};
-
-
-/**
- * The callback called when an XHR succeeds in downloading a remote file.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @private
- */
-goog.net.FileDownloader.prototype.xhrSuccess_ = function(download) {
- if (download.cancelled) {
- return;
- }
-
- var name = this.sanitize_(this.getName_(
- /** @type {!goog.net.XhrIo} */ (download.xhr)));
- var resp = /** @type {ArrayBuffer} */ (download.xhr.getResponse());
- if (!resp) {
- // This should never happen - it indicates the XHR hasn't completed, has
- // failed or has been cleaned up. If it does happen (eg. due to a bug
- // somewhere) we don't want to pass null to getBlob - it's not valid and
- // triggers a bug in some versions of WebKit causing it to crash.
- this.error_(download);
- return;
- }
-
- download.blob = goog.fs.getBlob(resp);
- delete download.xhr;
-
- this.getDir_(download.url, goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE).
- addCallback(function(dir) {
- return dir.getFile(
- name, goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE);
- }).
- addCallback(goog.bind(this.fileSuccess_, this, download)).
- addErrback(goog.bind(this.error_, this, download));
-};
-
-
-/**
- * The callback called when a file that will be used for saving a file is
- * successfully opened.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @param {!goog.fs.FileEntry} file The newly-opened file object.
- * @private
- */
-goog.net.FileDownloader.prototype.fileSuccess_ = function(download, file) {
- if (download.cancelled) {
- file.remove();
- return;
- }
-
- download.file = file;
- file.createWriter().
- addCallback(goog.bind(this.fileWriterSuccess_, this, download)).
- addErrback(goog.bind(this.error_, this, download));
-};
-
-
-/**
- * The callback called when a file writer is succesfully created for writing a
- * file to the filesystem.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @param {!goog.fs.FileWriter} writer The newly-created file writer object.
- * @private
- */
-goog.net.FileDownloader.prototype.fileWriterSuccess_ = function(
- download, writer) {
- if (download.cancelled) {
- download.file.remove();
- return;
- }
-
- download.writer = writer;
- writer.write(/** @type {!Blob} */ (download.blob));
- this.eventHandler_.listenOnce(
- writer,
- goog.fs.FileSaver.EventType.WRITE_END,
- goog.bind(this.writeEnd_, this, download));
-};
-
-
-/**
- * The callback called when file writing ends, whether or not it's successful.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @private
- */
-goog.net.FileDownloader.prototype.writeEnd_ = function(download) {
- if (download.cancelled || download.writer.getError()) {
- this.error_(download, download.writer.getError());
- return;
- }
-
- delete this.downloads_[download.url];
- download.deferred.callback(download.blob);
-};
-
-
-/**
- * The error callback for all asynchronous operations. Ensures that all stages
- * of a given download are cleaned up, and emits the error event.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * this download.
- * @param {goog.fs.Error=} opt_err The file error object. Only defined if the
- * error was raised by the file API.
- * @private
- */
-goog.net.FileDownloader.prototype.error_ = function(download, opt_err) {
- if (download.file) {
- download.file.remove();
- }
-
- if (download.cancelled) {
- return;
- }
-
- delete this.downloads_[download.url];
- download.deferred.errback(
- new goog.net.FileDownloader.Error(download, opt_err));
-};
-
-
-/**
- * Abort the download of the given URL.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download to abort.
- * @private
- */
-goog.net.FileDownloader.prototype.cancel_ = function(download) {
- goog.dispose(download);
- delete this.downloads_[download.url];
-};
-
-
-/**
- * Get the directory for a given URL. If the directory already exists when this
- * is called, it will contain exactly one file: the downloaded file.
- *
- * This not only calls the FileSystem API's getFile method, but attempts to
- * distribute the files so that they don't overload the filesystem. The spec
- * says directories can't contain more than 5000 files
- * (http://www.w3.org/TR/file-system-api/#directories), so this ensures that
- * each file is put into a subdirectory based on its SHA1 hash.
- *
- * All parameters are the same as in the FileSystem API's Entry#getFile method.
- *
- * @param {string} url The URL corresponding to the directory to get.
- * @param {goog.fs.DirectoryEntry.Behavior} behavior The behavior to pass to the
- * underlying method.
- * @return {!goog.async.Deferred} The deferred DirectoryEntry object.
- * @private
- */
-goog.net.FileDownloader.prototype.getDir_ = function(url, behavior) {
- // 3 hex digits provide 16**3 = 4096 different possible dirnames, which is
- // less than the maximum of 5000 entries. Downloaded files should be
- // distributed roughly evenly throughout the directories due to the hash
- // function, allowing many more than 5000 files to be downloaded.
- //
- // The leading ` ensures that no illegal dirnames are accidentally used. % was
- // previously used, but Chrome has a bug (as of 12.0.725.0 dev) where
- // filenames are URL-decoded before checking their validity, so filenames
- // containing e.g. '%3f' (the URL-encoding of :, an invalid character) are
- // rejected.
- var dirname = '`' + Math.abs(goog.crypt.hash32.encodeString(url)).
- toString(16).substring(0, 3);
-
- return this.dir_.
- getDirectory(dirname, goog.fs.DirectoryEntry.Behavior.CREATE).
- addCallback(function(dir) {
- return dir.getDirectory(this.sanitize_(url), behavior);
- }, this);
-};
-
-
-/**
- * Get the file for a given URL. This will only retrieve files that have already
- * been saved; it shouldn't be used for creating the file in the first place.
- * This is because the filename isn't necessarily determined by the URL, but by
- * the headers of the XHR response.
- *
- * @param {string} url The URL corresponding to the file to get.
- * @return {!goog.async.Deferred} The deferred FileEntry object.
- * @private
- */
-goog.net.FileDownloader.prototype.getFile_ = function(url) {
- return this.getDir_(url, goog.fs.DirectoryEntry.Behavior.DEFAULT).
- addCallback(function(dir) {
- return dir.listDirectory().addCallback(function(files) {
- goog.asserts.assert(files.length == 1);
- // If the filesystem somehow gets corrupted and we end up with an
- // empty directory here, it makes sense to just return the normal
- // file-not-found error.
- return files[0] || dir.getFile('file');
- });
- });
-};
-
-
-/**
- * Sanitize a string so it can be safely used as a file or directory name for
- * the FileSystem API.
- *
- * @param {string} str The string to sanitize.
- * @return {string} The sanitized string.
- * @private
- */
-goog.net.FileDownloader.prototype.sanitize_ = function(str) {
- // Add a prefix, since certain prefixes are disallowed for paths. None of the
- // disallowed prefixes start with '`'. We use ` rather than % for escaping the
- // filename due to a Chrome bug (as of 12.0.725.0 dev) where filenames are
- // URL-decoded before checking their validity, so filenames containing e.g.
- // '%3f' (the URL-encoding of :, an invalid character) are rejected.
- return '`' + str.replace(/[\/\\<>:?*"|%`]/g, encodeURIComponent).
- replace(/%/g, '`');
-};
-
-
-/**
- * Gets the filename specified by the XHR. This first attempts to parse the
- * Content-Disposition header for a filename and, failing that, falls back on
- * deriving the filename from the URL.
- *
- * @param {!goog.net.XhrIo} xhr The XHR containing the response headers.
- * @return {string} The filename.
- * @private
- */
-goog.net.FileDownloader.prototype.getName_ = function(xhr) {
- var disposition = xhr.getResponseHeader('Content-Disposition');
- var match = disposition &&
- disposition.match(/^attachment *; *filename="(.*)"$/i);
- if (match) {
- // The Content-Disposition header allows for arbitrary backslash-escaped
- // characters (usually " and \). We want to unescape them before using them
- // in the filename.
- return match[1].replace(/\\(.)/g, '$1');
- }
-
- return this.urlToName_(xhr.getLastUri());
-};
-
-
-/**
- * Extracts the basename from a URL.
- *
- * @param {string} url The URL.
- * @return {string} The basename.
- * @private
- */
-goog.net.FileDownloader.prototype.urlToName_ = function(url) {
- var segments = url.split('/');
- return segments[segments.length - 1];
-};
-
-
-/**
- * Remove all event listeners for an XHR and release it back into the pool.
- *
- * @param {!goog.net.XhrIo} xhr The XHR to free.
- * @private
- */
-goog.net.FileDownloader.prototype.freeXhr_ = function(xhr) {
- goog.events.removeAll(xhr);
- this.pool_.addFreeObject(xhr);
-};
-
-
-/** @override */
-goog.net.FileDownloader.prototype.disposeInternal = function() {
- delete this.dir_;
- goog.dispose(this.eventHandler_);
- delete this.eventHandler_;
- goog.object.forEach(this.downloads_, function(download) {
- download.deferred.cancel();
- }, this);
- delete this.downloads_;
- goog.dispose(this.pool_);
- delete this.pool_;
-
- goog.base(this, 'disposeInternal');
-};
-
-
-
-/**
- * The error object for FileDownloader download errors.
- *
- * @param {!goog.net.FileDownloader.Download_} download The download object for
- * the download in question.
- * @param {goog.fs.Error=} opt_fsErr The file error object, if this was a file
- * error.
- *
- * @constructor
- * @extends {goog.debug.Error}
- */
-goog.net.FileDownloader.Error = function(download, opt_fsErr) {
- goog.base(this, 'Error capturing URL ' + download.url);
-
- /**
- * The URL the event relates to.
- * @type {string}
- */
- this.url = download.url;
-
- if (download.xhr) {
- this.xhrStatus = download.xhr.getStatus();
- this.xhrErrorCode = download.xhr.getLastErrorCode();
- this.message += ': XHR failed with status ' + this.xhrStatus +
- ' (error code ' + this.xhrErrorCode + ')';
- } else if (opt_fsErr) {
- this.fileError = opt_fsErr;
- this.message += ': file API failed (' + opt_fsErr.message + ')';
- }
-};
-goog.inherits(goog.net.FileDownloader.Error, goog.debug.Error);
-
-
-/**
- * The status of the XHR. Only set if the error was caused by an XHR failure.
- * @type {number|undefined}
- */
-goog.net.FileDownloader.Error.prototype.xhrStatus;
-
-
-/**
- * The error code of the XHR. Only set if the error was caused by an XHR
- * failure.
- * @type {goog.net.ErrorCode|undefined}
- */
-goog.net.FileDownloader.Error.prototype.xhrErrorCode;
-
-
-/**
- * The file API error. Only set if the error was caused by the file API.
- * @type {goog.fs.Error|undefined}
- */
-goog.net.FileDownloader.Error.prototype.fileError;
-
-
-
-/**
- * A struct containing the data for a single download.
- *
- * @param {string} url The URL for the file being downloaded.
- * @param {!goog.net.FileDownloader} downloader The parent FileDownloader.
- * @extends {goog.Disposable}
- * @constructor
- * @private
- */
-goog.net.FileDownloader.Download_ = function(url, downloader) {
- goog.base(this);
-
- /**
- * The URL for the file being downloaded.
- * @type {string}
- */
- this.url = url;
-
- /**
- * The Deferred that will be fired when the download is complete.
- * @type {!goog.async.Deferred}
- */
- this.deferred = new goog.async.Deferred(
- goog.bind(downloader.cancel_, downloader, this));
-
- /**
- * Whether this download has been cancelled by the user.
- * @type {boolean}
- */
- this.cancelled = false;
-
- /**
- * The XhrIo object for downloading the file. Only set once it's been
- * retrieved from the pool.
- * @type {goog.net.XhrIo}
- */
- this.xhr = null;
-
- /**
- * The name of the blob being downloaded. Only sey once the XHR has completed,
- * if it completed successfully.
- * @type {?string}
- */
- this.name = null;
-
- /**
- * The downloaded blob. Only set once the XHR has completed, if it completed
- * successfully.
- * @type {Blob}
- */
- this.blob = null;
-
- /**
- * The file entry where the blob is to be stored. Only set once it's been
- * loaded from the filesystem.
- * @type {goog.fs.FileEntry}
- */
- this.file = null;
-
- /**
- * The file writer for writing the blob to the filesystem. Only set once it's
- * been loaded from the filesystem.
- * @type {goog.fs.FileWriter}
- */
- this.writer = null;
-};
-goog.inherits(goog.net.FileDownloader.Download_, goog.Disposable);
-
-
-/** @override */
-goog.net.FileDownloader.Download_.prototype.disposeInternal = function() {
- this.cancelled = true;
- if (this.xhr) {
- this.xhr.abort();
- } else if (this.writer && this.writer.getReadyState() ==
- goog.fs.FileSaver.ReadyState.WRITING) {
- this.writer.abort();
- }
-
- goog.base(this, 'disposeInternal');
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader_test.html.svn-base
deleted file mode 100644
index f70b54a..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/filedownloader_test.html.svn-base
+++ /dev/null
@@ -1,372 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2011 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<title>Closure Unit Tests - goog.net.FileDownloader</title>
-<script src="../base.js"></script>
-<script>
-goog.require('goog.fs.Error.ErrorCode')
-goog.require('goog.net.ErrorCode')
-goog.require('goog.net.FileDownloader')
-goog.require('goog.testing.fs')
-goog.require('goog.testing.jsunit')
-goog.require('goog.testing.net.XhrIoPool')
-goog.require('goog.testing.AsyncTestCase')
-goog.require('goog.testing.PropertyReplacer')
-</script>
-</head>
-<body>
-<script>
-
-var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall();
-var xhrIoPool, xhr, fs, dir, downloader;
-
-function setUpPage() {
- goog.testing.fs.install(new goog.testing.PropertyReplacer());
-}
-
-function setUp() {
- xhrIoPool = new goog.testing.net.XhrIoPool();
- xhr = xhrIoPool.getXhr();
- fs = new goog.testing.fs.FileSystem();
- dir = fs.getRoot();
- downloader = new goog.net.FileDownloader(dir, xhrIoPool);
-}
-
-function tearDown() {
- goog.dispose(downloader);
-}
-
-function testDownload() {
- downloader.download('/foo/bar').addCallback(function(blob) {
- var fileEntry = dir.getFileSync('`3fa/``2Ffoo`2Fbar/`bar');
- assertEquals('data', blob.toString());
- assertEquals('data', fileEntry.fileSync().toString());
- asyncTestCase.continueTesting();
- }).addErrback(function(err) { throw err; });
-
- assertEquals('/foo/bar', xhr.getLastUri());
- assertEquals(goog.net.XhrIo.ResponseType.ARRAY_BUFFER, xhr.getResponseType());
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testDownload');
-}
-
-function testGetDownloadedBlob() {
- downloader.download('/foo/bar').
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addCallback(function(blob) { assertEquals('data', blob.toString()); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testGetDownloadedBlob');
-}
-
-function testGetLocalUrl() {
- downloader.download('/foo/bar').
- addCallback(function() { return downloader.getLocalUrl('/foo/bar'); }).
- addCallback(function(url) { assertMatches(/\/`bar$/, url); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testGetLocalUrl');
-}
-
-function testLocalUrlWithContentDisposition() {
- downloader.download('/foo/bar').
- addCallback(function() { return downloader.getLocalUrl('/foo/bar'); }).
- addCallback(function(url) { assertMatches(/\/`qux`22bap$/, url); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- xhr.simulateResponse(
- 200, 'data', {'Content-Disposition': 'attachment; filename="qux\\"bap"'});
- asyncTestCase.waitForAsync('testGetLocalUrl');
-}
-
-function testIsDownloaded() {
- downloader.download('/foo/bar').
- addCallback(function() { return downloader.isDownloaded('/foo/bar'); }).
- addCallback(assertTrue).
- addCallback(function() { return downloader.isDownloaded('/foo/baz'); }).
- addCallback(assertFalse).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testIsDownloaded');
-}
-
-function testRemove() {
- downloader.download('/foo/bar').
- addCallback(function() { return downloader.remove('/foo/bar'); }).
- addCallback(function() { return downloader.isDownloaded('/foo/bar'); }).
- addCallback(assertFalse).
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addErrback(function(err) {
- assertEquals(goog.fs.Error.ErrorCode.NOT_FOUND, err.code);
- var download = downloader.download('/foo/bar');
- xhr.simulateResponse(200, 'more data');
- return download;
- }).
- addCallback(function() { return downloader.isDownloaded('/foo/bar'); }).
- addCallback(assertTrue).
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addCallback(function(blob) {
- assertEquals('more data', blob.toString());
- }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testRemove');
-}
-
-function testSetBlob() {
- downloader.setBlob('/foo/bar', goog.testing.fs.getBlob('data')).
- addCallback(function() { return downloader.isDownloaded('/foo/bar'); }).
- addCallback(assertTrue).
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addCallback(function(blob) {
- assertEquals('data', blob.toString());
- }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- asyncTestCase.waitForAsync('testSetBlob');
-}
-
-function testSetBlobWithName() {
- downloader.setBlob('/foo/bar', goog.testing.fs.getBlob('data'), 'qux').
- addCallback(function() { return downloader.getLocalUrl('/foo/bar'); }).
- addCallback(function(url) { assertMatches(/\/`qux$/, url); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase)).
- addErrback(function(err) { throw err; });
-
- asyncTestCase.waitForAsync('testSetBlob');
-}
-
-function testDownloadDuringDownload() {
- var download1 = downloader.download('/foo/bar');
- var download2 = downloader.download('/foo/bar');
-
- download1.
- addCallback(function() { return download2; }).
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addCallback(function(blob) { assertEquals('data', blob.toString()); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- // There should only need to be one response for both downloads, since the
- // second should return the same deferred as the first.
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testDownloadeduringDownload');
-}
-
-function testGetDownloadedBlobDuringDownload() {
- var download = downloader.download('/foo/bar');
- downloader.waitForDownload('/foo/bar').addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).addCallback(function(blob) {
- assertTrue(download.hasFired());
- assertEquals('data', blob.toString());
- asyncTestCase.continueTesting();
- });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testGetDownloadedBlobDuringDownload');
-}
-
-function testIsDownloadedDuringDownload() {
- var download = downloader.download('/foo/bar');
- downloader.waitForDownload('/foo/bar').addCallback(function() {
- return downloader.isDownloaded('/foo/bar');
- }).addCallback(function(isDownloaded) {
- assertTrue(download.hasFired());
- assertTrue(isDownloaded);
- asyncTestCase.continueTesting();
- });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testIsDownloadedDuringDownload');
-}
-
-function testRemoveDuringDownload() {
- var download = downloader.download('/foo/bar');
- downloader.
- waitForDownload('/foo/bar').
- addCallback(function() { return downloader.remove('/foo/bar'); }).
- addCallback(function() { assertTrue(download.hasFired()); }).
- addCallback(function() { return downloader.isDownloaded('/foo/bar'); }).
- addCallback(assertFalse).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testRemoveDuringDownload');
-}
-
-function testSetBlobDuringDownload() {
- var download = downloader.download('/foo/bar');
- downloader.
- waitForDownload('/foo/bar').
- addCallback(function() {
- return downloader.setBlob(
- '/foo/bar', goog.testing.fs.getBlob('blob data'));
- }).
- addErrback(function(err) {
- assertEquals(goog.fs.Error.ErrorCode.PATH_EXISTS, err.fileError.code);
- return download;
- }).
- addCallback(function() {
- return downloader.getDownloadedBlob('/foo/bar');
- }).
- addCallback(function(b) { assertEquals('xhr data', b.toString()); }).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- xhr.simulateResponse(200, 'xhr data');
- asyncTestCase.waitForAsync('testSetBlobDuringDownload');
-}
-
-function testDownloadCancelledBeforeXhr() {
- var download = downloader.download('/foo/bar');
- download.cancel();
-
- download.
- addErrback(function() {
- assertEquals('/foo/bar', xhr.getLastUri());
- assertEquals(goog.net.ErrorCode.ABORT, xhr.getLastErrorCode());
- assertFalse(xhr.isActive());
-
- return downloader.isDownloaded('/foo/bar');
- }).
- addCallback(assertFalse).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- asyncTestCase.waitForAsync('testDownloadCancelledBeforeXhr');
-}
-
-function testDownloadCancelledAfterXhr() {
- var download = downloader.download('/foo/bar');
- xhr.simulateResponse(200, 'data');
- download.cancel();
-
- download.
- addErrback(function() {
- assertEquals('/foo/bar', xhr.getLastUri());
- assertEquals(goog.net.ErrorCode.NO_ERROR, xhr.getLastErrorCode());
- assertFalse(xhr.isActive());
-
- return downloader.isDownloaded('/foo/bar');
- }).
- addCallback(assertFalse).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- asyncTestCase.waitForAsync('testDownloadCancelledAfterXhr');
-}
-
-function testFailedXhr() {
- downloader.download('/foo/bar').
- addErrback(function(err) {
- assertEquals('/foo/bar', err.url);
- assertEquals(404, err.xhrStatus);
- assertEquals(goog.net.ErrorCode.HTTP_ERROR, err.xhrErrorCode);
- assertUndefined(err.fileError);
-
- return downloader.isDownloaded('/foo/bar');
- }).
- addCallback(assertFalse).
- addCallback(goog.bind(asyncTestCase.continueTesting, asyncTestCase));
-
- xhr.simulateResponse(404);
- asyncTestCase.waitForAsync('testFailedXhr');
-}
-
-function testFailedDownloadSave() {
- downloader.download('/foo/bar').
- addCallback(function() {
- var download = downloader.download('/foo/bar');
- xhr.simulateResponse(200, 'data');
- return download;
- }).
- addErrback(function(err) {
- assertEquals('/foo/bar', err.url);
- assertUndefined(err.xhrStatus);
- assertUndefined(err.xhrErrorCode);
- assertEquals(goog.fs.Error.ErrorCode.PATH_EXISTS, err.fileError.code);
-
- asyncTestCase.continueTesting();
- });
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testFailedDownloadSave');
-}
-
-function testFailedGetDownloadedBlob() {
- downloader.getDownloadedBlob('/foo/bar').
- addErrback(function(err) {
- assertEquals(goog.fs.Error.ErrorCode.NOT_FOUND, err.code);
- asyncTestCase.continueTesting();
- });
-
- asyncTestCase.waitForAsync('testFailedGetDownloadedBlob');
-}
-
-function testFailedRemove() {
- downloader.remove('/foo/bar').
- addErrback(function(err) {
- assertEquals(goog.fs.Error.ErrorCode.NOT_FOUND, err.code);
- asyncTestCase.continueTesting();
- });
-
- asyncTestCase.waitForAsync('testFailedRemove');
-}
-
-function testIsDownloading() {
- assertFalse(downloader.isDownloading('/foo/bar'));
- downloader.download('/foo/bar').addCallback(function() {
- assertFalse(downloader.isDownloading('/foo/bar'));
- asyncTestCase.continueTesting();
- });
-
- assertTrue(downloader.isDownloading('/foo/bar'));
-
- xhr.simulateResponse(200, 'data');
- asyncTestCase.waitForAsync('testIsDownloading');
-}
-
-function testIsDownloadingWhenCancelled() {
- assertFalse(downloader.isDownloading('/foo/bar'));
- var deferred = downloader.download('/foo/bar').addErrback(function() {
- assertFalse(downloader.isDownloading('/foo/bar'));
- });
-
- assertTrue(downloader.isDownloading('/foo/bar'));
- deferred.cancel();
-}
-
-function assertMatches(expected, actual) {
- assert(
- 'Expected "' + actual + '" to match ' + expected,
- expected.test(actual));
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/httpstatus.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/httpstatus.js.svn-base
deleted file mode 100644
index eecb270..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/httpstatus.js.svn-base
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Constants for HTTP status codes.
- */
-
-goog.provide('goog.net.HttpStatus');
-
-
-/**
- * HTTP Status Codes defined in RFC 2616.
- * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- * @enum {number}
- */
-goog.net.HttpStatus = {
- // Informational 1xx
- CONTINUE: 100,
- SWITCHING_PROTOCOLS: 101,
-
- // Successful 2xx
- OK: 200,
- CREATED: 201,
- ACCEPTED: 202,
- NON_AUTHORITATIVE_INFORMATION: 203,
- NO_CONTENT: 204,
- RESET_CONTENT: 205,
- PARTIAL_CONTENT: 206,
-
- // Redirection 3xx
- MULTIPLE_CHOICES: 300,
- MOVED_PERMANENTLY: 301,
- FOUND: 302,
- SEE_OTHER: 303,
- NOT_MODIFIED: 304,
- USE_PROXY: 305,
- TEMPORARY_REDIRECT: 307,
-
- // Client Error 4xx
- BAD_REQUEST: 400,
- UNAUTHORIZED: 401,
- PAYMENT_REQUIRED: 402,
- FORBIDDEN: 403,
- NOT_FOUND: 404,
- METHOD_NOT_ALLOWED: 405,
- NOT_ACCEPTABLE: 406,
- PROXY_AUTHENTICATION_REQUIRED: 407,
- REQUEST_TIMEOUT: 408,
- CONFLICT: 409,
- GONE: 410,
- LENGTH_REQUIRED: 411,
- PRECONDITION_FAILED: 412,
- REQUEST_ENTITY_TOO_LARGE: 413,
- REQUEST_URI_TOO_LONG: 414,
- UNSUPPORTED_MEDIA_TYPE: 415,
- REQUEST_RANGE_NOT_SATISFIABLE: 416,
- EXPECTATION_FAILED: 417,
-
- // Server Error 5xx
- INTERNAL_SERVER_ERROR: 500,
- NOT_IMPLEMENTED: 501,
- BAD_GATEWAY: 502,
- SERVICE_UNAVAILABLE: 503,
- GATEWAY_TIMEOUT: 504,
- HTTP_VERSION_NOT_SUPPORTED: 505,
-
- /*
- * IE returns this code for 204 due to its use of URLMon, which returns this
- * code for 'Operation Aborted'. The status text is 'Unknown', the response
- * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7.
- */
- QUIRK_IE_NO_CONTENT: 1223
-};
-
-
-/**
- * Returns whether the given status should be considered successful.
- *
- * Successful codes are OK (200), CREATED (201), ACCEPTED (202),
- * NO CONTENT (204), NOT MODIFIED (304), and IE's no content code (1223).
- *
- * @param {number} status The status code to test.
- * @return {boolean} Whether the status code should be considered successful.
- */
-goog.net.HttpStatus.isSuccess = function(status) {
- switch (status) {
- case goog.net.HttpStatus.OK:
- case goog.net.HttpStatus.CREATED:
- case goog.net.HttpStatus.ACCEPTED:
- case goog.net.HttpStatus.NO_CONTENT:
- case goog.net.HttpStatus.NOT_MODIFIED:
- case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:
- return true;
-
- default:
- return false;
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test.html.svn-base
deleted file mode 100644
index d2f4a14..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test.html.svn-base
+++ /dev/null
@@ -1,147 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - Iframe/XHR Execution Context</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.events');
- goog.require('goog.debug.Console');
- goog.require('goog.net.XhrLite');
- goog.require('goog.net.IframeIo');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.jsunit');
- goog.require('goog.Timer');
-</script>
-</head>
-<body>
- <p>
- XmlHttpRequests that initiate from code executed in an iframe, that is then
- destroyed, result in an error in FireFox. This test case is used to verify
- that Closure's IframeIo and XhrLite do not suffer from this problem. See
- <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=369939">
- https://bugzilla.mozilla.org/show_bug.cgi?id=369939</a>.
- </p>
- <p>
- NOTE(pupius): 14/11/2011 The XhrMonitor code has been removed since the
- above bug doesn't manifest in any currently supported versions. This test
- is left in place as a way of verifying the problem doesn't resurface.
- </p>
- <script>
- var c = new goog.debug.Console;
- c.setCapturing(true);
- goog.debug.LogManager.getRoot().setLevel(goog.debug.Logger.Level.ALL);
-
- // Can't use exportSymbol if we want JsUnit support
- top.GG_iframeFn = goog.net.IframeIo.handleIncrementalData;
-
- // Make the dispose time short enough that it will cause the bug to appear
- goog.net.IframeIo.IFRAME_DISPOSE_DELAY_MS = 0;
-
-
- var fileName = 'iframe_xhr_test_response.html';
- var iframeio;
-
- // Create an async test case
- var testCase = new goog.testing.AsyncTestCase(document.title);
- testCase.stepTimeout = 4 * 1000;
- testCase.resultCount = 0;
- testCase.xhrCount = 0;
- testCase.error = null;
-
- /** Set up the iframe io and request the test response page. */
- testCase.setUpPage = function() {
- testCase.waitForAsync('setUpPage');
- iframeio = new goog.net.IframeIo();
- goog.events.listen(
- iframeio, 'incrementaldata', this.onIframeData, false, this);
- goog.events.listen(
- iframeio, 'ready', this.onIframeReady, false, this);
- iframeio.send(fileName);
-
- this.add(new goog.testing.TestCase.Test(
- 'test results', this.testResults, this));
- };
-
- /** Disposes the iframe object. */
- testCase.tearDownPage = function() {
- iframeio.dispose();
- };
-
- /** Handles the packets received from the Iframe incremental results. */
- testCase.onIframeData = function(e) {
- this.log('Data received : ' + e.data);
- this.resultCount++;
- goog.net.XhrLite.send(fileName, goog.bind(this.onXhrData, this));
- };
-
- /** Handles the iframe becoming ready. */
- testCase.onIframeReady = function(e) {
- this.log('Iframe ready');
- var me = this;
- goog.net.XhrLite.send(fileName, goog.bind(this.onXhrData, this));
- };
-
- /** Handles the response from an Xhr request. */
- testCase.onXhrData = function(e) {
- this.xhrCount++;
- // We access status directly so that XhrLite doesn't mask the error that
- // would be thrown in FF if this worked correctly.
- try {
- this.log('Xhr Received: ' + e.target.xhr_.status);
- } catch (e) {
- this.log('ERROR: ' + e.message);
- this.error = e;
- }
- if (this.xhrCount == 4 && this.resultCount == 3) {
- // Wait for the async iframe disposal to fire.
- this.log('Test set up finished, waiting 500ms for iframe disposal');
- goog.Timer.callOnce(goog.bind(this.continueTesting, this), 0);
- }
- };
-
- /** The main test function that validates the results were as expected. */
- testCase.testResults = function() {
- assertEquals('There should be 3 data packets', 3, this.resultCount);
- // 3 results + 1 ready
- assertEquals('There should be 4 XHR results', 4, this.xhrCount);
- if (this.error) {
- throw this.error;
- }
-
- assertEquals('There should be no iframes left', 0,
- document.getElementsByTagName('iframe').length);
- }
-
- /** This test only runs on GECKO browsers. */
- if (goog.userAgent.GECKO) {
- /** Used by the JsUnit test runner. */
- var testXhrMonitorWorksForIframeIoRequests = function() {
- testCase.reset();
- testCase.cycleTests();
- }
-
- /** Used by the JsUnit test runner. */
- var setUpPage = function() {
- testCase.runTests();
- }
- }
-
- // Standalone Closure Test Runner.
- if (typeof G_testRunner != 'undefined') {
- if (goog.userAgent.GECKO) {
- G_testRunner.initialize(testCase);
- } else {
- G_testRunner.setStrict(false);
- }
- }
-
- </script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test_response.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test_response.html.svn-base
deleted file mode 100644
index 3dafbef..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframe_xhr_test_response.html.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
-<!--
-Copyright 2010 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
- <head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
- </head>
- <body>
- <script>top.GG_iframeFn(window, [1, 1, 2, 4, 8]);</script>
- <script>top.GG_iframeFn(window, [12, 20, 32, 52, 84]);</script>
- <script>top.GG_iframeFn(window, [136, 220, 356, 576, 932]);</script>
- </body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio.js.svn-base
deleted file mode 100644
index deb8b39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio.js.svn-base
+++ /dev/null
@@ -1,1300 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Class for managing requests via iFrames. Supports a number of
- * methods of transfer.
- *
- * Gets and Posts can be performed and the resultant page read in as text,
- * JSON, or from the HTML DOM.
- *
- * Using an iframe causes the throbber to spin, this is good for providing
- * feedback to the user that an action has occurred.
- *
- * Requests do not affect the history stack, see goog.History if you require
- * this behavior.
- *
- * The responseText and responseJson methods assume the response is plain,
- * text. You can access the Iframe's DOM through responseXml if you need
- * access to the raw HTML.
- *
- * Tested:
- * + FF2.0 (Win Linux)
- * + IE6, IE7
- * + Opera 9.1,
- * + Chrome
- * - Opera 8.5 fails because of no textContent and buggy innerText support
- *
- * NOTE: Safari doesn't fire the onload handler when loading plain text files
- *
- * This has been tested with Drip in IE to ensure memory usage is as constant
- * as possible. When making making thousands of requests, memory usage stays
- * constant for a while but then starts increasing (<500k for 2000
- * requests) -- this hasn't yet been tracked down yet, though it is cleared up
- * after a refresh.
- *
- *
- * BACKGROUND FILE UPLOAD:
- * By posting an arbitrary form through an IframeIo object, it is possible to
- * implement background file uploads. Here's how to do it:
- *
- * - Create a form:
- * <pre>
- * &lt;form id="form" enctype="multipart/form-data" method="POST"&gt;
- * &lt;input name="userfile" type="file" /&gt;
- * &lt;/form&gt;
- * </pre>
- *
- * - Have the user click the file input
- * - Create an IframeIo instance
- * <pre>
- * var io = new goog.net.IframeIo;
- * goog.events.listen(io, goog.net.EventType.COMPLETE,
- * function() { alert('Sent'); });
- * io.sendFromForm(document.getElementById('form'));
- * </pre>
- *
- *
- * INCREMENTAL LOADING:
- * Gmail sends down multiple script blocks which get executed as they are
- * received by the client. This allows incremental rendering of the thread
- * list and conversations.
- *
- * This requires collaboration with the server that is sending the requested
- * page back. To set incremental loading up, you should:
- *
- * A) In the application code there should be an externed reference to
- * <code>handleIncrementalData()</code>. e.g.
- * goog.exportSymbol('GG_iframeFn', goog.net.IframeIo.handleIncrementalData);
- *
- * B) The response page should them call this method directly, an example
- * response would look something like this:
- * <pre>
- * &lt;html&gt;
- * &lt;head&gt;
- * &lt;meta content="text/html;charset=UTF-8" http-equiv="content-type"&gt;
- * &lt;/head&gt;
- * &lt;body&gt;
- * &lt;script&gt;
- * D = top.P ? function(d) { top.GG_iframeFn(window, d) } : function() {};
- * &lt;/script&gt;
- *
- * &lt;script&gt;D([1, 2, 3, 4, 5]);&lt;/script&gt;
- * &lt;script&gt;D([6, 7, 8, 9, 10]);&lt;/script&gt;
- * &lt;script&gt;D([11, 12, 13, 14, 15]);&lt;/script&gt;
- * &lt;/body&gt;
- * &lt;/html&gt;
- * </pre>
- *
- * Your application should then listen, on the IframeIo instance, to the event
- * goog.net.EventType.INCREMENTAL_DATA. The event object contains a
- * 'data' member which is the content from the D() calls above.
- *
- * NOTE: There can be problems if you save a reference to the data object in IE.
- * If you save an array, and the iframe is dispose, then the array looses its
- * prototype and thus array methods like .join(). You can get around this by
- * creating arrays using the parent window's Array constructor, or you can
- * clone the array.
- *
- *
- * EVENT MODEL:
- * The various send methods work asynchronously. You can be notified about
- * the current status of the request (completed, success or error) by
- * listening for events on the IframeIo object itself. The following events
- * will be sent:
- * - goog.net.EventType.COMPLETE: when the request is completed
- * (either sucessfully or unsuccessfully). You can find out about the result
- * using the isSuccess() and getLastError
- * methods.
- * - goog.net.EventType.SUCCESS</code>: when the request was completed
- * successfully
- * - goog.net.EventType.ERROR: when the request failed
- * - goog.net.EventType.ABORT: when the request has been aborted
- *
- * Example:
- * <pre>
- * var io = new goog.net.IframeIo();
- * goog.events.listen(io, goog.net.EventType.COMPLETE,
- * function() { alert('request complete'); });
- * io.sendFromForm(...);
- * </pre>
- *
- */
-
-goog.provide('goog.net.IframeIo');
-goog.provide('goog.net.IframeIo.IncrementalDataEvent');
-
-goog.require('goog.Timer');
-goog.require('goog.Uri');
-goog.require('goog.debug');
-goog.require('goog.debug.Logger');
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.events.EventTarget');
-goog.require('goog.events.EventType');
-goog.require('goog.json');
-goog.require('goog.net.ErrorCode');
-goog.require('goog.net.EventType');
-goog.require('goog.reflect');
-goog.require('goog.string');
-goog.require('goog.structs');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Class for managing requests via iFrames.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.IframeIo = function() {
-
- /**
- * Name for this IframeIo and frame
- * @type {string}
- * @private
- */
- this.name_ = goog.net.IframeIo.getNextName_();
-
- /**
- * An array of iframes that have been finished with. We need them to be
- * disposed async, so we don't confuse the browser (see below).
- * @type {Array.<Element>}
- * @private
- */
- this.iframesForDisposal_ = [];
-
- // Create a lookup from names to instances of IframeIo. This is a helper
- // function to be used in conjunction with goog.net.IframeIo.getInstanceByName
- // to find the IframeIo object associated with a particular iframe. Used in
- // incremental scripts etc.
- goog.net.IframeIo.instances_[this.name_] = this;
-
-};
-goog.inherits(goog.net.IframeIo, goog.events.EventTarget);
-
-
-/**
- * Object used as a map to lookup instances of IframeIo objects by name.
- * @type {Object}
- * @private
- */
-goog.net.IframeIo.instances_ = {};
-
-
-/**
- * Prefix for frame names
- * @type {string}
- */
-goog.net.IframeIo.FRAME_NAME_PREFIX = 'closure_frame';
-
-
-/**
- * Suffix that is added to inner frames used for sending requests in non-IE
- * browsers
- * @type {string}
- */
-goog.net.IframeIo.INNER_FRAME_SUFFIX = '_inner';
-
-
-/**
- * The number of milliseconds after a request is completed to dispose the
- * iframes. This can be done lazily so we wait long enough for any processing
- * that occurred as a result of the response to finish.
- * @type {number}
- */
-goog.net.IframeIo.IFRAME_DISPOSE_DELAY_MS = 2000;
-
-
-/**
- * Counter used when creating iframes
- * @type {number}
- * @private
- */
-goog.net.IframeIo.counter_ = 0;
-
-
-/**
- * Form element to post to.
- * @type {HTMLFormElement}
- * @private
- */
-goog.net.IframeIo.form_;
-
-
-/**
- * Static send that creates a short lived instance of IframeIo to send the
- * request.
- * @param {goog.Uri|string} uri Uri of the request, it is up the caller to
- * manage query string params.
- * @param {Function=} opt_callback Event handler for when request is completed.
- * @param {string=} opt_method Default is GET, POST uses a form to submit the
- * request.
- * @param {boolean=} opt_noCache Append a timestamp to the request to avoid
- * caching.
- * @param {Object|goog.structs.Map=} opt_data Map of key-value pairs that
- * will be posted to the server via the iframe's form.
- */
-goog.net.IframeIo.send = function(
- uri, opt_callback, opt_method, opt_noCache, opt_data) {
-
- var io = new goog.net.IframeIo();
- goog.events.listen(io, goog.net.EventType.READY, io.dispose, false, io);
- if (opt_callback) {
- goog.events.listen(io, goog.net.EventType.COMPLETE, opt_callback);
- }
- io.send(uri, opt_method, opt_noCache, opt_data);
-};
-
-
-/**
- * Find an iframe by name (assumes the context is goog.global since that is
- * where IframeIo's iframes are kept).
- * @param {string} fname The name to find.
- * @return {HTMLIFrameElement} The iframe element with that name.
- */
-goog.net.IframeIo.getIframeByName = function(fname) {
- return window.frames[fname];
-};
-
-
-/**
- * Find an instance of the IframeIo object by name.
- * @param {string} fname The name to find.
- * @return {goog.net.IframeIo} The instance of IframeIo.
- */
-goog.net.IframeIo.getInstanceByName = function(fname) {
- return goog.net.IframeIo.instances_[fname];
-};
-
-
-/**
- * Handles incremental data and routes it to the correct iframeIo instance.
- * The HTML page requested by the IframeIo instance should contain script blocks
- * that call an externed reference to this method.
- * @param {Window} win The window object.
- * @param {Object} data The data object.
- */
-goog.net.IframeIo.handleIncrementalData = function(win, data) {
- // If this is the inner-frame, then we need to use the parent instead.
- var iframeName = goog.string.endsWith(win.name,
- goog.net.IframeIo.INNER_FRAME_SUFFIX) ? win.parent.name : win.name;
-
- var iframeIoName = iframeName.substring(0, iframeName.lastIndexOf('_'));
- var iframeIo = goog.net.IframeIo.getInstanceByName(iframeIoName);
- if (iframeIo && iframeName == iframeIo.iframeName_) {
- iframeIo.handleIncrementalData_(data);
- } else {
- goog.debug.Logger.getLogger('goog.net.IframeIo').info(
- 'Incremental iframe data routed for unknown iframe');
- }
-};
-
-
-/**
- * @return {string} The next iframe name.
- * @private
- */
-goog.net.IframeIo.getNextName_ = function() {
- return goog.net.IframeIo.FRAME_NAME_PREFIX + goog.net.IframeIo.counter_++;
-};
-
-
-/**
- * Gets a static form, one for all instances of IframeIo since IE6 leaks form
- * nodes that are created/removed from the document.
- * @return {HTMLFormElement} The static form.
- * @private
- */
-goog.net.IframeIo.getForm_ = function() {
- if (!goog.net.IframeIo.form_) {
- goog.net.IframeIo.form_ =
- /** @type {HTMLFormElement} */(goog.dom.createDom('form'));
- goog.net.IframeIo.form_.acceptCharset = 'utf-8';
-
- // Hide the form and move it off screen
- var s = goog.net.IframeIo.form_.style;
- s.position = 'absolute';
- s.visibility = 'hidden';
- s.top = s.left = '-10px';
- s.width = s.height = '10px';
- s.overflow = 'hidden';
-
- goog.dom.getDocument().body.appendChild(goog.net.IframeIo.form_);
- }
- return goog.net.IframeIo.form_;
-};
-
-
-/**
- * Adds the key value pairs from a map like data structure to a form
- * @param {HTMLFormElement} form The form to add to.
- * @param {Object|goog.structs.Map|goog.Uri.QueryData} data The data to add.
- * @private
- */
-goog.net.IframeIo.addFormInputs_ = function(form, data) {
- goog.structs.forEach(data, function(value, key) {
- var inp = goog.dom.createDom('input',
- {'type': 'hidden', 'name': key, 'value': value});
- form.appendChild(inp);
- });
-};
-
-
-/**
- * Reference to a logger for the IframeIo objects
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.IframeIo.prototype.logger_ =
- goog.debug.Logger.getLogger('goog.net.IframeIo');
-
-
-/**
- * Reference to form element that gets reused for requests to the iframe.
- * @type {HTMLFormElement}
- * @private
- */
-goog.net.IframeIo.prototype.form_ = null;
-
-
-/**
- * Reference to the iframe being used for the current request, or null if no
- * request is currently active.
- * @type {HTMLIFrameElement}
- * @private
- */
-goog.net.IframeIo.prototype.iframe_ = null;
-
-
-/**
- * Name of the iframe being used for the current request, or null if no
- * request is currently active.
- * @type {?string}
- * @private
- */
-goog.net.IframeIo.prototype.iframeName_ = null;
-
-
-/**
- * Next id so that iframe names are unique.
- * @type {number}
- * @private
- */
-goog.net.IframeIo.prototype.nextIframeId_ = 0;
-
-
-/**
- * Whether the object is currently active with a request.
- * @type {boolean}
- * @private
- */
-goog.net.IframeIo.prototype.active_ = false;
-
-
-/**
- * Whether the last request is complete.
- * @type {boolean}
- * @private
- */
-goog.net.IframeIo.prototype.complete_ = false;
-
-
-/**
- * Whether the last request was a success.
- * @type {boolean}
- * @private
- */
-goog.net.IframeIo.prototype.success_ = false;
-
-
-/**
- * The URI for the last request.
- * @type {goog.Uri}
- * @private
- */
-goog.net.IframeIo.prototype.lastUri_ = null;
-
-
-/**
- * The text content of the last request.
- * @type {?string}
- * @private
- */
-goog.net.IframeIo.prototype.lastContent_ = null;
-
-
-/**
- * Last error code
- * @type {goog.net.ErrorCode}
- * @private
- */
-goog.net.IframeIo.prototype.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
-
-
-/**
- * Number of milliseconds after which an incomplete request will be aborted and
- * a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout is set.
- * @type {number}
- * @private
- */
-goog.net.IframeIo.prototype.timeoutInterval_ = 0;
-
-
-/**
- * Window timeout ID used to cancel the timeout event handler if the request
- * completes successfully.
- * @type {?number}
- * @private
- */
-goog.net.IframeIo.prototype.timeoutId_ = null;
-
-
-/**
- * Window timeout ID used to detect when firefox silently fails.
- * @type {?number}
- * @private
- */
-goog.net.IframeIo.prototype.firefoxSilentErrorTimeout_ = null;
-
-
-/**
- * Window timeout ID used by the timer that disposes the iframes.
- * @type {?number}
- * @private
- */
-goog.net.IframeIo.prototype.iframeDisposalTimer_ = null;
-
-
-/**
- * This is used to ensure that we don't handle errors twice for the same error.
- * We can reach the {@link #handleError_} method twice in IE if the form is
- * submitted while IE is offline and the URL is not available.
- * @type {boolean}
- * @private
- */
-goog.net.IframeIo.prototype.errorHandled_;
-
-
-/**
- * Sends a request via an iframe.
- *
- * A HTML form is used and submitted to the iframe, this simplifies the
- * difference between GET and POST requests. The iframe needs to be created and
- * destroyed for each request otherwise the request will contribute to the
- * history stack.
- *
- * sendFromForm does some clever trickery (thanks jlim) in non-IE browsers to
- * stop a history entry being added for POST requests.
- *
- * @param {goog.Uri|string} uri Uri of the request.
- * @param {string=} opt_method Default is GET, POST uses a form to submit the
- * request.
- * @param {boolean=} opt_noCache Append a timestamp to the request to avoid
- * caching.
- * @param {Object|goog.structs.Map=} opt_data Map of key-value pairs.
- */
-goog.net.IframeIo.prototype.send = function(
- uri, opt_method, opt_noCache, opt_data) {
-
- if (this.active_) {
- throw Error('[goog.net.IframeIo] Unable to send, already active.');
- }
-
- var uriObj = new goog.Uri(uri);
- this.lastUri_ = uriObj;
- var method = opt_method ? opt_method.toUpperCase() : 'GET';
-
- if (opt_noCache) {
- uriObj.makeUnique();
- }
-
- this.logger_.info('Sending iframe request: ' + uriObj + ' [' + method + ']');
-
- // Build a form for this request
- this.form_ = goog.net.IframeIo.getForm_();
-
- if (method == 'GET') {
- // For GET requests, we assume that the caller didn't want the queryparams
- // already specified in the URI to be clobbered by the form, so we add the
- // params here.
- goog.net.IframeIo.addFormInputs_(this.form_, uriObj.getQueryData());
- }
-
- if (opt_data) {
- // Create form fields for each of the data values
- goog.net.IframeIo.addFormInputs_(this.form_, opt_data);
- }
-
- // Set the URI that the form will be posted
- this.form_.action = uriObj.toString();
- this.form_.method = method;
-
- this.sendFormInternal_();
-};
-
-
-/**
- * Sends the data stored in an existing form to the server. The HTTP method
- * should be specified on the form, the action can also be specified but can
- * be overridden by the optional URI param.
- *
- * This can be used in conjunction will a file-upload input to upload a file in
- * the background without affecting history.
- *
- * Example form:
- * <pre>
- * &lt;form action="/server/" enctype="multipart/form-data" method="POST"&gt;
- * &lt;input name="userfile" type="file"&gt;
- * &lt;/form&gt;
- * </pre>
- *
- * @param {HTMLFormElement} form Form element used to send the request to the
- * server.
- * @param {string=} opt_uri Uri to set for the destination of the request, by
- * default the uri will come from the form.
- * @param {boolean=} opt_noCache Append a timestamp to the request to avoid
- * caching.
- */
-goog.net.IframeIo.prototype.sendFromForm = function(form, opt_uri,
- opt_noCache) {
- if (this.active_) {
- throw Error('[goog.net.IframeIo] Unable to send, already active.');
- }
-
- var uri = new goog.Uri(opt_uri || form.action);
- if (opt_noCache) {
- uri.makeUnique();
- }
-
- this.logger_.info('Sending iframe request from form: ' + uri);
-
- this.lastUri_ = uri;
- this.form_ = form;
- this.form_.action = uri.toString();
- this.sendFormInternal_();
-};
-
-
-/**
- * Abort the current Iframe request
- * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -
- * defaults to ABORT.
- */
-goog.net.IframeIo.prototype.abort = function(opt_failureCode) {
- if (this.active_) {
- this.logger_.info('Request aborted');
- goog.events.removeAll(this.getRequestIframe_());
- this.complete_ = false;
- this.active_ = false;
- this.success_ = false;
- this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;
-
- this.dispatchEvent(goog.net.EventType.ABORT);
-
- this.makeReady_();
- }
-};
-
-
-/** @override */
-goog.net.IframeIo.prototype.disposeInternal = function() {
- this.logger_.fine('Disposing iframeIo instance');
-
- // If there is an active request, abort it
- if (this.active_) {
- this.logger_.fine('Aborting active request');
- this.abort();
- }
-
- // Call super-classes implementation (remove listeners)
- goog.net.IframeIo.superClass_.disposeInternal.call(this);
-
- // Add the current iframe to the list of iframes for disposal.
- if (this.iframe_) {
- this.scheduleIframeDisposal_();
- }
-
- // Disposes of the form
- this.disposeForm_();
-
- // Nullify anything that might cause problems and clear state
- delete this.errorChecker_;
- this.form_ = null;
- this.lastCustomError_ = this.lastContent_ = this.lastContentHtml_ = null;
- this.lastUri_ = null;
- this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
-
- delete goog.net.IframeIo.instances_[this.name_];
-};
-
-
-/**
- * @return {boolean} True if transfer is complete.
- */
-goog.net.IframeIo.prototype.isComplete = function() {
- return this.complete_;
-};
-
-
-/**
- * @return {boolean} True if transfer was successful.
- */
-goog.net.IframeIo.prototype.isSuccess = function() {
- return this.success_;
-};
-
-
-/**
- * @return {boolean} True if a transfer is in progress.
- */
-goog.net.IframeIo.prototype.isActive = function() {
- return this.active_;
-};
-
-
-/**
- * Returns the last response text (i.e. the text content of the iframe).
- * Assumes plain text!
- * @return {?string} Result from the server.
- */
-goog.net.IframeIo.prototype.getResponseText = function() {
- return this.lastContent_;
-};
-
-
-/**
- * Returns the last response html (i.e. the innerHtml of the iframe).
- * @return {?string} Result from the server.
- */
-goog.net.IframeIo.prototype.getResponseHtml = function() {
- return this.lastContentHtml_;
-};
-
-
-/**
- * Parses the content as JSON. This is a safe parse and may throw an error
- * if the response is malformed.
- * Use goog.json.unsafeparse(this.getResponseText()) if you are sure of the
- * state of the returned content.
- * @return {Object} The parsed content.
- */
-goog.net.IframeIo.prototype.getResponseJson = function() {
- return goog.json.parse(this.lastContent_);
-};
-
-
-/**
- * Returns the document object from the last request. Not truely XML, but
- * used to mirror the XhrIo interface.
- * @return {HTMLDocument} The document object from the last request.
- */
-goog.net.IframeIo.prototype.getResponseXml = function() {
- if (!this.iframe_) return null;
-
- return this.getContentDocument_();
-};
-
-
-/**
- * Get the uri of the last request.
- * @return {goog.Uri} Uri of last request.
- */
-goog.net.IframeIo.prototype.getLastUri = function() {
- return this.lastUri_;
-};
-
-
-/**
- * Gets the last error code.
- * @return {goog.net.ErrorCode} Last error code.
- */
-goog.net.IframeIo.prototype.getLastErrorCode = function() {
- return this.lastErrorCode_;
-};
-
-
-/**
- * Gets the last error message.
- * @return {string} Last error message.
- */
-goog.net.IframeIo.prototype.getLastError = function() {
- return goog.net.ErrorCode.getDebugMessage(this.lastErrorCode_);
-};
-
-
-/**
- * Gets the last custom error.
- * @return {Object} Last custom error.
- */
-goog.net.IframeIo.prototype.getLastCustomError = function() {
- return this.lastCustomError_;
-};
-
-
-/**
- * Sets the callback function used to check if a loaded IFrame is in an error
- * state.
- * @param {Function} fn Callback that expects a document object as it's single
- * argument.
- */
-goog.net.IframeIo.prototype.setErrorChecker = function(fn) {
- this.errorChecker_ = fn;
-};
-
-
-/**
- * Gets the callback function used to check if a loaded IFrame is in an error
- * state.
- * @return {Function} A callback that expects a document object as it's single
- * argument.
- */
-goog.net.IframeIo.prototype.getErrorChecker = function() {
- return this.errorChecker_;
-};
-
-
-/**
- * Returns the number of milliseconds after which an incomplete request will be
- * aborted, or 0 if no timeout is set.
- * @return {number} Timeout interval in milliseconds.
- */
-goog.net.IframeIo.prototype.getTimeoutInterval = function() {
- return this.timeoutInterval_;
-};
-
-
-/**
- * Sets the number of milliseconds after which an incomplete request will be
- * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no
- * timeout is set.
- * @param {number} ms Timeout interval in milliseconds; 0 means none.
- */
-goog.net.IframeIo.prototype.setTimeoutInterval = function(ms) {
- // TODO (pupius) - never used - doesn't look like timeouts were implemented
- this.timeoutInterval_ = Math.max(0, ms);
-};
-
-
-/**
- * Submits the internal form to the iframe.
- * @private
- */
-goog.net.IframeIo.prototype.sendFormInternal_ = function() {
- this.active_ = true;
- this.complete_ = false;
- this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
-
- // Make Iframe
- this.createIframe_();
-
- if (goog.userAgent.IE) {
- // In IE we simply create the frame, wait until it is ready, then post the
- // form to the iframe and wait for the readystate to change to 'complete'
-
- // Set the target to the iframe's name
- this.form_.target = this.iframeName_ || '';
- this.appendIframe_();
- goog.events.listen(this.iframe_, goog.events.EventType.READYSTATECHANGE,
- this.onIeReadyStateChange_, false, this);
-
- /** @preserveTry */
- try {
- this.errorHandled_ = false;
- this.form_.submit();
- } catch (e) {
- // If submit threw an exception then it probably means the page that the
- // code is running on the local file system and the form's action was
- // pointing to a file that doesn't exist, causing the browser to fire an
- // exception. IE also throws an exception when it is working offline and
- // the URL is not available.
-
- goog.events.unlisten(this.iframe_, goog.events.EventType.READYSTATECHANGE,
- this.onIeReadyStateChange_, false, this);
-
- this.handleError_(goog.net.ErrorCode.ACCESS_DENIED);
- }
-
- } else {
- // For all other browsers we do some trickery to ensure that there is no
- // entry on the history stack. Thanks go to jlim for the prototype for this
-
- this.logger_.fine('Setting up iframes and cloning form');
-
- this.appendIframe_();
-
- var innerFrameName = this.iframeName_ +
- goog.net.IframeIo.INNER_FRAME_SUFFIX;
-
- // Open and document.write another iframe into the iframe
- var doc = goog.dom.getFrameContentDocument(this.iframe_);
- var html = '<body><iframe id=' + innerFrameName +
- ' name=' + innerFrameName + '></iframe>';
- if (document.baseURI) {
- // On Safari 4 and 5 the new iframe doesn't inherit the current baseURI.
- html = '<head><base href="' + goog.string.htmlEscape(document.baseURI) +
- '"></head>' + html;
- }
- if (goog.userAgent.OPERA) {
- // Opera adds a history entry when document.write is used.
- // Change the innerHTML of the page instead.
- doc.documentElement.innerHTML = html;
- } else {
- doc.write(html);
- }
-
- // Listen for the iframe's load
- goog.events.listen(doc.getElementById(innerFrameName),
- goog.events.EventType.LOAD, this.onIframeLoaded_, false, this);
-
- // Fix text areas, since importNode won't clone changes to the value
- var textareas = this.form_.getElementsByTagName('textarea');
- for (var i = 0, n = textareas.length; i < n; i++) {
- // The childnodes represent the initial child nodes for the text area
- // appending a text node essentially resets the initial value ready for
- // it to be clones - while maintaining HTML escaping.
- var value = textareas[i].value;
- if (goog.dom.getRawTextContent(textareas[i]) != value) {
- goog.dom.setTextContent(textareas[i], value);
- textareas[i].value = value;
- }
- }
-
- // Append a cloned form to the iframe
- var clone = doc.importNode(this.form_, true);
- clone.target = innerFrameName;
- // Work around crbug.com/66987
- clone.action = this.form_.action;
- doc.body.appendChild(clone);
-
- // Fix select boxes, importNode won't override the default value
- var selects = this.form_.getElementsByTagName('select');
- var clones = clone.getElementsByTagName('select');
- for (var i = 0, n = selects.length; i < n; i++) {
- var selectsOptions = selects[i].getElementsByTagName('option');
- var clonesOptions = clones[i].getElementsByTagName('option');
- for (var j = 0, m = selectsOptions.length; j < m; j++) {
- clonesOptions[j].selected = selectsOptions[j].selected;
- }
- }
-
- // Some versions of Firefox (1.5 - 1.5.07?) fail to clone the value
- // attribute for <input type="file"> nodes, which results in an empty
- // upload if the clone is submitted. Check, and if the clone failed, submit
- // using the original form instead.
- var inputs = this.form_.getElementsByTagName('input');
- var inputClones = clone.getElementsByTagName('input');
- for (var i = 0, n = inputs.length; i < n; i++) {
- if (inputs[i].type == 'file') {
- if (inputs[i].value != inputClones[i].value) {
- this.logger_.fine('File input value not cloned properly. Will ' +
- 'submit using original form.');
- this.form_.target = innerFrameName;
- clone = this.form_;
- break;
- }
- }
- }
-
- this.logger_.fine('Submitting form');
-
- /** @preserveTry */
- try {
- this.errorHandled_ = false;
- clone.submit();
- doc.close();
-
- if (goog.userAgent.GECKO) {
- // This tests if firefox silently fails, this can happen, for example,
- // when the server resets the connection because of a large file upload
- this.firefoxSilentErrorTimeout_ =
- goog.Timer.callOnce(this.testForFirefoxSilentError_, 250, this);
- }
-
- } catch (e) {
- // If submit threw an exception then it probably means the page that the
- // code is running on the local file system and the form's action was
- // pointing to a file that doesn't exist, causing the browser to fire an
- // exception.
-
- this.logger_.severe(
- 'Error when submitting form: ' + goog.debug.exposeException(e));
-
- goog.events.unlisten(doc.getElementById(innerFrameName),
- goog.events.EventType.LOAD, this.onIframeLoaded_, false, this);
-
- doc.close();
-
- this.handleError_(goog.net.ErrorCode.FILE_NOT_FOUND);
- }
- }
-};
-
-
-/**
- * Handles the load event of the iframe for IE, determines if the request was
- * successful or not, handles clean up and dispatching of appropriate events.
- * @param {goog.events.BrowserEvent} e The browser event.
- * @private
- */
-goog.net.IframeIo.prototype.onIeReadyStateChange_ = function(e) {
- if (this.iframe_.readyState == 'complete') {
- goog.events.unlisten(this.iframe_, goog.events.EventType.READYSTATECHANGE,
- this.onIeReadyStateChange_, false, this);
- var doc;
- /** @preserveTry */
- try {
- doc = goog.dom.getFrameContentDocument(this.iframe_);
-
- // IE serves about:blank when it cannot load the resource while offline.
- if (goog.userAgent.IE && doc.location == 'about:blank' &&
- !navigator.onLine) {
- this.handleError_(goog.net.ErrorCode.OFFLINE);
- return;
- }
- } catch (ex) {
- this.handleError_(goog.net.ErrorCode.ACCESS_DENIED);
- return;
- }
- this.handleLoad_(/** @type {HTMLDocument} */(doc));
- }
-};
-
-
-/**
- * Handles the load event of the iframe for non-IE browsers.
- * @param {goog.events.BrowserEvent} e The browser event.
- * @private
- */
-goog.net.IframeIo.prototype.onIframeLoaded_ = function(e) {
- // In Opera, the default "about:blank" page of iframes fires an onload
- // event that we'd like to ignore.
- if (goog.userAgent.OPERA &&
- this.getContentDocument_().location == 'about:blank') {
- return;
- }
- goog.events.unlisten(this.getRequestIframe_(),
- goog.events.EventType.LOAD, this.onIframeLoaded_, false, this);
- this.handleLoad_(this.getContentDocument_());
-};
-
-
-/**
- * Handles generic post-load
- * @param {HTMLDocument} contentDocument The frame's document.
- * @private
- */
-goog.net.IframeIo.prototype.handleLoad_ = function(contentDocument) {
- this.logger_.fine('Iframe loaded');
-
- this.complete_ = true;
- this.active_ = false;
-
- var errorCode;
-
- // Try to get the innerHTML. If this fails then it can be an access denied
- // error or the document may just not have a body, typical case is if there
- // is an IE's default 404.
- /** @preserveTry */
- try {
- var body = contentDocument.body;
- this.lastContent_ = body.textContent || body.innerText;
- this.lastContentHtml_ = body.innerHTML;
- } catch (ex) {
- errorCode = goog.net.ErrorCode.ACCESS_DENIED;
- }
-
- // Use a callback function, defined by the application, to analyse the
- // contentDocument and determine if it is an error page. Applications
- // may send down markers in the document, define JS vars, or some other test.
- var customError;
- if (!errorCode && typeof this.errorChecker_ == 'function') {
- customError = this.errorChecker_(contentDocument);
- if (customError) {
- errorCode = goog.net.ErrorCode.CUSTOM_ERROR;
- }
- }
-
- this.logger_.finer('Last content: ' + this.lastContent_);
- this.logger_.finer('Last uri: ' + this.lastUri_);
-
- if (errorCode) {
- this.logger_.fine('Load event occurred but failed');
- this.handleError_(errorCode, customError);
-
- } else {
- this.logger_.fine('Load succeeded');
- this.success_ = true;
- this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.SUCCESS);
-
- this.makeReady_();
- }
-};
-
-
-/**
- * Handles errors.
- * @param {goog.net.ErrorCode} errorCode Error code.
- * @param {Object=} opt_customError If error is CUSTOM_ERROR, this is the
- * client-provided custom error.
- * @private
- */
-goog.net.IframeIo.prototype.handleError_ = function(errorCode,
- opt_customError) {
- if (!this.errorHandled_) {
- this.success_ = false;
- this.active_ = false;
- this.complete_ = true;
- this.lastErrorCode_ = errorCode;
- if (errorCode == goog.net.ErrorCode.CUSTOM_ERROR) {
- this.lastCustomError_ = opt_customError;
- }
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.ERROR);
-
- this.makeReady_();
-
- this.errorHandled_ = true;
- }
-};
-
-
-/**
- * Dispatches an event indicating that the IframeIo instance has received a data
- * packet via incremental loading. The event object has a 'data' member.
- * @param {Object} data Data.
- * @private
- */
-goog.net.IframeIo.prototype.handleIncrementalData_ = function(data) {
- this.dispatchEvent(new goog.net.IframeIo.IncrementalDataEvent(data));
-};
-
-
-/**
- * Finalizes the request, schedules the iframe for disposal, and maybe disposes
- * the form.
- * @private
- */
-goog.net.IframeIo.prototype.makeReady_ = function() {
- this.logger_.info('Ready for new requests');
- var iframe = this.iframe_;
- this.scheduleIframeDisposal_();
- this.disposeForm_();
- this.dispatchEvent(goog.net.EventType.READY);
-};
-
-
-/**
- * Creates an iframe to be used with a request. We use a new iframe for each
- * request so that requests don't create history entries.
- * @private
- */
-goog.net.IframeIo.prototype.createIframe_ = function() {
- this.logger_.fine('Creating iframe');
-
- this.iframeName_ = this.name_ + '_' + (this.nextIframeId_++).toString(36);
-
- var iframeAttributes = {'name': this.iframeName_, 'id': this.iframeName_};
- // Setting the source to javascript:"" is a fix to remove IE6 mixed content
- // warnings when being used in an https page.
- if (goog.userAgent.IE && goog.userAgent.VERSION < 7) {
- iframeAttributes.src = 'javascript:""';
- }
-
- this.iframe_ = /** @type {HTMLIFrameElement} */(goog.dom.createDom(
- 'iframe', iframeAttributes));
-
- var s = this.iframe_.style;
- s.visibility = 'hidden';
- s.width = s.height = '10px';
-
- // There are reports that safari 2.0.3 has a bug where absolutely positioned
- // iframes can't have their src set.
- if (!goog.userAgent.WEBKIT) {
- s.position = 'absolute';
- s.top = s.left = '-10px';
- } else {
- s.marginTop = s.marginLeft = '-10px';
- }
-};
-
-
-/**
- * Appends the Iframe to the document body.
- * @private
- */
-goog.net.IframeIo.prototype.appendIframe_ = function() {
- goog.dom.getDocument().body.appendChild(this.iframe_);
-};
-
-
-/**
- * Schedules an iframe for disposal, async. We can't remove the iframes in the
- * same execution context as the response, otherwise some versions of Firefox
- * will not detect that the response has correctly finished and the loading bar
- * will stay active forever.
- * @private
- */
-goog.net.IframeIo.prototype.scheduleIframeDisposal_ = function() {
- var iframe = this.iframe_;
-
- // There shouldn't be a case where the iframe is null and we get to this
- // stage, but the error reports in http://b/909448 indicate it is possible.
- if (iframe) {
- // NOTE(user): Stops Internet Explorer leaking the iframe object. This
- // shouldn't be needed, since the events have all been removed, which
- // should in theory clean up references. Oh well...
- iframe.onreadystatechange = null;
- iframe.onload = null;
- iframe.onerror = null;
-
- this.iframesForDisposal_.push(iframe);
- }
-
- if (this.iframeDisposalTimer_) {
- goog.Timer.clear(this.iframeDisposalTimer_);
- this.iframeDisposalTimer_ = null;
- }
-
- if (goog.userAgent.GECKO || goog.userAgent.OPERA) {
- // For FF and Opera, we must dispose the iframe async,
- // but it doesn't need to be done as soon as possible.
- // We therefore schedule it for 2s out, so as not to
- // affect any other actions that may have been triggered by the request.
- this.iframeDisposalTimer_ = goog.Timer.callOnce(
- this.disposeIframes_, goog.net.IframeIo.IFRAME_DISPOSE_DELAY_MS, this);
-
- } else {
- // For non-Gecko browsers we dispose straight away.
- this.disposeIframes_();
- }
-
- // Nullify reference
- this.iframe_ = null;
- this.iframeName_ = null;
-};
-
-
-/**
- * Disposes any iframes.
- * @private
- */
-goog.net.IframeIo.prototype.disposeIframes_ = function() {
- if (this.iframeDisposalTimer_) {
- // Clear the timer
- goog.Timer.clear(this.iframeDisposalTimer_);
- this.iframeDisposalTimer_ = null;
- }
-
- while (this.iframesForDisposal_.length != 0) {
- var iframe = this.iframesForDisposal_.pop();
- this.logger_.info('Disposing iframe');
- goog.dom.removeNode(iframe);
- }
-};
-
-
-/**
- * Disposes of the Form. Since IE6 leaks form nodes, this just cleans up the
- * DOM and nullifies the instances reference so the form can be used for another
- * request.
- * @private
- */
-goog.net.IframeIo.prototype.disposeForm_ = function() {
- if (this.form_ && this.form_ == goog.net.IframeIo.form_) {
- goog.dom.removeChildren(this.form_);
- }
- this.form_ = null;
-};
-
-
-/**
- * @return {HTMLDocument} The appropriate content document.
- * @private
- */
-goog.net.IframeIo.prototype.getContentDocument_ = function() {
- if (this.iframe_) {
- return /** @type {HTMLDocument} */(goog.dom.getFrameContentDocument(
- this.getRequestIframe_()));
- }
- return null;
-};
-
-
-/**
- * @return {HTMLIFrameElement} The appropriate iframe to use for requests
- * (created in sendForm_).
- * @private
- */
-goog.net.IframeIo.prototype.getRequestIframe_ = function() {
- if (this.iframe_) {
- return /** @type {HTMLIFrameElement} */(goog.userAgent.IE ? this.iframe_ :
- goog.dom.getFrameContentDocument(this.iframe_).getElementById(
- this.iframeName_ + goog.net.IframeIo.INNER_FRAME_SUFFIX));
- }
- return null;
-};
-
-
-/**
- * Tests for a silent failure by firefox that can occur when the connection is
- * reset by the server or is made to an illegal URL.
- * @private
- */
-goog.net.IframeIo.prototype.testForFirefoxSilentError_ = function() {
- if (this.active_) {
- var doc = this.getContentDocument_();
-
- // This is a hack to test of the document has loaded with a page that
- // we can't access, such as a network error, that won't report onload
- // or onerror events.
- if (doc && !goog.reflect.canAccessProperty(doc, 'documentUri')) {
- goog.events.unlisten(this.getRequestIframe_(),
- goog.events.EventType.LOAD, this.onIframeLoaded_, false, this);
-
- if (navigator.onLine) {
- this.logger_.warning('Silent Firefox error detected');
- this.handleError_(goog.net.ErrorCode.FF_SILENT_ERROR);
- } else {
- this.logger_.warning('Firefox is offline so report offline error ' +
- 'instead of silent error');
- this.handleError_(goog.net.ErrorCode.OFFLINE);
- }
- return;
- }
- this.firefoxSilentErrorTimeout_ =
- goog.Timer.callOnce(this.testForFirefoxSilentError_, 250, this);
- }
-};
-
-
-
-/**
- * Class for representing incremental data events.
- * @param {Object} data The data associated with the event.
- * @extends {goog.events.Event}
- * @constructor
- */
-goog.net.IframeIo.IncrementalDataEvent = function(data) {
- goog.events.Event.call(this, goog.net.EventType.INCREMENTAL_DATA);
-
- /**
- * The data associated with the event.
- * @type {Object}
- */
- this.data = data;
-};
-goog.inherits(goog.net.IframeIo.IncrementalDataEvent, goog.events.Event);
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.data.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.data.svn-base
deleted file mode 100644
index fed4357..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.data.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-This is just a file that iframeio_different_base_test.html requests to test
-iframeIo.
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.html.svn-base
deleted file mode 100644
index 476cbe8..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_different_base_test.html.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-<html>
-<!--
-Copyright 2011 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<title>Closure Unit Tests - goog.net.IframeIo (with different base URL)</title>
-<script>
-// We use a different base to reproduce the conditions of crbug.com/66987
-var href = window.location.href;
-var newHref = href.replace(/net.*/, '');
-document.write('<base href="' + newHref + '">');
-
-var baseScript = 'base.js';
-document.write('<script src="' + baseScript + '"><\/script>');
-</script>
-<script>
- goog.require('goog.net.IframeIo');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-<script>
-
-var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall();
-
-function testDifferentBaseUri() {
- var io = new goog.net.IframeIo();
- goog.events.listen(io, goog.net.EventType.COMPLETE,
- function() {
- assertNotEquals('File should have expected content.',
- -1, io.getResponseText().indexOf('just a file'));
- asyncTestCase.continueTesting();
- });
- io.send('net/iframeio_different_base_test.data');
- asyncTestCase.waitForAsync('Waiting for iframeIo respons.');
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_test.html.svn-base
deleted file mode 100644
index f1e60e2..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeio_test.html.svn-base
+++ /dev/null
@@ -1,374 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2006 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.IframeIo</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.debug.DivConsole');
- goog.require('goog.net.IframeIo');
- goog.require('goog.testing.jsunit');
-</script>
-<style>
-
- html, body {
- width: 100%;
- height: 100%;
- overflow:hidden;
- }
-
- #log {
- position: absolute;
- top: 0px;
- width: 50%;
- right: 0%;
- height: 100%;
- overflow: auto;
- }
-
- p, input {
- font-family: verdana, helvetica, arial, sans-serif;
- font-size: small;
- margin: 0px;
- }
-
- input {
- font-family: verdana, helvetica, arial, sans-serif;
- font-size: x-small;
- }
-
- i {
- font-size: 85%;
- }
-
-
-</style>
-</head>
-<body>
-<p>
- <b>IframeIo manual tests:</b><br><br>
- <i>All operations should have no effect on history.</i><br>
- <br>
- <i>These tests require the ClosureTestServer<br>
- to be running with the IframeIoTestServlet.</i><br>
-<br></p>
-
-<p>
- <a href="javascript:simpleGet()">Simple GET</a><br>
- <a href="javascript:simplePost()">Simple POST</a><br>
- <a href="javascript:jsonEcho('GET')">JSON echo (get)</a><br>
- <a href="javascript:jsonEcho('POST')">JSON echo (post)</a><br>
- <a href="javascript:abort()">Test abort</a>
-</p>
-<form id="uploadform" action="/iframeio/upload" enctype="multipart/form-data" method="POST">
- <p><a href="javascript:sendFromForm()">Upload</a> <input name="userfile" type="file"> (big files should fail)</p>
-</form>
-<p>
- <a href="javascript:incremental()">Incremental results</a><br>
- <a href="javascript:redirect1()">Redirect (google.com)</a><br>
- <a href="javascript:redirect2()">Redirect (/iframeio/ping)</a><br>
- <a href="javascript:localUrl1()">Local request (Win path)</a><br>
- <a href="javascript:localUrl2()">Local request (Linux path)</a><br>
- <a href="javascript:badUrl()">Out of domain request</a><br>
- <a href="javascript:getServerTime(false)">Test cache</a> (Date should stay the same for subsequent tests)<br>
- <a href="javascript:getServerTime(true)">Test no-cache</a><br>
- <a href="javascript:errorGse404()">GSE 404 Error</a><br>
- <a href="javascript:errorGfe()">Simulated GFE Error</a><br>
- <a href="javascript:errorGmail()">Simulated Gmail Server Error</a><br><br>
-</p>
-<form id="testfrm" action="/iframeio/jsonecho" method="POST">
- <p><b>Comprehensive Form Post Test:</b><br>
- <input name="textinput" type="text" value="Default"> Text Input<br>
- Text Area<br>
- <textarea name="textarea">Default</textarea><br>
- <input name="checkbox1" type="checkbox" checked="checked"> Checkbox, default on<br>
- <input name="checkbox2" type="checkbox"> Checkbox, default off<br>
- Radio: <input name="radio" type="radio" value="Default" checked="checked"> Default,
- <input name="radio" type="radio" value="Foo"> Foo,
- <input name="radio" type="radio" value="Bar"> Bar<br>
- <select name="select">
- <option>One</option>
- <option>Two</option>
- <option selected="selected">Three (Default)</option>
- <option>Four</option>
- <option>Five</option>
- </select><br>
- <select name="selectmultiple">
- <option>One</option>
- <option selected="selected">Two (Default checked)</option>
- <option selected="selected">Three (Default checked)</option>
- <option>Four</option>
- </select>
- <a href="javascript:postForm()">Submit this form</a>
- </p>
-</form>
-<p><br><br>
-TODO(pupius):<br>
-- Local timeout
-</p>
-<div id="log"></div>
-
-<script>
-// MANUAL TESTS - The tests should be run in the browser from the Closure Test
-// Server
-
-// Set up a logger to track responses
-goog.debug.LogManager.getRoot().setLevel(goog.debug.Logger.Level.INFO);
-var logconsole = new goog.debug.DivConsole(document.getElementById('log'));
-logconsole.setCapturing(true);
-
-var testLogger = goog.debug.Logger.getLogger('test');
-
-
-/** Creates an iframeIo instance and sets up the test environment */
-function getTestIframeIo() {
- logconsole.addSeparator();
- logconsole.getFormatter().resetRelativeTimeStart();
-
- var io = new goog.net.IframeIo();
- io.setErrorChecker(checkForError);
-
- goog.events.listen(io, 'success', onSuccess);
- goog.events.listen(io, 'error', onError);
- goog.events.listen(io, 'ready', onReady);
-
- return io;
-}
-
-/**
- * Checks for error strings returned by the GSE and error variables that
- * the Gmail server and GFE set on certain errors.
- */
-function checkForError(doc) {
- var win = goog.dom.getWindow(doc);
- var text = doc.body.textContent || doc.body.innerText || '';
- var gseError = text.match(/([^\n]+)\nError ([0-9]{3})/);
- if (gseError) {
- return '(Error ' + gseError[2] + ') ' + gseError[1];
- } else if (win.gmail_error) {
- return win.gmail_error + 700;
- } else if (win.rc) {
- return 600 + win.rc % 100;
- } else {
- return null;
- }
-}
-
-/** Logs the status of an iframeIo object */
-function logStatus(i) {
- testLogger.fine('Is complete/success/active: ' +
- [i.isComplete(), i.isSuccess(), i.isActive()].join('/'));
-}
-
-function onSuccess(e) {
- testLogger.warning('Request Succeeded');
- logStatus(e.target);
-}
-
-function onError(e) {
- testLogger.warning('Request Errored: ' + e.target.getLastError());
- logStatus(e.target);
-}
-
-function onReady(e) {
- testLogger.info('Test finished and iframe ready, disposing test object');
- e.target.dispose();
-}
-
-
-
-function simpleGet() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'complete', onSimpleTestComplete);
- io.send('/iframeio/ping', 'GET');
-}
-
-
-function simplePost() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'complete', onSimpleTestComplete);
- io.send('/iframeio/ping', 'POST');
-}
-
-function onSimpleTestComplete(e) {
- testLogger.info('ResponseText: ' + e.target.getResponseText());
-}
-
-function abort() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'complete', onAbortComplete);
- goog.events.listen(io, 'abort', onAbort);
- io.send('/iframeio/ping', 'GET');
- io.abort();
-}
-
-function onAbortComplete(e) {
- testLogger.info('Hmm, request should have been aborted');
-}
-
-function onAbort(e) {
- testLogger.info('Request aborted');
-}
-
-
-function errorGse404() {
- var io = getTestIframeIo();
- io.send('/iframeio/404', 'GET');
-}
-
-function jsonEcho(method) {
- var io = getTestIframeIo();
- goog.events.listen(io, 'complete', onJsonComplete);
- var data = {'p1': 'x', 'p2': 'y', 'p3': 'z', 'r': 10};
- io.send('/iframeio/jsonecho?q1=a&q2=b&q3=c&r=5', method, false, data);
-}
-
-function onJsonComplete(e) {
- testLogger.info('ResponseText: ' + e.target.getResponseText());
- var json = e.target.getResponseJson();
- testLogger.info('ResponseJson:\n' + goog.debug.deepExpose(json, true));
-}
-
-
-
-function sendFromForm() {
- var io = getTestIframeIo()
- goog.events.listen(io, 'success', onUploadSuccess);
- goog.events.listen(io, 'error', onUploadError);
- io.sendFromForm(document.getElementById('uploadform'));
-}
-
-function onUploadSuccess(e) {
- testLogger.shout('Upload Succeeded');
- testLogger.info('ResponseText: ' + e.target.getResponseText());
-}
-
-function onUploadError(e) {
- testLogger.shout('Upload Errored');
- testLogger.info('ResponseText: ' + e.target.getResponseText());
-}
-
-
-function redirect1() {
- var io = getTestIframeIo();
- io.send('/iframeio/redirect', 'GET');
-}
-
-function redirect2() {
- var io = getTestIframeIo();
- io.send('/iframeio/move', 'GET');
-}
-
-function badUrl() {
- var io = getTestIframeIo();
- io.send('http://news.bbc.co.uk', 'GET');
-}
-
-function localUrl1() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'complete', onLocalSuccess);
- io.send('c:\test.txt', 'GET');
-}
-
-function localUrl2() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'success', onLocalSuccess);
- io.send('//test.txt', 'GET');
-}
-
-function onLocalSuccess(e) {
- testLogger.info('The file was found:\n' + e.target.getResponseText());
-}
-
-function getServerTime(noCache) {
- var io = getTestIframeIo();
- goog.events.listen(io, 'success', onTestCacheSuccess);
- io.send('/iframeio/datetime', 'GET', noCache);
-}
-
-function onTestCacheSuccess(e) {
- testLogger.info('Date reported: ' + e.target.getResponseText());
-}
-
-
-function errorGmail() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'error', onGmailError);
- io.send('/iframeio/gmailerror', 'GET');
-}
-
-function onGmailError(e) {
- testLogger.info('Gmail error: ' + e.target.getLastError());
-}
-
-
-function errorGfe() {
- var io = getTestIframeIo();
- goog.events.listen(io, 'error', onGfeError);
- io.send('/iframeio/gfeerror', 'GET');
-}
-
-function onGfeError(e) {
- testLogger.info('GFE error: ' + e.target.getLastError());
-}
-
-
-
-function incremental() {
- var io = getTestIframeIo();
- io.send('/iframeio/incremental', 'GET');
-}
-
-window['P'] = function(iframe, data) {
- var iframeIo = goog.net.IframeIo.getInstanceByName(iframe.name);
- testLogger.info('Data recieved - ' + data);
-};
-
-
-function postForm() {
- var io = getTestIframeIo()
- goog.events.listen(io, 'complete', onJsonComplete);
- io.sendFromForm(document.getElementById('testfrm'));
-}
-
-</script>
-
-
-
-<script>
-// UNIT TESTS - to be run via the JsUnit testRunner
-
-// TODO(user): How to unit test all of this? Creating a MockIframe could
-// help for the IE code path, but since the other browsers require weird
-// behaviors this becomes very tricky.
-
-
-function testGetForm() {
- var frm1 = goog.net.IframeIo.getForm_;
- var frm2 = goog.net.IframeIo.getForm_;
- assertEquals(frm1, frm2);
-}
-
-
-function testAddFormInputs() {
- var form = document.createElement('form');
- goog.net.IframeIo.addFormInputs_(form, {'a': 1, 'b': 2, 'c': 3});
- var inputs = form.getElementsByTagName('input');
- assertEquals(3, inputs.length);
- for (var i = 0; i < inputs.length; i++) {
- assertEquals('hidden', inputs[i].type);
- var n = inputs[i].name;
- assertEquals(n == 'a' ? '1' : n == 'b' ? '2' : '3', inputs[i].value);
- }
-}
-
-</script>
-
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor.js.svn-base
deleted file mode 100644
index df08a59..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor.js.svn-base
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Class that can be used to determine when an iframe is loaded.
- */
-
-goog.provide('goog.net.IframeLoadMonitor');
-
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.events.EventTarget');
-goog.require('goog.events.EventType');
-goog.require('goog.userAgent');
-
-
-
-/**
- * The correct way to determine whether an iframe has completed loading
- * is different in IE and Firefox. This class abstracts above these
- * differences, providing a consistent interface for:
- * <ol>
- * <li> Determing if an iframe is currently loaded
- * <li> Listening for an iframe that is not currently loaded, to finish loading
- * </ol>
- *
- * @param {HTMLIFrameElement} iframe An iframe.
- * @param {boolean=} opt_hasContent Does the loaded iframe have content.
- * @extends {goog.events.EventTarget}
- * @constructor
- */
-goog.net.IframeLoadMonitor = function(iframe, opt_hasContent) {
- goog.base(this);
-
- /**
- * Iframe whose load state is monitored by this IframeLoadMonitor
- * @type {HTMLIFrameElement}
- * @private
- */
- this.iframe_ = iframe;
-
- /**
- * Whether or not the loaded iframe has any content.
- * @type {boolean}
- * @private
- */
- this.hasContent_ = !!opt_hasContent;
-
- /**
- * Whether or not the iframe is loaded.
- * @type {boolean}
- * @private
- */
- this.isLoaded_ = this.isLoadedHelper_();
-
- if (!this.isLoaded_) {
- // IE 6 (and lower?) does not reliably fire load events, so listen to
- // readystatechange.
- // IE 7 does not reliably fire readystatechange events but listening on load
- // seems to work just fine.
- var isIe6OrLess = goog.userAgent.IE && !goog.userAgent.isVersion('7');
- var loadEvtType = isIe6OrLess ?
- goog.events.EventType.READYSTATECHANGE : goog.events.EventType.LOAD;
- this.onloadListenerKey_ = goog.events.listen(
- this.iframe_, loadEvtType, this.handleLoad_, false, this);
-
- // Sometimes we still don't get the event callback, so we'll poll just to
- // be safe.
- this.intervalId_ = window.setInterval(
- goog.bind(this.handleLoad_, this),
- goog.net.IframeLoadMonitor.POLL_INTERVAL_MS_);
- }
-};
-goog.inherits(goog.net.IframeLoadMonitor, goog.events.EventTarget);
-
-
-/**
- * Event type dispatched by a goog.net.IframeLoadMonitor when it internal iframe
- * finishes loading for the first time after construction of the
- * goog.net.IframeLoadMonitor
- * @type {string}
- */
-goog.net.IframeLoadMonitor.LOAD_EVENT = 'ifload';
-
-
-/**
- * Poll interval for polling iframe load states in milliseconds.
- * @type {number}
- * @private
- */
-goog.net.IframeLoadMonitor.POLL_INTERVAL_MS_ = 100;
-
-
-/**
- * Key for iframe load listener, or null if not currently listening on the
- * iframe for a load event.
- * @type {?number}
- * @private
- */
-goog.net.IframeLoadMonitor.prototype.onloadListenerKey_ = null;
-
-
-/**
- * Returns whether or not the iframe is loaded.
- * @return {boolean} whether or not the iframe is loaded.
- */
-goog.net.IframeLoadMonitor.prototype.isLoaded = function() {
- return this.isLoaded_;
-};
-
-
-/**
- * Stops the poll timer if this IframeLoadMonitor is currently polling.
- * @private
- */
-goog.net.IframeLoadMonitor.prototype.maybeStopTimer_ = function() {
- if (this.intervalId_) {
- window.clearInterval(this.intervalId_);
- this.intervalId_ = null;
- }
-};
-
-
-/**
- * Returns the iframe whose load state this IframeLoader monitors.
- * @return {HTMLIFrameElement} the iframe whose load state this IframeLoader
- * monitors.
- */
-goog.net.IframeLoadMonitor.prototype.getIframe = function() {
- return this.iframe_;
-};
-
-
-/** @override */
-goog.net.IframeLoadMonitor.prototype.disposeInternal = function() {
- delete this.iframe_;
- this.maybeStopTimer_();
- goog.events.unlistenByKey(this.onloadListenerKey_);
- goog.net.IframeLoadMonitor.superClass_.disposeInternal.call(this);
-};
-
-
-/**
- * Returns whether or not the iframe is loaded. Determines this by inspecting
- * browser dependent properties of the iframe.
- * @return {boolean} whether or not the iframe is loaded.
- * @private
- */
-goog.net.IframeLoadMonitor.prototype.isLoadedHelper_ = function() {
- var isLoaded = false;
- /** @preserveTry */
- try {
- // IE will reliably have readyState set to complete if the iframe is loaded
- // For everything else, the iframe is loaded if there is a body and if the
- // body should have content the firstChild exists. Firefox can fire
- // the LOAD event and then a few hundred ms later replace the
- // contentDocument once the content is loaded.
- isLoaded = goog.userAgent.IE ? this.iframe_.readyState == 'complete' :
- !!goog.dom.getFrameContentDocument(this.iframe_).body &&
- (!this.hasContent_ ||
- !!goog.dom.getFrameContentDocument(this.iframe_).body.firstChild);
- } catch (e) {
- // Ignore these errors. This just means that the iframe is not loaded
- // IE will throw error reading readyState if the iframe is not appended
- // to the dom yet.
- // Firefox will throw error getting the iframe body if the iframe is not
- // fully loaded.
- }
- return isLoaded;
-};
-
-
-/**
- * Handles an event indicating that the loading status of the iframe has
- * changed. In Firefox this is a goog.events.EventType.LOAD event, in IE
- * this is a goog.events.EventType.READYSTATECHANGED
- * @private
- */
-goog.net.IframeLoadMonitor.prototype.handleLoad_ = function() {
- // Only do the handler if the iframe is loaded.
- if (this.isLoadedHelper_()) {
- this.maybeStopTimer_();
- goog.events.unlistenByKey(this.onloadListenerKey_);
- this.onloadListenerKey_ = null;
- this.isLoaded_ = true;
- this.dispatchEvent(goog.net.IframeLoadMonitor.LOAD_EVENT);
- }
-};
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test.html.svn-base
deleted file mode 100644
index 501d477..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test.html.svn-base
+++ /dev/null
@@ -1,113 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Closure Unit Tests - goog.net.IframeLoadMonitor</title>
- <script src="../base.js"></script>
- <script>
- goog.require('goog.dom');
- goog.require('goog.events');
- goog.require('goog.net.IframeLoadMonitor');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.jsunit');
- </script>
-</head>
-<body>
-<div id="frame_parent"></div>
-<script>
- var TEST_FRAME_SRCS = ['iframeloadmonitor_test_frame.html',
- 'iframeloadmonitor_test_frame2.html',
- 'iframeloadmonitor_test_frame3.html'];
-
- // Create a new test case.
- var iframeLoaderTestCase = new goog.testing.AsyncTestCase(document.title);
- iframeLoaderTestCase.stepTimeout = 4 * 1000;
-
- // Array holding all iframe load monitors.
- iframeLoaderTestCase.iframeLoadMonitors_ = [];
-
- // How many single frames finished loading
- iframeLoaderTestCase.singleComplete_ = 0;
-
- /** Sets up the test environment, adds tests and sets up the worker pools. */
- iframeLoaderTestCase.setUpPage = function() {
- this.log('Setting tests up');
- iframeLoaderTestCase.waitForAsync('loading iframes');
-
- var dom = goog.dom.getDomHelper();
-
- // Load single frame
- var frame = dom.createDom('iframe');
- this.iframeLoadMonitors_.push(new goog.net.IframeLoadMonitor(frame));
- goog.events.listen(this.iframeLoadMonitors_[0],
- goog.net.IframeLoadMonitor.LOAD_EVENT, this);
- var frameParent = dom.getElement('frame_parent');
- dom.appendChild(frameParent, frame);
- this.log('Loading frame at: ' + TEST_FRAME_SRCS[0]);
- frame.src = TEST_FRAME_SRCS[0];
-
- // Load single frame with content check
- var frame1 = dom.createDom('iframe');
- this.iframeLoadMonitors_.push(new goog.net.IframeLoadMonitor(frame1, true));
- goog.events.listen(this.iframeLoadMonitors_[1],
- goog.net.IframeLoadMonitor.LOAD_EVENT, this);
- var frameParent = dom.getElement('frame_parent');
- dom.appendChild(frameParent, frame1);
- this.log('Loading frame with content check at: ' + TEST_FRAME_SRCS[0]);
- frame1.src = TEST_FRAME_SRCS[0];
-
- this.add(new goog.testing.TestCase.Test(
- 'test results', this.testResults, this));
- };
-
-
- /** Handles any events fired */
- iframeLoaderTestCase.handleEvent = function(e) {
- this.log('handleEvent, type: ' + e.type);
- if (e.type == goog.net.IframeLoadMonitor.LOAD_EVENT) {
- this.singleComplete_++;
- this.callbacksComplete();
- }
- };
-
- /** Checks if all the load callbacks are done*/
- iframeLoaderTestCase.callbacksComplete = function() {
- if (this.singleComplete_ == 2) {
- iframeLoaderTestCase.continueTesting();
- }
- }
-
- /** Tests the results. */
- iframeLoaderTestCase.testResults = function() {
- this.log('getting test results');
- for (var i = 0; i < this.iframeLoadMonitors_.length; i++) {
- assertTrue(this.iframeLoadMonitors_[i].isLoaded());
- }
- };
-
- /** Used by the JsUnit test runner. */
- function testResults() {
- iframeLoaderTestCase.testResults();
- }
-
- /** Used by the JsUnit test runner. */
- function setUpPage() {
- iframeLoaderTestCase.runTests();
- }
-
- /** Standalone Closure Test Runner. */
- if (typeof G_testRunner != 'undefined') {
- G_testRunner.initialize(iframeLoaderTestCase);
- }
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame.html.svn-base
deleted file mode 100644
index 9fbcbfa..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame.html.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-<!--
-Copyright 2010 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head><title>Iframe Load Test Frame 1</title></head>
-<body>
- Iframe Load Test Frame 1
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame2.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame2.html.svn-base
deleted file mode 100644
index 7d436e2..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame2.html.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-<!--
-Copyright 2010 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head><title>Iframe Load Test Frame 2</title></head>
-<body>
- Iframe Load Test Frame 2
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame3.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame3.html.svn-base
deleted file mode 100644
index 910b639..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/iframeloadmonitor_test_frame3.html.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-<!--
-Copyright 2010 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head><title>Iframe Load Test Frame 3</title></head>
-<body>
- Iframe Load Test Frame 3
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader.js.svn-base
deleted file mode 100644
index cbe4467..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader.js.svn-base
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Image loader utility class. Useful when an application needs
- * to preload multiple images, for example so they can be sized.
- *
- * @author attila@google.com (Attila Bodis)
- * @author zachlloyd@google.com (Zachary Lloyd)
- */
-
-goog.provide('goog.net.ImageLoader');
-
-goog.require('goog.dom');
-goog.require('goog.events.EventHandler');
-goog.require('goog.events.EventTarget');
-goog.require('goog.events.EventType');
-goog.require('goog.net.EventType');
-goog.require('goog.object');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Image loader utility class. Raises a {@link goog.events.EventType.LOAD}
- * event for each image loaded, with an {@link Image} object as the target of
- * the event, normalized to have {@code naturalHeight} and {@code naturalWidth}
- * attributes.
- * @param {Element=} opt_parent An optional parent element whose document object
- * should be used to load images.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.ImageLoader = function(opt_parent) {
- goog.events.EventTarget.call(this);
- this.images_ = {};
- this.handler_ = new goog.events.EventHandler(this);
- this.parent_ = opt_parent;
-};
-goog.inherits(goog.net.ImageLoader, goog.events.EventTarget);
-
-
-/**
- * Map of image IDs to images src, used to keep track of the images to load.
- * @private
- * @type {Object.<string, string>}
- */
-goog.net.ImageLoader.prototype.images_;
-
-
-/**
- * Event handler object, used to keep track of onload and onreadystatechange
- * listeners.
- * @private
- * @type {goog.events.EventHandler}
- */
-goog.net.ImageLoader.prototype.handler_;
-
-
-/**
- * The parent element whose document object will be used to load images.
- * Useful if you want to load the images from a window other than the current
- * window in order to control the Referer header sent when the image is loaded.
- * @type {(Element|undefined)}
- * @private
- */
-goog.net.ImageLoader.prototype.parent_;
-
-
-/**
- * Adds an image to the image loader, and associates it with the given ID
- * string. If an image with that ID already exists, it is silently replaced.
- * When the image in question is loaded, the target of the LOAD event will be
- * an {@code Image} object with {@code id} and {@code src} attributes based on
- * these arguments.
- * @param {string} id The ID of the image to load.
- * @param {string|Image} image Either the source URL of the image or the HTML
- * image element itself (or any object with a {@code src} property, really).
- */
-goog.net.ImageLoader.prototype.addImage = function(id, image) {
- var src = goog.isString(image) ? image : image.src;
- if (src) {
- // For now, we just store the source URL for the image.
- this.images_[id] = src;
- }
-};
-
-
-/**
- * Removes the image associated with the given ID string from the image loader.
- * @param {string} id The ID of the image to remove.
- */
-goog.net.ImageLoader.prototype.removeImage = function(id) {
- goog.object.remove(this.images_, id);
-};
-
-
-/**
- * Starts loading all images in the image loader in parallel. Raises a LOAD
- * event each time an image finishes loading, and a COMPLETE event after all
- * images have finished loading.
- */
-goog.net.ImageLoader.prototype.start = function() {
- goog.object.forEach(this.images_, this.loadImage_, this);
-};
-
-
-/**
- * Creates an {@code Image} object with the specified ID and source URL, and
- * listens for network events raised as the image is loaded.
- * @private
- * @param {string} src The image source URL.
- * @param {string} id The unique ID of the image to load.
- */
-goog.net.ImageLoader.prototype.loadImage_ = function(src, id) {
- var image;
- if (this.parent_) {
- var dom = goog.dom.getDomHelper(this.parent_);
- image = dom.createDom('img');
- } else {
- image = new Image();
- }
-
- // Internet Explorer doesn't reliably raise LOAD events on images, so we must
- // use READY_STATE_CHANGE (thanks, Jeff!).
- // If the image is cached locally, IE won't fire the LOAD event while the
- // onreadystate event is fired always. On the other hand, the ERROR event
- // is always fired whenever the image is not loaded successfully no matter
- // whether it's cached or not.
-
- var loadEvent = goog.userAgent.IE ? goog.net.EventType.READY_STATE_CHANGE :
- goog.events.EventType.LOAD;
- this.handler_.listen(image, [
- loadEvent, goog.net.EventType.ABORT, goog.net.EventType.ERROR
- ], this.onNetworkEvent_);
-
- image.id = id;
- image.src = src;
-};
-
-
-/**
- * Handles net events (READY_STATE_CHANGE, LOAD, ABORT, and ERROR).
- * @private
- * @param {goog.events.Event} evt The network event to handle.
- */
-goog.net.ImageLoader.prototype.onNetworkEvent_ = function(evt) {
- var image = evt.currentTarget;
-
- if (!image) {
- return;
- }
-
- if (evt.type == goog.net.EventType.READY_STATE_CHANGE) {
- // This implies that the user agent is IE; see loadImage()_.
- // Noe that this block is used to check whether the image is ready to
- // dispatch the COMPLETE event.
- if (image.readyState == goog.net.EventType.COMPLETE) {
- // This is the IE equivalent of a LOAD event.
- evt.type = goog.events.EventType.LOAD;
- } else {
- // This may imply that the load failed.
- // Note that the image has only the following states:
- // * uninitialized
- // * loading
- // * complete
- // When the ERROR or the ABORT event is fired, the readyState
- // will be either uninitialized or loading and we'd ignore those states
- // since they will be handled separately (eg: evt.type = 'ERROR').
-
- // Notes from MSDN : The states through which an object passes are
- // determined by that object. An object can skip certain states
- // (for example, interactive) if the state does not apply to that object.
- // see http://msdn.microsoft.com/en-us/library/ms534359(VS.85).aspx
-
- // The image is not loaded, ignore.
- return;
- }
- }
-
- // Add natural width/height properties for non-Gecko browsers.
- if (typeof image.naturalWidth == 'undefined') {
- if (evt.type == goog.events.EventType.LOAD) {
- image.naturalWidth = image.width;
- image.naturalHeight = image.height;
- } else {
- // This implies that the image fails to be loaded.
- image.naturalWidth = 0;
- image.naturalHeight = 0;
- }
- }
-
- // Redispatch the event on behalf of the image. Note that the external
- // listener may dispose this instance.
- this.dispatchEvent({type: evt.type, target: image});
-
- if (this.isDisposed()) {
- // If instance was disposed by listener, exit this function.
- return;
- }
-
- // Remove the image from the map.
- goog.object.remove(this.images_, image.id);
-
- // If this was the last image, raise a COMPLETE event.
- if (goog.object.isEmpty(this.images_)) {
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- // Unlisten for all network events.
- if (this.handler_) {
- this.handler_.removeAll();
- }
- }
-};
-
-
-/** @override */
-goog.net.ImageLoader.prototype.disposeInternal = function() {
- if (this.images_) {
- delete this.images_;
- }
- if (this.handler_) {
- this.handler_.dispose();
- this.handler_ = null;
- }
- goog.net.ImageLoader.superClass_.disposeInternal.call(this);
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_test.html.svn-base
deleted file mode 100644
index 9d8b3d8..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_test.html.svn-base
+++ /dev/null
@@ -1,200 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2006 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Closure Unit Tests - goog.net.ImageLoader</title>
- <script src="../base.js"></script>
- <script>
- goog.require('goog.events');
- goog.require('goog.events.EventType');
- goog.require('goog.net.ImageLoader');
- goog.require('goog.structs.Map');
- goog.require('goog.testing.jsunit');
- </script>
-</head>
-<body>
-<script>
-
-
-
- var TEST_IMAGES = new goog.structs.Map();
-
- var TEST_EVENT_TYPES = [
- goog.events.EventType.LOAD,
- goog.net.EventType.COMPLETE,
- goog.net.EventType.ERROR
- ];
-
- // TEST_IMAGES.set(FileName, Expected Size (width, height), Expected event)
- var EVENT_TYPE_LOAD = goog.events.EventType.LOAD;
- TEST_IMAGES.set('imageloader_testimg1.gif', [20, 20, EVENT_TYPE_LOAD]);
- TEST_IMAGES.set('imageloader_testimg2.gif', [20, 20, EVENT_TYPE_LOAD]);
- TEST_IMAGES.set('imageloader_testimg3.gif', [32, 32, EVENT_TYPE_LOAD]);
-
- var EVENT_TYPE_ERROR = goog.net.EventType.ERROR;
- TEST_IMAGES.set('this-is-not-image-1.gif', [0, 0, EVENT_TYPE_ERROR]);
- TEST_IMAGES.set('this-is-not-image-2.gif', [0, 0, EVENT_TYPE_ERROR]);
-
- var TIMEOUT = 5000;
- // in milleseconds
-
- // Create a new test case.
- var imageLoaderTestCase = new goog.testing.TestCase(document.title);
- var setUpPageStatus;
-
- // Keep track of time so we can timeout if the images don't load.
- imageLoaderTestCase.elapsedTime_ = 0;
-
- imageLoaderTestCase.results_ = new goog.structs.Map();
-
- /** True once the test environment is set up. */
- imageLoaderTestCase.isSetUp = false;
-
- /** True once the page is ready for the test to be run. */
- imageLoaderTestCase.isReady = false;
-
- // A regular image loader.
- imageLoaderTestCase.imageLoader = new goog.net.ImageLoader();
-
- // An image loader that is used to check whether we can dispose
- // it safely whenever an event is fired before the COMPLETE event.
- imageLoaderTestCase.disposalImageLoader = new goog.net.ImageLoader();
-
- /** Sets up the test environment, adds tests and sets up the worker pools. */
- imageLoaderTestCase.setUpTests = function() {
- this.log('Setting tests up');
-
- this.add(new goog.testing.TestCase.Test('testCompleteResults',
- this.testCompleteResults, this));
-
- this.isSetUp = true;
-
- var keys = TEST_IMAGES.getKeys();
- for (var i = 0; i < keys.length; i++) {
- this.log('Adding image: ' + keys[i]);
- this.imageLoader.addImage('img_' + i, keys[i]);
- this.disposalImageLoader.addImage('img_' + i, keys[i]);
- }
-
- goog.events.listen(this.imageLoader, TEST_EVENT_TYPES,
- this.handleImageLoaderEvent, false, this);
-
- goog.events.listen(this.disposalImageLoader, TEST_EVENT_TYPES,
- this.handleDisposalImageLoaderEvent, false, this);
-
- this.disposalImageLoader.start();
- };
-
- /** Handles any events fired on the disposalImageLoader */
- imageLoaderTestCase.handleDisposalImageLoaderEvent = function(e) {
- switch (e.type) {
- case goog.events.EventType.LOAD:
- case goog.net.EventType.ERROR:
- // Make sure that we can dispose this.disposalImageLoader safely.
- this.disposalImageLoader.dispose();
-
- // then starts the regular image loader.
- this.imageLoader.start();
- break;
-
- case goog.net.EventType.COMPLETE:
- throw new Error('disposalImageLoader should have been disposed.');
- break;
- }
- };
-
-
- /** Handles any events fired on the imageLoader */
- imageLoaderTestCase.handleImageLoaderEvent = function(e) {
- this.log('handleEvent, type: ' + e.type);
-
- switch (e.type) {
- case goog.events.EventType.LOAD:
- var image = e.target;
- this.results_.set(image.src.substring(image.src.lastIndexOf('/') + 1),
- [image.naturalWidth, image.naturalHeight, e.type]);
- break;
-
- case goog.net.EventType.ERROR:
- var image = e.target;
- this.results_.set(image.src.substring(image.src.lastIndexOf('/') + 1),
- [image.naturalWidth, image.naturalHeight, e.type]);
- break;
-
- case goog.net.EventType.COMPLETE:
- setUpPageStatus = 'complete';
- this.isReady = true;
- break;
- }
- };
-
-
- /** Tests the results. */
- imageLoaderTestCase.testCompleteResults = function() {
- var keys = TEST_IMAGES.getKeys();
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- this.log(key);
-
- // Check if fires the COMPLETE event.
- assertTrue('Image is not loaded completely',
- this.results_.containsKey(key));
-
- // Chcekc size.
- assertTrue('Image size is not correct',
- this.results_.get(key)[0] == TEST_IMAGES.get(key)[0] &&
- this.results_.get(key)[1] == TEST_IMAGES.get(key)[1]);
-
- // Check if fired the correct event.
- assertTrue('Event *' + TEST_IMAGES.get(key)[2] + '* must be fired',
- this.results_.get(key)[2] == TEST_IMAGES.get(key)[2]);
- }
- };
-
- /** Waits until the tests are ready to begin, before running them. */
- imageLoaderTestCase.runTests = function() {
- if (!this.isSetUp) {
- this.setUpTests();
- }
- if (this.isReady) {
- this.execute();
- } else {
- if (this.elapsedTime_ > TIMEOUT) {
- this.log('timed out');
- setUpPageStatus = 'complete';
- this.isReady = true;
- return;
- }
- this.log('Not ready, waiting');
- this.elapsedTime_ += 100;
- // Try again in 100ms
- setTimeout('imageLoaderTestCase.runTests()', 100);
- }
- };
-
- /** Used by the JsUnit test runner. */
- function testCompleteResults() {
- imageLoaderTestCase.testCompleteResults();
- }
-
- /** Used by the JsUnit test runner. */
- function setUpPage() {
- imageLoaderTestCase.runTests();
- }
-
- /** Standalone Closure Test Runner. */
- if (typeof G_testRunner != 'undefined') {
- G_testRunner.initialize(imageLoaderTestCase);
- }
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg1.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg1.gif.svn-base
deleted file mode 100644
index 18b295b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg1.gif.svn-base
+++ /dev/null
Binary files differ
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg2.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg2.gif.svn-base
deleted file mode 100644
index 6916832..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg2.gif.svn-base
+++ /dev/null
Binary files differ
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg3.gif.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg3.gif.svn-base
deleted file mode 100644
index fe5e378..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/imageloader_testimg3.gif.svn-base
+++ /dev/null
Binary files differ
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress.js.svn-base
deleted file mode 100644
index 43f46b5..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress.js.svn-base
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview This file contains classes to handle IPv4 and IPv6 addresses.
- * This implementation is mostly based on Google's project:
- * http://code.google.com/p/ipaddr-py/.
- *
- */
-
-goog.provide('goog.net.IpAddress');
-goog.provide('goog.net.Ipv4Address');
-goog.provide('goog.net.Ipv6Address');
-
-goog.require('goog.array');
-goog.require('goog.math.Integer');
-goog.require('goog.object');
-goog.require('goog.string');
-
-
-
-/**
- * Abstract class defining an IP Address.
- *
- * Please use goog.net.IpAddress static methods or
- * goog.net.Ipv4Address/Ipv6Address classes.
- *
- * @param {!goog.math.Integer} address The Ip Address.
- * @param {number} version The version number (4, 6).
- * @constructor
- */
-goog.net.IpAddress = function(address, version) {
- /**
- * The IP Address.
- * @type {!goog.math.Integer}
- * @private
- */
- this.ip_ = address;
-
- /**
- * The IP Address version.
- * @type {number}
- * @private
- */
- this.version_ = version;
-
- /**
- * The IPAddress, as string.
- * @type {string}
- * @private
- */
- this.ipStr_ = '';
-};
-
-
-/**
- * @return {number} The IP Address version.
- */
-goog.net.IpAddress.prototype.getVersion = function() {
- return this.version_;
-};
-
-
-/**
- * @param {!goog.net.IpAddress} other The other IP Address.
- * @return {boolean} true if the IP Addresses are equal.
- */
-goog.net.IpAddress.prototype.equals = function(other) {
- return (this.version_ == other.getVersion() &&
- this.ip_.equals(other.toInteger()));
-};
-
-
-/**
- * @return {goog.math.Integer} The IP Address, as an Integer.
- */
-goog.net.IpAddress.prototype.toInteger = function() {
- return /** @type {goog.math.Integer} */ (goog.object.clone(this.ip_));
-};
-
-
-/**
- * @return {string} The IP Address, as an URI string following RFC 3986.
- */
-goog.net.IpAddress.prototype.toUriString = goog.abstractMethod;
-
-
-/**
- * @return {string} The IP Address, as a string.
- */
-goog.net.IpAddress.prototype.toString = goog.abstractMethod;
-
-
-/**
- * Parses an IP Address in a string.
- * If the string is malformed, the function will simply return null
- * instead of raising an exception.
- *
- * @param {string} address The IP Address.
- * @see {goog.net.Ipv4Address}
- * @see {goog.net.Ipv6Address}
- * @return {goog.net.IpAddress} The IP Address or null.
- */
-goog.net.IpAddress.fromString = function(address) {
- try {
- if (address.indexOf(':') != -1) {
- return new goog.net.Ipv6Address(address);
- }
-
- return new goog.net.Ipv4Address(address);
- } catch (e) {
- // Both constructors raise exception if the address is malformed (ie.
- // invalid). The user of this function should not care about catching
- // the exception, espcially if it's used to validate an user input.
- return null;
- }
-};
-
-
-/**
- * Tries to parse a string represented as a host portion of an URI.
- * See RFC 3986 for more details on IPv6 addresses inside URI.
- * If the string is malformed, the function will simply return null
- * instead of raising an exception.
- *
- * @param {string} address A RFC 3986 encoded IP address.
- * @see {goog.net.Ipv4Address}
- * @see {goog.net.Ipv6Address}
- * @return {goog.net.IpAddress} The IP Address.
- */
-goog.net.IpAddress.fromUriString = function(address) {
- try {
- if (goog.string.startsWith(address, '[') &&
- goog.string.endsWith(address, ']')) {
- return new goog.net.Ipv6Address(
- address.substring(1, address.length - 1));
- }
-
- return new goog.net.Ipv4Address(address);
- } catch (e) {
- // Both constructors raise exception if the address is malformed (ie.
- // invalid). The user of this function should not care about catching
- // the exception, espcially if it's used to validate an user input.
- return null;
- }
-};
-
-
-
-/**
- * Takes a string or a number and returns a IPv4 Address.
- *
- * This constructor accepts strings and instance of goog.math.Integer.
- * If you pass a goog.math.Integer, make sure that its sign is set to positive.
- * @param {(string|!goog.math.Integer)} address The address to store.
- * @extends {goog.net.IpAddress}
- * @constructor
- */
-goog.net.Ipv4Address = function(address) {
- var ip = goog.math.Integer.ZERO;
- if (address instanceof goog.math.Integer) {
- if (address.getSign() != 0 ||
- address.lessThan(goog.math.Integer.ZERO) ||
- address.greaterThan(goog.net.Ipv4Address.MAX_ADDRESS_)) {
- throw Error('The address does not look like an IPv4.');
- } else {
- ip = goog.object.clone(address);
- }
- } else {
- if (!goog.net.Ipv4Address.REGEX_.test(address)) {
- throw Error(address + ' does not look like an IPv4 address.');
- }
-
- var octets = address.split('.');
- if (octets.length != 4) {
- throw Error(address + ' does not look like an IPv4 address.');
- }
-
- for (var i = 0; i < octets.length; i++) {
- var parsedOctet = goog.string.toNumber(octets[i]);
- if (isNaN(parsedOctet) ||
- parsedOctet < 0 || parsedOctet > 255 ||
- (octets[i].length != 1 && goog.string.startsWith(octets[i], '0'))) {
- throw Error('In ' + address + ', octet ' + i + ' is not valid');
- }
- var intOctet = goog.math.Integer.fromNumber(parsedOctet);
- ip = ip.shiftLeft(8).or(intOctet);
- }
- }
- goog.base(this, /** @type {!goog.math.Integer} */ (ip), 4);
-};
-goog.inherits(goog.net.Ipv4Address, goog.net.IpAddress);
-
-
-/**
- * Regular expression matching all the allowed chars for IPv4.
- * @type {RegExp}
- * @private
- * @const
- */
-goog.net.Ipv4Address.REGEX_ = /^[0-9.]*$/;
-
-
-/**
- * The Maximum length for a netmask (aka, the number of bits for IPv4).
- * @type {number}
- * @const
- */
-goog.net.Ipv4Address.MAX_NETMASK_LENGTH = 32;
-
-
-/**
- * The Maximum address possible for IPv4.
- * @type {goog.math.Integer}
- * @private
- * @const
- */
-goog.net.Ipv4Address.MAX_ADDRESS_ = goog.math.Integer.ONE.shiftLeft(
- goog.net.Ipv4Address.MAX_NETMASK_LENGTH).subtract(goog.math.Integer.ONE);
-
-
-/**
- * @override
- */
-goog.net.Ipv4Address.prototype.toString = function() {
- if (this.ipStr_) {
- return this.ipStr_;
- }
-
- var ip = this.ip_.getBitsUnsigned(0);
- var octets = [];
- for (var i = 3; i >= 0; i--) {
- octets[i] = String((ip & 0xff));
- ip = ip >>> 8;
- }
-
- this.ipStr_ = octets.join('.');
-
- return this.ipStr_;
-};
-
-
-/**
- * @override
- */
-goog.net.Ipv4Address.prototype.toUriString = function() {
- return this.toString();
-};
-
-
-
-/**
- * Takes a string or a number and returns an IPv6 Address.
- *
- * This constructor accepts strings and instance of goog.math.Integer.
- * If you pass a goog.math.Integer, make sure that its sign is set to positive.
- * @param {(string|!goog.math.Integer)} address The address to store.
- * @constructor
- * @extends {goog.net.IpAddress}
- */
-goog.net.Ipv6Address = function(address) {
- var ip = goog.math.Integer.ZERO;
- if (address instanceof goog.math.Integer) {
- if (address.getSign() != 0 ||
- address.lessThan(goog.math.Integer.ZERO) ||
- address.greaterThan(goog.net.Ipv6Address.MAX_ADDRESS_)) {
- throw Error('The address does not look like a valid IPv6.');
- } else {
- ip = goog.object.clone(address);
- }
- } else {
- if (!goog.net.Ipv6Address.REGEX_.test(address)) {
- throw Error(address + ' is not a valid IPv6 address.');
- }
-
- var splitColon = address.split(':');
- if (splitColon[splitColon.length - 1].indexOf('.') != -1) {
- var newHextets = goog.net.Ipv6Address.dottedQuadtoHextets_(
- splitColon[splitColon.length - 1]);
- goog.array.removeAt(splitColon, splitColon.length - 1);
- goog.array.extend(splitColon, newHextets);
- address = splitColon.join(':');
- }
-
- var splitDoubleColon = address.split('::');
- if (splitDoubleColon.length > 2 ||
- (splitDoubleColon.length == 1 && splitColon.length != 8)) {
- throw Error(address + ' is not a valid IPv6 address.');
- }
-
- var ipArr;
- if (splitDoubleColon.length > 1) {
- ipArr = goog.net.Ipv6Address.explode_(splitDoubleColon);
- } else {
- ipArr = splitColon;
- }
-
- if (ipArr.length != 8) {
- throw Error(address + ' is not a valid IPv6 address');
- }
-
- for (var i = 0; i < ipArr.length; i++) {
- var parsedHextet = goog.math.Integer.fromString(ipArr[i], 16);
- if (parsedHextet.lessThan(goog.math.Integer.ZERO) ||
- parsedHextet.greaterThan(goog.net.Ipv6Address.MAX_HEXTET_VALUE_)) {
- throw Error(ipArr[i] + ' in ' + address + ' is not a valid hextet.');
- }
- ip = ip.shiftLeft(16).or(parsedHextet);
- }
- }
- goog.base(this, /** @type {!goog.math.Integer} */ (ip), 6);
-};
-goog.inherits(goog.net.Ipv6Address, goog.net.IpAddress);
-
-
-/**
- * Regular expression matching all allowed chars for an IPv6.
- * @type {RegExp}
- * @private
- * @const
- */
-goog.net.Ipv6Address.REGEX_ = /^([a-fA-F0-9]*:){2}[a-fA-F0-9:.]*$/;
-
-
-/**
- * The Maximum length for a netmask (aka, the number of bits for IPv6).
- * @type {number}
- * @const
- */
-goog.net.Ipv6Address.MAX_NETMASK_LENGTH = 128;
-
-
-/**
- * The maximum value of a hextet.
- * @type {goog.math.Integer}
- * @private
- * @const
- */
-goog.net.Ipv6Address.MAX_HEXTET_VALUE_ = goog.math.Integer.fromInt(65535);
-
-
-/**
- * The Maximum address possible for IPv6.
- * @type {goog.math.Integer}
- * @private
- * @const
- */
-goog.net.Ipv6Address.MAX_ADDRESS_ = goog.math.Integer.ONE.shiftLeft(
- goog.net.Ipv6Address.MAX_NETMASK_LENGTH).subtract(goog.math.Integer.ONE);
-
-
-/**
- * @override
- */
-goog.net.Ipv6Address.prototype.toString = function() {
- if (this.ipStr_) {
- return this.ipStr_;
- }
-
- var outputArr = [];
- for (var i = 3; i >= 0; i--) {
- var bits = this.ip_.getBitsUnsigned(i);
- var firstHextet = bits >>> 16;
- var secondHextet = bits & 0xffff;
- outputArr.push(firstHextet.toString(16));
- outputArr.push(secondHextet.toString(16));
- }
-
- outputArr = goog.net.Ipv6Address.compress_(outputArr);
- this.ipStr_ = outputArr.join(':');
- return this.ipStr_;
-};
-
-
-/**
- * @override
- */
-goog.net.Ipv6Address.prototype.toUriString = function() {
- return '[' + this.toString() + ']';
-};
-
-
-/**
- * This method is in charge of expanding/exploding an IPv6 string from its
- * compressed form.
- * @private
- * @param {!Array.<string>} address An IPv6 address split around '::'.
- * @return {Array.<string>} The expanded version of the IPv6.
- */
-goog.net.Ipv6Address.explode_ = function(address) {
- var basePart = address[0].split(':');
- var secondPart = address[1].split(':');
-
- if (basePart.length == 1 && basePart[0] == '') {
- basePart = [];
- }
- if (secondPart.length == 1 && secondPart[0] == '') {
- secondPart = [];
- }
-
- // Now we fill the gap with 0.
- var gap = 8 - (basePart.length + secondPart.length);
-
- if (gap < 1) {
- return [];
- }
-
- goog.array.extend(basePart, goog.array.repeat('0', gap));
-
- // Now we merge the basePart + gap + secondPart
- goog.array.extend(basePart, secondPart);
-
- return basePart;
-};
-
-
-/**
- * This method is in charge of compressing an expanded IPv6 array of hextets.
- * @private
- * @param {!Array.<string>} hextets The array of hextet.
- * @return {Array.<string>} The compressed version of this array.
- */
-goog.net.Ipv6Address.compress_ = function(hextets) {
- var bestStart = -1;
- var start = -1;
- var bestSize = 0;
- var size = 0;
- for (var i = 0; i < hextets.length; i++) {
- if (hextets[i] == '0') {
- size++;
- if (start == -1) {
- start = i;
- }
- if (size > bestSize) {
- bestSize = size;
- bestStart = start;
- }
- } else {
- start = -1;
- size = 0;
- }
- }
-
- if (bestSize > 0) {
- if ((bestStart + bestSize) == hextets.length) {
- hextets.push('');
- }
- hextets.splice(bestStart, bestSize, '');
-
- if (bestStart == 0) {
- hextets = [''].concat(hextets);
- }
- }
- return hextets;
-};
-
-
-/**
- * This method will convert an IPv4 to a list of 2 hextets.
- *
- * For instance, 1.2.3.4 will be converted to ['0102', '0304'].
- * @private
- * @param {string} quads An IPv4 as a string.
- * @return {Array.<string>} A list of 2 hextets.
- */
-goog.net.Ipv6Address.dottedQuadtoHextets_ = function(quads) {
- var ip4 = new goog.net.Ipv4Address(quads).toInteger();
- var bits = ip4.getBitsUnsigned(0);
- var hextets = [];
-
- hextets.push(((bits >>> 16) & 0xffff).toString(16));
- hextets.push((bits & 0xffff).toString(16));
-
- return hextets;
-};
-
-
-/**
- * @return {boolean} true if the IPv6 contains a mapped IPv4.
- */
-goog.net.Ipv6Address.prototype.isMappedIpv4Address = function() {
- return (this.ip_.getBitsUnsigned(3) == 0 &&
- this.ip_.getBitsUnsigned(2) == 0 &&
- this.ip_.getBitsUnsigned(1) == 0xffff);
-};
-
-
-/**
- * Will return the mapped IPv4 address in this IPv6 address.
- * @return {goog.net.Ipv4Address} an IPv4 or null.
- */
-goog.net.Ipv6Address.prototype.getMappedIpv4Address = function() {
- if (!this.isMappedIpv4Address()) {
- return null;
- }
-
- var newIpv4 = new goog.math.Integer([this.ip_.getBitsUnsigned(0)], 0);
- return new goog.net.Ipv4Address(newIpv4);
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress_test.html.svn-base
deleted file mode 100644
index 8ffe01c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/ipaddress_test.html.svn-base
+++ /dev/null
@@ -1,227 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2011 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
-
-Test suite inspired from http://code.google.com/p/ipaddr-py/ and
-Google's Guava InetAddresses test suite available on
-http://code.google.com/p/guava-libraries/
--->
- <head>
- <meta http-equiv='X-UA-Compatible' content='IE=edge'>
- <title>Closure Unit Test - goog.net.IpAddress</title>
- <script src='../base.js' type='text/javascript'></script>
- <script type='text/javascript'>
- goog.require('goog.array');
- goog.require('goog.math.Integer');
- goog.require('goog.net.IpAddress');
- goog.require('goog.net.Ipv4Address');
- goog.require('goog.net.Ipv6Address');
- goog.require('goog.testing.jsunit');
- </script>
- </head>
- <body>
- <script text='text/javascript'>
- function testInvalidStrings() {
- assertEquals(null, goog.net.IpAddress.fromString(''));
- assertEquals(null, goog.net.IpAddress.fromString('016.016.016.016'));
- assertEquals(null, goog.net.IpAddress.fromString('016.016.016'));
- assertEquals(null, goog.net.IpAddress.fromString('016.016'));
- assertEquals(null, goog.net.IpAddress.fromString('016'));
- assertEquals(null, goog.net.IpAddress.fromString('000.000.000.000'));
- assertEquals(null, goog.net.IpAddress.fromString('000'));
- assertEquals(null,
- goog.net.IpAddress.fromString('0x0a.0x0a.0x0a.0x0a'));
- assertEquals(null, goog.net.IpAddress.fromString('0x0a.0x0a.0x0a'));
- assertEquals(null, goog.net.IpAddress.fromString('0x0a.0x0a'));
- assertEquals(null, goog.net.IpAddress.fromString('0x0a'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42'));
- assertEquals(null, goog.net.IpAddress.fromString('42..42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42..42.42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.42.'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.42...'));
- assertEquals(null, goog.net.IpAddress.fromString('.42.42.42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('...42.42.42.42'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.-0'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.+0'));
- assertEquals(null, goog.net.IpAddress.fromString('.'));
- assertEquals(null, goog.net.IpAddress.fromString('...'));
- assertEquals(null, goog.net.IpAddress.fromString('bogus'));
- assertEquals(null, goog.net.IpAddress.fromString('bogus.com'));
- assertEquals(null, goog.net.IpAddress.fromString('192.168.0.1.com'));
- assertEquals(null,
- goog.net.IpAddress.fromString('12345.67899.-54321.-98765'));
- assertEquals(null, goog.net.IpAddress.fromString('257.0.0.0'));
- assertEquals(null, goog.net.IpAddress.fromString('42.42.42.-42'));
- assertEquals(null, goog.net.IpAddress.fromString('3ff3:::1'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::1.net'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::1::1'));
- assertEquals(null, goog.net.IpAddress.fromString('1::2::3::4:5'));
- assertEquals(null, goog.net.IpAddress.fromString('::7:6:5:4:3:2:'));
- assertEquals(null, goog.net.IpAddress.fromString(':6:5:4:3:2:1::'));
- assertEquals(null, goog.net.IpAddress.fromString('2001::db:::1'));
- assertEquals(null, goog.net.IpAddress.fromString('FEDC:9878'));
- assertEquals(null, goog.net.IpAddress.fromString('+1.+2.+3.4'));
- assertEquals(null, goog.net.IpAddress.fromString('1.2.3.4e0'));
- assertEquals(null, goog.net.IpAddress.fromString('::7:6:5:4:3:2:1:0'));
- assertEquals(null, goog.net.IpAddress.fromString('7:6:5:4:3:2:1:0::'));
- assertEquals(null, goog.net.IpAddress.fromString('9:8:7:6:5:4:3::2:1'));
- assertEquals(null, goog.net.IpAddress.fromString('0:1:2:3::4:5:6:7'));
- assertEquals(null,
- goog.net.IpAddress.fromString('3ffe:0:0:0:0:0:0:0:1'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::10000'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::goog'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::-0'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::+0'));
- assertEquals(null, goog.net.IpAddress.fromString('3ffe::-1'));
- assertEquals(null, goog.net.IpAddress.fromString(':'));
- assertEquals(null, goog.net.IpAddress.fromString(':::'));
- assertEquals(null, goog.net.IpAddress.fromString('a:'));
- assertEquals(null, goog.net.IpAddress.fromString('::a:'));
- assertEquals(null, goog.net.IpAddress.fromString('0xa::'));
- assertEquals(null, goog.net.IpAddress.fromString('::1.2.3'));
- assertEquals(null, goog.net.IpAddress.fromString('::1.2.3.4.5'));
- assertEquals(null, goog.net.IpAddress.fromString('::1.2.3.4:'));
- assertEquals(null, goog.net.IpAddress.fromString('1.2.3.4::'));
- assertEquals(null, goog.net.IpAddress.fromString('2001:db8::1:'));
- assertEquals(null, goog.net.IpAddress.fromString(':2001:db8::1'));
- }
-
- function testVersion() {
- var ip4 = goog.net.IpAddress.fromString('1.2.3.4');
- assertEquals(ip4.getVersion(), 4);
-
- var ip6 = goog.net.IpAddress.fromString('2001:dead::beef:1');
- assertEquals(ip6.getVersion(), 6);
-
- ip6 = goog.net.IpAddress.fromString('::192.168.1.1');
- assertEquals(ip6.getVersion(), 6);
- }
-
- function testStringIpv4Address() {
- assertEquals('192.168.1.1',
- new goog.net.Ipv4Address('192.168.1.1').toString());
- assertEquals('1.1.1.1',
- new goog.net.Ipv4Address('1.1.1.1').toString());
- assertEquals('224.56.33.2',
- new goog.net.Ipv4Address('224.56.33.2').toString());
- assertEquals('255.255.255.255',
- new goog.net.Ipv4Address('255.255.255.255').toString());
- assertEquals('0.0.0.0',
- new goog.net.Ipv4Address('0.0.0.0').toString());
- }
-
- function testIntIpv4Address() {
- var ip4Str = new goog.net.Ipv4Address('1.1.1.1');
- var ip4Int = new goog.net.Ipv4Address(
- new goog.math.Integer([16843009], 0));
-
- assertTrue(ip4Str.equals(ip4Int));
- assertEquals(ip4Str.toString(), ip4Int.toString());
-
- assertThrows('Ipv4(-1)', goog.partial(goog.net.Ipv4Address,
- goog.math.Integer.fromInt(-1)));
- assertThrows('Ipv4(2**32)',
- goog.partial(goog.net.Ipv4Address,
- goog.math.Integer.ONE.shiftLeft(32)));
- }
-
- function testStringIpv6Address() {
- assertEquals('1:2:3:4:5:6:7:8',
- new goog.net.Ipv6Address('1:2:3:4:5:6:7:8').toString());
- assertEquals('::1:2:3:4:5:6:7',
- new goog.net.Ipv6Address('::1:2:3:4:5:6:7').toString());
- assertEquals('1:2:3:4:5:6:7::',
- new goog.net.Ipv6Address('1:2:3:4:5:6:7:0').toString());
- assertEquals('2001:0:0:4::8',
- new goog.net.Ipv6Address('2001:0:0:4:0:0:0:8').toString());
- assertEquals('2001::4:5:6:7:8',
- new goog.net.Ipv6Address('2001:0:0:4:5:6:7:8').toString());
- assertEquals('2001::3:4:5:6:7:8',
- new goog.net.Ipv6Address('2001:0:3:4:5:6:7:8').toString());
- assertEquals('0:0:3::ffff',
- new goog.net.Ipv6Address('0:0:3:0:0:0:0:ffff').toString());
- assertEquals('::4:0:0:0:ffff',
- new goog.net.Ipv6Address('0:0:0:4:0:0:0:ffff').toString());
- assertEquals('::5:0:0:ffff',
- new goog.net.Ipv6Address('0:0:0:0:5:0:0:ffff').toString());
- assertEquals('1::4:0:0:7:8',
- new goog.net.Ipv6Address('1:0:0:4:0:0:7:8').toString());
- assertEquals('::',
- new goog.net.Ipv6Address('0:0:0:0:0:0:0:0').toString());
- assertEquals('::1',
- new goog.net.Ipv6Address('0:0:0:0:0:0:0:1').toString());
- assertEquals('2001:658:22a:cafe::',
- new goog.net.Ipv6Address(
- '2001:0658:022a:cafe:0000:0000:0000:0000').toString());
- assertEquals('::102:304',
- new goog.net.Ipv6Address('::1.2.3.4').toString());
- assertEquals('::ffff:303:303',
- new goog.net.Ipv6Address('::ffff:3.3.3.3').toString());
- assertEquals('::ffff:ffff',
- new goog.net.Ipv6Address('::255.255.255.255').toString());
- }
-
- function testIntIpv6Address() {
- var ip6Str = new goog.net.Ipv6Address('2001::dead:beef:1');
- var ip6Int = new goog.net.Ipv6Address(
- new goog.math.Integer([3203334145, 57005, 0, 536936448], 0));
-
- assertTrue(ip6Str.equals(ip6Int));
- assertEquals(ip6Str.toString(), ip6Int.toString());
-
- assertThrows('Ipv6(-1)', goog.partial(goog.net.Ipv6Address,
- goog.math.Integer.fromInt(-1)));
- assertThrows('Ipv6(2**128)',
- goog.partial(goog.net.Ipv6Address,
- goog.math.Integer.ONE.shiftLeft(128)));
-
- }
-
- function testDottedQuadIpv6() {
- var ip6 = new goog.net.Ipv6Address('7::0.128.0.127');
- ip6 = new goog.net.Ipv6Address('7::0.128.0.128');
- ip6 = new goog.net.Ipv6Address('7::128.128.0.127');
- ip6 = new goog.net.Ipv6Address('7::0.128.128.127');
- }
-
- function testMappedIpv4Address() {
- var testAddresses = ['::ffff:1.2.3.4', '::FFFF:102:304'];
- var ipv4Str = '1.2.3.4';
-
- var ip1 = new goog.net.Ipv6Address(testAddresses[0]);
- var ip2 = new goog.net.Ipv6Address(testAddresses[1]);
- var ipv4 = new goog.net.Ipv4Address(ipv4Str);
-
- assertTrue(ip1.isMappedIpv4Address());
- assertTrue(ip2.isMappedIpv4Address());
- assertTrue(ip1.equals(ip2));
- assertTrue(ipv4.equals(ip1.getMappedIpv4Address()));
- assertTrue(ipv4.equals(ip2.getMappedIpv4Address()));
- }
-
-
- function testUriString() {
- var ip4Str = '192.168.1.1';
- var ip4Uri = goog.net.IpAddress.fromUriString(ip4Str);
- var ip4 = goog.net.IpAddress.fromString(ip4Str);
- assertTrue(ip4Uri.equals(ip4));
-
- var ip6Str = '2001:dead::beef:1';
- assertEquals(null, goog.net.IpAddress.fromUriString(ip6Str));
-
- var ip6Uri = goog.net.IpAddress.fromUriString('[' + ip6Str + ']');
- var ip6 = goog.net.IpAddress.fromString(ip6Str);
- assertTrue(ip6Uri.equals(ip6));
- assertEquals(ip6Uri.toString(), ip6Str);
- assertEquals(ip6Uri.toUriString(), '[' + ip6Str + ']');
- }
- </script>
- </body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader.js.svn-base
deleted file mode 100644
index 653b205..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader.js.svn-base
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview A utility to load JavaScript files.
- * Refactored from goog.net.Jsonp.
- *
- */
-
-goog.provide('goog.net.jsloader');
-goog.provide('goog.net.jsloader.Error');
-
-goog.require('goog.array');
-goog.require('goog.async.Deferred');
-goog.require('goog.debug.Error');
-goog.require('goog.dom');
-goog.require('goog.userAgent');
-
-
-/**
- * The name of the property of goog.global under which the JavaScript
- * verification object is stored by the loaded script.
- * @type {string}
- * @private
- */
-goog.net.jsloader.GLOBAL_VERIFY_OBJS_ = 'closure_verification';
-
-
-/**
- * The default length of time, in milliseconds, we are prepared to wait for a
- * load request to complete.
- * @type {number}
- */
-goog.net.jsloader.DEFAULT_TIMEOUT = 5000;
-
-
-/**
- * Optional parameters for goog.net.jsloader.send.
- * timeout: The length of time, in milliseconds, we are prepared to wait
- * for a load request to complete. Default it 5 seconds.
- * document: The HTML document under which to load the JavaScript. Default is
- * the current document.
- * cleanupWhenDone: If true clean up the script tag after script completes to
- * load. This is important if you just want to read data from the JavaScript
- * and then throw it away. Default is false.
- *
- * @typedef {{
- * timeout: (number|undefined),
- * document: (HTMLDocument|undefined),
- * cleanupWhenDone: (boolean|undefined)
- * }}
- */
-goog.net.jsloader.Options;
-
-
-/**
- * Scripts (URIs) waiting to be loaded.
- * @type {Array.<string>}
- * @private
- */
-goog.net.jsloader.scriptsToLoad_ = [];
-
-
-/**
- * Loads and evaluates the JavaScript files at the specified URIs, in order.
- *
- * @param {Array.<string>} uris The URIs to load.
- * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See
- * goog.net.jsloader.options documentation for details.
- */
-goog.net.jsloader.loadMany = function(uris, opt_options) {
- // Loading the scripts in serial introduces asynchronosity into the flow.
- // Therefore, there are race conditions where client A can kick off the load
- // sequence for client B, even though client A's scripts haven't all been
- // loaded yet.
- //
- // To work around this issue, all module loads share a queue.
- if (!uris.length) {
- return;
- }
-
- if (goog.userAgent.GECKO && !goog.userAgent.isVersion(2)) {
- // For <script> tags that are loaded in this manner, Gecko 1.9 and earlier
- // ensures that tag order is consistent with evaluation order.
- // Unfortunately, other browsers do not make that guarantee. So the other
- // browsers need a slower and more complex implementation.
- for (var i = 0; i < uris.length; i++) {
- goog.net.jsloader.load(uris[i], opt_options);
- }
- } else {
- var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;
- goog.array.extend(goog.net.jsloader.scriptsToLoad_, uris);
- if (isAnotherModuleLoading) {
- // jsloader is still loading some other scripts.
- // In order to prevent the race condition noted above, we just add
- // these URIs to the end of the scripts' queue and return.
- return;
- }
-
- uris = goog.net.jsloader.scriptsToLoad_;
- var popAndLoadNextScript = function() {
- var uri = uris.shift();
- var deferred = goog.net.jsloader.load(uri, opt_options);
- if (uris.length) {
- deferred.addBoth(popAndLoadNextScript);
- }
- };
- popAndLoadNextScript();
- }
-};
-
-
-/**
- * Loads and evaluates a JavaScript file.
- * When the script loads, a user callback is called.
- * It is the client's responsibility to verify that the script ran successfully.
- *
- * @param {string} uri The URI of the JavaScript.
- * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See
- * goog.net.jsloader.Options documentation for details.
- * @return {!goog.async.Deferred} The deferred result, that may be used to add
- * callbacks and/or cancel the transmission.
- * The error callback will be called with a single goog.net.jsloader.Error
- * parameter.
- */
-goog.net.jsloader.load = function(uri, opt_options) {
- var options = opt_options || {};
- var doc = options.document || document;
-
- var script = goog.dom.createElement(goog.dom.TagName.SCRIPT);
- var request = {script_: script, timeout_: undefined};
- var deferred = new goog.async.Deferred(goog.net.jsloader.cancel_, request);
-
- // Set a timeout.
- var timeout = null;
- var timeoutDuration = goog.isDefAndNotNull(options.timeout) ?
- options.timeout : goog.net.jsloader.DEFAULT_TIMEOUT;
- if (timeoutDuration > 0) {
- timeout = window.setTimeout(function() {
- goog.net.jsloader.cleanup_(script, true);
- deferred.errback(new goog.net.jsloader.Error(
- goog.net.jsloader.ErrorCode.TIMEOUT,
- 'Timeout reached for loading script ' + uri));
- }, timeoutDuration);
- request.timeout_ = timeout;
- }
-
- // Hang the user callback to be called when the script completes to load.
- // NOTE(user): This callback will be called in IE even upon error. In any
- // case it is the client's responsibility to verify that the script ran
- // successfully.
- script.onload = script.onreadystatechange = function() {
- if (!script.readyState || script.readyState == 'loaded' ||
- script.readyState == 'complete') {
- var removeScriptNode = options.cleanupWhenDone || false;
- goog.net.jsloader.cleanup_(script, removeScriptNode, timeout);
- deferred.callback(null);
- }
- };
-
- // Add an error callback.
- // NOTE(user): Not supported in IE.
- script.onerror = function() {
- goog.net.jsloader.cleanup_(script, true, timeout);
- deferred.errback(new goog.net.jsloader.Error(
- goog.net.jsloader.ErrorCode.LOAD_ERROR,
- 'Error while loading script ' + uri));
- };
-
- // Add the script element to the document.
- goog.dom.setProperties(script, {
- 'type': 'text/javascript',
- 'charset': 'UTF-8',
- // NOTE(user): Safari never loads the script if we don't set
- // the src attribute before appending.
- 'src': uri
- });
- var scriptParent = goog.net.jsloader.getScriptParentElement_(doc);
- scriptParent.appendChild(script);
-
- return deferred;
-};
-
-
-/**
- * Loads a JavaScript file and verifies it was evaluated successfully, using a
- * verification object.
- * The verification object is set by the loaded JavaScript at the end of the
- * script.
- * We verify this object was set and return its value in the success callback.
- * If the object is not defined we trigger an error callback.
- *
- * @param {string} uri The URI of the JavaScript.
- * @param {string} verificationObjName The name of the verification object that
- * the loaded script should set.
- * @param {goog.net.jsloader.Options} options Optional parameters. See
- * goog.net.jsloader.Options documentation for details.
- * @return {!goog.async.Deferred} The deferred result, that may be used to add
- * callbacks and/or cancel the transmission.
- * The success callback will be called with a single parameter containing
- * the value of the verification object.
- * The error callback will be called with a single goog.net.jsloader.Error
- * parameter.
- */
-goog.net.jsloader.loadAndVerify = function(uri, verificationObjName, options) {
- // Define the global objects variable.
- if (!goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]) {
- goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_] = {};
- }
- var verifyObjs = goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_];
-
- // Verify that the expected object does not exist yet.
- if (goog.isDef(verifyObjs[verificationObjName])) {
- // TODO(user): Error or reset variable?
- return goog.async.Deferred.fail(new goog.net.jsloader.Error(
- goog.net.jsloader.ErrorCode.VERIFY_OBJECT_ALREADY_EXISTS,
- 'Verification object ' + verificationObjName + ' already defined.'));
- }
-
- // Send request to load the JavaScript.
- var sendDeferred = goog.net.jsloader.load(uri, options);
-
- // Create a deferred object wrapping the send result.
- var deferred = new goog.async.Deferred(sendDeferred.cancel);
-
- // Call user back with object that was set by the script.
- sendDeferred.addCallback(function() {
- var result = verifyObjs[verificationObjName];
- if (goog.isDef(result)) {
- deferred.callback(result);
- delete verifyObjs[verificationObjName];
- } else {
- // Error: script was not loaded properly.
- deferred.errback(new goog.net.jsloader.Error(
- goog.net.jsloader.ErrorCode.VERIFY_ERROR,
- 'Script ' + uri + ' loaded, but verification object ' +
- verificationObjName + ' was not defined.'));
- }
- });
-
- // Pass error to new deferred object.
- sendDeferred.addErrback(function(error) {
- if (goog.isDef(verifyObjs[verificationObjName])) {
- delete verifyObjs[verificationObjName];
- }
- deferred.errback(error);
- });
-
- return deferred;
-};
-
-
-/**
- * Gets the DOM element under which we should add new script elements.
- * How? Take the first head element, and if not found take doc.documentElement,
- * which always exists.
- *
- * @param {!HTMLDocument} doc The relevant document.
- * @return {!Element} The script parent element.
- * @private
- */
-goog.net.jsloader.getScriptParentElement_ = function(doc) {
- var headElements = doc.getElementsByTagName(goog.dom.TagName.HEAD);
- if (!headElements || goog.array.isEmpty(headElements)) {
- return doc.documentElement;
- } else {
- return headElements[0];
- }
-};
-
-
-/**
- * Cancels a given request.
- * @this {{script_: Element, timeout_: number}} The request context.
- * @private
- */
-goog.net.jsloader.cancel_ = function() {
- var request = this;
- if (request && request.script_) {
- var scriptNode = request.script_;
- if (scriptNode && scriptNode.tagName == 'SCRIPT') {
- goog.net.jsloader.cleanup_(scriptNode, true, request.timeout_);
- }
- }
-};
-
-
-/**
- * Removes the script node and the timeout.
- *
- * @param {Node} scriptNode The node to be cleaned up.
- * @param {boolean} removeScriptNode If true completely remove the script node.
- * @param {?number=} opt_timeout The timeout handler to cleanup.
- * @private
- */
-goog.net.jsloader.cleanup_ = function(scriptNode, removeScriptNode,
- opt_timeout) {
- if (goog.isDefAndNotNull(opt_timeout)) {
- goog.global.clearTimeout(opt_timeout);
- }
-
- scriptNode.onload = goog.nullFunction;
- scriptNode.onerror = goog.nullFunction;
- scriptNode.onreadystatechange = goog.nullFunction;
-
- // Do this after a delay (removing the script node of a running script can
- // confuse older IEs).
- if (removeScriptNode) {
- window.setTimeout(function() {
- goog.dom.removeNode(scriptNode);
- }, 0);
- }
-};
-
-
-/**
- * Possible error codes for jsloader.
- * @enum {number}
- */
-goog.net.jsloader.ErrorCode = {
- LOAD_ERROR: 0,
- TIMEOUT: 1,
- VERIFY_ERROR: 2,
- VERIFY_OBJECT_ALREADY_EXISTS: 3
-};
-
-
-
-/**
- * A jsloader error.
- *
- * @param {goog.net.jsloader.ErrorCode} code The error code.
- * @param {string=} opt_message Additional message.
- * @constructor
- * @extends {goog.debug.Error}
- */
-goog.net.jsloader.Error = function(code, opt_message) {
- var msg = 'Jsloader error (code #' + code + ')';
- if (opt_message) {
- msg += ': ' + opt_message;
- }
- goog.base(this, msg);
-
- /**
- * The code for this error.
- *
- * @type {goog.net.jsloader.ErrorCode}
- */
- this.code = code;
-};
-goog.inherits(goog.net.jsloader.Error, goog.debug.Error);
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader_test.html.svn-base
deleted file mode 100644
index 0436abe..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsloader_test.html.svn-base
+++ /dev/null
@@ -1,134 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2011 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.jsloader</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.async.Deferred');
- goog.require('goog.dom');
- goog.require('goog.net.jsloader');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-<script>
-
-// Initialize the AsyncTestCase.
-var testCase = goog.testing.AsyncTestCase.createAndInstall(document.title);
-testCase.stepTimeout = 5 * 1000; // 5 seconds
-
-
-testCase.setUp = function() {
- goog.provide = goog.nullFunction;
-}
-
-
-testCase.tearDown = function() {
- // Remove all the fake scripts.
- var scripts = goog.array.clone(
- document.getElementsByTagName('SCRIPT'));
- for (var i = 0; i < scripts.length; i++) {
- if (scripts[i].src.indexOf('testdata') != -1) {
- goog.dom.removeNode(scripts[i]);
- }
- }
-}
-
-
-// Sunny day scenario for load function.
-function testLoad() {
- testCase.waitForAsync('testLoad');
-
- window.test1 = null;
- var testUrl = 'testdata/jsloader_test1.js';
- var result = goog.net.jsloader.load(testUrl);
- result.addCallback(function() {
- testCase.continueTesting();
-
- var script = result.defaultScope_.script_;
-
- assertNotNull('script created', script);
- assertEquals('encoding is utf-8', 'UTF-8', script.charset);
-
- // Check that the URI matches ours.
- assertTrue('server URI', script.src.indexOf(testUrl) >= 0);
-
- // Check that the script was really loaded.
- assertEquals('verification object', 'Test #1 loaded', window.test1);
- });
-}
-
-
-// Sunny day scenario for loadAndVerify function.
-function testLoadAndVerify() {
- testCase.waitForAsync('testLoadAndVerify');
-
- var testUrl = 'testdata/jsloader_test2.js';
- var result = goog.net.jsloader.loadAndVerify(testUrl, 'test2');
- result.addCallback(function(verifyObj) {
- testCase.continueTesting();
-
- // Check that the verification object has passed ok.
- assertEquals('verification object', 'Test #2 loaded', verifyObj);
- });
-}
-
-
-// What happens when the verification object is not set by the loaded script?
-function testLoadAndVerifyError() {
- testCase.waitForAsync('testLoadAndVerifyError');
-
- var testUrl = 'testdata/jsloader_test2.js';
- var result = goog.net.jsloader.loadAndVerify(testUrl, 'fake');
- result.addErrback(function(error) {
- testCase.continueTesting();
-
- // Check that the error code is right.
- assertEquals('verification error', goog.net.jsloader.ErrorCode.VERIFY_ERROR,
- error.code);
- });
-}
-
-
-// Test the loadMany function.
-function testLoadMany() {
- testCase.waitForAsync('testLoadMany');
-
- // Load test #3 and then #1.
- window.test1 = null;
- var testUrls1 = ['testdata/jsloader_test3.js', 'testdata/jsloader_test1.js'];
- goog.net.jsloader.loadMany(testUrls1);
-
- window.test3Callback = function(msg) {
- testCase.continueTesting();
-
- // Check that the 1st test was not loaded yet.
- assertEquals('verification object', null, window.test1);
-
- // Load test #4, which is supposed to wait for #1 to load.
- testCase.waitForAsync('testLoadMany');
- var testUrls2 = ['testdata/jsloader_test4.js'];
- goog.net.jsloader.loadMany(testUrls2);
- };
-
- window.test4Callback = function(msg) {
- testCase.continueTesting();
-
- // Check that the 1st test was already loaded.
- assertEquals('verification object', 'Test #1 loaded', window.test1);
- };
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp.js.svn-base
deleted file mode 100644
index 5276a70..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp.js.svn-base
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// The original file lives here: http://go/cross_domain_channel.js
-
-/**
- * @fileoverview Implements a cross-domain communication channel. A
- * typical web page is prevented by browser security from sending
- * request, such as a XMLHttpRequest, to other servers than the ones
- * from which it came. The Jsonp class provides a workound, by
- * using dynamically generated script tags. Typical usage:.
- *
- * var jsonp = new goog.net.Jsonp(new goog.Uri('http://my.host.com/servlet'));
- * var payload = { 'foo': 1, 'bar': true };
- * jsonp.send(payload, function(reply) { alert(reply) });
- *
- * This script works in all browsers that are currently supported by
- * the Google Maps API, which is IE 6.0+, Firefox 0.8+, Safari 1.2.4+,
- * Netscape 7.1+, Mozilla 1.4+, Opera 8.02+.
- *
- */
-
-goog.provide('goog.net.Jsonp');
-
-goog.require('goog.Uri');
-goog.require('goog.dom');
-goog.require('goog.net.jsloader');
-
-// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-//
-// This class allows us (Google) to send data from non-Google and thus
-// UNTRUSTED pages to our servers. Under NO CIRCUMSTANCES return
-// anything sensitive, such as session or cookie specific data. Return
-// only data that you want parties external to Google to have. Also
-// NEVER use this method to send data from web pages to untrusted
-// servers, or redirects to unknown servers (www.google.com/cache,
-// /q=xx&btnl, /url, www.googlepages.com, etc.)
-//
-// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-
-
-
-/**
- * Creates a new cross domain channel that sends data to the specified
- * host URL. By default, if no reply arrives within 5s, the channel
- * assumes the call failed to complete successfully.
- *
- * @param {goog.Uri|string} uri The Uri of the server side code that receives
- * data posted through this channel (e.g.,
- * "http://maps.google.com/maps/geo").
- *
- * @param {string=} opt_callbackParamName The parameter name that is used to
- * specify the callback. Defaults to "callback".
- *
- * @constructor
- */
-goog.net.Jsonp = function(uri, opt_callbackParamName) {
- /**
- * The uri_ object will be used to encode the payload that is sent to the
- * server.
- * @type {goog.Uri}
- * @private
- */
- this.uri_ = new goog.Uri(uri);
-
- /**
- * This is the callback parameter name that is added to the uri.
- * @type {string}
- * @private
- */
- this.callbackParamName_ = opt_callbackParamName ?
- opt_callbackParamName : 'callback';
-
- /**
- * The length of time, in milliseconds, this channel is prepared
- * to wait for for a request to complete. The default value is 5 seconds.
- * @type {number}
- * @private
- */
- this.timeout_ = 5000;
-};
-
-
-/**
- * The name of the property of goog.global under which the callback is
- * stored.
- */
-goog.net.Jsonp.CALLBACKS = '_callbacks_';
-
-
-/**
- * Used to generate unique callback IDs. The counter must be global because
- * all channels share a common callback object.
- * @private
- */
-goog.net.Jsonp.scriptCounter_ = 0;
-
-
-/**
- * Sets the length of time, in milliseconds, this channel is prepared
- * to wait for for a request to complete. If the call is not competed
- * within the set time span, it is assumed to have failed. To wait
- * indefinitely for a request to complete set the timout to a negative
- * number.
- *
- * @param {number} timeout The length of time before calls are
- * interrupted.
- */
-goog.net.Jsonp.prototype.setRequestTimeout = function(timeout) {
- this.timeout_ = timeout;
-};
-
-
-/**
- * Returns the current timeout value, in milliseconds.
- *
- * @return {number} The timeout value.
- */
-goog.net.Jsonp.prototype.getRequestTimeout = function() {
- return this.timeout_;
-};
-
-
-/**
- * Sends the given payload to the URL specified at the construction
- * time. The reply is delivered to the given replyCallback. If the
- * errorCallback is specified and the reply does not arrive within the
- * timeout period set on this channel, the errorCallback is invoked
- * with the original payload.
- *
- * If no reply callback is specified, then the response is expected to
- * consist of calls to globally registered functions. No &callback=
- * URL parameter will be sent in the request, and the script element
- * will be cleaned up after the timeout.
- *
- * @param {Object=} opt_payload Name-value pairs. If given, these will be
- * added as parameters to the supplied URI as GET parameters to the
- * given server URI.
- *
- * @param {Function=} opt_replyCallback A function expecting one
- * argument, called when the reply arrives, with the response data.
- *
- * @param {Function=} opt_errorCallback A function expecting one
- * argument, called on timeout, with the payload (if given), otherwise
- * null.
- *
- * @param {string=} opt_callbackParamValue Value to be used as the
- * parameter value for the callback parameter (callbackParamName).
- * To be used when the value needs to be fixed by the client for a
- * particular request, to make use of the cached responses for the request.
- * NOTE: If multiple requests are made with the same
- * opt_callbackParamValue, only the last call will work whenever the
- * response comes back.
- *
- * @return {Object} A request descriptor that may be used to cancel this
- * transmission, or null, if the message may not be cancelled.
- */
-goog.net.Jsonp.prototype.send = function(opt_payload,
- opt_replyCallback,
- opt_errorCallback,
- opt_callbackParamValue) {
-
- var payload = opt_payload || null;
-
- var id = opt_callbackParamValue ||
- '_' + (goog.net.Jsonp.scriptCounter_++).toString(36) +
- goog.now().toString(36);
-
- if (!goog.global[goog.net.Jsonp.CALLBACKS]) {
- goog.global[goog.net.Jsonp.CALLBACKS] = {};
- }
-
- var script = goog.dom.createElement('script');
-
- // Create a new Uri object onto which this payload will be added
- var uri = this.uri_.clone();
- if (payload) {
- goog.net.Jsonp.addPayloadToUri_(payload, uri);
- }
-
- if (opt_replyCallback) {
- var reply = goog.net.Jsonp.newReplyHandler_(id, opt_replyCallback);
- goog.global[goog.net.Jsonp.CALLBACKS][id] = reply;
-
- uri.setParameterValues(this.callbackParamName_,
- goog.net.Jsonp.CALLBACKS + '.' + id);
- }
-
- var deferred = goog.net.jsloader.load(uri.toString(),
- {timeout: this.timeout_, cleanupWhenDone: true});
- var error = goog.net.Jsonp.newErrorHandler_(id, payload, opt_errorCallback);
- deferred.addErrback(error);
-
- return {id_: id, deferred_: deferred};
-};
-
-
-/**
- * Cancels a given request. The request must be exactly the object returned by
- * the send method.
- *
- * @param {Object} request The request object returned by the send method.
- */
-goog.net.Jsonp.prototype.cancel = function(request) {
- if (request) {
- if (request.deferred_) {
- request.deferred_.cancel();
- }
- if (request.id_) {
- goog.net.Jsonp.cleanup_(request.id_, false);
- }
- }
-};
-
-
-/**
- * Creates a timeout callback that calls the given timeoutCallback with the
- * original payload.
- *
- * @param {string} id The id of the script node.
- * @param {Object} payload The payload that was sent to the server.
- * @param {Function=} opt_errorCallback The function called on timeout.
- * @return {!Function} A zero argument function that handles callback duties.
- * @private
- */
-goog.net.Jsonp.newErrorHandler_ = function(id,
- payload,
- opt_errorCallback) {
- /**
- * When we call across domains with a request, this function is the
- * timeout handler. Once it's done executing the user-specified
- * error-handler, it removes the script node and original function.
- */
- return function() {
- goog.net.Jsonp.cleanup_(id, false);
- if (opt_errorCallback) {
- opt_errorCallback(payload);
- }
- };
-};
-
-
-/**
- * Creates a reply callback that calls the given replyCallback with data
- * returned by the server.
- *
- * @param {string} id The id of the script node.
- * @param {Function} replyCallback The function called on reply.
- * @return {Function} A reply callback function.
- * @private
- */
-goog.net.Jsonp.newReplyHandler_ = function(id, replyCallback) {
- /**
- * This function is the handler for the all-is-well response. It
- * clears the error timeout handler, calls the user's handler, then
- * removes the script node and itself.
- *
- * @param {...Object} var_args The response data sent from the server.
- */
- return function(var_args) {
- goog.net.Jsonp.cleanup_(id, true);
- replyCallback.apply(undefined, arguments);
- };
-};
-
-
-/**
- * Removes the script node and reply handler with the given id.
- *
- * @param {string} id The id of the script node to be removed.
- * @param {boolean} deleteReplyHandler If true, delete the reply handler
- * instead of setting it to nullFunction (if we know the callback could
- * never be called again).
- * @private
- */
-goog.net.Jsonp.cleanup_ = function(id, deleteReplyHandler) {
- if (goog.global[goog.net.Jsonp.CALLBACKS][id]) {
- if (deleteReplyHandler) {
- delete goog.global[goog.net.Jsonp.CALLBACKS][id];
- } else {
- // Removing the script tag doesn't necessarily prevent the script
- // from firing, so we make the callback a noop.
- goog.global[goog.net.Jsonp.CALLBACKS][id] = goog.nullFunction;
- }
- }
-};
-
-
-/**
- * Returns URL encoded payload. The payload should be a map of name-value
- * pairs, in the form {"foo": 1, "bar": true, ...}. If the map is empty,
- * the URI will be unchanged.
- *
- * <p>The method uses hasOwnProperty() to assure the properties are on the
- * object, not on its prototype.
- *
- * @param {!Object} payload A map of value name pairs to be encoded.
- * A value may be specified as an array, in which case a query parameter
- * will be created for each value, e.g.:
- * {"foo": [1,2]} will encode to "foo=1&foo=2".
- *
- * @param {!goog.Uri} uri A Uri object onto which the payload key value pairs
- * will be encoded.
- *
- * @return {!goog.Uri} A reference to the Uri sent as a parameter.
- * @private
- */
-goog.net.Jsonp.addPayloadToUri_ = function(payload, uri) {
- for (var name in payload) {
- // NOTE(user): Safari/1.3 doesn't have hasOwnProperty(). In that
- // case, we iterate over all properties as a very lame workaround.
- if (!payload.hasOwnProperty || payload.hasOwnProperty(name)) {
- uri.setParameterValues(name, payload[name]);
- }
- }
- return uri;
-};
-
-
-// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-//
-// This class allows us (Google) to send data from non-Google and thus
-// UNTRUSTED pages to our servers. Under NO CIRCUMSTANCES return
-// anything sensitive, such as session or cookie specific data. Return
-// only data that you want parties external to Google to have. Also
-// NEVER use this method to send data from web pages to untrusted
-// servers, or redirects to unknown servers (www.google.com/cache,
-// /q=xx&btnl, /url, www.googlepages.com, etc.)
-//
-// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp_test.html.svn-base
deleted file mode 100644
index f016153..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/jsonp_test.html.svn-base
+++ /dev/null
@@ -1,327 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.Jsonp</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.dom');
- goog.require('goog.net.Jsonp');
- goog.require('goog.testing.jsunit');
- goog.require('goog.userAgent');
- goog.require('goog.testing.recordFunction');
- goog.require('goog.testing.PropertyReplacer');
-</script>
-</head>
-<body>
-<script>
-// Global vars to facilitate a shared set up function.
-
-var timeoutWasCalled;
-var timeoutHandler;
-
-var fakeUrl = 'http://fake-site.eek/';
-
-var originalTimeout;
-function setUp() {
- timeoutWasCalled = false;
- timeoutHandler = null;
- originalTimeout = window.setTimeout;
- window.setTimeout = function(handler, time) {
- timeoutWasCalled = true;
- timeoutHandler = handler;
- };
-}
-
-// Firefox throws a JS error when a script is not found. We catch that here and
-// ensure the test case doesn't fail because of it.
-var originalOnError = window.onerror;
-window.onerror = function(msg, url, line) {
- // TODO(user): Safari 3 on the farm returns an object instead of the typcial
- // params. Pass through errors for safari for now.
- if (goog.userAgent.WEBKIT ||
- msg == 'Error loading script' && url.indexOf('fake-site') != -1) {
- return true;
- } else {
- return originalOnError && originalOnError(msg, url, line);
- }
-};
-
-function tearDown() {
- window.setTimeout = originalTimeout;
-}
-
-// Quick function records the before-state of the DOM, and then return a
-// a function to check that XDC isn't leaving stuff behind.
-function newCleanupGuard() {
- var bodyChildCount = document.body.childNodes.length;
-
- return function() {
- // let any timeout queues finish before we check these:
- window.setTimeout(function() {
- var propCounter = 0;
-
- // All callbacks should have been deleted or be the null function.
- for (var id in goog.global[goog.net.Jsonp.CALLBACKS]) {
- if (goog.global[goog.net.Jsonp.CALLBACKS][id] != goog.nullFunction) {
- propCounter++;
- }
- }
-
- assertEquals(
- 'script cleanup', bodyChildCount, document.body.childNodes.length);
- assertEquals('window jsonp array empty', 0, propCounter);
- }, 0);
- }
-}
-
-function getScriptElement(result) {
- return result.deferred_.defaultScope_.script_;
-}
-
-
-// Check that send function is sane when things go well.
-function testSend() {
- var replyReceived;
- var jsonp = new goog.net.Jsonp(fakeUrl);
-
- var checkCleanup = newCleanupGuard();
-
- var userCallback = function(data) {
- replyReceived = data;
- }
-
- var payload = {atisket: 'atasket', basket: 'yellow'};
- var result = jsonp.send(payload, userCallback);
-
- var script = getScriptElement(result);
-
- assertNotNull('script created', script);
- assertEquals('encoding is utf-8', 'UTF-8', script.charset);
-
- // Check that the URL matches our payload.
- assertTrue('payload in url', script.src.indexOf('basket=yellow') > -1);
- assertTrue('server url', script.src.indexOf(fakeUrl) == 0);
-
- // Now, we have to track down the name of the callback function, so we can
- // call that to simulate a returned request + verify that the callback
- // function does not break if it receives a second unexpected parameter.
- var callbackName = /callback=([^&]+)/.exec(script.src)[1];
- var callbackFunc = eval(callbackName);
- callbackFunc({some: 'data', another: ['data', 'right', 'here']},
- 'unexpected');
- assertEquals('input was received', 'right', replyReceived.another[1]);
-
- // Because the callbackFunc calls cleanUp_ and that calls setTimeout which
- // we have overwritten, we have to call the timeoutHandler to actually do
- // the cleaning.
- timeoutHandler();
-
- checkCleanup();
- timeoutHandler();
-}
-
-
-// Check that send function is sane when things go well.
-function testSendWhenCallbackHasTwoParameters() {
- var replyReceived, replyReceived2;
- var jsonp = new goog.net.Jsonp(fakeUrl);
-
- var checkCleanup = newCleanupGuard();
-
- var userCallback = function(data, opt_data2) {
- replyReceived = data;
- replyReceived2 = opt_data2;
- }
-
- var payload = {atisket: 'atasket', basket: 'yellow'};
- var result = jsonp.send(payload, userCallback);
- var script = getScriptElement(result);
-
- // Test a callback function that receives two parameters.
- var callbackName = /callback=([^&]+)/.exec(script.src)[1];
- var callbackFunc = eval(callbackName);
- callbackFunc('param1', {some: 'data', another: ['data', 'right', 'here']});
- assertEquals('input was received', 'param1', replyReceived);
- assertEquals('second input was received', 'right',
- replyReceived2.another[1]);
-
- // Because the callbackFunc calls cleanUp_ and that calls setTimeout which
- // we have overwritten, we have to call the timeoutHandler to actually do
- // the cleaning.
- timeoutHandler();
-
- checkCleanup();
- timeoutHandler();
-}
-
-// Check that send function works correctly when callback param value is
-// specified.
-function testSendWithCallbackParamValue() {
- var replyReceived;
- var jsonp = new goog.net.Jsonp(fakeUrl);
-
- var checkCleanup = newCleanupGuard();
-
- var userCallback = function(data) {
- replyReceived = data;
- }
-
- var payload = {atisket: 'atasket', basket: 'yellow'};
- var result = jsonp.send(payload, userCallback, undefined, 'dummyId');
-
- var script = getScriptElement(result);
-
- assertNotNull('script created', script);
- assertEquals('encoding is utf-8', 'UTF-8', script.charset);
-
- // Check that the URL matches our payload.
- assertTrue('payload in url', script.src.indexOf('basket=yellow') > -1);
- assertTrue('dummyId in url',
- script.src.indexOf('callback=_callbacks_.dummyId') > -1);
- assertTrue('server url', script.src.indexOf(fakeUrl) == 0);
-
- // Now, we simulate a returned request using the known callback function
- // name.
- var callbackFunc = _callbacks_.dummyId;
- callbackFunc({some: 'data', another: ['data', 'right', 'here']});
- assertEquals('input was received', 'right', replyReceived.another[1]);
-
- // Because the callbackFunc calls cleanUp_ and that calls setTimeout which
- // we have overwritten, we have to call the timeoutHandler to actually do
- // the cleaning.
- timeoutHandler();
-
- checkCleanup();
- timeoutHandler();
-}
-
-
-// Check that the send function is sane when the thing goes south.
-function testSendFailure() {
- var replyReceived = false;
- var errorReplyReceived = false;
-
- var jsonp = new goog.net.Jsonp(fakeUrl);
-
- var checkCleanup = newCleanupGuard();
-
- var userCallback = function(data) {
- replyReceived = data;
- }
- var userErrorCallback = function(data) {
- errorReplyReceived = data;
- }
-
- var payload = { justa: 'test' };
-
- jsonp.send(payload, userCallback, userErrorCallback);
-
- assertTrue('timeout called', timeoutWasCalled);
-
- // Now, simulate the time running out, so we go into error mode.
- // After jsonp.send(), the timeoutHandler now is the Jsonp.cleanUp_ function.
- timeoutHandler();
- // But that function also calls a setTimeout(), so it changes the timeout
- // handler once again, so to actually clean up we have to call the
- // timeoutHandler() once again. Fun!
- timeoutHandler();
-
- assertFalse('standard callback not called', replyReceived);
-
- // The user's error handler should be called back with the same payload
- // passed back to it.
- assertEquals('error handler called', 'test', errorReplyReceived.justa);
-
- // Check that the relevant cleanup has occurred.
- checkCleanup();
- // Check cleanup just calls setTimeout so we have to call the handler to
- // actually check that the cleanup worked.
- timeoutHandler();
-}
-
-
-// Check that a cancel call works and cleans up after itself.
-function testCancel() {
- var checkCleanup = newCleanupGuard();
-
- var successCalled = false;
- var successCallback = function() {
- successCalled = true;
- };
-
- // Send and cancel a request, then make sure it was cleaned up.
- var jsonp = new goog.net.Jsonp(fakeUrl);
- var requestObject = jsonp.send({test: 'foo'}, successCallback);
- jsonp.cancel(requestObject);
-
- for (var key in goog.global[goog.net.Jsonp.CALLBACKS]) {
- assertNotEquals('The success callback should have been removed',
- goog.global[goog.net.Jsonp.CALLBACKS][key],
- successCallback);
- }
-
- // Make sure cancelling removes the script tag
- checkCleanup();
- timeoutHandler();
-}
-
-function testPayloadParameters() {
- var checkCleanup = newCleanupGuard();
-
- var jsonp = new goog.net.Jsonp(fakeUrl);
- var result = jsonp.send({
- 'foo': 3,
- 'bar': 'baz'
- });
-
- var script = getScriptElement(result);
- assertEquals('Payload parameters should have been added to url.',
- fakeUrl + '?foo=3&bar=baz',
- script.src);
-
- checkCleanup();
- timeoutHandler();
-}
-
-function testOptionalPayload() {
- var checkCleanup = newCleanupGuard();
-
- var errorCallback = goog.testing.recordFunction();
-
- var stubs = new goog.testing.PropertyReplacer();
- stubs.set(goog.global, 'setTimeout', function(errorHandler) {
- errorHandler();
- });
-
- var jsonp = new goog.net.Jsonp(fakeUrl);
- var result = jsonp.send(null, null, errorCallback);
-
- var script = getScriptElement(result);
- assertEquals('Parameters should not have been added to url.',
- fakeUrl, script.src);
-
- // Clear the script hooks because we triggered the error manually.
- script.onload = goog.nullFunction;
- script.onerror = goog.nullFunction;
- script.onreadystatechange = goog.nullFunction;
-
- var errorCallbackArguments = errorCallback.getLastCall().getArguments();
- assertEquals(1, errorCallbackArguments.length);
- assertNull(errorCallbackArguments[0]);
-
- checkCleanup();
- stubs.reset();
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockiframeio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockiframeio.js.svn-base
deleted file mode 100644
index 13423fd..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockiframeio.js.svn-base
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Mock of IframeIo for unit testing.
- */
-
-goog.provide('goog.net.MockIFrameIo');
-goog.require('goog.events.EventTarget');
-goog.require('goog.net.ErrorCode');
-goog.require('goog.net.IframeIo');
-goog.require('goog.net.IframeIo.IncrementalDataEvent');
-
-
-
-/**
- * Mock implenetation of goog.net.IframeIo. This doesn't provide a mock
- * implementation for all cases, but it's not too hard to add them as needed.
- * @param {goog.testing.TestQueue} testQueue Test queue for inserting test
- * events.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.MockIFrameIo = function(testQueue) {
- goog.events.EventTarget.call(this);
-
- /**
- * Queue of events write to
- * @type {goog.testing.TestQueue}
- * @private
- */
- this.testQueue_ = testQueue;
-
-};
-goog.inherits(goog.net.MockIFrameIo, goog.events.EventTarget);
-
-
-/**
- * Whether MockIFrameIo is active.
- * @type {boolean}
- * @private
- */
-goog.net.MockIFrameIo.prototype.active_ = false;
-
-
-/**
- * Last content.
- * @type {string}
- * @private
- */
-goog.net.MockIFrameIo.prototype.lastContent_ = '';
-
-
-/**
- * Last error code.
- * @type {goog.net.ErrorCode}
- * @private
- */
-goog.net.MockIFrameIo.prototype.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
-
-
-/**
- * Last error message.
- * @type {string}
- * @private
- */
-goog.net.MockIFrameIo.prototype.lastError_ = '';
-
-
-/**
- * Last custom error.
- * @type {Object}
- * @private
- */
-goog.net.MockIFrameIo.prototype.lastCustomError_ = null;
-
-
-/**
- * Last URI.
- * @type {goog.Uri}
- * @private
- */
-goog.net.MockIFrameIo.prototype.lastUri_ = null;
-
-
-/**
- * Simulates the iframe send.
- *
- * @param {goog.Uri|string} uri Uri of the request.
- * @param {string=} opt_method Default is GET, POST uses a form to submit the
- * request.
- * @param {boolean=} opt_noCache Append a timestamp to the request to avoid
- * caching.
- * @param {Object|goog.structs.Map=} opt_data Map of key-value pairs.
- */
-goog.net.MockIFrameIo.prototype.send = function(uri, opt_method, opt_noCache,
- opt_data) {
- if (this.active_) {
- throw Error('[goog.net.IframeIo] Unable to send, already active.');
- }
-
- this.testQueue_.enqueue(['s', uri, opt_method, opt_noCache, opt_data]);
- this.complete_ = false;
- this.active_ = true;
-};
-
-
-/**
- * Simulates the iframe send from a form.
- * @param {Element} form Form element used to send the request to the server.
- * @param {string=} opt_uri Uri to set for the destination of the request, by
- * default the uri will come from the form.
- * @param {boolean=} opt_noCache Append a timestamp to the request to avoid
- * caching.
- */
-goog.net.MockIFrameIo.prototype.sendFromForm = function(form, opt_uri,
- opt_noCache) {
- if (this.active_) {
- throw Error('[goog.net.IframeIo] Unable to send, already active.');
- }
-
- this.testQueue_.enqueue(['s', form, opt_uri, opt_noCache]);
- this.complete_ = false;
- this.active_ = true;
-};
-
-
-/**
- * Simulates aborting the current Iframe request.
- * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -
- * defaults to ABORT.
- */
-goog.net.MockIFrameIo.prototype.abort = function(opt_failureCode) {
- if (this.active_) {
- this.testQueue_.enqueue(['a', opt_failureCode]);
- this.complete_ = false;
- this.active_ = false;
- this.success_ = false;
- this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;
- this.dispatchEvent(goog.net.EventType.ABORT);
- this.simulateReady();
- }
-};
-
-
-/**
- * Simulates receive of incremental data.
- * @param {Object} data Data.
- */
-goog.net.MockIFrameIo.prototype.simulateIncrementalData = function(data) {
- this.dispatchEvent(new goog.net.IframeIo.IncrementalDataEvent(data));
-};
-
-
-/**
- * Simulates the iframe is done.
- * @param {goog.net.ErrorCode} errorCode The error code for any error that
- * should be simulated.
- */
-goog.net.MockIFrameIo.prototype.simulateDone = function(errorCode) {
- if (errorCode) {
- this.success_ = false;
- this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;
- this.lastError_ = this.getLastError();
- this.dispatchEvent(goog.net.EventType.ERROR);
- } else {
- this.success_ = true;
- this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
- this.dispatchEvent(goog.net.EventType.SUCCESS);
- }
- this.complete_ = true;
- this.dispatchEvent(goog.net.EventType.COMPLETE);
-};
-
-
-/**
- * Simulates the IFrame is ready for the next request.
- */
-goog.net.MockIFrameIo.prototype.simulateReady = function() {
- this.dispatchEvent(goog.net.EventType.READY);
-};
-
-
-/**
- * @return {boolean} True if transfer is complete.
- */
-goog.net.MockIFrameIo.prototype.isComplete = function() {
- return this.complete_;
-};
-
-
-/**
- * @return {boolean} True if transfer was successful.
- */
-goog.net.MockIFrameIo.prototype.isSuccess = function() {
- return this.success_;
-};
-
-
-/**
- * @return {boolean} True if a transfer is in progress.
- */
-goog.net.MockIFrameIo.prototype.isActive = function() {
- return this.active_;
-};
-
-
-/**
- * Returns the last response text (i.e. the text content of the iframe).
- * Assumes plain text!
- * @return {string} Result from the server.
- */
-goog.net.MockIFrameIo.prototype.getResponseText = function() {
- return this.lastContent_;
-};
-
-
-/**
- * Parses the content as JSON. This is a safe parse and may throw an error
- * if the response is malformed.
- * @return {Object} The parsed content.
- */
-goog.net.MockIFrameIo.prototype.getResponseJson = function() {
- return goog.json.parse(this.lastContent_);
-};
-
-
-/**
- * Get the uri of the last request.
- * @return {goog.Uri} Uri of last request.
- */
-goog.net.MockIFrameIo.prototype.getLastUri = function() {
- return this.lastUri_;
-};
-
-
-/**
- * Gets the last error code.
- * @return {goog.net.ErrorCode} Last error code.
- */
-goog.net.MockIFrameIo.prototype.getLastErrorCode = function() {
- return this.lastErrorCode_;
-};
-
-
-/**
- * Gets the last error message.
- * @return {string} Last error message.
- */
-goog.net.MockIFrameIo.prototype.getLastError = function() {
- return goog.net.ErrorCode.getDebugMessage(this.lastErrorCode_);
-};
-
-
-/**
- * Gets the last custom error.
- * @return {Object} Last custom error.
- */
-goog.net.MockIFrameIo.prototype.getLastCustomError = function() {
- return this.lastCustomError_;
-};
-
-
-/**
- * Sets the callback function used to check if a loaded IFrame is in an error
- * state.
- * @param {Function} fn Callback that expects a document object as it's single
- * argument.
- */
-goog.net.MockIFrameIo.prototype.setErrorChecker = function(fn) {
- this.errorChecker_ = fn;
-};
-
-
-/**
- * Gets the callback function used to check if a loaded IFrame is in an error
- * state.
- * @return {Function} A callback that expects a document object as it's single
- * argument.
- */
-goog.net.MockIFrameIo.prototype.getErrorChecker = function() {
- return this.errorChecker_;
-};
-
-
-/**
- * Returns the number of milliseconds after which an incomplete request will be
- * aborted, or 0 if no timeout is set.
- * @return {number} Timeout interval in milliseconds.
- */
-goog.net.MockIFrameIo.prototype.getTimeoutInterval = function() {
- return this.timeoutInterval_;
-};
-
-
-/**
- * Sets the number of milliseconds after which an incomplete request will be
- * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no
- * timeout is set.
- * @param {number} ms Timeout interval in milliseconds; 0 means none.
- */
-goog.net.MockIFrameIo.prototype.setTimeoutInterval = function(ms) {
- // TODO (pupius) - never used - doesn't look like timeouts were implemented
- this.timeoutInterval_ = Math.max(0, ms);
-};
-
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite.js.svn-base
deleted file mode 100644
index 2ff5995..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite.js.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Mock of XhrLite for unit testing.
- *
- */
-
-goog.provide('goog.net.MockXhrLite');
-
-goog.require('goog.testing.net.XhrIo');
-
-
-
-/**
- * Mock implementation of goog.net.XhrLite. This doesn't provide a mock
- * implementation for all cases, but it's not too hard to add them as needed.
- * @param {goog.testing.TestQueue=} opt_testQueue Test queue for inserting test
- * events.
- * @deprecated Use goog.testing.net.XhrIo.
- * @constructor
- */
-goog.net.MockXhrLite = goog.testing.net.XhrIo;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite_test.html.svn-base
deleted file mode 100644
index c52743a..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/mockxhrlite_test.html.svn-base
+++ /dev/null
@@ -1,109 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.MockXhrLite</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.dom.xml');
- goog.require('goog.events');
- goog.require('goog.net.MockXhrLite');
- goog.require('goog.testing.asserts');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-<script>
-
-function testGetResponseText() {
- // Text response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertEquals('text', e.target.getResponseText());
- });
- xhr.simulateResponse(200, 'text');
- assertTrue(called);
-
- // XML response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- var xml = goog.dom.xml.createDocument();
- xml.appendChild(xml.createElement('root'));
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- var text = e.target.getResponseText();
- assertTrue(/<root ?\/>/.test(text));
- });
- xhr.simulateResponse(200, xml);
- assertTrue(called);
-}
-
-function testGetResponseJson() {
- // Valid JSON response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertArrayEquals([0, 1], e.target.getResponseJson());
- });
- xhr.simulateResponse(200, '[0, 1]');
- assertTrue(called);
-
- // Invalid JSON response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertThrows(e.target.getResponseJson);
- });
- xhr.simulateResponse(200, '[0, 1');
- assertTrue(called);
-
- // XML response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- var xml = goog.dom.xml.createDocument();
- xml.appendChild(xml.createElement('root'));
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertThrows(e.target.getResponseJson);
- });
- xhr.simulateResponse(200, xml);
- assertTrue(called);
-}
-
-function testGetResponseXml() {
- // Text response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertNull(e.target.getResponseXml());
- });
- xhr.simulateResponse(200, 'text');
- assertTrue(called);
-
- // XML response came.
- var called = false;
- var xhr = new goog.net.MockXhrLite();
- var xml = goog.dom.xml.createDocument();
- xml.appendChild(xml.createElement('root'));
- goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
- called = true;
- assertEquals(xml, e.target.getResponseXml());
- });
- xhr.simulateResponse(200, xml);
- assertTrue(called);
-}
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor.js.svn-base
deleted file mode 100644
index 721f5cc..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor.js.svn-base
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Class that can be used to determine when multiple iframes have
- * been loaded. Refactored from static APIs in IframeLoadMonitor.
- */
-goog.provide('goog.net.MultiIframeLoadMonitor');
-
-goog.require('goog.net.IframeLoadMonitor');
-
-
-
-/**
- * Provides a wrapper around IframeLoadMonitor, to allow the caller to wait for
- * multiple iframes to load.
- *
- * @param {Array.<HTMLIFrameElement>} iframes Array of iframe elements to
- * wait until they are loaded.
- * @param {function():void} callback The callback to invoke once the frames have
- * loaded.
- * @param {boolean=} opt_hasContent true if the monitor should wait until the
- * iframes have content (body.firstChild != null).
- * @constructor
- */
-goog.net.MultiIframeLoadMonitor = function(iframes, callback, opt_hasContent) {
- /**
- * Array of IframeLoadMonitors we use to track the loaded status of any
- * currently unloaded iframes.
- * @type {Array.<goog.net.IframeLoadMonitor>}
- * @private
- */
- this.pendingIframeLoadMonitors_ = [];
-
- /**
- * Callback which is invoked when all of the iframes are loaded.
- * @type {function():void}
- * @private
- */
- this.callback_ = callback;
-
- for (var i = 0; i < iframes.length; i++) {
- var iframeLoadMonitor = new goog.net.IframeLoadMonitor(
- iframes[i], opt_hasContent);
- if (iframeLoadMonitor.isLoaded()) {
- // Already loaded - don't need to wait
- iframeLoadMonitor.dispose();
- } else {
- // Iframe isn't loaded yet - register to be notified when it is
- // loaded, and track this monitor so we can dispose later as
- // required.
- this.pendingIframeLoadMonitors_.push(iframeLoadMonitor);
- goog.events.listen(
- iframeLoadMonitor, goog.net.IframeLoadMonitor.LOAD_EVENT, this);
- }
- }
- if (!this.pendingIframeLoadMonitors_.length) {
- // All frames were already loaded
- this.callback_();
- }
-};
-
-
-/**
- * Handles a pending iframe load monitor load event.
- * @param {goog.events.Event} e The goog.net.IframeLoadMonitor.LOAD_EVENT event.
- */
-goog.net.MultiIframeLoadMonitor.prototype.handleEvent = function(e) {
- var iframeLoadMonitor = e.target;
- // iframeLoadMonitor is now loaded, remove it from the array of
- // pending iframe load monitors.
- for (var i = 0; i < this.pendingIframeLoadMonitors_.length; i++) {
- if (this.pendingIframeLoadMonitors_[i] == iframeLoadMonitor) {
- this.pendingIframeLoadMonitors_.splice(i, 1);
- break;
- }
- }
-
- // Disposes of the iframe load monitor. We created this iframe load monitor
- // and installed the single listener on it, so it is safe to dispose it
- // in the middle of this event handler.
- iframeLoadMonitor.dispose();
-
- // If there are no more pending iframe load monitors, all the iframes
- // have loaded, and so we invoke the callback.
- if (!this.pendingIframeLoadMonitors_.length) {
- this.callback_();
- }
-};
-
-
-/**
- * Stops monitoring the iframes, cleaning up any associated resources. In
- * general, the object cleans up its own resources before invoking the
- * callback, so this API should only be used if the caller wants to stop the
- * monitoring before the iframes are loaded (for example, if the caller is
- * implementing a timeout).
- */
-goog.net.MultiIframeLoadMonitor.prototype.stopMonitoring = function() {
- for (var i = 0; i < this.pendingIframeLoadMonitors_.length; i++) {
- this.pendingIframeLoadMonitors_[i].dispose();
- }
- this.pendingIframeLoadMonitors_.length = 0;
-};
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor_test.html.svn-base
deleted file mode 100644
index 7b7696d..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/multiiframeloadmonitor_test.html.svn-base
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Closure Unit Tests - goog.net.MultiIframeLoadMonitor</title>
- <script src="../base.js"></script>
- <script>
- goog.require('goog.dom');
- goog.require('goog.events');
- goog.require('goog.net.MultiIframeLoadMonitor');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.jsunit');
- </script>
-</head>
-<body>
-<div id="frame_parent"></div>
-<script>
- var TEST_FRAME_SRCS = ['iframeloadmonitor_test_frame.html',
- 'iframeloadmonitor_test_frame2.html',
- 'iframeloadmonitor_test_frame3.html'];
-
- // Create a new test case.
- var iframeLoaderTestCase = new goog.testing.AsyncTestCase(document.title);
- iframeLoaderTestCase.stepTimeout = 4 * 1000;
-
- // How many multpile frames finished loading
- iframeLoaderTestCase.multipleComplete_ = 0;
-
- iframeLoaderTestCase.numMonitors = 0;
- iframeLoaderTestCase.disposeCalled = 0;
-
- /** Sets up the test environment, adds tests and sets up the worker pools. */
- iframeLoaderTestCase.setUpPage = function() {
- this.log('Setting tests up');
- iframeLoaderTestCase.waitForAsync('loading iframes');
-
- var dom = goog.dom.getDomHelper();
-
- // Load multiple with callback
- var frame1 = dom.createDom('iframe');
- var frame2 = dom.createDom('iframe');
- var multiMonitor = new goog.net.MultiIframeLoadMonitor(
- [frame1, frame2], goog.bind(this.multipleCallback, this));
- this.log('Loading frames at: ' + TEST_FRAME_SRCS[0] + ' and '
- + TEST_FRAME_SRCS[1]);
- // Make sure they don't look loaded yet.
- assertEquals(0, this.multipleComplete_);
- var frameParent = dom.getElement('frame_parent');
- dom.appendChild(frameParent, frame1);
- frame1.src = TEST_FRAME_SRCS[0];
- dom.appendChild(frameParent, frame2);
- frame2.src = TEST_FRAME_SRCS[1];
-
- // Load multiple with callback and content check
- var frame3 = dom.createDom('iframe');
- var frame4 = dom.createDom('iframe');
- var multiMonitor = new goog.net.MultiIframeLoadMonitor(
- [frame3, frame4], goog.bind(this.multipleContentCallback, this), true);
- this.log('Loading frames with content check at: ' + TEST_FRAME_SRCS[1] +
- ' and ' + TEST_FRAME_SRCS[2]);
- dom.appendChild(frameParent, frame3);
- frame3.src = TEST_FRAME_SRCS[1];
- dom.appendChild(frameParent, frame4);
- frame4.src = TEST_FRAME_SRCS[2];
-
- this.add(new goog.testing.TestCase.Test(
- 'test results', this.testResults, this));
- this.add(new goog.testing.TestCase.Test(
- 'stopMonitoring', this.testStop, this));
- };
-
-
- /** Callback for the multiple frame load test case */
- iframeLoaderTestCase.multipleCallback = function() {
- this.log('multiple frames finished loading');
- this.multipleComplete_++;
- this.multipleCompleteNoContent_ = true;
- this.callbacksComplete();
- };
-
- /** Callback for the multiple frame with content load test case */
- iframeLoaderTestCase.multipleContentCallback = function() {
- this.log('multiple frames with content finished loading');
- this.multipleComplete_++;
- this.multipleCompleteContent_ = true;
- this.callbacksComplete();
- };
-
- /** Checks if all the load callbacks are done*/
- iframeLoaderTestCase.callbacksComplete = function() {
- if (this.multipleComplete_ == 2) {
- iframeLoaderTestCase.continueTesting();
- }
- }
-
- /** Tests the results. */
- iframeLoaderTestCase.testResults = function() {
- this.log('getting test results');
- assertTrue(this.multipleCompleteNoContent_);
- assertTrue(this.multipleCompleteContent_);
- };
-
- iframeLoaderTestCase.fakeLoadMonitor = function() {
- // Replaces IframeLoadMonitor with a fake version that just tracks
- // instantiations/disposals
- this.loadMonitorConstructor = goog.net.IframeLoadMonitor;
- var that = this;
- goog.net.IframeLoadMonitor = function() {
- that.numMonitors++;
- return {
- isLoaded: function() { return false; },
- dispose: function() { that.disposeCalled++; },
- attachEvent: function() {}
- };
- }
- goog.net.IframeLoadMonitor.LOAD_EVENT = 'ifload';
- };
-
- iframeLoaderTestCase.unfakeLoadMonitor = function() {
- goog.net.IframeLoadMonitor = this.loadMonitorConstructor;
- };
-
-
- iframeLoaderTestCase.testStop = function() {
- // create two unloaded frames, make sure that load monitors are loaded
- // behind the scenes, then make sure they are disposed properly.
- this.fakeLoadMonitor();
- var dom = goog.dom.getDomHelper();
- var frames = [dom.createDom('iframe'), dom.createDom('iframe')];
- var multiMonitor = new goog.net.MultiIframeLoadMonitor(
- frames,
- function() {
- fail("should not invoke callback for unloaded rames");
- });
- assertEquals(frames.length, this.numMonitors);
- assertEquals(0, this.disposeCalled);
- multiMonitor.stopMonitoring();
- assertEquals(frames.length, this.disposeCalled);
- this.unfakeLoadMonitor();
- };
-
- /** Used by the JsUnit test runner. */
- function testResults() {
- iframeLoaderTestCase.testResults();
- }
-
- /** Used by the JsUnit test runner. */
- function testDispose() {
- iframeLoaderTestCase.testDispose();
- }
-
- /** Used by the JsUnit test runner. */
- function setUpPage() {
- iframeLoaderTestCase.runTests();
- }
-
- /** Standalone Closure Test Runner. */
- if (typeof G_testRunner != 'undefined') {
- G_testRunner.initialize(iframeLoaderTestCase);
- }
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester.js.svn-base
deleted file mode 100644
index 972abab..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester.js.svn-base
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of goog.net.NetworkTester.
- */
-
-goog.provide('goog.net.NetworkTester');
-goog.require('goog.Timer');
-goog.require('goog.Uri');
-goog.require('goog.debug.Logger');
-
-
-
-/**
- * Creates an instance of goog.net.NetworkTester which can be used to test
- * for internet connectivity by seeing if an image can be loaded from
- * google.com. It can also be tested with other URLs.
- * @param {Function} callback Callback that is called when the test completes.
- * The callback takes a single boolean parameter. True indicates the URL
- * was reachable, false indicates it wasn't.
- * @param {Object=} opt_handler Handler object for the callback.
- * @param {goog.Uri=} opt_uri URI to use for testing.
- * @constructor
- */
-goog.net.NetworkTester = function(callback, opt_handler, opt_uri) {
- /**
- * Callback that is called when the test completes.
- * The callback takes a single boolean parameter. True indicates the URL was
- * reachable, false indicates it wasn't.
- * @type {Function}
- * @private
- */
- this.callback_ = callback;
-
- /**
- * Handler object for the callback.
- * @type {Object|undefined}
- * @private
- */
- this.handler_ = opt_handler;
-
- if (!opt_uri) {
- // set the default URI to be based on the cleardot image at google.com
- // We need to add a 'rand' to make sure the response is not fulfilled
- // by browser cache. Use protocol-relative URLs to avoid insecure content
- // warnings in IE.
- opt_uri = new goog.Uri('//www.google.com/images/cleardot.gif');
- opt_uri.makeUnique();
- }
-
- /**
- * Uri to use for test. Defaults to using an image off of google.com
- * @type {goog.Uri}
- * @private
- */
- this.uri_ = opt_uri;
-};
-
-
-/**
- * Default timeout
- * @type {number}
- */
-goog.net.NetworkTester.DEFAULT_TIMEOUT_MS = 10000;
-
-
-/**
- * Logger object
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.NetworkTester.prototype.logger_ =
- goog.debug.Logger.getLogger('goog.net.NetworkTester');
-
-
-/**
- * Timeout for test
- * @type {number}
- * @private
- */
-goog.net.NetworkTester.prototype.timeoutMs_ =
- goog.net.NetworkTester.DEFAULT_TIMEOUT_MS;
-
-
-/**
- * Whether we've already started running.
- * @type {boolean}
- * @private
- */
-goog.net.NetworkTester.prototype.running_ = false;
-
-
-/**
- * Number of retries to attempt
- * @type {number}
- * @private
- */
-goog.net.NetworkTester.prototype.retries_ = 0;
-
-
-/**
- * Attempt number we're on
- * @type {number}
- * @private
- */
-goog.net.NetworkTester.prototype.attempt_ = 0;
-
-
-/**
- * Pause between retries in milliseconds.
- * @type {number}
- * @private
- */
-goog.net.NetworkTester.prototype.pauseBetweenRetriesMs_ = 0;
-
-
-/**
- * Timer for timeouts.
- * @type {?number}
- * @private
- */
-goog.net.NetworkTester.prototype.timeoutTimer_ = null;
-
-
-/**
- * Timer for pauses between retries.
- * @type {?number}
- * @private
- */
-goog.net.NetworkTester.prototype.pauseTimer_ = null;
-
-
-/**
- * Returns the timeout in milliseconds.
- * @return {number} Timeout in milliseconds.
- */
-goog.net.NetworkTester.prototype.getTimeout = function() {
- return this.timeoutMs_;
-};
-
-
-/**
- * Sets the timeout in milliseconds.
- * @param {number} timeoutMs Timeout in milliseconds.
- */
-goog.net.NetworkTester.prototype.setTimeout = function(timeoutMs) {
- this.timeoutMs_ = timeoutMs;
-};
-
-
-/**
- * Returns the numer of retries to attempt.
- * @return {number} Number of retries to attempt.
- */
-goog.net.NetworkTester.prototype.getNumRetries = function() {
- return this.retries_;
-};
-
-
-/**
- * Sets the timeout in milliseconds.
- * @param {number} retries Number of retries to attempt.
- */
-goog.net.NetworkTester.prototype.setNumRetries = function(retries) {
- this.retries_ = retries;
-};
-
-
-/**
- * Returns the pause between retries in milliseconds.
- * @return {number} Pause between retries in milliseconds.
- */
-goog.net.NetworkTester.prototype.getPauseBetweenRetries = function() {
- return this.pauseBetweenRetriesMs_;
-};
-
-
-/**
- * Sets the pause between retries in milliseconds.
- * @param {number} pauseMs Pause between retries in milliseconds.
- */
-goog.net.NetworkTester.prototype.setPauseBetweenRetries = function(pauseMs) {
- this.pauseBetweenRetriesMs_ = pauseMs;
-};
-
-
-/**
- * Returns the uri to use for the test.
- * @return {goog.Uri} The uri for the test.
- */
-goog.net.NetworkTester.prototype.getUri = function() {
- return this.uri_;
-};
-
-
-/**
- * Sets the uri to use for the test.
- * @param {goog.Uri} uri The uri for the test.
- */
-goog.net.NetworkTester.prototype.setUri = function(uri) {
- this.uri_ = uri;
-};
-
-
-/**
- * Returns whether the tester is currently running.
- * @return {boolean} True if it's running, false if it's not running.
- */
-goog.net.NetworkTester.prototype.isRunning = function() {
- return this.running_;
-};
-
-
-/**
- * Starts the process of testing the network.
- */
-goog.net.NetworkTester.prototype.start = function() {
- if (this.running_) {
- throw Error('NetworkTester.start called when already running');
- }
- this.running_ = true;
-
- this.logger_.info('Starting');
- this.attempt_ = 0;
- this.startNextAttempt_();
-};
-
-
-/**
- * Stops the testing of the network. This is a noop if not running.
- */
-goog.net.NetworkTester.prototype.stop = function() {
- this.cleanupCallbacks_();
- this.running_ = false;
-};
-
-
-/**
- * Starts the next attempt to load an image.
- * @private
- */
-goog.net.NetworkTester.prototype.startNextAttempt_ = function() {
- this.attempt_++;
-
- if (goog.net.NetworkTester.getNavigatorOffline_()) {
- this.logger_.info('Browser is set to work offline.');
- // Call in a timeout to make async like the rest.
- goog.Timer.callOnce(goog.bind(this.onResult, this, false), 0);
- } else {
- this.logger_.info('Loading image (attempt ' + this.attempt_ +
- ') at ' + this.uri_);
- this.image_ = new Image();
- this.image_.onload = goog.bind(this.onImageLoad_, this);
- this.image_.onerror = goog.bind(this.onImageError_, this);
- this.image_.onabort = goog.bind(this.onImageAbort_, this);
-
- this.timeoutTimer_ = goog.Timer.callOnce(this.onImageTimeout_,
- this.timeoutMs_, this);
- this.image_.src = String(this.uri_);
- }
-};
-
-
-/**
- * @return {boolean} Whether navigator.onLine returns false.
- * @private
- */
-goog.net.NetworkTester.getNavigatorOffline_ = function() {
- return 'onLine' in navigator && !navigator.onLine;
-};
-
-
-/**
- * Callback for the image successfully loading.
- * @private
- */
-goog.net.NetworkTester.prototype.onImageLoad_ = function() {
- this.logger_.info('Image loaded');
- this.onResult(true);
-};
-
-
-/**
- * Callback for the image failing to load.
- * @private
- */
-goog.net.NetworkTester.prototype.onImageError_ = function() {
- this.logger_.info('Image load error');
- this.onResult(false);
-};
-
-
-/**
- * Callback for the image load being aborted.
- * @private
- */
-goog.net.NetworkTester.prototype.onImageAbort_ = function() {
- this.logger_.info('Image load aborted');
- this.onResult(false);
-};
-
-
-/**
- * Callback for the image load timing out.
- * @private
- */
-goog.net.NetworkTester.prototype.onImageTimeout_ = function() {
- this.logger_.info('Image load timed out');
- this.onResult(false);
-};
-
-
-/**
- * Handles a successful or failed result.
- * @param {boolean} succeeded Whether the image load succeeded.
- */
-goog.net.NetworkTester.prototype.onResult = function(succeeded) {
- this.cleanupCallbacks_();
-
- if (succeeded) {
- this.running_ = false;
- this.callback_.call(this.handler_, true);
- } else {
- if (this.attempt_ <= this.retries_) {
- if (this.pauseBetweenRetriesMs_) {
- this.pauseTimer_ = goog.Timer.callOnce(this.onPauseFinished_,
- this.pauseBetweenRetriesMs_, this);
- } else {
- this.startNextAttempt_();
- }
- } else {
- this.running_ = false;
- this.callback_.call(this.handler_, false);
- }
- }
-};
-
-
-/**
- * Callback for the pause between retry timer.
- * @private
- */
-goog.net.NetworkTester.prototype.onPauseFinished_ = function() {
- this.pauseTimer_ = null;
- this.startNextAttempt_();
-};
-
-
-/**
- * Cleans up the handlers and timer associated with the image.
- * @private
- */
-goog.net.NetworkTester.prototype.cleanupCallbacks_ = function() {
- // clear handlers to avoid memory leaks
- // NOTE(user): Nullified individually to avoid compiler warnings
- // (BUG 658126)
- if (this.image_) {
- this.image_.onload = null;
- this.image_.onerror = null;
- this.image_.onabort = null;
- this.image_ = null;
- }
- if (this.timeoutTimer_) {
- goog.Timer.clear(this.timeoutTimer_);
- this.timeoutTimer_ = null;
- }
- if (this.pauseTimer_) {
- goog.Timer.clear(this.pauseTimer_);
- this.pauseTimer_ = null;
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester_test.html.svn-base
deleted file mode 100644
index 67fc4ad..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/networktester_test.html.svn-base
+++ /dev/null
@@ -1,227 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2006 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.NetworkTester</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.Uri')
- goog.require('goog.net.NetworkTester');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-
-<script>
- var clock;
-
- function setUp() {
- clock = new goog.testing.MockClock(true);
- }
-
- function tearDown() {
- clock.dispose();
- }
-
- function testSuccess() {
- // set up the tster
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // simulate the image load and verify
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onload.call(null);
- assertTrue(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testFailure() {
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // simulate the image failure and verify
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onerror.call(null);
- assertFalse(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testAbort() {
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // simulate the image abort and verify
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onabort.call(null);
- assertFalse(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testTimeout() {
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // simulate the image timeout and verify
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- clock.tick(10000);
- assertFalse(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testRetries() {
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- tester.setNumRetries(1);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // try number 1 fails
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onerror.call(null);
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // try number 2 succeeds
- image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onload.call(null);
- assertTrue(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testPauseBetweenRetries() {
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- tester.setNumRetries(1);
- tester.setPauseBetweenRetries(1000);
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // try number 1 fails
- var image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onerror.call(null);
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // need to pause 1000 ms for the second attempt
- assertNull(tester.image_);
- clock.tick(1000);
-
- // try number 2 succeeds
- image = tester.image_;
- assertEquals(String(tester.getUri()), image.src);
- assertTrue(handler.isEmpty());
- image.onload.call(null);
- assertTrue(handler.dequeue());
- assertFalse(tester.isRunning());
- }
-
- function testNonDefaultUri() {
- var handler = new Handler();
- var newUri = new goog.Uri('//www.google.com/images/cleardot2.gif');
- var tester = new goog.net.NetworkTester(handler.callback, handler, newUri);
- var testerUri = tester.getUri();
- assertTrue(testerUri.toString().indexOf('cleardot2') > -1);
- }
-
- function testOffline() {
-
- // set up the tester
- var handler = new Handler();
- var tester = new goog.net.NetworkTester(handler.callback, handler);
- var orgGetNavigatorOffline = goog.net.NetworkTester.getNavigatorOffline_;
- goog.net.NetworkTester.getNavigatorOffline_ = function() {
- return true;
- };
- try {
- assertFalse(tester.isRunning());
- tester.start();
- assertTrue(handler.isEmpty());
- assertTrue(tester.isRunning());
-
- // the call is done async
- clock.tick(1);
-
- assertFalse(handler.dequeue());
- assertFalse(tester.isRunning());
- } finally {
- // Clean up!
- goog.net.NetworkTester.getNavigatorOffline_ = orgGetNavigatorOffline;
- }
- }
-
- // Handler object for verifying callback
- function Handler() {
- this.events_ = [];
- };
-
- Handler.prototype.callback = function(result) {
- this.events_.push(result);
- };
-
- Handler.prototype.isEmpty = function() {
- return this.events_.length == 0;
- }
-
- Handler.prototype.dequeue = function() {
- if (this.isEmpty()) {
- throw Error("Handler is empty");
- }
- return this.events_.shift();
- };
-
- // override image constructor for test - can't use a real image due to
- // async load of images - have to simulate it
- function Image() {
- }
-
-
-</script>
-
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/tmpnetwork.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/tmpnetwork.js.svn-base
deleted file mode 100644
index 6f9c03c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/tmpnetwork.js.svn-base
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview tmpnetwork.js contains some temporary networking functions
- * for browserchannel which will be moved at a later date.
- */
-
-
-/**
- * Namespace for BrowserChannel
- */
-goog.provide('goog.net.tmpnetwork');
-
-goog.require('goog.Uri');
-goog.require('goog.net.ChannelDebug');
-
-
-/**
- * Default timeout to allow for google.com pings.
- * @type {number}
- */
-goog.net.tmpnetwork.GOOGLECOM_TIMEOUT = 10000;
-
-
-goog.net.tmpnetwork.testGoogleCom = function(callback, opt_imageUri) {
- // We need to add a 'rand' to make sure the response is not fulfilled
- // by browser cache.
- var uri = opt_imageUri;
- if (!uri) {
- uri = new goog.Uri('//www.google.com/images/cleardot.gif');
- uri.makeUnique();
- }
- goog.net.tmpnetwork.testLoadImage(uri.toString(),
- goog.net.tmpnetwork.GOOGLECOM_TIMEOUT, callback);
-};
-
-
-/**
- * Test loading the given image, retrying if necessary.
- * @param {string} url URL to the iamge.
- * @param {number} timeout Milliseconds before giving up.
- * @param {Function} callback Function to call with results.
- * @param {number} retries The number of times to retry.
- * @param {number=} opt_pauseBetweenRetriesMS Optional number of milliseconds
- * between retries - defaults to 0.
- */
-goog.net.tmpnetwork.testLoadImageWithRetries = function(url, timeout, callback,
- retries, opt_pauseBetweenRetriesMS) {
- var channelDebug = new goog.net.ChannelDebug();
- channelDebug.debug('TestLoadImageWithRetries: ' + opt_pauseBetweenRetriesMS);
- if (retries == 0) {
- // no more retries, give up
- callback(false);
- return;
- }
-
- var pauseBetweenRetries = opt_pauseBetweenRetriesMS || 0;
- retries--;
- goog.net.tmpnetwork.testLoadImage(url, timeout, function(succeeded) {
- if (succeeded) {
- callback(true);
- } else {
- // try again
- goog.global.setTimeout(function() {
- goog.net.tmpnetwork.testLoadImageWithRetries(url, timeout, callback,
- retries, pauseBetweenRetries);
- }, pauseBetweenRetries);
- }
- });
-};
-
-
-/**
- * Test loading the given image.
- * @param {string} url URL to the iamge.
- * @param {number} timeout Milliseconds before giving up.
- * @param {Function} callback Function to call with results.
- */
-goog.net.tmpnetwork.testLoadImage = function(url, timeout, callback) {
- var channelDebug = new goog.net.ChannelDebug();
- channelDebug.debug('TestLoadImage: loading ' + url);
- var img = new Image();
- img.onload = function() {
- try {
- channelDebug.debug('TestLoadImage: loaded');
- goog.net.tmpnetwork.clearImageCallbacks_(img);
- callback(true);
- } catch (e) {
- channelDebug.dumpException(e);
- }
- };
- img.onerror = function() {
- try {
- channelDebug.debug('TestLoadImage: error');
- goog.net.tmpnetwork.clearImageCallbacks_(img);
- callback(false);
- } catch (e) {
- channelDebug.dumpException(e);
- }
- };
- img.onabort = function() {
- try {
- channelDebug.debug('TestLoadImage: abort');
- goog.net.tmpnetwork.clearImageCallbacks_(img);
- callback(false);
- } catch (e) {
- channelDebug.dumpException(e);
- }
- };
- img.ontimeout = function() {
- try {
- channelDebug.debug('TestLoadImage: timeout');
- goog.net.tmpnetwork.clearImageCallbacks_(img);
- callback(false);
- } catch (e) {
- channelDebug.dumpException(e);
- }
- };
-
- goog.global.setTimeout(function() {
- if (img.ontimeout) {
- img.ontimeout();
- }
- }, timeout);
- img.src = url;
-};
-
-
-/**
- * Clear handlers to avoid memory leaks.
- * @param {Image} img The image to clear handlers from.
- * @private
- */
-goog.net.tmpnetwork.clearImageCallbacks_ = function(img) {
- // NOTE(user): Nullified individually to avoid compiler warnings
- // (BUG 658126)
- img.onload = null;
- img.onerror = null;
- img.onabort = null;
- img.ontimeout = null;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket.js.svn-base
deleted file mode 100644
index 85b7e0a..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket.js.svn-base
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Definition of the WebSocket class. A WebSocket provides a
- * bi-directional, full-duplex communications channel, over a single TCP socket.
- *
- * See http://dev.w3.org/html5/websockets/
- * for the full HTML5 WebSocket API.
- *
- * Typical usage will look like this:
- *
- * var ws = new goog.net.WebSocket();
- *
- * var handler = new goog.events.EventHandler();
- * handler.listen(ws, goog.net.WebSocket.EventType.OPENED, onOpen);
- * handler.listen(ws, goog.net.WebSocket.EventType.MESSAGE, onMessage);
- *
- * try {
- * ws.open('ws://127.0.0.1:4200');
- * } catch (e) {
- * ...
- * }
- *
- */
-
-goog.provide('goog.net.WebSocket');
-goog.provide('goog.net.WebSocket.ErrorEvent');
-goog.provide('goog.net.WebSocket.EventType');
-goog.provide('goog.net.WebSocket.MessageEvent');
-
-goog.require('goog.Timer');
-goog.require('goog.asserts');
-goog.require('goog.debug.Logger');
-goog.require('goog.debug.entryPointRegistry');
-goog.require('goog.events');
-goog.require('goog.events.Event');
-goog.require('goog.events.EventTarget');
-
-
-
-/**
- * Class encapsulating the logic for using a WebSocket.
- *
- * @param {boolean=} opt_autoReconnect True if the web socket should
- * automatically reconnect or not. This is true by default.
- * @param {function(number):number=} opt_getNextReconnect A function for
- * obtaining the time until the next reconnect attempt. Given the reconnect
- * attempt count (which is a positive integer), the function should return a
- * positive integer representing the milliseconds to the next reconnect
- * attempt. The default function used is an exponential back-off. Note that
- * this function is never called if auto reconnect is disabled.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.WebSocket = function(opt_autoReconnect, opt_getNextReconnect) {
- goog.base(this);
-
- /**
- * True if the web socket should automatically reconnect or not.
- * @type {boolean}
- * @private
- */
- this.autoReconnect_ = goog.isDef(opt_autoReconnect) ?
- opt_autoReconnect : true;
-
- /**
- * A function for obtaining the time until the next reconnect attempt.
- * Given the reconnect attempt count (which is a positive integer), the
- * function should return a positive integer representing the milliseconds to
- * the next reconnect attempt.
- * @type {function(number):number}
- * @private
- */
- this.getNextReconnect_ = opt_getNextReconnect ||
- goog.net.WebSocket.EXPONENTIAL_BACKOFF_;
-
- /**
- * The time, in milliseconds, that must elapse before the next attempt to
- * reconnect.
- * @type {number}
- * @private
- */
- this.nextReconnect_ = this.getNextReconnect_(this.reconnectAttempt_);
-};
-goog.inherits(goog.net.WebSocket, goog.events.EventTarget);
-
-
-/**
- * The actual web socket that will be used to send/receive messages.
- * @type {WebSocket}
- * @private
- */
-goog.net.WebSocket.prototype.webSocket_ = null;
-
-
-/**
- * The URL to which the web socket will connect.
- * @type {?string}
- * @private
- */
-goog.net.WebSocket.prototype.url_ = null;
-
-
-/**
- * The subprotocol name used when establishing the web socket connection.
- * @type {string|undefined}
- * @private
- */
-goog.net.WebSocket.prototype.protocol_ = undefined;
-
-
-/**
- * True if a call to the close callback is expected or not.
- * @type {boolean}
- * @private
- */
-goog.net.WebSocket.prototype.closeExpected_ = false;
-
-
-/**
- * Keeps track of the number of reconnect attempts made since the last
- * successful connection.
- * @type {number}
- * @private
- */
-goog.net.WebSocket.prototype.reconnectAttempt_ = 0;
-
-
-/**
- * The logger for this class.
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.WebSocket.prototype.logger_ = goog.debug.Logger.getLogger(
- 'goog.net.WebSocket');
-
-
-/**
- * The events fired by the web socket.
- * @enum {string} The event types for the web socket.
- */
-goog.net.WebSocket.EventType = {
-
- /**
- * Fired when an attempt to open the WebSocket fails or there is a connection
- * failure after a successful connection has been established.
- */
- CLOSED: goog.events.getUniqueId('closed'),
-
- /**
- * Fired when the WebSocket encounters an error.
- */
- ERROR: goog.events.getUniqueId('error'),
-
- /**
- * Fired when a new message arrives from the WebSocket.
- */
- MESSAGE: goog.events.getUniqueId('message'),
-
- /**
- * Fired when the WebSocket connection has been established.
- */
- OPENED: goog.events.getUniqueId('opened')
-};
-
-
-/**
- * The various states of the web socket.
- * @enum {number} The states of the web socket.
- * @private
- */
-goog.net.WebSocket.ReadyState_ = {
- // This is the initial state during construction.
- CONNECTING: 0,
- // This is when the socket is actually open and ready for data.
- OPEN: 1,
- // This is when the socket is in the middle of a close handshake.
- // Note that this is a valid state even if the OPEN state was never achieved.
- CLOSING: 2,
- // This is when the socket is actually closed.
- CLOSED: 3
-};
-
-
-/**
- * The maximum amount of time between reconnect attempts for the exponential
- * back-off in milliseconds.
- * @type {number}
- * @private
- */
-goog.net.WebSocket.EXPONENTIAL_BACKOFF_CEILING_ = 60 * 1000;
-
-
-/**
- * Computes the next reconnect time given the number of reconnect attempts since
- * the last successful connection.
- *
- * @param {number} attempt The number of reconnect attempts since the last
- * connection.
- * @return {number} The time, in milliseconds, until the next reconnect attempt.
- * @const
- * @private
- */
-goog.net.WebSocket.EXPONENTIAL_BACKOFF_ = function(attempt) {
- var time = Math.pow(2, attempt) * 1000;
- return Math.min(time, goog.net.WebSocket.EXPONENTIAL_BACKOFF_CEILING_);
-};
-
-
-/**
- * Installs exception protection for all entry points introduced by
- * goog.net.WebSocket instances which are not protected by
- * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},
- * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or
- * {@link goog.events.protectBrowserEventEntryPoint}.
- *
- * @param {!goog.debug.ErrorHandler} errorHandler Error handler with which to
- * protect the entry points.
- */
-goog.net.WebSocket.protectEntryPoints = function(errorHandler) {
- goog.net.WebSocket.prototype.onOpen_ = errorHandler.protectEntryPoint(
- goog.net.WebSocket.prototype.onOpen_);
- goog.net.WebSocket.prototype.onClose_ = errorHandler.protectEntryPoint(
- goog.net.WebSocket.prototype.onClose_);
- goog.net.WebSocket.prototype.onMessage_ = errorHandler.protectEntryPoint(
- goog.net.WebSocket.prototype.onMessage_);
- goog.net.WebSocket.prototype.onError_ = errorHandler.protectEntryPoint(
- goog.net.WebSocket.prototype.onError_);
-};
-
-
-/**
- * Creates and opens the actual WebSocket. Only call this after attaching the
- * appropriate listeners to this object. If listeners aren't registered, then
- * the {@code goog.net.WebSocket.EventType.OPENED} event might be missed.
- *
- * @param {string} url The URL to which to connect.
- * @param {string=} opt_protocol The subprotocol to use. The connection will
- * only be established if the server reports that it has selected this
- * subprotocol. The subprotocol name must all be a non-empty ASCII string
- * with no control characters and no spaces in them (i.e. only characters
- * in the range U+0021 to U+007E).
- */
-goog.net.WebSocket.prototype.open = function(url, opt_protocol) {
- // Sanity check. This works only in modern browsers.
- goog.asserts.assert(goog.global['WebSocket'],
- 'This browser does not support WebSocket');
-
- // Don't do anything if the web socket is already open.
- goog.asserts.assert(!this.isOpen(), 'The WebSocket is already open');
-
- // Clear any pending attempts to reconnect.
- this.clearReconnectTimer_();
-
- // Construct the web socket.
- this.url_ = url;
- this.protocol_ = opt_protocol;
-
- // This check has to be made otherwise you get protocol mismatch exceptions
- // for passing undefined, null, '', or [].
- if (this.protocol_) {
- this.logger_.info('Opening the WebSocket on ' + this.url_ +
- ' with protocol ' + this.protocol_);
- this.webSocket_ = new WebSocket(this.url_, this.protocol_);
- } else {
- this.logger_.info('Opening the WebSocket on ' + this.url_);
- this.webSocket_ = new WebSocket(this.url_);
- }
-
- // Register the event handlers. Note that it is not possible for these
- // callbacks to be missed because it is registered after the web socket is
- // instantiated. Because of the synchronous nature of JavaScript, this code
- // will execute before the browser creates the resource and makes any calls
- // to these callbacks.
- this.webSocket_.onopen = goog.bind(this.onOpen_, this);
- this.webSocket_.onclose = goog.bind(this.onClose_, this);
- this.webSocket_.onmessage = goog.bind(this.onMessage_, this);
- this.webSocket_.onerror = goog.bind(this.onError_, this);
-};
-
-
-/**
- * Closes the web socket connection.
- */
-goog.net.WebSocket.prototype.close = function() {
-
- // Clear any pending attempts to reconnect.
- this.clearReconnectTimer_();
-
- // Attempt to close only if the web socket was created.
- if (this.webSocket_) {
- this.logger_.info('Closing the WebSocket.');
-
- // Close is expected here since it was a direct call. Close is considered
- // unexpected when opening the connection fails or there is some other form
- // of connection loss after being connected.
- this.closeExpected_ = true;
- this.webSocket_.close();
- this.webSocket_ = null;
- }
-};
-
-
-/**
- * Sends the message over the web socket.
- *
- * @param {string} message The message to send.
- */
-goog.net.WebSocket.prototype.send = function(message) {
- // Make sure the socket is ready to go before sending a message.
- goog.asserts.assert(this.isOpen(), 'Cannot send without an open socket');
-
- // Send the message and let onError_ be called if it fails thereafter.
- this.webSocket_.send(message);
-};
-
-
-/**
- * Checks to see if the web socket is open or not.
- *
- * @return {boolean} True if the web socket is open, false otherwise.
- */
-goog.net.WebSocket.prototype.isOpen = function() {
- return !!this.webSocket_ &&
- this.webSocket_.readyState == goog.net.WebSocket.ReadyState_.OPEN;
-};
-
-
-/**
- * Called when the web socket has connected.
- *
- * @private
- */
-goog.net.WebSocket.prototype.onOpen_ = function() {
- this.logger_.info('WebSocket opened on ' + this.url_);
- this.dispatchEvent(goog.net.WebSocket.EventType.OPENED);
-
- // Set the next reconnect interval.
- this.reconnectAttempt_ = 0;
- this.nextReconnect_ = this.getNextReconnect_(this.reconnectAttempt_);
-};
-
-
-/**
- * Called when the web socket has closed.
- *
- * @param {!Event} event The close event.
- * @private
- */
-goog.net.WebSocket.prototype.onClose_ = function(event) {
- this.logger_.info('The WebSocket on ' + this.url_ + ' closed.');
-
- // Firing this event allows handlers to query the URL.
- this.dispatchEvent(goog.net.WebSocket.EventType.CLOSED);
-
- // Always clear out the web socket on a close event.
- this.webSocket_ = null;
-
- // See if this is an expected call to onClose_.
- if (this.closeExpected_) {
- this.logger_.info('The WebSocket closed normally.');
- // Only clear out the URL if this is a normal close.
- this.url_ = null;
- this.protocol_ = undefined;
- } else {
- // Unexpected, so try to reconnect.
- this.logger_.severe('The WebSocket disconnected unexpectedly: ' +
- event.data);
-
- // Only try to reconnect if it is enabled.
- if (this.autoReconnect_) {
- // Log the reconnect attempt.
- var seconds = Math.floor(this.nextReconnect_ / 1000);
- this.logger_.info('Seconds until next reconnect attempt: ' + seconds);
-
- // Actually schedule the timer.
- this.reconnectTimer_ = goog.Timer.callOnce(
- goog.bind(this.open, this, this.url_, this.protocol_),
- this.nextReconnect_, this);
-
- // Set the next reconnect interval.
- this.reconnectAttempt_++;
- this.nextReconnect_ = this.getNextReconnect_(this.reconnectAttempt_);
- }
- }
- this.closeExpected_ = false;
-};
-
-
-/**
- * Called when a new message arrives from the server.
- *
- * @param {MessageEvent} event The web socket message event.
- * @private
- */
-goog.net.WebSocket.prototype.onMessage_ = function(event) {
- var message = /** @type {string} */ (event.data);
- this.dispatchEvent(new goog.net.WebSocket.MessageEvent(message));
-};
-
-
-/**
- * Called when there is any error in communication.
- *
- * @param {Event} event The error event containing the error data.
- * @private
- */
-goog.net.WebSocket.prototype.onError_ = function(event) {
- var data = /** @type {string} */ event.data;
- this.logger_.severe('An error occurred: ' + data);
- this.dispatchEvent(new goog.net.WebSocket.ErrorEvent(data));
-};
-
-
-/**
- * Clears the reconnect timer.
- *
- * @private
- */
-goog.net.WebSocket.prototype.clearReconnectTimer_ = function() {
- if (goog.isDefAndNotNull(this.reconnectTimer_)) {
- goog.Timer.clear(this.reconnectTimer_);
- }
- this.reconnectTimer_ = null;
-};
-
-
-/** @override */
-goog.net.WebSocket.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
- this.close();
-};
-
-
-
-/**
- * Object representing a new incoming message event.
- *
- * @param {string} message The raw message coming from the web socket.
- * @extends {goog.events.Event}
- * @constructor
- */
-goog.net.WebSocket.MessageEvent = function(message) {
- goog.base(this, goog.net.WebSocket.EventType.MESSAGE);
-
- /**
- * The new message from the web socket.
- * @type {string}
- */
- this.message = message;
-};
-goog.inherits(goog.net.WebSocket.MessageEvent, goog.events.Event);
-
-
-
-/**
- * Object representing an error event. This is fired whenever an error occurs
- * on the web socket.
- *
- * @param {string} data The error data.
- * @extends {goog.events.Event}
- * @constructor
- */
-goog.net.WebSocket.ErrorEvent = function(data) {
- goog.base(this, goog.net.WebSocket.EventType.ERROR);
-
- /**
- * The error data coming from the web socket.
- * @type {string}
- */
- this.data = data;
-};
-goog.inherits(goog.net.WebSocket.ErrorEvent, goog.events.Event);
-
-
-// Register the WebSocket as an entry point, so that it can be monitored for
-// exception handling, etc.
-goog.debug.entryPointRegistry.register(
- /**
- * @param {function(!Function): !Function} transformer The transforming
- * function.
- */
- function(transformer) {
- goog.net.WebSocket.prototype.onOpen_ =
- transformer(goog.net.WebSocket.prototype.onOpen_);
- goog.net.WebSocket.prototype.onClose_ =
- transformer(goog.net.WebSocket.prototype.onClose_);
- goog.net.WebSocket.prototype.onMessage_ =
- transformer(goog.net.WebSocket.prototype.onMessage_);
- goog.net.WebSocket.prototype.onError_ =
- transformer(goog.net.WebSocket.prototype.onError_);
- });
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket_test.html.svn-base
deleted file mode 100644
index 4901830..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/websocket_test.html.svn-base
+++ /dev/null
@@ -1,367 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2011 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.WebSocket</title>
-<script type="text/javascript" src="../base.js"></script>
-<script type="text/javascript">
- goog.require('goog.debug.EntryPointMonitor');
- goog.require('goog.debug.ErrorHandler');
- goog.require('goog.debug.entryPointRegistry');
- goog.require('goog.events');
- goog.require('goog.functions');
- goog.require('goog.net.WebSocket');
- goog.require('goog.net.WebSocket.EventType');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.PropertyReplacer');
- goog.require('goog.testing.jsunit');
- goog.require('goog.testing.recordFunction');
-</script>
-</head>
-<body>
-
-<!-- Define unit tests. -->
-<script type="text/javascript" >
-
-var webSocket;
-var mockClock;
-var pr;
-var testUrl;
-
-var originalOnOpen = goog.net.WebSocket.prototype.onOpen_;
-var originalOnClose = goog.net.WebSocket.prototype.onClose_;
-var originalOnMessage = goog.net.WebSocket.prototype.onMessage_;
-var originalOnError = goog.net.WebSocket.prototype.onError_;
-
-function setUp() {
- pr = new goog.testing.PropertyReplacer();
- pr.set(goog.global, 'WebSocket', MockWebSocket);
- mockClock = new goog.testing.MockClock(true);
- testUrl = 'ws://127.0.0.1:4200';
- testProtocol = 'xmpp';
-}
-
-function tearDown() {
- pr.reset();
- goog.net.WebSocket.prototype.onOpen_ = originalOnOpen;
- goog.net.WebSocket.prototype.onClose_ = originalOnClose;
- goog.net.WebSocket.prototype.onMessage_ = originalOnMessage;
- goog.net.WebSocket.prototype.onError_ = originalOnError;
- goog.dispose(mockClock);
- goog.dispose(webSocket);
-}
-
-function testOpenInUnsupportingBrowserThrowsException() {
- // Null out WebSocket to simulate lack of support.
- if (goog.global.WebSocket) {
- goog.global.WebSocket = null;
- }
-
- webSocket = new goog.net.WebSocket();
- assertThrows('Open should fail if WebSocket is not defined.',
- function() {
- webSocket.open(testUrl);
- });
-}
-
-function testOpenTwiceThrowsException() {
- webSocket = new goog.net.WebSocket();
- webSocket.open(testUrl);
- simulateOpenEvent(webSocket.webSocket_);
-
- assertThrows('Attempting to open a second time should fail.',
- function() {
- webSocket.open(testUrl);
- });
-}
-
-function testSendWithoutOpeningThrowsException() {
- webSocket = new goog.net.WebSocket();
-
- assertThrows('Send should fail if the web socket was not first opened.',
- function() {
- webSocket.send('test message');
- });
-}
-
-function testOpenWithProtocol() {
- webSocket = new goog.net.WebSocket();
- webSocket.open(testUrl, testProtocol);
- var ws = webSocket.webSocket_;
- simulateOpenEvent(ws);
- assertEquals(testUrl, ws.url);
- assertEquals(testProtocol, ws.protocol);
-}
-
-function testOpenAndClose() {
- webSocket = new goog.net.WebSocket();
- assertFalse(webSocket.isOpen());
- webSocket.open(testUrl);
- var ws = webSocket.webSocket_;
- simulateOpenEvent(ws);
- assertTrue(webSocket.isOpen());
- assertEquals(testUrl, ws.url);
- webSocket.close();
- simulateCloseEvent(ws);
- assertFalse(webSocket.isOpen());
-}
-
-function testReconnectionDisabled() {
- // Construct the web socket and disable reconnection.
- webSocket = new goog.net.WebSocket(false);
-
- // Record how many times open is called.
- pr.set(webSocket, 'open', goog.testing.recordFunction(webSocket.open));
-
- // Open the web socket.
- webSocket.open(testUrl);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
- assertFalse(webSocket.isOpen());
-
- // Simulate failure.
- var ws = webSocket.webSocket_;
- simulateCloseEvent(ws);
- assertFalse(webSocket.isOpen());
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
-
- // Make sure a reconnection doesn't happen.
- mockClock.tick(100000);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
-}
-
-function testReconnectionWithFailureOnFirstOpen() {
- // Construct the web socket with a linear back-off.
- webSocket = new goog.net.WebSocket(true, linearBackOff);
-
- // Record how many times open is called.
- pr.set(webSocket, 'open', goog.testing.recordFunction(webSocket.open));
-
- // Open the web socket.
- webSocket.open(testUrl, testProtocol);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
- assertFalse(webSocket.isOpen());
-
- // Simulate failure.
- var ws = webSocket.webSocket_;
- simulateCloseEvent(ws);
- assertFalse(webSocket.isOpen());
- assertEquals(1, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
-
- // Make sure the reconnect doesn't happen before it should.
- mockClock.tick(linearBackOff(0) - 1);
- assertEquals(1, webSocket.open.getCallCount());
- mockClock.tick(1);
- assertEquals(2, webSocket.open.getCallCount());
-
- // Simulate another failure.
- simulateCloseEvent(ws);
- assertFalse(webSocket.isOpen());
- assertEquals(2, webSocket.reconnectAttempt_);
- assertEquals(2, webSocket.open.getCallCount());
-
- // Make sure the reconnect doesn't happen before it should.
- mockClock.tick(linearBackOff(1) - 1);
- assertEquals(2, webSocket.open.getCallCount());
- mockClock.tick(1);
- assertEquals(3, webSocket.open.getCallCount());
-
- // Simulate connection success.
- simulateOpenEvent(ws);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(3, webSocket.open.getCallCount());
-
- // Make sure the reconnection has the same url and protocol.
- assertEquals(testUrl, ws.url);
- assertEquals(testProtocol, ws.protocol);
-
- // Ensure no further calls to open are made.
- mockClock.tick(linearBackOff(10));
- assertEquals(3, webSocket.open.getCallCount());
-}
-
-function testReconnectionWithFailureAfterOpen() {
- // Construct the web socket with a linear back-off.
- webSocket = new goog.net.WebSocket(true, fibonacciBackOff);
-
- // Record how many times open is called.
- pr.set(webSocket, 'open', goog.testing.recordFunction(webSocket.open));
-
- // Open the web socket.
- webSocket.open(testUrl);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
- assertFalse(webSocket.isOpen());
-
- // Simulate connection success.
- var ws = webSocket.webSocket_;
- simulateOpenEvent(ws);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
-
- // Let some time pass, then fail the connection.
- mockClock.tick(100000);
- simulateCloseEvent(ws);
- assertFalse(webSocket.isOpen());
- assertEquals(1, webSocket.reconnectAttempt_);
- assertEquals(1, webSocket.open.getCallCount());
-
- // Make sure the reconnect doesn't happen before it should.
- mockClock.tick(fibonacciBackOff(0) - 1);
- assertEquals(1, webSocket.open.getCallCount());
- mockClock.tick(1);
- assertEquals(2, webSocket.open.getCallCount());
-
- // Simulate connection success.
- ws = webSocket.webSocket_;
- simulateOpenEvent(ws);
- assertEquals(0, webSocket.reconnectAttempt_);
- assertEquals(2, webSocket.open.getCallCount());
-
- // Ensure no further calls to open are made.
- mockClock.tick(fibonacciBackOff(10));
- assertEquals(2, webSocket.open.getCallCount());
-}
-
-function testExponentialBackOff() {
- assertEquals(1000, goog.net.WebSocket.EXPONENTIAL_BACKOFF_(0));
- assertEquals(2000, goog.net.WebSocket.EXPONENTIAL_BACKOFF_(1));
- assertEquals(4000, goog.net.WebSocket.EXPONENTIAL_BACKOFF_(2));
- assertEquals(60000, goog.net.WebSocket.EXPONENTIAL_BACKOFF_(6));
- assertEquals(60000, goog.net.WebSocket.EXPONENTIAL_BACKOFF_(7));
-}
-
-function testEntryPointRegistry() {
- var monitor = new goog.debug.EntryPointMonitor();
- var replacement = function() {};
- monitor.wrap = goog.testing.recordFunction(
- goog.functions.constant(replacement));
-
- goog.debug.entryPointRegistry.monitorAll(monitor);
- assertTrue(monitor.wrap.getCallCount() >= 1);
- assertEquals(replacement, goog.net.WebSocket.prototype.onOpen_);
- assertEquals(replacement, goog.net.WebSocket.prototype.onClose_);
- assertEquals(replacement, goog.net.WebSocket.prototype.onMessage_);
- assertEquals(replacement, goog.net.WebSocket.prototype.onError_);
-}
-
-function testErrorHandlerCalled() {
- var errorHandlerCalled = false;
- var errorHandler = new goog.debug.ErrorHandler(function() {
- errorHandlerCalled = true;
- });
- goog.net.WebSocket.protectEntryPoints(errorHandler);
-
- webSocket = new goog.net.WebSocket();
- goog.events.listenOnce(webSocket, goog.net.WebSocket.EventType.OPENED,
- function() {
- throw Error();
- });
-
- webSocket.open(testUrl);
- var ws = webSocket.webSocket_;
- assertThrows(function() {
- simulateOpenEvent(ws);
- });
-
- assertTrue('Error handler callback should be called when registered as ' +
- 'protecting the entry points.', errorHandlerCalled);
-}
-
-/**
- * Simulates the browser firing the open event for the given web socket.
- * @param {MockWebSocket} ws The mock web socket.
- */
-function simulateOpenEvent(ws) {
- ws.readyState = goog.net.WebSocket.ReadyState_.OPEN;
- ws.onopen();
-}
-
-/**
- * Simulates the browser firing the close event for the given web socket.
- * @param {MockWebSocket} ws The mock web socket.
- */
-function simulateCloseEvent(ws) {
- ws.readyState = goog.net.WebSocket.ReadyState_.CLOSED;
- ws.onclose({data: 'mock close event'});
-}
-
-/**
- * Strategy for reconnection that backs off linearly with a 1 second offset.
- * @param {number} attempt The number of reconnects since the last connection.
- * @return {number} The amount of time to the next reconnect, in milliseconds.
- */
-function linearBackOff(attempt) {
- return (attempt * 1000) + 1000;
-}
-
-/**
- * Strategy for reconnection that backs off with the fibonacci pattern. It is
- * offset by 5 seconds so the first attempt will happen after 5 seconds.
- * @param {number} attempt The number of reconnects since the last connection.
- * @return {number} The amount of time to the next reconnect, in milliseconds.
- */
-function fibonacciBackOff(attempt) {
- return (fibonacci(attempt) * 1000) + 5000;
-}
-
-/**
- * Computes the desired fibonacci number.
- * @param {number} n The nth desired fibonacci number.
- * @return {number} The nth fibonacci number.
- */
-function fibonacci(n) {
- if (n == 0) {
- return 0;
- } else if (n == 1) {
- return 1;
- } else {
- return fibonacci(n - 2) + fibonacci(n - 1);
- }
-}
-
-
-
-/**
- * Mock WebSocket constructor.
- * @param {string} url The url to the web socket server.
- * @param {string} protocol The protocol to use.
- * @constructor
- */
-MockWebSocket = function(url, protocol) {
- this.url = url;
- this.protocol = protocol;
- this.readyState = goog.net.WebSocket.ReadyState_.CONNECTING;
-};
-
-
-/**
- * Mocks out the close method of the WebSocket.
- */
-MockWebSocket.prototype.close = function() {
- this.readyState = goog.net.WebSocket.ReadyState_.CLOSING;
-};
-
-
-/**
- * Mocks out the send method of the WebSocket.
- */
-MockWebSocket.prototype.send = function() {
- // Nothing to do here.
-};
-
-</script>
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/wrapperxmlhttpfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/wrapperxmlhttpfactory.js.svn-base
deleted file mode 100644
index 2a0a159..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/wrapperxmlhttpfactory.js.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2010 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Implementation of XmlHttpFactory which allows construction from
- * simple factory methods.
- * @author dbk@google.com (David Barrett-Kahn)
- */
-
-goog.provide('goog.net.WrapperXmlHttpFactory');
-
-goog.require('goog.net.XmlHttpFactory');
-
-
-
-/**
- * An xhr factory subclass which can be constructed using two factory methods.
- * This exists partly to allow the preservation of goog.net.XmlHttp.setFactory()
- * with an unchanged signature.
- * @param {function() : !(XMLHttpRequest|GearsHttpRequest)} xhrFactory A
- * function which returns a new XHR object.
- * @param {function() : !Object} optionsFactory A function which returns the
- * options associated with xhr objects from this factory.
- * @extends {goog.net.XmlHttpFactory}
- * @constructor
- */
-goog.net.WrapperXmlHttpFactory = function(xhrFactory, optionsFactory) {
- goog.net.XmlHttpFactory.call(this);
-
- /**
- * XHR factory method.
- * @type {function() : !(XMLHttpRequest|GearsHttpRequest)}
- * @private
- */
- this.xhrFactory_ = xhrFactory;
-
- /**
- * Options factory method.
- * @type {function() : !Object}
- * @private
- */
- this.optionsFactory_ = optionsFactory;
-};
-goog.inherits(goog.net.WrapperXmlHttpFactory, goog.net.XmlHttpFactory);
-
-
-/** @override */
-goog.net.WrapperXmlHttpFactory.prototype.createInstance = function() {
- return this.xhrFactory_();
-};
-
-
-/** @override */
-goog.net.WrapperXmlHttpFactory.prototype.getOptions = function() {
- return this.optionsFactory_();
-};
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio.js.svn-base
deleted file mode 100644
index 09e30fa..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio.js.svn-base
+++ /dev/null
@@ -1,1082 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Wrapper class for handling XmlHttpRequests.
- *
- * One off requests can be sent through goog.net.XhrIo.send() or an
- * instance can be created to send multiple requests. Each request uses its
- * own XmlHttpRequest object and handles clearing of the event callback to
- * ensure no leaks.
- *
- * XhrIo is event based, it dispatches events when a request finishes, fails or
- * succeeds or when the ready-state changes. The ready-state or timeout event
- * fires first, followed by a generic completed event. Then the abort, error,
- * or success event is fired as appropriate. Lastly, the ready event will fire
- * to indicate that the object may be used to make another request.
- *
- * The error event may also be called before completed and
- * ready-state-change if the XmlHttpRequest.open() or .send() methods throw.
- *
- * This class does not support multiple requests, queuing, or prioritization.
- *
- * Tested = IE6, FF1.5, Safari, Opera 8.5
- *
- * TODO(user): Error cases aren't playing nicely in Safari.
- *
- */
-
-
-goog.provide('goog.net.XhrIo');
-goog.provide('goog.net.XhrIo.ResponseType');
-
-goog.require('goog.Timer');
-goog.require('goog.debug.Logger');
-goog.require('goog.debug.entryPointRegistry');
-goog.require('goog.debug.errorHandlerWeakDep');
-goog.require('goog.events.EventTarget');
-goog.require('goog.json');
-goog.require('goog.net.ErrorCode');
-goog.require('goog.net.EventType');
-goog.require('goog.net.HttpStatus');
-goog.require('goog.net.XmlHttp');
-goog.require('goog.object');
-goog.require('goog.structs');
-goog.require('goog.structs.Map');
-goog.require('goog.uri.utils');
-
-
-
-/**
- * Basic class for handling XMLHttpRequests.
- * @param {goog.net.XmlHttpFactory=} opt_xmlHttpFactory Factory to use when
- * creating XMLHttpRequest objects.
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.XhrIo = function(opt_xmlHttpFactory) {
- goog.events.EventTarget.call(this);
-
- /**
- * Map of default headers to add to every request, use:
- * XhrIo.headers.set(name, value)
- * @type {goog.structs.Map}
- */
- this.headers = new goog.structs.Map();
-
- /**
- * Optional XmlHttpFactory
- * @type {goog.net.XmlHttpFactory}
- * @private
- */
- this.xmlHttpFactory_ = opt_xmlHttpFactory || null;
-};
-goog.inherits(goog.net.XhrIo, goog.events.EventTarget);
-
-
-/**
- * Response types that may be requested for XMLHttpRequests.
- * @enum {string}
- * @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute
- */
-goog.net.XhrIo.ResponseType = {
- DEFAULT: '',
- TEXT: 'text',
- DOCUMENT: 'document',
- // Not supported as of Chrome 10.0.612.1 dev
- BLOB: 'blob',
- ARRAY_BUFFER: 'arraybuffer'
-};
-
-
-/**
- * A reference to the XhrIo logger
- * @type {goog.debug.Logger}
- * @private
- */
-goog.net.XhrIo.prototype.logger_ =
- goog.debug.Logger.getLogger('goog.net.XhrIo');
-
-
-/**
- * The Content-Type HTTP header name
- * @type {string}
- */
-goog.net.XhrIo.CONTENT_TYPE_HEADER = 'Content-Type';
-
-
-/**
- * The pattern matching the 'http' and 'https' URI schemes
- * @type {!RegExp}
- */
-goog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i;
-
-
-/**
- * The Content-Type HTTP header value for a url-encoded form
- * @type {string}
- */
-goog.net.XhrIo.FORM_CONTENT_TYPE =
- 'application/x-www-form-urlencoded;charset=utf-8';
-
-
-/**
- * All non-disposed instances of goog.net.XhrIo created
- * by {@link goog.net.XhrIo.send} are in this Array.
- * @see goog.net.XhrIo.cleanup
- * @type {Array.<goog.net.XhrIo>}
- * @private
- */
-goog.net.XhrIo.sendInstances_ = [];
-
-
-/**
- * Static send that creates a short lived instance of XhrIo to send the
- * request.
- * @see goog.net.XhrIo.cleanup
- * @param {string|goog.Uri} url Uri to make request to.
- * @param {Function=} opt_callback Callback function for when request is
- * complete.
- * @param {string=} opt_method Send method, default: GET.
- * @param {string|GearsBlob=} opt_content Post data. This can be a Gears blob
- * if the underlying HTTP request object is a Gears HTTP request.
- * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
- * request.
- * @param {number=} opt_timeoutInterval Number of milliseconds after which an
- * incomplete request will be aborted; 0 means no timeout is set.
- */
-goog.net.XhrIo.send = function(url, opt_callback, opt_method, opt_content,
- opt_headers, opt_timeoutInterval) {
- var x = new goog.net.XhrIo();
- goog.net.XhrIo.sendInstances_.push(x);
- if (opt_callback) {
- goog.events.listen(x, goog.net.EventType.COMPLETE, opt_callback);
- }
- goog.events.listen(x,
- goog.net.EventType.READY,
- goog.partial(goog.net.XhrIo.cleanupSend_, x));
- if (opt_timeoutInterval) {
- x.setTimeoutInterval(opt_timeoutInterval);
- }
- x.send(url, opt_method, opt_content, opt_headers);
-};
-
-
-/**
- * Disposes all non-disposed instances of goog.net.XhrIo created by
- * {@link goog.net.XhrIo.send}.
- * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance
- * it creates when the request completes or fails. However, if
- * the request never completes, then the goog.net.XhrIo is not disposed.
- * This can occur if the window is unloaded before the request completes.
- * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo
- * it creates and make the client of {@link goog.net.XhrIo.send} be
- * responsible for disposing it in this case. However, this makes things
- * significantly more complicated for the client, and the whole point
- * of {@link goog.net.XhrIo.send} is that it's simple and easy to use.
- * Clients of {@link goog.net.XhrIo.send} should call
- * {@link goog.net.XhrIo.cleanup} when doing final
- * cleanup on window unload.
- */
-goog.net.XhrIo.cleanup = function() {
- var instances = goog.net.XhrIo.sendInstances_;
- while (instances.length) {
- instances.pop().dispose();
- }
-};
-
-
-/**
- * Installs exception protection for all entry point introduced by
- * goog.net.XhrIo instances which are not protected by
- * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},
- * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or
- * {@link goog.events.protectBrowserEventEntryPoint}.
- *
- * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to
- * protect the entry point(s).
- */
-goog.net.XhrIo.protectEntryPoints = function(errorHandler) {
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =
- errorHandler.protectEntryPoint(
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);
-};
-
-
-/**
- * Disposes of the specified goog.net.XhrIo created by
- * {@link goog.net.XhrIo.send} and removes it from
- * {@link goog.net.XhrIo.pendingStaticSendInstances_}.
- * @param {goog.net.XhrIo} XhrIo An XhrIo created by
- * {@link goog.net.XhrIo.send}.
- * @private
- */
-goog.net.XhrIo.cleanupSend_ = function(XhrIo) {
- XhrIo.dispose();
- goog.array.remove(goog.net.XhrIo.sendInstances_, XhrIo);
-};
-
-
-/**
- * Whether XMLHttpRequest is active. A request is active from the time send()
- * is called until onReadyStateChange() is complete, or error() or abort()
- * is called.
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.active_ = false;
-
-
-/**
- * Reference to an XMLHttpRequest object that is being used for the transfer.
- * @type {XMLHttpRequest|GearsHttpRequest}
- * @private
- */
-goog.net.XhrIo.prototype.xhr_ = null;
-
-
-/**
- * The options to use with the current XMLHttpRequest object.
- * @type {Object}
- * @private
- */
-goog.net.XhrIo.prototype.xhrOptions_ = null;
-
-
-/**
- * Last URL that was requested.
- * @type {string|goog.Uri}
- * @private
- */
-goog.net.XhrIo.prototype.lastUri_ = '';
-
-
-/**
- * Method for the last request.
- * @type {string}
- * @private
- */
-goog.net.XhrIo.prototype.lastMethod_ = '';
-
-
-/**
- * Last error code.
- * @type {goog.net.ErrorCode}
- * @private
- */
-goog.net.XhrIo.prototype.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
-
-
-/**
- * Last error message.
- * @type {Error|string}
- * @private
- */
-goog.net.XhrIo.prototype.lastError_ = '';
-
-
-/**
- * This is used to ensure that we don't dispatch an multiple ERROR events. This
- * can happen in IE when it does a synchronous load and one error is handled in
- * the ready statte change and one is handled due to send() throwing an
- * exception.
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.errorDispatched_ = false;
-
-
-/**
- * Used to make sure we don't fire the complete event from inside a send call.
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.inSend_ = false;
-
-
-/**
- * Used in determining if a call to {@link #onReadyStateChange_} is from within
- * a call to this.xhr_.open.
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.inOpen_ = false;
-
-
-/**
- * Used in determining if a call to {@link #onReadyStateChange_} is from within
- * a call to this.xhr_.abort.
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.inAbort_ = false;
-
-
-/**
- * Number of milliseconds after which an incomplete request will be aborted and
- * a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout is set.
- * @type {number}
- * @private
- */
-goog.net.XhrIo.prototype.timeoutInterval_ = 0;
-
-
-/**
- * Window timeout ID used to cancel the timeout event handler if the request
- * completes successfully.
- * @type {Object}
- * @private
- */
-goog.net.XhrIo.prototype.timeoutId_ = null;
-
-
-/**
- * The requested type for the response. The empty string means use the default
- * XHR behavior.
- * @type {goog.net.XhrIo.ResponseType}
- * @private
- */
-goog.net.XhrIo.prototype.responseType_ = goog.net.XhrIo.ResponseType.DEFAULT;
-
-
-/**
- * Whether a "credentialed" request is to be sent (one that is aware of cookies
- * and authentication) . This is applicable only for cross-domain requests and
- * more recent browsers that support this part of the HTTP Access Control
- * standard.
- *
- * @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#withcredentials
- *
- * @type {boolean}
- * @private
- */
-goog.net.XhrIo.prototype.withCredentials_ = false;
-
-
-/**
- * Returns the number of milliseconds after which an incomplete request will be
- * aborted, or 0 if no timeout is set.
- * @return {number} Timeout interval in milliseconds.
- */
-goog.net.XhrIo.prototype.getTimeoutInterval = function() {
- return this.timeoutInterval_;
-};
-
-
-/**
- * Sets the number of milliseconds after which an incomplete request will be
- * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no
- * timeout is set.
- * @param {number} ms Timeout interval in milliseconds; 0 means none.
- */
-goog.net.XhrIo.prototype.setTimeoutInterval = function(ms) {
- this.timeoutInterval_ = Math.max(0, ms);
-};
-
-
-/**
- * Sets the desired type for the response. At time of writing, this is only
- * supported in very recent versions of WebKit (10.0.612.1 dev and later).
- *
- * If this is used, the response may only be accessed via {@link #getResponse}.
- *
- * @param {goog.net.XhrIo.ResponseType} type The desired type for the response.
- */
-goog.net.XhrIo.prototype.setResponseType = function(type) {
- this.responseType_ = type;
-};
-
-
-/**
- * Gets the desired type for the response.
- * @return {goog.net.XhrIo.ResponseType} The desired type for the response.
- */
-goog.net.XhrIo.prototype.getResponseType = function() {
- return this.responseType_;
-};
-
-
-/**
- * Sets whether a "credentialed" request that is aware of cookie and
- * authentication information should be made. This option is only supported by
- * browsers that support HTTP Access Control. As of this writing, this option
- * is not supported in IE.
- *
- * @param {boolean} withCredentials Whether this should be a "credentialed"
- * request.
- */
-goog.net.XhrIo.prototype.setWithCredentials = function(withCredentials) {
- this.withCredentials_ = withCredentials;
-};
-
-
-/**
- * Gets whether a "credentialed" request is to be sent.
- * @return {boolean} The desired type for the response.
- */
-goog.net.XhrIo.prototype.getWithCredentials = function() {
- return this.withCredentials_;
-};
-
-
-/**
- * Instance send that actually uses XMLHttpRequest to make a server call.
- * @param {string|goog.Uri} url Uri to make request to.
- * @param {string=} opt_method Send method, default: GET.
- * @param {string|GearsBlob=} opt_content Post data. This can be a Gears blob
- * if the underlying HTTP request object is a Gears HTTP request.
- * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
- * request.
- */
-goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content,
- opt_headers) {
- if (this.xhr_) {
- throw Error('[goog.net.XhrIo] Object is active with another request');
- }
-
- var method = opt_method ? opt_method.toUpperCase() : 'GET';
-
- this.lastUri_ = url;
- this.lastError_ = '';
- this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR;
- this.lastMethod_ = method;
- this.errorDispatched_ = false;
- this.active_ = true;
-
- // Use the factory to create the XHR object and options
- this.xhr_ = this.createXhr();
- this.xhrOptions_ = this.xmlHttpFactory_ ?
- this.xmlHttpFactory_.getOptions() : goog.net.XmlHttp.getOptions();
-
- // Set up the onreadystatechange callback
- this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this);
-
- /**
- * Try to open the XMLHttpRequest (always async), if an error occurs here it
- * is generally permission denied
- * @preserveTry
- */
- try {
- this.logger_.fine(this.formatMsg_('Opening Xhr'));
- this.inOpen_ = true;
- this.xhr_.open(method, url, true); // Always async!
- this.inOpen_ = false;
- } catch (err) {
- this.logger_.fine(this.formatMsg_('Error opening Xhr: ' + err.message));
- this.error_(goog.net.ErrorCode.EXCEPTION, err);
- return;
- }
-
- // We can't use null since this won't allow POSTs to have a content length
- // specified which will cause some proxies to return a 411 error.
- var content = opt_content || '';
-
- var headers = this.headers.clone();
-
- // Add headers specific to this request
- if (opt_headers) {
- goog.structs.forEach(opt_headers, function(value, key) {
- headers.set(key, value);
- });
- }
-
- if (method == 'POST' &&
- !headers.containsKey(goog.net.XhrIo.CONTENT_TYPE_HEADER)) {
- // For POST requests, default to the url-encoded form content type.
- headers.set(goog.net.XhrIo.CONTENT_TYPE_HEADER,
- goog.net.XhrIo.FORM_CONTENT_TYPE);
- }
-
- // Add the headers to the Xhr object
- goog.structs.forEach(headers, function(value, key) {
- this.xhr_.setRequestHeader(key, value);
- }, this);
-
- if (this.responseType_) {
- this.xhr_.responseType = this.responseType_;
- }
-
- if (goog.object.containsKey(this.xhr_, 'withCredentials')) {
- this.xhr_.withCredentials = this.withCredentials_;
- }
-
- /**
- * Try to send the request, or other wise report an error (404 not found).
- * @preserveTry
- */
- try {
- if (this.timeoutId_) {
- // This should never happen, since the if (this.active_) above shouldn't
- // let execution reach this point if there is a request in progress...
- goog.Timer.defaultTimerObject.clearTimeout(this.timeoutId_);
- this.timeoutId_ = null;
- }
- if (this.timeoutInterval_ > 0) {
- this.logger_.fine(this.formatMsg_('Will abort after ' +
- this.timeoutInterval_ + 'ms if incomplete'));
- this.timeoutId_ = goog.Timer.defaultTimerObject.setTimeout(
- goog.bind(this.timeout_, this), this.timeoutInterval_);
- }
- this.logger_.fine(this.formatMsg_('Sending request'));
- this.inSend_ = true;
- this.xhr_.send(content);
- this.inSend_ = false;
-
- } catch (err) {
- this.logger_.fine(this.formatMsg_('Send error: ' + err.message));
- this.error_(goog.net.ErrorCode.EXCEPTION, err);
- }
-};
-
-
-/**
- * Creates a new XHR object.
- * @return {XMLHttpRequest|GearsHttpRequest} The newly created XHR object.
- * @protected
- */
-goog.net.XhrIo.prototype.createXhr = function() {
- return this.xmlHttpFactory_ ?
- this.xmlHttpFactory_.createInstance() : goog.net.XmlHttp();
-};
-
-
-/**
- * The request didn't complete after {@link goog.net.XhrIo#timeoutInterval_}
- * milliseconds; raises a {@link goog.net.EventType.TIMEOUT} event and aborts
- * the request.
- * @private
- */
-goog.net.XhrIo.prototype.timeout_ = function() {
- if (typeof goog == 'undefined') {
- // If goog is undefined then the callback has occurred as the application
- // is unloading and will error. Thus we let it silently fail.
- } else if (this.xhr_) {
- this.lastError_ = 'Timed out after ' + this.timeoutInterval_ +
- 'ms, aborting';
- this.lastErrorCode_ = goog.net.ErrorCode.TIMEOUT;
- this.logger_.fine(this.formatMsg_(this.lastError_));
- this.dispatchEvent(goog.net.EventType.TIMEOUT);
- this.abort(goog.net.ErrorCode.TIMEOUT);
- }
-};
-
-
-/**
- * Something errorred, so inactivate, fire error callback and clean up
- * @param {goog.net.ErrorCode} errorCode The error code.
- * @param {Error} err The error object.
- * @private
- */
-goog.net.XhrIo.prototype.error_ = function(errorCode, err) {
- this.active_ = false;
- if (this.xhr_) {
- this.inAbort_ = true;
- this.xhr_.abort(); // Ensures XHR isn't hung (FF)
- this.inAbort_ = false;
- }
- this.lastError_ = err;
- this.lastErrorCode_ = errorCode;
- this.dispatchErrors_();
- this.cleanUpXhr_();
-};
-
-
-/**
- * Dispatches COMPLETE and ERROR in case of an error. This ensures that we do
- * not dispatch multiple error events.
- * @private
- */
-goog.net.XhrIo.prototype.dispatchErrors_ = function() {
- if (!this.errorDispatched_) {
- this.errorDispatched_ = true;
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.ERROR);
- }
-};
-
-
-/**
- * Abort the current XMLHttpRequest
- * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use -
- * defaults to ABORT.
- */
-goog.net.XhrIo.prototype.abort = function(opt_failureCode) {
- if (this.xhr_ && this.active_) {
- this.logger_.fine(this.formatMsg_('Aborting'));
- this.active_ = false;
- this.inAbort_ = true;
- this.xhr_.abort();
- this.inAbort_ = false;
- this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT;
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.ABORT);
- this.cleanUpXhr_();
- }
-};
-
-
-/**
- * Nullifies all callbacks to reduce risks of leaks.
- * @override
- * @protected
- */
-goog.net.XhrIo.prototype.disposeInternal = function() {
- if (this.xhr_) {
- // We explicitly do not call xhr_.abort() unless active_ is still true.
- // This is to avoid unnecessarily aborting a successful request when
- // dispose() is called in a callback triggered by a complete response, but
- // in which browser cleanup has not yet finished.
- // (See http://b/issue?id=1684217.)
- if (this.active_) {
- this.active_ = false;
- this.inAbort_ = true;
- this.xhr_.abort();
- this.inAbort_ = false;
- }
- this.cleanUpXhr_(true);
- }
-
- goog.net.XhrIo.superClass_.disposeInternal.call(this);
-};
-
-
-/**
- * Internal handler for the XHR object's readystatechange event. This method
- * checks the status and the readystate and fires the correct callbacks.
- * If the request has ended, the handlers are cleaned up and the XHR object is
- * nullified.
- * @private
- */
-goog.net.XhrIo.prototype.onReadyStateChange_ = function() {
- if (!this.inOpen_ && !this.inSend_ && !this.inAbort_) {
- // Were not being called from within a call to this.xhr_.send
- // this.xhr_.abort, or this.xhr_.open, so this is an entry point
- this.onReadyStateChangeEntryPoint_();
- } else {
- this.onReadyStateChangeHelper_();
- }
-};
-
-
-/**
- * Used to protect the onreadystatechange handler entry point. Necessary
- * as {#onReadyStateChange_} maybe called from within send or abort, this
- * method is only called when {#onReadyStateChange_} is called as an
- * entry point.
- * {@see #protectEntryPoints}
- * @private
- */
-goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() {
- this.onReadyStateChangeHelper_();
-};
-
-
-/**
- * Helper for {@link #onReadyStateChange_}. This is used so that
- * entry point calls to {@link #onReadyStateChange_} can be routed through
- * {@link #onReadyStateChangeEntryPoint_}.
- * @private
- */
-goog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() {
- if (!this.active_) {
- // can get called inside abort call
- return;
- }
-
- if (typeof goog == 'undefined') {
- // NOTE(user): If goog is undefined then the callback has occurred as the
- // application is unloading and will error. Thus we let it silently fail.
-
- } else if (
- this.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] &&
- this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE &&
- this.getStatus() == 2) {
- // NOTE(user): In IE if send() errors on a *local* request the readystate
- // is still changed to COMPLETE. We need to ignore it and allow the
- // try/catch around send() to pick up the error.
- this.logger_.fine(this.formatMsg_(
- 'Local request error detected and ignored'));
-
- } else {
-
- // In IE when the response has been cached we sometimes get the callback
- // from inside the send call and this usually breaks code that assumes that
- // XhrIo is asynchronous. If that is the case we delay the callback
- // using a timer.
- if (this.inSend_ &&
- this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE) {
- goog.Timer.defaultTimerObject.setTimeout(
- goog.bind(this.onReadyStateChange_, this), 0);
- return;
- }
-
- this.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE);
-
- // readyState indicates the transfer has finished
- if (this.isComplete()) {
- this.logger_.fine(this.formatMsg_('Request complete'));
-
- this.active_ = false;
-
- // Call the specific callbacks for success or failure. Only call the
- // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)
- if (this.isSuccess()) {
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.SUCCESS);
- } else {
- this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;
- this.lastError_ = this.getStatusText() + ' [' + this.getStatus() + ']';
- this.dispatchErrors_();
- }
-
- this.cleanUpXhr_();
- }
- }
-};
-
-
-/**
- * Remove the listener to protect against leaks, and nullify the XMLHttpRequest
- * object.
- * @param {boolean=} opt_fromDispose If this is from the dispose (don't want to
- * fire any events).
- * @private
- */
-goog.net.XhrIo.prototype.cleanUpXhr_ = function(opt_fromDispose) {
- if (this.xhr_) {
- // Save reference so we can mark it as closed after the READY event. The
- // READY event may trigger another request, thus we must nullify this.xhr_
- var xhr = this.xhr_;
- var clearedOnReadyStateChange =
- this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ?
- goog.nullFunction : null;
- this.xhr_ = null;
- this.xhrOptions_ = null;
-
- if (this.timeoutId_) {
- // Cancel any pending timeout event handler.
- goog.Timer.defaultTimerObject.clearTimeout(this.timeoutId_);
- this.timeoutId_ = null;
- }
-
- if (!opt_fromDispose) {
- this.dispatchEvent(goog.net.EventType.READY);
- }
-
- try {
- // NOTE(user): Not nullifying in FireFox can still leak if the callbacks
- // are defined in the same scope as the instance of XhrIo. But, IE doesn't
- // allow you to set the onreadystatechange to NULL so nullFunction is
- // used.
- xhr.onreadystatechange = clearedOnReadyStateChange;
- } catch (e) {
- // This seems to occur with a Gears HTTP request. Delayed the setting of
- // this onreadystatechange until after READY is sent out and catching the
- // error to see if we can track down the problem.
- this.logger_.severe('Problem encountered resetting onreadystatechange: ' +
- e.message);
- }
- }
-};
-
-
-/**
- * @return {boolean} Whether there is an active request.
- */
-goog.net.XhrIo.prototype.isActive = function() {
- return !!this.xhr_;
-};
-
-
-/**
- * @return {boolean} Whether the request has completed.
- */
-goog.net.XhrIo.prototype.isComplete = function() {
- return this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE;
-};
-
-
-/**
- * @return {boolean} Whether the request completed with a success.
- */
-goog.net.XhrIo.prototype.isSuccess = function() {
- var status = this.getStatus();
- // A zero status code is considered successful for local files.
- return goog.net.HttpStatus.isSuccess(status) ||
- status === 0 && !this.isLastUriEffectiveSchemeHttp_();
-};
-
-
-/**
- * @return {boolean} whether the effective scheme of the last URI that was
- * fetched was 'http' or 'https'.
- * @private
- */
-goog.net.XhrIo.prototype.isLastUriEffectiveSchemeHttp_ = function() {
- var scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_));
- return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme);
-};
-
-
-/**
- * Get the readystate from the Xhr object
- * Will only return correct result when called from the context of a callback
- * @return {goog.net.XmlHttp.ReadyState} goog.net.XmlHttp.ReadyState.*.
- */
-goog.net.XhrIo.prototype.getReadyState = function() {
- return this.xhr_ ?
- /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) :
- goog.net.XmlHttp.ReadyState.UNINITIALIZED;
-};
-
-
-/**
- * Get the status from the Xhr object
- * Will only return correct result when called from the context of a callback
- * @return {number} Http status.
- */
-goog.net.XhrIo.prototype.getStatus = function() {
- /**
- * IE doesn't like you checking status until the readystate is greater than 2
- * (i.e. it is recieving or complete). The try/catch is used for when the
- * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.
- * @preserveTry
- */
- try {
- return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?
- this.xhr_.status : -1;
- } catch (e) {
- this.logger_.warning('Can not get status: ' + e.message);
- return -1;
- }
-};
-
-
-/**
- * Get the status text from the Xhr object
- * Will only return correct result when called from the context of a callback
- * @return {string} Status text.
- */
-goog.net.XhrIo.prototype.getStatusText = function() {
- /**
- * IE doesn't like you checking status until the readystate is greater than 2
- * (i.e. it is recieving or complete). The try/catch is used for when the
- * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_.
- * @preserveTry
- */
- try {
- return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ?
- this.xhr_.statusText : '';
- } catch (e) {
- this.logger_.fine('Can not get status: ' + e.message);
- return '';
- }
-};
-
-
-/**
- * Get the last Uri that was requested
- * @return {string} Last Uri.
- */
-goog.net.XhrIo.prototype.getLastUri = function() {
- return String(this.lastUri_);
-};
-
-
-/**
- * Get the response text from the Xhr object
- * Will only return correct result when called from the context of a callback.
- * @return {string} Result from the server, or '' if no result available.
- */
-goog.net.XhrIo.prototype.getResponseText = function() {
- /** @preserveTry */
- try {
- return this.xhr_ ? this.xhr_.responseText : '';
- } catch (e) {
- // http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute
- // states that responseText should return '' (and responseXML null)
- // when the state is not LOADING or DONE. Instead, IE and Gears can
- // throw unexpected exceptions, eg, when a request is aborted or no
- // data is available yet.
- this.logger_.fine('Can not get responseText: ' + e.message);
- return '';
- }
-};
-
-
-/**
- * Get the response XML from the Xhr object
- * Will only return correct result when called from the context of a callback.
- * @return {Document} The DOM Document representing the XML file, or null
- * if no result available.
- */
-goog.net.XhrIo.prototype.getResponseXml = function() {
- /** @preserveTry */
- try {
- return this.xhr_ ? this.xhr_.responseXML : null;
- } catch (e) {
- this.logger_.fine('Can not get responseXML: ' + e.message);
- return null;
- }
-};
-
-
-/**
- * Get the response and evaluates it as JSON from the Xhr object
- * Will only return correct result when called from the context of a callback
- * @param {string=} opt_xssiPrefix Optional XSSI prefix string to use for
- * stripping of the response before parsing. This needs to be set only if
- * your backend server prepends the same prefix string to the JSON response.
- * @return {Object|undefined} JavaScript object.
- */
-goog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) {
- if (!this.xhr_) {
- return undefined;
- }
-
- var responseText = this.xhr_.responseText;
- if (opt_xssiPrefix && responseText.indexOf(opt_xssiPrefix) == 0) {
- responseText = responseText.substring(opt_xssiPrefix.length);
- }
-
- return goog.json.parse(responseText);
-};
-
-
-/**
- * Get the response as the type specificed by {@link #setResponseType}. At time
- * of writing, this is only directly supported in very recent versions of WebKit
- * (10.0.612.1 dev and later). If the field is not supported directly, we will
- * try to emulate it.
- *
- * Emulating the response means following the rules laid out at
- * http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-response-attribute.
- *
- * On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only
- * response types of DEFAULT or TEXT may be used, and the response returned will
- * be the text response.
- *
- * On browsers with Mozilla's draft support for array buffers (Firefox 4, 5),
- * only response types of DEFAULT, TEXT, and ARRAY_BUFFER may be used, and the
- * response returned will be either the text response or the Mozilla
- * implementation of the array buffer response.
- *
- * On browsers will full support, any valid response type supported by the
- * browser may be used, and the response provided by the browser will be
- * returned.
- *
- * @return {*} The response.
- */
-goog.net.XhrIo.prototype.getResponse = function() {
- /** @preserveTry */
- try {
- if (!this.xhr_) {
- return null;
- }
- if ('response' in this.xhr_) {
- return this.xhr_.response;
- }
- switch (this.responseType_) {
- case goog.net.XhrIo.ResponseType.DEFAULT:
- case goog.net.XhrIo.ResponseType.TEXT:
- return this.xhr_.responseText;
- // DOCUMENT and BLOB don't need to be handled here because they are
- // introduced in the same spec that adds the .response field, and would
- // have been caught above.
- // ARRAY_BUFFER needs an implementation for Firefox 4, where it was
- // implemented using a draft spec rather than the final spec.
- case goog.net.XhrIo.ResponseType.ARRAY_BUFFER:
- if ('mozResponseArrayBuffer' in this.xhr_) {
- return this.xhr_.mozResponseArrayBuffer;
- }
- }
- // Fell through to a response type that is not supported on this browser.
- this.logger_.severe('Response type ' + this.responseType_ + ' is not ' +
- 'supported on this browser');
- return null;
- } catch (e) {
- this.logger_.fine('Can not get response: ' + e.message);
- return null;
- }
-};
-
-
-/**
- * Get the value of the response-header with the given name from the Xhr object
- * Will only return correct result when called from the context of a callback
- * and the request has completed
- * @param {string} key The name of the response-header to retrieve.
- * @return {string|undefined} The value of the response-header named key.
- */
-goog.net.XhrIo.prototype.getResponseHeader = function(key) {
- return this.xhr_ && this.isComplete() ?
- this.xhr_.getResponseHeader(key) : undefined;
-};
-
-
-/**
- * Gets the text of all the headers in the response.
- * Will only return correct result when called from the context of a callback
- * and the request has completed.
- * @return {string} The value of the response headers or empty string.
- */
-goog.net.XhrIo.prototype.getAllResponseHeaders = function() {
- return this.xhr_ && this.isComplete() ?
- this.xhr_.getAllResponseHeaders() : '';
-};
-
-
-/**
- * Get the last error message
- * @return {goog.net.ErrorCode} Last error code.
- */
-goog.net.XhrIo.prototype.getLastErrorCode = function() {
- return this.lastErrorCode_;
-};
-
-
-/**
- * Get the last error message
- * @return {string} Last error message.
- */
-goog.net.XhrIo.prototype.getLastError = function() {
- return goog.isString(this.lastError_) ? this.lastError_ :
- String(this.lastError_);
-};
-
-
-/**
- * Adds the last method, status and URI to the message. This is used to add
- * this information to the logging calls.
- * @param {string} msg The message text that we want to add the extra text to.
- * @return {string} The message with the extra text appended.
- * @private
- */
-goog.net.XhrIo.prototype.formatMsg_ = function(msg) {
- return msg + ' [' + this.lastMethod_ + ' ' + this.lastUri_ + ' ' +
- this.getStatus() + ']';
-};
-
-
-// Register the xhr handler as an entry point, so that
-// it can be monitored for exception handling, etc.
-goog.debug.entryPointRegistry.register(
- /**
- * @param {function(!Function): !Function} transformer The transforming
- * function.
- */
- function(transformer) {
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ =
- transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);
- });
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio_test.html.svn-base
deleted file mode 100644
index 096f8f6..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrio_test.html.svn-base
+++ /dev/null
@@ -1,639 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
- Author: arv@google.com (Erik Arvidsson)
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.XhrIo</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.debug.ErrorHandler');
- goog.require('goog.functions');
- goog.require('goog.net.WrapperXmlHttpFactory');
- goog.require('goog.net.XhrIo');
- goog.require('goog.object');
- goog.require('goog.string');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.jsunit');
- goog.require('goog.testing.net.XhrIo');
- goog.require('goog.testing.recordFunction');
- goog.require('goog.Uri');
-</script>
-<script>
-
-function MockXmlHttp() {}
-
-MockXmlHttp.prototype.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
-
-MockXmlHttp.prototype.status = 200;
-
-MockXmlHttp.syncSend = false;
-
-MockXmlHttp.prototype.send = function(opt_data) {
- this.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
-
- if (MockXmlHttp.syncSend) {
- this.complete();
- }
-
-};
-
-MockXmlHttp.prototype.complete = function() {
- this.readyState = goog.net.XmlHttp.ReadyState.LOADING;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.LOADED;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.INTERACTIVE;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.COMPLETE;
- this.onreadystatechange();
-};
-
-
-MockXmlHttp.prototype.open = function(verb, uri, async) {
-};
-
-MockXmlHttp.prototype.abort = function() {};
-
-MockXmlHttp.prototype.setRequestHeader = function(key, value) {};
-
-var lastMockXmlHttp;
-goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
- function() {
- lastMockXmlHttp = new MockXmlHttp();
- return lastMockXmlHttp;
- },
- function() {
- return {};
- }));
-
-
-var clock;
-var originalEntryPoint =
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_;
-
-function setUp() {
- lastMockXmlHttp = null;
- clock = new goog.testing.MockClock(true);
-}
-
-function tearDown() {
- clock.dispose();
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = originalEntryPoint;
-}
-
-
-function testSyncSend() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should be succesful', e.target.isSuccess());
- count++;
-
- });
-
- var inSend = true;
- x.send('url');
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-function testSyncSendFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('url');
- lastMockXmlHttp.status = 404;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendRelativeZeroStatus() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertEquals('Should be the same as ', e.target.isSuccess(),
- window.location.href.toLowerCase().indexOf("file:") == 0);
- count++;
- });
-
- var inSend = true;
- x.send('relative');
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendRelativeUriZeroStatus() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertEquals('Should be the same as ', e.target.isSuccess(),
- window.location.href.toLowerCase().indexOf("file:") == 0);
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('relative'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('http://foo');
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpUpperZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('HTTP://foo');
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpUpperUriZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('HTTP://foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpUriZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('http://foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpUriZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('HTTP://foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendHttpsZeroStatusFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('https://foo');
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendFileUpperZeroStatusSuccess() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('FILE:///foo');
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendFileUriZeroStatusSuccess() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('file:///foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendDummyUriZeroStatusSuccess() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('dummy:///foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendFileUpperUriZeroStatusSuccess() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send(goog.Uri.parse('FILE:///foo'));
- lastMockXmlHttp.status = 0;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testSendFromListener() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- count++;
-
- var e = assertThrows(function() {
- x.send('url2');
- });
- assertEquals('[goog.net.XhrIo] Object is active with another request',
- e.message);
- });
-
- x.send('url');
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testStatesDuringEvents() {
- MockXmlHttp.syncSend = true;
-
- var x = new goog.net.XhrIo;
- var readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
- goog.events.listen(x, goog.net.EventType.READY_STATE_CHANGE, function(e) {
- readyState++;
- assertObjectEquals(e.target, x);
- assertEquals(x.getReadyState(), readyState);
- assertTrue(x.isActive());
- });
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertObjectEquals(e.target, x);
- assertTrue(x.isActive());
- });
- goog.events.listen(x, goog.net.EventType.SUCCESS, function(e) {
- assertObjectEquals(e.target, x);
- assertTrue(x.isActive());
- });
- goog.events.listen(x, goog.net.EventType.READY, function(e) {
- assertObjectEquals(e.target, x);
- assertFalse(x.isActive());
- });
-
- x.send('url');
-
- clock.tick(1); // callOnce(f, 0, ...)
-}
-
-
-function testProtectEntryPointCalledOnAsyncSend() {
- MockXmlHttp.syncSend = false;
-
- var errorHandlerCallbackCalled = false;
- var errorHandler = new goog.debug.ErrorHandler(function() {
- errorHandlerCallbackCalled = true;
- });
-
- goog.net.XhrIo.protectEntryPoints(errorHandler);
-
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.READY_STATE_CHANGE, function(e) {
- throw Error();
- });
-
- x.send('url');
- assertThrows(function() {
- lastMockXmlHttp.complete();
- });
-
- assertTrue('Error handler callback should be called on async send.',
- errorHandlerCallbackCalled);
-}
-
-
-function testDisposeInternalDoesNotAbortXhrRequestObjectWhenActiveIsFalse() {
- MockXmlHttp.syncSend = false;
-
- var xmlHttp = goog.net.XmlHttp;
- var abortCalled = false;
- var x = new goog.net.XhrIo;
-
- goog.net.XmlHttp.prototype.abort = function() { abortCalled = true; }
-
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- this.active_ = false;
- this.dispose();
- }, false, x);
-
- x.send('url');
- lastMockXmlHttp.complete();
-
- goog.net.XmlHttp = xmlHttp;
- assertFalse(abortCalled);
-}
-
-function testCallingAbortFromWithinAbortCallbackDoesntLoop() {
- var x = new goog.net.XhrIo;
- goog.events.listen(x, goog.net.EventType.ABORT, function(e) {
- x.abort(); // Shouldn't get a stack overflow
- });
- x.send('url');
- x.abort();
-}
-
-function testFactoryInjection() {
- var xhr = new MockXmlHttp();
- var optionsFactoryCalled = 0;
- var xhrFactoryCalled = 0;
- var wrapperFactory = new goog.net.WrapperXmlHttpFactory(
- function() {
- xhrFactoryCalled++;
- return xhr;
- },
- function() {
- optionsFactoryCalled++;
- return {};
- });
- var xhrIo = new goog.net.XhrIo(wrapperFactory);
-
- xhrIo.send('url');
-
- assertEquals('XHR factory should have been called', 1, xhrFactoryCalled);
- assertEquals('Options factory should have been called', 1,
- optionsFactoryCalled);
-}
-
-function testGoogTestingNetXhrIoIsInSync() {
- var xhrIo = new goog.net.XhrIo();
- var testingXhrIo = new goog.testing.net.XhrIo();
-
- var propertyComparator = function(value, key, obj) {
- if (goog.string.endsWith(key, '_')) {
- // Ignore private properties/methods
- return true;
- } else if (typeof value == 'function' && typeof this[key] != 'function') {
- // Only type check is sufficient for functions
- fail('Mismatched property:'+ key + ': gooo.net.XhrIo has:<' +
- value + '>; while goog.testing.net.XhrIo has:<' + this[key] + '>');
- return true;
- } else {
- // Ignore all other type of properties.
- return true;
- }
- };
-
- goog.object.every(xhrIo, propertyComparator, testingXhrIo);
-}
-
-function testEntryPointRegistry() {
- var monitor = new goog.debug.EntryPointMonitor();
- var replacement = function() {};
- monitor.wrap = goog.testing.recordFunction(
- goog.functions.constant(replacement));
-
- goog.debug.entryPointRegistry.monitorAll(monitor);
- assertTrue(monitor.wrap.getCallCount() >= 1);
- assertEquals(
- replacement,
- goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_);
-}
-
-function testSetWithCredentials() {
- // Test on XHR objects that don't have the withCredentials property (older
- // browsers).
- var x = new goog.net.XhrIo;
- x.setWithCredentials(true);
- x.send('url');
- assertFalse(
- 'withCredentials should not be set on an XHR object if the property ' +
- 'does not exist.',
- goog.object.containsKey(lastMockXmlHttp, 'withCredentials'));
-
- // Test on XHR objects that have the withCredentials property.
- MockXmlHttp.prototype.withCredentials = false;
- x = new goog.net.XhrIo;
- x.setWithCredentials(true);
- x.send('url');
- assertTrue(
- 'withCredentials should be set on an XHR object if the property exists',
- goog.object.containsKey(lastMockXmlHttp, 'withCredentials'));
-
- assertTrue(
- 'withCredentials value not set on XHR object',
- lastMockXmlHttp.withCredentials);
-
- // Reset the prototype so it does not effect other tests.
- delete MockXmlHttp.prototype.withCredentials;
-}
-
-function testGetResponse() {
- var x = new goog.net.XhrIo;
-
- // No XHR yet
- assertEquals(null, x.getResponse());
-
- // XHR with no .response and no response type, gets text.
- x.xhr_ = {};
- x.xhr_.responseText = 'text';
- assertEquals('text', x.getResponse());
-
- // Response type of text gets text as well.
- x.setResponseType(goog.net.XhrIo.ResponseType.TEXT);
- x.xhr_.responseText = '';
- assertEquals('', x.getResponse());
-
- // Response type of array buffer gets the array buffer.
- x.xhr_.mozResponseArrayBuffer = 'ab';
- x.setResponseType(goog.net.XhrIo.ResponseType.ARRAY_BUFFER);
- assertEquals('ab', x.getResponse());
-
- // With a response field, it is returned no matter what value it has.
- x.xhr_.response = undefined;
- assertEquals(undefined, x.getResponse());
-
- x.xhr_.response = null;
- assertEquals(null, x.getResponse());
-
- x.xhr_.response = '';
- assertEquals('', x.getResponse());
-
- x.xhr_.response = 'resp';
- assertEquals('resp', x.getResponse());
-}
-
-</script>
-</head>
-
-<body>
-</body>
-
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhriopool.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhriopool.js.svn-base
deleted file mode 100644
index 1b2e171..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhriopool.js.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Creates a pool of XhrIo objects to use. This allows multiple
- * XhrIo objects to be grouped together and requests will use next available
- * XhrIo object.
- *
- */
-
-goog.provide('goog.net.XhrIoPool');
-
-goog.require('goog.net.XhrIo');
-goog.require('goog.structs');
-goog.require('goog.structs.PriorityPool');
-
-
-
-/**
- * A pool of XhrIo objects.
- * @param {goog.structs.Map=} opt_headers Map of default headers to add to every
- * request.
- * @param {number=} opt_minCount Minimum number of objects (Default: 1).
- * @param {number=} opt_maxCount Maximum number of objects (Default: 10).
- * @constructor
- * @extends {goog.structs.PriorityPool}
- */
-goog.net.XhrIoPool = function(opt_headers, opt_minCount, opt_maxCount) {
- goog.structs.PriorityPool.call(this, opt_minCount, opt_maxCount);
-
- /**
- * Map of default headers to add to every request.
- * @type {goog.structs.Map|undefined}
- * @private
- */
- this.headers_ = opt_headers;
-};
-goog.inherits(goog.net.XhrIoPool, goog.structs.PriorityPool);
-
-
-/**
- * Creates an instance of an XhrIo object to use in the pool.
- * @return {goog.net.XhrIo} The created object.
- */
-goog.net.XhrIoPool.prototype.createObject = function() {
- var xhrIo = new goog.net.XhrIo();
- var headers = this.headers_;
- if (headers) {
- goog.structs.forEach(headers, function(value, key) {
- xhrIo.headers.set(key, value);
- });
- }
- return xhrIo;
-};
-
-
-/**
- * Should be overridden to dispose of an object, default implementation is to
- * remove all its members which should render it useless.
- * @param {goog.net.XhrIo} obj The object to dispose.
- */
-goog.net.XhrIoPool.prototype.disposeObject = function(obj) {
- obj.dispose();
-};
-
-
-/**
- * Determine if an object has become unusable and should not be used.
- * @param {goog.net.XhrIo} obj The object to test.
- * @return {boolean} Whether the object can be reused, which is true if the
- * object is not disposed and not active.
- */
-goog.net.XhrIoPool.prototype.objectCanBeReused = function(obj) {
- // An active XhrIo object should never be used.
- return !obj.isDisposed() && !obj.isActive();
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite.js.svn-base
deleted file mode 100644
index 0e56e4e..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite.js.svn-base
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Wrapper class for handling XmlHttpRequests.
- */
-
-
-goog.provide('goog.net.XhrLite');
-
-goog.require('goog.net.XhrIo');
-
-
-
-/**
- * Basic class for handling XmlHttpRequests.
- * @deprecated Use goog.net.XhrIo instead.
- * @constructor
- */
-goog.net.XhrLite = goog.net.XhrIo;
-
-// Statics are needed to avoid code removal.
-
-
-/**
- * Static send that creates a short lived instance of XhrIo to send the
- * request.
- * @see goog.net.XhrIo.cleanup
- * @param {string} url Uri to make request too.
- * @param {Function=} opt_callback Callback function for when request is
- * complete.
- * @param {string=} opt_method Send method, default: GET.
- * @param {string=} opt_content Post data.
- * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
- * request.
- * @param {number=} opt_timeoutInterval Number of milliseconds after which an
- * incomplete request will be aborted; 0 means no timeout is set.
- */
-goog.net.XhrLite.send = goog.net.XhrIo.send;
-
-
-/**
- * Disposes all non-disposed instances of goog.net.XhrIo created by
- * {@link goog.net.XhrIo.send}.
- * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance
- * it creates when the request completes or fails. However, if
- * the request never completes, then the goog.net.XhrIo is not disposed.
- * This can occur if the window is unloaded before the request completes.
- * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo
- * it creates and make the client of {@link goog.net.XhrIo.send} be
- * responsible for disposing it in this case. However, this makes things
- * significantly more complicated for the client, and the whole point
- * of {@link goog.net.XhrIo.send} is that it's simple and easy to use.
- * Clients of {@link goog.net.XhrIo.send} should call
- * {@link goog.net.XhrIo.cleanup} when doing final
- * cleanup on window unload.
- */
-goog.net.XhrLite.cleanup = goog.net.XhrIo.cleanup;
-
-
-/**
- * Installs exception protection for all entry point introduced by
- * goog.net.XhrIo instances which are not protected by
- * {@link goog.debug.ErrorHandler#protectWindowSetTimeout},
- * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or
- * {@link goog.events.protectBrowserEventEntryPoint}.
- *
- * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to
- * protect the entry point(s).
- * @param {boolean=} opt_tracers Whether to install tracers around the entry
- * point.
- */
-goog.net.XhrLite.protectEntryPoints = goog.net.XhrIo.protectEntryPoints;
-
-
-/**
- * Disposes of the specified goog.net.XhrIo created by
- * {@link goog.net.XhrIo.send} and removes it from
- * {@link goog.net.XhrIo.pendingStaticSendInstances_}.
- * @param {goog.net.XhrIo} XhrIo An XhrIo created by
- * {@link goog.net.XhrIo.send}.
- * @private
- */
-goog.net.XhrLite.cleanupSend_ = goog.net.XhrIo.cleanupSend_;
-
-
-/**
- * The Content-Type HTTP header name
- * @type {string}
- */
-goog.net.XhrLite.CONTENT_TYPE_HEADER = goog.net.XhrIo.CONTENT_TYPE_HEADER;
-
-
-/**
- * The Content-Type HTTP header value for a url-encoded form
- * @type {string}
- */
-goog.net.XhrLite.FORM_CONTENT_TYPE = goog.net.XhrIo.FORM_CONTENT_TYPE;
-
-
-/**
- * All non-disposed instances of goog.net.XhrIo created
- * by {@link goog.net.XhrIo.send} are in this Array.
- * @see goog.net.XhrIo.cleanup
- * @type {Array.<goog.net.XhrIo>}
- * @private
- */
-goog.net.XhrLite.sendInstances_ = goog.net.XhrIo.sendInstances_;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite_test.html.svn-base
deleted file mode 100644
index 9f91788..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlite_test.html.svn-base
+++ /dev/null
@@ -1,157 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-Copyright 2007 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<!--
- Author: arv@google.com (Erik Arvidsson)
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>Closure Unit Tests - goog.net.XhrLite</title>
-<script src="../base.js"></script>
-<script>
- goog.require('goog.debug.ErrorHandler');
- goog.require('goog.net.WrapperXmlHttpFactory');
- goog.require('goog.net.XhrLite');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.jsunit');
-</script>
-<script>
-
-function MockXmlHttp() {}
-
-MockXmlHttp.prototype.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
-
-MockXmlHttp.prototype.status = 200;
-
-MockXmlHttp.syncSend = false;
-
-MockXmlHttp.prototype.send = function(opt_data) {
- this.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
-
- if (MockXmlHttp.syncSend) {
- this.complete();
- }
-
-};
-
-MockXmlHttp.prototype.complete = function() {
- this.readyState = goog.net.XmlHttp.ReadyState.LOADING;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.LOADED;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.INTERACTIVE;
- this.onreadystatechange();
-
- this.readyState = goog.net.XmlHttp.ReadyState.COMPLETE;
- this.onreadystatechange();
-};
-
-
-MockXmlHttp.prototype.open = function(verb, uri, async) {
-};
-
-MockXmlHttp.prototype.abort = function() {};
-
-MockXmlHttp.prototype.setRequestHeader = function(key, value) {};
-
-goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
- function() {
- return new MockXmlHttp();
- },
- function() {
- return {};
- }));
-
-var clock;
-
-function setUp() {
- clock = new goog.testing.MockClock(true);
-}
-
-function tearDown() {
- clock.dispose();
-}
-
-
-function testSyncSend() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrLite;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertTrue('Should be succesful', e.target.isSuccess());
- count++;
-
- });
-
- var inSend = true;
- x.send('url');
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-function testSyncSendFailure() {
- MockXmlHttp.syncSend = true;
- var count = 0;
-
- var x = new goog.net.XhrLite;
- goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
- assertFalse('Should not fire complete from inside send', inSend);
- assertFalse('Should not be succesful', e.target.isSuccess());
- count++;
- });
-
- var inSend = true;
- x.send('url');
- x.xhr_.status = 404;
- inSend = false;
-
- clock.tick(1); // callOnce(f, 0, ...)
-
- assertEquals('Complete should have been called once', 1, count);
-}
-
-
-function testProtectEntryPointCalledOnAsyncSend() {
- MockXmlHttp.syncSend = false;
-
- var errorHandlerCallbackCalled = false;
- var errorHandler = new goog.debug.ErrorHandler(function() {
- errorHandlerCallbackCalled = true;
- });
-
- goog.net.XhrLite.protectEntryPoints(errorHandler);
-
- var x = new goog.net.XhrLite;
- goog.events.listen(x, goog.net.EventType.READY_STATE_CHANGE, function(e) {
- throw Error();
- });
-
- x.send('url');
- assertThrows(function() {
- x.xhr_.complete();
- });
-
- assertTrue('Error handler callback should be called on async send.',
- errorHandlerCallbackCalled);
-}
-
-
-</script>
-</head>
-
-<body>
-</body>
-
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlitepool.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlitepool.js.svn-base
deleted file mode 100644
index 9e4ce85..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrlitepool.js.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Creates a pool of XhrLite objects to use. This allows multiple
- * XhrLite objects to be grouped together and requests will use next available
- * XhrLite object.
- *
- */
-
-goog.provide('goog.net.XhrLitePool');
-
-goog.require('goog.net.XhrIoPool');
-
-
-
-/**
- * A pool of XhrLite objects.
- * @param {goog.structs.Map=} opt_headers Map of default headers to add to every
- * request.
- * @param {number=} opt_minCount Min. number of objects (Default: 1).
- * @param {number=} opt_maxCount Max. number of objects (Default: 10).
- * @deprecated Use goog.net.XhrIoPool.
- * @constructor
- */
-goog.net.XhrLitePool = goog.net.XhrIoPool;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrmanager.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrmanager.js.svn-base
deleted file mode 100644
index 36339f4..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xhrmanager.js.svn-base
+++ /dev/null
@@ -1,757 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Manages a pool of XhrIo's. This handles all the details of
- * dealing with the XhrPool and provides a simple interface for sending requests
- * and managing events.
- *
- * This class supports queueing & prioritization of requests (XhrIoPool
- * handles this) and retrying of requests.
- *
- * The events fired by the XhrManager are an aggregation of the events of
- * each of its XhrIo objects (with some filtering, i.e., ERROR only called
- * when there are no more retries left). For this reason, all send requests have
- * to have an id, so that the user of this object can know which event is for
- * which request.
- *
- */
-
-goog.provide('goog.net.XhrManager');
-goog.provide('goog.net.XhrManager.Event');
-goog.provide('goog.net.XhrManager.Request');
-
-goog.require('goog.Disposable');
-goog.require('goog.events');
-goog.require('goog.events.Event');
-goog.require('goog.events.EventHandler');
-goog.require('goog.events.EventTarget');
-goog.require('goog.net.EventType');
-goog.require('goog.net.XhrIo');
-goog.require('goog.net.XhrIoPool');
-goog.require('goog.structs.Map');
-
-// TODO(user): Add some time in between retries.
-
-
-
-/**
- * A manager of an XhrIoPool.
- * @param {number=} opt_maxRetries Max. number of retries (Default: 1).
- * @param {goog.structs.Map=} opt_headers Map of default headers to add to every
- * request.
- * @param {number=} opt_minCount Min. number of objects (Default: 1).
- * @param {number=} opt_maxCount Max. number of objects (Default: 10).
- * @param {number=} opt_timeoutInterval Timeout (in ms) before aborting an
- * attempt (Default: 0ms).
- * @constructor
- * @extends {goog.events.EventTarget}
- */
-goog.net.XhrManager = function(
- opt_maxRetries,
- opt_headers,
- opt_minCount,
- opt_maxCount,
- opt_timeoutInterval) {
-
- /**
- * Maximum number of retries for a given request
- * @type {number}
- * @private
- */
- this.maxRetries_ = goog.isDef(opt_maxRetries) ? opt_maxRetries : 1;
-
- /**
- * Timeout interval for an attempt of a given request.
- * @type {number}
- * @private
- */
- this.timeoutInterval_ =
- goog.isDef(opt_timeoutInterval) ? Math.max(0, opt_timeoutInterval) : 0;
-
- /**
- * The pool of XhrIo's to use.
- * @type {goog.net.XhrIoPool}
- * @private
- */
- this.xhrPool_ = new goog.net.XhrIoPool(
- opt_headers, opt_minCount, opt_maxCount);
-
- /**
- * Map of ID's to requests.
- * @type {goog.structs.Map}
- * @private
- */
- this.requests_ = new goog.structs.Map();
-
- /**
- * The event handler.
- * @type {goog.events.EventHandler}
- * @private
- */
- this.eventHandler_ = new goog.events.EventHandler(this);
-};
-goog.inherits(goog.net.XhrManager, goog.events.EventTarget);
-
-
-/**
- * Error to throw when a send is attempted with an ID that the manager already
- * has registered for another request.
- * @type {string}
- * @private
- */
-goog.net.XhrManager.ERROR_ID_IN_USE_ = '[goog.net.XhrManager] ID in use';
-
-
-/**
- * The goog.net.EventType's to listen/unlisten for on the XhrIo object.
- * @type {Array.<goog.net.EventType>}
- * @private
- */
-goog.net.XhrManager.XHR_EVENT_TYPES_ = [
- goog.net.EventType.READY,
- goog.net.EventType.COMPLETE,
- goog.net.EventType.SUCCESS,
- goog.net.EventType.ERROR,
- goog.net.EventType.ABORT,
- goog.net.EventType.TIMEOUT];
-
-
-/**
- * Sets the number of milliseconds after which an incomplete request will be
- * aborted. Zero means no timeout is set.
- * @param {number} ms Timeout interval in milliseconds; 0 means none.
- */
-goog.net.XhrManager.prototype.setTimeoutInterval = function(ms) {
- this.timeoutInterval_ = Math.max(0, ms);
-};
-
-
-/**
- * Returns the number of reuqests either in flight, or waiting to be sent.
- * @return {number} The number of requests in flight or pending send.
- */
-goog.net.XhrManager.prototype.getOutstandingCount = function() {
- return this.requests_.getCount();
-};
-
-
-/**
- * Registers the given request to be sent. Throws an error if a request
- * already exists with the given ID.
- * NOTE: It is not sent immediately. It is queued and will be sent when an
- * XhrIo object becomes available, taking into account the request's
- * priority.
- * @param {string} id The id of the request.
- * @param {string} url Uri to make the request too.
- * @param {string=} opt_method Send method, default: GET.
- * @param {string=} opt_content Post data.
- * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
- * request.
- * @param {*=} opt_priority The priority of the request.
- * @param {Function=} opt_callback Callback function for when request is
- * complete. The only param is the event object from the COMPLETE event.
- * @param {number=} opt_maxRetries The maximum number of times the request
- * should be retried.
- * @return {goog.net.XhrManager.Request} The queued request object.
- */
-goog.net.XhrManager.prototype.send = function(
- id,
- url,
- opt_method,
- opt_content,
- opt_headers,
- opt_priority,
- opt_callback,
- opt_maxRetries) {
- var requests = this.requests_;
- // Check if there is already a request with the given id.
- if (requests.get(id)) {
- throw Error(goog.net.XhrManager.ERROR_ID_IN_USE_);
- }
-
- // Make the Request object.
- var request = new goog.net.XhrManager.Request(
- url,
- goog.bind(this.handleEvent_, this, id),
- opt_method,
- opt_content,
- opt_headers,
- opt_callback,
- goog.isDef(opt_maxRetries) ? opt_maxRetries : this.maxRetries_);
- this.requests_.set(id, request);
-
- // Setup the callback for the pool.
- var callback = goog.bind(this.handleAvailableXhr_, this, id);
- this.xhrPool_.getObject(callback, opt_priority);
-
- return request;
-};
-
-
-/**
- * Aborts the request associated with id.
- * @param {string} id The id of the request to abort.
- * @param {boolean=} opt_force If true, remove the id now so it can be reused.
- * No events are fired and the callback is not called when forced.
- */
-goog.net.XhrManager.prototype.abort = function(id, opt_force) {
- var request = this.requests_.get(id);
- if (request) {
- var xhrIo = request.xhrIo;
- request.setAborted(true);
- if (opt_force) {
- // We remove listeners to make sure nothing gets called if a new request
- // with the same id is made.
- this.removeXhrListener_(xhrIo, request.getXhrEventCallback());
- goog.events.listenOnce(
- xhrIo,
- goog.net.EventType.READY,
- function() { this.xhrPool_.releaseObject(xhrIo); },
- false,
- this);
- this.requests_.remove(id);
- }
- if (xhrIo) {
- xhrIo.abort();
- }
- }
-};
-
-
-/**
- * Handles when an XhrIo object becomes available. Sets up the events, fires
- * the READY event, and starts the process to send the request.
- * @param {string} id The id of the request the XhrIo is for.
- * @param {goog.net.XhrIo} xhrIo The available XhrIo object.
- * @private
- */
-goog.net.XhrManager.prototype.handleAvailableXhr_ = function(id, xhrIo) {
- var request = this.requests_.get(id);
- // Make sure the request doesn't already have an XhrIo attached. This can
- // happen if a forced abort occurs before an XhrIo is available, and a new
- // request with the same id is made.
- if (request && !request.xhrIo) {
- this.addXhrListener_(xhrIo, request.getXhrEventCallback());
-
- // Set properties for the XhrIo.
- xhrIo.setTimeoutInterval(this.timeoutInterval_);
-
- // Add a reference to the XhrIo object to the request.
- request.xhrIo = request.xhrLite = xhrIo;
-
- // Notify the listeners.
- this.dispatchEvent(new goog.net.XhrManager.Event(
- goog.net.EventType.READY, this, id, xhrIo));
-
- // Send the request.
- this.retry_(id, xhrIo);
-
- // If the request was aborted before it got an XhrIo object, abort it now.
- if (request.getAborted()) {
- xhrIo.abort();
- }
- } else {
- // If the request has an XhrIo object already, or no request exists, just
- // return the XhrIo back to the pool.
- this.xhrPool_.releaseObject(xhrIo);
- }
-};
-
-
-/**
- * Handles all events fired by the XhrIo object for a given request.
- * @param {string} id The id of the request.
- * @param {goog.events.Event} e The event.
- * @return {Object} The return value from the handler, if any.
- * @private
- */
-goog.net.XhrManager.prototype.handleEvent_ = function(id, e) {
- var xhrIo = /** @type {goog.net.XhrIo} */(e.target);
- switch (e.type) {
- case goog.net.EventType.READY:
- this.retry_(id, xhrIo);
- break;
-
- case goog.net.EventType.COMPLETE:
- return this.handleComplete_(id, xhrIo, e);
-
- case goog.net.EventType.SUCCESS:
- this.handleSuccess_(id, xhrIo);
- break;
-
- // A timeout is handled like an error.
- case goog.net.EventType.TIMEOUT:
- case goog.net.EventType.ERROR:
- this.handleError_(id, xhrIo);
- break;
-
- case goog.net.EventType.ABORT:
- this.handleAbort_(id, xhrIo);
- break;
- }
- return null;
-};
-
-
-/**
- * Attempts to retry the given request. If the request has already attempted
- * the maximum number of retries, then it removes the request and releases
- * the XhrIo object back into the pool.
- * @param {string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object.
- * @private
- */
-goog.net.XhrManager.prototype.retry_ = function(id, xhrIo) {
- var request = this.requests_.get(id);
-
- // If the request has not completed and it is below its max. retries.
- if (request && !request.getCompleted() && !request.hasReachedMaxRetries()) {
- request.increaseAttemptCount();
- xhrIo.send(request.getUrl(), request.getMethod(), request.getContent(),
- request.getHeaders());
- } else {
- if (request) {
- // Remove the events on the XhrIo objects.
- this.removeXhrListener_(xhrIo, request.getXhrEventCallback());
-
- // Remove the request.
- this.requests_.remove(id);
- }
- // Release the XhrIo object back into the pool.
- this.xhrPool_.releaseObject(xhrIo);
- }
-};
-
-
-/**
- * Handles the complete of a request. Dispatches the COMPLETE event and sets the
- * the request as completed if the request has succeeded, or is done retrying.
- * @param {string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object.
- * @param {goog.events.Event} e The original event.
- * @return {Object} The return value from the callback, if any.
- * @private
- */
-goog.net.XhrManager.prototype.handleComplete_ = function(id, xhrIo, e) {
- // Only if the request is done processing should a COMPLETE event be fired.
- var request = this.requests_.get(id);
- if (xhrIo.getLastErrorCode() == goog.net.ErrorCode.ABORT ||
- xhrIo.isSuccess() || request.hasReachedMaxRetries()) {
- this.dispatchEvent(new goog.net.XhrManager.Event(
- goog.net.EventType.COMPLETE, this, id, xhrIo));
-
- // If the request exists, we mark it as completed and call the callback
- if (request) {
- request.setCompleted(true);
- // Call the complete callback as if it was set as a COMPLETE event on the
- // XhrIo directly.
- if (request.getCompleteCallback()) {
- return request.getCompleteCallback().call(xhrIo, e);
- }
- }
- }
- return null;
-};
-
-
-/**
- * Handles the abort of an underlying XhrIo object.
- * @param {string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object.
- * @private
- */
-goog.net.XhrManager.prototype.handleAbort_ = function(id, xhrIo) {
- // Fire event.
- // NOTE: The complete event should always be fired before the abort event, so
- // the bulk of the work is done in handleComplete.
- this.dispatchEvent(new goog.net.XhrManager.Event(
- goog.net.EventType.ABORT, this, id, xhrIo));
-};
-
-
-/**
- * Handles the success of a request. Dispatches the SUCCESS event and sets the
- * the request as completed.
- * @param {string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object.
- * @private
- */
-goog.net.XhrManager.prototype.handleSuccess_ = function(id, xhrIo) {
- // Fire event.
- // NOTE: We don't release the XhrIo object from the pool here.
- // It is released in the retry method, when we know it is back in the
- // ready state.
- this.dispatchEvent(new goog.net.XhrManager.Event(
- goog.net.EventType.SUCCESS, this, id, xhrIo));
-};
-
-
-/**
- * Handles the error of a request. If the request has not reach its maximum
- * number of retries, then it lets the request retry naturally (will let the
- * request hit the READY state). Else, it dispatches the ERROR event.
- * @param {string} id The id of the request.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object.
- * @private
- */
-goog.net.XhrManager.prototype.handleError_ = function(id, xhrIo) {
- var request = this.requests_.get(id);
-
- // If the maximum number of retries has been reached.
- if (request.hasReachedMaxRetries()) {
- // Fire event.
- // NOTE: We don't release the XhrIo object from the pool here.
- // It is released in the retry method, when we know it is back in the
- // ready state.
- this.dispatchEvent(new goog.net.XhrManager.Event(
- goog.net.EventType.ERROR, this, id, xhrIo));
- }
-};
-
-
-/**
- * Remove listeners for XHR events on an XhrIo object.
- * @param {goog.net.XhrIo} xhrIo The object to stop listenening to events on.
- * @param {Function} func The callback to remove from event handling.
- * @param {string|Array.<string>=} opt_types Event types to remove listeners
- * for. Defaults to XHR_EVENT_TYPES_.
- * @private
- */
-goog.net.XhrManager.prototype.removeXhrListener_ = function(xhrIo,
- func,
- opt_types) {
- var types = opt_types || goog.net.XhrManager.XHR_EVENT_TYPES_;
- this.eventHandler_.unlisten(xhrIo, types, func);
-};
-
-
-/**
- * Adds a listener for XHR events on an XhrIo object.
- * @param {goog.net.XhrIo} xhrIo The object listen to events on.
- * @param {Function} func The callback when the event occurs.
- * @param {string|Array.<string>=} opt_types Event types to attach listeners to.
- * Defaults to XHR_EVENT_TYPES_.
- * @private
- */
-goog.net.XhrManager.prototype.addXhrListener_ = function(xhrIo,
- func,
- opt_types) {
- var types = opt_types || goog.net.XhrManager.XHR_EVENT_TYPES_;
- this.eventHandler_.listen(xhrIo, types, func);
-};
-
-
-/** @override */
-goog.net.XhrManager.prototype.disposeInternal = function() {
- goog.net.XhrManager.superClass_.disposeInternal.call(this);
-
- this.xhrPool_.dispose();
- this.xhrPool_ = null;
-
- this.eventHandler_.dispose();
- this.eventHandler_ = null;
-
- // Call dispose on each request.
- var requests = this.requests_;
- goog.structs.forEach(requests, function(value, key) {
- value.dispose();
- });
- requests.clear();
- this.requests_ = null;
-};
-
-
-
-/**
- * An event dispatched by XhrManager.
- *
- * @param {goog.net.EventType} type Event Type.
- * @param {goog.net.XhrManager} target Reference to the object that is the
- * target of this event.
- * @param {string} id The id of the request this event is for.
- * @param {goog.net.XhrIo} xhrIo The XhrIo object of the request.
- * @constructor
- * @extends {goog.events.Event}
- */
-goog.net.XhrManager.Event = function(type, target, id, xhrIo) {
- goog.events.Event.call(this, type, target);
-
- /**
- * The id of the request this event is for.
- * @type {string}
- */
- this.id = id;
-
- /**
- * The XhrIo object of the request.
- * @type {goog.net.XhrIo}
- */
- this.xhrIo = xhrIo;
-
- /**
- * The xhrLite field aliases xhrIo for backwards compatibility.
- * @type {goog.net.XhrLite}
- */
- this.xhrLite = /** @type {goog.net.XhrLite} */ (xhrIo);
-};
-goog.inherits(goog.net.XhrManager.Event, goog.events.Event);
-
-
-/** @override */
-goog.net.XhrManager.Event.prototype.disposeInternal = function() {
- goog.net.XhrManager.Event.superClass_.disposeInternal.call(this);
- delete this.id;
- this.xhrIo = null;
- this.xhrLite = null;
-};
-
-
-
-/**
- * An encapsulation of everything needed to make a Xhr request.
- * NOTE: This is used internal to the XhrManager.
- *
- * @param {string} url Uri to make the request too.
- * @param {Function} xhrEventCallback Callback attached to the events of the
- * XhrIo object of the request.
- * @param {string=} opt_method Send method, default: GET.
- * @param {string=} opt_content Post data.
- * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
- * request.
- * @param {Function=} opt_callback Callback function for when request is
- * complete. NOTE: Only 1 callback supported across all events.
- * @param {number=} opt_maxRetries The maximum number of times the request
- * should be retried (Default: 1).
- *
- * @constructor
- * @extends {goog.Disposable}
- */
-goog.net.XhrManager.Request = function(url, xhrEventCallback, opt_method,
- opt_content, opt_headers, opt_callback, opt_maxRetries) {
- goog.Disposable.call(this);
-
- /**
- * Uri to make the request too.
- * @type {string}
- * @private
- */
- this.url_ = url;
-
- /**
- * Send method.
- * @type {string}
- * @private
- */
- this.method_ = opt_method || 'GET';
-
- /**
- * Post data.
- * @type {string|undefined}
- * @private
- */
- this.content_ = opt_content;
-
- /**
- * Map of headers
- * @type {Object|goog.structs.Map|null}
- * @private
- */
- this.headers_ = opt_headers || null;
-
- /**
- * The maximum number of times the request should be retried.
- * @type {number}
- * @private
- */
- this.maxRetries_ = goog.isDef(opt_maxRetries) ? opt_maxRetries : 1;
-
- /**
- * The number of attempts so far.
- * @type {number}
- * @private
- */
- this.attemptCount_ = 0;
-
- /**
- * Whether the request has been completed.
- * @type {boolean}
- * @private
- */
- this.completed_ = false;
-
- /**
- * Whether the request has been aborted.
- * @type {boolean}
- * @private
- */
- this.aborted_ = false;
-
- /**
- * Callback attached to the events of the XhrIo object.
- * @type {Function|undefined}
- * @private
- */
- this.xhrEventCallback_ = xhrEventCallback;
-
- /**
- * Callback function called when request is complete.
- * @type {Function|undefined}
- * @private
- */
- this.completeCallback_ = opt_callback;
-
- /**
- * The XhrIo instance handling this request. Set in handleAvailableXhr.
- * @type {goog.net.XhrIo}
- */
- this.xhrIo = null;
-
-};
-goog.inherits(goog.net.XhrManager.Request, goog.Disposable);
-
-
-/**
- * Gets the uri.
- * @return {string} The uri to make the request to.
- */
-goog.net.XhrManager.Request.prototype.getUrl = function() {
- return this.url_;
-};
-
-
-/**
- * Gets the send method.
- * @return {string} The send method.
- */
-goog.net.XhrManager.Request.prototype.getMethod = function() {
- return this.method_;
-};
-
-
-/**
- * Gets the post data.
- * @return {string|undefined} The post data.
- */
-goog.net.XhrManager.Request.prototype.getContent = function() {
- return this.content_;
-};
-
-
-/**
- * Gets the map of headers.
- * @return {Object|goog.structs.Map} The map of headers.
- */
-goog.net.XhrManager.Request.prototype.getHeaders = function() {
- return this.headers_;
-};
-
-
-/**
- * Gets the maximum number of times the request should be retried.
- * @return {number} The maximum number of times the request should be retried.
- */
-goog.net.XhrManager.Request.prototype.getMaxRetries = function() {
- return this.maxRetries_;
-};
-
-
-/**
- * Gets the number of attempts so far.
- * @return {number} The number of attempts so far.
- */
-goog.net.XhrManager.Request.prototype.getAttemptCount = function() {
- return this.attemptCount_;
-};
-
-
-/**
- * Increases the number of attempts so far.
- */
-goog.net.XhrManager.Request.prototype.increaseAttemptCount = function() {
- this.attemptCount_++;
-};
-
-
-/**
- * Returns whether the request has reached the maximum number of retries.
- * @return {boolean} Whether the request has reached the maximum number of
- * retries.
- */
-goog.net.XhrManager.Request.prototype.hasReachedMaxRetries = function() {
- return this.attemptCount_ > this.maxRetries_;
-};
-
-
-/**
- * Sets the completed status.
- * @param {boolean} complete The completed status.
- */
-goog.net.XhrManager.Request.prototype.setCompleted = function(complete) {
- this.completed_ = complete;
-};
-
-
-/**
- * Gets the completed status.
- * @return {boolean} The completed status.
- */
-goog.net.XhrManager.Request.prototype.getCompleted = function() {
- return this.completed_;
-};
-
-
-/**
- * Sets the aborted status.
- * @param {boolean} aborted True if the request was aborted, otherwise False.
- */
-goog.net.XhrManager.Request.prototype.setAborted = function(aborted) {
- this.aborted_ = aborted;
-};
-
-
-/**
- * Gets the aborted status.
- * @return {boolean} True if request was aborted, otherwise False.
- */
-goog.net.XhrManager.Request.prototype.getAborted = function() {
- return this.aborted_;
-};
-
-
-/**
- * Gets the callback attached to the events of the XhrIo object.
- * @return {Function|undefined} The callback attached to the events of the
- * XhrIo object.
- */
-goog.net.XhrManager.Request.prototype.getXhrEventCallback = function() {
- return this.xhrEventCallback_;
-};
-
-
-/**
- * Gets the callback for when the request is complete.
- * @return {Function|undefined} The callback for when the request is complete.
- */
-goog.net.XhrManager.Request.prototype.getCompleteCallback = function() {
- return this.completeCallback_;
-};
-
-
-/** @override */
-goog.net.XhrManager.Request.prototype.disposeInternal = function() {
- goog.net.XhrManager.Request.superClass_.disposeInternal.call(this);
- delete this.xhrEventCallback_;
- delete this.completeCallback_;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttp.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttp.js.svn-base
deleted file mode 100644
index da85a65..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttp.js.svn-base
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2006 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Low level handling of XMLHttpRequest.
- * @author arv@google.com (Erik Arvidsson)
- * @author dbk@google.com (David Barrett-Kahn)
- */
-
-goog.provide('goog.net.DefaultXmlHttpFactory');
-goog.provide('goog.net.XmlHttp');
-goog.provide('goog.net.XmlHttp.OptionType');
-goog.provide('goog.net.XmlHttp.ReadyState');
-
-goog.require('goog.net.WrapperXmlHttpFactory');
-goog.require('goog.net.XmlHttpFactory');
-
-
-/**
- * Static class for creating XMLHttpRequest objects.
- * @return {!(XMLHttpRequest|GearsHttpRequest)} A new XMLHttpRequest object.
- */
-goog.net.XmlHttp = function() {
- return goog.net.XmlHttp.factory_.createInstance();
-};
-
-
-/**
- * Gets the options to use with the XMLHttpRequest objects obtained using
- * the static methods.
- * @return {Object} The options.
- */
-goog.net.XmlHttp.getOptions = function() {
- return goog.net.XmlHttp.factory_.getOptions();
-};
-
-
-/**
- * Type of options that an XmlHttp object can have.
- * @enum {number}
- */
-goog.net.XmlHttp.OptionType = {
- /**
- * Whether a goog.nullFunction should be used to clear the onreadystatechange
- * handler instead of null.
- */
- USE_NULL_FUNCTION: 0,
-
- /**
- * NOTE(user): In IE if send() errors on a *local* request the readystate
- * is still changed to COMPLETE. We need to ignore it and allow the
- * try/catch around send() to pick up the error.
- */
- LOCAL_REQUEST_ERROR: 1
-};
-
-
-/**
- * Status constants for XMLHTTP, matches:
- * http://msdn.microsoft.com/library/default.asp?url=/library/
- * en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp
- * @enum {number}
- */
-goog.net.XmlHttp.ReadyState = {
- /**
- * Constant for when xmlhttprequest.readyState is uninitialized
- */
- UNINITIALIZED: 0,
-
- /**
- * Constant for when xmlhttprequest.readyState is loading.
- */
- LOADING: 1,
-
- /**
- * Constant for when xmlhttprequest.readyState is loaded.
- */
- LOADED: 2,
-
- /**
- * Constant for when xmlhttprequest.readyState is in an interactive state.
- */
- INTERACTIVE: 3,
-
- /**
- * Constant for when xmlhttprequest.readyState is completed
- */
- COMPLETE: 4
-};
-
-
-/**
- * The global factory instance for creating XMLHttpRequest objects.
- * @type {goog.net.XmlHttpFactory}
- * @private
- */
-goog.net.XmlHttp.factory_;
-
-
-/**
- * Sets the factories for creating XMLHttpRequest objects and their options.
- * @param {Function} factory The factory for XMLHttpRequest objects.
- * @param {Function} optionsFactory The factory for options.
- * @deprecated Use setGlobalFactory instead.
- */
-goog.net.XmlHttp.setFactory = function(factory, optionsFactory) {
- goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
- (/** @type {function() : !(XMLHttpRequest|GearsHttpRequest)} */ factory),
- (/** @type {function() : !Object}*/ optionsFactory)));
-};
-
-
-/**
- * Sets the global factory object.
- * @param {!goog.net.XmlHttpFactory} factory New global factory object.
- */
-goog.net.XmlHttp.setGlobalFactory = function(factory) {
- goog.net.XmlHttp.factory_ = factory;
-};
-
-
-
-/**
- * Default factory to use when creating xhr objects. You probably shouldn't be
- * instantiating this directly, but rather using it via goog.net.XmlHttp.
- * @extends {goog.net.XmlHttpFactory}
- * @constructor
- */
-goog.net.DefaultXmlHttpFactory = function() {
- goog.net.XmlHttpFactory.call(this);
-};
-goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory);
-
-
-/** @override */
-goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() {
- var progId = this.getProgId_();
- if (progId) {
- return new ActiveXObject(progId);
- } else {
- return new XMLHttpRequest();
- }
-};
-
-
-/** @override */
-goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {
- var progId = this.getProgId_();
- var options = {};
- if (progId) {
- options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true;
- options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true;
- }
- return options;
-};
-
-
-/**
- * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.
- * @type {?string}
- * @private
- */
-goog.net.DefaultXmlHttpFactory.prototype.ieProgId_ = null;
-
-
-/**
- * Initialize the private state used by other functions.
- * @return {string} The ActiveX PROG ID string to use to create xhr's in IE.
- * @private
- */
-goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {
- // The following blog post describes what PROG IDs to use to create the
- // XMLHTTP object in Internet Explorer:
- // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
- // However we do not (yet) fully trust that this will be OK for old versions
- // of IE on Win9x so we therefore keep the last 2.
- if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' &&
- typeof ActiveXObject != 'undefined') {
- // Candidate Active X types.
- var ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0',
- 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
- for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) {
- var candidate = ACTIVE_X_IDENTS[i];
- /** @preserveTry */
- try {
- new ActiveXObject(candidate);
- // NOTE(user): cannot assign progid and return candidate in one line
- // because JSCompiler complaings: BUG 658126
- this.ieProgId_ = candidate;
- return candidate;
- } catch (e) {
- // do nothing; try next choice
- }
- }
-
- // couldn't find any matches
- throw Error('Could not create ActiveXObject. ActiveX might be disabled,' +
- ' or MSXML might not be installed');
- }
-
- return /** @type {string} */ (this.ieProgId_);
-};
-
-
-//Set the global factory to an instance of the default factory.
-goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory());
diff --git a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttpfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttpfactory.js.svn-base
deleted file mode 100644
index ef2c719..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/.svn/text-base/xmlhttpfactory.js.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2010 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Interface for a factory for creating XMLHttpRequest objects
- * and metadata about them.
- * @author dbk@google.com (David Barrett-Kahn)
- */
-
-goog.provide('goog.net.XmlHttpFactory');
-
-
-
-/**
- * Abstract base class for an XmlHttpRequest factory.
- * @constructor
- */
-goog.net.XmlHttpFactory = function() {
-};
-
-
-/**
- * Cache of options - we only actually call internalGetOptions once.
- * @type {Object}
- * @private
- */
-goog.net.XmlHttpFactory.prototype.cachedOptions_ = null;
-
-
-/**
- * @return {!(XMLHttpRequest|GearsHttpRequest)} A new XMLHttpRequest instance.
- */
-goog.net.XmlHttpFactory.prototype.createInstance = goog.abstractMethod;
-
-
-/**
- * @return {Object} Options describing how xhr objects obtained from this
- * factory should be used.
- */
-goog.net.XmlHttpFactory.prototype.getOptions = function() {
- return this.cachedOptions_ ||
- (this.cachedOptions_ = this.internalGetOptions());
-};
-
-
-/**
- * Override this method in subclasses to preserve the caching offered by
- * getOptions().
- * @return {Object} Options describing how xhr objects obtained from this
- * factory should be used.
- * @protected
- */
-goog.net.XmlHttpFactory.prototype.internalGetOptions = goog.abstractMethod;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/browserchannel.js b/contexts/data/lib/closure-library/closure/goog/net/browserchannel.js
index fbfef88..7390500 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/browserchannel.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/browserchannel.js
@@ -39,6 +39,8 @@ goog.provide('goog.net.BrowserChannel.Event');
goog.provide('goog.net.BrowserChannel.Handler');
goog.provide('goog.net.BrowserChannel.LogSaver');
goog.provide('goog.net.BrowserChannel.QueuedMap');
+goog.provide('goog.net.BrowserChannel.ServerReachability');
+goog.provide('goog.net.BrowserChannel.ServerReachabilityEvent');
goog.provide('goog.net.BrowserChannel.Stat');
goog.provide('goog.net.BrowserChannel.StatEvent');
goog.provide('goog.net.BrowserChannel.State');
@@ -46,11 +48,13 @@ goog.provide('goog.net.BrowserChannel.TimingEvent');
goog.require('goog.Uri');
goog.require('goog.array');
+goog.require('goog.asserts');
goog.require('goog.debug.Logger');
goog.require('goog.debug.TextFormatter');
goog.require('goog.events.Event');
goog.require('goog.events.EventTarget');
goog.require('goog.json');
+goog.require('goog.json.EvalJsonProcessor');
goog.require('goog.net.BrowserTestChannel');
goog.require('goog.net.ChannelDebug');
goog.require('goog.net.ChannelRequest');
@@ -67,22 +71,22 @@ goog.require('goog.userAgent');
/**
* Encapsulates the logic for a single BrowserChannel.
*
- * @param {string} clientVersion An application-specific version number that
- * is sent to the server when connected.
+ * @param {string=} opt_clientVersion An application-specific version number
+ * that is sent to the server when connected.
* @constructor
*/
-goog.net.BrowserChannel = function(clientVersion) {
+goog.net.BrowserChannel = function(opt_clientVersion) {
/**
* The application specific version that is passed to the server.
- * @type {string}
+ * @type {?string}
* @private
*/
- this.clientVersion_ = clientVersion;
+ this.clientVersion_ = opt_clientVersion || null;
/**
* The current state of the BrowserChannel. It should be one of the
* goog.net.BrowserChannel.State constants.
- * @type {goog.net.BrowserChannel.State}
+ * @type {!goog.net.BrowserChannel.State}
* @private
*/
this.state_ = goog.net.BrowserChannel.State.INIT;
@@ -105,10 +109,18 @@ goog.net.BrowserChannel = function(clientVersion) {
/**
* The channel debug used for browserchannel logging
- * @type {goog.net.ChannelDebug}
+ * @type {!goog.net.ChannelDebug}
* @private
*/
this.channelDebug_ = new goog.net.ChannelDebug();
+
+ /**
+ * Parser for a response payload. Defaults to use
+ * {@code goog.json.unsafeParse}. The parser should return an array.
+ * @type {!goog.string.Parser}
+ * @private
+ */
+ this.parser_ = new goog.json.EvalJsonProcessor(null, true);
};
@@ -117,9 +129,10 @@ goog.net.BrowserChannel = function(clientVersion) {
* Simple container class for a (mapId, map) pair.
* @param {number} mapId The id for this map.
* @param {Object|goog.structs.Map} map The map itself.
+ * @param {Object=} opt_context The context associated with the map.
* @constructor
*/
-goog.net.BrowserChannel.QueuedMap = function(mapId, map) {
+goog.net.BrowserChannel.QueuedMap = function(mapId, map, opt_context) {
/**
* The id for this map.
* @type {number}
@@ -131,6 +144,12 @@ goog.net.BrowserChannel.QueuedMap = function(mapId, map) {
* @type {Object|goog.structs.Map}
*/
this.map = map;
+
+ /**
+ * The context for the map.
+ * @type {Object}
+ */
+ this.context = opt_context || null;
};
@@ -344,6 +363,61 @@ goog.net.BrowserChannel.prototype.backChannelAttemptId_;
/**
+ * The base part of the time before firing next retry request. Default is 5
+ * seconds. Note that a random delay is added (see {@link retryDelaySeedMs_})
+ * for all retries, and linear backoff is applied to the sum for subsequent
+ * retries.
+ * @type {number}
+ * @private
+ */
+goog.net.BrowserChannel.prototype.baseRetryDelayMs_ = 5 * 1000;
+
+
+/**
+ * A random time between 0 and this number of MS is added to the
+ * {@link baseRetryDelayMs_}. Default is 10 seconds.
+ * @type {number}
+ * @private
+ */
+goog.net.BrowserChannel.prototype.retryDelaySeedMs_ = 10 * 1000;
+
+
+/**
+ * Maximum number of attempts to connect to the server for forward channel
+ * requests. Defaults to 2.
+ * @type {number}
+ * @private
+ */
+goog.net.BrowserChannel.prototype.forwardChannelMaxRetries_ = 2;
+
+
+/**
+ * The timeout in milliseconds for a forward channel request. Defaults to 20
+ * seconds. Note that part of this timeout can be randomized.
+ * @type {number}
+ * @private
+ */
+goog.net.BrowserChannel.prototype.forwardChannelRequestTimeoutMs_ = 20 * 1000;
+
+
+/**
+ * A throttle time in ms for readystatechange events for the backchannel.
+ * Useful for throttling when ready state is INTERACTIVE (partial data).
+ *
+ * This throttle is useful if the server sends large data chunks down the
+ * backchannel. It prevents examining XHR partial data on every
+ * readystate change event. This is useful because large chunks can
+ * trigger hundreds of readystatechange events, each of which takes ~5ms
+ * or so to handle, in turn making the UI unresponsive for a significant period.
+ *
+ * If set to zero no throttle is used.
+ * @type {number}
+ * @private
+ */
+goog.net.BrowserChannel.prototype.readyStateChangeThrottleMs_ = 0;
+
+
+/**
* The latest protocol version that this class supports. We request this version
* from the server when opening the connection. Should match
* com.google.net.browserchannel.BrowserChannel.LATEST_CHANNEL_VERSION.
@@ -383,14 +457,6 @@ goog.net.BrowserChannel.State = {
/**
- * Maximum number of attempts to connect to the server for forward channel
- * requests.
- * @type {number}
- */
-goog.net.BrowserChannel.FORWARD_CHANNEL_MAX_RETRIES = 2;
-
-
-/**
* The timeout in milliseconds for a forward channel request.
* @type {number}
*/
@@ -406,22 +472,6 @@ goog.net.BrowserChannel.BACK_CHANNEL_MAX_RETRIES = 3;
/**
- * Default timeout in MS before the initial retry. Subsequent retries will be
- * slower.
- * @type {number}
- */
-goog.net.BrowserChannel.RETRY_DELAY_MS = 5 * 1000;
-
-
-/**
- * We will add a random time between 0 and this number of MS to retries to
- * the retry time for this request.
- * @type {number}
- */
-goog.net.BrowserChannel.RETRY_DELAY_SEED = 10 * 1000;
-
-
-/**
* A number in MS of how long we guess the maxmium amount of time a round trip
* to the server should take. In the future this could be substituted with a
* real measurement of the RTT.
@@ -471,7 +521,10 @@ goog.net.BrowserChannel.Error = {
BAD_DATA: 10,
/** An error due to a response that doesn't start with the magic cookie. */
- BAD_RESPONSE: 11
+ BAD_RESPONSE: 11,
+
+ /** ActiveX is blocked by the machine's admin settings. */
+ ACTIVE_X_BLOCKED: 12
};
@@ -587,6 +640,52 @@ goog.inherits(goog.net.BrowserChannel.TimingEvent, goog.events.Event);
/**
+ * The type of event that occurs every time some information about how reachable
+ * the server is is discovered.
+ */
+goog.net.BrowserChannel.Event.SERVER_REACHABILITY_EVENT =
+ 'serverreachability';
+
+
+/**
+ * Types of events which reveal information about the reachability of the
+ * server.
+ * @enum {number}
+ */
+goog.net.BrowserChannel.ServerReachability = {
+ REQUEST_MADE: 1,
+ REQUEST_SUCCEEDED: 2,
+ REQUEST_FAILED: 3,
+ BACK_CHANNEL_ACTIVITY: 4
+};
+
+
+
+/**
+ * Event class for goog.net.BrowserChannel.Event.SERVER_REACHABILITY_EVENT.
+ *
+ * @param {goog.events.EventTarget} target The stat event target for
+ the browser channel.
+ * @param {goog.net.BrowserChannel.ServerReachability} reachabilityType The
+ * reachability event type.
+ * @constructor
+ * @extends {goog.events.Event}
+ */
+goog.net.BrowserChannel.ServerReachabilityEvent = function(target,
+ reachabilityType) {
+ goog.events.Event.call(this,
+ goog.net.BrowserChannel.Event.SERVER_REACHABILITY_EVENT, target);
+
+ /**
+ * @type {goog.net.BrowserChannel.ServerReachability}
+ */
+ this.reachabilityType = reachabilityType;
+};
+goog.inherits(goog.net.BrowserChannel.ServerReachabilityEvent,
+ goog.events.Event);
+
+
+/**
* Enum that identifies events for statistics that are interesting to track.
* TODO(user) - Change name not to use Event or use EventTarget
* @enum {number}
@@ -672,7 +771,16 @@ goog.net.BrowserChannel.Stat = {
* Event indicating that we have determined that our hanging GET is not
* receiving data when it should be. Thus it is dead dead and will be retried.
*/
- BACKCHANNEL_DEAD: 20
+ BACKCHANNEL_DEAD: 20,
+
+ /**
+ * The browser declared itself offline during the lifetime of a request, or
+ * was offline when a request was initially made.
+ */
+ BROWSER_OFFLINE: 21,
+
+ /** ActiveX is blocked by the machine's admin settings. */
+ ACTIVE_X_BLOCKED: 22
};
@@ -713,7 +821,9 @@ goog.net.BrowserChannel.prototype.getChannelDebug = function() {
*/
goog.net.BrowserChannel.prototype.setChannelDebug = function(
channelDebug) {
- this.channelDebug_ = channelDebug;
+ if (goog.isDefAndNotNull(channelDebug)) {
+ this.channelDebug_ = channelDebug;
+ }
};
@@ -769,8 +879,8 @@ goog.net.BrowserChannel.endExecutionHook_ = function() { };
* @param {number=} opt_retryId The retry id for this request.
* @return {goog.net.ChannelRequest} The created channel request.
*/
-goog.net.BrowserChannel.createChannelRequest = function(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {
+goog.net.BrowserChannel.createChannelRequest = function(channel, channelDebug,
+ opt_sessionId, opt_requestId, opt_retryId) {
return new goog.net.ChannelRequest(
channel,
channelDebug,
@@ -785,20 +895,20 @@ goog.net.BrowserChannel.createChannelRequest = function(
*
* @param {string} testPath The path for the test connection.
* @param {string} channelPath The path for the channel connection.
- * @param {Object} extraParams Extra parameter keys and values to add to the
- * requests.
+ * @param {Object=} opt_extraParams Extra parameter keys and values to add to
+ * the requests.
* @param {string=} opt_oldSessionId Session ID from a previous session.
* @param {number=} opt_oldArrayId The last array ID from a previous session.
*/
goog.net.BrowserChannel.prototype.connect = function(testPath, channelPath,
- extraParams, opt_oldSessionId, opt_oldArrayId) {
+ opt_extraParams, opt_oldSessionId, opt_oldArrayId) {
this.channelDebug_.debug('connect()');
goog.net.BrowserChannel.notifyStatEvent(
goog.net.BrowserChannel.Stat.CONNECT_ATTEMPT);
this.path_ = channelPath;
- this.extraParams_ = extraParams || {};
+ this.extraParams_ = opt_extraParams || {};
// Attach parameters about the previous session if reconnecting.
if (opt_oldSessionId && goog.isDef(opt_oldArrayId)) {
@@ -831,8 +941,9 @@ goog.net.BrowserChannel.prototype.disconnect = function() {
var request = goog.net.BrowserChannel.createChannelRequest(
this, this.channelDebug_, this.sid_, rid);
request.sendUsingImgTag(uri);
- this.onClose_();
}
+
+ this.onClose_();
};
@@ -860,6 +971,7 @@ goog.net.BrowserChannel.prototype.connectTest_ = function(testPath) {
this.connectionTest_ = new goog.net.BrowserTestChannel(
this, this.channelDebug_);
this.connectionTest_.setExtraHeaders(this.extraHeaders_);
+ this.connectionTest_.setParser(this.parser_);
this.connectionTest_.connect(testPath);
};
@@ -933,6 +1045,18 @@ goog.net.BrowserChannel.prototype.setExtraHeaders = function(extraHeaders) {
/**
+ * Sets the throttle for handling onreadystatechange events for the request.
+ *
+ * @param {number} throttle The throttle in ms. A value of zero indicates
+ * no throttle.
+ */
+goog.net.BrowserChannel.prototype.setReadyStateChangeThrottle = function(
+ throttle) {
+ this.readyStateChangeThrottleMs_ = throttle;
+};
+
+
+/**
* Returns the handler used for channel callback events.
*
* @return {goog.net.BrowserChannel.Handler} The handler.
@@ -1016,8 +1140,9 @@ goog.net.BrowserChannel.prototype.setAllowChunkedMode =
* suitable for the wire and then reconstituted as a Map data structure that
* the server can process.
* @param {Object|goog.structs.Map} map The map to send.
+ * @param {?Object=} opt_context The context associated with the map.
*/
-goog.net.BrowserChannel.prototype.sendMap = function(map) {
+goog.net.BrowserChannel.prototype.sendMap = function(map, opt_context) {
if (this.state_ == goog.net.BrowserChannel.State.CLOSED) {
throw Error('Invalid operation: sending map when state is closed');
}
@@ -1034,7 +1159,8 @@ goog.net.BrowserChannel.prototype.sendMap = function(map) {
}
this.outgoingMaps_.push(
- new goog.net.BrowserChannel.QueuedMap(this.nextMapId_++, map));
+ new goog.net.BrowserChannel.QueuedMap(this.nextMapId_++, map,
+ opt_context));
if (this.state_ == goog.net.BrowserChannel.State.OPENING ||
this.state_ == goog.net.BrowserChannel.State.OPENED) {
this.ensureForwardChannel_();
@@ -1078,8 +1204,28 @@ goog.net.BrowserChannel.prototype.setFailFast = function(failFast) {
* in fail-fast mode.
*/
goog.net.BrowserChannel.prototype.getForwardChannelMaxRetries = function() {
- return this.failFast_ ?
- 0 : goog.net.BrowserChannel.FORWARD_CHANNEL_MAX_RETRIES;
+ return this.failFast_ ? 0 : this.forwardChannelMaxRetries_;
+};
+
+
+/**
+ * Sets the maximum number of attempts to connect to the server for forward
+ * channel requests.
+ * @param {number} retries The maximum number of attempts.
+ */
+goog.net.BrowserChannel.prototype.setForwardChannelMaxRetries =
+ function(retries) {
+ this.forwardChannelMaxRetries_ = retries;
+};
+
+
+/**
+ * Sets the timeout for a forward channel request.
+ * @param {number} timeoutMs The timeout in milliseconds.
+ */
+goog.net.BrowserChannel.prototype.setForwardChannelRequestTimeout =
+ function(timeoutMs) {
+ this.forwardChannelRequestTimeoutMs_ = timeoutMs;
};
@@ -1138,6 +1284,17 @@ goog.net.BrowserChannel.prototype.hasOutstandingRequests = function() {
/**
+ * Sets a new parser for the response payload. A custom parser may be set to
+ * avoid using eval(), for example. By default, the parser uses
+ * {@code goog.json.unsafeParse}.
+ * @param {!goog.string.Parser} parser Parser.
+ */
+goog.net.BrowserChannel.prototype.setParser = function(parser) {
+ this.parser_ = parser;
+};
+
+
+/**
* Returns the number of outstanding requests.
* @return {number} The number of outstanding requests to the server.
* @private
@@ -1331,9 +1488,8 @@ goog.net.BrowserChannel.prototype.makeForwardChannelRequest_ =
// randomize from 50%-100% of the forward channel timeout to avoid
// a big hit if servers happen to die at once.
request.setTimeout(
- Math.round(goog.net.BrowserChannel.FORWARD_CHANNEL_RETRY_TIMEOUT * 0.50) +
- Math.round(goog.net.BrowserChannel.FORWARD_CHANNEL_RETRY_TIMEOUT * 0.50 *
- Math.random()));
+ Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50) +
+ Math.round(this.forwardChannelRequestTimeoutMs_ * 0.50 * Math.random()));
this.forwardChannelRequest_ = request;
request.xmlHttpPost(uri, requestText, true);
};
@@ -1493,6 +1649,8 @@ goog.net.BrowserChannel.prototype.startBackChannel_ = function() {
'rpc',
this.backChannelAttemptId_);
this.backChannelRequest_.setExtraHeaders(this.extraHeaders_);
+ this.backChannelRequest_.setReadyStateChangeThrottle(
+ this.readyStateChangeThrottleMs_);
var uri = this.backChannelUri_.clone();
uri.setParameterValue('RID', 'rpc');
uri.setParameterValue('SID', this.sid_);
@@ -1596,12 +1754,12 @@ goog.net.BrowserChannel.prototype.onRequestData =
if (this.channelVersion_ > 7) {
var response;
try {
- response = (/** @type {Array} */ goog.json.unsafeParse(responseText));
+ response = this.parser_.parse(responseText);
} catch (ex) {
response = null;
}
if (goog.isArray(response) && response.length == 3) {
- this.handlePostResponse_(response);
+ this.handlePostResponse_(/** @type {Array} */ (response));
} else {
this.channelDebug_.debug('Bad POST response data returned');
this.signalError_(goog.net.BrowserChannel.Error.BAD_RESPONSE);
@@ -1616,7 +1774,9 @@ goog.net.BrowserChannel.prototype.onRequestData =
this.clearDeadBackchannelTimer_();
}
if (!goog.string.isEmpty(responseText)) {
- this.onInput_(/** @type {Array} */ (goog.json.unsafeParse(responseText)));
+ var response = this.parser_.parse(responseText);
+ goog.asserts.assert(goog.isArray(response));
+ this.onInput_(/** @type {Array} */ (response));
}
}
};
@@ -1765,6 +1925,7 @@ goog.net.BrowserChannel.prototype.clearDeadBackchannelTimer_ = function() {
goog.net.BrowserChannel.isFatalError_ =
function(error, statusCode) {
return error == goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID ||
+ error == goog.net.ChannelRequest.Error.ACTIVE_X_BLOCKED ||
(error == goog.net.ChannelRequest.Error.STATUS &&
statusCode > 0);
};
@@ -1804,6 +1965,7 @@ goog.net.BrowserChannel.prototype.onRequestComplete =
goog.now() - request.getRequestStartTime(),
this.forwardChannelRetryCount_);
this.ensureForwardChannel_();
+ this.onSuccess_();
this.pendingMaps_.length = 0;
} else { // i.e., back-channel
this.ensureBackChannel_();
@@ -1850,6 +2012,9 @@ goog.net.BrowserChannel.prototype.onRequestComplete =
case goog.net.ChannelRequest.Error.UNKNOWN_SESSION_ID:
this.signalError_(goog.net.BrowserChannel.Error.UNKNOWN_SESSION_ID);
break;
+ case goog.net.ChannelRequest.Error.ACTIVE_X_BLOCKED:
+ this.signalError_(goog.net.BrowserChannel.Error.ACTIVE_X_BLOCKED);
+ break;
default:
this.signalError_(goog.net.BrowserChannel.Error.REQUEST_FAILED);
break;
@@ -1863,8 +2028,8 @@ goog.net.BrowserChannel.prototype.onRequestComplete =
* @private
*/
goog.net.BrowserChannel.prototype.getRetryTime_ = function(retryCount) {
- var retryTime = goog.net.BrowserChannel.RETRY_DELAY_MS +
- Math.floor(Math.random() * goog.net.BrowserChannel.RETRY_DELAY_SEED);
+ var retryTime = this.baseRetryDelayMs_ +
+ Math.floor(Math.random() * this.retryDelaySeedMs_);
if (!this.isActive()) {
this.channelDebug_.debug('Inactive channel');
retryTime =
@@ -1877,6 +2042,18 @@ goog.net.BrowserChannel.prototype.getRetryTime_ = function(retryCount) {
/**
+ * @param {number} baseDelayMs The base part of the retry delay, in ms.
+ * @param {number} delaySeedMs A random delay between 0 and this is added to
+ * the base part.
+ */
+goog.net.BrowserChannel.prototype.setRetryDelay = function(baseDelayMs,
+ delaySeedMs) {
+ this.baseRetryDelayMs_ = baseDelayMs;
+ this.retryDelaySeedMs_ = delaySeedMs;
+};
+
+
+/**
* Processes the data returned by the server.
* @param {Array} respArray The response array returned by the server.
* @private
@@ -2001,6 +2178,17 @@ goog.net.BrowserChannel.prototype.testGoogleComCallback_ = function(networkUp) {
/**
+ * Called when messages have been successfully sent from the queue.
+ * @private
+ */
+goog.net.BrowserChannel.prototype.onSuccess_ = function() {
+ if (this.handler_) {
+ this.handler_.channelSuccess(this, this.pendingMaps_);
+ }
+};
+
+
+/**
* Called when we've determined the final error for a channel. It closes the
* notifiers the handler of the error and closes the channel.
* @param {goog.net.BrowserChannel.Error} error The error code for the failure.
@@ -2197,6 +2385,20 @@ goog.net.BrowserChannel.getStatEventTarget = function() {
/**
+ * Notify the channel that a particular fine grained network event has occurred.
+ * Should be considered package-private.
+ * @param {goog.net.BrowserChannel.ServerReachability} reachabilityType The
+ * reachability event type.
+ */
+goog.net.BrowserChannel.prototype.notifyServerReachabilityEvent = function(
+ reachabilityType) {
+ var target = goog.net.BrowserChannel.statEventTarget_;
+ target.dispatchEvent(new goog.net.BrowserChannel.ServerReachabilityEvent(
+ target, reachabilityType));
+};
+
+
+/**
* Helper function to call the stat event callback.
* @param {goog.net.BrowserChannel.Stat} stat The stat.
*/
@@ -2229,7 +2431,9 @@ goog.net.BrowserChannel.notifyTimingEvent = function(size, rtt, retries) {
* Currently, we only use secondary domains when using Trident's ActiveXObject,
* because it supports cross-domain requests out of the box. Even if we wanted
* to use secondary domains on Gecko/Webkit, they wouldn't work due to
- * security restrictions on cross-origin XHRs.
+ * security restrictions on cross-origin XHRs. Note that in IE10 we no longer
+ * use ActiveX since it's not supported in Metro mode and IE10 supports XHR
+ * streaming.
*
* If you need to use secondary domains on other browsers, you'll need
* to override this method in a subclass, and make sure that those browsers
@@ -2239,7 +2443,7 @@ goog.net.BrowserChannel.notifyTimingEvent = function(size, rtt, retries) {
* @see http://code.google.com/p/closure-library/issues/detail?id=339
*/
goog.net.BrowserChannel.prototype.shouldUseSecondaryDomains = function() {
- return goog.userAgent.IE;
+ return !goog.net.ChannelRequest.supportsXhrStreaming();
};
@@ -2385,6 +2589,20 @@ goog.net.BrowserChannel.Handler.prototype.channelHandleArray =
/**
+ * Indicates maps were successfully sent on the BrowserChannel.
+ *
+ * @param {goog.net.BrowserChannel} browserChannel The browser channel.
+ * @param {Array.<goog.net.BrowserChannel.QueuedMap>} deliveredMaps The
+ * array of maps that have been delivered to the server. This is a direct
+ * reference to the internal BrowserChannel array, so a copy should be made
+ * if the caller desires a reference to the data.
+ */
+goog.net.BrowserChannel.Handler.prototype.channelSuccess =
+ function(browserChannel, deliveredMaps) {
+};
+
+
+/**
* Indicates an error occurred on the BrowserChannel.
*
* @param {goog.net.BrowserChannel} browserChannel The browser channel.
diff --git a/contexts/data/lib/closure-library/closure/goog/net/browserchannel_test.html b/contexts/data/lib/closure-library/closure/goog/net/browserchannel_test.html
index 89bce9e..1fc0c5e 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/browserchannel_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/browserchannel_test.html
@@ -11,8 +11,8 @@ See the COPYING file for details.
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.net.BrowserChannel</title>
-<script type="text/javascript" src="../base.js"></script>
-<script type="text/javascript">
+<script src="../base.js"></script>
+<script>
goog.require('goog.Timer');
goog.require('goog.dom');
goog.require('goog.functions');
@@ -23,14 +23,14 @@ See the COPYING file for details.
goog.require('goog.string.StringBuffer');
goog.require('goog.structs.Map');
goog.require('goog.testing.MockClock');
+ goog.require('goog.testing.PropertyReplacer');
+ goog.require('goog.testing.recordFunction');
goog.require('goog.testing.asserts');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
-
-<!-- Define unit tests. -->
-<script type="text/javascript" >
+<script>
/**
* Delay between a network failure and the next network request.
@@ -42,10 +42,12 @@ var RETRY_TIME = 1000;
*/
var ALL_DAY_MS = 1000 * 60 * 60 * 24;
+var stubs = new goog.testing.PropertyReplacer();
+
var browserChannel;
+var deliveredMaps;
var handler;
var mockClock;
-var sb;
var gotError;
var numStatEvents;
var lastStatEvent;
@@ -56,20 +58,38 @@ var lastPostRetryCount;
// Set to true to see the channel debug output in the browser window.
var debug = false;
+// Debug message to print out when debug is true.
+var debugMessage = '';
function debugToWindow(message) {
if (debug) {
- sb.append(message + '<br>');
- goog.dom.getElement('debug').innerHTML = sb.toString();
+ debugMessage += message + '<br>';
+ goog.dom.getElement('debug').innerHTML = debugMessage;
}
}
/**
+ * Stubs goog.net.tmpnetwork to always time out. It maintains the
+ * contract given by goog.net.tmpnetwork.testGoogleCom, but always
+ * times out (calling callback(false)).
+ *
+ * stubTmpnetwork should be called in tests that require it before
+ * a call to testGoogleCom happens. It is reset at tearDown.
+ */
+function stubTmpnetwork() {
+ stubs.set(goog.net.tmpnetwork, 'testLoadImage',
+ function(url, timeout, callback) {
+ goog.Timer.callOnce(goog.partial(callback, false), timeout);
+ });
+}
+
+
+/**
* Mock ChannelRequest.
+ * @constructor
*/
-function MockChannelRequest() {}
-MockChannelRequest = function(channel, channelDebug, opt_sessionId,
+var MockChannelRequest = function(channel, channelDebug, opt_sessionId,
opt_requestId, opt_retryId) {
this.channel_ = channel;
this.channelDebug_ = channelDebug;
@@ -92,6 +112,9 @@ MockChannelRequest.prototype.setExtraHeaders = function(extraHeaders) {};
MockChannelRequest.prototype.setTimeout = function(timeout) {};
+MockChannelRequest.prototype.setReadyStateChangeThrottle =
+ function(throttle) {};
+
MockChannelRequest.prototype.xmlHttpPost = function(uri, postData,
decodeChunks) {
this.channelDebug_.debug('---> POST: ' + uri + ', ' + postData + ', ' +
@@ -156,7 +179,6 @@ function setUpPage() {
return new MockChannelRequest(
channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId);
};
- sb = new goog.string.StringBuffer();
// Mock out the stat notification code.
goog.net.BrowserChannel.notifyStatEvent = function(stat) {
@@ -188,6 +210,9 @@ function setUp() {
handler.channelError = function(channel, error) {
gotError = true;
};
+ handler.channelSuccess = function(channel, maps) {
+ deliveredMaps = goog.array.clone(maps);
+ };
handler.channelClosed = function(
channel, opt_pendingMaps, opt_undeliveredMaps) {
// Mock out the handler, and let it set a formatted user readable string
@@ -222,6 +247,7 @@ function setUp() {
function tearDown() {
mockClock.dispose();
+ stubs.reset();
debugToWindow('<hr>');
}
@@ -235,7 +261,9 @@ function formatArrayOfMaps(arrayOfMaps) {
var map = arrayOfMaps[i];
var keys = map.map.getKeys();
for (var j = 0; j < keys.length; j++) {
- result.push(keys[j] + ':' + map.map.get(keys[j]));
+ var tmp = keys[j] + ':' + map.map.get(keys[j]) + (map.context ?
+ ':' + map.context : '');
+ result.push(tmp);
}
}
return result.join(', ');
@@ -267,15 +295,27 @@ function testFormatArrayOfMaps() {
b.push(new goog.net.BrowserChannel.QueuedMap(0, map3));
assertEquals('k1:v1, k2:v2, k3:v3, k4:v4, k5:v5, k6:v6',
formatArrayOfMaps(b));
+
+ // One map with a context.
+ var c = [];
+ c.push(new goog.net.BrowserChannel.QueuedMap(0, map1, 'c1'));
+ assertEquals('k1:v1:c1, k2:v2:c1',
+ formatArrayOfMaps(c));
}
-function connect(opt_serverVersion, opt_hostPrefix, opt_uriPrefix) {
+function connectForwardChannel(
+ opt_serverVersion, opt_hostPrefix, opt_uriPrefix) {
var uriPrefix = opt_uriPrefix || '';
browserChannel.connect(uriPrefix + '/test', uriPrefix + '/bind', null);
mockClock.tick(0);
completeTestConnection();
completeForwardChannel(opt_serverVersion, opt_hostPrefix);
+}
+
+
+function connect(opt_serverVersion, opt_hostPrefix, opt_uriPrefix) {
+ connectForwardChannel(opt_serverVersion, opt_hostPrefix, opt_uriPrefix);
completeBackChannel();
}
@@ -411,10 +451,20 @@ function responseUnknownSessionId() {
}
-function sendMap(key, value) {
+function responseActiveXBlocked() {
+ browserChannel.backChannelRequest_.lastError_ =
+ goog.net.ChannelRequest.Error.ACTIVE_X_BLOCKED;
+ browserChannel.backChannelRequest_.successful_ = false;
+ browserChannel.onRequestComplete(
+ browserChannel.backChannelRequest_);
+ mockClock.tick(0);
+}
+
+
+function sendMap(key, value, opt_context) {
var map = new goog.structs.Map();
map.set(key, value);
- browserChannel.sendMap(map);
+ browserChannel.sendMap(map, opt_context);
mockClock.tick(0);
}
@@ -509,6 +559,7 @@ function testSendMap() {
sendMap('foo', 'bar');
responseVersion7();
assertEquals(2, numTimingEvents);
+ assertEquals('foo:bar', formatArrayOfMaps(deliveredMaps));
}
@@ -516,8 +567,10 @@ function testSendMap_twice() {
connect();
sendMap('foo1', 'bar1');
responseVersion7();
+ assertEquals('foo1:bar1', formatArrayOfMaps(deliveredMaps));
sendMap('foo2', 'bar2');
responseVersion7();
+ assertEquals('foo2:bar2', formatArrayOfMaps(deliveredMaps));
}
@@ -610,6 +663,8 @@ function testTimingEvent(){
* reports an error, and prevents another request from firing.
*/
function testSetFailFastWhileWaitingForRetry() {
+ stubTmpnetwork();
+
connect();
assertEquals(1, numTimingEvents);
@@ -637,12 +692,13 @@ function testSetFailFastWhileWaitingForRetry() {
assertEquals(1, browserChannel.forwardChannelRetryCount_);
assertTrue(gotError);
+ assertEquals(0, deliveredMaps.length);
// We get the error immediately before starting to ping google.com.
// Simulate that timing out. We should get a network error in addition to the
// initial failure.
gotError = false;
mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
+ assertTrue('No error after tmpnetwork ping timed out.', gotError);
// Make sure no more retry timers are firing.
mockClock.tick(ALL_DAY_MS);
@@ -658,6 +714,8 @@ function testSetFailFastWhileWaitingForRetry() {
* reports an error, and prevents another request from firing.
*/
function testSetFailFastWhileRetryXhrIsInFlight() {
+ stubTmpnetwork();
+
connect();
assertEquals(1, numTimingEvents);
@@ -702,7 +760,7 @@ function testSetFailFastWhileRetryXhrIsInFlight() {
// Simulate that timing out. We should get a network error in addition to the
gotError = false;
mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
+ assertTrue('No error after tmpnetwork ping timed out.', gotError);
// Make sure no more retry timers are firing.
mockClock.tick(ALL_DAY_MS);
@@ -717,6 +775,8 @@ function testSetFailFastWhileRetryXhrIsInFlight() {
* Makes sure that setting fail fast while not retrying doesn't cause a failure.
*/
function testSetFailFastAtRetryCount() {
+ stubTmpnetwork();
+
connect();
assertEquals(1, numTimingEvents);
@@ -744,7 +804,7 @@ function testSetFailFastAtRetryCount() {
// initial failure.
gotError = false;
mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
- assertTrue(gotError);
+ assertTrue('No error after tmpnetwork ping timed out.', gotError);
// Make sure no more retry timers are firing.
mockClock.tick(ALL_DAY_MS);
@@ -756,6 +816,8 @@ function testSetFailFastAtRetryCount() {
function testRequestFailedClosesChannel() {
+ stubTmpnetwork();
+
connect();
assertEquals(1, numTimingEvents);
@@ -774,6 +836,8 @@ function testRequestFailedClosesChannel() {
function testStatEventReportedOnlyOnce() {
+ stubTmpnetwork();
+
connect();
sendMap('foo', 'bar');
numStatEvents = 0;
@@ -789,7 +853,25 @@ function testStatEventReportedOnlyOnce() {
}
+function testActiveXBlockedEventReportedOnlyOnce() {
+ stubTmpnetwork();
+
+ connectForwardChannel();
+ numStatEvents = 0;
+ lastStatEvent = null;
+ responseActiveXBlocked();
+
+ assertEquals(1, numStatEvents);
+ assertEquals(goog.net.BrowserChannel.Stat.ERROR_OTHER, lastStatEvent);
+
+ mockClock.tick(goog.net.tmpnetwork.GOOGLECOM_TIMEOUT);
+ assertEquals('No new stat events should be reported.', 1, numStatEvents);
+}
+
+
function testStatEventReportedOnlyOnce_onNetworkUp() {
+ stubTmpnetwork();
+
connect();
sendMap('foo', 'bar');
numStatEvents = 0;
@@ -809,6 +891,8 @@ function testStatEventReportedOnlyOnce_onNetworkUp() {
function testStatEventReportedOnlyOnce_onNetworkDown() {
+ stubTmpnetwork();
+
connect();
sendMap('foo', 'bar');
numStatEvents = 0;
@@ -895,19 +979,19 @@ function testUndeliveredMaps_clearsPendingMapsAfterNotifying() {
}
-function testUndeliveredMaps_notifiesWhenNoResponseReceived() {
+function testUndeliveredMaps_notifiesWithContext() {
connect();
// First send two messages that succeed.
- sendMap('foo1', 'bar1');
+ sendMap('foo1', 'bar1', 'context1');
responseVersion7();
- sendMap('foo2', 'bar2');
+ sendMap('foo2', 'bar2', 'context2');
responseVersion7();
// Pretend the server hangs and no longer responds.
- sendMap('foo3', 'bar3');
- sendMap('foo4', 'bar4');
- sendMap('foo5', 'bar5');
+ sendMap('foo3', 'bar3', 'context3');
+ sendMap('foo4', 'bar4', 'context4');
+ sendMap('foo5', 'bar5', 'context5');
// Give up.
disconnect();
@@ -915,8 +999,9 @@ function testUndeliveredMaps_notifiesWhenNoResponseReceived() {
// Assert that we are informed of any undelivered messages; both about
// #3 that was sent but which we don't know if the server received, and
// #4 and #5 which remain in the outgoing maps and have not yet been sent.
- assertEquals('foo3:bar3', handler.pendingMapsString);
- assertEquals('foo4:bar4, foo5:bar5', handler.undeliveredMapsString);
+ assertEquals('foo3:bar3:context3', handler.pendingMapsString);
+ assertEquals('foo4:bar4:context4, foo5:bar5:context5',
+ handler.undeliveredMapsString);
}
@@ -937,6 +1022,8 @@ function testUndeliveredMaps_serviceUnavailable() {
function testUndeliveredMaps_onPingTimeout() {
+ stubTmpnetwork();
+
connect();
// Send a message.
@@ -1194,6 +1281,30 @@ function testPathWithHost() {
assertEquals(browserChannel.forwardChannelUri_.getDomain(), 'example.com');
}
+function testSetParser() {
+ var recordUnsafeParse = goog.testing.recordFunction(
+ goog.json.unsafeParse);
+ var parser = {};
+ parser.parse = recordUnsafeParse;
+ browserChannel.setParser(parser);
+
+ connect();
+ assertEquals(3, recordUnsafeParse.getCallCount());
+
+ var call3 = recordUnsafeParse.popLastCall();
+ var call2 = recordUnsafeParse.popLastCall();
+ var call1 = recordUnsafeParse.popLastCall();
+
+ assertEquals(1, call1.getArguments().length);
+ assertEquals('["b"]', call1.getArgument(0));
+
+ assertEquals(1, call2.getArguments().length);
+ assertEquals('[[0,["c","1234567890ABCDEF",null]]]', call2.getArgument(0));
+
+ assertEquals(1, call3.getArguments().length);
+ assertEquals('[[1,["foo"]]]', call3.getArgument(0));
+}
+
</script>
<div id="debug" style="font-size: small"></div>
</body>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/browsertestchannel.js b/contexts/data/lib/closure-library/closure/goog/net/browsertestchannel.js
index 6a66de7..cfc9257 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/browsertestchannel.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/browsertestchannel.js
@@ -25,10 +25,11 @@
goog.provide('goog.net.BrowserTestChannel');
-goog.require('goog.json');
+goog.require('goog.json.EvalJsonProcessor');
goog.require('goog.net.ChannelRequest');
goog.require('goog.net.ChannelRequest.Error');
goog.require('goog.net.tmpnetwork');
+goog.require('goog.string.Parser');
goog.require('goog.userAgent');
@@ -56,6 +57,14 @@ goog.net.BrowserTestChannel = function(channel, channelDebug) {
* @private
*/
this.channelDebug_ = channelDebug;
+
+ /**
+ * Parser for a response payload. Defaults to use
+ * {@code goog.json.unsafeParse}. The parser should return an array.
+ * @type {goog.string.Parser}
+ * @private
+ */
+ this.parser_ = new goog.json.EvalJsonProcessor(null, true);
};
@@ -229,6 +238,17 @@ goog.net.BrowserTestChannel.prototype.setExtraHeaders = function(extraHeaders) {
/**
+ * Sets a new parser for the response payload. A custom parser may be set to
+ * avoid using eval(), for example.
+ * By default, the parser uses {@code goog.json.unsafeParse}.
+ * @param {!goog.string.Parser} parser Parser.
+ */
+goog.net.BrowserTestChannel.prototype.setParser = function(parser) {
+ this.parser_ = parser;
+};
+
+
+/**
* Starts the test channel. This initiates connections to the server.
*
* @param {string} path The relative uri for the test connection.
@@ -270,6 +290,8 @@ goog.net.BrowserTestChannel.prototype.checkBlocked_ = function() {
goog.bind(this.checkBlockedCallback_, this),
goog.net.BrowserTestChannel.BLOCKED_RETRIES_,
goog.net.BrowserTestChannel.BLOCKED_PAUSE_BETWEEN_RETRIES_);
+ this.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_MADE);
};
@@ -289,6 +311,14 @@ goog.net.BrowserTestChannel.prototype.checkBlockedCallback_ = function(
goog.net.BrowserChannel.Stat.CHANNEL_BLOCKED);
this.channel_.testConnectionBlocked(this);
}
+
+ // We don't dispatch a REQUEST_FAILED server reachability event when the
+ // block request fails, as such a failure is not a good signal that the
+ // server has actually become unreachable.
+ if (succeeded) {
+ this.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_SUCCEEDED);
+ }
};
@@ -375,7 +405,7 @@ goog.net.BrowserTestChannel.prototype.onRequestData =
}
/** @preserveTry */
try {
- var respArray = goog.json.unsafeParse(responseText);
+ var respArray = this.parser_.parse(responseText);
} catch (e) {
this.channelDebug_.dumpException(e);
this.channel_.testConnectionFailure(this,
@@ -539,3 +569,14 @@ goog.net.BrowserTestChannel.prototype.checkForEarlyNonBuffered_ =
return goog.net.ChannelRequest.supportsXhrStreaming() ||
ms < goog.net.BrowserTestChannel.MIN_TIME_EXPECTED_BETWEEN_DATA_;
};
+
+
+/**
+ * Notifies the channel of a fine grained network event.
+ * @param {goog.net.BrowserChannel.ServerReachability} reachabilityType The
+ * reachability event type.
+ */
+goog.net.BrowserTestChannel.prototype.notifyServerReachabilityEvent =
+ function(reachabilityType) {
+ this.channel_.notifyServerReachabilityEvent(reachabilityType);
+};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/bulkloader.js b/contexts/data/lib/closure-library/closure/goog/net/bulkloader.js
index 70afa6f..777c55d 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/bulkloader.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/bulkloader.js
@@ -66,7 +66,7 @@ goog.net.BulkLoader.prototype.logger_ =
/**
- * Gets the response texts.
+ * Gets the response texts, in order.
* @return {Array.<string>} The response texts.
*/
goog.net.BulkLoader.prototype.getResponseTexts = function() {
@@ -75,6 +75,15 @@ goog.net.BulkLoader.prototype.getResponseTexts = function() {
/**
+ * Gets the request Uris.
+ * @return {Array.<string>} The request URIs, in order.
+ */
+goog.net.BulkLoader.prototype.getRequestUris = function() {
+ return this.helper_.getUris();
+};
+
+
+/**
* Starts the process of loading the URIs.
*/
goog.net.BulkLoader.prototype.load = function() {
diff --git a/contexts/data/lib/closure-library/closure/goog/net/bulkloader_test.html b/contexts/data/lib/closure-library/closure/goog/net/bulkloader_test.html
index 7b904fd..a394bf6 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/bulkloader_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/bulkloader_test.html
@@ -177,6 +177,7 @@ See the COPYING file for details.
function testBulkLoaderLoadSuccess() {
var uris = ['a', 'b', 'c'];
var bulkLoader = getSuccessfulBulkLoader(uris);
+ assertArrayEquals(uris, bulkLoader.getRequestUris());
bulkLoader.load();
diff --git a/contexts/data/lib/closure-library/closure/goog/net/channeldebug.js b/contexts/data/lib/closure-library/closure/goog/net/channeldebug.js
index b31f089..f216a76 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/channeldebug.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/channeldebug.js
@@ -54,6 +54,15 @@ goog.net.ChannelDebug.prototype.getLogger = function() {
/**
+ * Logs that the browser went offline during the lifetime of a request.
+ * @param {goog.Uri} url The URL being requested.
+ */
+goog.net.ChannelDebug.prototype.browserOfflineResponse = function(url) {
+ this.info('BROWSER_OFFLINE: ' + url);
+};
+
+
+/**
* Logs an XmlHttp request..
* @param {string} verb The request type (GET/POST).
* @param {goog.Uri} uri The request destination.
diff --git a/contexts/data/lib/closure-library/closure/goog/net/channelrequest.js b/contexts/data/lib/closure-library/closure/goog/net/channelrequest.js
index 919962d..78701b8 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/channelrequest.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/channelrequest.js
@@ -28,6 +28,7 @@ goog.provide('goog.net.ChannelRequest');
goog.provide('goog.net.ChannelRequest.Error');
goog.require('goog.Timer');
+goog.require('goog.async.Throttle');
goog.require('goog.events');
goog.require('goog.events.EventHandler');
goog.require('goog.net.EventType');
@@ -50,8 +51,8 @@ goog.require('goog.userAgent');
* @param {number=} opt_retryId The retry id for this request.
* @constructor
*/
-goog.net.ChannelRequest = function(
- channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) {
+goog.net.ChannelRequest = function(channel, channelDebug, opt_sessionId,
+ opt_requestId, opt_retryId) {
/**
* The BrowserChannel object that owns the request.
* @type {goog.net.BrowserChannel|goog.net.BrowserTestChannel}
@@ -255,6 +256,28 @@ goog.net.ChannelRequest.prototype.cancelled_ = false;
/**
+ * A throttle time in ms for readystatechange events for the backchannel.
+ * Useful for throttling when ready state is INTERACTIVE (partial data).
+ * If set to zero no throttle is used.
+ *
+ * @see goog.net.BrowserChannel.prototype.readyStateChangeThrottleMs_
+ *
+ * @type {number}
+ * @private
+ */
+goog.net.ChannelRequest.prototype.readyStateChangeThrottleMs_ = 0;
+
+
+/**
+ * The throttle for readystatechange events for the current request, or null
+ * if there is none.
+ * @type {goog.async.Throttle}
+ * @private
+ */
+goog.net.ChannelRequest.prototype.readyStateChangeThrottle_ = null;
+
+
+/**
* Default timeout in MS for a request. The server must return data within this
* time limit for the request to not timeout.
* @type {number}
@@ -335,7 +358,17 @@ goog.net.ChannelRequest.Error = {
/**
* Errors due to the handler throwing an exception.
*/
- HANDLER_EXCEPTION: 5
+ HANDLER_EXCEPTION: 5,
+
+ /**
+ * The browser declared itself offline during the request.
+ */
+ BROWSER_OFFLINE: 6,
+
+ /**
+ * IE is blocking ActiveX streaming.
+ */
+ ACTIVE_X_BLOCKED: 7
};
@@ -387,7 +420,7 @@ goog.net.ChannelRequest.INCOMPLETE_CHUNK_ = {};
* @see http://code.google.com/p/closure-library/issues/detail?id=346
*/
goog.net.ChannelRequest.supportsXhrStreaming = function() {
- return !goog.userAgent.IE;
+ return !goog.userAgent.IE || goog.userAgent.isDocumentMode(10);
};
@@ -412,6 +445,18 @@ goog.net.ChannelRequest.prototype.setTimeout = function(timeout) {
/**
+ * Sets the throttle for handling onreadystatechange events for the request.
+ *
+ * @param {number} throttle The throttle in ms. A value of zero indicates
+ * no throttle.
+ */
+goog.net.ChannelRequest.prototype.setReadyStateChangeThrottle = function(
+ throttle) {
+ this.readyStateChangeThrottleMs_ = throttle;
+};
+
+
+/**
* Uses XMLHTTP to send an HTTP POST to the server.
*
* @param {goog.Uri} uri The uri of the request.
@@ -476,8 +521,16 @@ goog.net.ChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {
var useSecondaryDomains = this.channel_.shouldUseSecondaryDomains();
this.xmlHttp_ = this.channel_.createXhrIo(useSecondaryDomains ?
hostPrefix : null);
- goog.events.listen(this.xmlHttp_, goog.net.EventType.READY_STATE_CHANGE,
- this.xmlHttpHandler_, false, this);
+
+ if (this.readyStateChangeThrottleMs_ > 0) {
+ this.readyStateChangeThrottle_ = new goog.async.Throttle(
+ goog.bind(this.xmlHttpHandler_, this, this.xmlHttp_),
+ this.readyStateChangeThrottleMs_);
+ }
+
+ this.eventHandler_.listen(this.xmlHttp_,
+ goog.net.EventType.READY_STATE_CHANGE,
+ this.readyStateChangeHandler_);
var headers = this.extraHeaders_ ? goog.object.clone(this.extraHeaders_) : {};
if (this.postData_) {
@@ -497,6 +550,8 @@ goog.net.ChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {
}
this.xmlHttp_.send(this.requestUri_, this.verb_, null, headers);
}
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_MADE);
this.channelDebug_.xmlHttpChannelRequest(this.verb_,
this.requestUri_, this.rid_, this.retryId_,
this.postData_);
@@ -504,12 +559,31 @@ goog.net.ChannelRequest.prototype.sendXmlHttp_ = function(hostPrefix) {
/**
+ * Handles a readystatechange event.
+ * @param {goog.events.Event} evt The event.
+ * @private
+ */
+goog.net.ChannelRequest.prototype.readyStateChangeHandler_ = function(evt) {
+ var xhr = /** @type {goog.net.XhrIo} */ (evt.target);
+ var throttle = this.readyStateChangeThrottle_;
+ if (throttle &&
+ xhr.getReadyState() == goog.net.XmlHttp.ReadyState.INTERACTIVE) {
+ // Only throttle in the partial data case.
+ this.channelDebug_.debug('Throttling readystatechange.');
+ throttle.fire();
+ } else {
+ // If we haven't throttled, just handle response directly.
+ this.xmlHttpHandler_(xhr);
+ }
+};
+
+
+/**
* XmlHttp handler
- * @param {goog.events.Event} e Event object, target is a XhrIo object.
+ * @param {goog.net.XhrIo} xmlhttp The XhrIo object for the current request.
* @private
*/
-goog.net.ChannelRequest.prototype.xmlHttpHandler_ = function(e) {
- var xmlhttp = e.target;
+goog.net.ChannelRequest.prototype.xmlHttpHandler_ = function(xmlhttp) {
goog.net.BrowserChannel.onStartExecution();
/** @preserveTry */
try {
@@ -540,6 +614,8 @@ goog.net.ChannelRequest.prototype.xmlHttpHandler_ = function(e) {
*/
goog.net.ChannelRequest.prototype.onXmlHttpReadyStateChanged_ = function() {
var readyState = this.xmlHttp_.getReadyState();
+ var errorCode = this.xmlHttp_.getLastErrorCode();
+ var statusCode = this.xmlHttp_.getStatus();
// If it is Safari less than 420+, there is a bug that causes null to be
// in the responseText on ready state interactive so we must wait for
// ready state complete.
@@ -564,6 +640,22 @@ goog.net.ChannelRequest.prototype.onXmlHttpReadyStateChanged_ = function() {
}
}
+ // Dispatch any appropriate network events.
+ if (!this.cancelled_ && readyState == goog.net.XmlHttp.ReadyState.COMPLETE &&
+ errorCode != goog.net.ErrorCode.ABORT) {
+
+ // Pretty conservative, these are the only known scenarios which we'd
+ // consider indicative of a truly non-functional network connection.
+ if (errorCode == goog.net.ErrorCode.TIMEOUT ||
+ statusCode <= 0) {
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_FAILED);
+ } else {
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_SUCCEEDED);
+ }
+ }
+
// got some data so cancel the watchdog timer
this.cancelWatchDogTimer_();
@@ -713,7 +805,8 @@ goog.net.ChannelRequest.prototype.pollResponse_ = function() {
/**
* Starts a polling interval for changes to responseText of the
* XMLHttpRequest, for browsers that don't fire onreadystatechange
- * as data comes in incrementally.
+ * as data comes in incrementally. This timer is disabled in
+ * cleanup_().
* @private
*/
goog.net.ChannelRequest.prototype.startPolling_ = function() {
@@ -724,12 +817,27 @@ goog.net.ChannelRequest.prototype.startPolling_ = function() {
/**
- * Stops the polling interval for changes to responseText.
+ * Called when the browser declares itself offline at the start of a request or
+ * during its lifetime. Abandons that request.
* @private
*/
-goog.net.ChannelRequest.prototype.stopPolling_ = function() {
- this.pollingTimer_.stop();
- this.eventHandler_.removeAll();
+goog.net.ChannelRequest.prototype.cancelRequestAsBrowserIsOffline_ =
+ function() {
+ if (this.successful_) {
+ // Should never happen.
+ this.channelDebug_.severe(
+ 'Received browser offline event even though request completed ' +
+ 'successfully');
+ }
+
+ this.channelDebug_.browserOfflineResponse(this.requestUri_);
+ this.cleanup_();
+
+ // set error and dispatch failure
+ this.lastError_ = goog.net.ChannelRequest.Error.BROWSER_OFFLINE;
+ goog.net.BrowserChannel.notifyStatEvent(
+ goog.net.BrowserChannel.Stat.BROWSER_OFFLINE);
+ this.dispatchFailure_();
};
@@ -796,12 +904,26 @@ goog.net.ChannelRequest.prototype.tridentGet_ = function(usingSecondaryDomain) {
this.requestStartTime_ = goog.now();
this.ensureWatchDogTimer_();
- this.trident_ = new ActiveXObject('htmlfile');
+ var hostname = usingSecondaryDomain ? window.location.hostname : '';
+ this.requestUri_ = this.baseUri_.clone();
+ this.requestUri_.setParameterValue('DOMAIN', hostname);
+ this.requestUri_.setParameterValue('t', this.retryId_);
+
+ try {
+ this.trident_ = new ActiveXObject('htmlfile');
+ } catch (e) {
+ this.channelDebug_.severe('ActiveX blocked');
+ this.cleanup_();
+
+ this.lastError_ = goog.net.ChannelRequest.Error.ACTIVE_X_BLOCKED;
+ goog.net.BrowserChannel.notifyStatEvent(
+ goog.net.BrowserChannel.Stat.ACTIVE_X_BLOCKED);
+ this.dispatchFailure_();
+ return;
+ }
- var hostname = '';
var body = '<html><body>';
if (usingSecondaryDomain) {
- hostname = window.location.hostname;
body += '<script>document.domain="' + hostname + '"</scr' + 'ipt>';
}
body += '</body></html>';
@@ -817,12 +939,11 @@ goog.net.ChannelRequest.prototype.tridentGet_ = function(usingSecondaryDomain) {
var div = this.trident_.createElement('div');
this.trident_.parentWindow.document.body.appendChild(div);
- this.requestUri_ = this.baseUri_.clone();
- this.requestUri_.setParameterValue('DOMAIN', hostname);
- this.requestUri_.setParameterValue('t', this.retryId_);
div.innerHTML = '<iframe src="' + this.requestUri_ + '"></iframe>';
this.channelDebug_.tridentChannelRequest('GET',
this.requestUri_, this.rid_, this.retryId_);
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_MADE);
};
@@ -885,10 +1006,11 @@ goog.net.ChannelRequest.prototype.onTridentDoneAsync_ = function(successful) {
}
this.channelDebug_.tridentChannelResponseDone(
this.rid_, successful);
- this.cancelWatchDogTimer_();
this.cleanup_();
this.successful_ = successful;
this.channel_.onRequestComplete(this);
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.BACK_CHANNEL_ACTIVITY);
};
@@ -923,7 +1045,6 @@ goog.net.ChannelRequest.prototype.imgTagGet_ = function() {
*/
goog.net.ChannelRequest.prototype.cancel = function() {
this.cancelled_ = true;
- this.cancelWatchDogTimer_();
this.cleanup_();
};
@@ -1003,6 +1124,12 @@ goog.net.ChannelRequest.prototype.handleTimeout_ = function() {
}
this.channelDebug_.timeoutResponse(this.requestUri_);
+ // IMG requests never notice if they were successful, and always 'time out'.
+ // This fact says nothing about reachability.
+ if (this.type_ != goog.net.ChannelRequest.Type_.IMG) {
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.REQUEST_FAILED);
+ }
this.cleanup_();
// set error and dispatch failure
@@ -1033,15 +1160,24 @@ goog.net.ChannelRequest.prototype.dispatchFailure_ = function() {
* @private
*/
goog.net.ChannelRequest.prototype.cleanup_ = function() {
- this.stopPolling_();
+ this.cancelWatchDogTimer_();
+
+ goog.dispose(this.readyStateChangeThrottle_);
+ this.readyStateChangeThrottle_ = null;
+
+ // Stop the polling timer, if necessary.
+ this.pollingTimer_.stop();
+
+ // Unhook all event handlers.
+ this.eventHandler_.removeAll();
+
if (this.xmlHttp_) {
// clear out this.xmlHttp_ before aborting so we handle getting reentered
// inside abort
var xmlhttp = this.xmlHttp_;
this.xmlHttp_ = null;
- goog.events.unlisten(xmlhttp, goog.net.EventType.READY_STATE_CHANGE,
- this.xmlHttpHandler_, false, this);
xmlhttp.abort();
+ xmlhttp.dispose();
}
if (this.trident_) {
@@ -1131,6 +1267,8 @@ goog.net.ChannelRequest.prototype.safeOnRequestData_ = function(data) {
/** @preserveTry */
try {
this.channel_.onRequestData(this, data);
+ this.channel_.notifyServerReachabilityEvent(
+ goog.net.BrowserChannel.ServerReachability.BACK_CHANNEL_ACTIVITY);
} catch (e) {
// Dump debug info, but keep going without closing the channel.
this.channelDebug_.dumpException(
diff --git a/contexts/data/lib/closure-library/closure/goog/net/channelrequest_test.html b/contexts/data/lib/closure-library/closure/goog/net/channelrequest_test.html
index 1bca491..4581067 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/channelrequest_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/channelrequest_test.html
@@ -11,21 +11,27 @@ See the COPYING file for details.
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.net.ChannelRequest</title>
-<script src="../base.js"></script>
-<script>
+<script src="../base.js" type="text/javascript"></script>
+<script type="text/javascript">
goog.require('goog.functions');
goog.require('goog.net.BrowserChannel');
goog.require('goog.net.ChannelDebug');
goog.require('goog.net.ChannelRequest');
goog.require('goog.testing.MockClock');
+goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.net.XhrIo');
+goog.require('goog.testing.recordFunction');
</script>
</head>
<body>
-<script>
+<script type="text/javascript">
+var channelRequest;
+var mockBrowserChannel;
var mockClock;
+var stubs;
+var xhrIo;
/**
* Time to wait for a network request to time out, before aborting.
@@ -33,6 +39,11 @@ var mockClock;
var WATCHDOG_TIME = 2000;
/**
+ * Time to throttle readystatechange events.
+ */
+var THROTTLE_TIME = 500;
+
+/**
* A really long time - used to make sure no more timeouts will fire.
*/
var ALL_DAY_MS = 1000 * 60 * 60 * 24;
@@ -41,10 +52,12 @@ var ALL_DAY_MS = 1000 * 60 * 60 * 24;
function setUp() {
mockClock = new goog.testing.MockClock();
mockClock.install();
+ stubs = new goog.testing.PropertyReplacer();
}
function tearDown() {
+ stubs.reset();
mockClock.uninstall();
}
@@ -54,14 +67,7 @@ function tearDown() {
* @constructor
*/
function MockBrowserChannel() {
- this.createXhrIo = function(domainPrefix) {
- assertNull(domainPrefix);
- var xhrIo = new goog.testing.net.XhrIo();
- xhrIo.abort = xhrIo.abort || function() {
- this.active_ = false;
- };
- return xhrIo;
- }
+ this.reachabilityEvents = {};
this.isClosed = function() {
return false;
};
@@ -72,6 +78,12 @@ function MockBrowserChannel() {
return false;
}
this.completedRequests = [];
+ this.notifyServerReachabilityEvent = function(reachabilityType) {
+ if (!this.reachabilityEvents[reachabilityType]) {
+ this.reachabilityEvents[reachabilityType] = 0;
+ }
+ this.reachabilityEvents[reachabilityType]++;
+ };
this.onRequestComplete = function(request) {
this.completedRequests.push(request);
};
@@ -84,49 +96,102 @@ function MockBrowserChannel() {
* testability:
* <ul>
* <li>The BrowserChannel is a MockBrowserChannel.
- * <li>createXhrIo_() returns the xhrIo that is passed in.
* <li>The new watchdogTimeoutCallCount property tracks onWatchDogTimeout_()
* calls.
* <li>The timeout is set to WATCHDOG_TIME.
* </ul>
- * @param {goog.testing.net.XhrIo} xhrIo A test XhrIo.
- * @return {goog.net.ChannelRequest} A slightly modified ChannelRequest
*/
-function createChannelRequest(xhrIo) {
+function createChannelRequest() {
+ xhrIo = new goog.testing.net.XhrIo();
+ xhrIo.abort = xhrIo.abort || function() {
+ this.active_ = false;
+ };
+
// Install mock browser channel and no-op debug logger.
- var req = new goog.net.ChannelRequest(
- new MockBrowserChannel(),
+ mockBrowserChannel = new MockBrowserChannel();
+ channelRequest = new goog.net.ChannelRequest(
+ mockBrowserChannel,
new goog.net.ChannelDebug());
// Install test XhrIo.
- req.createXhrIo_ = function() {
+ mockBrowserChannel.createXhrIo = function() {
return xhrIo;
};
// Install watchdogTimeoutCallCount.
- req.watchdogTimeoutCallCount = 0;
- req.originalOnWatchDogTimeout = req.onWatchDogTimeout_;
- req.onWatchDogTimeout_ = function() {
+ channelRequest.watchdogTimeoutCallCount = 0;
+ channelRequest.originalOnWatchDogTimeout = channelRequest.onWatchDogTimeout_;
+ channelRequest.onWatchDogTimeout_ = function() {
this.watchdogTimeoutCallCount++;
return this.originalOnWatchDogTimeout();
};
- req.setTimeout(WATCHDOG_TIME);
+ channelRequest.setTimeout(WATCHDOG_TIME);
+}
+
- return req;
+/**
+ * Run through the lifecycle of a long lived request, checking that the right
+ * network events are reported.
+ */
+function testNetworkEvents() {
+ createChannelRequest();
+
+ channelRequest.xmlHttpPost(new goog.Uri('some_uri'), 'some_postdata', true);
+ checkReachabilityEvents(1, 0, 0, 0);
+ if (goog.net.ChannelRequest.supportsXhrStreaming()) {
+ xhrIo.simulatePartialResponse('17\nI am a BC Message');
+ checkReachabilityEvents(1, 0, 0, 1);
+ xhrIo.simulatePartialResponse('23\nI am another BC Message');
+ checkReachabilityEvents(1, 0, 0, 2);
+ xhrIo.simulateResponse(200, '16\Final BC Message');
+ checkReachabilityEvents(1, 1, 0, 2);
+ } else {
+ xhrIo.simulateResponse(200, '16\Final BC Message');
+ checkReachabilityEvents(1, 1, 0, 0);
+ }
}
/**
- * Creates a test XhrIo, with the abort() method defined.
- * @return {goog.testing.net.XhrIo} A test XhrIo.
+ * Test throttling of readystatechange events.
*/
-function createXhrIo() {
- var xhrIo = new goog.testing.net.XhrIo();
- xhrIo.abort = xhrIo.abort || function() {
- this.active_ = false;
- };
- return xhrIo;
+function testNetworkEvents_throttleReadyStateChange() {
+ createChannelRequest();
+ channelRequest.setReadyStateChangeThrottle(THROTTLE_TIME);
+
+ var recordedHandler =
+ goog.testing.recordFunction(channelRequest.xmlHttpHandler_);
+ stubs.set(channelRequest, 'xmlHttpHandler_', recordedHandler);
+
+ channelRequest.xmlHttpPost(new goog.Uri('some_uri'), 'some_postdata', true);
+ assertEquals(1, recordedHandler.getCallCount());
+
+ checkReachabilityEvents(1, 0, 0, 0);
+ if (goog.net.ChannelRequest.supportsXhrStreaming()) {
+ xhrIo.simulatePartialResponse('17\nI am a BC Message');
+ checkReachabilityEvents(1, 0, 0, 1);
+ assertEquals(3, recordedHandler.getCallCount());
+
+ // Second event should be throttled
+ xhrIo.simulatePartialResponse('23\nI am another BC Message');
+ assertEquals(3, recordedHandler.getCallCount());
+
+ xhrIo.simulatePartialResponse('27\nI am yet another BC Message');
+ assertEquals(3, recordedHandler.getCallCount());
+ mockClock.tick(THROTTLE_TIME);
+
+ checkReachabilityEvents(1, 0, 0, 3);
+ // Only one more call because of throttling.
+ assertEquals(4, recordedHandler.getCallCount());
+
+ xhrIo.simulateResponse(200, '16\Final BC Message');
+ checkReachabilityEvents(1, 1, 0, 3);
+ assertEquals(5, recordedHandler.getCallCount());
+ } else {
+ xhrIo.simulateResponse(200, '16\Final BC Message');
+ checkReachabilityEvents(1, 1, 0, 0);
+ }
}
@@ -135,53 +200,81 @@ function createXhrIo() {
* expires.
*/
function testRequestTimeout() {
- var xhrIo = createXhrIo();
- var req = createChannelRequest(xhrIo);
+ createChannelRequest();
- req.xmlHttpPost(new goog.Uri('some_uri'), 'some_postdata', true);
- assertEquals(0, req.watchdogTimeoutCallCount);
- assertEquals(0, req.channel_.completedRequests.length);
+ channelRequest.xmlHttpPost(new goog.Uri('some_uri'), 'some_postdata', true);
+ assertEquals(0, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(0, channelRequest.channel_.completedRequests.length);
// Watchdog timeout.
mockClock.tick(WATCHDOG_TIME);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
- assertFalse(req.getSuccess());
+ assertEquals(1, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(1, channelRequest.channel_.completedRequests.length);
+ assertFalse(channelRequest.getSuccess());
// Make sure no more timers are firing.
mockClock.tick(ALL_DAY_MS);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
+ assertEquals(1, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(1, channelRequest.channel_.completedRequests.length);
+
+ checkReachabilityEvents(1, 0, 1, 0);
}
+
function testRequestTimeoutWithUnexpectedException() {
- var xhrIo = createXhrIo();
- var req = createChannelRequest(xhrIo);
- req.channel_.createXhrIo = goog.functions.error('Weird error');
+ createChannelRequest();
+ channelRequest.channel_.createXhrIo = goog.functions.error('Weird error');
try {
- req.xmlHttpGet(new goog.Uri('some_uri'), true, null);
+ channelRequest.xmlHttpGet(new goog.Uri('some_uri'), true, null);
fail('Expected error');
} catch (e) {
assertEquals('Weird error', e.message);
}
- assertEquals(0, req.watchdogTimeoutCallCount);
- assertEquals(0, req.channel_.completedRequests.length);
+ assertEquals(0, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(0, channelRequest.channel_.completedRequests.length);
// Watchdog timeout.
mockClock.tick(WATCHDOG_TIME);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
- assertFalse(req.getSuccess());
+ assertEquals(1, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(1, channelRequest.channel_.completedRequests.length);
+ assertFalse(channelRequest.getSuccess());
// Make sure no more timers are firing.
mockClock.tick(ALL_DAY_MS);
- assertEquals(1, req.watchdogTimeoutCallCount);
- assertEquals(1, req.channel_.completedRequests.length);
+ assertEquals(1, channelRequest.watchdogTimeoutCallCount);
+ assertEquals(1, channelRequest.channel_.completedRequests.length);
+
+ checkReachabilityEvents(0, 0, 1, 0);
+}
+
+function testActiveXBlocked() {
+ createChannelRequest();
+ stubs.set(goog.global, 'ActiveXObject',
+ goog.functions.error('Active X blocked'));
+
+ channelRequest.tridentGet(new goog.Uri('some_uri'), false);
+ assertFalse(channelRequest.getSuccess());
+ assertEquals(goog.net.ChannelRequest.Error.ACTIVE_X_BLOCKED,
+ channelRequest.getLastError());
+
+ checkReachabilityEvents(0, 0, 0, 0);
}
+function checkReachabilityEvents(reqMade, reqSucceeded, reqFail, backChannel) {
+ var Reachability = goog.net.BrowserChannel.ServerReachability;
+ assertEquals(reqMade,
+ mockBrowserChannel.reachabilityEvents[Reachability.REQUEST_MADE] || 0);
+ assertEquals(reqSucceeded,
+ mockBrowserChannel.reachabilityEvents[Reachability.REQUEST_SUCCEEDED] || 0);
+ assertEquals(reqFail,
+ mockBrowserChannel.reachabilityEvents[Reachability.REQUEST_FAILED] || 0);
+ assertEquals(backChannel,
+ mockBrowserChannel.reachabilityEvents[Reachability.BACK_CHANNEL_ACTIVITY]
+ || 0);
+}
</script>
</body>
</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/cookies.js b/contexts/data/lib/closure-library/closure/goog/net/cookies.js
index 9978f27..10cc5b8 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/cookies.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/cookies.js
@@ -60,35 +60,11 @@ goog.net.Cookies.SPLIT_RE_ = /\s*;\s*/;
/**
- * Test cookie name. Used for a temp cookie when testing if cookies are
- * enabled.
- * @type {string}
- * @private
- */
-goog.net.Cookies.TEST_COOKIE_NAME_ = 'COOKIES_TEST_';
-
-
-/**
* Returns true if cookies are enabled.
* @return {boolean} True if cookies are enabled.
*/
goog.net.Cookies.prototype.isEnabled = function() {
- var isEnabled = this.isNavigatorCookieEnabled_();
-
- if (isEnabled && goog.userAgent.WEBKIT) {
- // Chrome has a bug where it will report cookies as enabled even if they
- // are not, see http://code.google.com/p/chromium/issues/detail?id=1850 .
- // To work around, we set a unique cookie, then check for it.
- var cookieName = goog.net.Cookies.TEST_COOKIE_NAME_ + goog.now();
- goog.net.cookies.set(cookieName, '1');
- if (!this.get(cookieName)) {
- return false;
- }
- // Remove temp cookie.
- this.remove(cookieName);
- }
-
- return isEnabled;
+ return navigator.cookieEnabled;
};
@@ -217,6 +193,9 @@ goog.net.Cookies.prototype.get = function(name, opt_default) {
if (part.indexOf(nameEq) == 0) {
return part.substr(nameEq.length);
}
+ if (part == name) {
+ return '';
+ }
}
return opt_default;
};
@@ -354,16 +333,6 @@ goog.net.Cookies.prototype.getParts_ = function() {
/**
- * Returns navigator.cookieEnabled. Overridden in unit tests.
- * @return {boolean} The value of navigator.cookieEnabled.
- * @private
- */
-goog.net.Cookies.prototype.isNavigatorCookieEnabled_ = function() {
- return navigator.cookieEnabled;
-};
-
-
-/**
* Gets the names and values for all the cookies.
* @return {Object} An object with keys and values.
* @private
diff --git a/contexts/data/lib/closure-library/closure/goog/net/cookies_test.html b/contexts/data/lib/closure-library/closure/goog/net/cookies_test.html
index 10ec66c..170e686 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/cookies_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/cookies_test.html
@@ -13,6 +13,7 @@ See the COPYING file for details.
<script>
goog.require('goog.array');
goog.require('goog.net.cookies');
+ goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
</script>
</head>
@@ -21,6 +22,7 @@ See the COPYING file for details.
var cookies = goog.net.cookies;
var baseCount = 0;
+var stubs = new goog.testing.PropertyReplacer();
function checkForCookies() {
if (!cookies.isEnabled()) {
@@ -46,20 +48,11 @@ function setUp() {
function tearDown() {
// Clear up after ourselves.
cookies.clear();
+ stubs.reset();
}
function testIsEnabled() {
- // Save static function prior to mocking.
- var isNavigatorCookieEnabled = cookies.isNavigatorCookieEnabled_;
- try {
- cookies.isNavigatorCookieEnabled_ = function() { return true; };
- assertTrue(cookies.isEnabled());
- cookies.isNavigatorCookieEnabled_ = function() { return false; };
- assertFalse(cookies.isEnabled());
- } finally {
- // Restore static function.
- cookies.isNavigatorCookieEnabled_ = isNavigatorCookieEnabled;
- }
+ assertEquals(navigator.cookieEnabled, cookies.isEnabled());
}
function testCount() {
@@ -196,6 +189,24 @@ function testSetCookieMaxAgeZero() {
}
}
+function testGetEmptyCookie() {
+ var value = '';
+
+ cookies.set('test', value);
+
+ assertEquals(value, cookies.get('test'));
+}
+
+function testGetEmptyCookieIE() {
+ stubs.set(cookies, 'getCookie_', function() {
+ return 'test1; test2; test3';
+ });
+
+ assertEquals('', cookies.get('test1'));
+ assertEquals('', cookies.get('test2'));
+ assertEquals('', cookies.get('test3'));
+}
+
// TODO(chrisn): Testing max age > 0 requires a mock clock.
function mockSetCookie(var_args) {
diff --git a/contexts/data/lib/closure-library/closure/goog/net/crossdomainrpc_test.css b/contexts/data/lib/closure-library/closure/goog/net/crossdomainrpc_test.css
new file mode 100644
index 0000000..73cc311
--- /dev/null
+++ b/contexts/data/lib/closure-library/closure/goog/net/crossdomainrpc_test.css
@@ -0,0 +1,7 @@
+/*
+ * Copyright 2010 The Closure Library Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by the Apache License, Version 2.0.
+ * See the COPYING file for details.
+ */
+
diff --git a/contexts/data/lib/closure-library/closure/goog/net/httpstatus.js b/contexts/data/lib/closure-library/closure/goog/net/httpstatus.js
index eecb270..8b6ef75 100755
--- a/contexts/data/lib/closure-library/closure/goog/net/httpstatus.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/httpstatus.js
@@ -88,7 +88,8 @@ goog.net.HttpStatus = {
* Returns whether the given status should be considered successful.
*
* Successful codes are OK (200), CREATED (201), ACCEPTED (202),
- * NO CONTENT (204), NOT MODIFIED (304), and IE's no content code (1223).
+ * NO CONTENT (204), PARTIAL CONTENT (206), NOT MODIFIED (304),
+ * and IE's no content code (1223).
*
* @param {number} status The status code to test.
* @return {boolean} Whether the status code should be considered successful.
@@ -99,6 +100,7 @@ goog.net.HttpStatus.isSuccess = function(status) {
case goog.net.HttpStatus.CREATED:
case goog.net.HttpStatus.ACCEPTED:
case goog.net.HttpStatus.NO_CONTENT:
+ case goog.net.HttpStatus.PARTIAL_CONTENT:
case goog.net.HttpStatus.NOT_MODIFIED:
case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:
return true;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/imageloader.js b/contexts/data/lib/closure-library/closure/goog/net/imageloader.js
index cbe4467..5cd2a5f 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/imageloader.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/imageloader.js
@@ -18,10 +18,12 @@
*
* @author attila@google.com (Attila Bodis)
* @author zachlloyd@google.com (Zachary Lloyd)
+ * @author jonemerson@google.com (Jon Emerson)
*/
goog.provide('goog.net.ImageLoader');
+goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
@@ -37,6 +39,23 @@ goog.require('goog.userAgent');
* event for each image loaded, with an {@link Image} object as the target of
* the event, normalized to have {@code naturalHeight} and {@code naturalWidth}
* attributes.
+ *
+ * To use this class, run:
+ *
+ * <pre>
+ * var imageLoader = new goog.net.ImageLoader();
+ * goog.events.listen(imageLoader, goog.net.EventType.COMPLETE,
+ * function(e) { ... });
+ * imageLoader.addImage("image_id", "http://path/to/image.gif");
+ * imageLoader.start();
+ * </pre>
+ *
+ * The start() method must be called to start image loading. Images can be
+ * added and removed after loading has started, but only those images added
+ * before start() was called will be loaded until start() is called again.
+ * A goog.net.EventType.COMPLETE event will be dispatched only once all
+ * outstanding images have completed uploading.
+ *
* @param {Element=} opt_parent An optional parent element whose document object
* should be used to load images.
* @constructor
@@ -44,38 +63,61 @@ goog.require('goog.userAgent');
*/
goog.net.ImageLoader = function(opt_parent) {
goog.events.EventTarget.call(this);
- this.images_ = {};
+
+ /**
+ * Map of image IDs to their image src, used to keep track of the images to
+ * load. Once images have started loading, they're removed from this map.
+ * @type {!Object.<string, string>}
+ * @private
+ */
+ this.imageIdToUrlMap_ = {};
+
+ /**
+ * Map of image IDs to their image element, used only for images that are in
+ * the process of loading. Used to clean-up event listeners and to know
+ * when we've completed loading images.
+ * @type {!Object.<string, !Element>}
+ * @private
+ */
+ this.imageIdToImageMap_ = {};
+
+ /**
+ * Event handler object, used to keep track of onload and onreadystatechange
+ * listeners.
+ * @type {!goog.events.EventHandler}
+ * @private
+ */
this.handler_ = new goog.events.EventHandler(this);
+
+ /**
+ * The parent element whose document object will be used to load images.
+ * Useful if you want to load the images from a window other than the current
+ * window in order to control the Referer header sent when the image is
+ * loaded.
+ * @type {Element|undefined}
+ * @private
+ */
this.parent_ = opt_parent;
};
goog.inherits(goog.net.ImageLoader, goog.events.EventTarget);
/**
- * Map of image IDs to images src, used to keep track of the images to load.
- * @private
- * @type {Object.<string, string>}
- */
-goog.net.ImageLoader.prototype.images_;
-
-
-/**
- * Event handler object, used to keep track of onload and onreadystatechange
- * listeners.
+ * An array of event types to listen to on images. This is browser dependent.
+ * Internet Explorer doesn't reliably raise LOAD events on images, so we must
+ * use READY_STATE_CHANGE. If the image is cached locally, IE won't fire the
+ * LOAD event while the onreadystate event is fired always. On the other hand,
+ * the ERROR event is always fired whenever the image is not loaded successfully
+ * no matter whether it's cached or not.
+ * @type {!Array.<string>}
* @private
- * @type {goog.events.EventHandler}
*/
-goog.net.ImageLoader.prototype.handler_;
-
-
-/**
- * The parent element whose document object will be used to load images.
- * Useful if you want to load the images from a window other than the current
- * window in order to control the Referer header sent when the image is loaded.
- * @type {(Element|undefined)}
- * @private
- */
-goog.net.ImageLoader.prototype.parent_;
+goog.net.ImageLoader.IMAGE_LOAD_EVENTS_ = [
+ goog.userAgent.IE ? goog.net.EventType.READY_STATE_CHANGE :
+ goog.events.EventType.LOAD,
+ goog.net.EventType.ABORT,
+ goog.net.EventType.ERROR
+];
/**
@@ -92,17 +134,34 @@ goog.net.ImageLoader.prototype.addImage = function(id, image) {
var src = goog.isString(image) ? image : image.src;
if (src) {
// For now, we just store the source URL for the image.
- this.images_[id] = src;
+ this.imageIdToUrlMap_[id] = src;
}
};
/**
* Removes the image associated with the given ID string from the image loader.
+ * If the image was previously loading, removes any listeners for its events
+ * and dispatches a COMPLETE event if all remaining images have now completed.
* @param {string} id The ID of the image to remove.
*/
goog.net.ImageLoader.prototype.removeImage = function(id) {
- goog.object.remove(this.images_, id);
+ delete this.imageIdToUrlMap_[id];
+
+ var image = this.imageIdToImageMap_[id];
+ if (image) {
+ delete this.imageIdToImageMap_[id];
+
+ // Stop listening for events on the image.
+ this.handler_.unlisten(image, goog.net.ImageLoader.IMAGE_LOAD_EVENTS_,
+ this.onNetworkEvent_);
+
+ // If this was the last image, raise a COMPLETE event.
+ if (goog.object.isEmpty(this.imageIdToImageMap_) &&
+ goog.object.isEmpty(this.imageIdToUrlMap_)) {
+ this.dispatchEvent(goog.net.EventType.COMPLETE);
+ }
+ }
};
@@ -112,18 +171,36 @@ goog.net.ImageLoader.prototype.removeImage = function(id) {
* images have finished loading.
*/
goog.net.ImageLoader.prototype.start = function() {
- goog.object.forEach(this.images_, this.loadImage_, this);
+ // Iterate over the keys, rather than the full object, to essentially clone
+ // the initial queued images in case any event handlers decide to add more
+ // images before this loop has finished executing.
+ var imageIdToUrlMap = this.imageIdToUrlMap_;
+ goog.array.forEach(goog.object.getKeys(imageIdToUrlMap),
+ function(id) {
+ var src = imageIdToUrlMap[id];
+ if (src) {
+ delete imageIdToUrlMap[id];
+ this.loadImage_(src, id);
+ }
+ }, this);
};
/**
* Creates an {@code Image} object with the specified ID and source URL, and
* listens for network events raised as the image is loaded.
- * @private
* @param {string} src The image source URL.
* @param {string} id The unique ID of the image to load.
+ * @private
*/
goog.net.ImageLoader.prototype.loadImage_ = function(src, id) {
+ if (this.isDisposed()) {
+ // When loading an image in IE7 (and maybe IE8), the error handler
+ // may fire before we yield JS control. If the error handler
+ // dispose the ImageLoader, this method will throw exception.
+ return;
+ }
+
var image;
if (this.parent_) {
var dom = goog.dom.getDomHelper(this.parent_);
@@ -132,18 +209,9 @@ goog.net.ImageLoader.prototype.loadImage_ = function(src, id) {
image = new Image();
}
- // Internet Explorer doesn't reliably raise LOAD events on images, so we must
- // use READY_STATE_CHANGE (thanks, Jeff!).
- // If the image is cached locally, IE won't fire the LOAD event while the
- // onreadystate event is fired always. On the other hand, the ERROR event
- // is always fired whenever the image is not loaded successfully no matter
- // whether it's cached or not.
-
- var loadEvent = goog.userAgent.IE ? goog.net.EventType.READY_STATE_CHANGE :
- goog.events.EventType.LOAD;
- this.handler_.listen(image, [
- loadEvent, goog.net.EventType.ABORT, goog.net.EventType.ERROR
- ], this.onNetworkEvent_);
+ this.handler_.listen(image, goog.net.ImageLoader.IMAGE_LOAD_EVENTS_,
+ this.onNetworkEvent_);
+ this.imageIdToImageMap_[id] = image;
image.id = id;
image.src = src;
@@ -152,18 +220,18 @@ goog.net.ImageLoader.prototype.loadImage_ = function(src, id) {
/**
* Handles net events (READY_STATE_CHANGE, LOAD, ABORT, and ERROR).
- * @private
* @param {goog.events.Event} evt The network event to handle.
+ * @private
*/
goog.net.ImageLoader.prototype.onNetworkEvent_ = function(evt) {
- var image = evt.currentTarget;
+ var image = /** @type {Element} */ (evt.currentTarget);
if (!image) {
return;
}
if (evt.type == goog.net.EventType.READY_STATE_CHANGE) {
- // This implies that the user agent is IE; see loadImage()_.
+ // This implies that the user agent is IE; see loadImage_().
// Noe that this block is used to check whether the image is ready to
// dispatch the COMPLETE event.
if (image.readyState == goog.net.EventType.COMPLETE) {
@@ -210,28 +278,15 @@ goog.net.ImageLoader.prototype.onNetworkEvent_ = function(evt) {
return;
}
- // Remove the image from the map.
- goog.object.remove(this.images_, image.id);
-
- // If this was the last image, raise a COMPLETE event.
- if (goog.object.isEmpty(this.images_)) {
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- // Unlisten for all network events.
- if (this.handler_) {
- this.handler_.removeAll();
- }
- }
+ this.removeImage(image.id);
};
/** @override */
goog.net.ImageLoader.prototype.disposeInternal = function() {
- if (this.images_) {
- delete this.images_;
- }
- if (this.handler_) {
- this.handler_.dispose();
- this.handler_ = null;
- }
+ delete this.imageIdToUrlMap_;
+ delete this.imageIdToImageMap_;
+ goog.dispose(this.handler_);
+
goog.net.ImageLoader.superClass_.disposeInternal.call(this);
};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/imageloader_test.html b/contexts/data/lib/closure-library/closure/goog/net/imageloader_test.html
index 9d8b3d8..1e2f045 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/imageloader_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/imageloader_test.html
@@ -13,187 +13,289 @@ See the COPYING file for details.
<title>Closure Unit Tests - goog.net.ImageLoader</title>
<script src="../base.js"></script>
<script>
+ goog.require('goog.Timer');
+ goog.require('goog.dispose');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.net.ImageLoader');
- goog.require('goog.structs.Map');
+ goog.require('goog.object');
+ goog.require('goog.testing.AsyncTestCase');
goog.require('goog.testing.jsunit');
+ goog.require('goog.testing.recordFunction');
</script>
</head>
<body>
<script>
+var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(document.title);
+// Set the AsyncTestCase timeout to larger value to allow more time
+// for images to load.
+asyncTestCase.stepTimeout = 5000;
- var TEST_IMAGES = new goog.structs.Map();
+var TEST_EVENT_TYPES = [
+ goog.events.EventType.LOAD,
+ goog.net.EventType.COMPLETE,
+ goog.net.EventType.ERROR
+];
- var TEST_EVENT_TYPES = [
- goog.events.EventType.LOAD,
- goog.net.EventType.COMPLETE,
- goog.net.EventType.ERROR
- ];
- // TEST_IMAGES.set(FileName, Expected Size (width, height), Expected event)
- var EVENT_TYPE_LOAD = goog.events.EventType.LOAD;
- TEST_IMAGES.set('imageloader_testimg1.gif', [20, 20, EVENT_TYPE_LOAD]);
- TEST_IMAGES.set('imageloader_testimg2.gif', [20, 20, EVENT_TYPE_LOAD]);
- TEST_IMAGES.set('imageloader_testimg3.gif', [32, 32, EVENT_TYPE_LOAD]);
+/**
+ * Mapping from test image file name to:
+ * [expected width, expected height, expected event to be fired].
+ */
+var TEST_IMAGES = {
+ 'imageloader_testimg1.gif': [20, 20, goog.events.EventType.LOAD],
+ 'imageloader_testimg2.gif': [20, 20, goog.events.EventType.LOAD],
+ 'imageloader_testimg3.gif': [32, 32, goog.events.EventType.LOAD],
- var EVENT_TYPE_ERROR = goog.net.EventType.ERROR;
- TEST_IMAGES.set('this-is-not-image-1.gif', [0, 0, EVENT_TYPE_ERROR]);
- TEST_IMAGES.set('this-is-not-image-2.gif', [0, 0, EVENT_TYPE_ERROR]);
+ 'this-is-not-image-1.gif': [0, 0, goog.net.EventType.ERROR],
+ 'this-is-not-image-2.gif': [0, 0, goog.net.EventType.ERROR]
+};
- var TIMEOUT = 5000;
- // in milleseconds
- // Create a new test case.
- var imageLoaderTestCase = new goog.testing.TestCase(document.title);
- var setUpPageStatus;
+var startTime;
+var loader;
- // Keep track of time so we can timeout if the images don't load.
- imageLoaderTestCase.elapsedTime_ = 0;
- imageLoaderTestCase.results_ = new goog.structs.Map();
+function setUp() {
+ startTime = goog.now();
- /** True once the test environment is set up. */
- imageLoaderTestCase.isSetUp = false;
-
- /** True once the page is ready for the test to be run. */
- imageLoaderTestCase.isReady = false;
-
- // A regular image loader.
- imageLoaderTestCase.imageLoader = new goog.net.ImageLoader();
-
- // An image loader that is used to check whether we can dispose
- // it safely whenever an event is fired before the COMPLETE event.
- imageLoaderTestCase.disposalImageLoader = new goog.net.ImageLoader();
-
- /** Sets up the test environment, adds tests and sets up the worker pools. */
- imageLoaderTestCase.setUpTests = function() {
- this.log('Setting tests up');
-
- this.add(new goog.testing.TestCase.Test('testCompleteResults',
- this.testCompleteResults, this));
-
- this.isSetUp = true;
-
- var keys = TEST_IMAGES.getKeys();
- for (var i = 0; i < keys.length; i++) {
- this.log('Adding image: ' + keys[i]);
- this.imageLoader.addImage('img_' + i, keys[i]);
- this.disposalImageLoader.addImage('img_' + i, keys[i]);
- }
-
- goog.events.listen(this.imageLoader, TEST_EVENT_TYPES,
- this.handleImageLoaderEvent, false, this);
-
- goog.events.listen(this.disposalImageLoader, TEST_EVENT_TYPES,
- this.handleDisposalImageLoaderEvent, false, this);
-
- this.disposalImageLoader.start();
- };
-
- /** Handles any events fired on the disposalImageLoader */
- imageLoaderTestCase.handleDisposalImageLoaderEvent = function(e) {
- switch (e.type) {
- case goog.events.EventType.LOAD:
- case goog.net.EventType.ERROR:
- // Make sure that we can dispose this.disposalImageLoader safely.
- this.disposalImageLoader.dispose();
-
- // then starts the regular image loader.
- this.imageLoader.start();
- break;
-
- case goog.net.EventType.COMPLETE:
- throw new Error('disposalImageLoader should have been disposed.');
- break;
- }
- };
+ loader = new goog.net.ImageLoader();
+ // Adds test images to the loader.
+ var i = 0;
+ for (var key in TEST_IMAGES) {
+ var imageId = 'img_' + i++;
+ loader.addImage(imageId, key);
+ }
+}
- /** Handles any events fired on the imageLoader */
- imageLoaderTestCase.handleImageLoaderEvent = function(e) {
- this.log('handleEvent, type: ' + e.type);
-
- switch (e.type) {
- case goog.events.EventType.LOAD:
- var image = e.target;
- this.results_.set(image.src.substring(image.src.lastIndexOf('/') + 1),
- [image.naturalWidth, image.naturalHeight, e.type]);
- break;
-
- case goog.net.EventType.ERROR:
- var image = e.target;
- this.results_.set(image.src.substring(image.src.lastIndexOf('/') + 1),
- [image.naturalWidth, image.naturalHeight, e.type]);
- break;
-
- case goog.net.EventType.COMPLETE:
- setUpPageStatus = 'complete';
- this.isReady = true;
- break;
- }
- };
+function tearDown() {
+ goog.dispose(loader);
+}
- /** Tests the results. */
- imageLoaderTestCase.testCompleteResults = function() {
- var keys = TEST_IMAGES.getKeys();
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- this.log(key);
- // Check if fires the COMPLETE event.
- assertTrue('Image is not loaded completely',
- this.results_.containsKey(key));
+/**
+ * Tests loading image and disposing before loading completes.
+ */
+function testDisposeInTheMiddleOfLoadingWorks() {
+ goog.events.listen(loader, TEST_EVENT_TYPES,
+ goog.partial(handleDisposalImageLoaderEvent, loader));
+ // waitForAsync before starting loader just in case
+ // handleDisposalImageLoaderEvent is called from within loader.start
+ // (before we yield control). This may happen in IE7/IE8.
+ asyncTestCase.waitForAsync('Waiting for loader handler to fire.');
+ loader.start();
+}
- // Chcekc size.
- assertTrue('Image size is not correct',
- this.results_.get(key)[0] == TEST_IMAGES.get(key)[0] &&
- this.results_.get(key)[1] == TEST_IMAGES.get(key)[1]);
- // Check if fired the correct event.
- assertTrue('Event *' + TEST_IMAGES.get(key)[2] + '* must be fired',
- this.results_.get(key)[2] == TEST_IMAGES.get(key)[2]);
- }
- };
+function handleDisposalImageLoaderEvent(loader, e) {
+ assertFalse('Handler is still invoked after loader is disposed.',
+ loader.isDisposed());
- /** Waits until the tests are ready to begin, before running them. */
- imageLoaderTestCase.runTests = function() {
- if (!this.isSetUp) {
- this.setUpTests();
- }
- if (this.isReady) {
- this.execute();
- } else {
- if (this.elapsedTime_ > TIMEOUT) {
- this.log('timed out');
- setUpPageStatus = 'complete';
- this.isReady = true;
- return;
- }
- this.log('Not ready, waiting');
- this.elapsedTime_ += 100;
- // Try again in 100ms
- setTimeout('imageLoaderTestCase.runTests()', 100);
- }
- };
+ switch (e.type) {
+ case goog.net.EventType.COMPLETE:
+ fail('This test should never get COMPLETE event.');
+ return;
- /** Used by the JsUnit test runner. */
- function testCompleteResults() {
- imageLoaderTestCase.testCompleteResults();
+ case goog.events.EventType.LOAD:
+ case goog.net.EventType.ERROR:
+ loader.dispose();
+ break;
}
- /** Used by the JsUnit test runner. */
- function setUpPage() {
- imageLoaderTestCase.runTests();
- }
+ // Make sure that handler is never called again after disposal before
+ // marking test as successful.
+ asyncTestCase.waitForAsync('Wait to ensure that COMPLETE is never fired');
+ goog.Timer.callOnce(function() {
+ asyncTestCase.continueTesting();
+ }, 500);
+}
+
+
+/**
+ * Tests loading of images until completion.
+ */
+function testLoadingUntilCompletion() {
+ var results = {};
+ goog.events.listen(loader, TEST_EVENT_TYPES,
+ function(e) {
+ switch (e.type) {
+ case goog.events.EventType.LOAD:
+ var image = e.target;
+ results[image.src.substring(image.src.lastIndexOf('/') + 1)] =
+ [image.naturalWidth, image.naturalHeight, e.type];
+ return;
+
+ case goog.net.EventType.ERROR:
+ var image = e.target;
+ results[image.src.substring(image.src.lastIndexOf('/') + 1)] =
+ [image.naturalWidth, image.naturalHeight, e.type];
+ return;
+
+ case goog.net.EventType.COMPLETE:
+ // Test completes successfully.
+ asyncTestCase.continueTesting();
+
+ assertImagesAreCorrect(results);
+ return;
+ }
+ });
+
+ // waitForAsync before starting loader just in case handleImageLoaderEvent
+ // is called from within loader.start (before we yield control).
+ // This may happen in IE7/IE8.
+ asyncTestCase.waitForAsync('Waiting for loader handler to fire.');
+ loader.start();
+}
+
+
+function assertImagesAreCorrect(results) {
+ assertEquals(
+ goog.object.getCount(TEST_IMAGES), goog.object.getCount(results));
+ goog.object.forEach(TEST_IMAGES, function(value, key) {
+ // Check if fires the COMPLETE event.
+ assertTrue('Image is not loaded completely.', key in results);
+
+ var image = results[key];
+
+ // Check image size.
+ assertEquals('Image width is not correct', value[0], image[0]);
+ assertEquals('Image length is not correct', value[1], image[1]);
+
+ // Check if fired the correct event.
+ assertEquals('Event *' + value[2] + '* must be fired', value[2], image[2]);
+ });
+}
+
+
+/**
+ * Overrides the loader's loadImage_ method so that it dispatches an image
+ * loaded event immediately, causing any event listners to receive them
+ * synchronously. This allows tests to assume synchronous execution.
+ */
+function makeLoaderSynchronous(loader) {
+ var originalLoadImage = loader.loadImage_;
+ loader.loadImage_ = function(src, id) {
+ originalLoadImage.call(this, src, id);
+
+ var event = new goog.events.Event(goog.events.EventType.LOAD);
+ event.currentTarget = this.imageIdToImageMap_[id];
+ loader.onNetworkEvent_(event);
+ };
- /** Standalone Closure Test Runner. */
- if (typeof G_testRunner != 'undefined') {
- G_testRunner.initialize(imageLoaderTestCase);
- }
+ // Make listen() a no-op.
+ loader.handler_.listen = goog.nullFunction
+}
+
+
+/**
+ * Verifies that if an additional image is added after start() was called, but
+ * before COMPLETE was dispatched, no COMPLETE event is sent. Verifies COMPLETE
+ * is finally sent when .start() is called again and all images have now
+ * completed loading.
+ */
+function testImagesAddedAfterStart() {
+ // Use synchronous image loading.
+ makeLoaderSynchronous(loader);
+
+ // Add another image once the first images finishes loading.
+ goog.events.listenOnce(loader, goog.events.EventType.LOAD, function() {
+ loader.addImage('extra_image', 'extra_image.gif');
+ });
+
+ // Keep track of the total # of image loads.
+ var loadRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.events.EventType.LOAD, loadRecordFn);
+
+ // Keep track of how many times COMPLETE was dispatched.
+ var completeRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.net.EventType.COMPLETE, completeRecordFn);
+
+ // Start testing.
+ loader.start();
+ assertEquals(
+ 'COMPLETE event should not have been dispatched yet: An image was ' +
+ 'added after the initial batch was started.',
+ 0, completeRecordFn.getCallCount());
+ assertEquals('Just the test images should have loaded',
+ goog.object.getCount(TEST_IMAGES), loadRecordFn.getCallCount());
+
+ loader.start();
+ assertEquals('COMPLETE should have been dispatched once.',
+ 1, completeRecordFn.getCallCount());
+ assertEquals('All images should have been loaded',
+ goog.object.getCount(TEST_IMAGES) + 1, loadRecordFn.getCallCount());
+}
+
+
+/**
+ * Verifies that more images can be added after an upload starts, and start()
+ * can be called for them, resulting in just one COMPLETE event once all the
+ * images have completed.
+ */
+function testImagesAddedAndStartedAfterStart() {
+ // Use synchronous image loading.
+ makeLoaderSynchronous(loader);
+
+ // Keep track of the total # of image loads.
+ var loadRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.events.EventType.LOAD, loadRecordFn);
+
+ // Add more images once the first images finishes loading, and call start()
+ // to get them going.
+ goog.events.listenOnce(loader, goog.events.EventType.LOAD, function(e) {
+ loader.addImage('extra_image', 'extra_image.gif');
+ loader.addImage('extra_image2', 'extra_image2.gif');
+ loader.start();
+ });
+
+ // Keep track of how many times COMPLETE was dispatched.
+ var completeRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.net.EventType.COMPLETE, completeRecordFn);
+
+ // Start testing. Make sure all 7 images loaded.
+ loader.start();
+ assertEquals('COMPLETE should have been dispatched once.',
+ 1, completeRecordFn.getCallCount());
+ assertEquals('All images should have been loaded',
+ goog.object.getCount(TEST_IMAGES) + 2, loadRecordFn.getCallCount());
+}
+
+
+/**
+ * Verifies that if images are removed after loading has started, COMPLETE
+ * is dispatched once the remaining images have finished.
+ */
+function testImagesRemovedAfterStart() {
+ // Use synchronous image loading.
+ makeLoaderSynchronous(loader);
+
+ // Remove 2 images once the first image finishes loading.
+ goog.events.listenOnce(loader, goog.events.EventType.LOAD, function(e) {
+ loader.removeImage(
+ goog.array.peek(goog.object.getKeys(this.imageIdToUrlMap_)));
+ loader.removeImage(
+ goog.array.peek(goog.object.getKeys(this.imageIdToUrlMap_)));
+ });
+
+ // Keep track of the total # of image loads.
+ var loadRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.events.EventType.LOAD, loadRecordFn);
+
+ // Keep track of how many times COMPLETE was dispatched.
+ var completeRecordFn = goog.testing.recordFunction();
+ goog.events.listen(loader, goog.net.EventType.COMPLETE, completeRecordFn);
+
+ // Start testing. Make sure only the 3 images remaining loaded.
+ loader.start();
+ assertEquals('COMPLETE should have been dispatched once.',
+ 1, completeRecordFn.getCallCount());
+ assertEquals('All images should have been loaded',
+ goog.object.getCount(TEST_IMAGES) - 2, loadRecordFn.getCallCount());
+}
</script>
</body>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/ipaddress.js b/contexts/data/lib/closure-library/closure/goog/net/ipaddress.js
index 43f46b5..ef01ad5 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/ipaddress.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/ipaddress.js
@@ -98,6 +98,7 @@ goog.net.IpAddress.prototype.toUriString = goog.abstractMethod;
/**
* @return {string} The IP Address, as a string.
+ * @override
*/
goog.net.IpAddress.prototype.toString = goog.abstractMethod;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/jsloader.js b/contexts/data/lib/closure-library/closure/goog/net/jsloader.js
index 653b205..5c28835 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/jsloader.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/jsloader.js
@@ -13,8 +13,8 @@
// limitations under the License.
/**
- * @fileoverview A utility to load JavaScript files.
- * Refactored from goog.net.Jsonp.
+ * @fileoverview A utility to load JavaScript files via DOM script tags.
+ * Refactored from goog.net.Jsonp. Works cross-domain.
*
*/
@@ -73,7 +73,18 @@ goog.net.jsloader.scriptsToLoad_ = [];
/**
- * Loads and evaluates the JavaScript files at the specified URIs, in order.
+ * Loads and evaluates the JavaScript files at the specified URIs, guaranteeing
+ * the order of script loads.
+ *
+ * Because we have to load the scripts in serial (load script 1, exec script 1,
+ * load script 2, exec script 2, and so on), this will be slower than doing
+ * the network fetches in parallel.
+ *
+ * If you need to load a large number of scripts but dependency order doesn't
+ * matter, you should just call goog.net.jsloader.load N times.
+ *
+ * If you need to load a large number of scripts on the same domain,
+ * you may want to use goog.module.ModuleLoader.
*
* @param {Array.<string>} uris The URIs to load.
* @param {goog.net.jsloader.Options=} opt_options Optional parameters. See
@@ -90,34 +101,24 @@ goog.net.jsloader.loadMany = function(uris, opt_options) {
return;
}
- if (goog.userAgent.GECKO && !goog.userAgent.isVersion(2)) {
- // For <script> tags that are loaded in this manner, Gecko 1.9 and earlier
- // ensures that tag order is consistent with evaluation order.
- // Unfortunately, other browsers do not make that guarantee. So the other
- // browsers need a slower and more complex implementation.
- for (var i = 0; i < uris.length; i++) {
- goog.net.jsloader.load(uris[i], opt_options);
- }
- } else {
- var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;
- goog.array.extend(goog.net.jsloader.scriptsToLoad_, uris);
- if (isAnotherModuleLoading) {
- // jsloader is still loading some other scripts.
- // In order to prevent the race condition noted above, we just add
- // these URIs to the end of the scripts' queue and return.
- return;
- }
-
- uris = goog.net.jsloader.scriptsToLoad_;
- var popAndLoadNextScript = function() {
- var uri = uris.shift();
- var deferred = goog.net.jsloader.load(uri, opt_options);
- if (uris.length) {
- deferred.addBoth(popAndLoadNextScript);
- }
- };
- popAndLoadNextScript();
+ var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;
+ goog.array.extend(goog.net.jsloader.scriptsToLoad_, uris);
+ if (isAnotherModuleLoading) {
+ // jsloader is still loading some other scripts.
+ // In order to prevent the race condition noted above, we just add
+ // these URIs to the end of the scripts' queue and return.
+ return;
}
+
+ uris = goog.net.jsloader.scriptsToLoad_;
+ var popAndLoadNextScript = function() {
+ var uri = uris.shift();
+ var deferred = goog.net.jsloader.load(uri, opt_options);
+ if (uris.length) {
+ deferred.addBoth(popAndLoadNextScript);
+ }
+ };
+ popAndLoadNextScript();
};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/jsonp.js b/contexts/data/lib/closure-library/closure/goog/net/jsonp.js
index 5276a70..814591a 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/jsonp.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/jsonp.js
@@ -181,8 +181,6 @@ goog.net.Jsonp.prototype.send = function(opt_payload,
goog.global[goog.net.Jsonp.CALLBACKS] = {};
}
- var script = goog.dom.createElement('script');
-
// Create a new Uri object onto which this payload will be added
var uri = this.uri_.clone();
if (payload) {
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/all-wcprops
deleted file mode 100644
index 4ba95ef..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/all-wcprops
+++ /dev/null
@@ -1,29 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 50
-/svn/!svn/ver/1452/trunk/closure/goog/net/testdata
-END
-jsloader_test2.js
-K 25
-svn:wc:ra_dav:version-url
-V 68
-/svn/!svn/ver/1452/trunk/closure/goog/net/testdata/jsloader_test2.js
-END
-jsloader_test3.js
-K 25
-svn:wc:ra_dav:version-url
-V 68
-/svn/!svn/ver/1452/trunk/closure/goog/net/testdata/jsloader_test3.js
-END
-jsloader_test4.js
-K 25
-svn:wc:ra_dav:version-url
-V 68
-/svn/!svn/ver/1452/trunk/closure/goog/net/testdata/jsloader_test4.js
-END
-jsloader_test1.js
-K 25
-svn:wc:ra_dav:version-url
-V 68
-/svn/!svn/ver/1452/trunk/closure/goog/net/testdata/jsloader_test1.js
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/entries b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/entries
deleted file mode 100644
index 621ed39..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/entries
+++ /dev/null
@@ -1,164 +0,0 @@
-10
-
-dir
-1494
-http://closure-library.googlecode.com/svn/trunk/closure/goog/net/testdata
-http://closure-library.googlecode.com/svn
-
-
-
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0b95b8e8-c90f-11de-9d4f-f947ee5921c8
-
-jsloader_test2.js
-file
-
-
-
-
-2011-12-23T22:42:29.998349Z
-29e0eb8361ec520d2125352209589461
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-845
-
-jsloader_test3.js
-file
-
-
-
-
-2011-12-23T22:42:29.998349Z
-9e3bb1fbfe7ca1a8b70b7339bb6e0154
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-828
-
-jsloader_test4.js
-file
-
-
-
-
-2011-12-23T22:42:29.998349Z
-3415399ba68ff9ed965da1d849279faf
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-828
-
-jsloader_test1.js
-file
-
-
-
-
-2011-12-23T22:42:29.999349Z
-dffdc3191af40222534b3cca3b48bec9
-2011-12-07T06:16:31.000000Z
-1452
-ebixon@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-821
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test1.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test1.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test1.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test2.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test2.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test2.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test3.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test3.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test3.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test4.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test4.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/prop-base/jsloader_test4.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test1.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test1.js.svn-base
deleted file mode 100644
index 59d2162..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test1.js.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// All Rights Reserved
-
-/**
- * @fileoverview Test #1 of jsloader.
- */
-
-goog.provide('goog.net.testdata.jsloader_test1');
-goog.setTestOnly('jsloader_test1');
-
-window['test1'] = 'Test #1 loaded';
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test2.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test2.js.svn-base
deleted file mode 100644
index 8690539..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test2.js.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// All Rights Reserved
-
-/**
- * @fileoverview Test #2 of jsloader.
- */
-
-goog.provide('goog.net.testdata.jsloader_test2');
-goog.setTestOnly('jsloader_test2');
-
-window['closure_verification']['test2'] = 'Test #2 loaded';
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test3.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test3.js.svn-base
deleted file mode 100644
index 7c1181d..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test3.js.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// All Rights Reserved
-
-/**
- * @fileoverview Test #3 of jsloader.
- */
-
-goog.provide('goog.net.testdata.jsloader_test3');
-goog.setTestOnly('jsloader_test3');
-
-window['test3Callback']('Test #3 loaded');
diff --git a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test4.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test4.js.svn-base
deleted file mode 100644
index 591209c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/testdata/.svn/text-base/jsloader_test4.js.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// All Rights Reserved
-
-/**
- * @fileoverview Test #4 of jsloader.
- */
-
-goog.provide('goog.net.testdata.jsloader_test4');
-goog.setTestOnly('jsloader_test4');
-
-window['test4Callback']('Test #4 loaded');
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xhrio.js b/contexts/data/lib/closure-library/closure/goog/net/xhrio.js
index 09e30fa..c12cecb 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xhrio.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xhrio.js
@@ -88,7 +88,7 @@ goog.inherits(goog.net.XhrIo, goog.events.EventTarget);
/**
* Response types that may be requested for XMLHttpRequests.
* @enum {string}
- * @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute
+ * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute
*/
goog.net.XhrIo.ResponseType = {
DEFAULT: '',
@@ -149,8 +149,9 @@ goog.net.XhrIo.sendInstances_ = [];
* @param {Function=} opt_callback Callback function for when request is
* complete.
* @param {string=} opt_method Send method, default: GET.
- * @param {string|GearsBlob=} opt_content Post data. This can be a Gears blob
- * if the underlying HTTP request object is a Gears HTTP request.
+ * @param {string|FormData|GearsBlob=} opt_content
+ * Post data. This can be a Gears blob if the underlying HTTP request object
+ * is a Gears HTTP request.
* @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
* request.
* @param {number=} opt_timeoutInterval Number of milliseconds after which an
@@ -356,7 +357,7 @@ goog.net.XhrIo.prototype.responseType_ = goog.net.XhrIo.ResponseType.DEFAULT;
* more recent browsers that support this part of the HTTP Access Control
* standard.
*
- * @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#withcredentials
+ * @see http://www.w3.org/TR/XMLHttpRequest/#the-withcredentials-attribute
*
* @type {boolean}
* @private
@@ -434,15 +435,17 @@ goog.net.XhrIo.prototype.getWithCredentials = function() {
* Instance send that actually uses XMLHttpRequest to make a server call.
* @param {string|goog.Uri} url Uri to make request to.
* @param {string=} opt_method Send method, default: GET.
- * @param {string|GearsBlob=} opt_content Post data. This can be a Gears blob
- * if the underlying HTTP request object is a Gears HTTP request.
+ * @param {string|FormData|GearsBlob=} opt_content
+ * Post data. This can be a Gears blob if the underlying HTTP request object
+ * is a Gears HTTP request.
* @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
* request.
*/
goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content,
opt_headers) {
if (this.xhr_) {
- throw Error('[goog.net.XhrIo] Object is active with another request');
+ throw Error('[goog.net.XhrIo] Object is active with another request=' +
+ this.lastUri_ + '; newUri=' + url);
}
var method = opt_method ? opt_method.toUpperCase() : 'GET';
@@ -491,9 +494,15 @@ goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content,
});
}
+ var contentIsFormData = (goog.global['FormData'] &&
+ (content instanceof goog.global['FormData']));
if (method == 'POST' &&
- !headers.containsKey(goog.net.XhrIo.CONTENT_TYPE_HEADER)) {
- // For POST requests, default to the url-encoded form content type.
+ !headers.containsKey(goog.net.XhrIo.CONTENT_TYPE_HEADER) &&
+ !contentIsFormData) {
+ // For POST requests, default to the url-encoded form content type
+ // unless this is a FormData request. For FormData, the browser will
+ // automatically add a multipart/form-data content type with an appropriate
+ // multipart boundary.
headers.set(goog.net.XhrIo.CONTENT_TYPE_HEADER,
goog.net.XhrIo.FORM_CONTENT_TYPE);
}
@@ -729,18 +738,21 @@ goog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() {
this.active_ = false;
- // Call the specific callbacks for success or failure. Only call the
- // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)
- if (this.isSuccess()) {
- this.dispatchEvent(goog.net.EventType.COMPLETE);
- this.dispatchEvent(goog.net.EventType.SUCCESS);
- } else {
- this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;
- this.lastError_ = this.getStatusText() + ' [' + this.getStatus() + ']';
- this.dispatchErrors_();
+ try {
+ // Call the specific callbacks for success or failure. Only call the
+ // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED)
+ if (this.isSuccess()) {
+ this.dispatchEvent(goog.net.EventType.COMPLETE);
+ this.dispatchEvent(goog.net.EventType.SUCCESS);
+ } else {
+ this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR;
+ this.lastError_ =
+ this.getStatusText() + ' [' + this.getStatus() + ']';
+ this.dispatchErrors_();
+ }
+ } finally {
+ this.cleanUpXhr_();
}
-
- this.cleanUpXhr_();
}
}
};
@@ -961,7 +973,7 @@ goog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) {
* try to emulate it.
*
* Emulating the response means following the rules laid out at
- * http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-response-attribute.
+ * http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute
*
* On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only
* response types of DEFAULT or TEXT may be used, and the response returned will
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xhrio_test.html b/contexts/data/lib/closure-library/closure/goog/net/xhrio_test.html
index 096f8f6..a78eaf2 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xhrio_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/xhrio_test.html
@@ -21,6 +21,7 @@ See the COPYING file for details.
goog.require('goog.object');
goog.require('goog.string');
goog.require('goog.testing.MockClock');
+ goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.net.XhrIo');
goog.require('goog.testing.recordFunction');
@@ -34,6 +35,8 @@ MockXmlHttp.prototype.readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
MockXmlHttp.prototype.status = 200;
+MockXmlHttp.prototype.headers = {};
+
MockXmlHttp.syncSend = false;
MockXmlHttp.prototype.send = function(opt_data) {
@@ -65,7 +68,9 @@ MockXmlHttp.prototype.open = function(verb, uri, async) {
MockXmlHttp.prototype.abort = function() {};
-MockXmlHttp.prototype.setRequestHeader = function(key, value) {};
+MockXmlHttp.prototype.setRequestHeader = function(key, value) {
+ this.headers[key] = value;
+};
var lastMockXmlHttp;
goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
@@ -78,6 +83,7 @@ goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(
}));
+var propertyReplacer = new goog.testing.PropertyReplacer();
var clock;
var originalEntryPoint =
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_;
@@ -88,6 +94,7 @@ function setUp() {
}
function tearDown() {
+ propertyReplacer.reset();
clock.dispose();
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = originalEntryPoint;
}
@@ -413,8 +420,8 @@ function testSendFromListener() {
var e = assertThrows(function() {
x.send('url2');
});
- assertEquals('[goog.net.XhrIo] Object is active with another request',
- e.message);
+ assertEquals('[goog.net.XhrIo] Object is active with another request=url' +
+ '; newUri=url2', e.message);
});
x.send('url');
@@ -479,6 +486,24 @@ function testProtectEntryPointCalledOnAsyncSend() {
errorHandlerCallbackCalled);
}
+function testXHRIsDiposedEvenIfAListenerThrowsAnExceptionOnComplete() {
+ MockXmlHttp.syncSend = false;
+
+ var x = new goog.net.XhrIo;
+
+ goog.events.listen(x, goog.net.EventType.COMPLETE, function(e) {
+ throw Error();
+ }, false, x);
+
+ x.send('url');
+ assertThrows(function() {
+ lastMockXmlHttp.complete();
+ });
+
+ // The XHR should have been disposed, even though the listener threw an
+ // exception.
+ assertNull(x.xhr_);
+}
function testDisposeInternalDoesNotAbortXhrRequestObjectWhenActiveIsFalse() {
MockXmlHttp.syncSend = false;
@@ -510,6 +535,28 @@ function testCallingAbortFromWithinAbortCallbackDoesntLoop() {
x.abort();
}
+function testPostSetsContentTypeHeader() {
+ var x = new goog.net.XhrIo;
+
+ x.send('url', 'POST', 'content');
+ var headers = lastMockXmlHttp.headers;
+ assertEquals(1, goog.object.getCount(headers));
+ assertEquals(
+ headers[goog.net.XhrIo.CONTENT_TYPE_HEADER],
+ goog.net.XhrIo.FORM_CONTENT_TYPE);
+}
+
+function testPostFormDataDoesNotSetContentTypeHeader() {
+ function FakeFormData() {}
+
+ propertyReplacer.set(goog.global, 'FormData', FakeFormData);
+
+ var x = new goog.net.XhrIo;
+ x.send('url', 'POST', new FakeFormData());
+ var headers = lastMockXmlHttp.headers;
+ assertTrue(goog.object.isEmpty(headers));
+}
+
function testFactoryInjection() {
var xhr = new MockXmlHttp();
var optionsFactoryCalled = 0;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xhriopool.js b/contexts/data/lib/closure-library/closure/goog/net/xhriopool.js
index 1b2e171..ecbfca6 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xhriopool.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xhriopool.js
@@ -52,6 +52,7 @@ goog.inherits(goog.net.XhrIoPool, goog.structs.PriorityPool);
/**
* Creates an instance of an XhrIo object to use in the pool.
* @return {goog.net.XhrIo} The created object.
+ * @override
*/
goog.net.XhrIoPool.prototype.createObject = function() {
var xhrIo = new goog.net.XhrIo();
@@ -66,22 +67,14 @@ goog.net.XhrIoPool.prototype.createObject = function() {
/**
- * Should be overridden to dispose of an object, default implementation is to
- * remove all its members which should render it useless.
- * @param {goog.net.XhrIo} obj The object to dispose.
- */
-goog.net.XhrIoPool.prototype.disposeObject = function(obj) {
- obj.dispose();
-};
-
-
-/**
* Determine if an object has become unusable and should not be used.
- * @param {goog.net.XhrIo} obj The object to test.
+ * @param {Object} obj The object to test.
* @return {boolean} Whether the object can be reused, which is true if the
* object is not disposed and not active.
+ * @override
*/
goog.net.XhrIoPool.prototype.objectCanBeReused = function(obj) {
// An active XhrIo object should never be used.
- return !obj.isDisposed() && !obj.isActive();
+ var xhr = /** @type {goog.net.XhrIo} */ (obj);
+ return !xhr.isDisposed() && !xhr.isActive();
};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xhrmanager.js b/contexts/data/lib/closure-library/closure/goog/net/xhrmanager.js
index 36339f4..d7b786b 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xhrmanager.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xhrmanager.js
@@ -139,7 +139,9 @@ goog.net.XhrManager.prototype.setTimeoutInterval = function(ms) {
/**
- * Returns the number of reuqests either in flight, or waiting to be sent.
+ * Returns the number of requests either in flight, or waiting to be sent.
+ * The count will include the current request if used within a COMPLETE event
+ * handler or callback.
* @return {number} The number of requests in flight or pending send.
*/
goog.net.XhrManager.prototype.getOutstandingCount = function() {
@@ -148,6 +150,17 @@ goog.net.XhrManager.prototype.getOutstandingCount = function() {
/**
+ * Returns an array of request ids that are either in flight, or waiting to
+ * be sent. The id of the current request will be included if used within a
+ * COMPLETE event handler or callback.
+ * @return {!Array.<string>} Request ids in flight or pending send.
+ */
+goog.net.XhrManager.prototype.getOutstandingRequestIds = function() {
+ return this.requests_.getKeys();
+};
+
+
+/**
* Registers the given request to be sent. Throws an error if a request
* already exists with the given ID.
* NOTE: It is not sent immediately. It is queued and will be sent when an
@@ -159,11 +172,14 @@ goog.net.XhrManager.prototype.getOutstandingCount = function() {
* @param {string=} opt_content Post data.
* @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
* request.
- * @param {*=} opt_priority The priority of the request.
+ * @param {*=} opt_priority The priority of the request. A smaller value means a
+ * higher priority.
* @param {Function=} opt_callback Callback function for when request is
* complete. The only param is the event object from the COMPLETE event.
* @param {number=} opt_maxRetries The maximum number of times the request
* should be retried.
+ * @param {goog.net.XhrIo.ResponseType=} opt_responseType The response type of
+ * this request; defaults to goog.net.XhrIo.ResponseType.DEFAULT.
* @return {goog.net.XhrManager.Request} The queued request object.
*/
goog.net.XhrManager.prototype.send = function(
@@ -174,7 +190,8 @@ goog.net.XhrManager.prototype.send = function(
opt_headers,
opt_priority,
opt_callback,
- opt_maxRetries) {
+ opt_maxRetries,
+ opt_responseType) {
var requests = this.requests_;
// Check if there is already a request with the given id.
if (requests.get(id)) {
@@ -189,7 +206,8 @@ goog.net.XhrManager.prototype.send = function(
opt_content,
opt_headers,
opt_callback,
- goog.isDef(opt_maxRetries) ? opt_maxRetries : this.maxRetries_);
+ goog.isDef(opt_maxRetries) ? opt_maxRetries : this.maxRetries_,
+ opt_responseType);
this.requests_.set(id, request);
// Setup the callback for the pool.
@@ -212,15 +230,17 @@ goog.net.XhrManager.prototype.abort = function(id, opt_force) {
var xhrIo = request.xhrIo;
request.setAborted(true);
if (opt_force) {
- // We remove listeners to make sure nothing gets called if a new request
- // with the same id is made.
- this.removeXhrListener_(xhrIo, request.getXhrEventCallback());
- goog.events.listenOnce(
- xhrIo,
- goog.net.EventType.READY,
- function() { this.xhrPool_.releaseObject(xhrIo); },
- false,
- this);
+ if (xhrIo) {
+ // We remove listeners to make sure nothing gets called if a new request
+ // with the same id is made.
+ this.removeXhrListener_(xhrIo, request.getXhrEventCallback());
+ goog.events.listenOnce(
+ xhrIo,
+ goog.net.EventType.READY,
+ function() { this.xhrPool_.releaseObject(xhrIo); },
+ false,
+ this);
+ }
this.requests_.remove(id);
}
if (xhrIo) {
@@ -247,6 +267,7 @@ goog.net.XhrManager.prototype.handleAvailableXhr_ = function(id, xhrIo) {
// Set properties for the XhrIo.
xhrIo.setTimeoutInterval(this.timeoutInterval_);
+ xhrIo.setResponseType(request.getResponseType());
// Add a reference to the XhrIo object to the request.
request.xhrIo = request.xhrLite = xhrIo;
@@ -511,10 +532,6 @@ goog.inherits(goog.net.XhrManager.Event, goog.events.Event);
/** @override */
goog.net.XhrManager.Event.prototype.disposeInternal = function() {
- goog.net.XhrManager.Event.superClass_.disposeInternal.call(this);
- delete this.id;
- this.xhrIo = null;
- this.xhrLite = null;
};
@@ -534,12 +551,14 @@ goog.net.XhrManager.Event.prototype.disposeInternal = function() {
* complete. NOTE: Only 1 callback supported across all events.
* @param {number=} opt_maxRetries The maximum number of times the request
* should be retried (Default: 1).
+ * @param {goog.net.XhrIo.ResponseType=} opt_responseType The response type of
+ * this request; defaults to goog.net.XhrIo.ResponseType.DEFAULT.
*
* @constructor
* @extends {goog.Disposable}
*/
goog.net.XhrManager.Request = function(url, xhrEventCallback, opt_method,
- opt_content, opt_headers, opt_callback, opt_maxRetries) {
+ opt_content, opt_headers, opt_callback, opt_maxRetries, opt_responseType) {
goog.Disposable.call(this);
/**
@@ -613,6 +632,13 @@ goog.net.XhrManager.Request = function(url, xhrEventCallback, opt_method,
this.completeCallback_ = opt_callback;
/**
+ * A response type to set on this.xhrIo when it's populated.
+ * @type {!goog.net.XhrIo.ResponseType}
+ * @private
+ */
+ this.responseType_ = opt_responseType || goog.net.XhrIo.ResponseType.DEFAULT;
+
+ /**
* The XhrIo instance handling this request. Set in handleAvailableXhr.
* @type {goog.net.XhrIo}
*/
@@ -749,6 +775,17 @@ goog.net.XhrManager.Request.prototype.getCompleteCallback = function() {
};
+/**
+ * Gets the response type that will be set on this request's XhrIo when it's
+ * available.
+ * @return {!goog.net.XhrIo.ResponseType} The response type to be set
+ * when an XhrIo becomes available to this request.
+ */
+goog.net.XhrManager.Request.prototype.getResponseType = function() {
+ return this.responseType_;
+};
+
+
/** @override */
goog.net.XhrManager.Request.prototype.disposeInternal = function() {
goog.net.XhrManager.Request.superClass_.disposeInternal.call(this);
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xhrmanager_test.html b/contexts/data/lib/closure-library/closure/goog/net/xhrmanager_test.html
new file mode 100644
index 0000000..81350e1
--- /dev/null
+++ b/contexts/data/lib/closure-library/closure/goog/net/xhrmanager_test.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+<!--
+Copyright 2012 The Closure Library Authors. All Rights Reserved.
+
+Use of this source code is governed by the Apache License, Version 2.0.
+See the COPYING file for details.
+-->
+<!--
+-->
+<head>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<title>Closure Unit Tests - goog.net.XhrManager</title>
+<script src="../base.js"></script>
+<script>
+ goog.require('goog.events');
+ goog.require('goog.net.EventType');
+ goog.require('goog.net.XhrManager');
+ goog.require('goog.testing.jsunit');
+ goog.require('goog.testing.net.XhrIoPool');
+ goog.require('goog.testing.recordFunction');
+</script>
+</head>
+<body>
+<script>
+
+ /** @type {goog.net.XhrManager} */
+ var xhrManager
+
+ /** @type {goog.testing.net.XhrIo} */
+ var xhrIo;
+
+
+ function setUp() {
+ xhrManager = new goog.net.XhrManager();
+ xhrManager.xhrPool_ = new goog.testing.net.XhrIoPool();
+ xhrIo = xhrManager.xhrPool_.getXhr();
+ }
+
+
+ function tearDown() {
+ goog.dispose(xhrManager);
+ }
+
+
+ function testGetOutstandingRequestIds() {
+ assertArrayEquals(
+ 'No outstanding requests', [], xhrManager.getOutstandingRequestIds());
+
+ xhrManager.send('test1', '/test1');
+ assertArrayEquals(
+ 'Single outstanding request', ['test1'],
+ xhrManager.getOutstandingRequestIds());
+
+ xhrManager.send('test2', '/test2');
+ assertArrayEquals(
+ 'Two outstanding requests', ['test1', 'test2'],
+ xhrManager.getOutstandingRequestIds());
+
+ xhrIo.simulateResponse(200, 'data');
+ assertArrayEquals(
+ 'Single outstanding request', ['test2'],
+ xhrManager.getOutstandingRequestIds());
+
+ xhrIo.simulateResponse(200, 'data');
+ assertArrayEquals(
+ 'No outstanding requests', [], xhrManager.getOutstandingRequestIds());
+ }
+
+
+ function testForceAbortQueuedRequest() {
+ xhrManager.send('test', '/test');
+ xhrManager.send('queued', '/queued');
+
+ assertNotThrows(
+ 'Forced abort of queued request should not throw an error',
+ goog.bind(xhrManager.abort, xhrManager, 'queued', true));
+
+ assertNotThrows(
+ 'Forced abort of normal request should not throw an error',
+ goog.bind(xhrManager.abort, xhrManager, 'test', true));
+ }
+
+
+ function testDefaultResponseType() {
+ var callback = goog.testing.recordFunction(function(e) {
+ assertEquals('test1', e.id);
+ assertEquals(
+ goog.net.XhrIo.ResponseType.DEFAULT, e.xhrIo.getResponseType());
+ eventCalled = true;
+ });
+ goog.events.listenOnce(xhrManager, goog.net.EventType.READY, callback);
+ xhrManager.send('test1', '/test2');
+ assertEquals(1, callback.getCallCount());
+
+ xhrIo.simulateResponse(200, 'data'); // Do this to make tearDown() happy.
+ }
+
+
+ function testNonDefaultResponseType() {
+ var callback = goog.testing.recordFunction(function(e) {
+ assertEquals('test2', e.id);
+ assertEquals(
+ goog.net.XhrIo.ResponseType.ARRAY_BUFFER, e.xhrIo.getResponseType());
+ eventCalled = true;
+ });
+ goog.events.listenOnce(xhrManager, goog.net.EventType.READY, callback);
+ xhrManager.send('test2', '/test2',
+ undefined /* opt_method */,
+ undefined /* opt_content */,
+ undefined /* opt_headers */,
+ undefined /* opt_priority */,
+ undefined /* opt_callback */,
+ undefined /* opt_maxRetries */,
+ goog.net.XhrIo.ResponseType.ARRAY_BUFFER);
+ assertEquals(1, callback.getCallCount());
+
+ xhrIo.simulateResponse(200, 'data'); // Do this to make tearDown() happy.
+ }
+
+</script>
+</body>
+</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xmlhttp.js b/contexts/data/lib/closure-library/closure/goog/net/xmlhttp.js
index da85a65..da64e9f 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xmlhttp.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xmlhttp.js
@@ -37,6 +37,13 @@ goog.net.XmlHttp = function() {
/**
+ * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to
+ * true strips the ActiveX probing code.
+ */
+goog.net.XmlHttp.ASSUME_NATIVE_XHR = false;
+
+
+/**
* Gets the options to use with the XMLHttpRequest objects obtained using
* the static methods.
* @return {Object} The options.
@@ -168,10 +175,10 @@ goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() {
/**
* The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized.
- * @type {?string}
+ * @type {string|undefined}
* @private
*/
-goog.net.DefaultXmlHttpFactory.prototype.ieProgId_ = null;
+goog.net.DefaultXmlHttpFactory.prototype.ieProgId_;
/**
@@ -180,6 +187,10 @@ goog.net.DefaultXmlHttpFactory.prototype.ieProgId_ = null;
* @private
*/
goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() {
+ if (goog.net.XmlHttp.ASSUME_NATIVE_XHR) {
+ return '';
+ }
+
// The following blog post describes what PROG IDs to use to create the
// XMLHTTP object in Internet Explorer:
// http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/all-wcprops
deleted file mode 100644
index bdcf701..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/all-wcprops
+++ /dev/null
@@ -1,77 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 45
-/svn/!svn/ver/1477/trunk/closure/goog/net/xpc
-END
-iframepollingtransport.js
-K 25
-svn:wc:ra_dav:version-url
-V 71
-/svn/!svn/ver/1362/trunk/closure/goog/net/xpc/iframepollingtransport.js
-END
-crosspagechannel_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 72
-/svn/!svn/ver/1302/trunk/closure/goog/net/xpc/crosspagechannel_test.html
-END
-nativemessagingtransport_test.html
-K 25
-svn:wc:ra_dav:version-url
-V 80
-/svn/!svn/ver/1122/trunk/closure/goog/net/xpc/nativemessagingtransport_test.html
-END
-xpc.js
-K 25
-svn:wc:ra_dav:version-url
-V 51
-/svn/!svn/ver/850/trunk/closure/goog/net/xpc/xpc.js
-END
-nixtransport.js
-K 25
-svn:wc:ra_dav:version-url
-V 61
-/svn/!svn/ver/1302/trunk/closure/goog/net/xpc/nixtransport.js
-END
-transport.js
-K 25
-svn:wc:ra_dav:version-url
-V 58
-/svn/!svn/ver/1020/trunk/closure/goog/net/xpc/transport.js
-END
-relay.js
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/850/trunk/closure/goog/net/xpc/relay.js
-END
-iframerelaytransport.js
-K 25
-svn:wc:ra_dav:version-url
-V 69
-/svn/!svn/ver/1302/trunk/closure/goog/net/xpc/iframerelaytransport.js
-END
-crosspagechannel.js
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/svn/!svn/ver/1477/trunk/closure/goog/net/xpc/crosspagechannel.js
-END
-nativemessagingtransport.js
-K 25
-svn:wc:ra_dav:version-url
-V 73
-/svn/!svn/ver/1302/trunk/closure/goog/net/xpc/nativemessagingtransport.js
-END
-crosspagechannelrole.js
-K 25
-svn:wc:ra_dav:version-url
-V 69
-/svn/!svn/ver/1122/trunk/closure/goog/net/xpc/crosspagechannelrole.js
-END
-frameelementmethodtransport.js
-K 25
-svn:wc:ra_dav:version-url
-V 76
-/svn/!svn/ver/1302/trunk/closure/goog/net/xpc/frameelementmethodtransport.js
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/entries b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/entries
deleted file mode 100644
index 608c60c..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/entries
+++ /dev/null
@@ -1,439 +0,0 @@
-10
-
-dir
-1494
-http://closure-library.googlecode.com/svn/trunk/closure/goog/net/xpc
-http://closure-library.googlecode.com/svn
-
-
-
-2011-12-14T19:06:32.000000Z
-1477
-dpb@google.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0b95b8e8-c90f-11de-9d4f-f947ee5921c8
-
-iframepollingtransport.js
-file
-
-
-
-
-2011-12-23T22:42:30.163351Z
-c62fdd9adccdf1db5738eb994d6d423a
-2011-10-27T21:00:19.000000Z
-1362
-junyin@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-25019
-
-crosspagechannel_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.164351Z
-377b19f3f6438ec732b6562830399601
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11801
-
-nativemessagingtransport_test.html
-file
-
-
-
-
-2011-12-23T22:42:30.165351Z
-381477fd2a0f9f8155f5dcef63e04063
-2011-07-13T22:50:38.000000Z
-1122
-mknichel@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4892
-
-xpc.js
-file
-
-
-
-
-2011-12-23T22:42:30.165351Z
-86f55130f1502a8761205ca0c029556e
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6184
-
-nixtransport.js
-file
-
-
-
-
-2011-12-23T22:42:30.166351Z
-e9e39d8a1754a26b504cfa3f2524a08d
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-14881
-
-transport.js
-file
-
-
-
-
-2011-12-23T22:42:30.167351Z
-d86182105ba1f92fc5ada97d6d46108b
-2011-06-09T19:55:41.000000Z
-1020
-ivaylobakalov@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2717
-
-relay.js
-file
-
-
-
-
-2011-12-23T22:42:30.167351Z
-3c3f467b3f3ee5808f93b7bc6f2385aa
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2201
-
-iframerelaytransport.js
-file
-
-
-
-
-2011-12-23T22:42:30.168351Z
-7ee604e01e9ef5a1680536b7cbb8f0e4
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-11612
-
-testdata
-dir
-
-crosspagechannel.js
-file
-
-
-
-
-2011-12-23T22:42:30.169351Z
-09cb6b5db328c49d539274c3b1805819
-2011-12-14T19:06:32.000000Z
-1477
-dpb@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-21370
-
-nativemessagingtransport.js
-file
-
-
-
-
-2011-12-23T22:42:30.169351Z
-c9bcc0a1161b7772cb8e3f52cc582d17
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-9836
-
-crosspagechannelrole.js
-file
-
-
-
-
-2011-12-23T22:42:30.170351Z
-9c07a99aa10ead74a5287bbd9b56ab32
-2011-07-13T22:50:38.000000Z
-1122
-mknichel@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-881
-
-frameelementmethodtransport.js
-file
-
-
-
-
-2011-12-23T22:42:30.171351Z
-87e0ce3003224561c690fae06d2776c8
-2011-09-27T00:20:47.000000Z
-1302
-bmccann@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7318
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannel_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannelrole.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannelrole.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/crosspagechannelrole.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/frameelementmethodtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/frameelementmethodtransport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/frameelementmethodtransport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframepollingtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframepollingtransport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframepollingtransport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframerelaytransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframerelaytransport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/iframerelaytransport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport_test.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nativemessagingtransport_test.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nixtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nixtransport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/nixtransport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/relay.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/relay.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/relay.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/transport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/transport.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/transport.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/xpc.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/xpc.js.svn-base
deleted file mode 100644
index 530636b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/prop-base/xpc.js.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 15
-text/javascript
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel.js.svn-base
deleted file mode 100644
index f14e95e..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel.js.svn-base
+++ /dev/null
@@ -1,673 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Provides the class CrossPageChannel, the main class in
- * goog.net.xpc.
- *
- * @see ../../demos/xpc/index.html
- */
-
-goog.provide('goog.net.xpc.CrossPageChannel');
-
-goog.require('goog.Disposable');
-goog.require('goog.Uri');
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.json');
-goog.require('goog.messaging.AbstractChannel');
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.CrossPageChannelRole');
-goog.require('goog.net.xpc.FrameElementMethodTransport');
-goog.require('goog.net.xpc.IframePollingTransport');
-goog.require('goog.net.xpc.IframeRelayTransport');
-goog.require('goog.net.xpc.NativeMessagingTransport');
-goog.require('goog.net.xpc.NixTransport');
-goog.require('goog.net.xpc.Transport');
-goog.require('goog.userAgent');
-
-
-
-/**
- * A communication channel between two documents from different domains.
- * Provides asynchronous messaging.
- *
- * @param {Object} cfg Channel configuration object.
- * @param {goog.dom.DomHelper=} opt_domHelper The optional dom helper to
- * use for looking up elements in the dom.
- * @constructor
- * @extends {goog.messaging.AbstractChannel}
- */
-goog.net.xpc.CrossPageChannel = function(cfg, opt_domHelper) {
- goog.base(this);
-
- for (var i = 0, uriField; uriField = goog.net.xpc.UriCfgFields[i]; i++) {
- if (uriField in cfg && !/^https?:\/\//.test(cfg[uriField])) {
- throw Error('URI ' + cfg[uriField] + ' is invalid for field ' + uriField);
- }
- }
-
- /**
- * The configuration for this channel.
- * @type {Object}
- * @private
- */
- this.cfg_ = cfg;
-
- /**
- * The name of the channel.
- * @type {string}
- * @protected
- */
- this.name = this.cfg_[goog.net.xpc.CfgFields.CHANNEL_NAME] ||
- goog.net.xpc.getRandomString(10);
-
- /**
- * The dom helper to use for accessing the dom.
- * @type {goog.dom.DomHelper}
- * @private
- */
- this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();
-
- /**
- * Collects deferred function calls which will be made once the connection
- * has been fully set up.
- * @type {!Array.<function()>}
- * @private
- */
- this.deferredDeliveries_ = [];
-
- // If LOCAL_POLL_URI or PEER_POLL_URI is not available, try using
- // robots.txt from that host.
- cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] =
- cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] ||
- goog.uri.utils.getHost(this.domHelper_.getWindow().location.href) +
- '/robots.txt';
- // PEER_URI is sometimes undefined in tests.
- cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] =
- cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] ||
- goog.uri.utils.getHost(cfg[goog.net.xpc.CfgFields.PEER_URI] || '') +
- '/robots.txt';
-
- goog.net.xpc.channels_[this.name] = this;
-
- goog.events.listen(window, 'unload',
- goog.net.xpc.CrossPageChannel.disposeAll_);
-
- goog.net.xpc.logger.info('CrossPageChannel created: ' + this.name);
-};
-goog.inherits(goog.net.xpc.CrossPageChannel, goog.messaging.AbstractChannel);
-
-
-/**
- * Regexp for escaping service names.
- * @type {RegExp}
- * @private
- */
-goog.net.xpc.CrossPageChannel.TRANSPORT_SERVICE_ESCAPE_RE_ =
- new RegExp('^%*' + goog.net.xpc.TRANSPORT_SERVICE_ + '$');
-
-
-/**
- * Regexp for unescaping service names.
- * @type {RegExp}
- * @private
- */
-goog.net.xpc.CrossPageChannel.TRANSPORT_SERVICE_UNESCAPE_RE_ =
- new RegExp('^%+' + goog.net.xpc.TRANSPORT_SERVICE_ + '$');
-
-
-/**
- * The transport.
- * @type {goog.net.xpc.Transport?}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.transport_ = null;
-
-
-/**
- * The channel state.
- * @type {number}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.state_ =
- goog.net.xpc.ChannelStates.NOT_CONNECTED;
-
-
-/**
- * @override
- * @return {boolean} Whether the channel is connected.
- */
-goog.net.xpc.CrossPageChannel.prototype.isConnected = function() {
- return this.state_ == goog.net.xpc.ChannelStates.CONNECTED;
-};
-
-
-/**
- * Reference to the window-object of the peer page.
- * @type {Object}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.peerWindowObject_ = null;
-
-
-/**
- * Reference to the iframe-element.
- * @type {Object}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.iframeElement_ = null;
-
-
-/**
- * Sets the window object the foreign document resides in.
- *
- * @param {Object} peerWindowObject The window object of the peer.
- */
-goog.net.xpc.CrossPageChannel.prototype.setPeerWindowObject =
- function(peerWindowObject) {
- this.peerWindowObject_ = peerWindowObject;
-};
-
-
-/**
- * Determine which transport type to use for this channel / useragent.
- * @return {goog.net.xpc.TransportTypes|undefined} The best transport type.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.determineTransportType_ = function() {
- var transportType;
- if (goog.isFunction(document.postMessage) ||
- goog.isFunction(window.postMessage) ||
- // IE8 supports window.postMessage, but
- // typeof window.postMessage returns "object"
- (goog.userAgent.IE && window.postMessage)) {
- transportType = goog.net.xpc.TransportTypes.NATIVE_MESSAGING;
- } else if (goog.userAgent.GECKO) {
- transportType = goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD;
- } else if (goog.userAgent.IE &&
- this.cfg_[goog.net.xpc.CfgFields.PEER_RELAY_URI]) {
- transportType = goog.net.xpc.TransportTypes.IFRAME_RELAY;
- } else if (goog.userAgent.IE && goog.net.xpc.NixTransport.isNixSupported()) {
- transportType = goog.net.xpc.TransportTypes.NIX;
- } else {
- transportType = goog.net.xpc.TransportTypes.IFRAME_POLLING;
- }
- return transportType;
-};
-
-
-/**
- * Creates the transport for this channel. Chooses from the available
- * transport based on the user agent and the configuration.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.createTransport_ = function() {
- // return, if the transport has already been created
- if (this.transport_) {
- return;
- }
-
- if (!this.cfg_[goog.net.xpc.CfgFields.TRANSPORT]) {
- this.cfg_[goog.net.xpc.CfgFields.TRANSPORT] =
- this.determineTransportType_();
- }
-
- switch (this.cfg_[goog.net.xpc.CfgFields.TRANSPORT]) {
- case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
- this.transport_ = new goog.net.xpc.NativeMessagingTransport(
- this,
- this.cfg_[goog.net.xpc.CfgFields.PEER_HOSTNAME],
- this.domHelper_);
- break;
- case goog.net.xpc.TransportTypes.NIX:
- this.transport_ = new goog.net.xpc.NixTransport(this, this.domHelper_);
- break;
- case goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD:
- this.transport_ =
- new goog.net.xpc.FrameElementMethodTransport(this, this.domHelper_);
- break;
- case goog.net.xpc.TransportTypes.IFRAME_RELAY:
- this.transport_ =
- new goog.net.xpc.IframeRelayTransport(this, this.domHelper_);
- break;
- case goog.net.xpc.TransportTypes.IFRAME_POLLING:
- this.transport_ =
- new goog.net.xpc.IframePollingTransport(this, this.domHelper_);
- break;
- }
-
- if (this.transport_) {
- goog.net.xpc.logger.info('Transport created: ' + this.transport_.getName());
- } else {
- throw Error('CrossPageChannel: No suitable transport found!');
- }
-};
-
-
-/**
- * Returns the transport type in use for this channel.
- * @return {number} Transport-type identifier.
- */
-goog.net.xpc.CrossPageChannel.prototype.getTransportType = function() {
- return this.transport_.getType();
-};
-
-
-/**
- * Returns the tranport name in use for this channel.
- * @return {string} The transport name.
- */
-goog.net.xpc.CrossPageChannel.prototype.getTransportName = function() {
- return this.transport_.getName();
-};
-
-
-/**
- * @return {Object} Configuration-object to be used by the peer to
- * initialize the channel.
- */
-goog.net.xpc.CrossPageChannel.prototype.getPeerConfiguration = function() {
- var peerCfg = {};
- peerCfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = this.name;
- peerCfg[goog.net.xpc.CfgFields.TRANSPORT] =
- this.cfg_[goog.net.xpc.CfgFields.TRANSPORT];
-
- if (this.cfg_[goog.net.xpc.CfgFields.LOCAL_RELAY_URI]) {
- peerCfg[goog.net.xpc.CfgFields.PEER_RELAY_URI] =
- this.cfg_[goog.net.xpc.CfgFields.LOCAL_RELAY_URI];
- }
- if (this.cfg_[goog.net.xpc.CfgFields.LOCAL_POLL_URI]) {
- peerCfg[goog.net.xpc.CfgFields.PEER_POLL_URI] =
- this.cfg_[goog.net.xpc.CfgFields.LOCAL_POLL_URI];
- }
- if (this.cfg_[goog.net.xpc.CfgFields.PEER_POLL_URI]) {
- peerCfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] =
- this.cfg_[goog.net.xpc.CfgFields.PEER_POLL_URI];
- }
-
- return peerCfg;
-};
-
-
-/**
- * Creates the iframe containing the peer page in a specified parent element.
- * This method does not connect the channel, connect() still has to be called
- * separately.
- *
- * @param {!Element} parentElm The container element the iframe is appended to.
- * @param {Function=} opt_configureIframeCb If present, this function gets
- * called with the iframe element as parameter to allow setting properties
- * on it before it gets added to the DOM. If absent, the iframe's width and
- * height are set to '100%'.
- * @param {boolean=} opt_addCfgParam Whether to add the peer configuration as
- * URL parameter (default: true).
- * @return {!HTMLIFrameElement} The iframe element.
- */
-goog.net.xpc.CrossPageChannel.prototype.createPeerIframe = function(
- parentElm, opt_configureIframeCb, opt_addCfgParam) {
-
- var iframeId = this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID];
- if (!iframeId) {
- // Create a randomized ID for the iframe element to avoid
- // bfcache-related issues.
- iframeId = this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID] =
- 'xpcpeer' + goog.net.xpc.getRandomString(4);
- }
-
- // TODO(user) Opera creates a history-entry when creating an iframe
- // programmatically as follows. Find a way which avoids this.
-
- var iframeElm = goog.dom.createElement('IFRAME');
- iframeElm.id = iframeElm.name = iframeId;
- if (opt_configureIframeCb) {
- opt_configureIframeCb(iframeElm);
- } else {
- iframeElm.style.width = iframeElm.style.height = '100%';
- }
-
- var peerUri = this.getPeerUri(opt_addCfgParam);
-
- if (goog.userAgent.GECKO || goog.userAgent.WEBKIT) {
- // Appending the iframe in a timeout to avoid a weird fastback issue, which
- // is present in Safari and Gecko.
- this.deferConnect_ = true;
- window.setTimeout(
- goog.bind(function() {
- this.deferConnect_ = false;
- parentElm.appendChild(iframeElm);
- iframeElm.src = peerUri.toString();
- goog.net.xpc.logger.info('peer iframe created (' + iframeId + ')');
- if (this.connectDeferred_) {
- this.connect(this.connectCb_);
- }
- }, this), 1);
- } else {
- iframeElm.src = peerUri.toString();
- parentElm.appendChild(iframeElm);
- goog.net.xpc.logger.info('peer iframe created (' + iframeId + ')');
- }
-
- return /** @type {!HTMLIFrameElement} */ (iframeElm);
-};
-
-
-/**
- * Returns the peer URI, with an optional URL parameter for configuring the peer
- * window.
- *
- * @param {boolean=} opt_addCfgParam Whether to add the peer configuration as
- * URL parameter (default: true).
- * @return {!goog.Uri} The peer URI.
- */
-goog.net.xpc.CrossPageChannel.prototype.getPeerUri = function(opt_addCfgParam) {
- var peerUri = this.cfg_[goog.net.xpc.CfgFields.PEER_URI];
- if (goog.isString(peerUri)) {
- peerUri = this.cfg_[goog.net.xpc.CfgFields.PEER_URI] =
- new goog.Uri(peerUri);
- }
-
- // Add the channel configuration used by the peer as URL parameter.
- if (opt_addCfgParam !== false) {
- peerUri.setParameterValue('xpc',
- goog.json.serialize(
- this.getPeerConfiguration()));
- }
-
- return peerUri;
-};
-
-
-/**
- * Flag whether connecting should be deferred.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.deferConnect_ = false;
-
-
-/**
- * Flag to remember if connect() has been called.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.connectDeferred_ = false;
-
-
-/**
- * Initiates connecting the channel. When this method is called, all the
- * information needed to connect the channel has to be available.
- *
- * @override
- * @param {Function=} opt_connectCb The function to be called when the
- * channel has been connected and is ready to be used.
- */
-goog.net.xpc.CrossPageChannel.prototype.connect = function(opt_connectCb) {
- this.connectCb_ = opt_connectCb || goog.nullFunction;
-
- if (this.deferConnect_) {
- goog.net.xpc.logger.info('connect() deferred');
- this.connectDeferred_ = true;
- return;
- }
- this.connectDeferred_ = false;
-
- goog.net.xpc.logger.info('connect()');
- if (this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID]) {
- this.iframeElement_ = this.domHelper_.getElement(
- this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID]);
- }
- if (this.iframeElement_) {
- var winObj = this.iframeElement_.contentWindow;
- // accessing the window using contentWindow doesn't work in safari
- if (!winObj) {
- winObj = window.frames[this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID]];
- }
- this.setPeerWindowObject(winObj);
- }
-
- // if the peer window object has not been set at this point, we assume
- // being in an iframe and the channel is meant to be to the containing page
- if (!this.peerWindowObject_) {
- // throw an error if we are in the top window (== not in an iframe)
- if (window == top) {
- throw Error(
- "CrossPageChannel: Can't connect, peer window-object not set.");
- } else {
- this.setPeerWindowObject(window.parent);
- }
- }
-
- this.createTransport_();
-
- this.transport_.connect();
-
- // Now we run any deferred deliveries collected while connection was deferred.
- while (this.deferredDeliveries_.length > 0) {
- this.deferredDeliveries_.shift()();
- }
-};
-
-
-/**
- * Closes the channel.
- */
-goog.net.xpc.CrossPageChannel.prototype.close = function() {
- if (!this.isConnected()) return;
- this.state_ = goog.net.xpc.ChannelStates.CLOSED;
- this.transport_.dispose();
- this.transport_ = null;
- this.connectCb_ = null;
- this.connectDeferred_ = false;
- this.deferredDeliveries_.length = 0;
- goog.net.xpc.logger.info('Channel "' + this.name + '" closed');
-};
-
-
-/**
- * Called by the transport when the channel is connected.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.notifyConnected_ = function() {
- if (this.isConnected()) {
- return;
- }
- this.state_ = goog.net.xpc.ChannelStates.CONNECTED;
- goog.net.xpc.logger.info('Channel "' + this.name + '" connected');
- this.connectCb_();
-};
-
-
-/**
- * Called by the transport in case of an unrecoverable failure.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.notifyTransportError_ = function() {
- goog.net.xpc.logger.info('Transport Error');
- this.close();
-};
-
-
-/** @override */
-goog.net.xpc.CrossPageChannel.prototype.send = function(serviceName, payload) {
- if (!this.isConnected()) {
- goog.net.xpc.logger.severe('Can\'t send. Channel not connected.');
- return;
- }
- // Check if the peer is still around.
- // NOTE(user): This check is not reliable in IE, where a document in an
- // iframe does not get unloaded when removing the iframe element from the DOM.
- // TODO(user): Find something that works in IE as well.
- // NOTE(user): "!this.peerWindowObject_.closed" evaluates to 'false' in IE9
- // sometimes even though typeof(this.peerWindowObject_.closed) is boolean and
- // this.peerWindowObject_.closed evaluates to 'false'. Casting it to a Boolean
- // results in sane evaluation. When this happens, it's in the inner iframe
- // when querying its parent's 'closed' status. Note that this is a different
- // case than mibuerge@'s note above.
- if (Boolean(this.peerWindowObject_.closed)) {
- goog.net.xpc.logger.severe('Peer has disappeared.');
- this.close();
- return;
- }
- if (goog.isObject(payload)) {
- payload = goog.json.serialize(payload);
- }
-
- // Partially URL-encode the service name because some characters (: and |) are
- // used as delimiters for some transports, and we want to allow those
- // characters in service names.
- this.transport_.send(this.escapeServiceName_(serviceName), payload);
-};
-
-
-/**
- * Delivers messages to the appropriate service-handler.
- *
- * @param {string} serviceName The name of the port.
- * @param {string} payload The payload.
- * @param {string=} opt_origin An optional origin for the message, where the
- * underlying transport makes that available. If this is specified, and
- * the PEER_HOSTNAME parameter was provided, they must match or the message
- * will be rejected.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.deliver_ = function(
- serviceName, payload, opt_origin) {
-
- // This covers the very rare (but producable) case where the inner frame
- // becomes ready and sends its setup message while the outer frame is
- // deferring its connect method waiting for the inner frame to be ready.
- // Without it that message can be passed to deliver_, which is unable to
- // process it because the channel is not yet fully configured.
- if (this.connectDeferred_) {
- this.deferredDeliveries_.push(
- goog.bind(this.deliver_, this, serviceName, payload, opt_origin));
- return;
- }
-
- // Check whether the origin of the message is as expected.
- if (!this.isMessageOriginAcceptable_(opt_origin)) {
- goog.net.xpc.logger.warning('Message received from unapproved origin "' +
- opt_origin + '" - rejected.');
- return;
- }
-
- if (this.isDisposed()) {
- goog.net.xpc.logger.warning('CrossPageChannel::deliver_(): Disposed.');
- } else if (!serviceName ||
- serviceName == goog.net.xpc.TRANSPORT_SERVICE_) {
- this.transport_.transportServiceHandler(payload);
- } else {
- // only deliver messages if connected
- if (this.isConnected()) {
- this.deliver(this.unescapeServiceName_(serviceName), payload);
- } else {
- goog.net.xpc.logger.info('CrossPageChannel::deliver_(): Not connected.');
- }
- }
-};
-
-
-/**
- * Escape the user-provided service name for sending across the channel. This
- * URL-encodes certain special characters so they don't conflict with delimiters
- * used by some of the transports, and adds a special prefix if the name
- * conflicts with the reserved transport service name.
- *
- * This is the opposite of {@link #unescapeServiceName_}.
- *
- * @param {string} name The name of the service to escape.
- * @return {string} The escaped service name.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.escapeServiceName_ = function(name) {
- if (goog.net.xpc.CrossPageChannel.TRANSPORT_SERVICE_ESCAPE_RE_.test(name)) {
- name = '%' + name;
- }
- return name.replace(/[%:|]/g, encodeURIComponent);
-};
-
-
-/**
- * Unescape the escaped service name that was sent across the channel. This is
- * the opposite of {@link #escapeServiceName_}.
- *
- * @param {string} name The name of the service to unescape.
- * @return {string} The unescaped service name.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.unescapeServiceName_ = function(name) {
- name = name.replace(/%[0-9a-f]{2}/gi, decodeURIComponent);
- if (goog.net.xpc.CrossPageChannel.TRANSPORT_SERVICE_UNESCAPE_RE_.test(name)) {
- return name.substring(1);
- } else {
- return name;
- }
-};
-
-
-/**
- * Returns the role of this channel (either inner or outer).
- * @return {number} The role of this channel.
- */
-goog.net.xpc.CrossPageChannel.prototype.getRole = function() {
- return window.parent == this.peerWindowObject_ ?
- goog.net.xpc.CrossPageChannelRole.INNER :
- goog.net.xpc.CrossPageChannelRole.OUTER;
-};
-
-
-/**
- * Returns whether an incoming message with the given origin is acceptable.
- * If an incoming request comes with a specified (non-empty) origin, and the
- * PEER_HOSTNAME config parameter has also been provided, the two must match,
- * or the message is unacceptable.
- * @param {string=} opt_origin The origin associated with the incoming message.
- * @return {boolean} Whether the message is acceptable.
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.isMessageOriginAcceptable_ = function(
- opt_origin) {
- var peerHostname = this.cfg_[goog.net.xpc.CfgFields.PEER_HOSTNAME];
- return goog.string.isEmptySafe(opt_origin) ||
- goog.string.isEmptySafe(peerHostname) ||
- opt_origin == this.cfg_[goog.net.xpc.CfgFields.PEER_HOSTNAME];
-};
-
-
-/** @override */
-goog.net.xpc.CrossPageChannel.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
-
- this.close();
-
- this.peerWindowObject_ = null;
- this.iframeElement_ = null;
- delete goog.net.xpc.channels_[this.name];
- this.deferredDeliveries_.length = 0;
-};
-
-
-/**
- * Disposes all channels.
- * @private
- */
-goog.net.xpc.CrossPageChannel.disposeAll_ = function() {
- for (var name in goog.net.xpc.channels_) {
- var ch = goog.net.xpc.channels_[name];
- if (ch) {
- ch.dispose();
- }
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel_test.html.svn-base
deleted file mode 100644
index 7b895b8..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannel_test.html.svn-base
+++ /dev/null
@@ -1,420 +0,0 @@
-<!DOCTYPE html>
-<!--
--->
-<html>
-<!--
-Copyright 2009 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>CrossPageChannel: End-to-End Test</title>
-<script src="../../base.js"></script>
-<script>
- goog.require('goog.Disposable');
- goog.require('goog.Uri');
- goog.require('goog.debug.Logger');
- goog.require('goog.dom');
- goog.require('goog.net.xpc.CrossPageChannel');
- goog.require('goog.object');
- goog.require('goog.testing.AsyncTestCase');
- goog.require('goog.testing.PropertyReplacer');
- goog.require('goog.testing.jsunit');
-</script>
-</head>
-<body>
-<script>
-
-var IFRAME_LOAD_WAIT_MS = 2000;
-var stubs = new goog.testing.PropertyReplacer();
-var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(
- document.title);
-var uniqueId = 0;
-var driver;
-
-
-function setUpPage() {
- asyncTestCase.stepTimeout = 10 * 1000;
-
- // Show debug log
- var debugDiv = goog.dom.getElement('debugDiv');
- var logger = goog.debug.Logger.getLogger('goog.net.xpc');
- logger.setLevel(goog.debug.Logger.Level.ALL);
- logger.addHandler(function(logRecord) {
- var msgElm = goog.dom.createDom('div');
- msgElm.innerHTML = logRecord.getMessage();
- goog.dom.appendChild(debugDiv, msgElm);
- });
-}
-
-
-function setUp() {
- driver = new Driver();
-}
-
-
-function tearDown() {
- stubs.reset();
- driver.dispose();
-}
-
-
-function testCreateIframeSpecifyId() {
- driver.createPeerIframe('new_iframe');
-
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- asyncTestCase.continueTesting();
- driver.checkPeerIframe();
- }, IFRAME_LOAD_WAIT_MS);
-}
-
-
-function testCreateIframeRandomId() {
- driver.createPeerIframe();
-
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- asyncTestCase.continueTesting();
- driver.checkPeerIframe();
- }, IFRAME_LOAD_WAIT_MS);
-}
-
-
-function testCreateIframeWithDom() {
- driver.createPeerIframe(goog.dom.getDomHelper());
-
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- asyncTestCase.continueTesting();
- driver.checkPeerIframe();
- }, IFRAME_LOAD_WAIT_MS);
-}
-
-
-function testCreateIframeAsynchronousConnect() {
- driver.createPeerIframe('new_iframe');
-
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- driver.connect();
- }, IFRAME_LOAD_WAIT_MS);
-}
-
-
-function testCreateIframeSynchronousConnect() {
- driver.createPeerIframe('new_iframe');
- driver.connect();
-}
-
-
-function testExistingIframeConnect() {
- driver.createChannel('test_iframe');
- driver.connect();
-}
-
-function testEscapeServiceName() {
- var escape = goog.net.xpc.CrossPageChannel.prototype.escapeServiceName_;
- assertEquals('Shouldn\'t escape alphanumeric name',
- 'fooBar123', escape('fooBar123'));
- assertEquals('Shouldn\'t escape most non-alphanumeric characters',
- '`~!@#$^&*()_-=+ []{}\'";,<.>/?\\',
- escape('`~!@#$^&*()_-=+ []{}\'";,<.>/?\\'));
- assertEquals('Should escape %, |, and :',
- 'foo%3ABar%7C123%25', escape('foo:Bar|123%'));
- assertEquals('Should escape tp', '%25tp', escape('tp'));
- assertEquals('Should escape %tp', '%25%25tp', escape('%tp'));
- assertEquals('Should not escape stp', 'stp', escape('stp'));
- assertEquals('Should not escape s%tp', 's%25tp', escape('s%tp'));
-}
-
-function testSameDomainCheck_noMessageOrigin() {
- var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
- goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
- assertTrue(channel.isMessageOriginAcceptable_(undefined));
-}
-
-function testSameDomainCheck_noPeerHostname() {
- var channel = new goog.net.xpc.CrossPageChannel({});
- assertTrue(channel.isMessageOriginAcceptable_('http://foo.com'));
-}
-
-function testSameDomainCheck_unconfigured() {
- var channel = new goog.net.xpc.CrossPageChannel({});
- assertTrue(channel.isMessageOriginAcceptable_(undefined));
-}
-
-function testSameDomainCheck_originsMatch() {
- var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
- goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
- assertTrue(channel.isMessageOriginAcceptable_('http://foo.com'));
-}
-
-function testSameDomainCheck_originsMismatch() {
- var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
- goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
- assertFalse(channel.isMessageOriginAcceptable_('http://nasty.com'));
-}
-
-function testUnescapeServiceName() {
- var unescape = goog.net.xpc.CrossPageChannel.prototype.unescapeServiceName_;
- assertEquals('Shouldn\'t modify alphanumeric name',
- 'fooBar123', unescape('fooBar123'));
- assertEquals('Shouldn\'t modify most non-alphanumeric characters',
- '`~!@#$^&*()_-=+ []{}\'";,<.>/?\\',
- unescape('`~!@#$^&*()_-=+ []{}\'";,<.>/?\\'));
- assertEquals('Should unescape URL-escapes',
- 'foo:Bar|123%', unescape('foo%3ABar%7C123%25'));
- assertEquals('Should unescape tp', 'tp', unescape('%25tp'));
- assertEquals('Should unescape %tp', '%tp', unescape('%25%25tp'));
- assertEquals('Should not escape stp', 'stp', unescape('stp'));
- assertEquals('Should not escape s%tp', 's%tp', unescape('s%25tp'));
-}
-
-
-/**
- * Driver for the tests for CrossPageChannel.
- *
- * @constructor
- * @extends {goog.Disposable}
- */
-Driver = function() {
- goog.Disposable.call(this);
-
- /**
- * The peer iframe.
- * @type {!Element}
- * @private
- */
- this.iframe_ = null;
-
- /**
- * The ID of the peer iframe.
- * @type {string}
- * @private
- */
- this.iframeId_ = 'test_iframe';
-
- /**
- * Channel configuration object.
- * @type {Object}
- * @private
- */
- this.cfg_ = null;
-
- /**
- * The channel to use.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = null;
-};
-goog.inherits(Driver, goog.Disposable);
-
-
-/** @override */
-Driver.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
-
- if (this.channel_) {
- this.channel_.dispose();
- }
-};
-
-
-/**
- * Returns the child peer's window object.
- * @return {Window} Child peer's window.
- * @private
- */
-Driver.prototype.getInnerPeer_ = function() {
- return window.frames[this.iframeId_];
-};
-
-
-/**
- * Creates the channel.
- * @param {string=} opt_iframeId If present, the ID of the iframe to use,
- * otherwise, tells the channel to generate an iframe ID.
- * @param {goog.dom.DomHelper=} opt_domHelper The optional dom helper to use
- * for determining which window to use.
- */
-Driver.prototype.createChannel = function(opt_iframeId, opt_domHelper) {
- var cfg = {};
- if (opt_iframeId) {
- this.iframeId_ = opt_iframeId;
- cfg[goog.net.xpc.CfgFields.IFRAME_ID] = opt_iframeId;
- }
- cfg[goog.net.xpc.CfgFields.PEER_URI] = 'testdata/inner_peer.html';
- cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = 'test_channel' + uniqueId++;
- cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] = 'does-not-exist.html';
- cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] = 'does-not-exist.html';
- function resolveUri(fieldName) {
- cfg[fieldName] =
- goog.Uri.resolve(window.location.href, cfg[fieldName]).toString();
- }
- resolveUri(goog.net.xpc.CfgFields.PEER_URI);
- resolveUri(goog.net.xpc.CfgFields.LOCAL_POLL_URI);
- resolveUri(goog.net.xpc.CfgFields.PEER_POLL_URI);
-
- this.channel_ = new goog.net.xpc.CrossPageChannel(cfg, opt_domHelper);
- this.channel_.registerService('msg', goog.bind(this.msgHandler_, this));
- this.cfg_ = cfg;
-};
-
-
-/**
- * Creates the peer iframe.
- * @param {string=} opt_iframeId If present, the ID of the iframe to create,
- * otherwise, generates an iframe ID.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for
- * finding the elements in the iframe.
- */
-Driver.prototype.createPeerIframe = function(opt_iframeId, opt_domHelper) {
- var expectedIframeId;
-
- if (opt_iframeId) {
- expectedIframeId = opt_iframeId = opt_iframeId + uniqueId++;
- } else {
- // Have createPeerIframe() generate an ID
- stubs.set(goog.net.xpc, 'getRandomString', function(length) {
- return '' + length;
- });
- expectedIframeId = 'xpcpeer4';
- }
- assertNull('element[id=' + expectedIframeId + '] exists',
- goog.dom.getElement(expectedIframeId));
-
- this.createChannel(opt_iframeId, opt_domHelper);
- this.iframe_ = this.channel_.createPeerIframe(document.body);
-
- assertEquals(expectedIframeId, this.iframe_.id);
- this.iframeId_ = expectedIframeId;
-};
-
-
-/**
- * Checks if the peer iframe has been created.
- */
-Driver.prototype.checkPeerIframe = function() {
- assertNotNull(goog.dom.getElement(this.iframeId_));
- var peer = this.getInnerPeer_();
- assertNotNull(peer);
- assertNotNull(peer.document);
-};
-
-
-/**
- * Starts the connection. The connection happens asynchronously.
- */
-Driver.prototype.connect = function() {
- // TODO(user): Get tests to pass for all transports
- if (!this.isTransportTestable_()) {
- asyncTestCase.continueTesting();
- return;
- }
-
- if (this.iframe_) {
- // When we create an iframe, we send the config
- // and it connects itself.
- this.childConnected_();
- } else {
- asyncTestCase.waitForAsync('parent and child connect');
- var peer = this.getInnerPeer_();
- peer.instantiateChannel(this.cfg_);
- peer.connectChannel(goog.bind(this.childConnected_, this));
- }
-
- this.channel_.connect(goog.bind(this.parentConnected_, this));
-};
-
-
-/**
- * Determines if the transport type for the channel is testable.
- * Some transports are misusing global state or making other
- * assumptions that cause connections to fail.
- * @return {boolean} Whether the transport is testable.
- * @private
- */
-Driver.prototype.isTransportTestable_ = function() {
- var testable = true;
-
- var transportType = this.channel_.determineTransportType_();
- switch (transportType) {
- case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
- case goog.net.xpc.TransportTypes.IFRAME_RELAY:
- case goog.net.xpc.TransportTypes.IFRAME_POLLING:
- case goog.net.xpc.TransportTypes.FLASH:
- case goog.net.xpc.TransportTypes.NIX:
- testable = false;
- break;
- }
-
- return testable;
-};
-
-
-/**
- * Callback for the parent connection.
- * @private
- */
-Driver.prototype.parentConnected_ = function() {
- var peer = this.getInnerPeer_();
- if (peer.isConnected()) {
- asyncTestCase.waitForAsync('child echo');
- } else {
- asyncTestCase.waitForAsync('child connect');
- }
-
- this.channel_.send('echo', 'hello')
-};
-
-
-/**
- * Callback for the child connection.
- * @private
- */
-Driver.prototype.childConnected_ = function() {
- if (this.channel_.isConnected()) {
- asyncTestCase.waitForAsync('child echo');
- } else {
- asyncTestCase.waitForAsync('parent connect');
- }
-};
-
-
-/**
- * The handler function for incoming msg requests.
- * @param {string} payload The message payload.
- * @private
- */
-Driver.prototype.msgHandler_ = function(payload) {
- assertTrue('parent should be connected', this.channel_.isConnected());
- var peer = this.getInnerPeer_();
- assertTrue('child should be connected', peer.isConnected());
- assertEquals('hello', payload);
-
- asyncTestCase.continueTesting();
-};
-
-
-</script>
-
-<!-- Debug box. -->
-<div style="position:absolute; float: right; top: 10px; right: 10px">
-Debug [<a href="#" onclick="document.getElementById('debugDiv').innerHTML = '';">clear</a>]: <br/>
-<div id="debugDiv" style="border: 1px #000000 solid; font-size:xx-small"></div>
-</div>
-
-<!--
-Setup inner peer. This must be done in the <body>, so that the inner peer iframe
-blocks the onload event in this window until it is fully loaded. The JsUnit
-tests will execute after the onload event fires.
--->
-<iframe name=test_iframe id=test_iframe src=testdata/inner_peer.html width=300 height=250>
-</iframe>
-
-</body>
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannelrole.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannelrole.js.svn-base
deleted file mode 100644
index 0d31fe9..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/crosspagechannelrole.js.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Provides the enum for the role of the CrossPageChannel.
- *
- */
-
-goog.provide('goog.net.xpc.CrossPageChannelRole');
-
-
-/**
- * The role of the peer.
- * @enum {number}
- */
-goog.net.xpc.CrossPageChannelRole = {
- OUTER: 0,
- INNER: 1
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/frameelementmethodtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/frameelementmethodtransport.js.svn-base
deleted file mode 100644
index f99ed6f..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/frameelementmethodtransport.js.svn-base
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the frame element method transport for cross-domain
- * communication. It exploits the fact that FF lets a page in an
- * iframe call a method on the iframe-element it is contained in, even if the
- * containing page is from a different domain.
- *
- */
-
-
-goog.provide('goog.net.xpc.FrameElementMethodTransport');
-
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.CrossPageChannelRole');
-goog.require('goog.net.xpc.Transport');
-
-
-
-/**
- * Frame-element method transport.
- *
- * Firefox allows a document within an iframe to call methods on the
- * iframe-element added by the containing document.
- * NOTE(user): Tested in all FF versions starting from 1.0
- *
- * @param {goog.net.xpc.CrossPageChannel} channel The channel this transport
- * belongs to.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for finding
- * the correct window.
- * @constructor
- * @extends {goog.net.xpc.Transport}
- */
-goog.net.xpc.FrameElementMethodTransport = function(channel, opt_domHelper) {
- goog.base(this, opt_domHelper);
-
- /**
- * The channel this transport belongs to.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = channel;
-
- // To transfer messages, this transport basically uses normal function calls,
- // which are synchronous. To avoid endless recursion, the delivery has to
- // be artificially made asynchronous.
-
- /**
- * Array for queued messages.
- * @type {Array}
- * @private
- */
- this.queue_ = [];
-
- /**
- * Callback function which wraps deliverQueued_.
- * @type {Function}
- * @private
- */
- this.deliverQueuedCb_ = goog.bind(this.deliverQueued_, this);
-};
-goog.inherits(goog.net.xpc.FrameElementMethodTransport, goog.net.xpc.Transport);
-
-
-/**
- * The transport type.
- * @type {number}
- * @protected
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD;
-
-
-/**
- * Flag used to enforce asynchronous messaging semantics.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.recursive_ = false;
-
-
-/**
- * Timer used to enforce asynchronous message delivery.
- * @type {number}
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.timer_ = 0;
-
-
-/**
- * Holds the function to send messages to the peer
- * (once it becomes available).
- * @type {Function}
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.outgoing_ = null;
-
-
-/**
- * Connect this transport.
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.connect = function() {
- if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER) {
- // get shortcut to iframe-element
- this.iframeElm_ = this.channel_.iframeElement_;
-
- // add the gateway function to the iframe-element
- // (to be called by the peer)
- this.iframeElm_['XPC_toOuter'] = goog.bind(this.incoming_, this);
-
- // at this point we just have to wait for a notification from the peer...
-
- } else {
- this.attemptSetup_();
- }
-};
-
-
-/**
- * Only used from within an iframe. Attempts to attach the method
- * to be used for sending messages by the containing document. Has to
- * wait until the containing document has finished. Therefore calls
- * itself in a timeout if not successful.
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.attemptSetup_ = function() {
- var retry = true;
- /** @preserveTry */
- try {
- if (!this.iframeElm_) {
- // throws security exception when called too early
- this.iframeElm_ = this.getWindow().frameElement;
- }
- // check if iframe-element and the gateway-function to the
- // outer-frame are present
- // TODO(user) Make sure the following code doesn't throw any exceptions
- if (this.iframeElm_ && this.iframeElm_['XPC_toOuter']) {
- // get a reference to the gateway function
- this.outgoing_ = this.iframeElm_['XPC_toOuter'];
- // attach the gateway function the other document will use
- this.iframeElm_['XPC_toOuter']['XPC_toInner'] =
- goog.bind(this.incoming_, this);
- // stop retrying
- retry = false;
- // notify outer frame
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
- // notify channel that the transport is ready
- this.channel_.notifyConnected_();
- }
- }
- catch (e) {
- goog.net.xpc.logger.severe(
- 'exception caught while attempting setup: ' + e);
- }
- // retry necessary?
- if (retry) {
- if (!this.attemptSetupCb_) {
- this.attemptSetupCb_ = goog.bind(this.attemptSetup_, this);
- }
- this.getWindow().setTimeout(this.attemptSetupCb_, 100);
- }
-};
-
-
-/**
- * Handles transport service messages.
- * @param {string} payload The message content.
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.transportServiceHandler =
- function(payload) {
- if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER &&
- !this.channel_.isConnected() && payload == goog.net.xpc.SETUP_ACK_) {
- // get a reference to the gateway function
- this.outgoing_ = this.iframeElm_['XPC_toOuter']['XPC_toInner'];
- // notify the channel we're ready
- this.channel_.notifyConnected_();
- } else {
- throw Error('Got unexpected transport message.');
- }
-};
-
-
-/**
- * Process incoming message.
- * @param {string} serviceName The name of the service the message is to be
- * delivered to.
- * @param {string} payload The message to process.
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.incoming_ =
- function(serviceName, payload) {
- if (!this.recursive_ && this.queue_.length == 0) {
- this.channel_.deliver_(serviceName, payload);
- }
- else {
- this.queue_.push({serviceName: serviceName, payload: payload});
- if (this.queue_.length == 1) {
- this.timer_ = this.getWindow().setTimeout(this.deliverQueuedCb_, 1);
- }
- }
-};
-
-
-/**
- * Delivers queued messages.
- * @private
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.deliverQueued_ =
- function() {
- while (this.queue_.length) {
- var msg = this.queue_.shift();
- this.channel_.deliver_(msg.serviceName, msg.payload);
- }
-};
-
-
-/**
- * Send a message
- * @param {string} service The name off the service the message is to be
- * delivered to.
- * @param {string} payload The message content.
- */
-goog.net.xpc.FrameElementMethodTransport.prototype.send =
- function(service, payload) {
- this.recursive_ = true;
- this.outgoing_(service, payload);
- this.recursive_ = false;
-};
-
-
-/** @override */
-goog.net.xpc.FrameElementMethodTransport.prototype.disposeInternal =
- function() {
- goog.net.xpc.FrameElementMethodTransport.superClass_.disposeInternal.call(
- this);
- this.outgoing_ = null;
- this.iframeElm_ = null;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframepollingtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframepollingtransport.js.svn-base
deleted file mode 100644
index aaa96ae..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframepollingtransport.js.svn-base
+++ /dev/null
@@ -1,829 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the iframe polling transport.
- */
-
-
-goog.provide('goog.net.xpc.IframePollingTransport');
-goog.provide('goog.net.xpc.IframePollingTransport.Receiver');
-goog.provide('goog.net.xpc.IframePollingTransport.Sender');
-
-goog.require('goog.array');
-goog.require('goog.dom');
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.CrossPageChannelRole');
-goog.require('goog.net.xpc.Transport');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Iframe polling transport. Uses hidden iframes to transfer data
- * in the fragment identifier of the URL. The peer polls the iframe's location
- * for changes.
- * Unfortunately, in Safari this screws up the history, because Safari doesn't
- * allow to call location.replace() on a window containing a document from a
- * different domain (last version tested: 2.0.4).
- *
- * @param {goog.net.xpc.CrossPageChannel} channel The channel this
- * transport belongs to.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for finding
- * the correct window.
- * @constructor
- * @extends {goog.net.xpc.Transport}
- */
-goog.net.xpc.IframePollingTransport = function(channel, opt_domHelper) {
- goog.base(this, opt_domHelper);
-
- /**
- * The channel this transport belongs to.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The URI used to send messages.
- * @type {string}
- * @private
- */
- this.sendUri_ = this.channel_.cfg_[goog.net.xpc.CfgFields.PEER_POLL_URI];
-
- /**
- * The URI which is polled for incoming messages.
- * @type {string}
- * @private
- */
- this.rcvUri_ = this.channel_.cfg_[goog.net.xpc.CfgFields.LOCAL_POLL_URI];
-
- /**
- * The queue to hold messages which can't be sent immediately.
- * @type {Array}
- * @private
- */
- this.sendQueue_ = [];
-};
-goog.inherits(goog.net.xpc.IframePollingTransport, goog.net.xpc.Transport);
-
-
-/**
- * The transport type.
- * @type {number}
- * @protected
- */
-goog.net.xpc.IframePollingTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.IFRAME_POLLING;
-
-
-/**
- * Sequence counter.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.sequence_ = 0;
-
-
-/**
- * Flag indicating whether we are waiting for an acknoledgement.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.waitForAck_ = false;
-
-
-/**
- * Flag indicating if channel has been initialized.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.initialized_ = false;
-
-
-/**
- * The string used to prefix all iframe names and IDs.
- * @type {string}
- */
-goog.net.xpc.IframePollingTransport.IFRAME_PREFIX = 'googlexpc';
-
-
-/**
- * Returns the name/ID of the message frame.
- * @return {string} Name of message frame.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.getMsgFrameName_ = function() {
- return goog.net.xpc.IframePollingTransport.IFRAME_PREFIX + '_' +
- this.channel_.name + '_msg';
-};
-
-
-/**
- * Returns the name/ID of the ack frame.
- * @return {string} Name of ack frame.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.getAckFrameName_ = function() {
- return goog.net.xpc.IframePollingTransport.IFRAME_PREFIX + '_' +
- this.channel_.name + '_ack';
-};
-
-
-/**
- * Connects this transport.
- */
-goog.net.xpc.IframePollingTransport.prototype.connect = function() {
- if (this.isDisposed()) {
- // We should stop polling for connecting if the transport has been
- // disposed (i.e., the channel has been closed), otherwise
- // outerPeerReconnect_() may throw exceptions when it refers
- // channel_.peerWindowObject_ which is reset to null by channel_.close().
- return;
- }
-
- goog.net.xpc.logger.fine('transport connect called');
- if (!this.initialized_) {
- goog.net.xpc.logger.fine('initializing...');
- this.constructSenderFrames_();
- this.initialized_ = true;
- }
- this.checkForeignFramesReady_();
-};
-
-
-/**
- * Creates the iframes which are used to send messages (and acknowledgements)
- * to the peer. Sender iframes contain a document from a different origin and
- * therefore their content can't be accessed.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.constructSenderFrames_ =
- function() {
- var name = this.getMsgFrameName_();
- this.msgIframeElm_ = this.constructSenderFrame_(name);
- this.msgWinObj_ = this.getWindow().frames[name];
-
- name = this.getAckFrameName_();
- this.ackIframeElm_ = this.constructSenderFrame_(name);
- this.ackWinObj_ = this.getWindow().frames[name];
-};
-
-
-/**
- * Constructs a sending frame the the given id.
- * @param {string} id The id.
- * @return {Element} The constructed frame.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.constructSenderFrame_ =
- function(id) {
- goog.net.xpc.logger.finest('constructing sender frame: ' + id);
- var ifr = goog.dom.createElement('iframe');
- var s = ifr.style;
- s.position = 'absolute';
- s.top = '-10px'; s.left = '10px'; s.width = '1px'; s.height = '1px';
- ifr.id = ifr.name = id;
- ifr.src = this.sendUri_ + '#INITIAL';
- this.getWindow().document.body.appendChild(ifr);
- return ifr;
-};
-
-
-/**
- * The protocol for reconnecting is for the inner frame to change channel
- * names, and then communicate the new channel name to the outer peer.
- * The outer peer looks in a predefined location for the channel name
- * upate. It is important to use a completely new channel name, as this
- * will ensure that all messaging iframes are not in the bfcache.
- * Otherwise, Safari may pollute the history when modifying the location
- * of bfcached iframes.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.innerPeerReconnect_ = function() {
- goog.net.xpc.logger.finest('innerPeerReconnect called');
- this.channel_.name = goog.net.xpc.getRandomString(10);
- goog.net.xpc.logger.finest('switching channels: ' + this.channel_.name);
- this.deconstructSenderFrames_();
- this.initialized_ = false;
- // Communicate new channel name to outer peer.
- this.reconnectFrame_ = this.constructSenderFrame_(
- goog.net.xpc.IframePollingTransport.IFRAME_PREFIX +
- '_reconnect_' + this.channel_.name);
-};
-
-
-/**
- * Scans inner peer for a reconnect message, which will be used to update
- * the outer peer's channel name. If a reconnect message is found, the
- * sender frames will be cleaned up to make way for the new sender frames.
- * Only called by the outer peer.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.outerPeerReconnect_ = function() {
- goog.net.xpc.logger.finest('outerPeerReconnect called');
- var frames = this.channel_.peerWindowObject_.frames;
- var length = frames.length;
- for (var i = 0; i < length; i++) {
- var frameName;
- try {
- if (frames[i] && frames[i].name) {
- frameName = frames[i].name;
- }
- } catch (e) {
- // Do nothing.
- }
- if (!frameName) {
- continue;
- }
- var message = frameName.split('_');
- if (message.length == 3 &&
- message[0] == goog.net.xpc.IframePollingTransport.IFRAME_PREFIX &&
- message[1] == 'reconnect') {
- // This is a legitimate reconnect message from the peer. Start using
- // the peer provided channel name, and start a connection over from
- // scratch.
- this.channel_.name = message[2];
- this.deconstructSenderFrames_();
- this.initialized_ = false;
- break;
- }
- }
-};
-
-
-/**
- * Cleans up the existing sender frames owned by this peer. Only called by
- * the outer peer.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.deconstructSenderFrames_ =
- function() {
- goog.net.xpc.logger.finest('deconstructSenderFrames called');
- if (this.msgIframeElm_) {
- this.msgIframeElm_.parentNode.removeChild(this.msgIframeElm_);
- this.msgIframeElm_ = null;
- this.msgWinObj_ = null;
- }
- if (this.ackIframeElm_) {
- this.ackIframeElm_.parentNode.removeChild(this.ackIframeElm_);
- this.ackIframeElm_ = null;
- this.ackWinObj_ = null;
- }
-};
-
-
-/**
- * Checks if the frames in the peer's page are ready. These contain a
- * document from the own domain and are the ones messages are received through.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.checkForeignFramesReady_ =
- function() {
- // check if the connected iframe ready
- if (!(this.isRcvFrameReady_(this.getMsgFrameName_()) &&
- this.isRcvFrameReady_(this.getAckFrameName_()))) {
- goog.net.xpc.logger.finest('foreign frames not (yet) present');
-
- if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.INNER &&
- !this.reconnectFrame_) {
- // The inner peer should always have its receiving frames ready.
- // It is safe to assume the channel name has fallen out of sync
- // (which happens with bfcached frames). Create "reconnect" frames,
- // which the outer peer will find, and use to resync the channel names.
- this.innerPeerReconnect_();
- } else if (this.channel_.getRole() ==
- goog.net.xpc.CrossPageChannelRole.OUTER) {
- // The inner peer is either not loaded yet, or the receiving
- // frames are simply missing. Since we cannot discern the two cases, we
- // should scan for a reconnect message from the inner peer.
- this.outerPeerReconnect_();
- }
-
- // start a timer to check again
- this.getWindow().setTimeout(goog.bind(this.connect, this), 100);
- } else {
- goog.net.xpc.logger.fine('foreign frames present');
-
- // Create receivers.
- this.msgReceiver_ = new goog.net.xpc.IframePollingTransport.Receiver(
- this,
- this.channel_.peerWindowObject_.frames[this.getMsgFrameName_()],
- goog.bind(this.processIncomingMsg, this));
- this.ackReceiver_ = new goog.net.xpc.IframePollingTransport.Receiver(
- this,
- this.channel_.peerWindowObject_.frames[this.getAckFrameName_()],
- goog.bind(this.processIncomingAck, this));
-
- this.checkLocalFramesPresent_();
- }
-};
-
-
-/**
- * Checks if the receiving frame is ready.
- * @param {string} frameName Which receiving frame to check.
- * @return {boolean} Whether the receiving frame is ready.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.isRcvFrameReady_ =
- function(frameName) {
- goog.net.xpc.logger.finest('checking for receive frame: ' + frameName);
- /** @preserveTry */
- try {
- var winObj = this.channel_.peerWindowObject_.frames[frameName];
- if (!winObj || winObj.location.href.indexOf(this.rcvUri_) != 0) {
- return false;
- }
- } catch (e) {
- return false;
- }
- return true;
-};
-
-
-/**
- * Checks if the iframes created in the own document are ready.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.checkLocalFramesPresent_ =
- function() {
-
- // Are the sender frames ready?
- // These contain a document from the peer's domain, therefore we can only
- // check if the frame itself is present.
- var frames = this.channel_.peerWindowObject_.frames;
- if (!(frames[this.getAckFrameName_()] &&
- frames[this.getMsgFrameName_()])) {
- // start a timer to check again
- if (!this.checkLocalFramesPresentCb_) {
- this.checkLocalFramesPresentCb_ = goog.bind(
- this.checkLocalFramesPresent_, this);
- }
- this.getWindow().setTimeout(this.checkLocalFramesPresentCb_, 100);
- goog.net.xpc.logger.fine('local frames not (yet) present');
- } else {
- // Create senders.
- this.msgSender_ = new goog.net.xpc.IframePollingTransport.Sender(
- this.sendUri_, this.msgWinObj_);
- this.ackSender_ = new goog.net.xpc.IframePollingTransport.Sender(
- this.sendUri_, this.ackWinObj_);
-
- goog.net.xpc.logger.fine('local frames ready');
-
- this.getWindow().setTimeout(goog.bind(function() {
- this.msgSender_.send(goog.net.xpc.SETUP);
- this.sentConnectionSetup_ = true;
- this.waitForAck_ = true;
- goog.net.xpc.logger.fine('SETUP sent');
- }, this), 100);
- }
-};
-
-
-/**
- * Check if connection is ready.
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.checkIfConnected_ = function() {
- if (this.sentConnectionSetupAck_ && this.rcvdConnectionSetupAck_) {
- this.channel_.notifyConnected_();
-
- if (this.deliveryQueue_) {
- goog.net.xpc.logger.fine('delivering queued messages ' +
- '(' + this.deliveryQueue_.length + ')');
-
- for (var i = 0, m; i < this.deliveryQueue_.length; i++) {
- m = this.deliveryQueue_[i];
- this.channel_.deliver_(m.service, m.payload);
- }
- delete this.deliveryQueue_;
- }
- } else {
- goog.net.xpc.logger.finest('checking if connected: ' +
- 'ack sent:' + this.sentConnectionSetupAck_ +
- ', ack rcvd: ' + this.rcvdConnectionSetupAck_);
- }
-};
-
-
-/**
- * Processes an incoming message.
- * @param {string} raw The complete received string.
- */
-goog.net.xpc.IframePollingTransport.prototype.processIncomingMsg =
- function(raw) {
- goog.net.xpc.logger.finest('msg received: ' + raw);
-
- if (raw == goog.net.xpc.SETUP) {
- if (!this.ackSender_) {
- // Got SETUP msg, but we can't send an ack.
- return;
- }
-
- this.ackSender_.send(goog.net.xpc.SETUP_ACK_);
- goog.net.xpc.logger.finest('SETUP_ACK sent');
-
- this.sentConnectionSetupAck_ = true;
- this.checkIfConnected_();
-
- } else if (this.channel_.isConnected() || this.sentConnectionSetupAck_) {
-
- var pos = raw.indexOf('|');
- var head = raw.substring(0, pos);
- var frame = raw.substring(pos + 1);
-
- // check if it is a framed message
- pos = head.indexOf(',');
- if (pos == -1) {
- var seq = head;
- // send acknowledgement
- this.ackSender_.send('ACK:' + seq);
- this.deliverPayload_(frame);
- } else {
- var seq = head.substring(0, pos);
- // send acknowledgement
- this.ackSender_.send('ACK:' + seq);
-
- var partInfo = head.substring(pos + 1).split('/');
- var part0 = parseInt(partInfo[0], 10);
- var part1 = parseInt(partInfo[1], 10);
- // create an array to accumulate the parts if this is the
- // first frame of a message
- if (part0 == 1) {
- this.parts_ = [];
- }
- this.parts_.push(frame);
- // deliver the message if this was the last frame of a message
- if (part0 == part1) {
- this.deliverPayload_(this.parts_.join(''));
- delete this.parts_;
- }
- }
- } else {
- goog.net.xpc.logger.warning('received msg, but channel is not connected');
- }
-};
-
-
-/**
- * Process an incoming acknowdedgement.
- * @param {string} msgStr The incoming ack string to process.
- */
-goog.net.xpc.IframePollingTransport.prototype.processIncomingAck =
- function(msgStr) {
- goog.net.xpc.logger.finest('ack received: ' + msgStr);
-
- if (msgStr == goog.net.xpc.SETUP_ACK_) {
- this.waitForAck_ = false;
- this.rcvdConnectionSetupAck_ = true;
- // send the next frame
- this.checkIfConnected_();
-
- } else if (this.channel_.isConnected()) {
- if (!this.waitForAck_) {
- goog.net.xpc.logger.warning('got unexpected ack');
- return;
- }
-
- var seq = parseInt(msgStr.split(':')[1], 10);
- if (seq == this.sequence_) {
- this.waitForAck_ = false;
- this.sendNextFrame_();
- } else {
- goog.net.xpc.logger.warning('got ack with wrong sequence');
- }
- } else {
- goog.net.xpc.logger.warning('received ack, but channel not connected');
- }
-};
-
-
-/**
- * Sends a frame (message part).
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.sendNextFrame_ = function() {
- // do nothing if we are waiting for an acknowledgement or the
- // queue is emtpy
- if (this.waitForAck_ || !this.sendQueue_.length) {
- return;
- }
-
- var s = this.sendQueue_.shift();
- ++this.sequence_;
- this.msgSender_.send(this.sequence_ + s);
- goog.net.xpc.logger.finest('msg sent: ' + this.sequence_ + s);
-
-
- this.waitForAck_ = true;
-};
-
-
-/**
- * Delivers a message.
- * @param {string} s The complete message string ("<service_name>:<payload>").
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.deliverPayload_ = function(s) {
- // determine the service name and the payload
- var pos = s.indexOf(':');
- var service = s.substr(0, pos);
- var payload = s.substring(pos + 1);
-
- // deliver the message
- if (!this.channel_.isConnected()) {
- // as valid messages can come in before a SETUP_ACK has
- // been received (because subchannels for msgs and acks are independent),
- // delay delivery of early messages until after 'connect'-event
- (this.deliveryQueue_ || (this.deliveryQueue_ = [])).
- push({service: service, payload: payload});
- goog.net.xpc.logger.finest('queued delivery');
- } else {
- this.channel_.deliver_(service, payload);
- }
-};
-
-
-// ---- send message ----
-
-
-/**
- * Maximal frame length.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframePollingTransport.prototype.MAX_FRAME_LENGTH_ = 3800;
-
-
-/**
- * Sends a message. Splits it in multiple frames if too long (exceeds IE's
- * URL-length maximum.
- * Wireformat: <seq>[,<frame_no>/<#frames>]|<frame_content>
- *
- * @param {string} service Name of service this the message has to be delivered.
- * @param {string} payload The message content.
- */
-goog.net.xpc.IframePollingTransport.prototype.send =
- function(service, payload) {
- var frame = service + ':' + payload;
- // put in queue
- if (!goog.userAgent.IE || payload.length <= this.MAX_FRAME_LENGTH_) {
- this.sendQueue_.push('|' + frame);
- }
- else {
- var l = payload.length;
- var num = Math.ceil(l / this.MAX_FRAME_LENGTH_); // number of frames
- var pos = 0;
- var i = 1;
- while (pos < l) {
- this.sendQueue_.push(',' + i + '/' + num + '|' +
- frame.substr(pos, this.MAX_FRAME_LENGTH_));
- i++;
- pos += this.MAX_FRAME_LENGTH_;
- }
- }
- this.sendNextFrame_();
-};
-
-
-/** @override */
-goog.net.xpc.IframePollingTransport.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
-
- var receivers = goog.net.xpc.IframePollingTransport.receivers_;
- goog.array.remove(receivers, this.msgReceiver_);
- goog.array.remove(receivers, this.ackReceiver_);
- this.msgReceiver_ = this.ackReceiver_ = null;
-
- goog.dom.removeNode(this.msgIframeElm_);
- goog.dom.removeNode(this.ackIframeElm_);
- this.msgIframeElm_ = this.ackIframeElm_ = null;
- this.msgWinObj_ = this.ackWinObj_ = null;
-};
-
-
-/**
- * Array holding all Receiver-instances.
- * @type {Array.<goog.net.xpc.IframePollingTransport.Receiver>}
- * @private
- */
-goog.net.xpc.IframePollingTransport.receivers_ = [];
-
-
-/**
- * Short polling interval.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframePollingTransport.TIME_POLL_SHORT_ = 10;
-
-
-/**
- * Long polling interval.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframePollingTransport.TIME_POLL_LONG_ = 100;
-
-
-/**
- * Period how long to use TIME_POLL_SHORT_ before raising polling-interval
- * to TIME_POLL_LONG_ after an activity.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframePollingTransport.TIME_SHORT_POLL_AFTER_ACTIVITY_ =
- 1000;
-
-
-/**
- * Polls all receivers.
- * @private
- */
-goog.net.xpc.IframePollingTransport.receive_ = function() {
- var rcvd = false;
- /** @preserveTry */
- try {
- for (var i = 0, l = goog.net.xpc.IframePollingTransport.receivers_.length;
- i < l; i++) {
- rcvd = rcvd ||
- goog.net.xpc.IframePollingTransport.receivers_[i].receive();
- }
- } catch (e) {
- goog.net.xpc.logger.info('receive_() failed: ' + e);
- // Notify the channel that the transport had an error.
- goog.net.xpc.IframePollingTransport.receivers_[i].
- transport_.channel_.notifyTransportError_();
- // notifyTransportError_() closes the channel and dispoases the transport.
- // If there are no other channels present, this.receivers_ will now be empty
- // and there is not need to keep polling.
- if (!goog.net.xpc.IframePollingTransport.receivers_.length) {
- return;
- }
- }
-
- var now = goog.now();
- if (rcvd) {
- goog.net.xpc.IframePollingTransport.lastActivity_ = now;
- }
-
- // Schedule next check.
- var t = now - goog.net.xpc.IframePollingTransport.lastActivity_ <
- goog.net.xpc.IframePollingTransport.TIME_SHORT_POLL_AFTER_ACTIVITY_ ?
- goog.net.xpc.IframePollingTransport.TIME_POLL_SHORT_ :
- goog.net.xpc.IframePollingTransport.TIME_POLL_LONG_;
- goog.net.xpc.IframePollingTransport.rcvTimer_ = window.setTimeout(
- goog.net.xpc.IframePollingTransport.receiveCb_, t);
-};
-
-
-/**
- * Callback that wraps receive_ to be used in timers.
- * @type {Function}
- * @private
- */
-goog.net.xpc.IframePollingTransport.receiveCb_ = goog.bind(
- goog.net.xpc.IframePollingTransport.receive_,
- goog.net.xpc.IframePollingTransport);
-
-
-/**
- * Starts the polling loop.
- * @private
- */
-goog.net.xpc.IframePollingTransport.startRcvTimer_ = function() {
- goog.net.xpc.logger.fine('starting receive-timer');
- goog.net.xpc.IframePollingTransport.lastActivity_ = goog.now();
- if (goog.net.xpc.IframePollingTransport.rcvTimer_) {
- window.clearTimeout(goog.net.xpc.IframePollingTransport.rcvTimer_);
- }
- goog.net.xpc.IframePollingTransport.rcvTimer_ = window.setTimeout(
- goog.net.xpc.IframePollingTransport.receiveCb_,
- goog.net.xpc.IframePollingTransport.TIME_POLL_SHORT_);
-};
-
-
-
-/**
- * goog.net.xpc.IframePollingTransport.Sender
- *
- * Utility class to send message-parts to a document from a different origin.
- *
- * @constructor
- * @param {string} url The url the other document will use for polling.
- * @param {Object} windowObj The frame used for sending information to.
- */
-goog.net.xpc.IframePollingTransport.Sender = function(url, windowObj) {
- /**
- * The URI used to sending messages.
- * @type {string}
- * @private
- */
- this.sendUri_ = url;
-
- /**
- * The window object of the iframe used to send messages.
- * The script instantiating the Sender won't have access to
- * the content of sendFrame_.
- * @type {Object}
- * @private
- */
- this.sendFrame_ = windowObj;
-
- /**
- * Cycle counter (used to make sure that sending two identical messages sent
- * in direct succession can be recognized as such by the receiver).
- * @type {number}
- * @private
- */
- this.cycle_ = 0;
-};
-
-
-/**
- * Sends a message-part (frame) to the peer.
- * The message-part is encoded and put in the fragment identifier
- * of the URL used for sending (and belongs to the origin/domain of the peer).
- * @param {string} payload The message to send.
- */
-goog.net.xpc.IframePollingTransport.Sender.prototype.send = function(payload) {
- this.cycle_ = ++this.cycle_ % 2;
-
- var url = this.sendUri_ + '#' + this.cycle_ + encodeURIComponent(payload);
-
- // TODO(user) Find out if try/catch is still needed
- /** @preserveTry */
- try {
- // safari doesn't allow to call location.replace()
- if (goog.userAgent.WEBKIT) {
- this.sendFrame_.location.href = url;
- } else {
- this.sendFrame_.location.replace(url);
- }
- } catch (e) {
- goog.net.xpc.logger.severe('sending failed', e);
- }
-
- // Restart receiver timer on short polling interval, to support use-cases
- // where we need to capture responses quickly.
- goog.net.xpc.IframePollingTransport.startRcvTimer_();
-};
-
-
-
-/**
- * goog.net.xpc.IframePollingTransport.Receiver
- *
- * @constructor
- * @param {goog.net.xpc.Transport} transport The transport to receive from.
- * @param {Object} windowObj The window-object to poll for location-changes.
- * @param {Function} callback The callback-function to be called when
- * location has changed.
- */
-goog.net.xpc.IframePollingTransport.Receiver = function(transport,
- windowObj,
- callback) {
-
- this.transport_ = transport;
- this.rcvFrame_ = windowObj;
-
- this.cb_ = callback;
-
- this.currentLoc_ = this.rcvFrame_.location.href.split('#')[0] + '#INITIAL';
-
- goog.net.xpc.IframePollingTransport.receivers_.push(this);
- goog.net.xpc.IframePollingTransport.startRcvTimer_();
-};
-
-
-/**
- * Polls the location of the receiver-frame for changes.
- * @return {boolean} Whether a change has been detected.
- */
-goog.net.xpc.IframePollingTransport.Receiver.prototype.receive = function() {
- var loc = this.rcvFrame_.location.href;
-
- if (loc != this.currentLoc_) {
- this.currentLoc_ = loc;
- var payload = loc.split('#')[1];
- if (payload) {
- payload = payload.substr(1); // discard first character (cycle)
- this.cb_(decodeURIComponent(payload));
- }
- return true;
- } else {
- return false;
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframerelaytransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframerelaytransport.js.svn-base
deleted file mode 100644
index 2f49ad5..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/iframerelaytransport.js.svn-base
+++ /dev/null
@@ -1,388 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the iframe relay tranport.
- */
-
-
-goog.provide('goog.net.xpc.IframeRelayTransport');
-
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.Transport');
-goog.require('goog.userAgent');
-
-
-
-/**
- * Iframe relay transport. Creates hidden iframes containing a document
- * from the peer's origin. Data is transferred in the fragment identifier.
- * Therefore the document loaded in the iframes can be served from the
- * browser's cache.
- *
- * @param {goog.net.xpc.CrossPageChannel} channel The channel this
- * transport belongs to.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for finding
- * the correct window.
- * @constructor
- * @extends {goog.net.xpc.Transport}
- */
-goog.net.xpc.IframeRelayTransport = function(channel, opt_domHelper) {
- goog.base(this, opt_domHelper);
-
- /**
- * The channel this transport belongs to.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The URI used to relay data to the peer.
- * @type {string}
- * @private
- */
- this.peerRelayUri_ =
- this.channel_.cfg_[goog.net.xpc.CfgFields.PEER_RELAY_URI];
-
- /**
- * The id of the iframe the peer page lives in.
- * @type {string}
- * @private
- */
- this.peerIframeId_ = this.channel_.cfg_[goog.net.xpc.CfgFields.IFRAME_ID];
-
- if (goog.userAgent.WEBKIT) {
- goog.net.xpc.IframeRelayTransport.startCleanupTimer_();
- }
-};
-goog.inherits(goog.net.xpc.IframeRelayTransport, goog.net.xpc.Transport);
-
-
-if (goog.userAgent.WEBKIT) {
- /**
- * Array to keep references to the relay-iframes. Used only if
- * there is no way to detect when the iframes are loaded. In that
- * case the relay-iframes are removed after a timeout.
- * @type {Array.<Object>}
- * @private
- */
- goog.net.xpc.IframeRelayTransport.iframeRefs_ = [];
-
-
- /**
- * Interval at which iframes are destroyed.
- * @type {number}
- * @private
- */
- goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_ = 1000;
-
-
- /**
- * Time after which a relay-iframe is destroyed.
- * @type {number}
- * @private
- */
- goog.net.xpc.IframeRelayTransport.IFRAME_MAX_AGE_ = 3000;
-
-
- /**
- * The cleanup timer id.
- * @type {number}
- * @private
- */
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ = 0;
-
-
- /**
- * Starts the cleanup timer.
- * @private
- */
- goog.net.xpc.IframeRelayTransport.startCleanupTimer_ = function() {
- if (!goog.net.xpc.IframeRelayTransport.cleanupTimer_) {
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ = window.setTimeout(
- function() { goog.net.xpc.IframeRelayTransport.cleanup_(); },
- goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_);
- }
- };
-
-
- /**
- * Remove all relay-iframes which are older than the maximal age.
- * @param {number=} opt_maxAge The maximal age in milliseconds.
- * @private
- */
- goog.net.xpc.IframeRelayTransport.cleanup_ = function(opt_maxAge) {
- var now = goog.now();
- var maxAge =
- opt_maxAge || goog.net.xpc.IframeRelayTransport.IFRAME_MAX_AGE_;
-
- while (goog.net.xpc.IframeRelayTransport.iframeRefs_.length &&
- now - goog.net.xpc.IframeRelayTransport.iframeRefs_[0].timestamp >=
- maxAge) {
- var ifr = goog.net.xpc.IframeRelayTransport.iframeRefs_.
- shift().iframeElement;
- goog.dom.removeNode(ifr);
- goog.net.xpc.logger.finest('iframe removed');
- }
-
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ = window.setTimeout(
- goog.net.xpc.IframeRelayTransport.cleanupCb_,
- goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_);
- };
-
-
- /**
- * Function which wraps cleanup_().
- * @private
- */
- goog.net.xpc.IframeRelayTransport.cleanupCb_ = function() {
- goog.net.xpc.IframeRelayTransport.cleanup_();
- };
-}
-
-
-/**
- * Maximum sendable size of a payload via a single iframe in IE.
- * @type {number}
- * @private
- */
-goog.net.xpc.IframeRelayTransport.IE_PAYLOAD_MAX_SIZE_ = 1800;
-
-
-/**
- * @typedef {{fragments: !Array.<string>, received: number, expected: number}}
- */
-goog.net.xpc.IframeRelayTransport.FragmentInfo;
-
-
-/**
- * Used to track incoming payload fragments. The implementation can process
- * incoming fragments from several channels at a time, even if data is
- * out-of-order or interleaved.
- *
- * @type {!Object.<string, !goog.net.xpc.IframeRelayTransport.FragmentInfo>}
- * @private
- */
-goog.net.xpc.IframeRelayTransport.fragmentMap_ = {};
-
-
-/**
- * The transport type.
- * @type {number}
- */
-goog.net.xpc.IframeRelayTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.IFRAME_RELAY;
-
-
-/**
- * Connects this transport.
- */
-goog.net.xpc.IframeRelayTransport.prototype.connect = function() {
- if (!this.getWindow()['xpcRelay']) {
- this.getWindow()['xpcRelay'] =
- goog.net.xpc.IframeRelayTransport.receiveMessage_;
- }
-
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP);
-};
-
-
-/**
- * Processes an incoming message.
- *
- * @param {string} channelName The name of the channel.
- * @param {string} frame The raw frame content.
- * @private
- */
-goog.net.xpc.IframeRelayTransport.receiveMessage_ =
- function(channelName, frame) {
- var pos = frame.indexOf(':');
- var header = frame.substr(0, pos);
- var payload = frame.substr(pos + 1);
-
- if (!goog.userAgent.IE || (pos = header.indexOf('|')) == -1) {
- // First, the easy case.
- var service = header;
- } else {
- // There was a fragment id in the header, so this is a message
- // fragment, not a whole message.
- var service = header.substr(0, pos);
- var fragmentIdStr = header.substr(pos + 1);
-
- // Separate the message id string and the fragment number. Note that
- // there may be a single leading + in the argument to parseInt, but
- // this is harmless.
- pos = fragmentIdStr.indexOf('+');
- var messageIdStr = fragmentIdStr.substr(0, pos);
- var fragmentNum = parseInt(fragmentIdStr.substr(pos + 1), 10);
- var fragmentInfo =
- goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr];
- if (!fragmentInfo) {
- fragmentInfo =
- goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr] =
- {fragments: [], received: 0, expected: 0};
- }
-
- if (goog.string.contains(fragmentIdStr, '++')) {
- fragmentInfo.expected = fragmentNum + 1;
- }
- fragmentInfo.fragments[fragmentNum] = payload;
- fragmentInfo.received++;
-
- if (fragmentInfo.received != fragmentInfo.expected) {
- return;
- }
-
- // We've received all outstanding fragments; combine what we've received
- // into payload and fall out to the call to deliver_.
- payload = fragmentInfo.fragments.join('');
- delete goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr];
- }
-
- goog.net.xpc.channels_[channelName].deliver_(service,
- decodeURIComponent(payload));
-};
-
-
-/**
- * Handles transport service messages (internal signalling).
- * @param {string} payload The message content.
- */
-goog.net.xpc.IframeRelayTransport.prototype.transportServiceHandler =
- function(payload) {
- if (payload == goog.net.xpc.SETUP) {
- // TODO(user) Safari swallows the SETUP_ACK from the iframe to the
- // container after hitting reload.
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
- this.channel_.notifyConnected_();
- }
- else if (payload == goog.net.xpc.SETUP_ACK_) {
- this.channel_.notifyConnected_();
- }
-};
-
-
-/**
- * Sends a message.
- *
- * @param {string} service Name of service this the message has to be delivered.
- * @param {string} payload The message content.
- */
-goog.net.xpc.IframeRelayTransport.prototype.send = function(service, payload) {
- // If we're on IE and the post-encoding payload is large, split it
- // into multiple payloads and send each one separately. Otherwise,
- // just send the whole thing.
- var encodedPayload = encodeURIComponent(payload);
- var encodedLen = encodedPayload.length;
- var maxSize = goog.net.xpc.IframeRelayTransport.IE_PAYLOAD_MAX_SIZE_;
-
- if (goog.userAgent.IE && encodedLen > maxSize) {
- // A probabilistically-unique string used to link together all fragments
- // in this message.
- var messageIdStr = goog.string.getRandomString();
-
- for (var startIndex = 0, fragmentNum = 0; startIndex < encodedLen;
- fragmentNum++) {
- var payloadFragment = encodedPayload.substr(startIndex, maxSize);
- startIndex += maxSize;
- var fragmentIdStr =
- messageIdStr + (startIndex >= encodedLen ? '++' : '+') + fragmentNum;
- this.send_(service, payloadFragment, fragmentIdStr);
- }
- } else {
- this.send_(service, encodedPayload);
- }
-};
-
-
-/**
- * Sends an encoded message or message fragment.
- * @param {string} service Name of service this the message has to be delivered.
- * @param {string} encodedPayload The message content, URI encoded.
- * @param {string=} opt_fragmentIdStr If sending a fragment, a string that
- * identifies the fragment.
- * @private
- */
-goog.net.xpc.IframeRelayTransport.prototype.send_ =
- function(service, encodedPayload, opt_fragmentIdStr) {
- // IE requires that we create the onload attribute inline, otherwise the
- // handler is not triggered
- if (goog.userAgent.IE) {
- var div = this.getWindow().document.createElement('div');
- div.innerHTML = '<iframe onload="this.xpcOnload()"></iframe>';
- var ifr = div.childNodes[0];
- div = null;
- ifr['xpcOnload'] = goog.net.xpc.IframeRelayTransport.iframeLoadHandler_;
- } else {
- var ifr = this.getWindow().document.createElement('iframe');
-
- if (goog.userAgent.WEBKIT) {
- // safari doesn't fire load-events on iframes.
- // keep a reference and remove after a timeout.
- goog.net.xpc.IframeRelayTransport.iframeRefs_.push({
- timestamp: goog.now(),
- iframeElement: ifr
- });
- } else {
- goog.events.listen(ifr, 'load',
- goog.net.xpc.IframeRelayTransport.iframeLoadHandler_);
- }
- }
-
- var style = ifr.style;
- style.visibility = 'hidden';
- style.width = ifr.style.height = '0px';
- style.position = 'absolute';
-
- var url = this.peerRelayUri_;
- url += '#' + this.channel_.name;
- if (this.peerIframeId_) {
- url += ',' + this.peerIframeId_;
- }
- url += '|' + service;
- if (opt_fragmentIdStr) {
- url += '|' + opt_fragmentIdStr;
- }
- url += ':' + encodedPayload;
-
- ifr.src = url;
-
- this.getWindow().document.body.appendChild(ifr);
-
- goog.net.xpc.logger.finest('msg sent: ' + url);
-};
-
-
-/**
- * The iframe load handler. Gets called as method on the iframe element.
- * @private
- * @this Element
- */
-goog.net.xpc.IframeRelayTransport.iframeLoadHandler_ = function() {
- goog.net.xpc.logger.finest('iframe-load');
- goog.dom.removeNode(this);
- this.xpcOnload = null;
-};
-
-
-/** @override */
-goog.net.xpc.IframeRelayTransport.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
- if (goog.userAgent.WEBKIT) {
- goog.net.xpc.IframeRelayTransport.cleanup_(0);
- }
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport.js.svn-base
deleted file mode 100644
index 4458471..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport.js.svn-base
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the class which uses native messaging
- * facilities for cross domain communication.
- *
- */
-
-
-goog.provide('goog.net.xpc.NativeMessagingTransport');
-
-goog.require('goog.events');
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.CrossPageChannelRole');
-goog.require('goog.net.xpc.Transport');
-
-
-
-/**
- * The native messaging transport
- *
- * Uses document.postMessage() to send messages to other documents.
- * Receiving is done by listening on 'message'-events on the document.
- *
- * @param {goog.net.xpc.CrossPageChannel} channel The channel this
- * transport belongs to.
- * @param {string} peerHostname The hostname (protocol, domain, and port) of the
- * peer.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for
- * finding the correct window/document.
- * @constructor
- * @extends {goog.net.xpc.Transport}
- */
-goog.net.xpc.NativeMessagingTransport = function(channel, peerHostname,
- opt_domHelper) {
- goog.base(this, opt_domHelper);
-
- /**
- * The channel this transport belongs to.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The hostname of the peer. This parameterizes all calls to postMessage, and
- * should contain the precise protocol, domain, and port of the peer window.
- * @type {string}
- * @private
- */
- this.peerHostname_ = peerHostname || '*';
-};
-goog.inherits(goog.net.xpc.NativeMessagingTransport, goog.net.xpc.Transport);
-
-
-/**
- * Flag indicating if this instance of the transport has been initialized.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.NativeMessagingTransport.prototype.initialized_ = false;
-
-
-/**
- * The transport type.
- * @type {number}
- */
-goog.net.xpc.NativeMessagingTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.NATIVE_MESSAGING;
-
-
-/**
- * Tracks the number of NativeMessagingTransport channels that have been
- * initialized but not disposed yet in a map keyed by the UID of the window
- * object. This allows for multiple windows to be initiallized and listening
- * for messages.
- * @type {Object.<number>}
- * @private
- */
-goog.net.xpc.NativeMessagingTransport.activeCount_ = {};
-
-
-/**
- * Initializes this transport. Registers a listener for 'message'-events
- * on the document.
- * @param {Window} listenWindow The window to listen to events on.
- * @private
- */
-goog.net.xpc.NativeMessagingTransport.initialize_ = function(listenWindow) {
- var uid = goog.getUid(listenWindow);
- var value = goog.net.xpc.NativeMessagingTransport.activeCount_[uid];
- if (!goog.isNumber(value)) {
- value = 0;
- }
- if (value == 0) {
- // Listen for message-events. These are fired on window in FF3 and on
- // document in Opera.
- goog.events.listen(
- listenWindow.postMessage ? listenWindow : listenWindow.document,
- 'message',
- goog.net.xpc.NativeMessagingTransport.messageReceived_,
- false,
- goog.net.xpc.NativeMessagingTransport);
- }
- goog.net.xpc.NativeMessagingTransport.activeCount_[uid] = value + 1;
-};
-
-
-/**
- * Processes an incoming message-event.
- * @param {goog.events.BrowserEvent} msgEvt The message event.
- * @return {boolean} True if message was successfully delivered to a channel.
- * @private
- */
-goog.net.xpc.NativeMessagingTransport.messageReceived_ = function(msgEvt) {
- var data = msgEvt.getBrowserEvent().data;
-
- if (!goog.isString(data)) {
- return false;
- }
-
- var headDelim = data.indexOf('|');
- var serviceDelim = data.indexOf(':');
-
- // make sure we got something reasonable
- if (headDelim == -1 || serviceDelim == -1) {
- return false;
- }
-
- var channelName = data.substring(0, headDelim);
- var service = data.substring(headDelim + 1, serviceDelim);
- var payload = data.substring(serviceDelim + 1);
-
- goog.net.xpc.logger.fine('messageReceived: channel=' + channelName +
- ', service=' + service + ', payload=' + payload);
-
- // Attempt to deliver message to the channel. Keep in mind that it may not
- // exist for several reasons, including but not limited to:
- // - a malformed message
- // - the channel simply has not been created
- // - channel was created in a different namespace
- // - message was sent to the wrong window
- // - channel has become stale (e.g. caching iframes and back clicks)
- var channel = goog.net.xpc.channels_[channelName];
- if (channel) {
- channel.deliver_(service, payload, msgEvt.getBrowserEvent().origin);
- return true;
- }
-
- // Check if there are any stale channel names that can be updated.
- for (var staleChannelName in goog.net.xpc.channels_) {
- var staleChannel = goog.net.xpc.channels_[staleChannelName];
- if (staleChannel.getRole() == goog.net.xpc.CrossPageChannelRole.INNER &&
- !staleChannel.isConnected() &&
- service == goog.net.xpc.TRANSPORT_SERVICE_ &&
- payload == goog.net.xpc.SETUP) {
- // Inner peer received SETUP message but channel names did not match.
- // Start using the channel name sent from outer peer. The channel name
- // of the inner peer can easily become out of date, as iframe's and their
- // JS state get cached in many browsers upon page reload or history
- // navigation (particularly Firefox 1.5+). We can trust the outer peer,
- // since we only accept postMessage messages from the same hostname that
- // originally setup the channel.
- goog.net.xpc.logger.fine('changing channel name to ' + channelName);
- staleChannel.name = channelName;
- // Remove old stale pointer to channel.
- delete goog.net.xpc.channels_[staleChannelName];
- // Create fresh pointer to channel.
- goog.net.xpc.channels_[channelName] = staleChannel;
- staleChannel.deliver_(service, payload);
- return true;
- }
- }
-
- // Failed to find a channel to deliver this message to, so simply ignore it.
- goog.net.xpc.logger.info('channel name mismatch; message ignored"');
- return false;
-};
-
-
-/**
- * Handles transport service messages.
- * @param {string} payload The message content.
- */
-goog.net.xpc.NativeMessagingTransport.prototype.transportServiceHandler =
- function(payload) {
- switch (payload) {
- case goog.net.xpc.SETUP:
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
- break;
- case goog.net.xpc.SETUP_ACK_:
- this.channel_.notifyConnected_();
- break;
- }
-};
-
-
-/**
- * Connects this transport.
- */
-goog.net.xpc.NativeMessagingTransport.prototype.connect = function() {
- goog.net.xpc.NativeMessagingTransport.initialize_(this.getWindow());
- this.initialized_ = true;
- this.connectWithRetries_();
-};
-
-
-/**
- * Connects to other peer. In the case of the outer peer, the setup messages are
- * likely sent before the inner peer is ready to receive them. Therefore, this
- * function will continue trying to send the SETUP message until the inner peer
- * responds. In the case of the inner peer, it will occasionally have its
- * channel name fall out of sync with the outer peer, particularly during
- * soft-reloads and history navigations.
- * @private
- */
-goog.net.xpc.NativeMessagingTransport.prototype.connectWithRetries_ =
- function() {
- if (this.channel_.isConnected() || this.isDisposed()) {
- return;
- }
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP);
- this.getWindow().setTimeout(goog.bind(this.connectWithRetries_, this), 100);
-};
-
-
-/**
- * Sends a message.
- * @param {string} service The name off the service the message is to be
- * delivered to.
- * @param {string} payload The message content.
- */
-goog.net.xpc.NativeMessagingTransport.prototype.send = function(service,
- payload) {
- var win = this.channel_.peerWindowObject_;
- if (!win) {
- goog.net.xpc.logger.fine('send(): window not ready');
- return;
- }
-
- // postMessage is a method of the window object, except in some versions of
- // Opera, where it is a method of the document object.
- var obj = win.postMessage ? win : win.document;
- this.send = function(service, payload) {
- goog.net.xpc.logger.fine('send(): payload=' + payload +
- ' to hostname=' + this.peerHostname_);
- obj.postMessage(this.channel_.name + '|' + service + ':' + payload,
- this.peerHostname_);
- };
- this.send(service, payload);
-};
-
-
-/** @override */
-goog.net.xpc.NativeMessagingTransport.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
- if (this.initialized_) {
- var listenWindow = this.getWindow();
- var uid = goog.getUid(listenWindow);
- var value = goog.net.xpc.NativeMessagingTransport.activeCount_[uid];
- goog.net.xpc.NativeMessagingTransport.activeCount_[uid] = value - 1;
- if (value == 1) {
- goog.events.unlisten(
- listenWindow.postMessage ? listenWindow : listenWindow.document,
- 'message',
- goog.net.xpc.NativeMessagingTransport.messageReceived_,
- false,
- goog.net.xpc.NativeMessagingTransport);
- }
- }
- // Cleaning up this.send as it is an instance method, created in
- // goog.net.xpc.NativeMessagingTransport.prototype.send and has a closure over
- // this.channel_.peerWindowObject_.
- delete this.send;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport_test.html.svn-base
deleted file mode 100644
index a18cb2a..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nativemessagingtransport_test.html.svn-base
+++ /dev/null
@@ -1,165 +0,0 @@
-<!--
--->
-<html>
-<!--
-Copyright 2008 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-<head>
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<title>NativeMessagingTransport Unit-Tests</title>
-<script src="../../base.js"></script>
-<script>
- goog.require('goog.net.xpc.CrossPageChannel');
- goog.require('goog.net.xpc.CrossPageChannelRole');
- goog.require('goog.net.xpc.NativeMessagingTransport');
- goog.require('goog.testing.events');
- goog.require('goog.testing.jsunit');
-</script>
-<script>
-
-function tearDown() {
- goog.net.xpc.NativeMessagingTransport.activeCount_ = {};
- goog.events.removeAll(window.postMessage ? window : document, 'message');
-}
-
-
-function testConstructor() {
- var t = new goog.net.xpc.NativeMessagingTransport(null, 'http://g.com:80');
- assertEquals('http://g.com:80', t.peerHostname_);
-
- var t = new goog.net.xpc.NativeMessagingTransport(null, null);
- assertEquals('*', t.peerHostname_);
- t.dispose();
-}
-
-
-function testConstructorDom() {
- var t = new goog.net.xpc.NativeMessagingTransport(
- null, 'http://g.com:80', goog.dom.getDomHelper());
- assertEquals('http://g.com:80', t.peerHostname_);
-
- var t = new goog.net.xpc.NativeMessagingTransport(null, null);
- assertEquals('*', t.peerHostname_);
- t.dispose();
-}
-
-
-function testDispose() {
- var xpc = getTestChannel();
- var listenedObj = window.postMessage ? window : document;
-
- var t0 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- t0.dispose();
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
-
- var t1 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- t1.connect();
- t1.dispose();
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
-
- var t2 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- var t3 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- t2.connect();
- t3.connect();
- t2.dispose();
- assertEquals(1, goog.events.removeAll(listenedObj, 'message'));
-}
-
-
-function testDisposeWithDom() {
- var xpc = getTestChannel(goog.dom.getDomHelper());
- var listenedObj = window.postMessage ? window : document;
-
- var t0 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- t0.dispose();
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
-
- var t1 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- t1.connect();
- t1.dispose();
- assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
-
- var t2 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- var t3 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- t2.connect();
- t3.connect();
- t2.dispose();
- assertEquals(1, goog.events.removeAll(listenedObj, 'message'));
-}
-
-
-function testBogusMessages() {
- var e = createMockEvent('bogus_message');
- assertFalse(goog.net.xpc.NativeMessagingTransport.messageReceived_(e));
-
- e = createMockEvent('bogus|message');
- assertFalse(goog.net.xpc.NativeMessagingTransport.messageReceived_(e));
-
- e = createMockEvent('bogus|message:data');
- assertFalse(goog.net.xpc.NativeMessagingTransport.messageReceived_(e));
-}
-
-
-function testSendingMessagesToUnconnectedInnerPeer() {
- var xpc = getTestChannel();
-
- var serviceResult, payloadResult;
- xpc.deliver_ = function(service, payload) {
- serviceResult = service;
- payloadResult = payload;
- };
-
- // Construct an unconnected inner peer.
- xpc.getRole = function() {
- return goog.net.xpc.CrossPageChannelRole.INNER;
- };
- xpc.isConnected = function() {
- return false;
- };
- var t = new goog.net.xpc.NativeMessagingTransport(xpc, 'http://g.com');
-
- // Test a valid message.
- var e = createMockEvent('test_channel|test_service:test_payload');
- assertTrue(goog.net.xpc.NativeMessagingTransport.messageReceived_(e));
- assertEquals('test_service', serviceResult);
- assertEquals('test_payload', payloadResult);
- assertEquals('Ensure channel name has not been changed.',
- 'test_channel',
- t.channel_.name);
-
- // Test updating a stale inner peer.
- var e = createMockEvent('new_channel|tp:SETUP');
- assertTrue(goog.net.xpc.NativeMessagingTransport.messageReceived_(e));
- assertEquals('tp', serviceResult);
- assertEquals('SETUP', payloadResult);
- assertEquals('Ensure channel name has been updated.',
- 'new_channel',
- t.channel_.name);
- t.dispose();
-}
-
-
-function createMockEvent(data) {
- var event = {};
- event.getBrowserEvent = function() { return {data: data} };
- return event;
-}
-
-
-function getTestChannel(opt_domHelper) {
- var cfg = {};
- cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = 'test_channel';
- return new goog.net.xpc.CrossPageChannel(cfg, opt_domHelper);
-}
-
-</script>
-</head>
-
-<body></body>
-
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nixtransport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nixtransport.js.svn-base
deleted file mode 100644
index d3b0dd7..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/nixtransport.js.svn-base
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2008 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the NIX (Native IE XDC) method transport for
- * cross-domain communication. It exploits the fact that Internet Explorer
- * allows a window that is the parent of an iframe to set said iframe window's
- * opener property to an object. This object can be a function that in turn
- * can be used to send a message despite same-origin constraints. Note that
- * this function, if a pure JavaScript object, opens up the possibilitiy of
- * gaining a hold of the context of the other window and in turn, attacking
- * it. This implementation therefore wraps the JavaScript objects used inside
- * a VBScript class. Since VBScript objects are passed in JavaScript as a COM
- * wrapper (like DOM objects), they are thus opaque to JavaScript
- * (except for the interface they expose). This therefore provides a safe
- * method of transport.
- *
- *
- * Initially based on FrameElementTransport which shares some similarities
- * to this method.
- */
-
-goog.provide('goog.net.xpc.NixTransport');
-
-goog.require('goog.net.xpc');
-goog.require('goog.net.xpc.CrossPageChannelRole');
-goog.require('goog.net.xpc.Transport');
-goog.require('goog.reflect');
-
-
-/**
- * NIX method transport.
- *
- * NOTE(user): NIX method tested in all IE versions starting from 6.0.
- *
- * @param {goog.net.xpc.CrossPageChannel} channel The channel this transport
- * belongs to.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for finding
- * the correct window.
- * @constructor
- * @extends {goog.net.xpc.Transport}
- */
-goog.net.xpc.NixTransport = function(channel, opt_domHelper) {
- goog.base(this, opt_domHelper);
-
- /**
- * The channel this transport belongs to.
- * @type {goog.net.xpc.CrossPageChannel}
- * @private
- */
- this.channel_ = channel;
-
- /**
- * The authorization token, if any, used by this transport.
- * @type {?string}
- * @private
- */
- this.authToken_ = channel[goog.net.xpc.CfgFields.AUTH_TOKEN] || '';
-
- /**
- * The authorization token, if any, that must be sent by the other party
- * for setup to occur.
- * @type {?string}
- * @private
- */
- this.remoteAuthToken_ =
- channel[goog.net.xpc.CfgFields.REMOTE_AUTH_TOKEN] || '';
-
- // Conduct the setup work for NIX in general, if need be.
- goog.net.xpc.NixTransport.conductGlobalSetup_(this.getWindow());
-
- // Setup aliases so that VBScript can call these methods
- // on the transport class, even if they are renamed during
- // compression.
- this[goog.net.xpc.NixTransport.NIX_HANDLE_MESSAGE] = this.handleMessage_;
- this[goog.net.xpc.NixTransport.NIX_CREATE_CHANNEL] = this.createChannel_;
-};
-goog.inherits(goog.net.xpc.NixTransport, goog.net.xpc.Transport);
-
-
-// Consts for NIX. VBScript doesn't allow items to start with _ for some
-// reason, so we need to make these names quite unique, as they will go into
-// the global namespace.
-
-
-/**
- * Global name of the Wrapper VBScript class.
- * Note that this class will be stored in the *global*
- * namespace (i.e. window in browsers).
- * @type {string}
- */
-goog.net.xpc.NixTransport.NIX_WRAPPER = 'GCXPC____NIXVBS_wrapper';
-
-
-/**
- * Global name of the GetWrapper VBScript function. This
- * constant is used by JavaScript to call this function.
- * Note that this function will be stored in the *global*
- * namespace (i.e. window in browsers).
- * @type {string}
- */
-goog.net.xpc.NixTransport.NIX_GET_WRAPPER = 'GCXPC____NIXVBS_get_wrapper';
-
-
-/**
- * The name of the handle message method used by the wrapper class
- * when calling the transport.
- * @type {string}
- */
-goog.net.xpc.NixTransport.NIX_HANDLE_MESSAGE = 'GCXPC____NIXJS_handle_message';
-
-
-/**
- * The name of the create channel method used by the wrapper class
- * when calling the transport.
- * @type {string}
- */
-goog.net.xpc.NixTransport.NIX_CREATE_CHANNEL = 'GCXPC____NIXJS_create_channel';
-
-
-/**
- * A "unique" identifier that is stored in the wrapper
- * class so that the wrapper can be distinguished from
- * other objects easily.
- * @type {string}
- */
-goog.net.xpc.NixTransport.NIX_ID_FIELD = 'GCXPC____NIXVBS_container';
-
-
-/**
- * Determines if the installed version of IE supports accessing window.opener
- * after it has been set to a non-Window/null value. NIX relies on this being
- * possible.
- * @return {boolean} Whether window.opener behavior is compatible with NIX.
- */
-goog.net.xpc.NixTransport.isNixSupported = function() {
- var isSupported = false;
- try {
- var oldOpener = window.opener;
- // The compiler complains (as it should!) if we set window.opener to
- // something other than a window or null.
- window.opener = /** @type {Window} */ ({});
- isSupported = goog.reflect.canAccessProperty(window, 'opener');
- window.opener = oldOpener;
- } catch(e) { }
- return isSupported;
-};
-
-
-/**
- * Conducts the global setup work for the NIX transport method.
- * This function creates and then injects into the page the
- * VBScript code necessary to create the NIX wrapper class.
- * Note that this method can be called multiple times, as
- * it internally checks whether the work is necessary before
- * proceeding.
- * @private
- */
-goog.net.xpc.NixTransport.conductGlobalSetup_ = function(listenWindow) {
- if (listenWindow['nix_setup_complete']) {
- return;
- }
-
- // Inject the VBScript code needed.
- var vbscript =
- // We create a class to act as a wrapper for
- // a Javascript call, to prevent a break in of
- // the context.
- 'Class ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n ' +
-
- // An internal member for keeping track of the
- // transport for which this wrapper exists.
- 'Private m_Transport\n' +
-
- // An internal member for keeping track of the
- // auth token associated with the context that
- // created this wrapper. Used for validation
- // purposes.
- 'Private m_Auth\n' +
-
- // Method for internally setting the value
- // of the m_Transport property. We have the
- // isEmpty check to prevent the transport
- // from being overridden with an illicit
- // object by a malicious party.
- 'Public Sub SetTransport(transport)\n' +
- 'If isEmpty(m_Transport) Then\n' +
- 'Set m_Transport = transport\n' +
- 'End If\n' +
- 'End Sub\n' +
-
- // Method for internally setting the value
- // of the m_Auth property. We have the
- // isEmpty check to prevent the transport
- // from being overridden with an illicit
- // object by a malicious party.
- 'Public Sub SetAuth(auth)\n' +
- 'If isEmpty(m_Auth) Then\n' +
- 'm_Auth = auth\n' +
- 'End If\n' +
- 'End Sub\n' +
-
- // Returns the auth token to the gadget, so it can
- // confirm a match before initiating the connection
- 'Public Function GetAuthToken()\n ' +
- 'GetAuthToken = m_Auth\n' +
- 'End Function\n' +
-
- // A wrapper method which causes a
- // message to be sent to the other context.
- 'Public Sub SendMessage(service, payload)\n ' +
- 'Call m_Transport.' +
- goog.net.xpc.NixTransport.NIX_HANDLE_MESSAGE + '(service, payload)\n' +
- 'End Sub\n' +
-
- // Method for setting up the inner->outer
- // channel.
- 'Public Sub CreateChannel(channel)\n ' +
- 'Call m_Transport.' +
- goog.net.xpc.NixTransport.NIX_CREATE_CHANNEL + '(channel)\n' +
- 'End Sub\n' +
-
- // An empty field with a unique identifier to
- // prevent the code from confusing this wrapper
- // with a run-of-the-mill value found in window.opener.
- 'Public Sub ' + goog.net.xpc.NixTransport.NIX_ID_FIELD + '()\n ' +
- 'End Sub\n' +
- 'End Class\n ' +
-
- // Function to get a reference to the wrapper.
- 'Function ' +
- goog.net.xpc.NixTransport.NIX_GET_WRAPPER + '(transport, auth)\n' +
- 'Dim wrap\n' +
- 'Set wrap = New ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n' +
- 'wrap.SetTransport transport\n' +
- 'wrap.SetAuth auth\n' +
- 'Set ' + goog.net.xpc.NixTransport.NIX_GET_WRAPPER + ' = wrap\n' +
- 'End Function';
-
- try {
- listenWindow.execScript(vbscript, 'vbscript');
- listenWindow['nix_setup_complete'] = true;
- }
- catch (e) {
- goog.net.xpc.logger.severe(
- 'exception caught while attempting global setup: ' + e);
- }
-};
-
-
-/**
- * The transport type.
- * @type {number}
- * @protected
- */
-goog.net.xpc.NixTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.NIX;
-
-
-/**
- * Keeps track of whether the local setup has completed (i.e.
- * the initial work towards setting the channel up has been
- * completed for this end).
- * @type {boolean}
- * @private
- */
-goog.net.xpc.NixTransport.prototype.localSetupCompleted_ = false;
-
-
-/**
- * The NIX channel used to talk to the other page. This
- * object is in fact a reference to a VBScript class
- * (see above) and as such, is in fact a COM wrapper.
- * When using this object, make sure to not access methods
- * without calling them, otherwise a COM error will be thrown.
- * @type {Object}
- * @private
- */
-goog.net.xpc.NixTransport.prototype.nixChannel_ = null;
-
-
-/**
- * Connect this transport.
- */
-goog.net.xpc.NixTransport.prototype.connect = function() {
- if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER) {
- this.attemptOuterSetup_();
- } else {
- this.attemptInnerSetup_();
- }
-};
-
-
-/**
- * Attempts to setup the channel from the perspective
- * of the outer (read: container) page. This method
- * will attempt to create a NIX wrapper for this transport
- * and place it into the "opener" property of the inner
- * page's window object. If it fails, it will continue
- * to loop until it does so.
- *
- * @private
- */
-goog.net.xpc.NixTransport.prototype.attemptOuterSetup_ = function() {
- if (this.localSetupCompleted_) {
- return;
- }
-
- // Get shortcut to iframe-element that contains the inner
- // page.
- var innerFrame = this.channel_.iframeElement_;
-
- try {
- // Attempt to place the NIX wrapper object into the inner
- // frame's opener property.
- innerFrame.contentWindow.opener =
- this.getWindow()[goog.net.xpc.NixTransport.NIX_GET_WRAPPER]
- (this, this.authToken_);
- this.localSetupCompleted_ = true;
- }
- catch (e) {
- goog.net.xpc.logger.severe(
- 'exception caught while attempting setup: ' + e);
- }
-
- // If the retry is necessary, reattempt this setup.
- if (!this.localSetupCompleted_) {
- this.getWindow().setTimeout(goog.bind(this.attemptOuterSetup_, this), 100);
- }
-};
-
-
-/**
- * Attempts to setup the channel from the perspective
- * of the inner (read: iframe) page. This method
- * will attempt to *read* the opener object from the
- * page's opener property. If it succeeds, this object
- * is saved into nixChannel_ and the channel is confirmed
- * with the container by calling CreateChannel with an instance
- * of a wrapper for *this* page. Note that if this method
- * fails, it will continue to loop until it succeeds.
- *
- * @private
- */
-goog.net.xpc.NixTransport.prototype.attemptInnerSetup_ = function() {
- if (this.localSetupCompleted_) {
- return;
- }
-
- try {
- var opener = this.getWindow().opener;
-
- // Ensure that the object contained inside the opener
- // property is in fact a NIX wrapper.
- if (opener && goog.net.xpc.NixTransport.NIX_ID_FIELD in opener) {
- this.nixChannel_ = opener;
-
- // Ensure that the NIX channel given to use is valid.
- var remoteAuthToken = this.nixChannel_['GetAuthToken']();
-
- if (remoteAuthToken != this.remoteAuthToken_) {
- goog.net.xpc.logger.severe('Invalid auth token from other party');
- return;
- }
-
- // Complete the construction of the channel by sending our own
- // wrapper to the container via the channel they gave us.
- this.nixChannel_['CreateChannel'](
- this.getWindow()[goog.net.xpc.NixTransport.NIX_GET_WRAPPER](this,
- this.authToken_));
-
- this.localSetupCompleted_ = true;
-
- // Notify channel that the transport is ready.
- this.channel_.notifyConnected_();
- }
- }
- catch (e) {
- goog.net.xpc.logger.severe(
- 'exception caught while attempting setup: ' + e);
- return;
- }
-
- // If the retry is necessary, reattempt this setup.
- if (!this.localSetupCompleted_) {
- this.getWindow().setTimeout(goog.bind(this.attemptInnerSetup_, this), 100);
- }
-};
-
-
-/**
- * Internal method called by the inner page, via the
- * NIX wrapper, to complete the setup of the channel.
- *
- * @param {Object} channel The NIX wrapper of the
- * inner page.
- * @private
- */
-goog.net.xpc.NixTransport.prototype.createChannel_ = function(channel) {
- // Verify that the channel is in fact a NIX wrapper.
- if (typeof channel != 'unknown' ||
- !(goog.net.xpc.NixTransport.NIX_ID_FIELD in channel)) {
- goog.net.xpc.logger.severe('Invalid NIX channel given to createChannel_');
- }
-
- this.nixChannel_ = channel;
-
- // Ensure that the NIX channel given to use is valid.
- var remoteAuthToken = this.nixChannel_['GetAuthToken']();
-
- if (remoteAuthToken != this.remoteAuthToken_) {
- goog.net.xpc.logger.severe('Invalid auth token from other party');
- return;
- }
-
- // Indicate to the CrossPageChannel that the channel is setup
- // and ready to use.
- this.channel_.notifyConnected_();
-};
-
-
-/**
- * Internal method called by the other page, via the NIX wrapper,
- * to deliver a message.
- * @param {string} serviceName The name of the service the message is to be
- * delivered to.
- * @param {string} payload The message to process.
- * @private
- */
-goog.net.xpc.NixTransport.prototype.handleMessage_ =
- function(serviceName, payload) {
-
- function deliveryHandler() {
- this.channel_.deliver_(serviceName, payload);
- }
-
- this.getWindow().setTimeout(goog.bind(deliveryHandler, this), 1);
-};
-
-
-/**
- * Sends a message.
- * @param {string} service The name of the service the message is to be
- * delivered to.
- * @param {string} payload The message content.
- */
-goog.net.xpc.NixTransport.prototype.send = function(service, payload) {
- // Verify that the NIX channel we have is valid.
- if (typeof(this.nixChannel_) !== 'unknown') {
- goog.net.xpc.logger.severe('NIX channel not connected');
- }
-
- // Send the message via the NIX wrapper object.
- this.nixChannel_['SendMessage'](service, payload);
-};
-
-
-/** @override */
-goog.net.xpc.NixTransport.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
- this.nixChannel_ = null;
-};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/relay.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/relay.js.svn-base
deleted file mode 100644
index a79e7a5..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/relay.js.svn-base
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Standalone script to be included in the relay-document
- * used by goog.net.xpc.IframeRelayTransport. This script will decode the
- * fragment identifier, determine the target window object and deliver
- * the data to it.
- *
- */
-
-goog.provide('goog.net.xpc.relay');
-
-(function() {
- // Decode the fragement identifier.
- // location.href is expected to be structured as follows:
- // <url>#<channel_name>[,<iframe_id>]|<data>
-
- // Get the fragment identifier.
- var raw = window.location.hash;
- if (!raw) {
- return;
- }
- if (raw.charAt(0) == '#') {
- raw = raw.substring(1);
- }
- var pos = raw.indexOf('|');
- var head = raw.substring(0, pos).split(',');
- var channelName = head[0];
- var iframeId = head.length == 2 ? head[1] : null;
- var frame = raw.substring(pos + 1);
-
- // Find the window object of the peer.
- //
- // The general structure of the frames looks like this:
- // - peer1
- // - relay2
- // - peer2
- // - relay1
- //
- // We are either relay1 or relay2.
-
- var win;
- if (iframeId) {
- // We are relay2 and need to deliver the data to peer2.
- win = window.parent.frames[iframeId];
- } else {
- // We are relay1 and need to deliver the data to peer1.
- win = window.parent.parent;
- }
-
- // Deliver the data.
- try {
- win['xpcRelay'](channelName, frame);
- } catch (e) {
- // Nothing useful can be done here.
- // It would be great to inform the sender the delivery of this message
- // failed, but this is not possible because we are already in the receiver's
- // domain at this point.
- }
-})();
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/transport.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/transport.js.svn-base
deleted file mode 100644
index b9148af..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/transport.js.svn-base
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Contains the base class for transports.
- *
- */
-
-
-goog.provide('goog.net.xpc.Transport');
-
-goog.require('goog.Disposable');
-goog.require('goog.dom');
-goog.require('goog.net.xpc');
-
-
-
-/**
- * The base class for transports.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for
- * finding the window objects.
- * @constructor
- * @extends {goog.Disposable};
- */
-goog.net.xpc.Transport = function(opt_domHelper) {
- goog.Disposable.call(this);
-
- /**
- * The dom helper to use for finding the window objects to reference.
- * @type {goog.dom.DomHelper}
- * @private
- */
- this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();
-};
-goog.inherits(goog.net.xpc.Transport, goog.Disposable);
-
-
-/**
- * The transport type.
- * @type {number}
- * @protected
- */
-goog.net.xpc.Transport.prototype.transportType = 0;
-
-
-/**
- * @return {number} The transport type identifier.
- */
-goog.net.xpc.Transport.prototype.getType = function() {
- return this.transportType;
-};
-
-
-/**
- * Returns the window associated with this transport instance.
- * @return {Window} The window to use.
- */
-goog.net.xpc.Transport.prototype.getWindow = function() {
- return this.domHelper_.getWindow();
-};
-
-
-/**
- * Return the transport name.
- * @return {string} the transport name.
- */
-goog.net.xpc.Transport.prototype.getName = function() {
- return goog.net.xpc.TransportNames[this.transportType] || '';
-};
-
-
-/**
- * Handles transport service messages (internal signalling).
- * @param {string} payload The message content.
- */
-goog.net.xpc.Transport.prototype.transportServiceHandler = goog.abstractMethod;
-
-
-/**
- * Connects this transport.
- * The transport implementation is expected to call
- * CrossPageChannel.prototype.notifyConnected_ when the channel is ready
- * to be used.
- */
-goog.net.xpc.Transport.prototype.connect = goog.abstractMethod;
-
-
-/**
- * Sends a message.
- * @param {string} service The name off the service the message is to be
- * delivered to.
- * @param {string|Object} payload The message content.
- */
-goog.net.xpc.Transport.prototype.send = goog.abstractMethod;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/xpc.js.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/xpc.js.svn-base
deleted file mode 100644
index c74a349..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/.svn/text-base/xpc.js.svn-base
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2007 The Closure Library Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * @fileoverview Provides the namesspace for client-side communication
- * between pages originating from different domains (it works also
- * with pages from the same domain, but doing that is kinda
- * pointless).
- *
- * The only publicly visible class is goog.net.xpc.CrossPageChannel.
- *
- * Note: The preferred name for the main class would have been
- * CrossDomainChannel. But as there already is a class named like
- * that (which serves a different purpose) in the maps codebase,
- * CrossPageChannel was chosen to avoid confusion.
- *
- * CrossPageChannel abstracts the underlying transport mechanism to
- * provide a common interface in all browsers.
- *
- */
-
-/*
-TODO(user)
-- resolve fastback issues in Safari (IframeRelayTransport)
- */
-
-
-/**
- * Namespace for CrossPageChannel
- */
-goog.provide('goog.net.xpc');
-goog.provide('goog.net.xpc.CfgFields');
-goog.provide('goog.net.xpc.ChannelStates');
-goog.provide('goog.net.xpc.TransportNames');
-goog.provide('goog.net.xpc.TransportTypes');
-goog.provide('goog.net.xpc.UriCfgFields');
-
-goog.require('goog.debug.Logger');
-
-
-/**
- * Enum used to identify transport types.
- * @enum {number}
- */
-goog.net.xpc.TransportTypes = {
- NATIVE_MESSAGING: 1,
- FRAME_ELEMENT_METHOD: 2,
- IFRAME_RELAY: 3,
- IFRAME_POLLING: 4,
- FLASH: 5,
- NIX: 6
-};
-
-
-/**
- * Enum containing transport names. These need to correspond to the
- * transport class names for createTransport_() to work.
- * @type {Object}
- */
-goog.net.xpc.TransportNames = {
- '1': 'NativeMessagingTransport',
- '2': 'FrameElementMethodTransport',
- '3': 'IframeRelayTransport',
- '4': 'IframePollingTransport',
- '5': 'FlashTransport',
- '6': 'NixTransport'
-};
-
-
-// TODO(user): Add auth token support to other methods.
-
-
-/**
- * Field names used on configuration object.
- * @type {Object}
- */
-goog.net.xpc.CfgFields = {
- /**
- * Channel name identifier.
- * Both peers have to be initialized with
- * the same channel name. If not present, a channel name is
- * generated (which then has to transferred to the peer somehow).
- */
- CHANNEL_NAME: 'cn',
- /**
- * Authorization token. If set, NIX will use this authorization token
- * to validate the setup.
- */
- AUTH_TOKEN: 'at',
- /**
- * Remote party's authorization token. If set, NIX will validate this
- * authorization token against that sent by the other party.
- */
- REMOTE_AUTH_TOKEN: 'rat',
- /**
- * The URI of the peer page.
- */
- PEER_URI: 'pu',
- /**
- * Ifame-ID identifier.
- * The id of the iframe element the peer-document lives in.
- */
- IFRAME_ID: 'ifrid',
- /**
- * Transport type identifier.
- * The transport type to use. Possible values are entries from
- * goog.net.xpc.TransportTypes. If not present, the transport is
- * determined automatically based on the useragent's capabilities.
- */
- TRANSPORT: 'tp',
- /**
- * Local relay URI identifier (IframeRelayTransport-specific).
- * The URI (can't contain a fragment identifier) used by the peer to
- * relay data through.
- */
- LOCAL_RELAY_URI: 'lru',
- /**
- * Peer relay URI identifier (IframeRelayTransport-specific).
- * The URI (can't contain a fragment identifier) used to relay data
- * to the peer.
- */
- PEER_RELAY_URI: 'pru',
- /**
- * Local poll URI identifier (IframePollingTransport-specific).
- * The URI (can't contain a fragment identifier)which is polled
- * to receive data from the peer.
- */
- LOCAL_POLL_URI: 'lpu',
- /**
- * Local poll URI identifier (IframePollingTransport-specific).
- * The URI (can't contain a fragment identifier) used to send data
- * to the peer.
- */
- PEER_POLL_URI: 'ppu',
- /**
- * The hostname of the peer window, including protocol, domain, and port
- * (if specified). Used for security sensitive applications that make
- * use of NativeMessagingTransport (i.e. most applications).
- */
- PEER_HOSTNAME: 'ph'
-};
-
-
-/**
- * Config properties that need to be URL sanitized.
- * @type {Array}.<string>
- */
-goog.net.xpc.UriCfgFields = [
- goog.net.xpc.CfgFields.PEER_URI,
- goog.net.xpc.CfgFields.LOCAL_RELAY_URI,
- goog.net.xpc.CfgFields.PEER_RELAY_URI,
- goog.net.xpc.CfgFields.LOCAL_POLL_URI,
- goog.net.xpc.CfgFields.PEER_POLL_URI
-];
-
-
-/**
- * @enum {number}
- */
-goog.net.xpc.ChannelStates = {
- NOT_CONNECTED: 1,
- CONNECTED: 2,
- CLOSED: 3
-};
-
-
-/**
- * The name of the transport service (used for internal signalling).
- * @type {string}
- * @private
- */
-goog.net.xpc.TRANSPORT_SERVICE_ = 'tp';
-
-
-/**
- * Transport signaling message: setup.
- * @protected
- */
-goog.net.xpc.SETUP = 'SETUP';
-
-
-/**
- * Transport signaling message: setup acknowledgement.
- * @private
- */
-goog.net.xpc.SETUP_ACK_ = 'SETUP_ACK';
-
-
-/**
- * Object holding active channels.
- * @type {Object}
- * @private
- */
-goog.net.xpc.channels_ = {};
-
-
-/**
- * Returns a random string.
- * @param {number} length How many characters the string shall contain.
- * @param {string=} opt_characters The characters used.
- * @return {string} The random string.
- */
-goog.net.xpc.getRandomString = function(length, opt_characters) {
- var chars = opt_characters || goog.net.xpc.randomStringCharacters_;
- var charsLength = chars.length;
- var s = '';
- while (length-- > 0) {
- s += chars.charAt(Math.floor(Math.random() * charsLength));
- }
- return s;
-};
-
-
-/**
- * The default characters used for random string generation.
- * @type {string}
- * @private
- */
-goog.net.xpc.randomStringCharacters_ =
- 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
-
-
-/**
- * The logger.
- * @type {goog.debug.Logger}
- */
-goog.net.xpc.logger = goog.debug.Logger.getLogger('goog.net.xpc');
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel.js
index f14e95e..171cad1 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel.js
@@ -23,8 +23,11 @@ goog.provide('goog.net.xpc.CrossPageChannel');
goog.require('goog.Disposable');
goog.require('goog.Uri');
+goog.require('goog.async.Deferred');
+goog.require('goog.async.Delay');
goog.require('goog.dom');
goog.require('goog.events');
+goog.require('goog.events.EventHandler');
goog.require('goog.json');
goog.require('goog.messaging.AbstractChannel');
goog.require('goog.net.xpc');
@@ -68,7 +71,6 @@ goog.net.xpc.CrossPageChannel = function(cfg, opt_domHelper) {
/**
* The name of the channel.
* @type {string}
- * @protected
*/
this.name = this.cfg_[goog.net.xpc.CfgFields.CHANNEL_NAME] ||
goog.net.xpc.getRandomString(10);
@@ -88,6 +90,13 @@ goog.net.xpc.CrossPageChannel = function(cfg, opt_domHelper) {
*/
this.deferredDeliveries_ = [];
+ /**
+ * An event handler used to listen for load events on peer iframes.
+ * @type {!goog.events.EventHandler}
+ * @private
+ */
+ this.peerLoadHandler_ = new goog.events.EventHandler(this);
+
// If LOCAL_POLL_URI or PEER_POLL_URI is not available, try using
// robots.txt from that host.
cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] =
@@ -100,7 +109,7 @@ goog.net.xpc.CrossPageChannel = function(cfg, opt_domHelper) {
goog.uri.utils.getHost(cfg[goog.net.xpc.CfgFields.PEER_URI] || '') +
'/robots.txt';
- goog.net.xpc.channels_[this.name] = this;
+ goog.net.xpc.channels[this.name] = this;
goog.events.listen(window, 'unload',
goog.net.xpc.CrossPageChannel.disposeAll_);
@@ -129,6 +138,25 @@ goog.net.xpc.CrossPageChannel.TRANSPORT_SERVICE_UNESCAPE_RE_ =
/**
+ * A delay between the transport reporting as connected and the calling of the
+ * connection callback. Sometimes used to paper over timing vulnerabilities.
+ * @type {goog.async.Delay}
+ * @private
+ */
+goog.net.xpc.CrossPageChannel.prototype.connectionDelay_ = null;
+
+
+/**
+ * A deferred which is set to non-null while a peer iframe is being created
+ * but has not yet thrown its load event, and which fires when that load event
+ * arrives.
+ * @type {goog.async.Deferred}
+ * @private
+ */
+goog.net.xpc.CrossPageChannel.prototype.peerWindowDeferred_ = null;
+
+
+/**
* The transport.
* @type {goog.net.xpc.Transport?}
* @private
@@ -171,6 +199,28 @@ goog.net.xpc.CrossPageChannel.prototype.iframeElement_ = null;
/**
+ * Returns the configuration object for this channel.
+ * Package private. Do not call from outside goog.net.xpc.
+ *
+ * @return {Object} The configuration object for this channel.
+ */
+goog.net.xpc.CrossPageChannel.prototype.getConfig = function() {
+ return this.cfg_;
+};
+
+
+/**
+ * Returns a reference to the iframe-element.
+ * Package private. Do not call from outside goog.net.xpc.
+ *
+ * @return {Object} A reference to the iframe-element.
+ */
+goog.net.xpc.CrossPageChannel.prototype.getIframeElement = function() {
+ return this.iframeElement_;
+};
+
+
+/**
* Sets the window object the foreign document resides in.
*
* @param {Object} peerWindowObject The window object of the peer.
@@ -182,6 +232,42 @@ goog.net.xpc.CrossPageChannel.prototype.setPeerWindowObject =
/**
+ * Returns the window object the foreign document resides in.
+ * Package private. Do not call from outside goog.net.xpc.
+ *
+ * @return {Object} The window object of the peer.
+ */
+goog.net.xpc.CrossPageChannel.prototype.getPeerWindowObject = function() {
+ return this.peerWindowObject_;
+};
+
+
+/**
+ * Determines whether the peer window is available (e.g. not closed).
+ * Package private. Do not call from outside goog.net.xpc.
+ *
+ * @return {boolean} Whether the peer window is available.
+ */
+goog.net.xpc.CrossPageChannel.prototype.isPeerAvailable = function() {
+ // NOTE(user): This check is not reliable in IE, where a document in an
+ // iframe does not get unloaded when removing the iframe element from the DOM.
+ // TODO(user): Find something that works in IE as well.
+ // NOTE(user): "!this.peerWindowObject_.closed" evaluates to 'false' in IE9
+ // sometimes even though typeof(this.peerWindowObject_.closed) is boolean and
+ // this.peerWindowObject_.closed evaluates to 'false'. Casting it to a Boolean
+ // results in sane evaluation. When this happens, it's in the inner iframe
+ // when querying its parent's 'closed' status. Note that this is a different
+ // case than mibuerge@'s note above.
+ try {
+ return !!this.peerWindowObject_ && !Boolean(this.peerWindowObject_.closed);
+ } catch (e) {
+ // If the window is closing, an error may be thrown.
+ return false;
+ }
+};
+
+
+/**
* Determine which transport type to use for this channel / useragent.
* @return {goog.net.xpc.TransportTypes|undefined} The best transport type.
* @private
@@ -226,10 +312,14 @@ goog.net.xpc.CrossPageChannel.prototype.createTransport_ = function() {
switch (this.cfg_[goog.net.xpc.CfgFields.TRANSPORT]) {
case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
+ var protocolVersion = this.cfg_[
+ goog.net.xpc.CfgFields.NATIVE_TRANSPORT_PROTOCOL_VERSION] || 2;
this.transport_ = new goog.net.xpc.NativeMessagingTransport(
this,
this.cfg_[goog.net.xpc.CfgFields.PEER_HOSTNAME],
- this.domHelper_);
+ this.domHelper_,
+ !!this.cfg_[goog.net.xpc.CfgFields.ONE_SIDED_HANDSHAKE],
+ protocolVersion);
break;
case goog.net.xpc.TransportTypes.NIX:
this.transport_ = new goog.net.xpc.NixTransport(this, this.domHelper_);
@@ -283,6 +373,8 @@ goog.net.xpc.CrossPageChannel.prototype.getPeerConfiguration = function() {
peerCfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = this.name;
peerCfg[goog.net.xpc.CfgFields.TRANSPORT] =
this.cfg_[goog.net.xpc.CfgFields.TRANSPORT];
+ peerCfg[goog.net.xpc.CfgFields.ONE_SIDED_HANDSHAKE] =
+ this.cfg_[goog.net.xpc.CfgFields.ONE_SIDED_HANDSHAKE];
if (this.cfg_[goog.net.xpc.CfgFields.LOCAL_RELAY_URI]) {
peerCfg[goog.net.xpc.CfgFields.PEER_RELAY_URI] =
@@ -296,6 +388,13 @@ goog.net.xpc.CrossPageChannel.prototype.getPeerConfiguration = function() {
peerCfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] =
this.cfg_[goog.net.xpc.CfgFields.PEER_POLL_URI];
}
+ var role = this.cfg_[goog.net.xpc.CfgFields.ROLE];
+ if (role) {
+ peerCfg[goog.net.xpc.CfgFields.ROLE] =
+ role == goog.net.xpc.CrossPageChannelRole.INNER ?
+ goog.net.xpc.CrossPageChannelRole.OUTER :
+ goog.net.xpc.CrossPageChannelRole.INNER;
+ }
return peerCfg;
};
@@ -317,6 +416,7 @@ goog.net.xpc.CrossPageChannel.prototype.getPeerConfiguration = function() {
*/
goog.net.xpc.CrossPageChannel.prototype.createPeerIframe = function(
parentElm, opt_configureIframeCb, opt_addCfgParam) {
+ goog.net.xpc.logger.info('createPeerIframe()');
var iframeId = this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID];
if (!iframeId) {
@@ -329,7 +429,7 @@ goog.net.xpc.CrossPageChannel.prototype.createPeerIframe = function(
// TODO(user) Opera creates a history-entry when creating an iframe
// programmatically as follows. Find a way which avoids this.
- var iframeElm = goog.dom.createElement('IFRAME');
+ var iframeElm = goog.dom.getDomHelper(parentElm).createElement('IFRAME');
iframeElm.id = iframeElm.name = iframeId;
if (opt_configureIframeCb) {
opt_configureIframeCb(iframeElm);
@@ -337,21 +437,21 @@ goog.net.xpc.CrossPageChannel.prototype.createPeerIframe = function(
iframeElm.style.width = iframeElm.style.height = '100%';
}
+ this.cleanUpIncompleteConnection_();
+ this.peerWindowDeferred_ =
+ new goog.async.Deferred(undefined, this);
var peerUri = this.getPeerUri(opt_addCfgParam);
+ this.peerLoadHandler_.listenOnce(iframeElm, 'load',
+ this.peerWindowDeferred_.callback, false, this.peerWindowDeferred_);
if (goog.userAgent.GECKO || goog.userAgent.WEBKIT) {
// Appending the iframe in a timeout to avoid a weird fastback issue, which
// is present in Safari and Gecko.
- this.deferConnect_ = true;
window.setTimeout(
goog.bind(function() {
- this.deferConnect_ = false;
parentElm.appendChild(iframeElm);
iframeElm.src = peerUri.toString();
goog.net.xpc.logger.info('peer iframe created (' + iframeId + ')');
- if (this.connectDeferred_) {
- this.connect(this.connectCb_);
- }
}, this), 1);
} else {
iframeElm.src = peerUri.toString();
@@ -364,6 +464,22 @@ goog.net.xpc.CrossPageChannel.prototype.createPeerIframe = function(
/**
+ * Clean up after any incomplete attempt to establish and connect to a peer
+ * iframe.
+ * @private
+ */
+goog.net.xpc.CrossPageChannel.prototype.cleanUpIncompleteConnection_ =
+ function() {
+ if (this.peerWindowDeferred_) {
+ this.peerWindowDeferred_.cancel();
+ this.peerWindowDeferred_ = null;
+ }
+ this.deferredDeliveries_.length = 0;
+ this.peerLoadHandler_.removeAll();
+};
+
+
+/**
* Returns the peer URI, with an optional URL parameter for configuring the peer
* window.
*
@@ -390,22 +506,6 @@ goog.net.xpc.CrossPageChannel.prototype.getPeerUri = function(opt_addCfgParam) {
/**
- * Flag whether connecting should be deferred.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.deferConnect_ = false;
-
-
-/**
- * Flag to remember if connect() has been called.
- * @type {boolean}
- * @private
- */
-goog.net.xpc.CrossPageChannel.prototype.connectDeferred_ = false;
-
-
-/**
* Initiates connecting the channel. When this method is called, all the
* information needed to connect the channel has to be available.
*
@@ -416,14 +516,24 @@ goog.net.xpc.CrossPageChannel.prototype.connectDeferred_ = false;
goog.net.xpc.CrossPageChannel.prototype.connect = function(opt_connectCb) {
this.connectCb_ = opt_connectCb || goog.nullFunction;
- if (this.deferConnect_) {
- goog.net.xpc.logger.info('connect() deferred');
- this.connectDeferred_ = true;
- return;
+ // If we know of a peer window whose creation has been requested but is not
+ // complete, peerWindowDeferred_ will be non-null, and we should block on it.
+ if (this.peerWindowDeferred_) {
+ this.peerWindowDeferred_.addCallback(this.continueConnection_);
+ } else {
+ this.continueConnection_();
}
- this.connectDeferred_ = false;
+};
+
- goog.net.xpc.logger.info('connect()');
+/**
+ * Continues the connection process once we're as sure as we can be that the
+ * peer iframe has been created.
+ * @private
+ */
+goog.net.xpc.CrossPageChannel.prototype.continueConnection_ = function() {
+ goog.net.xpc.logger.info('continueConnection_()');
+ this.peerWindowDeferred_ = null;
if (this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID]) {
this.iframeElement_ = this.domHelper_.getElement(
this.cfg_[goog.net.xpc.CfgFields.IFRAME_ID]);
@@ -441,7 +551,7 @@ goog.net.xpc.CrossPageChannel.prototype.connect = function(opt_connectCb) {
// being in an iframe and the channel is meant to be to the containing page
if (!this.peerWindowObject_) {
// throw an error if we are in the top window (== not in an iframe)
- if (window == top) {
+ if (window == window.top) {
throw Error(
"CrossPageChannel: Can't connect, peer window-object not set.");
} else {
@@ -464,36 +574,55 @@ goog.net.xpc.CrossPageChannel.prototype.connect = function(opt_connectCb) {
* Closes the channel.
*/
goog.net.xpc.CrossPageChannel.prototype.close = function() {
- if (!this.isConnected()) return;
+ this.cleanUpIncompleteConnection_();
this.state_ = goog.net.xpc.ChannelStates.CLOSED;
- this.transport_.dispose();
+ goog.dispose(this.transport_);
this.transport_ = null;
this.connectCb_ = null;
- this.connectDeferred_ = false;
- this.deferredDeliveries_.length = 0;
+ goog.dispose(this.connectionDelay_);
+ this.connectionDelay_ = null;
goog.net.xpc.logger.info('Channel "' + this.name + '" closed');
};
/**
+ * Package-private.
* Called by the transport when the channel is connected.
- * @private
+ * @param {number=} opt_delay Delay this number of milliseconds before calling
+ * the connection callback. Usage is discouraged, but can be used to paper
+ * over timing vulnerabilities when there is no alternative.
*/
-goog.net.xpc.CrossPageChannel.prototype.notifyConnected_ = function() {
- if (this.isConnected()) {
+goog.net.xpc.CrossPageChannel.prototype.notifyConnected = function(opt_delay) {
+ if (this.isConnected() ||
+ (this.connectionDelay_ && this.connectionDelay_.isActive())) {
return;
}
this.state_ = goog.net.xpc.ChannelStates.CONNECTED;
goog.net.xpc.logger.info('Channel "' + this.name + '" connected');
- this.connectCb_();
+ goog.dispose(this.connectionDelay_);
+ if (opt_delay) {
+ this.connectionDelay_ =
+ new goog.async.Delay(this.connectCb_, opt_delay);
+ this.connectionDelay_.start();
+ } else {
+ this.connectionDelay_ = null;
+ this.connectCb_();
+ }
};
/**
- * Called by the transport in case of an unrecoverable failure.
+ * Alias for notifyConected, for backward compatibility reasons.
* @private
*/
-goog.net.xpc.CrossPageChannel.prototype.notifyTransportError_ = function() {
+goog.net.xpc.CrossPageChannel.prototype.notifyConnected_ =
+ goog.net.xpc.CrossPageChannel.prototype.notifyConnected;
+
+
+/**
+ * Called by the transport in case of an unrecoverable failure.
+ */
+goog.net.xpc.CrossPageChannel.prototype.notifyTransportError = function() {
goog.net.xpc.logger.info('Transport Error');
this.close();
};
@@ -506,16 +635,7 @@ goog.net.xpc.CrossPageChannel.prototype.send = function(serviceName, payload) {
return;
}
// Check if the peer is still around.
- // NOTE(user): This check is not reliable in IE, where a document in an
- // iframe does not get unloaded when removing the iframe element from the DOM.
- // TODO(user): Find something that works in IE as well.
- // NOTE(user): "!this.peerWindowObject_.closed" evaluates to 'false' in IE9
- // sometimes even though typeof(this.peerWindowObject_.closed) is boolean and
- // this.peerWindowObject_.closed evaluates to 'false'. Casting it to a Boolean
- // results in sane evaluation. When this happens, it's in the inner iframe
- // when querying its parent's 'closed' status. Note that this is a different
- // case than mibuerge@'s note above.
- if (Boolean(this.peerWindowObject_.closed)) {
+ if (!this.isPeerAvailable()) {
goog.net.xpc.logger.severe('Peer has disappeared.');
this.close();
return;
@@ -532,7 +652,11 @@ goog.net.xpc.CrossPageChannel.prototype.send = function(serviceName, payload) {
/**
- * Delivers messages to the appropriate service-handler.
+ * Delivers messages to the appropriate service-handler. Named xpcDeliver to
+ * avoid name conflict with {@code deliver} function in superclass
+ * goog.messaging.AbstractChannel.
+ *
+ * Package private. Do not call from outside goog.net.xpc.
*
* @param {string} serviceName The name of the port.
* @param {string} payload The payload.
@@ -540,19 +664,18 @@ goog.net.xpc.CrossPageChannel.prototype.send = function(serviceName, payload) {
* underlying transport makes that available. If this is specified, and
* the PEER_HOSTNAME parameter was provided, they must match or the message
* will be rejected.
- * @private
*/
-goog.net.xpc.CrossPageChannel.prototype.deliver_ = function(
+goog.net.xpc.CrossPageChannel.prototype.xpcDeliver = function(
serviceName, payload, opt_origin) {
- // This covers the very rare (but producable) case where the inner frame
+ // This check covers the very rare (but producable) case where the inner frame
// becomes ready and sends its setup message while the outer frame is
- // deferring its connect method waiting for the inner frame to be ready.
- // Without it that message can be passed to deliver_, which is unable to
- // process it because the channel is not yet fully configured.
- if (this.connectDeferred_) {
+ // deferring its connect method waiting for the inner frame to be ready. The
+ // resulting deferral ensures the message will not be processed until the
+ // channel is fully configured.
+ if (this.peerWindowDeferred_) {
this.deferredDeliveries_.push(
- goog.bind(this.deliver_, this, serviceName, payload, opt_origin));
+ goog.bind(this.xpcDeliver, this, serviceName, payload, opt_origin));
return;
}
@@ -564,7 +687,7 @@ goog.net.xpc.CrossPageChannel.prototype.deliver_ = function(
}
if (this.isDisposed()) {
- goog.net.xpc.logger.warning('CrossPageChannel::deliver_(): Disposed.');
+ goog.net.xpc.logger.warning('CrossPageChannel::xpcDeliver(): Disposed.');
} else if (!serviceName ||
serviceName == goog.net.xpc.TRANSPORT_SERVICE_) {
this.transport_.transportServiceHandler(payload);
@@ -573,7 +696,8 @@ goog.net.xpc.CrossPageChannel.prototype.deliver_ = function(
if (this.isConnected()) {
this.deliver(this.unescapeServiceName_(serviceName), payload);
} else {
- goog.net.xpc.logger.info('CrossPageChannel::deliver_(): Not connected.');
+ goog.net.xpc.logger.info(
+ 'CrossPageChannel::xpcDeliver(): Not connected.');
}
}
};
@@ -622,9 +746,14 @@ goog.net.xpc.CrossPageChannel.prototype.unescapeServiceName_ = function(name) {
* @return {number} The role of this channel.
*/
goog.net.xpc.CrossPageChannel.prototype.getRole = function() {
- return window.parent == this.peerWindowObject_ ?
- goog.net.xpc.CrossPageChannelRole.INNER :
- goog.net.xpc.CrossPageChannelRole.OUTER;
+ var role = this.cfg_[goog.net.xpc.CfgFields.ROLE];
+ if (role) {
+ return role;
+ } else {
+ return window.parent == this.peerWindowObject_ ?
+ goog.net.xpc.CrossPageChannelRole.INNER :
+ goog.net.xpc.CrossPageChannelRole.OUTER;
+ }
};
@@ -648,14 +777,14 @@ goog.net.xpc.CrossPageChannel.prototype.isMessageOriginAcceptable_ = function(
/** @override */
goog.net.xpc.CrossPageChannel.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
-
this.close();
this.peerWindowObject_ = null;
this.iframeElement_ = null;
- delete goog.net.xpc.channels_[this.name];
- this.deferredDeliveries_.length = 0;
+ delete goog.net.xpc.channels[this.name];
+ goog.dispose(this.peerLoadHandler_);
+ delete this.peerLoadHandler_;
+ goog.base(this, 'disposeInternal');
};
@@ -664,10 +793,7 @@ goog.net.xpc.CrossPageChannel.prototype.disposeInternal = function() {
* @private
*/
goog.net.xpc.CrossPageChannel.disposeAll_ = function() {
- for (var name in goog.net.xpc.channels_) {
- var ch = goog.net.xpc.channels_[name];
- if (ch) {
- ch.dispose();
- }
+ for (var name in goog.net.xpc.channels) {
+ goog.dispose(goog.net.xpc.channels[name]);
}
};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel_test.html b/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel_test.html
index 7b895b8..0c77626 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/crosspagechannel_test.html
@@ -11,10 +11,11 @@ See the COPYING file for details.
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>CrossPageChannel: End-to-End Test</title>
-<script src="../../base.js"></script>
-<script>
+<script type="text/javascript" src="../../base.js"></script>
+<script type="text/javascript">
goog.require('goog.Disposable');
goog.require('goog.Uri');
+ goog.require('goog.async.Deferred');
goog.require('goog.debug.Logger');
goog.require('goog.dom');
goog.require('goog.net.xpc.CrossPageChannel');
@@ -25,18 +26,25 @@ See the COPYING file for details.
</script>
</head>
<body>
-<script>
+<script type="text/javascript">
-var IFRAME_LOAD_WAIT_MS = 2000;
+// Set this to false when working on this test. It needs to be true for
+// automated testing, as some browsers (eg IE8) choke on the large numbers of
+// iframes this test would otherwise leave active.
+var CLEAN_UP_IFRAMES = true;
+
+var IFRAME_LOAD_WAIT_MS = 1000;
var stubs = new goog.testing.PropertyReplacer();
var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(
document.title);
var uniqueId = 0;
var driver;
-
+var canAccessSameDomainIframe = true;
+var accessCheckIframes = [];
function setUpPage() {
- asyncTestCase.stepTimeout = 10 * 1000;
+ // This test is insanely slow on IE8 for some reason.
+ asyncTestCase.stepTimeout = 20 * 1000;
// Show debug log
var debugDiv = goog.dom.getElement('debugDiv');
@@ -47,6 +55,8 @@ function setUpPage() {
msgElm.innerHTML = logRecord.getMessage();
goog.dom.appendChild(debugDiv, msgElm);
});
+ asyncTestCase.waitForAsync('Checking if we can access same domain iframes');
+ checkSameDomainIframeAccess();
}
@@ -61,13 +71,42 @@ function tearDown() {
}
+function checkSameDomainIframeAccess() {
+ accessCheckIframes.push(
+ create1x1Iframe('nonexistant', 'testdata/i_am_non_existant.html'));
+ window.setTimeout(function () {
+ accessCheckIframes.push(
+ create1x1Iframe('existant', 'testdata/access_checker.html'));
+ }, 10);
+}
+
+
+function create1x1Iframe(iframeId, src) {
+ var iframeAccessChecker = goog.dom.createElement('IFRAME');
+ iframeAccessChecker.id = iframeAccessChecker.name = iframeId;
+ iframeAccessChecker.style.width = iframeAccessChecker.style.height = '1px';
+ iframeAccessChecker.src = src;
+ document.body.insertBefore(iframeAccessChecker, document.body.firstChild);
+ return iframeAccessChecker;
+}
+
+
+function sameDomainIframeAccessComplete(canAccess) {
+ canAccessSameDomainIframe = canAccess;
+ for (var i = 0; i < accessCheckIframes.length; i++) {
+ document.body.removeChild(accessCheckIframes[i]);
+ }
+ asyncTestCase.continueTesting();
+}
+
+
function testCreateIframeSpecifyId() {
driver.createPeerIframe('new_iframe');
asyncTestCase.waitForAsync('iframe load');
window.setTimeout(function() {
- asyncTestCase.continueTesting();
driver.checkPeerIframe();
+ asyncTestCase.continueTesting();
}, IFRAME_LOAD_WAIT_MS);
}
@@ -77,44 +116,298 @@ function testCreateIframeRandomId() {
asyncTestCase.waitForAsync('iframe load');
window.setTimeout(function() {
- asyncTestCase.continueTesting();
driver.checkPeerIframe();
+ asyncTestCase.continueTesting();
}, IFRAME_LOAD_WAIT_MS);
}
-function testCreateIframeWithDom() {
- driver.createPeerIframe(goog.dom.getDomHelper());
+// The following batch of tests:
+// * Establishes a peer iframe
+// * Connects an XPC channel between the frames
+// * From the connection callback in each frame, sends an 'echo' request, and
+// expects a 'response' response.
+// * Reconnects the inner frame, sends an 'echo', expects a 'response'.
+// * Optionally, reconnects the outer frame, sends an 'echo', expects a
+// 'response'.
+// * Optionally, reconnects the inner frame, but first reconfigures it to the
+// alternate protocol version, simulating an inner frame navigation that
+// picks up a new/old version.
+//
+// Every valid combination of protocol versions is tested, with both single and
+// double ended handshakes. Two timing scenarios are tested per combination,
+// which is what the 'reverse' parameter distinguishes.
+//
+// Where single sided handshake is in use, reconnection by the outer frame is
+// not supported, and therefore is not tested.
+//
+// The only known issue migrating to V2 is that once two V2 peers have
+// connected, replacing either peer with a V1 peer will not work. Upgrading V1
+// peers to v2 is supported, as is replacing the only v2 peer in a connection
+// with a v1.
+
+
+function testLifeCycle_v1_v1() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- asyncTestCase.continueTesting();
- driver.checkPeerIframe();
- }, IFRAME_LOAD_WAIT_MS);
+
+function testLifeCycle_v1_v1_rev() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
}
-function testCreateIframeAsynchronousConnect() {
- driver.createPeerIframe('new_iframe');
+function testLifeCycle_v1_v1_onesided() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
- asyncTestCase.waitForAsync('iframe load');
- window.setTimeout(function() {
- driver.connect();
- }, IFRAME_LOAD_WAIT_MS);
+
+function testLifeCycle_v1_v1_onesided_rev() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
}
-function testCreateIframeSynchronousConnect() {
- driver.createPeerIframe('new_iframe');
- driver.connect();
+function testLifeCycle_v1_v2() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v1_v2_rev() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function testLifeCycle_v1_v2_onesided() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v1_v2_onesided_rev() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function testLifeCycle_v2_v1() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v2_v1_rev() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function testLifeCycle_v2_v1_onesided() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v2_v1_onesided_rev() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ true /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function testLifeCycle_v2_v2() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ false /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v2_v2_rev() {
+ checkLifeCycle(
+ false /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* outerFrameReconnectSupported */,
+ false /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function testLifeCycle_v2_v2_onesided() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ false /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
+function testLifeCycle_v2_v2_onesided_rev() {
+ checkLifeCycle(
+ true /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* outerFrameReconnectSupported */,
+ false /* innerFrameMigrationSupported */,
+ true /* reverse */);
+}
+
+
+function checkLifeCycle(oneSidedHandshake, innerProtocolVersion,
+ outerProtocolVersion, outerFrameReconnectSupported,
+ innerFrameMigrationSupported, reverse) {
+ driver.createPeerIframe('new_iframe', oneSidedHandshake,
+ innerProtocolVersion, outerProtocolVersion);
+ driver.connect(true /* fullLifeCycleTest */, outerFrameReconnectSupported,
+ innerFrameMigrationSupported, reverse);
}
-function testExistingIframeConnect() {
- driver.createChannel('test_iframe');
- driver.connect();
+function testConnectMismatchedNames_v1_v1() {
+ checkConnectMismatchedNames(
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* reverse */);
}
+
+function testConnectMismatchedNames_v1_v1_rev() {
+ checkConnectMismatchedNames(
+ 1 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v1_v2() {
+ checkConnectMismatchedNames(
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v1_v2_rev() {
+ checkConnectMismatchedNames(
+ 1 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v2_v1() {
+ checkConnectMismatchedNames(
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ false /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v2_v1_rev() {
+ checkConnectMismatchedNames(
+ 2 /* innerProtocolVersion */,
+ 1 /* outerProtocolVersion */,
+ true /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v2_v2() {
+ checkConnectMismatchedNames(
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ false /* reverse */);
+}
+
+
+function testConnectMismatchedNames_v2_v2_rev() {
+ checkConnectMismatchedNames(
+ 2 /* innerProtocolVersion */,
+ 2 /* outerProtocolVersion */,
+ true /* reverse */);
+}
+
+
+function checkConnectMismatchedNames(innerProtocolVersion,
+ outerProtocolVersion, reverse) {
+ driver.createPeerIframe('new_iframe', false /* oneSidedHandshake */, innerProtocolVersion,
+ outerProtocolVersion, true /* opt_randomChannelNames */);
+ driver.connect(false /* fullLifeCycleTest */,
+ false /* outerFrameReconnectSupported */,
+ false /* innerFrameMigrationSupported */,
+ false /* reverse */);
+}
+
+
function testEscapeServiceName() {
var escape = goog.net.xpc.CrossPageChannel.prototype.escapeServiceName_;
assertEquals('Shouldn\'t escape alphanumeric name',
@@ -130,34 +423,40 @@ function testEscapeServiceName() {
assertEquals('Should not escape s%tp', 's%25tp', escape('s%tp'));
}
+
function testSameDomainCheck_noMessageOrigin() {
var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
assertTrue(channel.isMessageOriginAcceptable_(undefined));
}
+
function testSameDomainCheck_noPeerHostname() {
var channel = new goog.net.xpc.CrossPageChannel({});
assertTrue(channel.isMessageOriginAcceptable_('http://foo.com'));
}
+
function testSameDomainCheck_unconfigured() {
var channel = new goog.net.xpc.CrossPageChannel({});
assertTrue(channel.isMessageOriginAcceptable_(undefined));
}
+
function testSameDomainCheck_originsMatch() {
var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
assertTrue(channel.isMessageOriginAcceptable_('http://foo.com'));
}
+
function testSameDomainCheck_originsMismatch() {
var channel = new goog.net.xpc.CrossPageChannel(goog.object.create(
goog.net.xpc.CfgFields.PEER_HOSTNAME, 'http://foo.com'));
assertFalse(channel.isMessageOriginAcceptable_('http://nasty.com'));
}
+
function testUnescapeServiceName() {
var unescape = goog.net.xpc.CrossPageChannel.prototype.unescapeServiceName_;
assertEquals('Shouldn\'t modify alphanumeric name',
@@ -175,6 +474,18 @@ function testUnescapeServiceName() {
/**
+ * Tests the case where the channel is disposed before it is fully connected.
+ */
+function testDisposeBeforeConnect() {
+ asyncTestCase.waitForAsync('Checking disposal before connection.')
+ driver.createPeerIframe('new_iframe', false /* oneSidedHandshake */,
+ 2 /* innerProtocolVersion */, 2 /* outerProtocolVersion */,
+ true /* opt_randomChannelNames */);
+ driver.connectOuterAndDispose();
+}
+
+
+/**
* Driver for the tests for CrossPageChannel.
*
* @constructor
@@ -191,36 +502,79 @@ Driver = function() {
this.iframe_ = null;
/**
- * The ID of the peer iframe.
- * @type {string}
+ * The channel to use.
+ * @type {goog.net.xpc.CrossPageChannel}
* @private
*/
- this.iframeId_ = 'test_iframe';
+ this.channel_ = null;
/**
- * Channel configuration object.
+ * Outer frame configuration object.
* @type {Object}
* @private
*/
- this.cfg_ = null;
+ this.outerFrameCfg_ = null;
/**
- * The channel to use.
- * @type {goog.net.xpc.CrossPageChannel}
+ * The initial name of the outer channel.
+ * @type {?string}
* @private
*/
- this.channel_ = null;
+ this.initialOuterChannelName_ = null;
+
+ /**
+ * Inner frame configuration object.
+ * @type {Object}
+ * @private
+ */
+ this.innerFrameCfg_ = null;
+
+ /**
+ * The contents of the payload of the 'echo' request sent by the inner frame.
+ * @type {?string}
+ * @private
+ */
+ this.innerFrameEchoPayload_ = null;
+
+ /**
+ * The contents of the payload of the 'echo' request sent by the outer frame.
+ * @type {?string}
+ * @private
+ */
+ this.outerFrameEchoPayload_ = null;
+
+ /**
+ * A deferred which fires when the inner frame receives its echo response.
+ * @type {goog.async.Deferred}
+ * @private
+ */
+ this.innerFrameResponseReceived_ = new goog.async.Deferred();
+
+ /**
+ * A deferred which fires when the outer frame receives its echo response.
+ * @type {goog.async.Deferred}
+ * @private
+ */
+ this.outerFrameResponseReceived_ = new goog.async.Deferred();
+
};
goog.inherits(Driver, goog.Disposable);
/** @override */
Driver.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
-
- if (this.channel_) {
- this.channel_.dispose();
+ // Required to make this test perform acceptably (and pass) on slow browsers,
+ // esp IE8.
+ if (CLEAN_UP_IFRAMES) {
+ goog.dom.removeNode(this.iframe_);
+ delete this.iframe_;
}
+ goog.dispose(this.channel_);
+ this.innerFrameResponseReceived_.cancel();
+ this.innerFrameResponseReceived_ = null;
+ this.outerFrameResponseReceived_.cancel();
+ this.outerFrameResponseReceived_ = null;
+ goog.base(this, 'disposeInternal');
};
@@ -230,27 +584,44 @@ Driver.prototype.disposeInternal = function() {
* @private
*/
Driver.prototype.getInnerPeer_ = function() {
- return window.frames[this.iframeId_];
+ return this.iframe_.contentWindow;
};
/**
- * Creates the channel.
+ * Sets up the configuration objects for the inner and outer frames.
* @param {string=} opt_iframeId If present, the ID of the iframe to use,
* otherwise, tells the channel to generate an iframe ID.
- * @param {goog.dom.DomHelper=} opt_domHelper The optional dom helper to use
- * for determining which window to use.
+ * @param {boolean=} opt_oneSidedHandshake Whether the one sided handshake
+ * config option should be set.
+ * @param {string=} opt_channelName The name of the channel to use, or null
+ * to generate one.
+ * @param {number=} opt_innerProtocolVersion The native transport protocol
+ * version used in the inner iframe.
+ * @param {number=} opt_outerProtocolVersion The native transport protocol
+ * version used in the outer iframe.
+ * @param {boolean=} randomChannelNames Whether the different ends of the
+ * channel should be allowed to pick differing, random names.
+ * @return {string} The name of the created channel.
+ * @private
*/
-Driver.prototype.createChannel = function(opt_iframeId, opt_domHelper) {
+Driver.prototype.setConfiguration_ = function(opt_iframeId,
+ opt_oneSidedHandshake, opt_channelName, opt_innerProtocolVersion,
+ opt_outerProtocolVersion, opt_randomChannelNames) {
var cfg = {};
if (opt_iframeId) {
- this.iframeId_ = opt_iframeId;
cfg[goog.net.xpc.CfgFields.IFRAME_ID] = opt_iframeId;
}
cfg[goog.net.xpc.CfgFields.PEER_URI] = 'testdata/inner_peer.html';
- cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = 'test_channel' + uniqueId++;
+ if (!opt_randomChannelNames) {
+ var channelName = opt_channelName || 'test_channel' + uniqueId++;
+ cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = channelName;
+ }
cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] = 'does-not-exist.html';
cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] = 'does-not-exist.html';
+ cfg[goog.net.xpc.CfgFields.ONE_SIDED_HANDSHAKE] = !!opt_oneSidedHandshake;
+ cfg[goog.net.xpc.CfgFields.NATIVE_TRANSPORT_PROTOCOL_VERSION] =
+ opt_outerProtocolVersion;
function resolveUri(fieldName) {
cfg[fieldName] =
goog.Uri.resolve(window.location.href, cfg[fieldName]).toString();
@@ -258,10 +629,60 @@ Driver.prototype.createChannel = function(opt_iframeId, opt_domHelper) {
resolveUri(goog.net.xpc.CfgFields.PEER_URI);
resolveUri(goog.net.xpc.CfgFields.LOCAL_POLL_URI);
resolveUri(goog.net.xpc.CfgFields.PEER_POLL_URI);
+ this.outerFrameCfg_ = cfg;
+ this.innerFrameCfg_ = goog.object.clone(cfg);
+ this.innerFrameCfg_[
+ goog.net.xpc.CfgFields.NATIVE_TRANSPORT_PROTOCOL_VERSION] =
+ opt_innerProtocolVersion;
+};
- this.channel_ = new goog.net.xpc.CrossPageChannel(cfg, opt_domHelper);
- this.channel_.registerService('msg', goog.bind(this.msgHandler_, this));
- this.cfg_ = cfg;
+
+/**
+ * Creates an outer frame channel object.
+ * @private
+ */
+Driver.prototype.createChannel_ = function() {
+ if (this.channel_) {
+ this.channel_.dispose();
+ }
+ this.channel_ = new goog.net.xpc.CrossPageChannel(this.outerFrameCfg_);
+ this.channel_.registerService('echo',
+ goog.bind(this.echoHandler_, this));
+ this.channel_.registerService('response',
+ goog.bind(this.responseHandler_, this));
+
+ return this.channel_.name;
+};
+
+
+/**
+ * Checks the names of the inner and outer frames meet expectations.
+ * @private
+ */
+Driver.prototype.checkChannelNames_ = function() {
+ var outerName = this.channel_.name;
+ var innerName = this.getInnerPeer_().channel.name;
+ var configName = this.innerFrameCfg_[goog.net.xpc.CfgFields.CHANNEL_NAME]
+ || null;
+
+ // The outer channel never changes its name.
+ assertEquals(this.initialOuterChannelName_, outerName);
+ // The name should be as configured, if it was configured.
+ if (configName) {
+ assertEquals(configName, innerName);
+ }
+ // The names of both ends of the channel should match.
+ assertEquals(innerName, outerName);
+ G_testRunner.log('Channel name: ' + innerName);
+};
+
+
+/**
+ * Returns the configuration of the xpc.
+ * @return {?Object} The configuration of the xpc.
+ */
+Driver.prototype.getInnerFrameConfiguration = function() {
+ return this.innerFrameCfg_;
};
@@ -269,10 +690,20 @@ Driver.prototype.createChannel = function(opt_iframeId, opt_domHelper) {
* Creates the peer iframe.
* @param {string=} opt_iframeId If present, the ID of the iframe to create,
* otherwise, generates an iframe ID.
- * @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for
- * finding the elements in the iframe.
+ * @param {boolean=} opt_oneSidedHandshake Whether a one sided handshake is
+ * specified.
+ * @param {number=} opt_innerProtocolVersion The native transport protocol
+ * version used in the inner iframe.
+ * @param {number=} opt_outerProtocolVersion The native transport protocol
+ * version used in the outer iframe.
+ * @param {boolean=} opt_randomChannelNames Whether the ends of the channel
+ * should be allowed to pick differing, random names.
+ * @return {!Array.<string>} The id of the created iframe and the name of the
+ * created channel.
*/
-Driver.prototype.createPeerIframe = function(opt_iframeId, opt_domHelper) {
+Driver.prototype.createPeerIframe = function(opt_iframeId,
+ opt_oneSidedHandshake, opt_innerProtocolVersion, opt_outerProtocolVersion,
+ opt_randomChannelNames) {
var expectedIframeId;
if (opt_iframeId) {
@@ -287,11 +718,14 @@ Driver.prototype.createPeerIframe = function(opt_iframeId, opt_domHelper) {
assertNull('element[id=' + expectedIframeId + '] exists',
goog.dom.getElement(expectedIframeId));
- this.createChannel(opt_iframeId, opt_domHelper);
+ this.setConfiguration_(opt_iframeId, opt_oneSidedHandshake,
+ undefined /* opt_channelName */, opt_innerProtocolVersion,
+ opt_outerProtocolVersion, opt_randomChannelNames);
+ var channelName = this.createChannel_();
+ this.initialOuterChannelName_ = channelName;
this.iframe_ = this.channel_.createPeerIframe(document.body);
assertEquals(expectedIframeId, this.iframe_.id);
- this.iframeId_ = expectedIframeId;
};
@@ -299,7 +733,7 @@ Driver.prototype.createPeerIframe = function(opt_iframeId, opt_domHelper) {
* Checks if the peer iframe has been created.
*/
Driver.prototype.checkPeerIframe = function() {
- assertNotNull(goog.dom.getElement(this.iframeId_));
+ assertNotNull(this.iframe_);
var peer = this.getInnerPeer_();
assertNotNull(peer);
assertNotNull(peer.document);
@@ -309,112 +743,282 @@ Driver.prototype.checkPeerIframe = function() {
/**
* Starts the connection. The connection happens asynchronously.
*/
-Driver.prototype.connect = function() {
- // TODO(user): Get tests to pass for all transports
+Driver.prototype.connect = function(fullLifeCycleTest,
+ outerFrameReconnectSupported, innerFrameMigrationSupported, reverse) {
if (!this.isTransportTestable_()) {
asyncTestCase.continueTesting();
return;
}
- if (this.iframe_) {
- // When we create an iframe, we send the config
- // and it connects itself.
- this.childConnected_();
+ asyncTestCase.waitForAsync('parent and child connect');
+
+ // Set the criteria for the initial handshake portion of the test.
+ this.reinitializeDeferreds_();
+ this.innerFrameResponseReceived_.awaitDeferred(
+ this.outerFrameResponseReceived_);
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.checkChannelNames_, this));
+
+ if (fullLifeCycleTest) {
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.testReconnects_, this,
+ outerFrameReconnectSupported, innerFrameMigrationSupported));
} else {
- asyncTestCase.waitForAsync('parent and child connect');
- var peer = this.getInnerPeer_();
- peer.instantiateChannel(this.cfg_);
- peer.connectChannel(goog.bind(this.childConnected_, this));
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(asyncTestCase.continueTesting, asyncTestCase));
+ }
+
+ this.continueConnect_(reverse);
+};
+
+
+Driver.prototype.continueConnect_ = function(reverse) {
+ // Wait until the peer is fully established. Establishment is sometimes very
+ // slow indeed, especially on virtual machines, so a fixed timeout is not
+ // suitable. This wait is required because we want to take precise control
+ // of the channel startup timing, and shouldn't be needed in production use,
+ // where the inner frame's channel is typically not started by a DOM call as
+ // it is here.
+ if (!this.getInnerPeer_() || !this.getInnerPeer_().instantiateChannel) {
+ window.setTimeout(goog.bind(this.continueConnect_, this, reverse), 100);
+ return;
}
- this.channel_.connect(goog.bind(this.parentConnected_, this));
+ var connectFromOuterFrame = goog.bind(this.channel_.connect, this.channel_,
+ goog.bind(this.outerFrameConnected_, this));
+ var innerConfig = this.innerFrameCfg_;
+ var connectFromInnerFrame = goog.bind(this.getInnerPeer_().instantiateChannel,
+ this.getInnerPeer_(), innerConfig);
+
+ // Take control of the timing and reverse of each frame's first SETUP call. If
+ // these happen to fire right on top of each other, that tends to mask
+ // problems that reliably occur when there is a short delay.
+ window.setTimeout(connectFromOuterFrame, reverse ? 1 : 10);
+ window.setTimeout(connectFromInnerFrame, reverse ? 10 : 1);
};
/**
- * Determines if the transport type for the channel is testable.
- * Some transports are misusing global state or making other
- * assumptions that cause connections to fail.
- * @return {boolean} Whether the transport is testable.
+ * Called by the outer frame connection callback.
* @private
*/
-Driver.prototype.isTransportTestable_ = function() {
- var testable = true;
+Driver.prototype.outerFrameConnected_ = function() {
+ var payload = this.outerFrameEchoPayload_ =
+ goog.net.xpc.getRandomString(10);
+ this.channel_.send('echo', payload);
+};
- var transportType = this.channel_.determineTransportType_();
- switch (transportType) {
- case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
- case goog.net.xpc.TransportTypes.IFRAME_RELAY:
- case goog.net.xpc.TransportTypes.IFRAME_POLLING:
- case goog.net.xpc.TransportTypes.FLASH:
- case goog.net.xpc.TransportTypes.NIX:
- testable = false;
- break;
- }
- return testable;
+/**
+ * Called by the inner frame connection callback.
+ */
+Driver.prototype.innerFrameConnected = function() {
+ var payload = this.innerFrameEchoPayload_ =
+ goog.net.xpc.getRandomString(10);
+ this.getInnerPeer_().sendEcho(payload);
+};
+
+
+/**
+ * The handler function for incoming echo requests.
+ * @param {string} payload The message payload.
+ * @private
+ */
+Driver.prototype.echoHandler_ = function(payload) {
+ assertTrue('outer frame should be connected', this.channel_.isConnected());
+ var peer = this.getInnerPeer_();
+ assertTrue('child should be connected', peer.isConnected());
+ this.channel_.send('response', payload);
};
/**
- * Callback for the parent connection.
+ * The handler function for incoming echo responses.
+ * @param {string} payload The message payload.
* @private
*/
-Driver.prototype.parentConnected_ = function() {
+Driver.prototype.responseHandler_ = function(payload) {
+ assertTrue('outer frame should be connected', this.channel_.isConnected());
var peer = this.getInnerPeer_();
- if (peer.isConnected()) {
- asyncTestCase.waitForAsync('child echo');
+ assertTrue('child should be connected', peer.isConnected());
+ assertEquals(this.outerFrameEchoPayload_, payload);
+ this.outerFrameResponseReceived_.callback(true);
+};
+
+
+/**
+ * The handler function for incoming echo replies.
+ * @param {string} payload The message payload.
+ * @private
+ */
+Driver.prototype.innerFrameGotResponse = function(payload) {
+ assertTrue('outer frame should be connected', this.channel_.isConnected());
+ var peer = this.getInnerPeer_();
+ assertTrue('child should be connected', peer.isConnected());
+ assertEquals(this.innerFrameEchoPayload_, payload);
+ this.innerFrameResponseReceived_.callback(true);
+};
+
+
+/**
+ * The second phase of the standard test, where reconnections of both the inner
+ * and outer frames are performed.
+ * @param {boolean} outerFrameReconnectSupported Whether outer frame reconnects
+ * are supported, and should be tested.
+ * @private
+ */
+Driver.prototype.testReconnects_ = function(outerFrameReconnectSupported,
+ innerFrameMigrationSupported) {
+ G_testRunner.log('Performing inner frame reconnect');
+ this.reinitializeDeferreds_();
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.checkChannelNames_, this));
+
+ if (outerFrameReconnectSupported) {
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.performOuterFrameReconnect_, this,
+ innerFrameMigrationSupported));
+ } else if (innerFrameMigrationSupported) {
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.migrateInnerFrame_, this));
} else {
- asyncTestCase.waitForAsync('child connect');
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(asyncTestCase.continueTesting, asyncTestCase));
}
- this.channel_.send('echo', 'hello')
+ this.performInnerFrameReconnect_();
};
/**
- * Callback for the child connection.
+ * Initializes the deferreds and clears the echo payloads, ready for another
+ * sub-test.
* @private
*/
-Driver.prototype.childConnected_ = function() {
- if (this.channel_.isConnected()) {
- asyncTestCase.waitForAsync('child echo');
+Driver.prototype.reinitializeDeferreds_ = function() {
+ this.innerFrameEchoPayload_ = null;
+ this.outerFrameEchoPayload_ = null;
+ this.innerFrameResponseReceived_.cancel();
+ this.innerFrameResponseReceived_ = new goog.async.Deferred();
+ this.outerFrameResponseReceived_.cancel();
+ this.outerFrameResponseReceived_ = new goog.async.Deferred();
+};
+
+
+/**
+ * Get the inner frame to reconnect, and repeat the echo test.
+ * @private
+ */
+Driver.prototype.performInnerFrameReconnect_ = function() {
+ var peer = this.getInnerPeer_();
+ peer.instantiateChannel(this.innerFrameCfg_);
+};
+
+
+/**
+ * Get the outer frame to reconnect, and repeat the echo test.
+ * @private
+ */
+Driver.prototype.performOuterFrameReconnect_ = function(
+ innerFrameMigrationSupported) {
+ G_testRunner.log('Reconnecting outer frame');
+ this.reinitializeDeferreds_();
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.checkChannelNames_, this));
+ if (innerFrameMigrationSupported) {
+ this.outerFrameResponseReceived_.addCallback(
+ goog.bind(this.migrateInnerFrame_, this));
} else {
- asyncTestCase.waitForAsync('parent connect');
+ this.outerFrameResponseReceived_.addCallback(
+ goog.bind(asyncTestCase.continueTesting, asyncTestCase));
}
+ this.createChannel_();
+ this.channel_.connect(goog.bind(this.outerFrameConnected_, this));
};
/**
- * The handler function for incoming msg requests.
- * @param {string} payload The message payload.
+ * Migrate the inner frame to the alternate protocol version and reconnect it.
* @private
*/
-Driver.prototype.msgHandler_ = function(payload) {
- assertTrue('parent should be connected', this.channel_.isConnected());
- var peer = this.getInnerPeer_();
- assertTrue('child should be connected', peer.isConnected());
- assertEquals('hello', payload);
+Driver.prototype.migrateInnerFrame_ = function() {
+ G_testRunner.log('Migrating inner frame');
+ this.reinitializeDeferreds_();
+ var innerFrameProtoVersion = this.innerFrameCfg_[
+ goog.net.xpc.CfgFields.NATIVE_TRANSPORT_PROTOCOL_VERSION];
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(this.checkChannelNames_, this));
+ this.innerFrameResponseReceived_.addCallback(
+ goog.bind(asyncTestCase.continueTesting, asyncTestCase));
+ this.innerFrameCfg_[
+ goog.net.xpc.CfgFields.NATIVE_TRANSPORT_PROTOCOL_VERSION] =
+ innerFrameProtoVersion == 1 ? 2 : 1;
+ this.performInnerFrameReconnect_();
+};
- asyncTestCase.continueTesting();
+
+/**
+ * Determines if the transport type for the channel is testable.
+ * Some transports are misusing global state or making other
+ * assumptions that cause connections to fail.
+ * @return {boolean} Whether the transport is testable.
+ * @private
+ */
+Driver.prototype.isTransportTestable_ = function() {
+ var testable = false;
+
+ var transportType = this.channel_.determineTransportType_();
+ switch (transportType) {
+ case goog.net.xpc.TransportTypes.IFRAME_RELAY:
+ case goog.net.xpc.TransportTypes.IFRAME_POLLING:
+ testable = canAccessSameDomainIframe;
+ break;
+ case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
+ case goog.net.xpc.TransportTypes.FLASH:
+ case goog.net.xpc.TransportTypes.NIX:
+ testable = true;
+ break;
+ }
+
+ return testable;
+};
+
+
+/**
+ * Connect the outer channel but not the inner one. Wait a short time, then
+ * dispose the outer channel and make sure it was torn down properly.
+ */
+Driver.prototype.connectOuterAndDispose = function() {
+ this.channel_.connect();
+ window.setTimeout(goog.bind(this.disposeAndCheck_, this), 2000);
};
+/**
+ * Dispose the cross-page channel. Check that the transport was also
+ * disposed, and allow to run briefly to make sure no timers which will cause
+ * failures are still running.
+ */
+Driver.prototype.disposeAndCheck_ = function() {
+ assertFalse(this.channel_.isConnected());
+ var transport = this.channel_.transport_;
+ this.channel_.dispose();
+ assertNull(this.channel_.transport_);
+ assertTrue(this.channel_.isDisposed());
+ assertTrue(transport.isDisposed());
+
+ // Let any errors caused by erroneous retries happen.
+ window.setTimeout(goog.bind(asyncTestCase.continueTesting, asyncTestCase),
+ 2000);
+};
+
</script>
<!-- Debug box. -->
-<div style="position:absolute; float: right; top: 10px; right: 10px">
+<div style="position:absolute; float: right; top: 10px; right: 10px; width: 500px">
Debug [<a href="#" onclick="document.getElementById('debugDiv').innerHTML = '';">clear</a>]: <br/>
-<div id="debugDiv" style="border: 1px #000000 solid; font-size:xx-small"></div>
+<div id="debugDiv" style="border: 1px #000000 solid; font-size:xx-small; background: #fff;"></div>
</div>
-<!--
-Setup inner peer. This must be done in the <body>, so that the inner peer iframe
-blocks the onload event in this window until it is fully loaded. The JsUnit
-tests will execute after the onload event fires.
--->
-<iframe name=test_iframe id=test_iframe src=testdata/inner_peer.html width=300 height=250>
-</iframe>
-
</body>
</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/frameelementmethodtransport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/frameelementmethodtransport.js
index f99ed6f..0b601dd 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/frameelementmethodtransport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/frameelementmethodtransport.js
@@ -78,9 +78,10 @@ goog.inherits(goog.net.xpc.FrameElementMethodTransport, goog.net.xpc.Transport);
* The transport type.
* @type {number}
* @protected
+ * @override
*/
goog.net.xpc.FrameElementMethodTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD;
+ goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD;
/**
@@ -110,11 +111,12 @@ goog.net.xpc.FrameElementMethodTransport.outgoing_ = null;
/**
* Connect this transport.
+ * @override
*/
goog.net.xpc.FrameElementMethodTransport.prototype.connect = function() {
if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER) {
// get shortcut to iframe-element
- this.iframeElm_ = this.channel_.iframeElement_;
+ this.iframeElm_ = this.channel_.getIframeElement();
// add the gateway function to the iframe-element
// (to be called by the peer)
@@ -157,7 +159,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.attemptSetup_ = function() {
// notify outer frame
this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
// notify channel that the transport is ready
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
}
}
catch (e) {
@@ -177,6 +179,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.attemptSetup_ = function() {
/**
* Handles transport service messages.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.FrameElementMethodTransport.prototype.transportServiceHandler =
function(payload) {
@@ -185,7 +188,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.transportServiceHandler =
// get a reference to the gateway function
this.outgoing_ = this.iframeElm_['XPC_toOuter']['XPC_toInner'];
// notify the channel we're ready
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
} else {
throw Error('Got unexpected transport message.');
}
@@ -202,7 +205,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.transportServiceHandler =
goog.net.xpc.FrameElementMethodTransport.prototype.incoming_ =
function(serviceName, payload) {
if (!this.recursive_ && this.queue_.length == 0) {
- this.channel_.deliver_(serviceName, payload);
+ this.channel_.xpcDeliver(serviceName, payload);
}
else {
this.queue_.push({serviceName: serviceName, payload: payload});
@@ -221,7 +224,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.deliverQueued_ =
function() {
while (this.queue_.length) {
var msg = this.queue_.shift();
- this.channel_.deliver_(msg.serviceName, msg.payload);
+ this.channel_.xpcDeliver(msg.serviceName, msg.payload);
}
};
@@ -231,6 +234,7 @@ goog.net.xpc.FrameElementMethodTransport.prototype.deliverQueued_ =
* @param {string} service The name off the service the message is to be
* delivered to.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.FrameElementMethodTransport.prototype.send =
function(service, payload) {
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport.js
index aaa96ae..9f52c44 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport.js
@@ -60,14 +60,16 @@ goog.net.xpc.IframePollingTransport = function(channel, opt_domHelper) {
* @type {string}
* @private
*/
- this.sendUri_ = this.channel_.cfg_[goog.net.xpc.CfgFields.PEER_POLL_URI];
+ this.sendUri_ =
+ this.channel_.getConfig()[goog.net.xpc.CfgFields.PEER_POLL_URI];
/**
* The URI which is polled for incoming messages.
* @type {string}
* @private
*/
- this.rcvUri_ = this.channel_.cfg_[goog.net.xpc.CfgFields.LOCAL_POLL_URI];
+ this.rcvUri_ =
+ this.channel_.getConfig()[goog.net.xpc.CfgFields.LOCAL_POLL_URI];
/**
* The queue to hold messages which can't be sent immediately.
@@ -80,12 +82,23 @@ goog.inherits(goog.net.xpc.IframePollingTransport, goog.net.xpc.Transport);
/**
+ * The number of times the inner frame will check for evidence of the outer
+ * frame before it tries its reconnection sequence. These occur at 100ms
+ * intervals, making this an effective max waiting period of 500ms.
+ * @type {number}
+ * @private
+ */
+goog.net.xpc.IframePollingTransport.prototype.pollsBeforeReconnect_ = 5;
+
+
+/**
* The transport type.
* @type {number}
* @protected
+ * @override
*/
goog.net.xpc.IframePollingTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.IFRAME_POLLING;
+ goog.net.xpc.TransportTypes.IFRAME_POLLING;
/**
@@ -113,6 +126,14 @@ goog.net.xpc.IframePollingTransport.prototype.initialized_ = false;
/**
+ * Reconnection iframe created by inner peer.
+ * @type {Element}
+ * @private
+ */
+goog.net.xpc.IframePollingTransport.prototype.reconnectFrame_ = null;
+
+
+/**
* The string used to prefix all iframe names and IDs.
* @type {string}
*/
@@ -142,14 +163,55 @@ goog.net.xpc.IframePollingTransport.prototype.getAckFrameName_ = function() {
/**
+ * Determines whether the channel is still available. The channel is
+ * unavailable if the transport was disposed or the peer is no longer
+ * available.
+ * @return {boolean} Whether the channel is available.
+ */
+goog.net.xpc.IframePollingTransport.prototype.isChannelAvailable = function() {
+ return !this.isDisposed() && this.channel_.isPeerAvailable();
+};
+
+
+/**
+ * Safely retrieves the frames from the peer window. If an error is thrown
+ * (e.g. the window is closing) an empty frame object is returned.
+ * @return {!Object.<!Window>} The frames from the peer window.
+ * @private
+ */
+goog.net.xpc.IframePollingTransport.prototype.getPeerFrames_ = function() {
+ try {
+ if (this.isChannelAvailable()) {
+ return this.channel_.getPeerWindowObject().frames || {};
+ }
+ } catch (e) {
+ // An error may be thrown if the window is closing.
+ goog.net.xpc.logger.fine('error retrieving peer frames');
+ }
+ return {};
+};
+
+
+/**
+ * Safely retrieves the peer frame with the specified name.
+ * @param {string} frameName The name of the peer frame to retrieve.
+ * @return {Window} The peer frame with the specified name.
+ * @private
+ */
+goog.net.xpc.IframePollingTransport.prototype.getPeerFrame_ = function(
+ frameName) {
+ return this.getPeerFrames_()[frameName];
+};
+
+
+/**
* Connects this transport.
+ * @override
*/
goog.net.xpc.IframePollingTransport.prototype.connect = function() {
- if (this.isDisposed()) {
- // We should stop polling for connecting if the transport has been
- // disposed (i.e., the channel has been closed), otherwise
- // outerPeerReconnect_() may throw exceptions when it refers
- // channel_.peerWindowObject_ which is reset to null by channel_.close().
+ if (!this.isChannelAvailable()) {
+ // When the channel is unavailable there is no peer to poll so stop trying
+ // to connect.
return;
}
@@ -211,16 +273,25 @@ goog.net.xpc.IframePollingTransport.prototype.constructSenderFrame_ =
* of bfcached iframes.
* @private
*/
-goog.net.xpc.IframePollingTransport.prototype.innerPeerReconnect_ = function() {
- goog.net.xpc.logger.finest('innerPeerReconnect called');
+goog.net.xpc.IframePollingTransport.prototype.maybeInnerPeerReconnect_ =
+ function() {
+ // Reconnection has been found to not function on some browsers (eg IE7), so
+ // it's important that the mechanism only be triggered as a last resort. As
+ // such, we poll a number of times to find the outer iframe before triggering
+ // it.
+ if (this.reconnectFrame_ || this.pollsBeforeReconnect_-- > 0) {
+ return;
+ }
+
+ goog.net.xpc.logger.finest('Inner peer reconnect triggered.');
this.channel_.name = goog.net.xpc.getRandomString(10);
goog.net.xpc.logger.finest('switching channels: ' + this.channel_.name);
this.deconstructSenderFrames_();
this.initialized_ = false;
// Communicate new channel name to outer peer.
this.reconnectFrame_ = this.constructSenderFrame_(
- goog.net.xpc.IframePollingTransport.IFRAME_PREFIX +
- '_reconnect_' + this.channel_.name);
+ goog.net.xpc.IframePollingTransport.IFRAME_PREFIX +
+ '_reconnect_' + this.channel_.name);
};
@@ -233,7 +304,7 @@ goog.net.xpc.IframePollingTransport.prototype.innerPeerReconnect_ = function() {
*/
goog.net.xpc.IframePollingTransport.prototype.outerPeerReconnect_ = function() {
goog.net.xpc.logger.finest('outerPeerReconnect called');
- var frames = this.channel_.peerWindowObject_.frames;
+ var frames = this.getPeerFrames_();
var length = frames.length;
for (var i = 0; i < length; i++) {
var frameName;
@@ -296,13 +367,13 @@ goog.net.xpc.IframePollingTransport.prototype.checkForeignFramesReady_ =
this.isRcvFrameReady_(this.getAckFrameName_()))) {
goog.net.xpc.logger.finest('foreign frames not (yet) present');
- if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.INNER &&
- !this.reconnectFrame_) {
- // The inner peer should always have its receiving frames ready.
- // It is safe to assume the channel name has fallen out of sync
- // (which happens with bfcached frames). Create "reconnect" frames,
- // which the outer peer will find, and use to resync the channel names.
- this.innerPeerReconnect_();
+ if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.INNER) {
+ // The outer peer might need a short time to get its frames ready, as
+ // CrossPageChannel prevents them from getting created until the inner
+ // peer's frame has thrown its loaded event. This method is a noop for
+ // the first few times it's called, and then allows the reconnection
+ // sequence to begin.
+ this.maybeInnerPeerReconnect_();
} else if (this.channel_.getRole() ==
goog.net.xpc.CrossPageChannelRole.OUTER) {
// The inner peer is either not loaded yet, or the receiving
@@ -319,11 +390,11 @@ goog.net.xpc.IframePollingTransport.prototype.checkForeignFramesReady_ =
// Create receivers.
this.msgReceiver_ = new goog.net.xpc.IframePollingTransport.Receiver(
this,
- this.channel_.peerWindowObject_.frames[this.getMsgFrameName_()],
+ this.getPeerFrame_(this.getMsgFrameName_()),
goog.bind(this.processIncomingMsg, this));
this.ackReceiver_ = new goog.net.xpc.IframePollingTransport.Receiver(
this,
- this.channel_.peerWindowObject_.frames[this.getAckFrameName_()],
+ this.getPeerFrame_(this.getAckFrameName_()),
goog.bind(this.processIncomingAck, this));
this.checkLocalFramesPresent_();
@@ -342,7 +413,7 @@ goog.net.xpc.IframePollingTransport.prototype.isRcvFrameReady_ =
goog.net.xpc.logger.finest('checking for receive frame: ' + frameName);
/** @preserveTry */
try {
- var winObj = this.channel_.peerWindowObject_.frames[frameName];
+ var winObj = this.getPeerFrame_(frameName);
if (!winObj || winObj.location.href.indexOf(this.rcvUri_) != 0) {
return false;
}
@@ -363,7 +434,7 @@ goog.net.xpc.IframePollingTransport.prototype.checkLocalFramesPresent_ =
// Are the sender frames ready?
// These contain a document from the peer's domain, therefore we can only
// check if the frame itself is present.
- var frames = this.channel_.peerWindowObject_.frames;
+ var frames = this.getPeerFrames_();
if (!(frames[this.getAckFrameName_()] &&
frames[this.getMsgFrameName_()])) {
// start a timer to check again
@@ -398,7 +469,7 @@ goog.net.xpc.IframePollingTransport.prototype.checkLocalFramesPresent_ =
*/
goog.net.xpc.IframePollingTransport.prototype.checkIfConnected_ = function() {
if (this.sentConnectionSetupAck_ && this.rcvdConnectionSetupAck_) {
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
if (this.deliveryQueue_) {
goog.net.xpc.logger.fine('delivering queued messages ' +
@@ -406,7 +477,7 @@ goog.net.xpc.IframePollingTransport.prototype.checkIfConnected_ = function() {
for (var i = 0, m; i < this.deliveryQueue_.length; i++) {
m = this.deliveryQueue_[i];
- this.channel_.deliver_(m.service, m.payload);
+ this.channel_.xpcDeliver(m.service, m.payload);
}
delete this.deliveryQueue_;
}
@@ -551,7 +622,7 @@ goog.net.xpc.IframePollingTransport.prototype.deliverPayload_ = function(s) {
push({service: service, payload: payload});
goog.net.xpc.logger.finest('queued delivery');
} else {
- this.channel_.deliver_(service, payload);
+ this.channel_.xpcDeliver(service, payload);
}
};
@@ -574,6 +645,7 @@ goog.net.xpc.IframePollingTransport.prototype.MAX_FRAME_LENGTH_ = 3800;
*
* @param {string} service Name of service this the message has to be delivered.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.IframePollingTransport.prototype.send =
function(service, payload) {
@@ -653,23 +725,25 @@ goog.net.xpc.IframePollingTransport.TIME_SHORT_POLL_AFTER_ACTIVITY_ =
* @private
*/
goog.net.xpc.IframePollingTransport.receive_ = function() {
+ var receivers = goog.net.xpc.IframePollingTransport.receivers_;
+ var receiver;
var rcvd = false;
+
/** @preserveTry */
try {
- for (var i = 0, l = goog.net.xpc.IframePollingTransport.receivers_.length;
- i < l; i++) {
- rcvd = rcvd ||
- goog.net.xpc.IframePollingTransport.receivers_[i].receive();
+ for (var i = 0; receiver = receivers[i]; i++) {
+ rcvd = rcvd || receiver.receive();
}
} catch (e) {
goog.net.xpc.logger.info('receive_() failed: ' + e);
+
// Notify the channel that the transport had an error.
- goog.net.xpc.IframePollingTransport.receivers_[i].
- transport_.channel_.notifyTransportError_();
- // notifyTransportError_() closes the channel and dispoases the transport.
+ receiver.transport_.channel_.notifyTransportError();
+
+ // notifyTransportError() closes the channel and disposes the transport.
// If there are no other channels present, this.receivers_ will now be empty
- // and there is not need to keep polling.
- if (!goog.net.xpc.IframePollingTransport.receivers_.length) {
+ // and there is no need to keep polling.
+ if (!receivers.length) {
return;
}
}
@@ -787,7 +861,8 @@ goog.net.xpc.IframePollingTransport.Sender.prototype.send = function(payload) {
* goog.net.xpc.IframePollingTransport.Receiver
*
* @constructor
- * @param {goog.net.xpc.Transport} transport The transport to receive from.
+ * @param {goog.net.xpc.IframePollingTransport} transport The transport to
+ * receive from.
* @param {Object} windowObj The window-object to poll for location-changes.
* @param {Function} callback The callback-function to be called when
* location has changed.
@@ -795,12 +870,15 @@ goog.net.xpc.IframePollingTransport.Sender.prototype.send = function(payload) {
goog.net.xpc.IframePollingTransport.Receiver = function(transport,
windowObj,
callback) {
-
+ /**
+ * The transport to receive from.
+ * @type {goog.net.xpc.IframePollingTransport}
+ * @private
+ */
this.transport_ = transport;
this.rcvFrame_ = windowObj;
this.cb_ = callback;
-
this.currentLoc_ = this.rcvFrame_.location.href.split('#')[0] + '#INITIAL';
goog.net.xpc.IframePollingTransport.receivers_.push(this);
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport_test.html b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport_test.html
new file mode 100644
index 0000000..16dda85
--- /dev/null
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport_test.html
@@ -0,0 +1,295 @@
+<!DOCTYPE html>
+<html>
+<!--
+Copyright 2012 The Closure Library Authors. All Rights Reserved.
+
+Use of this source code is governed by the Apache License, Version 2.0.
+See the COPYING file for details.
+-->
+<!--
+-->
+<head>
+<meta http-equiv="X-IframePollingTransport-Compatible" content="IE=edge">
+<title>NativeMessagingTransport Unit-Tests</title>
+<script src="../../base.js"></script>
+<script>
+ goog.require('goog.Timer');
+ goog.require('goog.dom');
+ goog.require('goog.dom.TagName');
+ goog.require('goog.functions');
+ goog.require('goog.net.xpc');
+ goog.require('goog.net.xpc.CrossPageChannel');
+ goog.require('goog.net.xpc.CrossPageChannelRole');
+ goog.require('goog.object');
+ goog.require('goog.testing.MockClock');
+ goog.require('goog.testing.jsunit');
+ goog.require('goog.testing.recordFunction');
+</script>
+<script>
+
+var mockClock = null;
+var outerChannel = null;
+var innerChannel = null;
+
+function setUp() {
+ mockClock = new goog.testing.MockClock(true /* opt_autoInstall */);
+
+ // Create the peer windows.
+ var outerPeerHostName = 'https://www.youtube.com';
+ var outerPeerWindow = createMockPeerWindow(outerPeerHostName);
+
+ var innerPeerHostName = 'https://www.google.com';
+ var innerPeerWindow = createMockPeerWindow(innerPeerHostName);
+
+ // Create the channels.
+ outerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.OUTER, 'test',
+ outerPeerHostName, outerPeerWindow, innerPeerHostName, innerPeerWindow);
+ innerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.INNER, 'test',
+ innerPeerHostName, innerPeerWindow, outerPeerHostName, outerPeerWindow);
+};
+
+
+function tearDown() {
+ outerChannel.dispose();
+ innerChannel.dispose();
+ mockClock.uninstall();
+};
+
+
+/** Tests that connection happens normally and callbacks are invoked. */
+function testConnect() {
+ var outerConnectCallback = goog.testing.recordFunction();
+ var innerConnectCallback = goog.testing.recordFunction();
+
+ // Connect the two channels.
+ outerChannel.connect(outerConnectCallback);
+ innerChannel.connect(innerConnectCallback);
+ mockClock.tick(1000);
+
+ // Check that channels were connected and callbacks invoked.
+ assertEquals(1, outerConnectCallback.getCallCount());
+ assertEquals(1, innerConnectCallback.getCallCount());
+ assertTrue(outerChannel.isConnected());
+ assertTrue(innerChannel.isConnected());
+};
+
+
+/** Tests that messages are successfully delivered to the inner peer. */
+function testSend_outerToInner() {
+ var serviceCallback = goog.testing.recordFunction();
+
+ // Register a service handler in the inner channel.
+ innerChannel.registerService('svc', function(payload) {
+ assertEquals('hello', payload);
+ serviceCallback();
+ });
+
+ // Connect the two channels.
+ outerChannel.connect();
+ innerChannel.connect();
+ mockClock.tick(1000);
+
+ // Send a message.
+ outerChannel.send('svc', 'hello');
+ mockClock.tick(1000);
+
+ // Check that the message was handled.
+ assertEquals(1, serviceCallback.getCallCount());
+};
+
+
+/** Tests that messages are successfully delivered to the outer peer. */
+function testSend_innerToOuter() {
+ var serviceCallback = goog.testing.recordFunction();
+
+ // Register a service handler in the inner channel.
+ outerChannel.registerService('svc', function(payload) {
+ assertEquals('hello', payload);
+ serviceCallback();
+ });
+
+ // Connect the two channels.
+ outerChannel.connect();
+ innerChannel.connect();
+ mockClock.tick(1000);
+
+ // Send a message.
+ innerChannel.send('svc', 'hello');
+ mockClock.tick(1000);
+
+ // Check that the message was handled.
+ assertEquals(1, serviceCallback.getCallCount());
+};
+
+
+/** Tests that closing the outer peer does not cause an error. */
+function testSend_outerPeerClosed() {
+ // Connect the inner channel.
+ innerChannel.connect();
+ mockClock.tick(1000);
+
+ // Close the outer peer before it has a chance to connect.
+ closeWindow(innerChannel.getPeerWindowObject());
+
+ // Allow timers to execute (and fail).
+ mockClock.tick(1000);
+};
+
+
+/** Tests that closing the inner peer does not cause an error. */
+function testSend_innerPeerClosed() {
+ // Connect the outer channel.
+ outerChannel.connect();
+ mockClock.tick(1000);
+
+ // Close the inner peer before it has a chance to connect.
+ closeWindow(outerChannel.getPeerWindowObject());
+
+ // Allow timers to execute (and fail).
+ mockClock.tick(1000);
+};
+
+
+/** Tests that partially closing the outer peer does not cause an error. */
+function testSend_outerPeerClosing() {
+ // Connect the inner channel.
+ innerChannel.connect();
+ mockClock.tick(1000);
+
+ // Close the outer peer before it has a chance to connect, but
+ // leave closed set to false to simulate a partially closed window.
+ closeWindow(innerChannel.getPeerWindowObject());
+ innerChannel.getPeerWindowObject().closed = false;
+
+ // Allow timers to execute (and fail).
+ mockClock.tick(1000);
+};
+
+
+/** Tests that partially closing the inner peer does not cause an error. */
+function testSend_innerPeerClosing() {
+ // Connect the outer channel.
+ outerChannel.connect();
+ mockClock.tick(1000);
+
+ // Close the inner peer before it has a chance to connect, but
+ // leave closed set to false to simulate a partially closed window.
+ closeWindow(outerChannel.getPeerWindowObject());
+ outerChannel.getPeerWindowObject().closed = false;
+
+ // Allow timers to execute (and fail).
+ mockClock.tick(1000);
+};
+
+
+/**
+ * Creates a channel with the specified configuration, using frame polling.
+ * @param {!goog.net.xpc.CrossPageChannelRole} role The channel role.
+ * @param {string} channelName The channel name.
+ * @param {string} fromHostName The host name of the window hosting the channel.
+ * @param {!Object} fromWindow The window hosting the channel.
+ * @param {string} toHostName The host name of the peer window.
+ * @param {!Object} toWindow The peer window.
+ */
+function createChannel(role, channelName, fromHostName, fromWindow, toHostName,
+ toWindow) {
+
+ // Build a channel config using frame polling.
+ var channelConfig = goog.object.create(
+ goog.net.xpc.CfgFields.ROLE,
+ role,
+ goog.net.xpc.CfgFields.PEER_HOSTNAME,
+ toHostName,
+ goog.net.xpc.CfgFields.CHANNEL_NAME,
+ channelName,
+ goog.net.xpc.CfgFields.LOCAL_POLL_URI,
+ fromHostName + '/robots.txt',
+ goog.net.xpc.CfgFields.PEER_POLL_URI,
+ toHostName + '/robots.txt',
+ goog.net.xpc.CfgFields.TRANSPORT,
+ goog.net.xpc.TransportTypes.IFRAME_POLLING);
+
+ // Build the channel.
+ var channel = new goog.net.xpc.CrossPageChannel(channelConfig);
+ channel.setPeerWindowObject(toWindow);
+
+ // Update the transport's getWindow, to return the correct host window.
+ channel.createTransport_();
+ channel.transport_.getWindow = goog.functions.constant(fromWindow);
+ return channel;
+};
+
+
+/**
+ * Creates a mock window to use as a peer. The peer window will host the frame
+ * elements.
+ * @param {string} url The peer window's initial URL.
+ */
+function createMockPeerWindow(url) {
+ var mockPeer = createMockWindow(url);
+
+ // Update the appendChild method to use a mock frame window.
+ mockPeer.document.body.appendChild = function(el) {
+ assertEquals(goog.dom.TagName.IFRAME, el.tagName);
+ mockPeer.frames[el.name] = createMockWindow(el.src);
+ mockPeer.document.body.element.appendChild(el);
+ };
+
+ return mockPeer;
+};
+
+
+/**
+ * Creates a mock window.
+ * @param {string} url The window's initial URL.
+ */
+function createMockWindow(url) {
+ // Create the mock window, document and body.
+ var mockWindow = {};
+ var mockDocument = {};
+ var mockBody = {};
+ var mockLocation = {};
+
+ // Configure the mock window's document body.
+ mockBody.element = goog.dom.createDom(goog.dom.TagName.BODY);
+
+ // Configure the mock window's document.
+ mockDocument.body = mockBody;
+
+ // Configure the mock window's location.
+ mockLocation.href = url;
+ mockLocation.replace = function(value) { mockLocation.href = value; }
+
+ // Configure the mock window.
+ mockWindow.document = mockDocument;
+ mockWindow.frames = {};
+ mockWindow.location = mockLocation;
+ mockWindow.setTimeout = goog.Timer.callOnce;
+
+ return mockWindow;
+};
+
+
+/**
+ * Emulates closing the specified window by clearing frames, document and
+ * location.
+ */
+function closeWindow(targetWindow) {
+ // Close any child frame windows.
+ for (var frameName in targetWindow.frames) {
+ closeWindow(targetWindow.frames[frameName]);
+ }
+
+ // Clear the target window, set closed to true.
+ targetWindow.closed = true;
+ targetWindow.frames = null;
+ targetWindow.document = null;
+ targetWindow.location = null;
+};
+
+</script>
+</head>
+
+<body></body>
+
+</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/iframerelaytransport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframerelaytransport.js
index 2f49ad5..1281c49 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/iframerelaytransport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/iframerelaytransport.js
@@ -56,14 +56,15 @@ goog.net.xpc.IframeRelayTransport = function(channel, opt_domHelper) {
* @private
*/
this.peerRelayUri_ =
- this.channel_.cfg_[goog.net.xpc.CfgFields.PEER_RELAY_URI];
+ this.channel_.getConfig()[goog.net.xpc.CfgFields.PEER_RELAY_URI];
/**
* The id of the iframe the peer page lives in.
* @type {string}
* @private
*/
- this.peerIframeId_ = this.channel_.cfg_[goog.net.xpc.CfgFields.IFRAME_ID];
+ this.peerIframeId_ =
+ this.channel_.getConfig()[goog.net.xpc.CfgFields.IFRAME_ID];
if (goog.userAgent.WEBKIT) {
goog.net.xpc.IframeRelayTransport.startCleanupTimer_();
@@ -183,13 +184,15 @@ goog.net.xpc.IframeRelayTransport.fragmentMap_ = {};
/**
* The transport type.
* @type {number}
+ * @override
*/
goog.net.xpc.IframeRelayTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.IFRAME_RELAY;
+ goog.net.xpc.TransportTypes.IFRAME_RELAY;
/**
* Connects this transport.
+ * @override
*/
goog.net.xpc.IframeRelayTransport.prototype.connect = function() {
if (!this.getWindow()['xpcRelay']) {
@@ -248,19 +251,20 @@ goog.net.xpc.IframeRelayTransport.receiveMessage_ =
}
// We've received all outstanding fragments; combine what we've received
- // into payload and fall out to the call to deliver_.
+ // into payload and fall out to the call to xpcDeliver.
payload = fragmentInfo.fragments.join('');
delete goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr];
}
- goog.net.xpc.channels_[channelName].deliver_(service,
- decodeURIComponent(payload));
+ goog.net.xpc.channels[channelName].
+ xpcDeliver(service, decodeURIComponent(payload));
};
/**
* Handles transport service messages (internal signalling).
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.IframeRelayTransport.prototype.transportServiceHandler =
function(payload) {
@@ -268,10 +272,10 @@ goog.net.xpc.IframeRelayTransport.prototype.transportServiceHandler =
// TODO(user) Safari swallows the SETUP_ACK from the iframe to the
// container after hitting reload.
this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
}
else if (payload == goog.net.xpc.SETUP_ACK_) {
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
}
};
@@ -281,6 +285,7 @@ goog.net.xpc.IframeRelayTransport.prototype.transportServiceHandler =
*
* @param {string} service Name of service this the message has to be delivered.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.IframeRelayTransport.prototype.send = function(service, payload) {
// If we're on IE and the post-encoding payload is large, split it
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport.js
index 4458471..e0674fa 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport.js
@@ -21,7 +21,11 @@
goog.provide('goog.net.xpc.NativeMessagingTransport');
+goog.require('goog.Timer');
+goog.require('goog.asserts');
+goog.require('goog.async.Deferred');
goog.require('goog.events');
+goog.require('goog.events.EventHandler');
goog.require('goog.net.xpc');
goog.require('goog.net.xpc.CrossPageChannelRole');
goog.require('goog.net.xpc.Transport');
@@ -40,11 +44,16 @@ goog.require('goog.net.xpc.Transport');
* peer.
* @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for
* finding the correct window/document.
+ * @param {boolean=} opt_oneSidedHandshake If this is true, only the outer
+ * transport sends a SETUP message and expects a SETUP_ACK. The inner
+ * transport goes connected when it receives the SETUP.
+ * @param {number=} opt_protocolVersion Which version of its setup protocol the
+ * transport should use. The default is '2'.
* @constructor
* @extends {goog.net.xpc.Transport}
*/
goog.net.xpc.NativeMessagingTransport = function(channel, peerHostname,
- opt_domHelper) {
+ opt_domHelper, opt_oneSidedHandshake, opt_protocolVersion) {
goog.base(this, opt_domHelper);
/**
@@ -55,17 +64,135 @@ goog.net.xpc.NativeMessagingTransport = function(channel, peerHostname,
this.channel_ = channel;
/**
+ * Which version of the transport's protocol should be used.
+ * @type {number}
+ * @private
+ */
+ this.protocolVersion_ = opt_protocolVersion || 2;
+ goog.asserts.assert(this.protocolVersion_ >= 1);
+ goog.asserts.assert(this.protocolVersion_ <= 2);
+
+ /**
* The hostname of the peer. This parameterizes all calls to postMessage, and
* should contain the precise protocol, domain, and port of the peer window.
* @type {string}
* @private
*/
this.peerHostname_ = peerHostname || '*';
+
+ /**
+ * The event handler.
+ * @type {!goog.events.EventHandler}
+ * @private
+ */
+ this.eventHandler_ = new goog.events.EventHandler(this);
+
+ /**
+ * Timer for connection reattempts.
+ * @type {!goog.Timer}
+ * @private
+ */
+ this.maybeAttemptToConnectTimer_ = new goog.Timer(100, this.getWindow());
+
+ /**
+ * Whether one-sided handshakes are enabled.
+ * @type {boolean}
+ * @private
+ */
+ this.oneSidedHandshake_ = !!opt_oneSidedHandshake;
+
+ /**
+ * Fires once we've received our SETUP_ACK message.
+ * @type {!goog.async.Deferred}
+ * @private
+ */
+ this.setupAckReceived_ = new goog.async.Deferred();
+
+ /**
+ * Fires once we've sent our SETUP_ACK message.
+ * @type {!goog.async.Deferred}
+ * @private
+ */
+ this.setupAckSent_ = new goog.async.Deferred();
+
+ /**
+ * Fires once we're marked connected.
+ * @type {!goog.async.Deferred}
+ * @private
+ */
+ this.connected_ = new goog.async.Deferred();
+
+ /**
+ * The unique ID of this side of the connection. Used to determine when a peer
+ * is reloaded.
+ * @type {string}
+ * @private
+ */
+ this.endpointId_ = goog.net.xpc.getRandomString(10);
+
+ /**
+ * The unique ID of the peer. If we get a message from a peer with an ID we
+ * don't expect, we reset the connection.
+ * @type {?string}
+ * @private
+ */
+ this.peerEndpointId_ = null;
+
+ // We don't want to mark ourselves connected until we have sent whatever
+ // message will cause our counterpart in the other frame to also declare
+ // itself connected, if there is such a message. Otherwise we risk a user
+ // message being sent in advance of that message, and it being discarded.
+ if (this.oneSidedHandshake_) {
+ if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.INNER) {
+ // One sided handshake, inner frame:
+ // SETUP_ACK must be received.
+ this.connected_.awaitDeferred(this.setupAckReceived_);
+ } else {
+ // One sided handshake, outer frame:
+ // SETUP_ACK must be sent.
+ this.connected_.awaitDeferred(this.setupAckSent_);
+ }
+ } else {
+ // Two sided handshake:
+ // SETUP_ACK has to have been received, and sent.
+ this.connected_.awaitDeferred(this.setupAckReceived_);
+ if (this.protocolVersion_ == 2) {
+ this.connected_.awaitDeferred(this.setupAckSent_);
+ }
+ }
+ this.connected_.addCallback(this.notifyConnected_, this);
+ this.connected_.callback(true);
+
+ this.eventHandler_.
+ listen(this.maybeAttemptToConnectTimer_, goog.Timer.TICK,
+ this.maybeAttemptToConnect_);
+
+ goog.net.xpc.logger.info('NativeMessagingTransport created. ' +
+ 'protocolVersion=' + this.protocolVersion_ + ', oneSidedHandshake=' +
+ this.oneSidedHandshake_ + ', role=' + this.channel_.getRole());
};
goog.inherits(goog.net.xpc.NativeMessagingTransport, goog.net.xpc.Transport);
/**
+ * Length of the delay in milliseconds between the channel being connected and
+ * the connection callback being called, in cases where coverage of timing flaws
+ * is required.
+ * @type {number}
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.CONNECTION_DELAY_MS_ = 200;
+
+
+/**
+ * Current determination of peer's protocol version, or null for unknown.
+ * @type {?number}
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.peerProtocolVersion_ = null;
+
+
+/**
* Flag indicating if this instance of the transport has been initialized.
* @type {boolean}
* @private
@@ -76,12 +203,21 @@ goog.net.xpc.NativeMessagingTransport.prototype.initialized_ = false;
/**
* The transport type.
* @type {number}
+ * @override
*/
goog.net.xpc.NativeMessagingTransport.prototype.transportType =
goog.net.xpc.TransportTypes.NATIVE_MESSAGING;
/**
+ * The delimiter used for transport service messages.
+ * @type {string}
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_ = ',';
+
+
+/**
* Tracks the number of NativeMessagingTransport channels that have been
* initialized but not disposed yet in a map keyed by the UID of the window
* object. This allows for multiple windows to be initiallized and listening
@@ -93,6 +229,28 @@ goog.net.xpc.NativeMessagingTransport.activeCount_ = {};
/**
+ * Id of a timer user during postMessage sends.
+ * @type {number}
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.sendTimerId_ = 0;
+
+
+/**
+ * Checks whether the peer transport protocol version could be as indicated.
+ * @param {number} version The version to check for.
+ * @return {boolean} Whether the peer transport protocol version is as
+ * indicated, or null.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.couldPeerVersionBe_ =
+ function(version) {
+ return this.peerProtocolVersion_ == null ||
+ this.peerProtocolVersion_ == version;
+};
+
+
+/**
* Initializes this transport. Registers a listener for 'message'-events
* on the document.
* @param {Window} listenWindow The window to listen to events on.
@@ -153,19 +311,23 @@ goog.net.xpc.NativeMessagingTransport.messageReceived_ = function(msgEvt) {
// - channel was created in a different namespace
// - message was sent to the wrong window
// - channel has become stale (e.g. caching iframes and back clicks)
- var channel = goog.net.xpc.channels_[channelName];
+ var channel = goog.net.xpc.channels[channelName];
if (channel) {
- channel.deliver_(service, payload, msgEvt.getBrowserEvent().origin);
+ channel.xpcDeliver(service, payload, msgEvt.getBrowserEvent().origin);
return true;
}
+ var transportMessageType =
+ goog.net.xpc.NativeMessagingTransport.parseTransportPayload_(payload)[0];
+
// Check if there are any stale channel names that can be updated.
- for (var staleChannelName in goog.net.xpc.channels_) {
- var staleChannel = goog.net.xpc.channels_[staleChannelName];
+ for (var staleChannelName in goog.net.xpc.channels) {
+ var staleChannel = goog.net.xpc.channels[staleChannelName];
if (staleChannel.getRole() == goog.net.xpc.CrossPageChannelRole.INNER &&
!staleChannel.isConnected() &&
service == goog.net.xpc.TRANSPORT_SERVICE_ &&
- payload == goog.net.xpc.SETUP) {
+ (transportMessageType == goog.net.xpc.SETUP ||
+ transportMessageType == goog.net.xpc.SETUP_NTPV2)) {
// Inner peer received SETUP message but channel names did not match.
// Start using the channel name sent from outer peer. The channel name
// of the inner peer can easily become out of date, as iframe's and their
@@ -176,10 +338,10 @@ goog.net.xpc.NativeMessagingTransport.messageReceived_ = function(msgEvt) {
goog.net.xpc.logger.fine('changing channel name to ' + channelName);
staleChannel.name = channelName;
// Remove old stale pointer to channel.
- delete goog.net.xpc.channels_[staleChannelName];
+ delete goog.net.xpc.channels[staleChannelName];
// Create fresh pointer to channel.
- goog.net.xpc.channels_[channelName] = staleChannel;
- staleChannel.deliver_(service, payload);
+ goog.net.xpc.channels[channelName] = staleChannel;
+ staleChannel.xpcDeliver(service, payload);
return true;
}
}
@@ -193,27 +355,135 @@ goog.net.xpc.NativeMessagingTransport.messageReceived_ = function(msgEvt) {
/**
* Handles transport service messages.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.NativeMessagingTransport.prototype.transportServiceHandler =
function(payload) {
- switch (payload) {
+ var transportParts =
+ goog.net.xpc.NativeMessagingTransport.parseTransportPayload_(payload);
+ var transportMessageType = transportParts[0];
+ var peerEndpointId = transportParts[1];
+ switch (transportMessageType) {
+ case goog.net.xpc.SETUP_ACK_:
+ this.setPeerProtocolVersion_(1);
+ if (!this.setupAckReceived_.hasFired()) {
+ this.setupAckReceived_.callback(true);
+ }
+ break;
+ case goog.net.xpc.SETUP_ACK_NTPV2:
+ if (this.protocolVersion_ == 2) {
+ this.setPeerProtocolVersion_(2);
+ if (!this.setupAckReceived_.hasFired()) {
+ this.setupAckReceived_.callback(true);
+ }
+ }
+ break;
case goog.net.xpc.SETUP:
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
+ this.setPeerProtocolVersion_(1);
+ this.sendSetupAckMessage_(1);
break;
- case goog.net.xpc.SETUP_ACK_:
- this.channel_.notifyConnected_();
+ case goog.net.xpc.SETUP_NTPV2:
+ if (this.protocolVersion_ == 2) {
+ var prevPeerProtocolVersion = this.peerProtocolVersion_;
+ this.setPeerProtocolVersion_(2);
+ this.sendSetupAckMessage_(2);
+ if ((prevPeerProtocolVersion == 1 || this.peerEndpointId_ != null) &&
+ this.peerEndpointId_ != peerEndpointId) {
+ // Send a new SETUP message since the peer has been replaced.
+ goog.net.xpc.logger.info('Sending SETUP and changing peer ID to: ' +
+ peerEndpointId);
+ this.sendSetupMessage_();
+ }
+ this.peerEndpointId_ = peerEndpointId;
+ }
break;
}
};
/**
+ * Sends a SETUP transport service message of the correct protocol number for
+ * our current situation.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.sendSetupMessage_ =
+ function() {
+ // 'real' (legacy) v1 transports don't know about there being v2 ones out
+ // there, and we shouldn't either.
+ goog.asserts.assert(!(this.protocolVersion_ == 1 &&
+ this.peerProtocolVersion_ == 2));
+
+ if (this.protocolVersion_ == 2 && this.couldPeerVersionBe_(2)) {
+ var payload = goog.net.xpc.SETUP_NTPV2;
+ payload += goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_;
+ payload += this.endpointId_;
+ this.send(goog.net.xpc.TRANSPORT_SERVICE_, payload);
+ }
+
+ // For backward compatibility reasons, the V1 SETUP message can be sent by
+ // both V1 and V2 transports. Once a V2 transport has 'heard' another V2
+ // transport it starts ignoring V1 messages, so the V2 message must be sent
+ // first.
+ if (this.couldPeerVersionBe_(1)) {
+ this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP);
+ }
+};
+
+
+/**
+ * Sends a SETUP_ACK transport service message of the correct protocol number
+ * for our current situation.
+ * @param {number} protocolVersion The protocol version of the SETUP message
+ * which gave rise to this ack message.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.sendSetupAckMessage_ =
+ function(protocolVersion) {
+ goog.asserts.assert(this.protocolVersion_ != 1 || protocolVersion != 2,
+ 'Shouldn\'t try to send a v2 setup ack in v1 mode.');
+ if (this.protocolVersion_ == 2 && this.couldPeerVersionBe_(2) &&
+ protocolVersion == 2) {
+ this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_NTPV2);
+ } else if (this.couldPeerVersionBe_(1) && protocolVersion == 1) {
+ this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
+ } else {
+ return;
+ }
+
+ if (!this.setupAckSent_.hasFired()) {
+ this.setupAckSent_.callback(true);
+ }
+};
+
+
+/**
+ * Attempts to set the peer protocol number. Downgrades from 2 to 1 are not
+ * permitted.
+ * @param {number} version The new protocol number.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.setPeerProtocolVersion_ =
+ function(version) {
+ if (version > this.peerProtocolVersion_) {
+ this.peerProtocolVersion_ = version;
+ }
+ if (this.peerProtocolVersion_ == 1) {
+ if (!this.setupAckSent_.hasFired() && !this.oneSidedHandshake_) {
+ this.setupAckSent_.callback(true);
+ }
+ this.peerEndpointId_ = null;
+ }
+};
+
+
+/**
* Connects this transport.
+ * @override
*/
goog.net.xpc.NativeMessagingTransport.prototype.connect = function() {
goog.net.xpc.NativeMessagingTransport.initialize_(this.getWindow());
this.initialized_ = true;
- this.connectWithRetries_();
+ this.maybeAttemptToConnect_();
};
@@ -226,13 +496,20 @@ goog.net.xpc.NativeMessagingTransport.prototype.connect = function() {
* soft-reloads and history navigations.
* @private
*/
-goog.net.xpc.NativeMessagingTransport.prototype.connectWithRetries_ =
+goog.net.xpc.NativeMessagingTransport.prototype.maybeAttemptToConnect_ =
function() {
- if (this.channel_.isConnected() || this.isDisposed()) {
+ // In a one-sided handshake, the outer frame does not send a SETUP message,
+ // but the inner frame does.
+ var outerFrame = this.channel_.getRole() ==
+ goog.net.xpc.CrossPageChannelRole.OUTER;
+ if ((this.oneSidedHandshake_ && outerFrame) ||
+ this.channel_.isConnected() ||
+ this.isDisposed()) {
+ this.maybeAttemptToConnectTimer_.stop();
return;
}
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP);
- this.getWindow().setTimeout(goog.bind(this.connectWithRetries_, this), 100);
+ this.maybeAttemptToConnectTimer_.start();
+ this.sendSetupMessage_();
};
@@ -241,31 +518,74 @@ goog.net.xpc.NativeMessagingTransport.prototype.connectWithRetries_ =
* @param {string} service The name off the service the message is to be
* delivered to.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.NativeMessagingTransport.prototype.send = function(service,
payload) {
- var win = this.channel_.peerWindowObject_;
+ var win = this.channel_.getPeerWindowObject();
if (!win) {
goog.net.xpc.logger.fine('send(): window not ready');
return;
}
- // postMessage is a method of the window object, except in some versions of
- // Opera, where it is a method of the document object.
- var obj = win.postMessage ? win : win.document;
this.send = function(service, payload) {
- goog.net.xpc.logger.fine('send(): payload=' + payload +
- ' to hostname=' + this.peerHostname_);
- obj.postMessage(this.channel_.name + '|' + service + ':' + payload,
- this.peerHostname_);
+ // In IE8 (and perhaps elsewhere), it seems like postMessage is sometimes
+ // implemented as a synchronous call. That is, calling it synchronously
+ // calls whatever listeners it has, and control is not returned to the
+ // calling thread until those listeners are run. This produces different
+ // ordering to all other browsers, and breaks this protocol. This timer
+ // callback is introduced to produce standard behavior across all browsers.
+ var transport = this;
+ var channelName = this.channel_.name;
+ var sendFunctor = function() {
+ transport.sendTimerId_ = 0;
+
+ try {
+ // postMessage is a method of the window object, except in some
+ // versions of Opera, where it is a method of the document object. It
+ // also seems that the appearance of postMessage on the peer window
+ // object can sometimes be delayed.
+ var obj = win.postMessage ? win : win.document;
+ if (!obj.postMessage) {
+ goog.net.xpc.logger.warning('Peer window had no postMessage ' +
+ 'function.');
+ return;
+ }
+
+ obj.postMessage(channelName + '|' + service + ':' + payload,
+ transport.peerHostname_);
+ goog.net.xpc.logger.fine('send(): service=' + service + ' payload=' +
+ payload + ' to hostname=' + transport.peerHostname_);
+ } catch (error) {
+ // There is some evidence (not totally convincing) that postMessage can
+ // be missing or throw errors during a narrow timing window during
+ // startup. This protects against that.
+ goog.net.xpc.logger.warning('Error performing postMessage, ignoring.',
+ error);
+ }
+ };
+ this.sendTimerId_ = goog.Timer.callOnce(sendFunctor, 0);
};
this.send(service, payload);
};
+/**
+ * Notify the channel that this transport is connected. If either transport is
+ * protocol v1, a short delay is required to paper over timing vulnerabilities
+ * in that protocol version.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.prototype.notifyConnected_ =
+ function() {
+ var delay = (this.protocolVersion_ == 1 || this.peerProtocolVersion_ == 1) ?
+ goog.net.xpc.NativeMessagingTransport.CONNECTION_DELAY_MS_ : undefined;
+ this.channel_.notifyConnected(delay);
+};
+
+
/** @override */
goog.net.xpc.NativeMessagingTransport.prototype.disposeInternal = function() {
- goog.base(this, 'disposeInternal');
if (this.initialized_) {
var listenWindow = this.getWindow();
var uid = goog.getUid(listenWindow);
@@ -280,8 +600,48 @@ goog.net.xpc.NativeMessagingTransport.prototype.disposeInternal = function() {
goog.net.xpc.NativeMessagingTransport);
}
}
+
+ if (this.sendTimerId_) {
+ goog.Timer.clear(this.sendTimerId_);
+ this.sendTimerId_ = 0;
+ }
+
+ goog.dispose(this.eventHandler_);
+ delete this.eventHandler_;
+
+ goog.dispose(this.maybeAttemptToConnectTimer_);
+ delete this.maybeAttemptToConnectTimer_;
+
+ this.setupAckReceived_.cancel();
+ delete this.setupAckReceived_;
+ this.setupAckSent_.cancel();
+ delete this.setupAckSent_;
+ this.connected_.cancel();
+ delete this.connected_;
+
// Cleaning up this.send as it is an instance method, created in
// goog.net.xpc.NativeMessagingTransport.prototype.send and has a closure over
// this.channel_.peerWindowObject_.
delete this.send;
+
+ goog.base(this, 'disposeInternal');
+};
+
+
+/**
+ * Parse a transport service payload message. For v1, it is simply expected to
+ * be 'SETUP' or 'SETUP_ACK'. For v2, an example setup message is
+ * 'SETUP_NTPV2,abc123', where the second part is the endpoint id. The v2 setup
+ * ack message is simply 'SETUP_ACK_NTPV2'.
+ * @param {string} payload The payload.
+ * @return {!Array.<?string>} An array with the message type as the first member
+ * and the endpoint id as the second, if one was sent, or null otherwise.
+ * @private
+ */
+goog.net.xpc.NativeMessagingTransport.parseTransportPayload_ =
+ function(payload) {
+ var transportParts = (/** @type {!Array.<?string>} */ payload.split(
+ goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_));
+ transportParts[1] = transportParts[1] || null;
+ return transportParts;
};
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport_test.html b/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport_test.html
index a18cb2a..8e2086c 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport_test.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/nativemessagingtransport_test.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
<!--
-->
<html>
@@ -10,15 +11,20 @@ See the COPYING file for details.
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>NativeMessagingTransport Unit-Tests</title>
-<script src="../../base.js"></script>
-<script>
+<script src="../../base.js" type="text/javascript"></script>
+<script type="text/javascript">
goog.require('goog.net.xpc.CrossPageChannel');
goog.require('goog.net.xpc.CrossPageChannelRole');
goog.require('goog.net.xpc.NativeMessagingTransport');
goog.require('goog.testing.events');
goog.require('goog.testing.jsunit');
</script>
-<script>
+<script type="text/javascript">
+
+// This test only tests the native messaing transport protocol version 2.
+// Testing of previous versions and of backward/forward compatibility is done
+// in crosspagechannel_test.html.
+
function tearDown() {
goog.net.xpc.NativeMessagingTransport.activeCount_ = {};
@@ -27,21 +33,32 @@ function tearDown() {
function testConstructor() {
- var t = new goog.net.xpc.NativeMessagingTransport(null, 'http://g.com:80');
+ var xpc = getTestChannel();
+
+ var t = new goog.net.xpc.NativeMessagingTransport(xpc, 'http://g.com:80',
+ undefined /* opt_domHelper */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
assertEquals('http://g.com:80', t.peerHostname_);
- var t = new goog.net.xpc.NativeMessagingTransport(null, null);
+ var t = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, undefined /* opt_domHelper */,
+ false /* opt_oneSidedHandshake */, 2 /* opt_protocolVersion */);
assertEquals('*', t.peerHostname_);
t.dispose();
}
function testConstructorDom() {
+ var xpc = getTestChannel();
+
var t = new goog.net.xpc.NativeMessagingTransport(
- null, 'http://g.com:80', goog.dom.getDomHelper());
+ xpc, 'http://g.com:80', goog.dom.getDomHelper(),
+ false /* opt_oneSidedHandshake */, 2 /* opt_protocolVersion */);
assertEquals('http://g.com:80', t.peerHostname_);
- var t = new goog.net.xpc.NativeMessagingTransport(null, null);
+ var t = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
assertEquals('*', t.peerHostname_);
t.dispose();
}
@@ -51,18 +68,26 @@ function testDispose() {
var xpc = getTestChannel();
var listenedObj = window.postMessage ? window : document;
- var t0 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t0 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
t0.dispose();
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- var t1 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t1 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
t1.connect();
t1.dispose();
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- var t2 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- var t3 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t2 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
+ var t3 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
t2.connect();
t3.connect();
t2.dispose();
@@ -74,18 +99,26 @@ function testDisposeWithDom() {
var xpc = getTestChannel(goog.dom.getDomHelper());
var listenedObj = window.postMessage ? window : document;
- var t0 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t0 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
t0.dispose();
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- var t1 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t1 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
t1.connect();
t1.dispose();
assertEquals(0, goog.events.removeAll(listenedObj, 'message'));
- var t2 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
- var t3 = new goog.net.xpc.NativeMessagingTransport(xpc, null);
+ var t2 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
+ var t3 = new goog.net.xpc.NativeMessagingTransport(xpc,
+ null /* peerHostName */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
t2.connect();
t3.connect();
t2.dispose();
@@ -109,7 +142,7 @@ function testSendingMessagesToUnconnectedInnerPeer() {
var xpc = getTestChannel();
var serviceResult, payloadResult;
- xpc.deliver_ = function(service, payload) {
+ xpc.xpcDeliver = function(service, payload) {
serviceResult = service;
payloadResult = payload;
};
@@ -121,7 +154,8 @@ function testSendingMessagesToUnconnectedInnerPeer() {
xpc.isConnected = function() {
return false;
};
- var t = new goog.net.xpc.NativeMessagingTransport(xpc, 'http://g.com');
+ var t = new goog.net.xpc.NativeMessagingTransport(xpc, 'http://g.com',
+ false /* opt_oneSidedHandshake */, 2 /* opt_protocolVersion */);
// Test a valid message.
var e = createMockEvent('test_channel|test_service:test_payload');
@@ -144,6 +178,109 @@ function testSendingMessagesToUnconnectedInnerPeer() {
}
+function testSignalConnected_innerFrame() {
+ checkSignalConnected(false /* oneSidedHandshake */,
+ true /* innerFrame */);
+}
+
+
+function testSignalConnected_outerFrame() {
+ checkSignalConnected(false /* oneSidedHandshake */,
+ false /* innerFrame */);
+}
+
+
+function testSignalConnected_singleSided_innerFrame() {
+ checkSignalConnected(true /* oneSidedHandshake */,
+ true /* innerFrame */);
+}
+
+
+function testSignalConnected_singleSided_outerFrame() {
+ checkSignalConnected(true /* oneSidedHandshake */,
+ false /* innerFrame */);
+}
+
+
+function checkSignalConnected(oneSidedHandshake, innerFrame,
+ peerProtocolVersion, protocolVersion) {
+ var xpc = getTestChannel();
+ var connected = false;
+ xpc.notifyConnected = function() {
+ if (connected) {
+ fail();
+ } else {
+ connected = true;
+ }
+ };
+ xpc.getRole = function() {
+ return innerFrame ? goog.net.xpc.CrossPageChannelRole.INNER :
+ goog.net.xpc.CrossPageChannelRole.OUTER;
+ };
+ xpc.isConnected = function() {
+ return false;
+ };
+
+ var transport = new goog.net.xpc.NativeMessagingTransport(xpc, 'http://g.com',
+ undefined /* opt_domHelper */,
+ oneSidedHandshake /* opt_oneSidedHandshake */,
+ 2 /* protocolVerion */);
+ var sentPayloads = [];
+ transport.send = function(service, payload) {
+ assertEquals(goog.net.xpc.TRANSPORT_SERVICE_, service);
+ sentPayloads.push(payload);
+ }
+ function assertSent(payloads) {
+ assertArrayEquals(payloads, sentPayloads);
+ sentPayloads = [];
+ }
+ var endpointId = transport.endpointId_;
+ var peerEndpointId1 = 'abc123';
+ var peerEndpointId2 = 'def234';
+
+ assertFalse(connected);
+ if (!oneSidedHandshake || innerFrame) {
+ transport.transportServiceHandler(goog.net.xpc.SETUP_NTPV2 + ',' +
+ peerEndpointId1);
+ transport.transportServiceHandler(goog.net.xpc.SETUP);
+ assertSent([goog.net.xpc.SETUP_ACK_NTPV2]);
+ assertFalse(connected);
+ transport.transportServiceHandler(goog.net.xpc.SETUP_ACK_NTPV2);
+ assertSent([]);
+ assertTrue(connected);
+ } else {
+ transport.transportServiceHandler(goog.net.xpc.SETUP_ACK_NTPV2);
+ assertSent([]);
+ assertFalse(connected);
+ transport.transportServiceHandler(goog.net.xpc.SETUP_NTPV2 + ',' +
+ peerEndpointId1);
+ transport.transportServiceHandler(goog.net.xpc.SETUP);
+ assertSent([goog.net.xpc.SETUP_ACK_NTPV2]);
+ assertTrue(connected);
+ }
+
+ // Verify that additional transport service traffic doesn't cause duplicate
+ // notifications.
+ transport.transportServiceHandler(goog.net.xpc.SETUP_NTPV2 + ',' +
+ peerEndpointId1);
+ transport.transportServiceHandler(goog.net.xpc.SETUP);
+ assertSent([goog.net.xpc.SETUP_ACK_NTPV2]);
+ transport.transportServiceHandler(goog.net.xpc.SETUP_ACK_NTPV2);
+ assertSent([]);
+
+ // Simulate a reconnection by sending a SETUP message from a frame with a
+ // different endpoint id. No further connection callbacks should fire, but
+ // a new SETUP message should be triggered.
+ transport.transportServiceHandler(goog.net.xpc.SETUP_NTPV2 + ',' +
+ peerEndpointId2);
+ transport.transportServiceHandler(goog.net.xpc.SETUP);
+ assertSent([goog.net.xpc.SETUP_ACK_NTPV2, goog.net.xpc.SETUP_NTPV2 + ',' +
+ endpointId]);
+ transport.transportServiceHandler(goog.net.xpc.SETUP_ACK_NTPV2);
+ assertSent([]);
+}
+
+
function createMockEvent(data) {
var event = {};
event.getBrowserEvent = function() { return {data: data} };
@@ -154,7 +291,9 @@ function createMockEvent(data) {
function getTestChannel(opt_domHelper) {
var cfg = {};
cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = 'test_channel';
- return new goog.net.xpc.CrossPageChannel(cfg, opt_domHelper);
+ return new goog.net.xpc.CrossPageChannel(cfg, opt_domHelper,
+ undefined /* opt_domHelper */, false /* opt_oneSidedHandshake */,
+ 2 /* opt_protocolVersion */);
}
</script>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/nixtransport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/nixtransport.js
index d3b0dd7..7e00b7b 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/nixtransport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/nixtransport.js
@@ -39,6 +39,7 @@ goog.require('goog.net.xpc.Transport');
goog.require('goog.reflect');
+
/**
* NIX method transport.
*
@@ -153,7 +154,7 @@ goog.net.xpc.NixTransport.isNixSupported = function() {
window.opener = /** @type {Window} */ ({});
isSupported = goog.reflect.canAccessProperty(window, 'opener');
window.opener = oldOpener;
- } catch(e) { }
+ } catch (e) { }
return isSupported;
};
@@ -165,6 +166,7 @@ goog.net.xpc.NixTransport.isNixSupported = function() {
* Note that this method can be called multiple times, as
* it internally checks whether the work is necessary before
* proceeding.
+ * @param {Window} listenWindow The window containing the affected page.
* @private
*/
goog.net.xpc.NixTransport.conductGlobalSetup_ = function(listenWindow) {
@@ -174,79 +176,79 @@ goog.net.xpc.NixTransport.conductGlobalSetup_ = function(listenWindow) {
// Inject the VBScript code needed.
var vbscript =
- // We create a class to act as a wrapper for
- // a Javascript call, to prevent a break in of
- // the context.
- 'Class ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n ' +
-
- // An internal member for keeping track of the
- // transport for which this wrapper exists.
- 'Private m_Transport\n' +
-
- // An internal member for keeping track of the
- // auth token associated with the context that
- // created this wrapper. Used for validation
- // purposes.
- 'Private m_Auth\n' +
-
- // Method for internally setting the value
- // of the m_Transport property. We have the
- // isEmpty check to prevent the transport
- // from being overridden with an illicit
- // object by a malicious party.
- 'Public Sub SetTransport(transport)\n' +
- 'If isEmpty(m_Transport) Then\n' +
- 'Set m_Transport = transport\n' +
- 'End If\n' +
- 'End Sub\n' +
-
- // Method for internally setting the value
- // of the m_Auth property. We have the
- // isEmpty check to prevent the transport
- // from being overridden with an illicit
- // object by a malicious party.
- 'Public Sub SetAuth(auth)\n' +
- 'If isEmpty(m_Auth) Then\n' +
- 'm_Auth = auth\n' +
- 'End If\n' +
- 'End Sub\n' +
-
- // Returns the auth token to the gadget, so it can
- // confirm a match before initiating the connection
- 'Public Function GetAuthToken()\n ' +
- 'GetAuthToken = m_Auth\n' +
- 'End Function\n' +
-
- // A wrapper method which causes a
- // message to be sent to the other context.
- 'Public Sub SendMessage(service, payload)\n ' +
- 'Call m_Transport.' +
- goog.net.xpc.NixTransport.NIX_HANDLE_MESSAGE + '(service, payload)\n' +
- 'End Sub\n' +
-
- // Method for setting up the inner->outer
- // channel.
- 'Public Sub CreateChannel(channel)\n ' +
- 'Call m_Transport.' +
- goog.net.xpc.NixTransport.NIX_CREATE_CHANNEL + '(channel)\n' +
- 'End Sub\n' +
-
- // An empty field with a unique identifier to
- // prevent the code from confusing this wrapper
- // with a run-of-the-mill value found in window.opener.
- 'Public Sub ' + goog.net.xpc.NixTransport.NIX_ID_FIELD + '()\n ' +
- 'End Sub\n' +
- 'End Class\n ' +
-
- // Function to get a reference to the wrapper.
- 'Function ' +
- goog.net.xpc.NixTransport.NIX_GET_WRAPPER + '(transport, auth)\n' +
- 'Dim wrap\n' +
- 'Set wrap = New ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n' +
- 'wrap.SetTransport transport\n' +
- 'wrap.SetAuth auth\n' +
- 'Set ' + goog.net.xpc.NixTransport.NIX_GET_WRAPPER + ' = wrap\n' +
- 'End Function';
+ // We create a class to act as a wrapper for
+ // a Javascript call, to prevent a break in of
+ // the context.
+ 'Class ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n ' +
+
+ // An internal member for keeping track of the
+ // transport for which this wrapper exists.
+ 'Private m_Transport\n' +
+
+ // An internal member for keeping track of the
+ // auth token associated with the context that
+ // created this wrapper. Used for validation
+ // purposes.
+ 'Private m_Auth\n' +
+
+ // Method for internally setting the value
+ // of the m_Transport property. We have the
+ // isEmpty check to prevent the transport
+ // from being overridden with an illicit
+ // object by a malicious party.
+ 'Public Sub SetTransport(transport)\n' +
+ 'If isEmpty(m_Transport) Then\n' +
+ 'Set m_Transport = transport\n' +
+ 'End If\n' +
+ 'End Sub\n' +
+
+ // Method for internally setting the value
+ // of the m_Auth property. We have the
+ // isEmpty check to prevent the transport
+ // from being overridden with an illicit
+ // object by a malicious party.
+ 'Public Sub SetAuth(auth)\n' +
+ 'If isEmpty(m_Auth) Then\n' +
+ 'm_Auth = auth\n' +
+ 'End If\n' +
+ 'End Sub\n' +
+
+ // Returns the auth token to the gadget, so it can
+ // confirm a match before initiating the connection
+ 'Public Function GetAuthToken()\n ' +
+ 'GetAuthToken = m_Auth\n' +
+ 'End Function\n' +
+
+ // A wrapper method which causes a
+ // message to be sent to the other context.
+ 'Public Sub SendMessage(service, payload)\n ' +
+ 'Call m_Transport.' +
+ goog.net.xpc.NixTransport.NIX_HANDLE_MESSAGE + '(service, payload)\n' +
+ 'End Sub\n' +
+
+ // Method for setting up the inner->outer
+ // channel.
+ 'Public Sub CreateChannel(channel)\n ' +
+ 'Call m_Transport.' +
+ goog.net.xpc.NixTransport.NIX_CREATE_CHANNEL + '(channel)\n' +
+ 'End Sub\n' +
+
+ // An empty field with a unique identifier to
+ // prevent the code from confusing this wrapper
+ // with a run-of-the-mill value found in window.opener.
+ 'Public Sub ' + goog.net.xpc.NixTransport.NIX_ID_FIELD + '()\n ' +
+ 'End Sub\n' +
+ 'End Class\n ' +
+
+ // Function to get a reference to the wrapper.
+ 'Function ' +
+ goog.net.xpc.NixTransport.NIX_GET_WRAPPER + '(transport, auth)\n' +
+ 'Dim wrap\n' +
+ 'Set wrap = New ' + goog.net.xpc.NixTransport.NIX_WRAPPER + '\n' +
+ 'wrap.SetTransport transport\n' +
+ 'wrap.SetAuth auth\n' +
+ 'Set ' + goog.net.xpc.NixTransport.NIX_GET_WRAPPER + ' = wrap\n' +
+ 'End Function';
try {
listenWindow.execScript(vbscript, 'vbscript');
@@ -263,9 +265,10 @@ goog.net.xpc.NixTransport.conductGlobalSetup_ = function(listenWindow) {
* The transport type.
* @type {number}
* @protected
+ * @override
*/
goog.net.xpc.NixTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.NIX;
+ goog.net.xpc.TransportTypes.NIX;
/**
@@ -292,6 +295,7 @@ goog.net.xpc.NixTransport.prototype.nixChannel_ = null;
/**
* Connect this transport.
+ * @override
*/
goog.net.xpc.NixTransport.prototype.connect = function() {
if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER) {
@@ -319,14 +323,14 @@ goog.net.xpc.NixTransport.prototype.attemptOuterSetup_ = function() {
// Get shortcut to iframe-element that contains the inner
// page.
- var innerFrame = this.channel_.iframeElement_;
+ var innerFrame = this.channel_.getIframeElement();
try {
// Attempt to place the NIX wrapper object into the inner
// frame's opener property.
- innerFrame.contentWindow.opener =
- this.getWindow()[goog.net.xpc.NixTransport.NIX_GET_WRAPPER]
- (this, this.authToken_);
+ var theWindow = this.getWindow();
+ var getWrapper = theWindow[goog.net.xpc.NixTransport.NIX_GET_WRAPPER];
+ innerFrame.contentWindow.opener = getWrapper(this, this.authToken_);
this.localSetupCompleted_ = true;
}
catch (e) {
@@ -376,14 +380,14 @@ goog.net.xpc.NixTransport.prototype.attemptInnerSetup_ = function() {
// Complete the construction of the channel by sending our own
// wrapper to the container via the channel they gave us.
- this.nixChannel_['CreateChannel'](
- this.getWindow()[goog.net.xpc.NixTransport.NIX_GET_WRAPPER](this,
- this.authToken_));
+ var theWindow = this.getWindow();
+ var getWrapper = theWindow[goog.net.xpc.NixTransport.NIX_GET_WRAPPER];
+ this.nixChannel_['CreateChannel'](getWrapper(this, this.authToken_));
this.localSetupCompleted_ = true;
// Notify channel that the transport is ready.
- this.channel_.notifyConnected_();
+ this.channel_.notifyConnected();
}
}
catch (e) {
@@ -408,25 +412,25 @@ goog.net.xpc.NixTransport.prototype.attemptInnerSetup_ = function() {
* @private
*/
goog.net.xpc.NixTransport.prototype.createChannel_ = function(channel) {
- // Verify that the channel is in fact a NIX wrapper.
- if (typeof channel != 'unknown' ||
- !(goog.net.xpc.NixTransport.NIX_ID_FIELD in channel)) {
- goog.net.xpc.logger.severe('Invalid NIX channel given to createChannel_');
- }
+ // Verify that the channel is in fact a NIX wrapper.
+ if (typeof channel != 'unknown' ||
+ !(goog.net.xpc.NixTransport.NIX_ID_FIELD in channel)) {
+ goog.net.xpc.logger.severe('Invalid NIX channel given to createChannel_');
+ }
- this.nixChannel_ = channel;
+ this.nixChannel_ = channel;
- // Ensure that the NIX channel given to use is valid.
- var remoteAuthToken = this.nixChannel_['GetAuthToken']();
+ // Ensure that the NIX channel given to use is valid.
+ var remoteAuthToken = this.nixChannel_['GetAuthToken']();
- if (remoteAuthToken != this.remoteAuthToken_) {
- goog.net.xpc.logger.severe('Invalid auth token from other party');
- return;
- }
+ if (remoteAuthToken != this.remoteAuthToken_) {
+ goog.net.xpc.logger.severe('Invalid auth token from other party');
+ return;
+ }
- // Indicate to the CrossPageChannel that the channel is setup
- // and ready to use.
- this.channel_.notifyConnected_();
+ // Indicate to the CrossPageChannel that the channel is setup
+ // and ready to use.
+ this.channel_.notifyConnected();
};
@@ -440,11 +444,10 @@ goog.net.xpc.NixTransport.prototype.createChannel_ = function(channel) {
*/
goog.net.xpc.NixTransport.prototype.handleMessage_ =
function(serviceName, payload) {
-
- function deliveryHandler() {
- this.channel_.deliver_(serviceName, payload);
- }
-
+ /** @this {goog.net.xpc.NixTransport} */
+ var deliveryHandler = function() {
+ this.channel_.xpcDeliver(serviceName, payload);
+ };
this.getWindow().setTimeout(goog.bind(deliveryHandler, this), 1);
};
@@ -454,6 +457,7 @@ goog.net.xpc.NixTransport.prototype.handleMessage_ =
* @param {string} service The name of the service the message is to be
* delivered to.
* @param {string} payload The message content.
+ * @override
*/
goog.net.xpc.NixTransport.prototype.send = function(service, payload) {
// Verify that the NIX channel we have is valid.
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/all-wcprops
deleted file mode 100644
index 70d4082..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/all-wcprops
+++ /dev/null
@@ -1,11 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 53
-/svn/!svn/ver/850/trunk/closure/goog/net/xpc/testdata
-END
-inner_peer.html
-K 25
-svn:wc:ra_dav:version-url
-V 69
-/svn/!svn/ver/850/trunk/closure/goog/net/xpc/testdata/inner_peer.html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/entries b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/entries
deleted file mode 100644
index 1546951..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/entries
+++ /dev/null
@@ -1,62 +0,0 @@
-10
-
-dir
-1494
-http://closure-library.googlecode.com/svn/trunk/closure/goog/net/xpc/testdata
-http://closure-library.googlecode.com/svn
-
-
-
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0b95b8e8-c90f-11de-9d4f-f947ee5921c8
-
-inner_peer.html
-file
-
-
-
-
-2011-12-23T22:42:30.122351Z
-8ebad8dd356b11b51e61f3a141b470f1
-2011-04-12T20:35:47.000000Z
-850
-diegosalas@google.com
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2646
-
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/prop-base/inner_peer.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/prop-base/inner_peer.html.svn-base
deleted file mode 100644
index d356868..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/prop-base/inner_peer.html.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-K 13
-svn:mime-type
-V 9
-text/html
-END
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/text-base/inner_peer.html.svn-base b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/text-base/inner_peer.html.svn-base
deleted file mode 100644
index 3d9530b..0000000
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/.svn/text-base/inner_peer.html.svn-base
+++ /dev/null
@@ -1,106 +0,0 @@
-<!DOCTYPE html>
-<!--
-
- This file is responsible for setting up the inner peer half of an XPC
- communication channel. It instantiates a CrossPageChannel and attempts to
- connect to the outer peer. The XPC configuration should match that of the
- outer peer (i.e. same channel name, polling URIs, etc).
--->
-<html>
-<!--
-Copyright 2009 The Closure Library Authors. All Rights Reserved.
-
-Use of this source code is governed by the Apache License, Version 2.0.
-See the COPYING file for details.
--->
-
-<head>
-<script src="../../../base.js"></script>
-<script>
-goog.require('goog.debug.Logger');
-goog.require('goog.dom');
-goog.require('goog.events');
-goog.require('goog.events.EventType');
-goog.require('goog.net.xpc.CrossPageChannel');
-</script>
-<script>
-var channel;
-var queuedMessage;
-
-function clearDebug() {
- document.getElementById('debugDiv').innerHTML = '';
-}
-
-function instantiateChannel(cfg) {
- if (window.channel) {
- window.channel.dispose();
- }
- window.channel = new goog.net.xpc.CrossPageChannel(cfg);
- window.channel.registerService('echo', echoHandler);
-}
-
-function connectChannel(opt_callback) {
- var callback = opt_callback || goog.nullFunction;
-
- window.channel.connect(function() {
- callback();
-
- var message = window.queuedMessage;
- if (message) {
- window.queuedMessage = null;
- echoHandler(message);
- }
- });
-}
-
-function isConnected() {
- return window.channel && window.channel.isConnected();
-}
-
-function echoHandler(payload) {
- // TODO(user): Works around the bug where the parent
- // can get the connect callback before the child is
- // marked as connected.
- if (isConnected()) {
- window.channel.send('msg', payload);
- } else {
- window.queuedMessage = payload;
- }
-}
-
-function handleLoad(evt) {
- // Get the channel configuration passed by the containing document.
- var xpc = (new goog.Uri(window.location.href)).getParameterValue('xpc');
- if (xpc) {
- var cfg = goog.json.parse(xpc);
- instantiateChannel(cfg);
- connectChannel();
- }
-}
-
-goog.events.listen(window, goog.events.EventType.LOAD, handleLoad);
-
-</script>
-</head>
-
-<body>
-
-<div style="position:absolute">
- Debug [<a href="#" onclick="clearDebug()">clear</a>]: <br>
- <div id=debugDiv style="border: 1px #000000 solid; font-size:xx-small"></div>
-</div>
-
-<script>
-var debugDiv = goog.dom.getElement('debugDiv');
-var logger = goog.debug.Logger.getLogger('goog.net.xpc');
-logger.setLevel(goog.debug.Logger.Level.ALL);
-logger.addHandler(function(logRecord) {
- var msgElm = goog.dom.createDom('div');
- msgElm.innerHTML = logRecord.getMessage();
- goog.dom.appendChild(debugDiv, msgElm);
-});
-</script>
-
-</body>
-
-</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/access_checker.html b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/access_checker.html
new file mode 100644
index 0000000..10a421e
--- /dev/null
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/access_checker.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+
+ This file checks whether the current browser can access properties from same
+ domain iframes. This is currently a problem on the matrix brower ie6 and xp.
+ For some reason it can't access same domain iframes.
+ TODO(user): Figure out why it can't.
+ -->
+<html>
+ <!--
+ Copyright 2011 The Closure Library Authors. All Rights Reserved.
+
+ Use of this source code is governed by the Apache License, Version 2.0.
+ See the COPYING file for details.
+ -->
+ <head>
+ <title>The access checking iframe</title>
+ </head>
+ <body>
+ <script type="text/javascript">
+ try {
+ var sameDomainIframeHref = parent.frames['nonexistant'].location.href;
+ parent.sameDomainIframeAccessComplete(true);
+ } catch (e) {
+ parent.sameDomainIframeAccessComplete(false);
+ }
+ </script>
+ </body>
+</html>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/inner_peer.html b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/inner_peer.html
index 3d9530b..5542f79 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/inner_peer.html
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/testdata/inner_peer.html
@@ -15,18 +15,21 @@ See the COPYING file for details.
-->
<head>
-<script src="../../../base.js"></script>
-<script>
+<title>XPC test inner frame</title>
+<script src="../../../base.js" type="text/javascript"></script>
+<script type="text/javascript">
goog.require('goog.debug.Logger');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.net.xpc.CrossPageChannel');
</script>
-<script>
+<script type="text/javascript">
var channel;
var queuedMessage;
+var OBJECT_RESULT_FROM_SERVICE = {'favorites': 'pie'};
+
function clearDebug() {
document.getElementById('debugDiv').innerHTML = '';
}
@@ -37,49 +40,35 @@ function instantiateChannel(cfg) {
}
window.channel = new goog.net.xpc.CrossPageChannel(cfg);
window.channel.registerService('echo', echoHandler);
+ window.channel.registerService('response', responseHandler);
+ connectChannel(
+ parent.driver && parent.driver.innerFrameConnected ?
+ goog.bind(parent.driver.innerFrameConnected, parent.driver) : null);
}
function connectChannel(opt_callback) {
- var callback = opt_callback || goog.nullFunction;
+ window.channel.connect(opt_callback || goog.nullFunction);
+}
- window.channel.connect(function() {
- callback();
+function sendEcho(payload) {
+ window.channel.send('echo', payload);
+}
- var message = window.queuedMessage;
- if (message) {
- window.queuedMessage = null;
- echoHandler(message);
- }
- });
+function echoHandler(payload) {
+ window.channel.send('response', payload);
+ return OBJECT_RESULT_FROM_SERVICE;
}
function isConnected() {
return window.channel && window.channel.isConnected();
}
-function echoHandler(payload) {
- // TODO(user): Works around the bug where the parent
- // can get the connect callback before the child is
- // marked as connected.
- if (isConnected()) {
- window.channel.send('msg', payload);
- } else {
- window.queuedMessage = payload;
- }
-}
-
-function handleLoad(evt) {
- // Get the channel configuration passed by the containing document.
- var xpc = (new goog.Uri(window.location.href)).getParameterValue('xpc');
- if (xpc) {
- var cfg = goog.json.parse(xpc);
- instantiateChannel(cfg);
- connectChannel();
+function responseHandler(payload) {
+ if (parent.driver && parent.driver.innerFrameGotResponse) {
+ parent.driver.innerFrameGotResponse(payload);
}
}
-goog.events.listen(window, goog.events.EventType.LOAD, handleLoad);
-
</script>
</head>
@@ -90,7 +79,7 @@ goog.events.listen(window, goog.events.EventType.LOAD, handleLoad);
<div id=debugDiv style="border: 1px #000000 solid; font-size:xx-small"></div>
</div>
-<script>
+<script type="text/javascript">
var debugDiv = goog.dom.getElement('debugDiv');
var logger = goog.debug.Logger.getLogger('goog.net.xpc');
logger.setLevel(goog.debug.Logger.Level.ALL);
@@ -99,6 +88,7 @@ logger.addHandler(function(logRecord) {
msgElm.innerHTML = logRecord.getMessage();
goog.dom.appendChild(debugDiv, msgElm);
});
+
</script>
</body>
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/transport.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/transport.js
index b9148af..6f63651 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/transport.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/transport.js
@@ -90,7 +90,7 @@ goog.net.xpc.Transport.prototype.transportServiceHandler = goog.abstractMethod;
/**
* Connects this transport.
* The transport implementation is expected to call
- * CrossPageChannel.prototype.notifyConnected_ when the channel is ready
+ * CrossPageChannel.prototype.notifyConnected when the channel is ready
* to be used.
*/
goog.net.xpc.Transport.prototype.connect = goog.abstractMethod;
@@ -100,6 +100,6 @@ goog.net.xpc.Transport.prototype.connect = goog.abstractMethod;
* Sends a message.
* @param {string} service The name off the service the message is to be
* delivered to.
- * @param {string|Object} payload The message content.
+ * @param {string} payload The message content.
*/
goog.net.xpc.Transport.prototype.send = goog.abstractMethod;
diff --git a/contexts/data/lib/closure-library/closure/goog/net/xpc/xpc.js b/contexts/data/lib/closure-library/closure/goog/net/xpc/xpc.js
index c74a349..be1b62e 100644
--- a/contexts/data/lib/closure-library/closure/goog/net/xpc/xpc.js
+++ b/contexts/data/lib/closure-library/closure/goog/net/xpc/xpc.js
@@ -148,7 +148,45 @@ goog.net.xpc.CfgFields = {
* (if specified). Used for security sensitive applications that make
* use of NativeMessagingTransport (i.e. most applications).
*/
- PEER_HOSTNAME: 'ph'
+ PEER_HOSTNAME: 'ph',
+ /**
+ * Usually both frames using a connection initially send a SETUP message to
+ * each other, and each responds with a SETUP_ACK. A frame marks itself
+ * connected when it receives that SETUP_ACK. If this parameter is true
+ * however, the channel it is passed to will not send a SETUP, but rather will
+ * wait for one from its peer and mark itself connected when that arrives.
+ * Peer iframes created using such a channel will send SETUP however, and will
+ * wait for SETUP_ACK before marking themselves connected. The goal is to
+ * cope with a situation where the availability of the URL for the peer frame
+ * cannot be relied on, eg when the application is offline. Without this
+ * setting, the primary frame will attempt to send its SETUP message every
+ * 100ms, forever. This floods the javascript console with uncatchable
+ * security warnings, and fruitlessly burns CPU. There is one scenario this
+ * mode will not support, and that is reconnection by the outer frame, ie the
+ * creation of a new channel object to connect to a peer iframe which was
+ * already communicating with a previous channel object of the same name. If
+ * that behavior is needed, this mode should not be used. Reconnection by
+ * inner frames is supported in this mode however.
+ */
+ ONE_SIDED_HANDSHAKE: 'osh',
+ /**
+ * The frame role (inner or outer). Used to explicitly indicate the role for
+ * each peer whenever the role cannot be reliably determined (e.g. the two
+ * peer windows are not parent/child frames). If unspecified, the role will
+ * be dynamically determined, assuming a parent/child frame setup.
+ */
+ ROLE: 'role',
+ /**
+ * Which version of the native transport startup protocol should be used, the
+ * default being '2'. Version 1 had various timing vulnerabilities, which
+ * had to be compensated for by introducing delays, and is deprecated. V1
+ * and V2 are broadly compatible, although the more robust timing and lack
+ * of delays is not gained unless both sides are using V2. The only
+ * unsupported case of cross-protocol interoperation is where a connection
+ * starts out with V2 at both ends, and one of the ends reconnects as a V1.
+ * All other initial startup and reconnection scenarios are supported.
+ */
+ NATIVE_TRANSPORT_PROTOCOL_VERSION: 'nativeProtocolVersion'
};
@@ -178,31 +216,47 @@ goog.net.xpc.ChannelStates = {
/**
* The name of the transport service (used for internal signalling).
* @type {string}
- * @private
+ * @suppress {underscore}
*/
goog.net.xpc.TRANSPORT_SERVICE_ = 'tp';
/**
* Transport signaling message: setup.
- * @protected
+ * @type {string}
*/
goog.net.xpc.SETUP = 'SETUP';
/**
+ * Transport signaling message: setup for native transport protocol v2.
+ * @type {string}
+ */
+goog.net.xpc.SETUP_NTPV2 = 'SETUP_NTPV2';
+
+
+/**
* Transport signaling message: setup acknowledgement.
- * @private
+ * @type {string}
+ * @suppress {underscore}
*/
goog.net.xpc.SETUP_ACK_ = 'SETUP_ACK';
/**
+ * Transport signaling message: setup acknowledgement.
+ * @type {string}
+ */
+goog.net.xpc.SETUP_ACK_NTPV2 = 'SETUP_ACK_NTPV2';
+
+
+/**
* Object holding active channels.
- * @type {Object}
- * @private
+ * Package private. Do not call from outside goog.net.xpc.
+ *
+ * @type {Object.<string, goog.net.xpc.CrossPageChannel>}
*/
-goog.net.xpc.channels_ = {};
+goog.net.xpc.channels = {};
/**