| OLD | NEW |
| 1 // Helper method that waits for a {success: <boolean>, result: any} reply on | 1 // Helper method that waits for a {success: <boolean>, result: any} reply on |
| 2 // a port and returns a promise that resolves (if success is true) or rejects | 2 // a port and returns a promise that resolves (if success is true) or rejects |
| 3 // the promise with the value of the result attribute. | 3 // the promise with the value of the result attribute. |
| 4 function reply_as_promise(t, port) { | 4 function reply_as_promise(t, port) { |
| 5 return new Promise(function(resolve, reject) { | 5 return new Promise(function(resolve, reject) { |
| 6 var got_reply = false; | 6 var got_reply = false; |
| 7 port.onmessage = t.step_func(function(event) { | 7 port.onmessage = t.step_func(function(event) { |
| 8 assert_false(got_reply); | 8 assert_false(got_reply); |
| 9 assert_true('success' in event.data); | 9 assert_true('success' in event.data); |
| 10 assert_true('result' in event.data); | 10 assert_true('result' in event.data); |
| 11 got_reply = true; | 11 got_reply = true; |
| 12 if (event.data.success) | 12 if (event.data.success) |
| 13 resolve(event.data.result); | 13 resolve(event.data.result); |
| 14 else | 14 else |
| 15 reject(event.data.result); | 15 reject(event.data.result); |
| 16 }); | 16 }); |
| 17 }); | 17 }); |
| 18 } | 18 } |
| 19 | 19 |
| 20 // Method that behaves similarly to navigator.connect, but the actual connect | 20 // Method that behaves similarly to navigator.services.connect, but the actual |
| 21 // call is made from a cross origin iframe. | 21 // connect call is made from a cross origin iframe. Also the returned port is a |
| 22 function cross_origin_connect(t, service) { | 22 // MessagePort instead of a ServicePort, but with targetURL, name and data |
| 23 // attributes set. |
| 24 function cross_origin_connect(t, service, options) { |
| 23 // |service| could be a relative URL, but for this to work from the iframe it | 25 // |service| could be a relative URL, but for this to work from the iframe it |
| 24 // needs an absolute URL. | 26 // needs an absolute URL. |
| 25 var target_url = new URL(service, location.origin + base_path()); | 27 var target_url = new URL(service, location.origin + base_path()); |
| 26 return with_iframe( | 28 return with_iframe( |
| 27 cross_origin + base_path() + 'resources/connect-helper.html') | 29 cross_origin + base_path() + 'resources/connect-helper.html') |
| 28 .then(function(iframe) { | 30 .then(function(iframe) { |
| 29 var channel = new MessageChannel(); | 31 var channel = new MessageChannel(); |
| 30 iframe.contentWindow.postMessage( | 32 iframe.contentWindow.postMessage( |
| 31 {connect: target_url.href, port: channel.port2}, '*', [channel.port2])
; | 33 {connect: target_url.href, port: channel.port2, options: options}, '*'
, [channel.port2]); |
| 32 return reply_as_promise(t, channel.port1); | 34 return reply_as_promise(t, channel.port1); |
| 33 }); | 35 }) |
| 36 .then(function(result) { |
| 37 var port = result.port; |
| 38 port.targetURL = result.targetURL; |
| 39 port.name = result.name; |
| 40 port.data = result.data; |
| 41 return port; |
| 42 }); |
| 34 } | 43 } |
| 35 | 44 |
| 36 // Method that behaves similarly to navigator.connect, but the actual connect | 45 // Method that behaves similarly to navigator.connect, but the actual connect |
| 37 // call is made from a worker. | 46 // call is made from a worker. Also the returned port is a MessagePort instead |
| 38 function connect_from_worker(t, service) { | 47 // of a ServicePort, but with targetURL, name and data attributes set. |
| 48 function connect_from_worker(t, service, options) { |
| 39 // |service| is a relative URL, but for this to work from the worker it needs | 49 // |service| is a relative URL, but for this to work from the worker it needs |
| 40 // an absolute URL. | 50 // an absolute URL. |
| 41 var target_url = location.origin + base_path() + service; | 51 var target_url = location.origin + base_path() + service; |
| 42 var worker = new Worker('resources/connect-helper.js'); | 52 var worker = new Worker('resources/connect-helper.js'); |
| 43 var channel = new MessageChannel(); | 53 var channel = new MessageChannel(); |
| 44 worker.postMessage | 54 worker.postMessage |
| 45 ({connect: target_url, port: channel.port2}, [channel.port2]); | 55 ({connect: target_url, port: channel.port2, options: options}, [channel.port
2]); |
| 46 return reply_as_promise(t, channel.port1); | 56 return reply_as_promise(t, channel.port1) |
| 47 } | 57 .then(function(result) { |
| 48 | 58 var port = result.port; |
| 49 // Similar to Promise.race, except that returned promise only rejects if all | 59 port.targetURL = result.targetURL; |
| 50 // passed promises reject. Used temporarily to support both old and new client | 60 port.name = result.name; |
| 51 // side APIs. | 61 port.data = result.data; |
| 52 function first_to_resolve(promises) { | 62 return port; |
| 53 return new Promise(function(resolve, reject) { | 63 }); |
| 54 var remaining = promises.length; | |
| 55 var resolved = false; | |
| 56 for (var i = 0; i < promises.length; ++i) { | |
| 57 Promise.resolve(promises[i]) | |
| 58 .then(function(result) { | |
| 59 if (!resolved) { | |
| 60 resolve(result); | |
| 61 resolved = true; | |
| 62 } | |
| 63 }) | |
| 64 .catch(function(result) { | |
| 65 remaining--; | |
| 66 if (remaining === 0) { | |
| 67 reject(result); | |
| 68 } | |
| 69 }); | |
| 70 } | |
| 71 }); | |
| 72 } | 64 } |
| 73 | 65 |
| 74 // Takes (a promise resolving to) a ServicePort instance, and returns a Promise | 66 // Takes (a promise resolving to) a ServicePort instance, and returns a Promise |
| 75 // that resolves to a MessagePort wrapping that ServicePort. Used to support | 67 // that resolves to a MessagePort wrapping that ServicePort. Used to simplify |
| 76 // both old and new APIs at the same time. | 68 // testing code and to allow forwarding a connection from a cross origin iframe |
| 69 // or worker to the main test runner. |
| 77 function wrap_in_port(maybe_port) { | 70 function wrap_in_port(maybe_port) { |
| 78 return Promise.resolve(maybe_port).then( | 71 return Promise.resolve(maybe_port).then( |
| 79 function(port) { | 72 function(port) { |
| 80 var channel = new MessageChannel(); | 73 var channel = new MessageChannel(); |
| 81 channel.port2.onmessage = function(event) { | 74 channel.port2.onmessage = function(event) { |
| 82 port.postMessage(event.data, event.ports); | 75 port.postMessage(event.data, event.ports); |
| 83 }; | 76 }; |
| 84 // Should use addEventListener and check source of event, but source isn't | 77 // Should use addEventListener and check source of event, but source isn't |
| 85 // set yet, so for now just assume only one wrapped port is used at a time
. | 78 // set yet, so for now just assume only one wrapped port is used at a time
. |
| 86 navigator.services.onmessage = function(event) { | 79 navigator.services.onmessage = function(event) { |
| 87 channel.port2.postMessage(event.data, event.ports); | 80 channel.port2.postMessage(event.data, event.ports); |
| 88 }; | 81 }; |
| 82 channel.port1.targetURL = port.targetURL; |
| 83 channel.port1.name = port.name; |
| 84 channel.port1.data = port.data; |
| 89 return channel.port1; | 85 return channel.port1; |
| 90 } | 86 } |
| 91 ); | 87 ); |
| 92 } | 88 } |
| 93 | 89 |
| 94 var promise_tests = Promise.resolve(); | 90 var promise_tests = Promise.resolve(); |
| 95 // Helper function to run promise tests one after the other. | 91 // Helper function to run promise tests one after the other. |
| 96 // TODO(ortuno): Remove once https://github.com/w3c/testharness.js/pull/115/file
s | 92 // TODO(ortuno): Remove once https://github.com/w3c/testharness.js/pull/115/file
s |
| 97 // gets through. | 93 // gets through. |
| 98 function sequential_promise_test(func, name) { | 94 function sequential_promise_test(func, name) { |
| 99 var test = async_test(name); | 95 var test = async_test(name); |
| 100 promise_tests = promise_tests.then(function() { | 96 promise_tests = promise_tests.then(function() { |
| 101 return test.step(func, test, test); | 97 return test.step(func, test, test); |
| 102 }).then(function() { | 98 }).then(function() { |
| 103 test.done(); | 99 test.done(); |
| 104 }).catch(test.step_func(function(value) { | 100 }).catch(test.step_func(function(value) { |
| 105 // step_func catches the error again so the error doesn't propagate. | 101 // step_func catches the error again so the error doesn't propagate. |
| 106 throw value; | 102 throw value; |
| 107 })); | 103 })); |
| 108 } | 104 } |
| OLD | NEW |